rabbitmq-server-3.5.7/0000755000177700017770000000000012633765070014454 5ustar michaelmichaelrabbitmq-server-3.5.7/scripts/0000755000177700017770000000000012633765070016143 5ustar michaelmichaelrabbitmq-server-3.5.7/scripts/rabbitmq-env.bat0000755000177700017770000001722412633765070021233 0ustar michaelmichael@echo off REM Scopes the variables to the current batch file REM setlocal rem Preserve values that might contain exclamation marks before rem enabling delayed expansion set TDP0=%~dp0 REM setlocal enabledelayedexpansion REM SCRIPT_DIR=`dirname $SCRIPT_PATH` REM RABBITMQ_HOME="${SCRIPT_DIR}/.." set SCRIPT_DIR=%TDP0% set RABBITMQ_HOME=%SCRIPT_DIR%.. REM ## Set defaults REM . ${SCRIPT_DIR}/rabbitmq-defaults call "%SCRIPT_DIR%\rabbitmq-defaults.bat" REM These common defaults aren't referenced in the batch scripts REM ## Common defaults REM SERVER_ERL_ARGS="+P 1048576" REM REM # warn about old rabbitmq.conf file, if no new one REM if [ -f /etc/rabbitmq/rabbitmq.conf ] && \ REM [ ! -f ${CONF_ENV_FILE} ] ; then REM echo -n "WARNING: ignoring /etc/rabbitmq/rabbitmq.conf -- " REM echo "location has moved to ${CONF_ENV_FILE}" REM fi REM ERL_ARGS aren't referenced in the batch scripts REM Common defaults REM set SERVER_ERL_ARGS=+P 1048576 REM ## Get configuration variables from the configure environment file REM [ -f ${CONF_ENV_FILE} ] && . ${CONF_ENV_FILE} || true if exist "!RABBITMQ_CONF_ENV_FILE!" ( call "!RABBITMQ_CONF_ENV_FILE!" ) REM Check for the short names here too if "!RABBITMQ_USE_LONGNAME!"=="" ( if "!USE_LONGNAME!"=="" ( set RABBITMQ_NAME_TYPE="-sname" ) ) if "!RABBITMQ_USE_LONGNAME!"=="true" ( if "!USE_LONGNAME!"=="true" ( set RABBITMQ_NAME_TYPE="-name" ) ) if "!COMPUTERNAME!"=="" ( set COMPUTERNAME=localhost ) REM [ "x" = "x$RABBITMQ_NODENAME" ] && RABBITMQ_NODENAME=${NODENAME} if "!RABBITMQ_NODENAME!"=="" ( if "!NODENAME!"=="" ( set RABBITMQ_NODENAME=rabbit@!COMPUTERNAME! ) else ( set RABBITMQ_NODENAME=!NODENAME! ) ) REM REM ##--- Set environment vars RABBITMQ_ to defaults if not set REM REM DEFAULT_NODE_IP_ADDRESS=auto REM DEFAULT_NODE_PORT=5672 REM [ "x" = "x$RABBITMQ_NODE_IP_ADDRESS" ] && RABBITMQ_NODE_IP_ADDRESS=${NODE_IP_ADDRESS} REM [ "x" = "x$RABBITMQ_NODE_PORT" ] && RABBITMQ_NODE_PORT=${NODE_PORT} REM [ "x" = "x$RABBITMQ_NODE_IP_ADDRESS" ] && [ "x" != "x$RABBITMQ_NODE_PORT" ] && RABBITMQ_NODE_IP_ADDRESS=${DEFAULT_NODE_IP_ADDRESS} REM [ "x" != "x$RABBITMQ_NODE_IP_ADDRESS" ] && [ "x" = "x$RABBITMQ_NODE_PORT" ] && RABBITMQ_NODE_PORT=${DEFAULT_NODE_PORT} REM if "!RABBITMQ_NODE_IP_ADDRESS!"=="" ( REM if not "!RABBITMQ_NODE_PORT!"=="" ( REM set RABBITMQ_NODE_IP_ADDRESS=auto REM ) REM ) else ( REM if "!RABBITMQ_NODE_PORT!"=="" ( REM set RABBITMQ_NODE_PORT=5672 REM ) REM ) if "!RABBITMQ_NODE_IP_ADDRESS!"=="" ( if not "!NODE_IP_ADDRESS!"=="" ( set RABBITMQ_NODE_IP_ADDRESS=!NODE_IP_ADDRESS! ) ) if "!RABBITMQ_NODE_PORT!"=="" ( if not "!NODE_PORT!"=="" ( set RABBITMQ_NODE_PORT=!NODE_PORT! ) ) if "!RABBITMQ_NODE_IP_ADDRESS!"=="" ( if not "!RABBITMQ_NODE_PORT!"=="" ( set RABBITMQ_NODE_IP_ADDRESS=auto ) ) else ( if "!RABBITMQ_NODE_PORT!"=="" ( set RABBITMQ_NODE_PORT=5672 ) ) REM [ "x" = "x$RABBITMQ_DIST_PORT" ] && RABBITMQ_DIST_PORT=${DIST_PORT} REM [ "x" = "x$RABBITMQ_DIST_PORT" ] && [ "x" = "x$RABBITMQ_NODE_PORT" ] && RABBITMQ_DIST_PORT=$((${DEFAULT_NODE_PORT} + 20000)) REM [ "x" = "x$RABBITMQ_DIST_PORT" ] && [ "x" != "x$RABBITMQ_NODE_PORT" ] && RABBITMQ_DIST_PORT=$((${RABBITMQ_NODE_PORT} + 20000)) if "!RABBITMQ_DIST_PORT!"=="" ( if "!DIST_PORT!"=="" ( if "!RABBITMQ_NODE_PORT!"=="" ( set RABBITMQ_DIST_PORT=25672 ) else ( set /a RABBITMQ_DIST_PORT=20000+!RABBITMQ_NODE_PORT! ) ) else ( set RABBITMQ_DIST_PORT=!DIST_PORT! ) ) REM [ "x" = "x$RABBITMQ_SERVER_ERL_ARGS" ] && RABBITMQ_SERVER_ERL_ARGS=${SERVER_ERL_ARGS} REM No Windows equivalent REM [ "x" = "x$RABBITMQ_CONFIG_FILE" ] && RABBITMQ_CONFIG_FILE=${CONFIG_FILE} if "!RABBITMQ_CONFIG_FILE!"=="" ( if "!CONFIG_FILE!"=="" ( set RABBITMQ_CONFIG_FILE=!RABBITMQ_BASE!\rabbitmq ) else ( set RABBITMQ_CONFIG_FILE=!CONFIG_FILE! ) ) REM [ "x" = "x$RABBITMQ_LOG_BASE" ] && RABBITMQ_LOG_BASE=${LOG_BASE} if "!RABBITMQ_LOG_BASE!"=="" ( if "!LOG_BASE!"=="" ( set RABBITMQ_LOG_BASE=!RABBITMQ_BASE!\log ) else ( set RABBITMQ_LOG_BASE=!LOG_BASE! ) ) REM [ "x" = "x$RABBITMQ_MNESIA_BASE" ] && RABBITMQ_MNESIA_BASE=${MNESIA_BASE} if "!RABBITMQ_MNESIA_BASE!"=="" ( if "!MNESIA_BASE!"=="" ( set RABBITMQ_MNESIA_BASE=!RABBITMQ_BASE!\db ) else ( set RABBITMQ_MNESIA_BASE=!MNESIA_BASE! ) ) REM [ "x" = "x$RABBITMQ_SERVER_START_ARGS" ] && RABBITMQ_SERVER_START_ARGS=${SERVER_START_ARGS} REM No Windows equivalent REM [ "x" = "x$RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS" ] && RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS=${SERVER_ADDITIONAL_ERL_ARGS} REM No Windows equivalent REM [ "x" = "x$RABBITMQ_MNESIA_DIR" ] && RABBITMQ_MNESIA_DIR=${MNESIA_DIR} REM [ "x" = "x$RABBITMQ_MNESIA_DIR" ] && RABBITMQ_MNESIA_DIR=${RABBITMQ_MNESIA_BASE}/${RABBITMQ_NODENAME} if "!RABBITMQ_MNESIA_DIR!"=="" ( if "!MNESIA_DIR!"=="" ( set RABBITMQ_MNESIA_DIR=!RABBITMQ_MNESIA_BASE!/!RABBITMQ_NODENAME!-mnesia ) else ( set RABBITMQ_MNESIA_DIR=!MNESIA_DIR! ) ) REM [ "x" = "x$RABBITMQ_PID_FILE" ] && RABBITMQ_PID_FILE=${PID_FILE} REM [ "x" = "x$RABBITMQ_PID_FILE" ] && RABBITMQ_PID_FILE=${RABBITMQ_MNESIA_DIR}.pid REM No Windows equivalent REM [ "x" = "x$RABBITMQ_BOOT_MODULE" ] && RABBITMQ_BOOT_MODULE=${BOOT_MODULE} if "!RABBITMQ_BOOT_MODULE!"=="" ( if "!BOOT_MODULE!"=="" ( set RABBITMQ_BOOT_MODULE=rabbit ) else ( set RABBITMQ_BOOT_MODULE=!BOOT_MODULE! ) ) REM [ "x" = "x$RABBITMQ_PLUGINS_EXPAND_DIR" ] && RABBITMQ_PLUGINS_EXPAND_DIR=${PLUGINS_EXPAND_DIR} REM [ "x" = "x$RABBITMQ_PLUGINS_EXPAND_DIR" ] && RABBITMQ_PLUGINS_EXPAND_DIR=${RABBITMQ_MNESIA_BASE}/${RABBITMQ_NODENAME}-plugins-expand if "!RABBITMQ_PLUGINS_EXPAND_DIR!"=="" ( if "!PLUGINS_EXPAND_DIR!"=="" ( set RABBITMQ_PLUGINS_EXPAND_DIR=!RABBITMQ_MNESIA_BASE!/!RABBITMQ_NODENAME!-plugins-expand ) else ( set RABBITMQ_PLUGINS_EXPAND_DIR=!PLUGINS_EXPAND_DIR! ) ) REM [ "x" = "x$RABBITMQ_ENABLED_PLUGINS_FILE" ] && RABBITMQ_ENABLED_PLUGINS_FILE=${ENABLED_PLUGINS_FILE} if "!RABBITMQ_ENABLED_PLUGINS_FILE!"=="" ( if "!ENABLED_PLUGINS_FILE!"=="" ( set RABBITMQ_ENABLED_PLUGINS_FILE=!RABBITMQ_BASE!\enabled_plugins ) else ( set RABBITMQ_ENABLED_PLUGINS_FILE=!ENABLED_PLUGINS_FILE! ) ) REM [ "x" = "x$RABBITMQ_PLUGINS_DIR" ] && RABBITMQ_PLUGINS_DIR=${PLUGINS_DIR} if "!RABBITMQ_PLUGINS_DIR!"=="" ( if "!PLUGINS_DIR!"=="" ( set RABBITMQ_PLUGINS_DIR=!RABBITMQ_HOME!\plugins ) else ( set RABBITMQ_PLUGINS_DIR=!PLUGINS_DIR! ) ) REM ## Log rotation REM [ "x" = "x$RABBITMQ_LOGS" ] && RABBITMQ_LOGS=${LOGS} REM [ "x" = "x$RABBITMQ_LOGS" ] && RABBITMQ_LOGS="${RABBITMQ_LOG_BASE}/${RABBITMQ_NODENAME}.log" if "!RABBITMQ_LOGS!"=="" ( if "!LOGS!"=="" ( set RABBITMQ_LOGS=!RABBITMQ_LOG_BASE!\!RABBITMQ_NODENAME!.log ) else ( set RABBITMQ_LOGS=!LOGS! ) ) REM [ "x" = "x$RABBITMQ_SASL_LOGS" ] && RABBITMQ_SASL_LOGS=${SASL_LOGS} REM [ "x" = "x$RABBITMQ_SASL_LOGS" ] && RABBITMQ_SASL_LOGS="${RABBITMQ_LOG_BASE}/${RABBITMQ_NODENAME}-sasl.log" if "!RABBITMQ_SASL_LOGS!"=="" ( if "!SASL_LOGS!"=="" ( set RABBITMQ_SASL_LOGS=!RABBITMQ_LOG_BASE!\!RABBITMQ_NODENAME!-sasl.log ) else ( set RABBITMQ_SASL_LOGS=!SASL_LOGS! ) ) REM [ "x" = "x$RABBITMQ_CTL_ERL_ARGS" ] && RABBITMQ_CTL_ERL_ARGS=${CTL_ERL_ARGS} if "!$RABBITMQ_CTL_ERL_ARGS!"=="" ( if not "!CTL_ERL_ARGS!"=="" ( set RABBITMQ_CTL_ERL_ARGS=!CTL_ERL_ARGS! ) ) REM ADDITIONAL WINDOWS ONLY CONFIG ITEMS REM rabbitmq-plugins.bat REM if "!RABBITMQ_SERVICENAME!"=="" ( REM set RABBITMQ_SERVICENAME=RabbitMQ REM ) if "!RABBITMQ_SERVICENAME!"=="" ( if "!SERVICENAME!"=="" ( set RABBITMQ_SERVICENAME=RabbitMQ ) else ( set RABBITMQ_SERVICENAME=!SERVICENAME! ) ) REM ##--- End of overridden variables REM REM # Since we source this elsewhere, don't accidentally stop execution REM true rabbitmq-server-3.5.7/scripts/rabbitmqctl0000755000177700017770000000247212633765070020402 0ustar michaelmichael#!/bin/sh -e ## The contents of this file are subject to the Mozilla Public License ## Version 1.1 (the "License"); you may not use this file except in ## compliance with the License. You may obtain a copy of the License ## at http://www.mozilla.org/MPL/ ## ## 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 Original Code is RabbitMQ. ## ## The Initial Developer of the Original Code is GoPivotal, Inc. ## Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. ## # Get default settings with user overrides for (RABBITMQ_) # Non-empty defaults should be set in rabbitmq-env . `dirname $0`/rabbitmq-env # We specify Mnesia dir and sasl error logger since some actions # (e.g. forget_cluster_node --offline) require us to impersonate the # real node. RABBITMQ_USE_LONGNAME=${RABBITMQ_USE_LONGNAME} \ exec ${ERL_DIR}erl \ -pa "${RABBITMQ_HOME}/ebin" \ -noinput \ -hidden \ ${RABBITMQ_CTL_ERL_ARGS} \ -boot "${CLEAN_BOOT_FILE}" \ -sasl errlog_type error \ -mnesia dir "\"${RABBITMQ_MNESIA_DIR}\"" \ -s rabbit_control_main \ -nodename $RABBITMQ_NODENAME \ -extra "$@" rabbitmq-server-3.5.7/scripts/rabbitmqctl.bat0000755000177700017770000000332712633765070021147 0ustar michaelmichael@echo off REM The contents of this file are subject to the Mozilla Public License REM Version 1.1 (the "License"); you may not use this file except in REM compliance with the License. You may obtain a copy of the License REM at http://www.mozilla.org/MPL/ REM REM Software distributed under the License is distributed on an "AS IS" REM basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See REM the License for the specific language governing rights and REM limitations under the License. REM REM The Original Code is RabbitMQ. REM REM The Initial Developer of the Original Code is GoPivotal, Inc. REM Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. REM REM Scopes the variables to the current batch file setlocal rem Preserve values that might contain exclamation marks before rem enabling delayed expansion set TDP0=%~dp0 set STAR=%* setlocal enabledelayedexpansion REM Get default settings with user overrides for (RABBITMQ_) REM Non-empty defaults should be set in rabbitmq-env call "%TDP0%\rabbitmq-env.bat" if not exist "!ERLANG_HOME!\bin\erl.exe" ( echo. echo ****************************** echo ERLANG_HOME not set correctly. echo ****************************** echo. echo Please either set ERLANG_HOME to point to your Erlang installation or place the echo RabbitMQ server distribution in the Erlang lib folder. echo. exit /B 1 ) "!ERLANG_HOME!\bin\erl.exe" ^ -pa "!TDP0!..\ebin" ^ -noinput ^ -hidden ^ !RABBITMQ_CTL_ERL_ARGS! ^ -sasl errlog_type error ^ -mnesia dir \""!RABBITMQ_MNESIA_DIR:\=/!"\" ^ -s rabbit_control_main ^ -nodename !RABBITMQ_NODENAME! ^ -extra !STAR! endlocal endlocal rabbitmq-server-3.5.7/scripts/rabbitmq-defaults.bat0000755000177700017770000000213212633765070022242 0ustar michaelmichael@echo off REM ### next line potentially updated in package install steps REM set SYS_PREFIX= REM ### next line will be updated when generating a standalone release REM ERL_DIR= set ERL_DIR= REM These boot files don't appear to be referenced in the batch scripts REM set CLEAN_BOOT_FILE=start_clean REM set SASL_BOOT_FILE=start_sasl REM ## Set default values if "!RABBITMQ_BASE!"=="" ( set RABBITMQ_BASE=!APPDATA!\RabbitMQ ) REM BOOT_MODULE="rabbit" REM CONFIG_FILE=${SYS_PREFIX}/etc/rabbitmq/rabbitmq REM LOG_BASE=${SYS_PREFIX}/var/log/rabbitmq REM MNESIA_BASE=${SYS_PREFIX}/var/lib/rabbitmq/mnesia REM ENABLED_PLUGINS_FILE=${SYS_PREFIX}/etc/rabbitmq/enabled_plugins set BOOT_MODULE=rabbit set CONFIG_FILE=!RABBITMQ_BASE!\rabbitmq set LOG_BASE=!RABBITMQ_BASE!\log set MNESIA_BASE=!RABBITMQ_BASE!\db set ENABLED_PLUGINS_FILE=!RABBITMQ_BASE!\enabled_plugins REM PLUGINS_DIR="${RABBITMQ_HOME}/plugins" set PLUGINS_DIR=!TDP0!..\plugins REM CONF_ENV_FILE=${SYS_PREFIX}/etc/rabbitmq/rabbitmq-env.conf if "!RABBITMQ_CONF_ENV_FILE!"=="" ( set RABBITMQ_CONF_ENV_FILE=!RABBITMQ_BASE!\rabbitmq-env-conf.bat ) rabbitmq-server-3.5.7/scripts/rabbitmq-server.bat0000755000177700017770000000706412633765070021752 0ustar michaelmichael@echo off REM The contents of this file are subject to the Mozilla Public License REM Version 1.1 (the "License"); you may not use this file except in REM compliance with the License. You may obtain a copy of the License REM at http://www.mozilla.org/MPL/ REM REM Software distributed under the License is distributed on an "AS IS" REM basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See REM the License for the specific language governing rights and REM limitations under the License. REM REM The Original Code is RabbitMQ. REM REM The Initial Developer of the Original Code is GoPivotal, Inc. REM Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. REM setlocal rem Preserve values that might contain exclamation marks before rem enabling delayed expansion set TDP0=%~dp0 set STAR=%* setlocal enabledelayedexpansion REM Get default settings with user overrides for (RABBITMQ_) REM Non-empty defaults should be set in rabbitmq-env call "%TDP0%\rabbitmq-env.bat" if not exist "!ERLANG_HOME!\bin\erl.exe" ( echo. echo ****************************** echo ERLANG_HOME not set correctly. echo ****************************** echo. echo Please either set ERLANG_HOME to point to your Erlang installation or place the echo RabbitMQ server distribution in the Erlang lib folder. echo. exit /B 1 ) set RABBITMQ_EBIN_ROOT=!TDP0!..\ebin "!ERLANG_HOME!\bin\erl.exe" ^ -pa "!RABBITMQ_EBIN_ROOT!" ^ -noinput -hidden ^ -s rabbit_prelaunch ^ !RABBITMQ_NAME_TYPE! rabbitmqprelaunch!RANDOM!!TIME:~9! ^ -extra "!RABBITMQ_NODENAME!" if ERRORLEVEL 2 ( rem dist port mentioned in config, do not attempt to set it ) else if ERRORLEVEL 1 ( exit /B 1 ) else ( set RABBITMQ_DIST_ARG=-kernel inet_dist_listen_min !RABBITMQ_DIST_PORT! -kernel inet_dist_listen_max !RABBITMQ_DIST_PORT! ) set RABBITMQ_EBIN_PATH="-pa !RABBITMQ_EBIN_ROOT!" if exist "!RABBITMQ_CONFIG_FILE!.config" ( set RABBITMQ_CONFIG_ARG=-config "!RABBITMQ_CONFIG_FILE!" ) else ( set RABBITMQ_CONFIG_ARG= ) set RABBITMQ_LISTEN_ARG= if not "!RABBITMQ_NODE_IP_ADDRESS!"=="" ( if not "!RABBITMQ_NODE_PORT!"=="" ( set RABBITMQ_LISTEN_ARG=-rabbit tcp_listeners [{\""!RABBITMQ_NODE_IP_ADDRESS!"\","!RABBITMQ_NODE_PORT!"}] ) ) set RABBITMQ_START_RABBIT= if "!RABBITMQ_NODE_ONLY!"=="" ( set RABBITMQ_START_RABBIT=-s "!RABBITMQ_BOOT_MODULE!" boot ) if "!RABBITMQ_IO_THREAD_POOL_SIZE!"=="" ( set RABBITMQ_IO_THREAD_POOL_ARG=30 ) "!ERLANG_HOME!\bin\erl.exe" ^ -pa "!RABBITMQ_EBIN_ROOT!" ^ -noinput ^ -boot start_sasl ^ !RABBITMQ_START_RABBIT! ^ !RABBITMQ_CONFIG_ARG! ^ !RABBITMQ_NAME_TYPE! !RABBITMQ_NODENAME! ^ +W w ^ +A "!RABBITMQ_IO_THREAD_POOL_SIZE!" ^ +P 1048576 ^ !RABBITMQ_LISTEN_ARG! ^ !RABBITMQ_SERVER_ERL_ARGS! ^ -kernel inet_default_connect_options "[{nodelay, true}]" ^ !RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS! ^ -sasl errlog_type error ^ -sasl sasl_error_logger false ^ -rabbit error_logger {file,\""!RABBITMQ_LOGS:\=/!"\"} ^ -rabbit sasl_error_logger {file,\""!RABBITMQ_SASL_LOGS:\=/!"\"} ^ -rabbit enabled_plugins_file \""!RABBITMQ_ENABLED_PLUGINS_FILE:\=/!"\" ^ -rabbit plugins_dir \""!RABBITMQ_PLUGINS_DIR:\=/!"\" ^ -rabbit plugins_expand_dir \""!RABBITMQ_PLUGINS_EXPAND_DIR:\=/!"\" ^ -os_mon start_cpu_sup false ^ -os_mon start_disksup false ^ -os_mon start_memsup false ^ -mnesia dir \""!RABBITMQ_MNESIA_DIR:\=/!"\" ^ !RABBITMQ_SERVER_START_ARGS! ^ !RABBITMQ_DIST_ARG! ^ !STAR! endlocal endlocal rabbitmq-server-3.5.7/scripts/rabbitmq-service.bat0000755000177700017770000001511512633765070022100 0ustar michaelmichael@echo off REM The contents of this file are subject to the Mozilla Public License REM Version 1.1 (the "License"); you may not use this file except in REM compliance with the License. You may obtain a copy of the License REM at http://www.mozilla.org/MPL/ REM REM Software distributed under the License is distributed on an "AS IS" REM basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See REM the License for the specific language governing rights and REM limitations under the License. REM REM The Original Code is RabbitMQ. REM REM The Initial Developer of the Original Code is GoPivotal, Inc. REM Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. REM setlocal rem Preserve values that might contain exclamation marks before rem enabling delayed expansion set TN0=%~n0 set TDP0=%~dp0 set P1=%1 setlocal enabledelayedexpansion REM Get default settings with user overrides for (RABBITMQ_) REM Non-empty defaults should be set in rabbitmq-env call "%TDP0%\rabbitmq-env.bat" set STARVAR= shift :loop1 if "%1"=="" goto after_loop set STARVAR=%STARVAR% %1 shift goto loop1 :after_loop if "!ERLANG_SERVICE_MANAGER_PATH!"=="" ( if not exist "!ERLANG_HOME!\bin\erl.exe" ( echo. echo ****************************** echo ERLANG_HOME not set correctly. echo ****************************** echo. echo Please either set ERLANG_HOME to point to your Erlang installation or place the echo RabbitMQ server distribution in the Erlang lib folder. echo. exit /B ) for /f "delims=" %%i in ('dir /ad/b "!ERLANG_HOME!"') do if exist "!ERLANG_HOME!\%%i\bin\erlsrv.exe" ( set ERLANG_SERVICE_MANAGER_PATH=!ERLANG_HOME!\%%i\bin ) ) set CONSOLE_FLAG= set CONSOLE_LOG_VALID= for %%i in (new reuse) do if "%%i" == "!RABBITMQ_CONSOLE_LOG!" set CONSOLE_LOG_VALID=TRUE if "!CONSOLE_LOG_VALID!" == "TRUE" ( set CONSOLE_FLAG=-debugtype !RABBITMQ_CONSOLE_LOG! ) rem *** End of configuration *** if not exist "!ERLANG_SERVICE_MANAGER_PATH!\erlsrv.exe" ( echo. echo ********************************************** echo ERLANG_SERVICE_MANAGER_PATH not set correctly. echo ********************************************** echo. echo "!ERLANG_SERVICE_MANAGER_PATH!\erlsrv.exe" not found echo Please set ERLANG_SERVICE_MANAGER_PATH to the folder containing "erlsrv.exe". echo. exit /B 1 ) if "!P1!" == "install" goto INSTALL_SERVICE for %%i in (start stop disable enable list remove) do if "%%i" == "!P1!" goto MODIFY_SERVICE echo. echo ********************* echo Service control usage echo ********************* echo. echo !TN0! help - Display this help echo !TN0! install - Install the !RABBITMQ_SERVICENAME! service echo !TN0! remove - Remove the !RABBITMQ_SERVICENAME! service echo. echo The following actions can also be accomplished by using echo Windows Services Management Console (services.msc): echo. echo !TN0! start - Start the !RABBITMQ_SERVICENAME! service echo !TN0! stop - Stop the !RABBITMQ_SERVICENAME! service echo !TN0! disable - Disable the !RABBITMQ_SERVICENAME! service echo !TN0! enable - Enable the !RABBITMQ_SERVICENAME! service echo. exit /B :INSTALL_SERVICE if not exist "!RABBITMQ_BASE!" ( echo Creating base directory !RABBITMQ_BASE! & md "!RABBITMQ_BASE!" ) "!ERLANG_SERVICE_MANAGER_PATH!\erlsrv" list !RABBITMQ_SERVICENAME! 2>NUL 1>NUL if errorlevel 1 ( "!ERLANG_SERVICE_MANAGER_PATH!\erlsrv" add !RABBITMQ_SERVICENAME! -internalservicename !RABBITMQ_SERVICENAME! ) else ( echo !RABBITMQ_SERVICENAME! service is already present - only updating service parameters ) set RABBITMQ_EBIN_ROOT=!TDP0!..\ebin "!ERLANG_HOME!\bin\erl.exe" ^ -pa "!RABBITMQ_EBIN_ROOT!" ^ -noinput -hidden ^ -s rabbit_prelaunch ^ !RABBITMQ_NAME_TYPE! rabbitmqprelaunch!RANDOM!!TIME:~9! if ERRORLEVEL 3 ( rem ERRORLEVEL means (or greater) so we need to catch all other failure rem cases here exit /B 1 ) else if ERRORLEVEL 2 ( rem dist port mentioned in config, do not attempt to set it ) else if ERRORLEVEL 1 ( exit /B 1 ) else ( set RABBITMQ_DIST_ARG=-kernel inet_dist_listen_min !RABBITMQ_DIST_PORT! -kernel inet_dist_listen_max !RABBITMQ_DIST_PORT! ) if exist "!RABBITMQ_CONFIG_FILE!.config" ( set RABBITMQ_CONFIG_ARG=-config "!RABBITMQ_CONFIG_FILE!" ) else ( set RABBITMQ_CONFIG_ARG= ) set RABBITMQ_LISTEN_ARG= if not "!RABBITMQ_NODE_IP_ADDRESS!"=="" ( if not "!RABBITMQ_NODE_PORT!"=="" ( set RABBITMQ_LISTEN_ARG=-rabbit tcp_listeners "[{\"!RABBITMQ_NODE_IP_ADDRESS!\", !RABBITMQ_NODE_PORT!}]" ) ) set RABBITMQ_START_RABBIT= if "!RABBITMQ_NODE_ONLY!"=="" ( set RABBITMQ_START_RABBIT=-s "!RABBITMQ_BOOT_MODULE!" boot ) if "!RABBITMQ_IO_THREAD_POOL_SIZE!"=="" ( set RABBITMQ_IO_THREAD_POOL_SIZE=30 ) set ERLANG_SERVICE_ARGUMENTS= ^ -pa "!RABBITMQ_EBIN_ROOT!" ^ -boot start_sasl ^ !RABBITMQ_START_RABBIT! ^ !RABBITMQ_CONFIG_ARG! ^ +W w ^ +A "!RABBITMQ_IO_THREAD_POOL_SIZE!" ^ +P 1048576 ^ !RABBITMQ_LISTEN_ARG! ^ !RABBITMQ_SERVER_ERL_ARGS! ^ -kernel inet_default_connect_options "[{nodelay,true}]" ^ !RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS! ^ -sasl errlog_type error ^ -sasl sasl_error_logger false ^ -rabbit error_logger {file,\""!RABBITMQ_LOGS:\=/!"\"} ^ -rabbit sasl_error_logger {file,\""!RABBITMQ_SASL_LOGS:\=/!"\"} ^ -rabbit enabled_plugins_file \""!RABBITMQ_ENABLED_PLUGINS_FILE:\=/!"\" ^ -rabbit plugins_dir \""!RABBITMQ_PLUGINS_DIR:\=/!"\" ^ -rabbit plugins_expand_dir \""!RABBITMQ_PLUGINS_EXPAND_DIR:\=/!"\" ^ -rabbit windows_service_config \""!RABBITMQ_CONFIG_FILE:\=/!"\" ^ -os_mon start_cpu_sup false ^ -os_mon start_disksup false ^ -os_mon start_memsup false ^ -mnesia dir \""!RABBITMQ_MNESIA_DIR:\=/!"\" ^ !RABBITMQ_SERVER_START_ARGS! ^ !RABBITMQ_DIST_ARG! ^ !STARVAR! set ERLANG_SERVICE_ARGUMENTS=!ERLANG_SERVICE_ARGUMENTS:\=\\! set ERLANG_SERVICE_ARGUMENTS=!ERLANG_SERVICE_ARGUMENTS:"=\"! "!ERLANG_SERVICE_MANAGER_PATH!\erlsrv" set !RABBITMQ_SERVICENAME! ^ -machine "!ERLANG_SERVICE_MANAGER_PATH!\erl.exe" ^ -env ERL_CRASH_DUMP="!RABBITMQ_BASE:\=/!/erl_crash.dump" ^ -workdir "!RABBITMQ_BASE!" ^ -stopaction "rabbit:stop_and_halt()." ^ !RABBITMQ_NAME_TYPE! !RABBITMQ_NODENAME! ^ !CONSOLE_FLAG! ^ -comment "Multi-protocol open source messaging broker" ^ -args "!ERLANG_SERVICE_ARGUMENTS!" > NUL goto END :MODIFY_SERVICE "!ERLANG_SERVICE_MANAGER_PATH!\erlsrv" !P1! !RABBITMQ_SERVICENAME! goto END :END endlocal endlocal rabbitmq-server-3.5.7/scripts/rabbitmq-server0000755000177700017770000001360612633765070021204 0ustar michaelmichael#!/bin/sh -e ## The contents of this file are subject to the Mozilla Public License ## Version 1.1 (the "License"); you may not use this file except in ## compliance with the License. You may obtain a copy of the License ## at http://www.mozilla.org/MPL/ ## ## 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 Original Code is RabbitMQ. ## ## The Initial Developer of the Original Code is GoPivotal, Inc. ## Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. ## # Get default settings with user overrides for (RABBITMQ_) # Non-empty defaults should be set in rabbitmq-env . `dirname $0`/rabbitmq-env RABBITMQ_START_RABBIT= [ "x" = "x$RABBITMQ_ALLOW_INPUT" ] && RABBITMQ_START_RABBIT=" -noinput" [ "x" = "x$RABBITMQ_NODE_ONLY" ] && RABBITMQ_START_RABBIT="$RABBITMQ_START_RABBIT -s $RABBITMQ_BOOT_MODULE boot " case "$(uname -s)" in CYGWIN*) # we make no attempt to record the cygwin pid; rabbitmqctl wait # will not be able to make sense of it anyway ;; *) # When -detached is passed, we don't write the pid, since it'd be the # wrong one detached="" for opt in "$@"; do if [ "$opt" = "-detached" ]; then detached="true" fi done if [ $detached ]; then echo "Warning: PID file not written; -detached was passed." 1>&2 else mkdir -p $(dirname ${RABBITMQ_PID_FILE}); echo $$ > ${RABBITMQ_PID_FILE} fi esac RABBITMQ_EBIN_ROOT="${RABBITMQ_HOME}/ebin" set +e RABBITMQ_CONFIG_FILE=$RABBITMQ_CONFIG_FILE \ RABBITMQ_DIST_PORT=$RABBITMQ_DIST_PORT \ ${ERL_DIR}erl -pa "$RABBITMQ_EBIN_ROOT" \ -boot "${CLEAN_BOOT_FILE}" \ -noinput \ -hidden \ -s rabbit_prelaunch \ ${RABBITMQ_NAME_TYPE} rabbitmqprelaunch$$ \ -extra "${RABBITMQ_NODENAME}" PRELAUNCH_RESULT=$? if [ ${PRELAUNCH_RESULT} = 2 ] ; then # dist port is mentioned in config, so do not set it true elif [ ${PRELAUNCH_RESULT} = 0 ] ; then # dist port is not mentioned in the config file, we can set it RABBITMQ_DIST_ARG="-kernel inet_dist_listen_min ${RABBITMQ_DIST_PORT} -kernel inet_dist_listen_max ${RABBITMQ_DIST_PORT}" else exit ${PRELAUNCH_RESULT} fi set -e RABBITMQ_CONFIG_ARG= [ -f "${RABBITMQ_CONFIG_FILE}.config" ] && RABBITMQ_CONFIG_ARG="-config ${RABBITMQ_CONFIG_FILE}" RABBITMQ_LISTEN_ARG= [ "x" != "x$RABBITMQ_NODE_PORT" ] && [ "x" != "x$RABBITMQ_NODE_IP_ADDRESS" ] && RABBITMQ_LISTEN_ARG="-rabbit tcp_listeners [{\""${RABBITMQ_NODE_IP_ADDRESS}"\","${RABBITMQ_NODE_PORT}"}]" # If $RABBITMQ_LOGS is '-', send all log messages to stdout. Likewise # for RABBITMQ_SASL_LOGS. This is particularily useful for Docker # images. if [ "$RABBITMQ_LOGS" = '-' ]; then RABBIT_ERROR_LOGGER='tty' else RABBIT_ERROR_LOGGER='{file,"'${RABBITMQ_LOGS}'"}' fi if [ "$RABBITMQ_SASL_LOGS" = '-' ]; then SASL_ERROR_LOGGER=tty RABBIT_SASL_ERROR_LOGGER='tty' else SASL_ERROR_LOGGER=false RABBIT_SASL_ERROR_LOGGER='{file,"'${RABBITMQ_SASL_LOGS}'"}' fi # we need to turn off path expansion because some of the vars, notably # RABBITMQ_SERVER_ERL_ARGS, contain terms that look like globs and # there is no other way of preventing their expansion. set -f start_rabbitmq_server() { RABBITMQ_CONFIG_FILE=$RABBITMQ_CONFIG_FILE \ exec ${ERL_DIR}erl \ -pa ${RABBITMQ_EBIN_ROOT} \ ${RABBITMQ_START_RABBIT} \ ${RABBITMQ_NAME_TYPE} ${RABBITMQ_NODENAME} \ -boot "${SASL_BOOT_FILE}" \ ${RABBITMQ_CONFIG_ARG} \ +W w \ +A ${RABBITMQ_IO_THREAD_POOL_SIZE} \ ${RABBITMQ_SERVER_ERL_ARGS} \ +K true \ -kernel inet_default_connect_options "[{nodelay,true}]" \ ${RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS} \ ${RABBITMQ_LISTEN_ARG} \ -sasl errlog_type error \ -sasl sasl_error_logger "$SASL_ERROR_LOGGER" \ -rabbit error_logger "$RABBIT_ERROR_LOGGER" \ -rabbit sasl_error_logger "$RABBIT_SASL_ERROR_LOGGER" \ -rabbit enabled_plugins_file "\"$RABBITMQ_ENABLED_PLUGINS_FILE\"" \ -rabbit plugins_dir "\"$RABBITMQ_PLUGINS_DIR\"" \ -rabbit plugins_expand_dir "\"$RABBITMQ_PLUGINS_EXPAND_DIR\"" \ -os_mon start_cpu_sup false \ -os_mon start_disksup false \ -os_mon start_memsup false \ -mnesia dir "\"${RABBITMQ_MNESIA_DIR}\"" \ ${RABBITMQ_SERVER_START_ARGS} \ ${RABBITMQ_DIST_ARG} \ "$@" } stop_rabbitmq_server() { RABBITMQCTL="$(dirname "$0")/rabbitmqctl" if ${RABBITMQCTL} -n ${RABBITMQ_NODENAME} status >/dev/null 2>&1; then ${RABBITMQCTL} -n ${RABBITMQ_NODENAME} stop fi } if [ 'x' = "x$RABBITMQ_ALLOW_INPUT" -a -z "$detached" ]; then # When RabbitMQ runs in the foreground but the Erlang shell is # disabled, we setup signal handlers to stop RabbitMQ properly. This # is at least useful in the case of Docker. # The Erlang VM should ignore SIGINT. RABBITMQ_SERVER_START_ARGS="${RABBITMQ_SERVER_START_ARGS} +B i" # Signal handlers. They all stop RabbitMQ properly (using # rabbitmqctl stop). Depending on the signal, this script will exwit # with a non-zero error code: # SIGHUP SIGTERM SIGTSTP # They are considered a normal process termination, so the script # exits with 0. # SIGINT # They are considered an abnormal process termination, the script # exits with the job exit code. trap "stop_rabbitmq_server; exit 0" HUP TERM TSTP trap "stop_rabbitmq_server" INT start_rabbitmq_server "$@" & # Block until RabbitMQ exits or a signal is caught. # Waits for last command (which is start_rabbitmq_server) wait $! else start_rabbitmq_server "$@" fi rabbitmq-server-3.5.7/scripts/rabbitmq-plugins0000755000177700017770000000230712633765070021353 0ustar michaelmichael#!/bin/sh -e ## The contents of this file are subject to the Mozilla Public License ## Version 1.1 (the "License"); you may not use this file except in ## compliance with the License. You may obtain a copy of the License ## at http://www.mozilla.org/MPL/ ## ## 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 Original Code is RabbitMQ. ## ## The Initial Developer of the Original Code is GoPivotal, Inc. ## Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. ## # Get default settings with user overrides for (RABBITMQ_) # Non-empty defaults should be set in rabbitmq-env . `dirname $0`/rabbitmq-env RABBITMQ_USE_LONGNAME=${RABBITMQ_USE_LONGNAME} \ exec ${ERL_DIR}erl \ -pa "${RABBITMQ_HOME}/ebin" \ -noinput \ -hidden \ ${RABBITMQ_CTL_ERL_ARGS} \ -boot "${CLEAN_BOOT_FILE}" \ -s rabbit_plugins_main \ -enabled_plugins_file "$RABBITMQ_ENABLED_PLUGINS_FILE" \ -plugins_dist_dir "$RABBITMQ_PLUGINS_DIR" \ -nodename $RABBITMQ_NODENAME \ -extra "$@" rabbitmq-server-3.5.7/scripts/rabbitmq-env0000755000177700017770000001623312633765070020465 0ustar michaelmichael#!/bin/sh -e ## The contents of this file are subject to the Mozilla Public License ## Version 1.1 (the "License"); you may not use this file except in ## compliance with the License. You may obtain a copy of the License ## at http://www.mozilla.org/MPL/ ## ## 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 Original Code is RabbitMQ. ## ## The Initial Developer of the Original Code is GoPivotal, Inc. ## Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. ## # We set +e here since since our test for "readlink -f" below needs to # be able to fail. set +e # Determine where this script is really located (if this script is # invoked from another script, this is the location of the caller) SCRIPT_PATH="$0" while [ -h "$SCRIPT_PATH" ] ; do # Determine if readlink -f is supported at all. TODO clean this up. FULL_PATH=`readlink -f $SCRIPT_PATH 2>/dev/null` if [ "$?" != "0" ]; then REL_PATH=`readlink $SCRIPT_PATH` if expr "$REL_PATH" : '/.*' > /dev/null; then SCRIPT_PATH="$REL_PATH" else SCRIPT_PATH="`dirname "$SCRIPT_PATH"`/$REL_PATH" fi else SCRIPT_PATH=$FULL_PATH fi done set -e SCRIPT_DIR=`dirname $SCRIPT_PATH` RABBITMQ_HOME="${SCRIPT_DIR}/.." ## Set defaults . ${SCRIPT_DIR}/rabbitmq-defaults ## Common defaults SERVER_ERL_ARGS="+P 1048576" # warn about old rabbitmq.conf file, if no new one if [ -f /etc/rabbitmq/rabbitmq.conf ] && \ [ ! -f ${CONF_ENV_FILE} ] ; then echo -n "WARNING: ignoring /etc/rabbitmq/rabbitmq.conf -- " echo "location has moved to ${CONF_ENV_FILE}" fi # We save the current value of $RABBITMQ_PID_FILE in case it was set by # an init script. If $CONF_ENV_FILE overrides it again, we must ignore # it and warn the user. saved_RABBITMQ_PID_FILE=$RABBITMQ_PID_FILE ## Get configuration variables from the configure environment file [ -f ${CONF_ENV_FILE} ] && . ${CONF_ENV_FILE} || true if [ "$saved_RABBITMQ_PID_FILE" -a \ "$saved_RABBITMQ_PID_FILE" != "$RABBITMQ_PID_FILE" ]; then echo "WARNING: RABBITMQ_PID_FILE was already set by the init script to:" 1>&2 echo " $saved_RABBITMQ_PID_FILE" 1>&2 echo " The value set in rabbitmq-env.conf is ignored because it" 1>&2 echo " would break the init script." 1>&2 RABBITMQ_PID_FILE="$saved_RABBITMQ_PID_FILE" fi [ "x" = "x$RABBITMQ_USE_LONGNAME" ] && RABBITMQ_USE_LONGNAME=${USE_LONGNAME} if [ "xtrue" = "x$RABBITMQ_USE_LONGNAME" ] ; then RABBITMQ_NAME_TYPE=-name [ "x" = "x$HOSTNAME" ] && HOSTNAME=`env hostname -f` [ "x" = "x$NODENAME" ] && NODENAME=rabbit@${HOSTNAME} else RABBITMQ_NAME_TYPE=-sname [ "x" = "x$HOSTNAME" ] && HOSTNAME=`env hostname` [ "x" = "x$NODENAME" ] && NODENAME=rabbit@${HOSTNAME%%.*} fi ##--- Set environment vars RABBITMQ_ to defaults if not set rmq_realpath() { local path=$1 if [ -d "$path" ]; then cd "$path" && pwd elif [ -f "$path" ]; then cd "$(dirname "$path")" && echo $(pwd)/$(basename "$path") else echo "$path" fi } rmq_check_if_shared_with_mnesia() { local var local mnesia_dir=$(rmq_realpath "${RABBITMQ_MNESIA_DIR}") local prefix="WARNING:" for var in "$@"; do local dir=$(eval "echo \"\$$var\"") case $(rmq_realpath "$dir") in ${mnesia_dir}) warning=1 echo "$prefix $var is equal to RABBITMQ_MNESIA_DIR" 1>&2 ;; ${mnesia_dir}/*) warning=1 echo "$prefix $var is located inside RABBITMQ_MNESIA_DIR" 1>&2 ;; esac if [ "x$warning" = "x1" ]; then prefix=" " fi done if [ "x$warning" = "x1" ]; then echo "$prefix => Auto-clustering will not work ('cluster_nodes' in rabbitmq.config)" 1>&2 fi } DEFAULT_NODE_IP_ADDRESS=auto DEFAULT_NODE_PORT=5672 [ "x" = "x$RABBITMQ_NODE_IP_ADDRESS" ] && RABBITMQ_NODE_IP_ADDRESS=${NODE_IP_ADDRESS} [ "x" = "x$RABBITMQ_NODE_PORT" ] && RABBITMQ_NODE_PORT=${NODE_PORT} [ "x" = "x$RABBITMQ_NODE_IP_ADDRESS" ] && [ "x" != "x$RABBITMQ_NODE_PORT" ] && RABBITMQ_NODE_IP_ADDRESS=${DEFAULT_NODE_IP_ADDRESS} [ "x" != "x$RABBITMQ_NODE_IP_ADDRESS" ] && [ "x" = "x$RABBITMQ_NODE_PORT" ] && RABBITMQ_NODE_PORT=${DEFAULT_NODE_PORT} [ "x" = "x$RABBITMQ_DIST_PORT" ] && RABBITMQ_DIST_PORT=${DIST_PORT} [ "x" = "x$RABBITMQ_DIST_PORT" ] && [ "x" = "x$RABBITMQ_NODE_PORT" ] && RABBITMQ_DIST_PORT=$((${DEFAULT_NODE_PORT} + 20000)) [ "x" = "x$RABBITMQ_DIST_PORT" ] && [ "x" != "x$RABBITMQ_NODE_PORT" ] && RABBITMQ_DIST_PORT=$((${RABBITMQ_NODE_PORT} + 20000)) [ "x" = "x$RABBITMQ_NODENAME" ] && RABBITMQ_NODENAME=${NODENAME} [ "x" = "x$RABBITMQ_IO_THREAD_POOL_SIZE" ] && RABBITMQ_IO_THREAD_POOL_SIZE=${IO_THREAD_POOL_SIZE} [ "x" = "x$RABBITMQ_SERVER_ERL_ARGS" ] && RABBITMQ_SERVER_ERL_ARGS=${SERVER_ERL_ARGS} [ "x" = "x$RABBITMQ_CONFIG_FILE" ] && RABBITMQ_CONFIG_FILE=${CONFIG_FILE} [ "x" = "x$RABBITMQ_LOG_BASE" ] && RABBITMQ_LOG_BASE=${LOG_BASE} [ "x" = "x$RABBITMQ_MNESIA_BASE" ] && RABBITMQ_MNESIA_BASE=${MNESIA_BASE} [ "x" = "x$RABBITMQ_SERVER_START_ARGS" ] && RABBITMQ_SERVER_START_ARGS=${SERVER_START_ARGS} [ "x" = "x$RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS" ] && RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS=${SERVER_ADDITIONAL_ERL_ARGS} [ "x" = "x$RABBITMQ_MNESIA_DIR" ] && RABBITMQ_MNESIA_DIR=${MNESIA_DIR} [ "x" = "x$RABBITMQ_MNESIA_DIR" ] && RABBITMQ_MNESIA_DIR=${RABBITMQ_MNESIA_BASE}/${RABBITMQ_NODENAME} [ "x" = "x$RABBITMQ_PID_FILE" ] && RABBITMQ_PID_FILE=${PID_FILE} [ "x" = "x$RABBITMQ_PID_FILE" ] && RABBITMQ_PID_FILE=${RABBITMQ_MNESIA_DIR}.pid [ "x" = "x$RABBITMQ_BOOT_MODULE" ] && RABBITMQ_BOOT_MODULE=${BOOT_MODULE} [ "x" = "x$RABBITMQ_PLUGINS_EXPAND_DIR" ] && RABBITMQ_PLUGINS_EXPAND_DIR=${PLUGINS_EXPAND_DIR} [ "x" = "x$RABBITMQ_PLUGINS_EXPAND_DIR" ] && RABBITMQ_PLUGINS_EXPAND_DIR=${RABBITMQ_MNESIA_BASE}/${RABBITMQ_NODENAME}-plugins-expand [ "x" = "x$RABBITMQ_ENABLED_PLUGINS_FILE" ] && RABBITMQ_ENABLED_PLUGINS_FILE=${ENABLED_PLUGINS_FILE} [ "x" = "x$RABBITMQ_PLUGINS_DIR" ] && RABBITMQ_PLUGINS_DIR=${PLUGINS_DIR} ## Log rotation [ "x" = "x$RABBITMQ_LOGS" ] && RABBITMQ_LOGS=${LOGS} [ "x" = "x$RABBITMQ_LOGS" ] && RABBITMQ_LOGS="${RABBITMQ_LOG_BASE}/${RABBITMQ_NODENAME}.log" [ "x" = "x$RABBITMQ_SASL_LOGS" ] && RABBITMQ_SASL_LOGS=${SASL_LOGS} [ "x" = "x$RABBITMQ_SASL_LOGS" ] && RABBITMQ_SASL_LOGS="${RABBITMQ_LOG_BASE}/${RABBITMQ_NODENAME}-sasl.log" [ "x" = "x$RABBITMQ_CTL_ERL_ARGS" ] && RABBITMQ_CTL_ERL_ARGS=${CTL_ERL_ARGS} # Check if files and directories non-related to Mnesia are configured # to be in $RABBITMQ_MNESIA_DIR. If this is the case, issue a warning # because it will prevent auto-clustering from working (the node will be # considered non-virgin). rmq_check_if_shared_with_mnesia \ RABBITMQ_CONFIG_FILE \ RABBITMQ_LOG_BASE \ RABBITMQ_PID_FILE \ RABBITMQ_PLUGINS_EXPAND_DIR \ RABBITMQ_ENABLED_PLUGINS_FILE \ RABBITMQ_PLUGINS_DIR \ RABBITMQ_LOGS \ RABBITMQ_SASL_LOGS ##--- End of overridden variables # Since we source this elsewhere, don't accidentally stop execution true rabbitmq-server-3.5.7/scripts/rabbitmq-plugins.bat0000755000177700017770000000331012633765070022113 0ustar michaelmichael@echo off REM The contents of this file are subject to the Mozilla Public License REM Version 1.1 (the "License"); you may not use this file except in REM compliance with the License. You may obtain a copy of the License REM at http://www.mozilla.org/MPL/ REM REM Software distributed under the License is distributed on an "AS IS" REM basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See REM the License for the specific language governing rights and REM limitations under the License. REM REM The Original Code is RabbitMQ. REM REM The Initial Developer of the Original Code is GoPivotal, Inc. REM Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. REM setlocal rem Preserve values that might contain exclamation marks before rem enabling delayed expansion set TDP0=%~dp0 set STAR=%* setlocal enabledelayedexpansion REM Get default settings with user overrides for (RABBITMQ_) REM Non-empty defaults should be set in rabbitmq-env call "!TDP0!\rabbitmq-env.bat" if not exist "!ERLANG_HOME!\bin\erl.exe" ( echo. echo ****************************** echo ERLANG_HOME not set correctly. echo ****************************** echo. echo Please either set ERLANG_HOME to point to your Erlang installation or place the echo RabbitMQ server distribution in the Erlang lib folder. echo. exit /B 1 ) "!ERLANG_HOME!\bin\erl.exe" ^ -pa "!TDP0!..\ebin" ^ -noinput ^ -hidden ^ !RABBITMQ_CTL_ERL_ARGS! ^ -s rabbit_plugins_main ^ -enabled_plugins_file "!RABBITMQ_ENABLED_PLUGINS_FILE!" ^ -plugins_dist_dir "!RABBITMQ_PLUGINS_DIR:\=/!" ^ -nodename !RABBITMQ_NODENAME! ^ -extra !STAR! endlocal endlocal rabbitmq-server-3.5.7/scripts/rabbitmq-echopid.bat0000755000177700017770000000175512633765070022060 0ustar michaelmichael@echo off REM Usage: rabbitmq-echopid.bat REM REM (s)name of the erlang node to connect to (required) setlocal set TDP0=%~dp0 REM Get default settings with user overrides for (RABBITMQ_) REM Non-empty defaults should be set in rabbitmq-env call "!TDP0!\rabbitmq-env.bat" if "%1"=="" goto fail :: set timeout vars :: set TIMEOUT=10 set TIMER=1 :: check that wmic exists :: set WMIC_PATH=%SYSTEMROOT%\System32\Wbem\wmic.exe if not exist "%WMIC_PATH%" ( goto fail ) :getpid for /f "usebackq tokens=* skip=1" %%P IN (`%%WMIC_PATH%% process where "name='erl.exe' and commandline like '%%%RABBITMQ_NAME_TYPE% %1%%'" get processid 2^>nul`) do ( set PID=%%P goto echopid ) :echopid :: check for pid not found :: if "%PID%" == "" ( PING 127.0.0.1 -n 2 > nul set /a TIMER+=1 if %TIMEOUT%==%TIMER% goto fail goto getpid ) :: show pid :: echo %PID% :: all done :: :ok endlocal EXIT /B 0 :: something went wrong :: :fail endlocal EXIT /B 1 rabbitmq-server-3.5.7/scripts/rabbitmq-defaults0000755000177700017770000000235612633765070021505 0ustar michaelmichael#!/bin/sh -e ## The contents of this file are subject to the Mozilla Public License ## Version 1.1 (the "License"); you may not use this file except in ## compliance with the License. You may obtain a copy of the License ## at http://www.mozilla.org/MPL/ ## ## 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 Original Code is RabbitMQ. ## ## The Initial Developer of the Original Code is GoPivotal, Inc. ## Copyright (c) 2012-2015 Pivotal Software, Inc. All rights reserved. ## ### next line potentially updated in package install steps SYS_PREFIX= ### next line will be updated when generating a standalone release ERL_DIR= CLEAN_BOOT_FILE=start_clean SASL_BOOT_FILE=start_sasl ## Set default values BOOT_MODULE="rabbit" CONFIG_FILE=${SYS_PREFIX}/etc/rabbitmq/rabbitmq LOG_BASE=${SYS_PREFIX}/var/log/rabbitmq MNESIA_BASE=${SYS_PREFIX}/var/lib/rabbitmq/mnesia ENABLED_PLUGINS_FILE=${SYS_PREFIX}/etc/rabbitmq/enabled_plugins PLUGINS_DIR="${RABBITMQ_HOME}/plugins" IO_THREAD_POOL_SIZE=64 CONF_ENV_FILE=${SYS_PREFIX}/etc/rabbitmq/rabbitmq-env.conf rabbitmq-server-3.5.7/plugins-src/0000755000177700017770000000000012633765070016722 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management/0000755000177700017770000000000012633765070022635 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/0000755000177700017770000000000012633765070023615 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/0000755000177700017770000000000012633765070024441 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/index.html0000644000177700017770000000251112633765070026435 0ustar michaelmichael RabbitMQ Management
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/cli/0000755000177700017770000000000012633765070025210 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/cli/index.html0000644000177700017770000000170212633765070027205 0ustar michaelmichael rabbitmqadmin

rabbitmqadmin

Download it from here (Right click, Save as), make executable, and drop it in your path. Note that many browsers will rename the file rabbitmqadmin.txt. You will need Python 2.x, 2.6 or later (i.e. not Python 3).

See the rabbitmqadmin page on the website for more information on its use, or invoke rabbitmqadmin --help for usage instructions. Windows users will need to ensure Python is on their path, and invoke rabbitmqadmin as python.exe rabbitmqadmin.

rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/favicon.ico0000644000177700017770000000047612633765070026571 0ustar michaelmichael(( fÿ—Áÿýþÿÿÿÿ•¿ÿt¬ÿ5000C@0300C@000033030#3303033303033303033353533333333333rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/api/0000755000177700017770000000000012633765070025212 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/api/index.html0000644000177700017770000006075012633765070027217 0ustar michaelmichael RabbitMQ Management HTTP API

RabbitMQ Management HTTP API

Introduction

Apart from this help page, all URIs will serve only resources of type application/json, and will require HTTP basic authentication (using the standard RabbitMQ user database). The default user is guest/guest.

Many URIs require the name of a virtual host as part of the path, since names only uniquely identify objects within a virtual host. As the default virtual host is called "/", this will need to be encoded as "%2f".

PUTing a resource creates it. The JSON object you upload must have certain mandatory keys (documented below) and may have optional keys. Other keys are ignored. Missing mandatory keys constitute an error.

Since bindings do not have names or IDs in AMQP we synthesise one based on all its properties. Since predicting this name is hard in the general case, you can also create bindings by POSTing to a factory URI. See the example below.

Many URIs return lists. Such URIs can have the query string parameters sort and sort_reverse added. sort allows you to select a primary field to sort by, and sort_reverse will reverse the sort order if set to true. The sort parameter can contain subfields separated by dots. This allows you to sort by a nested component of the listed items; it does not allow you to sort by more than one field. See the example below.

You can also restrict what information is returned per item with the columns parameter. This is a comma-separated list of subfields separated by dots. See the example below.

Most of the GET queries return many fields per object. See the separate stats documentation.

Examples

A few quick examples for Windows and Unix, using the command line tool curl:

  • Get a list of vhosts:
    :: Windows
    C:\> curl -i -u guest:guest http://localhost:15672/api/vhosts
    
    # Unix
    $ curl -i -u guest:guest http://localhost:15672/api/vhosts
    
    HTTP/1.1 200 OK
    Server: MochiWeb/1.1 WebMachine/1.10.0 (never breaks eye contact)
    Date: Mon, 16 Sep 2013 12:00:02 GMT
    Content-Type: application/json
    Content-Length: 30
    
    [{"name":"/","tracing":false}]
    
  • Get a list of channels, fast publishers first, restricting the info items we get back:
    :: Windows
    C:\> curl -i -u guest:guest "http://localhost:15672/api/channels?sort=message_stats.publish_details.rate&sort_reverse=true&columns=name,message_stats.publish_details.rate,message_stats.deliver_get_details.rate"
    
    # Unix
    $ curl -i -u guest:guest 'http://localhost:15672/api/channels?sort=message_stats.publish_details.rate&sort_reverse=true&columns=name,message_stats.publish_details.rate,message_stats.deliver_get_details.rate'
    
    HTTP/1.1 200 OK
    Server: MochiWeb/1.1 WebMachine/1.10.0 (never breaks eye contact)
    Date: Mon, 16 Sep 2013 12:01:17 GMT
    Content-Type: application/json
    Content-Length: 219
    Cache-Control: no-cache
    
    [{"message_stats":{"publish_details":{"rate" ... (remainder elided)
  • Create a new vhost:
    :: Windows
    C:\> curl -i -u guest:guest -H "content-type:application/json" ^
          -XPUT http://localhost:15672/api/vhosts/foo
    
    # Unix
    $ curl -i -u guest:guest -H "content-type:application/json" \
       -XPUT http://localhost:15672/api/vhosts/foo
    
    HTTP/1.1 204 No Content
    Server: MochiWeb/1.1 WebMachine/1.10.0 (never breaks eye contact)
    Date: Mon, 16 Sep 2013 12:03:00 GMT
    Content-Type: application/json
    Content-Length: 0

    Note: you must specify application/json as the mime type.

    Note: the name of the object is not needed in the JSON object uploaded, since it is in the URI. As a virtual host has no properties apart from its name, this means you do not need to specify a body at all!

  • Create a new exchange in the default virtual host:
    :: Windows
    C:\> curl -i -u guest:guest -H "content-type:application/json" ^
           -XPUT -d"{""type"":""direct"",""durable"":true}" ^
           http://localhost:15672/api/exchanges/%2f/my-new-exchange
    
    # Unix
    $ curl -i -u guest:guest -H "content-type:application/json" \
        -XPUT -d'{"type":"direct","durable":true}' \
        http://localhost:15672/api/exchanges/%2f/my-new-exchange
    
    HTTP/1.1 204 No Content
    Server: MochiWeb/1.1 WebMachine/1.10.0 (never breaks eye contact)
    Date: Mon, 16 Sep 2013 12:04:00 GMT
    Content-Type: application/json
    Content-Length: 0

    Note: we never return a body in response to a PUT or DELETE, unless it fails.

  • And delete it again:
    :: Windows
    C:\> curl -i -u guest:guest -H "content-type:application/json" ^
           -XDELETE http://localhost:15672/api/exchanges/%2f/my-new-exchange
    
    # Unix
    $ curl -i -u guest:guest -H "content-type:application/json" \
        -XDELETE http://localhost:15672/api/exchanges/%2f/my-new-exchange
    
    HTTP/1.1 204 No Content
    Server: MochiWeb/1.1 WebMachine/1.10.0 (never breaks eye contact)
    Date: Mon, 16 Sep 2013 12:05:30 GMT
    Content-Type: application/json
    Content-Length: 0

Reference

GET PUT DELETE POST Path Description
X /api/overview Various random bits of information that describe the whole system.
X X /api/cluster-name Name identifying this RabbitMQ cluster.
X /api/nodes A list of nodes in the RabbitMQ cluster.
X /api/nodes/name An individual node in the RabbitMQ cluster. Add "?memory=true" to get memory statistics, and "?binary=true" to get a breakdown of binary memory use (may be expensive if there are many small binaries in the system).
X /api/extensions A list of extensions to the management plugin.
X X /api/definitions
/api/all-configuration (deprecated)
The server definitions - exchanges, queues, bindings, users, virtual hosts, permissions and parameters. Everything apart from messages. POST to upload an existing set of definitions. Note that:
  • The definitions are merged. Anything already existing on the server but not in the uploaded definitions is untouched.
  • Conflicting definitions on immutable objects (exchanges, queues and bindings) will cause an error.
  • Conflicting definitions on mutable objects will cause the object in the server to be overwritten with the object from the definitions.
  • In the event of an error you will be left with a part-applied set of definitions.
For convenience you may upload a file from a browser to this URI (i.e. you can use multipart/form-data as well as application/json) in which case the definitions should be uploaded as a form field named "file".
X /api/connections A list of all open connections.
X X /api/connections/name An individual connection. DELETEing it will close the connection. Optionally set the "X-Reason" header when DELETEing to provide a reason.
X /api/connections/name/channels List of all channels for a given connection.
X /api/channels A list of all open channels.
X /api/channels/channel Details about an individual channel.
X /api/consumers A list of all consumers.
X /api/consumers/vhost A list of all consumers in a given virtual host.
X /api/exchanges A list of all exchanges.
X /api/exchanges/vhost A list of all exchanges in a given virtual host.
X X X /api/exchanges/vhost/name An individual exchange. To PUT an exchange, you will need a body looking something like this:
{"type":"direct","auto_delete":false,"durable":true,"internal":false,"arguments":{}}
The type key is mandatory; other keys are optional.

When DELETEing an exchange you can add the query string parameter if-unused=true. This prevents the delete from succeeding if the exchange is bound to a queue or as a source to another exchange.

X /api/exchanges/vhost/name/bindings/source A list of all bindings in which a given exchange is the source.
X /api/exchanges/vhost/name/bindings/destination A list of all bindings in which a given exchange is the destination.
X /api/exchanges/vhost/name/publish Publish a message to a given exchange. You will need a body looking something like:
{"properties":{},"routing_key":"my key","payload":"my body","payload_encoding":"string"}
All keys are mandatory. The payload_encoding key should be either "string" (in which case the payload will be taken to be the UTF-8 encoding of the payload field) or "base64" (in which case the payload field is taken to be base64 encoded).
If the message is published successfully, the response will look like:
{"routed": true}
routed will be true if the message was sent to at least one queue.

Please note that the HTTP API is not ideal for high performance publishing; the need to create a new TCP connection for each message published can limit message throughput compared to AMQP or other protocols using long-lived connections.

X /api/queues A list of all queues.
X /api/queues/vhost A list of all queues in a given virtual host.
X X X /api/queues/vhost/name An individual queue. To PUT a queue, you will need a body looking something like this:
{"auto_delete":false,"durable":true,"arguments":{},"node":"rabbit@smacmullen"}
All keys are optional.

When DELETEing a queue you can add the query string parameters if-empty=true and / or if-unused=true. These prevent the delete from succeeding if the queue contains messages, or has consumers, respectively.

X /api/queues/vhost/name/bindings A list of all bindings on a given queue.
X /api/queues/vhost/name/contents Contents of a queue. DELETE to purge. Note you can't GET this.
X /api/queues/vhost/name/actions Actions that can be taken on a queue. POST a body like:
{"action":"sync"}
Currently the actions which are supported are sync and cancel_sync.
X /api/queues/vhost/name/get Get messages from a queue. (This is not an HTTP GET as it will alter the state of the queue.) You should post a body looking like:
{"count":5,"requeue":true,"encoding":"auto","truncate":50000}
  • count controls the maximum number of messages to get. You may get fewer messages than this if the queue cannot immediately provide them.
  • requeue determines whether the messages will be removed from the queue. If requeue is true they will be requeued - but their redelivered flag will be set.
  • encoding must be either "auto" (in which case the payload will be returned as a string if it is valid UTF-8, and base64 encoded otherwise), or "base64" (in which case the payload will always be base64 encoded).
  • If truncate is present it will truncate the message payload if it is larger than the size given (in bytes).

truncate is optional; all other keys are mandatory.

Please note that the get path in the HTTP API is intended for diagnostics etc - it does not implement reliable delivery and so should be treated as a sysadmin's tool rather than a general API for messaging.

X /api/bindings A list of all bindings.
X /api/bindings/vhost A list of all bindings in a given virtual host.
X X /api/bindings/vhost/e/exchange/q/queue A list of all bindings between an exchange and a queue. Remember, an exchange and a queue can be bound together many times! To create a new binding, POST to this URI. You will need a body looking something like this:
{"routing_key":"my_routing_key","arguments":{}}
All keys are optional. The response will contain a Location header telling you the URI of your new binding.
X X /api/bindings/vhost/e/exchange/q/queue/props An individual binding between an exchange and a queue. The props part of the URI is a "name" for the binding composed of its routing key and a hash of its arguments.
X X /api/bindings/vhost/e/source/e/destination A list of all bindings between two exchanges. Similar to the list of all bindings between an exchange and a queue, above.
X X /api/bindings/vhost/e/source/e/destination/props An individual binding between two exchanges. Similar to the individual binding between an exchange and a queue, above.
X /api/vhosts A list of all vhosts.
X X X /api/vhosts/name An individual virtual host. As a virtual host usually only has a name, you do not need an HTTP body when PUTing one of these. To enable / disable tracing, provide a body looking like:
{"tracing":true}
X /api/vhosts/name/permissions A list of all permissions for a given virtual host.
X /api/users A list of all users.
X X X /api/users/name An individual user. To PUT a user, you will need a body looking something like this:
{"password":"secret","tags":"administrator"}
or:
{"password_hash":"2lmoth8l4H0DViLaK9Fxi6l9ds8=", "tags":"administrator"}
The tags key is mandatory. Either password or password_hash must be set. Setting password_hash to "" will ensure the user cannot use a password to log in. tags is a comma-separated list of tags for the user. Currently recognised tags are "administrator", "monitoring" and "management".
X /api/users/user/permissions A list of all permissions for a given user.
X /api/whoami Details of the currently authenticated user.
X /api/permissions A list of all permissions for all users.
X X X /api/permissions/vhost/user An individual permission of a user and virtual host. To PUT a permission, you will need a body looking something like this:
{"configure":".*","write":".*","read":".*"}
All keys are mandatory.
X /api/parameters A list of all parameters.
X /api/parameters/component A list of all parameters for a given component.
X /api/parameters/component/vhost A list of all parameters for a given component and virtual host.
X X X /api/parameters/component/vhost/name An individual parameter. To PUT a parameter, you will need a body looking something like this:
{"vhost": "/","component":"federation","name":"local_username","value":"guest"}
X /api/policies A list of all policies.
X /api/policies/vhost A list of all policies in a given virtual host.
X X X /api/policies/vhost/name An individual policy. To PUT a policy, you will need a body looking something like this:
{"pattern":"^amq.", "definition": {"federation-upstream-set":"all"}, "priority":0, "apply-to": "all"}
pattern and definition are mandatory, priority and apply-to are optional.
X /api/aliveness-test/vhost Declares a test queue, then publishes and consumes a message. Intended for use by monitoring tools. If everything is working correctly, will return HTTP status 200 with body:
{"status":"ok"}
Note: the test queue will not be deleted (to to prevent queue churn if this is repeatedly pinged).
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/doc/0000755000177700017770000000000012633765070025206 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/doc/stats.html0000644000177700017770000006330112633765070027235 0ustar michaelmichael RabbitMQ Management HTTP Stats

RabbitMQ Management HTTP Stats

Introduction

Most of the GET requests you can issue to the HTTP API return JSON objects with a large number of keys. While a few of these keys represent things you set yourself in a PUT request or AMQP command (e.g. queue durability or arguments), most of them represent statistics to do with the object in question. This page attempts to document them.

It should be read in conjunction with the manual page for rabbitmqctl (see your installation if on Unix / Linux, or the RabbitMQ website for the latest version). Any field which can be returned by a command of the form rabbitmqctl list_something will also be returned in the equivalent part of the HTTP API, so all those keys are not documented here. However, the HTTP API also adds a lot of extra fields which are not available in rabbitmqctl.

_details objects

Many fields represent a count of some kind: queue length, messages acknowledged, bytes received and so on. Such absolute counts returned by the HTTP API will often have a corresponding _details object which offers information on how this count has changed. So for example, from a queue:

    "messages": 123619,
    "messages_details": {
      "avg": 41206.333333333336,
      "avg_rate": 1030.1583333333333,
      "rate": 24723.8,
      "samples": [
        {
          "sample": 123619,
          "timestamp": 1400680560000
        },
        {
          "sample": 0,
          "timestamp": 1400680500000
        },
        {
          "sample": 0,
          "timestamp": 1400680440000
        }
      ]
    }

Here we have a messages count (the total messages in the queue), with some additional data:

avg The average value for the requested time period (see below).
avg_rate The average rate for the requested time period.
rate How much the count has changed per second in the most recent sampling interval.
samples Snapshots showing how the value has changed over the requested time period.

avg, avg_rate and samples will only appear if you request a specific time period by appending query parameters to the URL. To do this you need to set an age and an increment for the samples you want. The end of the range returned will always correspond to the present.

Different types of data take different query parameters to return samples, as in the following table. You can specify more than one set of parameters if the resource you are requesting can generate more than one type of sample (for example, queues can return message rates and queue lengths).

Messages sent and received msg_rates_age / msg_rates_incr
Bytes sent and received data_rates_age / data_rates_incr
Queue lengths lengths_age / lengths_incr
Node statistics (e.g. file descriptors, disk space free) node_stats_age / node_stats_incr

For example, appending ?lengths_age=3600&lengths_incr=60 will return the last hour's data on queue lengths, with a sample for every minute.

message_stats objects

Many objects (including queues, exchanges and channels) will return counts of messages passing through them. These are included in a message_stats object (which in turn will contain _details objects for each count, as described above).

These can contain:

publish Count of messages published.
publish_in Count of messages published "in" to an exchange, i.e. not taking account of routing.
publish_out Count of messages published "out" of an exchange, i.e. taking account of routing.
confirm Count of messages confirmed.
deliver Count of messages delivered in acknowledgement mode to consumers.
deliver_noack Count of messages delivered in no-acknowledgement mode to consumers.
get Count of messages delivered in acknowledgement mode in response to basic.get.
get_noack Count of messages delivered in no-acknowledgement mode in response to basic.get.
deliver_get Sum of all four of the above.
redeliver Count of subset of messages in deliver_get which had the redelivered flag set.
return Count of messages returned to publisher as unroutable.

Only fields for which some activity has taken place will appear.

Detailed message stats objects

In addition, queues, exchanges and channels can return a breakdown of message stats for each of their neighbours (i.e. adjacent objects in the chain: channel -> exchange -> queue -> channel). This will only happen if the rates_mode configuration item has been switched to detailed from its default of basic.

As this possibly constitutes a large quantity of data, it is also only returned when querying a single channel, queue or exchange rather than a list. Note also that the default sample retention policy means that these detailed message stats do not retain historical data for more than a few seconds.

The detailed message stats objects have different names depending on where they are (documented below). Each set of detailed stats consists of a list of objects with two fields, one identifying the partner object and one stats which is a message_stats object as described above.

For example, from a queue:

  "incoming": [
    {
      "stats": {
        "publish": 352593,
        "publish_details": {
          "rate": 100.2
        }
      },
      "exchange": {
        "name": "my-exchange",
        "vhost": "/"
      }
    }
    {
      "stats": {
        "publish": 543784,
        "publish_details": {
          "rate": 54.6
        }
      },
      "exchange": {
        "name": "amq.topic",
        "vhost": "/"
      }
    }
  ],

This queue is currently receiving messages from two exchanges: 100.2 msg/s from "my-exchange" and 54.6 msg/s from "amq.topic".

/api/overview

This has the following fields:

cluster_name The name of the entire cluster, as set with rabbitmqctl set_cluster_name.
contexts A list of web application contexts in the cluster.
erlang_full_version A string with extended detail about the Erlang VM and how it was compiled, for the node connected to.
erlang_version A string with the Erlang version of the node connected to. As clusters should all run the same version this can be taken as representing the cluster.
exchange_types A list of all exchange types available.
listeners All (non-HTTP) network listeners for all nodes in the cluster. (See contexts in /api/nodes for HTTP).
management_version Version of the management plugin in use.
message_stats A message_stats object for everything the user can see - for all vhosts regardless of permissions in the case of monitoring and administrator users, and for all vhosts the user has access to for other users.
node The name of the cluster node this management plugin instance is running on.
object_totals An object containing global counts of all connections, channels, exchanges, queues and consumers, subject to the same visibility rules as for message_stats.
queue_totals An object containing sums of the messages, messages_ready and messages_unacknowledged fields for all queues, again subject to the same visibility rules as for message_stats.
rabbitmq_version Version of RabbitMQ on the node which processed this request.
rates_mode 'none', 'basic' or 'detailed'.
statistics_db_event_queue Number of outstanding statistics events yet to be processed by the database.
statistics_db_node Name of the cluster node hosting the management statistics database.

/api/nodes

This has the following fields:

applications List of all Erlang applications running on the node.
auth_mechanisms List of all SASL authentication mechanisms installed on the node.
cluster_links A list of the other nodes in the cluster. For each node, there are details of the TCP connection used to connect to it and statistics on data that has been transferred.
config_files List of config files read by the node.
contexts List of all HTTP listeners on the node.
db_dir Location of the persistent storage used by the node.
disk_free Disk free space in bytes.
disk_free_alarm Whether the disk alarm has gone off.
disk_free_limit Point at which the disk alarm will go off.
enabled_plugins List of plugins which are both explicitly enabled and running.
exchange_types Exchange types available on the node.
fd_total File descriptors available.
fd_used Used file descriptors.
io_read_avg_time Average wall time (milliseconds) for each disk read operation in the last statistics interval.
io_read_bytes Total number of bytes read from disk by the persister.
io_read_count Total number of read operations by the persister.
io_reopen_count Total number of times the persister has needed to recycle file handles between queues. In an ideal world this number will be zero; if the number is large, performance might be improved by increasing the number of file handles available to RabbitMQ.
io_seek_avg_time Average wall time (milliseconds) for each seek operation in the last statistics interval.
io_seek_count Total number of seek operations by the persister.
io_sync_avg_time Average wall time (milliseconds) for each fsync() operation in the last statistics interval.
io_sync_count Total number of fsync() operations by the persister.
io_write_avg_time Average wall time (milliseconds) for each disk write operation in the last statistics interval.
io_write_bytes Total number of bytes written to disk by the persister.
io_write_count Total number of write operations by the persister.
log_file Location of main log file.
mem_used Memory used in bytes.
mem_alarm Whether the memory alarm has gone off.
mem_limit Point at which the memory alarm will go off.
mnesia_disk_tx_count Number of Mnesia transactions which have been performed that required writes to disk. (e.g. creating a durable queue). Only transactions which originated on this node are included.
mnesia_ram_tx_count Number of Mnesia transactions which have been performed that did not require writes to disk. (e.g. creating a transient queue). Only transactions which originated on this node are included.
msg_store_read_count Number of messages which have been read from the message store.
msg_store_write_count Number of messages which have been written to the message store.
name Node name.
net_ticktime Current kernel net_ticktime setting for the node.
os_pid Process identifier for the Operating System under which this node is running.
partitions List of network partitions this node is seeing.
proc_total Maximum number of Erlang processes.
proc_used Number of Erlang processes in use.
processors Number of cores detected and usable by Erlang.
queue_index_journal_write_count Number of records written to the queue index journal. Each record represents a message being published to a queue, being delivered from a queue, and being acknowledged in a queue.
queue_index_read_count Number of records read from the queue index.
queue_index_write_count Number of records written to the queue index.
rates_mode 'none', 'basic' or 'detailed'.
run_queue Average number of Erlang processes waiting to run.
running Boolean for whether this node is up. Obviously if this is false, most other stats will be missing.
sasl_log_file Location of sasl log file.
sockets_total File descriptors available for use as sockets.
sockets_used File descriptors used as sockets.
type 'disc' or 'ram'.
uptime Time since the Erlang VM started, in milliseconds.

/api/nodes/(name)

All of the above, plus:

memory Detailed memory use statistics. Only appears if ?memory=true is appended to the URL.
binary Detailed breakdown of the owners of binary memory. Only appears if ?binary=true is appended to the URL. Note that this can be an expensive query if there are many small binaries in the system.

/api/connections

/api/connections/(name)

See documentation for rabbitmqctl list_connections. No additional fields, although pid is replaced by node.

Note also that while non-AMQP connections will appear in this list (unlike rabbitmqctl list_connections), they will omit many of the connection-level statistics.

/api/connections/(name)/channels

/api/channels

See documentation for rabbitmqctl list_channels, with pid replaced by node, plus:

connection_details Some basic details about the owning connection.
message_stats See the section on message_stats above.

/api/channels/(name)

All the above, plus

publishes Detailed message stats (see section above) for publishes to exchanges.
deliveries Detailed message stats for deliveries from queues.
consumer_details List of consumers on this channel, with some details on each.

/api/exchanges

/api/exchanges/(vhost)

See documentation for rabbitmqctl list_exchanges, plus:

message_stats See the section on message_stats above.

/api/exchanges/(vhost)/(name)

All the above, plus:

incoming Detailed message stats (see section above) for publishes from channels into this exchange.
outgoing Detailed message stats for publishes from this exchange into queues.

/api/queues

/api/queues/(vhost)

See documentation for rabbitmqctl list_queues, with all references to pids replaced by nodes plus:

message_stats See the section on message_stats above.

/api/queues/(vhost)/(name)

All the above, plus:

incoming Detailed message stats (see section above) for publishes from exchanges into this queue.
deliveries Detailed message stats for deliveries from this queue into channels.
consumer_details List of consumers on this channel, with some details on each.

/api/vhosts/

/api/vhosts/(name)

All the fields from rabbitmqctl list_vhosts (i.e. name and tracing) plus:

message_stats Global message_stats for this vhost. Note that activity for other users in this vhost is shown, even for users without the monitoring tag.
messages messages_ready messages_acknowledged Sum of these fields for all queues in the vhost.
recv_oct send_oct Sum of these fields for all connections to the vhost.
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/0000755000177700017770000000000012633765070025055 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/charts.js0000644000177700017770000002547212633765070026711 0ustar michaelmichael// // Formatting side // function message_rates(id, stats) { var items = [['Publish', 'publish'], ['Confirm', 'confirm'], ['Publish (In)', 'publish_in'], ['Publish (Out)', 'publish_out'], ['Deliver', 'deliver'], ['Redelivered', 'redeliver'], ['Acknowledge', 'ack'], ['Get', 'get'], ['Deliver (noack)', 'deliver_no_ack'], ['Get (noack)', 'get_no_ack'], ['Return', 'return_unroutable'], ['Disk read', 'disk_reads'], ['Disk write', 'disk_writes']]; return rates_chart_or_text(id, stats, items, fmt_rate, fmt_rate_axis, true, 'Message rates', 'message-rates'); } function queue_lengths(id, stats) { var items = [['Ready', 'messages_ready'], ['Unacked', 'messages_unacknowledged'], ['Total', 'messages']]; return rates_chart_or_text(id, stats, items, fmt_num_thousands, fmt_plain_axis, false, 'Queued messages', 'queued-messages'); } function data_rates(id, stats) { var items = [['From client', 'recv_oct'], ['To client', 'send_oct']]; return rates_chart_or_text(id, stats, items, fmt_rate_bytes, fmt_rate_bytes_axis, true, 'Data rates'); } function rates_chart_or_text(id, stats, items, fmt, axis_fmt, chart_rates, heading, heading_help) { var prefix = chart_h3(id, heading, heading_help); return prefix + rates_chart_or_text_no_heading( id, id, stats, items, fmt, axis_fmt, chart_rates); } function rates_chart_or_text_no_heading(type_id, id, stats, items, fmt, axis_fmt, chart_rates) { var mode = get_pref('rate-mode-' + type_id); var range = get_pref('chart-range'); var res; if (keys(stats).length > 0) { if (mode == 'chart') { res = rates_chart( type_id, id, items, stats, fmt, axis_fmt, 'full', chart_rates); } else { res = rates_text(items, stats, mode, fmt, chart_rates); } if (res == "") res = '

Waiting for data...

'; } else { res = '

Currently idle

'; } return res; } function chart_h3(id, heading, heading_help) { var mode = get_pref('rate-mode-' + id); var range = get_pref('chart-range'); return '

' + heading + ' (' + prefix_title(mode, range) + ')' + (heading_help == undefined ? '' : ' ') + '

'; } function prefix_title(mode, range) { var desc = CHART_PERIODS[range]; if (mode == 'chart') { return 'chart: ' + desc.toLowerCase(); } else if (mode == 'curr') { return 'current value'; } else { return 'moving average: ' + desc.toLowerCase(); } } function node_stat_count(used_key, limit_key, stats, thresholds) { var used = stats[used_key]; var limit = stats[limit_key]; if (typeof used == 'number') { return node_stat(used_key, 'Used', limit_key, 'available', stats, fmt_plain, fmt_plain_axis, fmt_color(used / limit, thresholds)); } else { return used; } } function node_stat_count_bar(used_key, limit_key, stats, thresholds) { var used = stats[used_key]; var limit = stats[limit_key]; if (typeof used == 'number') { return node_stat_bar(used_key, limit_key, 'available', stats, fmt_plain_axis, fmt_color(used / limit, thresholds)); } else { return used; } } function node_stat(used_key, used_name, limit_key, suffix, stats, fmt, axis_fmt, colour, help, invert) { if (get_pref('rate-mode-node-stats') == 'chart') { var items = [[used_name, used_key], ['Limit', limit_key]]; add_fake_limit_details(used_key, limit_key, stats); return rates_chart('node-stats', 'node-stats-' + used_key, items, stats, fmt, axis_fmt, 'node', false); } else { return node_stat_bar(used_key, limit_key, suffix, stats, axis_fmt, colour, help, invert); } } function add_fake_limit_details(used_key, limit_key, stats) { var source = stats[used_key + '_details'].samples; var limit = stats[limit_key]; var dest = []; for (var i in source) { dest[i] = {sample: limit, timestamp: source[i].timestamp}; } stats[limit_key + '_details'] = {samples: dest}; } function node_stat_bar(used_key, limit_key, suffix, stats, fmt, colour, help, invert) { var used = stats[used_key]; var limit = stats[limit_key]; var width = 120; var res = ''; var other_colour = colour; var ratio = invert ? (limit / used) : (used / limit); if (ratio > 1) { ratio = 1 / ratio; inverted = true; colour += '-dark'; } else { other_colour += '-dark'; } var offset = Math.round(width * (1 - ratio)); res += '
'; res += '
'; res += fmt(used); if (help != null) { res += ' '; } res += '
'; // status-bar-main res += '' + fmt(limit) + ' ' + suffix + ''; res += '
'; // status-bar return res; } function node_stats_prefs() { return chart_h3('node-stats', 'Node statistics'); } function rates_chart(type_id, id, items, stats, fmt, axis_fmt, type, chart_rates) { function show(key) { return get_pref('chart-line-' + id + key) === 'true'; } var size = get_pref('chart-size-' + type_id); var legend = []; chart_data[id] = {}; chart_data[id]['data'] = {}; chart_data[id]['fmt'] = axis_fmt; var ix = 0; for (var i in items) { var name = items[i][0]; var key = items[i][1]; var key_details = key + '_details'; if (key_details in stats) { if (show(key)) { chart_data[id]['data'][name] = stats[key_details]; chart_data[id]['data'][name].ix = ix; } var value = chart_rates ? pick_rate(fmt, stats, key) : pick_abs(fmt, stats, key); legend.push({name: name, key: key, value: value, show: show(key)}); ix++; } } var html = '
'; html += ''; for (var i = 0; i < legend.length; i++) { if (i % 3 == 0 && i < legend.length - 1) { html += '
'; } html += '' } html += '
'; html += legend[i].name + ''; html += '
' + legend[i].value + '
'; return legend.length > 0 ? html : ''; } function rates_text(items, stats, mode, fmt, chart_rates) { var res = ''; for (var i in items) { var name = items[i][0]; var key = items[i][1]; var key_details = key + '_details'; if (key_details in stats) { var details = stats[key_details]; res += '
' + name + ''; res += chart_rates ? pick_rate(fmt, stats, key, mode) : pick_abs(fmt, stats, key, mode); res += '
'; } } return res == '' ? '' : '
' + res + '
'; } // // Rendering side // function render_charts() { $('.chart').map(function() { render_chart($(this)); }); } var chart_colors = {full: ['#edc240', '#afd8f8', '#cb4b4b', '#4da74d', '#9440ed', '#666666', '#aaaaaa'], node: ['#6ae26a', '#e24545']}; var chart_chrome = { series: { lines: { show: true } }, grid: { borderWidth: 2, borderColor: "#aaa" }, xaxis: { tickColor: "#fff", mode: "time", timezone: "browser" }, yaxis: { tickColor: "#eee", min: 0 }, legend: { show: false } }; function chart_fill(mode, i) { return mode =='node' && i == 0; } function render_chart(div) { var id = div.attr('id').substring('chart-'.length); var rate_mode = div.hasClass('chart-rates'); var out_data = []; var data = chart_data[id]['data']; var fmt = chart_data[id]['fmt']; var mode = div.hasClass('chart-full') ? 'full': 'node'; var colors = chart_colors[mode]; for (var name in data) { var series = data[name]; var samples = series.samples; var i = series.ix; var d = []; for (var j = 1; j < samples.length; j++) { var x = samples[j].timestamp; var y; if (rate_mode) { // TODO This doesn't work well if you are looking at // stuff in the browser that is finer granularity than // the data we have in the DB (and thus we get // duplicated entries). Do we care? We should just // never allow that... y = (samples[j - 1].sample - samples[j].sample) * 1000 / (samples[j - 1].timestamp - samples[j].timestamp); } else { y = samples[j].sample; } d.push([x, y]); } out_data.push({data: d, color: colors[i], shadowSize: 0, lines: {show: true, fill: chart_fill(mode, i)}}); } chart_data[id] = {}; chart_chrome.yaxis.tickFormatter = fmt_y_axis(fmt); $.plot(div, out_data, chart_chrome); } function fmt_y_axis(fmt) { return function (val, axis) { // axis.ticks seems to include the bottom value but not the top if (axis.max == 1 && axis.ticks.length > 1) { var newTicks = [axis.ticks[0]]; axis.ticks = newTicks; } return fmt(val, axis.max); } } function update_rate_options(sammy) { var id = sammy.params['id']; store_pref('rate-mode-' + id, sammy.params['mode']); store_pref('chart-size-' + id, sammy.params['size']); store_pref('chart-range', sammy.params['range']); partial_update(); } rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/jquery.flot.time.min.js0000644000177700017770000001143112633765070031414 0ustar michaelmichael/* Pretty handling of time axes. Copyright (c) 2007-2013 IOLA and Ole Laursen. Licensed under the MIT license. Set axis.mode to "time" to enable. See the section "Time series data" in API.txt for details. */(function(e){function n(e,t){return t*Math.floor(e/t)}function r(e,t,n,r){if(typeof e.strftime=="function")return e.strftime(t);var i=function(e,t){return e=""+e,t=""+(t==null?"0":t),e.length==1?t+e:e},s=[],o=!1,u=e.getHours(),a=u<12;n==null&&(n=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]),r==null&&(r=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]);var f;u>12?f=u-12:u==0?f=12:f=u;for(var l=0;l=u)break;var h=l[c][0],p=l[c][1];if(p=="year"){if(i.minTickSize!=null&&i.minTickSize[1]=="year")h=Math.floor(i.minTickSize[0]);else{var d=Math.pow(10,Math.floor(Math.log(e.delta/o.year)/Math.LN10)),v=e.delta/o.year/d;v<1.5?h=1:v<3?h=2:v<7.5?h=5:h=10,h*=d}h<1&&(h=1)}e.tickSize=i.tickSize||[h,p];var m=e.tickSize[0];p=e.tickSize[1];var g=m*o[p];p=="second"?r.setSeconds(n(r.getSeconds(),m)):p=="minute"?r.setMinutes(n(r.getMinutes(),m)):p=="hour"?r.setHours(n(r.getHours(),m)):p=="month"?r.setMonth(n(r.getMonth(),m)):p=="quarter"?r.setMonth(3*n(r.getMonth()/3,m)):p=="year"&&r.setFullYear(n(r.getFullYear(),m)),r.setMilliseconds(0),g>=o.minute&&r.setSeconds(0),g>=o.hour&&r.setMinutes(0),g>=o.day&&r.setHours(0),g>=o.day*4&&r.setDate(1),g>=o.month*2&&r.setMonth(n(r.getMonth(),3)),g>=o.quarter*2&&r.setMonth(n(r.getMonth(),6)),g>=o.year&&r.setMonth(0);var y=0,b=Number.NaN,w;do{w=b,b=r.getTime(),t.push(b);if(p=="month"||p=="quarter")if(m<1){r.setDate(1);var E=r.getTime();r.setMonth(r.getMonth()+(p=="quarter"?3:1));var S=r.getTime();r.setTime(b+y*o.hour+(S-E)*m),y=r.getHours(),r.setHours(0)}else r.setMonth(r.getMonth()+m*(p=="quarter"?3:1));else p=="year"?r.setFullYear(r.getFullYear()+m):r.setTime(b+g)}while(b=1){return"rgb("+[G.r,G.g,G.b].join(",")+")"}else{return"rgba("+[G.r,G.g,G.b,G.a].join(",")+")"}};G.normalize=function(){function H(J,K,I){return KI?I:K)}G.r=H(0,parseInt(G.r),255);G.g=H(0,parseInt(G.g),255);G.b=H(0,parseInt(G.b),255);G.a=H(0,G.a,1);return G};G.clone=function(){return B.color.make(G.r,G.b,G.g,G.a)};return G.normalize()};B.color.extract=function(D,C){var E;do{E=D.css(C).toLowerCase();if(E!=""&&E!="transparent"){break}D=D.parent()}while(!B.nodeName(D.get(0),"body"));if(E=="rgba(0, 0, 0, 0)"){E="transparent"}return B.color.parse(E)};B.color.parse=function(F){var E,C=B.color.make;if(E=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10))}if(E=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10),parseFloat(E[4]))}if(E=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55)}if(E=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55,parseFloat(E[4]))}if(E=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(F)){return C(parseInt(E[1],16),parseInt(E[2],16),parseInt(E[3],16))}if(E=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(F)){return C(parseInt(E[1]+E[1],16),parseInt(E[2]+E[2],16),parseInt(E[3]+E[3],16))}var D=B.trim(F).toLowerCase();if(D=="transparent"){return C(255,255,255,0)}else{E=A[D]||[0,0,0];return C(E[0],E[1],E[2])}};var A={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery); // the actual Flot code (function($) { // Cache the prototype hasOwnProperty for faster access var hasOwnProperty = Object.prototype.hasOwnProperty; /////////////////////////////////////////////////////////////////////////// // The Canvas object is a wrapper around an HTML5 tag. // // @constructor // @param {string} cls List of classes to apply to the canvas. // @param {element} container Element onto which to append the canvas. // // Requiring a container is a little iffy, but unfortunately canvas // operations don't work unless the canvas is attached to the DOM. function Canvas(cls, container) { var element = container.children("." + cls)[0]; if (element == null) { element = document.createElement("canvas"); element.className = cls; $(element).css({ direction: "ltr", position: "absolute", left: 0, top: 0 }) .appendTo(container); // If HTML5 Canvas isn't available, fall back to [Ex|Flash]canvas if (!element.getContext) { if (window.G_vmlCanvasManager) { element = window.G_vmlCanvasManager.initElement(element); } else { throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode."); } } } this.element = element; var context = this.context = element.getContext("2d"); // Determine the screen's ratio of physical to device-independent // pixels. This is the ratio between the canvas width that the browser // advertises and the number of pixels actually present in that space. // The iPhone 4, for example, has a device-independent width of 320px, // but its screen is actually 640px wide. It therefore has a pixel // ratio of 2, while most normal devices have a ratio of 1. var devicePixelRatio = window.devicePixelRatio || 1, backingStoreRatio = context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1; this.pixelRatio = devicePixelRatio / backingStoreRatio; // Size the canvas to match the internal dimensions of its container this.resize(container.width(), container.height()); // Collection of HTML div layers for text overlaid onto the canvas this.textContainer = null; this.text = {}; // Cache of text fragments and metrics, so we can avoid expensively // re-calculating them when the plot is re-rendered in a loop. this._textCache = {}; } // Resizes the canvas to the given dimensions. // // @param {number} width New width of the canvas, in pixels. // @param {number} width New height of the canvas, in pixels. Canvas.prototype.resize = function(width, height) { if (width <= 0 || height <= 0) { throw new Error("Invalid dimensions for plot, width = " + width + ", height = " + height); } var element = this.element, context = this.context, pixelRatio = this.pixelRatio; // Resize the canvas, increasing its density based on the display's // pixel ratio; basically giving it more pixels without increasing the // size of its element, to take advantage of the fact that retina // displays have that many more pixels in the same advertised space. // Resizing should reset the state (excanvas seems to be buggy though) if (this.width != width) { element.width = width * pixelRatio; element.style.width = width + "px"; this.width = width; } if (this.height != height) { element.height = height * pixelRatio; element.style.height = height + "px"; this.height = height; } // Save the context, so we can reset in case we get replotted. The // restore ensure that we're really back at the initial state, and // should be safe even if we haven't saved the initial state yet. context.restore(); context.save(); // Scale the coordinate space to match the display density; so even though we // may have twice as many pixels, we still want lines and other drawing to // appear at the same size; the extra pixels will just make them crisper. context.scale(pixelRatio, pixelRatio); }; // Clears the entire canvas area, not including any overlaid HTML text Canvas.prototype.clear = function() { this.context.clearRect(0, 0, this.width, this.height); }; // Finishes rendering the canvas, including managing the text overlay. Canvas.prototype.render = function() { var cache = this._textCache; // For each text layer, add elements marked as active that haven't // already been rendered, and remove those that are no longer active. for (var layerKey in cache) { if (hasOwnProperty.call(cache, layerKey)) { var layer = this.getTextLayer(layerKey), layerCache = cache[layerKey]; layer.hide(); for (var styleKey in layerCache) { if (hasOwnProperty.call(layerCache, styleKey)) { var styleCache = layerCache[styleKey]; for (var key in styleCache) { if (hasOwnProperty.call(styleCache, key)) { var positions = styleCache[key].positions; for (var i = 0, position; position = positions[i]; i++) { if (position.active) { if (!position.rendered) { layer.append(position.element); position.rendered = true; } } else { positions.splice(i--, 1); if (position.rendered) { position.element.detach(); } } } if (positions.length == 0) { delete styleCache[key]; } } } } } layer.show(); } } }; // Creates (if necessary) and returns the text overlay container. // // @param {string} classes String of space-separated CSS classes used to // uniquely identify the text layer. // @return {object} The jQuery-wrapped text-layer div. Canvas.prototype.getTextLayer = function(classes) { var layer = this.text[classes]; // Create the text layer if it doesn't exist if (layer == null) { // Create the text layer container, if it doesn't exist if (this.textContainer == null) { this.textContainer = $("
") .css({ position: "absolute", top: 0, left: 0, bottom: 0, right: 0, 'font-size': "smaller", color: "#545454" }) .insertAfter(this.element); } layer = this.text[classes] = $("
") .addClass(classes) .css({ position: "absolute", top: 0, left: 0, bottom: 0, right: 0 }) .appendTo(this.textContainer); } return layer; }; // Creates (if necessary) and returns a text info object. // // The object looks like this: // // { // width: Width of the text's wrapper div. // height: Height of the text's wrapper div. // element: The jQuery-wrapped HTML div containing the text. // positions: Array of positions at which this text is drawn. // } // // The positions array contains objects that look like this: // // { // active: Flag indicating whether the text should be visible. // rendered: Flag indicating whether the text is currently visible. // element: The jQuery-wrapped HTML div containing the text. // x: X coordinate at which to draw the text. // y: Y coordinate at which to draw the text. // } // // Each position after the first receives a clone of the original element. // // The idea is that that the width, height, and general 'identity' of the // text is constant no matter where it is placed; the placements are a // secondary property. // // Canvas maintains a cache of recently-used text info objects; getTextInfo // either returns the cached element or creates a new entry. // // @param {string} layer A string of space-separated CSS classes uniquely // identifying the layer containing this text. // @param {string} text Text string to retrieve info for. // @param {(string|object)=} font Either a string of space-separated CSS // classes or a font-spec object, defining the text's font and style. // @param {number=} angle Angle at which to rotate the text, in degrees. // Angle is currently unused, it will be implemented in the future. // @param {number=} width Maximum width of the text before it wraps. // @return {object} a text info object. Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) { var textStyle, layerCache, styleCache, info; // Cast the value to a string, in case we were given a number or such text = "" + text; // If the font is a font-spec object, generate a CSS font definition if (typeof font === "object") { textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px/" + font.lineHeight + "px " + font.family; } else { textStyle = font; } // Retrieve (or create) the cache for the text's layer and styles layerCache = this._textCache[layer]; if (layerCache == null) { layerCache = this._textCache[layer] = {}; } styleCache = layerCache[textStyle]; if (styleCache == null) { styleCache = layerCache[textStyle] = {}; } info = styleCache[text]; // If we can't find a matching element in our cache, create a new one if (info == null) { var element = $("
").html(text) .css({ position: "absolute", 'max-width': width, top: -9999 }) .appendTo(this.getTextLayer(layer)); if (typeof font === "object") { element.css({ font: textStyle, color: font.color }); } else if (typeof font === "string") { element.addClass(font); } info = styleCache[text] = { width: element.outerWidth(true), height: element.outerHeight(true), element: element, positions: [] }; element.detach(); } return info; }; // Adds a text string to the canvas text overlay. // // The text isn't drawn immediately; it is marked as rendering, which will // result in its addition to the canvas on the next render pass. // // @param {string} layer A string of space-separated CSS classes uniquely // identifying the layer containing this text. // @param {number} x X coordinate at which to draw the text. // @param {number} y Y coordinate at which to draw the text. // @param {string} text Text string to draw. // @param {(string|object)=} font Either a string of space-separated CSS // classes or a font-spec object, defining the text's font and style. // @param {number=} angle Angle at which to rotate the text, in degrees. // Angle is currently unused, it will be implemented in the future. // @param {number=} width Maximum width of the text before it wraps. // @param {string=} halign Horizontal alignment of the text; either "left", // "center" or "right". // @param {string=} valign Vertical alignment of the text; either "top", // "middle" or "bottom". Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) { var info = this.getTextInfo(layer, text, font, angle, width), positions = info.positions; // Tweak the div's position to match the text's alignment if (halign == "center") { x -= info.width / 2; } else if (halign == "right") { x -= info.width; } if (valign == "middle") { y -= info.height / 2; } else if (valign == "bottom") { y -= info.height; } // Determine whether this text already exists at this position. // If so, mark it for inclusion in the next render pass. for (var i = 0, position; position = positions[i]; i++) { if (position.x == x && position.y == y) { position.active = true; return; } } // If the text doesn't exist at this position, create a new entry // For the very first position we'll re-use the original element, // while for subsequent ones we'll clone it. position = { active: true, rendered: false, element: positions.length ? info.element.clone() : info.element, x: x, y: y } positions.push(position); // Move the element to its final position within the container position.element.css({ top: Math.round(y), left: Math.round(x), 'text-align': halign // In case the text wraps }); }; // Removes one or more text strings from the canvas text overlay. // // If no parameters are given, all text within the layer is removed. // // Note that the text is not immediately removed; it is simply marked as // inactive, which will result in its removal on the next render pass. // This avoids the performance penalty for 'clear and redraw' behavior, // where we potentially get rid of all text on a layer, but will likely // add back most or all of it later, as when redrawing axes, for example. // // @param {string} layer A string of space-separated CSS classes uniquely // identifying the layer containing this text. // @param {number=} x X coordinate of the text. // @param {number=} y Y coordinate of the text. // @param {string=} text Text string to remove. // @param {(string|object)=} font Either a string of space-separated CSS // classes or a font-spec object, defining the text's font and style. // @param {number=} angle Angle at which the text is rotated, in degrees. // Angle is currently unused, it will be implemented in the future. Canvas.prototype.removeText = function(layer, x, y, text, font, angle) { if (text == null) { var layerCache = this._textCache[layer]; if (layerCache != null) { for (var styleKey in layerCache) { if (hasOwnProperty.call(layerCache, styleKey)) { var styleCache = layerCache[styleKey]; for (var key in styleCache) { if (hasOwnProperty.call(styleCache, key)) { var positions = styleCache[key].positions; for (var i = 0, position; position = positions[i]; i++) { position.active = false; } } } } } } } else { var positions = this.getTextInfo(layer, text, font, angle).positions; for (var i = 0, position; position = positions[i]; i++) { if (position.x == x && position.y == y) { position.active = false; } } } }; /////////////////////////////////////////////////////////////////////////// // The top-level container for the entire plot. function Plot(placeholder, data_, options_, plugins) { // data is on the form: // [ series1, series2 ... ] // where series is either just the data as [ [x1, y1], [x2, y2], ... ] // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... } var series = [], options = { // the color theme used for graphs colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"], legend: { show: true, noColumns: 1, // number of colums in legend table labelFormatter: null, // fn: string -> string labelBoxBorderColor: "#ccc", // border color for the little label boxes container: null, // container (as jQuery object) to put legend in, null means default on top of graph position: "ne", // position of default legend container within plot margin: 5, // distance from grid edge to default legend container within plot backgroundColor: null, // null means auto-detect backgroundOpacity: 0.85, // set to 0 to avoid background sorted: null // default to no legend sorting }, xaxis: { show: null, // null = auto-detect, true = always, false = never position: "bottom", // or "top" mode: null, // null or "time" font: null, // null (derived from CSS in placeholder) or object like { size: 11, lineHeight: 13, style: "italic", weight: "bold", family: "sans-serif", variant: "small-caps" } color: null, // base color, labels, ticks tickColor: null, // possibly different color of ticks, e.g. "rgba(0,0,0,0.15)" transform: null, // null or f: number -> number to transform axis inverseTransform: null, // if transform is set, this should be the inverse function min: null, // min. value to show, null means set automatically max: null, // max. value to show, null means set automatically autoscaleMargin: null, // margin in % to add if auto-setting min/max ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks tickFormatter: null, // fn: number -> string labelWidth: null, // size of tick labels in pixels labelHeight: null, reserveSpace: null, // whether to reserve space even if axis isn't shown tickLength: null, // size in pixels of ticks, or "full" for whole line alignTicksWithAxis: null, // axis number or null for no sync tickDecimals: null, // no. of decimals, null means auto tickSize: null, // number or [number, "unit"] minTickSize: null // number or [number, "unit"] }, yaxis: { autoscaleMargin: 0.02, position: "left" // or "right" }, xaxes: [], yaxes: [], series: { points: { show: false, radius: 3, lineWidth: 2, // in pixels fill: true, fillColor: "#ffffff", symbol: "circle" // or callback }, lines: { // we don't put in show: false so we can see // whether lines were actively disabled lineWidth: 2, // in pixels fill: false, fillColor: null, steps: false // Omit 'zero', so we can later default its value to // match that of the 'fill' option. }, bars: { show: false, lineWidth: 2, // in pixels barWidth: 1, // in units of the x axis fill: true, fillColor: null, align: "left", // "left", "right", or "center" horizontal: false, zero: true }, shadowSize: 3, highlightColor: null }, grid: { show: true, aboveData: false, color: "#545454", // primary color used for outline and labels backgroundColor: null, // null for transparent, else color borderColor: null, // set if different from the grid color tickColor: null, // color for the ticks, e.g. "rgba(0,0,0,0.15)" margin: 0, // distance from the canvas edge to the grid labelMargin: 5, // in pixels axisMargin: 8, // in pixels borderWidth: 2, // in pixels minBorderMargin: null, // in pixels, null means taken from points radius markings: null, // array of ranges or fn: axes -> array of ranges markingsColor: "#f4f4f4", markingsLineWidth: 2, // interactive stuff clickable: false, hoverable: false, autoHighlight: true, // highlight in case mouse is near mouseActiveRadius: 10 // how far the mouse can be away to activate an item }, interaction: { redrawOverlayInterval: 1000/60 // time between updates, -1 means in same flow }, hooks: {} }, surface = null, // the canvas for the plot itself overlay = null, // canvas for interactive stuff on top of plot eventHolder = null, // jQuery object that events should be bound to ctx = null, octx = null, xaxes = [], yaxes = [], plotOffset = { left: 0, right: 0, top: 0, bottom: 0}, plotWidth = 0, plotHeight = 0, hooks = { processOptions: [], processRawData: [], processDatapoints: [], processOffset: [], drawBackground: [], drawSeries: [], draw: [], bindEvents: [], drawOverlay: [], shutdown: [] }, plot = this; // public functions plot.setData = setData; plot.setupGrid = setupGrid; plot.draw = draw; plot.getPlaceholder = function() { return placeholder; }; plot.getCanvas = function() { return surface.element; }; plot.getPlotOffset = function() { return plotOffset; }; plot.width = function () { return plotWidth; }; plot.height = function () { return plotHeight; }; plot.offset = function () { var o = eventHolder.offset(); o.left += plotOffset.left; o.top += plotOffset.top; return o; }; plot.getData = function () { return series; }; plot.getAxes = function () { var res = {}, i; $.each(xaxes.concat(yaxes), function (_, axis) { if (axis) res[axis.direction + (axis.n != 1 ? axis.n : "") + "axis"] = axis; }); return res; }; plot.getXAxes = function () { return xaxes; }; plot.getYAxes = function () { return yaxes; }; plot.c2p = canvasToAxisCoords; plot.p2c = axisToCanvasCoords; plot.getOptions = function () { return options; }; plot.highlight = highlight; plot.unhighlight = unhighlight; plot.triggerRedrawOverlay = triggerRedrawOverlay; plot.pointOffset = function(point) { return { left: parseInt(xaxes[axisNumber(point, "x") - 1].p2c(+point.x) + plotOffset.left, 10), top: parseInt(yaxes[axisNumber(point, "y") - 1].p2c(+point.y) + plotOffset.top, 10) }; }; plot.shutdown = shutdown; plot.resize = function () { var width = placeholder.width(), height = placeholder.height(); surface.resize(width, height); overlay.resize(width, height); }; // public attributes plot.hooks = hooks; // initialize initPlugins(plot); parseOptions(options_); setupCanvases(); setData(data_); setupGrid(); draw(); bindEvents(); function executeHooks(hook, args) { args = [plot].concat(args); for (var i = 0; i < hook.length; ++i) hook[i].apply(this, args); } function initPlugins() { // References to key classes, allowing plugins to modify them var classes = { Canvas: Canvas }; for (var i = 0; i < plugins.length; ++i) { var p = plugins[i]; p.init(plot, classes); if (p.options) $.extend(true, options, p.options); } } function parseOptions(opts) { $.extend(true, options, opts); // $.extend merges arrays, rather than replacing them. When less // colors are provided than the size of the default palette, we // end up with those colors plus the remaining defaults, which is // not expected behavior; avoid it by replacing them here. if (opts && opts.colors) { options.colors = opts.colors; } if (options.xaxis.color == null) options.xaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString(); if (options.yaxis.color == null) options.yaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString(); if (options.xaxis.tickColor == null) // grid.tickColor for back-compatibility options.xaxis.tickColor = options.grid.tickColor || options.xaxis.color; if (options.yaxis.tickColor == null) // grid.tickColor for back-compatibility options.yaxis.tickColor = options.grid.tickColor || options.yaxis.color; if (options.grid.borderColor == null) options.grid.borderColor = options.grid.color; if (options.grid.tickColor == null) options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString(); // Fill in defaults for axis options, including any unspecified // font-spec fields, if a font-spec was provided. // If no x/y axis options were provided, create one of each anyway, // since the rest of the code assumes that they exist. var i, axisOptions, axisCount, fontDefaults = { style: placeholder.css("font-style"), size: Math.round(0.8 * (+placeholder.css("font-size").replace("px", "") || 13)), variant: placeholder.css("font-variant"), weight: placeholder.css("font-weight"), family: placeholder.css("font-family") }; fontDefaults.lineHeight = fontDefaults.size * 1.15; axisCount = options.xaxes.length || 1; for (i = 0; i < axisCount; ++i) { axisOptions = options.xaxes[i]; if (axisOptions && !axisOptions.tickColor) { axisOptions.tickColor = axisOptions.color; } axisOptions = $.extend(true, {}, options.xaxis, axisOptions); options.xaxes[i] = axisOptions; if (axisOptions.font) { axisOptions.font = $.extend({}, fontDefaults, axisOptions.font); if (!axisOptions.font.color) { axisOptions.font.color = axisOptions.color; } } } axisCount = options.yaxes.length || 1; for (i = 0; i < axisCount; ++i) { axisOptions = options.yaxes[i]; if (axisOptions && !axisOptions.tickColor) { axisOptions.tickColor = axisOptions.color; } axisOptions = $.extend(true, {}, options.yaxis, axisOptions); options.yaxes[i] = axisOptions; if (axisOptions.font) { axisOptions.font = $.extend({}, fontDefaults, axisOptions.font); if (!axisOptions.font.color) { axisOptions.font.color = axisOptions.color; } } } // backwards compatibility, to be removed in future if (options.xaxis.noTicks && options.xaxis.ticks == null) options.xaxis.ticks = options.xaxis.noTicks; if (options.yaxis.noTicks && options.yaxis.ticks == null) options.yaxis.ticks = options.yaxis.noTicks; if (options.x2axis) { options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis); options.xaxes[1].position = "top"; } if (options.y2axis) { options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis); options.yaxes[1].position = "right"; } if (options.grid.coloredAreas) options.grid.markings = options.grid.coloredAreas; if (options.grid.coloredAreasColor) options.grid.markingsColor = options.grid.coloredAreasColor; if (options.lines) $.extend(true, options.series.lines, options.lines); if (options.points) $.extend(true, options.series.points, options.points); if (options.bars) $.extend(true, options.series.bars, options.bars); if (options.shadowSize != null) options.series.shadowSize = options.shadowSize; if (options.highlightColor != null) options.series.highlightColor = options.highlightColor; // save options on axes for future reference for (i = 0; i < options.xaxes.length; ++i) getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i]; for (i = 0; i < options.yaxes.length; ++i) getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i]; // add hooks from options for (var n in hooks) if (options.hooks[n] && options.hooks[n].length) hooks[n] = hooks[n].concat(options.hooks[n]); executeHooks(hooks.processOptions, [options]); } function setData(d) { series = parseData(d); fillInSeriesOptions(); processData(); } function parseData(d) { var res = []; for (var i = 0; i < d.length; ++i) { var s = $.extend(true, {}, options.series); if (d[i].data != null) { s.data = d[i].data; // move the data instead of deep-copy delete d[i].data; $.extend(true, s, d[i]); d[i].data = s.data; } else s.data = d[i]; res.push(s); } return res; } function axisNumber(obj, coord) { var a = obj[coord + "axis"]; if (typeof a == "object") // if we got a real axis, extract number a = a.n; if (typeof a != "number") a = 1; // default to first axis return a; } function allAxes() { // return flat array without annoying null entries return $.grep(xaxes.concat(yaxes), function (a) { return a; }); } function canvasToAxisCoords(pos) { // return an object with x/y corresponding to all used axes var res = {}, i, axis; for (i = 0; i < xaxes.length; ++i) { axis = xaxes[i]; if (axis && axis.used) res["x" + axis.n] = axis.c2p(pos.left); } for (i = 0; i < yaxes.length; ++i) { axis = yaxes[i]; if (axis && axis.used) res["y" + axis.n] = axis.c2p(pos.top); } if (res.x1 !== undefined) res.x = res.x1; if (res.y1 !== undefined) res.y = res.y1; return res; } function axisToCanvasCoords(pos) { // get canvas coords from the first pair of x/y found in pos var res = {}, i, axis, key; for (i = 0; i < xaxes.length; ++i) { axis = xaxes[i]; if (axis && axis.used) { key = "x" + axis.n; if (pos[key] == null && axis.n == 1) key = "x"; if (pos[key] != null) { res.left = axis.p2c(pos[key]); break; } } } for (i = 0; i < yaxes.length; ++i) { axis = yaxes[i]; if (axis && axis.used) { key = "y" + axis.n; if (pos[key] == null && axis.n == 1) key = "y"; if (pos[key] != null) { res.top = axis.p2c(pos[key]); break; } } } return res; } function getOrCreateAxis(axes, number) { if (!axes[number - 1]) axes[number - 1] = { n: number, // save the number for future reference direction: axes == xaxes ? "x" : "y", options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis) }; return axes[number - 1]; } function fillInSeriesOptions() { var neededColors = series.length, maxIndex = -1, i; // Subtract the number of series that already have fixed colors or // color indexes from the number that we still need to generate. for (i = 0; i < series.length; ++i) { var sc = series[i].color; if (sc != null) { neededColors--; if (typeof sc == "number" && sc > maxIndex) { maxIndex = sc; } } } // If any of the series have fixed color indexes, then we need to // generate at least as many colors as the highest index. if (neededColors <= maxIndex) { neededColors = maxIndex + 1; } // Generate all the colors, using first the option colors and then // variations on those colors once they're exhausted. var c, colors = [], colorPool = options.colors, colorPoolSize = colorPool.length, variation = 0; for (i = 0; i < neededColors; i++) { c = $.color.parse(colorPool[i % colorPoolSize] || "#666"); // Each time we exhaust the colors in the pool we adjust // a scaling factor used to produce more variations on // those colors. The factor alternates negative/positive // to produce lighter/darker colors. // Reset the variation after every few cycles, or else // it will end up producing only white or black colors. if (i % colorPoolSize == 0 && i) { if (variation >= 0) { if (variation < 0.5) { variation = -variation - 0.2; } else variation = 0; } else variation = -variation; } colors[i] = c.scale('rgb', 1 + variation); } // Finalize the series options, filling in their colors var colori = 0, s; for (i = 0; i < series.length; ++i) { s = series[i]; // assign colors if (s.color == null) { s.color = colors[colori].toString(); ++colori; } else if (typeof s.color == "number") s.color = colors[s.color].toString(); // turn on lines automatically in case nothing is set if (s.lines.show == null) { var v, show = true; for (v in s) if (s[v] && s[v].show) { show = false; break; } if (show) s.lines.show = true; } // If nothing was provided for lines.zero, default it to match // lines.fill, since areas by default should extend to zero. if (s.lines.zero == null) { s.lines.zero = !!s.lines.fill; } // setup axes s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, "x")); s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, "y")); } } function processData() { var topSentry = Number.POSITIVE_INFINITY, bottomSentry = Number.NEGATIVE_INFINITY, fakeInfinity = Number.MAX_VALUE, i, j, k, m, length, s, points, ps, x, y, axis, val, f, p, data, format; function updateAxis(axis, min, max) { if (min < axis.datamin && min != -fakeInfinity) axis.datamin = min; if (max > axis.datamax && max != fakeInfinity) axis.datamax = max; } $.each(allAxes(), function (_, axis) { // init axis axis.datamin = topSentry; axis.datamax = bottomSentry; axis.used = false; }); for (i = 0; i < series.length; ++i) { s = series[i]; s.datapoints = { points: [] }; executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]); } // first pass: clean and copy data for (i = 0; i < series.length; ++i) { s = series[i]; data = s.data; format = s.datapoints.format; if (!format) { format = []; // find out how to copy format.push({ x: true, number: true, required: true }); format.push({ y: true, number: true, required: true }); if (s.bars.show || (s.lines.show && s.lines.fill)) { var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero)); format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale }); if (s.bars.horizontal) { delete format[format.length - 1].y; format[format.length - 1].x = true; } } s.datapoints.format = format; } if (s.datapoints.pointsize != null) continue; // already filled in s.datapoints.pointsize = format.length; ps = s.datapoints.pointsize; points = s.datapoints.points; var insertSteps = s.lines.show && s.lines.steps; s.xaxis.used = s.yaxis.used = true; for (j = k = 0; j < data.length; ++j, k += ps) { p = data[j]; var nullify = p == null; if (!nullify) { for (m = 0; m < ps; ++m) { val = p[m]; f = format[m]; if (f) { if (f.number && val != null) { val = +val; // convert to number if (isNaN(val)) val = null; else if (val == Infinity) val = fakeInfinity; else if (val == -Infinity) val = -fakeInfinity; } if (val == null) { if (f.required) nullify = true; if (f.defaultValue != null) val = f.defaultValue; } } points[k + m] = val; } } if (nullify) { for (m = 0; m < ps; ++m) { val = points[k + m]; if (val != null) { f = format[m]; // extract min/max info if (f.autoscale) { if (f.x) { updateAxis(s.xaxis, val, val); } if (f.y) { updateAxis(s.yaxis, val, val); } } } points[k + m] = null; } } else { // a little bit of line specific stuff that // perhaps shouldn't be here, but lacking // better means... if (insertSteps && k > 0 && points[k - ps] != null && points[k - ps] != points[k] && points[k - ps + 1] != points[k + 1]) { // copy the point to make room for a middle point for (m = 0; m < ps; ++m) points[k + ps + m] = points[k + m]; // middle point has same y points[k + 1] = points[k - ps + 1]; // we've added a point, better reflect that k += ps; } } } } // give the hooks a chance to run for (i = 0; i < series.length; ++i) { s = series[i]; executeHooks(hooks.processDatapoints, [ s, s.datapoints]); } // second pass: find datamax/datamin for auto-scaling for (i = 0; i < series.length; ++i) { s = series[i]; points = s.datapoints.points; ps = s.datapoints.pointsize; format = s.datapoints.format; var xmin = topSentry, ymin = topSentry, xmax = bottomSentry, ymax = bottomSentry; for (j = 0; j < points.length; j += ps) { if (points[j] == null) continue; for (m = 0; m < ps; ++m) { val = points[j + m]; f = format[m]; if (!f || f.autoscale === false || val == fakeInfinity || val == -fakeInfinity) continue; if (f.x) { if (val < xmin) xmin = val; if (val > xmax) xmax = val; } if (f.y) { if (val < ymin) ymin = val; if (val > ymax) ymax = val; } } } if (s.bars.show) { // make sure we got room for the bar on the dancing floor var delta; switch (s.bars.align) { case "left": delta = 0; break; case "right": delta = -s.bars.barWidth; break; case "center": delta = -s.bars.barWidth / 2; break; default: throw new Error("Invalid bar alignment: " + s.bars.align); } if (s.bars.horizontal) { ymin += delta; ymax += delta + s.bars.barWidth; } else { xmin += delta; xmax += delta + s.bars.barWidth; } } updateAxis(s.xaxis, xmin, xmax); updateAxis(s.yaxis, ymin, ymax); } $.each(allAxes(), function (_, axis) { if (axis.datamin == topSentry) axis.datamin = null; if (axis.datamax == bottomSentry) axis.datamax = null; }); } function setupCanvases() { // Make sure the placeholder is clear of everything except canvases // from a previous plot in this container that we'll try to re-use. placeholder.css("padding", 0) // padding messes up the positioning .children(":not(.flot-base,.flot-overlay)").remove(); if (placeholder.css("position") == 'static') placeholder.css("position", "relative"); // for positioning labels and overlay surface = new Canvas("flot-base", placeholder); overlay = new Canvas("flot-overlay", placeholder); // overlay canvas for interactive features ctx = surface.context; octx = overlay.context; // define which element we're listening for events on eventHolder = $(overlay.element).unbind(); // If we're re-using a plot object, shut down the old one var existing = placeholder.data("plot"); if (existing) { existing.shutdown(); overlay.clear(); } // save in case we get replotted placeholder.data("plot", plot); } function bindEvents() { // bind events if (options.grid.hoverable) { eventHolder.mousemove(onMouseMove); // Use bind, rather than .mouseleave, because we officially // still support jQuery 1.2.6, which doesn't define a shortcut // for mouseenter or mouseleave. This was a bug/oversight that // was fixed somewhere around 1.3.x. We can return to using // .mouseleave when we drop support for 1.2.6. eventHolder.bind("mouseleave", onMouseLeave); } if (options.grid.clickable) eventHolder.click(onClick); executeHooks(hooks.bindEvents, [eventHolder]); } function shutdown() { if (redrawTimeout) clearTimeout(redrawTimeout); eventHolder.unbind("mousemove", onMouseMove); eventHolder.unbind("mouseleave", onMouseLeave); eventHolder.unbind("click", onClick); executeHooks(hooks.shutdown, [eventHolder]); } function setTransformationHelpers(axis) { // set helper functions on the axis, assumes plot area // has been computed already function identity(x) { return x; } var s, m, t = axis.options.transform || identity, it = axis.options.inverseTransform; // precompute how much the axis is scaling a point // in canvas space if (axis.direction == "x") { s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min)); m = Math.min(t(axis.max), t(axis.min)); } else { s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min)); s = -s; m = Math.max(t(axis.max), t(axis.min)); } // data point to canvas coordinate if (t == identity) // slight optimization axis.p2c = function (p) { return (p - m) * s; }; else axis.p2c = function (p) { return (t(p) - m) * s; }; // canvas coordinate to data point if (!it) axis.c2p = function (c) { return m + c / s; }; else axis.c2p = function (c) { return it(m + c / s); }; } function measureTickLabels(axis) { var opts = axis.options, ticks = axis.ticks || [], labelWidth = opts.labelWidth || 0, labelHeight = opts.labelHeight || 0, maxWidth = labelWidth || axis.direction == "x" ? Math.floor(surface.width / (ticks.length || 1)) : null; legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis", layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles, font = opts.font || "flot-tick-label tickLabel"; for (var i = 0; i < ticks.length; ++i) { var t = ticks[i]; if (!t.label) continue; var info = surface.getTextInfo(layer, t.label, font, null, maxWidth); labelWidth = Math.max(labelWidth, info.width); labelHeight = Math.max(labelHeight, info.height); } axis.labelWidth = opts.labelWidth || labelWidth; axis.labelHeight = opts.labelHeight || labelHeight; } function allocateAxisBoxFirstPhase(axis) { // find the bounding box of the axis by looking at label // widths/heights and ticks, make room by diminishing the // plotOffset; this first phase only looks at one // dimension per axis, the other dimension depends on the // other axes so will have to wait var lw = axis.labelWidth, lh = axis.labelHeight, pos = axis.options.position, tickLength = axis.options.tickLength, axisMargin = options.grid.axisMargin, padding = options.grid.labelMargin, all = axis.direction == "x" ? xaxes : yaxes, index, innermost; // determine axis margin var samePosition = $.grep(all, function (a) { return a && a.options.position == pos && a.reserveSpace; }); if ($.inArray(axis, samePosition) == samePosition.length - 1) axisMargin = 0; // outermost // determine tick length - if we're innermost, we can use "full" if (tickLength == null) { var sameDirection = $.grep(all, function (a) { return a && a.reserveSpace; }); innermost = $.inArray(axis, sameDirection) == 0; if (innermost) tickLength = "full"; else tickLength = 5; } if (!isNaN(+tickLength)) padding += +tickLength; // compute box if (axis.direction == "x") { lh += padding; if (pos == "bottom") { plotOffset.bottom += lh + axisMargin; axis.box = { top: surface.height - plotOffset.bottom, height: lh }; } else { axis.box = { top: plotOffset.top + axisMargin, height: lh }; plotOffset.top += lh + axisMargin; } } else { lw += padding; if (pos == "left") { axis.box = { left: plotOffset.left + axisMargin, width: lw }; plotOffset.left += lw + axisMargin; } else { plotOffset.right += lw + axisMargin; axis.box = { left: surface.width - plotOffset.right, width: lw }; } } // save for future reference axis.position = pos; axis.tickLength = tickLength; axis.box.padding = padding; axis.innermost = innermost; } function allocateAxisBoxSecondPhase(axis) { // now that all axis boxes have been placed in one // dimension, we can set the remaining dimension coordinates if (axis.direction == "x") { axis.box.left = plotOffset.left - axis.labelWidth / 2; axis.box.width = surface.width - plotOffset.left - plotOffset.right + axis.labelWidth; } else { axis.box.top = plotOffset.top - axis.labelHeight / 2; axis.box.height = surface.height - plotOffset.bottom - plotOffset.top + axis.labelHeight; } } function adjustLayoutForThingsStickingOut() { // possibly adjust plot offset to ensure everything stays // inside the canvas and isn't clipped off var minMargin = options.grid.minBorderMargin, margins = { x: 0, y: 0 }, i, axis; // check stuff from the plot (FIXME: this should just read // a value from the series, otherwise it's impossible to // customize) if (minMargin == null) { minMargin = 0; for (i = 0; i < series.length; ++i) minMargin = Math.max(minMargin, 2 * (series[i].points.radius + series[i].points.lineWidth/2)); } margins.x = margins.y = Math.ceil(minMargin); // check axis labels, note we don't check the actual // labels but instead use the overall width/height to not // jump as much around with replots $.each(allAxes(), function (_, axis) { var dir = axis.direction; if (axis.reserveSpace) margins[dir] = Math.ceil(Math.max(margins[dir], (dir == "x" ? axis.labelWidth : axis.labelHeight) / 2)); }); plotOffset.left = Math.max(margins.x, plotOffset.left); plotOffset.right = Math.max(margins.x, plotOffset.right); plotOffset.top = Math.max(margins.y, plotOffset.top); plotOffset.bottom = Math.max(margins.y, plotOffset.bottom); } function setupGrid() { var i, axes = allAxes(), showGrid = options.grid.show; // Initialize the plot's offset from the edge of the canvas for (var a in plotOffset) { var margin = options.grid.margin || 0; plotOffset[a] = typeof margin == "number" ? margin : margin[a] || 0; } executeHooks(hooks.processOffset, [plotOffset]); // If the grid is visible, add its border width to the offset for (var a in plotOffset) { if(typeof(options.grid.borderWidth) == "object") { plotOffset[a] += showGrid ? options.grid.borderWidth[a] : 0; } else { plotOffset[a] += showGrid ? options.grid.borderWidth : 0; } } // init axes $.each(axes, function (_, axis) { axis.show = axis.options.show; if (axis.show == null) axis.show = axis.used; // by default an axis is visible if it's got data axis.reserveSpace = axis.show || axis.options.reserveSpace; setRange(axis); }); if (showGrid) { var allocatedAxes = $.grep(axes, function (axis) { return axis.reserveSpace; }); $.each(allocatedAxes, function (_, axis) { // make the ticks setupTickGeneration(axis); setTicks(axis); snapRangeToTicks(axis, axis.ticks); // find labelWidth/Height for axis measureTickLabels(axis); }); // with all dimensions calculated, we can compute the // axis bounding boxes, start from the outside // (reverse order) for (i = allocatedAxes.length - 1; i >= 0; --i) allocateAxisBoxFirstPhase(allocatedAxes[i]); // make sure we've got enough space for things that // might stick out adjustLayoutForThingsStickingOut(); $.each(allocatedAxes, function (_, axis) { allocateAxisBoxSecondPhase(axis); }); } plotWidth = surface.width - plotOffset.left - plotOffset.right; plotHeight = surface.height - plotOffset.bottom - plotOffset.top; // now we got the proper plot dimensions, we can compute the scaling $.each(axes, function (_, axis) { setTransformationHelpers(axis); }); if (showGrid) { drawAxisLabels(); } insertLegend(); } function setRange(axis) { var opts = axis.options, min = +(opts.min != null ? opts.min : axis.datamin), max = +(opts.max != null ? opts.max : axis.datamax), delta = max - min; if (delta == 0.0) { // degenerate case var widen = max == 0 ? 1 : 0.01; if (opts.min == null) min -= widen; // always widen max if we couldn't widen min to ensure we // don't fall into min == max which doesn't work if (opts.max == null || opts.min != null) max += widen; } else { // consider autoscaling var margin = opts.autoscaleMargin; if (margin != null) { if (opts.min == null) { min -= delta * margin; // make sure we don't go below zero if all values // are positive if (min < 0 && axis.datamin != null && axis.datamin >= 0) min = 0; } if (opts.max == null) { max += delta * margin; if (max > 0 && axis.datamax != null && axis.datamax <= 0) max = 0; } } } axis.min = min; axis.max = max; } function setupTickGeneration(axis) { var opts = axis.options; // estimate number of ticks var noTicks; if (typeof opts.ticks == "number" && opts.ticks > 0) noTicks = opts.ticks; else // heuristic based on the model a*sqrt(x) fitted to // some data points that seemed reasonable noTicks = 0.3 * Math.sqrt(axis.direction == "x" ? surface.width : surface.height); var delta = (axis.max - axis.min) / noTicks, dec = -Math.floor(Math.log(delta) / Math.LN10), maxDec = opts.tickDecimals; if (maxDec != null && dec > maxDec) { dec = maxDec; } var magn = Math.pow(10, -dec), norm = delta / magn, // norm is between 1.0 and 10.0 size; if (norm < 1.5) { size = 1; } else if (norm < 3) { size = 2; // special case for 2.5, requires an extra decimal if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) { size = 2.5; ++dec; } } else if (norm < 7.5) { size = 5; } else { size = 10; } size *= magn; if (opts.minTickSize != null && size < opts.minTickSize) { size = opts.minTickSize; } axis.delta = delta; axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec); axis.tickSize = opts.tickSize || size; // Time mode was moved to a plug-in in 0.8, but since so many people use this // we'll add an especially friendly make sure they remembered to include it. if (opts.mode == "time" && !axis.tickGenerator) { throw new Error("Time mode requires the flot.time plugin."); } // Flot supports base-10 axes; any other mode else is handled by a plug-in, // like flot.time.js. if (!axis.tickGenerator) { axis.tickGenerator = function (axis) { var ticks = [], start = floorInBase(axis.min, axis.tickSize), i = 0, v = Number.NaN, prev; do { prev = v; v = start + i * axis.tickSize; ticks.push(v); ++i; } while (v < axis.max && v != prev); return ticks; }; axis.tickFormatter = function (value, axis) { var factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1; var formatted = "" + Math.round(value * factor) / factor; // If tickDecimals was specified, ensure that we have exactly that // much precision; otherwise default to the value's own precision. if (axis.tickDecimals != null) { var decimal = formatted.indexOf("."); var precision = decimal == -1 ? 0 : formatted.length - decimal - 1; if (precision < axis.tickDecimals) { return (precision ? formatted : formatted + ".") + ("" + factor).substr(1, axis.tickDecimals - precision); } } return formatted; }; } if ($.isFunction(opts.tickFormatter)) axis.tickFormatter = function (v, axis) { return "" + opts.tickFormatter(v, axis); }; if (opts.alignTicksWithAxis != null) { var otherAxis = (axis.direction == "x" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1]; if (otherAxis && otherAxis.used && otherAxis != axis) { // consider snapping min/max to outermost nice ticks var niceTicks = axis.tickGenerator(axis); if (niceTicks.length > 0) { if (opts.min == null) axis.min = Math.min(axis.min, niceTicks[0]); if (opts.max == null && niceTicks.length > 1) axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]); } axis.tickGenerator = function (axis) { // copy ticks, scaled to this axis var ticks = [], v, i; for (i = 0; i < otherAxis.ticks.length; ++i) { v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min); v = axis.min + v * (axis.max - axis.min); ticks.push(v); } return ticks; }; // we might need an extra decimal since forced // ticks don't necessarily fit naturally if (!axis.mode && opts.tickDecimals == null) { var extraDec = Math.max(0, -Math.floor(Math.log(axis.delta) / Math.LN10) + 1), ts = axis.tickGenerator(axis); // only proceed if the tick interval rounded // with an extra decimal doesn't give us a // zero at end if (!(ts.length > 1 && /\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec)))) axis.tickDecimals = extraDec; } } } } function setTicks(axis) { var oticks = axis.options.ticks, ticks = []; if (oticks == null || (typeof oticks == "number" && oticks > 0)) ticks = axis.tickGenerator(axis); else if (oticks) { if ($.isFunction(oticks)) // generate the ticks ticks = oticks(axis); else ticks = oticks; } // clean up/labelify the supplied ticks, copy them over var i, v; axis.ticks = []; for (i = 0; i < ticks.length; ++i) { var label = null; var t = ticks[i]; if (typeof t == "object") { v = +t[0]; if (t.length > 1) label = t[1]; } else v = +t; if (label == null) label = axis.tickFormatter(v, axis); if (!isNaN(v)) axis.ticks.push({ v: v, label: label }); } } function snapRangeToTicks(axis, ticks) { if (axis.options.autoscaleMargin && ticks.length > 0) { // snap to ticks if (axis.options.min == null) axis.min = Math.min(axis.min, ticks[0].v); if (axis.options.max == null && ticks.length > 1) axis.max = Math.max(axis.max, ticks[ticks.length - 1].v); } } function draw() { surface.clear(); executeHooks(hooks.drawBackground, [ctx]); var grid = options.grid; // draw background, if any if (grid.show && grid.backgroundColor) drawBackground(); if (grid.show && !grid.aboveData) { drawGrid(); } for (var i = 0; i < series.length; ++i) { executeHooks(hooks.drawSeries, [ctx, series[i]]); drawSeries(series[i]); } executeHooks(hooks.draw, [ctx]); if (grid.show && grid.aboveData) { drawGrid(); } surface.render(); // A draw implies that either the axes or data have changed, so we // should probably update the overlay highlights as well. triggerRedrawOverlay(); } function extractRange(ranges, coord) { var axis, from, to, key, axes = allAxes(); for (var i = 0; i < axes.length; ++i) { axis = axes[i]; if (axis.direction == coord) { key = coord + axis.n + "axis"; if (!ranges[key] && axis.n == 1) key = coord + "axis"; // support x1axis as xaxis if (ranges[key]) { from = ranges[key].from; to = ranges[key].to; break; } } } // backwards-compat stuff - to be removed in future if (!ranges[key]) { axis = coord == "x" ? xaxes[0] : yaxes[0]; from = ranges[coord + "1"]; to = ranges[coord + "2"]; } // auto-reverse as an added bonus if (from != null && to != null && from > to) { var tmp = from; from = to; to = tmp; } return { from: from, to: to, axis: axis }; } function drawBackground() { ctx.save(); ctx.translate(plotOffset.left, plotOffset.top); ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)"); ctx.fillRect(0, 0, plotWidth, plotHeight); ctx.restore(); } function drawGrid() { var i, axes, bw, bc; ctx.save(); ctx.translate(plotOffset.left, plotOffset.top); // draw markings var markings = options.grid.markings; if (markings) { if ($.isFunction(markings)) { axes = plot.getAxes(); // xmin etc. is backwards compatibility, to be // removed in the future axes.xmin = axes.xaxis.min; axes.xmax = axes.xaxis.max; axes.ymin = axes.yaxis.min; axes.ymax = axes.yaxis.max; markings = markings(axes); } for (i = 0; i < markings.length; ++i) { var m = markings[i], xrange = extractRange(m, "x"), yrange = extractRange(m, "y"); // fill in missing if (xrange.from == null) xrange.from = xrange.axis.min; if (xrange.to == null) xrange.to = xrange.axis.max; if (yrange.from == null) yrange.from = yrange.axis.min; if (yrange.to == null) yrange.to = yrange.axis.max; // clip if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max || yrange.to < yrange.axis.min || yrange.from > yrange.axis.max) continue; xrange.from = Math.max(xrange.from, xrange.axis.min); xrange.to = Math.min(xrange.to, xrange.axis.max); yrange.from = Math.max(yrange.from, yrange.axis.min); yrange.to = Math.min(yrange.to, yrange.axis.max); if (xrange.from == xrange.to && yrange.from == yrange.to) continue; // then draw xrange.from = xrange.axis.p2c(xrange.from); xrange.to = xrange.axis.p2c(xrange.to); yrange.from = yrange.axis.p2c(yrange.from); yrange.to = yrange.axis.p2c(yrange.to); if (xrange.from == xrange.to || yrange.from == yrange.to) { // draw line ctx.beginPath(); ctx.strokeStyle = m.color || options.grid.markingsColor; ctx.lineWidth = m.lineWidth || options.grid.markingsLineWidth; ctx.moveTo(xrange.from, yrange.from); ctx.lineTo(xrange.to, yrange.to); ctx.stroke(); } else { // fill area ctx.fillStyle = m.color || options.grid.markingsColor; ctx.fillRect(xrange.from, yrange.to, xrange.to - xrange.from, yrange.from - yrange.to); } } } // draw the ticks axes = allAxes(); bw = options.grid.borderWidth; for (var j = 0; j < axes.length; ++j) { var axis = axes[j], box = axis.box, t = axis.tickLength, x, y, xoff, yoff; if (!axis.show || axis.ticks.length == 0) continue; ctx.lineWidth = 1; // find the edges if (axis.direction == "x") { x = 0; if (t == "full") y = (axis.position == "top" ? 0 : plotHeight); else y = box.top - plotOffset.top + (axis.position == "top" ? box.height : 0); } else { y = 0; if (t == "full") x = (axis.position == "left" ? 0 : plotWidth); else x = box.left - plotOffset.left + (axis.position == "left" ? box.width : 0); } // draw tick bar if (!axis.innermost) { ctx.strokeStyle = axis.options.color; ctx.beginPath(); xoff = yoff = 0; if (axis.direction == "x") xoff = plotWidth + 1; else yoff = plotHeight + 1; if (ctx.lineWidth == 1) { if (axis.direction == "x") { y = Math.floor(y) + 0.5; } else { x = Math.floor(x) + 0.5; } } ctx.moveTo(x, y); ctx.lineTo(x + xoff, y + yoff); ctx.stroke(); } // draw ticks ctx.strokeStyle = axis.options.tickColor; ctx.beginPath(); for (i = 0; i < axis.ticks.length; ++i) { var v = axis.ticks[i].v; xoff = yoff = 0; if (isNaN(v) || v < axis.min || v > axis.max // skip those lying on the axes if we got a border || (t == "full" && ((typeof bw == "object" && bw[axis.position] > 0) || bw > 0) && (v == axis.min || v == axis.max))) continue; if (axis.direction == "x") { x = axis.p2c(v); yoff = t == "full" ? -plotHeight : t; if (axis.position == "top") yoff = -yoff; } else { y = axis.p2c(v); xoff = t == "full" ? -plotWidth : t; if (axis.position == "left") xoff = -xoff; } if (ctx.lineWidth == 1) { if (axis.direction == "x") x = Math.floor(x) + 0.5; else y = Math.floor(y) + 0.5; } ctx.moveTo(x, y); ctx.lineTo(x + xoff, y + yoff); } ctx.stroke(); } // draw border if (bw) { // If either borderWidth or borderColor is an object, then draw the border // line by line instead of as one rectangle bc = options.grid.borderColor; if(typeof bw == "object" || typeof bc == "object") { if (typeof bw !== "object") { bw = {top: bw, right: bw, bottom: bw, left: bw}; } if (typeof bc !== "object") { bc = {top: bc, right: bc, bottom: bc, left: bc}; } if (bw.top > 0) { ctx.strokeStyle = bc.top; ctx.lineWidth = bw.top; ctx.beginPath(); ctx.moveTo(0 - bw.left, 0 - bw.top/2); ctx.lineTo(plotWidth, 0 - bw.top/2); ctx.stroke(); } if (bw.right > 0) { ctx.strokeStyle = bc.right; ctx.lineWidth = bw.right; ctx.beginPath(); ctx.moveTo(plotWidth + bw.right / 2, 0 - bw.top); ctx.lineTo(plotWidth + bw.right / 2, plotHeight); ctx.stroke(); } if (bw.bottom > 0) { ctx.strokeStyle = bc.bottom; ctx.lineWidth = bw.bottom; ctx.beginPath(); ctx.moveTo(plotWidth + bw.right, plotHeight + bw.bottom / 2); ctx.lineTo(0, plotHeight + bw.bottom / 2); ctx.stroke(); } if (bw.left > 0) { ctx.strokeStyle = bc.left; ctx.lineWidth = bw.left; ctx.beginPath(); ctx.moveTo(0 - bw.left/2, plotHeight + bw.bottom); ctx.lineTo(0- bw.left/2, 0); ctx.stroke(); } } else { ctx.lineWidth = bw; ctx.strokeStyle = options.grid.borderColor; ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw); } } ctx.restore(); } function drawAxisLabels() { $.each(allAxes(), function (_, axis) { if (!axis.show || axis.ticks.length == 0) return; var box = axis.box, legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis", layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles, font = axis.options.font || "flot-tick-label tickLabel", tick, x, y, halign, valign; surface.removeText(layer); for (var i = 0; i < axis.ticks.length; ++i) { tick = axis.ticks[i]; if (!tick.label || tick.v < axis.min || tick.v > axis.max) continue; if (axis.direction == "x") { halign = "center"; x = plotOffset.left + axis.p2c(tick.v); if (axis.position == "bottom") { y = box.top + box.padding; } else { y = box.top + box.height - box.padding; valign = "bottom"; } } else { valign = "middle"; y = plotOffset.top + axis.p2c(tick.v); if (axis.position == "left") { x = box.left + box.width - box.padding; halign = "right"; } else { x = box.left + box.padding; } } surface.addText(layer, x, y, tick.label, font, null, null, halign, valign); } }); } function drawSeries(series) { if (series.lines.show) drawSeriesLines(series); if (series.bars.show) drawSeriesBars(series); if (series.points.show) drawSeriesPoints(series); } function drawSeriesLines(series) { function plotLine(datapoints, xoffset, yoffset, axisx, axisy) { var points = datapoints.points, ps = datapoints.pointsize, prevx = null, prevy = null; ctx.beginPath(); for (var i = ps; i < points.length; i += ps) { var x1 = points[i - ps], y1 = points[i - ps + 1], x2 = points[i], y2 = points[i + 1]; if (x1 == null || x2 == null) continue; // clip with ymin if (y1 <= y2 && y1 < axisy.min) { if (y2 < axisy.min) continue; // line segment is outside // compute new intersection point x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; y1 = axisy.min; } else if (y2 <= y1 && y2 < axisy.min) { if (y1 < axisy.min) continue; x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; y2 = axisy.min; } // clip with ymax if (y1 >= y2 && y1 > axisy.max) { if (y2 > axisy.max) continue; x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; y1 = axisy.max; } else if (y2 >= y1 && y2 > axisy.max) { if (y1 > axisy.max) continue; x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; y2 = axisy.max; } // clip with xmin if (x1 <= x2 && x1 < axisx.min) { if (x2 < axisx.min) continue; y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; x1 = axisx.min; } else if (x2 <= x1 && x2 < axisx.min) { if (x1 < axisx.min) continue; y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; x2 = axisx.min; } // clip with xmax if (x1 >= x2 && x1 > axisx.max) { if (x2 > axisx.max) continue; y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; x1 = axisx.max; } else if (x2 >= x1 && x2 > axisx.max) { if (x1 > axisx.max) continue; y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; x2 = axisx.max; } if (x1 != prevx || y1 != prevy) ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset); prevx = x2; prevy = y2; ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset); } ctx.stroke(); } function plotLineArea(datapoints, axisx, axisy) { var points = datapoints.points, ps = datapoints.pointsize, bottom = Math.min(Math.max(0, axisy.min), axisy.max), i = 0, top, areaOpen = false, ypos = 1, segmentStart = 0, segmentEnd = 0; // we process each segment in two turns, first forward // direction to sketch out top, then once we hit the // end we go backwards to sketch the bottom while (true) { if (ps > 0 && i > points.length + ps) break; i += ps; // ps is negative if going backwards var x1 = points[i - ps], y1 = points[i - ps + ypos], x2 = points[i], y2 = points[i + ypos]; if (areaOpen) { if (ps > 0 && x1 != null && x2 == null) { // at turning point segmentEnd = i; ps = -ps; ypos = 2; continue; } if (ps < 0 && i == segmentStart + ps) { // done with the reverse sweep ctx.fill(); areaOpen = false; ps = -ps; ypos = 1; i = segmentStart = segmentEnd + ps; continue; } } if (x1 == null || x2 == null) continue; // clip x values // clip with xmin if (x1 <= x2 && x1 < axisx.min) { if (x2 < axisx.min) continue; y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; x1 = axisx.min; } else if (x2 <= x1 && x2 < axisx.min) { if (x1 < axisx.min) continue; y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; x2 = axisx.min; } // clip with xmax if (x1 >= x2 && x1 > axisx.max) { if (x2 > axisx.max) continue; y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; x1 = axisx.max; } else if (x2 >= x1 && x2 > axisx.max) { if (x1 > axisx.max) continue; y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; x2 = axisx.max; } if (!areaOpen) { // open area ctx.beginPath(); ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom)); areaOpen = true; } // now first check the case where both is outside if (y1 >= axisy.max && y2 >= axisy.max) { ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max)); ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max)); continue; } else if (y1 <= axisy.min && y2 <= axisy.min) { ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min)); ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min)); continue; } // else it's a bit more complicated, there might // be a flat maxed out rectangle first, then a // triangular cutout or reverse; to find these // keep track of the current x values var x1old = x1, x2old = x2; // clip the y values, without shortcutting, we // go through all cases in turn // clip with ymin if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) { x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; y1 = axisy.min; } else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) { x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; y2 = axisy.min; } // clip with ymax if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) { x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; y1 = axisy.max; } else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) { x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; y2 = axisy.max; } // if the x value was changed we got a rectangle // to fill if (x1 != x1old) { ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1)); // it goes to (x1, y1), but we fill that below } // fill triangular section, this sometimes result // in redundant points if (x1, y1) hasn't changed // from previous line to, but we just ignore that ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1)); ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2)); // fill the other rectangle if it's there if (x2 != x2old) { ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2)); ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2)); } } } ctx.save(); ctx.translate(plotOffset.left, plotOffset.top); ctx.lineJoin = "round"; var lw = series.lines.lineWidth, sw = series.shadowSize; // FIXME: consider another form of shadow when filling is turned on if (lw > 0 && sw > 0) { // draw shadow as a thick and thin line with transparency ctx.lineWidth = sw; ctx.strokeStyle = "rgba(0,0,0,0.1)"; // position shadow at angle from the mid of line var angle = Math.PI/18; plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis); ctx.lineWidth = sw/2; plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis); } ctx.lineWidth = lw; ctx.strokeStyle = series.color; var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight); if (fillStyle) { ctx.fillStyle = fillStyle; plotLineArea(series.datapoints, series.xaxis, series.yaxis); } if (lw > 0) plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis); ctx.restore(); } function drawSeriesPoints(series) { function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) { var points = datapoints.points, ps = datapoints.pointsize; for (var i = 0; i < points.length; i += ps) { var x = points[i], y = points[i + 1]; if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) continue; ctx.beginPath(); x = axisx.p2c(x); y = axisy.p2c(y) + offset; if (symbol == "circle") ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false); else symbol(ctx, x, y, radius, shadow); ctx.closePath(); if (fillStyle) { ctx.fillStyle = fillStyle; ctx.fill(); } ctx.stroke(); } } ctx.save(); ctx.translate(plotOffset.left, plotOffset.top); var lw = series.points.lineWidth, sw = series.shadowSize, radius = series.points.radius, symbol = series.points.symbol; // If the user sets the line width to 0, we change it to a very // small value. A line width of 0 seems to force the default of 1. // Doing the conditional here allows the shadow setting to still be // optional even with a lineWidth of 0. if( lw == 0 ) lw = 0.0001; if (lw > 0 && sw > 0) { // draw shadow in two steps var w = sw / 2; ctx.lineWidth = w; ctx.strokeStyle = "rgba(0,0,0,0.1)"; plotPoints(series.datapoints, radius, null, w + w/2, true, series.xaxis, series.yaxis, symbol); ctx.strokeStyle = "rgba(0,0,0,0.2)"; plotPoints(series.datapoints, radius, null, w/2, true, series.xaxis, series.yaxis, symbol); } ctx.lineWidth = lw; ctx.strokeStyle = series.color; plotPoints(series.datapoints, radius, getFillStyle(series.points, series.color), 0, false, series.xaxis, series.yaxis, symbol); ctx.restore(); } function drawBar(x, y, b, barLeft, barRight, offset, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) { var left, right, bottom, top, drawLeft, drawRight, drawTop, drawBottom, tmp; // in horizontal mode, we start the bar from the left // instead of from the bottom so it appears to be // horizontal rather than vertical if (horizontal) { drawBottom = drawRight = drawTop = true; drawLeft = false; left = b; right = x; top = y + barLeft; bottom = y + barRight; // account for negative bars if (right < left) { tmp = right; right = left; left = tmp; drawLeft = true; drawRight = false; } } else { drawLeft = drawRight = drawTop = true; drawBottom = false; left = x + barLeft; right = x + barRight; bottom = b; top = y; // account for negative bars if (top < bottom) { tmp = top; top = bottom; bottom = tmp; drawBottom = true; drawTop = false; } } // clip if (right < axisx.min || left > axisx.max || top < axisy.min || bottom > axisy.max) return; if (left < axisx.min) { left = axisx.min; drawLeft = false; } if (right > axisx.max) { right = axisx.max; drawRight = false; } if (bottom < axisy.min) { bottom = axisy.min; drawBottom = false; } if (top > axisy.max) { top = axisy.max; drawTop = false; } left = axisx.p2c(left); bottom = axisy.p2c(bottom); right = axisx.p2c(right); top = axisy.p2c(top); // fill the bar if (fillStyleCallback) { c.beginPath(); c.moveTo(left, bottom); c.lineTo(left, top); c.lineTo(right, top); c.lineTo(right, bottom); c.fillStyle = fillStyleCallback(bottom, top); c.fill(); } // draw outline if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) { c.beginPath(); // FIXME: inline moveTo is buggy with excanvas c.moveTo(left, bottom + offset); if (drawLeft) c.lineTo(left, top + offset); else c.moveTo(left, top + offset); if (drawTop) c.lineTo(right, top + offset); else c.moveTo(right, top + offset); if (drawRight) c.lineTo(right, bottom + offset); else c.moveTo(right, bottom + offset); if (drawBottom) c.lineTo(left, bottom + offset); else c.moveTo(left, bottom + offset); c.stroke(); } } function drawSeriesBars(series) { function plotBars(datapoints, barLeft, barRight, offset, fillStyleCallback, axisx, axisy) { var points = datapoints.points, ps = datapoints.pointsize; for (var i = 0; i < points.length; i += ps) { if (points[i] == null) continue; drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, offset, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth); } } ctx.save(); ctx.translate(plotOffset.left, plotOffset.top); // FIXME: figure out a way to add shadows (for instance along the right edge) ctx.lineWidth = series.bars.lineWidth; ctx.strokeStyle = series.color; var barLeft; switch (series.bars.align) { case "left": barLeft = 0; break; case "right": barLeft = -series.bars.barWidth; break; case "center": barLeft = -series.bars.barWidth / 2; break; default: throw new Error("Invalid bar alignment: " + series.bars.align); } var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null; plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, 0, fillStyleCallback, series.xaxis, series.yaxis); ctx.restore(); } function getFillStyle(filloptions, seriesColor, bottom, top) { var fill = filloptions.fill; if (!fill) return null; if (filloptions.fillColor) return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor); var c = $.color.parse(seriesColor); c.a = typeof fill == "number" ? fill : 0.4; c.normalize(); return c.toString(); } function insertLegend() { placeholder.find(".legend").remove(); if (!options.legend.show) return; var fragments = [], entries = [], rowStarted = false, lf = options.legend.labelFormatter, s, label; // Build a list of legend entries, with each having a label and a color for (var i = 0; i < series.length; ++i) { s = series[i]; if (s.label) { label = lf ? lf(s.label, s) : s.label; if (label) { entries.push({ label: label, color: s.color }); } } } // Sort the legend using either the default or a custom comparator if (options.legend.sorted) { if ($.isFunction(options.legend.sorted)) { entries.sort(options.legend.sorted); } else if (options.legend.sorted == "reverse") { entries.reverse(); } else { var ascending = options.legend.sorted != "descending"; entries.sort(function(a, b) { return a.label == b.label ? 0 : ( (a.label < b.label) != ascending ? 1 : -1 // Logical XOR ); }); } } // Generate markup for the list of entries, in their final order for (var i = 0; i < entries.length; ++i) { var entry = entries[i]; if (i % options.legend.noColumns == 0) { if (rowStarted) fragments.push(''); fragments.push(''); rowStarted = true; } fragments.push( '
' + '' + entry.label + '' ); } if (rowStarted) fragments.push(''); if (fragments.length == 0) return; var table = '' + fragments.join("") + '
'; if (options.legend.container != null) $(options.legend.container).html(table); else { var pos = "", p = options.legend.position, m = options.legend.margin; if (m[0] == null) m = [m, m]; if (p.charAt(0) == "n") pos += 'top:' + (m[1] + plotOffset.top) + 'px;'; else if (p.charAt(0) == "s") pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;'; if (p.charAt(1) == "e") pos += 'right:' + (m[0] + plotOffset.right) + 'px;'; else if (p.charAt(1) == "w") pos += 'left:' + (m[0] + plotOffset.left) + 'px;'; var legend = $('
' + table.replace('style="', 'style="position:absolute;' + pos +';') + '
').appendTo(placeholder); if (options.legend.backgroundOpacity != 0.0) { // put in the transparent background // separately to avoid blended labels and // label boxes var c = options.legend.backgroundColor; if (c == null) { c = options.grid.backgroundColor; if (c && typeof c == "string") c = $.color.parse(c); else c = $.color.extract(legend, 'background-color'); c.a = 1; c = c.toString(); } var div = legend.children(); $('
').prependTo(legend).css('opacity', options.legend.backgroundOpacity); } } } // interactive features var highlights = [], redrawTimeout = null; // returns the data item the mouse is over, or null if none is found function findNearbyItem(mouseX, mouseY, seriesFilter) { var maxDistance = options.grid.mouseActiveRadius, smallestDistance = maxDistance * maxDistance + 1, item = null, foundPoint = false, i, j, ps; for (i = series.length - 1; i >= 0; --i) { if (!seriesFilter(series[i])) continue; var s = series[i], axisx = s.xaxis, axisy = s.yaxis, points = s.datapoints.points, mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster my = axisy.c2p(mouseY), maxx = maxDistance / axisx.scale, maxy = maxDistance / axisy.scale; ps = s.datapoints.pointsize; // with inverse transforms, we can't use the maxx/maxy // optimization, sadly if (axisx.options.inverseTransform) maxx = Number.MAX_VALUE; if (axisy.options.inverseTransform) maxy = Number.MAX_VALUE; if (s.lines.show || s.points.show) { for (j = 0; j < points.length; j += ps) { var x = points[j], y = points[j + 1]; if (x == null) continue; // For points and lines, the cursor must be within a // certain distance to the data point if (x - mx > maxx || x - mx < -maxx || y - my > maxy || y - my < -maxy) continue; // We have to calculate distances in pixels, not in // data units, because the scales of the axes may be different var dx = Math.abs(axisx.p2c(x) - mouseX), dy = Math.abs(axisy.p2c(y) - mouseY), dist = dx * dx + dy * dy; // we save the sqrt // use <= to ensure last point takes precedence // (last generally means on top of) if (dist < smallestDistance) { smallestDistance = dist; item = [i, j / ps]; } } } if (s.bars.show && !item) { // no other point can be nearby var barLeft = s.bars.align == "left" ? 0 : -s.bars.barWidth/2, barRight = barLeft + s.bars.barWidth; for (j = 0; j < points.length; j += ps) { var x = points[j], y = points[j + 1], b = points[j + 2]; if (x == null) continue; // for a bar graph, the cursor must be inside the bar if (series[i].bars.horizontal ? (mx <= Math.max(b, x) && mx >= Math.min(b, x) && my >= y + barLeft && my <= y + barRight) : (mx >= x + barLeft && mx <= x + barRight && my >= Math.min(b, y) && my <= Math.max(b, y))) item = [i, j / ps]; } } } if (item) { i = item[0]; j = item[1]; ps = series[i].datapoints.pointsize; return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps), dataIndex: j, series: series[i], seriesIndex: i }; } return null; } function onMouseMove(e) { if (options.grid.hoverable) triggerClickHoverEvent("plothover", e, function (s) { return s["hoverable"] != false; }); } function onMouseLeave(e) { if (options.grid.hoverable) triggerClickHoverEvent("plothover", e, function (s) { return false; }); } function onClick(e) { triggerClickHoverEvent("plotclick", e, function (s) { return s["clickable"] != false; }); } // trigger click or hover event (they send the same parameters // so we share their code) function triggerClickHoverEvent(eventname, event, seriesFilter) { var offset = eventHolder.offset(), canvasX = event.pageX - offset.left - plotOffset.left, canvasY = event.pageY - offset.top - plotOffset.top, pos = canvasToAxisCoords({ left: canvasX, top: canvasY }); pos.pageX = event.pageX; pos.pageY = event.pageY; var item = findNearbyItem(canvasX, canvasY, seriesFilter); if (item) { // fill in mouse pos for any listeners out there item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left, 10); item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top, 10); } if (options.grid.autoHighlight) { // clear auto-highlights for (var i = 0; i < highlights.length; ++i) { var h = highlights[i]; if (h.auto == eventname && !(item && h.series == item.series && h.point[0] == item.datapoint[0] && h.point[1] == item.datapoint[1])) unhighlight(h.series, h.point); } if (item) highlight(item.series, item.datapoint, eventname); } placeholder.trigger(eventname, [ pos, item ]); } function triggerRedrawOverlay() { var t = options.interaction.redrawOverlayInterval; if (t == -1) { // skip event queue drawOverlay(); return; } if (!redrawTimeout) redrawTimeout = setTimeout(drawOverlay, t); } function drawOverlay() { redrawTimeout = null; // draw highlights octx.save(); overlay.clear(); octx.translate(plotOffset.left, plotOffset.top); var i, hi; for (i = 0; i < highlights.length; ++i) { hi = highlights[i]; if (hi.series.bars.show) drawBarHighlight(hi.series, hi.point); else drawPointHighlight(hi.series, hi.point); } octx.restore(); executeHooks(hooks.drawOverlay, [octx]); } function highlight(s, point, auto) { if (typeof s == "number") s = series[s]; if (typeof point == "number") { var ps = s.datapoints.pointsize; point = s.datapoints.points.slice(ps * point, ps * (point + 1)); } var i = indexOfHighlight(s, point); if (i == -1) { highlights.push({ series: s, point: point, auto: auto }); triggerRedrawOverlay(); } else if (!auto) highlights[i].auto = false; } function unhighlight(s, point) { if (s == null && point == null) { highlights = []; triggerRedrawOverlay(); return; } if (typeof s == "number") s = series[s]; if (typeof point == "number") { var ps = s.datapoints.pointsize; point = s.datapoints.points.slice(ps * point, ps * (point + 1)); } var i = indexOfHighlight(s, point); if (i != -1) { highlights.splice(i, 1); triggerRedrawOverlay(); } } function indexOfHighlight(s, p) { for (var i = 0; i < highlights.length; ++i) { var h = highlights[i]; if (h.series == s && h.point[0] == p[0] && h.point[1] == p[1]) return i; } return -1; } function drawPointHighlight(series, point) { var x = point[0], y = point[1], axisx = series.xaxis, axisy = series.yaxis, highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(); if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) return; var pointRadius = series.points.radius + series.points.lineWidth / 2; octx.lineWidth = pointRadius; octx.strokeStyle = highlightColor; var radius = 1.5 * pointRadius; x = axisx.p2c(x); y = axisy.p2c(y); octx.beginPath(); if (series.points.symbol == "circle") octx.arc(x, y, radius, 0, 2 * Math.PI, false); else series.points.symbol(octx, x, y, radius, false); octx.closePath(); octx.stroke(); } function drawBarHighlight(series, point) { var highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(), fillStyle = highlightColor, barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2; octx.lineWidth = series.bars.lineWidth; octx.strokeStyle = highlightColor; drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth, 0, function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth); } function getColorOrGradient(spec, bottom, top, defaultColor) { if (typeof spec == "string") return spec; else { // assume this is a gradient spec; IE currently only // supports a simple vertical gradient properly, so that's // what we support too var gradient = ctx.createLinearGradient(0, top, 0, bottom); for (var i = 0, l = spec.colors.length; i < l; ++i) { var c = spec.colors[i]; if (typeof c != "string") { var co = $.color.parse(defaultColor); if (c.brightness != null) co = co.scale('rgb', c.brightness); if (c.opacity != null) co.a *= c.opacity; c = co.toString(); } gradient.addColorStop(i / (l - 1), c); } return gradient; } } } // Add the plot function to the top level of the jQuery object $.plot = function(placeholder, data, options) { //var t0 = new Date(); var plot = new Plot($(placeholder), data, options, $.plot.plugins); //(window.console ? console.log : alert)("time used (msecs): " + ((new Date()).getTime() - t0.getTime())); return plot; }; $.plot.version = "0.8.1"; $.plot.plugins = []; // Also add the plot function as a chainable property $.fn.plot = function(data, options) { return this.each(function() { $.plot(this, data, options); }); }; // round to nearby lower multiple of base function floorInBase(n, base) { return base * Math.floor(n / base); } })(jQuery); rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/0000755000177700017770000000000012633765070026031 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/channels-list.ejs0000644000177700017770000001516512633765070031310 0ustar michaelmichael<% if (channels.length > 0) { %> <% if (mode == 'standalone') { %> <%= group_heading('channels', 'Overview', [true, vhosts_interesting, nodes_interesting]) %> <% } else { %> <%= group_heading('channels', 'Overview', [true]) %> <% } %> <%= group_heading('channels', 'Details', []) %> <%= group_heading('channels', 'Transactions', []) %> <% if (rates_mode != 'none') { %> <%= group_heading('channels', 'Message rates', []) %> <% } %> <% if (mode == 'standalone') { %> <% if (nodes_interesting) { %> <% } %> <% if (vhosts_interesting) { %> <% } %> <% if (show_column('channels', 'user')) { %> <% } %> <% if (show_column('channels', 'mode')) { %> <% } %> <% if (show_column('channels', 'state')) { %> <% } %> <% if (show_column('channels', 'msgs-unconfirmed')) { %> <% } %> <% if (show_column('channels', 'prefetch')) { %> <% } %> <% if (show_column('channels', 'msgs-unacked')) { %> <% } %> <% if (show_column('channels', 'msgs-uncommitted')) { %> <% } %> <% if (show_column('channels', 'acks-uncommitted')) { %> <% } %> <% if (rates_mode != 'none') { %> <% if (show_column('channels', 'rate-publish')) { %> <% } %> <% if (show_column('channels', 'rate-confirm')) { %> <% } %> <% if (show_column('channels', 'rate-return')) { %> <% } %> <% if (show_column('channels', 'rate-deliver')) { %> <% } %> <% if (show_column('channels', 'rate-redeliver')) { %> <% } %> <% if (show_column('channels', 'rate-ack')) { %> <% } %> <% } %> <% } else { %> <% if (show_column('channels', 'user')) { %> <% } %> <% if (show_column('channels', 'mode')) { %> <% } %> <% if (show_column('channels', 'state')) { %> <% } %> <% if (show_column('channels', 'msgs-unconfirmed')) { %> <% } %> <% if (show_column('channels', 'prefetch')) { %> <% } %> <% if (show_column('channels', 'msgs-unacked')) { %> <% } %> <% if (show_column('channels', 'msgs-uncommitted')) { %> <% } %> <% if (show_column('channels', 'acks-uncommitted')) { %> <% } %> <% if (rates_mode != 'none') { %> <% if (show_column('channels', 'rate-publish')) { %> <% } %> <% if (show_column('channels', 'rate-confirm')) { %> <% } %> <% if (show_column('channels', 'rate-return')) { %> <% } %> <% if (show_column('channels', 'rate-deliver')) { %> <% } %> <% if (show_column('channels', 'rate-redeliver')) { %> <% } %> <% if (show_column('channels', 'rate-ack')) { %> <% } %> <% } %> <% } %> <% for (var i = 0; i < channels.length; i++) { var channel = channels[i]; %> > <% if (mode == 'standalone' && nodes_interesting) { %> <% } %> <% if (mode == 'standalone' && vhosts_interesting) { %> <% } %> <% if (show_column('channels', 'user')) { %> <% } %> <% if (show_column('channels', 'mode')) { %> <% } %> <% if (show_column('channels', 'state')) { %> <% } %> <% if (show_column('channels', 'msgs-unconfirmed')) { %> <% } %> <% if (show_column('channels', 'prefetch')) { %> <% } %> <% if (show_column('channels', 'msgs-unacked')) { %> <% } %> <% if (show_column('channels', 'msgs-uncommitted')) { %> <% } %> <% if (show_column('channels', 'acks-uncommitted')) { %> <% } %> <% if (rates_mode != 'none') { %> <% if (show_column('channels', 'rate-publish')) { %> <% } %> <% if (show_column('channels', 'rate-confirm')) { %> <% } %> <% if (show_column('channels', 'rate-return')) { %> <% } %> <% if (show_column('channels', 'rate-deliver')) { %> <% } %> <% if (show_column('channels', 'rate-redeliver')) { %> <% } %> <% if (show_column('channels', 'rate-ack')) { %> <% } %> <% } %> <% } %>
+/-
<%= fmt_sort('Channel', 'name') %><%= fmt_sort('Node', 'node') %><%= fmt_sort('Virtual host', 'vhost') %><%= fmt_sort('User name', 'user') %>Mode <%= fmt_sort('State', 'state') %><%= fmt_sort('Unconfirmed', 'messages_unconfirmed') %>Prefetch <%= fmt_sort('Unacked', 'messages_unacknowledged') %><%= fmt_sort('Uncommitted msgs', 'messages_uncommitted') %><%= fmt_sort('Uncommitted acks', 'acks_uncommitted') %><%= fmt_sort('publish', 'message_stats.publish_details.rate') %><%= fmt_sort('confirm', 'message_stats.confirm_details.rate') %><%= fmt_sort('return (mandatory)', 'message_stats.return_unroutable_details.rate') %><%= fmt_sort('deliver / get', 'message_stats.deliver_get_details.rate') %><%= fmt_sort('redelivered', 'message_stats.redeliver_details.rate') %><%= fmt_sort('ack', 'message_stats.ack_details.rate') %> ChannelUser nameMode StateUnconfirmedPrefetch UnackedUncommitted msgsUncommitted ackspublishconfirmreturn (mandatory)deliver / getredeliveredack
<%= link_channel(channel.name) %> <%= fmt_node(channel.node) %><%= fmt_string(channel.vhost) %><%= fmt_string(channel.user) %> <%= fmt_channel_mode(channel) %> <%= fmt_object_state(channel) %><%= channel.messages_unconfirmed %> <% if (channel.prefetch_count != 0) { %> <%= channel.prefetch_count %>
<% } %> <% if (channel.global_prefetch_count != 0) { %> <%= channel.global_prefetch_count %> (global) <% } %>
<%= channel.messages_unacknowledged %><%= channel.messages_uncommitted %><%= channel.acks_uncommitted %><%= fmt_detail_rate(channel.message_stats, 'publish') %><%= fmt_detail_rate(channel.message_stats, 'confirm') %><%= fmt_detail_rate(channel.message_stats, 'return_unroutable') %><%= fmt_detail_rate(channel.message_stats, 'deliver_get') %><%= fmt_detail_rate(channel.message_stats, 'redeliver') %><%= fmt_detail_rate(channel.message_stats, 'ack') %>
<% } else { %>

... no channels ...

<% } %> rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/policy.ejs0000644000177700017770000000206512633765070030036 0ustar michaelmichael

Policy: <%= fmt_string(policy.name) %><%= fmt_maybe_vhost(policy.vhost) %>

Overview

Pattern <%= fmt_string(policy.pattern) %>
Apply to <%= fmt_string(policy['apply-to']) %>
Definition <%= fmt_table_short(policy.definition) %>
Priority <%= fmt_string(policy.priority) %>

Delete this policy

rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/exchanges.ejs0000644000177700017770000001217412633765070030506 0ustar michaelmichael

Exchanges

All exchanges

<%= filter_ui(exchanges) %>
<% if (exchanges.length > 0) { %> <% if (vhosts_interesting) { %> <% } %> <% if (show_column('exchanges', 'type')) { %> <% } %> <% if (show_column('exchanges', 'features')) { %> <% } %> <% if (show_column('exchanges', 'features_no_policy')) { %> <% } %> <% if (show_column('exchanges', 'policy')) { %> <% } %> <% if (rates_mode != 'none') { %> <% if (show_column('exchanges', 'rate-in')) { %> <% } %> <% if (show_column('exchanges', 'rate-out')) { %> <% } %> <% } %> <% for (var i = 0; i < exchanges.length; i++) { var exchange = exchanges[i]; %> > <% if (vhosts_interesting) { %> <% } %> <% if (show_column('exchanges', 'features')) { %> <% } %> <% if (show_column('exchanges', 'features_no_policy')) { %> <% } %> <% if (show_column('exchanges', 'policy')) { %> <% } %> <% if (rates_mode != 'none') { %> <% if (show_column('exchanges', 'rate-in')) { %> <% } %> <% if (show_column('exchanges', 'rate-out')) { %> <% } %> <% } %> <% } %>
<%= fmt_sort('Virtual host', 'vhost') %><%= fmt_sort('Name', 'name') %><%= fmt_sort('Type', 'type') %>FeaturesFeatures<%= fmt_sort('Policy','policy') %><%= fmt_sort('Message rate in', 'message_stats.publish_in_details.rate') %><%= fmt_sort('Message rate out', 'message_stats.publish_out_details.rate') %>+/-
<%= fmt_string(exchange.vhost) %><%= link_exchange(exchange.vhost, exchange.name, exchange.arguments) %> <%= fmt_exchange_type(exchange.type) %> <%= fmt_features_short(exchange) %> <%= fmt_policy_short(exchange) %> <%= fmt_features_short(exchange) %> <%= fmt_string(exchange.policy) %> <%= fmt_detail_rate(exchange.message_stats, 'publish_in') %><%= fmt_detail_rate(exchange.message_stats, 'publish_out') %>
<% } else { %>

... no exchanges ...

<% } %>

Add a new exchange

<% if (vhosts_interesting) { %> <% } else { %> <% } %>
*
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/consumers.ejs0000644000177700017770000000224112633765070030551 0ustar michaelmichael<% if (consumers.length > 0) { %> <% if (mode == 'queue') { %> <% } else { %> <% } %> <% for (var i = 0; i < consumers.length; i++) { var consumer = consumers[i]; %> > <% if (mode == 'queue') { %> <% } else { %> <% } %> <% } %>
Channel Consumer tagConsumer tag QueueAck required Exclusive Prefetch count Arguments
<%= link_channel(consumer.channel_details.name) %> <%= fmt_string(consumer.consumer_tag) %><%= fmt_string(consumer.consumer_tag) %> <%= link_queue(consumer.queue.vhost, consumer.queue.name) %><%= fmt_boolean(consumer.ack_required) %> <%= fmt_boolean(consumer.exclusive) %> <%= consumer.prefetch_count %> <%= fmt_table_short(consumer.arguments) %>
<% } else { %>

... no consumers ...

<% } %> rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/error-popup.ejs0000644000177700017770000000013712633765070031027 0ustar michaelmichael
<%= text %>

Close
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/queue.ejs0000644000177700017770000002326712633765070027672 0ustar michaelmichael

Queue <%= fmt_string(queue.name) %><%= fmt_maybe_vhost(queue.vhost) %>

Overview

<%= queue_lengths('lengths-q', queue) %> <% if (rates_mode != 'none') { %> <%= message_rates('msg-rates-q', queue.message_stats) %> <% } %>

Details

<% if (queue.owner_pid_details != undefined) { %> <% } %> <% if (nodes_interesting) { %> <% if (queue.owner_pid_details == undefined) { %> <% } %> <% } %>
Features <%= fmt_features(queue) %>
Policy <%= fmt_string(queue.policy, '') %>
Exclusive owner <%= link_conn(queue.owner_pid_details.name) %>
Node <%= fmt_node(queue.node) %>
Slaves <% var has_unsynced_node = false; for (var i in queue.slave_nodes) { var node = queue.slave_nodes[i]; %> <% if (jQuery.inArray(node, queue.synchronised_slave_nodes) == -1) { has_unsynced_node = true; %> <%= fmt_node(node) %> (unsynchronised) <% } else { %> <%= fmt_node(node) %> <% } %>
<% } %> <% if (queue.state == 'syncing') { %>
<%= fmt_sync_state(queue) %>
<% } else if (has_unsynced_node) { %>
<% } %>
State <%= fmt_object_state(queue) %>
Consumers <%= fmt_string(queue.consumers) %>
Consumer utilisation <%= fmt_percent(queue.consumer_utilisation) %>
Total Ready Unacked In memory Persistent
Messages <%= fmt_num_thousands(queue.messages) %> <%= fmt_num_thousands(queue.messages_ready) %> <%= fmt_num_thousands(queue.messages_unacknowledged) %> <%= fmt_num_thousands(queue.messages_ram) %> <%= fmt_num_thousands(queue.messages_persistent) %>
Message body bytes <%= fmt_bytes(queue.message_bytes) %> <%= fmt_bytes(queue.message_bytes_ready) %> <%= fmt_bytes(queue.message_bytes_unacknowledged) %> <%= fmt_bytes(queue.message_bytes_ram) %> <%= fmt_bytes(queue.message_bytes_persistent) %>
Process memory <%= fmt_bytes(queue.memory) %>
<% if (rates_mode == 'detailed') { %>

Message rates breakdown

<%= format('msg-detail-publishes', {'mode': 'queue', 'object': queue.incoming, 'label': 'Incoming'}) %> <%= format('msg-detail-deliveries', {'mode': 'queue', 'object': queue.deliveries}) %>
<% } %>

Consumers

<%= format('consumers', {'mode': 'queue', 'consumers': queue.consumer_details}) %>

Bindings

<%= format('bindings', {'mode': 'queue', 'bindings': bindings}) %>

This queue

<%= format('add-binding', {'mode': 'queue', 'parent': queue}) %>
<%= format('publish', {'mode': 'queue', 'queue': queue}) %>

Get messages

Warning: getting messages from a queue is a destructive action.

<% if (user_policymaker) { %>

Move messages

<% if (NAVIGATION['Admin'][0]['Shovel Management'] == undefined) { %>

To move messages, the shovel plugin must be enabled, try:

$ rabbitmq-plugins enable rabbitmq_shovel rabbitmq_shovel_management
<% } else { %>

The shovel plugin can be used to move messages from this queue to another one. The form below will create a temporary shovel to move messages to another queue on the same virtual host, with default settings.

For more options see the shovel interface.

Destination queue:
<% } %>
<% } %>

Delete / purge

rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/channels.ejs0000644000177700017770000000023312633765070030325 0ustar michaelmichael

Channels

<%= filter_ui(channels) %>
<%= format('channels-list', {'channels': channels, 'mode': 'standalone'}) %>
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/registry.ejs0000644000177700017770000000107112633765070030403 0ustar michaelmichael<% if (node.running) { %> <% if (show_enabled) { %> <% } %> <% for (var i = 0; i < list.length; i++) { var item = list[i]; %> > <% if (show_enabled) { %> <% } %> <% } %>
Name DescriptionEnabled
<%= fmt_string(item.name) %> <%= fmt_string(item.description) %><%= fmt_boolean(item.enabled) %>
<% } else {%>

...node not running...

<% } %> rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/permissions.ejs0000644000177700017770000000562112633765070031113 0ustar michaelmichael

Permissions

Current permissions

<% if (permissions.length > 0) { %> <% if (mode == 'vhost') { %> <% } else { %> <% } %> <% for (var i = 0; i < permissions.length; i++) { var permission = permissions[i]; %> > <% if (mode == 'vhost') { %> <% } else { %> <% } %> <% } %>
UserVirtual hostConfigure regexp Write regexp Read regexp
<%= link_user(permission.user) %><%= link_vhost(permission.vhost) %><%= fmt_string(permission.configure) %> <%= fmt_string(permission.write) %> <%= fmt_string(permission.read) %>
<% } else { %>

... no permissions ...

<% } %>

Set permission

<% if (mode == 'vhost') { %> <% } else { %> <% } %>
User
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/partition.ejs0000644000177700017770000000512512633765070030550 0ustar michaelmichael
<% var partitions = []; for (var i = 0; i < nodes.length; i++) { var node = nodes[i]; if (node.partitions != undefined && node.partitions.length != 0) { partitions.push({'node': node.name, 'others': node.partitions}); } } if (partitions.length > 0) { %>

Network partition detected

Mnesia reports that this RabbitMQ cluster has experienced a network partition. There is a risk of losing data. Please read RabbitMQ documentation about network partitions and the possible solutions.

The nature of the partition is as follows:

<% for (var i = 0; i < partitions.length; i++) { var partition = partitions[i]; %> > <% } %>
NodeWas partitioned from
<%= partition.node %> <% for (var j = 0; j < partition.others.length; j++) { var other = partition.others[j]; %> <%= other %>
<% } %>

While running in this partitioned state, changes (such as queue or exchange declaration and binding) which take place in one partition will not be visible to other partition(s). Other behaviour is not guaranteed.

More information on network partitions.

<% } %> <% var ticktime = null; var ticktimes_unequal = false; for (var i = 0; i < nodes.length; i++) { var node_ticktime = nodes[i].net_ticktime; if (node_ticktime != undefined) { if (ticktime != null && node_ticktime != ticktime) { ticktimes_unequal = true; } ticktime = nodes[i].net_ticktime; } } if (ticktimes_unequal) { %>

The kernel net_ticktime values are set differently for different nodes in this cluster.

The values are:

<% for (var i = 0; i < nodes.length; i++) { %> > <% } %>
Nodenet_ticktime
<%= nodes[i].name %> <%= nodes[i].net_ticktime %>

This is a dangerous configuration; use of substantially unequal net_timetime values can lead to partitions being falsely detected.

More information on net_ticktime.

<% } %>
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/layout.ejs0000644000177700017770000000211112633765070030044 0ustar michaelmichael
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/connections.ejs0000644000177700017770000001137212633765070031062 0ustar michaelmichael

Connections

<%= filter_ui(connections) %>
<% if (connections.length > 0) { %> <%= group_heading('connections', 'Overview', [vhosts_interesting, nodes_interesting, true]) %> <%= group_heading('connections', 'Details', []) %> <%= group_heading('connections', 'Network', []) %> <% if (vhosts_interesting) { %> <% } %> <% if (nodes_interesting) { %> <% } %> <% if (show_column('connections', 'user')) { %> <% } %> <% if (show_column('connections', 'state')) { %> <% } %> <% if (show_column('connections', 'ssl')) { %> <% } %> <% if (show_column('connections', 'ssl_info')) { %> <% } %> <% if (show_column('connections', 'protocol')) { %> <% } %> <% if (show_column('connections', 'channels')) { %> <% } %> <% if (show_column('connections', 'channel_max')) { %> <% } %> <% if (show_column('connections', 'frame_max')) { %> <% } %> <% if (show_column('connections', 'auth_mechanism')) { %> <% } %> <% if (show_column('connections', 'client')) { %> <% } %> <% if (show_column('connections', 'from_client')) { %> <% } %> <% if (show_column('connections', 'to_client')) { %> <% } %> <% if (show_column('connections', 'heartbeat')) { %> <% } %> <% if (show_column('connections', 'connected_at')) { %> <% } %> <% for (var i = 0; i < connections.length; i++) { var connection = connections[i]; %> > <% if (vhosts_interesting) { %> <% } %> <% if (nodes_interesting) { %> <% } %> <% if (show_column('connections', 'user')) { %> <% } %> <% if (show_column('connections', 'state')) { %> <% } %> <% if (show_column('connections', 'ssl')) { %> <% } %> <% if (show_column('connections', 'ssl_info')) { %> <% } %> <% if (show_column('connections', 'protocol')) { %> <% } %> <% if (show_column('connections', 'channels')) { %> <% } %> <% if (show_column('connections', 'channel_max')) { %> <% } %> <% if (show_column('connections', 'frame_max')) { %> <% } %> <% if (show_column('connections', 'auth_mechanism')) { %> <% } %> <% if (show_column('connections', 'client')) { %> <% } %> <% if (show_column('connections', 'from_client')) { %> <% } %> <% if (show_column('connections', 'to_client')) { %> <% } %> <% if (show_column('connections', 'heartbeat')) { %> <% } %> <% if (show_column('connections', 'connected_at')) { %> <% } %> <% } %>
+/-
<%= fmt_sort('Virtual host', 'vhost') %><%= fmt_sort('Name', 'name') %><%= fmt_sort('Node', 'node') %><%= fmt_sort('User name', 'user') %><%= fmt_sort('State', 'state') %><%= fmt_sort('SSL / TLS', 'ssl') %>SSL Details<%= fmt_sort('Protocol', 'protocol') %><%= fmt_sort('Channels', 'channels') %><%= fmt_sort('Channel max', 'channel_max') %><%= fmt_sort('Frame max', 'frame_max') %><%= fmt_sort('Auth mechanism', 'auth_mechanism') %><%= fmt_sort('Client', 'properties') %><%= fmt_sort('From client', 'recv_oct_details.rate') %><%= fmt_sort('To client', 'send_oct_details.rate') %><%= fmt_sort('Heartbeat', 'timeout') %><%= fmt_sort('Connected at', 'connected_at') %>
<%= fmt_string(connection.vhost) %><%= link_conn(connection.name) %><%= fmt_node(connection.node) %><%= fmt_string(connection.user) %><%= fmt_object_state(connection) %><%= fmt_boolean(connection.ssl, '') %> <% if (connection.ssl) { %> <%= connection.ssl_protocol %> <%= connection.ssl_key_exchange %> <%= connection.ssl_cipher %> <%= connection.ssl_hash %> <% } %> <%= connection.protocol %><%= fmt_string(connection.channels, '') %><%= fmt_string(connection.channel_max, '') %><%= fmt_string(connection.frame_max, '') %><%= fmt_string(connection.auth_mechanism, '') %><%= fmt_client_name(connection.client_properties) %><%= fmt_detail_rate_bytes(connection, 'recv_oct') %><%= fmt_detail_rate_bytes(connection, 'send_oct') %><%= fmt_time(connection.timeout, 's') %><%= fmt_timestamp_mini(connection.connected_at) %>
<% } else { %>

... no connections ...

<% } %>
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/add-binding.ejs0000644000177700017770000000351212633765070030675 0ustar michaelmichael<% if (mode == 'queue') { %>

Add binding to this queue

<% } else { %>

Add binding from this exchange

<% } %>
<% if (mode == 'queue') { %> <% } else { %> <% } %> <% if (mode == 'queue') { %> <% } else { %> <% } %>
*
: *
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/paths.ejs0000644000177700017770000000120512633765070027651 0ustar michaelmichael
<% if (node.config_files.length == 1) { %> Config file <% } else { %> Config files <% } %> <% for (var i = 0; i < node.config_files.length; i++) { var config = node.config_files[i]; %> <%= config %> <% } %>
Database directory <%= node.db_dir %>
Log file <%= node.log_file %>
SASL log file <%= node.sasl_log_file %>
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/queues.ejs0000644000177700017770000002365312633765070030054 0ustar michaelmichael

Queues

All queues

<%= filter_ui(queues) %>
<% if (queues.length > 0) { %> <%= group_heading('queues', 'Overview', [vhosts_interesting, nodes_interesting, true]) %> <%= group_heading('queues', 'Messages', []) %> <%= group_heading('queues', 'Message bytes', []) %> <% if (rates_mode != 'none') { %> <%= group_heading('queues', 'Message rates', []) %> <% } %> <% if (vhosts_interesting) { %> <% } %> <% if (nodes_interesting) { %> <% } %> <% if (show_column('queues', 'features')) { %> <% } %> <% if (show_column('queues', 'features_no_policy')) { %> <% } %> <% if (show_column('queues', 'policy')) { %> <% } %> <% if (show_column('queues', 'consumers')) { %> <% } %> <% if (show_column('queues', 'consumer_utilisation')) { %> <% } %> <% if (show_column('queues', 'state')) { %> <% } %> <% if (show_column('queues', 'msgs-ready')) { %> <% } %> <% if (show_column('queues', 'msgs-unacked')) { %> <% } %> <% if (show_column('queues', 'msgs-ram')) { %> <% } %> <% if (show_column('queues', 'msgs-persistent')) { %> <% } %> <% if (show_column('queues', 'msgs-total')) { %> <% } %> <% if (show_column('queues', 'msg-bytes-ready')) { %> <% } %> <% if (show_column('queues', 'msg-bytes-unacked')) { %> <% } %> <% if (show_column('queues', 'msg-bytes-ram')) { %> <% } %> <% if (show_column('queues', 'msg-bytes-persistent')) { %> <% } %> <% if (show_column('queues', 'msg-bytes-total')) { %> <% } %> <% if (rates_mode != 'none') { %> <% if (show_column('queues', 'rate-incoming')) { %> <% } %> <% if (show_column('queues', 'rate-deliver')) { %> <% } %> <% if (show_column('queues', 'rate-redeliver')) { %> <% } %> <% if (show_column('queues', 'rate-ack')) { %> <% } %> <% } %> <% for (var i = 0; i < queues.length; i++) { var queue = queues[i]; %> > <% if (vhosts_interesting) { %> <% } %> <% if (nodes_interesting) { %> <% } %> <% if (show_column('queues', 'features')) { %> <% } %> <% if (show_column('queues', 'features_no_policy')) { %> <% } %> <% if (show_column('queues', 'policy')) { %> <% } %> <% if (show_column('queues', 'consumers')) { %> <% } %> <% if (show_column('queues', 'consumer_utilisation')) { %> <% } %> <% if (show_column('queues', 'state')) { %> <% } %> <% if (show_column('queues', 'msgs-ready')) { %> <% } %> <% if (show_column('queues', 'msgs-unacked')) { %> <% } %> <% if (show_column('queues', 'msgs-ram')) { %> <% } %> <% if (show_column('queues', 'msgs-persistent')) { %> <% } %> <% if (show_column('queues', 'msgs-total')) { %> <% } %> <% if (show_column('queues', 'msg-bytes-ready')) { %> <% } %> <% if (show_column('queues', 'msg-bytes-unacked')) { %> <% } %> <% if (show_column('queues', 'msg-bytes-ram')) { %> <% } %> <% if (show_column('queues', 'msg-bytes-persistent')) { %> <% } %> <% if (show_column('queues', 'msg-bytes-total')) { %> <% } %> <% if (rates_mode != 'none') { %> <% if (show_column('queues', 'rate-incoming')) { %> <% } %> <% if (show_column('queues', 'rate-deliver')) { %> <% } %> <% if (show_column('queues', 'rate-redeliver')) { %> <% } %> <% if (show_column('queues', 'rate-ack')) { %> <% } %> <% } %> <% } %>
+/-
<%= fmt_sort('Virtual host', 'vhost') %><%= fmt_sort('Name', 'name') %><%= fmt_sort('Node', 'node') %>FeaturesFeatures<%= fmt_sort('Policy','policy') %><%= fmt_sort('Consumers', 'consumers') %><%= fmt_sort('Consumer utilisation', 'consumer_utilisation') %><%= fmt_sort('State', 'state') %><%= fmt_sort('Ready', 'messages_ready') %><%= fmt_sort('Unacked', 'messages_unacknowledged') %><%= fmt_sort('In Memory', 'messages_ram') %><%= fmt_sort('Persistent', 'messages_persistent') %><%= fmt_sort('Total', 'messages') %><%= fmt_sort('Ready', 'message_bytes_ready') %><%= fmt_sort('Unacked', 'message_bytes_unacknowledged') %><%= fmt_sort('In Memory', 'message_bytes_ram') %><%= fmt_sort('Persistent', 'message_bytes_persistent') %><%= fmt_sort('Total', 'message_bytes') %><%= fmt_sort('incoming', 'message_stats.publish_details.rate') %><%= fmt_sort('deliver / get', 'message_stats.deliver_get_details.rate') %><%= fmt_sort('redelivered', 'message_stats.redeliver_details.rate') %><%= fmt_sort('ack', 'message_stats.ack_details.rate') %>
<%= fmt_string(queue.vhost) %><%= link_queue(queue.vhost, queue.name, queue.arguments) %> <%= fmt_node(queue.node) %> <%= fmt_mirrors(queue) %> <% if (queue.state == 'syncing') { %> <%= fmt_sync_state(queue) %> <% } %> <%= fmt_features_short(queue) %> <%= fmt_policy_short(queue) %> <%= fmt_features_short(queue) %><%= fmt_string(queue.policy) %><%= fmt_string(queue.consumers) %><%= fmt_percent(queue.consumer_utilisation) %><%= fmt_object_state(queue) %><%= fmt_num_thousands(queue.messages_ready) %><%= fmt_num_thousands(queue.messages_unacknowledged) %><%= fmt_num_thousands(queue.messages_ram) %><%= fmt_num_thousands(queue.messages_persistent) %><%= fmt_num_thousands(queue.messages) %><%= fmt_bytes(queue.message_bytes_ready) %><%= fmt_bytes(queue.message_bytes_unacknowledged) %><%= fmt_bytes(queue.message_bytes_ram) %><%= fmt_bytes(queue.message_bytes_persistent) %><%= fmt_bytes(queue.message_bytes) %><%= fmt_detail_rate(queue.message_stats, 'publish') %><%= fmt_detail_rate(queue.message_stats, 'deliver_get') %><%= fmt_detail_rate(queue.message_stats, 'redeliver') %><%= fmt_detail_rate(queue.message_stats, 'ack') %>
<% } else { %>

... no queues ...

<% } %>

Add a new queue

<% if (vhosts_interesting) { %> <% } else { %> <% } %> <% if (nodes_interesting) { var nodes = JSON.parse(sync_get('/nodes')); %> <% } %>
*
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/exchange.ejs0000644000177700017770000000536312633765070030325 0ustar michaelmichael

Exchange: <%= fmt_exchange(exchange.name) %><%= fmt_maybe_vhost(exchange.vhost) %>

Overview

<% if (rates_mode != 'none') { %> <%= message_rates('msg-rates-x', exchange.message_stats) %> <% } %>

Details

Type <%= fmt_exchange_type(exchange.type) %>
Features <%= fmt_features(exchange) %>
Policy <%= fmt_string(exchange.policy, '') %>
<% if (rates_mode == 'detailed') { %>

Message rates breakdown

<%= format('msg-detail-publishes', {'mode': 'exchange-incoming', 'object': exchange.incoming, 'label': 'Incoming '}) %> <%= format('msg-detail-publishes', {'mode': 'exchange-outgoing', 'object': exchange.outgoing, 'label': 'Outgoing '}) %>
<% } %>

Bindings

<% if (exchange.name == "") { %>

Default exchange

The default exchange is implicitly bound to every queue, with a routing key equal to the queue name. It it not possible to explicitly bind to, or unbind from the default exchange. It also cannot be deleted.

<% } else { %>
<% if (bindings_destination.length > 0) { %> <%= format('bindings', {'mode': 'exchange_destination', 'bindings': bindings_destination}) %>

<% } %>

This exchange

<%= format('bindings', {'mode': 'exchange_source', 'bindings': bindings_source}) %>
<%= format('add-binding', {'mode': 'exchange_source', 'parent': exchange}) %> <% } %>
<% if (!exchange.internal) { %> <%= format('publish', {'mode': 'exchange', 'exchange': exchange}) %> <% } %> <% if (exchange.name != "") { %>

Delete this exchange

<% } %> rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/node.ejs0000644000177700017770000002054512633765070027467 0ustar michaelmichael

Node <%= node.name %>

<% if (!node.running) { %>

Node not running

<% } else if (node.os_pid == undefined) { %>

Node statistics not available

<% } else { %>

Overview

<% if (rabbit_versions_interesting) { %> <% } %>
Uptime <%= fmt_uptime(node.uptime) %>
RabbitMQ Version <%= fmt_rabbit_version(node.applications) %>
Type <% if (node.type == 'disc') { %> Disc <% } else { %> RAM <% } %>
<%= format('paths', {node: node}) %>

Plugins

<% var plugins = get_plugins_list(node); for (var j = 0; j < plugins.length; j++) { var application = plugins[j]; %> > <% } %>
Name Version Description
<%= application.name %> <%= application.version %> <%= application.description %>

Process statistics

<%= node_stats_prefs() %>
File descriptors <% if (node.fd_used != 'install_handle_from_sysinternals') { %> <%= node_stat_count('fd_used', 'fd_total', node, FD_THRESHOLDS) %> <% } else { %>

handle.exe missing <%= node.fd_total %> available

<% } %>
Socket descriptors <%= node_stat_count('sockets_used', 'sockets_total', node, FD_THRESHOLDS) %>
Erlang processes <%= node_stat_count('proc_used', 'proc_total', node, PROCESS_THRESHOLDS) %>
Memory <% if (node.mem_limit != 'memory_monitoring_disabled') { %> <%= node_stat('mem_used', 'Used', 'mem_limit', 'high watermark', node, fmt_bytes, fmt_bytes_axis, node.mem_alarm ? 'red' : 'green', node.mem_alarm ? 'memory-alarm' : null) %> <% } else { %> <%= fmt_bytes(node.mem_used) %> <% } %>
Disk space <% if (node.disk_free_limit != 'disk_free_monitoring_disabled') { %> <%= node_stat('disk_free', 'Free', 'disk_free_limit', 'low watermark', node, fmt_bytes, fmt_bytes_axis, node.disk_free_alarm ? 'red' : 'green', node.disk_free_alarm ? 'disk_free-alarm' : null, true) %> <% } else { %> (not available) <% } %>

Persistence statistics

<%= rates_chart_or_text('mnesia-stats-count', node, [['RAM only', 'mnesia_ram_tx_count'], ['Disk', 'mnesia_disk_tx_count']], fmt_rate, fmt_rate_axis, true, 'Mnesia transactions', 'mnesia-transactions') %> <%= rates_chart_or_text('persister-msg-stats-count', node, [['QI Journal', 'queue_index_journal_write_count'], ['Store Read', 'msg_store_read_count'], ['Store Write', 'msg_store_write_count']], fmt_rate, fmt_rate_axis, true, 'Persistence operations (messages)', 'persister-operations-msg') %> <%= rates_chart_or_text('persister-bulk-stats-count', node, [['QI Read', 'queue_index_read_count'], ['QI Write', 'queue_index_write_count']], fmt_rate, fmt_rate_axis, true, 'Persistence operations (bulk)', 'persister-operations-bulk') %>

I/O statistics

<%= rates_chart_or_text('persister-io-stats-count', node, [['Read', 'io_read_count'], ['Write', 'io_write_count'], ['Seek', 'io_seek_count'], ['Sync', 'io_sync_count'], ['Reopen', 'io_reopen_count']], fmt_rate, fmt_rate_axis, true, 'I/O operations', 'io-operations') %> <%= rates_chart_or_text('persister-io-stats-bytes', node, [['Read', 'io_read_bytes'], ['Write', 'io_write_bytes']], fmt_rate_bytes, fmt_rate_bytes_axis, true, 'I/O data rates') %> <%= rates_chart_or_text('persister-io-stats-time', node, [['Read', 'io_read_avg_time'], ['Write', 'io_write_avg_time'], ['Seek', 'io_seek_avg_time'], ['Sync', 'io_sync_avg_time']], fmt_ms, fmt_ms, false, 'I/O average time per operation') %>

Cluster links

<% if (node.cluster_links.length > 0) { %> <% for (var i = 0; i < node.cluster_links.length; i++) { var link = node.cluster_links[i]; %> > <% } %>
Remote node Local address Local port Remote address Remote port <%= chart_h3('cluster-link-data-rates', 'Data rates') %>
<%= link_node(link.name) %> <%= fmt_string(link.sock_addr) %> <%= fmt_string(link.sock_port) %> <%= fmt_string(link.peer_addr) %> <%= fmt_string(link.peer_port) %> <%= rates_chart_or_text_no_heading( 'cluster-link-data-rates', 'cluster-link-data-rates' + link.name, link.stats, [['Recv', 'recv_bytes'], ['Send', 'send_bytes']], fmt_rate_bytes, fmt_rate_bytes_axis, true) %>
<% } else { %>

... no cluster links ...

<% } %>
<% } %>
<% if (node.running && node.os_pid != undefined) { %>

Memory details

Binary references

Warning: Calculating binary memory use can be expensive if there are many small binaries in the system.

<% } %>
<% if (node.running && node.os_pid != undefined) { %>

Advanced

VM

OS pid <%= node.os_pid %>
Rates mode <%= node.rates_mode %>
Net ticktime <%= node.net_ticktime %>s
Run queue <%= node.run_queue %>
Processors <%= node.processors %>

All applications

<% for (var j = 0; j < node.applications.length; j++) { var application = node.applications[j]; %> > <% } %>
Name Version Description
<%= application.name %> <%= application.version %> <%= application.description %>

Exchange types

<%= format('registry', {'list': node.exchange_types, 'node': node, 'show_enabled': false} ) %>

Authentication mechanisms

<%= format('registry', {'list': node.auth_mechanisms, 'node': node, 'show_enabled': true} ) %>
<% } %>
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/memory.ejs0000644000177700017770000000551112633765070030046 0ustar michaelmichael<% if (memory == "not_available") { %>

Memory statistics not available.

<% } else { %> <% var sections = {'queue_procs' : ['queue', 'Queues'], 'queue_slave_procs' : ['queue', 'Queues (slaves)'], 'binary' : ['binary', 'Binaries'], 'connection_readers' : ['conn', 'Connection readers'], 'connection_writers' : ['conn', 'Connection writers'], 'connection_channels' : ['conn', 'Connection channels'], 'connection_other' : ['conn', 'Connections (other)'], 'mnesia' : ['table', 'Mnesia'], 'msg_index' : ['table', 'Message store index'], 'mgmt_db' : ['table', 'Management database'], 'other_ets' : ['table', 'Other ETS tables'], 'plugins' : ['proc', 'Plugins'], 'other_proc' : ['proc', 'Other process memory'], 'code' : ['system', 'Code'], 'atom' : ['system', 'Atoms'], 'other_system' : ['system', 'Other system']}; %> <%= format('memory-bar', {sections: sections, memory: memory, total_out: []}) %>  
<% var key = [[{name: 'Queues', colour: 'queue', keys: [['queue_procs', 'queues'], ['queue_slave_procs', 'slaves']]}, {name: 'Binaries', colour: 'binary', keys: [['binary', '']]}], [{name: 'Connections', colour: 'conn', keys: [['connection_readers', 'readers'], ['connection_writers', 'writers'], ['connection_channels', 'channels'], ['connection_other', 'other']]}], [{name: 'Tables', colour: 'table', keys: [['mnesia', 'mnesia'], ['msg_index', 'message store index'], ['mgmt_db', 'management database'], ['other_ets', 'other']]}], [{name: 'Processes', colour: 'proc', keys: [['plugins', 'plugins'], ['other_proc', 'other']]}, {name: 'System', colour: 'system', keys: [['code', 'code'], ['atom', 'atoms'], ['other_system', 'other']]}]]; %> <%= format('memory-table', {key: key, memory: memory}) %>
Last updated: <%= fmt_date(new Date()) %>.
Total memory used at last update: <%= fmt_bytes(memory.total) %>
<% } %> rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/user.ejs0000644000177700017770000000522512633765070027516 0ustar michaelmichael

User: <%= fmt_string(user.name) %>

<% if (permissions.length == 0) { %>

This user does not have permission to access any virtual hosts.
Use "Set Permission" below to grant permission to access virtual hosts.

<% } %>

Overview

Tags <%= fmt_string(user.tags) %>
Can log in with password <%= fmt_boolean(user.password_hash.length > 0) %>
<%= format('permissions', {'mode': 'user', 'permissions': permissions, 'vhosts': vhosts, 'parent': user}) %>

Update this user

*
* (confirm)
[Admin] [Monitoring] [Policymaker] [Management] [None]

Delete this user

rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/msg-detail-publishes.ejs0000644000177700017770000000234512633765070032562 0ustar michaelmichael

<%= label %>

<% if (object && object.length > 0) { %> <% var col_confirm = mode != 'exchange-outgoing'; %> <% if (mode == 'channel') { %> <% } else if (mode == 'exchange-incoming') { %> <% } else if (mode == 'exchange-outgoing') { %> <% } else { %> <% } %> <% if (col_confirm) { %> <% } %> <% for (var i = 0; i < object.length; i++) { var pub = object[i]; %> > <% if (mode == 'channel') { %> <% } else if (mode == 'exchange-incoming') { %> <% } else if (mode == 'exchange-outgoing') { %> <% } else { %> <% } %> <% if (col_confirm) { %> <% } %> <% } %>
ExchangeChannelQueueExchangepublishconfirm
<%= link_exchange(pub.exchange.vhost, pub.exchange.name) %><%= link_channel(pub.channel_details.name) %><%= link_queue(pub.queue.vhost, pub.queue.name) %><%= link_exchange(pub.exchange.vhost, pub.exchange.name) %><%= fmt_detail_rate(pub.stats, 'publish') %><%= fmt_detail_rate(pub.stats, 'confirm') %>
<% } else { %>

... no publishes ...

<% } %> rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/msg-detail-deliveries.ejs0000644000177700017770000000134512633765070032716 0ustar michaelmichael

Deliveries

<% if (object && object.length > 0) { %> <% if (mode == 'queue') { %> <% } else { %> <% } %> <% for (var i = 0; i < object.length; i++) { var del = object[i]; %> > <% if (mode == 'queue') { %> <% } else { %> <% } %> <% } %>
ChannelQueuedeliver / get ack
<%= link_channel(del.channel_details.name) %><%= link_queue(del.queue.vhost, del.queue.name) %><%= fmt_detail_rate(del.stats, 'deliver_get') %> <%= fmt_detail_rate(del.stats, 'ack') %>
<% } else { %>

... no deliveries ...

<% } %> rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/login.ejs0000644000177700017770000000105512633765070027645 0ustar michaelmichael

*
*

rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/messages.ejs0000644000177700017770000000153412633765070030346 0ustar michaelmichael<% for (var i = 0; i < msgs.length; i++) { var msg = msgs[i]; %>

Message <%= i+1 %>

The server reported <%= msg.message_count %> messages remaining.

Exchange <%= fmt_exchange(msg.exchange) %>
Routing Key <%= fmt_string(msg.routing_key) %>
Redelivered <%= fmt_boolean(msg.redelivered) %>
Properties <%= fmt_table_short(msg.properties) %>
Payload <%= msg.payload_bytes %> bytes Encoding: <%= msg.payload_encoding %>
<%= fmt_maybe_wrap(msg.payload, msg.payload_encoding) %>
<% } %> rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/channel.ejs0000644000177700017770000000425612633765070030153 0ustar michaelmichael

Channel: <%= fmt_escape_html(channel.name) %><%= fmt_maybe_vhost(channel.vhost) %>

Overview

<% if (rates_mode != 'none') { %> <%= message_rates('msg-rates-ch', channel.message_stats) %> <% } %>

Details

<% if (nodes_interesting) { %> <% } %>
Connection <%= link_conn(channel.connection_details.name) %>
Node <%= fmt_node(channel.node) %>
Username <%= fmt_string(channel.user) %>
Mode <%= fmt_channel_mode(channel) %>
State <%= fmt_object_state(channel) %>
Prefetch count <%= channel.prefetch_count %>
Global prefetch count <%= channel.global_prefetch_count %>
Messages unacknowledged <%= channel.messages_unacknowledged %>
Messages unconfirmed <%= channel.messages_unconfirmed %>
Messages uncommitted <%= channel.messages_uncommitted %>
Acks uncommitted <%= channel.acks_uncommitted %>

Consumers

<%= format('consumers', {'mode': 'channel', 'consumers': channel.consumer_details}) %>
<% if (rates_mode == 'detailed') { %>

Message rates breakdown

<%= format('msg-detail-publishes', {'mode': 'channel', 'object': channel.publishes, 'label': 'Publishes'}) %> <%= format('msg-detail-deliveries', {'mode': 'channel', 'object': channel.deliveries}) %>
<% } %> rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/cluster-name.ejs0000644000177700017770000000177412633765070031144 0ustar michaelmichael

Cluster name: <%= fmt_string(cluster_name.name) %>

The cluster name can be used by clients to identify clusters over AMQP connections, and is used by the shovel and federation plugins to identify which clusters a message has been routed through.

Note that the cluster name is announced to clients in the AMQP server properties; i.e. before authentication has taken place. Therefore it should not be considered secret.

The cluster name is generated by default from the name of the first node in the cluster, but can be changed.

Change name

*
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/publish.ejs0000644000177700017770000000413212633765070030202 0ustar michaelmichael

Publish message

<% if (mode == 'queue') { %> <% } else { %> <% } %> <% if (mode == 'queue') { %> <% } else { %> <% } %>
Message will be published to the default exchange with routing key <%= fmt_string(queue.name) %>, routing it to this queue.
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/rate-options.ejs0000644000177700017770000000242312633765070031161 0ustar michaelmichael<% var id = span.attr('for'); var mode = get_pref('rate-mode-' + id); var size = get_pref('chart-size-' + id); var range = get_pref('chart-range'); %>

This time series

<%= fmt_radio('mode', 'Chart', 'chart', mode) %> <%= fmt_radio('mode', 'Current value', 'curr', mode) %> <% if (id != 'node-stats') { %> <%= fmt_radio('mode', 'Moving average', 'avg', mode) %> <% } %>
<%= fmt_radio('size', 'Small', 'small', size) %> <%= fmt_radio('size', 'Medium', 'medium', size) %> <%= fmt_radio('size', 'Large', 'large', size) %>

All time series

<% for (p in CHART_PERIODS) { %> <%= fmt_radio('range', CHART_PERIODS[p], p, range) %> <% } %>
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/vhosts.ejs0000644000177700017770000000677112633765070030075 0ustar michaelmichael

Virtual Hosts

All virtual hosts

<%= filter_ui(vhosts) %>
<% if (vhosts.length > 0) { %> <%= group_heading('vhosts', 'Messages', []) %> <%= group_heading('vhosts', 'Network', []) %> <% if (rates_mode != 'none') { %> <%= group_heading('vhosts', 'Message rates', []) %> <% } %> <% if (show_column('vhosts', 'msgs-ready')) { %> <% } %> <% if (show_column('vhosts', 'msgs-unacked')) { %> <% } %> <% if (show_column('vhosts', 'msgs-total')) { %> <% } %> <% if (show_column('vhosts', 'from_client')) { %> <% } %> <% if (show_column('vhosts', 'to_client')) { %> <% } %> <% if (rates_mode != 'none') { %> <% if (show_column('vhosts', 'rate-publish')) { %> <% } %> <% if (show_column('vhosts', 'rate-deliver')) { %> <% } %> <% } %> <% for (var i = 0; i < vhosts.length; i++) { var vhost = vhosts[i]; %> > <% if (show_column('vhosts', 'msgs-ready')) { %> <% } %> <% if (show_column('vhosts', 'msgs-unacked')) { %> <% } %> <% if (show_column('vhosts', 'msgs-total')) { %> <% } %> <% if (show_column('vhosts', 'from_client')) { %> <% } %> <% if (show_column('vhosts', 'to_client')) { %> <% } %> <% if (rates_mode != 'none') { %> <% if (show_column('vhosts', 'rate-publish')) { %> <% } %> <% if (show_column('vhosts', 'rate-deliver')) { %> <% } %> <% } %> <% } %>
Overview+/-
<%= fmt_sort('Name', 'name') %> Users <%= fmt_sort('Ready', 'messages_ready') %><%= fmt_sort('Unacked', 'messages_unacknowledged') %><%= fmt_sort('Total', 'messages') %><%= fmt_sort('From client', 'recv_oct_details.rate') %><%= fmt_sort('To client', 'send_oct_details.rate') %><%= fmt_sort('publish', 'message_stats.publish_details.rate') %><%= fmt_sort('deliver / get','message_stats.deliver_get_details.rate') %>
<%= link_vhost(vhost.name) %> <%= fmt_permissions(vhost, permissions, 'vhost', 'user', '

No users

') %>
<%= fmt_num_thousands(vhost.messages_ready) %><%= fmt_num_thousands(vhost.messages_unacknowledged) %><%= fmt_num_thousands(vhost.messages) %><%= fmt_detail_rate_bytes(vhost, 'recv_oct') %><%= fmt_detail_rate_bytes(vhost, 'send_oct') %><%= fmt_detail_rate(vhost.message_stats, 'publish') %><%= fmt_detail_rate(vhost.message_stats, 'deliver_get') %>
<% } else { %>

... no vhosts ...

<% } %>

Add a new virtual host

*
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/status.ejs0000644000177700017770000000007412633765070030060 0ustar michaelmichael

<%= text %>

rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/connection.ejs0000644000177700017770000000603212633765070030674 0ustar michaelmichael

Connection <%= fmt_string(connection.name) %><%= fmt_maybe_vhost(connection.vhost) %>

Overview

<%= data_rates('data-rates-conn', connection, 'Data rates') %>

Details

<% if (nodes_interesting) { %> <% } %> <% if (connection.ssl) { %> <% } %> <% if (connection.auth_mechanism) { %> <% } %>
Node <%= fmt_node(connection.node) %>
Username <%= fmt_string(connection.user) %>
Protocol <%= connection.protocol %>
Connected at <%= fmt_timestamp(connection.connected_at) %>
SSL <%= fmt_boolean(connection.ssl) %>
Authentication <%= connection.auth_mechanism %>
<% if (connection.state) { %>
State <%= fmt_object_state(connection) %>
Heartbeat <%= fmt_time(connection.timeout, 's') %>
Frame max <%= connection.frame_max %> bytes
Channel limit <%= connection.channel_max %> channels
<% } %>

Channels

<%= format('channels-list', {'channels': channels, 'mode': 'connection'}) %>
<% if (connection.ssl) { %>

SSL

Protocol Version <%= connection.ssl_protocol %>
Key Exchange Algorithm <%= connection.ssl_key_exchange %>
Cipher Algorithm <%= connection.ssl_cipher %>
Hash Algorithm <%= connection.ssl_hash %>
<% if (connection.peer_cert_issuer != '') { %>
Peer Certificate Issuer <%= connection.peer_cert_issuer %>
Peer Certificate Subject <%= connection.peer_cert_subject %>
Peer Certificate Validity <%= connection.peer_cert_validity %>
<% } %>
<% } %> <% if (properties_size(connection.client_properties) > 0) { %>

Client properties

<%= fmt_table_long(connection.client_properties) %>
<% } %>

Close this connection

rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/memory-bar.ejs0000644000177700017770000000104212633765070030603 0ustar michaelmichael
<% var width = 800; var pseudo_total = 0 for (var section in sections) { pseudo_total += memory[section]; } total_out[0] = pseudo_total; for (var section in sections) { if (memory[section] > 0) { var section_width = Math.round(width * memory[section] / pseudo_total); %>
<% } } %>
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/policies.ejs0000644000177700017770000001162612633765070030351 0ustar michaelmichael

Policies

All policies

<%= filter_ui(policies) %>
<% if (policies.length > 0) { %> <% if (vhosts_interesting) { %> <% } %> <% for (var i = 0; i < policies.length; i++) { var policy = policies[i]; %> > <% if (vhosts_interesting) { %> <% } %> <% } %>
Virtual HostName Pattern Apply to Definition Priority
<%= fmt_string(policy.vhost) %><%= link_policy(policy.vhost, policy.name) %> <%= fmt_string(policy.pattern) %> <%= fmt_string(policy['apply-to']) %> <%= fmt_table_short(policy.definition) %> <%= fmt_string(policy.priority) %>
<% } else { %>

... no policies ...

<% } %>

Add / update a policy

<% if (vhosts_interesting) { %> <% } else { %> <% } %>
*
*
*
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/import-succeeded.ejs0000644000177700017770000000012212633765070031763 0ustar michaelmichael

Import succeeded

Your definitions were imported successfully.

rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/vhost.ejs0000644000177700017770000000217312633765070027702 0ustar michaelmichael

Virtual Host: <%= fmt_string(vhost.name) %>

<% if (permissions.length == 0) { %>

No users have permission to access this virtual host.
Use "Set Permission" below to grant users permission to access this virtual host.

<% } %>

Overview

<%= queue_lengths('lengths-vhost', vhost) %> <% if (rates_mode != 'none') { %> <%= message_rates('msg-rates-vhost', vhost.message_stats) %> <% } %> <%= data_rates('data-rates-vhost', vhost, 'Data rates') %>

Details

Tracing enabled: <%= fmt_boolean(vhost.tracing) %>
<%= format('permissions', {'mode': 'vhost', 'permissions': permissions, 'users': users, 'parent': vhost}) %>

Delete this vhost

rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/404.ejs0000644000177700017770000000015412633765070027043 0ustar michaelmichael

Not found

The object you clicked on was not found; it may have been deleted on the server.

rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/overview.ejs0000644000177700017770000002354312633765070030411 0ustar michaelmichael

Overview

<% if (user_monitor) { %> <%= format('partition', {'nodes': nodes}) %> <% } %>
<% if (overview.statistics_db_event_queue > 1000) { %>

The management statistics database currently has a queue of <%= overview.statistics_db_event_queue %> events to process. If this number keeps increasing, so will the memory used by the management plugin. <% if (overview.rates_mode != 'none') { %> You may find it useful to set the rates_mode config item to none. <% } %>

<% } %>

Totals

<% if (overview.statistics_db_node != 'not_running') { %> <%= queue_lengths('lengths-over', overview.queue_totals) %> <% if (rates_mode != 'none') { %> <%= message_rates('msg-rates-over', overview.message_stats) %> <% } %> <% } else { %> Totals not available <% } %> <% if (overview.object_totals) { %>

Global counts

<% } %>
<% if (user_monitor) { %>
<% if (nodes.length == 1) { %>

Node

<% } else { %>

Nodes

<% } %>
<% if (nodes.length == 1) { %>

Node: <%= nodes[0].name %> (More about this node)

<% } %> <% if (nodes.length > 1) { %> <% } %> <% if (show_column('overview', 'file_descriptors')) { %> <% } %> <% if (show_column('overview', 'socket_descriptors')) { %> <% } %> <% if (show_column('overview', 'erlang_processes')) { %> <% } %> <% if (show_column('overview', 'memory')) { %> <% } %> <% if (show_column('overview', 'disk_space')) { %> <% } %> <% if (show_column('overview', 'uptime')) { %> <% } %> <% if (show_column('overview', 'rates_mode')) { %> <% } %> <% if (show_column('overview', 'info')) { %> <% } %> <% for (var i = 0; i < nodes.length; i++) { var node = nodes[i]; var colspan = group_count('overview', 'Statistics', []) + group_count('overview', 'General', []); %> > <% if (nodes.length > 1) { %> <% } %> <% if (!node.running) { %> <% } else if (node.os_pid == undefined) { %> <% } else { %> <% if (show_column('overview', 'file_descriptors')) { %> <% } %> <% if (show_column('overview', 'socket_descriptors')) { %> <% } %> <% if (show_column('overview', 'erlang_processes')) { %> <% } %> <% if (show_column('overview', 'memory')) { %> <% } %> <% if (show_column('overview', 'disk_space')) { %> <% } %> <% if (show_column('overview', 'uptime')) { %> <% } %> <% if (show_column('overview', 'rates_mode')) { %> <% } %> <% if (show_column('overview', 'info')) { %> <% } %> <% } %> <% } %>
NameFile descriptors Socket descriptors Erlang processesMemoryDisk spaceUptimeRates modeInfo+/-
<%= link_node(node.name) %> <% if (rabbit_versions_interesting) { %> RabbitMQ <%= fmt_rabbit_version(node.applications) %> <% } %>
Node not running
Node statistics not available
<% if (node.fd_used != 'install_handle_from_sysinternals') { %> <%= node_stat_count_bar('fd_used', 'fd_total', node, FD_THRESHOLDS) %> <% } else { %>

handle.exe missing <%= node.fd_total %> available

<% } %>
<%= node_stat_count_bar('sockets_used', 'sockets_total', node, FD_THRESHOLDS) %> <%= node_stat_count_bar('proc_used', 'proc_total', node, PROCESS_THRESHOLDS) %> <% if (node.mem_limit != 'memory_monitoring_disabled') { %> <%= node_stat_bar('mem_used', 'mem_limit', 'high watermark', node, fmt_bytes_axis, node.mem_alarm ? 'red' : 'green', node.mem_alarm ? 'memory-alarm' : null) %> <% } else { %> <%= fmt_bytes(node.mem_used) %> <% } %> <% if (node.disk_free_limit != 'disk_free_monitoring_disabled') { %> <%= node_stat_bar('disk_free', 'disk_free_limit', 'low watermark', node, fmt_bytes_axis, node.disk_free_alarm ? 'red' : 'green', node.disk_free_alarm ? 'disk_free-alarm' : null, true) %> <% } else { %> (not available) <% } %> <%= fmt_uptime(node.uptime) %><%= fmt_string(node.rates_mode) %> <% if (node.type == 'disc') { %> Disc <% } else { %> RAM <% } %> <%= fmt_plugins_small(node) %> <% if (overview.statistics_db_node == node.name) { %> Stats <% } %>
<% if (overview.statistics_db_node == 'not_running') { %>

Statistics database could not be contacted. Message rates and queue lengths will not be shown.

<% } %> <% if (nodes.length == 1 && nodes[0].os_pid != undefined) { %>

Paths

<%= format('paths', {node: nodes[0]}) %> <% } %>

Ports and contexts

Listening ports

<% if (nodes_interesting) { %> <% } %> <% for (var i = 0; i < overview.listeners.length; i++) { var listener = overview.listeners[i]; %> > <% if (nodes_interesting) { %> <% } %> <% } %>
ProtocolNodeBound to Port
<%= listener.protocol %><%= fmt_node(listener.node) %><%= listener.ip_address %> <%= listener.port %>

Web contexts

<% if (nodes_interesting) { %> <% } %> <% for (var i = 0; i < overview.contexts.length; i++) { var context = overview.contexts[i]; %> > <% if (nodes_interesting) { %> <% } %> <% } %>
ContextNodeBound to Port SSL Path
<%= context.description %><%= fmt_node(context.node) %><%= (context.ip != undefined) ? context.ip : "0.0.0.0" %> <%= context.port %> <%= fmt_boolean(context.ssl || false) %> <%= context.path %>

Import / export definitions

Export


Import


<% if (overview.rates_mode == 'none') { %>

Message rates disabled

Message rates are currently disabled.

To re-enable message rates, edit your configuration file and set rates_mode to basic or detailed in the rabbitmq_management application

<% } %> <% } %> rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/columns-options.ejs0000644000177700017770000000126012633765070031704 0ustar michaelmichael<% var mode = span.attr('for'); %>
<% for (var group in COLUMNS[mode]) { var options = COLUMNS[mode][group]; %> <% } %>

Columns for this table

<% for (var i = 0; i < options.length; i++) { %> <%= fmt_checkbox(mode + '-' + options[i][0], options[i][1], get_pref('column-' + mode + '-' + options[i][0]) == 'true') %> <% } %>
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/binary.ejs0000644000177700017770000000416112633765070030022 0ustar michaelmichael<% if (binary == "not_available") { %>

Binary statistics not available.

<% } else { %> <% var sections = {'queue_procs' : ['queue', 'Queues'], 'queue_slave_procs' : ['queue', 'Queues (slaves)'], 'connection_readers' : ['conn', 'Connection readers'], 'connection_writers' : ['conn', 'Connection writers'], 'connection_channels' : ['conn', 'Connection channels'], 'connection_other' : ['conn', 'Connections (other)'], 'msg_index' : ['table', 'Message store index'], 'mgmt_db' : ['table', 'Management database'], 'plugins' : ['proc', 'Plugins'], 'other' : ['system', 'Other binary references']}; var total_out = []; %> <%= format('memory-bar', {sections: sections, memory: binary, total_out: total_out}) %>  
<% var key = [[{name: 'Queues', colour: 'queue', keys: [['queue_procs', 'queues'], ['queue_slave_procs', 'slaves']]}], [{name: 'Connections', colour: 'conn', keys: [['connection_readers', 'readers'], ['connection_writers', 'writers'], ['connection_channels', 'channels'], ['connection_other', 'other']]}], [{name: 'Tables', colour: 'table', keys: [['msg_index', 'message store index'], ['mgmt_db', 'management database']]}], [{name: 'Processes', colour: 'proc', keys: [['plugins', 'plugins']]}, {name: 'System', colour: 'system', keys: [['other', 'other']]}]]; %> <%= format('memory-table', {key: key, memory: binary}) %>
Last updated: <%= fmt_date(new Date()) %>.
Total referenced binaries at last update: <%= fmt_bytes(total_out[0]) %>
<% } %> rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/users.ejs0000644000177700017770000000564412633765070027706 0ustar michaelmichael

Users

All users

<%= filter_ui(users) %>
<% if (users.length > 0) { %> <% for (var i = 0; i < users.length; i++) { var user = users[i]; %> > <% } %>
<%= fmt_sort('Name', 'name') %> <%= fmt_sort('Tags', 'tags') %> Can access virtual hosts Has password
<%= link_user(user.name) %> <%= fmt_string(user.tags) %> <%= fmt_permissions(user, permissions, 'user', 'vhost', '

No access

') %>
<%= fmt_boolean(user.password_hash.length > 0) %>
<% } else { %>

... no vhosts ...

<% } %>

Add a user

*
*
* (confirm)
rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/memory-table.ejs0000644000177700017770000000102112633765070031123 0ustar michaelmichael<% for (var i in key) { %> <% for (var j in key[i]) { var group = key[i][j]; %> <% } %>
<%= group.name %>
<% for (var k in group.keys) { var name = group.keys[k][0]; var label = group.keys[k][1]; %> <% } %>
<%= fmt_bytes(memory[name]) %> <%= label %>
<% } %> rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/tmpl/bindings.ejs0000644000177700017770000000443012633765070030332 0ustar michaelmichael<%= maybe_truncate(bindings) %> <% if (bindings.length > 0) { %> <% if (mode == 'exchange_source') { %> <% } else { %> <% } %> <% for (var i = 0; i < bindings.length; i++) { var binding = bindings[i]; %> > <% if (binding.source == '') { %> <% } else { %> <% if (mode == 'queue' || mode == 'exchange_destination') { %> <% } else if (binding.destination_type == 'exchange') { %> <% } else { %> <% } %> <% } %> <% } %>
ToFromRouting key Arguments
(Default exchange binding) <%= link_exchange(binding.vhost, binding.source) %> <%= link_exchange(binding.vhost, binding.destination) %> <%= link_queue(binding.vhost, binding.destination) %> <%= fmt_string(binding.routing_key) %> <%= fmt_table_short(binding.arguments) %>
<% } else { %>

... no bindings ...

<% } %> rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/jquery.flot.time.js0000644000177700017770000002672112633765070030642 0ustar michaelmichael/* Pretty handling of time axes. Copyright (c) 2007-2013 IOLA and Ole Laursen. Licensed under the MIT license. Set axis.mode to "time" to enable. See the section "Time series data" in API.txt for details. */ (function($) { var options = { xaxis: { timezone: null, // "browser" for local to the client or timezone for timezone-js timeformat: null, // format string to use twelveHourClock: false, // 12 or 24 time in time mode monthNames: null // list of names of months } }; // round to nearby lower multiple of base function floorInBase(n, base) { return base * Math.floor(n / base); } // Returns a string with the date d formatted according to fmt. // A subset of the Open Group's strftime format is supported. function formatDate(d, fmt, monthNames, dayNames) { if (typeof d.strftime == "function") { return d.strftime(fmt); } var leftPad = function(n, pad) { n = "" + n; pad = "" + (pad == null ? "0" : pad); return n.length == 1 ? pad + n : n; }; var r = []; var escape = false; var hours = d.getHours(); var isAM = hours < 12; if (monthNames == null) { monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; } if (dayNames == null) { dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; } var hours12; if (hours > 12) { hours12 = hours - 12; } else if (hours == 0) { hours12 = 12; } else { hours12 = hours; } for (var i = 0; i < fmt.length; ++i) { var c = fmt.charAt(i); if (escape) { switch (c) { case 'a': c = "" + dayNames[d.getDay()]; break; case 'b': c = "" + monthNames[d.getMonth()]; break; case 'd': c = leftPad(d.getDate()); break; case 'e': c = leftPad(d.getDate(), " "); break; case 'h': // For back-compat with 0.7; remove in 1.0 case 'H': c = leftPad(hours); break; case 'I': c = leftPad(hours12); break; case 'l': c = leftPad(hours12, " "); break; case 'm': c = leftPad(d.getMonth() + 1); break; case 'M': c = leftPad(d.getMinutes()); break; // quarters not in Open Group's strftime specification case 'q': c = "" + (Math.floor(d.getMonth() / 3) + 1); break; case 'S': c = leftPad(d.getSeconds()); break; case 'y': c = leftPad(d.getFullYear() % 100); break; case 'Y': c = "" + d.getFullYear(); break; case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break; case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break; case 'w': c = "" + d.getDay(); break; } r.push(c); escape = false; } else { if (c == "%") { escape = true; } else { r.push(c); } } } return r.join(""); } // To have a consistent view of time-based data independent of which time // zone the client happens to be in we need a date-like object independent // of time zones. This is done through a wrapper that only calls the UTC // versions of the accessor methods. function makeUtcWrapper(d) { function addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) { sourceObj[sourceMethod] = function() { return targetObj[targetMethod].apply(targetObj, arguments); }; }; var utc = { date: d }; // support strftime, if found if (d.strftime != undefined) { addProxyMethod(utc, "strftime", d, "strftime"); } addProxyMethod(utc, "getTime", d, "getTime"); addProxyMethod(utc, "setTime", d, "setTime"); var props = ["Date", "Day", "FullYear", "Hours", "Milliseconds", "Minutes", "Month", "Seconds"]; for (var p = 0; p < props.length; p++) { addProxyMethod(utc, "get" + props[p], d, "getUTC" + props[p]); addProxyMethod(utc, "set" + props[p], d, "setUTC" + props[p]); } return utc; }; // select time zone strategy. This returns a date-like object tied to the // desired timezone function dateGenerator(ts, opts) { if (opts.timezone == "browser") { return new Date(ts); } else if (!opts.timezone || opts.timezone == "utc") { return makeUtcWrapper(new Date(ts)); } else if (typeof timezoneJS != "undefined" && typeof timezoneJS.Date != "undefined") { var d = new timezoneJS.Date(); // timezone-js is fickle, so be sure to set the time zone before // setting the time. d.setTimezone(opts.timezone); d.setTime(ts); return d; } else { return makeUtcWrapper(new Date(ts)); } } // map of app. size of time units in milliseconds var timeUnitSize = { "second": 1000, "minute": 60 * 1000, "hour": 60 * 60 * 1000, "day": 24 * 60 * 60 * 1000, "month": 30 * 24 * 60 * 60 * 1000, "quarter": 3 * 30 * 24 * 60 * 60 * 1000, "year": 365.2425 * 24 * 60 * 60 * 1000 }; // the allowed tick sizes, after 1 year we use // an integer algorithm var baseSpec = [ [1, "second"], [2, "second"], [5, "second"], [10, "second"], [30, "second"], [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"], [30, "minute"], [1, "hour"], [2, "hour"], [4, "hour"], [8, "hour"], [12, "hour"], [1, "day"], [2, "day"], [3, "day"], [0.25, "month"], [0.5, "month"], [1, "month"], [2, "month"] ]; // we don't know which variant(s) we'll need yet, but generating both is // cheap var specMonths = baseSpec.concat([[3, "month"], [6, "month"], [1, "year"]]); var specQuarters = baseSpec.concat([[1, "quarter"], [2, "quarter"], [1, "year"]]); function init(plot) { plot.hooks.processOptions.push(function (plot, options) { $.each(plot.getAxes(), function(axisName, axis) { var opts = axis.options; if (opts.mode == "time") { axis.tickGenerator = function(axis) { var ticks = []; var d = dateGenerator(axis.min, opts); var minSize = 0; // make quarter use a possibility if quarters are // mentioned in either of these options var spec = (opts.tickSize && opts.tickSize[1] === "quarter") || (opts.minTickSize && opts.minTickSize[1] === "quarter") ? specQuarters : specMonths; if (opts.minTickSize != null) { if (typeof opts.tickSize == "number") { minSize = opts.tickSize; } else { minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]]; } } for (var i = 0; i < spec.length - 1; ++i) { if (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]] + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2 && spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) { break; } } var size = spec[i][0]; var unit = spec[i][1]; // special-case the possibility of several years if (unit == "year") { // if given a minTickSize in years, just use it, // ensuring that it's an integer if (opts.minTickSize != null && opts.minTickSize[1] == "year") { size = Math.floor(opts.minTickSize[0]); } else { var magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10)); var norm = (axis.delta / timeUnitSize.year) / magn; if (norm < 1.5) { size = 1; } else if (norm < 3) { size = 2; } else if (norm < 7.5) { size = 5; } else { size = 10; } size *= magn; } // minimum size for years is 1 if (size < 1) { size = 1; } } axis.tickSize = opts.tickSize || [size, unit]; var tickSize = axis.tickSize[0]; unit = axis.tickSize[1]; var step = tickSize * timeUnitSize[unit]; if (unit == "second") { d.setSeconds(floorInBase(d.getSeconds(), tickSize)); } else if (unit == "minute") { d.setMinutes(floorInBase(d.getMinutes(), tickSize)); } else if (unit == "hour") { d.setHours(floorInBase(d.getHours(), tickSize)); } else if (unit == "month") { d.setMonth(floorInBase(d.getMonth(), tickSize)); } else if (unit == "quarter") { d.setMonth(3 * floorInBase(d.getMonth() / 3, tickSize)); } else if (unit == "year") { d.setFullYear(floorInBase(d.getFullYear(), tickSize)); } // reset smaller components d.setMilliseconds(0); if (step >= timeUnitSize.minute) { d.setSeconds(0); } if (step >= timeUnitSize.hour) { d.setMinutes(0); } if (step >= timeUnitSize.day) { d.setHours(0); } if (step >= timeUnitSize.day * 4) { d.setDate(1); } if (step >= timeUnitSize.month * 2) { d.setMonth(floorInBase(d.getMonth(), 3)); } if (step >= timeUnitSize.quarter * 2) { d.setMonth(floorInBase(d.getMonth(), 6)); } if (step >= timeUnitSize.year) { d.setMonth(0); } var carry = 0; var v = Number.NaN; var prev; do { prev = v; v = d.getTime(); ticks.push(v); if (unit == "month" || unit == "quarter") { if (tickSize < 1) { // a bit complicated - we'll divide the // month/quarter up but we need to take // care of fractions so we don't end up in // the middle of a day d.setDate(1); var start = d.getTime(); d.setMonth(d.getMonth() + (unit == "quarter" ? 3 : 1)); var end = d.getTime(); d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize); carry = d.getHours(); d.setHours(0); } else { d.setMonth(d.getMonth() + tickSize * (unit == "quarter" ? 3 : 1)); } } else if (unit == "year") { d.setFullYear(d.getFullYear() + tickSize); } else { d.setTime(v + step); } } while (v < axis.max && v != prev); return ticks; }; axis.tickFormatter = function (v, axis) { var d = dateGenerator(v, axis.options); // first check global format if (opts.timeformat != null) { return formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames); } // possibly use quarters if quarters are mentioned in // any of these places var useQuarters = (axis.options.tickSize && axis.options.tickSize[1] == "quarter") || (axis.options.minTickSize && axis.options.minTickSize[1] == "quarter"); var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]]; var span = axis.max - axis.min; var suffix = (opts.twelveHourClock) ? " %p" : ""; var hourCode = (opts.twelveHourClock) ? "%I" : "%H"; var fmt; if (t < timeUnitSize.minute) { fmt = hourCode + ":%M:%S" + suffix; } else if (t < timeUnitSize.day) { if (span < 2 * timeUnitSize.day) { fmt = hourCode + ":%M" + suffix; } else { fmt = "%b %d " + hourCode + ":%M" + suffix; } } else if (t < timeUnitSize.month) { fmt = "%b %d"; } else if ((useQuarters && t < timeUnitSize.quarter) || (!useQuarters && t < timeUnitSize.year)) { if (span < timeUnitSize.year) { fmt = "%b"; } else { fmt = "%b %Y"; } } else if (useQuarters && t < timeUnitSize.year) { if (span < timeUnitSize.year) { fmt = "Q%q"; } else { fmt = "Q%q %Y"; } } else { fmt = "%Y"; } var rt = formatDate(d, fmt, opts.monthNames, opts.dayNames); return rt; }; } }); }); } $.plot.plugins.push({ init: init, options: options, name: 'time', version: '1.0' }); // Time-axis support used to be in Flot core, which exposed the // formatDate function on the plot object. Various plugins depend // on the function, so we need to re-expose it here. $.plot.formatDate = formatDate; })(jQuery); rabbitmq-server-3.5.7/plugins-src/rabbitmq-management/priv/www/js/sammy-0.6.0.js0000644000177700017770000016721712633765070027216 0ustar michaelmichael// name: sammy // version: 0.6.0pre (function($) { var Sammy, PATH_REPLACER = "([^\/]+)", PATH_NAME_MATCHER = /:([\w\d]+)/g, QUERY_STRING_MATCHER = /\?([^#]*)$/, // mainly for making `arguments` an Array _makeArray = function(nonarray) { return Array.prototype.slice.call(nonarray); }, // borrowed from jQuery _isFunction = function( obj ) { return Object.prototype.toString.call(obj) === "[object Function]"; }, _isArray = function( obj ) { return Object.prototype.toString.call(obj) === "[object Array]"; }, _decode = decodeURIComponent, _escapeHTML = function(s) { return s.replace(/&/g,'&').replace(//g,'>'); }, _routeWrapper = function(verb) { return function(path, callback) { return this.route.apply(this, [verb, path, callback]); }; }, _template_cache = {}, loggers = []; // `Sammy` (also aliased as $.sammy) is not only the namespace for a // number of prototypes, its also a top level method that allows for easy // creation/management of `Sammy.Application` instances. There are a // number of different forms for `Sammy()` but each returns an instance // of `Sammy.Application`. When a new instance is created using // `Sammy` it is added to an Object called `Sammy.apps`. This // provides for an easy way to get at existing Sammy applications. Only one // instance is allowed per `element_selector` so when calling // `Sammy('selector')` multiple times, the first time will create // the application and the following times will extend the application // already added to that selector. // // ### Example // // // returns the app at #main or a new app // Sammy('#main') // // // equivilent to "new Sammy.Application", except appends to apps // Sammy(); // Sammy(function() { ... }); // // // extends the app at '#main' with function. // Sammy('#main', function() { ... }); // Sammy = function() { var args = _makeArray(arguments), app, selector; Sammy.apps = Sammy.apps || {}; if (args.length === 0 || args[0] && _isFunction(args[0])) { // Sammy() return Sammy.apply(Sammy, ['body'].concat(args)); } else if (typeof (selector = args.shift()) == 'string') { // Sammy('#main') app = Sammy.apps[selector] || new Sammy.Application(); app.element_selector = selector; if (args.length > 0) { $.each(args, function(i, plugin) { app.use(plugin); }); } // if the selector changes make sure the refrence in Sammy.apps changes if (app.element_selector != selector) { delete Sammy.apps[selector]; } Sammy.apps[app.element_selector] = app; return app; } }; Sammy.VERSION = '0.6.0'; // Add to the global logger pool. Takes a function that accepts an // unknown number of arguments and should print them or send them somewhere // The first argument is always a timestamp. Sammy.addLogger = function(logger) { loggers.push(logger); }; // Sends a log message to each logger listed in the global // loggers pool. Can take any number of arguments. // Also prefixes the arguments with a timestamp. Sammy.log = function() { var args = _makeArray(arguments); args.unshift("[" + Date() + "]"); $.each(loggers, function(i, logger) { logger.apply(Sammy, args); }); }; if (typeof window.console != 'undefined') { if (_isFunction(console.log.apply)) { Sammy.addLogger(function() { window.console.log.apply(console, arguments); }); } else { Sammy.addLogger(function() { window.console.log(arguments); }); } } else if (typeof console != 'undefined') { Sammy.addLogger(function() { console.log.apply(console, arguments); }); } $.extend(Sammy, { makeArray: _makeArray, isFunction: _isFunction, isArray: _isArray }) // Sammy.Object is the base for all other Sammy classes. It provides some useful // functionality, including cloning, iterating, etc. Sammy.Object = function(obj) { // constructor return $.extend(this, obj || {}); }; $.extend(Sammy.Object.prototype, { // Escape HTML in string, use in templates to prevent script injection. // Also aliased as `h()` escapeHTML: _escapeHTML, h: _escapeHTML, // Returns a copy of the object with Functions removed. toHash: function() { var json = {}; $.each(this, function(k,v) { if (!_isFunction(v)) { json[k] = v; } }); return json; }, // Renders a simple HTML version of this Objects attributes. // Does not render functions. // For example. Given this Sammy.Object: // // var s = new Sammy.Object({first_name: 'Sammy', last_name: 'Davis Jr.'}); // s.toHTML() //=> 'first_name Sammy
last_name Davis Jr.
' // toHTML: function() { var display = ""; $.each(this, function(k, v) { if (!_isFunction(v)) { display += "" + k + " " + v + "
"; } }); return display; }, // Returns an array of keys for this object. If `attributes_only` // is true will not return keys that map to a `function()` keys: function(attributes_only) { var keys = []; for (var property in this) { if (!_isFunction(this[property]) || !attributes_only) { keys.push(property); } } return keys; }, // Checks if the object has a value at `key` and that the value is not empty has: function(key) { return this[key] && $.trim(this[key].toString()) != ''; }, // convenience method to join as many arguments as you want // by the first argument - useful for making paths join: function() { var args = _makeArray(arguments); var delimiter = args.shift(); return args.join(delimiter); }, // Shortcut to Sammy.log log: function() { Sammy.log.apply(Sammy, arguments); }, // Returns a string representation of this object. // if `include_functions` is true, it will also toString() the // methods of this object. By default only prints the attributes. toString: function(include_functions) { var s = []; $.each(this, function(k, v) { if (!_isFunction(v) || include_functions) { s.push('"' + k + '": ' + v.toString()); } }); return "Sammy.Object: {" + s.join(',') + "}"; } }); // The HashLocationProxy is the default location proxy for all Sammy applications. // A location proxy is a prototype that conforms to a simple interface. The purpose // of a location proxy is to notify the Sammy.Application its bound to when the location // or 'external state' changes. The HashLocationProxy considers the state to be // changed when the 'hash' (window.location.hash / '#') changes. It does this in two // different ways depending on what browser you are using. The newest browsers // (IE, Safari > 4, FF >= 3.6) support a 'onhashchange' DOM event, thats fired whenever // the location.hash changes. In this situation the HashLocationProxy just binds // to this event and delegates it to the application. In the case of older browsers // a poller is set up to track changes to the hash. Unlike Sammy 0.3 or earlier, // the HashLocationProxy allows the poller to be a global object, eliminating the // need for multiple pollers even when thier are multiple apps on the page. Sammy.HashLocationProxy = function(app, run_interval_every) { this.app = app; // set is native to false and start the poller immediately this.is_native = false; this._startPolling(run_interval_every); }; Sammy.HashLocationProxy.prototype = { // bind the proxy events to the current app. bind: function() { var proxy = this, app = this.app; $(window).bind('hashchange.' + this.app.eventNamespace(), function(e, non_native) { // if we receive a native hash change event, set the proxy accordingly // and stop polling if (proxy.is_native === false && !non_native) { Sammy.log('native hash change exists, using'); proxy.is_native = true; clearInterval(Sammy.HashLocationProxy._interval); } app.trigger('location-changed'); }); if (!Sammy.HashLocationProxy._bindings) { Sammy.HashLocationProxy._bindings = 0; } Sammy.HashLocationProxy._bindings++; }, // unbind the proxy events from the current app unbind: function() { $(window).unbind('hashchange.' + this.app.eventNamespace()); Sammy.HashLocationProxy._bindings--; if (Sammy.HashLocationProxy._bindings <= 0) { clearInterval(Sammy.HashLocationProxy._interval); } }, // get the current location from the hash. getLocation: function() { // Bypass the `window.location.hash` attribute. If a question mark // appears in the hash IE6 will strip it and all of the following // characters from `window.location.hash`. var matches = window.location.toString().match(/^[^#]*(#.+)$/); return matches ? matches[1] : ''; }, // set the current location to `new_location` setLocation: function(new_location) { return (window.location = new_location); }, _startPolling: function(every) { // set up interval var proxy = this; if (!Sammy.HashLocationProxy._interval) { if (!every) { every = 10; } var hashCheck = function() { current_location = proxy.getLocation(); if (!Sammy.HashLocationProxy._last_location || current_location != Sammy.HashLocationProxy._last_location) { setTimeout(function() { $(window).trigger('hashchange', [true]); }, 13); } Sammy.HashLocationProxy._last_location = current_location; }; hashCheck(); Sammy.HashLocationProxy._interval = setInterval(hashCheck, every); } } }; // Sammy.Application is the Base prototype for defining 'applications'. // An 'application' is a collection of 'routes' and bound events that is // attached to an element when `run()` is called. // The only argument an 'app_function' is evaluated within the context of the application. Sammy.Application = function(app_function) { var app = this; this.routes = {}; this.listeners = new Sammy.Object({}); this.arounds = []; this.befores = []; // generate a unique namespace this.namespace = (new Date()).getTime() + '-' + parseInt(Math.random() * 1000, 10); this.context_prototype = function() { Sammy.EventContext.apply(this, arguments); }; this.context_prototype.prototype = new Sammy.EventContext(); if (_isFunction(app_function)) { app_function.apply(this, [this]); } // set the location proxy if not defined to the default (HashLocationProxy) if (!this._location_proxy) { this.setLocationProxy(new Sammy.HashLocationProxy(this, this.run_interval_every)); } if (this.debug) { this.bindToAllEvents(function(e, data) { app.log(app.toString(), e.cleaned_type, data || {}); }); } }; Sammy.Application.prototype = $.extend({}, Sammy.Object.prototype, { // the four route verbs ROUTE_VERBS: ['get','post','put','delete'], // An array of the default events triggered by the // application during its lifecycle APP_EVENTS: ['run','unload','lookup-route','run-route','route-found','event-context-before','event-context-after','changed','error','check-form-submission','redirect'], _last_route: null, _location_proxy: null, _running: false, // Defines what element the application is bound to. Provide a selector // (parseable by `jQuery()`) and this will be used by `$element()` element_selector: 'body', // When set to true, logs all of the default events using `log()` debug: false, // When set to true, and the error() handler is not overriden, will actually // raise JS errors in routes (500) and when routes can't be found (404) raise_errors: false, // The time in milliseconds that the URL is queried for changes run_interval_every: 50, // The default template engine to use when using `partial()` in an // `EventContext`. `template_engine` can either be a string that // corresponds to the name of a method/helper on EventContext or it can be a function // that takes two arguments, the content of the unrendered partial and an optional // JS object that contains interpolation data. Template engine is only called/refered // to if the extension of the partial is null or unknown. See `partial()` // for more information template_engine: null, // //=> Sammy.Application: body toString: function() { return 'Sammy.Application:' + this.element_selector; }, // returns a jQuery object of the Applications bound element. $element: function() { return $(this.element_selector); }, // `use()` is the entry point for including Sammy plugins. // The first argument to use should be a function() that is evaluated // in the context of the current application, just like the `app_function` // argument to the `Sammy.Application` constructor. // // Any additional arguments are passed to the app function sequentially. // // For much more detail about plugins, check out: // http://code.quirkey.com/sammy/doc/plugins.html // // ### Example // // var MyPlugin = function(app, prepend) { // // this.helpers({ // myhelper: function(text) { // alert(prepend + " " + text); // } // }); // // }; // // var app = $.sammy(function() { // // this.use(MyPlugin, 'This is my plugin'); // // this.get('#/', function() { // this.myhelper('and dont you forget it!'); // //=> Alerts: This is my plugin and dont you forget it! // }); // // }); // // If plugin is passed as a string it assumes your are trying to load // Sammy."Plugin". This is the prefered way of loading core Sammy plugins // as it allows for better error-messaging. // // ### Example // // $.sammy(function() { // this.use('Mustache'); //=> Sammy.Mustache // this.use('Storage'); //=> Sammy.Storage // }); // use: function() { // flatten the arguments var args = _makeArray(arguments), plugin = args.shift(), plugin_name = plugin || ''; try { args.unshift(this); if (typeof plugin == 'string') { plugin_name = 'Sammy.' + plugin; plugin = Sammy[plugin]; } plugin.apply(this, args); } catch(e) { if (typeof plugin === 'undefined') { this.error("Plugin Error: called use() but plugin (" + plugin_name.toString() + ") is not defined", e); } else if (!_isFunction(plugin)) { this.error("Plugin Error: called use() but '" + plugin_name.toString() + "' is not a function", e); } else { this.error("Plugin Error", e); } } return this; }, // Sets the location proxy for the current app. By default this is set to // a new `Sammy.HashLocationProxy` on initialization. However, you can set // the location_proxy inside you're app function to give your app a custom // location mechanism. See `Sammy.HashLocationProxy` and `Sammy.DataLocationProxy` // for examples. // // `setLocationProxy()` takes an initialized location proxy. // // ### Example // // // to bind to data instead of the default hash; // var app = $.sammy(function() { // this.setLocationProxy(new Sammy.DataLocationProxy(this)); // }); // setLocationProxy: function(new_proxy) { var original_proxy = this._location_proxy; this._location_proxy = new_proxy; if (this.isRunning()) { if (original_proxy) { // if there is already a location proxy, unbind it. original_proxy.unbind(); } this._location_proxy.bind(); } }, // `route()` is the main method for defining routes within an application. // For great detail on routes, check out: http://code.quirkey.com/sammy/doc/routes.html // // This method also has aliases for each of the different verbs (eg. `get()`, `post()`, etc.) // // ### Arguments // // * `verb` A String in the set of ROUTE_VERBS or 'any'. 'any' will add routes for each // of the ROUTE_VERBS. If only two arguments are passed, // the first argument is the path, the second is the callback and the verb // is assumed to be 'any'. // * `path` A Regexp or a String representing the path to match to invoke this verb. // * `callback` A Function that is called/evaluated whent the route is run see: `runRoute()`. // It is also possible to pass a string as the callback, which is looked up as the name // of a method on the application. // route: function(verb, path, callback) { var app = this, param_names = [], add_route; // if the method signature is just (path, callback) // assume the verb is 'any' if (!callback && _isFunction(path)) { path = verb; callback = path; verb = 'any'; } verb = verb.toLowerCase(); // ensure verb is lower case // if path is a string turn it into a regex if (path.constructor == String) { // Needs to be explicitly set because IE will maintain the index unless NULL is returned, // which means that with two consecutive routes that contain params, the second set of params will not be found and end up in splat instead of params // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/RegExp/lastIndex PATH_NAME_MATCHER.lastIndex = 0; // find the names while ((path_match = PATH_NAME_MATCHER.exec(path)) !== null) { param_names.push(path_match[1]); } // replace with the path replacement path = new RegExp("^" + path.replace(PATH_NAME_MATCHER, PATH_REPLACER) + "$"); } // lookup callback if (typeof callback == 'string') { callback = app[callback]; } add_route = function(with_verb) { var r = {verb: with_verb, path: path, callback: callback, param_names: param_names}; // add route to routes array app.routes[with_verb] = app.routes[with_verb] || []; // place routes in order of definition app.routes[with_verb].push(r); }; if (verb === 'any') { $.each(this.ROUTE_VERBS, function(i, v) { add_route(v); }); } else { add_route(verb); } // return the app return this; }, // Alias for route('get', ...) get: _routeWrapper('get'), // Alias for route('post', ...) post: _routeWrapper('post'), // Alias for route('put', ...) put: _routeWrapper('put'), // Alias for route('delete', ...) del: _routeWrapper('delete'), // Alias for route('any', ...) any: _routeWrapper('any'), // `mapRoutes` takes an array of arrays, each array being passed to route() // as arguments, this allows for mass definition of routes. Another benefit is // this makes it possible/easier to load routes via remote JSON. // // ### Example // // var app = $.sammy(function() { // // this.mapRoutes([ // ['get', '#/', function() { this.log('index'); }], // // strings in callbacks are looked up as methods on the app // ['post', '#/create', 'addUser'], // // No verb assumes 'any' as the verb // [/dowhatever/, function() { this.log(this.verb, this.path)}]; // ]); // }) // mapRoutes: function(route_array) { var app = this; $.each(route_array, function(i, route_args) { app.route.apply(app, route_args); }); return this; }, // A unique event namespace defined per application. // All events bound with `bind()` are automatically bound within this space. eventNamespace: function() { return ['sammy-app', this.namespace].join('-'); }, // Works just like `jQuery.fn.bind()` with a couple noteable differences. // // * It binds all events to the application element // * All events are bound within the `eventNamespace()` // * Events are not actually bound until the application is started with `run()` // * callbacks are evaluated within the context of a Sammy.EventContext // // See http://code.quirkey.com/sammy/docs/events.html for more info. // bind: function(name, data, callback) { var app = this; // build the callback // if the arity is 2, callback is the second argument if (typeof callback == 'undefined') { callback = data; } var listener_callback = function() { // pull off the context from the arguments to the callback var e, context, data; e = arguments[0]; data = arguments[1]; if (data && data.context) { context = data.context; delete data.context; } else { context = new app.context_prototype(app, 'bind', e.type, data, e.target); } e.cleaned_type = e.type.replace(app.eventNamespace(), ''); callback.apply(context, [e, data]); }; // it could be that the app element doesnt exist yet // so attach to the listeners array and then run() // will actually bind the event. if (!this.listeners[name]) { this.listeners[name] = []; } this.listeners[name].push(listener_callback); if (this.isRunning()) { // if the app is running // *actually* bind the event to the app element this._listen(name, listener_callback); } return this; }, // Triggers custom events defined with `bind()` // // ### Arguments // // * `name` The name of the event. Automatically prefixed with the `eventNamespace()` // * `data` An optional Object that can be passed to the bound callback. // * `context` An optional context/Object in which to execute the bound callback. // If no context is supplied a the context is a new `Sammy.EventContext` // trigger: function(name, data) { this.$element().trigger([name, this.eventNamespace()].join('.'), [data]); return this; }, // Reruns the current route refresh: function() { this.last_location = null; this.trigger('location-changed'); return this; }, // Takes a single callback that is pushed on to a stack. // Before any route is run, the callbacks are evaluated in order within // the current `Sammy.EventContext` // // If any of the callbacks explicitly return false, execution of any // further callbacks and the route itself is halted. // // You can also provide a set of options that will define when to run this // before based on the route it proceeds. // // ### Example // // var app = $.sammy(function() { // // // will run at #/route but not at #/ // this.before('#/route', function() { // //... // }); // // // will run at #/ but not at #/route // this.before({except: {path: '#/route'}}, function() { // this.log('not before #/route'); // }); // // this.get('#/', function() {}); // // this.get('#/route', function() {}); // // }); // // See `contextMatchesOptions()` for a full list of supported options // before: function(options, callback) { if (_isFunction(options)) { callback = options; options = {}; } this.befores.push([options, callback]); return this; }, // A shortcut for binding a callback to be run after a route is executed. // After callbacks have no guarunteed order. after: function(callback) { return this.bind('event-context-after', callback); }, // Adds an around filter to the application. around filters are functions // that take a single argument `callback` which is the entire route // execution path wrapped up in a closure. This means you can decide whether // or not to proceed with execution by not invoking `callback` or, // more usefuly wrapping callback inside the result of an asynchronous execution. // // ### Example // // The most common use case for around() is calling a _possibly_ async function // and executing the route within the functions callback: // // var app = $.sammy(function() { // // var current_user = false; // // function checkLoggedIn(callback) { // // /session returns a JSON representation of the logged in user // // or an empty object // if (!current_user) { // $.getJSON('/session', function(json) { // if (json.login) { // // show the user as logged in // current_user = json; // // execute the route path // callback(); // } else { // // show the user as not logged in // current_user = false; // // the context of aroundFilters is an EventContext // this.redirect('#/login'); // } // }); // } else { // // execute the route path // callback(); // } // }; // // this.around(checkLoggedIn); // // }); // around: function(callback) { this.arounds.push(callback); return this; }, // Returns `true` if the current application is running. isRunning: function() { return this._running; }, // Helpers extends the EventContext prototype specific to this app. // This allows you to define app specific helper functions that can be used // whenever you're inside of an event context (templates, routes, bind). // // ### Example // // var app = $.sammy(function() { // // helpers({ // upcase: function(text) { // return text.toString().toUpperCase(); // } // }); // // get('#/', function() { with(this) { // // inside of this context I can use the helpers // $('#main').html(upcase($('#main').text()); // }}); // // }); // // // ### Arguments // // * `extensions` An object collection of functions to extend the context. // helpers: function(extensions) { $.extend(this.context_prototype.prototype, extensions); return this; }, // Helper extends the event context just like `helpers()` but does it // a single method at a time. This is especially useful for dynamically named // helpers // // ### Example // // // Trivial example that adds 3 helper methods to the context dynamically // var app = $.sammy(function(app) { // // $.each([1,2,3], function(i, num) { // app.helper('helper' + num, function() { // this.log("I'm helper number " + num); // }); // }); // // this.get('#/', function() { // this.helper2(); //=> I'm helper number 2 // }); // }); // // ### Arguments // // * `name` The name of the method // * `method` The function to be added to the prototype at `name` // helper: function(name, method) { this.context_prototype.prototype[name] = method; return this; }, // Actually starts the application's lifecycle. `run()` should be invoked // within a document.ready block to ensure the DOM exists before binding events, etc. // // ### Example // // var app = $.sammy(function() { ... }); // your application // $(function() { // document.ready // app.run(); // }); // // ### Arguments // // * `start_url` Optionally, a String can be passed which the App will redirect to // after the events/routes have been bound. run: function(start_url) { if (this.isRunning()) { return false; } var app = this; // actually bind all the listeners $.each(this.listeners.toHash(), function(name, callbacks) { $.each(callbacks, function(i, listener_callback) { app._listen(name, listener_callback); }); }); this.trigger('run', {start_url: start_url}); this._running = true; // set last location this.last_location = null; if (this.getLocation() == '' && typeof start_url != 'undefined') { this.setLocation(start_url); } // check url this._checkLocation(); this._location_proxy.bind(); this.bind('location-changed', function() { app._checkLocation(); }); // bind to submit to capture post/put/delete routes this.bind('submit', function(e) { var returned = app._checkFormSubmission($(e.target).closest('form')); return (returned === false) ? e.preventDefault() : false; }); // bind unload to body unload $(window).bind('beforeunload', function() { app.unload(); }); // trigger html changed return this.trigger('changed'); }, // The opposite of `run()`, un-binds all event listeners and intervals // `run()` Automaticaly binds a `onunload` event to run this when // the document is closed. unload: function() { if (!this.isRunning()) { return false; } var app = this; this.trigger('unload'); // clear interval this._location_proxy.unbind(); // unbind form submits this.$element().unbind('submit').removeClass(app.eventNamespace()); // unbind all events $.each(this.listeners.toHash() , function(name, listeners) { $.each(listeners, function(i, listener_callback) { app._unlisten(name, listener_callback); }); }); this._running = false; return this; }, // Will bind a single callback function to every event that is already // being listened to in the app. This includes all the `APP_EVENTS` // as well as any custom events defined with `bind()`. // // Used internally for debug logging. bindToAllEvents: function(callback) { var app = this; // bind to the APP_EVENTS first $.each(this.APP_EVENTS, function(i, e) { app.bind(e, callback); }); // next, bind to listener names (only if they dont exist in APP_EVENTS) $.each(this.listeners.keys(true), function(i, name) { if (app.APP_EVENTS.indexOf(name) == -1) { app.bind(name, callback); } }); return this; }, // Returns a copy of the given path with any query string after the hash // removed. routablePath: function(path) { return path.replace(QUERY_STRING_MATCHER, ''); }, // Given a verb and a String path, will return either a route object or false // if a matching route can be found within the current defined set. lookupRoute: function(verb, path) { var app = this, routed = false; this.trigger('lookup-route', {verb: verb, path: path}); if (typeof this.routes[verb] != 'undefined') { $.each(this.routes[verb], function(i, route) { if (app.routablePath(path).match(route.path)) { routed = route; return false; } }); } return routed; }, // First, invokes `lookupRoute()` and if a route is found, parses the // possible URL params and then invokes the route's callback within a new // `Sammy.EventContext`. If the route can not be found, it calls // `notFound()`. If `raise_errors` is set to `true` and // the `error()` has not been overriden, it will throw an actual JS // error. // // You probably will never have to call this directly. // // ### Arguments // // * `verb` A String for the verb. // * `path` A String path to lookup. // * `params` An Object of Params pulled from the URI or passed directly. // // ### Returns // // Either returns the value returned by the route callback or raises a 404 Not Found error. // runRoute: function(verb, path, params, target) { var app = this, route = this.lookupRoute(verb, path), context, wrapped_route, arounds, around, befores, before, callback_args, final_returned; this.log('runRoute', [verb, path].join(' ')); this.trigger('run-route', {verb: verb, path: path, params: params}); if (typeof params == 'undefined') { params = {}; } $.extend(params, this._parseQueryString(path)); if (route) { this.trigger('route-found', {route: route}); // pull out the params from the path if ((path_params = route.path.exec(this.routablePath(path))) !== null) { // first match is the full path path_params.shift(); // for each of the matches $.each(path_params, function(i, param) { // if theres a matching param name if (route.param_names[i]) { // set the name to the match params[route.param_names[i]] = _decode(param); } else { // initialize 'splat' if (!params.splat) { params.splat = []; } params.splat.push(_decode(param)); } }); } // set event context context = new this.context_prototype(this, verb, path, params, target); // ensure arrays arounds = this.arounds.slice(0); befores = this.befores.slice(0); // set the callback args to the context + contents of the splat callback_args = [context].concat(params.splat); // wrap the route up with the before filters wrapped_route = function() { var returned; while (befores.length > 0) { before = befores.shift(); // check the options if (app.contextMatchesOptions(context, before[0])) { returned = before[1].apply(context, [context]); if (returned === false) { return false; } } } app.last_route = route; context.trigger('event-context-before', {context: context}); returned = route.callback.apply(context, callback_args); context.trigger('event-context-after', {context: context}); return returned; }; $.each(arounds.reverse(), function(i, around) { var last_wrapped_route = wrapped_route; wrapped_route = function() { return around.apply(context, [last_wrapped_route]); }; }); try { final_returned = wrapped_route(); } catch(e) { this.error(['500 Error', verb, path].join(' '), e); } return final_returned; } else { return this.notFound(verb, path); } }, // Matches an object of options against an `EventContext` like object that // contains `path` and `verb` attributes. Internally Sammy uses this // for matching `before()` filters against specific options. You can set the // object to _only_ match certain paths or verbs, or match all paths or verbs _except_ // those that match the options. // // ### Example // // var app = $.sammy(), // context = {verb: 'get', path: '#/mypath'}; // // // match against a path string // app.contextMatchesOptions(context, '#/mypath'); //=> true // app.contextMatchesOptions(context, '#/otherpath'); //=> false // // equivilent to // app.contextMatchesOptions(context, {only: {path:'#/mypath'}}); //=> true // app.contextMatchesOptions(context, {only: {path:'#/otherpath'}}); //=> false // // match against a path regexp // app.contextMatchesOptions(context, /path/); //=> true // app.contextMatchesOptions(context, /^path/); //=> false // // match only a verb // app.contextMatchesOptions(context, {only: {verb:'get'}}); //=> true // app.contextMatchesOptions(context, {only: {verb:'post'}}); //=> false // // match all except a verb // app.contextMatchesOptions(context, {except: {verb:'post'}}); //=> true // app.contextMatchesOptions(context, {except: {verb:'get'}}); //=> false // // match all except a path // app.contextMatchesOptions(context, {except: {path:'#/otherpath'}}); //=> true // app.contextMatchesOptions(context, {except: {path:'#/mypath'}}); //=> false // contextMatchesOptions: function(context, match_options, positive) { // empty options always match var options = match_options; if (typeof options === 'undefined' || options == {}) { return true; } if (typeof positive === 'undefined') { positive = true; } // normalize options if (typeof options === 'string' || _isFunction(options.test)) { options = {path: options}; } if (options.only) { return this.contextMatchesOptions(context, options.only, true); } else if (options.except) { return this.contextMatchesOptions(context, options.except, false); } var path_matched = true, verb_matched = true; if (options.path) { // wierd regexp test if (_isFunction(options.path.test)) { path_matched = options.path.test(context.path); } else { path_matched = (options.path.toString() === context.path); } } if (options.verb) { verb_matched = options.verb === context.verb; } return positive ? (verb_matched && path_matched) : !(verb_matched && path_matched); }, // Delegates to the `location_proxy` to get the current location. // See `Sammy.HashLocationProxy` for more info on location proxies. getLocation: function() { return this._location_proxy.getLocation(); }, // Delegates to the `location_proxy` to set the current location. // See `Sammy.HashLocationProxy` for more info on location proxies. // // ### Arguments // // * `new_location` A new location string (e.g. '#/') // setLocation: function(new_location) { return this._location_proxy.setLocation(new_location); }, // Swaps the content of `$element()` with `content` // You can override this method to provide an alternate swap behavior // for `EventContext.partial()`. // // ### Example // // var app = $.sammy(function() { // // // implements a 'fade out'/'fade in' // this.swap = function(content) { // this.$element().hide('slow').html(content).show('slow'); // } // // get('#/', function() { // this.partial('index.html.erb') // will fade out and in // }); // // }); // swap: function(content) { return this.$element().html(content); }, // a simple global cache for templates. Uses the same semantics as // `Sammy.Cache` and `Sammy.Storage` so can easily be replaced with // a persistant storage that lasts beyond the current request. templateCache: function(key, value) { if (typeof value != 'undefined') { return _template_cache[key] = value; } else { return _template_cache[key]; } }, // This thows a '404 Not Found' error by invoking `error()`. // Override this method or `error()` to provide custom // 404 behavior (i.e redirecting to / or showing a warning) notFound: function(verb, path) { var ret = this.error(['404 Not Found', verb, path].join(' ')); return (verb === 'get') ? ret : true; }, // The base error handler takes a string `message` and an `Error` // object. If `raise_errors` is set to `true` on the app level, // this will re-throw the error to the browser. Otherwise it will send the error // to `log()`. Override this method to provide custom error handling // e.g logging to a server side component or displaying some feedback to the // user. error: function(message, original_error) { if (!original_error) { original_error = new Error(); } original_error.message = [message, original_error.message].join(' '); this.trigger('error', {message: original_error.message, error: original_error}); if (this.raise_errors) { throw(original_error); } else { this.log(original_error.message, original_error); } }, _checkLocation: function() { var location, returned; // get current location location = this.getLocation(); // compare to see if hash has changed if (location != this.last_location) { // reset last location this.last_location = location; // lookup route for current hash returned = this.runRoute('get', location); } return returned; }, _getFormVerb: function(form) { var $form = $(form), verb; $_method = $form.find('input[name="_method"]'); if ($_method.length > 0) { verb = $_method.val(); } if (!verb) { verb = $form[0].getAttribute('method'); } return $.trim(verb.toString().toLowerCase()); }, _checkFormSubmission: function(form) { var $form, path, verb, params, returned; this.trigger('check-form-submission', {form: form}); $form = $(form); path = $form.attr('action'); verb = this._getFormVerb($form); if (!verb || verb == '') { verb = 'get'; } this.log('_checkFormSubmission', $form, path, verb); if (verb === 'get') { this.setLocation(path + '?' + $form.serialize()); returned = false; } else { params = $.extend({}, this._parseFormParams($form)); returned = this.runRoute(verb, path, params, form.get(0)); }; return (typeof returned == 'undefined') ? false : returned; }, _parseFormParams: function($form) { var params = {}, form_fields = $form.serializeArray(), i; for (i = 0; i < form_fields.length; i++) { params = this._parseParamPair(params, form_fields[i].name, form_fields[i].value); } return params; }, _parseQueryString: function(path) { var params = {}, parts, pairs, pair, i; parts = path.match(QUERY_STRING_MATCHER); if (parts) { pairs = parts[1].split('&'); for (i = 0; i < pairs.length; i++) { pair = pairs[i].split('='); params = this._parseParamPair(params, _decode(pair[0]), _decode(pair[1])); } } return params; }, _parseParamPair: function(params, key, value) { if (params[key]) { if (_isArray(params[key])) { params[key].push(value); } else { params[key] = [params[key], value]; } } else { params[key] = value; } return params; }, _listen: function(name, callback) { return this.$element().bind([name, this.eventNamespace()].join('.'), callback); }, _unlisten: function(name, callback) { return this.$element().unbind([name, this.eventNamespace()].join('.'), callback); } }); // `Sammy.RenderContext` is an object that makes sequential template loading, // rendering and interpolation seamless even when dealing with asyncronous // operations. // // `RenderContext` objects are not usually created directly, rather they are // instatiated from an `Sammy.EventContext` by using `render()`, `load()` or // `partial()` which all return `RenderContext` objects. // // `RenderContext` methods always returns a modified `RenderContext` // for chaining (like jQuery itself). // // The core magic is in the `then()` method which puts the callback passed as // an argument into a queue to be executed once the previous callback is complete. // All the methods of `RenderContext` are wrapped in `then()` which allows you // to queue up methods by chaining, but maintaing a guarunteed execution order // even with remote calls to fetch templates. // Sammy.RenderContext = function(event_context) { this.event_context = event_context; this.callbacks = []; this.previous_content = null; this.content = null; this.next_engine = false; this.waiting = false; }; $.extend(Sammy.RenderContext.prototype, { // The "core" of the `RenderContext` object, adds the `callback` to the // queue. If the context is `waiting` (meaning an async operation is happening) // then the callback will be executed in order, once the other operations are // complete. If there is no currently executing operation, the `callback` // is executed immediately. // // The value returned from the callback is stored in `content` for the // subsiquent operation. If you return `false`, the queue will pause, and // the next callback in the queue will not be executed until `next()` is // called. This allows for the guarunteed order of execution while working // with async operations. // // ### Example // // this.get('#/', function() { // // initialize the RenderContext // // Even though `load()` executes async, the next `then()` // // wont execute until the load finishes // this.load('myfile.txt') // .then(function(content) { // // the first argument to then is the content of the // // prev operation // $('#main').html(content); // }); // }); // then: function(callback) { if (_isFunction(callback)) { var context = this; if (this.waiting) { this.callbacks.push(callback); } else { this.wait(); setTimeout(function() { var returned = callback.apply(context, [context.content, context.previous_content]); if (returned !== false) { context.next(returned); } }, 13); } } return this; }, // Pause the `RenderContext` queue. Combined with `next()` allows for async // operations. // // ### Example // // this.get('#/', function() { // this.load('mytext.json') // .then(function(content) { // var context = this, // data = JSON.parse(content); // // pause execution // context.wait(); // // post to a url // $.post(data.url, {}, function(response) { // context.next(JSON.parse(response)); // }); // }) // .then(function(data) { // // data is json from the previous post // $('#message').text(data.status); // }); // }); wait: function() { this.waiting = true; }, // Resume the queue, setting `content` to be used in the next operation. // See `wait()` for an example. next: function(content) { this.waiting = false; if (typeof content !== 'undefined') { this.previous_content = this.content; this.content = content; } if (this.callbacks.length > 0) { this.then(this.callbacks.shift()); } }, // Load a template into the context. // The `location` can either be a string specifiying the remote path to the // file, a jQuery object, or a DOM element. // // No interpolation happens by default, the content is stored in // `content`. // // In the case of a path, unless the option `{cache: false}` is passed the // data is stored in the app's `templateCache()`. // // If a jQuery or DOM object is passed the `innerHTML` of the node is pulled in. // This is useful for nesting templates as part of the initial page load wrapped // in invisible elements or `

Don't panic!

This is a SockJS hidden iframe. It's used for cross domain magic.

"). -define(IFRAME_HTMLFILE, "

Don't panic!

"). %% -------------------------------------------------------------------------- %% -spec welcome_screen(req(), headers(), service()) -> req(). welcome_screen(Req, Headers, _Service) -> H = [{"Content-Type", "text/plain; charset=UTF-8"}], sockjs_http:reply(200, H ++ Headers, "Welcome to SockJS!\n", Req). %% -spec options(req(), headers(), service()) -> req(). options(Req, Headers, _Service) -> sockjs_http:reply(204, Headers, "", Req). %% -spec iframe(req(), headers(), service()) -> req(). iframe(Req, Headers, #service{sockjs_url = SockjsUrl}) -> IFrame = io_lib:format(?IFRAME, [SockjsUrl]), MD5 = "\"" ++ binary_to_list(base64:encode(erlang:md5(IFrame))) ++ "\"", {H, Req2} = sockjs_http:header('If-None-Match', Req), case H of MD5 -> sockjs_http:reply(304, Headers, "", Req2); _ -> sockjs_http:reply( 200, [{"Content-Type", "text/html; charset=UTF-8"}, {"ETag", MD5}] ++ Headers, IFrame, Req2) end. %% -spec info_test(req(), headers(), service()) -> req(). info_test(Req, Headers, #service{websocket = Websocket, cookie_needed = CookieNeeded}) -> I = [{websocket, Websocket}, {cookie_needed, CookieNeeded}, {origins, [<<"*:*">>]}, {entropy, sockjs_util:rand32()}], D = sockjs_json:encode({I}), H = [{"Content-Type", "application/json; charset=UTF-8"}], sockjs_http:reply(200, H ++ Headers, D, Req). %% -------------------------------------------------------------------------- %% -spec xhr_polling(req(), headers(), service(), session()) -> req(). xhr_polling(Req, Headers, Service, Session) -> Req1 = chunk_start(Req, Headers), reply_loop(Req1, Session, 1, fun fmt_xhr/1, Service). %% -spec xhr_streaming(req(), headers(), service(), session()) -> req(). xhr_streaming(Req, Headers, Service = #service{response_limit = ResponseLimit}, Session) -> Req1 = chunk_start(Req, Headers), %% IE requires 2KB prefix: %% http://blogs.msdn.com/b/ieinternals/archive/2010/04/06/comet-streaming-in-internet-explorer-with-xmlhttprequest-and-xdomainrequest.aspx Req2 = chunk(Req1, list_to_binary(string:copies("h", 2048)), fun fmt_xhr/1), reply_loop(Req2, Session, ResponseLimit, fun fmt_xhr/1, Service). %% -spec eventsource(req(), headers(), service(), session()) -> req(). eventsource(Req, Headers, Service = #service{response_limit = ResponseLimit}, SessionId) -> Req1 = chunk_start(Req, Headers, "text/event-stream; charset=UTF-8"), Req2 = chunk(Req1, <<$\r, $\n>>), reply_loop(Req2, SessionId, ResponseLimit, fun fmt_eventsource/1, Service). %% -spec htmlfile(req(), headers(), service(), session()) -> req(). htmlfile(Req, Headers, Service = #service{response_limit = ResponseLimit}, SessionId) -> S = fun (Req1, CB) -> Req2 = chunk_start(Req1, Headers, "text/html; charset=UTF-8"), IFrame = iolist_to_binary(io_lib:format(?IFRAME_HTMLFILE, [CB])), %% Safari needs at least 1024 bytes to parse the %% website. Relevant: %% http://code.google.com/p/browsersec/wiki/Part2#Survey_of_content_sniffing_behaviors Padding = string:copies(" ", 1024 - size(IFrame)), Req3 = chunk(Req2, [IFrame, Padding, <<"\r\n\r\n">>]), reply_loop(Req3, SessionId, ResponseLimit, fun fmt_htmlfile/1, Service) end, verify_callback(Req, S). %% -spec jsonp(req(), headers(), service(), session()) -> req(). jsonp(Req, Headers, Service, SessionId) -> S = fun (Req1, CB) -> Req2 = chunk_start(Req1, Headers), reply_loop(Req2, SessionId, 1, fun (Body) -> fmt_jsonp(Body, CB) end, Service) end, verify_callback(Req, S). verify_callback(Req, Success) -> {CB, Req1} = sockjs_http:callback(Req), case CB of undefined -> sockjs_http:reply(500, [], "\"callback\" parameter required", Req1); _ -> Success(Req1, CB) end. %% -------------------------------------------------------------------------- %% -spec xhr_send(req(), headers(), service(), session()) -> req(). xhr_send(Req, Headers, _Service, Session) -> {Body, Req1} = sockjs_http:body(Req), case handle_recv(Req1, Body, Session) of {error, Req2} -> Req2; ok -> H = [{"content-type", "text/plain; charset=UTF-8"}], sockjs_http:reply(204, H ++ Headers, "", Req1) end. %% -spec jsonp_send(req(), headers(), service(), session()) -> req(). jsonp_send(Req, Headers, _Service, Session) -> {Body, Req1} = sockjs_http:body_qs(Req), case handle_recv(Req1, Body, Session) of {error, Req2} -> Req2; ok -> H = [{"content-type", "text/plain; charset=UTF-8"}], sockjs_http:reply(200, H ++ Headers, "ok", Req1) end. handle_recv(Req, Body, Session) -> case Body of _Any when Body =:= <<>> -> {error, sockjs_http:reply(500, [], "Payload expected.", Req)}; _Any -> case sockjs_json:decode(Body) of {ok, Decoded} when is_list(Decoded)-> sockjs_session:received(Decoded, Session), ok; {error, _} -> {error, sockjs_http:reply(500, [], "Broken JSON encoding.", Req)} end end. %% -------------------------------------------------------------------------- -define(STILL_OPEN, {2010, "Another connection still open"}). chunk_start(Req, Headers) -> chunk_start(Req, Headers, "application/javascript; charset=UTF-8"). chunk_start(Req, Headers, ContentType) -> sockjs_http:chunk_start(200, [{"Content-Type", ContentType}] ++ Headers, Req). reply_loop(Req, SessionId, ResponseLimit, Fmt, Service) -> Req0 = sockjs_http:hook_tcp_close(Req), case sockjs_session:reply(SessionId) of wait -> receive %% In Cowboy we need to capture async %% messages from the tcp connection - %% ie: {active, once}. {tcp_closed, _} -> Req0; %% In Cowboy we may in theory get real %% http requests, this is bad. {tcp, _S, Data} -> error_logger:error_msg( "Received unexpected data on a " "long-polling http connection: ~p. " "Connection aborted.~n", [Data]), Req1 = sockjs_http:abruptly_kill(Req), Req1; go -> Req1 = sockjs_http:unhook_tcp_close(Req0), reply_loop(Req1, SessionId, ResponseLimit, Fmt, Service) end; session_in_use -> Frame = sockjs_util:encode_frame({close, ?STILL_OPEN}), chunk_end(Req0, Frame, Fmt); {close, Frame} -> Frame1 = sockjs_util:encode_frame(Frame), chunk_end(Req0, Frame1, Fmt); {ok, Frame} -> Frame1 = sockjs_util:encode_frame(Frame), Frame2 = iolist_to_binary(Frame1), Req2 = chunk(Req0, Frame2, Fmt), reply_loop0(Req2, SessionId, ResponseLimit - size(Frame2), Fmt, Service) end. reply_loop0(Req, _SessionId, ResponseLimit, _Fmt, _Service) when ResponseLimit =< 0 -> chunk_end(Req); reply_loop0(Req, SessionId, ResponseLimit, Fmt, Service) -> reply_loop(Req, SessionId, ResponseLimit, Fmt, Service). chunk(Req, Body) -> {_, Req1} = sockjs_http:chunk(Body, Req), Req1. chunk(Req, Body, Fmt) -> chunk(Req, Fmt(Body)). chunk_end(Req) -> sockjs_http:chunk_end(Req). chunk_end(Req, Body, Fmt) -> Req1 = chunk(Req, Body, Fmt), chunk_end(Req1). %% -spec fmt_xhr(iodata()) -> iodata(). fmt_xhr(Body) -> [Body, "\n"]. %% -spec fmt_eventsource(iodata()) -> iodata(). fmt_eventsource(Body) -> Escaped = sockjs_util:url_escape(binary_to_list(iolist_to_binary(Body)), "%\r\n\0"), %% $% must be first! [<<"data: ">>, Escaped, <<"\r\n\r\n">>]. %% -spec fmt_htmlfile(iodata()) -> iodata(). fmt_htmlfile(Body) -> Double = sockjs_json:encode(iolist_to_binary(Body)), [<<"\r\n">>]. %% -spec fmt_jsonp(iodata(), iodata()) -> iodata(). fmt_jsonp(Body, Callback) -> %% Yes, JSONed twice, there isn't a a better way, we must pass %% a string back, and the script, will be evaled() by the %% browser. [Callback, "(", sockjs_json:encode(iolist_to_binary(Body)), ");\r\n"]. %% -------------------------------------------------------------------------- %% -spec websocket(req(), headers(), service()) -> req(). websocket(Req, Headers, Service) -> {_Any, Req1, {R1, R2}} = sockjs_handler:is_valid_ws(Service, Req), case {R1, R2} of {false, _} -> sockjs_http:reply(400, Headers, "Can \"Upgrade\" only to \"WebSocket\".", Req1); {_, false} -> sockjs_http:reply(400, Headers, "\"Connection\" must be \"Upgrade\"", Req1); {true, true} -> sockjs_http:reply(400, Headers, "This WebSocket request can't be handled.", Req1) end. %% -spec rawwebsocket(req(), headers(), service()) -> req(). rawwebsocket(Req, Headers, Service) -> websocket(Req, Headers, Service). rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/src/sockjs.app.src0000644000177700017770000000034612633765070032043 0ustar michaelmichael{application, sockjs, [ {description, "SockJS"}, {vsn, "0.3.4"}, {modules, []}, {registered, []}, {applications, [ kernel, stdlib ]}, {mod, { sockjs_app, []}} ]}. rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/src/sockjs_json.erl0000644000177700017770000000063212633765070032306 0ustar michaelmichael-module(sockjs_json). -export([encode/1, decode/1]). %% -------------------------------------------------------------------------- %% -spec encode(any()) -> iodata(). encode(Thing) -> mochijson2_fork:encode(Thing). %% -spec decode(iodata()) -> {ok, any()} | {error, any()}. decode(Encoded) -> try mochijson2_fork:decode(Encoded) of V -> {ok, V} catch _:E -> {error, E} end. rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/src/sockjs_http.erl0000644000177700017770000001146412633765070032321 0ustar michaelmichael-module(sockjs_http). -export([path/1, method/1, body/1, body_qs/1, header/2, jsessionid/1, callback/1, peername/1, sockname/1]). -export([reply/4, chunk_start/3, chunk/2, chunk_end/1]). -export([hook_tcp_close/1, unhook_tcp_close/1, abruptly_kill/1]). -include("sockjs_internal.hrl"). %% -------------------------------------------------------------------------- %% -spec path(req()) -> {string(), req()}. path({cowboy, Req}) -> {Path, Req1} = cowboy_http_req:raw_path(Req), {binary_to_list(Path), {cowboy, Req1}}. %% -spec method(req()) -> {atom(), req()}. method({cowboy, Req}) -> {Method, Req1} = cowboy_http_req:method(Req), case is_binary(Method) of true -> {list_to_atom(binary_to_list(Method)), {cowboy, Req1}}; false -> {Method, {cowboy, Req1}} end. %% -spec body(req()) -> {binary(), req()}. body({cowboy, Req}) -> {ok, Body, Req1} = cowboy_http_req:body(Req), {Body, {cowboy, Req1}}. %% -spec body_qs(req()) -> {binary(), req()}. body_qs(Req) -> {H, Req1} = header('Content-Type', Req), case H of H when H =:= "text/plain" orelse H =:= "" -> body(Req1); _ -> %% By default assume application/x-www-form-urlencoded body_qs2(Req1) end. body_qs2({cowboy, Req}) -> {BodyQS, Req1} = cowboy_http_req:body_qs(Req), case proplists:get_value(<<"d">>, BodyQS) of undefined -> {<<>>, {cowboy, Req1}}; V -> {V, {cowboy, Req1}} end. %% -spec header(atom(), req()) -> {nonempty_string() | undefined, req()}. header(K, {cowboy, Req})-> {H, Req2} = cowboy_http_req:header(K, Req), {V, Req3} = case H of undefined -> cowboy_http_req:header(list_to_binary(atom_to_list(K)), Req2); _ -> {H, Req2} end, case V of undefined -> {undefined, {cowboy, Req3}}; _ -> {binary_to_list(V), {cowboy, Req3}} end. %% -spec jsessionid(req()) -> {nonempty_string() | undefined, req()}. jsessionid({cowboy, Req}) -> {C, Req2} = cowboy_http_req:cookie(<<"JSESSIONID">>, Req), case C of _ when is_binary(C) -> {binary_to_list(C), {cowboy, Req2}}; undefined -> {undefined, {cowboy, Req2}} end. %% -spec callback(req()) -> {nonempty_string() | undefined, req()}. callback({cowboy, Req}) -> {CB, Req1} = cowboy_http_req:qs_val(<<"c">>, Req), case CB of undefined -> {undefined, {cowboy, Req1}}; _ -> {binary_to_list(CB), {cowboy, Req1}} end. %% -spec peername(req()) -> {{inet:ip_address(), non_neg_integer()}, req()}. peername({cowboy, Req}) -> {P, Req1} = cowboy_http_req:peer(Req), {P, {cowboy, Req1}}. %% -spec sockname(req()) -> {{inet:ip_address(), non_neg_integer()}, req()}. sockname({cowboy, Req} = R) -> {ok, _T, S} = cowboy_http_req:transport(Req), %% Cowboy has peername(), but doesn't have sockname() equivalent. {ok, Addr} = case S of _ when is_port(S) -> inet:sockname(S); _ -> {ok, {{0,0,0,0}, 0}} end, {Addr, R}. %% -------------------------------------------------------------------------- %% -spec reply(non_neg_integer(), headers(), iodata(), req()) -> req(). reply(Code, Headers, Body, {cowboy, Req}) -> Body1 = iolist_to_binary(Body), {ok, Req1} = cowboy_http_req:reply(Code, enbinary(Headers), Body1, Req), {cowboy, Req1}. %% -spec chunk_start(non_neg_integer(), headers(), req()) -> req(). chunk_start(Code, Headers, {cowboy, Req}) -> {ok, Req1} = cowboy_http_req:chunked_reply(Code, enbinary(Headers), Req), {cowboy, Req1}. %% -spec chunk(iodata(), req()) -> {ok | error, req()}. chunk(Chunk, {cowboy, Req} = R) -> case cowboy_http_req:chunk(Chunk, Req) of ok -> {ok, R}; {error, _E} -> {error, R} %% This shouldn't happen too often, usually we %% should catch tco socket closure before. end. %% -spec chunk_end(req()) -> req(). chunk_end({cowboy, _Req} = R) -> R. enbinary(L) -> [{list_to_binary(K), list_to_binary(V)} || {K, V} <- L]. %% -spec hook_tcp_close(req()) -> req(). hook_tcp_close(R = {cowboy, Req}) -> {ok, T, S} = cowboy_http_req:transport(Req), T:setopts(S,[{active,once}]), R. %% -spec unhook_tcp_close(req()) -> req(). unhook_tcp_close(R = {cowboy, Req}) -> {ok, T, S} = cowboy_http_req:transport(Req), T:setopts(S,[{active,false}]), R. %% -spec abruptly_kill(req()) -> req(). abruptly_kill(R = {cowboy, Req}) -> {ok, T, S} = cowboy_http_req:transport(Req), T:close(S), R. rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/src/mochijson2_fork.erl0000644000177700017770000010011212633765070033047 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2007 Mochi Media, Inc. %% Changes specific to SockJS: support for handling \xFFFE and \xFFFF %% characters. The usual xmerl_ucs:to_utf8 doesn't work for those (in %% fact these characters aren't valid unicode characters). But we can %% support them, why not: %% %% diff --git a/src/mochijson2_fork.erl b/src/mochijson2_fork.erl %% index ddd62c7..8c26fc6 100644 %% --- a/src/mochijson2_fork.erl %% +++ b/src/mochijson2_fork.erl %% @@ -458,7 +458,14 @@ tokenize_string(B, S=#decoder{offset=O}, Acc) -> %% Acc1 = lists:reverse(xmerl_ucs:to_utf8(CodePoint), Acc), %% tokenize_string(B, ?ADV_COL(S, 12), Acc1); %% true -> %% - Acc1 = lists:reverse(xmerl_ucs:to_utf8(C), Acc), %% + R = if C < 16#FFFE -> %% + xmerl_ucs:to_utf8(C); %% + true -> %% + [16#E0 + (C bsr 12), %% + 128+((C bsr 6) band 16#3F), %% + 128+(C band 16#3F)] %% + end, %% + Acc1 = lists:reverse(R, Acc), %% tokenize_string(B, ?ADV_COL(S, 6), Acc1) %% end; %% <<_:O/binary, C1, _/binary>> when C1 < 128 -> %% %% @doc Yet another JSON (RFC 4627) library for Erlang. mochijson2 works %% with binaries as strings, arrays as lists (without an {array, _}) %% wrapper and it only knows how to decode UTF-8 (and ASCII). %% %% JSON terms are decoded as follows (javascript -> erlang): %%
    %%
  • {"key": "value"} -> %% {struct, [{<<"key">>, <<"value">>}]}
  • %%
  • ["array", 123, 12.34, true, false, null] -> %% [<<"array">>, 123, 12.34, true, false, null] %%
  • %%
%%
    %%
  • Strings in JSON decode to UTF-8 binaries in Erlang
  • %%
  • Objects decode to {struct, PropList}
  • %%
  • Numbers decode to integer or float
  • %%
  • true, false, null decode to their respective terms.
  • %%
%% The encoder will accept the same format that the decoder will produce, %% but will also allow additional cases for leniency: %%
    %%
  • atoms other than true, false, null will be considered UTF-8 %% strings (even as a proplist key) %%
  • %%
  • {json, IoList} will insert IoList directly into the output %% with no validation %%
  • %%
  • {array, Array} will be encoded as Array %% (legacy mochijson style) %%
  • %%
  • A non-empty raw proplist will be encoded as an object as long %% as the first pair does not have an atom key of json, struct, %% or array %%
  • %%
-module(mochijson2_fork). -author('bob@mochimedia.com'). -export([encoder/1, encode/1]). -export([decoder/1, decode/1, decode/2]). %% This is a macro to placate syntax highlighters.. -define(Q, $\"). -define(ADV_COL(S, N), S#decoder{offset=N+S#decoder.offset, column=N+S#decoder.column}). -define(INC_COL(S), S#decoder{offset=1+S#decoder.offset, column=1+S#decoder.column}). -define(INC_LINE(S), S#decoder{offset=1+S#decoder.offset, column=1, line=1+S#decoder.line}). -define(INC_CHAR(S, C), case C of $\n -> S#decoder{column=1, line=1+S#decoder.line, offset=1+S#decoder.offset}; _ -> S#decoder{column=1+S#decoder.column, offset=1+S#decoder.offset} end). -define(IS_WHITESPACE(C), (C =:= $\s orelse C =:= $\t orelse C =:= $\r orelse C =:= $\n)). %% -type(decoder_option() :: any()). %% -type(handler_option() :: any()). %% -type(json_string() :: atom | binary()). %% -type(json_number() :: integer() | float()). %% -type(json_array() :: [json_term()]). %% -type(json_object() :: {struct, [{json_string(), json_term()}]}). %% -type(json_eep18_object() :: {[{json_string(), json_term()}]}). %% -type(json_iolist() :: {json, iolist()}). %% -type(json_term() :: json_string() | json_number() | json_array() | %% json_object() | json_eep18_object() | json_iolist()). -record(encoder, {handler=null, utf8=false}). -record(decoder, {object_hook=null, offset=0, line=1, column=1, state=null}). %% -type(utf8_option() :: boolean()). %% -type(encoder_option() :: handler_option() | utf8_option()). %% -spec encoder([encoder_option()]) -> function(). %% @doc Create an encoder/1 with the given options. %% Emit unicode as utf8 (default - false) encoder(Options) -> State = parse_encoder_options(Options, #encoder{}), fun (O) -> json_encode(O, State) end. %% -spec encode(json_term()) -> iolist(). %% @doc Encode the given as JSON to an iolist. encode(Any) -> json_encode(Any, #encoder{}). %% -spec decoder([decoder_option()]) -> function(). %% @doc Create a decoder/1 with the given options. decoder(Options) -> State = parse_decoder_options(Options, #decoder{}), fun (O) -> json_decode(O, State) end. %% -spec decode(iolist(), [{format, proplist | eep18 | struct}]) -> json_term(). %% @doc Decode the given iolist to Erlang terms using the given object format %% for decoding, where proplist returns JSON objects as [{binary(), json_term()}] %% proplists, eep18 returns JSON objects as {[binary(), json_term()]}, and struct %% returns them as-is. decode(S, Options) -> json_decode(S, parse_decoder_options(Options, #decoder{})). %% -spec decode(iolist()) -> json_term(). %% @doc Decode the given iolist to Erlang terms. decode(S) -> json_decode(S, #decoder{}). %% Internal API parse_encoder_options([], State) -> State; parse_encoder_options([{handler, Handler} | Rest], State) -> parse_encoder_options(Rest, State#encoder{handler=Handler}); parse_encoder_options([{utf8, Switch} | Rest], State) -> parse_encoder_options(Rest, State#encoder{utf8=Switch}). parse_decoder_options([], State) -> State; parse_decoder_options([{object_hook, Hook} | Rest], State) -> parse_decoder_options(Rest, State#decoder{object_hook=Hook}); parse_decoder_options([{format, Format} | Rest], State) when Format =:= struct orelse Format =:= eep18 orelse Format =:= proplist -> parse_decoder_options(Rest, State#decoder{object_hook=Format}). json_encode(true, _State) -> <<"true">>; json_encode(false, _State) -> <<"false">>; json_encode(null, _State) -> <<"null">>; json_encode(I, _State) when is_integer(I) -> integer_to_list(I); json_encode(F, _State) when is_float(F) -> mochinum_fork:digits(F); json_encode(S, State) when is_binary(S); is_atom(S) -> json_encode_string(S, State); json_encode([{K, _}|_] = Props, State) when (K =/= struct andalso K =/= array andalso K =/= json) -> json_encode_proplist(Props, State); json_encode({struct, Props}, State) when is_list(Props) -> json_encode_proplist(Props, State); json_encode({Props}, State) when is_list(Props) -> json_encode_proplist(Props, State); json_encode({}, State) -> json_encode_proplist([], State); json_encode(Array, State) when is_list(Array) -> json_encode_array(Array, State); json_encode({array, Array}, State) when is_list(Array) -> json_encode_array(Array, State); json_encode({json, IoList}, _State) -> IoList; json_encode(Bad, #encoder{handler=null}) -> exit({json_encode, {bad_term, Bad}}); json_encode(Bad, State=#encoder{handler=Handler}) -> json_encode(Handler(Bad), State). json_encode_array([], _State) -> <<"[]">>; json_encode_array(L, State) -> F = fun (O, Acc) -> [$,, json_encode(O, State) | Acc] end, [$, | Acc1] = lists:foldl(F, "[", L), lists:reverse([$\] | Acc1]). json_encode_proplist([], _State) -> <<"{}">>; json_encode_proplist(Props, State) -> F = fun ({K, V}, Acc) -> KS = json_encode_string(K, State), VS = json_encode(V, State), [$,, VS, $:, KS | Acc] end, [$, | Acc1] = lists:foldl(F, "{", Props), lists:reverse([$\} | Acc1]). json_encode_string(A, State) when is_atom(A) -> L = atom_to_list(A), case json_string_is_safe(L) of true -> [?Q, L, ?Q]; false -> json_encode_string_unicode(xmerl_ucs:from_utf8(L), State, [?Q]) end; json_encode_string(B, State) when is_binary(B) -> case json_bin_is_safe(B) of true -> [?Q, B, ?Q]; false -> json_encode_string_unicode(xmerl_ucs:from_utf8(B), State, [?Q]) end; json_encode_string(I, _State) when is_integer(I) -> [?Q, integer_to_list(I), ?Q]; json_encode_string(L, State) when is_list(L) -> case json_string_is_safe(L) of true -> [?Q, L, ?Q]; false -> json_encode_string_unicode(L, State, [?Q]) end. json_string_is_safe([]) -> true; json_string_is_safe([C | Rest]) -> case C of ?Q -> false; $\\ -> false; $\b -> false; $\f -> false; $\n -> false; $\r -> false; $\t -> false; C when C >= 0, C < $\s; C >= 16#7f, C =< 16#10FFFF -> false; C when C < 16#7f -> json_string_is_safe(Rest); _ -> false end. json_bin_is_safe(<<>>) -> true; json_bin_is_safe(<>) -> case C of ?Q -> false; $\\ -> false; $\b -> false; $\f -> false; $\n -> false; $\r -> false; $\t -> false; C when C >= 0, C < $\s; C >= 16#7f -> false; C when C < 16#7f -> json_bin_is_safe(Rest) end. json_encode_string_unicode([], _State, Acc) -> lists:reverse([$\" | Acc]); json_encode_string_unicode([C | Cs], State, Acc) -> Acc1 = case C of ?Q -> [?Q, $\\ | Acc]; %% Escaping solidus is only useful when trying to protect %% against "" injection attacks which are only %% possible when JSON is inserted into a HTML document %% in-line. mochijson2 does not protect you from this, so %% if you do insert directly into HTML then you need to %% uncomment the following case or escape the output of encode. %% %% $/ -> %% [$/, $\\ | Acc]; %% $\\ -> [$\\, $\\ | Acc]; $\b -> [$b, $\\ | Acc]; $\f -> [$f, $\\ | Acc]; $\n -> [$n, $\\ | Acc]; $\r -> [$r, $\\ | Acc]; $\t -> [$t, $\\ | Acc]; C when C >= 0, C < $\s -> [unihex(C) | Acc]; C when C >= 16#7f, C =< 16#10FFFF, State#encoder.utf8 -> [xmerl_ucs:to_utf8(C) | Acc]; C when C >= 16#7f, C =< 16#10FFFF, not State#encoder.utf8 -> [unihex(C) | Acc]; C when C < 16#7f -> [C | Acc]; _ -> exit({json_encode, {bad_char, C}}) end, json_encode_string_unicode(Cs, State, Acc1). hexdigit(C) when C >= 0, C =< 9 -> C + $0; hexdigit(C) when C =< 15 -> C + $a - 10. unihex(C) when C < 16#10000 -> <> = <>, Digits = [hexdigit(D) || D <- [D3, D2, D1, D0]], [$\\, $u | Digits]; unihex(C) when C =< 16#10FFFF -> N = C - 16#10000, S1 = 16#d800 bor ((N bsr 10) band 16#3ff), S2 = 16#dc00 bor (N band 16#3ff), [unihex(S1), unihex(S2)]. json_decode(L, S) when is_list(L) -> json_decode(iolist_to_binary(L), S); json_decode(B, S) -> {Res, S1} = decode1(B, S), {eof, _} = tokenize(B, S1#decoder{state=trim}), Res. decode1(B, S=#decoder{state=null}) -> case tokenize(B, S#decoder{state=any}) of {{const, C}, S1} -> {C, S1}; {start_array, S1} -> decode_array(B, S1); {start_object, S1} -> decode_object(B, S1) end. make_object(V, #decoder{object_hook=N}) when N =:= null orelse N =:= struct -> V; make_object({struct, P}, #decoder{object_hook=eep18}) -> {P}; make_object({struct, P}, #decoder{object_hook=proplist}) -> P; make_object(V, #decoder{object_hook=Hook}) -> Hook(V). decode_object(B, S) -> decode_object(B, S#decoder{state=key}, []). decode_object(B, S=#decoder{state=key}, Acc) -> case tokenize(B, S) of {end_object, S1} -> V = make_object({struct, lists:reverse(Acc)}, S1), {V, S1#decoder{state=null}}; {{const, K}, S1} -> {colon, S2} = tokenize(B, S1), {V, S3} = decode1(B, S2#decoder{state=null}), decode_object(B, S3#decoder{state=comma}, [{K, V} | Acc]) end; decode_object(B, S=#decoder{state=comma}, Acc) -> case tokenize(B, S) of {end_object, S1} -> V = make_object({struct, lists:reverse(Acc)}, S1), {V, S1#decoder{state=null}}; {comma, S1} -> decode_object(B, S1#decoder{state=key}, Acc) end. decode_array(B, S) -> decode_array(B, S#decoder{state=any}, []). decode_array(B, S=#decoder{state=any}, Acc) -> case tokenize(B, S) of {end_array, S1} -> {lists:reverse(Acc), S1#decoder{state=null}}; {start_array, S1} -> {Array, S2} = decode_array(B, S1), decode_array(B, S2#decoder{state=comma}, [Array | Acc]); {start_object, S1} -> {Array, S2} = decode_object(B, S1), decode_array(B, S2#decoder{state=comma}, [Array | Acc]); {{const, Const}, S1} -> decode_array(B, S1#decoder{state=comma}, [Const | Acc]) end; decode_array(B, S=#decoder{state=comma}, Acc) -> case tokenize(B, S) of {end_array, S1} -> {lists:reverse(Acc), S1#decoder{state=null}}; {comma, S1} -> decode_array(B, S1#decoder{state=any}, Acc) end. tokenize_string(B, S=#decoder{offset=O}) -> case tokenize_string_fast(B, O) of {escape, O1} -> Length = O1 - O, S1 = ?ADV_COL(S, Length), <<_:O/binary, Head:Length/binary, _/binary>> = B, tokenize_string(B, S1, lists:reverse(binary_to_list(Head))); O1 -> Length = O1 - O, <<_:O/binary, String:Length/binary, ?Q, _/binary>> = B, {{const, String}, ?ADV_COL(S, Length + 1)} end. tokenize_string_fast(B, O) -> case B of <<_:O/binary, ?Q, _/binary>> -> O; <<_:O/binary, $\\, _/binary>> -> {escape, O}; <<_:O/binary, C1, _/binary>> when C1 < 128 -> tokenize_string_fast(B, 1 + O); <<_:O/binary, C1, C2, _/binary>> when C1 >= 194, C1 =< 223, C2 >= 128, C2 =< 191 -> tokenize_string_fast(B, 2 + O); <<_:O/binary, C1, C2, C3, _/binary>> when C1 >= 224, C1 =< 239, C2 >= 128, C2 =< 191, C3 >= 128, C3 =< 191 -> tokenize_string_fast(B, 3 + O); <<_:O/binary, C1, C2, C3, C4, _/binary>> when C1 >= 240, C1 =< 244, C2 >= 128, C2 =< 191, C3 >= 128, C3 =< 191, C4 >= 128, C4 =< 191 -> tokenize_string_fast(B, 4 + O); _ -> throw(invalid_utf8) end. tokenize_string(B, S=#decoder{offset=O}, Acc) -> case B of <<_:O/binary, ?Q, _/binary>> -> {{const, iolist_to_binary(lists:reverse(Acc))}, ?INC_COL(S)}; <<_:O/binary, "\\\"", _/binary>> -> tokenize_string(B, ?ADV_COL(S, 2), [$\" | Acc]); <<_:O/binary, "\\\\", _/binary>> -> tokenize_string(B, ?ADV_COL(S, 2), [$\\ | Acc]); <<_:O/binary, "\\/", _/binary>> -> tokenize_string(B, ?ADV_COL(S, 2), [$/ | Acc]); <<_:O/binary, "\\b", _/binary>> -> tokenize_string(B, ?ADV_COL(S, 2), [$\b | Acc]); <<_:O/binary, "\\f", _/binary>> -> tokenize_string(B, ?ADV_COL(S, 2), [$\f | Acc]); <<_:O/binary, "\\n", _/binary>> -> tokenize_string(B, ?ADV_COL(S, 2), [$\n | Acc]); <<_:O/binary, "\\r", _/binary>> -> tokenize_string(B, ?ADV_COL(S, 2), [$\r | Acc]); <<_:O/binary, "\\t", _/binary>> -> tokenize_string(B, ?ADV_COL(S, 2), [$\t | Acc]); <<_:O/binary, "\\u", C3, C2, C1, C0, Rest/binary>> -> C = erlang:list_to_integer([C3, C2, C1, C0], 16), if C > 16#D7FF, C < 16#DC00 -> %% coalesce UTF-16 surrogate pair <<"\\u", D3, D2, D1, D0, _/binary>> = Rest, D = erlang:list_to_integer([D3,D2,D1,D0], 16), [CodePoint] = xmerl_ucs:from_utf16be(<>), Acc1 = lists:reverse(xmerl_ucs:to_utf8(CodePoint), Acc), tokenize_string(B, ?ADV_COL(S, 12), Acc1); true -> R = if C < 16#FFFE -> xmerl_ucs:to_utf8(C); true -> [16#E0 + (C bsr 12), 128+((C bsr 6) band 16#3F), 128+(C band 16#3F)] end, Acc1 = lists:reverse(R, Acc), tokenize_string(B, ?ADV_COL(S, 6), Acc1) end; <<_:O/binary, C1, _/binary>> when C1 < 128 -> tokenize_string(B, ?INC_CHAR(S, C1), [C1 | Acc]); <<_:O/binary, C1, C2, _/binary>> when C1 >= 194, C1 =< 223, C2 >= 128, C2 =< 191 -> tokenize_string(B, ?ADV_COL(S, 2), [C2, C1 | Acc]); <<_:O/binary, C1, C2, C3, _/binary>> when C1 >= 224, C1 =< 239, C2 >= 128, C2 =< 191, C3 >= 128, C3 =< 191 -> tokenize_string(B, ?ADV_COL(S, 3), [C3, C2, C1 | Acc]); <<_:O/binary, C1, C2, C3, C4, _/binary>> when C1 >= 240, C1 =< 244, C2 >= 128, C2 =< 191, C3 >= 128, C3 =< 191, C4 >= 128, C4 =< 191 -> tokenize_string(B, ?ADV_COL(S, 4), [C4, C3, C2, C1 | Acc]); _ -> throw(invalid_utf8) end. tokenize_number(B, S) -> case tokenize_number(B, sign, S, []) of {{int, Int}, S1} -> {{const, list_to_integer(Int)}, S1}; {{float, Float}, S1} -> {{const, list_to_float(Float)}, S1} end. tokenize_number(B, sign, S=#decoder{offset=O}, []) -> case B of <<_:O/binary, $-, _/binary>> -> tokenize_number(B, int, ?INC_COL(S), [$-]); _ -> tokenize_number(B, int, S, []) end; tokenize_number(B, int, S=#decoder{offset=O}, Acc) -> case B of <<_:O/binary, $0, _/binary>> -> tokenize_number(B, frac, ?INC_COL(S), [$0 | Acc]); <<_:O/binary, C, _/binary>> when C >= $1 andalso C =< $9 -> tokenize_number(B, int1, ?INC_COL(S), [C | Acc]) end; tokenize_number(B, int1, S=#decoder{offset=O}, Acc) -> case B of <<_:O/binary, C, _/binary>> when C >= $0 andalso C =< $9 -> tokenize_number(B, int1, ?INC_COL(S), [C | Acc]); _ -> tokenize_number(B, frac, S, Acc) end; tokenize_number(B, frac, S=#decoder{offset=O}, Acc) -> case B of <<_:O/binary, $., C, _/binary>> when C >= $0, C =< $9 -> tokenize_number(B, frac1, ?ADV_COL(S, 2), [C, $. | Acc]); <<_:O/binary, E, _/binary>> when E =:= $e orelse E =:= $E -> tokenize_number(B, esign, ?INC_COL(S), [$e, $0, $. | Acc]); _ -> {{int, lists:reverse(Acc)}, S} end; tokenize_number(B, frac1, S=#decoder{offset=O}, Acc) -> case B of <<_:O/binary, C, _/binary>> when C >= $0 andalso C =< $9 -> tokenize_number(B, frac1, ?INC_COL(S), [C | Acc]); <<_:O/binary, E, _/binary>> when E =:= $e orelse E =:= $E -> tokenize_number(B, esign, ?INC_COL(S), [$e | Acc]); _ -> {{float, lists:reverse(Acc)}, S} end; tokenize_number(B, esign, S=#decoder{offset=O}, Acc) -> case B of <<_:O/binary, C, _/binary>> when C =:= $- orelse C=:= $+ -> tokenize_number(B, eint, ?INC_COL(S), [C | Acc]); _ -> tokenize_number(B, eint, S, Acc) end; tokenize_number(B, eint, S=#decoder{offset=O}, Acc) -> case B of <<_:O/binary, C, _/binary>> when C >= $0 andalso C =< $9 -> tokenize_number(B, eint1, ?INC_COL(S), [C | Acc]) end; tokenize_number(B, eint1, S=#decoder{offset=O}, Acc) -> case B of <<_:O/binary, C, _/binary>> when C >= $0 andalso C =< $9 -> tokenize_number(B, eint1, ?INC_COL(S), [C | Acc]); _ -> {{float, lists:reverse(Acc)}, S} end. tokenize(B, S=#decoder{offset=O}) -> case B of <<_:O/binary, C, _/binary>> when ?IS_WHITESPACE(C) -> tokenize(B, ?INC_CHAR(S, C)); <<_:O/binary, "{", _/binary>> -> {start_object, ?INC_COL(S)}; <<_:O/binary, "}", _/binary>> -> {end_object, ?INC_COL(S)}; <<_:O/binary, "[", _/binary>> -> {start_array, ?INC_COL(S)}; <<_:O/binary, "]", _/binary>> -> {end_array, ?INC_COL(S)}; <<_:O/binary, ",", _/binary>> -> {comma, ?INC_COL(S)}; <<_:O/binary, ":", _/binary>> -> {colon, ?INC_COL(S)}; <<_:O/binary, "null", _/binary>> -> {{const, null}, ?ADV_COL(S, 4)}; <<_:O/binary, "true", _/binary>> -> {{const, true}, ?ADV_COL(S, 4)}; <<_:O/binary, "false", _/binary>> -> {{const, false}, ?ADV_COL(S, 5)}; <<_:O/binary, "\"", _/binary>> -> tokenize_string(B, ?INC_COL(S)); <<_:O/binary, C, _/binary>> when (C >= $0 andalso C =< $9) orelse C =:= $- -> tokenize_number(B, S); <<_:O/binary>> -> trim = S#decoder.state, {eof, S} end. %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). %% testing constructs borrowed from the Yaws JSON implementation. %% Create an object from a list of Key/Value pairs. obj_new() -> {struct, []}. is_obj({struct, Props}) -> F = fun ({K, _}) when is_binary(K) -> true end, lists:all(F, Props). obj_from_list(Props) -> Obj = {struct, Props}, ?assert(is_obj(Obj)), Obj. %% Test for equivalence of Erlang terms. %% Due to arbitrary order of construction, equivalent objects might %% compare unequal as erlang terms, so we need to carefully recurse %% through aggregates (tuples and objects). equiv({struct, Props1}, {struct, Props2}) -> equiv_object(Props1, Props2); equiv(L1, L2) when is_list(L1), is_list(L2) -> equiv_list(L1, L2); equiv(N1, N2) when is_number(N1), is_number(N2) -> N1 == N2; equiv(B1, B2) when is_binary(B1), is_binary(B2) -> B1 == B2; equiv(A, A) when A =:= true orelse A =:= false orelse A =:= null -> true. %% Object representation and traversal order is unknown. %% Use the sledgehammer and sort property lists. equiv_object(Props1, Props2) -> L1 = lists:keysort(1, Props1), L2 = lists:keysort(1, Props2), Pairs = lists:zip(L1, L2), true = lists:all(fun({{K1, V1}, {K2, V2}}) -> equiv(K1, K2) and equiv(V1, V2) end, Pairs). %% Recursively compare tuple elements for equivalence. equiv_list([], []) -> true; equiv_list([V1 | L1], [V2 | L2]) -> equiv(V1, V2) andalso equiv_list(L1, L2). decode_test() -> [1199344435545.0, 1] = decode(<<"[1199344435545.0,1]">>), <<16#F0,16#9D,16#9C,16#95>> = decode([34,"\\ud835","\\udf15",34]). e2j_vec_test() -> test_one(e2j_test_vec(utf8), 1). test_one([], _N) -> %% io:format("~p tests passed~n", [N-1]), ok; test_one([{E, J} | Rest], N) -> %% io:format("[~p] ~p ~p~n", [N, E, J]), true = equiv(E, decode(J)), true = equiv(E, decode(encode(E))), test_one(Rest, 1+N). e2j_test_vec(utf8) -> [ {1, "1"}, {3.1416, "3.14160"}, %% text representation may truncate, trail zeroes {-1, "-1"}, {-3.1416, "-3.14160"}, {12.0e10, "1.20000e+11"}, {1.234E+10, "1.23400e+10"}, {-1.234E-10, "-1.23400e-10"}, {10.0, "1.0e+01"}, {123.456, "1.23456E+2"}, {10.0, "1e1"}, {<<"foo">>, "\"foo\""}, {<<"foo", 5, "bar">>, "\"foo\\u0005bar\""}, {<<"">>, "\"\""}, {<<"\n\n\n">>, "\"\\n\\n\\n\""}, {<<"\" \b\f\r\n\t\"">>, "\"\\\" \\b\\f\\r\\n\\t\\\"\""}, {obj_new(), "{}"}, {obj_from_list([{<<"foo">>, <<"bar">>}]), "{\"foo\":\"bar\"}"}, {obj_from_list([{<<"foo">>, <<"bar">>}, {<<"baz">>, 123}]), "{\"foo\":\"bar\",\"baz\":123}"}, {[], "[]"}, {[[]], "[[]]"}, {[1, <<"foo">>], "[1,\"foo\"]"}, %% json array in a json object {obj_from_list([{<<"foo">>, [123]}]), "{\"foo\":[123]}"}, %% json object in a json object {obj_from_list([{<<"foo">>, obj_from_list([{<<"bar">>, true}])}]), "{\"foo\":{\"bar\":true}}"}, %% fold evaluation order {obj_from_list([{<<"foo">>, []}, {<<"bar">>, obj_from_list([{<<"baz">>, true}])}, {<<"alice">>, <<"bob">>}]), "{\"foo\":[],\"bar\":{\"baz\":true},\"alice\":\"bob\"}"}, %% json object in a json array {[-123, <<"foo">>, obj_from_list([{<<"bar">>, []}]), null], "[-123,\"foo\",{\"bar\":[]},null]"} ]. %% test utf8 encoding encoder_utf8_test() -> %% safe conversion case (default) [34,"\\u0001","\\u0442","\\u0435","\\u0441","\\u0442",34] = encode(<<1,"\321\202\320\265\321\201\321\202">>), %% raw utf8 output (optional) Enc = mochijson2:encoder([{utf8, true}]), [34,"\\u0001",[209,130],[208,181],[209,129],[209,130],34] = Enc(<<1,"\321\202\320\265\321\201\321\202">>). input_validation_test() -> Good = [ {16#00A3, <>}, %% pound {16#20AC, <>}, %% euro {16#10196, <>} %% denarius ], lists:foreach(fun({CodePoint, UTF8}) -> Expect = list_to_binary(xmerl_ucs:to_utf8(CodePoint)), Expect = decode(UTF8) end, Good), Bad = [ %% 2nd, 3rd, or 4th byte of a multi-byte sequence w/o leading byte <>, %% missing continuations, last byte in each should be 80-BF <>, <>, <>, %% we don't support code points > 10FFFF per RFC 3629 <>, %% escape characters trigger a different code path <> ], lists:foreach( fun(X) -> ok = try decode(X) catch invalid_utf8 -> ok end, %% could be {ucs,{bad_utf8_character_code}} or %% {json_encode,{bad_char,_}} {'EXIT', _} = (catch encode(X)) end, Bad). inline_json_test() -> ?assertEqual(<<"\"iodata iodata\"">>, iolist_to_binary( encode({json, [<<"\"iodata">>, " iodata\""]}))), ?assertEqual({struct, [{<<"key">>, <<"iodata iodata">>}]}, decode( encode({struct, [{key, {json, [<<"\"iodata">>, " iodata\""]}}]}))), ok. big_unicode_test() -> UTF8Seq = list_to_binary(xmerl_ucs:to_utf8(16#0001d120)), ?assertEqual( <<"\"\\ud834\\udd20\"">>, iolist_to_binary(encode(UTF8Seq))), ?assertEqual( UTF8Seq, decode(iolist_to_binary(encode(UTF8Seq)))), ok. custom_decoder_test() -> ?assertEqual( {struct, [{<<"key">>, <<"value">>}]}, (decoder([]))("{\"key\": \"value\"}")), F = fun ({struct, [{<<"key">>, <<"value">>}]}) -> win end, ?assertEqual( win, (decoder([{object_hook, F}]))("{\"key\": \"value\"}")), ok. atom_test() -> %% JSON native atoms [begin ?assertEqual(A, decode(atom_to_list(A))), ?assertEqual(iolist_to_binary(atom_to_list(A)), iolist_to_binary(encode(A))) end || A <- [true, false, null]], %% Atom to string ?assertEqual( <<"\"foo\"">>, iolist_to_binary(encode(foo))), ?assertEqual( <<"\"\\ud834\\udd20\"">>, iolist_to_binary(encode(list_to_atom(xmerl_ucs:to_utf8(16#0001d120))))), ok. key_encode_test() -> %% Some forms are accepted as keys that would not be strings in other %% cases ?assertEqual( <<"{\"foo\":1}">>, iolist_to_binary(encode({struct, [{foo, 1}]}))), ?assertEqual( <<"{\"foo\":1}">>, iolist_to_binary(encode({struct, [{<<"foo">>, 1}]}))), ?assertEqual( <<"{\"foo\":1}">>, iolist_to_binary(encode({struct, [{"foo", 1}]}))), ?assertEqual( <<"{\"foo\":1}">>, iolist_to_binary(encode([{foo, 1}]))), ?assertEqual( <<"{\"foo\":1}">>, iolist_to_binary(encode([{<<"foo">>, 1}]))), ?assertEqual( <<"{\"foo\":1}">>, iolist_to_binary(encode([{"foo", 1}]))), ?assertEqual( <<"{\"\\ud834\\udd20\":1}">>, iolist_to_binary( encode({struct, [{[16#0001d120], 1}]}))), ?assertEqual( <<"{\"1\":1}">>, iolist_to_binary(encode({struct, [{1, 1}]}))), ok. unsafe_chars_test() -> Chars = "\"\\\b\f\n\r\t", [begin ?assertEqual(false, json_string_is_safe([C])), ?assertEqual(false, json_bin_is_safe(<>)), ?assertEqual(<>, decode(encode(<>))) end || C <- Chars], ?assertEqual( false, json_string_is_safe([16#0001d120])), ?assertEqual( false, json_bin_is_safe(list_to_binary(xmerl_ucs:to_utf8(16#0001d120)))), ?assertEqual( [16#0001d120], xmerl_ucs:from_utf8( binary_to_list( decode(encode(list_to_atom(xmerl_ucs:to_utf8(16#0001d120))))))), ?assertEqual( false, json_string_is_safe([16#110000])), ?assertEqual( false, json_bin_is_safe(list_to_binary(xmerl_ucs:to_utf8([16#110000])))), %% solidus can be escaped but isn't unsafe by default ?assertEqual( <<"/">>, decode(<<"\"\\/\"">>)), ok. int_test() -> ?assertEqual(0, decode("0")), ?assertEqual(1, decode("1")), ?assertEqual(11, decode("11")), ok. large_int_test() -> ?assertEqual(<<"-2147483649214748364921474836492147483649">>, iolist_to_binary(encode(-2147483649214748364921474836492147483649))), ?assertEqual(<<"2147483649214748364921474836492147483649">>, iolist_to_binary(encode(2147483649214748364921474836492147483649))), ok. float_test() -> ?assertEqual(<<"-2147483649.0">>, iolist_to_binary(encode(-2147483649.0))), ?assertEqual(<<"2147483648.0">>, iolist_to_binary(encode(2147483648.0))), ok. handler_test() -> ?assertEqual( {'EXIT',{json_encode,{bad_term,{x,y}}}}, catch encode({x,y})), F = fun ({x,y}) -> [] end, ?assertEqual( <<"[]">>, iolist_to_binary((encoder([{handler, F}]))({x, y}))), ok. encode_empty_test_() -> [{A, ?_assertEqual(<<"{}">>, iolist_to_binary(encode(B)))} || {A, B} <- [{"eep18 {}", {}}, {"eep18 {[]}", {[]}}, {"{struct, []}", {struct, []}}]]. encode_test_() -> P = [{<<"k">>, <<"v">>}], JSON = iolist_to_binary(encode({struct, P})), [{atom_to_list(F), ?_assertEqual(JSON, iolist_to_binary(encode(decode(JSON, [{format, F}]))))} || F <- [struct, eep18, proplist]]. format_test_() -> P = [{<<"k">>, <<"v">>}], JSON = iolist_to_binary(encode({struct, P})), [{atom_to_list(F), ?_assertEqual(A, decode(JSON, [{format, F}]))} || {F, A} <- [{struct, {struct, P}}, {eep18, {P}}, {proplist, P}]]. -endif. rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/src/sockjs_handler.erl0000644000177700017770000002240212633765070032751 0ustar michaelmichael-module(sockjs_handler). -export([init_state/4]). -export([is_valid_ws/2, get_action/2]). -export([dispatch_req/2, handle_req/2]). -export([extract_info/1]). -include("sockjs_internal.hrl"). -define(SOCKJS_URL, "http://cdn.sockjs.org/sockjs-0.2.js"). %% -------------------------------------------------------------------------- %% -spec init_state(binary(), callback(), any(), list(tuple())) -> service(). init_state(Prefix, Callback, State, Options) -> #service{prefix = binary_to_list(Prefix), callback = Callback, state = State, sockjs_url = proplists:get_value(sockjs_url, Options, ?SOCKJS_URL), websocket = proplists:get_value(websocket, Options, true), cookie_needed = proplists:get_value(cookie_needed, Options, false), disconnect_delay = proplists:get_value(disconnect_delay, Options, 5000), heartbeat_delay = proplists:get_value(heartbeat_delay, Options, 25000), response_limit = proplists:get_value(response_limit, Options, 128*1024), logger = proplists:get_value(logger, Options, fun default_logger/3), subproto_pref = proplists:get_value(subproto_pref, Options) }. %% -------------------------------------------------------------------------- %% -spec is_valid_ws(service(), req()) -> {boolean(), req(), tuple()}. is_valid_ws(Service, Req) -> case get_action(Service, Req) of {{match, WS}, Req1} when WS =:= websocket orelse WS =:= rawwebsocket -> valid_ws_request(Service, Req1); {_Else, Req1} -> {false, Req1, {}} end. %% -spec valid_ws_request(service(), req()) -> {boolean(), req(), tuple()}. valid_ws_request(_Service, Req) -> {R1, Req1} = valid_ws_upgrade(Req), {R2, Req2} = valid_ws_connection(Req1), {R1 and R2, Req2, {R1, R2}}. valid_ws_upgrade(Req) -> case sockjs_http:header('Upgrade', Req) of {undefined, Req2} -> {false, Req2}; {V, Req2} -> case string:to_lower(V) of "websocket" -> {true, Req2}; _Else -> {false, Req2} end end. valid_ws_connection(Req) -> case sockjs_http:header('Connection', Req) of {undefined, Req2} -> {false, Req2}; {V, Req2} -> Vs = [string:strip(T) || T <- string:tokens(string:to_lower(V), ",")], {lists:member("upgrade", Vs), Req2} end. %% -spec get_action(service(), req()) -> {nomatch | {match, atom()}, req()}. get_action(Service, Req) -> {Dispatch, Req1} = dispatch_req(Service, Req), case Dispatch of {match, {_, Action, _, _, _}} -> {{match, Action}, Req1}; _Else -> {nomatch, Req1} end. %% -------------------------------------------------------------------------- strip_prefix(LongPath, Prefix) -> {A, B} = lists:split(length(Prefix), LongPath), case Prefix of A -> {ok, B}; _Any -> {error, io_lib:format("Wrong prefix: ~p is not ~p", [A, Prefix])} end. %% -type(dispatch_result() :: %% nomatch | %% {match, {send | recv | none , atom(), %% server(), session(), list(atom())}} | %% {bad_method, list(atom())}). %% -spec dispatch_req(service(), req()) -> {dispatch_result(), req()}. dispatch_req(#service{prefix = Prefix}, Req) -> {Method, Req1} = sockjs_http:method(Req), {LongPath, Req2} = sockjs_http:path(Req1), {ok, PathRemainder} = strip_prefix(LongPath, Prefix), {dispatch(Method, PathRemainder), Req2}. %% -spec dispatch(atom(), nonempty_string()) -> dispatch_result(). dispatch(Method, Path) -> lists:foldl( fun ({Match, MethodFilters}, nomatch) -> case Match(Path) of nomatch -> nomatch; [Server, Session] -> case lists:keyfind(Method, 1, MethodFilters) of false -> Methods = [ K || {K, _, _, _} <- MethodFilters], {bad_method, Methods}; {_Method, Type, A, Filters} -> {match, {Type, A, Server, Session, Filters}} end end; (_, Result) -> Result end, nomatch, filters()). %% -------------------------------------------------------------------------- filters() -> OptsFilters = [h_sid, xhr_cors, cache_for, xhr_options_post], %% websocket does not actually go via handle_req/3 but we need %% something in dispatch/2 [{t("/websocket"), [{'GET', none, websocket, []}]}, {t("/xhr_send"), [{'POST', recv, xhr_send, [h_sid, h_no_cache, xhr_cors]}, {'OPTIONS', none, options, OptsFilters}]}, {t("/xhr"), [{'POST', send, xhr_polling, [h_sid, h_no_cache, xhr_cors]}, {'OPTIONS', none, options, OptsFilters}]}, {t("/xhr_streaming"), [{'POST', send, xhr_streaming, [h_sid, h_no_cache, xhr_cors]}, {'OPTIONS', none, options, OptsFilters}]}, {t("/jsonp_send"), [{'POST', recv, jsonp_send, [h_sid, h_no_cache]}]}, {t("/jsonp"), [{'GET', send, jsonp, [h_sid, h_no_cache]}]}, {t("/eventsource"), [{'GET', send, eventsource, [h_sid, h_no_cache]}]}, {t("/htmlfile"), [{'GET', send, htmlfile, [h_sid, h_no_cache]}]}, {p("/websocket"), [{'GET', none, rawwebsocket, []}]}, {p(""), [{'GET', none, welcome_screen, []}]}, {p("/iframe[0-9-.a-z_]*.html"), [{'GET', none, iframe, [cache_for]}]}, {p("/info"), [{'GET', none, info_test, [h_no_cache, xhr_cors]}, {'OPTIONS', none, options, [h_sid, xhr_cors, cache_for, xhr_options_get]}]} ]. p(S) -> fun (Path) -> re(Path, "^" ++ S ++ "[/]?\$") end. t(S) -> fun (Path) -> re(Path, "^/([^/.]+)/([^/.]+)" ++ S ++ "[/]?\$") end. re(Path, S) -> case re:run(Path, S, [{capture, all_but_first, list}]) of nomatch -> nomatch; {match, []} -> [dummy, dummy]; {match, [Server, Session]} -> [Server, Session] end. %% -------------------------------------------------------------------------- %% -spec handle_req(service(), req()) -> req(). handle_req(Service = #service{logger = Logger}, Req) -> Req0 = Logger(Service, Req, http), {Dispatch, Req1} = dispatch_req(Service, Req0), handle(Dispatch, Service, Req1). handle(nomatch, _Service, Req) -> sockjs_http:reply(404, [], "", Req); handle({bad_method, Methods}, _Service, Req) -> MethodsStr = string:join([atom_to_list(M) || M <- Methods], ", "), H = [{"Allow", MethodsStr}], sockjs_http:reply(405, H, "", Req); handle({match, {Type, Action, _Server, Session, Filters}}, Service, Req) -> {Headers, Req2} = lists:foldl( fun (Filter, {Headers0, Req1}) -> sockjs_filters:Filter(Req1, Headers0) end, {[], Req}, Filters), case Type of send -> {Info, Req3} = extract_info(Req2), _SPid = sockjs_session:maybe_create(Session, Service, Info), sockjs_action:Action(Req3, Headers, Service, Session); recv -> try sockjs_action:Action(Req2, Headers, Service, Session) catch throw:no_session -> {H, Req3} = sockjs_filters:h_sid(Req2, []), sockjs_http:reply(404, H, "", Req3) end; none -> sockjs_action:Action(Req2, Headers, Service) end. %% -------------------------------------------------------------------------- %% -spec default_logger(service(), req(), websocket | http) -> req(). default_logger(_Service, Req, _Type) -> {LongPath, Req1} = sockjs_http:path(Req), {Method, Req2} = sockjs_http:method(Req1), io:format("~s ~s~n", [Method, LongPath]), Req2. %% -spec extract_info(req()) -> {info(), req()}. extract_info(Req) -> {Peer, Req0} = sockjs_http:peername(Req), {Sock, Req1} = sockjs_http:sockname(Req0), {Path, Req2} = sockjs_http:path(Req1), {Headers, Req3} = lists:foldl(fun (H, {Acc, R0}) -> case sockjs_http:header(H, R0) of {undefined, R1} -> {Acc, R1}; {V, R1} -> {[{H, V} | Acc], R1} end end, {[], Req2}, ['Referer', 'X-Client-Ip', 'X-Forwarded-For', 'X-Cluster-Client-Ip', 'Via', 'X-Real-Ip']), {[{peername, Peer}, {sockname, Sock}, {path, Path}, {headers, Headers}], Req3}. rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/src/sockjs_ws_handler.erl0000644000177700017770000000356212633765070033470 0ustar michaelmichael-module(sockjs_ws_handler). -export([received/3, reply/2, close/2]). -include("sockjs_internal.hrl"). %% -------------------------------------------------------------------------- %% -spec received(websocket|rawwebsocket, pid(), binary()) -> ok | shutdown. %% Ignore empty received(_RawWebsocket, _SessionPid, <<>>) -> ok; received(websocket, SessionPid, Data) -> case sockjs_json:decode(Data) of {ok, Msg} when is_binary(Msg) -> session_received([Msg], SessionPid); {ok, Messages} when is_list(Messages) -> session_received(Messages, SessionPid); _Else -> shutdown end; received(rawwebsocket, SessionPid, Data) -> session_received([Data], SessionPid). session_received(Messages, SessionPid) -> try sockjs_session:received(Messages, SessionPid) of ok -> ok catch no_session -> shutdown end. %% -spec reply(websocket|rawwebsocket, pid()) -> {close|open, binary()} | wait. reply(websocket, SessionPid) -> case sockjs_session:reply(SessionPid) of {W, Frame} when W =:= ok orelse W =:= close-> Frame1 = sockjs_util:encode_frame(Frame), {W, iolist_to_binary(Frame1)}; wait -> wait end; reply(rawwebsocket, SessionPid) -> case sockjs_session:reply(SessionPid, false) of {W, Frame} when W =:= ok orelse W =:= close-> case Frame of {open, nil} -> reply(rawwebsocket, SessionPid); {close, {_Code, _Reason}} -> {close, <<>>}; {data, [Msg]} -> {ok, iolist_to_binary(Msg)}; {heartbeat, nil} -> reply(rawwebsocket, SessionPid) end; wait -> wait end. %% -spec close(websocket|rawwebsocket, pid()) -> ok. close(_RawWebsocket, SessionPid) -> SessionPid ! force_shutdown, ok. ././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/src/sockjs_multiplex_channel.erlrabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/src/sockjs_multiplex_chann0000644000177700017770000000060612633765070033747 0ustar michaelmichael-compile({parse_transform,pmod_pt}). -module(sockjs_multiplex_channel, [Conn, Topic]). -export([send/1, close/0, close/2, info/0]). send(Data) -> Conn:send(iolist_to_binary(["msg", ",", Topic, ",", Data])). close() -> close(1000, "Normal closure"). close(_Code, _Reason) -> Conn:send(iolist_to_binary(["uns", ",", Topic])). info() -> Conn:info() ++ [{topic, Topic}]. rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/src/sockjs_util.erl0000644000177700017770000000232012633765070032306 0ustar michaelmichael-module(sockjs_util). -export([rand32/0]). -export([encode_frame/1]). -export([url_escape/2]). -include("sockjs_internal.hrl"). %% -------------------------------------------------------------------------- %% -spec rand32() -> non_neg_integer(). rand32() -> case get(random_seeded) of undefined -> {MegaSecs, Secs, MicroSecs} = now(), _ = random:seed(MegaSecs, Secs, MicroSecs), put(random_seeded, true); _Else -> ok end, random:uniform(erlang:trunc(math:pow(2,32)))-1. %% -spec encode_frame(frame()) -> iodata(). encode_frame({open, nil}) -> <<"o">>; encode_frame({close, {Code, Reason}}) -> [<<"c">>, sockjs_json:encode([Code, list_to_binary(Reason)])]; encode_frame({data, L}) -> [<<"a">>, sockjs_json:encode([iolist_to_binary(D) || D <- L])]; encode_frame({heartbeat, nil}) -> <<"h">>. %% -spec url_escape(string(), string()) -> iolist(). url_escape(Str, Chars) -> [case lists:member(Char, Chars) of true -> hex(Char); false -> Char end || Char <- Str]. hex(C) -> <> = <>, High = integer_to_list(High0), Low = integer_to_list(Low0), "%" ++ High ++ Low. rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/src/sockjs_session.erl0000644000177700017770000002734412633765070033031 0ustar michaelmichael-module(sockjs_session). -behaviour(gen_server). -export([init/0, start_link/3]). -export([maybe_create/3, reply/1, reply/2, received/2]). -export([send/2, close/3, info/1]). -export([init/1, handle_call/3, handle_info/2, terminate/2, code_change/3, handle_cast/2]). -include("sockjs_internal.hrl"). %% -type(handle() :: {?MODULE, {pid(), info()}}). -record(session, {id , %% session(), outbound_queue = queue:new() , %% queue() response_pid , %% pid() disconnect_tref , %% reference() disconnect_delay = 5000 , %% non_neg_integer() heartbeat_tref , %% reference() | triggered heartbeat_delay = 25000 , %% non_neg_integer() ready_state = connecting , %% connecting | open | closed close_msg , %% {non_neg_integer(), string()} callback, state, handle %% handle() }). -define(ETS, sockjs_table). %% -type(session_or_undefined() :: session() | undefined). %% -type(session_or_pid() :: session() | pid()). %% -------------------------------------------------------------------------- %% -spec init() -> ok. init() -> _ = ets:new(?ETS, [public, named_table]), ok. %% -spec start_link(session_or_undefined(), service(), info()) -> {ok, pid()}. start_link(SessionId, Service, Info) -> gen_server:start_link(?MODULE, {SessionId, Service, Info}, []). %% -spec maybe_create(session_or_undefined(), service(), info()) -> pid(). maybe_create(SessionId, Service, Info) -> case ets:lookup(?ETS, SessionId) of [] -> {ok, SPid} = sockjs_session_sup:start_child( SessionId, Service, Info), SPid; [{_, SPid}] -> SPid end. %% -spec received(list(iodata()), session_or_pid()) -> ok. received(Messages, SessionPid) when is_pid(SessionPid) -> case gen_server:call(SessionPid, {received, Messages}, infinity) of ok -> ok; error -> throw(no_session) %% TODO: should we respond 404 when session is closed? end; received(Messages, SessionId) -> received(Messages, spid(SessionId)). %% -spec send(iodata(), handle()) -> ok. send(Data, {?MODULE, {SPid, _}}) -> gen_server:cast(SPid, {send, Data}), ok. %% -spec close(non_neg_integer(), string(), handle()) -> ok. close(Code, Reason, {?MODULE, {SPid, _}}) -> gen_server:cast(SPid, {close, Code, Reason}), ok. %% -spec info(handle()) -> info(). info({?MODULE, {_SPid, Info}}) -> Info. %% -spec reply(session_or_pid()) -> %% wait | session_in_use | {ok | close, frame()}. reply(Session) -> reply(Session, true). %% -spec reply(session_or_pid(), boolean()) -> %% wait | session_in_use | {ok | close, frame()}. reply(SessionPid, Multiple) when is_pid(SessionPid) -> gen_server:call(SessionPid, {reply, self(), Multiple}, infinity); reply(SessionId, Multiple) -> reply(spid(SessionId), Multiple). %% -------------------------------------------------------------------------- cancel_timer_safe(Timer, Atom) -> case erlang:cancel_timer(Timer) of false -> receive Atom -> ok after 0 -> ok end; _ -> ok end. spid(SessionId) -> case ets:lookup(?ETS, SessionId) of [] -> throw(no_session); [{_, SPid}] -> SPid end. %% Mark a process as waiting for data. %% 1) The same process may ask for messages multiple times. mark_waiting(Pid, State = #session{response_pid = Pid, disconnect_tref = undefined}) -> State; %% 2) Noone else waiting - link and start heartbeat timeout. mark_waiting(Pid, State = #session{response_pid = undefined, disconnect_tref = DisconnectTRef, heartbeat_delay = HeartbeatDelay}) when DisconnectTRef =/= undefined -> link(Pid), cancel_timer_safe(DisconnectTRef, session_timeout), TRef = erlang:send_after(HeartbeatDelay, self(), heartbeat_triggered), State#session{response_pid = Pid, disconnect_tref = undefined, heartbeat_tref = TRef}. %% Prolong session lifetime. %% 1) Maybe clear up response_pid if already awaiting. unmark_waiting(RPid, State = #session{response_pid = RPid, heartbeat_tref = HeartbeatTRef, disconnect_tref = undefined, disconnect_delay = DisconnectDelay}) -> unlink(RPid), _ = case HeartbeatTRef of undefined -> ok; triggered -> ok; _Else -> cancel_timer_safe(HeartbeatTRef, heartbeat_triggered) end, TRef = erlang:send_after(DisconnectDelay, self(), session_timeout), State#session{response_pid = undefined, heartbeat_tref = undefined, disconnect_tref = TRef}; %% 2) prolong disconnect timer if no connection is waiting unmark_waiting(_Pid, State = #session{response_pid = undefined, disconnect_tref = DisconnectTRef, disconnect_delay = DisconnectDelay}) when DisconnectTRef =/= undefined -> cancel_timer_safe(DisconnectTRef, session_timeout), TRef = erlang:send_after(DisconnectDelay, self(), session_timeout), State#session{disconnect_tref = TRef}; %% 3) Event from someone else? Ignore. unmark_waiting(RPid, State = #session{response_pid = Pid, disconnect_tref = undefined}) when Pid =/= undefined andalso Pid =/= RPid -> State. %% -spec emit(emittable(), #session{}) -> #session{}. emit(What, State = #session{callback = Callback, state = UserState, handle = Handle}) -> R = case Callback of _ when is_function(Callback) -> Callback(Handle, What, UserState); _ when is_atom(Callback) -> case What of init -> Callback:sockjs_init(Handle, UserState); {recv, Data} -> Callback:sockjs_handle(Handle, Data, UserState); closed -> Callback:sockjs_terminate(Handle, UserState) end end, case R of {ok, UserState1} -> State#session{state = UserState1}; ok -> State end. %% -------------------------------------------------------------------------- %% -spec init({session_or_undefined(), service(), info()}) -> {ok, #session{}}. init({SessionId, #service{callback = Callback, state = UserState, disconnect_delay = DisconnectDelay, heartbeat_delay = HeartbeatDelay}, Info}) -> case SessionId of undefined -> ok; _Else -> ets:insert(?ETS, {SessionId, self()}) end, process_flag(trap_exit, true), TRef = erlang:send_after(DisconnectDelay, self(), session_timeout), {ok, #session{id = SessionId, callback = Callback, state = UserState, response_pid = undefined, disconnect_tref = TRef, disconnect_delay = DisconnectDelay, heartbeat_tref = undefined, heartbeat_delay = HeartbeatDelay, handle = {?MODULE, {self(), Info}}}}. handle_call({reply, Pid, _Multiple}, _From, State = #session{ response_pid = undefined, ready_state = connecting}) -> State0 = emit(init, State), State1 = unmark_waiting(Pid, State0), {reply, {ok, {open, nil}}, State1#session{ready_state = open}}; handle_call({reply, Pid, _Multiple}, _From, State = #session{ ready_state = closed, close_msg = CloseMsg}) -> State1 = unmark_waiting(Pid, State), {reply, {close, {close, CloseMsg}}, State1}; handle_call({reply, Pid, _Multiple}, _From, State = #session{ response_pid = RPid}) when RPid =/= Pid andalso RPid =/= undefined -> %% don't use unmark_waiting(), this shouldn't touch the session lifetime {reply, session_in_use, State}; handle_call({reply, Pid, Multiple}, _From, State = #session{ ready_state = open, response_pid = RPid, heartbeat_tref = HeartbeatTRef, outbound_queue = Q}) when RPid == undefined orelse RPid == Pid -> {Messages, Q1} = case Multiple of true -> {queue:to_list(Q), queue:new()}; false -> case queue:out(Q) of {{value, Msg}, Q2} -> {[Msg], Q2}; {empty, Q2} -> {[], Q2} end end, case {Messages, HeartbeatTRef} of {[], triggered} -> State1 = unmark_waiting(Pid, State), {reply, {ok, {heartbeat, nil}}, State1}; {[], _TRef} -> State1 = mark_waiting(Pid, State), {reply, wait, State1}; _More -> State1 = unmark_waiting(Pid, State), {reply, {ok, {data, Messages}}, State1#session{outbound_queue = Q1}} end; handle_call({received, Messages}, _From, State = #session{ready_state = open}) -> State2 = lists:foldl(fun(Msg, State1) -> emit({recv, iolist_to_binary(Msg)}, State1) end, State, Messages), {reply, ok, State2}; handle_call({received, _Data}, _From, State = #session{ready_state = _Any}) -> {reply, error, State}; handle_call(Request, _From, State) -> {stop, {odd_request, Request}, State}. handle_cast({send, Data}, State = #session{outbound_queue = Q, response_pid = RPid}) -> case RPid of undefined -> ok; _Else -> RPid ! go end, {noreply, State#session{outbound_queue = queue:in(Data, Q)}}; handle_cast({close, Status, Reason}, State = #session{response_pid = RPid}) -> case RPid of undefined -> ok; _Else -> RPid ! go end, {noreply, State#session{ready_state = closed, close_msg = {Status, Reason}}}; handle_cast(Cast, State) -> {stop, {odd_cast, Cast}, State}. handle_info({'EXIT', Pid, _Reason}, State = #session{response_pid = Pid}) -> %% It is illegal for a connection to go away when receiving, we %% may lose some messages that are in transit. Kill current %% session. {stop, normal, State#session{response_pid = undefined}}; handle_info(force_shutdown, State) -> %% Websockets may want to force closure sometimes {stop, normal, State}; handle_info(session_timeout, State = #session{response_pid = undefined}) -> {stop, normal, State}; handle_info(heartbeat_triggered, State = #session{response_pid = RPid}) when RPid =/= undefined -> RPid ! go, {noreply, State#session{heartbeat_tref = triggered}}; handle_info(Info, State) -> {stop, {odd_info, Info}, State}. terminate(_, State = #session{id = SessionId}) -> ets:delete(?ETS, SessionId), _ = emit(closed, State), ok. code_change(_OldVsn, State, _Extra) -> {ok, State}. rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/src/pmod_pt.erl0000644000177700017770000003244212633765070031427 0ustar michaelmichael%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 2013. 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(pmod_pt). -export([parse_transform/2, format_error/1]). %% Expand function definition forms of parameterized module. %% The code is based on the code in sys_expand_pmod which used to be %% included in the compiler, but details are different because %% sys_pre_expand has not been run. In particular: %% %% * Record definitions are still present and must be handled. %% %% * (Syntatic) local calls may actually be calls to an imported %% funtion or a BIF. It is a local call if and only if there %% is a definition for the function in the module. %% %% * When we introduce the module parameters and 'THIS' in each %% function, we must artificially use it to avoid a warning for %% unused variables. %% %% * On the other hand, we don't have to worry about module_info/0,1 %% because they have not been added yet. -record(pmod, {parameters, defined }). parse_transform(Forms0, _Options) -> put(?MODULE, []), Forms = transform(Forms0), case erase(?MODULE) of [] -> Forms; [_|_]=Errors -> File = get_file(Forms), {error,[{File,Errors}],[]} end. format_error(extends_self) -> "cannot extend from self"; format_error(define_instance) -> "defining instance function not allowed in parameterized module". add_error(Line, Error) -> put(?MODULE, get(?MODULE) ++ [{Line,?MODULE,Error}]). get_file([{attribute,_,file,{File,_}}|_]) -> File; get_file([_|T]) -> get_file(T). transform(Forms0) -> Def = collect_defined(Forms0), {Base,ModAs,Forms1} = attribs(Forms0, [], undefined, []), {Mod,Ps0} = case ModAs of {M0,P0} -> {M0,P0}; M0 -> {M0,undefined} end, Forms2 = case Ps0 of undefined -> Forms1; _ -> pmod_expand(Forms1, Mod, Base, Ps0, Def) end, %% Add new functions. NewFs0 = maybe_extend(Base, Mod, Ps0), NewExps = collect_defined(NewFs0), Forms3 = add_attributes(Forms2, [{attribute,0,export,NewExps}]), add_new_funcs(Forms3, NewFs0). pmod_expand(Forms0, Mod, Base, Ps0, Def) -> Ps = if is_atom(Base) -> ['BASE' | Ps0]; true -> Ps0 end, St0 = #pmod{parameters=Ps,defined=gb_sets:from_list(Def)}, {Forms1,_} = forms(Forms0, St0), Forms2 = update_exps(Forms1), Forms3 = update_forms(Forms2), NewFs0 = add_instance(Mod, Ps, []), NewFs = ensure_new(Base, Ps0, NewFs0), Forms = add_new_funcs(Forms3, NewFs), NewExps = collect_defined(NewFs), add_attributes(Forms, [{attribute,0,export,NewExps}]). add_attributes([{attribute,_,module,_}=F|Fs], Attrs) -> [F|Attrs++Fs]; add_attributes([F|Fs], Attrs) -> [F|add_attributes(Fs, Attrs)]. add_new_funcs([{eof,_}|_]=Fs, NewFs) -> NewFs ++ Fs; add_new_funcs([F|Fs], Es) -> [F|add_new_funcs(Fs, Es)]. maybe_extend([], _, _) -> %% No 'extends' attribute. []; maybe_extend(Base, _Mod, undefined) -> %% There is a an 'extends' attribute; the module is not parameterized. Name = '$handle_undefined_function', Args = [{var,0,'Func'},{var,0,'Args'}], Body = [make_apply({atom,0,Base}, {var,0,'Func'}, {var,0,'Args'})], F = {function,0,Name,2,[{clause,0,Args,[],Body}]}, [F]; maybe_extend(Base, Mod, Ps) -> %% There is a an 'extends' attribute; the module is parameterized. Name = '$handle_undefined_function', Args = [{var,0,'Func'},{var,0,'Args'}], DontCares = [{var,0,'_'} || _ <- Ps], TuplePs = {tuple,0,[{atom,0,Mod},{var,0,'BaseVars'}|DontCares]}, G = [{call,0,{atom,0,is_atom}, [{call,0,{atom,0,element}, [{integer,0,1},{var,0,'BaseVars'}]}]}], FixedArgs = make_lists_rev([{var,0,'Rs'}, {cons,0,{var,0,'BaseVars'},{nil,0}}]), Body = [{'case',0,make_lists_rev([{var,0,'Args'}]), [{clause,0,[{cons,0,TuplePs,{var,0,'Rs'}}],[G], [make_apply({atom,0,Base}, {var,0,'Func'}, FixedArgs)]}, {clause,0,[{var,0,'_'}],[], [make_apply({atom,0,Base}, {var,0,'Func'}, {var,0,'Args'})]} ]}], F = {function,0,Name,2,[{clause,0,Args,[],Body}]}, [F]. make_apply(M, F, A) -> {call,0,{remote,0,{atom,0,erlang},{atom,0,apply}},[M,F,A]}. make_lists_rev(As) -> {call,0,{remote,0,{atom,0,lists},{atom,0,reverse}},As}. ensure_new(Base, Ps, Fs) -> case has_new(Fs) of true -> Fs; false -> add_new(Base, Ps, Fs) end. has_new([{function,_L,new,_A,_Cs} | _Fs]) -> true; has_new([_ | Fs]) -> has_new(Fs); has_new([]) -> false. add_new(Base, Ps, Fs) -> Vs = [{var,0,V} || V <- Ps], As = if is_atom(Base) -> [{call,0,{remote,0,{atom,0,Base},{atom,0,new}},Vs} | Vs]; true -> Vs end, Body = [{call,0,{atom,0,instance},As}], add_func(new, Vs, Body, Fs). add_instance(Mod, Ps, Fs) -> Vs = [{var,0,V} || V <- Ps], AbsMod = [{tuple,0,[{atom,0,Mod}|Vs]}], add_func(instance, Vs, AbsMod, Fs). add_func(Name, Args, Body, Fs) -> A = length(Args), F = {function,0,Name,A,[{clause,0,Args,[],Body}]}, [F|Fs]. collect_defined(Fs) -> [{N,A} || {function,_,N,A,_} <- Fs]. attribs([{attribute,Line,module,{Mod,_}=ModAs}|T], Base, _, Acc) -> attribs(T, Base, ModAs, [{attribute,Line,module,Mod}|Acc]); attribs([{attribute,_,module,Mod}=H|T], Base, _, Acc) -> attribs(T, Base, Mod, [H|Acc]); attribs([{attribute,Line,extends,Base}|T], Base0, Ps, Acc) when is_atom(Base) -> Mod = case Ps of {Mod0,_} -> Mod0; Mod0 -> Mod0 end, case Mod of Base -> add_error(Line, extends_self), attribs(T, Base0, Ps, Acc); _ -> attribs(T, Base, Ps, Acc) end; attribs([H|T], Base, Ps, Acc) -> attribs(T, Base, Ps, [H|Acc]); attribs([], Base, Ps, Acc) -> {Base,Ps,lists:reverse(Acc)}. %% This is extremely simplistic for now; all functions get an extra %% parameter, whether they need it or not, except for static functions. update_function_name({F,A}) when F =/= new -> {F,A+1}; update_function_name(E) -> E. update_forms([{function,L,N,A,Cs}|Fs]) when N =/= new -> [{function,L,N,A+1,Cs}|update_forms(Fs)]; update_forms([F|Fs]) -> [F|update_forms(Fs)]; update_forms([]) -> []. update_exps([{attribute,Line,export,Es0}|T]) -> Es = [update_function_name(E) || E <- Es0], [{attribute,Line,export,Es}|update_exps(T)]; update_exps([H|T]) -> [H|update_exps(T)]; update_exps([]) -> []. %% Process the program forms. forms([F0|Fs0],St0) -> {F1,St1} = form(F0,St0), {Fs1,St2} = forms(Fs0,St1), {[F1|Fs1],St2}; forms([], St0) -> {[], St0}. %% Only function definitions are of interest here. State is not updated. form({function,Line,instance,_Arity,_Clauses}=F,St) -> add_error(Line, define_instance), {F,St}; form({function,Line,Name0,Arity0,Clauses0},St) when Name0 =/= new -> {Name,Arity,Clauses} = function(Name0, Arity0, Clauses0, St), {{function,Line,Name,Arity,Clauses},St}; %% Pass anything else through form(F,St) -> {F,St}. function(Name, Arity, Clauses0, St) -> Clauses1 = clauses(Clauses0,St), {Name,Arity,Clauses1}. clauses([C|Cs],#pmod{parameters=Ps}=St) -> {clause,L,H,G,B0} = clause(C,St), T = {tuple,L,[{var,L,V} || V <- ['_'|Ps]]}, B = [{match,L,{var,L,'_'},{var,L,V}} || V <- ['THIS'|Ps]] ++ B0, [{clause,L,H++[{match,L,T,{var,L,'THIS'}}],G,B}|clauses(Cs,St)]; clauses([],_St) -> []. clause({clause,Line,H,G,B0},St) -> %% We never update H and G, so we will just copy them. B1 = exprs(B0,St), {clause,Line,H,G,B1}. pattern_grp([{bin_element,L1,E1,S1,T1} | Fs],St) -> S2 = case S1 of default -> default; _ -> expr(S1,St) end, T2 = case T1 of default -> default; _ -> bit_types(T1) end, [{bin_element,L1,expr(E1,St),S2,T2} | pattern_grp(Fs,St)]; pattern_grp([],_St) -> []. bit_types([]) -> []; bit_types([Atom | Rest]) when is_atom(Atom) -> [Atom | bit_types(Rest)]; bit_types([{Atom, Integer} | Rest]) when is_atom(Atom), is_integer(Integer) -> [{Atom, Integer} | bit_types(Rest)]. exprs([E0|Es],St) -> E1 = expr(E0,St), [E1|exprs(Es,St)]; exprs([],_St) -> []. expr({var,_L,_V}=Var,_St) -> Var; expr({integer,_Line,_I}=Integer,_St) -> Integer; expr({float,_Line,_F}=Float,_St) -> Float; expr({atom,_Line,_A}=Atom,_St) -> Atom; expr({string,_Line,_S}=String,_St) -> String; expr({char,_Line,_C}=Char,_St) -> Char; expr({nil,_Line}=Nil,_St) -> Nil; expr({cons,Line,H0,T0},St) -> H1 = expr(H0,St), T1 = expr(T0,St), {cons,Line,H1,T1}; expr({lc,Line,E0,Qs0},St) -> Qs1 = lc_bc_quals(Qs0,St), E1 = expr(E0,St), {lc,Line,E1,Qs1}; expr({bc,Line,E0,Qs0},St) -> Qs1 = lc_bc_quals(Qs0,St), E1 = expr(E0,St), {bc,Line,E1,Qs1}; expr({tuple,Line,Es0},St) -> Es1 = expr_list(Es0,St), {tuple,Line,Es1}; expr({record,Line,Name,Is0},St) -> Is = record_fields(Is0,St), {record,Line,Name,Is}; expr({record,Line,E0,Name,Is0},St) -> E = expr(E0,St), Is = record_fields(Is0,St), {record,Line,E,Name,Is}; expr({record_field,Line,E0,Name,Key},St) -> E = expr(E0,St), {record_field,Line,E,Name,Key}; expr({block,Line,Es0},St) -> Es1 = exprs(Es0,St), {block,Line,Es1}; expr({'if',Line,Cs0},St) -> Cs1 = icr_clauses(Cs0,St), {'if',Line,Cs1}; expr({'case',Line,E0,Cs0},St) -> E1 = expr(E0,St), Cs1 = icr_clauses(Cs0,St), {'case',Line,E1,Cs1}; expr({'receive',Line,Cs0},St) -> Cs1 = icr_clauses(Cs0,St), {'receive',Line,Cs1}; expr({'receive',Line,Cs0,To0,ToEs0},St) -> To1 = expr(To0,St), ToEs1 = exprs(ToEs0,St), Cs1 = icr_clauses(Cs0,St), {'receive',Line,Cs1,To1,ToEs1}; expr({'try',Line,Es0,Scs0,Ccs0,As0},St) -> Es1 = exprs(Es0,St), Scs1 = icr_clauses(Scs0,St), Ccs1 = icr_clauses(Ccs0,St), As1 = exprs(As0,St), {'try',Line,Es1,Scs1,Ccs1,As1}; expr({'fun',_,{function,_,_,_}}=ExtFun,_St) -> ExtFun; expr({'fun',Line,Body},St) -> case Body of {clauses,Cs0} -> Cs1 = fun_clauses(Cs0,St), {'fun',Line,{clauses,Cs1}}; {function,F,A} = Function -> {F1,A1} = update_function_name({F,A}), if A1 =:= A -> {'fun',Line,Function}; true -> %% Must rewrite local fun-name to a fun that does a %% call with the extra THIS parameter. As = make_vars(A, Line), As1 = As ++ [{var,Line,'THIS'}], Call = {call,Line,{atom,Line,F1},As1}, Cs = [{clause,Line,As,[],[Call]}], {'fun',Line,{clauses,Cs}} end; {function,_M,_F,_A} = Fun4 -> %This is an error in lint! {'fun',Line,Fun4} end; expr({call,Lc,{atom,_,instance}=Name,As0},St) -> %% All local functions 'instance(...)' are static by definition, %% so they do not take a 'THIS' argument when called As1 = expr_list(As0,St), {call,Lc,Name,As1}; expr({call,Lc,{atom,_,new}=Name,As0},St) -> %% All local functions 'new(...)' are static by definition, %% so they do not take a 'THIS' argument when called As1 = expr_list(As0,St), {call,Lc,Name,As1}; expr({call,Lc,{atom,_Lf,F}=Atom,As0}, #pmod{defined=Def}=St) -> As1 = expr_list(As0,St), case gb_sets:is_member({F,length(As0)}, Def) of false -> %% BIF or imported function. {call,Lc,Atom,As1}; true -> %% Local function call - needs THIS parameter. {call,Lc,Atom,As1 ++ [{var,0,'THIS'}]} end; expr({call,Line,F0,As0},St) -> %% Other function call F1 = expr(F0,St), As1 = expr_list(As0,St), {call,Line,F1,As1}; expr({'catch',Line,E0},St) -> E1 = expr(E0,St), {'catch',Line,E1}; expr({match,Line,P,E0},St) -> E1 = expr(E0,St), {match,Line,P,E1}; expr({bin,Line,Fs},St) -> Fs2 = pattern_grp(Fs,St), {bin,Line,Fs2}; expr({op,Line,Op,A0},St) -> A1 = expr(A0,St), {op,Line,Op,A1}; expr({op,Line,Op,L0,R0},St) -> L1 = expr(L0,St), R1 = expr(R0,St), {op,Line,Op,L1,R1}; %% The following are not allowed to occur anywhere! expr({remote,Line,M0,F0},St) -> M1 = expr(M0,St), F1 = expr(F0,St), {remote,Line,M1,F1}. expr_list([E0|Es],St) -> E1 = expr(E0,St), [E1|expr_list(Es,St)]; expr_list([],_St) -> []. record_fields([{record_field,L,K,E0}|T],St) -> E = expr(E0,St), [{record_field,L,K,E}|record_fields(T,St)]; record_fields([],_) -> []. icr_clauses([C0|Cs],St) -> C1 = clause(C0,St), [C1|icr_clauses(Cs,St)]; icr_clauses([],_St) -> []. lc_bc_quals([{generate,Line,P,E0}|Qs],St) -> E1 = expr(E0,St), [{generate,Line,P,E1}|lc_bc_quals(Qs,St)]; lc_bc_quals([{b_generate,Line,P,E0}|Qs],St) -> E1 = expr(E0,St), [{b_generate,Line,P,E1}|lc_bc_quals(Qs,St)]; lc_bc_quals([E0|Qs],St) -> E1 = expr(E0,St), [E1|lc_bc_quals(Qs,St)]; lc_bc_quals([],_St) -> []. fun_clauses([C0|Cs],St) -> C1 = clause(C0,St), [C1|fun_clauses(Cs,St)]; fun_clauses([],_St) -> []. make_vars(N, L) -> make_vars(1, N, L). make_vars(N, M, L) when N =< M -> V = list_to_atom("X"++integer_to_list(N)), [{var,L,V} | make_vars(N + 1, M, L)]; make_vars(_, _, _) -> []. rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/src/sockjs.erl0000644000177700017770000000121612633765070031254 0ustar michaelmichael-module(sockjs). -export([send/2, close/1, close/3, info/1]). %% -type(conn() :: {sockjs_session, any()}). %% Send data over a connection. %% -spec send(iodata(), conn()) -> ok. send(Data, Conn = {sockjs_session, _}) -> sockjs_session:send(Data, Conn). %% Initiate a close of a connection. %% -spec close(conn()) -> ok. close(Conn) -> close(1000, "Normal closure", Conn). %% -spec close(non_neg_integer(), string(), conn()) -> ok. close(Code, Reason, Conn = {sockjs_session, _}) -> sockjs_session:close(Code, Reason, Conn). %% -spec info(conn()) -> [{atom(), any()}]. info(Conn = {sockjs_session, _}) -> sockjs_session:info(Conn). ././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/src/sockjs_cowboy_handler.erlrabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/src/sockjs_cowboy_handler.0000644000177700017770000000677512633765070033647 0ustar michaelmichael-module(sockjs_cowboy_handler). -behaviour(cowboy_http_handler). -behaviour(cowboy_http_websocket_handler). %% Cowboy http callbacks -export([init/3, handle/2, terminate/2]). %% Cowboy ws callbacks -export([websocket_init/3, websocket_handle/3, websocket_info/3, websocket_terminate/3]). -include("sockjs_internal.hrl"). %% -------------------------------------------------------------------------- init({_Any, http}, Req, Service) -> case sockjs_handler:is_valid_ws(Service, {cowboy, Req}) of {true, {cowboy, _Req1}, _Reason} -> {upgrade, protocol, cowboy_http_websocket}; {false, {cowboy, Req1}, _Reason} -> {ok, Req1, Service} end. handle(Req, Service) -> {cowboy, Req3} = sockjs_handler:handle_req(Service, {cowboy, Req}), {ok, Req3, Service}. terminate(_Req, _Service) -> ok. %% -------------------------------------------------------------------------- websocket_init(_TransportName, Req, Service = #service{logger = Logger, subproto_pref = SubProtocolPref}) -> Req3 = case cowboy_http_req:header(<<"Sec-Websocket-Protocol">>, Req) of {undefined, Req1} -> Req1; {SubProtocols, Req1} -> SelectedSubProtocol = choose_subprotocol_bin(SubProtocols, SubProtocolPref), {ok, Req2} = cowboy_http_req:set_resp_header( <<"Sec-Websocket-Protocol">>, SelectedSubProtocol, Req1), Req2 end, Req4 = Logger(Service, {cowboy, Req3}, websocket), Service1 = Service#service{disconnect_delay = 5*60*1000}, {Info, Req5} = sockjs_handler:extract_info(Req4), SessionPid = sockjs_session:maybe_create(undefined, Service1, Info), {RawWebsocket, {cowboy, Req7}} = case sockjs_handler:get_action(Service, Req5) of {{match, WS}, Req6} when WS =:= websocket orelse WS =:= rawwebsocket -> {WS, Req6} end, self() ! go, {ok, Req7, {RawWebsocket, SessionPid}}. websocket_handle({text, Data}, Req, {RawWebsocket, SessionPid} = S) -> case sockjs_ws_handler:received(RawWebsocket, SessionPid, Data) of ok -> {ok, Req, S}; shutdown -> {shutdown, Req, S} end; websocket_handle(_Unknown, Req, S) -> {shutdown, Req, S}. websocket_info(go, Req, {RawWebsocket, SessionPid} = S) -> case sockjs_ws_handler:reply(RawWebsocket, SessionPid) of wait -> {ok, Req, S}; {ok, Data} -> self() ! go, {reply, {text, Data}, Req, S}; {close, <<>>} -> {shutdown, Req, S}; {close, Data} -> self() ! shutdown, {reply, {text, Data}, Req, S} end; websocket_info(shutdown, Req, S) -> {shutdown, Req, S}. websocket_terminate(_Reason, _Req, {RawWebsocket, SessionPid}) -> sockjs_ws_handler:close(RawWebsocket, SessionPid), ok. %% -------------------------------------------------------------------------- choose_subprotocol_bin(SubProtocols, Pref) -> choose_subprotocol(re:split(SubProtocols, ", *"), Pref). choose_subprotocol(SubProtocols, undefined) -> erlang:hd(lists:reverse(lists:sort(SubProtocols))); choose_subprotocol(SubProtocols, Pref) -> case lists:filter(fun (E) -> lists:member(E, SubProtocols) end, Pref) of [Hd | _] -> Hd; [] -> choose_subprotocol(SubProtocols, undefined) end. rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/src/sockjs_app.erl0000644000177700017770000000040412633765070032112 0ustar michaelmichael-module(sockjs_app). -behaviour(application). -export([start/2, stop/1]). %% -spec start(_, _) -> {ok, pid()}. start(_StartType, _StartArgs) -> sockjs_session:init(), sockjs_session_sup:start_link(). %% -spec stop(_) -> ok. stop(_State) -> ok. rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/src/sockjs_internal.hrl0000644000177700017770000000250012633765070033150 0ustar michaelmichael %% -type(req() :: {cowboy, any()}). %% -type(user_session() :: nonempty_string()). %% -type(emittable() :: init|closed|{recv, binary()}). %% -type(callback() :: fun((user_session(), emittable(), any()) -> ok)). %% -type(logger() :: fun((any(), req(), websocket|http) -> req())). -record(service, {prefix , %% nonempty_string(), callback , %% callback() state , %% any() sockjs_url , %% nonempty_string() cookie_needed , %% boolean() websocket , %% boolean() disconnect_delay , %% non_neg_integer() heartbeat_delay , %% non_neg_integer() response_limit , %% non_neg_integer() logger , %% logger() subproto_pref %% [binary()] }). %% -type(service() :: #service{}). %% -type(headers() :: list({nonempty_string(), nonempty_string()})). %% -type(server() :: nonempty_string()). %% -type(session() :: nonempty_string()). %% -type(frame() :: {open, nil} | %% {close, {non_neg_integer(), string()}} | %% {data, list(iodata())} | %% {heartbeat, nil} ). %% -type(info() :: [{atom(), any()}]). rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/src/mochinum_fork.erl0000644000177700017770000002442012633765070032622 0ustar michaelmichael%% @copyright 2007 Mochi Media, Inc. %% @author Bob Ippolito %% @doc Useful numeric algorithms for floats that cover some deficiencies %% in the math module. More interesting is digits/1, which implements %% the algorithm from: %% http://www.cs.indiana.edu/~burger/fp/index.html %% See also "Printing Floating-Point Numbers Quickly and Accurately" %% in Proceedings of the SIGPLAN '96 Conference on Programming Language %% Design and Implementation. -module(mochinum_fork). -author("Bob Ippolito "). -export([digits/1, frexp/1, int_pow/2, int_ceil/1]). %% IEEE 754 Float exponent bias -define(FLOAT_BIAS, 1022). -define(MIN_EXP, -1074). -define(BIG_POW, 4503599627370496). %% External API %% @spec digits(number()) -> string() %% @doc Returns a string that accurately represents the given integer or float %% using a conservative amount of digits. Great for generating %% human-readable output, or compact ASCII serializations for floats. digits(N) when is_integer(N) -> integer_to_list(N); digits(0.0) -> "0.0"; digits(Float) -> {Frac1, Exp1} = frexp_int(Float), [Place0 | Digits0] = digits1(Float, Exp1, Frac1), {Place, Digits} = transform_digits(Place0, Digits0), R = insert_decimal(Place, Digits), case Float < 0 of true -> [$- | R]; _ -> R end. %% @spec frexp(F::float()) -> {Frac::float(), Exp::float()} %% @doc Return the fractional and exponent part of an IEEE 754 double, %% equivalent to the libc function of the same name. %% F = Frac * pow(2, Exp). frexp(F) -> frexp1(unpack(F)). %% @spec int_pow(X::integer(), N::integer()) -> Y::integer() %% @doc Moderately efficient way to exponentiate integers. %% int_pow(10, 2) = 100. int_pow(_X, 0) -> 1; int_pow(X, N) when N > 0 -> int_pow(X, N, 1). %% @spec int_ceil(F::float()) -> integer() %% @doc Return the ceiling of F as an integer. The ceiling is defined as %% F when F == trunc(F); %% trunc(F) when F < 0; %% trunc(F) + 1 when F > 0. int_ceil(X) -> T = trunc(X), case (X - T) of Pos when Pos > 0 -> T + 1; _ -> T end. %% Internal API int_pow(X, N, R) when N < 2 -> R * X; int_pow(X, N, R) -> int_pow(X * X, N bsr 1, case N band 1 of 1 -> R * X; 0 -> R end). insert_decimal(0, S) -> "0." ++ S; insert_decimal(Place, S) when Place > 0 -> L = length(S), case Place - L of 0 -> S ++ ".0"; N when N < 0 -> {S0, S1} = lists:split(L + N, S), S0 ++ "." ++ S1; N when N < 6 -> %% More places than digits S ++ lists:duplicate(N, $0) ++ ".0"; _ -> insert_decimal_exp(Place, S) end; insert_decimal(Place, S) when Place > -6 -> "0." ++ lists:duplicate(abs(Place), $0) ++ S; insert_decimal(Place, S) -> insert_decimal_exp(Place, S). insert_decimal_exp(Place, S) -> [C | S0] = S, S1 = case S0 of [] -> "0"; _ -> S0 end, Exp = case Place < 0 of true -> "e-"; false -> "e+" end, [C] ++ "." ++ S1 ++ Exp ++ integer_to_list(abs(Place - 1)). digits1(Float, Exp, Frac) -> Round = ((Frac band 1) =:= 0), case Exp >= 0 of true -> BExp = 1 bsl Exp, case (Frac =/= ?BIG_POW) of true -> scale((Frac * BExp * 2), 2, BExp, BExp, Round, Round, Float); false -> scale((Frac * BExp * 4), 4, (BExp * 2), BExp, Round, Round, Float) end; false -> case (Exp =:= ?MIN_EXP) orelse (Frac =/= ?BIG_POW) of true -> scale((Frac * 2), 1 bsl (1 - Exp), 1, 1, Round, Round, Float); false -> scale((Frac * 4), 1 bsl (2 - Exp), 2, 1, Round, Round, Float) end end. scale(R, S, MPlus, MMinus, LowOk, HighOk, Float) -> Est = int_ceil(math:log10(abs(Float)) - 1.0e-10), %% Note that the scheme implementation uses a 326 element look-up table %% for int_pow(10, N) where we do not. case Est >= 0 of true -> fixup(R, S * int_pow(10, Est), MPlus, MMinus, Est, LowOk, HighOk); false -> Scale = int_pow(10, -Est), fixup(R * Scale, S, MPlus * Scale, MMinus * Scale, Est, LowOk, HighOk) end. fixup(R, S, MPlus, MMinus, K, LowOk, HighOk) -> TooLow = case HighOk of true -> (R + MPlus) >= S; false -> (R + MPlus) > S end, case TooLow of true -> [(K + 1) | generate(R, S, MPlus, MMinus, LowOk, HighOk)]; false -> [K | generate(R * 10, S, MPlus * 10, MMinus * 10, LowOk, HighOk)] end. generate(R0, S, MPlus, MMinus, LowOk, HighOk) -> D = R0 div S, R = R0 rem S, TC1 = case LowOk of true -> R =< MMinus; false -> R < MMinus end, TC2 = case HighOk of true -> (R + MPlus) >= S; false -> (R + MPlus) > S end, case TC1 of false -> case TC2 of false -> [D | generate(R * 10, S, MPlus * 10, MMinus * 10, LowOk, HighOk)]; true -> [D + 1] end; true -> case TC2 of false -> [D]; true -> case R * 2 < S of true -> [D]; false -> [D + 1] end end end. unpack(Float) -> <> = <>, {Sign, Exp, Frac}. frexp1({_Sign, 0, 0}) -> {0.0, 0}; frexp1({Sign, 0, Frac}) -> Exp = log2floor(Frac), <> = <>, {Frac1, -(?FLOAT_BIAS) - 52 + Exp}; frexp1({Sign, Exp, Frac}) -> <> = <>, {Frac1, Exp - ?FLOAT_BIAS}. log2floor(Int) -> log2floor(Int, 0). log2floor(0, N) -> N; log2floor(Int, N) -> log2floor(Int bsr 1, 1 + N). transform_digits(Place, [0 | Rest]) -> transform_digits(Place, Rest); transform_digits(Place, Digits) -> {Place, [$0 + D || D <- Digits]}. frexp_int(F) -> case unpack(F) of {_Sign, 0, Frac} -> {Frac, ?MIN_EXP}; {_Sign, Exp, Frac} -> {Frac + (1 bsl 52), Exp - 53 - ?FLOAT_BIAS} end. %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). int_ceil_test() -> ?assertEqual(1, int_ceil(0.0001)), ?assertEqual(0, int_ceil(0.0)), ?assertEqual(1, int_ceil(0.99)), ?assertEqual(1, int_ceil(1.0)), ?assertEqual(-1, int_ceil(-1.5)), ?assertEqual(-2, int_ceil(-2.0)), ok. int_pow_test() -> ?assertEqual(1, int_pow(1, 1)), ?assertEqual(1, int_pow(1, 0)), ?assertEqual(1, int_pow(10, 0)), ?assertEqual(10, int_pow(10, 1)), ?assertEqual(100, int_pow(10, 2)), ?assertEqual(1000, int_pow(10, 3)), ok. digits_test() -> ?assertEqual("0", digits(0)), ?assertEqual("0.0", digits(0.0)), ?assertEqual("1.0", digits(1.0)), ?assertEqual("-1.0", digits(-1.0)), ?assertEqual("0.1", digits(0.1)), ?assertEqual("0.01", digits(0.01)), ?assertEqual("0.001", digits(0.001)), ?assertEqual("1.0e+6", digits(1000000.0)), ?assertEqual("0.5", digits(0.5)), ?assertEqual("4503599627370496.0", digits(4503599627370496.0)), %% small denormalized number %% 4.94065645841246544177e-324 =:= 5.0e-324 <> = <<0,0,0,0,0,0,0,1>>, ?assertEqual("5.0e-324", digits(SmallDenorm)), ?assertEqual(SmallDenorm, list_to_float(digits(SmallDenorm))), %% large denormalized number %% 2.22507385850720088902e-308 <> = <<0,15,255,255,255,255,255,255>>, ?assertEqual("2.225073858507201e-308", digits(BigDenorm)), ?assertEqual(BigDenorm, list_to_float(digits(BigDenorm))), %% small normalized number %% 2.22507385850720138309e-308 <> = <<0,16,0,0,0,0,0,0>>, ?assertEqual("2.2250738585072014e-308", digits(SmallNorm)), ?assertEqual(SmallNorm, list_to_float(digits(SmallNorm))), %% large normalized number %% 1.79769313486231570815e+308 <> = <<127,239,255,255,255,255,255,255>>, ?assertEqual("1.7976931348623157e+308", digits(LargeNorm)), ?assertEqual(LargeNorm, list_to_float(digits(LargeNorm))), %% issue #10 - mochinum:frexp(math:pow(2, -1074)). ?assertEqual("5.0e-324", digits(math:pow(2, -1074))), ok. frexp_test() -> %% zero ?assertEqual({0.0, 0}, frexp(0.0)), %% one ?assertEqual({0.5, 1}, frexp(1.0)), %% negative one ?assertEqual({-0.5, 1}, frexp(-1.0)), %% small denormalized number %% 4.94065645841246544177e-324 <> = <<0,0,0,0,0,0,0,1>>, ?assertEqual({0.5, -1073}, frexp(SmallDenorm)), %% large denormalized number %% 2.22507385850720088902e-308 <> = <<0,15,255,255,255,255,255,255>>, ?assertEqual( {0.99999999999999978, -1022}, frexp(BigDenorm)), %% small normalized number %% 2.22507385850720138309e-308 <> = <<0,16,0,0,0,0,0,0>>, ?assertEqual({0.5, -1021}, frexp(SmallNorm)), %% large normalized number %% 1.79769313486231570815e+308 <> = <<127,239,255,255,255,255,255,255>>, ?assertEqual( {0.99999999999999989, 1024}, frexp(LargeNorm)), %% issue #10 - mochinum:frexp(math:pow(2, -1074)). ?assertEqual( {0.5, -1073}, frexp(math:pow(2, -1074))), ok. -endif. rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/src/sockjs_service.erl0000644000177700017770000000032712633765070032776 0ustar michaelmichael-module(sockjs_service). -export([behaviour_info/1]). behaviour_info(callbacks) -> [ {sockjs_init, 2}, {sockjs_handle, 3}, {sockjs_terminate, 2} ]; behaviour_info(_Other) -> undefined. rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/src/sockjs_multiplex.erl0000644000177700017770000000502412633765070033360 0ustar michaelmichael-module(sockjs_multiplex). -behaviour(sockjs_service). -export([init_state/1]). -export([sockjs_init/2, sockjs_handle/3, sockjs_terminate/2]). -record(service, {callback, state, vconn}). %% -------------------------------------------------------------------------- init_state(Services) -> L = [{Topic, #service{callback = Callback, state = State}} || {Topic, Callback, State} <- Services], {orddict:from_list(L), orddict:new()}. sockjs_init(_Conn, {_Services, _Channels} = S) -> {ok, S}. sockjs_handle(Conn, Data, {Services, Channels}) -> [Type, Topic, Payload] = split($,, binary_to_list(Data), 3), case orddict:find(Topic, Services) of {ok, Service} -> Channels1 = action(Conn, {Type, Topic, Payload}, Service, Channels), {ok, {Services, Channels1}}; _Else -> {ok, {Services, Channels}} end. sockjs_terminate(_Conn, {Services, Channels}) -> _ = [ {emit(closed, Channel)} || {_Topic, Channel} <- orddict:to_list(Channels) ], {ok, {Services, orddict:new()}}. action(Conn, {Type, Topic, Payload}, Service, Channels) -> case {Type, orddict:is_key(Topic, Channels)} of {"sub", false} -> Channel = Service#service{ vconn = sockjs_multiplex_channel:new( Conn, Topic) }, orddict:store(Topic, emit(init, Channel), Channels); {"uns", true} -> Channel = orddict:fetch(Topic, Channels), emit(closed, Channel), orddict:erase(Topic, Channels); {"msg", true} -> Channel = orddict:fetch(Topic, Channels), orddict:store(Topic, emit({recv, Payload}, Channel), Channels); _Else -> %% Ignore Channels end. emit(What, Channel = #service{callback = Callback, state = State, vconn = VConn}) -> case Callback(VConn, What, State) of {ok, State1} -> Channel#service{state = State1}; ok -> Channel end. %% -------------------------------------------------------------------------- split(Char, Str, Limit) -> Acc = split(Char, Str, Limit, []), lists:reverse(Acc). split(_Char, _Str, 0, Acc) -> Acc; split(Char, Str, Limit, Acc) -> {L, R} = case string:chr(Str, Char) of 0 -> {Str, ""}; I -> {string:substr(Str, 1, I-1), string:substr(Str, I+1)} end, split(Char, R, Limit-1, [L | Acc]). rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/src/sockjs_session_sup.erl0000644000177700017770000000114412633765070033706 0ustar michaelmichael-module(sockjs_session_sup). -behaviour(supervisor). -export([start_link/0, start_child/3]). -export([init/1]). %% -------------------------------------------------------------------------- %% -spec start_link() -> ignore | {'ok', pid()} | {'error', any()}. start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). init([]) -> {ok, {{simple_one_for_one, 10, 10}, [{undefined, {sockjs_session, start_link, []}, transient, 5000, worker, [sockjs_session]}]}}. start_child(SessionId, Service, Info) -> supervisor:start_child(?MODULE, [SessionId, Service, Info]). rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/rebar0000755000177700017770000033665612633765070027531 0ustar michaelmichael#!/usr/bin/env escript %%! -noshell -noinput PK0XJ@,ìX“§Œ getopt.beam…YkpU–îö•ä¶â›´ÜJœ@A ÈNÚ‘’XN ×–eá†×`ÉRÛ–-KBj‡dfMâ É0Ìû½„–÷c€À ,CÈ𘭭­ekj«fvÙ**[Ôþ˜KíTíníÔTíwºÛŽL2»®:êsÏ=ïsî£ÝC»¯ë–¤õóÉþ]ýVeF’Ø’$íòM˜V¥jy«¹ZÝô™µR®<Ñ4YðÕ­Z±<á³*Óf¹îµ&k•Û½f­V©yKźUo®™{MH4U¦½{s¥YSŽxÇs¥º°–*å‰Qè-VÊÍÓæþñb¹Ð2[.˜@ÌÂÊb2Å‚Ëpþ"£¹z½8ÎÑ\m¢m9·MªWKEk×9g*)›û,šòXµY³Í™¯OVj–Ëà/Öê–‡ØÎ=svI\#çGË œv@îZ“«VMÐRn¶´(ToA°3æÌ˜YÓr…%—o/Z“$¶þ ZCgLge¾h;Ñ\,[æ„Yk«TJf®Ü6S„hCÂj—ÿYùb9_3g̲•+™ÄÊ£õª™µöWÍf«b?½ã¥JÎò˹Ú~OM²Šj=Ši×:_Ûœ+GŽDëâ$[î2º¤D¥`JRÛ§Xêäüü  CV›Ú. É¡•¡Ðdp`ÿfIÓ»6ëBc"%iÍ!µ/)ÉB4éBŽŠ&M°„ð°€Ç“>T ¶…49=Œ˜¬7µ^S hRt@S3z n&zÍDòÄ—-é=«0š–çzþ1ÑŸÈä{Žgú3õƒ‘ãõ–®žãû>ðläùZºb=Ûª Ý#òAOˆ6«!ÁtÔ`\èÁêÚ2Ô¬:ÒRž ±Ô[)­MÕä‘Oˆgó¾*Wåc„$ü2ùÍÖlUhaÕ„æ Áb"?(2#PeüSÖû5 0I`ªùZ;ÿZïýZO‹MèL„õ@80â1øŽ;½ªð¢"¨ ¦‰Á„ˆ1oúPV>ùšRCRr3ž¨7N~›M´ªâY ÆŽDó?k_í`ò7MmÿQ•µµZ x+ˆ<™ H ˆ˜Ð…6âQù¹q`½ò>ïë"œÁŒˆEÉ÷A]˜wޝ¢€(è¢%ô4é8× di'è>ÀŒh„·Eýê5JjP5Е ZÚìéÓtð° Ífù…˜Ö0Dd%ŠÉß– RPRš¢f1DXÊê¦6¿6'+kZçæ„Vúˆí•NñÕhPdÂ"ÑA¡[¶«káê:r5W =Â×iÁo×ýECÁTø´!èn§X=p¿pXÔíZá”y»e²²š]®c9{œ]­Êʹ´˜æ3øy²²žˆ†¬œ×Ã/Ðúµh"Â϶ôµªij–„]Uî*Kyh ¢Êùj(ŒêºH¸Z.ˆñõ&Bж&++Æy(Ó H·ÎežŒd dŒ:U¾~–ÊgQÈN~q¸Éï•Âënƒw°mŒw´‹Sü";¿XV.êá—„ûÃL› s,lÝm<P£…•WÓp3“²R,™Yª¶‡ªðbÁÀH @k=Ü6Oõ©p„‡ÙuA¢LYT];ùlYâ´։ÿbtG`D±€¬ÃF÷œ®ÃâòHËÊ%W…e¥ƒÒ})r±r™È×…]Þ7Ç#²r9Q¡8ÒÃ7Õ[æúë-$Rq¡Ý9™È{RTlÞîœntNl±ÉU·É;í&éó‹M¾´b`‘`ÕUY•N›3Æ»,b'æÑðò䉫ʷ€« …¥‰(Cs¾ùÛi<¢#ƒ–˜GæYÚANg`diƒP6DøF©§Ôæ)[}]¶ñ[Ô›dŰ»8J^Ãÿ9yR×èu7¼f§úxTV6Åøåu_ú¬DϺ,Á£ÔoF’ÏEê·Äùf´áf´áBMXG\ž^ê@jKT¡>ßÉ{Ôƒ epÚ°Ú°Úp+Ú°WV¶öðí‹m؃ֳÝÅþg< ]8¿¬ ƒv—wẪ‡º0¾Ô…ó)ëÌ.DPqêBâïðmNníZk±¬j±í,œ7•s;õm%ï $o}HV®ìᬟéÑ8ï×{é]M è¡L„÷'¨íú3ô+4Y5 ò÷dJ‡âN¯¨jj $Yé_Âbü &N1p%`å|XìáW¹VR°’"+¬P»T&Ô*²5LKZö’ÇÎ5hÏ$v½´Ý Ø8“š‡õñ!YIbk•! â¤Â™rü”•«bj4òc~„Й;â| l˜¥[ÓÖØ ÖWB°°kê£õ`ðÝÔ»ÛÚáêSüY¹°“ô Ä–z@K ¢àJ†¡Tê]K¥<Û†ƒýc•𸝡=?L¾ïy7U& _/„¯×Æy¾¦Yz¥ _£äëdŒ_wÚÙh¸Á‘°ëH¬ µR®›ŠExfÉ‘ðÙA¶2äñÀ*.WÊž8Õd(D'tVéܧýÛà7PVn@Vt~½?Ì¿#+×/•%@Ö鯤|g‰æo_"Þ°¸–/n\˰x#,_‚çMq~#,ßxvË·’å[mË7Ãòweåæ~‹§ßô8¿r·Ø l˜*6Ì[ô úSD 'ÜPH‡+,©;;å–³¸üݳ¹|ëŸsy.wàŒÍÆy¦s¶i곜ÁGé9†KÁ˜óJÚ2/+cSj?†`Lÿe|Ü9ŸðGø$+ÊŠ‰ž½Fņ0n#ÇdeÂFÞ”•I9!+Å•*]T›Õ/p¨"CÕŸÂnŸÛSÎ…Wåû ^&Ke»§OñY™ÆÂ´¹JÎʘþn¦¨_!š2u_žo oc)‚Äu[„×X*äŽj^g)ÃÕ#Üb)ᎬŸe©´;šð½,•uG{Wx¿a©*¡·ÃL föEø~–šsöGø÷XjÁ}/¿ÏRÇÜÑ÷#ü–zÓÝáw²Ô wtg„ÿ€¥¾pG?°Í|Eè_ÀÌfÔa.ÎïB-Õgó]ÆÈΡö,ò~u8ˆzÌËÊdƧò£²rÐÁ“•y{HV¹V~Õ[ úî8? Õ÷,©¾[VCõ=v¿úÉÊ‘V‰J†ºÜï÷**cmÔüh‰z´z³}þ6z¥£+ñþ°Tjƒ/ò:®~‚ÂÞ++?Aɽ(8xﵫ»à^çüÝ)Úßuq<ïïá`7Öp/}@kéÂÐ íçñ ØzÁöPÄf»”?¬µøm‰kKÌ;.>ã27%BpëáO¹‚C°ƒ?AYy<ŸÔZ6ÈÊŽ¤õIGÉS1þ袒¿„’íÈëÓÂß§ãÞùŒ¬#vÄg þS½Õ0Úýô0²ñÒÒ› ïàÕ$Éš¢IO4š Fu‘ú†vWÅPÿ)4F}‚?'+Ï’FlÏüùh«¤¯Xôº;S霣4u‡I±¢ÒI@š¡æyhNøÒüYù+ÒŒ­ü…Öl/AÑ .zLhƒ"12!‘¡&ò ÷»d…Niv8$š ¥­ÑêKo\ͪ¢ýÿ^¼ÓHÿK°€>|EV^& rùJË=~_Æñû²žn5.ìö¬fpÚçq×#%Â_¯ûüUœûê\6™I)–lébø¹™éÉ–ŽÓ÷g²òj'-žcÕd¾çLÆ×D“ƒ¼ÞÉ߀V:À2ˆK ¢-“,¥´Ab;‰…ðãiP¢¤9²otò7óŽlÞ‘UÔÿKøL oBÖÌÚrš-çÌËÊÏð”dA÷0~íòVŒ¿ÌœÕ‰(($+o#£ƒÈñ;­’Š4SOOÇdé~·‡à¦û8Ò}ÜN÷òd‹:½Õ×|ÿÜÊ?Ò:MX|w¥POÞáU•ÕL»Óª¶¬Ñ´þKYS·†$IUC9­CÊÝÕ¡Þjz;¤µCõ¢ù³’ælw‹û´æ²F=¡&Ã)%¨%™æÖ/äühI-ÈÚ 8òKUi[äºOsù Ú=æþè]Ó™°Éàq1 #¬É×vÇWêà'e\hâ:éü+0_B~"ÚpÌ*keåS¢@ü3ʈ!e¬|â.Ôù×qþ9¶þÏOß<èmØ(½0È$IÊXµú'ÖðLOy;Ðs4åÈ/Àh´ü.}orùyêÒš]~ÂÏk๠§³§«ßЀolðÇh + x´ÁŸ­.ý À•.슼¿A6Ñ€§b¼ªA玞ߛ’û(‡6NùºÚÿÌÅéïÀv7·Ï¹8É?ãâdçi÷iÃÐl™t®wuíré¿võIìÀCƒ;‹ñ<ï¾'÷ü]Ÿÿ¤P½_ýÃÚ?<ûÔ‹ S÷{-YÎ=6vñÛm­oõÉEG¶ÿ×e?^ë{øÞýTŽL^=ø»ß‰ì0šÛõ§«þ¿÷ýmêú>z¢íÑÔ]×§?;µ±ï½½ÿªÅ9w¼ñÑëÙÿÓŽW¯øáî÷}x÷7ÿ“Ëžxû"O™é>ðñ‘Þùã=_†ÿ´%öŸ·ýËo_Þò`å÷­—J;+yê­øxá·bvãú0äæâC@Òåy0èò¼p鯸8Ñ_rsG}ñ`›K Ðëââ.~? ÇŶ¸:ïlvñ9@ÌåÙØäâUÀ¥.OÐáÒ³€K\úM€‹\|3Åu- ÔÐGç»<ƒn} §>=WrÖ ùµVrú;ââD¿ °Æí1Ò½Z:½¶V»þÍ•%ÞU®¬êÚ¡\)ý–UÃó˃%Ò0ÙTØÞz™rY•¶]÷ö›Ç³7ÿÛ‰“Ãÿ]ëœ"_nÖš¬Ôlž‚¤MÍæÊS‘¯Ì˜¥R®¾¡R›°ÙV˜ûªôI‡>oo3ûC(9‰†-4´¿a9ceñãˆ3äuú±ø¿}‡¶ †ª•ÙraÕ×8XáþßßQ45•.Ã?Ú1zˆ£ÙýZ@ìØŸ"Fë³33¹Ú~G߬U(Ö¦%9V,E.NKÍÅr¾4[0áøÒµI†¹BAòìÞ98:2¼+9-­Údto26u£ÝÝFww÷"“r}"3:|ÍÐîiiÅDÑ ™cc›¢±Ív¾šé»œš–¼± [6Ĉ汊3æ¤o Ùû2×”óçVääÜ ÛÁze¶–7§¥ðÆId~#7§7Ökù5s,W³1çóâ³Vš’úÇêíÿ PK0XJ@𪎠T mustache.beamX påÞ½ï.·w¹%{·?6 d“½ü\øå.É~B„í ^.w›äHrwîí ,t¨Êˆ"3E+-ÂT:µ@¤Ó±SD‘ZÇ™–™ÊT¬T­Zµï··—\k3¼»ï½ßûóì÷-Û¹|EEñK}mËÚ´ÄEÑŸRµI§´pdP±F#ÉØ°Â(êp( ÇóRš‹˜C6"J†Õ”’¯_Cʺ¤šÒ •»ÃÃŽ¸²6Ô‹GÁ:e&: HÓŠ9’ˆ*–dZPlÉp4ÔáóFÑô°b&¼MU ©IU¬ª’GÀòÑ[:Uúcq%š§*Àªæh,¢!XÊ AŒPÈ’ÒªbŽ¥´”µ8¬iJ@:Ímâ:l«‘ØaD¸luŽ7Àÿ­§ˆ^Ðõú³ÀAC‘½Gy(ßÉl¢™âÅ0¨)dpÝÜ š™ #› ó+ñ²ÓÄ ì)Ù'rþ*všlw;¤ƒ+ýn=W,­ã‚G ŽÌdáqbœ{gœ»’åÜã"†›`([›€P‡­•\î —ÕºÚ¥«±®†‚[E&‘uç'"Ç'àÆÅ…9b½Qñä Ç"ÔÓÆ{3z3à<ÃË–œK³p–Î¥ÎI€sP‡sT‡óL€³ gA‡³`ÀY8 ¹pt8ÃÐ;º FÁ`TðRc¾QöèfÑ;V†ypªýû Û‹ƒ7‚npºô@ ˜¦HäAfFAÜNfé,s¶ëð 0Å:.{³Í‡\9ƒãÝ›’Óß^*;­Yˆ‡ò4΄~4˜©<´%yc3´t|³`•0ÑË΂!Ìâ…Ì8B™8åÛoá&ÓØ^…À·ì^ f8Ê–Åné Í”ƒ÷<€wE3;µ!Ù_Í–Ë­2[^„m¥ìlÛzvÍÌö°å~H«„„˜C~Lâ$/[ ÏC¥þ< x`¹JØ,± ¸7ë¸0ÓøÂ×tTs«Ørd¯ú?ãÎøÁ¸3¸•ÆÌÑL”Z ÷y Nj²73‚—R.³x'Á¾Œj¡›5Ml-"r“3ˆ,-0n/+‚¥\Kp´À£.’G½»E8ª,[!jÿ_w3¯Ÿ|º“Dމ:’ ¥¾‰•‘qNò™È)™]@vH† öŸL|Ä÷æÆ÷ê/Žm…xøìÙn(œ¬Ìd D­ˆõa»Ì6Ø=l#Í4”ÊÈy §\’#ÞКFâG‹N÷<›À³™fšˆYw£ ·flB. €ã%¸mÒ`­Õì|À/SD3ók؈lËÈDf"¢n)¦™»X¸hf!xߎ^pÄØÄç ¬fÚˆÚàkf]Qnf;a#ñ¯¬f;ý­~¶³¨×6ŸõÛ²í¶ ¶ƒfü¶s¥ÞàL"ïLìóÆ‹ëƒØíå74è˜0¨¸¡A'¼1uˆ<<^(“dÀöÁøI!Sif¤Ü f]Íì"H™=ì"ѯn°?ÃtÍÜ£y¶nÏL ôo1ø,€ûì"Q¦ÑÌR"(ËÈÒ.Ү鈢Vjj¼Pw$áN;4”ˆÊ²<d3ÞÁ o29€XÆ𓠞¼¯; ÞÄq‹€Š8„Ÿj¬Y4-ÇÞdÉif/äØÌ2ä$n™‡Ø”Gžõ““gÁ“¤›:CNøúœ˜†¼ ¨Ù°'9·|‡'6óslˆïœ˜„7u¬#=×ÿ/“´ÀÐ/3xò·¨Õwy Õyռɨg²!/0x“²ákËékžq'rÓÒ˜ù˜À¥×=™^ñå—¸ÆûY<õÔÏGNm“JK|MŸyï-ÜýQ,±~X>ÿ§îц›ö¿â\ÔõåÉ Öºú ¶]¾üÕ‘«k‹xßœÒóW+‡m'»íÇu?³rŸ/ïæÊãßö½1üÛ÷¢Ç^:ú£ãÿ:Ûþõ¼¿ì›?)½sÉ-ï=+ü¦¹òÄ+k·ix|ð¥|ñM¼ãÏîG",zùãýwnÛØðöÜ¡©Í{ÏŽ9½ùhþS¥ï#õíU… ž«ýpÏ{ >|ðaÇZ·æ ùmû!¶¾ðŽ×_üâÎ}I[Ûã'«Šž›òdÁ»‹åÛ¥UïE—Gš.¾o[ÿÇ“¼¶ïöó'ÿª¼ó¡§^¾:ß¿kôÖš [ó/¼ÿÂŽ/{î“;øsûÕKÛV-®ØZ|º¦ýÌÈ´eëÛv̾ýæ÷ŸÈ¿2|m½å¶Íÿüå¯Þ~húgŽ=wùëÞ5›¾¸õT¨ýÈÅòú§»ö¤Þðv|^ó³øk~:ïý+豯þ†ºöÕ¹Àè–ؤ·î«¿ïW¿?½qëÅ÷^÷òW6v>T÷ècM%Û--÷l{mÛ]}¿[¿åÂ’§÷4νkóO欗Ÿýà…ê~þüÁ±ÏÖLméÙÕ°óй3ƒ—Î<ðꥥ´–Ì8uÅÙùñßÌÛpdû§]â«¿¼ëÅG®^üÛqæ£ËÁO΋ýØyxÇÙÚŸ>¼¼ïtèU™ßë^wèƒÕ‰×?-84él”Zšˆl& ¼x œø€ ¼\Vü<ƒî*€* {hnÎ30;ç9/5ä—Ó ÞÕ¦i*Üm&;‘iÐ¥ÐÝ©8ùAÇ9ê›ÛVÉ£žç÷mý…{Æy·k 1È §µÁ„:D¹‚‰¡GURZ"^}«¢Æu¿+ÞÎ_ëñÌÄÜšH’ï)"È‹R¬þ¡%”JŒ„Õ{ôx‰´A<³Ò‹ ¢¬±xd8U¢ÔÄgžAºh”²ûnéZÚ v-ë¢ ꥺz©¾N ÕÕIuuuY#f•e¨«»sù•?Ó¥¯¯^ö4è%XÉÇHjˆ²xjk)6š4¥Í‡$"ߣ)ŠzÌjÅÚ-Ûk¹ÚÝÏ_­T”o€vw¿¬=ï];ã•ÄÄnV+ÏæÝÃsâÇèæ |ÓLÜ”÷R«5³Ðs»nØÓ$À VšÙ|ó-Ù7ìqæ} û®5Þ¼F0›.>-«øþ€àÖìé-Þ»çhìx¯Æ¡ôÞH cL0ŽôuÁK$Ü=wP‰>h5Êå³@x¸"Cú¼]¹ §>Vò¡Âc±VÂåIwP’ÈyŒAKƱVà˜Þ‹ðXA¡&Î@{“N9ï4ÚúJ`cµ×}GW*ˆÀ=¯ ,`©Ñíã œ¿ƒ´Ð¥‹’¸Ð i‰Ðö9y†Áì,D»2~¶0^zv൹jˆ}pž?€mçna']ÌD¼ä‹íLGÒÕÿVÁU5Òã¼@Ùg=Üá Ô!9a¢Š}…‘ô,ö ;êÞÉ;E[w´­£NZmc,×pËÙOÝ»3~Z®ÙçKW/]<;içdÔ¾EÜθ ¨;É^fk—µ/4DžÓŽh£”lªx½r{UóX8g`£Ê¬T.µVªp­²oÙ–G Aúµ ˜5ù ²,)?Á) >Á)é4ýš¢p´¢&Bä ôõ|¥v›k–‘>3 h’Ø òý½9{¦4pþ«í³ÿ–01®ô2bª[Éάéçöõ¶ù PK0XJ@w·f)p rebar.beam…X \åÚŸaö2,Œ Ì¢‚+‹H¬ ,A`¸® "* Çuvw`öÖÌ.Jæ¥cžÐÌì|YG1»Zfi–eif–ZieFjšÇK–¥3í 'Ó¾ç”Ów¾>~¿gæyŸ÷yÿÏå}Þç¶zòÔ, ê,¯*›Tðy0Lq†a.¥ÀÛ8Aáá\^%/>AÕÆ¹Ü¼CÅ nÎÛ®prî@˜¯3ÌåSµù „ 7‚óûÝ.;pù¼ ·s(Û8·ÈÓ¼—³¹y«_ðµ¹Ü.o{¤nµû¼m®vM;°¶»}6έA^Ù†ô”ª[Z«9/çîy5±rÁ¹*»Ðíø”b€á!4·¯]áòºQ¡a—èµÚ9»“'ø€Hxù9j^´ . "ô²z9O"pĨ9›ˆÞñ–3áA¯ƒosyy‡ÒÁÛ‚íˆa.·¨F~Ûç8H'òV‡KÐøü¼ Å.þ dGT ïíRtø\^52åvÙ4.Ñ*ðíA7'DH+å, ¤DàiÚ΋" <ÎëNÞíGX>@¹v^ãçXÊ í¢RbÕ!WÅpX [ Ä!È=Îí¶vqî /’hhóùÜJØ.;/ ;|6Qáh$é©BÞP( ¯ÕÍwñnu/Ø|"O.脤JÉŒÂ͉¤ BÜ$]JK'ßu;“Ö67×®¾9V—·ÍgõpÝ6ÞŠ*ˆ1fµ;!‚(«èçíVdBåòÁÛ¦vy|;/DB¼ aŠ*1 @=©¾NÞ+F"ukÀgå £ò:µÀ#/yJ6)í¿8,¥iƒ)à­ÿ6¥äl>!0\ÚåAr(*¯ÃåuQåá=6^Hp‰ÿ‡†Ê/À¶ÌUÙ8lUòïõÄ Í:Ç'8n/x¥ûHýÿuÑ9ˆðøA8Y(­QÈÓAã;Œàzf–ÑmO™e‚·É˜düO{“™ml zÙ<õÇÓ&c¬Q>³ÿf’BRàB:Ðp*|ÃÂ뀥±Ð_h8N‡Å$Ó¸.’¦K¹ :ˆ›J㪈Â&BWN`L9Aë ML¶¡I_ÎF$Ñ8kh"„šÁh]E„1¬#Ô:z`~vXÌÓ4îBËÆjZgXO¬–ˆÖ*hj(’ö1ìYXc2¬"4Ѭ…%Ö©XÒŽ!Hm­Uë\ PUc³Y‹æý£cðE V¯`™A3n…ͬ %½O‡?9À·„Åhâh|wA?QF0ú‚~¦ŒÉ©0öçåôdzá]GÂçðC†þ ‹Éܯ„æŒQ)¬@Ä` ~‰Ù[â8Y|9’[d ´„ ÆV²–†Õ ‡HžÏ-ilQÓ»Yæ’`î«Ñˬ)”2=k™ ’Bm:£Æ.(§IÊ8pwGÒ¬Åá‘ÑÒ"Ë"Äǰ„^Œ‰bˆ"‚bâYM4E÷QÑ8IÓ:¬J°W`³ "©k‹©œŒ#cq2¦‡¦A‡Œ*RGÆÓ8ÉÔ8©…Ì‘±º 'ãBác-Oè–Ö²›!Yr(LŃJ,:Ä)I‘´R˜èð:a•DÝ* •Ä1TR<›M%Ô0\ÒуŽj*×c9åzº¢ª"Œ¨Ê!ÀÔ!†ÍFîK¹—ªÊ„“Ãn­,` me4P‰P`)vJÜ0)›R6‘P‹„ÑðlHFÀFéXÍx±:j ¤eÒãšÊKm"ÇRà ¨@&Z„° RÂjX™4–Ahô’56¤1‚…ó %zLà)iª²•ˆ²š„ò;òVyÓEb´´¬\ò×L"À‡‘ÅT2NŽ‚­Ñád²bZ@hDR5?¼Ã*5)T@8 )Ë£äï°°A:HÄÈrÄkåo5ÄÇÊ:ñ@CeyÐ0™”(¯M)Ëu@£ÙM–uÐÚÑ@P*ÐYùŸ.ë€ÆÊkŽQæ3€2a&þŽÇdÞ$Ëá`,[Æ4åbè«"ÄçËòq@…ƒø"™G8Å2&’—Ê>ð±TÈ:hªd»(çå¹N–×Ú—)@SeÅ>MÖA|£Ì#Ì&™Ÿ"ç!LÎÛ ™G:3ñ­ƒ0 y­h¶°i{ðTá·©wm{'ÿØé#/&Rªy‹ßÅjµ¯U\Úuýæ1€îýr_ËãŠÊCSSj/Ü×âü×;†œ__f¸XvmØ{?įyŸãUkHðlÍÿÇýÏO?ò:—ZUoX Žü©÷™Í‹òt/Ÿý²À™ò÷Í¥ 33¨ýçŒGw–xX×{`yÇWþxhï󨩼mw?ÖS=w£³ øÝßæî_üþ£Î ÜËoÝäݬ¯Ñ/(äãÞ¿PøÒ´ƒçm*½úçgJÕ={ë6,àqdVOàÍô½•ïhvêÆ û+×Ñ—¶½<Ù:‰Ÿµ£÷¾¹õŽ¿]MniýFõÛUûNY{:v¢³J1zµ%;*vm­cûÍg9G[¾¨ÉØ»Ñ7âü¯êWï_¥’xþ"#áÅÖ9ûgLݳ´û:ÙF×]{çØÞœ³pK>9}U•óÙ s O³3íõƒ÷<øÖ‡e7Îÿ\õ†æpÚ ­Ø%l[ørúÊÄMÛ^;ýê†ã¾äÅ/®-ê<ý\òé GWEìV¦î° ìùÑxË9§¹ßç0,éí)*¸ùcxÇrß§Ôg{”'>p½ÿMeéØOµ» ž›òaÒòxã]ñ}ÛsØÜK7.|Âzíæ<ý×}°5×þÚë¤{,Õ·ßøÔ·é§ŸXôXóškâÓ§§Œ{øäú>åéÔäÿпÐùÆ„U‹“žëç+߸~òêñGÌ+ÿøx|l³ªäÑŸë{µ…);êÇW]il¾:åä+^)þµæ£enYù›÷ZGqÇ…†{æl3Ÿ¹rø­æb²ñìæ=Þ¸—×§õկعI3}TóvÅc'7ZÂÒ&=ü;ø•鯸Â`sÇk±÷?°#¢¤µ4ðòL¹`dŸâFâóï\r6îuéó¶Ü\~ÿU|»…™u%ï‡oø%½ñ<žwó{·âËÚ¬‰E ¾¦Y*m»®}µiÞó˜ßDÖ‰/çŸX꥗·~áülñãKR²^¸y¶ëÍ>GßÙ’uÆGoìüê×ñÏܧÔG=þpîæY5_í¬X7mƒñݨÎü3勵ÙüfvýÓÒ¯—uùåƒUŸ÷¾óIj漢ŸðûæîW²6?3cù舵«ï~¬bù²éñ;òÛÊýÌÇÛ½÷.zíd¸þ úÁôþ’ß¶\wÏñ¡ÂS»w~½+rýGkØÿ7õ®üOú_j½äDxüeUr û1ÝÛ÷7–|{ºdù>ÒøåÆêgŠfçi£—êÎ$i>Ÿ_·Î³ôÒÁNžìžu¸K¦®)K¿ø¹áç”sBd⾃Çïþëö qzÓÖ²y{>|5{ÃùÜ’#wõ~rêc ™:Ÿ½Qn½±¿ëÓN™wÿ®Oî̓û±CîÕè®ád¾I¾Gî¸;eÝ…-2~ Ðtìö×,c–5Èú讘$ËÑ}÷G[dîù©££¢Æ‹bþEÒW }uèGN TŒ’~a·ŠA‡º‘‚Ê 8\B'¦àm./’à®NLíòÚÝAïÀnÿ8í$`ÎáÀ4åM5u•ÖÆšIUXT¶)+Û”e²fe™²²²”ÈæŠiÖšúêÉXD»+ ãm¶ìsn‡ä“ü#n'ÜŽyf$S\Þ©‚›]ýw.ŒÓpÎEHо `ç;1}¦Óçá3Áq¾3Sì™ÒÙ·¹ ^pC%”ÙÄÚ„ÿPK0XJ@x‰VS@(rebar_abnfc_compiler.beammUmŒEžÝÙÞn·×cÛ-ô>øXé’wÝö 2÷Ñ«…㨀ømÙ¶Û»½¶»u?Ž3&zæ$^ˆ0!‚!&†D/ ‰„DAT"?P#â©Ñ#D~:Û.z!6yºï>óÌ;Ïûîd¦wõš´Ðï\Õij%ˆ,`~@—3’ž–2j>›Îj¥²R”uÚ ˜œ–Mëšf²†féY9-˜´f™éœ¢³%-g+T¬%u€lmå«Ù2’!ÿ› ê–ÊVókeÓ¨­J²ššWà€lÖ`VÑTwY×ÊEÅ0 7&ÓÃRђ霜—¬¢ÉU§+Fº¬Ë†¬š® AeµœìÚ8¨dá²ð²ZUS±œBQ¼ÎòÕÊ(S·dW^*2“Ǭ*•dÆviWBh.UÓ2C”=Jj—¬ëšî®z-jÃeêÚFS·¢æµi¶Ó)ï¾6gÕp´-o©mbèÆ ëq¯9Pýc4b¸ ŽôÏ¡.Å!ØCqqy…ˆQ‚Œ`3Šñ¨ V ©Æ!;Î@ªÈ€§€ 5P źQsQkÉ#˜E=)s)B$ý9!2„òý¢@¤Hÿ±¡VOáô· Q¼; ʤŸõqĨhÁ¥Ð Ž®ÙÝÙõFæ=bJp'ö¢„€ˆÄÿG±Øˆ/j@,iy\)È¡ðÄEtá>*õR(0¥vì²×NцŠÝj+ªJ¾’·ƒ;Êõ ¡;+ã!2Ô+t$ØÙ *Þ ÅÙ9!i†´Pnõú {—_ä ÆÇ!.IoÆY"?.âZæBZE n ?J¤xÜÄÿãW@‚ àZçá—éÈû¹½3Ã&8‚ Úæ0'LL=ææ‹ÓP#þךú:{S$Keû¹wÐ iï Öáì1/Ęæì);`LÇ Ý gnÆL'æ1'a4;sm}Ë”¹wß“ñ‘Š·ùŽ~ž3tbà¬MÞF¯¥®sÖ%¦Ìkp´€nü³¾O1mÍïX²sd÷žÔ‘þQmlëÒ½ûN¸î{°åf2poOrõ¯–|¶yË=WÔçÏ·Ï9q˜¿vñ£ÆG;®Ÿ®ÑK?ñí­_o¸qòrüÌØ±¦±W77*Î?üäßþNÓáYÃ+Ž£Í-ÒÊåß;d}“ß·ß<<æÝßkM,óS³_9våñ—O|¸iË­qž=t|æé•'äÛ§ê “åw?¹qí¯[×'ìúeá3ÉñÜë¯ER?ïˆl_´ÿ¡Åb˧ë'G÷|~óì[Aáúâ­Júܾ'äC…]G^º4¹drÛûiÏò¦mìüö\î÷÷ŸiØsîÙÇù±ÉS|: ú´¬]wFͽ©Ÿò]ýN«ìoísúhï‡:§Çö\ÃS¦©Û¹ÆŠ63Hæ6Ôʋʿ|³î›‘ïn]ÍH5\=pvh¨;©æñ˜»¢§l=]=ƒ ›¨ÉoåôKV©$éOÙ‚|êãC¿(9£¨6C(@+j¶håäp[*>«UÎ B<–˶ëd_Oz]rU¼¦EÅHTŒFÄt$"F"‘Û"f}÷Út²¿wuxS3™hGláPÅÓ°¬ØT¸bí‹Úc6G™JI¬Éà=tA"%VòH„䩬ÞP j%9ŒË…°¡gÕ3ü¿èŽ«®ß]C¸êÎŒaÚ ÿPK0XJ@ZkÛ›Ü rebar_app_utils.beamuVol[W¿Ï÷Ù~±ó’?'i’.}­“.©›ä9vR'iÖg§Ž•ªÍÚ¦Eü)¸þó’8±ý¬÷ž»²"QúekV¦1~¨:1 ¬ |´²R• $4 BИ¢"Ð4¦ibã €sž_S´(çÝsÏŸß9÷œ{¯ïì“'#„ø—L%Ž%,½Lˆë0!d²ÕÐrY#“­V35«X2}EÓžІ¿®²ÅÞ%ÍÊäŸ*‹Å’VÉ–5~E/V¼8+sÂSÅR!Ÿ5 ¼eÔ4÷b¶djnÍ0t£©ŽQÒ—(иiäC×-òhF)[Y¢Ó#Ó-Ž.céh&䲦Ë ¨²y}ÕÍé†ÅPT*æ³VQ¯˜Í/jÏ™/¬Ý(òçò&ÊZ sµX­jhªU Úb±¢<¦e+KK_Õ*¦XÒ³¶AW)l1*Á#ãÍCœZÉò7Ä¥ÕšÅjí|UË[oiFÙlÂÚË–jZSÕÐÁÖ´ÌVÌA+Õ­ÀmK=e­œÓ @hòø¡ðiGIA«Ä¥’žË–D”âJlã¦9a‹ó—õB­¤eŠ•E½æ;‡þ· #‘¡R¾ï •¡fLÇnl•O°T`Œ Íèwö#õ¿Ë@I Ç\=„“› ñ‚ KN ãÔVYf* ¦‚iB½Œ1œñ)>Ípæerü4MP)»bŠ<+ÓôÕ´%îxìe2?™¶ñmÁ-_DR¶|µºoíß³±UoPd«6†+¤¦Ué²LÔ êUÔ‰»ˆ:uÇÿO·æ NÅÅþP"ã(G•d”,$£,ŸŒÊfXì_ð=ûg˜rQ5yL'Ÿ6±¬ù Wþ€©ÄI ˜æíúìo?;[O}0MñXlÔ…°÷Hˆ‡îS8a YV ;ÐK¯,°°8e@8NÙ8e´}÷Û~˜…›™l¡M‡é‡;Õâþ«â'ìg ©ŸCÞ.ÿÐV†±u#Ø:€P!¢íT¯Š‘â('Dµ¿Qôÿá„1Õ§@~›°•"t^œ0ª(¨¨¾˜£sTqPƒjB Ðy&Ø$J ÅSØxÊB‚0Â鏸…• !Úë›C•ðxMà ”r®á‰˜xÂx'ÁQ‹‰OrT1ñ•(Y°ŒSx‰Î•«0rpu’ Ä;÷«ÈÄû^%‚ã­èØ¢M+˹—ÛåRƒ<Ø ÷8<úw6È{|”?æÈe Ý 8}ŽM?Ð^‡Gù€cÚçðC@à ±Fí4øhÀŸ@yê<ÖÄþ}ñ;¶SO»=ŽóëuxÌ»Ûáw8Ä9µhwøüÍj¨e‹Ãûœ<8§.'–ëhÑÂ|ÞÕKç¯iWŽùî*ìÒ©o?üõ]ØqbýBëæ›3÷^^ùáüéç§Çoÿèë+ìOÇÎø· Ñ®ûøZdü;ÆÓ¯Lýý¥ÑÛÏ_ó¼òÆüá}‡.ì|ïû?z³/~»û£ßßøÉþxâ÷NËË/l~nmýÌW’Õû»³×n¥z>¼ùò;kâ±õçÖßÿ×äò¾©üCø’çfâ§åÁ“þÞÀÆÉCËo÷ž‰ÈVúWŸýí¯Î|ëî¾g_íúÌÉÂÛϽÞ<þËÞçóâ½ï½»ëÇ¿xš¾~øß/ÜùüÏÞ˜{¿ùµÖï]‰|ö/ÞÚ3Õ+Gõ<®ñÓÎ^›tê Å~(êÔ{6âðcNý±^ ÐþGöö| aYŽ_-!Ú²«@ð©fO*ŒÜ|÷Ë~í»Rêá [Z¿[Y™™«,‚Ž·íy´÷êUûɇOˆö»3cÖÊå¬ñE4ðè5 ž«„×rÅ J¸â*ñ+ùR­ Èöp™‚®P ¾äé¹£‡3§æŽ¥VIë¨UF#J&Q"‘È–‘ð©™…ÌÜüì“«Ä¿T´d-—ÆÆVìœÎi† I­wlx|8†2Þ*–µeO ùVÖ•õeýY.ë·4õš‘×VÉÐȲ^ÖF qmuÂ#öëy›Û~¦ëy%‘3-,ôPK0XJ@<¡| rebar_appups.beam}Xlõ¿ó]ìËÅמ}NÒ¦Mrí¹´iêø;­“4pqâ¸éÏЦˆ!„ãø.‰ÛgÝÛ²‰­RùQA™: ÛûÁ i¬ãÇFé&Ú1Ð@ cÀ~Uc ˜ªŠhiï¿n TXzòçûÞç½ïû¾ï{ç\&öìQT€M¥Gw:f‰¢˜·)ŠÚ뷌ٜ•ÍU*ÕŠ½|Þ(VÎ1"d]3ZF1[u E»¥hæôlÞ,Ïæ[ç 'ëä,üªä,£ìdõ‚µÒ]ZÆÁ‚YµÑÑÈÙØn®P4ʹ’Á0 åȳcšÅK´ByÎ ÃW”^Ã*æÊóÌHt¤¥–’›_±ÌJ6¿`äYǪž‘~®PÖ³¸•í19 G±ýõ¨¸hÒÙê|s-PÑœg@š1T±`;¶ë³hÜh7¹KÖ6-§Y롈ê¯Væ­œnè©i.W´ P¹pþ¹9oµd@M<‘ˆ³È:fÍÍÂY\`™¦ƒ@‚Z»UÎBàüB-M7 ¸äà†¼:TÀ1Bõ;©ÝQílÍÕ²nÀQ ÝTtAWOo/7käJ°˜åò¥ Þˆí?£¬ûÊæ¡¬íXÞrg½s‡¬‚c°Žw¡ÙS0½s¦UÊ9KûÊàVÍ;³ìË/À=º¯–›Þ”Ó¡ÞüBµ¼h 5e¶dêU &;/*›ÓæÊyCçíjŰ ÐÞjEZKÞÔlm«ZËÕ⸷8k,ä »,>ç8Va¶ê@5P0W¬B™‰µ™€ªµ¬`gâùŒÃ¸Q›5)aK-ºÛiË1TÃzmäråÆ#Å|ø†þh,ÒùVJ (±o§¨@Q#ÁH½WA=W-ƒŠikT/±;#_›Ôhƒu ŽKQ¾ßÀ|‹Tís dD¢EOp­LË˦dMb|"¥1ã>QÔ˜„’EML3)@‹ª1’6ÎhصÁfh€ABŠ¡¤´äQÒ l ÂKûä)ÂR(ň¬6ަ¯èã WZšfXp÷(Z†’´8ëS+½ÌÅ–¦#!¶¦¥c²JÔZXÒXE 1«î¯…RER‘Ci6#»ÉfTÉ'Ÿ`Eaóq¹ò{èÉ(ËS)Vd‚PuCkž /©ôÔ2MÕ”0@¾‚jL( 4Iã[Ÿz ƒ$˜@8p‰‘H'1u‰B+?äZÃé0Zg.Y˜OÝʦY´V–¬þY-¤- $ Í$ì0OÕË %~µ†1ó ©5jBe2á ›I5‰ž³uªteã-’"Ψr<#e” YÊ0™8Ü»DÑø.ø:Än™¾™ í‚DÜÍXÈ·Ž%¬ž(úä 5¬I,æëbNæD‘>1ÖŠôY?%úD.À‰\¢_å:™>ŸüTòËò¨¤„0¬a9ð”܈\P“üžH_HüU’hz“ß Ò\ )HʨÄøˆœŠSûRq1Š<(òr*OÙ©¼x´WÚ|6¦xázi.è?q"ÀBáBǵ}X>mlZctí¨£Ù7Ãî­PÀtsäfè®Mœ†Ïœ`Ò™û™¥¶k:³Ät.ï1±» ë¹öA!Ä ¨8ØøØšPghÇø¥²ÁB­õ&”7¦‡I‡ "+AÇÀ¾+°RÓnZæTmw2˜!d¹9†|·R<+¦EVQÒˆÂ(Lzš‘zÀ9&V´ÌY?®£~3°XÕ ™òAQ¦ ‹¤@BË¼ŠœÕpZǬ J9CsRBÍ#i™óÌn°Ó\Ɔk…KÚ,Ó\›*´2ÃŒÐÚ>ÃoÚù¤°‚VÒXViD†®JI£e.à):…¨R‡ûÀ*)½B‡ÄA­€Z‘S <5‘óCyÖ4.ŒÉ1$¹Õ°û ?%»~;JTEln~8|w¹•—%l]"tàaVÁaF ãV'…NiTŠõ ]qþÊ„Ð55ŸPÁå*˜þJwh¸N0K|Ï&¡[á{h®«ÖÈÌpbÚ]ßrÔÝ42ì•inÍ2|ÞÂèŽaÙ»\˜vçJƈkèg8-?óÕkƒ"¸+àžUæÌõÙ¶ä®!ìV…õx!ëÛa¶…u…+hnÆ÷ÔŽ{²\´~;|DÛNÑ\dv‹Tt#j ~/F ⯡¹M Ü ÊHRècü¢8ÊH¬Æo§™ÐÖx?œ–aÜLûÂ&ÂÁü£¤&*HŒpúAâ'@â ŒûŽ7àɆv4ä°£A?…8}ï‹Ú@ê³p{ ÆOñqe¢Zž&µBÞò½™p)Ï»áò΂ƒ=pÈÅÃ?+MíÚÁÄÄ;»¯}Ôy¨k|ÚaÛ§s¿üÝȇ£!þ»=­¿òvù¾]©»»Ý‰~ùîî'žüèÜØ­÷~vÃ;¿¿9ö¦qüù;zÎ>=¿ýÈ=Á;‚ÛŸì{ë¥Ñs_V®ï ¾sòÂc·½¾9šä>”q·· -Lý}K_µí®ÿ¼pwéÅ­÷M­úÑŽÿ)§'ŸŽÅíÉ?ÇÖÜöë'?ÿÃ;ÍÆ>¦7J~Ï™ãŸEÏìùè†ìío¬{ä/Ï¥~"\8röƒWŽo2·?¸ÿéÒËÖS;ߺîÉGKûÎì{øçÞû‹‡“·ªÏq­×}|õÙ‡ûoïß–ß4þBäúýï?³÷Ù{NßòýGî¹wù57ý@í~ùä©ÿÞýÅ»ÞÚüT©Ôö¹ý¯=¯¿ÿø{ÿ¸í58â}ñ;Ûží¹ö¾ï™Ÿß­ùÍ?šþêÐÉ ÃùÞpºãŸ~AOÍ Q;Í<ÖúO¤Ç÷’Zƒ\Mî+ùµ;ØM0öË.‚±—vŒ}—!û7E0öø‰¹šÄªÏN½7p¶Ö=ÎßZâ‹sÙMô8¯„3"Ü4 o=ëh½<:Å´Ëî¢,RÇ_ÛÖ´ÉüÔûÒëËïrŸ\»BMÁðrebar_asn1_compiler.beammU]lU¾3wvgØ.pwg¡SZ¤iw¶­ Ô[Êv©–Ÿ0Ñ—éìÎÝÝÙŸ™u~ EC¦¤…&¦ÄŸŒ¾˜håÅÄhàÅ_ >F‰/614áEcðÜeVׄMÎî¹ç|ç;ß¹s÷ÎÔ‘ÙBñµýù‰CÛDH8ŽêS=V4=ÃôœQr›-»Á<9rä2|5ì¢rÒnX%Ó³"pÑôÙ¿`ì…N¬Ô`¦Cfy‘vÃï±XƒÌ`f©*ºõdTÒn–`Žz̰lOáŽÙdR͵um)n+ð“ùJ®S¶+¸Â‚˜ãºÅZœJAŒyžëÅ™×0J,¨zîI… ãDâà ØœWhT˜Ã<3`V[—kØ~àÇÊnÃjô4]+9¶Sv7½ÑµÞ6ôˆâìèP9t†ô!ÅsÝ€7J E3eG¢Ô¤k1ØÛ5Ø[‚~–ÀS"¦wh‚¶A#gha™ Š¥ ¢2J Ú$-èý´@QI¥¸D3XiMÐÅ´§ 4‰§©´p0:–ôod¢ žÀWÒHŽÄœ˜¾ª ­¤¦szÓ~I&úàGø -Ìñ:,k´ùC¥b?•pJ’õ£„’|"ûó…V¿ memîÙE¼gkû1RWÔÈ=‹ÒÒ„³ƒ+œpÜ’†dí,-,«²¶L1ôÐxh˼×¶ü<.ƒ¾U1Ø¢ דJ´WÑH^*\VùZ…íXå;"Â’KSôëD¸EÛp‡¦ñarC¸Ç—DPï!펠¤ ÖK%¤4¼::@Õ1™Ü“ AЃ@>%Õ|FÅ© ôj?„U:-ýy®e@M ð׉qZWE…v}º dâzˆÿ¡éf‹ÿÞKa0 L‹ÅÁd~ÀÖEqŽIFþz° `btn:j£3´© ¿¹+þxäsþ'"¿ÃÉñ[ÁžŒ89~{ïøbg‡_ã~þT{®±hžmQžD>ŠzȇԥWœ N-_÷Eý3Q^*ñyz£ºtÄ-ÆþÜuqÆxí›`×N½·ïÂĆs:É–wL|Ø÷Á¹üÛ…3ëWÄoç6úê+ãù›3?ýõÜèÓ©÷ßXÛrzç» ¯×¾_J¸ix÷¼Ð³W¸xm÷Õ]?_j÷¥_÷n]‹½¼Ú{þ³»EcqØœ}çÁêÊß·ö}|)uIúí“Ï¿»wfáöW‹áöÓ³·ùQ_ÿþ¾x&»sB3n©{/ºçéžaK׳í‰|y"<ø=üzƒOX-„ç}‡/‡ ó›zÄnMºûÖ…êýÞß¿¬q@Ü ƒªëµ1J{¡W-šEsÍÃÅS«!49í”!¯´y%^&ÃÝi»ŽÏq ­oß“†6›¦·ÐæuîÝ:’XÑvxD°ëH¶R#´˜…Ö…ŽÅʶì*†œe¡ÄþÓ3ŒãÓ‡òu´qDÏè#9ÝÈåô\.×)/N3¦O©£žŠh¬X{¦=Š<Ï<DÕQllx×ðIÝdÕx6çS4f)˜É¶@ß ½«£\¶ê6Y„³zÖ÷JÙöá?ïÿ¯­axÔ&Š~ÀÏÖ?PK0XJ@‘¬8£ô rebar_base_compiler.beamuWklÛÖ&u)‰¦uZ”üJâЦb'QlSí8vÓ\[–U§yhµ·aA6E²(›Öƒ I塘‘"¨‹µhd+ÐìGº0 Ã llÚ û[dÙþm- ¤Y†bÃòcŰ(v®tÝ*ëfàçžsîy|÷ÜcjéìS Ž ýu!3zÞ³kç‹s7«8f±àä‹×̯ٵ†U5ä4ë>»0j¡¾.¸fµj›­Ùõ²µ.®›^~Ó.ºþ’Yl®wµuU{ù«–ë¹È5/úâñéYUW*[õR¾ Ü]kæZ%_-¸^¾f—ºŽÝhmky.Úvµ×µjêg)å/;…FÃtÏišþr¡êšAê©jñŽ«l™¥ [±À°ÔíꋉôQ/ÔÌ`Érè[¤ÕRFØ´­zØ1kö¥V¨š]Ï7 ކ߅t<勊D%ÚIÌ,¬mV½lû,;P¶ZÁÃ;º‹M³i uóŠ'” VUdò’߬5¼«~oñ/ ‹g¿z&P§«’Y5=s×gEÛNÅt®ÝtÖL¿é8¶Ó …6AE#î¦v¬ñ8œÛäÌx¹Y×Ç{تºû†>™I fÖŠà¯X(8m½Ñ¡Çn£p¹ë–g;˜éÛÞ¸´]29.ð-è™kÿm-õð²/G²²Øjò`¹Å7B[[yD)‘¬ª"®@Ö"d%FÒA‹D[ ªD¾ gºÎ#-ÓuXƒÇ„¦U’#%Bœ ˆæF$™fT/#EÓ4ãÕÈc]&‚¦¥ˆ‡üäÀ¿å KJŽI¿žžK_ï#RäÇRô·ü­PŽô4¬‚H*B´AFPn@¥d3ö†€HD#†Bb=©‡s ÿ:‘úeÞ q„¤ÒDK‘´:Náï@¤ÿAˆäÀ3`Ž‘”YSø‚òÍ=¢p«E¶e=¨¾ÔBŽ|(# %S(ßÒù‡àmHåE98+°ÿuzj°¹ƒ´Ã2/ö€) .†g°‚æ‘–‚·2¯¤WâXIkd…‚S^TÎÈ·x1öÃ:/FCœþ¤ªã>4‡p@Ó{“¸—{i9bßIÄ‹ý`;¶3x }!ƒbåµz'ªã!º}¨µ}0‰÷ðâ ¬rívÑ@BÒhÇÇ{yqO[C¥YÇú/î%1¥…3òC'^Ügà~í Ñ öC£Pjàa¤´uûàBOGúðt ÇÑcÇûˆŠµ>Ä‹Úâ”$k:Ž+s ¨¶¤1“âQÈuL:„òb,:ƒÄd]Ÿ¡Ø’ªd¥á,œŠÐ¼ ± I0ðxŒH‡•/hF£²ªg4ZmNÙ&»Ù pŒw8^û\¯+ ‹Gd ƒä塞Z@$‡R¤#q|8-Gé)d ç× ‹p-ëܒвB6Òê\c[—ƒêìfB¯†h¹Lš¦³õ¿Ò÷ã^<2@Ÿã'c¼8ðOBLîÎé0RDƒ+-ÐÆj,›Šð¢Þ‡þShO#u'å8žV¤áè㜠¹hˆ,jÐ:´ix1q"¢cƒvŽÑêœd§x1ÙJüög…m˜,€ W†$Ú4ÔŽÉ¡ÿkbÈwä%UËJzV È/©©¬”È¢LJÓZ[f5CÛ9®5öh¯OA²H:¥k¸Ýât?GGèsH4ÇH‘òâ,–sô‚Lañ-^<"[´/éLù×/E\H†»Oû† ½»izƹïÂ?§ ¿OÌàÒU¸ap·`4Å‚ªØ£ã4)M&RÏó"¡#0B[ä¤7ß^m«20¬aŒ ° E,øqzUÒD: Ç+†Áz¢Í@´Ì ^B!¢Ñ›ŒZJTØx´Gu˜ét¸dàEê0 NfÁÙtü)I)@q+ž³Jÿù,×ôý ägÿ—@AÆwI@¨(äcö˜ñ»€v3¾(Ìø^ > hhO¿—ÙP~_‡|?ãc@:bÅ™œæ0Ñ!O1ùïc6Ó6‰›c”Ï\iÕNXÍI¦Ÿc<Çìè~‘aáco‡_ßR³NýL6Ëpz‚ù@ü꟟gzêç8‹à¾ó”åѽ¿úÛ•ïŸ~áMé¶¹n_—>½5òÔ;óÏÌþ%>ó‘æ5Ž ?7=Z[̽|äé‹vÍÿrã_ïËs8î×çÞýøW¿öþòŒR–âo¨gïÝh<ûQÿÉׯ+/Øïn;o¯þĺÿ‹Ûƒwû£¿zñÐÐW—+þ±WG^ÌŸ»ÿbí;?ûyþéîùøî—nÞ}Nøã/{›ïß“»<ïŽþ0~~ì½s¿ùQvü÷×¾÷É{¯…O=øú'þÍ ÝLï?e¯Ñüo°žè¬}†á‘šbü‰ÿÂa’ÙÓ÷(³QF˜|h˜ñQ¦ó±Þb¼Ììü¬ÆwÍ{žïƒÏT)⾇.¹õÖ¢.s7_åç^Y?ÿÍŸŽ|úî—~ð÷ÍÍôr½ :±e/Pû Ýð,»îRA ÄáÖ·cÞmÖjç*5ØM¾†+œ`­:•ðV… Zõµj³d–¸®f½d»YÚ@ +•8iáË˧ó«Ë§3nwRO$õdBÏ'z"‘Ø1¿’^É/ŸY:[áº×-O5‹ÅdʘÚlåtÉt\HªÂù‰é ƒÊϪ™"4çŸ ¾‚Tè.ð…P+ÁöWo…KLnØ5s7+“®³6ÙúIñ9÷èO— øÍ²9_t=ÚÀÿPK0XJ@I“Ð| rebar_cleaner.beamURKŽÓ@­¶Ï$b%[lPÛX;)ÒL‘À ÉøÓv:¶»£¶=À„`=Gàpœ€%‡àt{1Xz®ê×ϯJåZ^½°Tí|1»œ,€ÓSŽ}»AŠ=Šy£ŠÝêíF$Åy¯¾g4"±㢑’¼È[ãØ vÝŒ…eŠ]B#ÖÄ<õhÜ"÷ÝUv{•tdŽô[Géî–IóÏ\‰fæ,Ä"¸:Ü>±À‰€†teðÀ@Æ=]w”‡Ž=l™à¨Z Ž6lºŽLeðã Ôµn ç⤣7Ž:”„a¢ƒ2ø®£OkÝQaSð­4_e†¬QGU )ÐPêút'—|OÎOò‹w•Ï£úÛv­mÖ9ÔÞÊË’JýýZ×­ãQ h3¶/X°­çðŸfV\Öú’Jf§„ ^ç´:P~þ™ýø ¥ß^ÿºùš¼ýHöûùŠŠÑ"¥ÒkRßb‡‚0šK¢Â)æœq7/³Ìã怒ÉÊ"$< û„J‘Z„iâNJâˆPîTq†Ð9¹ºxænW—‹ú¶iÙ¦m™®e™–eEíWó»Z/¯èƤ0°ïÛgÓ'ûª§kÌsÑTéøéx*9­ Þ5}ñ#~{Š×ñºòzUƒ9+y€x<Ù± ODã8™ä<˜T«õ/;®õXlæ`æç…œï_PK0XJ@µ )»ÍÔ rebar_config.beam]VOlÛÖO’hIL(QvâÆIXSI˲(JN,h»Šà4qÝü)0`¨LIÏ6cŠÔHÊMN :ô°:¬Ø¥ËN-ÐKÓ¢9mÈ c¾-@l;äT» è¡ß£^µøñ÷~ßïû}ï‘Ô»øöÕ B©¿/7–®,…^!ü!4ŸñiÛò[ÏÝ´·Òm+ xèX¡í¹I–LÝݨ"\Çn—nÚ.í¦ì µKý¶бa¶ãmI0i °Iw©“äóøçQ¬x–0`¶.ñ.m¶ä ì6ÉçRQ-¯ñh-’>¨ùM÷¼îÀ¡`|Ó;ÊGî³%ØŠ²Qr:…÷*åJI/": •lîŠ×¥ Ÿ@(£áo Æ0,ÇrÓ2VëãdqœèË)ËDՊ㊑‘u³‰Ó ¦&$UdÅH\½/c=–»Š°™A(‰dÙ”/êJÓh’fÌTHD×a^Æ>$˜&‚ K3õYuXAÖŠå¦û£|åË îÖ 1Ò fS&¢ªÊøNýY¼1âñ†bD5’Pïã ¦Šïet5 2y“†Ú|L1I¾‘WH:âfÈâÁK3úò†rpÌüú‹âϋھY Y![nMVåÆSB~öüPS+d™ÄÂV±TM˜þvÄ5K6›*Iª*~rØa¾IX‡º‚¿‹åRY‹r]Ê’E¬­*´µR”²UX抲¦¯c1k6u²&o`19yÈQº$c1·ãp;^—&@bbTb¢jdÔu¶ Ðü Û@A•f£ÔÌ<õu‹‡ÊÇ@jãui¤&#) ¤ªEiR‹ÜT•5µÅÉÜW ç8”?Q—¦ gj´ü”××a †}@yؤzG^—/ªUX¡Q%šYPÌ xùT¦uO‚î ðrª(©$5uA:­ddöÍdxïÅS(‚%8]’Ô³YXëÏMöZ3S§AöTSÑXkú,¾Ë-ƒö4ËQ>“T¿­KôPy<¥{>£§Qdw$¥AÝè¶p‰`ñ Ø, ,ž="ÃKð$’z v—-ôt:þáä×€wx¯›`LÁ£*Mcñ 3àoF‚ÇÜ7„˜f6M`IRe(%ÊbE`–Áòì‚4G–ˆ;RÒžÂZ¬Éb‹%h¤¡)ŠYeʳXœ«IEr8]†lªëfŽ!à§ÂÐ5˜cU1Å*€5k Òy(¢h³Ò¼ò”}´¨%þdØÓ<{åÃâùšT%€\yXX¹@ýÇ £õ¡ÀkÒ¢t-ô¯³Ój¯WÌÂq4 1 Ä>7ËÇ8ž‚‘æÜ£üÇðû¾Á ÏpÃp&yÌ8¯ŒðOŽhžâÆ«œÃâiŽŸq–{cü×GðYÎgŸâ9®©Ã¨ŒèWÇ·Ø: OaaðyƒÄ5Îñ˜Õ+ðøìÈš1'xÌz8ν0l‚ãÇùZ~Íó˜­]–ÇlMãÜC‚Çh¤Ãc—íyaüþÖŸ:tcCÞ~´ùäÜ¥+—f÷ßzô·þv9yw•<üæq®\½–¿ô|Ü®\Ë?»ûYþYêÙó;ûWM»òéþ/Í_üö¿™¿æþòÍÇ{ÿü÷÷{çç¿üÊ0ÿœ{ôÿÛï×Ϥäw>¬Ý«oüŸœž/{VÛäÞæ¹§5³k™ûe{2Ãñž=KKaèÃõ¿qXçÛ±."»Ën°+£½ÆÝ½}¼÷»ëÿKÿkãÇ7!MoõáÔÓ o÷iDd ?6Y(¢$¼¾õ«Ÿ%‡³ÛB ,Í*æÓŽçw9‚dzhbH¾ ?ø/_u7€#ÓN™-]$EÇ­V0èõ,ÿö°ø ìÚþhÛv‚í”´ÝŽ3èÒ.zy¼aeq·‹RË7V/¿Ùº¾z¥±ƒŽzÅЊުTôJ¥ò‚$¾»r­µºvñí”Þ²C•¶ÛFµ6õËA˜ÚAñÚÜù¹ÄÐîÑíD^âY1+e¥-le"ƒ7ð;tÍ”·½-ƒqºSüN9:c½Œø‘tްh©°g ýPK0XJ@d©;ˆÌP&rebar_core.beam|X{tՙ׸ެ±¬FçI& ŠÈ$`çA®m9 ¯`b…R^²c[‰, I΃òHiC¡((´¡mØm»¥Ô}ÐÒ–Rvié‹RïÂn¡{gÏÙÿ9{ÎþÝý}wFöX|εïã»ßó÷}ßï»öàö@`óþáÑ¡k†Úõ™@ ´%<n:ÅB3_ª7­u¤ÒÈ—+Ín§Y-ԦؔÓî™­•ÉJÍ)«íæ¬,;ÅÙ©÷Nµ>Åh4fÛ]õ#½•V¾Ã 8Y¨¶œžÎ²¥7šõ’ÓjAÌÌL¡Vn«•V»š„ÔBi:\o8ÍB»R¯µz]Ö³íJµ¥;Ç Æ¥²“oÚÓ!(”/+«-§Ýb5çXW¥Þ 3…ö9î½£­Z¾ŽE_Ù©:m'_¨Vóõâa§ÔnÛÓÍú±ÞŽ:Ð-4Y©:ÕJ±»"—ê±B³¦Ò^¨å ÍÔ˳U§”z FµR’ÊJuœÚÑèLáD.1ínÍNNVŽw åBs*è4›õfßǨlOi°t ^á¹°á”i3²Œ¶P;A“¼§NW"n4D­Ô&ë½…r9“gœZ»·Qoµ½C£‰­™¢Ó$sò­Ù"ÙY®”ÚÁÉzµ\íw«Ö eü*ªpxm²2é ƒ†Ç«R›Ê -‡TÑ:“09bªZ/ª]{ö,ª-C “<•¢¥éz\òpo¯ëó|ûDà 5ªŒy=ßЮô 1òHhêQõ:ÇÒl›ÜêDç0ÝX\Tg§*µÞ!Ô­î÷}\^.ºÎs/+µBóD¯rJËsH¦o½6ù1YÛ¶'áò¤dµz{cò¬Ú–JVKñ[w€rGòÓ(¶ƒbû§RØ °“ë’Ÿr<6])MGjð84]•\ŠØ¶>ÚžÅý•I"¶¥=“VdwéfÈ+ ë“Aì2]6$?uìû¸À›ÛõÉO(sÐÔÕ"(Y¬I~´- M[Nr±gm³}BVž@ÏÔîÏÆb\ªè]}›tÅ¢hètmµ¢¸³5Š–‘ýKŽý(ýûDjDX)aHdfßfÝcüJEËâø ï_~üw|ޝ„®Œˆ1ŠšÁK%êÐZ¢²t› ‹u‹> õ0ã*Ü¿쯎4•hœŠbdŒÓÝqF¥ƒŠqYµ¹“æc Î z”š.¨JUÏÔÖÛüY~ˆÐvM‘P´kÖ †ºîùõt~=AâÀ¿VÑP×oÀ ×ý輺ÐñB`£*e󇲷i¶T¸¸ìÌ1ˆ=ÈÊ]Ö(³ ^“ýWQ)L6¶ÛEÙ¢†…î¾Fä Û.WùuÔÐ*¨!0JHìWíº½ê r~ 4 ü¶Â©ikúÔüƒƒ<8å,XJ%x.NP±bõßÿ.+_Ϙ…Äè']krŒÆ0Êä--Šf‚Õ8nSe“ŠæRs€_Oåç6òJ^É/—oÔ ·K®.×%Ž}އ>¡c]Oàü Âü™€¢Ýà>Dî êÚF•1?`´ŸÅùgáæW !úá­mJó›˜ßÌúL(s9? Y²úLPäAHõÈ("*ñ¿™Íëv€2'<‘Uå­›©‚Ýö°¿uçáä[üN¾ÅOD6=-tþøœŸà¬ØqA,|³ûVš f0+ºÅ^bÜ6í!–Rå{)6šÊjd¶¶ã4O á¤)ÅÚ­Ú†¬å,Á£”æuâ]ÛIl9|šE¸2ä2*†7Ø]8ÈC÷Ã~ÝáiüƳ|7¢a£¤iÙ¼B0¯Ì'ø”¢MRåKÓ{‰Tl)7E+ì-nL§y™”AyØ¢hŠÛa2ø4;‚óê¯á5+†ØÞA%‘2DInÄ¢zÆÜ¼Ï4ÌA>M뮦 ^Œ=`d$.úÆ`ï €¾X§Ð¢ "PJji~„¹þ®“ ˆ¯BümS+¶¼8¨YTðžÓu`á7È”‰ ͈y×gð·5țЪ¹ä?lX»-Þì6o›ü˜¢µ#¶Ý)ÑÖƒYð|ÂæÇÉ¡ÇÉ¡³ ü¨¢Íê²'žÚÔ¬g Ñ;J¸¡’}Œ›&ñJ—*¡ÑE©£B´L“úxÄʆYF²}f*¾- :Ëý&Ñ.F^'œ€-,nL¯þÊwð«è£I$ÕçpÞ†ƒî@ƒñ@qª˜äYx§k„Jî¿ *ÞIäðó]ün„-t-´EálÉpâ9<ââŽnΓpÜI?ðNâ©e¹¥]t^#Ë[ã]Pèî4¿Ók' HŸ‡äYrOD~‹‰ðQƒrÚÔ¶‘C~§¨Å1Êj@ò!P~7Ž#x§D—Ñmòûí^ÚÁÉ}ü±M¤IL¢ò˶ùƒ©©Ü_äsŠv?A?Þéœ÷Áþ9á_=æ÷2·'ô’¿¿Hjâè¡4m@[I< hCàjs1hûŠÛÝ$&=fdz1*ì@ò#`ð%b?<’æ§S^KŸÏZàvz…‹å”… =1ȇƒ_r0Ôét,S·òGc]d…|µjçèÔ—ä+ó1E{”ŽTyÔOGòY£hy…pÞ«ƒS¾ …>Åž@}‰ÊŒ5d§¦rŠFu‡!JÙ©¥U‚?ÉÐy´Uä.(³CÑž$ãÓT)_ÆÁj»)LÖÞãz´çV&š ˆGé…ó‰Á΂å½l-MÒbÞ„Í馻kÈO]â ?¢÷»ÎŸí¼ßÁëE¯Œ¨n!»¾“G'£»— ò§áÎgüx}†ðê¾ ŸÆŠ¡gzoÏg(â_“ÏÃiÏNQê>‡Õ=X}^¢Ym­áò½t?¾Ï3»Ãw˜™)›?oì2øóxm%ø×ç9>¬¿® ú΢W¥ü:ÙÁï ¥ð£Z@÷7±ñ<Éþ¤BL¾Ióê}ùpÙ ÿĽà7ã#¼©Ã<.™¯—Ìqý[8e ô5¢ÊCÂÃyωxkΤïsxz`Ÿë³~Öge+9 <Çœ%À¼@þ4¼uæE¥É ¢}›v`Àw(6ÔµŠö]l>€HüÊåb8¨íbný޾ˆ£ø–'íUºÍç)eç)e¿_ä/)Ú÷ôEö’»‚òÀXç[àiþ=JÍyRò‡ñTúÑÿ1Cà ‚ÐóµÅ%Dùoÿ8ÍH·‚‹ãâËü§‹òi™Õ6n .qxÙÏá§iþâð3pø8¼2ÀÁ"¦äà>woå?gáÓøôqõŠÿúÏé€=øåiþ3âôKpzëWø¯ý~ ?fˆ¨E¸íýurØëä°_ùkŠö«E‡½ ‡½FÙ~ÌÂSZe ú.ô{ðU¿ ¿Nó_’Ü×Ƀÿ áÃŒéF+S´7°ü2Øýf€ÿß1©‘^þ¦¶'šßÊ;nÉÅÆžoŽ[ŠöÛˆ9†Bï}Ö ëc^¢ÆF æfê› èÆ‘¢ý.Íß ±¿‡ˆ'aîø7ì• @ýpÔ°äCJ¶Köw<¨üü1ÍO¬þV_òo ð¿,Áå6_ -¿þ\äo+ÚŸ]Ï¿Ño/Ææ-?Û¿¤ùŸˆí9æ_Áûixâß–e¨,4ï Þõ§Ñ»Æ¼/A£q”6ɤòiRf‘#Þ*Ðò\ÝØùj—©Š‚ê½ú.iðïÐà«°î?–þ%é¶,4—¿âì9œ½7Àÿ†8xÖ¼oìÄ0‡ ¼> })l¤ÌáT`|8¥—üýqT÷÷GнA©DØ~Ïï€÷± ¼§hKó¿2ƒñv3Gÿx½b¦¿Œþ;„AG*†‚¡aôx{4Â]>š€÷ÿÛ¨·o`ļ}š¯ôæçbô{óU«=úµ뚦O·c>š>ýo÷Ù[öæwúæÄç.–ârÒÛÿBÀ}—§ó½>ýï ,arÎgËœOîƒ>úG|4Ox4ä“§¼}’ûŒç³´?zœòBÆ®ã~ö;4ÿ?ÿÿ]” PTUÇï.°Èc€ š$awy†=§»ÊS‚”ë>î²ìݸ»‹lŽ‚ ‘ˆ/¡P¥8ͨ°¨Xa©9*>Hˆ)¨l• í»ø55ܙߜÿùŸÿ9ßÙÝo/ñüél6`ƒ0Ï*„˜ã:£ÙÑ:*F` 4¢?‚ûÎù©a¨L€›¸Î2w{ÏÆC8Ä3 VBÌ&Êp~÷±8ǦcZ¨Å~¬ÛùMúmÊ$¾ãÕò[)Á×ø%^Y©%)3Ã\#ëyƒÁû÷Uy¯=/Ü=Ü.ÐÍfîÒÅ¥êÍvQ¡!xæÎî~cs„…³}¸ UûË|µ¦ëd§hËVƒvNñ`nÍçkc¼ü´¤a8Qµ9¹qÓë?î7~ëW¹ÕE~¢Ú¬q}¢²f5uÉÅSÿsSnÓøÿ.ÓÒgΓ%׆䣿ù?Ìxâ¦míoh¬TåºÖ´èì|åA²…ɱÕm·Fβ|g3®ýe1WdãÜoQÓëq´ÌøÓyibv4©kÌÅÖîn‹“ë™áøÉ£¿»z%ÅñúÛoׇçss#úf}ÞpŽÔOoë8è ¼?è8Ǻ§·šÏ:WòÐ[¸ãÔÚ½°cºãüZù®ñ>²Nnè]tZzr©‚Š:}¬òûG}ƒ\c_=Eæ›íy`”{?ͨõ· ²œ¸W={nÐK²î1{Áý¦ë¯—w޵øÜȵ×jÓšY[Q¸KD)Stkužªr=ÿ@Ñ@ª×ÞñˆÙ¸ûÅwK FÏиùVkÿwüžiÙDYBÈÛ±u3R£Æ£%Î^Póo#o2êú‰ä ‚6Å¡ŸëK«{ ƒ7Âù"‰ÿ¿šÁßÕíŒTe§e’£úWg õ’+ÍéŸë¿²îž¼˜Ö+xê8dÑúÝ—î Ó®$ ^šÊ–LœÉûø‘g]HtåÙãžï1j)Ó‘Ð/< {ktE_þ¿ëп ÔbÏ]j03´¢Gb¦øý> upõ) óÝ+zºÏoöaþ°u°óŸ˜? èð¿V…Úkæc¾5 ëèÐgêh3à#ÔÌ9…€3*ÜËx9˜É”¨OŽuI@ŠZˆqïN õ`;¾Ò€X<'Ø‚÷aF!ú„ÑÑ@8Þ- aô[@(î ÞÄZ@f¸¸Æhœs€uÀâù{l à…þ+€ Öu Ójif­ˆù´¬,¶Œ0ÉÓPËÊŽøæÒ@zÌæŸÿoÈ"5"I$Œ‹ŽWV™ ­)‘øùf/ß)¤5p)%aàäÀx¦Z…ŠÌâÀ¯g>.f‹-ÅVb–xÕò5j-%•„7K­"¹pqRÉÕÐR.MJÄôJ$UÓ¤/Içda ÓWÄ?PK0XJ@íHöõ è rebar_ct.beam}Xpåuß½ït·:kí=íéÿH^û„,[–´'lIXòêÏé,[–eëä‚cù´w·’Î:Ý*»{¶ qB“*néBIp!JÚ44&ƒ]BË`Bmh ÁÐ CŠqÒB\ê)m¦}o÷œM§šy·ï{÷{ÿßûVs½{ö…F¼ÔéÜÝiéS Cz†æ -¡ñ¤åJZž¤O¥"*Ò³céñÂqÍŠgô¤š\6ni¦Oŧ ÍÔ²–w,Ñ2é„'m¢fÁ˜š15·eä4÷QÕÈ:–2ú8ré“Ü’ (ÑŒ„njÍȨÙqWm-ѲG–9*9+1]æDa2£9|ZÖÌšíF3 Ý(°& ý¨7«›–áÆH|G´¥Å‘-LNhÉITôÀ·éì8ioh'ímí®´îÓ)ÕâÌ Ð„ª¦lMnJÔâÉ©”SOMq(ͪSšû°žÎzÕ„i’zJã ]·kÆ!vZµ& sÙ”6–Îj)oDjjªÐ®Þ„nZž´‡bdÒ¦ezÇ2ªeiY5µËPAßP§ÌÉëÏEvVܜ֒¦NêP:ÚÞ9@|‰Œ–*Hi‰ÜxšÐ «(©g2(Žgô„oLÏ8é™ü’Ü>y!xL§ÀœÎ¤-Ï”6•ÐŒbêÒqa±a†6žË¨Æ '†¾²GÄÌAå=ö§Y`?JPœÒ`R’ª¥¥ì0ÔŒÇÒ'¡“+ D)GÉ.›]¿¤ Ã><9øeSz*—Ñâéì˜n;Î;—Õ}ä¹!T—IV’á)וÖå§ÞÐX7–Ë‚xU]~%oÐXj: Qqè“bíœÆÒ3ž„šRq†é†I`˜Â¿…}çodL9+¸Š×K¬T$IŠèV¢LPiðÊŒâ*±@ŽH¬ì*NȬR$ËJЭˆ…TyAΑ›I®L™ž×ØAAb"U® ÄYPþñÊ’²HŠ‘;h­ŠÈ÷ÊìôNÂs¿/³w/ ©rK¼Ôz™´]&RaÜ]D ‚[à/#˯€—WÊ”ù¿ž;Í>„–¢ñJŠBÄösì)%*‹JÂ1!R()ìp>‚p ‚%‘=«¸É¬ !è!¡W F£J4 º‚½RSÔ'Fƒ‘&—èx¥A|‰Ä^€ /í ìW±¯T`9¡H$^a´•÷“6^´ã!Þ`-/оrA’ѪgFñ•ÛEˆNN˜fXÎ(²èeŽ)Ñc¢“‚½›&c‡Èx¥»kùb²ˆeãŠÁ?'B \¢¨€(J–Ë‚­õQÄ*TŒžKƒ­|9ÄSžO¹¸¨DÏŠ V2{hYÁ)ÂBüœrÁù,aI-_ꞇÆ@Ë Þ«”è%QnŒ¼´–/#×á®üŸ¸2œ‚€ äÂId–+Ç$VBüUÿ*ZEá‡0.`‡ùJh1_ “įžç×°ÜjZ áR+_‰Uä'V!.:uFÅè¯ÁQ fè®k¶|VK,'-?³Rˆåe®€ŠóóJÒG¨Á£Wàü ƒ¨dIDçœ¯Æøªaùusüz–[ RÊá¯Zj#W†}lçƒ,·^qû *3\1VŸá è0`0裂$D„øÃPÇÐ+‡þqt# ÚTËW_=¨”€¦b}Š[I! F8+Dˆ‹DÜ0å=@ * 0ýnÀ_åÇV¢V)äT¦ AY ¦ü1¡òW,´µ ÝÚ\'&aÁPYpèÅdø”ååh¿EÙ0ÄOÙñÇ(›"þ”]„›X®ÊÉ»½ÛI(AëÿÏú.ÈÂo݇åäáùSN8ʸ¶ùá±ÜMˆŒr«D¥‡ÌN èUaíŨ; :sR#²F$ cYcÏr³8 Ã(mán*b0³Z_Í-|-é$b0Ìo†õæÖÀØ)€­…3Q|õö5Çm†´8¡Šy :0¸±¾H°/Ù9ðÕ" +óM8XM8X s|#Ë5€Z^ŽO™ú û~ޏñrá*EÅ×j/žý¬E?° @‚ è $çr€.'ÂN±7ghqå Öˆ_bIš°$aöf¶™¾H`œQæa˜›Ð™«*Î r+±íðÜúR_´ÚI=vnÌ·aŽm¸Ü-ó|+˵Øw„›Kà³U¡L:¿LvBHÛ– Xú H'ŒVÈüv4´‹Õ>Çw°\»“~M¿—ÉÉd;SÀX7È;c7]o¬õ ±®9¾›åºcÕÔX÷ÇÆzÐXŒõ€¼—^`¾¢7@'{¡¾\e-…­ulÔPð’á6¢×µ ‡^@O‡±þQn!öæC0 ;ÀxT²oé-ÌÕÚïà¥÷‚ß}]èýz?tç<¿‹åv:—.ö|³8+}ò½³k©Èý˜Ênð¶¤E @ëa–va§¤Z~¦@'eÓÄ::à´ž{•b2 pëXnJ Ë!‚PâàbŒpd2ÜÂï'M';LtCæ}x¸qa•``V–ŠÛoWy˜Á›šû#°0nñHüV–»Ž{ÁËþS„XwD´'¸Þ¾œ¡X¾|‹Ÿ ó·¢Åƒ`b˜iáÝh¢á&FòM óÑDL AP£-|’ÉVÒ‚LDœ|sA™Oa_R8RêŸ`9ÕÉ·.}x&œÓ¬$,½–¼$Ã|½¤ß0tŒ«’ 3d1üG­ojžìY`or /ÄA+žÊÝyÿçùŠ\@ Ê£nÕEÌJÊ#fÕ] ´†â+ÖRñR¿Žòë‚”_Mã]²¹Ú¬ÚH1Èo¢˜Z Íƒ|å+óð @2•‡ò|55åùjËËq­úê ä·Su•<|Wž(­'ưƒb°¶ýy¹äÕp /žX¦1‘ì£ímî¦zC”Ç¿½TǦÞ\6Fë¸A*¿…böÐ̃ýi 0®„Õ6óÀÔÐȤ¸Wøåþk÷ž9³oûã+»]ÿËÓ%·ÿ{ç?mézúLbÑ|ü½¹æ¯ßvßm¿;sü‰†ßú«…«Õ_èªûé÷·Þöëêãó߬9¾_?ÿÒÈ‹? þñ_Ìßü«ø/jôŸÜ6tù–±¿“ž$·l.û9ž”Nöëɘ3Šö2DçqhÑ:Ãȸaf÷P~h'aÜ—>*ÇgÕÅß}º)ßI‰¥»ÜNñ[n¦|3=#_´…âñn çí|5ÅH@UTŽw]å1¯RÊãý¹‚îj!‡òîNË2ÐÞDNÀò‘#fÖ>dA©c:ôäøÅ÷»½¥Â1_úêáÃÝ}Ù1øòCïF¼WŸ¶ÒzÖD'ÅðöEq375¥ŸA€GÏY©´1ɸµD:‹6=ÉxÓÙd&—ÒRÌÇ?áLø.•b|]Ã}ý=ñXßîÈ$³¢Q5Ê!9 É¡Ph ÄíïŠ÷ ôî™d–§-IK$›Â͇혎h† AM2áú-õa”¹­ô”6áIÀÅøºêR}ê2•U‹ìM=g$µI¦ºaBŸÒ pm²Á4’ öcsñ¤U¯™ÃØÄ„iaÓÿPK0XJ@EsÝß¶´)rebar_deps.beam¼Yý{\UŸ›s“9æ”;¹SZ ”[îZ†ÐÛΙ´Å“L'*”¡‰ÒÊK2™¹IÆ&3ü¤å½âª…¢VPWÅÕ‚o(¸‹o€øÙuÕ]Q@AªˆE¶»¿ðìó¸Ÿï¹ó–Rì²?lŸgzï9çûþò9çÜŒ\¹sc °þááôÐCµÒ\ Ð}n ¸-Tñ&³•ñ¼W®†Ê¯\)å¼j•Óx<_¨ôú˹Rqª0šöjãÓ³¥Éì¬NKh<[Êa8U(æ»óÞd}z‰Ï1[šføuOeg«Þ’êžBYéèž-TkÕàT©âes3]¥=KË¥j­¡µÇ«Ìf‹Ó b—Ô‹yB½|·WÉV½`®4W.ÌB’W«—ǽâ¼^«Ô½®RµÔvÅb¡ÜŒ—ÛÓ¯ÔÔf*¥½KjÈÊõÚÒz9Ÿ­yj¬C{~iÞ›õKÈ,õ¶Ô7¿^+ÌV»³“¥Jͬ¶¼o†%Ôžë¥ 4çù$lU/S0¶˜óô÷— Å¥*P…IZÑs¥¼l –ûFùü´0^ÎÖf†AªW¬Ö+Jæ’l>¯Ö³ˆI¥TYBAW¬ÁŠ7ïU%Ò“Û›çÍ•à\¡Z-§»³óÙÂì)ÍéñBQ™ÍåüÌÃcÎ+ÖB~Thº§ |Ò Å©’ᇅŒjĦ27^™Z^ñn¨`^µT¯ä<äe93À˜-—Ç•Òìä¬wŠÏMsŠ9Ô P6àI ÒË|µØUñX¥^ KsÙZn¦[ý¯ïÍVŠÜÛWör5/Ïf²Uƒ.”ŠãðP‘Ò Ç•²:T¯6­ì*”zP€ ÓúOÉ—ögKÙ|cMj¬:_ìš™f“7Uz&+Ùbn†Õ²Ó*µ¤£§P¢\§f³5T^NÐtW.ßU„úÒ‚ š‹ÂãÇeÙ|)Ÿ-`™ÜTãµÒ8Ê{Ö[шk~|1•ŸAoŸ—«×(°K E#z&³ùleº·\)€Ø×(|?£¥s¥| ¤„žB¥Ò1>£±¦ ñþÙ\ôzgÃÆ~§ÿ”¦qìM{³¿Õ/6õOÕ‹ 9­¿£Ÿ0Ûæî®LöÖßÑ ‚ ØØ¢ŸõÔþf /bxË´Oéo#@Ë®•ýmX;ŽzÑ‚Ojâ]Åã>h*3XõðÒøÿà÷_ø9šÑÕw¶¥YË,C²ˆì2å&´’™2ÂtKXrÒ”]6áHÐ1hþšß”L³Á4³ Ëf}˜‘´:7`Ê{XÐÁB ¡ à Gü)©3ÝçÉS>GJb2ךHÝ ZŽæ`ù€Åk†cŒX¦2\&MÖ05y)Ó2]}¡°¥M,3¡nÙÇbuŠH×a}†©•%Ó142†±1ë´°\§ZÚ¡KÚa VÚ#¡„<Æ1 ˜pÀŽ3C+¥+™´õ 1û)[hs¥«o}^{Þ¦— ":ì/7ÌÄ"™©=c”4ë2G,Ûu3®ž¶MeÚQØþ&ŸaiÜXfÎIsq0EĦfB„M2/KSŸ6¢FQ’îãÆþ€Æû¶3›»b#½‹]±Ë•X ýQü^¢eÊ:¤t ¶|9 ä§B”Q+ŽZ£dõEü~ûVö•àD ñÓzáÓU`Å*(^ÕZ±ŠbkÇå¤3׳µÍÂ|1ýtKË*2òt¨²¡êŒ· ãjÈXÝV›gÚ@«À¦¼3 ËIÛ¨w·Ì¸uØÐøjŠèYÐp4X ±Æ¤P¸ûm¹©©fHAð×9Ôë0¶eë1ÄZGiÂÖ¶*´Þï(²íeLh3ÍL3­›TöAãÉfÕ¯lU=?Ò·´saIÐx&&Ö1÷tû«ëNÀ±ÀqÞ€èg°aˆ™È†câ—6lØ4âæ•6јpXÈ‘vDŽš2nËU¾îˆ|Rl@ 7øtÄs³)6¬¡•"¶ Î×xLºP„õ uTºOšðoAã͘¸€… j~…Ϙ­Ö­Á µ¾RãçQºuB¬g€^@YÞ@‰@©E©st<ß§.Äs“#6²ÍLl\!ïñБÐx\ºoÚ=ޏHã ”„ÿv!18¿ÈIbHÃÅ`ÐøÅ ‘4“"iâgõΰ¨Ø™×'Uo£dhЯîG—ºq€x¥Ív`UãÉq¡9dÆSŽŒ™gÔ».7ÜP$=š2}[“bk|K\l]!-±Ù[4¾y8Ž9Gl5&Ê#NÜusÄo²mr"Ó¤Ž[Ui'$‹ÊTd$ts@¬xªÔr†Iq RvI«öãR·e"N0‚òŒEHFPÞ ˆÎÖ^CR¸iH‚.–Öá¿ËÃŽ¸„²ñ.Ärh‚†!–ñ5H4õIåc[S¢Œ!2a–Љ3A&Å¥`¾´ÉlùRbFWØ ÖúÁG#¿;)\P»Íús©þ\Ô_Rl Š´Æ·© LçúLÝ`‚¾tŸ…,’â2H¸¬Sße-}meÄß\ª¸K;*î²æ;·Ã™Í˜ƒUÛÑGÛM }dS9b»½ÙÛWÈq9šã _Žh«í'éÆaÊË Äí*˜rUÛ”aæ 0W‘9)ª&j½fße@šiú!¿3$}¤_©ñÍÍ-éonüÊæÄ`c"Cž\ÕaýNX¿%£ñQGì¤VØI­0†V¸Zãc˜#˜CX߃ð¾WãïIŠ©Aüp&È §P€)#—»Ð/»ì 5KLìR°¡0c “£ºÌápÀ#Ø|ÓL7É Ó¨\¼÷KËérôxi×TÒ®^fd’b7˜w7™w/bNéŠÓ"N¿ewuduwG\Þ‡¸\‚ç5I1Ž˜7ÓC{Õ8R`P•IH°Ü×Sì®Wx킸Nã×¶0Ž÷ãeå ýTH½®µ_O o·Æô¦@‘¤£?“ÄÖ¶4I-—Í64h^Hé„uê|3Š&I'ТF:Í&°&pæá+’bN:7Ü‚Úp¬Œ‰iìF:Ÿf6 )žfñx:‚_T=mÚ®\i9%(XNx˜®r !( ï^èr1¥qϘ¤£Ê&‚²ëT3œ¡+Ô ~mîp£j›ºÒŒ86á©kª‰ŒkÁ²+áûT³˜Wº 51}R²¶J–N´T¬0ÃÑ·ªˆ4T$«¸j±ŠÄ§:¤.¡R·Ò<€½!l" Xvºz“…X ¾EÖöÈ„vsŸ¥ÔÔ\LM-)ªˆµ«(¢ÖƒŸÆvX‡5^\6a%Å€ò‘Ö ¾Ö¤-AFØüm]íbî$§îjƒÏAò0swR$˜9H0óQG|LãmÃÌÁÂÌÝÿØb˜9H0sPÁÌÇ3ŸÌ| 0ói<)îÌÜÛ 3÷ÌÜ«`æ`æ?$¬L§±E Á6âòsØñÒF \ (eðâoËî[øÏ:ÿ= XxBGï…ä Ý^þ–Hò'…aQÁ¦Sj?]÷·Êåö©ÅäëOBþéÅäç„üï‘ô)Ëgh¥_Ÿ?`XtsÃõ#Κéˆm§™MÆh÷„–€¶i´óbâ‹l\_TWÜÆË :ߤÐ&Åýè¤û;;é~“z]mü.ï·Ãtl^•‡Aw¸“ܿ0ýÛª —Ë¿î§Fxê ˜ý’# .|@9üe8ü8üU8ü5:. ÛýWð²^¾Š‡^¾†—ôò ùA_wă$èAÚ-¾AÐÃúM£7Ã&Â(¤85kÂÄuö ?ä¯^Ø\½hÑêÃþêÅÍÕE«ßôW“ÍÕÁE«ÿãö ØÀšGɸG•qÀ¸ïÀ¸ï¸ïiü‘^¤Ë¤xnn}¡ÛcÄñƒ¾€ú¶Æ¿’-Aê‹ÔQÄu9t|[õ;½†­f{í»­ÙK:f¿×š}WÇì£T?ôXóãЬú|Ѹõ<Oæðü~R<Ž\?~<?Nh2N¥tüºJ©žë§CÃQD4~ „xOâýÐ?ÒøÛˆ÷O&d:ŽºuùP«r‡UoÁž³ ëGðO))žÎ=Õ‰sOÎ=œ»NüX÷ÿ¢ËJt®%8Õ)ø'' X¤ùÉtœÜÀ§@’Q$©Á¶N‚¸j†""Ð TºsùŸ¬žÿ"ûhÃX«ñŸÒ Rð¯þ—Ô?Gã?Ãä ˜üù€øë5Œ!¦®mç¶¾GQR.tæwß/âg”æcŒÿÞcˆïkü—Ö›§Ä3l™c 1;žÏáÂüœa¶ Äù9º4£tR¸7ëôýÑùa#ž¥b}Vm¥¿Z¿Öø¯šZ®ñ·MÜžÜüzÑ虄ø%ó,mÏ5ÏàXø Ì™‡u¿ϳeFãkä æ ~­¯‘1ñ‚ºÃÓ'aúÂÜéæó ñ’üBÇÍýwºÏÄï™/ñ$Q÷ü5&ŽìùkȆkç‹#ñP„ÑT_6 ñ¡Î€¾Ø©é8æ4þû„øéüô샞—ÄÛÆ¿ U/wÿr§ñ/uŠücBü½ÜaüŸ ôF<ˆ?7Œ_iÿJÛøWŽ3~O§ñG;5½âTãNˆ?‘ÎW¡ç&èù¤xþꢯO¸qJTÁ«tCEu§pRŠã¤g«{Ù•äé? 7CÂkâ/m÷_‡±¯wºÿz§û¯uõ—„8F¦¼Þáþz žÿ™oÀ¬7:¿º¼¡>&R—¬gÑZeŒþPuÙ\Oí¿ÿGÿÿ]• TSWÇ_Ù‚¸´¢ Ä€"`6‘¡ «P6K¨³¼,Ä,¼$Èd*…‚up+‡"™ŽÀ-ÇQb , ŽJ¡ÂªwÂ܇×Ów|çüÏûåŸÿýÞw_à~‚x™Y™A¦‘¬l Sìaf ÐZ äõ6üM„¼3Áw¾;á¹Û ã=yÁü ä7>žaqB}_ÈxÏþñgíD^_xæ=¸/¼NÌ„…AŽŠ"ðGCŽzÖIJ%ì—KØK:Ìg2xoûâúê –2™„ýªßâ7yŒðtÐ/:Œû‘9j¼çRø«`Ö¿ºèpÐÈøïì ù] Í×ÁΫáw$Xÿè[9@¶„÷Eé”x?qð}êáÚYØ BùÇ…óà–ýIxG̪rÁM?÷Ázéiî­8™Ô$ß«?Î9[ÊSÝõ_Ç=›\?×ihGßm±ßtß7›Òv­SËÌž7·¨‡ƒ-VK˾–nw ORþ‹re²ê!Ý}aJ¶ýéWýô³sšhJ¨ÚɼkâŒïíŸû=nÍxÝĽNÇÂüä3Î;KÊË(«ë»7q§mýræ¼ÅîTBÖ7äù¬ »Äļ週› Ô?ÌQo˜Æçƒækmë Æ?ò?5œt³kxÃöÙ.1[LYÛékÙk$b÷f/‹Gõ']ïÒ7þáHú% ŽáÿËÒç:C?*kqœ®® X¬¸q\ét¹»˜Æ=m¬ðÈ<~Ý1ä ME?!vxÔÓØ‹´X˜­QÑÂê[íɲåˆï¥Æ ‹r¹`]ù‹š=CØöÝ¥j}|kÿÇV¯îf{¯ÅÄqæ7VI´‹ÝnÎöäiÖŸNkOb´¬3G}R>-bê]š®Ö2ß1Øi¦MoiJâ–e«8ú§žCªÿˆt¼äè‘x¹€•xæcˆ™ð˜÷”/mü¤`kíï«ÿ§ÖKî‘øåúw]º%-{ìõçWÔámEýUüîUëû«»÷¿mÛ¡ÝÛPûðòõ[öˆèû î­•6/Ö–s&Úûz¾Hí÷£GM DýoÜ£3ÏðÀÏÿ¢ÏØbkPßbà…;ƒ¡*äéËòºÎ¿ì•u\÷rZZŒHŒôÉ<àQ§?æ|5‰GÜ_ϳÉÒКrÙvç–jß¹\ZûU Éf‘ñëÖ<^ÝSMuÜlߣ1e0YÜdXþ[ÄÍdÕ¾çêÞ¶WûÎòá4£iýÃ'ówy£.ç'Ê=ã{‡ö[>Çøìëæ²] «ö=+}¾G•6â2[Øysl¦¤¨JsîaÔO&ûæå¹|ÒV™](|peÔ+åËfÏg®ÉHœJþ—I××3ƒx>äCžzë|È…<”ùÐ!È·²!iáÙñϷΓ,Èß)aæ2ú@rè7I ß$ƒ\}ülûH ó§!ã™ ô+ ã~1Pôñ}$CV@&ÁçGÀúøºpèãs%2(y=ëñu¿ƒub ‡CÆó»ü`MÈxŸ»Lä·Ùå ŸßÝ!ã>C¶Âµ®¡Z->—<ŠâI©™!gk”+”«‘üÒQ«bÍfgrTýó¹øÌÌð%þ~–Wòæxž¢Rke*¥7,EˆŠa*,C£S(øX.°Té´"&GÌQL‰;$™¡È”ƒ:*B¬tJ*–)Q‘” ¾‰ë°Ô˜¸ˆŒ”˜øH9bÏa±9,›•Áf³Ølö›Ð*nxrFLBT¢±‘È´®¨@ÀññõË\é)Å4 )9báËðgøâž¹V¦@¥–0}îñÍøÖ|>‰o»Ò F¥Ã„¨ñ`JU ” GåL &db¨€ýF"T­a ØÁL$T Áÿ>‘ÿPK0XJ@Ÿªnï0rebar_edoc.beamMS=oÓP½ös“4I‰‡HVËP©R›¤ ÄðšÒ–HýR?XÇ~IÇväRC%„Ô‰NL ýÌHH0± T6@ü$v¸ÏqE-ùžsß½ïù¾•Íí €4]_^\_ =~!.g}ÖÒ}™žA…!Õ- ­~0Ö÷t3¦m«ÏDÏåNÍ„A~h5<·muH‡…OåÐÛ· =´ŽT©‘m\àH…´\Fò…n“"(Bù¨Xü ÂÖÒ@)‘$x––·fš$R”¡‰¦XÌŽƒp˜t5骬dÔÇ(O€ðšɆ|(¼áTÞóvQQ nh'ôwù΀¿Ÿ ²ž’ð%2‰6z.ŸCä ÉYå’sãz¡$z q!".ñ9J—ïü%ò9ŠÆ…•@kõuLU¡úwã%Œ°¨zZçÅ`SPÕ=!½Ó¯KŸ&xUv‹.y‡=%Dõ”šÀé©`¿îG¶Å«$_IÕïõ“æET=¥ý_"|^$¨§tˆôAd"%.rDUu¯#“šôcV4TQó´>õ&®ðC@òƒPt㟪 kzêŒßÔõÔ9l«|û4¶ôÔ L…u˜¦%v×è8¢ $¨´H­‚_ìó´*­AqîÖkÅ-5q²i@ÓýkôPŒÂPüpt«OëÓ¥v}+T}GE"¥@2€ÍÔ;~]™Ž@ôf3a¸c=ºÇï ²UzÌßó'õvZ×¥ØpŸƒØ{D×Nt’z$¨ëT¨'MtJô$ú³±SYÝ/éQ¿ÞïÈÂïv©¥Ý™¶ë©Ox€g|깎S’ÒâÞàaúÔw|ê{D\ ¯ñ£Ãd­DáºîÝz¤OõéŸð<¨²ZååÙ8±NÏ תâ¹&Õ‹r­ß§É-Õp6’Â\ór+â<ˆ*¶x¹“ÊbI÷c!ûµ÷¥Òûmº²äMeÁß‹o¨A!©,õJ­ª_|‡ª¬²ýªøÞIüæ´ («jÐÑ¢ÐkVŠ‘NUèRˆ £tJzˆŒLWu5é•üÉ”¬úÍr ”Å ¬µ1„€é@=(ÏàÂ.ÛÖͦKË1‚qIðÇ%5¤±éþ~6>w1¿Ò¢ìWu-òHɤSr‹¿%Àk­jÂÚ ”ò¦<­AØ Pí=Q=„ ‡êtÖ¦#8yêÖE¹­Q×õ¨Wt;@€xfv³ypažÛ…yäÂ<¸ÐÂf*+´W\!=¢ñšˆ‡‚ýñ–í`ó¢ÊÊve¿rƒÆfeá[õ—g!i7°9¢<ëz6»JEöÁÿVœyvm{v7›Ÿ]ŽŒgIcWH-·ø׳ù Av[V”çè~QÞ¨“(XÄw%¼I´à£_Ñá1ôÎsôÚñ¬z䨻ÊFš>'yU›k·ÁÆ\58™´A»Sô ¦-í-”Â+x)o«Ïæ}šù²¢Bâš(·75‚"LÍ.á('^¿”¯Dº¯cR P/4³h@Q¹}•°“0kíf(\ÇTἤ§è*Ò×.ÑiUå¹ úýÕcKg2J‹ã`Ê¡Lcí[„£Â¡è Ø5Êv­(_S=îæqÞåÕ Nª}êÚ`(¥¤RíÉ㓊 ìf áÔªSl! ìœjÊ˵º²®:[mÓ%YEªDy!´G^^Œ°7 ?áFM#“N~èä¨òüÖI^§äh;²Zí;SdåF§Ó{%4X:’)¹M ásf¨Ö¶äP7‹À»ˆëÂzÄ9nK€÷¥¢¼¤ƒEBÊM70x² ª°„üS©®žòcÖTŸ$‡(ëS LÖ¦„’ØIFàfPb5xue‹ŸÎ«'äøMyM¤”þ”7™à}fk>E]ÀÅußùe.ù›¿@~»Kþ+.ùë! RÞÕ¨éÔ2t©½Š€•„€•º€å¢Ü ˆ8÷ ®LäÐÛhi/¡Æ+ŵ¯¨ÕXCàËÓl…;+)7Àú­ðbU[-¡5öHÕRòld/X»UÞÆéf«TQ^c7 ûҡסb&H=1'°_AÄx#îêÙ’sã9¢2@*Ê °ß†ç&àÊJ0ôƒ¡_‹÷ Ùx¿jÇûƒ¸ªF³Î–-[ÛÂɸ­žÛÚyltdÏ*wjlôüŠól±[lD±Y^”GºØèžÞ…ôH_Ðã„_Å/¨ŸÆ/h *刪”ÁÑ .§-Þ  -øTZñlÀ¹mhQÊôð+•}—ÚLCkh£vB”óºbSœ£Õc9†p'ÝB73®é„B¸YKt03D6ͨ² 0$´xBè'Ôl<ÆÌ~g ¶™ÕqaÀ…}2žÕÎbë€#{’Â5Ï®8ËL„»‹+»YQ”Ç!…$™N’Î#I¤wÁÞ‘º Ü…ÏwçA‚ü,þ¿¸ÑÍö·Y Ž^Æ÷wVAwñ8^ º…ý»ñ´»ØÚš’ꥥil's§Î2ÀYårõ½ÓFº*Õ~¶D1f‘á„Ô]Ð~xwÓ‹©ó:§¡NŽÔxïÂ6^aå=]lo ¡üõi ¡{ÜÊ÷ÆØ]¤ünÞ Á}]ìž/Üç¼'Æî&ÁI€àþ.vÀùÒ°˜ÝëW7â;OˆËíwËÝ 2Nï~Q>c“¤á>h¸v±C.ÓnÓ«ÌOmÄ›ôsU‡bì>Rp ¡ƒÑ£ =Õ¡z-åûA?Œ\íb÷û{ü¡(žÑžh¢Ïþžþ¬c÷Ûz‰.‹„ÓÇB1ØZ¯±©L¶ à = ìÁØÅމòê¤lÇ‹·7à‡þdÌ_}9VÛ€è…ÐÆªÒ†·]JJ|³&ñ\;׎w±G¤Fmêî“è½$ª±“äÀI§‘žVåÕ/ Ùq4’‡«+¼‹Ð÷7w~‰±‡()'uå(ÝQ1p? k ç¾²aÿž§»Øãµ à[ }»¸Š¾ñ\‡r,øÞ]’Ón«ÇØcdõ hzšžlè6ìê`OáõÈyzŠÞxžÆþIì?ÓÅž½h /Oô‰·4Éÿ89ï©.kϸ­=cO“µç íQh;ÓžêBNwõýì¢ð·ðWcì9~§œ³õ ‹ò X>†å‹X.å¯ay˯c“„þ²µ•þy±~¼„§ç5L—cx1ê0$Œz   †Ñ„!b4óÿƒx¸l€ËÎÀhãóY³9Ïsøœd¯äFˆÿŸ…xÚ]ô«ù¼æ§—Ó¯átZ/äúiÞÁõ“?a>'ÎOô¨‹~Ÿ/øÞ5_Îù)–U|¾Úå?ñôp:Å’påj ç!þµ.[s9­uW®Öszƒ+'½|¿&»ÑEßÄçT£>W>oçtÒ½ƒÏ02.ý†ËÏa—ÿ£.ž1—oã®<Œ»lísÑ']ü]úïwÑ»8ýAŒ‡x½ˆ~Ü¥ç„+®Gø¼V#1¹‹0ìÄOX(ðýA>x¬­\·Ìçίñ[Ë«gm¥b#û4—ý:×'xö½ù[<ãô¹MA˜öâïñyŠÓÏr}‚ø‹—ÞÆãaÎ÷$ßÄOþ)†Çœ~Šû!Ô}ô"Õï0—?*TÏ¥Pßôañç;Âcðxî9Gµ¿‡óïªgBô½¯â¹—ë¿“Ç/·¾Jgt‚óSž¦9þŽlÀÃäþ óüˆ¾C7ÎîÍ—)'À­çÆ]Ooþqñ‡šZ>óZ<¿íåÖ^¹ú… /)Ü'¬þééuÿ2ãðk¹ÃÊ ‹Nÿg×ùe‡æüöÝ>zû£ Ç^Iýègç~þ­oüÅ–÷ÄÒöo~ØÛ¸mïÈ?÷zÃÿÞæ—ýqë+o-kŠ?±bñâeÏÿdàwØêOØŸ&¾[èþã¤z´ò]ã/‡³Ïçž=óaÓ?ÞÿÓüÛÿ4Í]tõ±u¿<Ñþô«Çþ{Û£§>¨ÜÒŸþå·³`ׯÀÇßúh`ëÀê;ÿ݋շÕÛÇž8úøöºÓß[’Üú»[_ÿá;©žæº‚æù°»­xúçåÁÞz ó·Ÿmxôà7^úã݉ß<Û÷¾u{ŸZðï_{ð{¿ÿö+«îû«?¼üÖûÝþoþùÑ?ûxîÆÿðFâûû×'c׬øìÿY¼oþku7½ôÜŸi­øõ–O{Gß>×öƒ¦È꿽óOC{Ö<ô8kf)Ÿ?ª=Ë17®ÜXz”×ñ ÆI>æ2\ãóÓ—áê¯õñËpåÆÒ}œŸÎê>ßq/Ÿïãkšï¹ owsº}ÞÜsãªÈyry>¿ c„ÏoÁÈrYêqiN§žx§¯å2D§Þ:“Ï©ÿÞÊyVq]#õšmÜêÓ›ùœÎà>§»!Éù`Ä9îžnNoã2¤Ÿz‰Æçt^Ë}hè)—-Zp:Òˆ''HvÑYUaÎáý/¬žóúÛMß?ûõÎ>M¬/aOvø½Äï3Kôc¢M„úœÀœ_HÓve|“HÈ ‚ã³cBÒÀø☴„-£Æ±/Îaûλ;`c ?“Òv]ÑÛ¨mݦiUÇB×±NíZV¤¢ZØ_§X'mÒ‘è`b›¶÷³/ÔôæÞ{ïùžïy>ë®w`(LQÜ©îXצ.SËS”í EQkty$©'d=·?mæ)-_Pr²î´6­¥º¦™.C+ê)9!ï3ZÑL¤Ý•×ÒÅ\)ä€õI5cknÊ|#IC¾O†ô¢êžÝA+˜†» JiꨒAÙt@TÑÔª‚®rŠaULìM抲3-&‹9snªh€î„™Ìd÷j‹=¤N‹œIiiÙ>>¦¤ÆÜª¦‚2àRÔŒ]ÖuM¯*ïšÓ2ÌnŽéÚ8cêEÙ>šÌ²ÓÈ*…‚œv¥µYå6-[m%©&ó2; ±’CÒ#Žî3æt¦9Œâxœ*Ëic–ÅI–å”.—4Ìð)£Šœ¶—òDIuÿ\]•uYMÉi’ŒÁ2p¡%ÈÃx€”«Ã(JVûÇç vDI=Q¨½S*4s5È%zA[ ù²¡X”9~L˜|8ùZ¾˜§Ù:7Å;ù‰ÏÛùcH8h§„-~ìXé4€æ¨ ò[åõ0¤ÀÔŠ{®” g9·AP²rUbeøRwxŽýI‘gD®T„A¬x ¶¬Ö H³ ÷‡ÂI]#rŠ3¼ÈÇ|¶ÖòLò]ûôʼn3Gã·ƒµu»îÞ¹®]Þ¹ï³ ;zìâ÷ñ»uXk[UÿƒÙ'òü×ß8=~^yìnþÙã§¶ù_x!”z5~$"¾øZvêÝáñ¥™Â•ž›KÞÙ¾9¹­cûü‹;Ök·?8ܱþø¶›ÇF.,k{éö寽<¯n׿®™zù¿ñŸ±iÝ+¿Új»²á]ýí?½¾¿ÿ½K¹ÔIûGô^Û3¿M}ð=—rK«ÿÝ“m7ÿ³}à©_>ôí¿M|eš¦ŽŽ3O7œ{þÈožûéïvœ¹Û©mùðlõfè¥ï\kË óûŸißùÂëw~ÿÖzωW¡ ýZŠôìE°9ô¬²O]–Of|½å“Ù_gõÌO«µ¶,ha*懜ÅžÎÂÍžYúø,{, ki"<°j+Ît™¦NxäHdÌ–¦Ð^C-ݨ8ë;M„bI„PfÀµJ¦[´¼²k·}Ë•"Ï>gEKf»] |»á‰Ìk™M«?Ât:¨²ÓZµ«½UË/6œ²ÙVí†Õ°K’Õò×*Vl7æÔ»™v«Ü`•½Ëm˜­j,ÆçìvOÙµLߊ[®ë¸»`¯-ZU ÅoÆÊN³iµ|²ûl5ƒ¢éV=b; Ûó‹¾S,Ù-Ó}‚gD¤u×ö­"s{;|NƒÅýšë¬ï®•pˆ­:½7=\rܾr š[ŦS±âå†e¶H§Dˆ •é«X ê[f¹&3 ˜R%Ëlz¼,ø2¤ S¡¯“æÅM¨ï‹ëv£R6ÝŠÔp"^ïMF"ûÇ„æ×»%‡MAl6ïõ§ ¢:Àúv=ߪ695Þ(-ë“™q}|dü6†·­!4T¯ÃÙ ¨ó· ¦‚I‰%«œº§ R¼@,DU(Ö覚!è„â1¨é ¼E_UhŒ-°hLáÕ·(Nѽ‘•|'^¸:ßK½ÍÔ¦t)\ûÌÿ:æ.Æ’Ò¨Ê]î'*“¡{D<Þ$†AT’Ã1,’kˆ» p˜èÎÑ¿ã~ª&øYŒÇ¨’¢’)† ÞHÿ ç/åŒèw‹êÇ”»ŽŒ`ªð‚*ÊkÔ€ým×åC”W6‰ –Çqõ-•»al+ÜÇÐðˆÊ‰„ÜMW⪗…£!ix)§,ÁÄÁ¨êT½¹avp ˆi¬YÖ€ã9Æ&…H#§@S ÍF ù e„–|÷$ûÒ.6ÛðÉõƒ» VÆõ€ QLëâ +ƒÅÀö€ D†OF>à FxVw_„Ûß…îÂŒtÕ?áYüPä³ß–;"ÌØQüK`wE>ãywä§Á¾ÜUçž®ú“_ð»ñ\î,Ó‘vä£h?£Qž}†vÂöYî!E?û“S?8öôo)¹ð»·•W®ýùþ§câÞ—¾zíúoýè§ÞùkóÕëfùÒ×>ɽ³úÄjõzuèð0yä—ÿ{ñ>çx}çÙøÊiëìÈ…7¦?Xþ}þähíõBì®7†_xà©>óÞçG&¶ß=üŸÑK¼óä»WjßüäþÏê—þü̳ÒòçOË/Ol¼!<¾sÍrpú;ÿþ«õÉg/hǾýÒöºuñÒžíïþeðÊý9çÇÏ¿ùâô•×.üíƒ#ïy…OÿñÊÔc§…oýìÌòòž f¾ñ‡­»Ÿ{|ùúRpÊlo'¢Yg¢9²ùèÑþÙ Ç#½R‘æ±è\‰|ö¾8ùý³¾ï²™}¯Á²j± Âg¼VøÐ"èÉí¹ÄÐûëvþçòÛÞq_[›_l­Âây†¸…8-z*HïE/h6á­Î=Nàà µŽÂ—,‹pv ìjT¬ ê ZkÕnY•†µJIs§O,O.>˜«£)=3¥Oeôb&£g2™]øØüRqñ¡ã×Q_ÕöU«TšÊ÷®…œÎX®¤ê(nLÜ7a°ïÛM«ÖS‚/ÕûfÌ”Ì>“3å çnÙª£ñÉšÓ´&¸UŸôÜòdx¸åݺ~MÀuhm¶äùì0þPK0XJ@rs'@¿<3rebar_eunit.beamŒXkUvîžÛ]÷Ì÷LË¿ÀmKfY¸mÉ0c3v{ä±/öà1Øì²hz¤°F-É/Þ…°&ɲ°XXX ËÂîòòš÷#Ä„lò+)*Uù“üáGþ$U©¢*•üHUjóÛ­ÍÚ&q•¦»Ï=÷Üs¾ó¼ÞwðÐVEIgÆÆ÷ܾ§Y›Sý_Eùçß›vý¼×ª–›ù·Ûó+nµÔ•LFgʯRžÖ½j£å{ùbÙïªÓ µ¢ÇK^3_w›³ËÜbQ¾¸ZÓoy Ÿó¡àV³\iè3åj1OÒ‘J¹ÑlDfj•bÅXˆðõ½Š×ôòž[˜Õ õ¼o†Úù•B¾P›«ƒÓï+Öš ´¿#Óž;×XVwýf¹Y®U»R©~ßk@=w|eËê~­.O^FŠw+-/2ãV^Ä®ùMÞ͉*ž[øsyf™ÜJVGiSáD‘“ªUwÎÓî«•«Ü›.WiYÔ=¦†=ÁY­jуÁ^1Òh•›^o`C¡V)—t’TªÔ¦ÝŠF¢@²ÖôÍîFÓ/WKÝÍÚ1 ÞG¬ µz³¡—ùãž?]kxú"Uú ë hÁ)œð¡å6UB%I 'ö䙲ßhnYN;:¾¹w!`ÇK/ަo÷¸[®°ñ;²='°%†îà}9xBªdëž8tpbüвŠ|yF-’DS(ŠGËÕB¥Uô¢DŽd¢ï•Z×gõV3Rô¦[¥e|•Z‰á·u¡0„ü›‡K¦+^1ür«nåÔ¼©¸Í¦WÕðo{(¨ºÊµnÚî6Í€¹À›m=­PÆ=ÕÚ=")z°Z¦D‘¯‘FAñ|¿æ/w+8 x*/i^QÕÞ’_kÕóˆ¨"¸ePjåêL-Òœõk'ú—¨›Ÿ«»ñkU<.Ü’ ×"'fË…Yéò[yÞ+vO»E×/ ̺!1O”ŸiU{!y:ˆnÕ‰eVªÐÚDCIáUjX(öVkÕ¼wa„ðëÁ9mNÉENë.̶ªÇÂFŒº ©¢·Ò­”KÕ<’‚½"¨­jSM…¦ðþP¤èŒÈ÷Õ—Ðó ¯@YÛ]®Ñ1±N¯´aP¯¡§ÈìuQ¼òÍš zÑPðªMbJFPª…åØé•À²J·^ÏSÚ6zðV)\:Ò lÏw&Ü×l5òÓÌbí(x’ÈÀäã^·[È7Ýiæ!ñÜFÉœóêsE­Ñ¬Õõ*Ž=æùU¯Òs¬\ÁÊIàÖˆ´(Wùò@¶ n^õ8j’ßÐ(¸ýRk–5¢ÄÙª4x–Ÿpáh \®ä‹ðh4Ô,:Wþš¯í=xä€Ù,ÏyµV3OÌpg–hðmóêºÛjxáöEõò¤nÝ+®ü#R~Æ¥Pˈ`¯x^}9éÖ`SW2eËÖ‚1e§d…õš¯c­÷ÚxÚ©^Â’œG~^‘êÀnAâê?¢vl‘º-G),—äüî9onÚóõbYFœëŸÒnì@®¡·-oÕ5’¾>uI OÚŠçÖTDV¥é*Ò¥züÊ;¶á¹-…¶"qeÎÀŠ ©ËDểcmjIT/Y»:u¹ ÁÛöõË[SÝèo¥æì×rÙ©xꊉ¼%ôólýð­—ðlÙ®­J-7AX†Òï—§[M!à¬Ô¥er âQïdyÙøÆÀí«R‹M <0ðnléB[½K¸¯(& àv§¦º;˜ZÒ!YÞnÈ*‰k/á[Ôëòk—_ Y“êœ'–€%ªµ¼ìÌ2ËÖ¦– ?K„˜%@éT&¡8ŠÈÒå@§Ùp.·ˆä~­Ö¤ _¾°„Ý1º”æi·!Ç5 ºYô+EYó÷x5”àßYEQ{ñÌ©F×ÀFKµú¦ ‡Ö”wœbF-%jÉó5å—¢Šå°½à‹6¾/€!j8ôæä ÓÉY,jM8,|ÙÁW¢¤8™¸Óe:,µ§¢FDÑw"îÄX'1"v)NÎÁ±g$í0Ó q‰±?µŸÀ ‹çpPÉÀ–¨u~¤Åv´˜5ÆsŒ1'Ã3£)æ038úH¯ÏhQ!Jœ ð?‹Óñ‡™Ïh–صTd<Ù2}'ÓQs˜æ$ˆS³þÓaiz‡rؘÎô'4[l–'BæûãeNºwôÕ,ja{l'ó Ûõuãªíh¬_Óýª³ùÎ Ó¯õ ñ¥:áìeg§à€¯$Ì>PLuê6¦Öoaê™®}½¥J@ÜPϰAQÏûQ…÷bÜâŠz ›õ‹……©páK,\c©_õ9pm¨9úéè×âpnv4H°^âÏcIa„> ÙŸèÏÀþеE& ¦Ê (ÍûéH[åI‹ëC½†µK¦cÆé¸8¼BåænMîˆõZö®˜X!­‡ë+¡Ï;€ ˜WìŽ X`^ ɶ¡òÁ^­AÝA[¬Úb-à«ôubµÊW9¹3lT¬Qùj§ ú¬!'êÛL§+=´µÁ]4Æ-âÖn¾²3ø¸ªÏ1(~±€á±À8úv¹=½š£ß¸„€$”ñÅbyý‰ð5 gYÆxî Fÿ_R$‹Ë而Õ$M6É,’¨„«kPëj¨·CQùzxØÉïN¤àyv3´CtŒ>Ê"–ˆƒË÷.<7Hî‹àÞ î/Àí,rïiso÷˜¥ò¸-6š;M±‘ÀLÌM*OÆ>ËÌéÙ7»¼°É‘k°k¯£ò¡>ÛÑ#| Ë&ÅõY}ˆà2™£ïƒ35' øÚ¤¸–å¾tôuðËu*¿¶íÛDÐ:•_¤±cÆÎÈWŽ2®u±ñ È}eö÷ÒWS Q$\ïdÙ€—$´¸Á¶¹×¶±ŸŽÔ×ÁÞ€/ëP¤$Ž8â0¦hÔ¾Á)Šœ»Æbm )7t¼ÛÛTn#qÆVl9ˆåm‘6RšŽ£|Ò¨Ð!P;dF!†ÃþŒ@™Ò`ñv•g‚0@!°Ä¿«|»¬ÿë-r¸Á7 ~PS,qoÉ8±‘’‘†å¸Aé—8-Çû)IŽ~§)•‘Sm1L “E7¢›T~£Œ=…Nˆƒ³o¢CÈ SÔÀ´»^;’b'ÓÆíìU(µ7%ÅÍ̧zÄo¦¼ïÝ“]¶ØKçìÄéb÷4wC«ÚëôYüå¯ãl~ 5Öã^ãØwØã‹1•ïcñøYcq%=7DciýÛ†=±Ïb9?—Uù؈ØAû:ŠµØ‡jãä-BAÂcÚÐXQ4ª-”ü¿Ú]·oí^$Ý ÂÂâþ/ˆc<¾Ìˆ,ÃJJ÷³Hgýž€-Ç7øõ€4[²Û}ü§vŒîEå£ ãQ£f"çvðqBÁš¬Pné³ G/‚× c79"öÚýî'÷:¾¸ Þ¦ò[Á÷/"B„¬5–U&DzF!)ö§T&5§@FÝ.“”ÍÂ%ᛲýðÛd)‹ÙÍÆ”$#Ùx‚²‘¯2±c†pÇ~2ç°d–Ü”gtÈ*’-U~2VS2‰Ãà>(ûÀ„au¦œC dSX»ïÃó"ÒÑ™uBÿ¡'Âoh«: Ž9åá^‹R‰BZÛâ{dpJ¯Š;õš¸K¯‹»T~gPn ¾eD´G;娩'#£âˆÊï£Ê@Õ5æYµ›Û—ÝრôúFzXMïIg'A„ŽJàX zäÈ k¬a<œG'ჳ†â<ŒICü]§UG)0î†i-äÖ7mqwzgZÜM ~ Þ£òoŽØ|k¼?n8ö>;c93wÒ”÷\Jú6$H÷öÚV¿Fu‹jJ€Ugîäa`¾ÓÀ¼L³µ2u¥Î6ÐÐîc¬ä ¤ÒH@ÓYÇÆ86’øuäa .Þ¯¢ ¢?±H¸š¥µKÔ&ù)ÈSPûê®›Óñ 4MSÝ“›iðœp4R=rkjD DaQû –Ùû(´cr>3Ͱ<TÞ`%5 Ì7,…¸ú‰iÕ˜°¶q ¡4Juò¤Ea²qÙñ eIšT “Š0é´GÉ ÎÐlµ`Á ,˜¹œP½ô±ªÄx:bð [ý‡?Èæ“㉠h¬tŽœBw£1EÖ°ñß„ÌÕñ]ƒy‡'è ©R‚*§¡ÊlPí·ƒaˆî†#ÛÌx.HCÊ`}ñs_Rc*þ˜*¸¯%‡ëU¬Ó‹ßÈLÓ¸ÉÂ%İ\6¤¸æq¯R† |,+YEú°†”|djHabÏMŒúÚ0D]‡i—^ÁAã9̱#èYâ³ ò£xÖúP«1‡"ð•H…ï¦Ör${ŒÄÝL‹cæb9-—µDv»:DÐuÿˆ¨å:szm@'´6Æ,)Å m§&ƒ²ÌW9‡™ ×~=5$O8ˆ€}¿]Pç•7dñÇðÍ.P郒²ÀR¿EFƒ¥“Rc™ô¸°€Ð ~Þ„z?„z­>Éø4 ¡–š„C.fÄqê@›åÀÙžƒº‚û8Ž('†ö~ž„°“ÃâAÖ7aìa™½8Ù¡XgÖ/pÈ“»â%E†pÛCÊ7Š„”Œ„°ö禘9®™A匫üÔî^Жçä|g½˜7ýa1ßO£ ͧ±š¶ÇÒèBi£0–¶Pç'õG2bm~¾qM?%FÅ*Ÿ—ûA;=kÙAâ¼Èº ñ¨Êÿ„(ÐéѤø>SýyºÝíUù÷¡ßlLœ î6ãβ"ùcßéˆÂ·jýÁ5òÑrp:{®^1ýü5õ2pÙ²$@ü@ÇÇ*qS¾ü)Î<-þÌ Ór*ÿs¢@‹$ Zü•?âKÐý‡#âqàñøBQO/ÌÆl~«ÊŸãËØýä°ø1ÛÃÌøˆø‘¹? 7º1Sac¦¡CÄmÁð‹Y¨ý!g} Áðv¡åbã& 4þš `zRå?Έ'ÀŸà¨WpÔOAþŽÊŸÂç«ø|zX¼Ìp[ÛÃpe’û“âg 7Š¡ŸIGÿ&tô7’âZ‘7gUþ ð²)inWù³ù¸¾é¯±€óç œÏ«üçRÎëáÒsKÏÉ¥7X æy[¼@Õã9ÿâ‚xQå¿Ç¨8§ò¥*?—/™Tþ"¼3*~©ò—è¢Ce:­¶Ò ,Þuô7ÃVs•ÿ2øÜáq›¤"A}McAοœOV¿8oÁ¯ ‹_Ã-ñôfñj\?ßk;ÔÃ1¦cViLÐ\Œ‹ÑoÑ^ŬÐj¥ò_gįHÖo ëß‹7!‹æš70×¼‘µz'¦0Ú@“w®ýÀä^ÂÁoÑäõ–áµ âu•¿”• •¿.kŸuGRœGCeÙp….0.+ƒFƽáL²nÐTþfFÀ¥ñPÑ·hꀈ÷ âÃañq¨ÈGPä#Ó^¢È‡Š|(ò¡Ê?ΈHÊ'ò>¼ø#âdá'ÌÆx‹DÔ(Q˜²{ÉÈä|ÖiÈC‰¤N¿Mvzø‚>Àó/Għô)$(LÆíb”8ÄØ¸öŽ‹í&òv~„5">ÃÎϘÝ.Š À¢ÏL æd‘å“§#SüÆlœÉçdÚ4ì©}VœPQŸCÔLj°¿ŸCÔçLbÁp[aF'i¢›ŒËhJìývøŸ&íê÷áõ{rõß@Ú'ö·‚Ìý_ÿÿuVTWža&]b!šŒ®FWwŵ„X²TKp †¾*EÊ.ØKBŒüŠQCÄhì5š"Æc4b§J±¡!¢FF±€ÿûàÞñœÎùv¾¹sï÷î}åîÈ*NV«’$ƈ&ÎŽ3)8UŽÈȼŽs”x/òÃò§ì:*‘Xþôá7 5r¢ÚÈI:0¨À ’Œ*ÆÏ¨ͳícxo?5×r7ëT¢6Æ_Rp*YÍ©X¾¤TÉ¡¤Š‰Ã’ø‘,_ ïû2ƒp†óåÔ ^¡ jPW‹f£ZŠ7ªµ6¡ÂOù+üš;ÀO¼ÒLæT²‚¬<¨\ßý%U€k€Â¤1 BÿÐ ×ˆÄ (‰›C„°opZQ$;RæHè¢ÀRƒœ G->D¸Ž·8 ¼TÂ-•µ#B·9–ÿÔJAí¶A¸ÃITélnÓ5ÝÑ ’4þ‚À2˜Ç»á>碕 ЕlÛ–=;R+<à†qƒβ²›p¯Ph`ù{ÿ.Ì]ب ô†¾Kp_/üEx é=„QÊ!½G¡±-=˜¬`:½Gtt£^xH¢› °„§-ëØ_x¢Ržqµd©ZâÓqOZ—ê1Ë?Õ MDá(T‚ÂsƒÐüÿ†~NK4ë…g$ðo¬‚Àá*0‚|Aþ£þ&/!°Fd݃†m „ù I[Kk*ØÕ /!ØÝ‚ÏA0gÐ(¨QÇÁ^ðV9J -ÀÑ ½ÆŽ؃ÀppaD âÍÎöüxŽåÈ~qw8Sîük’$«Èž ʤ«Lp”áY-·ŒÙM«q†Õ×8w– 5NÊn%ëî$JŒIáÚ²•Ý•2ç`Žcs¦5Œ+hj:Ü@#ð†Qìö àNLëE¸’²» ¯aìëõ::¢á*ôq¼>$¶úØÎèCÞuAîx“òïŽv’Ã[”¾DåÓsVz¡_@?ä€þèOž5xð¤ü½P‡pæ@ø`ä&jN¨9 D;ñ B{`¥cBNjŸš‡PŠÁضZˆÝ £j‡ö ¸ž Ú£¨ùŒFN|bЇØã¨ØIh#µL¦òŸHñJ'íV€k•Û ä³¨œ‰ÏGŸCéÏ£ìSöO ˜Oå¿€â9È¡.`1Ú?§8™Û¥èó ímëÈbþ_R9|Eåö5Ú‰æZŒ]XOùox…Ûaþ›˜öý³…òùyÛžo;S;^·Mg5'‹)¾›òÿ ídoaÚ×î4Ó¾î%LûùªfÚÏÑY¦}ï§ò¼HÙ/»ié'Œžií#Éè»9ƒëñ6Æ9á½þY©ËÇ1k[í,qŒÝªI1p»ÐªÉ¶õ&ÆnЙÙp+Æç›¨Ç°)>¤wœÀç:Ì™QLv'gïÚK0W–™Þ™Œù Úɼطè¼]8n1þ$ÓÚÖOöýÏh?p$±Š“kà~uŠ˜Ö½Ä8¼{žì¡ýh?Œõ3ŠÛȹڇv2~kå܈þV¬k9À™øÛw$û`#ú/a°;Tlí5"1æƒ>hŸ=cµ%l|Zµ,FÕn]ù}~ä¼N¾áa=]7‹Ç49e콺}Ì{·íÙµ;yÚàù÷—®ø'ãP÷“‰Ýð9´r|ckŸ¦ƒ®!¿©âå´yQ‹§/‰/<»;âæé™g<Öw^3Ò×_Zïv§§ûÞ#ï>Ûäæpâ‹„ù.©£Ö~³qcÿµ·½Ýz›Ö[_pÉxt°¨aùˆïV/™»©!¦`ÍM箟®7t¨aø' Ý{4ªÛ"wùöÝèy­§æ‰-¸$bL¤9oÍÅôåëz ùáʽôS¯ONy'Bµ\ØãÖAÿ$fzòíÍCývö뻣htÝ©Äî¾Or¾üjߢnóËo]ÝúF¿_œoîœ]»¥jǪýEGΛå:o-=vÀ{Nà„Þ¿Ú­ZðÒôAˆ_ÎþÛzÜjê”W>:rÆó>£“ü-¬Ù¶{xÁ†Y¿qûqË`ÚªréýæØëuÁ˻ܩ¿{í\tNÿÁ‡–6HuÕ!š[½ï9½3|'ç­›‘z´qÒ†ê¤Õ¡+"WÆÎÝw÷ÊŽàÕûú5­I¸|ú­f½˜÷ûúuyų£Ÿ.tXºæ‹áÝ–øzþ›]CaxͨÆ3¹Sƒïí>¨ä'§çýUJÇnÆô¨‹ù:ÙÿìHöœMÑ‚öÞL·B¥ÿ§AøÞuvZýÌ%VÏâØJ—£QÜÕȜǫzÄ5}YªYsðÒÊ!ûï¹ýÞ%îĤ›Ê”> šw—LÏiô/YW|›yx|þý<ýÑéÛgkö¯íq87ØÔ踩ô¿Þp@F¤Å“³áÔï•þB÷”sÈÉ™®ANŽ]žÃ€JäÏÈÊ‘?”áù¼ (EûíWúÔ)ä×±¯~啞uy-ö;̱ý«°—Øá˜t_£{Ý¿èžE÷)º7Ñýh/ŽEþCö '¶‘"H%½©cIïÚ†>+^ée›‘/{¥—­FûgÈÉEþËòÑ>cŸ1„gº"ÏÀxr¥²‘OÌű’³Ñ àCäÀLœŸXÀtôÂ1HP‹ØÃP‹ÄŽA-ÂGâ‘“oÀñèïˆ@ûPÀhk Æýȉ|Ÿ¾‡ö>#ÓþŸëƒuõ@-r‘ÿV=ê“od-ròMýjvDÞö]ÑcÔ"—³of&ùžsÏ&_z컆›fKmyH™¹1çˆ8czà vYDùš¤$¿ ÔId¨ñwLKÏLLKµƒC#X¬Ö4k´-kêÔXëLâà–•™hMf–¸ÄTba“ÇÄÔø”¬K㔕š`™”˜jI˜ÂÁ»„Fi ñ^tXÐHS2óú@­×@í@/m´——ÖË˫͉ð3GòÌ8ONÌ”,qquúAI-9M³XmT2c¯à=@OlŠÌÄ©–)ðìx9Ö.VëËÆ - ÚÒ²¬ñ–d¦¯ç”´©OHÜ’ìi³Æ{Z-q±ÖvmÉJMÌ`±¦$ùÆÙ2ÉþPK0XJ@÷­Zsx rebar_file_utils.beamuWklÛÖ¾Ô¥$FZTâØNjÚ’ß‘EYrbKyÐödÅëdq³Z™’(›¶D*•ÄXáfvÞ°vÁ–"{t›Û"ØÖ¡«a¬ë­C°!-tk€ {¡M³nhú£@“aû ÛÎ¥h[õP<<÷Üó}çq¯¤ñc'"yK£É‘GL½ˆõB(ÊJF6Òyµ ¤+¦Z(;bÚÈ;ô2m.–çU‹ÐM=ë&>5ÜQ ¹¬lä\ŠQµYG(äÐ\ªž†EW^7вé,¨e³ìÎdÓT´º*†ÞQž£³¥´áGEÎιʦ¡j³ô¼®jŽâi†€hrQñh²©ž¶T§bºQ—S Š©¤É&šx¹ª—¢éŠfn«bôY â4ç ýÌŽš-éœj¤­dêÎfõÒbUwج9ç!ŒªÚ4*Š3/Ê “‘˦(/($MvºÔ2ÑY¥œ•KJº\’³JÙa(nC)@¯+ê¹ TSÕòúöYÅL×¼ûC›HáP¾¢…ÄP½eÜxõ­¿²ÁGÅpL|Èj è›6hÞ˜žSrõ‚Ê¡êgD©§8‡¯£/ÇI˜v#4¬à¸‚…QŒxQá¼Ò(Ì$)Q¢qí¶ÜhŽMH˜‹ÄÓnA€÷}'ñ–9o-ä͇xJÚ0íå.‰¼”BØ-ˆnN’RkJÖ0q?~S3G1Urø<>:ç@°Ÿ»‚ãWlbW€Ø öLæu f‘äç—äfìH+’7øwHJ‰Sâ$.I;I ŽRJÚÂâ•M«Àâ2°¸,v Ô-¯(4Ðï—pð`y©2ay ÂòÀåß¶º#±›;5|P*và$y‘:þqÐaÖ¡|ÕP£˜ ô±>~-ÆrÂDä)Ê’~Äü²´gìœÈ |ÊÓ”‚X¬™Àn’RQ€_8«î› Rª´%qÀßÈœñAê ¹3~H¾™£˜Cì.츌­Fpç‡ÙF`ÝT˺‰÷4õ±;ž=Ð 'Lƒ@1;9ILØRêœUuOv‹+RêJ+[sÙCr±ÂµÀ¶Ý1¶Ù·‡$ö„k˜ÖÚŽ~r·V·v« òn«Í»_{Ì)^à.V ðzÓ„­M»üÉMk#¼ÚWx†Ù€è± Ùž@"Àö4Jž6èéd;)&^ÀÝ+¥nÁ$Þ‰’aJb|‚¥~˜Ã~ɇ§8v„‰œEŒ㧘Eèπň ΀EǺ|¤†úÁTDíúE z öF`ï  Õå}öò>²¼–ohˆ^Ÿð궯Wr…‘y§1öq°k8Æî'‡Qؘb}ì|2 "{'0{ºÔÉ€N¤˜ÕS‘&«í!—xmàC16N>Š1BÓ¦ñù¢˜(–àIu¬ Úþ»1¨º¸ Äâñ‚°¶^²Ýö!ß= 5vÞÖývl¢7‚ì²ý[@vÛú ­6>Ájp¶NövÕèë1Iœîš˜=¶ðïµí{ABvn$f¸&>Ñɳ¤hÄÒo¯‹¶Žìg³m'Ø;krõÙ:c?‰c¼¢‘˜1Û±Ÿƒv<Šªç¢Aìö>ÊñÑ×.Lª&é ÔúÙÙg99ö[‘{â’祣¯RÁާŇ©q×ø*_êþCýÏ+ïÍ$Nþ2wµõö_>ݳúÙ3ýúöçãíñ®çO½úüs=‹ó-ôå¯Lýí©C‘^¿öfü¹–®î~C¹´ <’}qòáïÄÆ¿×ñ|ûî‘—ãÿþ?õ…Ì—ï=ùÃaµè¸ëzïäOþôÍÅë÷nß}⧯‡0³tÿ»á þcnŸvá¥búšºöJãØÍÄ¿¾õÚÈ‘ŽïÿÃqðý·Þþc@ºØ6³ÛQ×ì§ÞMƾx#<õxûͱ_½ófå~b¥ëÏ]úkûç¥Sz÷×ûÿûþýW?wíw¿‰ðÆjëïóÿ9>ñ¸1yøÂÒ[Ïì÷Þ‹ÖÅOܺøî·?4þ‰&õ,©kήwÔ®[¢¦†C[ê][㾚™Úv2cí¶Næ°m}žFLÓ óõ¥±Ì9rŸ.kÖ‹Æ¡2»üâÕ›7n\m¼xnðÑùù± -kNËŸ&þn½dªºV&W±Ö¯Øt¹R,ÊÆ"qpé~H. Zɨ±Pêr«Z¶PÉ)9´­¢å”¼ª)¹9 k¹òŒžœ˜üTú¡‰“ hû€"b:#‘Ⱥó™±éôÄÔø±T7«š‚’É Dcƒó§ÓŠQR Èëß×#6ÚT‹Êœ+çmÙ!{ä:™’Y‹`Y¯Yeõ‡çô¢âÊB¸ldÃÖíM­æïC?ü)˜‡ŒG2e“ ûÿPK0XJ@ÑQò6Glrebar_lfe_compiler.beam]TleþîÇÚ®íØ­s(q·5’ÑõÚKÄo­]Ýܯ8†Šè­í}momïš»+Û‚#à˜¹À$b†.?@`1Û&D·™Ñ¨`c€!1$FÜŒ¨HŒßu· 6yîÞ÷yŸïýž{{÷5´=ç Oðë[ê59 XÀ(u((VøT ñQ9SH1A¡NÆDEÕð5…Tû’4*K11n‰#O‰ªæ\b#aõaJÉJ6#Ñ[[–ÛÓQY@y= 1š°K²Ä£^ÜA”âyHQd%ßð"Ç) RRa\ÒŠÜcÁ /g4Õ¤ Œ¬h´îˆ”“¶´,dñ&¢“ uKÿʋ܆ÏËJnÎ8€ àÛ} ,ýöa`ä é¨` vË@Ò}NH›9):`TÀ!ÖC\¤q5 ‹)K†a Žt¼ÁÐÎrx 4ù`ñ·ü+eÑŸ^¸î¾rØ5Ó±ñèþÉÚé›_µ—™Žñ«:Çf6Ö V|hû`ÏÉ—ƒÒ±‘Ñ…ŠÛÝ u.ŽõûiÏ^e×ÎOÅ›ƒÛÆ'}'ïù&.:R·h–£Ëó$ÿ7O‹Óõš¦èÿÑî”>õ)j‡*å‰[_{ï2[Óé«ÙKŸ˜ïî4J1\3çô´®7ãOT”%U'L(È}Ö¼šM§ÃJŸ.0ÉYM•$ QD”t†“À,JÑTV@ÈÏJЉ® °ú;›Ÿæ·4¶“ ÐÇy}œÏËñ^/çõz—E–­¾±µ¡- lqQcQ$â«®Yßó´)*6•y5UµU5:Gkb%Lü‚_ “akØ&Â9ƒªœU¢( 8OBN#6Ž’U‰zr‡ÓÃè?Gf>žºA}DÕôwóPK0XJ@²†œYTrebar_log.beamMTÍoEŸÙñÇúcšµ×©Ó$m6^§Iq>Ö!A¢UÐ8i‚Ò$jÚ {í];¯wÍzq±Ì‘ Dê !!!U½ q©øÄ¥‡^rG9CÅ{«d¥Ÿæ÷Þ¼÷{oÆãwoïA¡ÈÎúfé~Éw[á„ó̪î•m·²Ë›^Õí˜É¡»æ:u«o˜~¹a»UÝ=Ñ="ënØô<× fµÛˆu À6M;BC($ôvÛ¶jºo¹N”G™Î±à6c· ÑÆÐë:†Y·Ó ¼ßëšáºnẅéÙºÓ Ár#u×ké>…P½k‰cݶŒ!'-Ë!-ý$1è.Øô8äñΡ۵ ~Þ8oµíAÑ“DË5º¶Yæçá ]²á’6\ÃDHh•ÐðÛ,’XÒ9„•$B!DÇ‘Ù2‰*($ѱ….¹CºÙ^juz?*šXcU–ž"̘7$û¬?$v:$íî é$üuI왕ýN¢šTø‘œ§‘Œ¿ûàçB:.!üÊòØW”÷ÿ"·Ïˆ²N¼N$µp&Ÿ3•ðŒ? g$ž†RÜx þtYâ”Ô4FòLÎ U˜âB4Cn.¤h´ò2È…zC£2ŒÊYÏÐT|”¦±˜by’ÊégXFNe¢ŠÆB²¨0(’fç$­ÉX”¡²˜îÅQ¨?ްx5w†Å,˜Ç®(#™áE†`™ä÷™!\oŸÓ•Š‚ÅkpòÇ& <易¬ÈÍë`*ª¼Q5ÛóèTŸ*U:}JsXœš§ª|ºÆ©2OsrªXœÖ€Þ‘i.Ë<ªžrWNÈUåk”§¡Ñæ¹r>Û«Ò›íÓ¹Sz ‹7Ùâ³lKâëÛRøz‹mi|}่–&»R‹óÜŠ üxàSzøÞCþȶ[m¾¶1ÄßBa€ €+ðTà¿ È| pí’ò¿~‰«|‰ ›'ƒºŸ¢€\°¿pþãçyrЋté?oŃÜXPÂŽåsýU;ù¶V©TôJåµóG½2ò$yþâÁ~ï³µÿ^ýûͯÏJ¥7¥Çíg_ý|ðÓoOôÁ .²ãÖx> îc:¨Áç™Ô¹˜ êM6 zžâÇJ¾ïÁ:÷¥Í=‡‚ÈqÇŽ„Š/_ìª3—ïFúŸö÷¾ÿøèhcÛ©Ãæ›A|ˆÇGÝ6Ÿl§N§ÛjéÞç< âv}Ãòš(dV-‡{°ÕDQË©Ù]Ã4ÐÅØ;$°g(¾þh{çnùáöýÍ&YÖŠËÚrQ+‹Z±X|$>Þ8(oïÞÛk¢DÃò³Z]~weõhÐŒð4ÕDá•Å÷W¸/ä[-ó0R…ô•.èq=¡cì¸]¯f6ÑìÒ¡Û2— q³¹ÔñjKƒù}ÁøÈ\„Y|„P©ÚñùeþPK0XJ@Ë"íª rebar_neotoma_compiler.beamuW l÷¿óÿb_9ûL’.qàäüRÖ Ž ã«¢M­f.öÙqìÜYwg L°¬”Öªº–!Ø`¢ôµQÒ6öÁ×Övˆ5¥šÖ©bS§MS‘ÖvUéÚ½ÿùL=P-=ûÝû¿ßû½w§óðúÑEy>ŇÖ™Ú$E9^§(*Ѥ+c²žT Œr2¥MsEwÙ ›ÖRI]ÓL—V2“éœîžÔÒ¥‚’T¶›NE/ÈjÖÑ×'T’ŒÉ†r;ÒKª§šV+š†§â”ÒÔL.‹²ŠékNS닺V,ä Ó¨cr«\()®´’‘KÓmh%=eUk°¨.;/“ÒÒJݶñ\jÜ£j*¸Ašœš­St]Óë+ Zԙ㺶1õ’R—‘ †â2ò¹bQI»ÓZ4›/UžTXÒ Q<XÒÔ’2ÔsVzwÅ’Ég‡–çTEIÕ.b-䯏‚ Ëä”tÕ’Õ‡u%£èŠšRÒÉ¢’5CUÙÖ §ÓI¥ L*ªÙV UÝÅI4G`È¡+.])ä”┡5]ŸÑµIË™5Jc¦.§LÆÈíPêJ*ðÜ`O.§f´FÂtÍuGðÎì‘`!ÕýÍð@(ºsFRW²¥‚¬©g%3W0ƸÓ0u˜ÓÔòŠj4ÿVH)©Lßã VmaÛ¶¶€¢˜waŸyªò)ƒ,"×4ïðu‰´8óE>Ž‘€Ã ÝŒ¨`äÇÝŽ!K}á€u” —HaÄd)ܽ'øf6b£v8!8ŠØ)Ó’Ã÷ Ocìàg„u’Hopø®Šô(b ¿3)àG¬E‡ÏÍóô”TBƒ¨Ô<;>àö>?z†Þ‹è#P~Nb|ŸoŸDO{$ £nì"ƒ¿‹Ç}Eî&œÀ/Kv7#—´'6 –ßBÑ×±_À ô…‰k’8/”ã¼ÍØÝö¡»ãé›·Ïë$Nh–ÇîÙÈ' 4ë]hÖ•;À,ÌÀP:ŠÈ&0VC`‚€ —X®* Zy ÐÅOñGøa1pw%P<à ‹‘„;ðÇ#^¿·Û¢º’goçGî~óqä@ñ(—Ø"”ñ]=²3ä\ÙüxÂ!Ø9bB Ìãš]WZkdYÞ‡ç0ï²È3"7«šOò4ÛYûDšu{Š.êqðÄi^äã~G¤2Õ2Ïãa¸­’ ÌS.ñ:Ëßp­&àÚ<Øç·Àu±Šn/PÉX W„§"8±Wpa˜„UËë`}.žõ’XF€á*¿öi/Ãs]àá*]"+¨<ëïãÚ íY<¶ØüM{Çý•žEðžI8+C6  ú €—ðìCëx¶‰fç 0"’š`Ùfšíã »–p=È#òC1•Â-7—¬Ù\X³v.ànãºiÖ*0¡@·ÅO@„|< ì‰r°ëì\²wó ûrðí]ÂÍGœˆÅ!dm¤×¶ÏY`Û‚íç0Ñûkì5ºddžA" Œ'jÛÚÏ𪾸&ö+5ö%58—Ùöª^ÅyOM__­ÁŒm}$fû¯YY“s˜èñí„s«_ÂÕR;N´uÊž…£*Ã%u“Ý ¹NØqQÛ—¢w÷^âöyØÎG#çê×ÖäL2ßáhÝöÃOß·|ýE‰/?}tUyÏ¿6uvv.’O\bÊfÞW>üñ.Ûjn}ägé7æümßÕðEîÚÙÿb[2V>Äÿåø;åÞßmØ|ãð©È“ù…-o^|ÿØ=£cßÿÁAm4°sUß‹ûË×®nÿô½Ï…Lû·~»ÔxëÕKá̾ýãk^ΟëZÀÎ8ýáPëÅ_6œØ·³wÛý¯p.¿ñw¿¼z_öÚ³·Nýf$s€v~@?üÜñ¬Ðº¿C^{âáØc§Þ8x~ó£n)ûnŒ…¾6¯ãù+#ÙCëw=®¿túÓÏðüô©WòìÞ'N×µ<ý½ç‚½k??ø“3??{ùDR}då“ûïyóØ’]W÷<&g®ø¸}zÇvÜšÿÇ×_|àÕ_ßxð¿?ÊÇZZO­~â»ýÕè¥CÏnoœ:_·ûC_¿xáü;¯M|¶ëò[g‡Þ;Ö|hqÇÆ9ûó>{wõá÷÷o̾}ôŸ»?ú ~iö-Eæs„»c>µ3¹×Öû@–Û:ÙA{^] !;¶Íö#>äžškÛ›ìÝ@öýã³uR—·ó°öuuçܶ2MÔÜMîvzÜ‘¦ÐVCµ.TžúäçÄwB¯ÿyÕ O…#ƒ›˜˜X1¢fà¬Áògˆ¿«òšmƒ3MqÖ»qÒ(MNÊúCļÏ›}žb”±œJ,t.O¹rjªPJ+iª¾¤ÂëxNUÒãÎÒiÊ»dÍÊ䦑µñ<Õ–Ba)’’¡ …ªNìæ“#ë†×穆lΕ±±p$ºh´UÑ •§ê¢ý‹û£ÄƘ¹IeÜ9³?ÉÙ-7È´ÌY+ÿòTt`\›T¸’0ôÔ€õù…v×ߘ~ø‹2A &¹çþPK0XJ@†LüU@” rebar_otp_app.beam…WlÜv·ïëÄÎåœ~sv“æG·—¶i/—ó%—’´ q.·lmZõˆiãâ»s'>û°}íÚ¡QRVeê@eDµAc…"ím ­hV FÑ€²v¡´ˆ÷õ9ɱ éÅÏï}Þçû¾Ÿ÷½Ë7£{ö%(*ôàpjh÷k(*p–¢(…·µ¬jg,·˜Q‹E6gŠº¡­*G!’)¹ºáuÇ{qìãÚ%­jR57,5ïÅ'¡¦J³mË®-WzUUjֲ݀5#V =¯ºš.Xù’¡9¡22g™“ú¡šCš›1¬œj°~º¦h[ECw\ÇË,›34Õ¬ó;ɸácÈâÕyÍÐ\­Z3-ÍtƒE[ƒòœæ8Õšm¨æ¡@4Ê’²ÃމÀª8­ÐöÚ$ß‚`„@¼8ãÀÙ‚É€$0×ôÞ²\=ôÞÂK†£ ¶@¥D'ƒ`œD)³Þ>ÒEÄaN hn=0öã†(‚<%á"›>.Ü‚”?€‚‡‰ŒI§"t'z/¢ßËê$ߎø4×G$ ¹¬br´€üt9$¡×dª"ùz±\¿ ùnP$n¡8'ÌÉ·ng3l§ž!ø[—^ äPÞé5Þéðܪ„Ñ8æšh.J" r'Ù%®™æb€`WG!Œ‡Àxl×R"0„N ˆ[>2ñ$#3’¡xŠ}|7|ž%¯:%Àg"}±|”W•ÝI^&=@ A²ïýÉJ‚Þ$߃Díwíä t¬P„'MüV0ƀѾÏú~ X,@¾kÁêü<ù®÷ãä]ðñ"Øjß_ÖTiöãd½µþzm`’!µë}XÄÇ¿Ý÷7‚mòý(X§ÏMjcxÙç!=$*úéöý$Xo…¿ÍÇ“Þ>T±÷þŠž·Wðìü€ðñ&~ꢭÇKö¸ÃÇvú>ùÙ öëBþÓ³]ºKæ}Ò×ï9{÷é;FâÉS—g¿zjöØÅçîœs­‹Å·þºù‹7ÿtWË‹»‡jøfçû¯?óÀ±˜ïßóðß×öWÃgÏ>ÿç§_>¹zcúÇc©Ÿß;ýÖpÿø–w×/D'¾>Ø)/´>Vú̧&Ú˜~÷ß?½>û»ŸÝ·o±fñòãÑ+¯Ü~²ïqóGçŸøÎÖO†þp£é¼ú­WkG ÅW5gƒ‹üâÍËßýÆåoOi?ùã•ÅËoŒnú[çç.<{ÎlJݽ§žÿýôS'ÞÎÞñÀÚºçª6V~F~äÙ7žäJã1>ýâ+kšž9%ûp÷è9>øƒß¬;‡þ™yðó5Gþ¢?Ôqç™Ûðë[wþòÇv~åû×½Ôúµ§N¼yxÿÇN•o{¯fóüý»ž¾öé3m»~/²ê 콯ÛÏÇÿõÛ/令]VŽè^ôg¡TÌwÐ÷ÉYðý.°>`=g/îûm>néll®˜{£¹®M8N$;ÈSä^齘˜ºv¥ë¾wŽ/ ¾pl×û/_zç½éé‘1srÏ:²?36>ºg†ª=¤»’–Ív÷${§½žk¶MÍPUÉ®m]Ic\½ MUgá â7j@ ªµ*­ò^ƒŽU²sÚ OY-k3q¸™Ç½‹íŠ·ôïE\Ƨ)j(ë¸dÿPK0XJ@3óÜ*rebar_port_compiler.beam„X{xÕ•×èÊÖ•ì댟²s“3Õ-»ááÒé@z\&®Ø`¹™Ë7`òd¾Ò´­ÆŒÝƨMÜhZM1oÉI¹6X,7¤‹'òM èvCå¸Ç>ܲ«Ír­ÊµZ‹öýåZ'ü;o1xÍß<lØíFÓîrTɵŽÔmVlUÛ.6Û) *ùf+7]+–'ËvQÙvv+åê”Ç6?ÜQ´'fJþ;x;kzòõzåE$?Si5År¡šlÔ¦¥ƒ;¦íFɶjrÕ#WRéÜÁ|#Xk =€ 5×tèK{åüDÅî°Z££ÙBª¨î>ö Q­VïÈOÀßþ†Í3Õ˜ ÇÎ4 Vkrœ²ÐZID]ZäÊUð¨Ì¹†Lã?ToÔê23C”^«Wò[ p6i’q†žÍ.7ð4çv£ÕÌ!PB­hËHÐ*HnGhºšGš-{:GÇ¡‰Š£ÓYk¥¿Öì„DÌúšÈùÂìÌâ[6³ÛËÎØCìf÷ÏÜúì^ÔݣλZùIYÐí™Dpn¡"lš„Ù¤¿˜ "í ÚÑ:ШêrƒNVËÕBe¦h3:‡Øfù¨-Ïe¼h§]-7Q®HV´y¨Œ ¨X©äj R{RЩœftºÄ3p¹{iáY/Iœ!eC2SœHü_;Fbqb°Rˆß`lÀF4áDqƒ!œ t0;šH¯– #£QÑ*v_b6—€3‡«Íƒ“ ɳÀ6ž6p˜‘X‘8óôl0=â'æâ gÍž«ÎQ,OÌ/\ó´_–ø@AœÕdeâ…uãe‰”äYÚå‰ùåž{µ„l$.3' faƒù8]$ákc"€vÓì–9ß„m8¼gâ |€ÊH„Q‚gòÌ ÁfP|¾ELUŸó;ŽqcHQý½«uEï±tK‹[,fmÔ¬¬/i 1+f-Ÿe΂lþúgÍêKæ&f=Èz-M1,•°Û‰™?i™šåÏXQ°‹FŪôÛ:Âô!æÓ†˜³4lh uÕŠkDc²HˆF93Pèg²û²Ã#§k{ vC _qV™b˜™âbœ:@þrbAiäqDòâ›;,¾&IR5õk Rørâ%pÏ•¨õ—¦Ä(ë¶ TK“j:]pÚâˆê¹i±Æ^î5örD5êDUjޏ^¦ð½Ø ¸Àø2Y7éÚÑ £¦¸Ä ßå$ù H¾ ð1ÙHdÑùyV‡“k²—€­³Œj²ËbIœ/Lâ±Hã_ Ûöϵô•¨€÷Æb‚dˆk¨X_ƒb=*® _!®VøU³%áj”pgv ©ó!°Ù6×ÒµbÂû5êë,Z/Õ©Ïs’±tÂ9:HÊgBûAvþ¯K‰¼{FöǶÇÄþ>Ë×ëÁ¹~î´˜C1ÝÛ'H¿ è·VÜ€†’Sø ê¨ê¼™ÄÚÍø:¸)gyWã¨íà™Ï1BÏdÇFbš†zæyÂó¦ØOÎÞ‹j¯ð 2°M¯‡¿Š=𥯣²§\9_WG*c–/aÚH@c(ýð… ’H&q{ÉÈí§q­z ¶&a÷C”ȈŒØ"Êá’¸QáeHFƒ¯(üFgVWø€g%%¦ÜÚ:¥…âXÉÚŠU2”ÁÊ-’ST$§d¥]#ª Ÿ6ÅJ _JT~!Ë—a½œÖ5p/ƒ{=%j.÷šä^s¹×$÷šË½FÜk’ûMàÞPøM¦¨÷sˆ[ø.÷´n‚ûàÞBŠQÿ3Ä!²ùl.‰Ø}Pá3@^éäÓALugzˆ<äS ?âô5.ü0\xà ÀN‰¹:•Ýæ¨ÛmŽR·9Ú7²ÅGBMqs¨(>ªð-“å« ›t»ÙY®†ûiùQgs—3ÅQæbƒ¼iÈû¸¬—èUÙ tžè·°,«uß.=¼Š›A–¯Ù¥³løâ¬†dX²[dŸ¾Ln‚ò·õh² *w§÷Ÿ(Âêsq/9­C6eùy”Ok‰#§0Óp‘„õýÔ-ÂM—0Š´Ú@ÅÛÇ #oà|]Á³ü|æ,û³» ˜ Jd£r/ìqw{½|nOC>äs£|&åÓ”ÏMò¹Y>·ÈgJj™Æ}Æ€™·Ã̃0úŽ´¸µïNª}*eò ¿s¶ß¸÷O*Nî}‘ë*œsÜß»5õ®Õ@8áØ7Ð/î†[¶RkRÅ`~7¦Ò©÷@ÚaîM‹{ íܹŒö+ê\žÜ jJÜç¦ÊýH{Qw4á;èê:ÿžF7œûLq?ÃöNþYÐî'ÍÈŸ€fG`ʉnàN:>ê¼ ÅQb7ö‹Xø¨lÔ¶QêöØ-D“‚ï'©~ž’ï)< ;×›÷Ð|®·Ìq}”¸64 &EèÃRîÊp…‰·XJ³ ™“TÔ¤-ܦOï(üa"Ñ6Há¸owŒRÉïØö¨|~ºCÌ>eõRµÜ¤ðOZþ 1í¥«Âf…ÿ-€·ø™´x !zŒ*…HEˆô-·Ç0> Ô[úwiq¨'™P‚÷)…Ÿ¤î”ÇrPžH‰Ïáž®¢ëÒ«á½Þ÷Ä'ÈÀöõøs¦xœ?ÂÛAødJ|A&BZ<…§§èÅÉ—¼@<•ôw«†ó^Ozy<02øI…ÁŸ'n_·;Àí锸R[ ølZèµÐ-ðmÊ«ÔÓ^†_2ʼn͗Áæ.ô‚gRâ+ N°¡7Ù=ª¼ÀhÎG 4t¼Õ<ã¥ÿŠ)¾LôÏ‚þn¤Ãߧųl;ÏRï<¥‹¯*ü2Þ‹ÃÓx:jeèKÀ™œõ=8‘*Õ®hû¥†²ø«Ý:'å)JžPÝ£~ð]è Î=ðÊ? rÅ0Ý7F´½¸o(üŸ°{/Œýç”xN6ü„x.¶-&ž“Ýäk¡KÄ7þ5l&“™1lf¶eÜͯ£Õ|Cá_ïÏeù®nô–]â$;ù& É,ß=yã_ û>hö¯‚jl(Ç’#¡«’x\Aá¤FW‹¬/†È¥Ûµå[ ¹4ϧċ2cRâmPKfLñnÎò>I¡}Þšœ\y^á/šâ[¤ŸO Hߦ3‹cÎ{(¯4ÄKÔ_’oÅßÁeæ» ÿ|,Øwé²¥k>Ç ^¢žø=°;µ¾Ÿ?h§Þ¼DzÍójôS|ôø!áË)ñ#‡lgH®^â—½Ä?2ʼnø?âO‹W(Ó^¡Lû±.~¢ðÏÒŸ¸‡ôU ?„H¿–?uÒ:ê~xÍ­&§ Édû©)^%ª×Aõ0Dü,-^'¯“ˆ7tñs…¿Ñ®Î×9ÜÔ" ÿùüOvð`ò˜¼™¿d¹ +"¬i#¡„4ïM¯y¿4Å/Hö¯@ö(4~+%~ýÿÄ·¼ô¿6ůˆþmÐbÿ#-Þ&Ýß&Ý£‹wþê@y‡Ü„ÿßõS@}7%~ç©`wxCð®WÆïLñ["|„ŸFügZ¼‡êøze¸ŸaôÂ¥ÅKô1‰¾ññ¤Óg·zßV·Â¸­j#QÍéÛ0¶;_N`XÂïS2¾/“ñ÷HÆ?(ü÷ôu@~ïäiÇ-ŸóÍ“>­ÒÑúƒü°*ZôƓՎnÈoƒ1êlqz›t>‚Íû ï0èh<þ>åôÁ´ÏÀ'ÿíÜþˆåcXþ)-þHÞü#yóϺø‹ÂÿŒ› 9šïèeJ=þ"¡¾3 Ý͘o¬ÕØG˜/š®ãßÿ'Lwbt`tb0Â]~ уÁ0¸ß§ Þ‹¡a(}‹]øŒ¥îœàË=´+\8ñ_íÇ]8ép®Ës†îÎû1.ðÌžy[Í7xà† ÀØèáoºs’»É#+íÎI·­=·{ðwxp.táCôùÞ…Ó|ص‹æ#.<‹±Û£ÃE.Á÷¸s‚_êâìŸÌãŸË=ü÷xàc=÷yôi˺ãϹñ½#çs~D›wù/ø_ÿÿ]V 8”iþfœY+á§ÈaвŽ#Y¤ƒ ý k3f03Ì0fGë°DŒCI»mH •Æ©)Ú«ƒ-Z«6»åÓ¿ÓÁé/$ÿûêíú]¾ëº=÷wÏý>ïó½—ëy è8ûôà࢑G€‡<ó‡kã×HP <‡¾Gy`δUz¼£µPÏ^±¯,ÒO8!òS+¸ â?Bî’íân”#u…7Õ[  ŽtyUT‹,ŠËpå³AœàÊÈ/Á>?ã6lð· Õ8òyôÎ`XË äŽ~ÇäˆVƒPŒô^ée§´ „£Hÿ ÕÉ9Öó+@ëo¢ú0YX‹ù¯A+Ôñ𕯠ä¡:šÐ·á0ͱ æ"ÿ…å< G˜ Aù/¢óÇË–9ì1ùP‚~©£á1 ¤#½à‹e½¨ƒŠÞ¡þ1™u¹$œ¡´ H]P~ÜÏ›Óo³Æ¯ÜúáãVFŸè©UÈ€,ÿ’öÝúaÂ]+Qf͹²oŸ(ë´ÌfàÒJÆý› UåIþÏN,Yìß`ÜÓH‹Ú{ðåt§¸@ïÞÆ7ê.sÁÞÅ£ûë§ST$r!œŽðüø4ÿݦYíÒ§°¸™´½<³?ÆE¤Eþ…˜¤‡—“S£Œ CbÅVÞí$×úš}çû´RùѦ>)î±;cÒSÍdNÚÅa&é­ ï•SÅf]{xýw)ã릮'HTóRê ²·©~Ä%ÍQ½_—<ÿ.im¹{¨^AëÂù†ŒïpÓ“VJ—:uJ3×F ³…Y;]\¤®Þ,^¼1ÑòË›¼8íÛ¶Äè˜šÓØÍ¿<”^_Gnýˆ‰+}låkŠŸz(ˆìJ³F»6ßö„2èß0' ®aÙôþöÀv_Ú›çñ2Š*´º+¼Mþ®½]±±ÁQïƒ@6ÚÂ^Y·È-`ZPÐ¥R}1½I¡oþÀ§³÷H¶Kþß’õœGƒ¯ 8cæZïî$\l×Êû±(Gí5ÞK¼KZpx¸>lá·ÇØØ£/åÙJhz¿–\¤&(‹—¯ÞÙt\ˆköT!sǾˆeÎÙØÅU¤1¶‹HçXöÝÆ×Vá۶;½a¸e¦§{2R=_ÞcN?»ªô£·ÌUñîoy*ž9n=$#¤‡ÔH³¿©LaÆiW¨Tê|ßm!ô£tF‘vÙéÒŠý%9­Nj#nÚ¤Ú½Nš‡©ª¦ë­SÆ3nÓ~×?ýq“9Mç¾ÝÞ®x"ß6'î}P¦ÝLélà«Û-Wq?C$v;ò}É·lê†n¼™Â÷\ëTßMô ýt¢7ÊLá~‚¹üÕ•Ã ç(La·d¼»ëÉþdYÇÙ Qɼc~I[x@îÛà>«w^"‡l‘ílå­ Ã&m“Ú¿=Ü_¹zü:•˜»µ¹§ç{©q­_i£uój“yFõ÷ÜPÕ6±€_ªÈ4)LÀgS=ÍŽôQ F›;WTņ¦Û‚üã ¼+gó{}¿©ª=%ºpY5k³ÊȱÜÍ×—Áª—>ø{‡n!¸y^žÞ s”–ã6Ú‘Y³ô6ìEWΔRø¦‰3ªE¢ßôRíå¼vN¼7½‘?ý²¹wÒËôúÃ¥5¥±)òö¢Z{»íE:ÏÌâuSñCq½ýéI7Y¯¦Îl:Þp«³ÑùÊFæÚ ›óiõê×þíg:ú`¿·ÆÙq¿óÍ[hEžÎýEwª#žÍ( :œ~¨ñ´ r4¤mó59-{ó<úî×ii j–ô%ëF•åT–tÏüwž¹®$¹þŸ'$&#s‡üný<X×wÆŽä+èY 3çuC Fõ »q^…»^ ŸïŒi Ä0'ôüh';Võà•ýfe.EúЪ\‚úb?Àq¤?]Õ!OϪ~\„ø}€BÄ;Wõæ|¤·¯êÍ+ûñʼ²ïæ O@òÔd"ï?³ª7¯ìÇ)('üŽDÄa½ È“‡4)´gÒáž°·chŸ(¤Ã;:qx¿³‡¹™ˆÃÙ€8œ"‡ëÂÐwA-å‡Z0âp†BÑÚÈ}ü°Owåôë÷ !Ýqè‡s‚+Ê ÿgߎ}š  ‡ˆÞ¡n`‹¸ € òl0Ç>ÝÅð>ÿ ytŒ‘GÀé‘® ‡t8[l@:œ´ÿ­¢#Ç…{f,Ÿvž†IÅŲ—_Øk°ƒ…i_á:=ú_Ø¿+æ1™NîlpŽ8ùe¿4ôËq¢y ; ²4L™Îår¸äX~T…› ²>Æà²0i:•Á† ŽÁÂäìÐH>NÃøl=ŒÁ¦Ó"¤Ào4¦¸Ç×äLöq÷taa*V–D+K+¢%™H´$‰ŸMò~NÈî^®ûX˜R8ƒ§O§R­¶Zoc.×GçÆ‚¢X˜Œµ¹¹5Ô¤yŒ(z„,˜äþ¢à)Š% Žòår±>7”Έœ(º(œÎ²ˆå†ZpéT ÷ÿŒÍáòÈ¡œ¨hF$kNçF2©±Ë3êÿPK0XJ@ƒe–›ð rebar_protobuffs_compiler.beammV}lgÏï9¾Ø¾äµÏùNÚkìõ˱}μ‘Â.Î\“®kK›v°i¸gûu|‰}çÝÓnC(ZW˜ˆºMc©üµ1þéTUEQ„Ī}hYµiˆNã£ðJ'Ô?&ž×¾°ôøžû=¿çû=ûö<œF¨ûz67óÐŒcÖâ>D¥†,ZÔ¬BÃ2³Ø¬TìBɬ7ôµ|®h3šŽ^³ýÝ(*€Ús‰w¬&õV´šM½Ô²L«»M­™ ¤‹Z5ÍXð:UË<á-Õ¨fxâñ¾ŽTº ‰©M 'ü¿ð%³L½'ªz©Š§SÓAÃ4 ô¤n;º±Ð]¤Z½U‡À¾ ­N…¢f·•ªUk™‚•Ç wxü¢©@6¬¢AiùN2ƒjzQ¬i¶S¨›e½¢Ó2÷¹ k/P­TõèfWÅ´êšÓm—4£ÆO »iÑBY·H»{†¶§å©/Ê´F¶;Ï,]m ‹&´€LM ëFÅì] ­Ì÷R¢5²Ôd¢VŠ}%J'҉͘˜’èK¸5nBgaxáÛ°c‚ÚŸgAà  ^ŽxÂã2'÷¤æ‘¤æ öÉ(sVã0‘8EÅ<.*Óµ˜³ŽrªÊãg ≘òqq‡Ô¼,©ž(€êÓØ§5¯`Ȉ;¾s Oø™[Ùœ…%ℊ%¦JìfWû&Äûd%óâFg ÅVÂó„ÿ¸óA„T? jÀ{û#8Œ$nÍö÷î­ ‚Ī䓫ùC’ +ˆ»¦AÂÝè4o›èÜ?D8!´Ù²•ä°GÊå´Ñn¸#À•6êä®lp#À•9¡/HdhS• Ü•Î>Òð‘3wZ=à=ÇãV»B?xËi`JÁ3XŠîû¥û@” ªd%„³™ÍJ2¯ÎJªQqLfxYìSÄ1Ø‘8K-q˜a¹˜F~F~^A浸8„«ùsR(¦æ€¿å#×ââ(’Á¡ˆO¾Ñxp]ÙLYÙXQ›2Íò µ›Ã¹ŽªùóRˆE ú“à#0a5ƒÙiQ9a$#ö³õB·£_Àœ0‡DØ}·N‰ã8(“Œ¡9Ž@öˆ2¾OŒb9‹‘”Å$£ÒÓⶨ7Q•\Ró,õ¤n§·q‚ <|˜¶AWìAãq‹›:Ê²Æ kvv—ƈâ„í :v°ý( aNØ `À]Sân$¬8vb¥MÇ—È$·±ÅÝq'KÇ$8NL‰‰ÇP§ãD§c"#Æ™cSà˜šTHˆo$Æ“uv¨b˜'·X”D‰°G‘'{)ËóùHN‚p „Q2bK¡#Ž5Ïü¹zƒ]¯ƒH `A<ˆ¤ÄïbxÖçê=.'îÀ%ïèЇ]ÎÎô1-¾[]þ6qWg¿OÑßag¾1¿ d»‹ïÙÕsâ¿tOîd«ßŒÛgܵïpuäÆÝx‚{mÉ~Ýa¾¿—èɳӫ—öñ3䙑K¿[—`]§ú½3Ÿ¿;¯|Âõ”^¾:vö{CO.œz0ù£×ÿØsåö_ýkrüòöúGßxõöîøÖžÏg¿œÝ³õâå}óï¸0XùËŸ»t÷×Wgß8;¿·û;]»÷‘Þýý§?ûÅ;W¾ÿ…ÌÀú+ßîìãŸ~ézßj
¾tnýáÉ‹ÏUPaå¥ÓOÝZëklÿÕéûsú½ƒÇV®®]yjôù›É¯ÞüÚÄÁ«äOËÃ_»Ö}ãFaäÖ¾cSËÂͼ9ò·#ïÿdöŸŸ|¼óñÕÚåû¹úiªÿ‹‡ŽBƒûÍÒ¼ûŸÀæ–rgÄ®IWg³L¸ú.w~œ»CÙÕÙžGÝÙõŒ¸8;#C®ÎÎÏ «÷º<ί»ÀŒãXl·§jÌZõ”^¶ÖAÐ ßÝ‚.\þõ‰'˜K¼öüŸgçŒ ØzZ|žñ}fÃÑMÃf@W‰­7’‚ݬ×5ë Fè2›üM/!žuƒ!œ¾„|ºQª5Ë´Œº›F™Â -W1ØÊeäÏÛÿ@a~î¡ÜêTÒ“ÊdZ)¤ÓJ:Þ Çfæì=¸„ º#ÓbqòîÌ=‹­š–©eCQKÈ›IÞ›Ì0Œwô:­vò}¨y4¿Ð8­§U m6­]BŸIUÍ:MAát)e[¥TëÍâ?Úÿ{]KÂÛÖ"B3EÛaý7PK0XJ@&0é ü rebar_rel_utils.beameWl׿ó;LJ“ />“@ÊÁH0IαóÃ’‹c”føƒn5ûœ\|æ|æÇÆ&V´*ÝJPY§ ©,õŸMJéè˜J·.k褭U”­k·±ª“VÔMV2±­Òö}çâv–¾~ß÷}ß÷ù~¾ß÷ÞÝ»¾ÇöF¸Kô>Úk›ã ãºÈ0LÏJKÒ¬”¥©¢5 ÞlÁéd²VeiÈ1{Ft;•>‘ᇳ†žÓÆunÔÌæ<¤gd‡J“FІfq¶UÔÝÚQÐW“9€e›¦AZ]+è©lnØD…S†yËÌÙ‚]¨0Ls¬˜çž'mæ EÃv™cnmÈ´l?Åù†‡vª–µ|¾P³Ô!8©¼f­Ð-C˸þDÖȤ5+ã²t˜œ7´´^=”ÍiÖ©”m¦5dzÞÒgÍbáA4ƒ¿h­*Õ¨gG¼dÞˆaiF¥ajjö@ I©2 )§ìbÞÐÝNž1ýÔp6—©&c¶f‘ÜWsìzÆ»lôhC‚³ªÌ7¯YzÎu „6dt\· ºË6J1Mg”_R* ¶•͸õcEÍàNhVnE)ÃA \ÚÌè¸6 ÓUñ@ªã¥Z?™×r™ 5s^ Nëç£#¤ätÔs<]H/ä*ÇÍLÑ(­ÕJ¨¬_ßüyÄÖ¶f#Ýð„ÒlVšaSÆ ÃT\3¥ßH?ˆŸÅ.߆•ªÆÃ0nœ`X,˜UWb 'P’AŒUÄy°¤Ñ6T¬S/œÒÙ¬0}J^Hr>,²GÈ_~7bϸ|×0;Ùuõ"QŽ\£WE)&2rLÄ¡ÀUy¦ŠQÕ¨Î#¤DfQt©1Ĉ1„å’BYq+*–“!#²—;¿…ª(5rE¯#iiFàºèõ©2r㋘Æ“à\¢šÄˆ—0ûÆ.Äι|^?f?\FXDÑÅ2„E@èZ”{åP<²Š.†ÔXˆŒ…p:°8è]YLGÓR,Íbi|6¼ÇÊ$aWHž%9/|1(ID‰åkª‰“„ÕnüÃò>°Ö¨¸LDð£(È2ÁO¸þÁ‚á%:J†OXðÇU—FnIˆ ÿÿ¬"¡€@í‚ êÀ\æÕU’¤Šœš”Dù=Ò|Ú…IÁŸŠÄ'¢ ˆ=8ß%¬qV2,¬‘Y¢ê‡µ;~ªKV94~Ê™’’=xRE²Î!Uæ¾JðTc ¸Ö…è<´†­§N‰ªw ^õhŠä—¨&§}è A0ÞÇòmP;%(ÜT@ Ïð"p—;>í¤XÁ}’˜ä’h7Ø:Iuº ËN8,‘.aìk9¢rDÂ’šEQ ¡ 8€,Åj¥›÷×Ȉ4ëe¹OŠ'á镈—ym ]üíèô.mULÎ'ýt°^î€Õ«>´óu,¿“X f‚¬%~5Ë÷±â&»„]òƒ'‚rÖ*I’#ÏÈrq7 ‡J«µ+,ô! ÚÖò‚êÏCË* ®A }w¹A*@XÆyg1<Õ«AV‚¸è{®†ÚÉ\‘ÚWS<ûõy¤žúŸµÔ.¬§þ$®LíA6QbßBíDßZæÓLu‚ÙBu¸72m3 ÒNq:@š#ñï¢>'Jó'~ÛËré.Ã'º+q’Ôy“Ö`OPüâ ­ÔNÚÕ ïÍeܨNòß@õG¨0´fue\j©^K…¥u÷S{ Õ—Öª’ê+è8KstQ|×Þ¬Mö¬)ûí“—¾2ùúžxÐ?;8½Ï1+ó•Ý_®ßyw.aãúÛ?~nÁJÝüÙ͆þz0qú;ÿ½ñÞ«‡íw¾ñ™µo깯V÷¼~élßßCÿöýགྷUí?}éÝ~ÉóüSÛ7Ö\øË3swºe4¼²¶ù™»ß¿û‹óOOœ¿7—ùÍþOúwœ~ßxûÊ÷6ÝÚ8ÛÒÚñøoÿô‡?¯¨¸uçÙ“ã‚/<9·ñ­[S÷;vãÚŽ‹{žýÉùÓáÚ…víà•—÷U·¿uhè õÅ[O^ª´^MŒzk?øôñîo~íG‹Ÿ¡ÝÏow¹ïÿ~ÿåé×f§ùOßùäŸç&>¾±søšÿvîºumúÍ…ØG5[ßmo{jÿþøû‰×^:óó=_¿ïúõß¾ÚÀì5ÓèÞ!õê¡5K‚l£º ¡:Y÷NªGzmÛ‚¶ñ¬A*~Ô•aÜ.N3÷^<ÿñÓßýÝÛ‡¬ÉTÛì¹wFGãý¹aãŽø{̼ —Ì1TdA·,ÓJŠããpõ'fцòÃéð=@,lvŒñdsi£˜Ñ3Ìò¥ü(‚±L†ñÆöïÝ™:ÐÿhbŒYÙ¦Û”¶ ’ •`0¸äÄŠ¦ú÷õ=6ÆTŽdmIj …ÛGNôæ;ƸÃ--abãìì¸~´búmÍ¥yµJÕª‚³h¥õ1¦¹õ¨9®·q}¬µ`¥[+ü²¶ü×ß=£½C›lÌÿPK0XJ@%TЃ^Hrebar_reltool.beamX tוžÑYcÙc<2¶± ƒ¥AþYâG6?Ï–eaclƒmBø‰¬Ÿ±-¬¿Œ$Œ œãÚ4q¶¤!°]6I7a›¤íö@ M›ôçJÒsZqCÒÓÓ’„&íf7ÝîRöt“4›fï=‘ží.ç\ôæ¾ûîýîwï»#«³o»“a*q»¯mk[&gî Ã0IASCA- ©±L2ãGÕ„ª3jé‚:ÍDcé¢X2 „“‰‘è¨0ªféÉt “MÅT=ZœÎ5ЫÚ~U3$Ǫ¦%µ‚‘`4¦F T-LŒ3cZr¢0ç;–E ¦ä~²9i ÇÔ`¢„øGä#ÕÄœéøÈá0jñ€6RQcjF ¨ÁðXaxL ö§\8QM±hˆœ,ÊÌ †’Z†'^Á¸Ê‡‚i}QšÒ’a5P•$*M‡|ª`ˆ&F’&ØOG“‰"È:£ÆuÁá0ßJX xUˤu0‘h8S8¢%ãX41e’ú'圤b@³fÑÔt2¶_ ìjÑ`(¦¦Ä,mW'G¢‰ˆ‰øODŒ#ÁXZåHàbŠ–IB )ýD!±ÜŒeÕÂl"¢Âa5Rœ‹–+›™ŒÆ’¡`ÌWx‰^SâE'%Ô Ž,L`ŸÎÆ2ðJ½ ‚©TAþ¸4ðiM@=@b—Ì“–«¾v¹Œ–UMÀc\MdŠ´lbžÜÒ¼*§Sj¸X'>™ÌÕ\…¸ù»B|<¯%øxp\%‹UnIjaµ0’§të‚(a:dLiÑD¦„PîCÑDP›4OhQH‡$YªPÃYx lBó¤&ñqpÌíKFš ,j&b îÌ*P¢éqM ¤{Œ5”åçKi™_&¢±H8¨E š ÏÐî@3ñÃÏïæX$Ví8šã&‚Z¢ š&¾¹p*@z …Õ‚\± šZž…è©®Fɹ¡Ð¥@ql2w9Hc”,ÒKo%›{ÎÁ l÷õøÚ|¥ó>LDbªVOF²ó¶„ì¼çª†ÏÐÕänÉ&”†¥ Ñ%MÍ ±°ý¥É û‹òÛ¶rÇ/ÜU†)n…$2¹³ à VV4”Õɬ\‚e,Ù1rsÌËØŽ,v“È`ÿ‹¢,bdõY È$ʵ¨HnGŒÔŽD›C•¦±UÂ6&œ,ÔnäVc·„í6lE«ÅnqsаœU6qjÊ;9$w Ù¾Šý âE³Ø1„¦Ë°ÄöC@2ذ_”ðqdRð‚ÍðfĦ e7evª˜¼€ˆ1Š‚È°Ç efQfO-¨Mb¿IÆ~N¦ö,ì—3ìùb†Á!ØŸr¼ü 6HØ/cØ9“xjÅo‘Ÿ†‡áÜÆu<ʉ½.jD–KQg¦rªLâY ¡ÈNä°y èÎc.RÈ$ω7ÄNYò›—ù­>É uÊ6¿¹ÎÏùlRnmó#X# g¯c»4–c70'Ræ!œ [tVo"ì²›Þâ,²,P¡Lº¹V(³agbø2Œlà []˜CF,¬SXÞ6È\ýS~Í ˆW0èËtŽ‘táI’y+$Û(³|y‰"C²ØÜ™ð' $k³S¢*kNÅ2تDv‹–“ü9Ð@ ¾Ü.«¾ ‡P‰ÌÎ^†_Äò•Å¢¨çÊWx„jH¨úVBŠP-µJBu>.TM ‹Y¾JÄŠÏf@>Žp{Šà‡‹¡ûxñ:¬ª»y ÄñòZP#µ€Èíck—D—C¨±™[ŠE  .  åÈ\ ±e„s± S–Ì­:ÿà*² Vº…%ˆ4ƒ(±ü’…69Kq,…C„]j /œ§ËÙ@V§v¤7ªd#4Vy@°åÒw6¸Wf¬÷0ës+»GX†ŠŒüb B²PÇòw€Ïv`wy V°Í («=B=xªÏ'²žYOˆ\1-¬dù¢Lˆlsfù•ذ65”´žÁY ¡ÊŽ@á2ô CŸZH¿wÞÇqŽ/x¾iÛ ¬bù;aM³ü*Ý'\œsÜ:£bVaNls€zšô+Üi ÌA:±žµÒìMãB¿,ñ ¸iÎß #Eh¶™7cÿ èÏ.½?BòÃ♚%³_âœ0n©M¢Ìø82ox‹»·Í†å𠦤¦N¨™r näÎÊì¦Wë ØH—U}ú©‹†ÅüR-ë“/#ÆË cõ|ã¬!AÖ‚ÿ>¨ËºuB7jCÞÐå]ïº*¦dÁ£ë±ÐÙ/øYÞÓîeÂí^1­]áÖ0`s¿ÐbÞ&´²|‹8<Õ©xýæ~ÚoðyPL–oúñ´¶«z†Œý«/íç%¯Ïå%e¯ƒ‹ èl9ªí¡G/ˬˆáñŽ…ùÌÃä7ߥ³E¾„ÝóïŸÖî•gÀM™w Ìw ›Ì»„6êeù Å©cÐSV,uà´þ*q‘÷Ä3@±wP0Vˆ¾Â`Z@òêÞ—%ã:øöyè;$A–HN/‘nö=ÂFðµ%ß×háü)ד’bù°GXô7Œ„^Ýñ­æY$ÍÊýó|äf!ç‚–'|ô³ü¦âaHÏ §íØåƶ, ŽêýÓAक„F˜Üy(ü‡Œ"¿ I‡Œ2¿ÊJ(p06HP»´* Y‹˜!oiŸ‘JÉbŸGÓaÃzu¬:ša–oË¡‘Ü„ry{ÃíÇxfPgÐý— J–ÁÞÚÿOÞªo©]çíM‹áŽýš¼Ø|/ÌXÚá¶ÒêýF*n½½â"@v(´ [à6Ô f,øX¾CŸ4–÷LÀ”tVÆp¼þ³p€ÔÎü.n÷*'ÐÉæ8uª³îUîÕŒÿDþÝòöD»?™;U|ìl^£ÖíäþA£?Á'2xæÈÿ»Ý¡_2ˆ¼éÁRÄ¢ÏÏWG¼>sØëÂGÚó ¤Ý­´l›ÿJÙ¬zÙjHÙŽ±üæ\Ù†_öŽ ²OÊW+Y2–#³rê)!Ü”.q¸_ÿ£ú½2ò÷K0ÖºÝÂZòö„å2A{È˜Û cn^‰½Å"¼I³5z„>Ù—²¶ItˆÊ|hèÐì#NúÁIÞÛŠœÈ%Ð:VòЩÃ^JŽë|͉Ãd|éùú8øÚeÕ\?/Ó[¸œd7¾véï;ø" L*a;@ȇ6÷Æã—ÑoPÛA8@R€ãð&Âe¨Wä,¿ƒhàõq)(e¾™åw‚2Çï&yØ8I‚7ò©Ü¼še‚ Ðw*ÀíN?_%+*“!Ì.8šw¯ö¢bEnCä0¸°Ã ªs{È}tÍÊ"ù:Cf8‡r/œ=¹#¨!ú^·°‹ép™„çÜB 1müáÐOÁ§a –.°tm¤ë]ÓµRBm‰X¨¾ DÊ[[ézH]W‚T@ƒTçÅ­Í‹µ4o-S{;ÈTOÖËézÈJjs'È*êÄrп•š@jÓLóž÷é¦öd½†Ú¯YGýŸëéz#È&z–`k£k•7/—Ž<}TG|ú©~ HåøÙJõĦ7Ÿíy9P=©áÕ›yëíÔ†øÙMõÄ~O?{)÷ž<›á¼Ú©}$DqŸ£y8ǨÍ>h^.±¼Ú‘µÁw€ôƒ™\oÓý»èš¡ùˆÔŸ¤”®yú©Kg61HëEž“4õÁ˜”Ož€8ÕßMã°×ÙÊžh†ô<àäŽøJv`oŸÕi­´–ÏtÊ›g_;úhýÅû—n;ZúÒéÂþļóEçS­¿oüroëwj#í¿8ùÉ»ïÙ#ö¬yìW_õløá½Çí·?R[»ç×?yêìÏw>¾ç?\ÿÄùÿ|á_”G~uõçÅG*¾R7|â¾—¬ïùÍŸJ÷ÿäÛå?­~r»é¯îô8Ö¾>8·çÔk_¸þó^aÅ]‹¾ðÌã§?êvÔ|„Ú\ôÌWû›Ã÷,ÞúV߱ׯ¸ŒáKâ÷LÿØ*ìW9!¿ð`äƒß¿|¢ìòd‹ÿàý»Ÿ~2ùDá§OŸøöV<>!…LO8Ö~÷ìÍ—çð”íxæ›Þ·¯º?¹·ûðÀ¾’ñ3cV½yrƽò¦ý½ñ¾¹·vTTýíɳ÷6oí£•sŸ?nÃ+Ÿë>²dåÅu«µý—[Þß}âb¢õáµç_¼¶Ê\ñ›¾So/»6Ù]rµèðë?^{ßÁ¡ƒ‡/þýÇßÙê¾yéùðÅoÝ{­¹ðòÓÏ\úüÜš›VÆ.Ž\½üáñ‡î=s%¸þúõï&Ü~ÃSøß/íª>mÛé»s^xÑý¥FÞ:õ§ÿþÙé?üÍKÎ_¾÷w3?}óg›.=p­çûÏøÁåÿ\uúw‡ÏlœªÝQóèƒïÝ¿¹éK>\±êÀ’Eg.=$ðØúäñ¦c{â>~ñéwªÎ­w~¹þŠ<º±Uþšã}ïÿëO5ß^qòꜯŒWü±v ÓtôŒú³«Â®o¼ ~ýŸßY;ù¦9°ëÁS+VŸ+7ñü•‡žãNþùèk†ožÛû›iqÑ+gJÞmzýkÛ{ö›k® ¬ lyBºã ÿDÝ¡Cþ­÷ƒ‰ñï~¿z·˜üÕ?7ü¹àÉ0é×çi?ç÷k‚öðîÏôk”®·ŒP2úèý"3©›ö5¹tÝÒNÏ’¹¸ž­ñÐ5™¯«©}=Côå 5T/Ògò¯¸-“ÑàsåŒ~£Ç íO'ô‡„È<»O}õ{Žf>UYôÀ‘¯ïÛçíJŒë¦ÛsÄÞ”L‘_ÞÒDQaý7î@:µIbPÌf"QmœáÔP4A4ltœ1EáX6¢F˜[¿ÍŽ!Ø‹DsûPWOG`°k«oœ)mVœÍJ³S 8ŠÓéœ7âwx]½}ãLÑh4#«¡P³Ë½zŸŽ‰þ8=ÎÝkÝDÇe¢qu¬&éZÐ4‹‚l°D˜Nfµ°:Î8šÆ’qµ €«ãMi-ܤÿV|k5ÿ[m£ªÅ`"¶…ÒBâÿPK0XJ@±œd‰Ürebar_require_vsn.beamUT_hEŸÙÙÛ½ìÖdï ÂÖ“Vs{,¨æ’\¯iÒkLbi}¹ÛÛ»Û»ÛÝëþ øP}ð)„Š…Š%RK‘ õÅ'ûpôÅ)>J‘h|ßQgöö4øñ}ó}¿™ß7³³ßéóøï«•s•Àµ?QÌ¥<ÒÒ½†G.‡–GÛ¾#®=´$ABÇ ¦.1úmâù–ëøÊ„H¼Àgìcãõ†ë´­ê@Œ©ñºÓ‘ý? vÃrÚ.çä…NÂÖ£+:nd&i…©ñ6·ƒ(äñ, ¬ŸÐ[®ÌLtÝ`Èdef=2 ºOdÛ5É$fh#s°äšX¦gUÀxÔ)R ¨pégT¨ —.ª3wK/*°9­*¸rx#ƒQVÔF<~‰ *9ÌgDMÕFè4šÃÂÃwápœU°Rå¹R•r¸¦fR<þ‰š¶ð¼z”«¢KÖ4$ªîb)›‰ä²(ŧÆzY,=ùŸ`ö1Áýïà'qšm˜(â ÕKjš KGz¸¶Ž’*Vá7güŽKK³þˆÓ¨®¬ÃßÙTI£ ©M´x[ìÂVì!³)D !¶ˆbŠB¢€2ű8®ÄwÌü4E†‚‹ùs1âsÕ+Ñþìñ³q^‰}6¦ã½¸˜ÃM°flíuŠ¿®|l4›Mþ2N,¼ ®Þ~Iq½Þk]~þö üH8óåò%ê‰Õ»´°5רŠÏãú™*AàQûÜ;ér&@ôiGGµûß>}qôÏY¿pc¸|f{½¥§MsBÄç_t‡û-Y@0ÁÄó\¯á‡¶­{;Œ ¸a`Z^ð¤e9,­>-Ç„&1ÁT蘤m9Äì"š3M -¾¶²¶ÜØZ9W탙¢V(jÅ‚Ö(´B¡0!%/,m6Vê§Ï÷ܱ•´ZÅRùÅ^TSÜú Qž?5_f1>°lÒZôáü sº¤Ë:Ô§£}7ô Òù|×µIžNúyß3òQøß;Ú¢æioéPiù{ÿPK0XJ@–h´{×´rebar_subdirs.beam]U]lÓV¾Îuc7©ÛÛ8%ma`–²MêÒ:maÔÉMICX)] {ë‚“Ü$n;³Ò¤!öÒI›Æ Ûx@hâ‰Ö &m/¬Ò$Ä~ؘ´I¤MšÚš4iÛ¹®³""}ɹßùιçß\Ï[L#¾šÉNöìB\!¤H-êNÁmˆãFšm:v‰ºntÓÑò ÓªÔ+”N•E˜®kÓY²­ŠQíd^Ó.éf¤M;4j¸·n4™œ÷œí¨è¦KùSºcunÊL»Š¦áz®P ½T ÙõH©FKupÛM±b˜ÔÒ”_± «Ç¡®m®Ò‚{¦aVg^H¦— lmØå–I †U±ÃÔ1u«ÚÃJ{ŠŽ§¶r¦S•–•RSÝÿgð5,«o Á>Ôql§?µ5œÑ±”YzS…j ÍØeŠPè5˜'A›Ÿ5Àv€À‘Pìy…Sº¢á¸€†ÇµEY %µ8ÖÆã‚ <¶@µ…âVB»¼wý§Ndy-‡pL‘9((‡‘פm`AU}'’¹æÉ—E¦8Ò«ÅeÇ äi€¨dV‘s‘ÞÖd?àäaÌ5çø#2w6‹Äw¾‹-§ÈP ,@Â*Š™»Þ>Â]ëBD ''oá·°’ÁHÎ`’¾%ÆI?ñMHü=ˆûw_‹áyÒäþdK‰ФÌ(å,'ö·]åÄX4!óZ2®á!œŸ”d|°•[’!9ÐI “÷3I4žI*3@Gžƒï™ÈNmz¿4sÙoqJŠs¢LT4«àÜznˆã“R2'¶2«RB>(K ˜µÔ·.mãľa)‘Œ eùÎa˜µ*k‘]XTU¨usç4¢©¾?Éü OùZ¤ÇT™û¡;EáÄýÒ îR”i ýÉXK¶Ç ¡¼Ì~2¾Fˆÿˆ’å1f³'¤~,c´ä9ÇÙAÊ7šì÷m@€|pÆÂì|œèp Ðð=Á™ d@<°·~0øŒÝÖì`|ö´_ÃKAÎþ@Kû…Ú˜mYÇÛ±Áÿ€ÅÅm¨c9:5gxLspïôÅ ¤»7TÂxXÙýúÂÒ¥¥÷Ï;'(_¿¸;ø[ÓIü|åðÃvý~húØ_ Þ Ý £·?__ÈŸ6&G¸îW¾‹½7uåÔß×âò“ØgŸnytá^ö§}?xSg~}üår>º´ºm®¶¼º¼údñ¯ê[¾O3Åë»÷˜ê‡Ú5úã•^½z÷ÆØà·ƒóÿ®DßA#]š³K¬Æ‰`æJÐßÀ3=õ}Fƒ5³;§=Ïa3{×dL-TFxÕµü…EÐ'î~ôôèe£ø`Ïí+¬¬Ìä­ øB¾žgzÁnz†m¹Œ—‘ä_BpQ7ºs† Âv˃۵ŽxZ4,ÆpF †U2[eZF-«L+†EË5 ¾rE2'òs‡ ÇóG³uÔ3¦¦ÇÔ±´ZH§Õt:݉oÌ,òó³Çê(Z5<…‹cã{WüšV©ãBQuÔ11²od‚q¼g4h-\„Ãø‹Ò#zTçôn¿@×n9%ZGã5»AG¡pZuÒ¨ÿزگŸ¸µWš.º;(ÿPK0XJ@)¨2rebar_templater.beamY pÇ•žÙi‡Ñ¶˜Õ,‰!„¥E#iIÜZiµüHüXíÏHZiÿ<» È?1e°Ï?‡Í¹bBŒ±sgsÑùBÎ9Lޝ‚qp*²9çb'¹Ø¦ÎgÇ©º;ßëÙ–´8JÕU¶êí¼é~ýÞ÷^¿÷ºWêÚ°©ãʾðúÚ×µg’qŽ–q78Ý4BA31â©X0c˜RØ4àé¦Râø #'N&¢ƒRÚÈcÉP0VÄdɈQ‹¦3îñéBÃŒƒ¶ÚZ[4Y84ãÁŒ-9R˜[Q1BÙÁi9µ±ä š¶'hFƒ¡˜‘. ªÒöct šˆ‘h8ƒÆÞÃ4“fQnQ6¥ ‚¡¤™™–MD 4"ÁXÚöÍGµiip³0vp%e¦ ˜Éx€š+ˆæ ! ™ðP,§í™dn°‡ §i¤“±=–¶HËß…¢‰ 9ZÎ$M£Ð4‹i3 »i€ù°!ƳéL0ÏýU(õKݱpÕn½¾Á­» £42¡J÷{Y¯ç V¹§N„›„™M@兇溧È?È&@Nvçê²¾‘ Ìqß\Î01©•ë€èp\1´NærŸ€îšÍ˶’ù*¯:T• QâçÒˆì*G…¸PzŸÊë¶’Ê“D\–ÛtCœ.»~œ¿{ ›#Á ¸èɹ ˜ìòy™È>d¹¸S,Ü0 S m…´ý‘äþqÉ*…x xN÷Lw·|¸ð!ÅÙÉÄýÇ!U4ÄÕDª4‚:ˆG!¶^€[Ð×÷ð¢¼ñ¢s|•ØJ¤*/*ÍxjGZS vi­@ªWã:¼šÜ» »zz?饮“iª²ËoBÊR(VL4ðåU¶ë×s!*d^IT,/ÎðàX »$–‚½°7Ó!«V ŒøóMÄÿ¦b'7ˆÿ:{½a½ ЍŠ2èšËê8^,ƒÂ´ ÀÚj·å¥íÔ]-¸6ºâÒ¨ð¢m|Þ‹Ô&KfU öjmöR%+t¼’W@(Q-ö"ɉ²8V®¤ƒ_E‡ Øx/í¥øÖ RåVYWY<•Ü$tû!î²8··Ãž¶çïi»rAV¡ÿº4šp9ÁB;Ý_ï;hÏê—»ÁeŸƒèN:mF s¤UîrùÅ™µx œ¼Ømf*jñZt¡ûss~Aê¡§ˆÇƺ¼8‹ž£+ð*^ôß!ÐÈAÚ†+‡¼´T(¹ =xI†ÎTE…Z¿=M¤S#U¤ º—D,¿ñâÖaÆ+hZHTŠ&¶QÁøaaJû–qA¡—8±’Vs_îX÷Lœ¥pZg c_ Þ>Uà[“vÐ,Í @̃hl¯Ã;Y4vüypnÆqÛŸ‰ã6+wxqçÔa‰],NL•±J„ š Zðîÿ_:T²tØÍ ¦Î[èÇýê~ÒÛG::iH´*zwL ¾0½XŠóÇo–8¢³ƒÞöúƯOP®A^M¹ßƒC½ìÖ-†à‚—³axV³£_£á'•"Qסi‡G î#´ø (þ]02@JÐzY\È‹ƒt‚!º0¨Š5¼…Á 7ã„Am;Rvþ. -iÑÄŔڦv”;EG<8J˜¨‚Šx3N ‡ 8çq\îÉkóü ­IxpŒ®Iš¬I5ã4´&EkÁ¦Ò ¿rt¯ÂÁO‰[L5½ôÀÙsK-¾I‘Ü] ¤Æ ¸ó ÜNãsÐXMHÎÜ%*íÁIj5V hœY‡Jè5 ’·Éµ–cz?ò).d&{@rN‚½ ¯ûàuàŽ6ã;Ü;îW§p¯7ëº÷3ͺîÈý*›æsiši Ò °ý¨ˆ£ ïŽÄQ^¼Óƒ÷!õfÌ>úãou<O›l-Td¢cÓ/1~:û툀J€Æ»€f°ß”3f1yªs.ãçUñL^Íã+óôÌÏ×OñTç/dò‹€nav¨5ÌŰ˜Éеzž_MLÏ ¥Œ§Skf<]ÛÂäéøŠ<ü·æaðæéì`ã@¾¼ø¬fãk€Ö2~Ðú<~ã©þî<»Íyv·äoeòÛ€¶çÉÜÆxjwg^Üv…§2ýy{Jc¦˜}ûh>p&»‹­b<ý |%Æ OóçÅÃÎøBFã¹`§®l‚Úò°÷³½Ì‡×ýð0غ,ÃÂñ/jŽîh†æí¤ëƒû¾ùdß{”vy塊M/Wl<ñTCíðÓøØJå•ü½Ó×<õéïýè#×;´{Ïïw”{+þ½â÷W_|÷ˆÝóÖã_»«é½W_¿ëjÍC[žªÙÑö¾¢õÏüÍücFjç[¿çÞ¸{ßDZÏÎöýàÄ£¶¯8ûYáù¿à>Ù%¼°±ôFà¼ÿÅý«Ç~è,~lûáCéM/¬ü§Æ§[Þ9]}êð£å÷”ut÷lþÍÉ·9yöÓçGþºÍYjœûÁÐôy·F|ëØ#wÏÙ·{ÿ³ØþøÖ%Ýe‹{±B­Dú/Ízã‡ÿ9ôÜÁó÷T öUà/ÜpÚßsòƒáË‹ºÐ÷:ê»øÓÚYŸê‹O_½4(½ôöü'–÷=ó£+u÷® ;_«ùÍo¸ž^utñû¯üí¥»ôyçÏ<üó+Æ®®·¦äåU‹Ñ±Ÿ_½ç¥Þk߯ùÙÄÖÎMTžÚ!ûÍuÿøÔž£ßÚrßûkZÒ·ùØ«âw;sîFù_~¨»ë´<í±ûÇf iÎ]yfÞÛkvýÜýäÁÒsóï®+«[rQi:û†ÙWôГ¯~ñùö£×ë¶ÔU¯~åèñ÷𮜿áíÊ•ï¾þå†o|÷ÙšÓŸ.­÷í›ÿô.ßòg7?9·'ö?³}ß(çYÿZïµSÛ>ºTúüºmßýò¹çîý‡þ«è•Ï_ºýLðïžþøJ[v°áÌŽoÝÑxÉkþý¿pü×}U‡¿-d×ÏØ«Û¾<øú'{³Ï_ Nû—íášOþJœ¾h]˻Ϳ8~Æù¢øäÞÏ—\v¯ýúÉÐ¥Gn7|¸²öûå/Ü—YQºÉ~ð¸z®ãrä­cÛ*¢ßYøüÿJÿúÁÌWN?ö“êÝ(Çþí¤s÷KŸðþê6ñܼ{T!lýÉ_ïTç™ov'Ã4çÍêeåôèWò??çCL&d|(Àøa ¬ÆÖ³þXª`|+7Ùwiÿhg5Gk0¾h%ãi?mc|5[O?[C?´_72žên`ü :Æ—µg2&íbÔú-¡=é„õ’¹ÖM÷ÝýµŸýîò©6ÇÕ¾ááŽÕ ˆ/Xò•·'S™h2‘¦…[ÿJ¤³ñxÐ¥…Él&5G8ÁEt„Žpöh"ËFŒ7ùO†!s‘'y7¯îî ô­^çá¦7ê zcƒhhÐÆ…Ä-½Õë»6ŒpEƒÑŒj„BMž%Ã&úÇm5Âx/]ì¡cB&7† a·ìׂ¶ , òÁb `:™5ÃÆç®JÆznŒÔ§Íp½õçéInò_9‹ 36ÜJghÿPK0XJ@HAÆñg ´rebar_upgrade.beamuXpÕß»·—Û\rd/{IHa“]r„lr‡õ‚!Kr—# ˜ibÿˆpÙÜm’#—Û›½=þL+Rk5þgÐ(TT¥L+j+¥¶•*¬0;âØj‘ 2XÇV:hë¿©ýÞîK²0x3ß½ï}ß÷~ïû÷Þî]çußm¢¨Ò}íÑe+—ÚE9ߥ(꯮ö+z<ŸÔ•¤ÊªUW µJ,µ®¦ãy#•Î¥5%Oh™Ô`Ù jÄ EÇCVÑÕŒO¦ô6)L+M­®®OiùÆQ•œ æÆ3J«eD¥×i©Lª§•Ì 3 ZRe,PcÈ© 39ÂÓ†žW=z>O ©‰áœ#¤Sý©Þªˆ„‚ýôdu-k™ÍÄP°±¡ié)R™ÍO ­­¨µ±Õ{æ³4ÞüÉnb6¤ÒÉ„¢']éTÎÈ(Ù¬šIz”dÒô,§c·r›rx—3ÉxF”aãç³.U×5Ý¥ôkºáJªýùÁBËß´6ˆ€ŠLÓ\BOe Æä!‰ž~M3âØ‹œ%ƒ0ZŽ66eU׆T&Ø\l-Û4’Ne†Ý8¢Ä†¤;GFH*†q« ]IIˆÔPi œGà»+‘Örª3¥ húˆb¸ˆL>놩ª$† ú#Úzs׸¡«*KæJ:m9Uˆ¿Í¼Í€ÉøÔ´@ÍhЖ»fJ]J:§hÉ<±+ÁÛæU —nÑØÜ0Ï4H …à…š04}ƒk€rC^曥dÔëfYEä^˜ò2 ¹)‰•Ù(rrч|7+˽ØÑüõáŨe1’XžmG”¿±B;âƒr0" b´0äd¹ùnÑnªOF=²(È‘ ìçdº6{z}~ºûgÅhBAˆhþ7r„Ãf!ä Ñ’—µ¶àŸ ,æ&,­OôE°µä-ƒa´›¥Yo¥‰3–r³Y˜xXy•RœCZ޲³ÔããÝf 3Ê-àv´×)È1ŠsK[*^¨w…UÔ¢Z{BL!ÂH ÎCò€pªd‰D¼B~ÿ4Npü8mì½H…· ‹\‡z9$cv „‘^KÈsø)ñ¸Ÿ¶Ä7ÊvÛÌE"—9Ÿ8)feªSB1,£K»9Gd# Ù¨êvl)–¡6!™åX7®•¤å?T ₊£(P4Ö‡¸¨ÈAb%3jÁ4†[’ÞˆeIR°ÊšÓá1Ô2F*7ÆM°<õǶ ŸÌÜìyHœŒüQ1¶Ù4ÀF$¢¾I7¸¨< ´ ä Œ¡ \Û­Í.ˆ¦–wì÷²<8''ÇveNpËLiøj9‚$+Ó¼8ÂyD–—¢¶ÚžáXÇ!9vˆÃ©óÌCn‰ñÃz‡›gÊÂ'QËIÛú“öõãdý¸;}™õ8Lyø,j9kC8kG8ONË1†½š—åç!¸€ä`ØbI‚Ž+μÌYid*^ú>Æ”"»€ÝÙvšÅƒ/†CSš2qSḬׇ̀Z€Ì*-ô–ržFã4?š¬5Sf+ö.«~t9äéÚ3•榔íÃUgʧÛôÐ3[ÌZOi¾ét€Z€¬>òrÐHdÅ4äE€ß8ÊòߊHǘ™:ÍlRÓ?­±c޲¬ –º,,îO†ƒeüPÄz(bYq·ä£}~™ Ab+áȉpÕš7¤ÊQöVFÅÔ½ ¼àž,A-ÁØH4´Œ]RVƒ…Yþ*Ò¯³,•³MÞªs9—O:WuÆA‡p¡­ §EJ.BÉEÛMB6C_ˆ/⣊c·ùmúì`ʧÚ,£è BßñLÍåãÃYæíÍwªÄÌ!Aõ™çADÓ"s?–á'ƒ•Ø©$à †ÆGŠ™ÏT-ë`*pògBò—À¤r<ÈÌTsñQíÆq\î*óO¦ârJœ§9¶<]ªÇ%âIkNÝ¥"‡G¤ào3ž©3+ Ï/(\•u§1UØíjp»Üž…Ÿ0Ç•E¼·ÆÁÌÍRÞÁÔÚ£Y™æ à:0žª6ùbü‡“Æa¯9¦s.yn ç*dè­ðÖ9˜Ú€W<Ë&ŸžŒöаH´J4?J&bBÌÚžÖÙEø¾bó[Ä!Ìo"”ƒ™'—¢U,3×Á\%àß|Ü< ä™yf;!žúVæ!T!Ê $‡>ìm_&/Pë#àmà&ÂÞ…B ÐévBí­·yÚÞ@ÐÓßœ'f„+&1lñÀzY°Þ9¼500,3< Xìl`BijñdLp@‹ÀÓk`ÒXL±Öù’HÉàÁ U¡÷⬮‘,ŒŽ¯­Â*ÈAx—/°ñnò~ƹ¨È T ä%6˜/!6¥@áý@eS¹ ¿‚à`Ì™6¾’ðÕ@³1g“µ5@s÷å _$Øð¾sÉÚ+€æ“=±Í"¯#ù˜Ük!ÁiZDâÂrÉfÓd“7û PÈf³Ø&¿’È1ÿâæ¯"6a bƒãºÚ†#Ì·Ûò½„Ÿ´_n³ï²Ùˆ˜nÄ=0•‡ÑÏ'<þÌ#X&uæ3½¶¸®!öÄ–*xeÎÛ0t}=Ñ;\›^õ¬H°Ö sºxãÎ{zÖh¥Ëükö-_½òÉÍG†Vf~<~CþÙ;ßü4ö¹|Sð¶ÿºñÁ/Þá8ì^ûù™G+w¹wh^o=÷Þ‹·_»Ml¼_ ¯¹{Û÷[ýðªy¿\xîÔ;•]¯¬zé?‡_zà‚ÑüÌû'¿3Ø÷Ò7G{Joض`îî¯}.p°¼lÉò®êëÆÎqþ†[}§¶7{¾‰½õ“ÿyO×Á7×Î_¹ùÕø' Wï¹ûÞm¶î|oûóý_'/ýürÖúÖWOÍ:µò÷Õ îÜs×ø©ê¹?ÚýÚ–GÚ_Ùñ—‡äÇŸzÚ«ò·®Z²¾ªùà™Þ?ÿÍýqѶ5'nüÁo–Øûz ibiñÑüž¯î ììê9{û¹Ð3g~QRû‡÷‹ü¯5}*|]–ÝðÐÇŸÞ{Ó¹33ŽÇÆ_h¬<~!xþù5®}ç‘ÛúËEéy¯éÇÿý§–Ýw~üå÷vT5¾}píãÕMkuó#[Ž©‰O|0®¸8zxyÉ¡ÔÑŠš7Þ~r½øYnã?ÝväÄîß>ñ“zçæ_]}}Ù £Ïòò±—ç6lŽ«úö‡÷¾ðñ¬ãò’µ›w¬øyÏSçÞüßÕwýë.ñc¹Ø™ßíoo>Y7çŽ[ÜòÑ-?6¶cþšqêö3˃׊­ÒƒÏ=[¯~xë™ø‘¿ëïžýdö}ªðÉÀÕûöŸ¸p„}¸&Ù>Ñ–Ù™ÝùéXÍö¶ê6 7á -ûÿÆ+º¤ì½ÓFäø,/µ‡V"Ç÷ÀÂWRÓ÷¾[„Ç¿'kÉZ¼WeÝmøþò¹k™aè¸ïšÆhCÎ$…Öç2æ$ÃRÍY·¼óX>£l¾÷ÔžÈÿê×­ëèÊ €ÎiÚÓØÞ­e”–ÉaAA’òšÿÄsù‘Eß„ ´¼?~‡)ZíOe°Ä‘¦Ü©L"OªIª0ŸIª©ŒšB K&)Oûõ]+"ñÞ®•Ñaª¤Yjj–š›¤xS“ÔÔÔ4iÄ|¯£'Þµªóºaªh0eðjs0´xéÓzUÏSÔ+´èÊE!,£Ôˆ:TÐù{ŠSñ(EŠC™a:˜ÓòzB¦CÚˆÚŽ«Ã9=Ñhþó1ÍMþý´HÕÓë(jYÎÀgÿÿPK0XJ@ÐbÝH'Ìrebar_utils.beamY xU–®êê¤+T¨¤‚NºA †tÒ $M¥ÛNó&Þ;ý¨twÒ/ºªÃK$€(*OŸƒß§Ž#ðÍ·;ìè,>fgu–_ Ž®Èè¸ß¬"«³êŒ;;ûßêÛ¤ÕuwÂwºÎ=÷Üó>çVÓ]ó62̘îιZ"Æ0ù£†ÙW˜Rü¾”7­E¢ª)¤hÞÀÚ ±/U ‰SDõúR°!¥p©tL3•²ñ©DB# yä¬Z®ÄÒ(OÅû­ú3)ë´̤·ñ b$¼ùj" (…Ùt!Iœ:7„CœÂÑŠ³[‘ø`b@)„ºtTÑçÂâœõØúÿUqƒ£Õ]ßXÿïÛ닯ÕÂß ÎñÿˆkªQ¯G£¡‘Š]ÿ½ä\Û«¬ÿvÒé†ã‡6hãE5ÕWշܚ虪úïölƒn™|~•¤¶¬~x€]‹˜X¯†!$°Ýb‡{=ゆ);Bd2;XÑPZ˰–"†11L[ 7­…³89Frr¢µ®ErÊV®”‘Xû Ž• ¥ E¶»HeÎhdŽËÆ*¥£É.Ú·síÜö y«roší•r¥¢Ä&åÓúshÇî5”>ϰ‡‹-Œ‘ù¥Ì•ɯq&ÑA²Y$þ¹ êˤ’2“ÅžYp’läx‹Ýž4”šKöl±È„oÊýDĸ)O”·p/v‹ìù~cÝGœ¹¼î#É~4ÔÚE–¿®ˆM"/¶ ÕÐ[S®Bµ„ª­æFÙ©—-_­ŽÁÑ&ø;¶ˆAÒ­zÎÊõ„– :ø¨°€¥ÎÕpHL —‰T•Ö ã8OR6·Jr£•l™ì¼dl¨yÁV!jO V–¯%BÄl\ž]ˆC˜õ·óe ØHôÇoÆC_;¼¹>ã ÌžÀÖ€åHÙ3$e¡–Ëø2G: d’]˜H4O¬O uG…X¾N–`®4ÏÂ#—7€·¼2ÜšŒ– ‘~51|¥ldåÄíx0 Šªàþhð5€ÿfȶ÷‘üT.ÜçPÕüuuB#ºßÆ•Ú!¹QöìEOF†N: í/óÕè (q—!™ešXöœ%é#ö=çõˆ{.9H À =MÐ7qŒíRôœG 7 Í$ôPÒ­A g¢¯0]ø1‘f½x›û›ë„ÒåB ió2Òè§©è´T—EòÑ;8³Ç¢ôõS-¤õ 2JçBéÔáÞ…µmÂ4ÔÑ´Ü®šFºjºjžÐjž/´±|«hA_Ø0%àûU©¤9;lm¤Õ­\žE’Y~šŽ2pKn/JF¼…ÄÀ¦;dák@¨µ $$íG…›X¾]<˸ âFÎ]@Z¢`BêáK8Ém“H°EÞ °µáð4@ŽÕÄê}Lw 7²üô:¡Ãj^tmŽñ¥¹†c:dí½Q”©wœÛÆN œ;,–,3JÆÂ@í8ùÒ²DB9GÕÜ4,ºŒíÙ¤îuéÈu)z\æeXtÒþB½š—gj Ÿ¿¾Npqæå:ÍÆeNô’sÒ¤w’ì°í°ˆ‡³¡LtÞ¥3Ý «à‹{ªà±ÙeZFZÄìÂL홤]gœºX¾‹ rÔCÙõ™ ¬äºŸX'Ì fQƹ >ÞÌ$®Í"š±˜-¶»­«›³ZÝ’5óä`ƒ‡/çК“X~X{Qs‹[I÷áëê„yœ‡²Ùe 5ºSツ܀õÊäáGI`À\'³Qÿ÷™ýuBÀÅfÅr;ì¤ïªLâU5çp.׸diŠ,c¯˜™„\—…ó˜Ë=ú‹¬nayeùìC¸âP*ʼƒéê†V!Ìur.Ò0j“ .\úk_en$~2.ŒÔc˜\bˆI!oý™K ïD|#ÝÀ–†­hæu14„W ÒÆ~´þ2a$/Ø/ÄųsWÞˆ™”MmBÙKç–yš”yºBv Ì:•å­BÚÚiu¸ðtuº=xötö8x:µYH«m‚昰8 çtˆ¸À5RÉ*y­4¯Ö˜× )–OŠ™+Éè‘27 ¦&®!–Œ!ýM.ƒÖSç 9´¹*4n¶üýT¥è“ÃgÏþ­gU}öh³,Ÿ&óf!Û€ÐáæZ‡ÐÜ– Mp›džÆuvà×m˜…õæ[… æMÂFóm­,¿ZªIËm2† Œ%È­úë™F›È4Ù’Ñ¿ hM½-Ûºó²­»ÆlF% L·5sÐ#¹­¾–TKs›°&nÉ}IÛ‚/¸BH†XéE²…TÓVˆÂb›\ÊÍù–¿PàévµRÒêSXþ·‚x'´ï¾ ø]àŸÊòwc¹Ë{°µøÀwe¶vcy'ìÜ#Z,nN7_IÌ;×}mÂ^Ì™½’…¼ YéD¹»wáÀ}ÃîénÈ·+YþA,ïÁò!½^2®¼äý‚… ù2ò^d4a¥wÒ$rgé0¼»À{ MxqzX“qrd^èdy?‡€q7’†•È[@+y·âèxÛ{±ýè°±‡AÚÿ´ G94a'‡/m¢Ð}­É·ýýŒËÈ8Ú,ÆQ†éÑR‹È—Ä™±$ž†“@ÛØa ôûc>£_ÔiÅ€–â%”àR^FyFªèÙëÕ”Nð±”?‹gy¬9rÆQüzÀ@` ŽÚv žòL&ßq©|ÂoϱÓAñ)€©9ô¬¯Ó­Ÿh§<7n¢8&ª‹Èé¤6LÎ9KpgŽ.ÅÝ€.z–ÄÓ0ffÓ³Ÿ“ãKwŽ râ°ð;t–žïÉñkqŽÞ¥t`eŽüÕ'ô[(7'ž$>ê#ѕȑ™µ‡Ð“9ùZ“c[2W)Nâ÷Ï'¾yggó¦¿~ýÀϦ¶ý^¶w{^š3ç·Õ÷Í;1³b‰Pó´|bàЇ”Ø¡/_:pøØîSK__ÉýdpWû½«ÎÊÕ÷,Ûò8›n:Øÿè³ÿÐuÛ©I9ý´O¾œÿѺ{÷éæ[[§½Õñõ»¶šÂºž+ì¤ÂçNxì±ùhè¸ðkÿÁ ï.X9kçíã·¸ºÌ»yÜñÝ—ö½Ütø¥—ß-âNm;þÆš®#§¾°?V8åÉ¿hîS§ßh=Þ5ë¼í|t»óÌó_w~¼±ìbéÜê’‹[O®úåÙ©Ïý¡6ñIjÂÓßM‘Ù‡~UóÕÛþÓå/,ÞØôÞÞão|˜÷³•¿)ŠVU4÷}pdž O¹Þ\SðMôñ‹ã¢'¿|B—Îû” ×}zʽÆ;ܺíùϪÇ,ìé¯úч»Þ~èO£G¼û_~oÞ®%‹ßڳ뾟|~ÿþÉo¶<{|ų»7lþŶ‚ÞºtcˬySfV¾#̨YÝ_¾aùÓ_D_|¥ÚøÊÏ‹µ)8õ×?¯¾ò~˜Ï?T±ù¯ÿßæ/ªyëкs³¾2¿ÓiN"@æC%1ûhýùάȹ3!·ßs{<·¯sgEn_çörnÿæölnŸæöæfzv°Ò×ÒT>™ñŠ“;/LùÉ]¢üË~Š“{·—òÌ¥@ð©šFîŽ ÛÈ-† A†Tãú".2[\Õc7ü]eÿÆÏºþÝüç‰þ~×Ìx©ó ¿)‘$?ò©„dèoj:ó¥Ö†üDZ FRŒQñGâ„ÂFS$ˆ¦ƒJþ±+Ìa/dÌÎÅ3çÜì]4s®{€Ñdol²75Ú½öÆÆÆ,¿ÄÕã9¯kþSŠhÅïor4·ôë6‘ŸaÔ“×ä¨è6šØFRQb`[Œ3ïÃH${’ØFqœ±.cò*FŒ—R„ë”$§~’BIÙƒÈôå“”‘ØÆXj§(`þ6p/µdA¬ ¯tÕ+< &¸ÌuŠ8%+m>ËŽˆ¹.„EŸWº®<‡Ž£ç:±~ŒëHÒ æ:Ðä"êz#ÐÙýËÿ#«q5zÉ’}^‡ Úè«•PÆ+È$»†é@„ïF1$‡¢ü~yHiÁ8. á¸,ùA ˆC>ðn Ê÷€‰$AGîX¢¤¡dH¡/ýmaœÂK¶†ØÀù˜f»Ã°ÛBb”€µ©ÉnÎãHIø€È‚§Ü‡A2’ )ž üVQe¸~¶£ð£þ4(Gù£âÐ|\/E!¥t€?âbaþ(Dr4í”ù) ¥ü©D»©;HP(›ÇÅ-æQÒžé-š$]2éM@í†q;šØý4;B8p… `Jìš 3©Ð,¸F-X‰¡ßê]·‘ë ‹a¸ü>„¸‹8ˆÈú¬}d«/;>ìG×(HpW!»ä¡úfì@S‡Ã|tô1°?­5ᣨE‘bpÁ>.J~.7~¢®H~\ç#4;^?càuÄ^]“†t—Áh˜?Fð'07!Û ÒÇÁÖ4$àD„?é¤~R?)*-‚ÙgìÛê„gxÀ£Yèƒãñ  “‹ˆKÀMâ[§¬wÁ’‹.kz7¹ì•L|äf!™ LíÞOö…Õc_sq@úä#áO;÷Kš8!K- Ü/”úØC|\X¦1Ť|)?\duBöa“fO‡ùñ9 ¨ç}*§P‹ “ÁܼŒ¹´.Ô_9Ä7wð©0Ÿ$êÓ ~œš‰ð³·I`*üYR¥³ðâÏ@¡î¦Ù3õ*Í@ÞïvWiÆm`6ÌO#A’’¢‡Ø9KZxŒ-‚¯ç¢ü³¹ÝSOŽ0¡ds¢$\ÅP28,Bº~Ý¥äöºJº»ƒfçë"`-Dø´Sñó ~^„l’Š#P÷‘‰ì'Wµ;}dá#owXXïz?,ˆØÂç&ý¼Ý( 4›óó$š `ü0¾("*mêÈœ™ò:Œô0•€<@ˆvæ ÎÈ59{dÎ9¿‘Èö8c«ëwTP»3|.™»[{ö¹ø\>t»d:<âk¯KFvñýΜÈ÷»æG\8G]ü€‹?äÄ8¤82£®9Á?æòsÂÑ=tÂ%sÚáïÌwø)ÿ¬ÃO‘ZÐÉ+¤Ô€ãC‘Uœ9ùvåÚ3U«ùYGþG~Ñ‘¥¼ïýý¤³&üsÎH¡ï®’šÌ8kìàQ ÷<=[4 æo`«ëÊ÷ 6{‚-nݸ1a¹á혹 |å“GþtñãCϼ%?þ³oÌ=ÿöÁñg~ñÀ‹üà•õuýÞûžH¦^¹ùÎâÏßìùZÏøG¹×ÿüä°§÷åŸ.=õêè¯qs[µ¥ûè½¾ÀûÞ[¾ùÎÆs…ÒÜÀ¿¾óÒá±__»vú­›ï¹÷×Wzßߨû͛߿ñÂ_KÿøÖÖûWÓï<ý·í¨°üü¥ßM¾1ùÆ_ùö/³ãÂCv=9^|ó‰n–·Ÿÿ÷¯¤Ó·¸¿xêŸ/üþkž/¿v4Êl5GâúÌé?w®.:ó…ÛruÞÉËŒ+wS@s?~[§ù GŽÈŒ%ú>Š:2¤ÆaG†ôkÈá÷]=²Sory—£Od:€;å&qræmùÛƒï<¢³Y"Z+ž<….kQ¨û•Ÿ<üê~;ÐýÔ‡øƒéÕÕÄL¥›ÿ±ä"ï­®“Ï(ƒ0óo}fŒZ¹¬êD ±Z3áSmb´l±B8tqò+¹R-¯å©Ýò{ù<ÅÅgfOg.ÌœM®Q­£JpT *™`P ƒ;BìÅD:337unj^.š’–ÍŽ†ÂÇV-Ÿ.iºN­Q áá±á0á1f±¬­4f¡÷ßV=*§6«´Új9hh¯Q#+Õ²6Žkk#†ž±þ;³;³¾‡5½´JÅàß$ð¿PK0XJ@¿…jjD–priv/templates/basicnif.c½U]o›0}çW\1©J[Ú½Fy¨:"EË҉ѾT•ei­;2&Ëøï³ÁHP³uRy0²}?Î=÷pù@yÌŠ„€K$Cœ¦Ÿž]ÇÉV4†@² MC’‹BÆ$*·Äƒý>IÁHU¡0øq{Þ°€ÍÝz=w¥M’B®d+gïT}ûgÌF´ÙlߥP˜ç‡dámVKá·¾'?' €ï< |çå °|Š}Î?±à¹†×¾»‡Çéü\î¬L +*øÿAø $CΗ:-èn “?x„…&Ó„Ø»šׇKÿˆ£Ê·÷fmvå—S9U/åû3ßVs,š·–1åcÆDŒ¤UàdD|ÿÂ÷äôéä$ÿTwÂÜ0ëôS-¤ ¿QMŠõm\k#IÁyÏn`"‰*$ï…SÅ–‘ÏM°î+‘5g®xq§¾¢ƒTÎÙæ½›tm+Oj:B_ƒ¶˜w‚&}¬-K(Ö¬ñb{‚Ø8x&a›mæÁM±"€y IÉqFc-–jÅ`EÈH&d©g‘zGù©ÚÀ›µÑ^Sâ©L¼©Æ27î]Q†UÁ8ÇïÁVÒJ°ÂþIãƒ(OE[Þpð.~Ê!­×ÅÁ3ŒÐM\GüîŸE×_ƒÛû œj&¸<`=ÒÙì³jtéÐèáácŒ4š+#$Enx]*Ô@5V¼vMÁHwâ`­±t<9¿Ì3úÃ?ñYœD:°Jè§QI¯m8jã"H–êeã‹«³ûIΔOf! ÀÊWAïòÛ; .U#+,hšPêÒ5Œ·ý©UýZbå󃺪åÚâÛZrLJQ)„ÑÜû¸D¯&S­û´²6ÏH!$×b‹ó·åêÄR¡‚<òøáK#ãûËéŠ.c;`Nçóká¦Û`– ;SW Ï5]1ÒZûÙÑ–¬È´SQxýñäÌ6ç†ÉýdéwîeÇéä2wËïãz,ãnüÃz1)¿jkÌÞ9þ»˜üÞïqP»ú¿P¿ol¯5–<0¬õ¶æ…/nág‘:9u Öå¯P4„lô"´"ýÐi±¿PK0XJ@ý+¡R‡ priv/templates/basicnif.template«.K,ÊLLÊI-ÖQˆ®ÎÍO)ÍIÕQPÊ­„0•jckõ¸ªKRs rK@2I‰Å™Éy™iz©E9J@~qQ²~5Tcm-X—Ždúäx4É õPK0XJ@Ȫ8’‚priv/templates/ctsuite.erlÝXmoÛ6þî_qÀä¼ìc¶nhÓvйC’~ ¶N1‰ÔH*‹çê¿ïŽ”l)vìd±S`úbŠâï幇GïïÃXç¹V±CëÀ–Ò!¤ÚÀlƹNªª×Ðo™a¿5_~;¿útpØH5ÎÊãLŽú{-eGõ‡£±;œ˜lÖöô½¤  m\,²Œ§÷÷[xH |.ÕØI­Nƒ+ýü ç*Õô‘¿óÞÁµ+ ²âà†ç¾Hò]§p‡Ó£{‘•…ÆÖBÑŽ,‚Þ t¥Q²ZÆk²à4Xt`*ÊÌAatÆI´a‡ÖÃÑu 6[ µÃS¸j¦Ž!­=iA«l 9 åxŸBi1á¡ñư‚fãD8ÞÒd Ú1¡¦ i_l™`ÕÞÁ­D¾ì뙓9:#ŠfÇZ%dÉOÇUu³£Lß]¶Þýw~¹©£ê_(Ý3?Š£?牉ü¤}¯’+Bë™°h«¹¯%AátÞ?)ää(žæ¤ÓØoË„…N†V! Á3øNˆø«D5F^NÊ4Íx4»À…»š «ÁÒjhá SÎ6ÍH*Lçæu¬æMƒ<)÷VEs*škú­š—5Î ð\0¦U~ÇÆôw`NÔÃè1©jn1ÈYÀ—ŽP*¡ƒ6 š ‘„8-R9¼EÓ?ˆVŒ¼ÖE¬h½ñ/´{Ä¥r2c‰õݪÙTHÊÂRvשé*išeéŽcÁ%.I Rð2Õ™’‰sëI#•Þ£YG"bA#MÈ®¸ž¥’Û­ÒN¡ìª)ða‡e ¶«r Á‘ûT]—aÛªÍ'ð¾Bh-ÛsÁ7© a$BM¡`— & ÖŒÝÔC³‹†Náôáîþæu|0rád ŒtS&{ð@UÓ v[ÉkòÕcƒ®a ÊnRj91ÜPûãëÇo_>†v –t˜RÅÖ’Ÿ}L¿7øQq¿ |Ôìi*3GeуõyýYK}WL©È,þ¼IœŸþŒ<ú/b\n1Ñoì³èäåP%¯S7BΔϗiûºI†Lleö`W$ÐeÿL«TÞ{˜=.Oü¡r'‹è…ÕªjÞ‰‹“ØŠ{¬?Dõúª.¤Z7¡³Q´ÔÞ½Ÿ—î£/‚‰Î©n}}/ècì5•¡K: çïMª ÅCÓ„ÜÔ±µE£¬ÓÝu(åœi]dò¯¸Ï‰§;BjÿÚ­`jÐSŠHßÒ=òˆ?±ª ÖsO$"FtR褢Ë,á×+¢òåÈ`®ïѫŠÛÊêA¶vî¬DÜsÂ뎀Ø)É6á^ËÄÓ3WRþCÀµ„³ŒZ}êDJê"c+ê%~”}·kRðhÑ“Ã.ùaSÛÐMNh¾|óMÅ&FºôW.SØ:7¶æR¸h\^Ä8Ü.´znMl9ªêÀ;ªŸÉH(Æ“U-ÕV€ñ á§ÂÛRÃËÐø,Úx æ¸í·“úJñvxÛ@B;C7? s8²‹ìa¿¹7ì–œ6ÜNº8Ù1+m½Z³zéüŸ{¡'‘ö¶ì÷RÀ¯ç?žçÿMš:x Ìw@„Û€8»÷<„¯cЭsç àÄKãÖ_ù­ëÿŒÿkà"ºž%zí±¶ÆÛ–„+ú^uãÿÕ]Òø¸§ ä¸Gu 2§¤åTV”Ù½ê°÷/PK0XJ@}Oê­P_priv/templates/ctsuite.template«.K,ÊLLÊI-ÖQˆ®.I-.ÉÍOÑQPÊ­Ò¥9©Jµ±µz\@‰Ü‚œÄ’T LrIqifIª^jQŽ Ò¢_ ÓY[êâ –jPK0XJ@ôävÞ priv/templates/simpleapp.app.srcmŽÁ „0 DïýŠà9,ì÷Ȳ¸6HØn-Mñüwk[P\s 3/ÌD‡CâÙ#¨fÉv]Ñ@oÔ’Œ‘C¥]·û ‹ìâÙT¤‰%Q$‹Ð¿ªw ,I×ùRôäð†H²Ž?ÿ EÿæÜ£Ç§ï¼KqÅä—¢L¾˜ PK0XJ@¤yE†\Ï!priv/templates/simpleapp.template«.K,ÊLLÊI-ÖQˆ®N,(ÈLÑQPÊ­²”jckõ¸ªKRs rKRÂÅ™@f*PJ„‹‹’•@‚EÉúÕµµp \:ãA R‹r0tÂ%pê,.Å¡&Ô PK0XJ@À­À‰œk priv/templates/simpleapp_app.erlÓÍÍO)ÍIÕ¨®N,(ÈL©­Òšz\\ºI©‰e™ù¥E@‘œÌäÄ’Ìü<Œªª‚#BD!91'')19»˜K7µ¢ ¿¨D#º¸$±¨DßHG¡¸$¿@ß0ªË–r€Ûr*™Ïv»F|0ˆ ©,HÕQ€°‹Ò‹5tí¸€ZÅ¥V`-ñ9™yÙ Ÿ‚< 6 $®!?[ PK0XJ@‡O³Ì priv/templates/simpleapp_sup.erl­RQKÃ0~ϯ¸—A ©ë|TÄ +LÔ§QJ–¦.,MJš¥ä¿{uÝêÃÞìA¸»/Ü÷}GâÊ­–´ëx]«"„¼iëèŠx+wü lë(¾HwPu}a6ƒ‡×”Äò«¶ÎÓMã¹ó¹Vf?O²¡áíŒÁµÞr±oF„2ÊÏ§Þ•ÔØ ÎB‰ˆB Í2Ÿ vJN°%ŒC¸¥2’>®Òõ’¦ Þ¿k1èÒã'b°ÉDVÜHã\'Ir`-ÍÂ0ÄíÿcÊÖ¯¬i¦ú—Œ|hñŒQŽ›?åN[Ô›ÁýóËòcýη^ˆi©^´x*Æý†PœøÄ¶³he‡ÉÈW$ÇŒV2X$á×bÈíPK0XJ@Û"'»ŒÏpriv/templates/simplefsm.erlµS]kÂ0}÷Wäe¡Õ}ø´‡ Á Â6‡2_DBÖ^5˜ÞHE‘þ÷%ÚÙV»½ØZšÜsOϽ9× U°‘@‡yŠ Iš­†û K¾jÑ 3{À\ б7šx#‡¼¾{_ož‰4îîˆ{ó²,ÝÏéoÐ×B!ñvké¸"ö† G>:54“WíûY¥òÓfÕ_‚@¡Û1¥h`ÈCh?vOYr $0Øj³oß•â=úi´sF œ+›¬! ºB¦¯`¾. Ý©¶u…›ïY§ ûYYë²K§Mâ¾kJ¯ë9;HåsiÌ}ryr¶¹C¦3ûÔë— ·|”u£E|®û V9þ‡K–™æâ,i»–)ó¬U2¶GÂNŸðyÿ¥°?(X?RáSk¹wˆÕVJ”÷sQÍG,v‰ÊÑeSP*¯”:§ôf;J” Ìû™çA¤lt’ìÉ3F¢bÎ2)t“ÀIÿöÝ‘”õa9Ú«üAÝýîwwäÝñøf?Ì`­Jž×5“×'þk&dÉ¥Õü#¯3xyþ[vef^^Šš´ŽßfPÙS¯ Öœ¾sƒÜÒÛÙ×?CH [¥Ð[^7\ÃE¡Ec¡R„´\³Â dp#ìjñ‘; ´¿£52~¥¯M³Ÿµ‚S0–i›óf]ÆIê–Ñàë[KŒÀ.90TqëÛsn,¤p‰‹Üþ¢ÑªàÆä${ù"… ¾’—ˆÛ_p¢r¸ä ÅFkLP}z#%ý%!aŸ”²)Üð'u WLÔ§`†ÃVr›¯¸–˜å¥(1Çy¡¤ä…Í 9î(&),+×Yƒðý7 *éü³zÃSh”¼~hCÔ>juÒÉå(Ä&„„Ê0ŸkfãˆÐáSCôAsƒ˜%yfóìoa:&‹ûöY²ÚÆ/·Æeèo³Ð§>6ZŒaÄßU>¸V”LŒvÅtÚ…ŸÕš³ò.P4¼$†ÌqLÁ(øgc,”›u3FeQœ¢CþÓKô19éQ4V5û{JŸÝYÁ꺗©O‰À@~wýôŸd1°€nÐnþZ#æ1;WJ}3„òˆ•¦@„÷ªÜÔ¨óûFb‰Pîá¼)hì™wÛcÒ`-ŒÍ­Ê™UëØ#&£Õ´‡Ï¼5Ý2îoÂöÁ²2"Ö½9Ù[ß^±9§¸¯™QrïPMÄöüÏ3Ú§x¼*, ¼Ì vßg7>XíØ>Ÿüþ‘l<š£Œa)_›‰´¥@q{e.¬ÆÃõ?¤‹£Ù }ÉciüÞó«–þ$Z“N~ñH¾&{@î}çBÀK‰ÿeØ5 ¡ÓÖªè=¬ûPPîý‰ ÂØUvúÑëe¤'ÏŽŽ]•jÄ«¢èwÞ]ßÒf0™ÆG£X2èÐ'#¨hf¸-”Z Ž~¹TUä#Vüˆ”¡jîuc×fÇ{ÑÃ%!LÃd`Ÿdk"dðψ\¾ãt‰ÍuÚS`MƒÑt­?7›ª·qB”Óøcó(ÛªÑð2=&)ž·¨èv1bcŸñ‡Ì’`Ïf2á™ù~\3K¥í·ó «ÊÈ•í&Í ì ‚²‹ Œ{þ¨?¶Êóú¢LVà"½Éf—øúéSˆ`V2¾V²u^­¥/0^kk~ò7¡«ÂÚDe¥ÐÎ3nÜ4žù¯Ü­µ[Øeé"Òn CB8Ü–9¿åÅ/5}>:Sƒ²Z±µ¦Êþ¤É¢<‰2QŒÎÔ¦.ÝôIÐ@äŸ}ÚEiü¬¹ojuÅêר}Èf'q¸ÐNéï4P’¿ÛeÞõ íâc\¯Ê¬ZqiB£_¢A|æ¹ßÖù[…[pllP¡œ^×vã÷XcŽ3¾‡:Ù' Â"ÌPÏ'=lÓWhlÁ&gî©¢J°‘$½HLœvïò…ûó¡ñæ>˜)’ÞhJ{Ï~#è’8`þ¹@~‰…a@Âø ^Š%Þ;¼Ë€÷æ+!™¾£»¶=¼-ÒEšn/dnKñŽÃ܉ÏÂôãsBlÇ!„¸Y"´0>§n¥ r¢ö‹ë4«£Çí*žòN׳qkÊþínß”CÿZ±3%m°B-|gl¾¹)˜l3Ý“oÛRI7b$}SowÕö*‰b“Ã5‘KgÌ5“§ß‹aœ©ÝI—‹Ì}æÿØc¨;ýí¨Ò´ˆš¡7L¥-W’róØAfû3ÑÖ CøNVêQ/{r‡ËÜv­4§JÚûñîeùE ÎbÕmôPK0XJ@Ó0fLj(priv/templates/simplenode.reltool.config•TÑŽ£0 |ïWDH+í®"ªû‡û‹£‹Bârц%ÙêzÀ¿Ÿ -¤¥‹z¼eìqÆö„.œg¿vlú:£«RiOØaà3 >Ô5N•ÒYÅ™¯O Î:ѶåQà,D¯Û!%ÞÇ–ˆÃYÖuÖ)Ðj2<ýÈæø¢‰±Oð³ D…BS@„4¾T±Ãêê…¥4 ,Ýý_W?,[9ËU[IBëÝ4 h*PЦ7Ç´•æ2Zø#Í—‚tüˆ”ÂËß8rg„qCYþž¡öòÂ~:f]d—V}aC¡á¶n;åTÚî±*þ çï{B^•æü|Ï-ø·d4¾™úªœìµ=ºžšÁzÐ7ÂöÁË·ì°jhòÆUL‘×:êÚ:Ù…ø´`ZM:¨Ë5÷†ãW<™}Ùñ“ÙËj¿eì®ÞÈw»]VC¤Guç ºx#Î<µ^Ô|NéÆÕ{ê<1Ñ—®ENFf {¬@ ,ºb|¦å)Øb(†q“Ûâ’šèÜ÷æ„­*·˜hý¿&¢sÞQ×Dħ" LJð0 IÒž“‘ËF­¥Œè¦œñ€3Kù·àýÔä¸ë°ÙÊ5gHÊOþPK0XJ@fê({õ priv/templates/simplenode.runner½XmsÚFþ®_±!j»Ø~r†¶—©y„“é$)ÈÒW zw2vMþ{wOï@Ò¤3©flÄÝÞî³ï{<}ÒºáQK­¬§àœ8 ½gý:ÿñ%i—”³;xHDHÊîÏA«ö 6øiËš\‡½ÉÌíLúãé¬ÛŸ´íç~öãéw­“ðìěภ{uáöRªÇ½“t §ëM;)ÙιÓ~Ns5º‘ÞÁ|³ÞšÏáI{â%±Œ,À‡Ý3圪dàp°OÁþÅZð:ÐÎÛ.TLƒ'“pã)—9kGëúq´&2_ ù€ò¹ÒÊZßâ8qq6sžìSôðŃ1CfŸÈ[3+õt{N¢iáÎIÔØ“ˆE$$ áò¢˜Ô x´–;½˜Lg½ÉU{î{zm+;¥ZJ{RϘ ›§½¹Õ›LÝÙwˆÁVðø0È.ÆãÝõ§'ð‘À\£ø‚!Ò´îÖMO.ʸÎ# WÆ·˜~N–ºÙa¥ ÷aÚ™øüLÝÁo“Kw6¾˜þÚþ& û4‡,¡Jò4JöÔUªé‹hÁ—ÿ¦1FxFùUJ—êzwFÃ×ýË/׻§Tý “\õp®}ïkƒ¯Ó*fÁ ‰°à™p……kó5uìðbЛ¡aÛs¶”,†£?õ3]±ø<3¥y~d'ƒý•€FVc¢¼\ywhWNfÇø¢Ì[ìIüÐL6Y@Çœ}Z _ˆ[άÎhô[?]`F×™ÝOÃ.}9pJΟ‡{@‰ ب® ‘H<¤WiÆïí~¬ާ4u/âæ2ĨïzM5Y¡ƒµ¡±9ÏŽº½éht…ñPpo±¬.U–ˆX Ì_íQé쌃‹a÷@ÊÒ|a§5?U¿dÌîc!uC±Y¶–¼7[jÅ'ÙZ`ÐÙ%®Š#Qêà’Ušýn¯‚†i¦ŸŽá¤Dˆ¢~iÀ?=+¾|ieŽqÕ¯o=žÆC€iP®ã"|0ôÍf³8a"ež˜4wÔ<—ü¹âQr¿ízXz£íkÉØ+·»íJo)¢×áÃvÈ4-ŒbáçqíhŠgÜï®…ó÷Úó#àÁ´é3K¦ööýÞzL!Ù÷vó¤õîæóÖ­·¹…£Gœ}03ì³Gó=>h¼êW7‰Fîï°E=Õ¦ÿzç÷Ë·ýáÉ!ðמӿéôwp§ýAïKôy»ýJ¤?ü R¦<¿L•¢|P,ËXYìŸwk •'bpz¸ŽPm@šCÕa³â˜6ó[b&žRv1Z»kEIÎKp¨1U!CÝÏ*ÛÛË:Év êS˜¤k&ñÞ `ƒ­”fJIs9-ãHî3¥˜"cø­¬Qâ¾â³°+¥â9NZ VÌìŠ"ÎdÇ Îß?5œz—1âž7݄߱øâjûFè<­=u¸Ëf µï~]Oý/HkÝ•šúg:ëŽFõNWé—ԧʧ…épû 2·DÖ¶¶ÙçÌÇé9ª¦IÑ‚1GõCÌ}/Ä€û3Á¡&ï|Ï9{‘ßdÍ@\=¾vÇä Óév“,—¨à Pç>¾Æ°MïbFn* mñ¼HÂózï«NIÅF û8ÿþj4š¾î_õÚ9¸*\W³B_AñÉz˜‘7XWÉþJð®À^JËA~‡~i(^õ‡é~JxhX-"jpÝ&QÅÂx2º¤‘/9x‡ßâ]=€#…õþýûV«U)îZ©8”šÈpŒ¿àÎdç†óðõ ”ådW>»r‡zéÌÄHõªŽöãÙ÷ œ‰>îÍt¨ÞîRf”ÝåT‰ÝÕÜVÅ?Ýd‹î¸‘™·égz¡0q"cª–ÜLöÐ:ç¨Ô ÛØÙ™ Åp'ƒÖ¨J»i³0±“” ’dÑÝLcȦaøÎ¶?4 á!¡Hâ#·R×wRíåleˆH1^+oÉ΋„|4€¶Ô´·Y/ئUK5k{0ç·iM¬ù©6Уt“ –Y?µþPK0XJ@8&’¬M$priv/templates/simplenode.sys.config}޽‚0…÷>Å I·ª˜ˆºêŒ#! b!$`MË ’¾»—‘8p·ó÷å¦ œ#9%1 }/ëŠa°¹mR†ïyG*c´‘®*e†²n”@@z3Æ+¯IΉٖ|2e×?¨îKÿñD•m)oµ™Q'>=ŽXW P6ý ÍŸ×¾SV`îŽÑaz'‰Ëc|¶~©eÌX#Läð;ŽÈÏíšæ™cÙš±7PK0XJ@¬d(ÄA"priv/templates/simplenode.templateu‘˃ E÷ý c·†nLÚiš†Z†¡Cø÷‚Õú@7drïÜ30¸Ž_‚A‘ÝÒ”qZd¹ìc™û‡G'g™l¶,èÀCÉ¢‡ VkˆV¯ó`n”­¸ØÄ˜ˆá‘èÃ%hC7yK¦ßÎײLÌ8pý•CÚª#EšRÌÌ@7®Äûcä¦'…B‹-ýB íxÅ­DØÔ0§&á8ÒqEuãC‘tï1ƒ¾Ù ûŒ¿µb¬å€øPK0XJ@Wš8±!priv/templates/simplenode.vm.argsM‘MO1†ïû+ÆìEcÁøãE‚‹A àÇt»³Ðìî”´S!üw§xÐôÒvÞ÷y;Ó4…7Õ"Ø x…@¶Ä$£x³ßǃ)‡‡Þåm§+«—$i kkƒPY¥ñìLK@×(Z&™GÖ¿Š?ÂÑ÷ŒÊqŠ¡U¤–Ø"ñ=¨À6sèYŠ>Ç`*0,dô jÛÊ6hÖ–¼Ù`„>¯ŠFr‹”X©Ðp§<ÂÖð ´`¥“3Ñf«||BNÑ5:ÂÖ¶i@Q *Ü‚ò;Ò2‡ªô¢>v!¦÷áúè!-U ¡ÐèâÔ´%œ“^„'-\x«käÈ6OG‹qÿ{1yŸÎgpÕ½»9’æ[T5< €-¸@ÐZ?‘þ‡£Ñì+Ï'‹þpžO¡×M~PK0XJ@ žJûKÀ,priv/templates/simplenode.windows.runner.cmd}T]oÚ0}ϯ¸ŠäŠª$+}DŠÄÃèÔ½0mÝ2ñ…XMìÈ6° èoŸ8Á¡ty²}Ï9>÷Ùi4¥ÌiE3»!®­0;Ýš³óÙ†Vð͆M@ײÜ„ššŒlÎjªP`\an¤ú;n)‡‚çp Të]…ÌÁר0œ8()MÍ6RÁ—gˆ–¼ÒY „¼0ŠÉ;«Ó4¾&ábÐñ2BÞ7/޶©F½²2ÒcȲ ø~P¥æ?_Á•æR¬£÷g%+І*³BU¦Œzqiä MÆO£$4@–Cjk~ýf¶Ô%L­ç•Q¼TF¯ºk­ÚMpߣ{Ÿy#°æbµ;LH¨M–ã)Õžç¾Í¤ï8Y‘«‹ˆ%ð ÄdgYÌ…M«,c˜m¥í£ß†ˆ¸Âô!ª)N‡h6è¬/AY‡1…×ÈÆáîî3©\ -KìÔü¶„×Å×Ũ14/ÆPs±ƒ—÷±¶•Œ¢éNÓ­å`^HøíÖS pôyú O ÷ä,¼ÐÉßxŽZÓùâÙ*ö%!]ï\ÃJ­ö)þ±Ï‹1 a‹$9ÄsUR±mŸMÐ37}AçcH´;@’C¤ ·n.‚yÍ+ U[ 1<< dúm“Í•æÆM¤nš~ŒîÓx˜o0·3¶ý{¼Jz®+Ö@“7îtByßöÛÒmC¯•‡t7cŸ±í|ýÜ”¿ç¢rpÅl»9‚«ÿLJ¶ }åÏÿÚ§K&y ÿPK0XJ@­Ò.´Z/priv/templates/simplenode.windows.start_erl.cmd•TMkã0½ëW ¦i]ÚÞ_ZØî¡Ë¶GƒQâq*jKF£ í¿ßñGd'4t×Fï½yoFvÆj·ÕµR™§~iÏÚïþ4d'@¾f¿O胠õÔ’-¹«M)ç!8¨Œç«U2H=‡7òŽå%lÇ&g¡ìU„*8éÞ#Ò^.TV‰ÐÍ#,JªMÃéj%²ïd9½½º»º_â0.°ãàJÙ…yz%ñUôj‚ª¬†µœÁ›¬+©°º!Qz:ðÎAüTK5XôT“fâ¢4>ňÁüp0N¯í§÷ðûõöä¹K«my ÇZå]´…XNJ¦èSàYÜy̘úh 'iÈ.]Ï eŸážbðn¢²ú£Ìè5Î¥1ß›w†;7-*S õØ<ž´“JÜ JWS}¹Gßòø““­³•ÙÁìè¶-†ê÷'µªeCg„æéÃ6—£Èû/Ëû&鿇Y›}3^Ùä~á4JœØŒ ñˆã&ðð• \oú‹w%•q 8¥—b‡î€c/ÙT¼@ÃÂñ6Å;•íœüÖÏê/PK0XJ@“Ù–”\”priv/templates/simplesrv.erlµR]kÂ0}ï¯È‹!]·ù¶‡ Á Âġ̑Ùk ÆÄ%©8Jÿûçú±½ ÖZrsï9Ü{Ï *Éà<7úÄ“¢èßáìØ‰«Lã$5 O ý{[./âù2žô4^Ÿc— z=þûx–áË3¹±\IŸJ[Ó{Â…¯ŒeÚRÁå>º]·Ú~µ¯î§à’Û莠“‰ºaBDƒZhlt_†\n• ô},è—Ì‚/Ú¨Ä!\i Ñ Ý4yqmm•–¸ÂÇË€• µt.”Û‘³í—‹ÒÀ­ÖþëÜ ŒïùðP§¦>W{‚üKáÆ©yÓ9¼g`,At¬Õ …uòW8 GñA‡_2 ¼±˜NMú $Õöâ ‡éÄýÿ€)Íè›dFI×c¤ö®¬fSLg"Yy%qõñÙjÖÜBÉßšªéZ•Ltªé'PK0XJ@Zƒ`óJV!priv/templates/simplesrv.template«.K,ÊLLÊI-ÖQˆ®..*ËLÑQPÊ­,N-*K-Rª­Õãª.IÍ-ÈI,IÊg™©@uz©E9J ¢dýjˆÆÚZ° PPK0XJ@,ìX“§Œ getopt.beamPK0XJ@𪎠T Ðmustache.beamPK0XJ@F8{ GÙ  rebar.appPK0XJ@w·f)p wrebar.beamPK0XJ@x‰VS@(Ÿ0rebar_abnfc_compiler.beamPK0XJ@ZkÛ›Ü 6rebar_app_utils.beamPK0XJ@<¡| ã=rebar_appups.beamPK0XJ@>»BMÁðŽHrebar_asn1_compiler.beamPK0XJ@‘¬8£ô …Mrebar_base_compiler.beamPK0XJ@I“Ð| ^Vrebar_cleaner.beamPK0XJ@µ )»ÍÔ  Xrebar_config.beamPK0XJ@d©;ˆÌP&œ_rebar_core.beamPK0XJ@íHöõ è •vrebar_ct.beamPK0XJ@EsÝß¶´)µƒrebar_deps.beamPK0XJ@Ÿªnï0˜›rebar_edoc.beamPK0XJ@BvDS§< ´žrebar_erlc_compiler.beamPK0XJ@€KNw ¤ ‘±rebar_erlydtl_compiler.beamPK0XJ@»žv`´ Ûºrebar_escripter.beamPK0XJ@rs'@¿<3ªÁrebar_eunit.beamPK0XJ@÷­Zsx —ßrebar_file_utils.beamPK0XJ@ÑQò6GlÊçrebar_lfe_compiler.beamPK0XJ@²†œYTFìrebar_log.beamPK0XJ@Ë"íª Ëðrebar_neotoma_compiler.beamPK0XJ@†LüU@” ®ùrebar_otp_app.beamPK0XJ@3óÜ*rebar_port_compiler.beamPK0XJ@ƒe–›ð Grebar_protobuffs_compiler.beamPK0XJ@&0é ü #rebar_rel_utils.beamPK0XJ@%TЃ^Hl,rebar_reltool.beamPK0XJ@±œd‰Üú;rebar_require_vsn.beamPK0XJ@–h´{×´·?rebar_subdirs.beamPK0XJ@)¨2¾Drebar_templater.beamPK0XJ@HAÆñg ´"Urebar_upgrade.beamPK0XJ@ÐbÝH'̹`rebar_utils.beamPK0XJ@NZ%ú ltrebar_xref.beamPK0XJ@¿…jjD–5priv/templates/basicnif.cPK0XJ@éz›ï°priv/templates/basicnif.erlPK0XJ@ý+¡R‡ „ƒpriv/templates/basicnif.templatePK0XJ@Ȫ8’‚„priv/templates/ctsuite.erlPK0XJ@}Oê­P_c‰priv/templates/ctsuite.templatePK0XJ@ôävÞ ð‰priv/templates/simpleapp.app.srcPK0XJ@¤yE†\Ï!¤Špriv/templates/simpleapp.templatePK0XJ@À­À‰œk ?‹priv/templates/simpleapp_app.erlPK0XJ@‡O³Ì Œpriv/templates/simpleapp_sup.erlPK0XJ@Û"'»ŒÏopriv/templates/simplefsm.erlPK0XJ@¥DŒrFS!5priv/templates/simplefsm.templatePK0XJ@Þùƒ8[nºpriv/templates/simplemod.erlPK0XJ@þ6ÛöV’!Opriv/templates/simplemod.templatePK0XJ@+]çI;D"äpriv/templates/simplemod_tests.erlPK0XJ@DV^$_‘priv/templates/simplenode.erl.scriptPK0XJ@ì,?¯ˆÓ"÷“priv/templates/simplenode.nodetoolPK0XJ@Ó0fLj(¿™priv/templates/simplenode.reltool.configPK0XJ@fê({õ Ì›priv/templates/simplenode.runnerPK0XJ@8&’¬M$ÿ¢priv/templates/simplenode.sys.configPK0XJ@¬d(ÄA"í£priv/templates/simplenode.templatePK0XJ@Wš8±!ñ¤priv/templates/simplenode.vm.argsPK0XJ@ žJûKÀ,h¦priv/templates/simplenode.windows.runner.cmdPK0XJ@­Ò.´Z/ý¨priv/templates/simplenode.windows.start_erl.cmdPK0XJ@“Ù–”\”þªpriv/templates/simplesrv.erlPK0XJ@Zƒ`óJV!”¬priv/templates/simplesrv.templatePK;;N­rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/Makefile0000644000177700017770000000276712633765070030141 0ustar michaelmichaelREBAR=./rebar .PHONY: all clean distclean all: deps $(REBAR) compile deps: $(REBAR) get-deps clean:: $(REBAR) clean rm -rf priv/www distclean:: rm -rf deps priv ebin # **** serve **** .PHONY: serve SERVE_SCRIPT=./examples/cowboy_test_server.erl serve: @if [ -e .pidfile.pid ]; then \ kill `cat .pidfile.pid`; \ rm .pidfile.pid; \ fi @while [ 1 ]; do \ $(REBAR) compile && ( \ echo " [*] Running erlang"; \ $(SERVE_SCRIPT) & \ SRVPID=$$!; \ echo $$SRVPID > .pidfile.pid; \ echo " [*] Pid: $$SRVPID"; \ ); \ inotifywait -r -q -e modify src/*erl examples/*erl src/*hrl; \ test -e .pidfile.pid && kill `cat .pidfile.pid`; \ rm -f .pidfile.pid; \ sleep 0.1; \ done # **** dialyzer **** .dialyzer_generic.plt: dialyzer \ --build_plt \ --output_plt .dialyzer_generic.plt \ --apps erts kernel stdlib compiler sasl os_mon mnesia \ tools public_key crypto ssl .dialyzer_sockjs.plt: .dialyzer_generic.plt dialyzer \ --no_native \ --add_to_plt \ --plt .dialyzer_generic.plt \ --output_plt .dialyzer_sockjs.plt -r deps/*/ebin distclean:: rm -f .dialyzer_sockjs.plt dialyze: .dialyzer_sockjs.plt @dialyzer \ --plt .dialyzer_sockjs.plt \ --no_native \ --fullpath \ -Wrace_conditions \ -Werror_handling \ -Wunmatched_returns \ ebin .PHONY: xref xref: $(REBAR) xref | egrep -v unused # **** release **** # 1. Commit # 2. Bump version in "src/sockjs.app.src" # 3. git tag -s "vx.y.z" -m "Release vx.y.z" rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/Changelog0000644000177700017770000000132712633765070030302 0ustar michaelmichael0.3.4 ===== * #41 - fix a traceback when websocket is too slow or too busy to prompty process incoming and outgoing data * #37 - make porting to new cowboy a tiny bit easier (allow 'method' to be a binary) 0.3.3 ===== * sockjs/sockjs-protocol#56 Fix for iOS 6 caching POSTs 0.3.0 ===== * Fixed {odd_info, heartbeat_triggered} exception (Isaev Ivan) * Changes to pass sockjs-protocol-0.3 * Fixed sockname badmatch (Egobrain) * Updated README * Introduced parametrized module API (to get multiplexer working). * Introduced Multiplexer example. * Fixed invalid catch in sockjs_json:decode (Isaev Ivan) * Bumped Cowboy version. * Specs were moved around to make R13 happy * Dropped milsultin support. rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/examples/0000755000177700017770000000000012633765070030303 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/examples/multiplex/0000755000177700017770000000000012633765070032326 5ustar michaelmichael././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/examples/multiplex/index.htmlrabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/examples/multiplex/index.h0000644000177700017770000000542312633765070033612 0ustar michaelmichael

SockJS Multiplex example

././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/examples/multiplex/multiplex.jsrabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/examples/multiplex/multipl0000644000177700017770000000421212633765070033736 0ustar michaelmichael// **** var DumbEventTarget = function() { this._listeners = {}; }; DumbEventTarget.prototype._ensure = function(type) { if(!(type in this._listeners)) this._listeners[type] = []; }; DumbEventTarget.prototype.addEventListener = function(type, listener) { this._ensure(type); this._listeners[type].push(listener); }; DumbEventTarget.prototype.emit = function(type) { this._ensure(type); var args = Array.prototype.slice.call(arguments, 1); if(this['on' + type]) this['on' + type].apply(this, args); for(var i=0; i < this._listeners[type].length; i++) { this._listeners[type][i].apply(this, args); } }; // **** var MultiplexedWebSocket = function(ws) { var that = this; this.ws = ws; this.channels = {}; this.ws.addEventListener('message', function(e) { var t = e.data.split(','); var type = t.shift(), name = t.shift(), payload = t.join(); if(!(name in that.channels)) { return; } var sub = that.channels[name]; switch(type) { case 'uns': delete that.channels[name]; sub.emit('close', {}); break; case 'msg': sub.emit('message', {data: payload}); break } }); }; MultiplexedWebSocket.prototype.channel = function(raw_name) { return this.channels[escape(raw_name)] = new Channel(this.ws, escape(raw_name), this.channels); }; var Channel = function(ws, name, channels) { DumbEventTarget.call(this); var that = this; this.ws = ws; this.name = name; this.channels = channels; var onopen = function() { that.ws.send('sub,' + that.name); that.emit('open'); }; if(ws.readyState > 0) { setTimeout(onopen, 0); } else { this.ws.addEventListener('open', onopen); } }; Channel.prototype = new DumbEventTarget() Channel.prototype.send = function(data) { this.ws.send('msg,' + this.name + ',' + data); }; Channel.prototype.close = function() { var that = this; this.ws.send('uns,' + this.name); delete this.channels[this.name]; setTimeout(function(){that.emit('close', {})},0); }; ././@LongLink0000644000000000000000000000016200000000000011602 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/examples/multiplex/cowboy_multiplex.erlrabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/examples/multiplex/cowboy_0000755000177700017770000000544512633765070033725 0ustar michaelmichael#!/usr/bin/env escript %%! -smp disable +A1 +K true -pa ebin deps/cowboy/ebin -input -module(cowboy_multiplex). -mode(compile). -export([main/1]). %% Cowboy callbacks -export([init/3, handle/2, terminate/2]). main(_) -> Port = 8081, application:start(sockjs), application:start(cowboy), MultiplexState = sockjs_multiplex:init_state( [{"ann", fun service_ann/3, []}, {"bob", fun service_bob/3, []}, {"carl", fun service_carl/3, []}]), SockjsState = sockjs_handler:init_state( <<"/multiplex">>, sockjs_multiplex, MultiplexState, []), VhostRoutes = [{[<<"multiplex">>, '...'], sockjs_cowboy_handler, SockjsState}, {'_', ?MODULE, []}], Routes = [{'_', VhostRoutes}], % any vhost io:format(" [*] Running at http://localhost:~p~n", [Port]), cowboy:start_listener(http, 100, cowboy_tcp_transport, [{port, Port}], cowboy_http_protocol, [{dispatch, Routes}]), receive _ -> ok end. %% -------------------------------------------------------------------------- init({_Any, http}, Req, []) -> {ok, Req, []}. handle(Req, State) -> {Path, Req1} = cowboy_http_req:path(Req), {ok, Req2} = case Path of [<<"multiplex.js">>] -> {ok, Data} = file:read_file("./examples/multiplex/multiplex.js"), cowboy_http_req:reply(200, [{<<"Content-Type">>, "application/javascript"}], Data, Req1); [] -> {ok, Data} = file:read_file("./examples/multiplex/index.html"), cowboy_http_req:reply(200, [{<<"Content-Type">>, "text/html"}], Data, Req1); _ -> cowboy_http_req:reply(404, [], <<"404 - Nothing here\n">>, Req1) end, {ok, Req2, State}. terminate(_Req, _State) -> ok. %% -------------------------------------------------------------------------- service_ann(Conn, init, State) -> Conn:send("Ann says hi!"), {ok, State}; service_ann(Conn, {recv, Data}, State) -> Conn:send(["Ann nods: ", Data]), {ok, State}; service_ann(_Conn, closed, State) -> {ok, State}. service_bob(Conn, init, State) -> Conn:send("Bob doesn't agree."), {ok, State}; service_bob(Conn, {recv, Data}, State) -> Conn:send(["Bob says no to: ", Data]), {ok, State}; service_bob(_Conn, closed, State) -> {ok, State}. service_carl(Conn, init, State) -> Conn:send("Carl says goodbye!"), Conn:close(), {ok, State}; service_carl(_Conn, _, State) -> {ok, State}. rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/examples/cowboy_echo.erl0000755000177700017770000000274312633765070033320 0ustar michaelmichael#!/usr/bin/env escript %%! -smp disable +A1 +K true -pa ebin deps/cowboy/ebin -input -module(cowboy_echo). -mode(compile). -export([main/1]). %% Cowboy callbacks -export([init/3, handle/2, terminate/2]). main(_) -> Port = 8081, application:start(sockjs), application:start(cowboy), SockjsState = sockjs_handler:init_state( <<"/echo">>, fun service_echo/3, state, []), VhostRoutes = [{[<<"echo">>, '...'], sockjs_cowboy_handler, SockjsState}, {'_', ?MODULE, []}], Routes = [{'_', VhostRoutes}], % any vhost io:format(" [*] Running at http://localhost:~p~n", [Port]), cowboy:start_listener(http, 100, cowboy_tcp_transport, [{port, Port}], cowboy_http_protocol, [{dispatch, Routes}]), receive _ -> ok end. %% -------------------------------------------------------------------------- init({_Any, http}, Req, []) -> {ok, Req, []}. handle(Req, State) -> {ok, Data} = file:read_file("./examples/echo.html"), {ok, Req1} = cowboy_http_req:reply(200, [{<<"Content-Type">>, "text/html"}], Data, Req), {ok, Req1, State}. terminate(_Req, _State) -> ok. %% -------------------------------------------------------------------------- service_echo(_Conn, init, state) -> {ok, state}; service_echo(Conn, {recv, Data}, state) -> Conn:send(Data); service_echo(_Conn, closed, state) -> {ok, state}. ././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/examples/cowboy_test_server.erlrabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/examples/cowboy_test_serve0000755000177700017770000000671112633765070034003 0ustar michaelmichael#!/usr/bin/env escript %%! -smp disable +A1 +K true -pa ebin deps/cowboy/ebin -input -module(cowboy_test_server). -mode(compile). -export([main/1]). %% Cowboy callbacks -export([init/3, handle/2, terminate/2]). main(_) -> Port = 8081, application:start(sockjs), application:start(cowboy), StateEcho = sockjs_handler:init_state( <<"/echo">>, fun service_echo/3, state, [{response_limit, 4096}]), StateClose = sockjs_handler:init_state( <<"/close">>, fun service_close/3, state, []), StateAmplify = sockjs_handler:init_state( <<"/amplify">>, fun service_amplify/3, state, []), StateBroadcast = sockjs_handler:init_state( <<"/broadcast">>, fun service_broadcast/3, state, []), StateDWSEcho = sockjs_handler:init_state( <<"/disabled_websocket_echo">>, fun service_echo/3, state, [{websocket, false}]), StateCNEcho = sockjs_handler:init_state( <<"/cookie_needed_echo">>, fun service_echo/3, state, [{cookie_needed, true}]), VRoutes = [{[<<"echo">>, '...'], sockjs_cowboy_handler, StateEcho}, {[<<"close">>, '...'], sockjs_cowboy_handler, StateClose}, {[<<"amplify">>, '...'], sockjs_cowboy_handler, StateAmplify}, {[<<"broadcast">>, '...'], sockjs_cowboy_handler, StateBroadcast}, {[<<"disabled_websocket_echo">>, '...'], sockjs_cowboy_handler, StateDWSEcho}, {[<<"cookie_needed_echo">>, '...'], sockjs_cowboy_handler, StateCNEcho}, {'_', ?MODULE, []}], Routes = [{'_', VRoutes}], % any vhost io:format(" [*] Running at http://localhost:~p~n", [Port]), cowboy:start_listener(http, 100, cowboy_tcp_transport, [{port, Port}], cowboy_http_protocol, [{dispatch, Routes}]), receive _ -> ok end. %% -------------------------------------------------------------------------- init({_Any, http}, Req, []) -> {ok, Req, []}. handle(Req, State) -> {ok, Req2} = cowboy_http_req:reply(404, [], <<"404 - Nothing here (via sockjs-erlang fallback)\n">>, Req), {ok, Req2, State}. terminate(_Req, _State) -> ok. %% -------------------------------------------------------------------------- service_echo(_Conn, init, state) -> {ok, state}; service_echo(Conn, {recv, Data}, state) -> Conn:send(Data); service_echo(_Conn, closed, state) -> {ok, state}. service_close(Conn, _, _State) -> Conn:close(3000, "Go away!"). service_amplify(Conn, {recv, Data}, _State) -> N0 = list_to_integer(binary_to_list(Data)), N = if N0 > 0 andalso N0 < 19 -> N0; true -> 1 end, Conn:send(list_to_binary( string:copies("x", round(math:pow(2, N))))); service_amplify(_Conn, _, _State) -> ok. service_broadcast(Conn, init, _State) -> case ets:info(broadcast_table, memory) of undefined -> ets:new(broadcast_table, [public, named_table]); _Any -> ok end, true = ets:insert(broadcast_table, {Conn}), ok; service_broadcast(Conn, closed, _State) -> true = ets:delete_object(broadcast_table, {Conn}), ok; service_broadcast(_Conn, {recv, Data}, _State) -> ets:foldl(fun({Conn1}, _Acc) -> Conn1:send(Data) end, [], broadcast_table), ok. rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/examples/echo.html0000644000177700017770000000401712633765070032111 0ustar michaelmichael

SockJS-erlang Echo example

rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/.done0000644000177700017770000000000012633765070027401 0ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/LICENSE-MIT-Mochiweb0000644000177700017770000000207712633765070031662 0ustar michaelmichaelThis is the MIT license. Copyright (c) 2007 Mochi Media, Inc. 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. rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/sockjs-erlang-git/rebar.config0000644000177700017770000000057312633765070030754 0ustar michaelmichael%% -*- erlang -*- %% This is the default `rebar.config` for SockJS-erlang. %% {erl_opts, [ %% fail_on_warning, bin_opt_info, warn_missing_spec, debug_info, warn_export_all ]}. {deps, [ {cowboy, ".*", {git, "git://github.com/extend/cowboy.git", "4fb2a6face6e7d6ff1dd34a02c3bd8b63d972624"}} ]}. rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/CONTRIBUTING.md0000644000177700017770000000424512633765070025400 0ustar michaelmichael## Overview RabbitMQ projects use pull requests to discuss, collaborate on and accept code contributions. Pull requests is the primary place of discussing code changes. ## How to Contribute The process is fairly standard: * Fork the repository or repositories you plan on contributing to * Clone [RabbitMQ umbrella repository](https://github.com/rabbitmq/rabbitmq-public-umbrella) * `cd umbrella`, `make co` * Create a branch with a descriptive name in the relevant repositories * Make your changes, run tests, commit with a [descriptive message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), push to your fork * Submit pull requests with an explanation what has been changed and **why** * Submit a filled out and signed [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) if needed (see below) * Be patient. We will get to your pull request eventually If what you are going to work on is a substantial change, please first ask the core team of their opinion on [RabbitMQ mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). ## (Brief) Code of Conduct In one line: don't be a dick. Be respectful to the maintainers and other contributors. Open source contributors put long hours into developing projects and doing user support. Those projects and user support are available for free. We believe this deserves some respect. Be respectful to people of all races, genders, religious beliefs and political views. Regardless of how brilliant a pull request is technically, we will not tolerate disrespectful or aggressive behaviour. Contributors who violate this straightforward Code of Conduct will see their pull requests closed and locked. ## Contributor Agreement If you want to contribute a non-trivial change, please submit a signed copy of our [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) around the time you submit your pull request. This will make it much easier (in some cases, possible) for the RabbitMQ team at Pivotal to merge your contribution. ## Where to Ask Questions If something isn't clear, feel free to ask on our [mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/0003-websocket-subprotocol0000644000177700017770000001002112633765070027776 0ustar michaelmichaeldiff --git a/src/sockjs_cowboy_handler.erl b/src/sockjs_cowboy_handler.erl index 3b1ffe3..d2f05ae 100644 --- a/src/sockjs_cowboy_handler.erl +++ b/src/sockjs_cowboy_handler.erl @@ -30,21 +30,35 @@ terminate(_Req, _Service) -> %% -------------------------------------------------------------------------- -websocket_init(_TransportName, Req, Service = #service{logger = Logger}) -> - Req0 = Logger(Service, {cowboy, Req}, websocket), +websocket_init(_TransportName, Req, + Service = #service{logger = Logger, + subproto_pref = SubProtocolPref}) -> + Req3 = case cowboy_http_req:header(<<"Sec-Websocket-Protocol">>, Req) of + {undefined, Req1} -> + Req1; + {SubProtocols, Req1} -> + SelectedSubProtocol = + choose_subprotocol_bin(SubProtocols, SubProtocolPref), + {ok, Req2} = cowboy_http_req:set_resp_header( + <<"Sec-Websocket-Protocol">>, + SelectedSubProtocol, Req1), + Req2 + end, + + Req4 = Logger(Service, {cowboy, Req3}, websocket), Service1 = Service#service{disconnect_delay = 5*60*1000}, - {Info, Req1} = sockjs_handler:extract_info(Req0), + {Info, Req5} = sockjs_handler:extract_info(Req4), SessionPid = sockjs_session:maybe_create(undefined, Service1, Info), - {RawWebsocket, {cowboy, Req3}} = - case sockjs_handler:get_action(Service, Req1) of - {{match, WS}, Req2} when WS =:= websocket orelse + {RawWebsocket, {cowboy, Req7}} = + case sockjs_handler:get_action(Service, Req5) of + {{match, WS}, Req6} when WS =:= websocket orelse WS =:= rawwebsocket -> - {WS, Req2} + {WS, Req6} end, self() ! go, - {ok, Req3, {RawWebsocket, SessionPid}}. + {ok, Req7, {RawWebsocket, SessionPid}}. websocket_handle({text, Data}, Req, {RawWebsocket, SessionPid} = S) -> case sockjs_ws_handler:received(RawWebsocket, SessionPid, Data) of @@ -69,3 +83,15 @@ websocket_info(shutdown, Req, S) -> websocket_terminate(_Reason, _Req, {RawWebsocket, SessionPid}) -> sockjs_ws_handler:close(RawWebsocket, SessionPid), ok. + +%% -------------------------------------------------------------------------- + +choose_subprotocol_bin(SubProtocols, Pref) -> + choose_subprotocol(re:split(SubProtocols, ", *"), Pref). +choose_subprotocol(SubProtocols, undefined) -> + erlang:hd(lists:reverse(lists:sort(SubProtocols))); +choose_subprotocol(SubProtocols, Pref) -> + case lists:filter(fun (E) -> lists:member(E, SubProtocols) end, Pref) of + [Hd | _] -> Hd; + [] -> choose_subprotocol(SubProtocols, undefined) + end. diff --git a/src/sockjs_handler.erl b/src/sockjs_handler.erl index b706453..81d4ef7 100644 --- a/src/sockjs_handler.erl +++ b/src/sockjs_handler.erl @@ -29,7 +29,9 @@ init_state(Prefix, Callback, State, Options) -> response_limit = proplists:get_value(response_limit, Options, 128*1024), logger = - proplists:get_value(logger, Options, fun default_logger/3) + proplists:get_value(logger, Options, fun default_logger/3), + subproto_pref = + proplists:get_value(subproto_pref, Options) }. %% -------------------------------------------------------------------------- diff --git a/src/sockjs_internal.hrl b/src/sockjs_internal.hrl index 629b2fe..eed5597 100644 --- a/src/sockjs_internal.hrl +++ b/src/sockjs_internal.hrl @@ -15,7 +15,8 @@ disconnect_delay , %% non_neg_integer() heartbeat_delay , %% non_neg_integer() response_limit , %% non_neg_integer() - logger %% logger() + logger , %% logger() + subproto_pref %% [binary()] }). %% -type(service() :: #service{}). rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/.srcdist_done0000644000177700017770000000000012633765070025611 0ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/hash.mk0000644000177700017770000000003512633765070024414 0ustar michaelmichaelUPSTREAM_SHORT_HASH:=3132eb9 rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/Makefile0000644000177700017770000000002712633765070024601 0ustar michaelmichaelinclude ../umbrella.mk rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/package.mk0000644000177700017770000000130212633765070025062 0ustar michaelmichaelAPP_NAME:=sockjs DEPS:=cowboy-wrapper UPSTREAM_GIT:=https://github.com/rabbitmq/sockjs-erlang.git UPSTREAM_REVISION:=3132eb920aea9abd5c5e65349331c32d8cfa961e # 0.3.4 RETAIN_ORIGINAL_VERSION:=true WRAPPER_PATCHES:=\ 0000-remove-spec-patch.diff \ 0001-a2b-b2a.diff \ 0002-parameterised-modules-r16a.diff \ 0003-websocket-subprotocol ORIGINAL_APP_FILE:=$(CLONE_DIR)/src/$(APP_NAME).app.src DO_NOT_GENERATE_APP_FILE=true ERLC_OPTS:=$(ERLC_OPTS) -D no_specs define construct_app_commands cp $(CLONE_DIR)/LICENSE-* $(APP_DIR) rm $(APP_DIR)/ebin/pmod_pt.beam endef define package_rules $(CLONE_DIR)/ebin/sockjs_multiplex_channel.beam: $(CLONE_DIR)/ebin/pmod_pt.beam endef rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/0002-parameterised-modules-r16a.diff0000644000177700017770000003433012633765070031420 0ustar michaelmichaeldiff --git a/src/pmod_pt.erl b/src/pmod_pt.erl new file mode 100644 index 0000000..db21974 --- /dev/null +++ b/src/pmod_pt.erl @@ -0,0 +1,461 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2013. 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(pmod_pt). +-export([parse_transform/2, + format_error/1]). + +%% Expand function definition forms of parameterized module. +%% The code is based on the code in sys_expand_pmod which used to be +%% included in the compiler, but details are different because +%% sys_pre_expand has not been run. In particular: +%% +%% * Record definitions are still present and must be handled. +%% +%% * (Syntatic) local calls may actually be calls to an imported +%% funtion or a BIF. It is a local call if and only if there +%% is a definition for the function in the module. +%% +%% * When we introduce the module parameters and 'THIS' in each +%% function, we must artificially use it to avoid a warning for +%% unused variables. +%% +%% * On the other hand, we don't have to worry about module_info/0,1 +%% because they have not been added yet. + +-record(pmod, {parameters, + defined + }). + +parse_transform(Forms0, _Options) -> + put(?MODULE, []), + Forms = transform(Forms0), + case erase(?MODULE) of + [] -> + Forms; + [_|_]=Errors -> + File = get_file(Forms), + {error,[{File,Errors}],[]} + end. + +format_error(extends_self) -> + "cannot extend from self"; +format_error(define_instance) -> + "defining instance function not allowed in parameterized module". + +add_error(Line, Error) -> + put(?MODULE, get(?MODULE) ++ [{Line,?MODULE,Error}]). + +get_file([{attribute,_,file,{File,_}}|_]) -> File; +get_file([_|T]) -> get_file(T). + +transform(Forms0) -> + Def = collect_defined(Forms0), + {Base,ModAs,Forms1} = attribs(Forms0, [], undefined, []), + {Mod,Ps0} = case ModAs of + {M0,P0} -> {M0,P0}; + M0 -> {M0,undefined} + end, + Forms2 = case Ps0 of + undefined -> + Forms1; + _ -> + pmod_expand(Forms1, Mod, Base, Ps0, Def) + end, + + %% Add new functions. + NewFs0 = maybe_extend(Base, Mod, Ps0), + NewExps = collect_defined(NewFs0), + Forms3 = add_attributes(Forms2, [{attribute,0,export,NewExps}]), + add_new_funcs(Forms3, NewFs0). + +pmod_expand(Forms0, Mod, Base, Ps0, Def) -> + Ps = if is_atom(Base) -> + ['BASE' | Ps0]; + true -> + Ps0 + end, + St0 = #pmod{parameters=Ps,defined=gb_sets:from_list(Def)}, + {Forms1,_} = forms(Forms0, St0), + Forms2 = update_exps(Forms1), + Forms3 = update_forms(Forms2), + NewFs0 = add_instance(Mod, Ps, []), + NewFs = ensure_new(Base, Ps0, NewFs0), + Forms = add_new_funcs(Forms3, NewFs), + NewExps = collect_defined(NewFs), + add_attributes(Forms, [{attribute,0,export,NewExps}]). + +add_attributes([{attribute,_,module,_}=F|Fs], Attrs) -> + [F|Attrs++Fs]; +add_attributes([F|Fs], Attrs) -> + [F|add_attributes(Fs, Attrs)]. + +add_new_funcs([{eof,_}|_]=Fs, NewFs) -> + NewFs ++ Fs; +add_new_funcs([F|Fs], Es) -> + [F|add_new_funcs(Fs, Es)]. + +maybe_extend([], _, _) -> + %% No 'extends' attribute. + []; +maybe_extend(Base, _Mod, undefined) -> + %% There is a an 'extends' attribute; the module is not parameterized. + Name = '$handle_undefined_function', + Args = [{var,0,'Func'},{var,0,'Args'}], + Body = [make_apply({atom,0,Base}, {var,0,'Func'}, {var,0,'Args'})], + F = {function,0,Name,2,[{clause,0,Args,[],Body}]}, + [F]; +maybe_extend(Base, Mod, Ps) -> + %% There is a an 'extends' attribute; the module is parameterized. + Name = '$handle_undefined_function', + Args = [{var,0,'Func'},{var,0,'Args'}], + DontCares = [{var,0,'_'} || _ <- Ps], + TuplePs = {tuple,0,[{atom,0,Mod},{var,0,'BaseVars'}|DontCares]}, + G = [{call,0,{atom,0,is_atom}, + [{call,0,{atom,0,element}, + [{integer,0,1},{var,0,'BaseVars'}]}]}], + FixedArgs = make_lists_rev([{var,0,'Rs'}, + {cons,0,{var,0,'BaseVars'},{nil,0}}]), + Body = [{'case',0,make_lists_rev([{var,0,'Args'}]), + [{clause,0,[{cons,0,TuplePs,{var,0,'Rs'}}],[G], + [make_apply({atom,0,Base}, {var,0,'Func'}, FixedArgs)]}, + {clause,0,[{var,0,'_'}],[], + [make_apply({atom,0,Base}, {var,0,'Func'}, {var,0,'Args'})]} + ]}], + F = {function,0,Name,2,[{clause,0,Args,[],Body}]}, + [F]. + +make_apply(M, F, A) -> + {call,0,{remote,0,{atom,0,erlang},{atom,0,apply}},[M,F,A]}. + +make_lists_rev(As) -> + {call,0,{remote,0,{atom,0,lists},{atom,0,reverse}},As}. + +ensure_new(Base, Ps, Fs) -> + case has_new(Fs) of + true -> + Fs; + false -> + add_new(Base, Ps, Fs) + end. + +has_new([{function,_L,new,_A,_Cs} | _Fs]) -> + true; +has_new([_ | Fs]) -> + has_new(Fs); +has_new([]) -> + false. + +add_new(Base, Ps, Fs) -> + Vs = [{var,0,V} || V <- Ps], + As = if is_atom(Base) -> + [{call,0,{remote,0,{atom,0,Base},{atom,0,new}},Vs} | Vs]; + true -> + Vs + end, + Body = [{call,0,{atom,0,instance},As}], + add_func(new, Vs, Body, Fs). + +add_instance(Mod, Ps, Fs) -> + Vs = [{var,0,V} || V <- Ps], + AbsMod = [{tuple,0,[{atom,0,Mod}|Vs]}], + add_func(instance, Vs, AbsMod, Fs). + +add_func(Name, Args, Body, Fs) -> + A = length(Args), + F = {function,0,Name,A,[{clause,0,Args,[],Body}]}, + [F|Fs]. + +collect_defined(Fs) -> + [{N,A} || {function,_,N,A,_} <- Fs]. + +attribs([{attribute,Line,module,{Mod,_}=ModAs}|T], Base, _, Acc) -> + attribs(T, Base, ModAs, [{attribute,Line,module,Mod}|Acc]); +attribs([{attribute,_,module,Mod}=H|T], Base, _, Acc) -> + attribs(T, Base, Mod, [H|Acc]); +attribs([{attribute,Line,extends,Base}|T], Base0, Ps, Acc) when is_atom(Base) -> + Mod = case Ps of + {Mod0,_} -> Mod0; + Mod0 -> Mod0 + end, + case Mod of + Base -> + add_error(Line, extends_self), + attribs(T, Base0, Ps, Acc); + _ -> + attribs(T, Base, Ps, Acc) + end; +attribs([H|T], Base, Ps, Acc) -> + attribs(T, Base, Ps, [H|Acc]); +attribs([], Base, Ps, Acc) -> + {Base,Ps,lists:reverse(Acc)}. + +%% This is extremely simplistic for now; all functions get an extra +%% parameter, whether they need it or not, except for static functions. + +update_function_name({F,A}) when F =/= new -> + {F,A+1}; +update_function_name(E) -> + E. + +update_forms([{function,L,N,A,Cs}|Fs]) when N =/= new -> + [{function,L,N,A+1,Cs}|update_forms(Fs)]; +update_forms([F|Fs]) -> + [F|update_forms(Fs)]; +update_forms([]) -> + []. + +update_exps([{attribute,Line,export,Es0}|T]) -> + Es = [update_function_name(E) || E <- Es0], + [{attribute,Line,export,Es}|update_exps(T)]; +update_exps([H|T]) -> + [H|update_exps(T)]; +update_exps([]) -> + []. + +%% Process the program forms. + +forms([F0|Fs0],St0) -> + {F1,St1} = form(F0,St0), + {Fs1,St2} = forms(Fs0,St1), + {[F1|Fs1],St2}; +forms([], St0) -> + {[], St0}. + +%% Only function definitions are of interest here. State is not updated. +form({function,Line,instance,_Arity,_Clauses}=F,St) -> + add_error(Line, define_instance), + {F,St}; +form({function,Line,Name0,Arity0,Clauses0},St) when Name0 =/= new -> + {Name,Arity,Clauses} = function(Name0, Arity0, Clauses0, St), + {{function,Line,Name,Arity,Clauses},St}; +%% Pass anything else through +form(F,St) -> {F,St}. + +function(Name, Arity, Clauses0, St) -> + Clauses1 = clauses(Clauses0,St), + {Name,Arity,Clauses1}. + +clauses([C|Cs],#pmod{parameters=Ps}=St) -> + {clause,L,H,G,B0} = clause(C,St), + T = {tuple,L,[{var,L,V} || V <- ['_'|Ps]]}, + B = [{match,L,{var,L,'_'},{var,L,V}} || V <- ['THIS'|Ps]] ++ B0, + [{clause,L,H++[{match,L,T,{var,L,'THIS'}}],G,B}|clauses(Cs,St)]; +clauses([],_St) -> []. + +clause({clause,Line,H,G,B0},St) -> + %% We never update H and G, so we will just copy them. + B1 = exprs(B0,St), + {clause,Line,H,G,B1}. + +pattern_grp([{bin_element,L1,E1,S1,T1} | Fs],St) -> + S2 = case S1 of + default -> + default; + _ -> + expr(S1,St) + end, + T2 = case T1 of + default -> + default; + _ -> + bit_types(T1) + end, + [{bin_element,L1,expr(E1,St),S2,T2} | pattern_grp(Fs,St)]; +pattern_grp([],_St) -> + []. + +bit_types([]) -> + []; +bit_types([Atom | Rest]) when is_atom(Atom) -> + [Atom | bit_types(Rest)]; +bit_types([{Atom, Integer} | Rest]) when is_atom(Atom), is_integer(Integer) -> + [{Atom, Integer} | bit_types(Rest)]. + +exprs([E0|Es],St) -> + E1 = expr(E0,St), + [E1|exprs(Es,St)]; +exprs([],_St) -> []. + +expr({var,_L,_V}=Var,_St) -> + Var; +expr({integer,_Line,_I}=Integer,_St) -> Integer; +expr({float,_Line,_F}=Float,_St) -> Float; +expr({atom,_Line,_A}=Atom,_St) -> Atom; +expr({string,_Line,_S}=String,_St) -> String; +expr({char,_Line,_C}=Char,_St) -> Char; +expr({nil,_Line}=Nil,_St) -> Nil; +expr({cons,Line,H0,T0},St) -> + H1 = expr(H0,St), + T1 = expr(T0,St), + {cons,Line,H1,T1}; +expr({lc,Line,E0,Qs0},St) -> + Qs1 = lc_bc_quals(Qs0,St), + E1 = expr(E0,St), + {lc,Line,E1,Qs1}; +expr({bc,Line,E0,Qs0},St) -> + Qs1 = lc_bc_quals(Qs0,St), + E1 = expr(E0,St), + {bc,Line,E1,Qs1}; +expr({tuple,Line,Es0},St) -> + Es1 = expr_list(Es0,St), + {tuple,Line,Es1}; +expr({record,Line,Name,Is0},St) -> + Is = record_fields(Is0,St), + {record,Line,Name,Is}; +expr({record,Line,E0,Name,Is0},St) -> + E = expr(E0,St), + Is = record_fields(Is0,St), + {record,Line,E,Name,Is}; +expr({record_field,Line,E0,Name,Key},St) -> + E = expr(E0,St), + {record_field,Line,E,Name,Key}; +expr({block,Line,Es0},St) -> + Es1 = exprs(Es0,St), + {block,Line,Es1}; +expr({'if',Line,Cs0},St) -> + Cs1 = icr_clauses(Cs0,St), + {'if',Line,Cs1}; +expr({'case',Line,E0,Cs0},St) -> + E1 = expr(E0,St), + Cs1 = icr_clauses(Cs0,St), + {'case',Line,E1,Cs1}; +expr({'receive',Line,Cs0},St) -> + Cs1 = icr_clauses(Cs0,St), + {'receive',Line,Cs1}; +expr({'receive',Line,Cs0,To0,ToEs0},St) -> + To1 = expr(To0,St), + ToEs1 = exprs(ToEs0,St), + Cs1 = icr_clauses(Cs0,St), + {'receive',Line,Cs1,To1,ToEs1}; +expr({'try',Line,Es0,Scs0,Ccs0,As0},St) -> + Es1 = exprs(Es0,St), + Scs1 = icr_clauses(Scs0,St), + Ccs1 = icr_clauses(Ccs0,St), + As1 = exprs(As0,St), + {'try',Line,Es1,Scs1,Ccs1,As1}; +expr({'fun',_,{function,_,_,_}}=ExtFun,_St) -> + ExtFun; +expr({'fun',Line,Body},St) -> + case Body of + {clauses,Cs0} -> + Cs1 = fun_clauses(Cs0,St), + {'fun',Line,{clauses,Cs1}}; + {function,F,A} = Function -> + {F1,A1} = update_function_name({F,A}), + if A1 =:= A -> + {'fun',Line,Function}; + true -> + %% Must rewrite local fun-name to a fun that does a + %% call with the extra THIS parameter. + As = make_vars(A, Line), + As1 = As ++ [{var,Line,'THIS'}], + Call = {call,Line,{atom,Line,F1},As1}, + Cs = [{clause,Line,As,[],[Call]}], + {'fun',Line,{clauses,Cs}} + end; + {function,_M,_F,_A} = Fun4 -> %This is an error in lint! + {'fun',Line,Fun4} + end; +expr({call,Lc,{atom,_,instance}=Name,As0},St) -> + %% All local functions 'instance(...)' are static by definition, + %% so they do not take a 'THIS' argument when called + As1 = expr_list(As0,St), + {call,Lc,Name,As1}; +expr({call,Lc,{atom,_,new}=Name,As0},St) -> + %% All local functions 'new(...)' are static by definition, + %% so they do not take a 'THIS' argument when called + As1 = expr_list(As0,St), + {call,Lc,Name,As1}; +expr({call,Lc,{atom,_Lf,F}=Atom,As0}, #pmod{defined=Def}=St) -> + As1 = expr_list(As0,St), + case gb_sets:is_member({F,length(As0)}, Def) of + false -> + %% BIF or imported function. + {call,Lc,Atom,As1}; + true -> + %% Local function call - needs THIS parameter. + {call,Lc,Atom,As1 ++ [{var,0,'THIS'}]} + end; +expr({call,Line,F0,As0},St) -> + %% Other function call + F1 = expr(F0,St), + As1 = expr_list(As0,St), + {call,Line,F1,As1}; +expr({'catch',Line,E0},St) -> + E1 = expr(E0,St), + {'catch',Line,E1}; +expr({match,Line,P,E0},St) -> + E1 = expr(E0,St), + {match,Line,P,E1}; +expr({bin,Line,Fs},St) -> + Fs2 = pattern_grp(Fs,St), + {bin,Line,Fs2}; +expr({op,Line,Op,A0},St) -> + A1 = expr(A0,St), + {op,Line,Op,A1}; +expr({op,Line,Op,L0,R0},St) -> + L1 = expr(L0,St), + R1 = expr(R0,St), + {op,Line,Op,L1,R1}; +%% The following are not allowed to occur anywhere! +expr({remote,Line,M0,F0},St) -> + M1 = expr(M0,St), + F1 = expr(F0,St), + {remote,Line,M1,F1}. + +expr_list([E0|Es],St) -> + E1 = expr(E0,St), + [E1|expr_list(Es,St)]; +expr_list([],_St) -> []. + +record_fields([{record_field,L,K,E0}|T],St) -> + E = expr(E0,St), + [{record_field,L,K,E}|record_fields(T,St)]; +record_fields([],_) -> []. + +icr_clauses([C0|Cs],St) -> + C1 = clause(C0,St), + [C1|icr_clauses(Cs,St)]; +icr_clauses([],_St) -> []. + +lc_bc_quals([{generate,Line,P,E0}|Qs],St) -> + E1 = expr(E0,St), + [{generate,Line,P,E1}|lc_bc_quals(Qs,St)]; +lc_bc_quals([{b_generate,Line,P,E0}|Qs],St) -> + E1 = expr(E0,St), + [{b_generate,Line,P,E1}|lc_bc_quals(Qs,St)]; +lc_bc_quals([E0|Qs],St) -> + E1 = expr(E0,St), + [E1|lc_bc_quals(Qs,St)]; +lc_bc_quals([],_St) -> []. + +fun_clauses([C0|Cs],St) -> + C1 = clause(C0,St), + [C1|fun_clauses(Cs,St)]; +fun_clauses([],_St) -> []. + +make_vars(N, L) -> + make_vars(1, N, L). + +make_vars(N, M, L) when N =< M -> + V = list_to_atom("X"++integer_to_list(N)), + [{var,L,V} | make_vars(N + 1, M, L)]; +make_vars(_, _, _) -> + []. diff --git a/src/sockjs_multiplex_channel.erl b/src/sockjs_multiplex_channel.erl index cbb8274..5afcfa3 100644 --- a/src/sockjs_multiplex_channel.erl +++ b/src/sockjs_multiplex_channel.erl @@ -1,3 +1,5 @@ +-compile({parse_transform,pmod_pt}). + -module(sockjs_multiplex_channel, [Conn, Topic]). -export([send/1, close/0, close/2, info/0]). rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/0000-remove-spec-patch.diff0000644000177700017770000010055112633765070027675 0ustar michaelmichaeldiff --git a/src/mochijson2_fork.erl b/src/mochijson2_fork.erl index 355f068..a088d9d 100644 --- a/src/mochijson2_fork.erl +++ b/src/mochijson2_fork.erl @@ -91,17 +91,17 @@ -define(IS_WHITESPACE(C), (C =:= $\s orelse C =:= $\t orelse C =:= $\r orelse C =:= $\n)). --type(decoder_option() :: any()). --type(handler_option() :: any()). - --type(json_string() :: atom | binary()). --type(json_number() :: integer() | float()). --type(json_array() :: [json_term()]). --type(json_object() :: {struct, [{json_string(), json_term()}]}). --type(json_eep18_object() :: {[{json_string(), json_term()}]}). --type(json_iolist() :: {json, iolist()}). --type(json_term() :: json_string() | json_number() | json_array() | - json_object() | json_eep18_object() | json_iolist()). +%% -type(decoder_option() :: any()). +%% -type(handler_option() :: any()). + +%% -type(json_string() :: atom | binary()). +%% -type(json_number() :: integer() | float()). +%% -type(json_array() :: [json_term()]). +%% -type(json_object() :: {struct, [{json_string(), json_term()}]}). +%% -type(json_eep18_object() :: {[{json_string(), json_term()}]}). +%% -type(json_iolist() :: {json, iolist()}). +%% -type(json_term() :: json_string() | json_number() | json_array() | +%% json_object() | json_eep18_object() | json_iolist()). -record(encoder, {handler=null, utf8=false}). @@ -112,27 +112,27 @@ column=1, state=null}). --type(utf8_option() :: boolean()). --type(encoder_option() :: handler_option() | utf8_option()). --spec encoder([encoder_option()]) -> function(). +%% -type(utf8_option() :: boolean()). +%% -type(encoder_option() :: handler_option() | utf8_option()). +%% -spec encoder([encoder_option()]) -> function(). %% @doc Create an encoder/1 with the given options. %% Emit unicode as utf8 (default - false) encoder(Options) -> State = parse_encoder_options(Options, #encoder{}), fun (O) -> json_encode(O, State) end. --spec encode(json_term()) -> iolist(). +%% -spec encode(json_term()) -> iolist(). %% @doc Encode the given as JSON to an iolist. encode(Any) -> json_encode(Any, #encoder{}). --spec decoder([decoder_option()]) -> function(). +%% -spec decoder([decoder_option()]) -> function(). %% @doc Create a decoder/1 with the given options. decoder(Options) -> State = parse_decoder_options(Options, #decoder{}), fun (O) -> json_decode(O, State) end. --spec decode(iolist(), [{format, proplist | eep18 | struct}]) -> json_term(). +%% -spec decode(iolist(), [{format, proplist | eep18 | struct}]) -> json_term(). %% @doc Decode the given iolist to Erlang terms using the given object format %% for decoding, where proplist returns JSON objects as [{binary(), json_term()}] %% proplists, eep18 returns JSON objects as {[binary(), json_term()]}, and struct @@ -140,7 +140,7 @@ decoder(Options) -> decode(S, Options) -> json_decode(S, parse_decoder_options(Options, #decoder{})). --spec decode(iolist()) -> json_term(). +%% -spec decode(iolist()) -> json_term(). %% @doc Decode the given iolist to Erlang terms. decode(S) -> json_decode(S, #decoder{}). diff --git a/src/sockjs.erl b/src/sockjs.erl index 68163ca..98b1173 100644 --- a/src/sockjs.erl +++ b/src/sockjs.erl @@ -2,23 +2,23 @@ -export([send/2, close/1, close/3, info/1]). --type(conn() :: {sockjs_session, any()}). +%% -type(conn() :: {sockjs_session, any()}). %% Send data over a connection. --spec send(iodata(), conn()) -> ok. +%% -spec send(iodata(), conn()) -> ok. send(Data, Conn = {sockjs_session, _}) -> sockjs_session:send(Data, Conn). %% Initiate a close of a connection. --spec close(conn()) -> ok. +%% -spec close(conn()) -> ok. close(Conn) -> close(1000, "Normal closure", Conn). --spec close(non_neg_integer(), string(), conn()) -> ok. +%% -spec close(non_neg_integer(), string(), conn()) -> ok. close(Code, Reason, Conn = {sockjs_session, _}) -> sockjs_session:close(Code, Reason, Conn). --spec info(conn()) -> [{atom(), any()}]. +%% -spec info(conn()) -> [{atom(), any()}]. info(Conn = {sockjs_session, _}) -> sockjs_session:info(Conn). diff --git a/src/sockjs_action.erl b/src/sockjs_action.erl index 3f13beb..4310963 100644 --- a/src/sockjs_action.erl +++ b/src/sockjs_action.erl @@ -45,17 +45,17 @@ %% -------------------------------------------------------------------------- --spec welcome_screen(req(), headers(), service()) -> req(). +%% -spec welcome_screen(req(), headers(), service()) -> req(). welcome_screen(Req, Headers, _Service) -> H = [{"Content-Type", "text/plain; charset=UTF-8"}], sockjs_http:reply(200, H ++ Headers, "Welcome to SockJS!\n", Req). --spec options(req(), headers(), service()) -> req(). +%% -spec options(req(), headers(), service()) -> req(). options(Req, Headers, _Service) -> sockjs_http:reply(204, Headers, "", Req). --spec iframe(req(), headers(), service()) -> req(). +%% -spec iframe(req(), headers(), service()) -> req(). iframe(Req, Headers, #service{sockjs_url = SockjsUrl}) -> IFrame = io_lib:format(?IFRAME, [SockjsUrl]), MD5 = "\"" ++ binary_to_list(base64:encode(erlang:md5(IFrame))) ++ "\"", @@ -68,7 +68,7 @@ iframe(Req, Headers, #service{sockjs_url = SockjsUrl}) -> end. --spec info_test(req(), headers(), service()) -> req(). +%% -spec info_test(req(), headers(), service()) -> req(). info_test(Req, Headers, #service{websocket = Websocket, cookie_needed = CookieNeeded}) -> I = [{websocket, Websocket}, @@ -81,12 +81,12 @@ info_test(Req, Headers, #service{websocket = Websocket, %% -------------------------------------------------------------------------- --spec xhr_polling(req(), headers(), service(), session()) -> req(). +%% -spec xhr_polling(req(), headers(), service(), session()) -> req(). xhr_polling(Req, Headers, Service, Session) -> Req1 = chunk_start(Req, Headers), reply_loop(Req1, Session, 1, fun fmt_xhr/1, Service). --spec xhr_streaming(req(), headers(), service(), session()) -> req(). +%% -spec xhr_streaming(req(), headers(), service(), session()) -> req(). xhr_streaming(Req, Headers, Service = #service{response_limit = ResponseLimit}, Session) -> Req1 = chunk_start(Req, Headers), @@ -96,7 +96,7 @@ xhr_streaming(Req, Headers, Service = #service{response_limit = ResponseLimit}, fun fmt_xhr/1), reply_loop(Req2, Session, ResponseLimit, fun fmt_xhr/1, Service). --spec eventsource(req(), headers(), service(), session()) -> req(). +%% -spec eventsource(req(), headers(), service(), session()) -> req(). eventsource(Req, Headers, Service = #service{response_limit = ResponseLimit}, SessionId) -> Req1 = chunk_start(Req, Headers, "text/event-stream; charset=UTF-8"), @@ -104,7 +104,7 @@ eventsource(Req, Headers, Service = #service{response_limit = ResponseLimit}, reply_loop(Req2, SessionId, ResponseLimit, fun fmt_eventsource/1, Service). --spec htmlfile(req(), headers(), service(), session()) -> req(). +%% -spec htmlfile(req(), headers(), service(), session()) -> req(). htmlfile(Req, Headers, Service = #service{response_limit = ResponseLimit}, SessionId) -> S = fun (Req1, CB) -> @@ -119,7 +119,7 @@ htmlfile(Req, Headers, Service = #service{response_limit = ResponseLimit}, end, verify_callback(Req, S). --spec jsonp(req(), headers(), service(), session()) -> req(). +%% -spec jsonp(req(), headers(), service(), session()) -> req(). jsonp(Req, Headers, Service, SessionId) -> S = fun (Req1, CB) -> Req2 = chunk_start(Req1, Headers), @@ -139,7 +139,7 @@ verify_callback(Req, Success) -> %% -------------------------------------------------------------------------- --spec xhr_send(req(), headers(), service(), session()) -> req(). +%% -spec xhr_send(req(), headers(), service(), session()) -> req(). xhr_send(Req, Headers, _Service, Session) -> {Body, Req1} = sockjs_http:body(Req), case handle_recv(Req1, Body, Session) of @@ -150,7 +150,7 @@ xhr_send(Req, Headers, _Service, Session) -> sockjs_http:reply(204, H ++ Headers, "", Req1) end. --spec jsonp_send(req(), headers(), service(), session()) -> req(). +%% -spec jsonp_send(req(), headers(), service(), session()) -> req(). jsonp_send(Req, Headers, _Service, Session) -> {Body, Req1} = sockjs_http:body_qs(Req), case handle_recv(Req1, Body, Session) of @@ -236,21 +236,21 @@ chunk_end(Req) -> sockjs_http:chunk_end(Req). chunk_end(Req, Body, Fmt) -> Req1 = chunk(Req, Body, Fmt), chunk_end(Req1). --spec fmt_xhr(iodata()) -> iodata(). +%% -spec fmt_xhr(iodata()) -> iodata(). fmt_xhr(Body) -> [Body, "\n"]. --spec fmt_eventsource(iodata()) -> iodata(). +%% -spec fmt_eventsource(iodata()) -> iodata(). fmt_eventsource(Body) -> Escaped = sockjs_util:url_escape(binary_to_list(iolist_to_binary(Body)), "%\r\n\0"), %% $% must be first! [<<"data: ">>, Escaped, <<"\r\n\r\n">>]. --spec fmt_htmlfile(iodata()) -> iodata(). +%% -spec fmt_htmlfile(iodata()) -> iodata(). fmt_htmlfile(Body) -> Double = sockjs_json:encode(iolist_to_binary(Body)), [<<"\r\n">>]. --spec fmt_jsonp(iodata(), iodata()) -> iodata(). +%% -spec fmt_jsonp(iodata(), iodata()) -> iodata(). fmt_jsonp(Body, Callback) -> %% Yes, JSONed twice, there isn't a a better way, we must pass %% a string back, and the script, will be evaled() by the @@ -259,7 +259,7 @@ fmt_jsonp(Body, Callback) -> %% -------------------------------------------------------------------------- --spec websocket(req(), headers(), service()) -> req(). +%% -spec websocket(req(), headers(), service()) -> req(). websocket(Req, Headers, Service) -> {_Any, Req1, {R1, R2}} = sockjs_handler:is_valid_ws(Service, Req), case {R1, R2} of @@ -274,6 +274,6 @@ websocket(Req, Headers, Service) -> "This WebSocket request can't be handled.", Req1) end. --spec rawwebsocket(req(), headers(), service()) -> req(). +%% -spec rawwebsocket(req(), headers(), service()) -> req(). rawwebsocket(Req, Headers, Service) -> websocket(Req, Headers, Service). diff --git a/src/sockjs_app.erl b/src/sockjs_app.erl index 1b8e77c..54aceb6 100644 --- a/src/sockjs_app.erl +++ b/src/sockjs_app.erl @@ -4,11 +4,11 @@ -export([start/2, stop/1]). --spec start(_, _) -> {ok, pid()}. +%% -spec start(_, _) -> {ok, pid()}. start(_StartType, _StartArgs) -> sockjs_session:init(), sockjs_session_sup:start_link(). --spec stop(_) -> ok. +%% -spec stop(_) -> ok. stop(_State) -> ok. diff --git a/src/sockjs_filters.erl b/src/sockjs_filters.erl index 15aa8e3..fba43cc 100644 --- a/src/sockjs_filters.erl +++ b/src/sockjs_filters.erl @@ -9,7 +9,7 @@ %% -------------------------------------------------------------------------- --spec cache_for(req(), headers()) -> {headers(), req()}. +%% -spec cache_for(req(), headers()) -> {headers(), req()}. cache_for(Req, Headers) -> Expires = calendar:gregorian_seconds_to_datetime( calendar:datetime_to_gregorian_seconds( @@ -18,7 +18,7 @@ cache_for(Req, Headers) -> {"Expires", httpd_util:rfc1123_date(Expires)}], {H ++ Headers, Req}. --spec h_sid(req(), headers()) -> {headers(), req()}. +%% -spec h_sid(req(), headers()) -> {headers(), req()}. h_sid(Req, Headers) -> %% Some load balancers do sticky sessions, but only if there is %% a JSESSIONID cookie. If this cookie isn't yet set, we shall @@ -31,12 +31,12 @@ h_sid(Req, Headers) -> end, {H ++ Headers, Req2}. --spec h_no_cache(req(), headers()) -> {headers(), req()}. +%% -spec h_no_cache(req(), headers()) -> {headers(), req()}. h_no_cache(Req, Headers) -> H = [{"Cache-Control", "no-store, no-cache, must-revalidate, max-age=0"}], {H ++ Headers, Req}. --spec xhr_cors(req(), headers()) -> {headers(), req()}. +%% -spec xhr_cors(req(), headers()) -> {headers(), req()}. xhr_cors(Req, Headers) -> {OriginH, Req1} = sockjs_http:header('Origin', Req), Origin = case OriginH of @@ -54,15 +54,15 @@ xhr_cors(Req, Headers) -> {"Access-Control-Allow-Credentials", "true"}], {H ++ AllowHeaders ++ Headers, Req2}. --spec xhr_options_post(req(), headers()) -> {headers(), req()}. +%% -spec xhr_options_post(req(), headers()) -> {headers(), req()}. xhr_options_post(Req, Headers) -> xhr_options(Req, Headers, ["OPTIONS", "POST"]). --spec xhr_options_get(req(), headers()) -> {headers(), req()}. +%% -spec xhr_options_get(req(), headers()) -> {headers(), req()}. xhr_options_get(Req, Headers) -> xhr_options(Req, Headers, ["OPTIONS", "GET"]). --spec xhr_options(req(), headers(), list(string())) -> {headers(), req()}. +%% -spec xhr_options(req(), headers(), list(string())) -> {headers(), req()}. xhr_options(Req, Headers, Methods) -> H = [{"Access-Control-Allow-Methods", string:join(Methods, ", ")}, {"Access-Control-Max-Age", integer_to_list(?YEAR)}], diff --git a/src/sockjs_handler.erl b/src/sockjs_handler.erl index ebb3982..b706453 100644 --- a/src/sockjs_handler.erl +++ b/src/sockjs_handler.erl @@ -11,7 +11,7 @@ %% -------------------------------------------------------------------------- --spec init_state(binary(), callback(), any(), list(tuple())) -> service(). +%% -spec init_state(binary(), callback(), any(), list(tuple())) -> service(). init_state(Prefix, Callback, State, Options) -> #service{prefix = binary_to_list(Prefix), callback = Callback, @@ -34,7 +34,7 @@ init_state(Prefix, Callback, State, Options) -> %% -------------------------------------------------------------------------- --spec is_valid_ws(service(), req()) -> {boolean(), req(), tuple()}. +%% -spec is_valid_ws(service(), req()) -> {boolean(), req(), tuple()}. is_valid_ws(Service, Req) -> case get_action(Service, Req) of {{match, WS}, Req1} when WS =:= websocket orelse @@ -44,7 +44,7 @@ is_valid_ws(Service, Req) -> {false, Req1, {}} end. --spec valid_ws_request(service(), req()) -> {boolean(), req(), tuple()}. +%% -spec valid_ws_request(service(), req()) -> {boolean(), req(), tuple()}. valid_ws_request(_Service, Req) -> {R1, Req1} = valid_ws_upgrade(Req), {R2, Req2} = valid_ws_connection(Req1), @@ -73,7 +73,7 @@ valid_ws_connection(Req) -> {lists:member("upgrade", Vs), Req2} end. --spec get_action(service(), req()) -> {nomatch | {match, atom()}, req()}. +%% -spec get_action(service(), req()) -> {nomatch | {match, atom()}, req()}. get_action(Service, Req) -> {Dispatch, Req1} = dispatch_req(Service, Req), case Dispatch of @@ -93,20 +93,20 @@ strip_prefix(LongPath, Prefix) -> end. --type(dispatch_result() :: - nomatch | - {match, {send | recv | none , atom(), - server(), session(), list(atom())}} | - {bad_method, list(atom())}). +%% -type(dispatch_result() :: +%% nomatch | +%% {match, {send | recv | none , atom(), +%% server(), session(), list(atom())}} | +%% {bad_method, list(atom())}). --spec dispatch_req(service(), req()) -> {dispatch_result(), req()}. +%% -spec dispatch_req(service(), req()) -> {dispatch_result(), req()}. dispatch_req(#service{prefix = Prefix}, Req) -> {Method, Req1} = sockjs_http:method(Req), {LongPath, Req2} = sockjs_http:path(Req1), {ok, PathRemainder} = strip_prefix(LongPath, Prefix), {dispatch(Method, PathRemainder), Req2}. --spec dispatch(atom(), nonempty_string()) -> dispatch_result(). +%% -spec dispatch(atom(), nonempty_string()) -> dispatch_result(). dispatch(Method, Path) -> lists:foldl( fun ({Match, MethodFilters}, nomatch) -> @@ -163,7 +163,7 @@ re(Path, S) -> %% -------------------------------------------------------------------------- --spec handle_req(service(), req()) -> req(). +%% -spec handle_req(service(), req()) -> req(). handle_req(Service = #service{logger = Logger}, Req) -> Req0 = Logger(Service, Req, http), @@ -202,14 +202,14 @@ handle({match, {Type, Action, _Server, Session, Filters}}, Service, Req) -> %% -------------------------------------------------------------------------- --spec default_logger(service(), req(), websocket | http) -> req(). +%% -spec default_logger(service(), req(), websocket | http) -> req(). default_logger(_Service, Req, _Type) -> {LongPath, Req1} = sockjs_http:path(Req), {Method, Req2} = sockjs_http:method(Req1), io:format("~s ~s~n", [Method, LongPath]), Req2. --spec extract_info(req()) -> {info(), req()}. +%% -spec extract_info(req()) -> {info(), req()}. extract_info(Req) -> {Peer, Req0} = sockjs_http:peername(Req), {Sock, Req1} = sockjs_http:sockname(Req0), diff --git a/src/sockjs_http.erl b/src/sockjs_http.erl index 9754119..5cdf431 100644 --- a/src/sockjs_http.erl +++ b/src/sockjs_http.erl @@ -8,22 +8,22 @@ %% -------------------------------------------------------------------------- --spec path(req()) -> {string(), req()}. +%% -spec path(req()) -> {string(), req()}. path({cowboy, Req}) -> {Path, Req1} = cowboy_http_req:raw_path(Req), {binary_to_list(Path), {cowboy, Req1}}. --spec method(req()) -> {atom(), req()}. +%% -spec method(req()) -> {atom(), req()}. method({cowboy, Req}) -> {Method, Req1} = cowboy_http_req:method(Req), case is_binary(Method) of true -> {binary_to_atom(Method, utf8), {cowboy, Req1}}; false -> {Method, {cowboy, Req1}} end. --spec body(req()) -> {binary(), req()}. +%% -spec body(req()) -> {binary(), req()}. body({cowboy, Req}) -> {ok, Body, Req1} = cowboy_http_req:body(Req), {Body, {cowboy, Req1}}. --spec body_qs(req()) -> {binary(), req()}. +%% -spec body_qs(req()) -> {binary(), req()}. body_qs(Req) -> {H, Req1} = header('Content-Type', Req), case H of @@ -42,7 +42,7 @@ body_qs2({cowboy, Req}) -> {V, {cowboy, Req1}} end. --spec header(atom(), req()) -> {nonempty_string() | undefined, req()}. +%% -spec header(atom(), req()) -> {nonempty_string() | undefined, req()}. header(K, {cowboy, Req})-> {H, Req2} = cowboy_http_req:header(K, Req), {V, Req3} = case H of @@ -55,7 +55,7 @@ header(K, {cowboy, Req})-> _ -> {binary_to_list(V), {cowboy, Req3}} end. --spec jsessionid(req()) -> {nonempty_string() | undefined, req()}. +%% -spec jsessionid(req()) -> {nonempty_string() | undefined, req()}. jsessionid({cowboy, Req}) -> {C, Req2} = cowboy_http_req:cookie(<<"JSESSIONID">>, Req), case C of @@ -65,7 +65,7 @@ jsessionid({cowboy, Req}) -> {undefined, {cowboy, Req2}} end. --spec callback(req()) -> {nonempty_string() | undefined, req()}. +%% -spec callback(req()) -> {nonempty_string() | undefined, req()}. callback({cowboy, Req}) -> {CB, Req1} = cowboy_http_req:qs_val(<<"c">>, Req), case CB of @@ -73,12 +73,12 @@ callback({cowboy, Req}) -> _ -> {binary_to_list(CB), {cowboy, Req1}} end. --spec peername(req()) -> {{inet:ip_address(), non_neg_integer()}, req()}. +%% -spec peername(req()) -> {{inet:ip_address(), non_neg_integer()}, req()}. peername({cowboy, Req}) -> {P, Req1} = cowboy_http_req:peer(Req), {P, {cowboy, Req1}}. --spec sockname(req()) -> {{inet:ip_address(), non_neg_integer()}, req()}. +%% -spec sockname(req()) -> {{inet:ip_address(), non_neg_integer()}, req()}. sockname({cowboy, Req} = R) -> {ok, _T, S} = cowboy_http_req:transport(Req), %% Cowboy has peername(), but doesn't have sockname() equivalent. @@ -92,18 +92,18 @@ sockname({cowboy, Req} = R) -> %% -------------------------------------------------------------------------- --spec reply(non_neg_integer(), headers(), iodata(), req()) -> req(). +%% -spec reply(non_neg_integer(), headers(), iodata(), req()) -> req(). reply(Code, Headers, Body, {cowboy, Req}) -> Body1 = iolist_to_binary(Body), {ok, Req1} = cowboy_http_req:reply(Code, enbinary(Headers), Body1, Req), {cowboy, Req1}. --spec chunk_start(non_neg_integer(), headers(), req()) -> req(). +%% -spec chunk_start(non_neg_integer(), headers(), req()) -> req(). chunk_start(Code, Headers, {cowboy, Req}) -> {ok, Req1} = cowboy_http_req:chunked_reply(Code, enbinary(Headers), Req), {cowboy, Req1}. --spec chunk(iodata(), req()) -> {ok | error, req()}. +%% -spec chunk(iodata(), req()) -> {ok | error, req()}. chunk(Chunk, {cowboy, Req} = R) -> case cowboy_http_req:chunk(Chunk, Req) of ok -> {ok, R}; @@ -112,25 +112,25 @@ chunk(Chunk, {cowboy, Req} = R) -> %% should catch tco socket closure before. end. --spec chunk_end(req()) -> req(). +%% -spec chunk_end(req()) -> req(). chunk_end({cowboy, _Req} = R) -> R. enbinary(L) -> [{list_to_binary(K), list_to_binary(V)} || {K, V} <- L]. --spec hook_tcp_close(req()) -> req(). +%% -spec hook_tcp_close(req()) -> req(). hook_tcp_close(R = {cowboy, Req}) -> {ok, T, S} = cowboy_http_req:transport(Req), T:setopts(S,[{active,once}]), R. --spec unhook_tcp_close(req()) -> req(). +%% -spec unhook_tcp_close(req()) -> req(). unhook_tcp_close(R = {cowboy, Req}) -> {ok, T, S} = cowboy_http_req:transport(Req), T:setopts(S,[{active,false}]), R. --spec abruptly_kill(req()) -> req(). +%% -spec abruptly_kill(req()) -> req(). abruptly_kill(R = {cowboy, Req}) -> {ok, T, S} = cowboy_http_req:transport(Req), T:close(S), diff --git a/src/sockjs_internal.hrl b/src/sockjs_internal.hrl index 4f696d8..629b2fe 100644 --- a/src/sockjs_internal.hrl +++ b/src/sockjs_internal.hrl @@ -1,32 +1,32 @@ --type(req() :: {cowboy, any()}). +%% -type(req() :: {cowboy, any()}). --type(user_session() :: nonempty_string()). --type(emittable() :: init|closed|{recv, binary()}). --type(callback() :: fun((user_session(), emittable(), any()) -> ok)). --type(logger() :: fun((any(), req(), websocket|http) -> req())). +%% -type(user_session() :: nonempty_string()). +%% -type(emittable() :: init|closed|{recv, binary()}). +%% -type(callback() :: fun((user_session(), emittable(), any()) -> ok)). +%% -type(logger() :: fun((any(), req(), websocket|http) -> req())). --record(service, {prefix :: nonempty_string(), - callback :: callback(), - state :: any(), - sockjs_url :: nonempty_string(), - cookie_needed :: boolean(), - websocket :: boolean(), - disconnect_delay :: non_neg_integer(), - heartbeat_delay :: non_neg_integer(), - response_limit :: non_neg_integer(), - logger :: logger() +-record(service, {prefix , %% nonempty_string(), + callback , %% callback() + state , %% any() + sockjs_url , %% nonempty_string() + cookie_needed , %% boolean() + websocket , %% boolean() + disconnect_delay , %% non_neg_integer() + heartbeat_delay , %% non_neg_integer() + response_limit , %% non_neg_integer() + logger %% logger() }). --type(service() :: #service{}). +%% -type(service() :: #service{}). --type(headers() :: list({nonempty_string(), nonempty_string()})). --type(server() :: nonempty_string()). --type(session() :: nonempty_string()). +%% -type(headers() :: list({nonempty_string(), nonempty_string()})). +%% -type(server() :: nonempty_string()). +%% -type(session() :: nonempty_string()). --type(frame() :: {open, nil} | - {close, {non_neg_integer(), string()}} | - {data, list(iodata())} | - {heartbeat, nil} ). +%% -type(frame() :: {open, nil} | +%% {close, {non_neg_integer(), string()}} | +%% {data, list(iodata())} | +%% {heartbeat, nil} ). --type(info() :: [{atom(), any()}]). +%% -type(info() :: [{atom(), any()}]). diff --git a/src/sockjs_json.erl b/src/sockjs_json.erl index e61f4b9..d3dae20 100644 --- a/src/sockjs_json.erl +++ b/src/sockjs_json.erl @@ -4,11 +4,11 @@ %% -------------------------------------------------------------------------- --spec encode(any()) -> iodata(). +%% -spec encode(any()) -> iodata(). encode(Thing) -> mochijson2_fork:encode(Thing). --spec decode(iodata()) -> {ok, any()} | {error, any()}. +%% -spec decode(iodata()) -> {ok, any()} | {error, any()}. decode(Encoded) -> try mochijson2_fork:decode(Encoded) of V -> {ok, V} diff --git a/src/sockjs_session.erl b/src/sockjs_session.erl index 66c5df0..7e4ae00 100644 --- a/src/sockjs_session.erl +++ b/src/sockjs_session.erl @@ -11,39 +11,39 @@ handle_cast/2]). -include("sockjs_internal.hrl"). --type(handle() :: {?MODULE, {pid(), info()}}). - --record(session, {id :: session(), - outbound_queue = queue:new() :: queue(), - response_pid :: pid(), - disconnect_tref :: reference(), - disconnect_delay = 5000 :: non_neg_integer(), - heartbeat_tref :: reference() | triggered, - heartbeat_delay = 25000 :: non_neg_integer(), - ready_state = connecting :: connecting | open | closed, - close_msg :: {non_neg_integer(), string()}, +%% -type(handle() :: {?MODULE, {pid(), info()}}). + +-record(session, {id , %% session(), + outbound_queue = queue:new() , %% queue() + response_pid , %% pid() + disconnect_tref , %% reference() + disconnect_delay = 5000 , %% non_neg_integer() + heartbeat_tref , %% reference() | triggered + heartbeat_delay = 25000 , %% non_neg_integer() + ready_state = connecting , %% connecting | open | closed + close_msg , %% {non_neg_integer(), string()} callback, state, - handle :: handle() + handle %% handle() }). -define(ETS, sockjs_table). --type(session_or_undefined() :: session() | undefined). --type(session_or_pid() :: session() | pid()). +%% -type(session_or_undefined() :: session() | undefined). +%% -type(session_or_pid() :: session() | pid()). %% -------------------------------------------------------------------------- --spec init() -> ok. +%% -spec init() -> ok. init() -> _ = ets:new(?ETS, [public, named_table]), ok. --spec start_link(session_or_undefined(), service(), info()) -> {ok, pid()}. +%% -spec start_link(session_or_undefined(), service(), info()) -> {ok, pid()}. start_link(SessionId, Service, Info) -> gen_server:start_link(?MODULE, {SessionId, Service, Info}, []). --spec maybe_create(session_or_undefined(), service(), info()) -> pid(). +%% -spec maybe_create(session_or_undefined(), service(), info()) -> pid(). maybe_create(SessionId, Service, Info) -> case ets:lookup(?ETS, SessionId) of [] -> {ok, SPid} = sockjs_session_sup:start_child( @@ -53,7 +53,7 @@ maybe_create(SessionId, Service, Info) -> end. --spec received(list(iodata()), session_or_pid()) -> ok. +%% -spec received(list(iodata()), session_or_pid()) -> ok. received(Messages, SessionPid) when is_pid(SessionPid) -> case gen_server:call(SessionPid, {received, Messages}, infinity) of ok -> ok; @@ -63,27 +63,27 @@ received(Messages, SessionPid) when is_pid(SessionPid) -> received(Messages, SessionId) -> received(Messages, spid(SessionId)). --spec send(iodata(), handle()) -> ok. +%% -spec send(iodata(), handle()) -> ok. send(Data, {?MODULE, {SPid, _}}) -> gen_server:cast(SPid, {send, Data}), ok. --spec close(non_neg_integer(), string(), handle()) -> ok. +%% -spec close(non_neg_integer(), string(), handle()) -> ok. close(Code, Reason, {?MODULE, {SPid, _}}) -> gen_server:cast(SPid, {close, Code, Reason}), ok. --spec info(handle()) -> info(). +%% -spec info(handle()) -> info(). info({?MODULE, {_SPid, Info}}) -> Info. --spec reply(session_or_pid()) -> - wait | session_in_use | {ok | close, frame()}. +%% -spec reply(session_or_pid()) -> +%% wait | session_in_use | {ok | close, frame()}. reply(Session) -> reply(Session, true). --spec reply(session_or_pid(), boolean()) -> - wait | session_in_use | {ok | close, frame()}. +%% -spec reply(session_or_pid(), boolean()) -> +%% wait | session_in_use | {ok | close, frame()}. reply(SessionPid, Multiple) when is_pid(SessionPid) -> gen_server:call(SessionPid, {reply, self(), Multiple}, infinity); reply(SessionId, Multiple) -> @@ -154,7 +154,7 @@ unmark_waiting(RPid, State = #session{response_pid = Pid, when Pid =/= undefined andalso Pid =/= RPid -> State. --spec emit(emittable(), #session{}) -> #session{}. +%% -spec emit(emittable(), #session{}) -> #session{}. emit(What, State = #session{callback = Callback, state = UserState, handle = Handle}) -> @@ -175,7 +175,7 @@ emit(What, State = #session{callback = Callback, %% -------------------------------------------------------------------------- --spec init({session_or_undefined(), service(), info()}) -> {ok, #session{}}. +%% -spec init({session_or_undefined(), service(), info()}) -> {ok, #session{}}. init({SessionId, #service{callback = Callback, state = UserState, disconnect_delay = DisconnectDelay, diff --git a/src/sockjs_session_sup.erl b/src/sockjs_session_sup.erl index 4197ce3..71c7ff4 100644 --- a/src/sockjs_session_sup.erl +++ b/src/sockjs_session_sup.erl @@ -7,7 +7,7 @@ %% -------------------------------------------------------------------------- --spec start_link() -> ignore | {'ok', pid()} | {'error', any()}. +%% -spec start_link() -> ignore | {'ok', pid()} | {'error', any()}. start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). diff --git a/src/sockjs_util.erl b/src/sockjs_util.erl index be3f972..9b9969d 100644 --- a/src/sockjs_util.erl +++ b/src/sockjs_util.erl @@ -8,7 +8,7 @@ %% -------------------------------------------------------------------------- --spec rand32() -> non_neg_integer(). +%% -spec rand32() -> non_neg_integer(). rand32() -> case get(random_seeded) of undefined -> @@ -21,7 +21,7 @@ rand32() -> random:uniform(erlang:trunc(math:pow(2,32)))-1. --spec encode_frame(frame()) -> iodata(). +%% -spec encode_frame(frame()) -> iodata(). encode_frame({open, nil}) -> <<"o">>; encode_frame({close, {Code, Reason}}) -> @@ -34,7 +34,7 @@ encode_frame({heartbeat, nil}) -> <<"h">>. --spec url_escape(string(), string()) -> iolist(). +%% -spec url_escape(string(), string()) -> iolist(). url_escape(Str, Chars) -> [case lists:member(Char, Chars) of true -> hex(Char); diff --git a/src/sockjs_ws_handler.erl b/src/sockjs_ws_handler.erl index bcf463d..c011c89 100644 --- a/src/sockjs_ws_handler.erl +++ b/src/sockjs_ws_handler.erl @@ -6,7 +6,7 @@ %% -------------------------------------------------------------------------- --spec received(websocket|rawwebsocket, pid(), binary()) -> ok | shutdown. +%% -spec received(websocket|rawwebsocket, pid(), binary()) -> ok | shutdown. %% Ignore empty received(_RawWebsocket, _SessionPid, <<>>) -> ok; @@ -30,7 +30,7 @@ session_received(Messages, SessionPid) -> no_session -> shutdown end. --spec reply(websocket|rawwebsocket, pid()) -> {close|open, binary()} | wait. +%% -spec reply(websocket|rawwebsocket, pid()) -> {close|open, binary()} | wait. reply(websocket, SessionPid) -> case sockjs_session:reply(SessionPid) of {W, Frame} when W =:= ok orelse W =:= close-> @@ -52,7 +52,7 @@ reply(rawwebsocket, SessionPid) -> wait end. --spec close(websocket|rawwebsocket, pid()) -> ok. +%% -spec close(websocket|rawwebsocket, pid()) -> ok. close(_RawWebsocket, SessionPid) -> SessionPid ! force_shutdown, ok. rabbitmq-server-3.5.7/plugins-src/sockjs-erlang-wrapper/0001-a2b-b2a.diff0000644000177700017770000000212512633765070025460 0ustar michaelmichaeldiff --git a/src/sockjs_http.erl b/src/sockjs_http.erl index 5cdf431..837b64f 100644 --- a/src/sockjs_http.erl +++ b/src/sockjs_http.erl @@ -15,7 +15,7 @@ path({cowboy, Req}) -> {Path, Req1} = cowboy_http_req:raw_path(Req), %% -spec method(req()) -> {atom(), req()}. method({cowboy, Req}) -> {Method, Req1} = cowboy_http_req:method(Req), case is_binary(Method) of - true -> {binary_to_atom(Method, utf8), {cowboy, Req1}}; + true -> {list_to_atom(binary_to_list(Method)), {cowboy, Req1}}; false -> {Method, {cowboy, Req1}} end. @@ -47,7 +47,7 @@ header(K, {cowboy, Req})-> {H, Req2} = cowboy_http_req:header(K, Req), {V, Req3} = case H of undefined -> - cowboy_http_req:header(atom_to_binary(K, utf8), Req2); + cowboy_http_req:header(list_to_binary(atom_to_list(K)), Req2); _ -> {H, Req2} end, case V of rabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/0000755000177700017770000000000012633765070022021 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/generate_deps0000644000177700017770000000444712633765070024562 0ustar michaelmichael#!/usr/bin/env escript %% -*- erlang -*- -mode(compile). main([IncludeDir, ErlDir, EbinDir, TargetFile]) -> ErlDirContents = filelib:wildcard("*.erl", ErlDir), ErlFiles = [filename:join(ErlDir, FileName) || FileName <- ErlDirContents], Modules = sets:from_list( [list_to_atom(filename:basename(FileName, ".erl")) || FileName <- ErlDirContents]), Headers = sets:from_list( [filename:join(IncludeDir, FileName) || FileName <- filelib:wildcard("*.hrl", IncludeDir)]), Deps = lists:foldl( fun (Path, Deps1) -> dict:store(Path, detect_deps(IncludeDir, EbinDir, Modules, Headers, Path), Deps1) end, dict:new(), ErlFiles), {ok, Hdl} = file:open(TargetFile, [write, delayed_write]), dict:fold( fun (_Path, [], ok) -> ok; (Path, Dep, ok) -> Module = filename:basename(Path, ".erl"), ok = file:write(Hdl, [EbinDir, "/", Module, ".beam: ", Path]), ok = sets:fold(fun (E, ok) -> file:write(Hdl, [" ", E]) end, ok, Dep), file:write(Hdl, ["\n"]) end, ok, Deps), ok = file:write(Hdl, [TargetFile, ": ", escript:script_name(), "\n"]), ok = file:sync(Hdl), ok = file:close(Hdl). detect_deps(IncludeDir, EbinDir, Modules, Headers, Path) -> {ok, Forms} = epp:parse_file(Path, [IncludeDir], [{use_specs, true}]), lists:foldl( fun ({attribute, _LineNumber, Attribute, Behaviour}, Deps) when Attribute =:= behaviour orelse Attribute =:= behavior -> case sets:is_element(Behaviour, Modules) of true -> sets:add_element( [EbinDir, "/", atom_to_list(Behaviour), ".beam"], Deps); false -> Deps end; ({attribute, _LineNumber, file, {FileName, _LineNumber1}}, Deps) -> case sets:is_element(FileName, Headers) of true -> sets:add_element(FileName, Deps); false -> Deps end; (_Form, Deps) -> Deps end, sets:new(), Forms). rabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/src/0000755000177700017770000000000012633765070022610 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/src/rabbit_shovel_parameters.erl0000644000177700017770000002745512633765070030377 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_shovel_parameters). -behaviour(rabbit_runtime_parameter). -include_lib("amqp_client/include/amqp_client.hrl"). -include("rabbit_shovel.hrl"). -export([validate/5, notify/4, notify_clear/3]). -export([register/0, unregister/0, parse/2]). -import(rabbit_misc, [pget/2, pget/3]). -rabbit_boot_step({?MODULE, [{description, "shovel parameters"}, {mfa, {rabbit_shovel_parameters, register, []}}, {cleanup, {?MODULE, unregister, []}}, {requires, rabbit_registry}, {enables, recovery}]}). register() -> rabbit_registry:register(runtime_parameter, <<"shovel">>, ?MODULE). unregister() -> rabbit_registry:unregister(runtime_parameter, <<"shovel">>). validate(_VHost, <<"shovel">>, Name, Def, User) -> [case pget2(<<"src-exchange">>, <<"src-queue">>, Def) of zero -> {error, "Must specify 'src-exchange' or 'src-queue'", []}; one -> ok; both -> {error, "Cannot specify 'src-exchange' and 'src-queue'", []} end, case pget2(<<"dest-exchange">>, <<"dest-queue">>, Def) of zero -> ok; one -> ok; both -> {error, "Cannot specify 'dest-exchange' and 'dest-queue'", []} end, case {pget(<<"delete-after">>, Def), pget(<<"ack-mode">>, Def)} of {N, <<"no-ack">>} when is_integer(N) -> {error, "Cannot specify 'no-ack' and numerical 'delete-after'", []}; _ -> ok end | rabbit_parameter_validation:proplist(Name, validation(User), Def)]; validate(_VHost, _Component, Name, _Term, _User) -> {error, "name not recognised: ~p", [Name]}. pget2(K1, K2, Defs) -> case {pget(K1, Defs), pget(K2, Defs)} of {undefined, undefined} -> zero; {undefined, _} -> one; {_, undefined} -> one; {_, _} -> both end. notify(VHost, <<"shovel">>, Name, Definition) -> rabbit_shovel_dyn_worker_sup_sup:adjust({VHost, Name}, Definition). notify_clear(VHost, <<"shovel">>, Name) -> rabbit_shovel_dyn_worker_sup_sup:stop_child({VHost, Name}). %%---------------------------------------------------------------------------- validation(User) -> [{<<"src-uri">>, validate_uri_fun(User), mandatory}, {<<"dest-uri">>, validate_uri_fun(User), mandatory}, {<<"src-exchange">>, fun rabbit_parameter_validation:binary/2,optional}, {<<"src-exchange-key">>,fun rabbit_parameter_validation:binary/2,optional}, {<<"src-queue">>, fun rabbit_parameter_validation:binary/2,optional}, {<<"dest-exchange">>, fun rabbit_parameter_validation:binary/2,optional}, {<<"dest-exchange-key">>,fun rabbit_parameter_validation:binary/2,optional}, {<<"dest-queue">>, fun rabbit_parameter_validation:binary/2,optional}, {<<"prefetch-count">>, fun rabbit_parameter_validation:number/2,optional}, {<<"reconnect-delay">>, fun rabbit_parameter_validation:number/2,optional}, {<<"add-forward-headers">>, fun rabbit_parameter_validation:boolean/2,optional}, {<<"publish-properties">>, fun validate_properties/2, optional}, {<<"ack-mode">>, rabbit_parameter_validation:enum( ['no-ack', 'on-publish', 'on-confirm']), optional}, {<<"delete-after">>, fun validate_delete_after/2, optional} ]. validate_uri_fun(User) -> fun (Name, Term) -> validate_uri(Name, Term, User) end. validate_uri(Name, Term, User) when is_binary(Term) -> case rabbit_parameter_validation:binary(Name, Term) of ok -> case amqp_uri:parse(binary_to_list(Term)) of {ok, P} -> validate_params_user(P, User); {error, E} -> {error, "\"~s\" not a valid URI: ~p", [Term, E]} end; E -> E end; validate_uri(Name, Term, User) -> case rabbit_parameter_validation:list(Name, Term) of ok -> case [V || URI <- Term, V <- [validate_uri(Name, URI, User)], element(1, V) =:= error] of [] -> ok; [E | _] -> E end; E -> E end. validate_params_user(#amqp_params_direct{}, none) -> ok; validate_params_user(#amqp_params_direct{virtual_host = VHost}, User = #user{username = Username}) -> case rabbit_vhost:exists(VHost) andalso (catch rabbit_access_control:check_vhost_access( User, VHost, undefined)) of ok -> ok; _ -> {error, "user \"~s\" may not connect to vhost \"~s\"", [Username, VHost]} end; validate_params_user(#amqp_params_network{}, _User) -> ok. validate_delete_after(_Name, <<"never">>) -> ok; validate_delete_after(_Name, <<"queue-length">>) -> ok; validate_delete_after(_Name, N) when is_integer(N) -> ok; validate_delete_after(Name, Term) -> {error, "~s should be number, \"never\" or \"queue-length\", actually was " "~p", [Name, Term]}. %% TODO headers? validate_properties(Name, Term) -> Str = fun rabbit_parameter_validation:binary/2, Num = fun rabbit_parameter_validation:number/2, rabbit_parameter_validation:proplist( Name, [{<<"content_type">>, Str, optional}, {<<"content_encoding">>, Str, optional}, {<<"delivery_mode">>, Num, optional}, {<<"priority">>, Num, optional}, {<<"correlation_id">>, Str, optional}, {<<"reply_to">>, Str, optional}, {<<"expiration">>, Str, optional}, {<<"message_id">>, Str, optional}, {<<"timestamp">>, Num, optional}, {<<"type">>, Str, optional}, {<<"user_id">>, Str, optional}, {<<"app_id">>, Str, optional}, {<<"cluster_id">>, Str, optional}], Term). %%---------------------------------------------------------------------------- parse({VHost, Name}, Def) -> SrcURIs = get_uris(<<"src-uri">>, Def), DestURIs = get_uris(<<"dest-uri">>, Def), SrcX = pget(<<"src-exchange">>, Def, none), SrcXKey = pget(<<"src-exchange-key">>, Def, <<>>), %% [1] SrcQ = pget(<<"src-queue">>, Def, none), DestX = pget(<<"dest-exchange">>, Def, none), DestXKey = pget(<<"dest-exchange-key">>, Def, none), DestQ = pget(<<"dest-queue">>, Def, none), %% [1] src-exchange-key is never ignored if src-exchange is set {SrcFun, Queue, Table1} = case SrcQ of none -> {fun (_Conn, Ch) -> Ms = [#'queue.declare'{exclusive = true}, #'queue.bind'{routing_key = SrcXKey, exchange = SrcX}], [amqp_channel:call(Ch, M) || M <- Ms] end, <<>>, [{<<"src-exchange">>, SrcX}, {<<"src-exchange-key">>, SrcXKey}]}; _ -> {fun (Conn, _Ch) -> ensure_queue(Conn, SrcQ) end, SrcQ, [{<<"src-queue">>, SrcQ}]} end, DestFun = fun (Conn, _Ch) -> case DestQ of none -> ok; _ -> ensure_queue(Conn, DestQ) end end, {X, Key} = case DestQ of none -> {DestX, DestXKey}; _ -> {<<>>, DestQ} end, Table2 = [{K, V} || {K, V} <- [{<<"dest-exchange">>, DestX}, {<<"dest-exchange-key">>, DestXKey}, {<<"dest-queue">>, DestQ}], V =/= none], PubFun = fun (_SrcURI, _DestURI, P0) -> P1 = case X of none -> P0; _ -> P0#'basic.publish'{exchange = X} end, case Key of none -> P1; _ -> P1#'basic.publish'{routing_key = Key} end end, AddHeaders = pget(<<"add-forward-headers">>, Def, false), Table0 = [{<<"shovelled-by">>, rabbit_nodes:cluster_name()}, {<<"shovel-type">>, <<"dynamic">>}, {<<"shovel-name">>, Name}, {<<"shovel-vhost">>, VHost}], SetProps = lookup_indices(pget(<<"publish-properties">>, Def, []), record_info(fields, 'P_basic')), PubPropsFun = fun (SrcURI, DestURI, P0) -> P = set_properties(P0, SetProps), case AddHeaders of true -> rabbit_shovel_util:update_headers( Table0, Table1 ++ Table2, SrcURI, DestURI, P); false -> P end end, {ok, #shovel{ sources = #endpoint{uris = SrcURIs, resource_declaration = SrcFun}, destinations = #endpoint{uris = DestURIs, resource_declaration = DestFun}, prefetch_count = pget(<<"prefetch-count">>, Def, 1000), ack_mode = translate_ack_mode( pget(<<"ack-mode">>, Def, <<"on-confirm">>)), publish_fields = PubFun, publish_properties = PubPropsFun, queue = Queue, reconnect_delay = pget(<<"reconnect-delay">>, Def, 1), delete_after = opt_b2a(pget(<<"delete-after">>, Def, <<"never">>)) }}. get_uris(Key, Def) -> URIs = case pget(Key, Def) of B when is_binary(B) -> [B]; L when is_list(L) -> L end, [binary_to_list(URI) || URI <- URIs]. translate_ack_mode(<<"on-confirm">>) -> on_confirm; translate_ack_mode(<<"on-publish">>) -> on_publish; translate_ack_mode(<<"no-ack">>) -> no_ack. ensure_queue(Conn, Queue) -> {ok, Ch} = amqp_connection:open_channel(Conn), try amqp_channel:call(Ch, #'queue.declare'{queue = Queue, passive = true}) catch exit:{{shutdown, {server_initiated_close, ?NOT_FOUND, _Text}}, _} -> {ok, Ch2} = amqp_connection:open_channel(Conn), amqp_channel:call(Ch2, #'queue.declare'{queue = Queue, durable = true}), catch amqp_channel:close(Ch2) after catch amqp_channel:close(Ch) end. opt_b2a(B) when is_binary(B) -> list_to_atom(binary_to_list(B)); opt_b2a(N) -> N. set_properties(Props, []) -> Props; set_properties(Props, [{Ix, V} | Rest]) -> set_properties(setelement(Ix, Props, V), Rest). lookup_indices(KVs, L) -> [{1 + list_find(list_to_atom(binary_to_list(K)), L), V} || {K, V} <- KVs]. list_find(K, L) -> list_find(K, L, 1). list_find(K, [K|_], N) -> N; list_find(K, [], _N) -> exit({not_found, K}); list_find(K, [_|L], N) -> list_find(K, L, N + 1). rabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/src/rabbit_shovel.erl0000644000177700017770000000161512633765070026142 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_shovel). -export([start/0, stop/0, start/2, stop/1]). start() -> rabbit_shovel_sup:start_link(), ok. stop() -> ok. start(normal, []) -> rabbit_shovel_sup:start_link(). stop(_State) -> ok. rabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/src/rabbit_shovel_dyn_worker_sup.erl0000644000177700017770000000270312633765070031273 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_shovel_dyn_worker_sup). -behaviour(supervisor2). -export([start_link/2, init/1]). -import(rabbit_misc, [pget/3]). -include_lib("rabbit_common/include/rabbit.hrl"). -define(SUPERVISOR, ?MODULE). start_link(Name, Config) -> supervisor2:start_link(?MODULE, [Name, Config]). %%---------------------------------------------------------------------------- init([Name, Config]) -> {ok, {{one_for_one, 1, ?MAX_WAIT}, [{Name, {rabbit_shovel_worker, start_link, [dynamic, Name, Config]}, case pget(<<"reconnect-delay">>, Config, 1) of N when is_integer(N) andalso N > 0 -> {transient, N}; _ -> temporary end, 16#ffffffff, worker, [rabbit_shovel_worker]}]}}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/src/rabbit_shovel_worker.erl0000644000177700017770000002473112633765070027537 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_shovel_worker). -behaviour(gen_server2). -export([start_link/3]). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -include_lib("amqp_client/include/amqp_client.hrl"). -include("rabbit_shovel.hrl"). -define(MAX_CONNECTION_CLOSE_TIMEOUT, 10000). -record(state, {inbound_conn, inbound_ch, outbound_conn, outbound_ch, name, type, config, inbound_uri, outbound_uri, unacked, remaining, %% [1] remaining_unacked}). %% [2] %% [1] Counts down until we shut down in all modes %% [2] Counts down until we stop publishing in on-confirm mode start_link(Type, Name, Config) -> ok = rabbit_shovel_status:report(Name, Type, starting), gen_server2:start_link(?MODULE, [Type, Name, Config], []). %%--------------------------- %% Gen Server Implementation %%--------------------------- init([Type, Name, Config]) -> gen_server2:cast(self(), init), {ok, Shovel} = parse(Type, Name, Config), {ok, #state{name = Name, type = Type, config = Shovel}}. parse(static, Name, Config) -> rabbit_shovel_config:parse(Name, Config); parse(dynamic, Name, Config) -> rabbit_shovel_parameters:parse(Name, Config). handle_call(_Msg, _From, State) -> {noreply, State}. handle_cast(init, State = #state{config = Config}) -> random:seed(now()), #shovel{sources = Sources, destinations = Destinations} = Config, {InboundConn, InboundChan, InboundURI} = make_conn_and_chan(Sources#endpoint.uris), {OutboundConn, OutboundChan, OutboundURI} = make_conn_and_chan(Destinations#endpoint.uris), %% Don't trap exits until we have established connections so that %% if we try to shut down while waiting for a connection to be %% established then we don't block process_flag(trap_exit, true), (Sources#endpoint.resource_declaration)(InboundConn, InboundChan), (Destinations#endpoint.resource_declaration)(OutboundConn, OutboundChan), NoAck = Config#shovel.ack_mode =:= no_ack, case NoAck of false -> Prefetch = Config#shovel.prefetch_count, #'basic.qos_ok'{} = amqp_channel:call( InboundChan, #'basic.qos'{prefetch_count = Prefetch}); true -> ok end, case Config#shovel.ack_mode of on_confirm -> #'confirm.select_ok'{} = amqp_channel:call(OutboundChan, #'confirm.select'{}), ok = amqp_channel:register_confirm_handler(OutboundChan, self()); _ -> ok end, Remaining = remaining(InboundChan, Config), case Remaining of 0 -> exit({shutdown, autodelete}); _ -> ok end, #'basic.consume_ok'{} = amqp_channel:subscribe( InboundChan, #'basic.consume'{queue = Config#shovel.queue, no_ack = NoAck}, self()), State1 = State#state{inbound_conn = InboundConn, inbound_ch = InboundChan, outbound_conn = OutboundConn, outbound_ch = OutboundChan, inbound_uri = InboundURI, outbound_uri = OutboundURI, remaining = Remaining, remaining_unacked = Remaining, unacked = gb_trees:empty()}, ok = report_running(State1), {noreply, State1}. handle_info(#'basic.consume_ok'{}, State) -> {noreply, State}; handle_info({#'basic.deliver'{delivery_tag = Tag, exchange = Exchange, routing_key = RoutingKey}, Msg = #amqp_msg{props = Props = #'P_basic'{}}}, State = #state{inbound_uri = InboundURI, outbound_uri = OutboundURI, config = #shovel{publish_properties = PropsFun, publish_fields = FieldsFun}}) -> Method = #'basic.publish'{exchange = Exchange, routing_key = RoutingKey}, Method1 = FieldsFun(InboundURI, OutboundURI, Method), Msg1 = Msg#amqp_msg{props = PropsFun(InboundURI, OutboundURI, Props)}, {noreply, publish(Tag, Method1, Msg1, State)}; handle_info(#'basic.ack'{delivery_tag = Seq, multiple = Multiple}, State = #state{config = #shovel{ack_mode = on_confirm}}) -> {noreply, confirm_to_inbound( fun (DTag, Multi) -> #'basic.ack'{delivery_tag = DTag, multiple = Multi} end, Seq, Multiple, State)}; handle_info(#'basic.nack'{delivery_tag = Seq, multiple = Multiple}, State = #state{config = #shovel{ack_mode = on_confirm}}) -> {noreply, confirm_to_inbound( fun (DTag, Multi) -> #'basic.nack'{delivery_tag = DTag, multiple = Multi} end, Seq, Multiple, State)}; handle_info(#'basic.cancel'{}, State = #state{name = Name}) -> rabbit_log:warning("Shovel ~p received 'basic.cancel' from the broker~n", [Name]), {stop, {shutdown, restart}, State}; handle_info({'EXIT', InboundConn, Reason}, State = #state{inbound_conn = InboundConn}) -> {stop, {inbound_conn_died, Reason}, State}; handle_info({'EXIT', OutboundConn, Reason}, State = #state{outbound_conn = OutboundConn}) -> {stop, {outbound_conn_died, Reason}, State}. terminate(Reason, #state{inbound_conn = undefined, inbound_ch = undefined, outbound_conn = undefined, outbound_ch = undefined, name = Name, type = Type}) -> rabbit_shovel_status:report(Name, Type, {terminated, Reason}), ok; terminate({shutdown, autodelete}, State = #state{name = {VHost, Name}, type = dynamic}) -> close_connections(State), %% See rabbit_shovel_dyn_worker_sup_sup:stop_child/1 put(shovel_worker_autodelete, true), rabbit_runtime_parameters:clear(VHost, <<"shovel">>, Name), rabbit_shovel_status:remove({VHost, Name}), ok; terminate(Reason, State) -> close_connections(State), rabbit_shovel_status:report(State#state.name, State#state.type, {terminated, Reason}), ok. code_change(_OldVsn, State, _Extra) -> {ok, State}. %%--------------------------- %% Helpers %%--------------------------- confirm_to_inbound(MsgCtr, Seq, Multiple, State = #state{inbound_ch = InboundChan, unacked = Unacked}) -> ok = amqp_channel:cast( InboundChan, MsgCtr(gb_trees:get(Seq, Unacked), Multiple)), {Unacked1, Removed} = remove_delivery_tags(Seq, Multiple, Unacked, 0), decr_remaining(Removed, State#state{unacked = Unacked1}). remove_delivery_tags(Seq, false, Unacked, 0) -> {gb_trees:delete(Seq, Unacked), 1}; remove_delivery_tags(Seq, true, Unacked, Count) -> case gb_trees:is_empty(Unacked) of true -> {Unacked, Count}; false -> {Smallest, _Val, Unacked1} = gb_trees:take_smallest(Unacked), case Smallest > Seq of true -> {Unacked, Count}; false -> remove_delivery_tags(Seq, true, Unacked1, Count+1) end end. report_running(State) -> rabbit_shovel_status:report( State#state.name, State#state.type, {running, [{src_uri, State#state.inbound_uri}, {dest_uri, State#state.outbound_uri}]}). publish(_Tag, _Method, _Msg, State = #state{remaining_unacked = 0}) -> %% We are in on-confirm mode, and are autodelete. We have %% published all the messages we need to; we just wait for acks to %% come back. So drop subsequent messages on the floor to be %% requeued later. State; publish(Tag, Method, Msg, State = #state{inbound_ch = InboundChan, outbound_ch = OutboundChan, config = Config, unacked = Unacked}) -> Seq = case Config#shovel.ack_mode of on_confirm -> amqp_channel:next_publish_seqno(OutboundChan); _ -> undefined end, ok = amqp_channel:call(OutboundChan, Method, Msg), decr_remaining_unacked( case Config#shovel.ack_mode of no_ack -> decr_remaining(1, State); on_confirm -> State#state{unacked = gb_trees:insert( Seq, Tag, Unacked)}; on_publish -> ok = amqp_channel:cast( InboundChan, #'basic.ack'{delivery_tag = Tag}), decr_remaining(1, State) end). make_conn_and_chan(URIs) -> URI = lists:nth(random:uniform(length(URIs)), URIs), {ok, AmqpParam} = amqp_uri:parse(URI), {ok, Conn} = amqp_connection:start(AmqpParam), link(Conn), {ok, Chan} = amqp_connection:open_channel(Conn), {Conn, Chan, list_to_binary(amqp_uri:remove_credentials(URI))}. remaining(_Ch, #shovel{delete_after = never}) -> unlimited; remaining(Ch, #shovel{delete_after = 'queue-length', queue = Queue}) -> #'queue.declare_ok'{message_count = N} = amqp_channel:call(Ch, #'queue.declare'{queue = Queue, passive = true}), N; remaining(_Ch, #shovel{delete_after = Count}) -> Count. decr_remaining(_N, State = #state{remaining = unlimited}) -> State; decr_remaining(N, State = #state{remaining = M}) -> case M > N of true -> State#state{remaining = M - N}; false -> exit({shutdown, autodelete}) end. decr_remaining_unacked(State = #state{remaining_unacked = unlimited}) -> State; decr_remaining_unacked(State = #state{remaining_unacked = 0}) -> State; decr_remaining_unacked(State = #state{remaining_unacked = N}) -> State#state{remaining_unacked = N - 1}. close_connections(State) -> catch amqp_connection:close(State#state.inbound_conn, ?MAX_CONNECTION_CLOSE_TIMEOUT), catch amqp_connection:close(State#state.outbound_conn, ?MAX_CONNECTION_CLOSE_TIMEOUT). rabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/src/rabbit_shovel_config.erl0000644000177700017770000002412312633765070027466 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_shovel_config). -export([parse/2, ensure_defaults/2]). -include_lib("amqp_client/include/amqp_client.hrl"). -include("rabbit_shovel.hrl"). -define(IGNORE_FIELDS, [delete_after]). -define(EXTRA_KEYS, [add_forward_headers]). parse(ShovelName, Config) -> {ok, Defaults} = application:get_env(defaults), try {ok, parse_shovel_config_dict( ShovelName, parse_shovel_config_proplist( enrich_shovel_config(Config, Defaults)))} catch throw:{error, Reason} -> {error, {invalid_shovel_configuration, ShovelName, Reason}} end. %% ensures that any defaults that have been applied to a parsed %% shovel, are written back to the original proplist ensure_defaults(ShovelConfig, ParsedShovel) -> lists:keystore(reconnect_delay, 1, ShovelConfig, {reconnect_delay, ParsedShovel#shovel.reconnect_delay}). enrich_shovel_config(Config, Defaults) -> Config1 = proplists:unfold(Config), case [E || E <- Config1, not (is_tuple(E) andalso tuple_size(E) == 2)] of [] -> case duplicate_keys(Config1) of [] -> return(lists:ukeysort(1, Config1 ++ Defaults)); Dups -> fail({duplicate_parameters, Dups}) end; Invalid -> fail({invalid_parameters, Invalid}) end. parse_shovel_config_proplist(Config) -> Dict = dict:from_list(Config), Fields = record_info(fields, shovel) -- ?IGNORE_FIELDS, Keys = dict:fetch_keys(Dict) -- ?EXTRA_KEYS, case {Keys -- Fields, Fields -- Keys} of {[], []} -> {_Pos, Dict1} = lists:foldl( fun (FieldName, {Pos, Acc}) -> {Pos + 1, dict:update(FieldName, fun (V) -> {V, Pos} end, Acc)} end, {2, Dict}, Fields), return(Dict1); {[], Missing} -> fail({missing_parameters, Missing}); {Unknown, _} -> fail({unrecognised_parameters, Unknown}) end. parse_shovel_config_dict(Name, Dict) -> Cfg = run_state_monad( [fun (Shovel) -> {ok, Value} = dict:find(Key, Dict), try {ParsedValue, Pos} = Fun(Value), return(setelement(Pos, Shovel, ParsedValue)) catch throw:{error, Reason} -> fail({invalid_parameter_value, Key, Reason}) end end || {Fun, Key} <- [{fun parse_endpoint/1, sources}, {fun parse_endpoint/1, destinations}, {fun parse_non_negative_integer/1, prefetch_count}, {fun parse_ack_mode/1, ack_mode}, {fun parse_binary/1, queue}, make_parse_publish(publish_fields), make_parse_publish(publish_properties), {fun parse_non_negative_number/1, reconnect_delay}]], #shovel{}), case dict:find(add_forward_headers, Dict) of {ok, true} -> add_forward_headers_fun(Name, Cfg); _ -> Cfg end. %% --=: Plain state monad implementation start :=-- run_state_monad(FunList, State) -> lists:foldl(fun (Fun, StateN) -> Fun(StateN) end, State, FunList). return(V) -> V. fail(Reason) -> throw({error, Reason}). %% --=: end :=-- parse_endpoint({Endpoint, Pos}) when is_list(Endpoint) -> Brokers = case proplists:get_value(brokers, Endpoint) of undefined -> case proplists:get_value(broker, Endpoint) of undefined -> fail({missing_endpoint_parameter, broker_or_brokers}); B -> [B] end; Bs when is_list(Bs) -> Bs; B -> fail({expected_list, brokers, B}) end, {[], Brokers1} = run_state_monad( lists:duplicate(length(Brokers), fun check_uri/1), {Brokers, []}), ResourceDecls = case proplists:get_value(declarations, Endpoint, []) of Decls when is_list(Decls) -> Decls; Decls -> fail({expected_list, declarations, Decls}) end, {[], ResourceDecls1} = run_state_monad( lists:duplicate(length(ResourceDecls), fun parse_declaration/1), {ResourceDecls, []}), DeclareFun = fun (_Conn, Ch) -> [amqp_channel:call(Ch, M) || M <- lists:reverse(ResourceDecls1)] end, return({#endpoint{uris = Brokers1, resource_declaration = DeclareFun}, Pos}); parse_endpoint({Endpoint, _Pos}) -> fail({require_list, Endpoint}). check_uri({[Uri | Uris], Acc}) -> case amqp_uri:parse(Uri) of {ok, _Params} -> return({Uris, [Uri | Acc]}); {error, _} = Err -> throw(Err) end. parse_declaration({[{Method, Props} | Rest], Acc}) when is_list(Props) -> FieldNames = try rabbit_framing_amqp_0_9_1:method_fieldnames(Method) catch exit:Reason -> fail(Reason) end, case proplists:get_keys(Props) -- FieldNames of [] -> ok; UnknownFields -> fail({unknown_fields, Method, UnknownFields}) end, {Res, _Idx} = lists:foldl( fun (K, {R, Idx}) -> NewR = case proplists:get_value(K, Props) of undefined -> R; V -> setelement(Idx, R, V) end, {NewR, Idx + 1} end, {rabbit_framing_amqp_0_9_1:method_record(Method), 2}, FieldNames), return({Rest, [Res | Acc]}); parse_declaration({[{Method, Props} | _Rest], _Acc}) -> fail({expected_method_field_list, Method, Props}); parse_declaration({[Method | Rest], Acc}) -> parse_declaration({[{Method, []} | Rest], Acc}). parse_non_negative_integer({N, Pos}) when is_integer(N) andalso N >= 0 -> return({N, Pos}); parse_non_negative_integer({N, _Pos}) -> fail({require_non_negative_integer, N}). parse_non_negative_number({N, Pos}) when is_number(N) andalso N >= 0 -> return({N, Pos}); parse_non_negative_number({N, _Pos}) -> fail({require_non_negative_number, N}). parse_binary({Binary, Pos}) when is_binary(Binary) -> return({Binary, Pos}); parse_binary({NotABinary, _Pos}) -> fail({require_binary, NotABinary}). parse_ack_mode({Val, Pos}) when Val =:= no_ack orelse Val =:= on_publish orelse Val =:= on_confirm -> return({Val, Pos}); parse_ack_mode({WrongVal, _Pos}) -> fail({ack_mode_value_requires_one_of, {no_ack, on_publish, on_confirm}, WrongVal}). make_parse_publish(publish_fields) -> {make_parse_publish1(record_info(fields, 'basic.publish')), publish_fields}; make_parse_publish(publish_properties) -> {make_parse_publish1(record_info(fields, 'P_basic')), publish_properties}. make_parse_publish1(ValidFields) -> fun ({Fields, Pos}) when is_list(Fields) -> make_publish_fun(Fields, Pos, ValidFields); ({Fields, _Pos}) -> fail({require_list, Fields}) end. make_publish_fun(Fields, Pos, ValidFields) -> SuppliedFields = proplists:get_keys(Fields), case SuppliedFields -- ValidFields of [] -> FieldIndices = make_field_indices(ValidFields, Fields), Fun = fun (_SrcUri, _DestUri, Publish) -> lists:foldl(fun ({Pos1, Value}, Pub) -> setelement(Pos1, Pub, Value) end, Publish, FieldIndices) end, return({Fun, Pos}); Unexpected -> fail({unexpected_fields, Unexpected, ValidFields}) end. make_field_indices(Valid, Fields) -> make_field_indices(Fields, field_map(Valid, 2), []). make_field_indices([], _Idxs , Acc) -> lists:reverse(Acc); make_field_indices([{Key, Value} | Rest], Idxs, Acc) -> make_field_indices(Rest, Idxs, [{dict:fetch(Key, Idxs), Value} | Acc]). field_map(Fields, Idx0) -> {Dict, _IdxMax} = lists:foldl(fun (Field, {Dict1, Idx1}) -> {dict:store(Field, Idx1, Dict1), Idx1 + 1} end, {dict:new(), Idx0}, Fields), Dict. duplicate_keys(PropList) -> proplists:get_keys( lists:foldl(fun (K, L) -> lists:keydelete(K, 1, L) end, PropList, proplists:get_keys(PropList))). add_forward_headers_fun(Name, #shovel{publish_properties = PubProps} = Cfg) -> PubProps2 = fun(SrcUri, DestUri, Props) -> rabbit_shovel_util:update_headers( [{<<"shovelled-by">>, rabbit_nodes:cluster_name()}, {<<"shovel-type">>, <<"static">>}, {<<"shovel-name">>, list_to_binary(atom_to_list(Name))}], [], SrcUri, DestUri, PubProps(SrcUri, DestUri, Props)) end, Cfg#shovel{publish_properties = PubProps2}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/src/rabbit_shovel_sup.erl0000644000177700017770000000654012633765070027033 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_shovel_sup). -behaviour(supervisor2). -export([start_link/0, init/1]). -import(rabbit_shovel_config, [ensure_defaults/2]). -include("rabbit_shovel.hrl"). start_link() -> case parse_configuration(application:get_env(shovels)) of {ok, Configurations} -> supervisor2:start_link({local, ?MODULE}, ?MODULE, [Configurations]); {error, Reason} -> {error, Reason} end. init([Configurations]) -> Len = dict:size(Configurations), ChildSpecs = [{rabbit_shovel_status, {rabbit_shovel_status, start_link, []}, transient, 16#ffffffff, worker, [rabbit_shovel_status]}, {rabbit_shovel_dyn_worker_sup_sup, {rabbit_shovel_dyn_worker_sup_sup, start_link, []}, transient, 16#ffffffff, supervisor, [rabbit_shovel_dyn_worker_sup_sup]} | make_child_specs(Configurations)], {ok, {{one_for_one, 2*Len, 2}, ChildSpecs}}. make_child_specs(Configurations) -> dict:fold( fun (ShovelName, ShovelConfig, Acc) -> [{ShovelName, {rabbit_shovel_worker_sup, start_link, [ShovelName, ShovelConfig]}, permanent, 16#ffffffff, supervisor, [rabbit_shovel_worker_sup]} | Acc] end, [], Configurations). parse_configuration(undefined) -> {ok, dict:new()}; parse_configuration({ok, Env}) -> {ok, Defaults} = application:get_env(defaults), parse_configuration(Defaults, Env, dict:new()). parse_configuration(_Defaults, [], Acc) -> {ok, Acc}; parse_configuration(Defaults, [{ShovelName, ShovelConfig} | Env], Acc) when is_atom(ShovelName) andalso is_list(ShovelConfig) -> case dict:is_key(ShovelName, Acc) of true -> {error, {duplicate_shovel_definition, ShovelName}}; false -> case validate_shovel_config(ShovelName, ShovelConfig) of {ok, Shovel} -> %% make sure the config we accumulate has any %% relevant default values (discovered during %% validation), applied back to it UpdatedConfig = ensure_defaults(ShovelConfig, Shovel), Acc2 = dict:store(ShovelName, UpdatedConfig, Acc), parse_configuration(Defaults, Env, Acc2); Error -> Error end end; parse_configuration(_Defaults, _, _Acc) -> {error, require_list_of_shovel_configurations}. validate_shovel_config(ShovelName, ShovelConfig) -> rabbit_shovel_config:parse(ShovelName, ShovelConfig). rabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/src/rabbitmq_shovel.app.src0000644000177700017770000000074012633765070027262 0ustar michaelmichael{application, rabbitmq_shovel, [{description, "Data Shovel for RabbitMQ"}, {vsn, "%%VSN%%"}, {modules, []}, {registered, []}, {env, [{defaults, [{prefetch_count, 1000}, {ack_mode, on_confirm}, {publish_fields, []}, {publish_properties, []}, {reconnect_delay, 5}] }]}, {mod, {rabbit_shovel, []}}, {applications, [kernel, stdlib, rabbit, amqp_client]}]}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/src/rabbit_shovel_util.erl0000644000177700017770000000232112633765070027172 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_shovel_util). -export([update_headers/5]). -include_lib("rabbit_common/include/rabbit_framing.hrl"). -define(ROUTING_HEADER, <<"x-shovelled">>). update_headers(Prefix, Suffix, SrcURI, DestURI, Props = #'P_basic'{headers = Headers}) -> Table = Prefix ++ [{<<"src-uri">>, SrcURI}, {<<"dest-uri">>, DestURI}] ++ Suffix, Headers2 = rabbit_basic:prepend_table_header( ?ROUTING_HEADER, [{K, longstr, V} || {K, V} <- Table], Headers), Props#'P_basic'{headers = Headers2}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/src/rabbit_shovel_dyn_worker_sup_sup.erl0000644000177700017770000000527312633765070032167 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_shovel_dyn_worker_sup_sup). -behaviour(mirrored_supervisor). -export([start_link/0, init/1, adjust/2, stop_child/1]). -import(rabbit_misc, [pget/2]). -include_lib("rabbit_common/include/rabbit.hrl"). -define(SUPERVISOR, ?MODULE). start_link() -> {ok, Pid} = mirrored_supervisor:start_link( {local, ?SUPERVISOR}, ?SUPERVISOR, fun rabbit_misc:execute_mnesia_transaction/1, ?MODULE, []), Shovels = rabbit_runtime_parameters:list_component(<<"shovel">>), [start_child({pget(vhost, Shovel), pget(name, Shovel)}, pget(value, Shovel)) || Shovel <- Shovels], {ok, Pid}. adjust(Name, Def) -> case child_exists(Name) of true -> stop_child(Name); false -> ok end, start_child(Name, Def). start_child(Name, Def) -> case mirrored_supervisor:start_child( ?SUPERVISOR, {Name, {rabbit_shovel_dyn_worker_sup, start_link, [Name, Def]}, transient, ?MAX_WAIT, worker, [rabbit_shovel_dyn_worker_sup]}) of {ok, _Pid} -> ok; {error, {already_started, _Pid}} -> ok end. child_exists(Name) -> lists:any(fun ({N, _, _, _}) -> N =:= Name end, mirrored_supervisor:which_children(?SUPERVISOR)). stop_child(Name) -> case get(shovel_worker_autodelete) of true -> ok; %% [1] _ -> ok = mirrored_supervisor:terminate_child(?SUPERVISOR, Name), ok = mirrored_supervisor:delete_child(?SUPERVISOR, Name), rabbit_shovel_status:remove(Name) end. %% [1] An autodeleting worker removes its own parameter, and thus ends %% up here via the parameter callback. It is a transient worker that %% is just about to terminate normally - so we don't need to tell the %% supervisor to stop us - and as usual if we call into our own %% supervisor we risk deadlock. %% %% See rabbit_shovel_worker:maybe_autodelete/1 %%---------------------------------------------------------------------------- init([]) -> {ok, {{one_for_one, 3, 10}, []}}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/src/rabbit_shovel_status.erl0000644000177700017770000000535712633765070027554 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_shovel_status). -behaviour(gen_server). -export([start_link/0]). -export([report/3, remove/1, status/0]). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -define(SERVER, ?MODULE). -define(ETS_NAME, ?MODULE). -record(state, {}). -record(entry, {name, type, info, timestamp}). start_link() -> gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). report(Name, Type, Info) -> gen_server:cast(?SERVER, {report, Name, Type, Info, calendar:local_time()}). remove(Name) -> gen_server:cast(?SERVER, {remove, Name}). status() -> gen_server:call(?SERVER, status, infinity). init([]) -> ?ETS_NAME = ets:new(?ETS_NAME, [named_table, {keypos, #entry.name}, private]), {ok, #state{}}. handle_call(status, _From, State) -> Entries = ets:tab2list(?ETS_NAME), {reply, [{Entry#entry.name, Entry#entry.type, Entry#entry.info, Entry#entry.timestamp} || Entry <- Entries], State}. handle_cast({report, Name, Type, Info, Timestamp}, State) -> true = ets:insert(?ETS_NAME, #entry{name = Name, type = Type, info = Info, timestamp = Timestamp}), rabbit_event:notify(shovel_worker_status, split_name(Name) ++ split_status(Info)), {noreply, State}; handle_cast({remove, Name}, State) -> true = ets:delete(?ETS_NAME, Name), rabbit_event:notify(shovel_worker_removed, split_name(Name)), {noreply, State}. handle_info(_Info, State) -> {noreply, State}. terminate(_Reason, _State) -> ok. code_change(_OldVsn, State, _Extra) -> {ok, State}. split_status({running, MoreInfo}) -> [{status, running} | MoreInfo]; split_status({terminated, Reason}) -> [{status, terminated}, {reason, Reason}]; split_status(Status) when is_atom(Status) -> [{status, Status}]. split_name({VHost, Name}) -> [{name, Name}, {vhost, VHost}]; split_name(Name) when is_atom(Name) -> [{name, Name}]. rabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/src/rabbit_shovel_worker_sup.erl0000644000177700017770000000317212633765070030422 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_shovel_worker_sup). -behaviour(mirrored_supervisor). -export([start_link/2, init/1]). -include("rabbit_shovel.hrl"). -include_lib("rabbit_common/include/rabbit.hrl"). start_link(ShovelName, ShovelConfig) -> mirrored_supervisor:start_link({local, ShovelName}, ShovelName, fun rabbit_misc:execute_mnesia_transaction/1, ?MODULE, [ShovelName, ShovelConfig]). init([Name, Config]) -> ChildSpecs = [{Name, {rabbit_shovel_worker, start_link, [static, Name, Config]}, case proplists:get_value(reconnect_delay, Config, none) of N when is_integer(N) andalso N > 0 -> {permanent, N}; _ -> temporary end, 16#ffffffff, worker, [rabbit_shovel_worker]}], {ok, {{one_for_one, 1, ?MAX_WAIT}, ChildSpecs}}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/README0000644000177700017770000000024412633765070022701 0ustar michaelmichaelGeneric build instructions are at: http://www.rabbitmq.com/plugin-development.html See the http://www.rabbitmq.com/shovel.html page for full instructions. rabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/CONTRIBUTING.md0000644000177700017770000000424512633765070024257 0ustar michaelmichael## Overview RabbitMQ projects use pull requests to discuss, collaborate on and accept code contributions. Pull requests is the primary place of discussing code changes. ## How to Contribute The process is fairly standard: * Fork the repository or repositories you plan on contributing to * Clone [RabbitMQ umbrella repository](https://github.com/rabbitmq/rabbitmq-public-umbrella) * `cd umbrella`, `make co` * Create a branch with a descriptive name in the relevant repositories * Make your changes, run tests, commit with a [descriptive message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), push to your fork * Submit pull requests with an explanation what has been changed and **why** * Submit a filled out and signed [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) if needed (see below) * Be patient. We will get to your pull request eventually If what you are going to work on is a substantial change, please first ask the core team of their opinion on [RabbitMQ mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). ## (Brief) Code of Conduct In one line: don't be a dick. Be respectful to the maintainers and other contributors. Open source contributors put long hours into developing projects and doing user support. Those projects and user support are available for free. We believe this deserves some respect. Be respectful to people of all races, genders, religious beliefs and political views. Regardless of how brilliant a pull request is technically, we will not tolerate disrespectful or aggressive behaviour. Contributors who violate this straightforward Code of Conduct will see their pull requests closed and locked. ## Contributor Agreement If you want to contribute a non-trivial change, please submit a signed copy of our [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) around the time you submit your pull request. This will make it much easier (in some cases, possible) for the RabbitMQ team at Pivotal to merge your contribution. ## Where to Ask Questions If something isn't clear, feel free to ask on our [mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). rabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/test/0000755000177700017770000000000012633765070023000 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/test/src/0000755000177700017770000000000012633765070023567 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/test/src/rabbit_shovel_test.erl0000644000177700017770000002332412633765070030161 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_shovel_test). -export([test/0]). -include_lib("amqp_client/include/amqp_client.hrl"). -include_lib("eunit/include/eunit.hrl"). -define(EXCHANGE, <<"test_exchange">>). -define(TO_SHOVEL, <<"to_the_shovel">>). -define(FROM_SHOVEL, <<"from_the_shovel">>). -define(UNSHOVELLED, <<"unshovelled">>). -define(SHOVELLED, <<"shovelled">>). -define(TIMEOUT, 1000). main_test() -> %% it may already be running. Stop if possible application:stop(rabbitmq_shovel), %% shovel can be started with zero shovels configured ok = application:start(rabbitmq_shovel), ok = application:stop(rabbitmq_shovel), %% various ways of breaking the config require_list_of_shovel_configurations = test_broken_shovel_configs(invalid_config), require_list_of_shovel_configurations = test_broken_shovel_configs([{test_shovel, invalid_shovel_config}]), Config = [{sources, [{broker, "amqp://"}]}, {destinations, [{broker, "amqp://"}]}, {queue, <<"">>}], {duplicate_shovel_definition, test_shovel} = test_broken_shovel_configs( [{test_shovel, Config}, {test_shovel, Config}]), {invalid_parameters, [{invalid, invalid, invalid}]} = test_broken_shovel_config([{invalid, invalid, invalid} | Config]), {duplicate_parameters, [queue]} = test_broken_shovel_config([{queue, <<"">>} | Config]), {missing_parameters, Missing} = test_broken_shovel_config([]), [destinations, queue, sources] = lists:sort(Missing), {unrecognised_parameters, [invalid]} = test_broken_shovel_config([{invalid, invalid} | Config]), {require_list, invalid} = test_broken_shovel_sources(invalid), {missing_endpoint_parameter, broker_or_brokers} = test_broken_shovel_sources([]), {expected_list, brokers, invalid} = test_broken_shovel_sources([{brokers, invalid}]), {expected_string_uri, 42} = test_broken_shovel_sources([{brokers, [42]}]), {{unexpected_uri_scheme, "invalid"}, "invalid://"} = test_broken_shovel_sources([{broker, "invalid://"}]), {{unable_to_parse_uri, no_scheme}, "invalid"} = test_broken_shovel_sources([{broker, "invalid"}]), {expected_list,declarations, invalid} = test_broken_shovel_sources([{broker, "amqp://"}, {declarations, invalid}]), {unknown_method_name, 42} = test_broken_shovel_sources([{broker, "amqp://"}, {declarations, [42]}]), {expected_method_field_list, 'queue.declare', 42} = test_broken_shovel_sources([{broker, "amqp://"}, {declarations, [{'queue.declare', 42}]}]), {unknown_fields, 'queue.declare', [invalid]} = test_broken_shovel_sources( [{broker, "amqp://"}, {declarations, [{'queue.declare', [invalid]}]}]), {{invalid_amqp_params_parameter, heartbeat, "text", [{"heartbeat", "text"}], {not_an_integer, "text"}}, _} = test_broken_shovel_sources( [{broker, "amqp://localhost/?heartbeat=text"}]), {{invalid_amqp_params_parameter, username, "text", [{"username", "text"}], {parameter_unconfigurable_in_query, username, "text"}}, _} = test_broken_shovel_sources([{broker, "amqp://?username=text"}]), {invalid_parameter_value, prefetch_count, {require_non_negative_integer, invalid}} = test_broken_shovel_config([{prefetch_count, invalid} | Config]), {invalid_parameter_value, ack_mode, {ack_mode_value_requires_one_of, {no_ack, on_publish, on_confirm}, invalid}} = test_broken_shovel_config([{ack_mode, invalid} | Config]), {invalid_parameter_value, queue, {require_binary, invalid}} = test_broken_shovel_config([{sources, [{broker, "amqp://"}]}, {destinations, [{broker, "amqp://"}]}, {queue, invalid}]), {invalid_parameter_value, publish_properties, {require_list, invalid}} = test_broken_shovel_config([{publish_properties, invalid} | Config]), {invalid_parameter_value, publish_properties, {unexpected_fields, [invalid], _}} = test_broken_shovel_config([{publish_properties, [invalid]} | Config]), {{invalid_ssl_parameter, fail_if_no_peer_cert, "42", _, {require_boolean, '42'}}, _} = test_broken_shovel_sources([{broker, "amqps://username:password@host:5673/vhost?cacertfile=/path/to/cacert.pem&certfile=/path/to/certfile.pem&keyfile=/path/to/keyfile.pem&verify=verify_peer&fail_if_no_peer_cert=42"}]), %% a working config application:set_env( rabbitmq_shovel, shovels, [{test_shovel, [{sources, [{broker, "amqp:///%2f?heartbeat=5"}, {declarations, [{'queue.declare', [exclusive, auto_delete]}, {'exchange.declare', [{exchange, ?EXCHANGE}, auto_delete]}, {'queue.bind', [{queue, <<>>}, {exchange, ?EXCHANGE}, {routing_key, ?TO_SHOVEL}]} ]}]}, {destinations, [{broker, "amqp:///%2f"}]}, {queue, <<>>}, {ack_mode, on_confirm}, {publish_fields, [{exchange, ?EXCHANGE}, {routing_key, ?FROM_SHOVEL}]}, {publish_properties, [{delivery_mode, 2}, {cluster_id, <<"my-cluster">>}, {content_type, ?SHOVELLED}]}, {add_forward_headers, true} ]}], infinity), ok = application:start(rabbitmq_shovel), await_running_shovel(test_shovel), {ok, Conn} = amqp_connection:start(#amqp_params_network{}), {ok, Chan} = amqp_connection:open_channel(Conn), #'queue.declare_ok'{ queue = Q } = amqp_channel:call(Chan, #'queue.declare' { exclusive = true }), #'queue.bind_ok'{} = amqp_channel:call(Chan, #'queue.bind' { queue = Q, exchange = ?EXCHANGE, routing_key = ?FROM_SHOVEL }), #'queue.bind_ok'{} = amqp_channel:call(Chan, #'queue.bind' { queue = Q, exchange = ?EXCHANGE, routing_key = ?TO_SHOVEL }), #'basic.consume_ok'{ consumer_tag = CTag } = amqp_channel:subscribe(Chan, #'basic.consume' { queue = Q, exclusive = true }, self()), receive #'basic.consume_ok'{ consumer_tag = CTag } -> ok after ?TIMEOUT -> throw(timeout_waiting_for_consume_ok) end, ok = amqp_channel:call(Chan, #'basic.publish' { exchange = ?EXCHANGE, routing_key = ?TO_SHOVEL }, #amqp_msg { payload = <<42>>, props = #'P_basic' { delivery_mode = 2, content_type = ?UNSHOVELLED } }), receive {#'basic.deliver' { consumer_tag = CTag, delivery_tag = AckTag, routing_key = ?FROM_SHOVEL }, #amqp_msg { payload = <<42>>, props = #'P_basic' { delivery_mode = 2, content_type = ?SHOVELLED, headers = [{<<"x-shovelled">>, _, _}]} }} -> ok = amqp_channel:call(Chan, #'basic.ack'{ delivery_tag = AckTag }) after ?TIMEOUT -> throw(timeout_waiting_for_deliver1) end, [{test_shovel, static, {running, _Info}, _Time}] = rabbit_shovel_status:status(), receive {#'basic.deliver' { consumer_tag = CTag, delivery_tag = AckTag1, routing_key = ?TO_SHOVEL }, #amqp_msg { payload = <<42>>, props = #'P_basic' { delivery_mode = 2, content_type = ?UNSHOVELLED } }} -> ok = amqp_channel:call(Chan, #'basic.ack'{ delivery_tag = AckTag1 }) after ?TIMEOUT -> throw(timeout_waiting_for_deliver2) end, amqp_channel:close(Chan), amqp_connection:close(Conn), ok. test_broken_shovel_configs(Configs) -> application:set_env(rabbitmq_shovel, shovels, Configs), {error, {Error, _}} = application:start(rabbitmq_shovel), Error. test_broken_shovel_config(Config) -> {invalid_shovel_configuration, test_shovel, Error} = test_broken_shovel_configs([{test_shovel, Config}]), Error. test_broken_shovel_sources(Sources) -> {invalid_parameter_value, sources, Error} = test_broken_shovel_config([{sources, Sources}, {destinations, [{broker, "amqp://"}]}, {queue, <<"">>}]), Error. await_running_shovel(Name) -> case [Name || {Name, _, {running, _}, _} <- rabbit_shovel_status:status()] of [_] -> ok; _ -> timer:sleep(100), await_running_shovel(Name) end. rabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/test/src/rabbit_shovel_test_all.erl0000644000177700017770000000246312633765070031012 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_shovel_test_all). -export([all_tests/0]). all_tests() -> ok = eunit:test(tests(rabbit_shovel_test, 60), [verbose]), ok = eunit:test(tests(rabbit_shovel_test_dyn, 60), [verbose]). tests(Module, Timeout) -> {foreach, fun() -> ok end, [{timeout, Timeout, fun () -> Module:F() end} || F <- funs(Module, "_test")] ++ [{timeout, Timeout, Fun} || Gen <- funs(Module, "_test_"), Fun <- Module:Gen()]}. funs(Module, Suffix) -> [F || {F, _Arity} <- proplists:get_value(exports, Module:module_info()), string:right(atom_to_list(F), length(Suffix)) =:= Suffix]. rabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/test/src/rabbit_shovel_test_dyn.erl0000644000177700017770000002702312633765070031033 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ Federation. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_shovel_test_dyn). -include_lib("eunit/include/eunit.hrl"). -include_lib("amqp_client/include/amqp_client.hrl"). -import(rabbit_misc, [pget/2]). simple_test() -> with_ch( fun (Ch) -> set_param(<<"test">>, [{<<"src-queue">>, <<"src">>}, {<<"dest-queue">>, <<"dest">>}]), publish_expect(Ch, <<>>, <<"src">>, <<"dest">>, <<"hello">>) end). set_properties_test() -> with_ch( fun (Ch) -> Ps = [{<<"src-queue">>, <<"src">>}, {<<"dest-queue">>, <<"dest">>}, {<<"publish-properties">>, [{<<"cluster_id">>, <<"x">>}]}], set_param(<<"test">>, Ps), #amqp_msg{props = #'P_basic'{cluster_id = Cluster}} = publish_expect(Ch, <<>>, <<"src">>, <<"dest">>, <<"hi">>), ?assertEqual(<<"x">>, Cluster) end). exchange_test() -> with_ch( fun (Ch) -> amqp_channel:call(Ch, #'queue.declare'{queue = <<"queue">>, durable = true}), amqp_channel:call( Ch, #'queue.bind'{queue = <<"queue">>, exchange = <<"amq.topic">>, routing_key = <<"test-key">>}), set_param(<<"test">>, [{<<"src-exchange">>, <<"amq.direct">>}, {<<"src-exchange-key">>,<<"test-key">>}, {<<"dest-exchange">>, <<"amq.topic">>}]), publish_expect(Ch, <<"amq.direct">>, <<"test-key">>, <<"queue">>, <<"hello">>), set_param(<<"test">>, [{<<"src-exchange">>, <<"amq.direct">>}, {<<"src-exchange-key">>, <<"test-key">>}, {<<"dest-exchange">>, <<"amq.topic">>}, {<<"dest-exchange-key">>,<<"new-key">>}]), publish(Ch, <<"amq.direct">>, <<"test-key">>, <<"hello">>), expect_empty(Ch, <<"queue">>), amqp_channel:call( Ch, #'queue.bind'{queue = <<"queue">>, exchange = <<"amq.topic">>, routing_key = <<"new-key">>}), publish_expect(Ch, <<"amq.direct">>, <<"test-key">>, <<"queue">>, <<"hello">>) end). restart_test() -> with_ch( fun (Ch) -> set_param(<<"test">>, [{<<"src-queue">>, <<"src">>}, {<<"dest-queue">>, <<"dest">>}]), %% The catch is because connections link to the shovel, %% so one connection will die, kill the shovel, kill %% the other connection, then we can't close it [catch amqp_connection:close(C) || C <- rabbit_direct:list()], publish_expect(Ch, <<>>, <<"src">>, <<"dest">>, <<"hello">>) end). change_definition_test() -> with_ch( fun (Ch) -> set_param(<<"test">>, [{<<"src-queue">>, <<"src">>}, {<<"dest-queue">>, <<"dest">>}]), publish_expect(Ch, <<>>, <<"src">>, <<"dest">>, <<"hello">>), set_param(<<"test">>, [{<<"src-queue">>, <<"src">>}, {<<"dest-queue">>, <<"dest2">>}]), publish_expect(Ch, <<>>, <<"src">>, <<"dest2">>, <<"hello">>), expect_empty(Ch, <<"dest">>), clear_param(<<"test">>), publish_expect(Ch, <<>>, <<"src">>, <<"src">>, <<"hello">>), expect_empty(Ch, <<"dest">>), expect_empty(Ch, <<"dest2">>) end). autodelete_test_() -> [autodelete_case({<<"on-confirm">>, <<"queue-length">>, 0, 100}), autodelete_case({<<"on-confirm">>, 50, 50, 50}), autodelete_case({<<"on-publish">>, <<"queue-length">>, 0, 100}), autodelete_case({<<"on-publish">>, 50, 50, 50}), %% no-ack is not compatible with explicit count autodelete_case({<<"no-ack">>, <<"queue-length">>, 0, 100})]. autodelete_case(Args) -> fun () -> with_ch(autodelete_do(Args)) end. autodelete_do({AckMode, After, ExpSrc, ExpDest}) -> fun (Ch) -> amqp_channel:call(Ch, #'confirm.select'{}), amqp_channel:call(Ch, #'queue.declare'{queue = <<"src">>}), publish_count(Ch, <<>>, <<"src">>, <<"hello">>, 100), amqp_channel:wait_for_confirms(Ch), set_param_nowait(<<"test">>, [{<<"src-queue">>, <<"src">>}, {<<"dest-queue">>, <<"dest">>}, {<<"ack-mode">>, AckMode}, {<<"delete-after">>, After}]), await_autodelete(<<"test">>), expect_count(Ch, <<"src">>, <<"hello">>, ExpSrc), expect_count(Ch, <<"dest">>, <<"hello">>, ExpDest) end. validation_test() -> URIs = [{<<"src-uri">>, <<"amqp://">>}, {<<"dest-uri">>, <<"amqp://">>}], %% Need valid src and dest URIs invalid_param([]), invalid_param([{<<"src-queue">>, <<"test">>}, {<<"src-uri">>, <<"derp">>}, {<<"dest-uri">>, <<"amqp://">>}]), invalid_param([{<<"src-queue">>, <<"test">>}, {<<"src-uri">>, [<<"derp">>]}, {<<"dest-uri">>, <<"amqp://">>}]), invalid_param([{<<"src-queue">>, <<"test">>}, {<<"dest-uri">>, <<"amqp://">>}]), %% Also need src exchange or queue invalid_param(URIs), valid_param([{<<"src-exchange">>, <<"test">>} | URIs]), QURIs = [{<<"src-queue">>, <<"test">>} | URIs], valid_param(QURIs), %% But not both invalid_param([{<<"src-exchange">>, <<"test">>} | QURIs]), %% Check these are of right type invalid_param([{<<"prefetch-count">>, <<"three">>} | QURIs]), invalid_param([{<<"reconnect-delay">>, <<"three">>} | QURIs]), invalid_param([{<<"ack-mode">>, <<"whenever">>} | QURIs]), invalid_param([{<<"delete-after">>, <<"whenever">>} | QURIs]), %% Check properties have to look property-ish invalid_param([{<<"publish-properties">>, [{<<"nonexistent">>, <<>>}]}]), invalid_param([{<<"publish-properties">>, [{<<"cluster_id">>, 2}]}]), invalid_param([{<<"publish-properties">>, <<"something">>}]), %% Can't use explicit message count and no-ack together invalid_param([{<<"delete-after">>, 1}, {<<"ack-mode">>, <<"no-ack">>} | QURIs]), ok. security_validation_test() -> [begin rabbit_vhost:add(U), rabbit_auth_backend_internal:add_user(U, <<>>), rabbit_auth_backend_internal:set_permissions( U, U, <<".*">>, <<".*">>, <<".*">>) end || U <- [<<"a">>, <<"b">>]], Qs = [{<<"src-queue">>, <<"test">>}, {<<"dest-queue">>, <<"test2">>}], A = lookup_user(<<"a">>), valid_param([{<<"src-uri">>, <<"amqp:///a">>}, {<<"dest-uri">>, <<"amqp:///a">>} | Qs], A), invalid_param([{<<"src-uri">>, <<"amqp:///a">>}, {<<"dest-uri">>, <<"amqp:///b">>} | Qs], A), invalid_param([{<<"src-uri">>, <<"amqp:///b">>}, {<<"dest-uri">>, <<"amqp:///a">>} | Qs], A), [begin rabbit_vhost:delete(U), rabbit_auth_backend_internal:delete_user(U) end || U <- [<<"a">>, <<"b">>]], ok. %%---------------------------------------------------------------------------- with_ch(Fun) -> {ok, Conn} = amqp_connection:start(#amqp_params_network{}), {ok, Ch} = amqp_connection:open_channel(Conn), Fun(Ch), amqp_connection:close(Conn), cleanup(), ok. publish(Ch, X, Key, Payload) when is_binary(Payload) -> publish(Ch, X, Key, #amqp_msg{payload = Payload}); publish(Ch, X, Key, Msg = #amqp_msg{}) -> amqp_channel:cast(Ch, #'basic.publish'{exchange = X, routing_key = Key}, Msg). publish_expect(Ch, X, Key, Q, Payload) -> publish(Ch, X, Key, Payload), expect(Ch, Q, Payload). expect(Ch, Q, Payload) -> amqp_channel:subscribe(Ch, #'basic.consume'{queue = Q, no_ack = true}, self()), receive #'basic.consume_ok'{consumer_tag = CTag} -> ok end, Msg = receive {#'basic.deliver'{}, #amqp_msg{payload = Payload} = M} -> M after 1000 -> exit({not_received, Payload}) end, amqp_channel:call(Ch, #'basic.cancel'{consumer_tag = CTag}), Msg. expect_empty(Ch, Q) -> ?assertMatch(#'basic.get_empty'{}, amqp_channel:call(Ch, #'basic.get'{ queue = Q })). publish_count(Ch, X, Key, M, Count) -> [publish(Ch, X, Key, M) || _ <- lists:seq(1, Count)]. expect_count(Ch, Q, M, Count) -> [expect(Ch, Q, M) || _ <- lists:seq(1, Count)], expect_empty(Ch, Q). set_param(Name, Value) -> set_param_nowait(Name, Value), await_shovel(Name). set_param_nowait(Name, Value) -> ok = rabbit_runtime_parameters:set( <<"/">>, <<"shovel">>, Name, [{<<"src-uri">>, <<"amqp://">>}, {<<"dest-uri">>, [<<"amqp://">>]} | Value], none). invalid_param(Value, User) -> {error_string, _} = rabbit_runtime_parameters:set( <<"/">>, <<"shovel">>, <<"invalid">>, Value, User). valid_param(Value, User) -> ok = rabbit_runtime_parameters:set( <<"/">>, <<"shovel">>, <<"a">>, Value, User), ok = rabbit_runtime_parameters:clear(<<"/">>, <<"shovel">>, <<"a">>). invalid_param(Value) -> invalid_param(Value, none). valid_param(Value) -> valid_param(Value, none). lookup_user(Name) -> {ok, User} = rabbit_access_control:check_user_login(Name, []), User. clear_param(Name) -> rabbit_runtime_parameters:clear(<<"/">>, <<"shovel">>, Name). cleanup() -> [rabbit_runtime_parameters:clear(pget(vhost, P), pget(component, P), pget(name, P)) || P <- rabbit_runtime_parameters:list()], [rabbit_amqqueue:delete(Q, false, false) || Q <- rabbit_amqqueue:list()]. await_shovel(Name) -> await(fun () -> lists:member(Name, shovels_from_status()) end). await_autodelete(Name) -> await(fun () -> not lists:member(Name, shovels_from_parameters()) end), await(fun () -> not lists:member(Name, shovels_from_status()) end). await(Pred) -> case Pred() of true -> ok; false -> timer:sleep(100), await(Pred) end. shovels_from_status() -> S = rabbit_shovel_status:status(), [N || {{<<"/">>, N}, dynamic, {running, _}, _} <- S]. shovels_from_parameters() -> L = rabbit_runtime_parameters:list(<<"/">>, <<"shovel">>), [pget(name, Shovel) || Shovel <- L]. rabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/.srcdist_done0000644000177700017770000000000012633765070024470 0ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/Makefile0000644000177700017770000000002712633765070023460 0ustar michaelmichaelinclude ../umbrella.mk rabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/ebin/0000755000177700017770000000000012633765070022736 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/include/0000755000177700017770000000000012633765070023444 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/include/rabbit_shovel.hrl0000644000177700017770000000173612633765070027005 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -record(endpoint, {uris, resource_declaration }). -record(shovel, {sources, destinations, prefetch_count, ack_mode, publish_fields, publish_properties, queue, reconnect_delay, delete_after = never }). rabbitmq-server-3.5.7/plugins-src/rabbitmq-shovel/package.mk0000644000177700017770000000015412633765070023745 0ustar michaelmichaelRELEASABLE:=true DEPS:=rabbitmq-erlang-client WITH_BROKER_TEST_COMMANDS:=rabbit_shovel_test_all:all_tests() rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/0000755000177700017770000000000012633765070022502 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/0000755000177700017770000000000012633765070025365 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/scripts/0000755000177700017770000000000012633765070027054 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/scripts/new_webmachine.sh0000755000177700017770000000143512633765070032371 0ustar michaelmichael#!/usr/bin/env bash SCRIPT=${0##*/} NAME=$1 DESTDIR=$2 usage() { echo "usage: new_webmachine.sh name [destdir]" } if [ -z $NAME ] || [[ $NAME =~ ^[\.\~\/] ]]; then usage exit 1 fi erl -noshell -eval 'halt(if is_atom('"$NAME"') -> 0; true -> 1 end).' if [[ $? -ne 0 ]]; then echo $SCRIPT: \""$NAME"\" is not allowed as a project name echo ' The project name must begin with a lowercase letter and' echo ' contain only alphanumeric characters and underscores.' usage exit 1 fi if [ -z $DESTDIR ]; then DESTDIR="." elif [[ $DESTDIR =~ /${NAME}$ ]]; then DESTDIR=${DESTDIR%/*} fi if [ ! -e $DESTDIR ]; then $(mkdir -p $DESTDIR) fi ABSDEST=$(cd $DESTDIR && pwd) cd ${0%/*}/../priv ../rebar create template=wmskel appid=$NAME prefix=$ABSDEST/$NAME rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/THANKS0000644000177700017770000000047212633765070026303 0ustar michaelmichaelThe following people have contributed to Webmachine: Andy Gross Justin Sheehy John Muellerleile Robert Ahrens Jeremy Latt Bryan Fink Ryan Tilder Taavi Talvik Marc Worrell Seth Falcon Tuncer Ayaz Martin Scholl Paul Mineiro Dave Smith Arjan Scherpenisse Benjamin Black Anthony Molinaro Phil Pirozhkov Rusty Klophausrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/0000755000177700017770000000000012633765070026345 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/www/0000755000177700017770000000000012633765070027171 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/www/index.html0000644000177700017770000000011712633765070031165 0ustar michaelmichael It Worked Running. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/trace/0000755000177700017770000000000012633765070027443 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/trace/wmtrace.js0000755000177700017770000004475212633765070031462 0ustar michaelmichaelvar HIGHLIGHT = '#cc00cc'; var REGULAR = '#666666'; var cols = { 'a':173, 'b':325, 'c':589, 'd':797, 'e':1005, 'f':1195, 'g':1402, 'gg':1515, 'h':1572, 'i':1799, 'j':1893, 'k':1988, 'l':2157, 'll':2346, 'm':2403, 'mm':2535, 'n':2554, 'o':2649, 'oo':2781, 'ooo':2801, 'p':2894, 'q':3007 }; var rows = { '1':221, '2':298, '3':373, '4':448, '5':524, '6':599, '7':675, '8':751, '9':826, '10':902, '11':977, '12':1053, '13':1129, '14':1204, '15':1280, '16':1355, '17':1431, '18':1506, '19':1583, '20':1658, '21':1734, '22':1809, '23':1885, '24':1961, '25':2036, '26':2112 }; var edges = { 'b14b13':['b14','b13'], 'b13b12':['b13','b12'], 'b13503':['b13','503'], 'b12b11':['b12','b11'], 'b12501':['b12','501'], 'b11b10':['b11','b10'], 'b11414':['b11','414'], 'b10b9':['b10','b9'], 'b10405':['b10','405'], 'b9b8':['b9','b8'], 'b9400':['b9','400'], 'b8b7':['b8','b7'], 'b8401':['b8','401'], 'b7b6':['b7','b6'], 'b7403':['b7','403'], 'b6b5':['b6','b5'], 'b6501':['b6','501a'], 'b5b4':['b5','b4'], 'b5415':['b5','415'], 'b4b3':['b4','b3'], 'b4413':['b4','b4'], 'b3c3':['b3','c3'], 'b3200':['b3','200'], 'c3c4':['c3','c4'], 'c3d4':['c3','d3','d4'], 'c4d4':['c4','d4'], 'c4406':['c4','406'], 'd4d5':['d4','d5'], 'd4e5':['d4','e4','e5'], 'd5e5':['d5','e5'], 'd5406':['d5','d7','406'], 'e5e6':['e5','e6'], 'e5f6':['e5','f5','f6'], 'e6f6':['e6','f6'], 'e6406':['e6','e7','406'], 'f6f7':['f6','f7'], 'f6g7':['f6','g6','g7'], 'f7g7':['f7','g7'], 'f7406':['f7','406'], 'g7g8':['g7','g8'], 'g7h7':['g7','h7'], 'g8g9':['g8','g9'], 'g8h10':['g8','h8','h10'], 'g9g11':['g9','g11'], 'g9h10':['g9','gg9','gg10','h10'], 'g11h10':['g11','gg11','gg10','h10'], 'g11412':['g11','g18','412a'], 'h7i7':['h7','i7'], 'h7412':['h7','412'], 'h10h11':['h10','h11'], 'h10i12':['h10','i10','i12'], 'h11h12':['h11','h12'], 'h11i12':['h11','i11','i12'], 'h12i12':['h12','i12'], 'h12412':['h12','412a'], 'i4p3':['i4','i3','p3'], 'i4301':['i4','301'], 'i7i4':['i7','i4'], 'i7k7':['i7','k7'], 'i12l13':['i12','l12','l13'], 'i12i13':['i12','i13'], 'i13k13':['i13','k13'], 'i13j18':['i13','i17','j17','j18'], 'j18412':['j18','412a'], 'j18304':['j18','304'], 'k5l5':['k5','l5'], 'k5301':['k5','301'], 'k7k5':['k7','k5'], 'k7l7':['k7','l7'], 'k13j18':['k13','k17','j17','j18'], 'k13l13':['k13','l13'], 'l5m5':['l5','m5'], 'l5307':['l5','307'], 'l7m7':['l7','m7'], 'l7404':['l7','l8','404'], 'l13l14':['l13','l14'], 'l13m16':['l13','m13','m16'], 'l14l15':['l14','l15'], 'l14m16':['l14','m14','m16'], 'l15l17':['l15','l17'], 'l15m16':['l15','ll15','ll16','m16'], 'l17m16':['l17','ll17','ll16','m16'], 'l17304':['l17','304'], 'm5n5':['m5','n5'], 'm5410':['m5','m4','410'], 'm7n11':['m7','n7','n11'], 'm7404':['m7','404'], 'm16m20':['m16','m20'], 'm16n16':['m16','n16'], 'm20o20':['m20','o20'], 'm20202':['m20','202'], 'n5n11':['n5','n11'], 'n5410':['n5','410'], 'n11p11':['n11','p11'], 'n11303':['n11','303'], 'n16n11':['n16','n11'], 'n16o16':['n16','o16'], 'o14p11':['o14','o11','p11'], 'o14409':['o14','409a'], 'o16o14':['o16','o14'], 'o16o18':['o16','o18'], 'o18200':['o18','200a'], 'o18300':['o18','oo18','300'], 'o20o18':['o20','o18'], 'o20204':['o20','204'], 'p3p11':['p3','p11'], 'p3409':['p3','409'], 'p11o20':['p11','p20','o20'], 'p11201':['p11','q11','201'] }; var ends = { '200': {col:'a', row:'3', width:190}, '200a': {col:'mm', row:'18', width:116}, '201': {col:'q', row:'12', width:154}, '202': {col:'m', row:'21', width:116}, '204': {col:'o', row:'21', width:152}, '300': {col:'oo', row:'19', width:152}, '301': {col:'k', row:'4', width:154}, '303': {col:'m', row:'11', width:116}, '304': {col:'l', row:'18', width:116}, '307': {col:'l', row:'4', width:154}, '400': {col:'a', row:'9', width:190}, '401': {col:'a', row:'8', width:190}, '403': {col:'a', row:'7', width:190}, '404': {col:'m', row:'8', width:116}, '405': {col:'a', row:'10', width:190}, '406': {col:'c', row:'7', width:152}, '409': {col:'p', row:'2', width:116}, '409a': {col:'oo', row:'14', width:116}, '410': {col:'n', row:'4', width:116}, '412': {col:'h', row:'6', width:152}, '412a': {col:'h', row:'18', width:152}, '413': {col:'a', row:'4', width:190}, '414': {col:'a', row:'11', width:190}, '415': {col:'a', row:'5', width:190}, '501a': {col:'a', row:'6', width:190}, '501': {col:'a', row:'12', width:190}, '503': {col:'a', row:'13', width:190} }; var canvas; function decorateTrace() { trace[0].x = cols[trace[0].d[0]]; trace[0].y = rows[trace[0].d.slice(1)]; trace[0].previewCalls = previewCalls(trace[0]); for (var i = 1; i < trace.length; i++) { trace[i].x = cols[trace[i].d[0]]; trace[i].y = rows[trace[i].d.slice(1)]; trace[i].previewCalls = previewCalls(trace[i]); var path = edges[trace[i-1].d+trace[i].d]; if (path) { trace[i].path = [path.length-1]; for (var p = 1; p < path.length; p++) { trace[i].path[p-1] = getSeg(path[p-1], path[p], p == path.length-1); } } else { trace[i].path = []; } } var path = edges[trace[i-1].d+response.code]; if (path) { var end = ends[path[path.length-1]]; response.x = cols[end.col]; response.y = rows[end.row]; response.width = end.width; response.type = 'normal'; response.path = [path.length-1]; for (var p = 1; p < path.length; p++) { response.path[p-1] = getSeg(path[p-1], path[p], p == path.length-1); } } else { var ld = trace[trace.length-1]; response.x = ld.x+50; response.y = ld.y-50; response.width = 38; response.type = 'other'; response.path = [ {x1: ld.x+10, y1: ld.y-10, x2: ld.x+36, y2: ld.y-36} ]; } }; function previewCalls(dec) { var prev = ''; for (var i = 0; i < dec.calls.length; i++) { if (dec.calls[i].output != "wmtrace_not_exported") prev += '
  • '+dec.calls[i].module+':'+dec.calls[i]['function']+'
  • '; } return prev; }; function drawTrace() { drawDecision(trace[0]); for (var i = 1; i < trace.length; i++) { drawPath(trace[i].path); drawDecision(trace[i]); } drawPath(response.path); drawResponse(); }; function drawResponse() { if (response.type == 'normal') { var context = canvas.getContext('2d'); context.strokeStyle=HIGHLIGHT; context.lineWidth=4; context.beginPath(); context.rect(response.x-(response.width/2), response.y-19, response.width, 38); context.stroke(); } else { var context = canvas.getContext('2d'); context.strokeStyle='#ff0000'; context.lineWidth=4; context.beginPath(); context.arc(response.x, response.y, 19, 0, 2*3.14159, false); context.stroke(); } }; function drawDecision(dec) { var context = canvas.getContext('2d'); if (dec.previewCalls == '') context.strokeStyle=REGULAR; else context.strokeStyle=HIGHLIGHT; context.lineWidth=4; context.beginPath(); context.moveTo(dec.x, dec.y-19); context.lineTo(dec.x+19, dec.y); context.lineTo(dec.x, dec.y+19); context.lineTo(dec.x-19, dec.y); context.closePath(); context.stroke(); }; function drawPath(path) { var context = canvas.getContext('2d'); context.strokeStyle=REGULAR; context.lineWidth=4; context.beginPath(); context.moveTo(path[0].x1, path[0].y1); for (var p = 0; p < path.length; p++) { context.lineTo(path[p].x2, path[p].y2); } context.stroke(); }; function getSeg(p1, p2, last) { var seg = { x1:cols[p1[0]], y1:rows[p1.slice(1)] }; if (ends[p2]) { seg.x2 = cols[ends[p2].col]; seg.y2 = rows[ends[p2].row]; } else { seg.x2 = cols[p2[0]]; seg.y2 = rows[p2.slice(1)]; } if (seg.x1 == seg.x2) { if (seg.y1 < seg.y2) { seg.y1 = seg.y1+19; if (last) seg.y2 = seg.y2-19; } else { seg.y1 = seg.y1-19; if (last) seg.y2 = seg.y2+19; } } else { //assume seg.y1 == seg.y2 if (seg.x1 < seg.x2) { seg.x1 = seg.x1+19; if (last) seg.x2 = seg.x2-(ends[p2] ? (ends[p2].width/2) : 19); } else { seg.x1 = seg.x1-19; if (last) seg.x2 = seg.x2+(ends[p2] ? (ends[p2].width/2) : 19); } } return seg; }; function traceDecision(name) { for (var i = trace.length-1; i >= 0; i--) if (trace[i].d == name) return trace[i]; }; var detailPanels = {}; function initDetailPanels() { var windowWidth = document.getElementById('sizetest').clientWidth; var infoPanel = document.getElementById('infopanel'); var panelWidth = windowWidth-infoPanel.offsetLeft; var panels = { 'request': document.getElementById('requestdetail'), 'response': document.getElementById('responsedetail'), 'decision': document.getElementById('decisiondetail') }; var tabs = { 'request': document.getElementById('requesttab'), 'response': document.getElementById('responsetab'), 'decision': document.getElementById('decisiontab') }; var decisionId = document.getElementById('decisionid'); var decisionCalls = document.getElementById('decisioncalls'); var callInput = document.getElementById('callinput'); var callOutput = document.getElementById('calloutput'); var lastUsedPanelWidth = windowWidth-infoPanel.offsetLeft; var setPanelWidth = function(width) { infoPanel.style.left = (windowWidth-width)+'px'; canvas.style.marginRight = (width+20)+'px'; panelWidth = width; }; setPanelWidth(panelWidth); var ensureVisible = function() { if (windowWidth-infoPanel.offsetLeft < 10) setPanelWidth(lastUsedPanelWidth); }; var decChoices = ''; for (var i = 0; i < trace.length; i++) { decChoices += ''; } decisionId.innerHTML = decChoices; decisionId.selectedIndex = -1; decisionId.onchange = function() { detailPanels.setDecision(traceDecision(decisionId.value)); } detailPanels.setDecision = function(dec) { decisionId.value = dec.d; var calls = []; for (var i = 0; i < dec.calls.length; i++) { calls.push(''); } decisionCalls.innerHTML = calls.join(''); decisionCalls.selectedIndex = 0; decisionCalls.onchange(); }; detailPanels.show = function(name) { for (p in panels) { if (p == name) { panels[p].style.display = 'block'; tabs[p].className = 'selectedtab'; } else { panels[p].style.display = 'none'; tabs[p].className = ''; } } ensureVisible(); }; detailPanels.hide = function() { setPanelWidth(0); } decisionCalls.onchange = function() { var val = decisionCalls.value; if (val) { var dec = traceDecision(val.substring(0, val.indexOf('-'))); var call = dec.calls[parseInt(val.substring(val.indexOf('-')+1, val.length))]; if (call.output != "wmtrace_not_exported") { callInput.style.color='#000000'; callInput.innerHTML = call.input; if (call.output != null) { callOutput.style.color = '#000000'; callOutput.innerHTML = call.output; } else { callOutput.style.color = '#ff0000'; callOutput.textContent = 'Error: '+call.module+':'+call['function']+' never returned'; } } else { callInput.style.color='#999999'; callInput.textContent = call.module+':'+call['function']+' was not exported'; callOutput.textContent = ''; } } else { callInput.textContent = ''; callOutput.textContent = ''; } }; var headersList = function(headers) { var h = ''; for (n in headers) h += '
  • '+n+': '+headers[n]; return h; }; document.getElementById('requestmethod').innerHTML = request.method; document.getElementById('requestpath').innerHTML = request.path; document.getElementById('requestheaders').innerHTML = headersList(request.headers); document.getElementById('requestbody').innerHTML = request.body; document.getElementById('responsecode').innerHTML = response.code; document.getElementById('responseheaders').innerHTML = headersList(response.headers); document.getElementById('responsebody').innerHTML = response.body; var infoControls = document.getElementById('infocontrols'); var md = false; var dragged = false; var msoff = 0; infoControls.onmousedown = function(ev) { md = true; dragged = false; msoff = ev.clientX-infoPanel.offsetLeft; }; infoControls.onclick = function(ev) { if (dragged) { lastUsedPanelWidth = panelWidth; } else if (panelWidth < 10) { switch(ev.target.id) { case 'requesttab': detailPanels.show('request'); break; case 'responsetab': detailPanels.show('response'); break; case 'decisiontab': detailPanels.show('decision'); break; default: ensureVisible(); } } else { var name = 'none'; switch(ev.target.id) { case 'requesttab': name = 'request'; break; case 'responsetab': name = 'response'; break; case 'decisiontab': name = 'decision'; break; } if (panels[name] && panels[name].style.display != 'block') detailPanels.show(name); else detailPanels.hide(); } return false; }; document.onmousemove = function(ev) { if (md) { dragged = true; panelWidth = windowWidth-(ev.clientX-msoff); if (panelWidth < 0) { panelWidth = 0; infoPanel.style.left = windowWidth+"px"; } else if (panelWidth > windowWidth-21) { panelWidth = windowWidth-21; infoPanel.style.left = '21px'; } else infoPanel.style.left = (ev.clientX-msoff)+"px"; canvas.style.marginRight = panelWidth+20+"px"; return false; } }; document.onmouseup = function() { md = false; }; window.onresize = function() { windowWidth = document.getElementById('sizetest').clientWidth; infoPanel.style.left = windowWidth-panelWidth+'px'; }; }; window.onload = function() { canvas = document.getElementById('v3map'); initDetailPanels(); var scale = 0.25; var coy = canvas.offsetTop; function findDecision(ev) { var x = (ev.clientX+window.pageXOffset)/scale; var y = (ev.clientY+window.pageYOffset-coy)/scale; for (var i = trace.length-1; i >= 0; i--) { if (x >= trace[i].x-19 && x <= trace[i].x+19 && y >= trace[i].y-19 && y <= trace[i].y+19) return trace[i]; } }; var preview = document.getElementById('preview'); var previewId = document.getElementById('previewid'); var previewCalls = document.getElementById('previewcalls'); function previewDecision(dec) { preview.style.left = (dec.x*scale)+'px'; preview.style.top = (dec.y*scale+coy+15)+'px'; preview.style.display = 'block'; previewId.textContent = dec.d; previewCalls.innerHTML = dec.previewCalls; }; function overResponse(ev) { var x = (ev.clientX+window.pageXOffset)/scale; var y = (ev.clientY+window.pageYOffset-coy)/scale; return (x >= response.x-(response.width/2) && x <= response.x+(response.width/2) && y >= response.y-19 && y <= response.y+19); }; decorateTrace(); var bg = new Image(3138, 2184); function drawMap() { var ctx = canvas.getContext("2d"); ctx.save(); ctx.scale(1/scale, 1/scale); ctx.fillStyle = '#ffffff'; ctx.fillRect(0, 0, 3138, 2184); ctx.restore(); ctx.drawImage(bg, 0, 0); drawTrace(); }; bg.onload = function() { canvas.getContext("2d").scale(scale, scale); drawMap(scale); canvas.onmousemove = function(ev) { if (findDecision(ev)) { canvas.style.cursor = 'pointer'; previewDecision(findDecision(ev)); } else { preview.style.display = 'none'; if (overResponse(ev)) canvas.style.cursor = 'pointer'; else canvas.style.cursor = 'default'; } }; canvas.onclick = function(ev) { var dec = findDecision(ev); if (dec) { detailPanels.setDecision(dec); detailPanels.show('decision'); } else if (overResponse(ev)) { detailPanels.show('response'); } }; document.getElementById('zoomin').onclick = function() { scale = scale*2; canvas.getContext("2d").scale(2, 2); drawMap(); }; document.getElementById('zoomout').onclick = function() { scale = scale/2; canvas.getContext("2d").scale(0.5, 0.5); drawMap(); }; }; bg.onerror = function() { alert('Failed to load background image.'); }; bg.src = 'static/map.png'; }; ././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/trace/http-headers-status-v3.pngrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/trace/http-headers-status-v0000644000177700017770000144573212633765070033562 0ustar michaelmichael‰PNG  IHDR Bˆå°vÍsRGB®ÎégAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<ÿŽIDATx^ìÝ œdey/~LâÕÄ«ÉÿÞĘ\·˜`î½IÔh”qÉ¢‰&¨j£(*Š‚ƒˆÄ]@EqAed†e€a‡a؆Fd“YØ5^ù?UO÷Û§OUWï]Këó~šÓ§Îò¾ßsªºéúÍó>áñÇßȃ @€ @€ @€ @€]ˆ“ @€ @€ @€ @€º(°QÏíÔ @€ @€ @€ @€1&· @€ @€ @€ @€]cêòpz @€ @€ @€ @€æQŒé¶Ûnk½Þk×®ÔM0Ùí'up @€ @€ @€ @€˜Ÿ3cЍÐöÛo¿xñâVÍêS{î¹glÖáGè¼Af’ÆÚ¦µ×_}l\ëUv©m¼©íÝpÀìºë®óóF1j @€ @€ @€ @€³'0ó1¦Í6Ûl¬SyêôÓOmòqØa‡Åú6•5±©£ê·Wª®yì±Ç¥u}lI£8`¶ªßÖH™aŠ-'cŠ Sl,Æ4{÷¢# @€ @€ @€ @€Ì[îĘªÜ‘"+ùT6‹¼QÛüÐXëcãxꡇª¡®ŠUF &cŠãDÊ*¶œ~Œ)椋„Vô*bàåQ»ÿªOårƶâÑ6tÕº}N~W;Kn–OµË¸¯„L˜`m~½±úܺ¾:œÖÓÅaË`óÙêš2eãZÇâhÕ½ªwE‡ÁÖNT¶Œ£µ?×ÔN4ÖÅ­ÝünƒØrùòå¡_[»É8`ÞQåöhK}‹Ç½¸6 @€ @€ @€ @€tK`0cL‘í¨æ“"ð‰¥’>ÉLR|üǸ1¦Ø+O%‰tÔ4«1Åî£É U°Ô”Ê› s]ùTyd%+HµÞ+åPeû¨›å,x幜OµK‡1ÏGˆÒV9-`ªsŸcËëeHeÊwRt£LuW ëD¾$zXzÕ6«”+ÆÔy­Ù 8Nç]Z‡»TãGa‡ÍlÍX«d‚gìcK&OT¢fÕÄO-x1²Lbu¸Ž­Ã‰{ IbL倭۴=W‡³dð®:мCJ©Ü-yäè[mD­Ú9ð)ß½v$@€ @€ @€ @€̪À¬Ä˜"TIŽÚ#£EµB;1¶Ìµ®¯; Ï´B´]ŸéjÞ%úSêU2‘SuûiƘb÷Rª5¬S‚2"A]Œ1e©¡Ú%ˆTM™¢®sÀ(vœƒS\èˆþDW«5ZCEYʨÃëªÕ¹dVcLåàåf¨v2‹`åšZŒ©\ˆ²}[í¸‚ó­ Ó%—\òOÿôOo}Û[·Ür‹-ãË[·|kõñ¶·ÆSok¶üOs¡ÙF=;Æc‹-·j[lñ–-ÞÒã-úüú׿þ‹_üâÃ?<«?Eœ @€ @€ @€̈À¬Ä˜2EÔú˜S™Z«:kXœ¨Z7¨VئÀÍeŒ)'§+§n1•lMfhâkõ‘;vˆ1ÅîÕí³|T‡Ó¥I‡]j·Wk‡«tèsÙlâ1¦Z .vÌ”[ç³d£<],”ÄXkð¨6É`ë ©Õ¹$áf5ÆTÎÒV»Ú«ˆ4Åcû¸ÏËH«i«o›ç›‘·’Þ<ÈvÛm·ù–o>ë‚3NYvÒ©g.]vÎégžæ9ËÏ>Åù+.½ð²•—®¼æÊ«¯]uõuW_s}£ÅªÕ+/¿ê²‹.[qþEçŸ{á9gæç.;í¬SOYvòI§-9aéâãO>Ž=æ„ï½xQ´EÇuÔqG6Ú±mG{DlÿÝŽŽãTÛ1K¾Gk<;áCuØòÄÓ–ìðÑžö´§}àèÍ«£W @€ @€ @€ @ *0+1¦¶¥•ƪº4ÍjL‘Xªå¥"Û‘³³å£sq£q'•«bM§S­šQkN¥ô3AJ*+:=jÍrUS\1„¶“ÊÕNQÛ¥ö:©!:SöÍXL‡>—ãÌHŒi,™8KµXQµþVÛ)Þ:w&‡S½¯J%ª™1u–qcL1Þ¸ 1äØ2¯~mŠÀ¶ÌI÷æÕ;à—¿òåsWœ}úÙ§yÞôÒEç­¸tù¥W^rõu«®¾~ÕE—\xÖ9gž¶ìÔÓÎ8íô3-Î8{ÙòD¼iõ«›y¦ /¸øüsW4òLËÎ9íÔ3O9yÙI'ž¾dñ©Çgžé¸9æÄïF)bIjKŽŽ£}ç¨oïÐ~{}ï¯î÷•½÷ÿê~ ÷=äðCŽ=ñ˜Å§?‰£}Ò8ÈÒ3OÙúý[o»í¶óê¢, @€ @€ @€ô©@ßǘÆedÔ£íå™ËjLµøKkN%RDYL¨7'•‹‡daÌ2NŶCŸË.1ÕbpŪóY2u”ùª\ÎS·²2VÔdëE[+ûTÝrfcLÕ²[Õ³´1Å|pÕ‚^ÕÎG˜¬v“·ÕŽqûzéÓ7²±ºý•½¿rá¥dŒé¼ ÏY~ñòKW^ºêš•—\vÑ·¾shÌ÷ìç<{£'lT}üÏßÿŸ¯}Ýk¿¼÷—/¸¨fºòê+¢nSäŸÎ>ÿ¬eç,kĘN?qÉ©'J#Ãtì’c¢,S¤—²,ÓDZlõ–>¿çç_ýšW?éIOzâŸø”§<%~ã7~ã…/zá.»íñ¦H Mü€N1¦÷m÷¾±n›»Ö†C€ @€ @€ @€ý.0ø1¦Zþ¦zÁz*ÆT õfŒ)缫ÍUW2=]1eħ:G^|}ŽË=‘àQíeÜa8eKkN®mý§ÖwŠg©ÕîÊ}ËÒZT©õPmcL¡4cL+.[ÉE†é‹/¸|Õe«®½êØãyã›Þø›¿ù›™^ú­ßú­§>õ©OúÓï÷~ï¿ý·ÿV"M/}ÙKúæW¬¼|åê•9æVœÖg~öéKÏ8å¤ÓOÌÙå¢xRVN*ÌuN2EòéÛG~k‹·mñ¤'?9Nú‚¼ ¦½ûò—¿¼óÎ;ÿÝßýÝÿøÿã Ox¦¯Þtÿ÷#O$Õy›SÎ8ù½Û¾WŒ©ßNë? @€ @€ @€æ‰À€Ç˜¢ÂM‡"@scªMjs´E5R¨ë1¦(VT‹+å‹¡:½]|›™˜ÈÖÄòÔbLµyÐÊY¦P©:‹\§¤‹ª¡¢¸"!S¹•ic¤9a_õÑa8yG• ø2>•y©òh1Mö,©öå£z‡Ä·qÒÚ³y!Ê£ím«mVøà}ûÕ½¿zÉ•;”aºüº›®Ýï€ýžýìggVéþÏÿùÿðŸøÄ'ân‰[⤓NúÌg>ó–·¼%6ˆlSlð»¿û»øàöË/¾àªÕ+W\ºâ¼‹Î;óü3¢¶SăNãÜe§uêÉËNjL-7º SçÚH'œºxÇ?üã?ú£cŽ9&Ïû­o}+Öl½õÖùíºuëÞµÕ»bÍæ[l1©idcê—U?  @€ @€ @€ @ <ÆAågÚÆ˜"êÕzÆ*49¹¢3µ,QoÞ‚Ó)Õ†Úö0Bš~ç#ÔZ iú‡Ô"¯6µE!0ñÎOù,1–¶·bcçg«™ëšÎl1¦•«¯¼øò‹¢Ó7=83LOyÊS¢êÒÏ~ö³ÎŒÚHÿëý¯Ø>fÛå»\wãµ—\yñÖùgŽd:åøãN<¶Qfé„Eç•‹éä¾ñÍ^ü’?íiOÛwŸ}~òãçÙ—.]úÿïÿýÜç>W:sÙe—=ç9Ïy泞¹ÇW÷ˆ½¦“dc€{Ø @€ @€ @€ 0f8ÆqHêÄL[­‚c=Õa—r8fÛ`ÍXëËŽ‘P©–Þ©õ*O]+¼Ô¡S<Õ9ßÓù¾‰M'5g7eky¡Ù8uhÌ͉:w>.èÄÓHSv˜›³tîÞ¸/–)®—wüÚ>_[uÝÕW_·êÌsÎxíë^™¤'=éIŸÿüç'Øç“O>ùÿøc¯?ÿ߾軋®½ñÚ—^xÞ…çžqÞ²SÏ\zÒé'F¥FA¦%Ç|wñÑcL'ž¾äc >‡zÛÛÞö_ÿõ_ÙŸÿüçwß}÷š5kn¿ýö˜`®ôj¯½öŠ-cú¹ØKŒi‚Ëf @€ @€ @€ Ðï3cêwŽÙîLéÕ!V5Ûgwüy+¡±(6‡ÿµ}¿u˜®¿åº/~ñ  úßøw¼ã?üðÄ)?üðßþíßnÄÞþ¶ëo¾î’+/.Ètú)ËNnÌ+wÊqÇžxLdúî $ÓX©£(Œôž÷½û OxÂ>ûìSÎoo¼ñûoÿíéOúATÖŸ}öÙO~òo¿âU¯ˆ½Ä˜&~±lI€ @€ @€ @€}- ÆÔ×—Oç è$°Ï¾_[sÇ­K—ú÷ÿ÷¢Jþççw^îÕÖ­[µ¸6lØðË_þ²¶ò¾ûîûÕ¯~+ï½÷Þw¿ûݱïŸþÙŸvÄw®¹nÕ…—,?wùÙËÎ9}é§œxÚ’ÅÍyå¾»äèqcLïÚz«ß}ÚïVg–<ôÐCãÈùØzë­ËHV­ZõüŸÿò¿ÛDŒÉýM€ @€ @€ @€óG@Œiþ\k#%0ïöÙwŸ»ÖÝuÐ!ýþü~”bÚn»í’à®»îŠÿê¯þêyÏ{Þ&›lrà>ðÀ1¿Û'>ñ‰¿üË¿ü“?ù“W½êUGydÖm:öØcë·~ëIO~òÇvþØM·ÞxÑ¥+FÍ+·tñq'{Ì ãWcŠÓSÿûS9æ˜r¢ÔS‰1•¾Å³+W®ü“çþÉߊ1ͻր  @€ @€ @€ 0¯Ęæõå7xƒ-°ï¾û¬»oí—öüb¤…~ÿ÷?bC1ÞH,Eé£X³Å=ëYÏzò“Ÿüßÿûßyçßÿþ÷Çʧ<å)Ï|æ3c¢·ßû½ß‹$SlAF¶)žÚâ­[¬¹ýÖ‹/¿èüçyþ§uÚÉËN:áÔÅÇ|ìD&•{ïû'ýâ¿XÌ£êR„¨båsžóœj•¦SO=õ7~ã7_õšWªÆ4Ø÷§Ñ @€ @€ @€ @€@U@ŒÉý@€ÀÀ ì»ß¾Xÿù/~>¢BñqÑEÅPO9唨®ô›¿ù›ýèGcò¸ÈmµÕVÿùŸÿù;¿ó;±r·ÝvûÁ~ðÉO~òMozÓÕW_ÛÇÜsïxÇ;âo|Ó¿wÇ÷.¹ââ .:ÿ¬óÏ<í¬S#Æ´äÔŽ?ù¸qcLKN;a×ÝwtÔk_ûÚÿøÇEüÛßþvy›m¶)kþë¿þ+2UQ;ê?Þó®ØkÑñGM¹E ê½Û¾wûí·Ø l` @€ @€ @€ 0@bLt1 …ÑÓƒë¿ð¥FŒé5¯yMä“âùÃ;,¾éä–-[V6?ꨣbåŸþéŸVWæ³<òÈŽ;îϾéÍo¼íΈ1]2…Säœ=âWÿëã8Ÿÿüç{ì±<ø¡‡kÞýîw—žœp O{ÚÓžÿçÏßÿÀýc¯)g˜bG1&/ @€ @€ @€è#1¦>ºXºJ€Àäª1¦W¾ò•·ß~{ìÄGDr(¦“;ñÄãÛŸþô§ëׯ?è ƒb峟ýì¨Õ”+×®]û³Ÿý,–£xÒ;ì0ÍS„Š¢´ÒîŸýTL`eŸ¾úÕ¯F:*óÇýßÿû?÷¹ÏÅò/~ñ‹ÓO?ýÏŸÿçQjëm¶žf)&1¦ÉÝ+¶&@€ @€ @€ @€n ˆ1uû 8?³&04©Ü>!¤ç?ÿùçœsNœêì³Ï~êSŸkb.¹[n¹åÃþð_þå_Æ´nÏxÆ3båvÛm+?ô¡EÎiñâűýÝwßý–·¼%žÚìM›MyR¹½xÑñ'÷Áà)Où'?éÉQáé†nˆëxà˜Û."V‘mzú<ý‰O|âë^ÿχ}ØwO8z:¥˜Ä˜fí¶r` @€ @€ @€˜1¦YauPzA`ß}÷Y{ï={}u¯¨oô»¿û»Qr)zõÐCí²Ë.ñm$“žÐ|üŸÿó>øàÏ~ö³OyÊSÊʘ`îøãí¯ºêª¿ø‹¿ˆõoÇÛoýþ-_~Ñù+Î;óü3N;ë´“—t©‹;ùؘý-RGTê<ŠmŽ=ñ˜wÙé™Ïz擞ô¤'?ùÉ/|á ·ÜbËø‡ˆdU˜~ÿ~ÿmïxë·úö4§“Ën˜T®nB} @€ @€ @€ @€ lôðÃßÙî1ÁýmF€ DÙ¡Ö7›{î¹g‚»Oa³}öÝçöÜ~äÑGn¼ñÆ‘CzÏ{Þ·Åq~ô£zè¡Qcé oxûÞõ®³Î:+VF÷¾ò•¯ÄšýוQ´é×ÍÇ‘GûþÎS~g·Ýw»áæëW\ºâ¼çžqÞ²SÏ\zÒé'ž°tñq'{Ì Š1eM¦ØþÀoøŽ­ÞñÜ?yîDý¥?|z´?þ_üú}ýÞûï9§qãP¬Ò$Æ4…{Æ.´ˆy0ýºèÞ @€ @€ @€˜mâC© Û=fûÄŽO€À|¸õÖ[[ßl®¸âŠÙsØg߯Ý|ÛMË/^þ¶·¿-¢HÏ{Þó–.]:©ÓÝqǯýëcß¿ü«¿<áÄÅ«V¯\~Éò³—Ÿ½ììÓO9ã”O[²ø”ã#x4ÁjL?Š”R–n:ê¸#<öˆl±OM¤¤Ó3Lª1MêBÛ˜Î6lð뢛„ @€ @€ @`¶Ęf[Øñ ˜ûÓ¾ûí{Óm7G’é€oìÿ;¿ó;‘FŠbK÷Ýwß/ÉÏþó/~ñ‹±×oþÖon·ýv·~ÿæ+®¾âÒ•—,¿ä‚s/<÷ÌóÎ8íìSO9óä¨Éy¦%§ž•™"Õ4ÁÇ.Õ6©Ý'r–3/8cÛn»ýöÛOp¼6#@€ÀXbLî  @€ @€ @€93ÆÔvê+  0eU«VÍq5¦=÷ÜsÙÙg\~ÕeW^uùû¶yïžð„È$½ï}ï{ðÁÇ}{ýÙÏ~¶ï¾û>éIOŠ]^ö²—ž~ÆiW_¿jé²¥G}Ä·ŽøÖ7¿}ð‡.<àà¯ïà~û}cß}¾þµ¯}}ïh{ïÿÕÞi}ëÀ-Þ¶Å;ßùÎ)_2; @ n¸áÕ˜ÆýÁa @€ @€ @€i Œcjûa••˜YYTnë­·~îsŸ»×Þ{]óu§œvòËÿîå‘IŠÇ[ßúÖk¯½ö¿øÅXo ëׯÿüç?ÿä'?96þ£?ú£}öûÚ-·Ý|Ô±G½bÓWDjšìC>2Y• µåižeè€OØèo|ãÌ^2G#@€@˜æ¯¡v'@€ @€ @€ P0©œû9˜ûIå"Æ ¡?þã?þŸ¿é{7->qñ‹_ò⌠ýÙŸýÙþûï%F¢2Ó£>úë_ÿ:¦{衇֮]»xñâW¼â¹Ùÿøÿã3Ÿýô÷ï¾í»‹Þäo7©&¦¼ü”§<åùÏþ ^ð‚§?ýéqßÿýßæÑžúÔ§>ç9Ï™ò‘ÛîhR¹9º¿†À@ ˜Tn /¯Á @€ @€ @€zE@Œ©W®„~xnŘ"Üóìç<û«û~õÆïÝtÒÒ“^ý÷¯~òo7Ê,Å#2C[n±åî»ï~Ì1Çì½÷Þ[mµÕ _øÂRiã7Þ{ß½¿wÇšS–òºyÝL¥‹¶Ûn»‡~øšk®Y¸páŸüÉŸl»í¶K–,yÆ3žñ¦˜ïÀœ©åqĘþ•e€æ@@Œi‚ @€ @€ @@ŒÉ=@€À t1Æ”I¦¯|í+×Þ¸úò«.Ûy—Ÿù¬gþöoÿvÛÀПøÄ§ÿáÓß²Å[N=ýÔ›Öܸdé’×½~Æ2LqÆ \|ñÅ/}éK?÷¹Ïí»ï¾¿ñ¿ñ|à ƒÚqÇ¿ùÍoþæoþ¦ÓÝ‘NC€À„Ę&LeC @€ @€ @€© l4õ]íI€ÞÈIåÊãþø>ý¹ÿ¼èÒ7ÝzÃ]°ë§>ùŠM_ñìç>;"Mdzžù¬g=ëEý¢í?¸ý)§|Ó­7^¹êŠC¾sèLÍ%Wºå‘¢ÓÊ•+£SÌm—ëwÛm·¥K—F¤if3Lª1õöªw @€ @€ @€ 0" Æän @``j1¦Èô<ñ‰¿µÙÿíèc>oŹW\}Åu7^wÃÍÑ®¿ñ–¢ÝpËõ×ßtݪÕW­¸dùIKOüðŽþý?øƒÏ}ò“Ÿ¼âŠ+¢Ó—¾ô¥o|ãyü˜Øî¬³Îšñs‰1 ìÍm` @€ @€ @€81¦»¤D€À°@kŒ)sBO}êS_ûº×~qÏ/~÷øïžxÊ’%'Ÿ°ä”F‹åã—·ßû½õío}Æ3ž1¡¢8æ[ßúÖ˜_鍊nŠS™Bn»í¶‹yåfãŒï}ï{Ý @€ @€ @€ @ ÷Ęzÿé!SØa‡:ƒžÐî1Y¢Ú1cò¸'>ñ‰qò²>;2ã§þíßþíOúÓSä³ @€ @€ @€˜C1¦9Äv*æV ænÛx~<ž÷¼ç=ó™ÏüÓ?ýÓÚp#Ãôë_ÿº­úÂ… 7m>baj—eýúõSÛ±ìµùæõ”CNðØÛl3t„\Ƚb@SÓ¨þÄ1׬™æ§ÞŸª@fµ7Ñ·¶ë'ÞãVÿ‰ïkK @€ @€ @€̸€ÓŒ“: æZ`Æ ^xáÃ?<ÁGziÁ‚«šm¶Ù&–'¸cu³Í§‚ÙxãúiË!'xìÚöùí{4Úô›núøªU£‡­­™ÈY¦ÖŸª@[èIôp:Vÿé; @€ @€ @€˜¦€Ó4íN€î L*Æ´hÑ¢Z)¿õ‘jÚ£™ŠJK±5Ãõˆ–/_žk–.]D §¨ü”•œjÇ–±WîËñ (b4ñdœ0‹'År¬Éoc!¾>òHce,ÄÊr˜QZ´hhÇ\({Å‘ËʽJ9¥ L*Æ¡¥Ì*ÕQ¢)ŸŠXRD”"® ¤Xi¤xÄB„œbM<߯r>ÇBl|*Žk2Æ9§“ÖEŒ&¦E‹8NăJr(¾Í€N$b!óL™pÊàQ)MûæÌk¹PöŠÁÅÆÖ‰ðM&ub9K+Å¡²‚Q5oTÛ&RGm4t´Ü+ÖäIc!ŽXkªOåªkb›X§ÎlVõQžÛäs÷8Nf¤R Œ.–³3I‘89–laÌ5 [Ž_ÎÏãĵçS)Ü:–oì5ÁBYóéõg¬ @€ @€ @€ÌŒ€ÓÌ8: º(0©SfŒZ{›A¥XÏÆLsÕ)çy䑈+ÅS%ÏËYÃ)K4åÑ¢žSìX]ÓÙ¤Z (絫MW7-B6µ¹ïÊ”je¡uR¹|ª:=\qâP­1¦Ší£cyê2…\ ?åšÖ§Ê–%'Tz••ª2ðìI9W,T³D¹K'j;ef«ä™ N¦âÙRö©vüê©«=ÏÍJ‚*1©ÚXªã³Ls&»Î·„g  @€ @€ @€˜ÏbLóùê;"0©Ó‚ j1¦ˆD5Æu•âÛ|D2)2LZÊåx*ÓNcН9Í\<²DÓbL%‘Óc*Ñ¥j¤)ÎÙ|ª,4;ÓXS(ej§Äzʳ­1¦ê6¹Wkâ'#GåD9êÜ,žÊM“*»³Œcʳ‡±W¶E~-£‹üP¬‰g³ŠRìR@òŒñl´ÌK•±äñ³·‰ºG­Õ˜2TbLYµ(ùT|›bCóÁM¤SÆŒ²ÀR>"®”ÓÌåXÊ0c³’èÊ(R ZµÕbLC‡nþ§ ³ô¼º&§ö«%¶l ?Ui™ @€ @€ @€3" Æ4#ŒB€n L*ưQ–MŠ…È0Õª1Åñl’b!&’‹ rû¨Æ ‘sŠmbÇØ&æ›ËóPQ·©cŠ-sã¶jÚ&³8YÍ(“4‘ÚÉ2E±&–cƒÌ U‹•oóø¹Wk5¦ˆe-¢,\²&Ž–ÝÈ,Qìžkrö´2½Z‰1e€) ÅK¤Ü7×äÆq®hÕmâÛœ®5fT6Žã4kc ¥”>ÊÉæÊ5cLÑÏZö<·ïcÊaæqªÏ#$NëXĘºùòvn @€ @€ @€óF`†cLW^yåâÅ‹gOʃ_ýõQ d¬~úé±Á”»ûÆÆ=Ë”?g;Ƶxì±ÇfötE¾ó%˜ÈI£o³z·L¤¶!0“1Ũ#oá¤x#…Dˆ¸RU#ª4UßfãÙXGn)y„œ].±P–˱¾ºÜJ]BBͳ=Ÿ+£S¥àPÒ¥Z^¨o*je^³œ¹¬Túi <åle¹c­@QíDÕøN9QìGhÛ‡RL(7.ñ r–ìX~›sÏÅfÙáêñ3UÍNµ]m›¶Y«ê]UMU#GÕüSn_ªCå·U̬¨”jÔ)ëBeZ«æ©¦Çªò­Óùå|‚µGµÃÕ^ÅrõZ”³”ÉûÊqjQ­ªŒeŠ€“› @€ @€ @€ú]`bL¥|QZä´k9›X†‡r}©WT%«Vú)¹–Zž&B6qÌêüqµèO5áT1mÃIÕþ”n”’N¹&ž}γä³"T<Ê wÕþä69äj«íèªÁ jE¢¶Õªª£¨v¾Š\RÝ`,Ì(”£‹þW§É‹oÛ²Wm‹I^Ù0*çªæ¨b˜­ ¤ê)ª÷C9KUµÚÉ~™é?Ù˜lŒiýúõ .Üc=-Z4Û}ëpü=ö˜îÉK÷«ãˆLiKѽ©œháÂÇyd*;Öö™~Ú^¥è[ôp:iú¯_ßpž¦Ò4q¦0@û @€ @€ @€ 0³Ó1e(§Vtg¬zH­³¹•yÇr6±Ro©3bCY+(žŠàK&oªQ¡,UŽ\ ÄÄS%~”“Á•I⪈9„œ7-NWž ùlNuÙl³Í2“޽òŒ¹q-ôÓvtÕmª‰ÚVŠÊˆXŽ¢Ì—uªE•r8Å*ûVŠEŸDÈ£•#d"ª”’ÊKYU›º®Š“+±Wémö°5ÆTN-â–Ã)“ÊUû0³w¼£HIŘ"ôñÆ/X° bLÛl³Í¦›nÚ-“7®Ÿyó͇֔…Î}+}Ï…Ü+Ò9Ó èäI㘫V:Dvjk&B7µþTÚ^¢èÉ4/]«ÿD†S¶‰qE©UiRqj8¥ÓG¨ ¹Ã7Á{rR†6&@€ @€ @€ @ *0ÝS­|N:")‹‰òBÕØP,Gº¥¦Ÿ•2¢!›͉xPfƒÊšLùÄ6qØj‚'–«ßÆ™ž‰ÍªYŸ¬ÔÚìO™ý-²ÏÕ³ä©óìq®øš{e'³>S°ÊÙsƒ¶£‹mJÀ¨º}mß:Ÿ¦èU³J72ÅUb!7®­•=ŽS2jÅ$ K9Qœ«ô°(U¯xu8ÕÎT{[[³¯vÛø–šÀ¤bL‘^Š S9BĘ֬Y“ß®j>ÊSe}.<Ò¬MT6ˆ8T,ÇײýX»u½"F‡Œæùc931™M)+c¡*Ë‘¡É¸R.”½2SÛ«Ùó‘ãĹJ¥¥rÀJ,Ç×ÄÁ«kâ©ÒóZu¨ÚÀc÷Ø2wÏTPK]Œ=;S(J!¢X+ cUa«7OAÎaÖpš—®ÍXÊxó\ùHÉšR9~Y¨ö'6Ž ]}t¾Xcõ'¡òk^∗•‹•Q³]v;£Nyõ+ù½Æ6¹2S½[µk÷d!/V‡ãªo @€ @€ @€O`ðcL0Ê FãQLîùÈEe£\˜Üζ&@€ÀŒ L*ÆgŽ$SdŒ"ÌÈÅš… –MY®©mŒ©l;f *¾F¤)Ž_sL™yšÈø²SnÊ W¬)å»r\e›Ì*å£R*gÌQ”ê\ÙùVíX™OUïɼŽ_•·L€ @€ @€ @€À¸ƒcŠ9Ñ"l4ÖtrãuØ i€éľ˜¾ÀdcLåŒñ©£Ì!EQ¥\Ÿ¦¶1¦Ì<Å#bLÕnÇöŠªF£ÆW9F‰†´Æ˜JÆ¥‰#Gh&³)e!–[+-eФÚÙÌú´Æ˜ªÛä^ùux¼ÿ–SµÎT)É+³8PÙ}سMŒ©úTœe£,­Œ¥:º,õÏ”U‰ÐOYŸ×§ k"©“½Ê…2¨RN©zêØ>~¬UÇlÝ+ð³8V«RkŒ©$º²oÕþT/Dq·?Õ‹•§«î’>µm²8SÜãÕ³§a¯Ê„Sé|M»<ÕcʧÊñǽím@€ @€ @€ @€ÀXƒcrí  0ð“Š1U+'…L$“Ê#¡"ÕÃM<Æ•œ"ÆT2,Å'šHŒ©ÄJ"}R,²;Y³§,ÄòX1¦jÔ&ò7Yü©THÊnÔâ8cL±q©ëSjÿd¨µìX²;¥ÖT¹k1£ZB+cF9–2º~))T­Æ”•œ2QT­Æ”çÊZAQj(cO±Pfö0¾–8nž:XK ';V®ËDbLe¼Y̩ڟ¶1¦qûSXJ@UCKe‰P®Td˜²DSÑ(‰®Ì6•qµj—§ZcLµã—«l @€ @€ @€É ˆ1MVÌöè9IŘ"o”sÉEÞ(H11Üš5kbedÊgãk¬Ì5‘jŠ…Ø8ÓN9ø˜].£Nñ5–c³,à 9ßÜ#<ï,ÕcÊŠAñˆ§"t’5u"Ê““‘e^¤L?—ÙÈÓäBÙ«5SªÅ¡ò¤±ù›ˆFåšœž,Ni¡X“›ÖjLñl†â¼¹{¦‹J‡s÷xäXb›Ø2ûßæ$zµSuãØ=ÓZyÀ2º ÖÄÑrñ5ó4cŠå$*IŒ1U9ÌX¬<ÖdÊ'0ÛŽ¥ZÃ)NZËTÿ2–êB0•µ›¢õb•vèO²§ÆÊšH*ÈY­*X­ {¥vjäˆòªµj—+R|òBäëø£è}C€ @€ @€ @€ÀxbLã yž=/0©SŒ&bFHвLñ5–s|‘dÊ R©«™¤ø6ÒH±&bIñµ:f¬Ïgs÷Ø8òL倉1•„M„{ò0‘ÅÉêAYÁ(“:ñTÎt–Ü«ÄhÊB¬Ì½b˲qIE„%3%ó”‡õYÕ©œ=ó@ñ(û–“ƾyüØ ÏUB9Ùó<~W®ÉŒQõ€ÕWÇ‘šÒ™<~utÙá uE+h¥'‘.Êþ´=þÐ ›­ñ-'r´ê6Ñ]wÝu¬nÌÞy'ÛÏ®lÿÐCu>ï¸t¥ÛNJ`€&cêŠÚlk³Úí •(U­fOëy«…šfµWƒqðêŒoƒ1"£ @€ @€ @€ @`6z1Ætúé§G„¨ÃhãÙ Ê\ýõpÀŒ»¬]»vûí·¿òÊ+ãøÕƒWÏÛ¹‡3Þ¥Þ9`\ÎæãnÐ;cÑ#0¨1¦êäesp±"ɳƒEËÙë:qäHÅ#V–ÅcMl•“ÊÁ3`ÈBÅrìOeu¥ÖkSíUž4ÖTO‘»´ž·Œ±Úɶ/'ãGgòø±¥žZûœa©ìpHìU’Âùhí|¢e9«µŒòÔf+aRÂ'6.õ“ª§(y¦’Œ‰sU£6Õ Oѯ–kÊ•cu ª!—«É8Q-ʨc¡š¬Ê«}¨n™ËeyüR䩊ƒdÈi¬Î…Vº]Û¡Õ[6+H•™ìâÚU§ºËaÆ6±ë«TÇ[íXlV;l¿Ht@Ï ˆ1õì¥Ñ1 @€ @€ @€˜¬À ĘªóµÕ2@Á‰tNLLVI¹A)ATº›ÅâÛR§šì)uŒªÇ/ɘê–e.¶8o)æ‡-á§rÆZ¨t Êí«ç­&uÊYÚ¼v1ª}¨–\Š,Tú$WîUê•…XYŠ0Õù*EégÛöí@µÃÑ¥œQ.I³‡e¯ZY¦2Õ]õ°e¼y„ZÛÃNö®µ=) ÆäN @€ @€ @€ @€˜S)ð“(XÉ9Ñ"=S&›++3îqœLäd´%·ŒÉÚr÷ئzœ¬á”ÇÌÂ?¯)ç¼N–>Šc–2Hµ°QkŒi¬Ôêå jç-a£rê±^n”Z¬ª0ûœ!¡œú-GWfÊ‹5iëKÑ£zåŒ%QÔö°m;P½­‹d†Ò?'΋…œ.°tu³Í6+W-7È©÷òBG -—óªåŪv`^NB`ŽĘæÜé @€ @€ @€ @`öf ÆTfË^f¡ œ‰,“+ñÈO®Ì˜Kmef˜"ÚRŽ–A™,/T›•Lõ¼™Ô)y 8Tdeʉ"&U¦B«RV{•ˆG¶,—kç-㪞¥íÀË¢¥$U®,}ާÊfee™“.“CµÑµÕ‹NVMªþ­‡«¥'%~TUÍã¤O,çÍ TV޵A¹ía«Å2xä‘G®m÷øÅ/~1ñƒØ’ @€ @€ @€ô‚À ĘzaƒÚ‡Ú\uƒ:Lã"@€ @€ @€ @€˜çbL=}D§Z±«žî®Î @€ @€ @€ @€˜’€Ó”Øæj§˜e/su6ç!@€ @€ @€ @€ Ð1¦î¸;+ @€ @€ @€ @€E@ŒÉÍ@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€.ǘ/^üØcÍÈe¸þúë—/_>#‡šþAfp\¥3§Ÿ~zŒqú}Ë#{tr¦Žæ8 @€ @€ @€ @€¦#ÐåÓöÛo?ÞW÷PN}fêhÓ9N$„öÜsÏé¡í¾»îºëm·Ý6S‡DTp¦Žæ8 @€ @€ @€ @€¦#0“1¦‡z¨µ+k×®m]™[F(§–¤i{„¶Ã›ø–ÑiÛÉÎ;Nj—‰÷¶ÃaKä«õhc¿íú\©¯Ã;l\œj­¬I yÜ#Û€ @€ @€ @€ @€@˜™S’âQ›މ LYY¦{»òÊ+seylذÁÅ#@€ @€ @€ @€ @`0FbLwÞyç7¾ñ‹ûáqÔQG-_¾|0.€Q @€ @€ @€ @€ 0*ÆtÈ!‡¬é‡Ç’%KĘܻ @€ @€ @€ @€F@Œi`.¥ @€ @€ @€ @€èW1¦~½rúM€ @€ @€ @€ @``ĘæRN} ëׯßxãÍÓ7uÁnï—/›o¾ù6ÛlÓíî8?^Xºt馛nš¯Ž ôJ·ôcªïÃñV3ôâ(©·Ê]W~è­þéM ì±ÇÕ{&Þ©z¬ƒº3Pñ¿–q•w'?êêvL\÷x·)›ÄrõÛùã`¤ý"wìªU«ú¥·sÜω·ñ9>i/Ÿ®ö†jðG†^¾^³Ñ7¯ˆÙPuÌ® ä/íÕnÄÿ·Øõë2ÙÄE\¸paÙËo8UÀÉâ«ÿ7™ì­eû(x‰Û;‹-êñëÉ ˆ1MVl·Þ~=íëëZýŸˆ1Ugíëqé<éÄçgñÒ(›ÅKÃÿ¨LÇÓ¾âf+Ä›°¿oºaæ@ z×ÍÁ霢ß„ úý öQÿã·¯ê?’‰¿£ù±ØG—oš]­}6àgšžvŸm¸cŘÆBcªÉTßÐ|:Û¯ÍÞ<¾ßgzóºèÕ4Z?ùδÇ4k÷9È@Õ ò¼~Ã)þñã;4Ræ‘G‰A¥çøætºY¨þRZû8lVÏëàæL@ŒiΨ{÷Dùƒ¼ü8ïÝŽêÙÕÿ‘ö—b· ˆÿ-©ÆÏã].Š3Á!0Kµ@IÜ~¥³Dí°E@ŒÉÍ0)¿"NŠËÆÓhýgþEàt<ûk_1¦þº^zëC¾÷€S §ü*å_ºÏÛ·1¦y{é{àùË[)¿¿·Ç/óbL}wѳS¹Ž~éþ鬤»be$™¼™÷Ýí­Ãjÿîµïn<1¦Á»¦“Qü}"†¬TÉäìzfëøÝ+ÿžQ­g.‹ŽtYÀü]¾óìôµûM\`ž]ÿî 7îºüå-fîÎe蟳æß¦Ë ¼ëŸ¾ëiŸ ø¬Ï.ØŒv·Ì×ÿ²?ÿGuFÏà`fRÀú;hŠ1ÕpÊßÜ|º?“/¾:–O¾ûêréìDòGa¹½ãÿã_z£›(_Ïl—W°ü£J¿áä•iûË œž¹mudâ~Ž?Ç­x÷®Ve›£;˜ÓÓg>ó™×¾öµ/yÉKâëÞ{ïÕæ§öX²d‰jfêæÉ‰–â=Nµÿ™"ûãäGyÆœ{gìM¡õæuÔ^‰1 ê•íåq‰1õòÕéÁ¾‰1õàEÔ.U&æì²,ƒz­[ÇUý+jüÿ©+5.}ŸŽÔçX.œS '~•Šgùg7Í>}ÉO³ÛbLÓ´{o äÂø„(ë§Æ[\|+ÆÔ›«C¯ò *ÊeˆÁo8i%ÆÔww²OV úïˆ2‡:Ù#Øž@ ÌQŒé¤“NzÎsž³ÑèGä™bý’LbL3xW•B>åÈgðà57µÿ‘öÿÕsÃî,=.¿ÃU¯ñ¿pñÿä=ÞgÝë_ZŒÉ¤rý{)û¨çš}t±z¡«ªÄõÂU˜'}¨M죮Õ9Ÿ'ós˜&•›Ÿ×½GíC¾Ökõ³d£S '«1ÅÊüØ?¯íßþ”{îÏ­S¦³c/ 䜯#’Lñcêåë5VßÊTN-ç7œ2µZÔÊÕôã®Ïc øc‹{càæ"ÆtÉ%—” S,TóL‘dcêâM¿ÖT?×ÏTÔÅþ8õÔªÿ#×Ô?˜˜£½L k —ÿQ‰÷:1¦»Ä=5œj $þúãï›=uuµ3bLƒzegi\bL³ë°­ùs°|¾›÷*\1On1¦yr¡f˜>äk½”ñ‡Áüg“ Õpª¿J…’¿¼ ÌûÀÄâó'neË>(? sFàè¹S]¾ÒÕêT|ÀÕ$â:öã@f¼ÏA®~"à‚vÀî ˆ1u×ßÙç@`.bL;í´S–aŠÐRDš"·3Ê•ÂLS˜]N5¦™º3jÕJâ°ÂÈ3e;—Ç)“5Ä‚?ÃÍ¥¼sõ¸@ü1ÿ'<2L=~±ú½{Õ÷áø{AüªÓï#ÒÿÞ¨Þu¹Üû}ÖÃ. ˆ1už:?ü· Ó¼ºjs-yç™WW¿›SçôcÏgµÏåÝÛ´UçÚšÏAgõ&ì̓×þÿ«7;©W&+P~FÚ#ÿ}{üdôÝ'ËØõí«ÊFâ7œrQâÞÎOÍ|@ÐõUf\ÀdÇ3Nꀽ&01¦-·Ü2‹0UKiÊ$S„œ&[IŒ©×n#ý!@€@Ï ”ôì¥Ñ1 @`°âoèƒ=@£#@€À@ øŸè¼¬E€æ­€ßmæí¥7púZ`ê1¦L&Å£5‡ôÚ×¾6ŸŠS‰(e¦ò(SË}æ3Ÿcêë{Hç  @€ @€ @€ @€LS`ê1¦(Ÿ›å”"TÍ!E\©D”b²ð¶¥±ö`žI5¦i^u» @€ @€ @€ @€è)©Ç˜ÆŠ+Eq¦Œ7Å´q­±¤x¶„œbᤓNš`t©º™SOÝC:C€ @€ @€ @€ @`šS1E®(&ËÄRuò¸Î³ÅE¶)w‰Gì~öÙg‹1MóÚ @€ @€ @€ @€@¿ L+Æ´÷Þ{׿•‹YäÚÎ4W²J1\dŠØSÙìàƒžl’I5¦~¿íôŸ @€ @€ @€ @€@U`Z1¦ˆ•ÚKiŠoK>©ZŸ©mJ©Ì=GcrS @€ @€ @€ @€˜ÏÓ1•4RÌWM5EY¦Îá¤K.¹¤D N:é¤I%™TcšÏ·¬± @€ @€ @€ @€ žÀtcL%™¤˜.§Š{ÉK^R%Å6TÊrMÕ‡ÓàÝOFD€ @€ @€ @€ @` Ó1E,)ê0•ôR.|æ3ŸiWª&™¢\Sn³Ï>[5¦)\<» @€ @€ @€ @€ ˆ1UI‘IŠKµLRÉ9ÅS9\ÔgŠŠMmK7M$ÏdR¹Á¸ùŒ‚ @€ @€ @€ @€@ Ì@Œ)‚Gez¸H&m¹å–µ(R[*ÄB>J)¦˜Šn"Ñ¥ê6bLn_ @€ @€ @€ @€ƒ$031¦vÚ©Ä’¢8Sk,)²JÕèRnkªÓÌM<Ì$Æ4H· ± @€ @€ @€ @€˜™ÓêÕ«#É”i¤Ï|æ31—\>b9¦–›xtI5&7+ @€ @€ @€ @€A˜™ÓÔÒHSÞK5¦A½‹ @€ @€ @€ @`~ ˆ1ÍÏënÔ @€ @€ @€ @€zH@Œ©‡.†® @€ @€ @€ @€˜ŸbLóóº5 @€ @€ @€ @€cê¡‹¡+ @€ @€ @€ @€æ§€Óü¼îFM€ @€ @€ @€ @ ‡Ęzèbè  @€ @€ @€ @€ù) Æ4?¯»Q @€ @€ @€ @€è!1¦ººB€ @€ @€ @€ @`~ ˆ1ÍÏënÔ @€ @€ @€ @€zH@Œ©‡.†® @€ @€ @€ @€˜Ÿ#1¦ 6ìµ×^‡ôÃãk_ûÚå—_>?/˜Q @€ @€ @€ @€<‘SŒ-’LwöÉc𮄠@€ @€ @€ @€˜·£bLóVÁÀ  @€ @€ @€ @€袀Sñš @€ @€ @€ @€†€“û€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º,0ÑÓ‚ V­ZÕåÎ:= @€ @€ @€ @€}.°ùæ›·Ž`B1¦È0m´ÑFbL}~è> @€ @€ @€ @€n ¬_¿>2Lo¼qk'Æ1-\¸p=öØtÓMŘºy › @€ @€ @€ @€@Ÿ l³Í6‹-šbŒ)Ç.ÆÔç÷€î @€ @€ @€ @€è 1¦ž¸ :A€ @€ @€ @€ @`> ˆ1Íç«oì @€ @€ @€ @€zB@Œ©'.ƒN @€ @€ @€ @€˜ÏÓŠ1m¾ùæ«V­šÏ|ÆN€ @€ @€ @€ @€Àô¦cšþé @€ @€ @€ @€m6âB€ @€ @€ @€ @€î ˆ1u×ßÙ  @€ @€ @€ @€x\ŒÉM@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ @€]cêòpz @€ @€ @€ @€ĘÜ @€ @€ @€ @€tY@Œ©ËÀé  @€ @€ @€ @€cr @€ @€ @€ @€ Ðe1¦._§'@€ @€ @€ @€ @@ŒÉ=@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ @€]cêòpz @€ @€ @€ @€ĘÜ @€ @€ @€ @€tY@Œ©ËÀé  @€ @€ @€ @€cr @€ @€ @€ @€ Ðe1¦._§'@€ @€ @€ @€ @@ŒÉ=@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ @€]cêòpz @€ @€ @€ @€ĘÜ @€ @€ @€ @€tY@Œ©ËÀé  @€ @€ @€ @€cr @€ @€ @€ @€ Ðe1¦._§'@€ @€ @€ @€ @@ŒÉ=@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ @€]cêòpz @€ @€ @€ @€ĘÜ @€ @€ @€ @€tY@Œ©ËÀé  @€ @€ @€ @€cr @€ @€ @€ @€ Ðe1¦._§'@€ @€ @€ @€ @@ŒÉ=@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ @€]cêòpz @€ @€ @€ @€ĘÜ @€ @€ @€ @€tY@Œ©ËÀé  @€ @€ @€ @€cr @€ @€ @€ @€ Ðe1¦._§'@€ @€ @€ @€ @@ŒÉ=@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ @€]cêòpz @€ @€ @€ @€ĘÜ @€ @€ @€ @€tY@Œ©ËÀé  @€ @€ @€ @€cr @€ @€ @€ @€ Ðe1¦._§'@€ @€ @€ @€ @@ŒÉ=@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ 0ß?üð×t|üMóÑy›yõì_þå_nºé¦‡|æ™gÎ÷Ëø'# Æ4-Û @€ @€ @€ @€ƒ(qœÏé«K–žUÚ §œ•mñÉöÖ·¿kË·¿ëø“Ïj'y\³{âюɶ$۲﷣OXmQ´ÅÃíøeG5ÚéG·#Ž?ýˆã¢íðc‡ÚaÇœí;ÕöÝS¿Ýlß:z¨ºhii‡,ZÚhGòÍf;8Ú‘ÙN>øˆ“j¶›ma´Ã‡Ûa'ã°“¢ð¡öõïœôõmÿoµý¾µ$Ú¾Ñiúçñ¡þk‡,i¶öþæp;ø„¯6Úâ·¿g‡­·Þzocš-1¦Ù’u\ @€ @€ @€ @ _"Ɖ¥µülí–vÏýfûÁýî´àSÑî¾ï§Ñîºw¨Ý¹á‘lwD[ÿÈíö“Û×ýäûÍvÛÚFûÞÚïžF[Ól·þ Ú¢Ýrw£Ýí®hßí·ol¶îˆöP´ëoo´ëšíÚïÿ0ÛêÛíšhß{0ÚÕÑÖ<¸ªÑ¸êÖ¡¶ò–¢]yËývóýW4Ûå7E»ï²h76Ú¥Ñn¸ï’îvñõvQ´ë¢mXíÚ f[½aùêõÑ.¸¦ÑÎo´uç_½î…/yù>‡.9wÕºhç¬Z{ÎUvv´•kÏj´{>þé}Řúåþï‘~Š1õÈ…Ð  @€ @€ @€ @ kcŠ’K%·TÒK`úA3ºô±ŸŠvw 0ÝûÓ‘S%Ô¦Q¦fŒ)3Lk¦FŒit†éG Ó]C¦fŒ©™aªÆ˜Fg˜1¦’aj‰1­¼µ‘aŠ1 g˜®hd˜š1¦Q¦ÖÓ†ZŒ)3LµÓyˆ1í,ÆÔµÛ¹_O,ÆÔ¯WN¿  @€ @€ @€ @€™ˆÓñ'ŸÕ -5rK]i÷Ř¢Ó¨ L#¦GJ¦IÖaÊ0ÕJ1Ê0M¶S3Æ4ÙRLÃÕ˜š¥˜*Õ˜†2LÕjLW¯ËSL'׬Æ4ªS³Ó=ÑĘfêæœ?Çcš?×ÚH  @€ @€ @€ @€öÍÓ™C¹¥á’Keò¸XøèÇw‹64\3½Ô:‹\ 0•¹äjE˜&P‡©QŠiò¦‘åÚ–bjÖa]ŠéƨÃ4ÅRL1£\5ÆÔvF¹³®còZ›´€Ó¤Éì@€ @€ @€ @€ ˜@ĘŽ;éÌÌ-ÝY)¹TfŽËS%½ôÈíë‡æ«Î"WLe"¹æ,r#ÉÅtr7G»+Zc"¹R„©9—ܬd˜®¸y8ÃTŸQîÞKn¸7Š0e»èºh-ÅT‰1UJ1]µ¶”b:³czËÛ¶ jû¯_ýzÀîÙA1¦Ät( @€ @€ @€ @ /"Æt̉gÜe–ª­Yr)«.íøñÝ¢Et©:y\kù¥’^Š:L#¦ü(ÒK•Sû‰äêu˜¾ÿеßÿa¶Õ·5Ú5Ѿ÷`´«£­‰ LÙ¸êÖFk[‡©s†©Ä˜.jĘÚg˜bR¹ ®i´óm]–b*1¦±J1cúÙÏÕ—÷‡Nω€Óœ0;  @€ @€ @€ ÐÃÓ’3"®4Ü~ÒH,UBK;î¼[´Zá¥ÖÚKYä†Ë/•)ä:˜Æ*ÂtÝèÓd˜†bL×n¸0Ûê `+Ãtîªu/|ÉË¿vÈ ç\Õ¨Ætv³Sµ“Sßì½Û51¦Þ½6zF€ @€ @€ @€Ì@ƾ»dY¦”ªí¶uCs¢}dçÝ¢ å–Öþ8ª.ekä–²UÓKÃå—êSȵ›E®aºîö‡­¥S3Ã4\„©Z‡©Y„iFê0™aª–b®ÃtÞªucÚû›S#Ã44ÜÚ³VÞ¦lm'•Sinîç>=‹SŸ^8Ý&@€ @€ @€ @€fL bLGŸ°,RJ¥}/²J¥ÝóãìôÉhµÜR5ºT­½Ô¹üR³ÓCÙ®¿}¨e†©6‹\k¦á¹ä†L%Ãtå-\yËýWÞ|Ì"×h7Ýy£ÝwY´íÒh7ܳÈe»øúF˹ä¦aªÇ˜VF€©‘a:k8Ã$Æ4c·æ|:Ó|ºÚÆJ€ @€ @€ @€´ˆÓ¢ÅËFJ+UË,5—?¼Ó'£ÝZ)¹ÔÈ-Uª.U£K7GÕ¥lw>¡¥Òn¸c(Àtýp€©c¦^ó½Ö"L¬j[„©’aj˜š¦`ªd˜2À4Í Ó9«Öf5¦j¦j†IŒÉël bLS@³  @€ @€ @€ 0Pc:êøeÃ)¥GD©Ö"ôÃÇ>Y¥j»ùî5Ú]Ù†£KH/E¦áÓÇ©ÀÔn¹F¦[­^„éæ±Š0 ÕaÉ0]רô"Ûµ.̶zÃòÕë£]0ö\rQ‡)2L1—ÜPŒ©]&“Ê Ôkc#Æ4‡ØNE€ @€ @€ @€ô¤@ĘŽ<þôZJ©|Y¥È0EN,5rKCõ–ÚU]jNW™9®eò¸ë¾ß&½ÔœB®Q~)ÚÕÙÖ<¸ªÑF*0•Y䚦Ê,ræR„©ãDrækG2L`jd˜®i´ómÝùW¯;/Ûªu`*¦ˆ1½ ª1|Bë\r™aR©'oó^ïÔ„bLË—/_¸páš5kz}4úG€ @€ @€ @€˜¼@ĘŽ8îôjJ©V`éCÛ5ZÎW›*.çŒkæ–:E—¾~Èw/¿þY{é¼Ënþäg¿ú­£OèR3½ôÃs.½é“ŸýÊIç\YI/5L‘[ŠöÍ£NùàN»ïòé/ŸqÑcT`jÎ"WHî†û–^pýv;îöé½îô©½&=‘\%Ô¦s›E˜¢5&’kƘ¾Úˆ1 …–JzIŒiòwß¼ÛcQó±~ýúÚÈÇ1m¾ùæÛl³Í{ì±é¦›.]ºtÞÉ0 @€ @€ @€ 0èÓ±§eD©mJéCÝ5ZÛÄÒ w<íúJÉ¥‘9ãbò¸fnié¹+ŸýÜçsÊZ:÷²›ÿúoþöÃ;ÿç›ßú®wo³CÔ^:tÑÒxv‡vó–ïzÓ–ïÊ L`Šö¢—lòÆ-¶úàÇvßê};<ë9Ï;áŒË¯¸ùþl—ßÔ~¹KohÌ"÷ª|Ã;¶þÐß9éßÞò΋®oT`šH®Y„iÑÒKßÿáOŽaj;‘ÜÕõ"L ÓÊFkƘ·¦—Ęýµ2Ýñm¼ñÆ ,È$R-É4NŒ)*0Å>yþU«V•åéöÈþ @€ @€ @€ @€žˆÓaÇœ6\QiT]¥L)}ð£»FŠ+N, - ç–²êR¶ˆ.ýÃëþµc:ù‚(¼Ñ¥(¼”3ǽè%{ö%7ýýkÿõ {œé¥-xÖeò¸H/E†©1\s ¹Ï}å ø6LÇ/»ìðÅ眶üú˜?.Úq§_é¥ïα§_¦cN»ô½É§÷\¦ïžzi˜N:ÿÚC9ûÄó®½ðÚ »iáÛßýÁ3.½í‚1&’.´îœj¦•ks"¹ˆ1}EŒ©gnà~éHL¦ìm$™âQíùøÕ˜ÊÖq (ËÔ/ÃÖO @€ @€ @€ @€À"ÆôcN@ÒXíƒ;îúw½.RJÕöý¡bKÕÐRæ–ªíÝQõè³_‰ÄÒwO:?£KGÇB#´ÔX^tÒy]:êÄóJí¥ƒçyQ~)f‘{泟·×GÆDr±ðïïùзŽ=û¯þúe‘aÚ}…±}‰¯{ìDd˜^ù¯ß÷Ð%\³þüF[wþÕëÎnm'’‹"L™a:ëÊ{^ðb1¦ Þ\6k/1¤˜Z®úÜDcLQŠ)j:µNJGš @€ @€ @€ Ðïcj(Å”p9+ÜvüD´Z\©5±饨·tÍmF±¥l1a\LWÒKÃÑ¥ósÚ¸ 0}h§Ý߸åV‘[ŠSÄ’>ø±Oeí¥H/Å·GDŒixò¸Ëoºï²›…—^øâM.½ñ¾h ;ù/Þ$Ê/EŒéœ+n¿øú{#À´íŽ»]tݽ/øë—zìÙÑ"·å—"Õu˜b¹%ç®þÔ—¾ñÍïže¡†2Lc˜Î‰YäšÉ ˜VÞ“ÓÆ‰1õû=ßÝþG€©uR¸ ŘbÏÈ0E’©»pv @€ @€ @€ @€ÀlDŒéÛß=µCQ¥í?ò‰hµ2KµÄRæ–"±4ÔÖ<%—¢ÞÒ!‹–.:éüH,}á«•èRN׈1-9/L[½ïC¯ù§7lõÞEkä–š¦˜9.bL1s\¦—rò¸S—_¿óî{½së]rÃ}‘^ÊS¤—"¥_c ¹(¿´íG>å—"½SÈEkĘVGŒéO"Ã-¢KÑ2ƘJ¦±f‘kf˜î‰–&1¦Ù¸çÕ1c^¹Ö SŒcÊô“:Lóêv1X @€ @€ @€ 0¯"Ætèѧ6cIÕ6RT)cL¥ÆÒ¨¸Rä–š‰¥œ'n¸=õ–¢ÒR¶$½ë};\xÍ]oÜb«Ïå æœq¼ð%›,»è†e+nX¾êÎŒ.E™¥Ó.¼!L]Š“ÇÅÌq‘^ÊÚK_9ਨ½ôãÏÉ L‘[:åüë^ð×›Dz)bL]·!ÒKQ~iÛ2Ê/UcL‘^ŠS˜b ¹?¹ÇÁGŸù¾vÍYä:˜†f‘«f˜TcšW¯Ž™lÌ%¶Ç'Æ饨è=š… ÎlÏ @€ @€ @€ ÐuFŒiÑÒ‘BJÕ¢JÍ”ÒvþD´–¬R†–‰¥U·6BKµõ–í–F‹ÂKG.9/f‹;øÈ“#«tä ç.øÏ/G¦ˆ.}î+m¶ÅV‡/>÷ãÿ¹×«ÿé ¥ðR¤—Î[yG䟶ßñS]úô^ £ðÒ—82ÒK]ŠÉã¾uÜ9¯ú‡7Dí¥0EŒ)2L+®Ýå—Þ?c:䘳¢Ež)ÒKo{÷_ÿæwüÝ3ãëÛþã}æ_¾èe‡Ÿtqf˜ÎYµ6æšB®Ý,rbL]¿K 9#\Æâ±|ùòê Æ‰1ÅÖeO1¦¸  @€ @€ @€hˆSLýV©¥4NʈҚ¶ûð.ÑZƒJeM5±”¹¥(¶¡¥¡vóý»üç—KÉ¥ƒŽ89j2}ࣟ*U—>ûå7{Ë;?¾û^¥ðÒ¥7Ü-§ÛùS{½êß°ÝŽ»sÚ¥9sÜÙ—ßé¥h»ï¹0ÓK]ŠvÆ¥·í÷­%Q~食ÜcÙ%·E‹ÚKQéükÖí¸ëQé#»î‘˜>ò‰=>ò‰/ 0­\ÛœB®}&“ÊyíLS bLÕ$ÒäbLÓ<·Ý  @€ @€ @€ @€½/1¦ouJÛ”Ræ“¶ýð.ÑJi¥ *•6WŠÜÒÍC-'‰+­™XÊÖ˜-®Zr©mt)LZ*-ÒK]­1sÜPkæ–²En©´ V7&Ëùã"½t~sæ¸Úüqç—_ªÀ4áS†™^ðâ—åàŵMÕowþô¾oyÛV·­ýIµýìç¿êý›A»%0N5¦nuËy  @€ @€ @€ @€s&1¦ƒ @€ @€ @€ @€³)1¦¯礋®‹(R¶‘@R.¿÷6fJixJ¸¨®T/°4\l)RJµV -Ô['·´n"Ñ¥³VÞÓ!„4ý§Ä˜fó~œ§Çcš§Þ°  @€ @€ @€ @€"Ј1}ûÄ !µm[àãÑFMW›®]u¥’[jM,u-5ª.­Š¸Ri£f‹;'ê-e]ui¶£KÕð““—ÏŒ ˆ1Í8© @€ @€ @€ @€}&1¦ý¿}bÌòVmÕâIïÙþãÑZ+*u*åôpÃsÃLW›!®%´T¯·TË-U'Œ›Ëè’SŸÝÖýÖ]1¦~»búK€ @€ @€ @€Ì´@ĘöýÖ’¡šI«×7š ¤Ò2ÆT[Y¾Tž.²JmâJõ2KYo©^l©sKµyèTcšé{Ðñcr @€ @€ @€ @€ó] c:tÉpiÝùEÝÞ½ÝÎÑ2™TZ£ŠÒXmÔ”p¦‡‹ÄÒ¡¥µQi)[-BÔ ßŠ1Í÷×Ì,Œ_ŒiP’ @€ @€ @€è+ˆ1ísè’±¤Œ17f8iTPi¨ºRÔXjF”ªíì«Öµ•kcn¸lg µÞ -µ§Ä˜úêïΊ1õÇuÒK @€ @€ @€ @`ö"ÆôµC–Düh¬öÛííœvɤ1ƒJ™X;®Ô¨´te/VZšHµ'1¦Ù»çí‘Řæí¥7p @€ @€ @€ @`H bL{ó„‘RI¥fÒð»¶Ý9Zk!¥v)¥‘ÉàʬpýW+Ò$ÆäÅ3ãbL3Nê€ @€ @€ @€ @€@Ÿ üË¿üË‹^ô¢3åãÕ¯~Í&/eµ=ç¹Ï{Ö³Ÿ[[Ù•oÿèÊyk'ý½ßûÿþê/îГçýÙó·~ÿ‡n[û“jûÙÏÕgw†îΡ€Ób; @€ @€ @€ Г6lX^yœwþGŸ°¬Ö?æäÖ•s½fÉÉß¾ø%s}ÒŠèÀD4n¼ý~1¦ž¼ß{´SbL=zat‹ @€ @€ @€è–Àýê×µüM|{Áš/²j£Ë¾Lôg²ÝP©[·t_œWŒ©/.“N @€ @€ @€ @€s'Л1¦5÷ÜÄ51¦ï^÷‚Éæ‡zd{1¦¹»‰ûðLbL}xÑt™ @€ @€ @€˜MÞŒ1e)¦l}ZIŒi6oÛ¾?¶Sß_B @€ @€ @€ @€fV cL¥SƘú´ “ÓÌÞ¨v41¦» †C€ @€ @€ @€LWàÿýú×ëxtí?ëÐnºóGwß;Î60©g/¾ý«¥S.¬ºûøIaV7þÁý^ÇÃãž"òaÓ½6ö\1¦Á½¶FF€ @€ @€ @€ „À¯þßc‹®{F-Æ´äæ Äà ‚À€“[ @€ @€ @€ ÐÓ×ß»_-ÔßÞùðÉ=Ýo#01¦ÉhÙ– @€ @€ @€ 0·mK1eŒIA¦¹½Î6»bL³ëëè @€ @€ @€ @€é<üØ-«Ö}6ÛÙßS¤—–ßùž²æÑ_n˜ÎÁíK wĘzçZè  @€ @€ @€ @ “À­1¦u?YމÀà ˆ1 Þ55" @€ @€ @€ @`0ĘóºUS@ŒÉ@€ @€ @€ @€è1¦þ¸Nz9%1¦)±Ù‰ @€ @€ @€ 0çbLsNî„s' Æ4wÖÎD€ @€ @€ @€˜Ž€ÓtôìÛãbL=~t @€ @€ @€ 0$ ÆäV`1¦¾¸†F€ @€ @€ @€ ”€Ó@]Nƒ- ÆäŽ @€ @€ @€ @€ô‡€S\'½œ’€Ó”ØìD€ @€ @€ @€˜s1¦9'w¹cš;kg"@€ @€ @€ @€LGà?:óU­Þ°×tb_½) ÆÔ›×E¯ @€ @€ @€ @€uŸüâΈ1­Z÷Y4O@Œi𮩠@€ @€ @€ @€ƒ)ð‹_=¼jýçÖÿdù`Ϩ淀Óü¾þFO€ @€ @€ @€ @ Ęzà"è @€ @€ @€ @ E`óã6§B`þˆ1ÍŸkm¤ @€ @€ @€ @€@߬Z¿JŒ©o®–ŽÎ„€ÓL(: @€ @€ @€ @`æÖ<¸fÓÃ6¶èºEfÚfé6±+7>`ã<É• ÷¸hXˆg£å–3w~G"Ð1¦. ;% @€ @€ @€ @ ³@„“¢ SlÑ¥Œ(Å·Wʽ"Ø´üÎåñ5òLñí#¿x¤<–@Ÿ ˆ1õé…Óm @€ @€ @€ @`²ðR5ºT*0Åú-­d}l5™²‰1 òÝ0?Æ&Æ4?®³Q @€ @€ @€ @€ý#¥Œ%U£KQŸ)*0ÅÊ 0eÂ)¾F‹õKo]Ú?ãÓSmĘÜ @€ @€ @€ @€Þ(E˜rò¸ì\†–baÁ9 "Ò fŠ…Ø, 2õÖô†À$Ę& fs @€ @€ @€ @€À, d5¦E×-Š|R9U|é¥hQx)ª4ÅúXÈ52L³|A~.ĘæBÙ9 @€ @€ @€ @€è Æäö @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ Ðþ׆ÓÖ¼f̓‡÷Gwõ’ÀdĘ&£e[ @€ @€ @€ @€@÷~ò‹;YµÑªuŸí^œ™Àl ˆ1Í–¬ã @€ @€ @€ @€fV@Œif=­§æWŒécûØF&/°zõêžzݶíÌÃ?ü‚ýÍ™gžÙû]ÕCs&pçwþùÿù«¾x Ï™‰ @€ @€ @€ôµÀ}ÞõW/ú›ƒÙ¾¯G¡óÚ Ì¯ÓÖ[o½ß7Y÷àÏFµ~¶v¨=ºï7yÛ¿¿kíÞsÿHûÁý6Ú}Ñ~íîÒîýé]•vç½?½sÃ#Ùîȶ¾Ñnj?¹}ÝO¾_i·­ûÉmk‡Ú÷Öþ¸Ñîi´5¥ýàÇ·µÝúƒÝr÷H»ùî5Ú]vÓ]µ;¾±Òn¸ãáîx(ÛõÑnj×ÝþÐPûþ¯­´Õ·ý°´kn{ðšï µ«¿÷`£­i´UCí«ni+o}`å-CíÊ[¸ò–ûíæû¯¨´Ëoº¿Ùî‹vY´‡Ú¥7Þ×h74Ú%7Ü;Ô®¿÷âJ»èº{/ºnC´¥]»áÂJ[¾z}i¬^Á5CíükÖ7ÚÕë¢WÚªu玴µ‹N½üÿèYç\µ6ÚÙÙV®=k¨ÝsÖÊ{μòž¼øåË—/ïñwÈ0ýÍ&›uÂÙÿÚ7H2õøÅÒ½9ˆ ÓßlòŠãN½0¾J2Í» @€ @€ @€ÌžÀÈGÃÿä£áÙcvä® Ì»S•"¥Tk÷ ç–ö=à·þû»2Ã4fz)bLõÓPzi$ÃÔ 0uÊ0 ˜"É4¦áÓÄ2L?ìœaZµ¦CŒ©C†©cjd˜†cLC¦fŒi$ÃtÃè Óõ‘acºvÊjŒiõ†Ž1¦F†©cªd˜Ö³j$ÆT2LÃ1¦F†©_bLñƒê¥›lºø´ #ˆvÅ ë^ãÇU×ÞQ¸‡"ï‹3.\¯‹«nÉË$™zèêè  @€ @€ @€À|4<4»ô—Àü‹1pHµÒÒH\©™[ÚçëS½êR–_]Š:LwÞÛ’^®À4Á"L·UŠ0µ«ÃÔ(ÂÔ¦S³ÓÍ¥S,t®Ã4Í S³Óp¦X?Ã4“¥˜1¦Ù*Å4~ŒéÊ>¨ÆÔøAõ·‘aZµµ"®´Ë¯—dê¯÷a½yF†éo7=sŵåu±ü*I¦™wvD @€ @€ @€9ðÑðœQ;Qæ]ŒiŸ¯³}J©™UúÚ׿1¦¶¡¥œ?®L7jò¸úüq1‘\} ¹˜N®L!W«À4͉äÆÉ0Mn.¹–:Lsœašt)¦‘éä¢&S™N.š3ÊSŠ)&’ËIå:”bêñIå†~P¾"êl•¸FdÎ.½ní«ÿQ Á.¾µ:u72ÃtÖE×–×EÌŒ¯‹ V~_M¦n^ç&@€ @€ @€˜ª@ëGÃù˜†§*j¿˜w1¦*e ©m‹g·|û»š•–êÅ–Úæ–*U—ÚG—¦–^jSéî¬Àô£›J¦;§[„)S/¥]sÛƒÓŸKnZu˜&ašÖtr‘aj1µrm³ M'¦Œ1ºìœþøç¥ýìç¿ê…tþ :áô×ßþÐuߊ1åϪ«n}à’k#ÉôúÓ—Ñ ]Õs&¦³/º¶ùºh–(»í‡åuqþÊï¿øe¯Xuõ5sÖ'"@€ @€ @€ 0M OÐî}$0ïbL{ïÿÍZE¥ê·ñì–oßꎨ®TÚúG"«TÚíë#®”í'Yr)Zd•ªí¶Ñ…—†fŽ‹ùãîjkîùñPûÁojmæ»%¢KÃé¥Z€éÆIÏ"×ø8?rK¥0_„iÕ­#sÉ­¼õF»¥Ñ®l´ûíæF»¢´›î¿|¨ÝwùM÷]íÆ¡vé÷5Ú vÉ ÷–vñõ÷–vQc.¹ÑÓÉ]»aŵ.,mõä2Lç­ZwîHk˜ê1¦•kÏ®d˜Îj˜JŒéè–U‹iÅ=Óõyþ Z²ì¢š“–RL͸FãbÅE¹hõ=¯úÇןrê²Iõvýúõ›o¾ùÆÍG,¬Y³&v_µjU®É•ñˆ•e³òÔÃ<ãòåË7ÝtÓ|v›m¶É•±I¬,]Š#çѪ,çÍ•±}ŽO—ª O|DñYU~œŸÅAâcßÖÝ—.]š+ãS¶üÌ7¶ŒÏ£'~"[ÎCycúê~߬ƒjËñìoߪ’UWjM,ez©pÉåïEh©’[ªM·¦cz©]#½TŸ?î·o¸#ÚCÙâcûˆ³d‹7¯¡öýñLÃE˜"þ2ÔÖ<ØüÈ?Û™‰)­˜š¦v¦›[Læ¡S3Ã4V€)’LÈ0žK®2\Û¹äÆÊ0E’騜Tnì SVcêµS-ÃTûY+ã‘*[qÍ&›dŠŸ4 .ÌwÃø¹߯’Œ1•·ÈøT²Gµ§JÀ"2L±K|ͽ,Xé¥ü‘ßæúØ=×Ç1ËÊü1–+3®9Ø+3UÚ ” SfûZK”å»V¼.νâ{=¥$SføÊ dF.DÜám«ëpðx9´M>u(¯£¹RB€ @€ @€˜{ ç,=Óüh¸$â#°òð¸ÃŒsó®üy¬qó€ñqsl–oMê,ãvÃ)0cLg ¥j+µ”¾²ßÁ[¼m«Zu¥òmk\©¹¦™X+´”…—ZsK?øQ[ª¶Ñ饇;Mך^j`U~©e ¹ö˜&`É0T`ŠRL3^„éºÑE˜®³Ó׬o›aªaZwΪ‘:Lg_µ6Z‰1•¹äªu˜z³Sü zÙßnzⲋ¢(Wf×ZgÎjÄ5šy²¨ƒµüê¼ò&Z“)~l”²Iù–Ñ¢xÔ²J%{ŒcŠŸI‘Fª¾oƳH5EÒ"#M™p*‡ª¥C2)RýW~ä{±AMS 2Lñº8ûâë"ÜY/Å4\¢läuqã}g_>é$Sü‚7a~-½_ì2Û”¿áeb=¥ZR,äšüM.^_ùËY–‹GüÒ¬ýn—IÁüÅ®Z±,ÖÇ·q„|”Íj‡*'-½*ö:šæfw @€ @€ @€Àœ Ô>UÞ¢ñX3Æ4s —hóƒªR„"ÿÍ|ùô*‹0å'\cŠ5ùiWõ³³œç$?ð*Ÿ…å|>sèDý(0ïbLTj™ôm¤œÒWö=ø-oÛª]\i8«4:®4ªÌÒpb©ZŠ9ã†g‹'·ô£›ïê]ŠÀJ³ðÒèÚKSK/ —_º¦”_Š…‘òKÍ L•òK™ßÌ)äj³ÈM.À4E˜:O$·þü«×E;¯Ò:g˜¢ÓQKÕ˜J†©L$W]è©jLC?¨Îhd˜†JÎTg”«ÌœW§cj²_pÕÝL2ÅÏŒZ¥™ŒeV)¾æ#~•´ÓX1¦ÖâIeʹX(?ŸJŒ)~te!ÁøqXj8•wÕÚTtýøn«Ï³'¦s.¾näuñý¡™›Ó,ŽÊ¡7¦¹l¾.μtÍ_ÿÍ$f—‹;3_%„—·qÖFÊ„S¾LòwµøÍ,îÛ|¥T#P¹&~‡+õÉjÕ˜J¤¯l“¿–£årt&wŒnä1³S¾”âÛèU-2ïu4{7¡# @€ @€ @€fV ÍGÃÃ5>량†Ë¿Ì¯ö¼ü«ø2N|–,Ê µjLùmëggµÏªòc¬Rÿif¹m`æ]ŒéËû4T<©]¥xö-oÝ*ÂIÕÖ(§ÔÚ~P­±q¥‘ÄRD—j•–òÛÚlq£rK‘aº³Ñâ3øj›ht©Y'ê-UÛêÛ~XÚ5·ýðš1ÒKµS}þ¸Q¦ærÑ¢êR¥EVf¸Ý×È O!× ”6z¹K®¿7&+müYä&_„©>‘\K¦œHîÈFŒé™g­¼§µSI2õNŒ©þƒêŽÆÔYg+CiÕ¼m3ÆÔ¸1_PŸ·ò®Wþý¿œrê²Îo^ñc£VB©Ä˜6Úh£ŒeÒ¨§CŒ©6­i5Æ»—:OÕ¼m-“Õ•e޹yç5h“ajÉöÕrèåuqÆ%k^4á$SþRUñ•)s8Õ*e¹&v) ¤üõ.Ö”°y&ŸZg‚‹-Ë‹%guŒCÅB™Ø1ŸÍ9³XZž.•iª8o-èu4ƒwC @€ @€ @€fU`œò3ôÑpkŒ)>`ªfòó©ò)UνkÚÆ˜jŸÅfµSë‡Ñ³jèà}*0ïbL{í{PûXRsê·½öiĘbatE¥zJ)k,Ý2F\©]bit±¥1BK:"£'Œk”ÛÉvûP‹ØÊHë]jD[¦”^êP~iú¦jz)–'`Z¾z}LWZÛYäF˜ÚL$טNnåÚf¦¡SÛ"L½cj›aÊé䢵+93TŠ)cL]·áœ+ïÚt¼$Süh©F”â}-¾Íy¬Ê§Ú›ÝX1¦Ö mþXªþôŠ5QQ¦Ô¤©¹üäËoµr5}ú†«Û3.¦—Öê0• Sç×EóýgÅuN¿xBI¦ ×ÒE‰1Å+¨ìUûµ/#McLñlÎÜcŠ•¹{‰ý•CE’)§®+)(¯£¿÷ @€ @€ 0KÕ¹ä230RÞb6?ÎùFÊ´<ùUù Y“"¦cŠ}k©¦YÒsØ~˜1¦}*½µ.ì¹ÏA›¿õmk)ÕV•VÊKwU[en¸œ'®Yf©µÒRV]ªÕ[jÍ-E€©’[§êR&Zª…—:Í·æjí¥O/ÅœM )m ¦ W¯ÜRiT2LÍÓ$f‘;'¢KÙšE˜Ê,rGžÒ¨ÆÔû1¦øAY%ˆç’kþ Ê\C¥˜š5KÉ™Z)¦‹®kÄ5.¼vÃÙWÞÙ9É”u\J—Œ(ÅÊ)Ęr>¬R©T‚©&?âD9mj¼“–‰´b¹LÑÕïï°ú?«™a:»:—Üp†)³}YKs¬RL‘í[qmãuqÚE·¾p¼šLqV •e¥ê¯q±Au*ßLÆfe–Æœ¸dÌóµ>YW© U~í+³ÂµT®ºcõPÑF¬ÆgõZ88 @€ @€ @€ÀŒLû£á¡À&øÑp)'Qæ)å-bMÊšÎ1¦ÖÏÎb÷üû&.0ïbL{|í Q ¤2×[s!žSK2©cJ)³JcXŠ+µK,ZjäTÚä–2¹ÒaθZt©6mܪ[G¥—VÆ´q£fŽ{ ÌW«½tEëäq™?®Y ¨íüq A¶k‡ÞI#O­š^jWiL1‘\¤—Žè‡SùAÕ ½5êrÕ3LÕš·4¦ü‹iþ“ú5“dYŠ)U# væw¾â5f—ˉ±Ê#Sˆ1Å^ñƒ*SJñˆQ9—V­€Mä-ò‡_< ¹q™]5ßËTcšø{úüÙ²d˜ª¯‹òöXæÊ0 ½.î+¯‹,Å4ôº¸fýÒ·¼ð%/¿òª«Ç¬U#+‰¥åM›±ôüõ.ïä½'ç¾ÛãǘÊ[›jjîû:ý3n½õÖ{|íÀ¡ÔQ‰UâÙ7oùΑ † )u(§”)¥ÎY¥‘¸Rez¸œ'nô$qíCKcä–~ŸÓ—Ö¨;RÚš߼廞ýœç½è%û…½Žb$]zÍkÿõYÏy^|Í L]zÍ?5×üÓ¿®¼e8ºtËý]:舓_øâMâÙh›m±Udb¢}ࣟŠvYD—šé¥Øà[èÒÈÊd]{)Ó3c˜†ÒK­¦Õ£LÕòK1‘\û)ä®^wvΪµQx©´¶˜2À”mš1¦_üêáu?Y>ý;³Ã*?¨†¦Ì‚ÑþcÏó^ó±S¢½i÷3·Úã¼S/»;"hqù¶ÝgÅ«?zÊ;¿xîwÏ»­™a×8ÿêuË.»ãï:&™²?¥Ò48Ùãä1ù(ð௙Рj(ÃtÑuCï®Í÷ÒòVù™ÃWÆ‹â5—Æûpý¯‹¡ôd%Ï»zÝÉËÇI2ÍÈ™xy$Éôw @€ @€ @€@—}øñÕ'O¤c}4%Nª 7>[2öG`•É?Á†'ûyîDÆb¢jCæçªSâä.ãǘ"=—eÄrľ¶ŽÓ—ö>°<ª-dzcª­¼a¤RÎ÷PÛRŽ´fD©´QY¥áR:9#Xk«UZž'nì©âš'UK.}h§Ýß´åV‘UZqÍ]/zÉ&g^|c|»Ë§¿Ñ¥øúÆ-¶ŠÜR|åøt?×T /E†)ÒKqr¦—¶zï‡"±Ñ¥í?ú©hZ&7Þ÷‚oË3–^j-¿4Æüqñ>iƒ¡VI/E’©`J/µL!W 0M3ƦUë>{øêß»ð®­gïE‘?¨N8}EãÖºsF²ÔX²âŽ Ûîyô5[}鼏޻çÊm÷¹0.Ó1çݶÙngÔJ1E,ô‚ëôKoÿ»WwªÉ4{ƒrdc D†i»ßç5ÃLæk+¯‹¡ ã 32LïÚã¼Kn¸/^ñ¶ðÆÝÏ8â¬5»»ñºˆ·¬ÈöÅë¢VŠéükï*ñº8é‚›_б&Óô¯ÝÄcLÓ?—# @€ @€ @€t_ þ%|öÅu3ûÑp| – yÎ÷¢ªÅÒKî*åGã>[ݨâ£áî_}=h'SßDY‡xÄB-H7~Œ©TF‰jL1aM_#7bL_]8V)ÖdzoÚò¹Á¨XR~;:œ4NP©1%ܳµ+µÖXª$–&ZŠ·ªF½¥5#SÅ}âÓ_ŽS–\ŠÓQK΋XR³äR£êR,}m^Škr!sK¯þ§7|öË^žU—† /-<üäŒ1e†é3{õ–FZká¥f ˜Ëld渉LWI/M°üÒ¹Q~©RiÌÓpù¥R‡iÊ1¦[î¹ç¼5»E€éUE›½Sþ Z|ÚŠj€)o›k¢}ïÁˆ1°âŽ¼Ð‹—ßþÆOñä‹ïÌi³"òõªOiøÏÓ× m†ÀB, N½äû/õ?Ÿrê²¾~Qëü@ dŒ)Ûa¦Ì0µâÚÖ`_ΧE˜â&Ï×E¼×yÖšS.¹«ýë¢Yþ­üUÜâu±äü›^ðâN³ËM\±±iÚ @€ @€ ÐgcÊ6F˜©óGÃñX|4üéÃVæG`ª%Ÿ:㸠¾?îGÃY ÄGÃ}vÃ̃îFz©D—Ê´ƒeÜãǘbÓ8DÎYØï\cúâW¶M#eÁ¤/DŒi‹w¶)žTýíû#ù¤¥]j[]i¬Kù1|m†¸j¥¥ZŠyârz¸ÒoXÍ÷¬Ò>ò”¾d“ZÊ’KZŠ.5sK±Ü 0Ý—Ñ¥øö¸Ó/‹(L^ŠÖ0íØhïØúC‘aŠ–¦ÓÆÍFzé¼±Ë/eþ ÑV6ÚYvO¶Zni:1¦0sënß¹úw3À4«1¦øAõ7›42L×5ï·¼†n›¼CÖ4~Ví|à¥ÿyØÊÿüÎÊøAuð©7ÅuÌ«öÅ#¯Ž¼íW»6æï»°Yìª *9Óàj-½X’©ßßÕ«ÿÕS»0Sd˜âuqæŠkÇz]D°/bL%Ôozw¶Úë¢%Û×ø._WÞ³ä¼ÙM2 Ö53 @€ @€ @€ŽÕS»0ÓÄ>>#>^|áíQÞâ›§Þ՘μò“øhøJ »K{N j2m¾ùæFªõlB1¦Ø'æ•‹£ SÏl2ŠÓ¾²p¬ÚH±>ž}ãïè°ÁDÂI%·Ô(™ÓhF8©µµ+µO,U*-uÎ-e½¥lqrLwÄ çVë-]1ZjF—FrKZÊOºüúœ0.ZÄ•¶Ûq·lÏ|Îó>½çÂWýãb93LQ˜®Ñ&PxéÂfá“j»`bµ—&™^0Q~iŠ1¦·˜2ÆtâÍ/ŠÙåf¶-¿e׿ÙäÇŸva5½Ô(Â4`Ê4[NzzüòïG½™íöYI¦üA—,&›‹ Ó¿í¶lé¥w¥ùHÉ™fÞ¶¼†’L{/xüÔÏjº,pø{F¢è%“>\™©™azÅ®•êýº8aÅíñK[³øÜýµ Sëë"Þ‚j¥˜Êëb(Étð.]ñªìG ~ü—MæwÛ @€ Ð ¬ö| @€˜#ã?Úþ#°fe¦f†iB ǧ`oÜýŒøPx«/{ÐÒ›&ôÑp³Hý£aÓõtãC³U *åìrK—.­>;~Œ©Ì€I¦~/È1¦Ïea‡òHñìßòŽñê' ‡“ÆÈ'eb©žRj–Ï)­C©¶Æ¬pÕ‰áÚÄ•FWZúœ~8´ØçgöÙ>÷•ƒ2ÔóÄUë-År–\ªæ–²êRF—¢ØÒ—8²:gÜ þz“H/Et)ª1Etéäó¯{泟÷õïœÔvθœÂ¬´ D—U‚b²³œïl¤M®öÒDË/M!ÆôÒM_úí‹^^­ÀT]>ôê‘ÊLcm3Ùõÿ¶ÝF[¾ã½#%»Ê5tÏ •àŠSd˜†³÷ÇO¬cοmÙåw_2”-Û1¦£ÎþÞP)¦¦mµäL¡8ôøåÿç÷ŸôÃ÷?¥ýÏjšÄ2n ,xÆÖoù—òžó*Ö‚}Y„)~‹ ÓðD™÷xÊMŸúö•ñºÈØeÔ'«½.âEј›²ñ ÜÚêûÃ'¿tà¿müÔŸoÿ$¯ “ˆºb @€ô¸Àgþ÷¤ÕïÖÿ;/ @€,ð±ßûì¶[lÿ‘Otþh8>‹†ÿó;WÖþù,>¸o÷Ñpã#°œ¤| ¶ßw–¾èÅ/}ôç¿êñÿiÓ½ˆ SŽqæc1¦˜Ž®D—.\ú+bLŸûò7ÚÖFÊ•ñlĘj´ $µ›÷mìˆRÆ•†‚J­“ÁÕg…kW©±”%Fj¡¥’^ÊÐÒW¦ ®º£Ô[zõ?½á+ß8*rK ?ùÕÿø†ˆ+Å×X¡¥…‡5ÖTCK‘aŠÜÒ)ç_—õ–"À߯ÇÿÛ~d·h]Ú}Ï…õ×/‹@@„–j¹¥F€itÕ¥FŒ¦Má¥õ]ª¥—š‘‚ÒÖÆTñÞZZËÌq“«½Ô:Áܧ\þ‡ôÌÎϽàÅ/?ú„e+ïX¶øúW¶’θí_ÖýdùŒ·Ï~ö³ñãjäÞ`šñt÷ÆŒ§9!`˜"½?¨Þÿµ ¿päÕIý®ÝðªO9þ‚ÛëÓÉUò¶1ðØä导ðœóo»lù£7^øx|ú®è–Àùûµù#ò‚g<~Þ~QÞ&o~ó›~ûø¡×E3šï®ù.šáÎ^ÅÉòu±üšõ›}ꌽ¿¶ý뢖í«ÌAùÅý½ö_þíÆË/‹×ÅÏoò¢ 0a“>Ù¸‡Å˜úú—E'@€˜'»=÷ñøwÏÝúÿ_ç%@€ @`^ \ul›À>ö{ZP>ÿ–1†q?Þý;WæG`¥Óø G†©ò؋Ί†¯¾ùžÛÖþD’ižüïoosÑ¢Ee.¹Xˆ0Ò$bL±iL$I¦|”ÊL½9Ôq{ÕxýïõjU¤Úr<»Ù[ÞÑR*©V9©|;œLʈRósôέ‘>ÉvK½U烚nì¸Rä–2±4ÜÓÃ5Þ°š-2LQl©´ÃŸsÜé—E¥l±¡¥cO¿´¬‰åL,•Ñ¥¨·é¥h¯ú‡×÷ÔK#³íG>­D—þuówF«êÒ¤¢Kµiã²2J=ºÔ Š6²¢CížxíæF;G‘Æzvâ1¦x+Öfºð®­Ç½ñ¦¶A$™¶ûð'Jn(¨1œÕˆ([T ŒèR¶ÌjD¦Ó/»{³Ý–EØ6ÚG¾~q3ô~¨ÓèéäF2L—ߘ£óãjjWÊ^3&¿°VÓôærüL2ðíãG¥—†ßQK¦m›s,F‹—Ænߺ"ÞÙNkóº¨Ô'íÊ0Ý~y]üü—é3v‘ü@—.Æ4à—Øð @€F bLû¼f`Fc  @€ô´ÀƒwŽú¬`*ÝŽ$Ãg÷úFç†wÿvĘF2Lc|6üÑðèéäâ£áj†ÉGÃ=}ÃÌÎE¥Œ!µVSR¹$вL`•/þI£xöß6ÿ÷qÓHíg|#Ÿ”‰¥fJitQ¥Žu•j–jq¥’X*ÃåÂÈÜpÃ3ÄE½¥Riié×år‰+•’K9ÝÒE×ekÔ[ŠvÒù×6BKc–\ÚÐy¸ Ð4Z»ªKm¢Kã§—šÑ¥™H/•TÓdcLù†~õ]gœ¶æ5Y™iöbLñŠ‹$Ó¶Þ%§Ê¾‘†f¬&mó*_ÄF¦¥—Þ•I²’aÊpXµfàP¦J†É«x—ëï!”SK€©Œk(Éô­ãK$´ä>‡óCo†']tgû×E›lßÈtr­¦|]H2õ÷­5g½cš3j'"@€ 0M1¦iÚ @€‰ ”S»S9L 3äGÃc}6æGã?‹†õA†§“kÍ0ùhxâЖs,0ÑÓwk–N¯üÏìùÖJHeM<1¦”§ÚÇ’"™”m¸ÒX³¿•”RK]¥F¸Ò²ºR£5SJ¥µ+UKÕIâj•–òÛÖÐÒPbi8´Ônª¸zniÌ’K× ÍW›0®G¢KÕÊLS‹1ݹ¡1McL$a¦Y1ÅY"ÉôþvÉ›*o›Ì´å]wB‰¦e-/\É0Å%hNÒ7œa®8V†©õÇÕ÷–-ºæ;{üòÑ¡™)ËkóÑÖßµbé,½Tvž DŒiìS1É$Óþ‡×òºz·¬½.2‹9ôºhù®ší+ÃTM2­[µ<^ñµv¼"æéM[¶“û€ @€@¿ˆ1õË•ÒO @€ 1¦Ž¦2ÄÈ3|zÏ&øXëGÃ9EOëGÃce˜$™àæÈ!Ì»ÓÐ˾äFGŽ>½Çcª…Ê·ÕìÑ„–GÍûVŸ®: \kP©Mi¥È¬Ü0Ôª)¥‘åÑÕôR#±4Tii¨ÌRã­´kð· -5£0mê-EŸkFÚP½¥‰æ–Ö3ºäR£>Pi³0gܸ3ÍM'Æ”ïþrCÛ·†MÛtý#3SÃ,“L#•f†LCÁµÌ¥5/hÎñ×È0 ×ÁšN.ë0M,ÃTýqõÀÍ«–n³i$™ZÇIŽhù¶hP]ˆÙùØDÎ^’LÕ LCo›ÃÅÉF½.V¼.Æú®s†©$™ŽÛ|ãxEüèî5µ~zELä þ6bLƒ @`PĘåJ @€>ˆÏ¿âS°‰=I¦=ë£á¡’%>®—·èœa’dšØe±Õœ Ì¿Só5?V‹w„Ýü߯¸éþhÃó¸»0R<©M¥vµ”ÚOW™n¬ºJµ)áje–*q¥‘‰áF%–:TZjZj-¶42OÜ„sK°gÇÙâšñšFÂfÆ'Œ7ÃL?ÆÔöõºjýªØx̓ C|/y¦òЍ­÷Š˜½{ ,ÆÔ‹WEŸ @€´cr_ @€ ЫïØê?vßãëí?«–·hóÏø×5ʈTÊ[L$Ô ÷*†~ÍGycúÏxÁ—™ÚZâíà_ßüïõ FOèV›ß­Ó\o™L*m¸–Rç”R‰§´ nh>¸¡êJS‰+5 ö´”YʪKŒ®´4~héêu-óÄ5‹Ô•[j¾iç–º]š©Iå:¼a,8gATcZ¸ráò;—o~ÜæÑö¸hRŸ)rK±»o³t›hÕ§:3’Lïûà‚¡â[£Le¬öY)e˜¢'1mVž‰S,¬øÂ6Ñ¢ÞLd5r.¹x*¾Æš\߯féˆ reì8ßSy2É´ÏÁǶ}]”âdï‹uÓÌ0=ò£½`óh7¿0 2Õnõ|EÄ« ×ç×X Œ…9´qª. ˆ1u Þi  @€LZ@ŒiÒdv @€ @`îI¦/}}b þ¬òѰ ÓÜ]0gšQycŠWû¨hÑè¤Q<û†7ÿ{û *!¤2¹[.´Ÿâ-Šå´¶1æ}«&–†Š*µ *ÕK+u¬®ÔŒ+µ™n¬ÄÒTCKç‰ë½ÜR­DÓ,UcŠdR´x©Fž)‚JùšúL¹ñ¦x6N¹fÑu‹rûÎH2½÷ƒ †¢l9-`s¹¼Ð™B;?²ecLz:ñ:L¥™ÌˆjL‘ÛÈ•9sVÔ›ÉLF|ͧ"½-ñ5·Úïzz~2ÉôµƒéðºhÌ}9üºÈe5„>‘¹ä¢ÓÏÙ¡—;¼¼"râÅòŠÈ _lkb›êLs±^•²¸ä=~1¦¿@ºG€ @ ˆ1¹ @€èmH2}ê‹_ŸòGÃ2L½}yõ®“À¼‹1}ª„ÛÅŒâÙ7¼éíãÄ’®šÌk¬jIãTQÉ'ª¥¥6)¥JPi(°’±•j[=fu¥¶–*q¥õçWæ†ËùGµUQZ©Þ!€ÑÅ–™€ÒšÅ–zªÞRç©åf)ÆÅ–¢äR¼òb!ç+˜b9ÒK‘aŠxS<›µšba"1¦Ø·‘dúÀÇGLó]Ö±³SÈ0•dFœ7‹ÐD˪KYŸ)ÖGù¥X™%šbûx¶º¥w_s I¦½:¦ì+ÅÉF2LWM+ÃcÉÄR,Du¥¼Õ³ØRyEÄSñÒˆB–bŠ…Ø l)Æ4÷C—O!ÆÔå àô @€&, Æ4a* @€ Ð-H2íö…ýÇÿ¬åŸñË0uë’9ïŒÌ¿S3±8V‹<ãëßôöÖgG*$E©´ë"‡TmRkk¼­´m×6Jé”V'Õ³JI߯j­“ÁE¨eq¥ösõ™.K}Zj4ÍRŒ©^* ¥>S¼ncåúGÖG hé­ÙÙâõ™&þzŽ$ÓÖøx)µU 0e¦¡ËT™ôt ¦èOIfä,ZÙÃŒqDD#Ödž)·Œ¸FÎ(—›Å69÷œ9È$ÓW<¦íë"ã˜Cï]•׍ê0•û?âæÏ_¸HºH€ @ ) ÆäF @€ @ O"É´ëç÷ç£ááÀd˜úäªêf'ycjd[çe^ÏþËß>Na¤±vï8¹[§BJcG”FWTªÏ×f¸œ®ÝdpÃÓõ™nT¥J\©MbiåH`"!¡Þßf–bLQ])Ú#¿x$&+¯¿,Èu˜Jí¥H2ÅšI•b*G‹$Ó»·ß9“j¥ØLãR6L%«1µ:Ly–H)•B2iŠ–u˜â©üšÛ”§âÛÜ ZViò 0—™dúò7Ž®¼.† ÈU‚}SË0Å@Jù±XŽSÞçY„©¼"bMí%[Æ+e.)œ«kbL]£wb @€“cš$˜Í  @€è¢@$™>ñ¹ýÆúh¸|(/ÃÔÅkäÔ3(0ïbLTì0;[<1¦´>5T*) &u $Uk)UJ(e-¥u6n-¥L)M$¨Ô¬>ÒÚÎŽ˜Ki+‘—lÍâ=ÍøKiÃÍÞ"M§‡³cšÁ—h‡CE’é?¶Ûyd¹«†.b™N†in†à,fV “L{ptV& ö­*Â4å ÓÌöÓÑV@Œi`/­ @€ œ€ÓÀ]R"@€ 0Ø‘dÚå³ûuøhX†i°o€y5ºycŠ”âX³³Åúx6bL6h)T&t«ÌìÖH*ù¤6³¼•dÒp>©c-¥¬»Ó¬¨4‘ RûÒJó1®4VÔ©¯cLñVÕH2m»s#š6ºØLΗ·ÉË_yáå7Þ¶ö'Ú£?ÿÕ¼zË3ØÈ$Ó¯‹êìŠSžKnàÅ p&ĘfRÓ± @€̦€Ólê:6 @€³!I¦ŸÝ·íGÃ2L³î˜Ý˜1¦ZÑ£ê·cúçÍÞ6‰ÔQ-„4•LÒÐŒ`ãæ“†*‹TË)år›¢J£ƒJ7ÜtÊ/Õöí÷S¼qD’é]ÛîTf‘ËÊ0uë-Õy{A “L_úú¢Úëý‹û/zí¿üÛ·ßß!Ø·öŸýü—²}½pû³bLýyÝôš @`> ˆ1ÍÇ«nÌ @€ú^ ’Lÿ̾µÀd˜úþºÀhycÊJkcµxöu›½­ÃxjmTK)˜4Fͤq¦{k7ï[eê·–”’ ÒT§À€S&™¶zÿNæ’óöN d’)rKåu!Ãäö˜ 1¦¹Pv @€3! Æ4ŠŽA€ @€ÀÜ D’içO$™d˜æþ8ãl Ì»S”Yk•5ñìëþím6èðT£0RçV)›TJ(5ç<ª¶{ΊLR­M5£3ƒU‹õPƒcŠ·‰’dR‡i¶ß4¿_ªI&¦~¹j}ßO1¦¾¿„@€ 0oĘæÍ¥6P @€ƒ'P’L2Lƒwq(æ]Œéí[ï°÷7Oh´ƒÛ´·¿{‡¿yùkÚ>U[ùÕƒO£-þêÁã·¯¼XëO~éÀÿïþAçž<ïùqô ˪³Pݹá‘|ûˆ$Ó›ÿýý›¼ü•^~c‡9³â©Gnά¼€º4ó‘dú—7ükÔ*ûÇþsÉͼ¯#¶ ˆ1¹+ @€ô‹€S¿\)ý$@€ @ @$™â#°M^ú²«o¾ÇGÃ_1¦c=ö5£‘ù¨¶¼è%¶ñÿ®­ôí ¼t“W<ëÙÏí<ÀW½æŸ.[}[ïǘâ½i¶—a°÷hÙ¦À÷ŸýÏ[ÿ÷3®9¢Ã/pkøÙÏ)Û7Mi»7ĘÜ @€úE@Œ©_®”~ @€ ÐVàÁ;?ñ7¿}õ·¿(Ãä<ùcj½~_Õž%ÐV 7«1=þËÇ_ðŒ^vJ‡«¦ÓཉQgu?Y~Ȫ.»}ÑX¯ &·ÐL ˆ1ͤ¦c @€˜M1¦ÙÔul @€f]àÁ;ßn£.ÙÃGóNís. ÆôI“èÑÓyûÅϪǿø¢þøçmG$Ã4ço°NØ}Œ1Ýúàá÷>ôXëëB†©ûWhÀz Æ4`Ôp @€X@Œi€/®¡ @€˜ÍÓã§~ÖGÃóájÏ·1Š1‰1˜´@/Ƙš¥˜?«¢­>¹õÇ• Ó|{s7Þøù¯Ž$Ó£¿Ü˵$“ “›dæĘfÞÔ  @€ÌŽ€Óì¸:* @€s$Ÿ¯Yþx„™ÜGÃsdî4s% Æ4éËd+÷Ø~ðz1Æ”¥˜²}ñEµW2LsõŽê<]xätîAI2É0uùR êéŘõÊ @€Àà ˆ1 Þ55" @€ƒ(ð½e‹®ùο|´þØ£¬¿kÅÒ2âj’ÉGÃx#̯1‰1‰1˜´@ÏŘª¥˜† 2Å;Yþ¸òƒj~½©ÏãÑ.½ué6K· ’L?¸ÿÑŸÿòWãni“cš4™ @€tI@Œ©KðNK€ @€ÀĸyÕÒm6$Së.‘mŠV]ï£á‰ÃÚ²Çæ{Œé§ýW¼ž;´{ø³~ôXçm<;Hq¹ï{hœ+·Mo½°«¥˜*™¢“²½u¥ôfÖ¢Ó‚sìqQã×µ5®‰¯«Ö¯*˱°þ‘õyòÿ÷ë__qϪ|ÖƒÀ ˆ1Í0¨Ã @€˜51¦Y£u` @€fD *0]¾ÿ‚hYŠéGw¯‰TSaʃG¼)¾­­Ï†c}>åA Oæ{Œ©O/›nh-ÅT)ÈŠÀ<X~çòØ8’L‘gÚô°M7?nó¨Ì+K}¦XÑ¥H8ÅB¤b}lîë˧óÄ˜Ü EÀϪA¹’Æ1ƒbL3ˆéPã ˆ1od  @€½! ÆÔ×A/ @€˜¢€†§g·>cꃋ¤‹&$àgÕ„˜l4¿Ęæ×õîúhŘº~ t€ @€ÀĘ&e3 @€zSÀGýy]ôj&ĘfBÑ1ô‚À/{|ÍòÇã'–ÃbLî…9cšSn'#@€ 0 oýûã‹?6ýíJ€ @€® ˆ1u•ßÉgU@ŒiVyœÀÌ \ó=Î^°ù÷–-ªzݪåñÔÌŸÏ ô³€S?_½>ì»S^4]&@€ @€ @€ý' ÆÔ×L'* Æ4Q)Ûè¥Ûlúèë[;sùþ n<~atR7ôˆ€S\ˆùÒ 1¦ùr¥“ @ ?îZ±ô¸Í7Ž?¤´v·íÊþ•^ @€ @ Ę܃+ Æ4¸×ÖÈNà—>Y¥ø\Æ•âk”_*e™âpܼ*ÖÇšX_"M‘yŠo£ýèî5Gb@Æcr‹Ì©€Óœr; @€qV|a›H2µn*cr÷ @€ ÐßbLý}ýô¾“€“ûƒ@? Äà"ɤøs[•"·k2±ñ¦ø¦X“ë£åæâovÑü…®Ÿ®´¾Î€Ó A:ÌÄĘ&æd+ @€s ÉRLñW”ø«ÈÙ 6ÿÊ+N½nÕòXŽ…ÚúX{å–sÐC§ @€ @€ÀÔʦngÏ^cêõ+¤ª¥äR^Н‘jÊJK™RŠHSþ….–ãküõ­”kŠ-s/óG@Œiþ\ëž©SO\ @€ ЈšÖù/¾â!ñ§’ø6–óï*Yµ:¾ b}´ü[J¤—ò¯(ñוø‹ G @€ô®€Sï^=›®€ÓtíO`.ª€ËDkâpñW¶H)eOb9þú–ÿp0žÍD­Ä›æ²ÃÎE`î|tõ!«6«ÝùðÉsß%gdÕ'?¾ÝFc¶Ïä± @€ÈôRv0–£Sþ%ÿ%XþC¯Xˆ¸R<Ëe}<MA¦¾¶ºF€ @€ÀãÿxC㳉ã?Æ‚Àà ˆ1 Þ55¢Èâò¯lQö<Ê¿,Œ S¤—²üRŽ?ÿ$_c¯ÜÒ¿#Ø;ÃÀZÎþþ›ÛƘ–Üü"Zf^à‹/jcŠõ @€tI ”\Š¿‡d±êø;Iþó°üšüÇ`Yë:ÿÁX¶(ÈÔ¥Ž;- @€&&1¦#¶žØ¦¶"ÐObLýtµôuž Ä¿Ì(Rüq-âojñ5ÿôV*-Å·ù§· 0åB~-³ËÍsFßcdRŠi>\ý.Œq¬‚L±Þƒ @€. D&)K.•ÐR$“ò¯%ùÄbƒüGbùÏÀâ¯.¥Sü½%Ÿò @€ @€@ï ˆ1õîµÑ³i ˆ1M‹ÏÎæR **EË3f…ó\(_kOå·Q¢)¶ÉšLæ@kA&¥˜æÏÕïÂH[ 2)ÅÔ…Ëà” @€FÊŒr‘IŠåˆ(Å¿ûНñ¯¼ò‰EP)N±¦üÓ¯\ÎâL(  @€ ÐëbL½~…ôoŠbLS„³ô²@kA&¥˜zùzõ}ßZ 2)ÅÔ÷Õ @€ @€ @€@ ˆ1õðÅѵéˆ1MGϾ лÕ‚LJ1õîu˜žU 2)Å40—Õ@ @€ @€ @€@o ˆ1õæuÑ«i ˆ1M›Ð @ 'ª™”bêÉK4XªdRŠi°®­Ñ @€ @€ @€žcê¹K¢C3# Æ43ŽŽB ûÞùxü¬:õ³Ýï‰è,ȤSÏ\AïHdRŠiЯ³ñ @€ ‚Àyû?~Ùƒ0c @€ @`Þ ˆ1ÍÛK?ècô+l|óG@Œiþ\k#°@dRŠiÂ`6œž@dRŠizŠö&@€ 0»=÷ñ}^3'r @€Ì’€Ó,Á:l·æWŒiõêÕŸíøØ}÷ÝwØa‡ÎÛxvÀ¶ß~ûÎ#Úk¯½{ì±n¿T'pþï¼üÍ=¶d÷ ljóHà˜s¶ŸG£5Ôn ¬þ»Ýç'@€ @`|;?ô̇¿´éøÛÙbÂþîÚ/2¿…>üðÃãÜóŽ{L_ >ûˆO@:çÎ;ïœðëÞ†æ…À~ûí×ùUãý­æ3.H΋[Ç Ì€ÓÜ8;Ëœ ̯ÓÖ[oý/oØìãŸØ½´?±ûHÛe÷~ýfñ—/Øy—OEÛ©m[ð©|êcc´.Øí£oÓvüønCmçÝv¬´ì¼[¥}ò#; µïôɶm‡}²µ}èc»µîú¡JûàGw­·wýàŽ»~`¤}â;Ž´í?ò‰¶m»|¢Ñ>\m»l÷á]¶­µvÙv‡]Þ?FÛæC»4Û‚Z{߇4Úëí½\0ª}`Á{?ðñh[·kïÙþãmÛ»·ÿx£m·s­ýÇv;—¶ù;Þÿߟú´ÿØvçh覆޵íNïzÿNøGÏ\¾|ùœ¿6'}Â3Ï<óo6yÅ›ÿñåýºšôøì@`*‡~øŸÿŸ¿ŠÿšÊÎö!0I¸Óâ~‹»n’ûÙœ @€9ˆéãO(Ñ"{1§'è“UÿîZû‹ëλìkýç×ÿ[üÝuÔ_\ÇþCkëŸXÛþ}µõ/«ü›jë_S;þµÓ_PÛþítÔNÇø«iÛ¿—¶þ±´õo¤üióO££þ.šÝh£ Í?‡¶üE´ñ·Ðç=ÿ/&û?¶±}\Ü6ro\úÆÕÿv;<íw·þ÷ö±þÆÞáìíÿ´Þéêüsú¨`Ô_ÑÇùûyË 0úÏæcÿͼõ¯å¹úmÿBÞú·ñÖ«!ëþ‡ü¬×ýÛ[ǼúÛîôòWÿs¼–ú½ÊàLN ~gˆ·¯|«|˜Øø ±|Œl³í­V–Õ>"¬ýüªýðýÆÕüpø³¿‘7«vïTµÏø*íUÞšÚ½/Uß‘jïE#?†šŸÓUÕÞ|òç-ÍÝò=g¨ÕÜìô”§>Mbrr7¢­ tcr{ ¨À¼‹1í÷CÖ=ð³lk‡Ú£kjû~ã·þû»î¹ÿÑÒ~pÿ£v_´ŸF»»´{zW¥ÝyïOïÜðHiwlxäŽõCíöõ4ÛOn_÷“ïWÚmkRÚ÷Öþ¸Ñîi´5¥ýàÇ·µÝúƒÝr÷H»ùîÝ|W¶‡oÊvg£ÝXi7Üñÿ³÷'Psgž/ÌÌ9÷Nß™3sû;÷»§Ým Ý=—¹ýMO»ñбeÛm›Õ Œ1›mÚòÂb±ãÆľ#‹Ù$!B }G í•’Ú­ ±·ÀÆØúþ™ÿ¬§¢r«¬zkÉÌú׉óž|³r‰üGTdÄ¿xž·Vn|“iÒ† =¿áM/­Gzã¹JZ¾î KËÖ½±lÝ®e/yi©¥µ»úªiç’5Õ´xÍÎÅ/iÑ‹¯{iµ—:iÁ ¯ûé5¤g‘Vé™U¯yi¥—æ¯ÜÁôôŠjš·bǼ瑶#͵ôÜö9Nš½|›¥YË·ÍZ¤™Ë¶Í\¶uæR/ͰԷuz5m1qÁ_ýõ>Ó–l™jiñ–)AÚzÔQG‰d*i‹­ÇjLÑŽüîñhÜ0~ÉÔ˜v:ºqPÇ£¾}çèã5ø6~7!¤€R@ H) ¤@“ ø Ó€Is–?2qÎgD25©bÌi@Ìî5ºÂÖzã­ÝÕl­‰†ÖŠ•ÕL¬±öÕËj¼YµÆ¦jÕÀšêTÍšj¦T³£FÔ oš5T×|šd8XMÍdjöÒ°±4ÁRê›Ii’uÔ5ÖÚEiÆ4­o Ì¡U‹èâ-Sͺhó7ÿ^££Zìñ?غ+ÞäŽÒ_°tõÞûü-6\c{l¨1°WlìQëzš]=΢î•~`Q¯šÓSJ¶ôŠ=Æ„îÙÏãK&ô³¹ÙÌûWú^,äÏmŸk Î6n†q³Š³ôÿù3^w×–~PjKÿì_ß(Œ©uí¢®TÐmØgß¿­Ì'3‰›wÖÌ!¢}{¦ï¶i6oÈÖ¬öEV"d#V3-Xi»^¬Ì²Õ²@6Y|[Õ¼ªÖï)ç åÌ i²é“1LAŸ)‚19 ÓVôŸÂ“;l[¼yÊ¢b`Ld˜¿°Í+¾—vÝö»Ñ"™ZÝTêzÅSÀg˜N`û†ß\ʉd*^)'Ç>Ãt¾Õ·#D2§ì”S) ¤€R@ HžRsfŸ;`Àä9Ï¡÷aÔ„9Ÿù¼|2µ¦ }H±»ÂÜzí®é+E]€©añÖˆÆ.M^a˜ÚI±¸¶S[ÿéÌûVÓ˜eŸ5k>mÁgüjÏÐRÏ8ŒÉVxú‹7ì.﬇1yK:amcòÖ'XÝQúÏúSÆÒLü‡W·‰a “ÞJà4†É5žWÇ2LAé» ±Å,÷ ¯õmÄæbLFø[Pú˜ZÓ ê*%R=ÂŒL)V¦=t‰S`jŽa²ÙÀò²݆ˆÛmIŒ©†³´y½Ê¤_LÁ\^å­TõAPƒ1Õ8HÁ˜j^=Œ©2…&½ÖFS‰~"z”( Œ)… ,´CžÃ˜0`ºU7KUgK7Ür'F\Õ… ô½ƒ.E|/…©êL LpÅ0Uü0Å.rqìŒ~˜f˜B J²2Lž+&oiQÅS00ë'ÃäàÞÃÔ +&0àQŒ)äŠ)ÿÞ˜<†é[‡-^½Ý¦Ïa7¹U$S;ÚK]³8 x Ó1'` g¿ ˜“àÑ]$SqʰH9E½‚?g«opdˆúvøÀã]½Z¤gV^¥€R@ H) ¤@ð¦/ ˜2÷9  \ñʨñ³E2µ¤01ÕØ]=ßö5îí¯7»kÔÖZÏÉ}"ÀqoëÛ¾Q?L=ñd¤Xü ã°÷ú¦\1ÅxÂðüa4âŒ'ðÆ”äŒÇ÷Lß4ÆTµº;¥Ïø˜àÇ4?-í!c{8ÄA_sC¬s¬ë­%Ø22Lîà ŽA½ ¸bª5•[È‚p¼‚ÚU¾Ñ0QWLæÅÃ˜î ¼1…œ£0.0¦–´‡ºH™ Æäø>ð^m5sˆ;<ŒiþcŠú“ 9“³F,ÖS:Ãä»bª‰¾Â¸+t˜Å([FV‰wÅäNÞŸbª¼ƒª®àoLt.`-½1ÅbLþì›ÇË c*ÓoDÏÒ}„1u¿ ”ƒ¶(ÐsÌaJ©Â*a…oùþIn´8n‡\.µƒ.…|/…ãÇÕÐK¾£ÈÊ»(rÑ@rµ®ÍŸdµ+S‰%g>Ý$!€©~˜ZÄ0ÁeeáäÂëàA× 'GW–Ęj—žTWŸ`ä–sŒ‰ Ó’·‡¦ÏѽånùdjK£©‹æ_2L´9²¡#V‚ßÅOOÉ”ÿ,XÉ0yõÍ·`Á“Õ7‘L+KeW H) ¤€R Ô  Ó¼çÜ/¾#Ÿýiùdêwécб»:ÌŠkwÝäÌõV ­ÛÞƒ‰5Íý‚'ˆÂ˜ÖÆ…{±J¬—çåj 9ךjzÚÂ0ÕºbJd˜ZI±Ä»br1¦Xg<ýÁ˜¢kƒXÂ?¦ù£®JBA—²”~8 ÓæwÖ"¹¥_‰Ç[ú±‘»Â0‹~Í÷IBé{±œqÄeq¢Ž¸‚ r>Æc÷-á˜úÝêeS€Sˆ[ Í!î½Ï¾O/~!ô:KІióƒ^Ûå4_¡Xr«1ý~šÈ0Ùd_œ+¦°—¸ì®˜,vJöˆr˜†s1¦š¦•ˆrhj„1•íw¢ç鮘º«¿îÞ6zcŠRJ>¨ä±J×Ý ŒéDw Hu(U -9cªÀ«m]Â"!so`§ÐK1!äâ<0¹#®€Éx×xÁ8a âyWWù+Ò*îpk¢z{Èv…Ú®úŸŒwŒÌˆr­ðÃÔJ†É 'ÇøßUŒ)NÎ_}bÓ˜ñS¶ì|ßÒëoý¾m?É. †éß:¬ïÅí±Óç(š›ï~äÃŽØýþû \Ô?´¯òiôÄοvíÚ¶Þ´…ׇ¨-¼Z[ŸºÐÃtÔ1'xæ'ßõw°¾ÖؼšüäôsϿ𒦟åØô¹ž­0í»;ïÕ¾ë7úìÑãÓsÕ*ýçÖªß#¦ÓÎ<ŸõÍu‰‡ú†%êÛa:ìžæÿ½÷Þë@£»àÓ\»{VÕz6qVwSw—R@ H) ¤€h‰d˜¦Î{>vÅ L(#ÆÍÉ´s×›-¹]o^„SÌêЊ§%×†ÖŠßx%db]ë©_K‹¢‰/¦ÖR,ž£zßF:Å£è^{íE»¨²¸ÑŠ-Þ˜е…n{£ŽuÖ˜„µÁoLðcš?ꧤ\ ‹)ýt|-3ÀK°Å®vœ`åÒ.ÏÓ½p¹–ó?Lé¥??[8¹G\né/‹ &è¯ïÝbޘ¥_1†c:ö¸¸¥í?~ôçÞlÖôÔR crßn!-Ú·y‹_‘¸æG0êF.0¹s‚tc©Ä’K÷ÔÊ0íê« 'rÅTÅjãJú„3‡psÝIºåñ®˜ˆ1ýUà©&¢\àŠÉom€1-Xö¢ÛÔìz'“nªóR  c*d±)Óõè9Œ æGµ•‘óµ>ÆÄÞ†%š¶ô.±ƒXŠBKQni½.%8^ª¬ ‚Ç¥ÐKv¯ãCÈU<050…`>Àätçô4¬»; îîLîìY¬)±TqJÉXïæ#×íÍC¯ÈRËü0U& ׇÓS2ÃDoL#Ç<åBi¨Bõ[m>‚ ÓÒ5;°V,ºŽÓç W¿~Ó]|hc$¦xaÎà¸ß~û <¸}O³mÛ¶#F4zý &pv9äœtÝL2¤Ñ»àʡѳ¢Ç#«¸rˆÜâÓÿ ê I T¦·¢¿ Z‘ø»tÚàó.h†d:t(~¨´-,«ÌÑk¢Ú„ ܽ…·¶KYU¯{ý”ܶ#cnùÛIÊaT«è^­…¿Ç Ãô–;k&]Y};ì¨ã†ÞÑ ÉĸµÂF›J´M4­ÍUsWK'éu0hÐ HŠoqâìÙ³›»©Î’R@ H) ¤€(¢Ãôôóq+^üÞ;¢«¬~}øc³>ý¹/Šdjºˆ1¹v×*¨TÁ•®½©jwÚZݰq)ðJÇöÞpÜ¢PšRCÕŒN˜|7öÁ*P %æšOÓ §°E0eôÔ‘b±hba†)™b9”Sl@1.éÆtÍÃB tÓ+†1U×GKÞ"cŠ–|K{J黾—²”~]|-» ®Ú Mµ¥_³¸ŽÙöÄPé¿ÿûšnt¢(º>ÆäQ˜Ñ–ÍÚ40wÑ œ:LŒ‚ºùj#ç>°òæò09~˜Vn¬‰%—•Xrýa˜z>*n cª 'gá‚©ºÊ<_@³ÜÆgéV0LÆ41À˜èM Ôà°©Æ4gÁª¼Mº½®*ÿ½«€0¦Þ-û’?yÏaL0×bI.¢ôÞµ7 ûî÷O4P)–Uª2Ô?Æö®  ¥XnÉw™Ž.£¬„àqqî—‚î‹ëö¶J/ùˆR¢Èycï Àä."É 0ùtS0Å3L+_{¦!†©6Ú7"¾× ÑC+‚wiÍr“ÚXr5 úO†1 Î(ànÊ!Æd SÅŽœEÂÌ7޼vÃ7D2hpç†á¥£åóèn³ŠÛ51ƒŽSBxG]<¨îÑÆ¾Unm¨VZQòWMG צT]19¾h˜ÆØìÙ^ûqS$q´ºÌ\C­Ìvzç1¦º9OÉmÝs[r@ÿ1¦Vý=†é¬ó3Ö·C'™@Ë‘%m-pm ‹‹1%Õ¨ØÖžøO×Dµ%UZ‘R@ H) º¨zÛÑéŠ}(Þ.Ëóâ°þx夯M¬ÁÀ'Ëíbégš¾oÒ‰ýq f˜©’/ypìÌO‰dj¶ü€1¥Ú]ßõì®Çž˜dnm™Wû—=?î¢Ð½T3 Bl¹X„¥7<¾átµ—e˜jV{fˆ&žHNe˜ˆ1¥P,McL¾Q½ÆÒîÂjs­Â4K¿})X sº%cתŽLjã1Õ˜<ûª¥'L¾¦¸Ò¯‰``á ,`S¥Ÿ‘`«ñÔ™aBéW1¦`YïfÃaÆÔlû§óʬ1¦HûVãïÌY¸ŠS‡îëÌ|î—B0+-X½MwÂäø tZª¸6*ÕSV†É‹kYq7PË0A(‰1ņ“³ÖFS™3z¶Î+ Œ©óšëŽQ ç0¦knZÞáþ‹o1œN•Rˆ%Ô5+B’¸%Ç·-GYî ¡ÇK‘V(x\"½Të÷8?Î]< !×O€©ÒïiÒ S¼¦ÃTñTb½oÉQ†És–kÉ[qBŸÉÆ€ŸàycJa˜rèÉa˜".gÌ ˆá¾û«†ÊN2ÅbLt?CgB0òʱYvîÄw:œ´I `n“¸‡3Ít7rȺ.KWF8‘¶Tœ‚mlÐvbþâc—2GM¸ vâÞÛ–%>.NïS!›²aL<€Y¥5™Çó©íjø–ÏʿۘÛ:ÒÂ÷ÐM SªaÚó ·òµŸÚ˜O&Ð$Q‡@VyÈ6Yí2"Tð/]ÂðwäVf;×~¬cîoÄ ž¤:º>oļEŒx"«½¬Ì¼>ûÅY5rsËãy°ý -Ãü*)“Ñë»p·í\Þ™wÅ^!ª•µ9íø=†¦ õíÐ#¿ßO&6§VëB%Ȇ(©úYéXcËÓšJ·iˆbLѪhõÊ*§U'ÖO«<î‹ ÚròÊ–«Pƒj°B-3Îe9#“Äêê>£½¡ø[s/n—ê¡&R*¤€R@ Ä)À¾ zèQtÀ_cöu2Àš¦vl¥PZ=ºJÁöXw:u§¹åOÌ9¦?ÿ…Óž~&5:Ý ‚GV¼p%L(÷™!’©¹rÆT×îõòB[kÝ¥¡nظæ\Ú›7 × D,3À°¤’‹8½ð î‚Oc˜,ˆOtþ8¼È3[41³‹SÅÒ<ÆäÕ£æwLðcš?«e,ýÐÂàk­ë ÑKñæt‡^ Ò£Qä]pù~ÝbK?Í WBé›û“ØÒoša‚Iü“ôÆ”\úòÆÔ\¨³J¬1¦¤YE¶cÆäûJ Ïâ¿ÈÞö^a1á/Øj°Ëܶ \’aŠz „Ÿx7¾ŠCX:dmF?L3L˜ 0¦pôRš4÷˜Jü“Ñ£uAaL]]·ì„½‡1E<âºÃ'øËÅpº:r® GP)Ì*W KÕ8q¡qu·T³<.—B^—¼þŠç\¤ÖñR4rœgˆñl1ȸ+ÎýR \¯c±ré Ùz9þ0,ÞS“»²$À”ì„©Â0yN˜è¸ÒK!†©0¹~,+SxÝIn½1Ã三¸bªDÎò¼ÎøÖ¨}ÝYI&7¨ç›É@`þÛÜ&‘ÅÁ.î4ò)Š1átºÁŒ²MuÛÚPlDÍ‘Ñ᲌Ì5TÔ´Êém›òç¶Ûˆòw?20[½dOÄieÆM I±4bÉNá’© e٠Љ¦½Çîá0Lµl_È0]qQÃ4cYþë)çd.g« 4va|Ë:Àê:€¹he@â¯Æ~V™y«xذƒí'ÆQJ³SpYþìWý1Ú̲äbLÌ<+QÈû‘ûÓãO›²¸ø#)™Œ^ eÁ¥°+›Ë+f2D®D¯ÕŠ'¶ã÷è0LuXR›a};¤’ ùg}@pÃJú¤T?ûÊZ*Ûc­™5Ñù­”ªh~Œ¬òu« /m9Ýæ·àÚO&„…žŽÕ™gÅ&0Êûâ_VWÈÂ:Ég$ÿÊߚ뇀î{ƒk_õ¸R@ H) J«@*B‡ÁúÀض'z5ècð[ëT`§õêÙùaïÂ=ØŽ$ÒÍýî-Ø“áuØñ#ƺNÇ–ÉSBÎ;¹ˆd7Û²Çþ¶e˜6cÈ”»‡½¬P_1”m{F\Öô±g±oyüå0ʺmì³ñ°ô§³‡j´:º Sàµ7à ôÞï{tÆþŸUt¹FõÞãaLÉvW˜[¯¾ñŽÀîZ1±¦Z+ÜR̤odQèÛAüz+BãâÇÕXSÍ­Eü*PobØRm±æZíVîÒ oäÈd “ñ™[ñá2LÍÇµŽši´fm§³°ÓØo©®ê¬uKß4ƔĨÑö>{ÁJLó‡&øã+@k E_µ±»^—ܰq5Ž—’}/¥„2Èî)`rçõ0½ðLµžµ–)#ÁV»Ê7c$AÇ0^]Ù /\Æ4ÌØ<'Lµ~˜T®áVO'ô†èN ùŠR˜.€ûñ½÷E+ |F0ã¼Ç…âÇÅ:KŠ"翪_q±o¨8¼2Þ”-_Fµo¢Æü0ñ½3r¢ç; )œœ‚ÊõÆïFOÙY„1uVoÝ­c ôÆ„³ÑHî:^…áô÷N¬:x$¢ä€JNÏ£f(`ÔNG¤ÆŸm5NœçÖ¸:´®q›äâ8hÅ¢KÇKñ¾—¢Áã|z©Žû¥ÊÜ]GâúÂu–’4à©>À•Îȃsw‰‰ë'9À$çºM~ÐóÆ´w4\>1¦†)b€óÏNä,Ã5°vçºÛ3‘LÄŒpaRMøàrœKƇÖX×ÄiÛv¬$®« Z0£“o7r/kóÓ¼µåÁææ95NëªÛ’òZ¿ôádŽ:B†lû—b:2áeí03´e&šfƒWèXãÞ;72†ÉY\°}žÃ9õ pÌJ˜EŸí«`Lø]œœ™dB¡ãç€r¤wŸP…gevë«DôWÙ ~‹_.h¿#Ô[ó@ÃB·º¬·ý"²ü]DÉõuÄ_ Ÿ4 c²Ÿ™À³mºÆIÊdôúð‹šàN~0QŒ)z…¨V”¢å¿ÇÃÄÅÜ|óf©o'“O&<>[|¢ÍŽ5)n+ǦÛÕœUÈê‹’ÍÌT…¦¦x|´*Z-ÅBœh’7¦PËIFÍ* (šg{:û Ì6™<»ïK, Ø”6çax@ûa¿¡]¦Œ6¤€R@ HžUö"\Ä;±‡}ZãõÑqãÒ²7E&ûéåa÷†›ªtl]SvÒÜ[°s…芰lWÃ5ynðÏ˺ùg§‹Ý¼þÅïÑftLæ9z…¨Víø=Æ1L!fn—±¤Ñ‰Ö·,$'X^6Éä–[Nk<­ú…ŠØ*¤GY0¦Øªh xˆx³ŠdÙcÆ¢-§ÛÀrªÅÊ3ë ®€ÆÙ¾bãɉ={(W\¢1o®Ç)\×±#‰Ò¶¼!Ò¥€R@ Hâ*À¾+ûä¬büu?l ;çè±Ø콸#ÊâvEB] Þ‚øµ‹YÜž:<ìDµy;vÙ¡²î"¯cR»ˆÛ½·n˜ O¬›m·Ðíq¤õc٥繮±C•ô§³‡Ê^Ó0ãø¹/ ˜êÇ’ ûar½ö&¯xA×ýžG¦Ë'SvÍq$0¦ v×\sk’­5€–+kÝE¡¾'ûºèRØ“}]÷KuðÔ "Ö„Å[ä™HÎõOo “M'Ã(êcL5Á}B¶Ðoþ½¨c­ôÊûŒoTÛmÏÌgW`š¿¹Ò_Í•À–6½U\‹ePÇ ¡ÒÐT5ž¯vB5y*™|P j3¯ç‚+`˜Rœ0U*ÀÌeÛf. (H$Øü@rðÆtí°GSÖô*¨\Cížîˆ1ŵoUôÌxvEüŒa0]˜ØˆÙË+Îe`µÕ²&+ì’Qä,ÊJM¹³’3?LQw€ž£'X _@ÖþÐ`¥åÙ‚i¸*ÆTñü€ÆÔ ¿=cçÆÔ9­u§Ž*ÐsÓ•×ßêL¸ÿâÛß;!z@uð*Õ.rT±¸GY¡¡uZJt¹T'`\(nÍ’‘°ã¥„Èq5¾—ªÁãšs¿TãÙqDrŒœ´²$ƒ¦: ot˜,¹cõêz£Å›_ ŒÉ&vj¹z,ðÿQ1À™Ë™Nî…—3\¸3ÇÕCëLfÐdSÄic.åäì/&2F0ÐjÉÅv6,ü–]–_|E~È¥Ìl½‘™_Í Ù#3‰bƒžð9w œÄ#ù-­¨\ñÉÕ¢<×rËœ˜ ÛlÇt¹¯Ü {æFg˜h] åŸWÃÔò—›Ã0½Éa^<Ôl˜ö~Ë·Ãûë‘L4ÁÛ#°òÐ(ÏpüQX…$†­ 8€UÈs¼c¥b=¤C&VïÐÁ¶|9¶Ž¹¿ˆèÜ@ôÇh{HþYÅÆ6áE[nn¹Å²J”…?pþ´qY†HÉdôú†6â DXìçÌ)ôFµbY´ð÷è1LgžÌ‚4Uߨ£¾}»žO&Ða±B·¼°RýP QjèII­¹sËԆȮE«bc2ïG¶ªÞšV|Åù°hËÉ Ãß‹Ur^ÙòÌŒÙÓ±¦á[¶ÞøkÏB•XßX]ÍOßY|䧦¸åM±.(¤€R   °o™go„ÝZöUðáëÕËFw†¥îÁDšì`»rhñ@ôÖ“±‘,»²îÕÜá[ä|6óéöp’0&ìg‹£ZYX76°‰yàNöôBʸåîbL¦6B^œM7à’åž}ºF1¦†Éõ¢Zwzïw?<ýŸ?sàÎ]o´žw8ÛÀ˜²Û]kl­5+B#nìãÜíÄ»\Š'WÒÐ¥¤àquØþ-ªæS¬c±T¬'»&µUÕ OV„%Ñ “k­µ‹nö0¦H 9w޹YŒ)ƨnföÏxS8|Ax=p“¥Ÿ3®^ƒe¾gåï%§ô=+º9ßrÝ/5„¯¹QäÒcº¦rr!#y8Œ`ЦŠm嬋H/áxŒÀŸ˜³âÒ«oç,9Ž#±Ã>ᓟ> ƒáO~ê¤_]t•C/¥ööW–lß{ß¿‹™»>*èÝzH†‹öœúƒ1}ô§Vì¸iÑ– ZQ7¯A†©ïÅí³‡Õ8ò’ÉG^쥓†Ìøê™ãåè³^8¹#.šôÐŒu4À™+&(IцܚF25ñD!ß!M\¡U§ÐÏG«®V÷:0ÓM4üVÝsu@Ó €a:ò˜\«4¹OZ¥ñ‹ð“~vÃ\c˜b~þ0 †iþ.~ðÓD’©é¬†Nt×4·êšÝºŽëð)vÝy·2Öòû‚a:õÌó£õ Ó?üpÛaÖ·GgoHªoæŠÉêÛ·O$™Zõík™1Å>¥ù@ª›gLåFó¬{¢R@ H) ¤@›0fšnl… az. utas»X\¥`kfb{Ť½IŠs¬Šë»·À÷:ü7„1ÙEx.Ž1軎cé6‰Ô¸ÑB¼ ÝçâºXn{Ü‘ 9šm+Ó„´ýbòamNça\AA¸§îÓÙCÕ­ Ã4ï9ócmË]ŒaŠtݹ&”ï\4iÔÌuI+^0Z6j*ü—È'ô÷›žX{ÐÖwgÇ–EŠÝ•ÆÕ+’í®ßøöá°©"}ì¸"ôècOªì9Ɉ¥{GM„55´"†V˜"¯¼a˜Tô“_ìû‰¿wç€ã½.Å9°w]ïÀ"jü –HzÖEØóÏŸ>À'‰cÝ/Å;à©õXï#,Û}Õ§L~1HýÁ)@X~|ÚùH°l¤#,tÂÔ&Œ FõX{;KA1ÍŸbfwêÀI´®‡êÀ7|+º¥ sm®­÷Œíx¨!Nøamp½.¥ KQßK^pVÿô/‡¢ô±ÓjÂ觤ÇËŠ¯¹Ð@(~S\ AÐK¾v*ÀÇ÷ý»Ä(rà †ÉÃ×Xú˜ê¾Jt@*0ú¬=/ݳû­èãcжonƒ†Ê6-K…¼¬qjà8^¢qû¨ïô‹³/ñ_[p9ÿ¹WðF[Zyaíÿ™/øé€Ë®½ƒ/,{O]ûpLöÙêÄ=-Ú:=pÛÞtžE‘«LáUÞGæ ®^ 9(k˜.Þò ‡1í¼RÞ˜zôW¦ÇnŸ˜ڧ­®Ü)h$ Ý-Æ£}Gw*«íº†Ó0¯DL77¡Ó½@oW\{»?5^¤ÎQSlÂP '8U"_rFNâXzà±'a…ÑÔ‚•›q=7ÐÇÒ/ιCnZß|×Cø74´®‰«…–²pKîxÛ§þêb,ላ -Ù±è’3ö~ý«ÿrh°~Èw€|ߣÓ~~æE^G‡ie°R-ä ÷wLÛ{ß¿O¤—¢‹ŠœÎ1¦$÷K5“³Ä$fˆîCß•q–›øCµÅÞP-”šÃ˜6lÛ €iÄó»«o¯9/ŸÜ®úºg¦¯ë°%`˜*ëÉÌ•(j&Î኉l0Lß¹xRÀ0½ðÚO®Ÿó•3Çœ¾=Øù`úÜwÅD\\ü[ZI2µo²¼!yaýDN¢®˜ºHCÓ&K{t'ïÛP&Kv0¦(ØG«ô)7Í;çŽgÌ?Ù‰WL¿qÌ ²}ÎïÂ[SRý]¼½0”'µ™dBU Em(héÐyežn¨ ú,éÙ&Ã[ßà‡é ³ÆÛ2͛Ƭ¨¶Ã¡úV1AzTn¥¾á=…®I>™Z"fûZfó½d~Y2ÌÙ,¶™YŽ×1R@ H) ¤€h·Сcãb@¸#:·`µ1ŸWÝп ÖfùŒuÁ‹Ø·¡[ð¦6R°ÃÜ«Ñi“»‡§X>Ý<à07jž{ßhNBKqö„nÄ‹G³mûíîÈS¹{¨§K;1ç?ŽŒÕÖ­!d˜¦Ì{Ηª Å-ráߣs6âH#­ÿôIDATc2/ª?½a†š±ŽÞ¬C®˜Ì„rÇH‘LžØÀ˜` CŠ…™hw­ÁõÌ­–*v×°¡õªïÂBV 6Ò'f,A2\ K@A/Á²jëBCìah…õ ÉŒ«8“¾ñäJ=tɆu1=lþ-Žøî‰§œ‰% ~ŒžJð¸¦ð¸˜l‘§ëýÂ]äé®ðüÒס Ó¿žv>ÌL¡(r†°Ð.Ú>Œ)2…_-ý©óžÿ›½÷M2³_iu`C¸ è­0‚5·»$8Zög¨ãsËóº”6ŽVô¨ 5!;½„æ¥Æÿ–=°!ÿ[¾fNP*SPô‘Ò÷ ãŽI\S»»º~Qxàä=àÎúË(ÌDŒÉ}9ÛÁ íÛTŸ¢vÆGbñã $ù ¼àÒkÑv~öÅœ¼qØH@KûþíßÓýÒyÿvõI?>啕Ë^Édó}h¦à~ 핹ˆC…fêö¯ñJà9#H˜ž2ên+31»d“tUÿµïø~#Æ”îöOÞ˜ŠúKQ¾ó©€0¦|–‹r•Y.kc¢ èr`L—_;4XÁc·/ÄøöÈïžàzNŠns,ýè§¿À¨Ø<Öb,}ïCÞ’ ÐXl]h #jÀÔ.·tóÆ„¡õ×C§äkß< 9ÊB…xõ~ú¯.†Áź,§ýêb$ ´ðý*ỷèÁL~z¶ò.rÀo¯¹ã¼Õ!Ÿ9`Ìä6êv;4¶lÐ†ßø‹oáu _ýÆ¡èè`ܶ±ñoWÝKpÓKz Ûî0 Û÷ø×!ÝýðÔúÔç¿üõCð÷–ß=n‘ãlÏM÷ŒuûCÀ˜œØº^¯+Šþ×þŸÇâ Éð=åâ_&ô“ð÷KŒ¿ßçïn>ièðI¶ç¶á“ÌYnJ¸÷F1¦µ›_Ÿµöê–ÿ­6mŘ<†é›‡-Y½Ý¢™löb1™»ŽÐïœøp ŽŸ¯ôù³n›Ä…“|ŒÉwÅTër†Z b/¿yDJt¹ÌÍ‹”SÀc˜¾{‚­· [¥_ÚuЙÀJ*1_|õßc˜üßÅ™þïbÄôuU†ÉqÅäý.<'Û›Oüɯ’¢Ëuî9u§|(à1LgœŸTß’†êæ?ž¹¾¡úÖn’)B*R@ H) ¤€R`Oû {ˆë1L ˜2÷¹Jï=ð×8aª0L0¡cÂòzQ½ö“oÖ˜¨ó§èÊí#¦`ú¿Ç}2Æ 3cб»:Î'’ì® kAa#¹àEXY½Õ¡•å €T0üÇßßù¦×P8Zéz‡Ž+Ÿ¶®,è»b丙fk½kÄâÁ¿\‹rçðñ0Ÿ¢Jà¯ÙQaa›4o쨞ÓÏxNw\×õ¼âÙß°Ú †S˜L‘`#ý·«oDzϟŸqÑñ'Ÿ¶÷ßþý¯¯ _õ_ùÆ¡HtZ XM¯ºåØ%ŽûÑ©4bψ ÏÀ^zØÀhAE"ÀtìOý'ß zÈQÇ£B90“šiô#‡Éôà#Ätþe·b›k;O?÷Š“O=/„°´c –œ…Lî• €Ÿ'¦ù“,íá:ðlPhöAѳ0¡Lvµ»$øt«¾E½^8€k€­  u! P40¨¾ã¥Hظׯ0v Vt”>ë}/a#¦Üo}𞇧¡”?é1ÊšìÚ÷ýš€tèQÇ£Üï50’ãï…W܆ @Ãø…—ßêÆï1™¾‚E Uâ‘Éˈ¯aÛ"" „1é},â ÆÄT 3¡á5_nãæ¼ÚØ¬á€j'¤&È©ç× …[r¢íÂä æ9ˆ·fÇM]ˆ9A¶Zh¦Ìa¶ÍUš©Á—\Ìõ8sñF2L'œ|ƒ¨ š (¸!À_LHôÈWÚ(Î%…£È¹eÅÅ@È MëHY&Ý„1é—(Z©€0¦Vª©kuZ,X‰äú“¶Ô÷Æ„¥óQ7Ú~‚ÝÃéË®Z+ÝíRlxßzäžÛ¤ÀsÌ¡®ÆŒgWsÍFMn˜mKî ŠÃfðIŽw¥7ÐÁΊûGoiÈMÃFN}æl<ýÜ+c_~Ý0ôW¦Î¡2´Þuä1'Z². 1&¸ŽÄHÛó¹f'º)çþúêSϺC/,ˆ ÿ]‚ÇcÄêvƒµ‡ ŸsÉU{cô… tk®¹m8¶É-ÑëŽGÿæÞÑÓ~vÆ…ØÀP –~}åPôxÇKÞ’5oÕÚ=OÅðÛè¢ëƒq8é%ìG{0ã¨Ìã–÷KwÓÁ9ºÓ;.’ùFÆ1wŒ˜„†å¿8ï ŒÓž¼ ¦ë†½4jÒRìI÷ZÉ!\–Fw#Ç<L˪S[1&2L‹_ØŠ0¸ãò{±Œatâ30aîüþ)kQŽ“¾zÂåÓQL®1í%7œœ¹ p _‘L-j]t™N(0L•±_5Ú¦öat‡èø-í«ÆX|áµIÑß…?£kóè†Öƒ-ƒH¦Ngîï†é0Lõê]7³¾1EPßV8íp¤¾‘%e}É”ûº  J) ¤€R@ ´@èÚÊ\Ô¿æ?{À€Ésž‹šPhE1ªè½ž½ývôÞ'/òì'0|c –%x³æ´ºî"™BSfªow½†v×[+ÊÁ`E<8ÃV8ê¥Äð:H£÷L¯ž›%ßÖ­…­6XTQÜXð ÷\ Ëêˆq3±1bÜ ˜79üØ”…ØøÎ1'>ÖT˜Rý1çw«@=ûê%W£†À§…!,œ¼‚=¤—°=ôþÇaõ¼×ûNë.=üä3°šÒ^Š[(&Œáè SŘ$†áôÊ[€itʳëA±À^Šô“_\€D3)§A®ÜùÐ ,°‹Òõè¥_ž?qÄ,‚¬ Y` Å OúÀ0|ÚùiÂ"ÊûûnÔSKca´ÉSuÕY­½¦xüB1Ío¥××§ÜÝ:b ÉJ?¦¬Ö(qÌý»u€¶ôaŽÇ2àƒþå0®þeéã/€«†˜Û-”¸‡1ùñ &Î^ËÎX´ÆX€k °ÁrGðÊýäÓ`3»z Ë}=³ùsÞ¢S°g^xåÅC†æÓKHà–θ`Š5á©ùë`$G¹?:u9*Š%Îr(w²ð{Pô(qü=æ¤S¼ °xËy¿½õÛß9>).‚ʵ꽣ë”Pcª…™ˆ1ÅÏ*V¦qÀ¤9ËC¸’­¿M rꆹĜ p[ó_`AW,©‡1Áö ­ù^Zø‚Y…Ñ4=ò䳈¬‚„ x% ½„„ µŒ¦BÞäÝÃSѯ¤åÛÑyÁ ™òÀD/•„¼CÎÿ̧@ÆI7aL%ü鑺¨€0¦.Н[÷[0L yß°7&8‚fàx{.‡7¦Ë®Û™àN|ûï²zDýa°û=ŒÉß`zèñYðXË¥?–¦ù|Hjo–ÝOô±„õ@TcŒí§gbÛBÛb{Äc3Ð/±Õ!è¾`;è² TÜY3ÑÙWa©Ð˜I H)a…ГsWbÄ… th*#.oÔMKìÊ ‘ËÆ)ØfÀ8`ZùÇ]ÞÐËǘп!½4~æóƒaÜrï8s¼Dt‰¸é™Çf<‡ž7&÷c˜ð×Ð%ËýÎç{ÉØ*‘ÝI/ž²—aƒsŽÍ¸ÊÄ<$cî—ð†è^úçÏa@þ»1sÓWfìQ}úóÜ?õgD&kî^¸e2ÿLýß8kèÿþµoºè…mnݳ­YßÀ0=:{çÎoxtè ®¿|úC3Ö¡t€1 Ÿö’Nn›ùBw§ÏE2õ»Õ:¤&´Ï5? ƨ,«èùij¯à‡b˜Ð¦9¿‹§†OuÕ0‹f˜6’鈟üûÿsÖ ªÀá?Ûë”3ÎK¯oXÆÔ7%7^¯Ä˜²Ö7Ç©»G2ü7ÕU_¶üKR ]ÁÛóêòµÂºR@ H) r©€Ï0} s‡!Š;Z¤mCÅѳ<Œ ó|è·£÷^Y–൷âŠÉìK$™nœù¿t¤Ó¾l#ÌÜœÅî5´†V„"¤°UñGýž_ ?¼ÒC¾w%3±Ò ¯°šÂÙ&€a4óÿzTz¬·i`:±ÀšO¬ÿ´`a´©Â(Š„S¯pb˜vT?pX5fÑ%Ø0= ó)]\0Á"Šb˜OiA½š*†½”^êi5½D¿;Ę`&¥—úA§_0ì¡)ƒN?æP:^Â&’+œ?·Ïô0c‚¡ïäSÏGÂ,ò·¿sÜy¿½åÞ1s¿xÐÁIvÑ6aL®Q=j~ÇÓüé¥ÏoA¤¡ø¸RPîVPâ0³c1pPÖz‰³þ•:°u€Vt«\L€u­Æa°­ø¥uå~ÿ£ÏûÀëRmÐ@Ôs¼„u¿°œ{À÷k‚'¾æ©Æôy¬øõ æ~¼úÜ"¾†mp¨]qñ5Éi*G)[ä&àk VÀ¢÷9¶-°£ô cBxxÒ2ü z å~í°GSLâòÆ”ËWY2µkÓž ?!ÃTŒgýå[ÃÏü‡Oì4«È†ëo>¾ïSµ]ǯAÍtaõæ7_ŒGÇKçýúj´]lÐb#œ¢E2‡nK…WÕßõ˜Zâ•À•¼W’ß4aÎHÖb‚Í%4MÞ\ÞsÛú‹ Ðá„V‹Þ˜ðJÂë¦ÆÔ[laLCSÂÒg'LÖòdñ Œ)?{e¡D c*QaöÚ£]BD9uÉCÏ2ÖÖ3bÅÇ`©imºeüg¿0àÍ]º±&‚{¥GXßÖìÆëçÎQ¾ÞôùŒuÇ_>ÝK—MÿÊã¿ð©Ñ³6@yPbÃäcòær†ýë>öÄmo¼ÿ§?ÿ¹Ð?pe¾Ü ÀEð¾…«¶ñwa+ûh•V2uñfþ.àßûòáK# ò»˜f¿ ˜‡ª¿‹J˜E·ÑVò“KŒ^~xkݺZQ8ëªúÉõ )êC °¾áßI ^©o>­›Ä’Nxzý_ýö½?ùæ×¾ç†ƒ”¤@V.ßß³¯=s¹=R@ H) Òxë­·:è ‡'Ω1¡8Ë]l"ËÀö.c×ãÄ#`?™½‘QTèµ×ï½{&oÅ‹³>­¿ðµÿuý“?›ðâ7Š2ºia>ǯùB5çå“~Æ1Q»kÅÊêùOªØ]öVXVï1Áu«sþ¥×À©’-=ÿß®¡‰«@Íu=­H6ã ;ê wŒ¡b A½å /z¶$àJp¶D¿¹æNQ¸M³*È•YK6ùÕw˜01ìÂ+´ záÃ>ufˆa5ešºpÃOyáOyÃôëŸó=^TÜÕc{ìôå0‚_1~þ _\n‰ ×y`‚÷Ÿ~>øl€^BºÜÓæ€‡î—à™6RcZLŒÉ !„ ËwOüù¹¿¹¥ÓÓÑ5kÏ‚HItµî'1}|ß$c»Õ.FªÖŸTCà2àhpgý­Zbéó/¼myEÏ:P)wÖ,ÆJŸiôSÏr­/Ëݼ.1d05ÒYˆ°ôïAzxŠžø*ËÝð5bL´“£ôÁ0!n <0_»ñî± :Ž—BËzY>ñ€Ê Žœ£|’3”ò†Ðèyx ’ï± ’õHð•-˜ £k/0Ü‹ÁŠl`QÙbpÅ·¾‹ã‹0ÊÂ¥è+]Œ²ÐkÁh clô]Žøî‰ç\r5 % ½µÌ\²£ƒ1ö9{Ñâèi ûáLò¾ÑÓÀ-11h76È-`⬲rh0m ´èréâ+‡¢¯X›èR5UBŹè| c$vÅMp4Ž!Ö…WÜ “Ðå7Þo£2ÒKô‹ËtûˆI¶¬„K‹à×ñìϱÀƒ´ó~s V^ÂhCtlc×BŒ AåÖmy÷Ùõ£¢0Ì4ýýÆ¿|ùr˜áæômpz·AÖÁîvã˜0Àaùà×búåè-öz~Ê ¼ÎÔමJ$#c˜ðtH"™ÚQ”ºf É„¦oÁŠ­)¿‹!#–᧺Fï¾Ékñ»¸wÒÿwáµ]ø]<8u-Ù>†“‹5LƒaºæÆaü]¼ñÎï[øºT€0¯KP³4ªÒûFpD£@{dÖú‡g®C;ü“ë瀙«´ÃÕúVÃÌEXÒ€a9Nõ­@u#/Y];[S^ÊBùR@ H*3½·ïÃÕ„Yn]w8a„–d ψ Xp#®Q´~Þ¾ßß{ï=÷"¸£ë ÞFI|°NãŠÃ%”öUC#É4j§÷6¡ØòôÞ1f„q,èº{Þ¬“½ö:Á éÍú›¾jÃëè½?³jç?ê¹Å`±Aå`Ã~–6fw­ØWÁ0M™·ü$l\vݰ)ó_pö0eþ*˜XÌu°D[ë©¿º c4˜XñíØÉ ]gK ”Pú×ß>TNÃÊ Ó(Ö‚rñ' ª°£ÎZ²ÀÁì¨G}‚gRxt3x%˜&¼â›O™0O|ØÑ'À7uÁz,ø|hâ3`˜¸à8 ­¦tQsÕc¶Ø|/\Ë2ì!S!B€ ôÒ wÅž‰ó^‚íâà#ÿÅyWÐRÊå°‹dáÚÎÇç¬Ãô£SÏ£- K:ËÒ&oLiFõ—v=1{¦ùCnHÌÆž\^ž·üe+M놬™™n–²ÀêÀ˜É ÍÙI5”ûu‘:0ú)¯Üî[×aHÇÚ$=¬è¬(ú T˜c×Xð½›xôÒ¯.¼ˆ@€¯Uʽ‚¯yåÎЀØ`(@¹ÃZŽ„2}rþK(zì¹àò[ƒøqþ*_˜Êý °å{¾C&w}/1&TcòÊVq”»Uƒ$ø0¦†Þ/=t01&Øzö *÷TþÊ1/¨œÛ|ÕN)²YÃOÌZfmšùXªlxЭ5\¡Ìp[rKt^À~ ½ !Ä ¼.¡±Bë‚,A/Ñ÷b›¢uºõÞqhšðzºê–ñn M(Ä3§€x%Ñà÷ŒÅ+ÉbYžqþLn¹Å>äM'Lê-Œ©g=zðî+ Œ©ûe ôWf¼1Ù=a˜(º+&§/½ê¶H¢ê¹ßbÄåö-¸¬§&Õ"ÒŒ§Î„m Kö/‚¬c”Déú;FX_„”̶]LÌ{ðqKô[‹o§Jc‚=„–ãöÒ«ïÀˆt‹s.¹ Ãlô]ð/vÒi$Z ¯‘®¹m8F\ÓŽ ¸%ŸÅœ-îŽ}o·„–ÐÅõ„×Å·\ Ão ¹ÑÅ9ñÀ¦,𢶛ç[ŒÃáý˜1ËÜ„UD¾î¹d3m9Æ`Lt¼„Þ¶çqOÊ/}í`úÈEbdwŒÒ±„ÀÞ{½·€U²ðÞ˜á_þe' °áo–ˆrÙ½1cbÌ4ÊñÌÔ&Œ Õ•$Óì%ëkúµdðýþëOo˜ ÓÒMÂôùcó6Ärtí¸brú S­Ž~˜ìÑD2õ·•ÕùíW€$Ó³+¶˜[2¶®ö»Àˆî†GŸÇ²Zð%øi¸ ~?¾vvÌïÂtÙ@Ëe˜D–´¿Hs}Ÿd:Î ¤H­¾Ÿÿ2a¶Ã×~Îe˜âê[e1w¥¾…&Õ·\׆fNS EY’R@ Hâ(ÐÕzf†ƒI-]˜¨Á®Uˆ¨ <)îÎ<Ø¿¶ÑÏ#§å^$Ä!¹“¹mÛ6ðLÈ’•É*\P¿j4cÉ4~v’ Å\¨Ž›· &c˜@ ºn\1ËÀ–9‘Ç“&vÝ{d aL0±¼2Û]öVâ)0¢"1’ü*qÏe×ÞAT ˆmªî¤/ ­H0 Œ™´Ͱ¿OÎ]‰ $ØNɬ[á4°—à—ëäÓ<[kÅŽê¦?ù4ü K)’‘+°¹Á¡ö^¡g Ô¤ã~t*XM¯¼ù Kg^x%é%ì¤Õ~w`2¼Gõ؆½î£Ž§ôÂËoÅ6l¤øK§¿håúœ©Ã´¼Èœ÷W``ôý-áÍeÜ›"a*ï,4Yh¾øÂ¢Ï4Vh²à¤Àæûøª"YËè–ø{É•C¹¬÷,Ÿ°D´„v‰ÍcYÂÞJx%ÁZ!Ï¢Lž1“ɃhëLlTN­Šè´˜:­¸î×z ŽÑåÜOVoL­ÏN7®Èát”z¶=øöðÇÅ÷0*æØ‡;~®Ìq.éø1H~wÄí”R]ݨvPª=¬ B ØN4nsklž–ÜEB6Ò6jG\ÕQ·3ðfϦš*¡âB.—nºg¬ÃÙã1n‰¾dÏÙ‰Œ3‚ÛbÆUƒéVPîj(Ü+ Âëºp7Æä×ø¡¾ÇÍY“Ñ÷Rt—¥G…E*.ÆCÕ¦íïmzëñ±«÷‡'íöaLø‰dš¹x}µS[‰^ÄFt²eýTúaò Ë¡'ࢠ“|2u£YÒ=V$oóŸÛ÷»¨:{·õ‘lÖŒ¹Lgû¢ “È’†K¨\'€dBÇ J/U@RÚO‡¤„iËN¯o3Ë0©¾•«ú´ùi„1µY`]^ H) Ê­z/7ïAðÄ=!Oæ‚®Îq ¿‚} <˜ž“¢{Hð¸ËÍ_:µ={6¯`÷ãÊ@yH2át3xðàP‰àâI_!3üЏó€!Ùö‡®yYÞÎnA 'ò©í²¼ KeÁ˜p)†LƺBÊXI2||vh­ ¦PïËÀ¼Þ»T¦J$èŠU3C¹~˜ÜÅ`½F2ƘXF Ù]Lªkh5T%£qµ2ï[5«z¥_–,þŽë·žäJÈŽj¾vlÃE—Òl§µ >CVS†‹ÚKÝužµ'˜6ŽN'8À°Ež4™v8¨\Ô¨îÚØ'Î\ö×ß§º&-›¥Ý/ýZ{=Ózmð ¥&Jßu¸תöó8Ëyhů[†=4…>·èv+âï¤â5Ü1•ÓùV :Pú(ti’7¦Œï( Œ‰S-ÀDq€1Yó•4·ˆ&Ì\–ôF«iÇ’1‡[BÃÅ~‹Ø4vâÏ}UÙKÊ}CÙ¼žÛ4Ù\ž½’⚣X€i³»8©É2éöW½÷œ«Ü>&Ýô{”R I„15)œNË»=‡1ýÛ•·E‘#Ûƒo1⊠¹(R–TN2'1”’gL±Ë*²ö–ƒ8áÜ€Üa\©_Ç·ëAKá8qSão °6üßÓ®íñTÇá¡ÁX¿Ð%ÇKŠÛ1‚¿%:^Âß”pïé P²ô¨b1¦  ûÖã+vÜû+ßöÞ¶÷þЂŽI¦‹ÖtãPÜ&Y‚áteî<†a꣦-f€Kb˜D2å½ÍVþ|<’é‡<½|³ó»–Q²mtWÖšU:&ÆbíâÚ$†)…,Y»«áUÂ*ÃÂ)@’ÉES µ Se1nu$½¾¥0L¡ú¶ìÞ!S|驚ÀÔpîeƒ '¦2ÜJ„1µRM]K H) zN€2@pðî'*ÂC¤œD]Àôu¢!là_Ì=ø»‡ÎŠp$¯ÉÅ…Àž¸ÇÍ€ˆóÖæ6 ‘K2 ÃíAì-QoLÌŸž‚ò‰è—Û8‘¹ÂGhÈeÄ”1ê‹26]I27Ë5¡¤/?ˆ2LÕÈã{TÄ®û#‹g÷É´ûÃí±‹ SŠÝæÖ_vWgÁgÈâê¬ÿtãéDWFX¥À¸Z ¨O,E¡%3¯ÅN ÓéNÿÐ¥`µ§ ¯ÔÚK·ÄÐK¾ß‹jìžTz &PxâÁRÏtWL8¬MÞ˜l Pìrßñ3<Œ©f¹o³¥oR§¦õ:Ä’o2Š-ý¬Ü’Ï>†çQpÍYñ¬õõÙµa#'ÃßI,½ÔOv …Ž¢Ï@Aåš~Å”üDaL“¯b¹è‡S쬢ñI8`üŒ¥YÝÔL:ÍW”[ Ý5 mÒ{*xIÕ¶QÉôRí[ÉdI?pÖFÄK˜§kÎw€0¦’7)z¼+ Œ©Ã‚ëvR ç0¦_¹5ÆR…1·‡ <.倸¯âɤšE?@më?"•âý*UWñã«d\)˜O­%–b=-Õ…–ØÑIô·TY?T[ÚêÆê{]ÊÜ%J§”ê~ÛOŒ)åwºß­žI®%’LÓ® Ö‘fsÐÿGeaغ¿‚Ç3yT–a¥3LœAýíZ’y]D ´II“&}å‡Ì]¶ÙÖ¦„µ+k˜’êï"aâïâÝݺ3ð‘³7ÍnÓê²¹Rà¾ûî;ì¨ãl wœ&Ï^u%·o²ä›&€PLϺ ëÛ¿ðGˆ0aЀÝ;·EÕØÚ7xS®TRf:­€0¦N+®ûI) ¤@©@c&úC¢g&n×± œ‚¯ c2‡ç€rp|ÝãbL8‘çE\‚‡§×Œ5|DÉe•ð/om@T¸nj(¿â-¸§À1I¡%-rsEhÉ2ŒLº¡è¨^`1{!Œ‰·èg=Éô¥_þجŠ¿ Ì÷U¸ìu–~˜b˜†LûÝ/»]÷W_ßÝÏl—ãt`L-±»Æ!JK­°}Õ™ñ±¬&KQfʼnD y܉ZPSœîTÕÇy©÷‰–BöÒx×;­6“¶ cJ7ª?>})¦ùëZÝ[^ú kIKt¹”¦À-}¨zÞª²kž×/%;ÖªkúŽ Œ©ímëŸBS²¦Ä˜Ò›/€V®æ˜¸ +Õ·Xíû«ê¿ @-¹¥PTÓXt‰ÝKQßKî\^ô}û&j¨µÉ2é&Œ©õ¿b]±—ÆÔË¥_êgï9Œé’!·&‡^Ç·•yÊšá±ë-)ÞsRœkb×ëc§bשReD*Å®ªqhŒ²"Ãl['ä·bˆ¥ˆ§¥zÐRBœ8ÌÔ:#ðŒÑâjÖµzH–±_•¥G•â)©q2o0¦¡‹‡Â!Ó„5FÃT1yda˜¶ì|ÿOþs©›>=\?ñ)L³—¾ö1À"£Ä3%1LÛÞ¨ù]àÇ‹Ÿùài^¨þÀñ[Žý™£ÀWö«/ƒô=ù wÝs/zY! ’ÖÖ7†U­e˜‚ú–‘aÚñæî~oÁ̓¸ßªÑÞ+™à™‰Ûø`)º{p ¾zyn7KOc¹ZS¹ÊSO#¤€VJ¤…\ŒÉe’1ºÂ_¸)2Œ g1ÏÀ˜ÀáÛèž$ŒÉÝ+r èC¾Êö»î…IP¹tskWã²`L<+„1™ÿ$>]ŒÉ¸Ë-á©› 'ªA2zä÷«¡<+˸³×·ì sˆ°q ™Þ~e-þb{çê> JtÂ/Møl÷ã/cÌa?ŽÁlÀcSsOª³Š¡€0¦b”“r)¤€9U€Žˆ˜9 B j\fð þµ¬¾ã•3À×Y»v-N‰îqÁ »¼(×aŒ6Þ"„þ`Àa¸¬eù1'F8W¶s!oLîƒð¦I“›PJtÝd¹¢,&2‹1írËØÍ'ö‘îr3I‹®úï~)¶†‘dºÌ Ç„Rõc»Ü¥!† ˜žß´ã«w;|ñ“¿ÿð#Œ á¬—ËØ¸Öì„];9r„ýÇäô÷ТlcjÎîšhn­µ¯¦-M Ub•hx¸Ø•ŸQ#jÈW}·6œ&˜LŒ×*‹hû0¦£úcSû0Í= í¥Ÿ!X-çnj´ô›×¢èRGVù cjQƒWºËcJ.RbL)í¾Âhåb´šYÂ0®”Ï4Ö9\LDËZ¯KÑp–Kk饸ÈqÁ,^#L뾌²Lº c*]#¢êª˜º*¿nÞ>zc 1Fî¿lzäqÙñ£4>)yüœ¼&•J)TŠw­-U‘a»v™ýI†FÝáq—ïO"‹³¥,ÜRk½àÖí0Õ= Kª Œ F+.¿sÁØ­€;`'éضð-Û°jeáH2MzfmP1*ìGcQÖúÿðѱÍÔA~˜Ú×’êÊ]T€$ӌůÔü.|ß¹¦eS'¶W¿ü0ñaÒß²£C?sü䱇ÇcnémÖ]¬»5H¦CŽü>_ÖEÎ@Rÿ•šXße˜¼·ƒÏ*aƒÁ3[ÂNlÃKþ‚X¿ØoßfÂÞ˜è®IŸÒ* Œ©´E«“R@ HN(@oL`hÜgÜZȆzcâ~¢<ÜÃq¢Ø=Ęx5";ü‘¢#%° ycbNHGñþkÒb–’Nç·Ä˜˜swdÌ?‘ÝšÏèzKâÒÎE¾°c'Î¥¿(^*ÄZa?¯æJÝ*oL¼#I¦{¬sü§1ÇS—]~óˆo|øª ¯3âslúŸ7ÃÄ•-t¼sFˆÁ#W°f ô¬ ;QÅ»qbLYì®u|ÖPÏÄê¸VJ5«¶ÌW}ýPqþ‚Ït)ˆÑSC®TÖy¶4dX][(hÆäÕ£Õ`,0¦¿Ù'=ALŨWú©‰T6ª§”¾ïÆ;&D`Œ³%oÈÓkŒñ<¦ _àš[+„1u£u,Â=…1%—’‡1ùÍW4ùŽ”<8 Œ™º$éí–äÅ ‹kÀtÈÒÆ…ÂYz3z•äIJŒ¼˜ZJ/YS“eÒMSÚå±8 c*NY)§ )ÐsÓE—ßþœ= |‹éÉtßHu¿ :UïÄ„“ÂéDÉq§”Îq½ëZ)˜¹OÕª#®ÌÄRxì b©ZŠ„û.—² ž»xL–UWÚy&¿ ºäÙì|>ô% Ëõ˜2œ"ÉôÔÓk][A'µ0Ųb˜jup±ðI¦ƒ§/zÙ<“E­ÒÁÊÚ%¾•°b"lΓûC޵SÛÏœçìgnäb±äUnC d `âJ°ùH;¼%í=ØÄû’U¬œ0KâßÝ;·f‡`]4á/·™, ±œ c*g¹ê©¤€R  ¸Û‚‚Ê-åà (‡OØŽ\µ$<\?µ H¦Ñ3jL(Œ9î/?°0ОËY–…ašºzÉ—ïýrH÷ÛÌ*=0aƒ ذí K¿²í®I¦×&ì®U+kFãj…VIZÿ™è¨>bJ­»ìÓ™Îä¥~Š_Ç‚Ôqtɵ¾¶ cú~J陲äc³O]»zL€‚„M¬þM³¥ûk}-5Zú!j-ºÖ×/ý®k˜úù6é‰Ó…1%30¦ºÍ@+—ôYÔ2Ý3\ŠSÀ4t)â ®åÓsY&Ý„1õDâ‡ì˜˜:&µnÔYzcºðò["`ÃŒv\x™‡1U¨£Düˆ ¹BÉóÊ”œ!t>©B)͉¬ÉâWÉq­DKÁ‘Fp¥xb)#´”7gKu{`YzTM`LF,Ù XfÕ¢‘Ë–èa›ëö²|H2=1o Aõ-–ÕÔEXSh@2 øÚÁSmªL®U:`±éXr¦’K+ºvj÷gî:]cpÉB‹¬Ì› ™þÎ÷k<á¥Ö·æ&c•À-!¨ï8 ¡âàu N˜Ì÷ý6á_PM<ÛîÎúfQáRaL…,6eZ H) J¢@ÓSIž¿8A’éžG¦;þz«~¬JÕ•u†iËÎ÷/Ÿ}ýj㯭L3+ì<ðÌä:èÅx0‹îâH“S`LÝ5@ŽªWÚZ»kŒeÕ5´Æ›Xkí«Ñ@`¶§Ù•ŸivÔ´ÅVª¶Óh¨¸Ž «kµÚ„1yFõ˜e½A5xt²‡1Å.ôÍdcÏn]O6ª‡ÂÖ†)Hö´èQkrKù±™ËS¡›Ù6f^S²¸Ä˜¼ö-þíæ½ÑpÀ£“×iÍÒAÛÊRÉð<`2aéº\ª¦ç0äx©²Lº cjãÏY—îA„1õ`¡÷Æ#÷ÆtÁe7§ðFøöïx.²¤”ÑrüWË·§ÃIÖAñÆTqî”"ƒ«P)žUJ —ˆ+ÅKþ¢4gÕuuåPöÁyÊ‘YzTÍaL°a]²•v\‹ÌXä™`ÀâÓ¨’Lç®!©ÆåƒtÂZA¨Xr½Ñ’ë)=H2M^¸É]VkViwemÿ&Ü?düœ±avêèÏœßâ0üÆ dTi•C’L$†mwl}kŽa‚Jd•°ðp¨A€™ð/ü3WÕDOKøÛø {Â)ØC§MF8•Cp=EŒ˜T-¤€R@ tO¸/ y0Šîé^îtçH2Ýýðt¯÷ž`B1WF† ±ähÏÁš4óÀÄ -?øŠëXhó¡-Ȣ˕µ„€1ÅØ]+kºÝ5«¡5uågŠ—zgñgWʼò3#,ên§b;Í…¿¥t«iû0¦«{¥Œž´ÓüI&÷–~½u¿1Ð’_úþ9K¡(*}aLemûû\˜’$ÆnßjçqZ¹$G€Õ&.ŽU ÖI6ê°6–e|ÕAtÉ}ïd™tÆÔß߬Η®˜TJª@/bL)ã" §1+éö*æøìQFü(i­Ou 'Å#JŽ;¥øÀÛã6;àZª«CjÇZIQá\Éqt\ b)vŸ¥GÕÆËS®%ìa¤9þÅËò°Ýœ‹$Óø9/Íx³ª+Å0•´ÝÖc%*’éK”n]„1¦¨”Q) ¤€R û d6jªkBq—»4Ê0uÿ‘ò—`LQ»«ke Û]@9)ÆUÇ‹Ršq5–Sñv&ÚTc\ì$¹¨úÚ)´‹úöaL!«»[ú£žZ„iþº Z´&D¬ëÕi~ZÔÓÄǃK³¥WÝ,•Y‹ÚÉ…1å¯íÌGŽ„1ÕØª’M:³‡hßF=¹(óDa§€ñaLS}ÂÑ&¤nQÉ2é&Œ)¿|å¢, c*KIê9B ôÆtÞonŠC‹‚a0¾ýv#&=JÀlÈ”eì X[Oªƒ(¥ƒJ‰®• µB¨!,©Ñƒ³ô¨r‹1áÇL’é±™«£1þÎþõG{âº-捻-;ßÿÓŸÿ¬fQ ”LL_<èà‰ó7àwjZ⇩dréqú©€G2~l`BÅÃÔOauz}„1Õ×HGH) ¤€R ªI¦;FNå$Ÿ;ZÃÔ’ŠŒ)³ÝÕ·²f°µ&ÂIÙüÓ{¿#áÀR\Ô;¦ÔÊdp¨m˜âŒêUûCOz#³·¬ôë,ýM,ýXK=Rú˜ZÒÜ•ð"˜êaL)³ŠhÓо=ôäÂèDagOÙÖCl«qârÄ-…,ðY&Ý„1•°Ñ#uQaL]_·n§=‡1û››RÀø–bê¤>o)SœûÙº;·TGÑq±Þâ#mû!üTñ É ê4âT©ŒcìF¥,ÇgéQåc2’iìŒÜçÃÔÎfS×.€ ™üê·Á‘¸¿ 1L(¹bf$j—[ÙÄ0³$‹–kaLE+1åW H) ¤€èº$™n1E S;ÊS¿ì®ZëWkÜê$TËŒ+%™FÛ…1¥ÕG>±Óü)N³1³×/ýÇZ=‚+%•¾0¦v´~e¸¦0¦zSúŒ!Ú7´rÁ1õ' FlÉ–ÄÙÀšqù…–¢­M–I7aLeh7ô ùQ@S~ÊB9i©½‡1]zS xtî¥7!:Ll`l€G5ìQÂR·Ï»Bœ”Æ'9}”Üx†Ì åÿ˜,=ªœcLQ’I SKI]¬¨ „H&1LE-È‚äÛ%™Ä0¤ÐŠŸMaLÅ/C=R@ H)ÐyB$“ü0µ°<Œ)«ÝÕ³²6mk7®Ö.ûLBU  ®U†Ö6aL Fõ`¹ïȉ ÿêoö©XÝ»Qúþ¢_UaL-lôJu)aL©“Ó|…\­9qAàÿ¯QÏI¸RÄyd«Þí¾N–I7aL¥j@ô0]W@S׋@h=‡1 ¾ôÆÒß"4LiäRGÑíÈ€Ù<'9>“â<'œ$/J Ü›¥G•ŒÉ%™Ä0µ§©ÔU ©€‘Lb˜ Y~EË4I&1LE+·"çWS‘KOy—R@ H) º¨€‘Lb˜Z[ À˜’ì®´µž“ÝîšÉÄê8R¢eÕ‡TĩԟnÆtø±IVw”þð‰ þê¯÷Éduo®ôE)e3ª cjm»Wž« cJǘþzŸhûæ6hhßÐÊÕ4qqMYbd•ÚX·u›ñœeÒMSyZ=IÆ”‡RPÚ @ÏaLû|âÿùägLJûþÝ~ÿŸÿëÿN9 ÓWŸ>ã¥B(ð?ÿé³ÿûÿþŸÒ³ú_þë9æ©u[Þµ´iû{mø1ö÷’}K—í¿ÿþG{¢›Õèö–ïÿéÏîïÍt¾(ˆãGÄ èšß\šþ»Øö†~)Ñ|góÆÛ‹ú6ôþaéõmÇ›äû9”»‚( Œ© ¥lJ) ¤€9T€$Ó7>|Õ†×Szï0¡üþÃr˜ÿ|f S+í®2®¶Mÿðÿcº-æñ›n¿/ôÓH¯u÷ߺQý~Ò·Á&›åÃ_µíñ a²n_&ÿëûË¿ßïS®_ññ?*ý÷¯–0Ÿínër%Œ)cªÛ|ý§¿ø?þáŸ>ßÄõ^köÿëÓ$½ƒ¤s¬Êÿ¤[ë~cº’h§˜ک®®ÝEz cÚ¾}ûìÚð”Pºýž‘ÑÚSb²”xhä–OŒ íÈúa§ïyg{ºN S\ݺ ¬½ñÿyݤ‡R~b˜ºP.%½åš]÷_õÔ~ö¥Ù)õM SI ¿%Œ©ªëžR@ H) ¤@iX¾iäÓ«ÇŠajaö‚ÝuÄè ¿¹ëÄ¢›I›°…â—’^U>øàƒÕ}Ìø)峺£ôQ ]²”þÒÕ›…1µ°m,Æ¥„1¥–Ó‚ Ü&nâSÓòپͽý¤<´Qu›š1geÒ­?aå²ÇÆÔã ¼ß[S´Óý%è[)«@N1¦w¶ï9ý/þøÈÙ¨ç±Ù–¦ò¶äz²düiþÝsLjÍÄ0©ö´P`Lwõíµ~ל¤ú&†©…jëR{„1©H) ¤€R  Œ]½ÿ˜>SI’ E~˜ú¡npjù슓WÜyÍôÿÑ·¾¯|V÷‰­I?®º7Êí(w”>ê@nsؾŒÉS£õ¿xÇ cj¤ÌÞxç÷íû¹õçÊ¿ÿ·O"õç ]<7§“nT +º¦€0¦®I¯·WaLÕHa]|CëÖÅR §=ªÑg×ðH¦7·GI&1LímJuõÜ*°yùžëÚ³jòîßmgÄ0å¶Ü š±Wß™üÄÚƒví^[ßÄ0´Xó›maLù-åL H) ¤€È»›Þz+6¼ùx¶P,¹V•_±Ì}us»öÕ]·Ì> ˈ…?«{pùh´V”cB¹£ôQPÊW¾éO$Œ©Ñú_¼ã…15RfùʶÍåMýl/l±Êé¤[#CÇJ®) Œ©kÒëÆíU@“0&)аyìQù®˜ØOÝ3ú¬?~ôg—dÃÔÞvTW/ˆ!²D SAÊ­¨Ù Õ71LE-È<ç[SžKGy“R@ H) ò­\1cÂÆŸþüg—·ÃÔ¢+â4jJžéЉ©25Z1J†1ÑS:dÆÔhý/Þñ˜)³|bLðÃÄé¡‚:dÊã¤[#µBÇJn* Œ©›êëÞmT@SÃKÉFàzœ&ÈcŠ®˜˜À3½³ÝH&1LmlAué|(°{ç¶ ƒ ½ýÊÚPŽæ^6hkßlÛid‰¦|]±s1dÞô°ú&†©Ø%ÛÜ cÊmÑ(cR@ H) ¤@¾0WL$™Ö¿ñ°‘Lb˜Z[tMØÜr{йb"ÈÒƒ™­%Ø芉©2 cj´þïxaL”Y1&sÅT\‡Lyœtk¤VèX)ÐM„1uS}Ý» ô:Æ„WcúðxéÚ]«6¾Û!´2ÖrPÜ(ôôËbÞÆe—v]1U2á2 ™Ä05!§N)œ/=5bÁ̓c³ ¶ “ûÈ1L…+âf S]Œ Ùþ÷þ(†)‡ÅW’, c*IAê1¤€R@ HN+`®˜ˆ1xþcýé’L¿ÿð£Nç¦Ô÷+“ÝÕuÅT2‡L«_y{ñ‹o¤ÛB›˜]ÆX8ýšYl°-7ü6wA×SÉ2­Ýü΂Õ;ÓeÙ°õ½?üñO¥n«ôp{öcj¤¼»ûÃô_M–_VsÍQÒYæŠ)Ÿ™ž_ÿ&RÁ&Ý©:V tYaL].ݾ] ô:ÆÔ.]u])ÐI\WLŽC¦NfA÷’ÝR Ó#÷®„—çN˜:x Ò²{79ø ƒ—&î‡s&æpÏÎÕ}Ýʹî[\FR@ ôˆ˜z¤ {ï1…1õ^™ë‰K¦@Ô“2•¬ˆõ8õ Ë%|€%mí› J {à tË„st×ÄÃð-3ò©Þåõ½+D  öº|@¥Ù›fóP°M œpLß¶>&9dR5j½˜Z¯©®(¤€R@ ”\XWLrÈTòRï÷ãźbbµ‘C¦~«[€ D]1 ,@±)‹* Œ©QÅòs|¬+&ÎÉ!S~ŠI9‘mU@S[åÕÅ»§€0¦îi¯;Kþ+ðá{n9xÏ yéê/ìùù^{.úDð/ö`ø¡(»æQ –À*aÁ&7f¸%üK/Mø–„“qNeIÏ×b€+KrÑ%z`ÂN|‹mFšÃ_&O-΄.'„1©H) ¤€R AžÝ|Ökbz`ù_Þ»ì/ìßkðb:¼WxõíÉVOF­ø–ñ/~Áöìþp{¯ѓωòµ²¦/·Ñ«þÁö nô¤*zè2* Œ©¸¥ŠUîœB:ë/½dÿâ+}¤€è„1õB)÷ä3 cêÉb×C—R]›<Ä~⥥|8=”HR€Aâð­ùd†Šã_| oL<Çà/cÏáHûJ Kì LÂñ†.a˜xÒK†:ah§ k¼°†úHV* Œ©•jêZR@ H) ¤@Ï)aÔÊOôÜcëû§@ßÖK²¼û‡Mý»ŒÎ.¤[ßÒ_³ëþBæ^™–é c*G !À¤½¦€0¦^+ñžy^aL=SÔzÐÒ+ Œ©ôE¬ŒS˜ài ß`Ü\.LÂßÝ;·câ]1ZbŒ9R  àZ ÃÆÙéØÀ„4xÚ`D‘Ã~lc'ö4q"ê( ŒIUD H) ¤€ýP@S?ÄëÝS…1õnÙïÙ#Œ©—K¿üÏ.Œ©e,Œ©娧* Œ©QÅt|AÆT‚R6¥@]„1Õ•HH) ¤€(˜JS”z) ¤€R  cê†ê…¿§0¦Âa?@S?ÄÓ©¹W@Sî‹(S…1e’IIÒ) Œ©tEª¢˜T¤@YÆT–’ÔsH) ¤€¨¯€0¦úé) ¤€R@ $* ŒI•£ „15!ZiNÆTš¢ÔƒÄ( Œ©ÕBS9ÊQO!U@S£Šéø‚( Œ© ¥lJº cª+‘R@ H)P„1•¦(õ R@ H) ¤@7ÆÔ Õ OaL…/Â~<€0¦~ˆ§Ss¯€0¦ÜQ¦ cÊ$“’¥S@SéŠTD„1©&H²( Œ©,%©çh¥»ßÚƒ™þ···òšº–HP`÷‡ÛaÖüýGoI!)Ð „1uBeÝC H) ¤€(­˜J[´í|0aLíT7ïׯ”÷Rþú£€0¦þ¨—Ÿs…1å§,”)ÐI„1uRmÝ«ƒ cê Øº•h«˜Ú*¯.^P4Í_Ђ+f¶×ìºÿ®¾½`Ù,fö•ë¢) ö­h%¦üJ) ¤€¹R@S®Š£(™ÆT”’jG>…1µCU]3/ cÊKIô/˜ú§ŸÎ–EU@SQKNù®£€0&U)P„1•¥$õ­T@Óü­TSת£€0&U‘Ž* ö­£rëfR@ H) ¤@ÙÆT¶íÈócêˆÌ9½‰0¦œŒ²Õ„1µDÆ®_DS׋@]Q@SWd×MÛ¯€0¦ök¬;HÎ( Œ©3:ë.ÅR@ÓüÅ*¯‚çVSÁ °hÙWûV´S~¥€R@ H\) Œ)WÅQ”Ìc*JIµ#Ÿëßx˜1ðoÇÅuM)Ðe„1u¹ZtûË÷ß’I) zMaL½Vâ=ó¼Â˜z¦¨õ ¥W@Sé‹XØ„šæoB4Ò¬˜šUNç5¥€Ú·¦dÓIR@ H) ¤€ ˜TšP@S¢•æ”Ñ«þ`¦Ò<‘D TÆT‚ÚðÎö=@n9¸¢GR 1„15¦—Ž.Œ˜ STʨ¨£€0&U)U@ÓüªT@SÅÖ­öìQû¦Z ¤€R@ H~(0uýQ£V~¢Щ½¨€0¦^,õÊ3£ÅÿâzY={™ÆT‚ÒåôŠR) zMaL½Vâ=ó¼Â˜z¦¨õ ¥W¸ýõ©ŸZúrÖ6¦€¦ùÓKG÷KaLý’O'7ª€Ú·FÓñR@ H) ¤€p˜óòɘT#U`í®ûáÇk÷·7z¢Ž/+_»yí®Jð z)£ÀªÉÞÌÂæå§À pzE©½¦€0¦^+ñžy^aL=SÔzP) ¤@* iþ,ôî=²0¦îiß“wVûÖ“Å®‡–R@ H) Z¥€0¦V)©ëH) ¤€R@ H)Ð5„1uMzݸ½ cj¯¾ººh­»wn›0hÒÛ¯¬ ]ù¥§F,¸ypko§«IÂ+ iþÂa‘@S‘J«yUûV‚BÔ#H) ¤€ÝS@S÷´/Æ×îZ;aÍ„bäU¹lµØêKêzR  L<3 «F 冓¹È¢2QOÌ¡°P”*ÄzRé{)Ð3 cꙢîµÆÔk%®ç-¶)¬ÒÜËáÛb?žr/Z®€¦ù[.©.˜¬€0&ÕŽŽ* ö­£rëfR@ H) ¤@ÙÆT¶mõó ¸o@ß¶¾V_U×+€(waL('e±qRX%L+`r¡ñKêŒ.(†éÃÝïEo¬BìBaè–R ' cÊIA(­V@S«Õõ¤@Û@Oô‘û¡ŸŠ xcqd ºhŠîyî)È©m%£ çXMóç¸pÊ—5aLå+Ó\?‘Ú·\2'¤€R@ ä]aLy/¡®æoЄAûݺYl™7ÛCñ|°€Ð0|‹mQ/]-®VÞ^¸@°!¡¬Q Æ6ŠEŒ¯p'üeqó+$ÔVæ@×’íQ³˜>Àägð—SŒù?tÑÚ¯™…ö”FóWE‘Ýõ™½èŠ)©—Ý;„…‹âÃa6a¤PÍë®3¥@ÎÆ”óRöšU@S³Êé<)Ð 0ØØ¹Ú[ fè}¢cŠ=„à¯uOÑ‹ÅØckßlâùHØÀ’‹näZ÷”ÝS@ÓüÝÓ¾ï,Œ© ½›¬ö­›êëÞR@ H) ¤@áÆTø"lçl{oðÜÌ x&P,ïýá=À+柉ßbÁ&ÐË2dÈý*ŸþgíZ$(ßOŠO±žË ¥ V‰™G5àJ;ñ×JܧŒiE?ÀÿNŸŒéý@ìë“K³ì‚µýHc•lÁ30Æ’ã\fHº`Çhf¡íEÒø –ἤB$¯†P œ0²‰$Eóh\o! ¢€0¦‚”²Ù¨˜ULÇKn*À®'»¡H$ë1®À6»§ lŽ—ì[€~*(}¤@) iþ*ìî<êî·o}w6ÓÂ-çßշ׊7Ù|Ûlé®eU`÷[{Ь1ͼiƨãίîÙµ©¬Ï­ç’R@ H) ¤@ËÆÔrIËtAƒT\>‰è>³7Í&¹ÂÀsL 9d¹~Å:t(€2 hÏRDŒÉˆ%Û`Yó¡@/¡zÐ Ü5ÑSWCñ1ܳmÛ6ü[Vˆ •\S®~׆³`©³AKdb8éDtË„frU|Ì æƒ¸¦=©±…ˆI".hGirV sF+»¶Hè¼ÆFM.Ìó+£R  „15!šNiD€J¿[ö —¢ û…15¢¥ŽÍ À‡ìü1^ŠM¯.Ïp "¤€R@ H)à) ŒIõ E¸ÛÀ„€ªZ†ùgÂ6¾5~…H<>ã'„1õËÂs DÿLüGòß ¼Ø@îžÙ³½ŒáxB0ø‹m Î º¾eûy¯Áƒ#?ØÀìʼ¾rïèn‡.‹¼ñ^6£,y8ÌuÄeè ×uËD]F°Y¨ÁŒùw1&œQ^ذÂ1ÂsññMC^Ùö° ¬Ä­ °Ç ÑêkEôú–[Üwä½Pô¸¸•u´¾¹¼·CÙÆby¬B˜2ÖŠÎFV‰Þz0YÀeÏØ0ÿ=øì vâHÒ0šYèLÑd¿ Y´ôBÄÕPp(>zÛb4Naæ(û½t¤…Q@SaŠJmLaL饣¥@0VÉVN˜kPŒ.Ðeg”94—¡ì›ÕÅüëÖR  cê‚è=wËg7Ÿ‹1aÏi¡î€3|'LÑtÇQ¸¹n!¤€R@ HÒ( Œ©4EÙŽ¡›%\àZ° µ ºúdâÝA;MX`FYòàrôTD¤‰¬È#ZHÑiÓ{ï½Gd‡‘J!ùPÉHìáÁø‹cð/X"lã\|H5…®ïfW#=ÃÓ±a>¢ìØÆ‡Ã;F/KR‡÷-ÆdÍàq”ˆ¤š§Éâ¡tÑ„¢'¸†¿ 9âÂ)2²è±A‚Í ‹z’ "»†Ã¬hH± ¬ÄYjø—µg¹erÄñÑë[é³¢°p¢}DEë.ÅÌà‚±—µ13˜²49ÆX%w³ X29wú€ûñW3 )ìwá¤OR!â+À¥ì¤—øÿb' T«Ü³K­#¥@‘ÆT¤ÒR^P@SbéP)Ð]È*!ôÆ—K膮„HÜOÊGÒ,÷(¢\w‹Owº£{oÝ5Ö!“\1õV%èäÓ&9d’+¦N–‚î%¤€R@ _aLÅ/Ã6>À²)æ0øìÚbØ 6p’ñ.ód)ó´ä²M¤”ð—°¯l’°séu‰¤ˆ‹1qO4 [ôú–as… òv¼ ý*…ãÁ¸;Ý….ëâ5@^Š…1Ñ&ðItÄ…Ü/±J`5wÿmècä5méE‰EF/VÐ–Žšè+Z±“+´eÞ¢×·<[=‰^0Zß,È$¶£—ukqº†ÄÑÁíS€¬®Ož ó˜kà”6ð-¾â$þ2ÒœfÚWÍ]™³?é…ˆR¶"”µ;aÄRÖG H* Œ©„…ªGòƤz ¤€åU@SyË6WOuÈ$WL¹* ²e&êI®˜ÊVÆz) ¤€R í c‚SÕ¶ßF7q Ðÿ ¿èã¢'æ¢ p’‰^‘Ì÷öðDóäÔÆÄë[î\ŒÉ½ ë{ ó0sÃÃ̸.ëÒ0Ø.ÆÔ ëú(²ˆr.„m:å'DÐ-䋚71ÙõÝŠ„íXŒ)Tßp={±ÒF³íbL¬ T·R@ H)ÐÓ cêéâ/óÃk¸^æÒÕ³I) z]aL½^:ôü!‡LrÅÔ!Ý{ö6Q‡LrÅÔ³•A.¤€R@ 4«€0¦f•Óy-PÀŘp9PJtkd®•EŽ ïǯ,|÷0ê9eq $^-t}÷I’0&ܾÂé=ˆ.yŒ¾ ]ÖÉèi-¬D—p1&(I@Í-,F‘+F„ˆtQ´ \êˆ×ŒrH,,œ½¾)šâ)ZßpÑ%ÖÌèeC1…1•¨æêQ¤€R ¯ cÊkÉ(_ýT@S?ÔéR@ H)c„1å¸pJ–5×!“\1•¬póø8®C&¹bÊc )OR@ H) ¤@ÞÆ”÷*uþ‚Ø#2xœa(€NÈàÒBøËãIq'90L8—aÈx þ;‚¼6ð1÷ú–c•ìtRS8€ÐoÊgøXc/K¦Š¹ÆªË.Æ„¯PŽÔ™…ee’5ÙIªE ÂJ“á۬ȬPXj¬¡ë[®\ŒÉª%«A´¾±½â¢—u÷c*uK¦‡“R@ H|( Œ)å \´\aL-—T”]Ràý·ö<ñ›=€6ô‘RÀƤÊÐ)Ì!“\1uJòÞ¾ëI®˜z».è饀R@ HæÆÔœn=~Ö¶wg÷mûÍ>z«­:¸±ÞÚq£6]¿M—m‡Í]sÆÆã´f©9étV€a3 »6 «Êb’œ’H5D ô ˜z°Ð{ã‘…1õF9ë){A 3ð®šxi/<«žQ dU@SV¥t\  C&™5[ ¥.‘E:d’+¦,Zé) ¤€R@ DƤJÑ„}[/Å ïÝ?ljâ\RtF­üÄk*úS(ÿR ^gî÷, Z ]èúÁé!¥>R@ ôš˜z­Ä{æy…1õLQëAK¯€0¦Ò±° „15!šNiV8dºù_âo³ÐyR èIËìÑLÇJ) ¤€RÀƤÊЄ˜š­4§c*MQêAbÆT‚j!Œ©…¨GÍ) Œ©9ÝtVîè-Œé¦›nÚK)Рÿå¿þ·M›6åþ·¼gÏ;ÛÏú§½–ß~F²ª,JŽ) Œ©cRëF{ö¼õÖ[ÇŸôü•R  |ðÁÇÿ¯Åè¢t@ÝB H) ¤€ * Œ©AÁt¸§ÀS‹ÏûÊw÷zý5’£8þ¬ÿûò{?Ûƒ®GîÞšyïÉÿc¯·–<Ñ [Ögüൗ=3ÑØëÊú€z.) ƤÊQRz c:ùä“oºí®­»Þ§ïoñÒîo»ëØãNÂÆf¤×«éÕ×w{é5¤ÅI/ïøw7mÚþž¥ÛßÛ¸-H¶½ç§w7l}w½“Ömy·’ÞyiË;/mÒÚÍïxéÕwÖéí5¯¾ý"Ò+AZýÊÛ^zÙK/¼üV6½µÊI+7¾µrã›L+6éù oiýÏ9iùº7,-[·kÙKAZúÒ./­õR_vö­Ù¹¤’¯Ù¹øÅ -zqç¢_÷Òê×:iÁ ¯ûé5¤g‘Vé™U¯yi¥—æ¯Ü¤;žvÒ¼;æ=´i.ÓsÛç8iöòm–f-ß6kYf.Ûæ¥¥[‘fXêÛ:½š¶Œ˜¸à¯þzŸiK¶ MeZì¥)^ÚŒ4yÑæO~úÀÙ³gç¿@õ|ñÏð¥åË—ç?·Ê¡è˜:$´nã1Lh{ÍЃ:H$“*D»Ãôõozñe×£Ö‰dj·Úº¾R@ H)PJ„1•²XÛúPèx£ûNøQG…y[ïÕ­‹¿çbï¾víÚ¾¾¾ne¬ë÷½ôÒK|ÊY_ûæ¡“'Oîzfú™%®Ršøª—ËºŸòñôªEë«_‘E«ˆ%ˆ<ûf¢Ãd&*hñ)ÛR ¿ cꯂ:?§ ôÆP ”Rlºtã­w}︓ `r饀©–^ɘ* S"À´Õ&l´aÚ†)À˜<†©‚1ec˜Þ3L>ÆTa˜°Qe˜3ÕbLÃTƒ1 “‡1y Sc &cª2L+ë3L`LÃäbLôuZ_cŠe˜ „1aºìš¡ÑæömøÌçE2å´ÁU¶º €0¦.ˆÞ‹·ô->F?1íðÃæˆdêÅJÐÁg¦qêŽûE}{rö2¼÷E2uP~ÝJ H) ¤€(‰˜JRz Ÿa0iÎrt‡þntÉH¦mÛ¶1Zñ?QQ 4pàÀÁƒï·ß~…XíÙÚz†é”3ÎÇzà…«¶ô/ý%™bnm†S®> E‰P”±‡ 0Å6’˜¶ŽåV7ꀰh}N­ÝÎ[ÈLÔNuum)P„1¡””Ç&è=ŒéÖ»\7K!béc¢×¥ã%Ï S*½’)‹&xcrœ0½ã„)ꇩ℠ޘ2ùaê'ÃTqÅøaê'ôš~˜ZéŠÉŘsÅ´´ÆS}ŒiQ1¼1aºüÚ¡KÃ’mΑLM4†:¥¤ c*iÁæê±<‹Ï<úÄ\k‡GÉ”«"*Uf<ãÔ·»ãþ1Vßž˜%’©TE¬‡‘R@ H) :£€0¦Îè\Ž»€a oòÜçØ ‡ÉôÖr‘L@[ÈÖÄbLpÞ¢…E9aÂÛ.GáÖ} 0L§žqþó»ë‚•[ûI2‘"êú'c:t(&æ ÔZw‰«®KÔ E«¥,3Q Q ú«€0¦þ*¨ósª@ÏaL7Ür'%7Yœ¸ëo¹SðoZbü8×ñR€.ÅÆ‹†«ë)5\À0ùäV[ 9l¤Ç’kÔSó S+ÂÉ5êŠiùöTŒ©Ž+&’cP¹WLù*G† ~¶l:~³f-^/ŸL9mt•­+ Œ©Ã‚÷Þí‹Ï“s­†EíðCÏ–O¦Þ«mb§¾ñ­Ã†Ý?&Tß&ÎÉÔvñu) ¤€R d c*Y¶ïqÈ0M™ûÜóë=ãÛ2c ïÖ{š÷É:Œx |°Ì$Â6üeoA'ôbcÕî ã9í®óŸÛòÕo2iÒ¤&Í´…˜ŒÚF8,¥ Ý¯Há«BÜãV*ì!œD<äáB{¬"1vAîQMM<©Nɳµ­7eÑÊsa%å-j&¢¿@6S2±L•g)Ф˜šN§å]žÃ˜®»ùÎ;%÷_|{Ì÷Oä/Bœ¥mïm¬¤ Û€+1½Kn ¸’›Ü°qièR„^ Ln¹4LÀ´î—*˜ª“?½š0Uœ0a0Ä’[» ‹KÐãñÓNÎ--^³sñ‹AZôâë^Zí¥…Nj,–\£~˜žK÷ômæRÏÓ K!†©Ïc˜j0¦Å[¦.Þ2ÅK›½Ta˜ˆ1ó”[¦`àòðËö¦ën÷JܦÏKŠ×OEM_´îÓŸûÒ¢%KÊ-Œ¡eUI«¬0BîÌ¢ ¼9xFNh¬Éø±åDYŽ…{Ç£ÙB%n¸ƒù,´cg®{³¥l ®ƒû¥€0¦~ɧ“Ó ÅgìSóB6Mÿí¹/J¼‡›uà—¾ÒÉd†ãÎC´©¯»Ä­b¡í×Ì?>IÍ{Cšpy´‹[^j4NÝùÀX¼÷CKÙIC}{|úR¼÷ׯo’dBþ;S ´ÑãÅj3.ëQ¤”KR}NéK´»Ð[^‹tA) ¤€RÀU@“êC]* Óó)ƒ>LzD£$ˆ³aýaP&f†Úk¯½6…¸dØx&‹þ†‘#¶éN‰“Ñ'ØÏíƒcÈ»ØÄQO4¨ôð`ÊP˜ºÒ•à0L§y~Åî†<`w}zùæ¯|ãqãŸhôaMs·Ð©­•]¨ ‰£ñFt§äzÌ≡€€(;s×äÖlÂ~#ÕpM‚tø`C S£ÅZ¬ãÛgÑ2çp¡ IÛ ìVÓ ÍæÜoæB6yšnh]W C«i®™ÓC©ƒfÉ~š‰lf$ÿ‚§˜õB¿J{(Ò½î4“}åÎvY¥µæ±î„Qh‚©¡f!£•5ãa ݺ­kj¬­òV/.Œ©CBë6V ç0¦ko¾3N"¥tíMÆ„ ‡UªC,‘^ qK £Kµî—2ÒK«¢ôRƒ“OÙï ;aª˜‚NOÀ”î„éõ/¼†ô,Òª =L¾&¤ù+wiÅŽ§4oÅŽyÏ#mGšËôœ—æXꧦ ÃŒi8ƒÊ%3L±(·NÿR#÷«0Lo¥XR@•M_øÒ§?÷ņH&w}o+ûC£‘6iÂUhè#"cEg'™êÎÁ[žÍ^c{Ðé´El0-a»¹É]æOA»@öÌ·IÏž»¬0¦ž+ò=°Y|̦r‰›&°´ÃÛÙÉDûNkñGZ±c5Š6õI¿nVõ‰ÞêÛàͦ>É>›]¼nhé E£Õ9Ý2NE]0›C}7­ïSŸûb$ƒ4 ìÆ>rl}cô ¾aqåjy"¥ª'•ëCôÛ¤¾D» ½åµH”R@ H) B <»ù¬»úzË.ª:ÐÃôôóî Ïõ¿ë úüõœ7Þõp£$“‹1‘G1‰]ed5 ÆÄn0¶’‰6×X`ّ͋Ù&[#ÃØL™´Ù4Y¸š;²¡5¸œ»­™½ ¸º7:7«ºÀñô}ÖTÚûÂmYà¡,Ù^ŸÇ„žÑjЉÃÇwÛ^Ûæ¹ö aL¡+à")š„²áŠSÿj´vÓ8u×cclèWáÕúöÂkc§6C2qòõ\×­o¡Š‘^ßøÔ ÃDà‚KH+¼•Ž•µí±ë³|Y”ö[pK$TÕí^¼>k)».Vñ¬'ªc4ª²|C7mk¡7ZIt¼R@ H)Є}[/ÆÔ„n=rŠÃ0Ń,tt†‰ƒ¾†5F2¡3ɱ{Èø‹¹ˆÅìrY0&v¤í:貤‚ø–CB.W@?×dP9ëÍRÃcì+f,4{ÝÜ¿ÂÕa:Ëc˜ê.[ÂòÝÙK_ýò×óÉd%k›HÁ˜XO &ŽÄ ÌÑ=+[¬8˜_Yl¸Œ‰0œ;ÀÁ¹ýñ)R¸ï© ›E+“…¡q‹–kH‡°¬x48˜ÎhI¸ßZ0~åú·ÆWöspçÜŸIOœû°!3QR¤ŽÀ,Ù¸™Ê»+±íEbu´Ã&}\ 2Ï9³Ã`‡!ÛN’¡‰Wà·Ì›µx¬®!ÈÌY¡¹·RÙè/Ü•õ Õ4ìq5 ÕsžîN0Ùƒ„ÚR›£®,$­k ÉnfÕÐT®2½ÚC™Ô|‰G‹ʸE“dótí«Vš|R÷t÷ú®yÖ}Iõì·.Œ©âêÒÝT ç0¦kn¥”ÖNòù¤knvô±'F]+qÏK[Þ©¦Íï€U²T-Õ„Š{ÄSˆ[zñ•·k½.…Ñ¥Ré%]Š÷½”?ŽAŽÃî—‰¬rý˜úå„)[ 9—ašîÄ’›æ8aÀÄ4|‚ç)…aÊ¡7&aºÞa˜".Cµ§%šOyvmv’) cb?iÐ ‚®ú@<‘]:l`ù²=6f6ÀˆŽdqeןÅmc;…ÿX‡’¡»³¯Él®çb³ŠÎ™M퇚d7†:™Ëe|KZŸËž¢÷²«ñ”Pï¹›ÍÜ[St“ŸÇžš—fÓ¬Z´=g„h‡ï{tFC>™Ð¬Ñm‹_­y¡±2Ô ¢mÁñlޏÁØ´r Í5‡Át$ã~e­™™/Ùbóv\¨ä2.¼>ö[°´A„ÞvdñhI7#)oÍ’=¾â1Ñg´’g;ÏÖ†ÌØÛ„M7vR®¸²ü›a"t¤IJ6h}na} ŒSz SȆîv"Ú êÛ˜)KòÉÄBD¶-0AÝú­)õÍ>¡ZįP¨¿•NlyÙ«–u½‹ØŠaUÝnmÝ›b-uP¬¬',JÎôà_[Ýn7uªµ…ÞÂú£KI) ¤€) cRõHR }Óž~>´€fÕ¥îB‚còÏÃßüõÃFe÷ÉD´ÝH")Ì ¶Ù©æD£ŽqÝ YÏýU|È?áÃE€ØãÌÙaæ•y/žË›áÄ‹¸_á›FÅ‘=⩆aJˆèí.[BéÏê{¥!’‰CfÚ'Yè,…”‚渕emCiŽYl[v8†_Ù ½Õ»‹;Š1FŠµÂ½”Š2)МEëþF,Z®!æzƒ–\%m Mà Ù÷€qb_…<—©t2>KŒ™(ÃôPCf"Ú=ðâp'2’¬Ž´ïY»²Xš†íÂ.f<4CP’¡‰76pYN$рÛš!ˆÖ›2aC•ŠùqUiküØêÚ›Ô- Ø+›`²‰ÁÌtF_eœk3ÑøP4Ør#d¤BøÛÉbz =8N¡õ×gÑD¯oMy©)ß)QãÏÕÔXÆxó‡ cj^;™kzcºúÆ;jh$—LÚò¾=ú{'º|R"¨DK5n–ªÄR,´å–V».—°á–Baã¼é«DzéßK½”!~\ß/nnÝrô™l ¸ŒŸBÈE£È­¬EÎ$W"‡mǼ1ÍBªøaÊà„ik Ãä’{ÐØöž²x3}/EÓ'?}`~¼1Õ0L¡±t²%1û&Í_»ÿg3ùdâ#Ô-s»)ìŽpû[<غŒØfÒí²K„l;Ñí¥Y‡¦n§Ð½—Í,ZNxw\„'æ{ØÿCW,šUæ6¶µv{¥6ø7×ͦ³½—]GºÖŸ\¿Ê”9aLe*ÍŽ„JlÏ‘=ükÔ©e ¤)½B’&IÙH²²5]së§j]1ùS0ƒ‚úöèäÅxïgŒ.g¢ÓS·¾™aÂ*FJ}3’$ŠÖ™¤òbM ½R£%‚ Z². «±Õy^ÇìõÌ?íGn=g_"zS>TË ½éÚ¢¥€R@ HFÆÔ¨b=r| Ù!®ôÁìYô]wGV’ÉíçSXýùÌ[ûrå0L.ØÛiW¯l‘eKóW옱$ÓÁãÆ?Ѧ¼¹€–ßÂ]Ôò‹ë‚ùQ ŽE+ÎÙs-޲ùA‚xlíu DIȦ¤[H[æGÒÎç$l&J™ò'ïš6Ñ¡Š åBkdŠÕÑ,oÆÄ°|] Lh¾‰æ›ŽáœQº¡É®Àzåšzl®Š† ‰+‡À8ÞK+­~vãºY²Ë²pùD¬Ìf§â-\£¦µnõ&¥gUžâ,÷›W`%·{ET†1™z6¿2½º¿&Ì£[4Ñë»%E˪íq1&^Ü5 ™é8TôöŒško‹!Œ©½úêê]S ç0¦«n¼#ì9É ‡o1Ÿ¡”*Õ°JI¸R•X‚Ë¥—-9qâ|h)™[ŠÄŒËæxé9då&×÷’·jß’·|ßÒξµz©?ޱSãǵ`ªa˜–o¯‰"˜¶…£È-ݚ䄉ä¼ä3LpÂ`L SÞ‚Ê9 SÍXš«Áâ]2T,)Ò÷äÓ™H¦hÀöTÜž¥áAè©ØZ.wLÂéCûÊ:I˜Èò³·gýEëù¹#–P·Ïºè`Ùt¾uͼb“—–Oö5ùq!}>»VìÌYGÖZåP¯ÿº¦œÐÒ%\$t/^'”á®5ù=xcaL=Xèm{ä˜UkfÎŽ·i.ñ`Óœ·bÇÜç·ÿnt&ŸL&¸t’&ƒP#lªû¬nãÃѵÛ@Ù(—-Ûp×m÷زv?îÂ)^“ËÙº²ÁŒ¾/BcàÐ1ö€n–Œ¦²á.³äfƵ ðA(ÛsüåRþkžÿðúp öòŠ^Á^+¦OLÊ_­ª€iÆ©ôúæcsxï?2)+Édõ¦ÃïØú­Iõ óÝŠlM›©k‘¹ûæNÖ«¤òâ18˵rFK$Š1¹ÇXVùî}ùÊæïŽ= ;8tS«™-,ôVU]G H) ¤€È¢€0¦,*õÚ1Œ%Wã‡Ée˜âÒÿ® ú®½=É”sŒ‰¾1zmÆ1Ä0ùqšÞ¤±Ý\á&-[Âøkú¢—|­]$“YP[þ“ä@Þ\·üº`[´\ü¥ž…¡!‹VÈnç¬u¡ŠG÷3<2ºd(d&ʃªÎC¬™ˆ¨e³ÀÚ˜§ŒŽÒ™Èt8UDCeÈ"Gë E€å„vH.°ŒZ`\à±ÎwbÔÐäÞ®`; Ê¡aÇ Aô9Ç«¹u,Z©p–­ë³Ò$WŠ­ÉvLl=w'˜ìÈÐëÞ2ïîw­”Ì­R| ‡ŒTfà5Œ‰‹š^£yˆ-÷ú¡_ïeWŽÅ˜ÜÚ{}>‚;—×áN¯ÜNS¯”tÏ=gïaL7ÜaQÞ¢WÝpÇÀïpR(QájX%BKµÄR2´Tñ·”[ò†Oa¯KñèRÔñR8r¦1¾—¢ô¦ZßKŒZRã~é/h ý ù=¤jZ‘ÉSSR¹éN¹(ÀDLĘ’ü0å cò¦ë*±ä|¬þ·bÇÒ!Ö~ÞóÞô9¼[=1oMŸLèš®NÞˆÁP߈{ˆÛ£cŘð­uPlÛ¦ Ñ›D‹½±P¯×m‰q¢»Ì‚]F÷^œéŒÞèP?‰¾ ¢[/3úõJéź­Ö³öȼ/¨ ò]{» cêšôe»1,>0gucÉUÌÙ.KšbÓä îžG¦×.çnØ”¡©t‡|„A ¿]A†Òp 6×8ÀZ!kÉ9¼´ƒí:¡ÖÌÀ¸»-KB\bÃFÎÖî%¥í"ô‹1Åf‰·³7QôYÏÜVÝ |=áÃ76ìA\AÈê#í Iš¤d£Uõ>0N=P‰%ç[yï^-~jQ]ŸLæh™çk·n}‹VŒ”úæÊz«âß5eïôØòÂ¥`U±¯Ì¤ªü!ŒÉ5Ä >Ð0Š¿ôÉy)\™F.ÖUëKDoju¯U…®ëH) ¤€V@S‡ÏÿíÈ0MucÉE®ÀšºØ!vü¡dñ}Ë·_sûCÙ£Ëå_–É¡Ç0y> õ^0„Ô`Ãxê¢Mí#™z¤ ô˜íP lѪXˆ¿d¡ô²[´bñ[oƧ3"ãq›nÀ~‹~@Ó„Y½L“^æíúm&ÚÁBÌb&rÍ;´–cŠZ a¡×"Y¬&c ™c Mv‹Œ2i0\QŠ­T49†¬Ø²•qa›UÅtŒÉµ@í²ëbL–yºK©²›^í¦6¯-šèõ]5¨¹)µ—ºEF”Í~¶f|Ã45ÖŽ†=|MaLPY÷è‚=‡1]yýQ‰{À$ ¹Þتp’¿Óq§Tõ«*UX¥XKÅKÑ8qÞ0ÉMëƒY++nŠñº”]ªu¼äM¸:èRÕ÷R½Ô¼û%ûö<xN¼á=Ós† <0¹ÓŒ>× Ó–¤(rðÀD€‰Qä_ Œ ÓÞ˴±tˆµw\1Adã›0wÍ?æÀEK–¦´7\t…~ Wä4J˜øU¬‹#z-"÷chvà, {ÌÞ° ï‡òfÞ5Øæˆ;9Ôa.câSðúìfñôXŒ »^F’z¥ìµ»dGbÖ¿݈g±ïB«ßk·ÆÔk%Þžç5‹ šÞ‹ÛMó¥cñy1ðÛ¬Ê]¸b‚±Àk‡—m»ëáié$“5˜|‹e-*[QÖ²ñ06Ȥ? ñ`ë ˆ•µTtiÃAi¨5ã~A‰¢†LHlºÝûb½…°W^„ (ŸŽfæÍ "6Ô¶‡WæYöâ=#%ââ0f’¯ îw·M.^ŸYBþùFˆ½B’&Q©ív-©€4NÝi »…n}‹±¡W\UÖØõmù¶‡ž\„÷~Jt9CŠ]1íÕiåªoÑŠ‘Rß\YðÊæÛ™U—¯i·Î°\’Ê‹—r_µöq+¿û^æ)nþQ‚fƒ#®dõ¿«K¬E8׺4!³—kÆjIéë"R@ H) ¤@ÇÆÔ1© q#c˜Bƒ¾¤i~. ¹b²AßÕ·ÉTˆrg&†éÍ4†)Õî ‚ CþÉ 7}é vùd*¤Êj~ˆµhEVIí VåE,Z˜Íáêèì-×;‹é€6N®yŸËϸß,?<%JœÐÅN~„ídN:l&¢ÝÆLŽ”=Öêè–5ír±ìŒÅ˜lЦ•XCSCmžî´‘‹ÅbL|´¨Šæ 3BrRÉ = câ“Ù< ír|"×fvQ.û´_ ¶£F*Ͳ˜^í¦îÁ!ãXôúT‰Ù ÉŽzÒâÊ"¶Ò´"3[tèúÌåwò'Ó‹÷ÆÔ‹¥ÞÏ\c²Òl4 ­ cr½u•TÙƒo:æ„øüpÑHpßøöáD”˜žœµäª›îòG¼oÝ7jâƒ/a¶7 bÚðæ7¾uø3–`ƒS¡=iâŒ%þU&h‰1¹—9ÜR(`œ_¬&lz¢nòÐ¥ÇK‰‘ã0,?ç’«‘\÷K_ýÆ¡G}‚ë{ {ξè*×ýú¸n½tØÀšø 6’&tˆÏ¼`È?}êóAÚÿóÿ´ÿç=êxÌûÎdZºµ†^ª !WÏSÀ0™û¥þcL»v/o÷‚ S@¼9s™§Ü4ïÈ‹'#sÇ3W\ÆÕ`puñï]ä§ ïYèû ­l@½ñs^¬K2a>æ–É…¦ÍQêì~YgÎØ9Il*á+»¦ïöc×U`'ú:¡Q¯½šÝ_Ù)Øp[°hV±'öÖÑ¡—Ûíæ|¼› ´hÁÂШEË’GÍûVG÷»ƒt»B¬é>‹9<¦%f¢\9cäôuK+KÝ~vãÜ Ï¼Œé¼+F,³7ÿG§‡ÒÍDfA¹„fm\ÃK¨8Bÿº˜Xã Ùšù%dh Ù3™±èD’kGrmžföቱ•Š_ñ¾î\˜Ý ;£ÓâI¶ ›`ŠZ–B™wm§f˜µc\[nèR|ØŒ¦W{ðuÔŒc|ö¨…-jLf&M^ûMÅÚÐÜë‡r›ÃcI²$Œ©$Ù£a ãñ^pÛ+ÈQc""Í—J 0&º´IJøSÊ+}ײ•ôæÉ?ýÅß~â¿sœƒôäÌ%Ÿúì-W:ãœKŽ>ö$üEºwÔD×ÇÒ¾ŸøïŸeâpÖ¨ñ³Rœ-eá–jÑ¥_ÕE—N=ë¢ÇNOç--:åÌ‹~~æEÏ:‘ãöùÛ¿Gò‚Ç­ôÒÃO>³×^{ýìŒ g7D/™ï¥O~êów?¹­íŠÇ0];4X ä84F•ÀHã–ÇVŽ™»ñÑ9ÐIýÙ sYŽ_=s¼×O½Ç0¦ÊH£bI™Þ·uܬ՟¬ç“©­ÏUЋÓ?ª-,ÀSDWôÑJ›maL¥-Ú=->cžœm‡ÇÍÛtÐYãÇÎ݈v °’_Ý>í0¨_¶Ã´ø€â­aJ–m…Eí𰇦Ö.×χä~^¤%§³3‰Ìp5OÆkâHZ²B oÆÓsuØÖwgßÕ·ú é0¦¯ë°a÷Izï\æ{iôìõ¨o˜A‘ï}`L5õÍyïýŸLý—+?õ­ÿÏ¢+H) ¤€½ €0¦^(å,Ï0Lóžs:áÏ»~¸¥ƒÎ0Ls6`¬wã˜ô¡þ“ëçpÐwÏSkB üAß–!"™²@›Ž¹ð{.ßÏòÇÓ/†éTŸa²ÅÆ®ße˜^1þ2† ËHÀ0ýô†¹Ý;iM°ŒÄ&hÆûO>³á‹òÉÔ¦’Õe¡À3÷ï9ý/öŒ>+fJ±hafá±¹Ѹ¡’“aBõ¾rIJøá¨‡g®Ã¤Ú:aò1&—Òë˜E«ôåÜ3Ì’(AÑ`™=k=¦‡`&:ë¶ùœB‹ÐÖí|¤{›7uñ¤P9`âvsÓü w`Â|$§$ÛWQc/ÃT 2hiÆ0âXš# o5ØE“PˆÏ\ÂåÓQRDÊ‚Õ`΂ ZR ר™/|òÓu¢ËµïÑ ze œ!˜.ÒTЇ*y¶…1•¼€Ûûx´ø<úÄÜ ^ï’[÷&3g£F{ +"–ÂâãµÃ+kÛáŠMo4 ÐO]²åö‘SÚJ2¡½ ÑëíÕ+õêÀ@Ñ`6êC˜$>c›úCû”õba¦*Ãx^¬©o|ïÃï—…&»ŒuÀW _®oÎ{ß«o}^}{p¼÷ÛG2媾º¶(óR@ H) ¤@g Æô‡ÞêÌít—|*@†iÊÜçb}¾%6XŒûò\­ €µ÷,)ãµyì ‘LýhPtj!ÆTˆbÊe&añùìÃä·ÃÁ[žïqr%Æd«ÖhñÔÖûo´cB;¼hóí#ÚK2åRÚ^Ì”kŸŠ…™<†é›‡Ýqÿ˜¤úÆ÷>ŒS|ïcúdüü—ñÞ3‡„÷þN1m]¬ë¯à½ïÓÛm%™z±hõÌR@ H) ¤@a Æ”1òoaŸROS }“ç>—Ô § óÁè„ãï_ÀBÌÃjŠ1ÍãÛñ—M E\²„X] ƒäå7‹dêF=4Œ)fÃtÊç§Ø]Qú NH°Áî:áéõ"™ºQö=pOØ`¦º-X°:5F†+G.ƒE 5ö„+¦c‚§gXо!]óðsA8¹Šsq³0È¢ÕŸªÖ ™(~zfIÌÍ¡œúRÅ,¹¨%Z*o†èŒñgÜ:_f¢þ“Ε…Q@SaŠJ +€X™`àS úº>Ædœ°Æºè$“Ç…\3”î‘,¹N’ðíw¾{¼»'i{à÷NúÝCÉ*¹|)!q6à` dô—^ûµo†YOK8 Ð,!c«„„ Ɔ;ò˜“FŒ›ùµo†qSZ„8EŒgÓþŸ9£)¤ß^sÇI?>ýÁ±3-yý‹¯ÿæš;'rÖEHk!aÏß=ñþG§Qââ!¸_ºïÑi‡+½ÿql#a?ùéˆ.}ÑU Ç„¾È$ûûÐÏ6ðø[bÂ6"Ç!aã¸JKX“„\ Ð1¦áãç]3mù±?d:ä°ÝÏOU¼s þXஆœG-Ìä3Lç™Ù?X°TY³Ä!?ŠÞØfo0† ös„“›µtÌã—=¸´.Á†¢H¦îê܃÷ì§§ü±ócªwÅ3S‹7 z¨ážy™®±ì†GŸûòÐŒu¿{jÍmãVÁB诜ñø#³6X$2Y´Zehj‰™È3K®Ù †‰…H³$¦¢yδVìtÝœß<Ðvè{웉ÖolË»V•R 3 cêŒÎºK@8‹à1hРP4ú“›¥·NmÈyë/ Œé·× 9FrÿÅ·ß9úø”øÕøi‹Á!~ö%HþÆÅÆ'aÛý×@%l¯õ¦?áT ”’£x ôþ1n˜¤¾ ¥¿J/LÂNpE¿½ötJ°Ah‰Aâ;ýÄŸFhéÁ1œOK@—-a{¾ú/‡^;t¸-½gKØD 1êF‚›%ü‹á7® nÉÒ½£=Œ‰ÜÒ½LcÀ8KÀ˜0P¨tÉ•CÁ*ÁëR€1ýâ|J‰ cbW `˜îÆ´ÿçÑ:ô¨ã±7KHˆgôR<®ÏǘFLŽã§-øwÂܵ¤—†Ÿt ý-t¦± ÷K'Ÿz¼1ýãþŸûÇöH¦bL¿›ÿO±³Øy÷Ò FLÒMì?üg{¹õ>B­þp ͱôèÙë9wÎõ@ž;kYÅ£õ·>}þ] Œa ¹qY®ï³ïï?ü¨õ?9]Q t]aL]/‚bf Ôa0Š”ÖLÚ²¹×&:m†½ ˆéé¯ËüeL;ì…õäª\KgÿúÆÏü_îìûM¼2tJ 8ûÂýü—çYÿÓ}ï³£hïýKî]dï}NŸð½ÏuÀ‡_øÔð©/Õ¾÷½úæ¹`têÛ5Ã=àãÿù?ÿßbìž®‰_Û%Và¡SŠÙ6+×R@ H) Z©€0¦VªYÀktÐA÷ŒœXí„W–ºƒ>†éÁ@ÏÓó:\•œuÛüh@1Ló3œœqÉfˆ9î;ñ'¿:ç³ÿõO?ûê„w]Ù—‚-vü*}†¤Ý ŠÞÓdËH¼µ£!G5‚+Hÿê¯÷Þü¯ÿµë® ô„gýåÉßûŽ;±h z¨átá3yÑ«p3†Œiäôuæi «£yËÓçݹ€kÎ1A#‹VglPÍDf–hKÖ–fI›ºõ±•°e2øå?~ôç¾Ì•e) |„1©"”B &À-“û(u0&¸r2LÑ“ § f%sõm®W¤Ð6¾>’r€aItž„>  19ýW#aÌ3nê"øRâä‚ÄTâÄ'ÓAß<ì²kïà¤ÔÜe/!šüô*pKžk%Œ×x”Òð±3ŽÐÒõ· %ÉS°J§žuA%BKt¼äxZò÷œyâÄ´tÂɧž–üÙ¯ŸŸqÑ}£§1NÜôEÈ-ZõÄ3GnéW¾7&¿ÿêM’!Uz –€+Áy2q%DŽûþN¥'€›î‹tæC¾ÿÃSá…#:àJw>4 (Ò0ÿ/Ñ¥cpÊO?ßè¥ ·äaL·˜„Î1Ó÷N:èÒ—:ôÐ%œŽi`àx Óéç^ñÝL˜ŸCj!Æ4rÌS÷ÆÄºêÒK6‘D;¾Ø‹vLwÖ³—mC·þ~rýœÛ_…2B¡ “z׫Ãci‡µçXú€¿NÌÓ½w ÃøëÝyðžrJÔ³[ÏS]‹j8VGûæà‡iéO¯Ÿ[, ^´úéëàÂø §x¿à©;'®®iÜdÑjEhŽ–˜‰h–äôJÿ™Öu<œÂêJ€héÓC™hÁ*L‰dêñ®‘¿À c*páõzÖGŒ¸pTAåBqåê{c÷'N¸6úúú -'1&†ƒ‰M¿¹ê¶#Ž>>ô•ùLŠÝ€_%ƒ“°ÁXoœã“tä1'â_lе’Í}޲@Òw¾{"œ-q}GpKˆ<-áïAÿr(þâ†Ã¿ØŸ„ ðI€–p:âÄax¦YK62$ÜGŸ\ {f.Þˆ¿Jø _MœµÜ’yZŸ„íÛî÷ë+‡‚[¿‡}†d‡}‚-î¯|ý8[·¤ç|ŒÉ‡ rKæu T¸%ü‹á{aãàr aã|ziò°‘“±ñèÔå ”@/aÞÄ€qæxišöû‚ÇÑU)Ò½ÍÞ놽„Èq؆Ë% Kð½4nÎŒ ±têyØøÝ˜¹­Å˜ÐCŠÂLs^n×<ªë¥WÝV©uÕÊcfÆ”aÂܹ7ØX± f1/¸kÆ?¾vvM£`,]uâ2L|@‘L…nâ”ù„1©Z4«I¦Qãç…l/q¶ÃX”ù?å¶Ã0àín‡Cë2k™2LKWof#¼eçûú³?5[f9>ThÅúïþa“eqå@2Ýú»Ñéï}/¨\å½Wÿcs7žyÛü#.| ï}Ì\=j¹oœÚVµ0Æ2L¾qŠI&ªך¶eíÂOcj›¸º°R@ IaLE*­öä•$ÓÄY˃>M)C‰!¡ŠÅs†ºò5‡Ù LtÂayƒtôز¶ÆOm'Üc˜>|Õ†×Ùßö†}í)ÎÐUÑéu½«V&; $ÓÏ~q^Êø‹šjÆ_ó6ò@¹_p·WîN]ëzᢣ×.#ÊÝ;rœ¿ÞÝýaG^7)»ÏÜ_S½+áäì±k-ZOqÑÃ"y z ”i€&,ZÆ4í%0Lhèоará_¯daE«?õ¬%f"£lñ†ÂêJX)š¾îÉg_Añ!L¦€²•™¨?E¥s¥@!ÆTˆbR&ãضmbÁ` ¹bÂáõ1&z 0.Tt…+\HàÉÅÊ ÔÈá3Þ(ˆñIô¢4¾–½ÌE$“~{Í“æ­â¿‹‚äÅ€Cöàãð·4fÒt"äÑI 8BžÝ·‰ØóÀ£ÓG?µ€Qá ]Ì™>´Vé‘'ŸÅý-ÑÓ÷ÐÕ-½Ý"H-!ÁÙ’EˆûÝ#Ó¦-ÜgK=ñÌU·<øÐÄgèr ÐÒÝOEÂÆ”gד[bº{ÔTocù¶ãç3`ܤgÖ!Ñëü-Ýx÷XN¤ùi+Ð¥Ç=ýÄÓ/ÑåÒãžÆßÑS–#fÜýãžÆà‰.Y¢Ë%†óF€~º÷KŒr냓È*aÃÅ•ðoF?L< °9üú¦OŸüôðÆdNlÌßp稕Ÿà|dû0&üÜXcmŒaëÆãO¿ 7¡^š±î©¯˜³Ð‰Ï¼|ÍÃÏa,M†Éuúꎥ£ “H¦¢7qÊŒ˜T-ú¡í>=>;¶Æùa6Â~;ìÆ’«¶Ã.SaIC‘Lý(«¼ŸêÚ§B“e= ™îTßz“Õ70sæéýÑÙñÞ=kCˆ]¦³w 'ç.°s{5"™ò^{Zž?aL-—T”R@ Hb* Œ©˜åÖâ\$ÓÌe5ü¾#|ó¼‹N¸MlÄ´uÓ—l™±½ôì “H¦—_Êå cŠLvH¦ŸþâÜ èÿ[ï&¯« Á0þ@?L罄ñ×øù›jã4m ¦Š£š(ÃÄÒÉÔ¹:Pâ;Ƙì¡ëZ´0»clܸ*ÓCcæläjøU£–ß?emÀ0É¢ÕêêÔ3Ì’n¼Kx d@@âÝO¾è…épÜÅEQK™‰Z]ªºžèž˜º§½îÜfûŸè¥2aL-ÉA.(äß®º¼Ql·À˜ˆeL!2‰|R|8ɇ@ñ©‚(«„~¤%oÅ¿è'”Ðˬ†‡óq%$°JæiÉ %#–ÜJ¸ N¹%ó·„¾ŽË-“O,¹‰Ü’› ]bÀ¸ T\eÃq¹äù^Š¢Kt¼ä¢K·´xóy¿½¾—ài‰È1¦,þ–ÒicÚ´ý=Ôç5»îÌÔVŒ wñ*í•·Y²´”©e¯tRéñµ–a ¥“&‘Lyh©”‡V* Œ©•jöâµh÷ñø,FtuaÏ«¼·w•Ç  “z•oÏJl¯À/NÔXË0‰d*k%£}* `²§&ÉtËÝ£Ý÷>;‡Vßê¾÷ý¾VepņždœŠúdÚ¹ºïÃÝ^?'ôÁþ²–NÏ=—0¦ž+r=°R@ Ä+ ŒI5ƒ d?cidÐØcCƒ>ØNi& úhät„ü0¹k à“é½×·Æö±Ñí«¼SÞd€É.å‘L§Ÿ›ÅîJ†‰¥OÛx8’ ã…+‰aÊB2¡V¼ýÊZÈ+î^;S2ÀdbТ5òñÙÍX´bñ—Š…A­þ׸™‰úÿ°º‚mW@SÛ%Ö º£@ÏaL¿¾òÖÒÈ¥Ž^|ßcJâ²2I!V)Qò¢ÕÆ€J ¬’Å[ªàJœ4¾hÃÙ]e¸üñÀ¯Ò¯.º*Ä-yÄ’7ÖªK™ ¥Ê¨¬!n)Œ.UCÅ1fÜ–tt©âxÉC—èx‰|,vîÆ$!ŠœûoÓ·”är);~Ôª#Û„1 Ä óÖýà6£o[þ¸oþb'ý3á/¶±1âùø Ûø[÷÷’éâ+n±j;6wÖIs™Yü0‰aª[: H c*Riå:¯´û<0ff€×LfЬkÎÎÂ0-X½L‰+Þx­àeÁ7ß,xÅðm‚6ð/7øZÁ)¹T™KU€&ªî|8ã{¿fúÄa—³3Lô·DoLä™°_zÊ«H؉ ¬ç~FMØiGªH £€0¦Â•2*¤€íU@S{õ-àÕI2Ú;è3?%u}u¦™£¹ûûûÉ×ÐÆjö¨‘ »ÜØ@ÛzÚôØÄc¬‹^@seL?>mpdüU ?'m ÉÆè'ÃÄ¡k‚7דpDݯY®kUn2X´ÆÎ¬‰íPYÝ‹¬[¶|èâ¡\¶'‹VJ•iÖLÔäR71L¹ùù*#R ›˜²é¤£ §@ÏaLõ~TÙƒo=긔¢ÁÝè6©Žó¤«äÏ}¦§Z¿Jɬ’ã])W Âu»á’ˆ%o)I¶‚ƒaÂÄXMÊ-1„Yo´Tá–ª.—ZÅ!õó:m˜¬ó.8æ’ßûÃ{h¬kŽ©e„œÛöÞ6£—pN©Û|€dºèò[ `òœ0ùQäj‚²/³¥`ÍÄ’ÃT·t@ÁÆT°Ëuvi÷¹ïÑ®'¼ ¦AÓG $õâ¨âmè8mnŽa¢(öÁ%×?_(À›ø6Á{' ›k¹{>s4Q]?lTúV}ï‡ë[v†‰b›eœ$ö˜&L–€sZvïÚзöÍÆ16Å‚=ø ëƒ{¾Ð "€0¦‚”²)¤€íV@S».âõI2™²$¥îÙN}c)ü0M‹ úê2L°¼mÙù>&t§Ñ¯6§§èr£û=¤Xð/W § TÝoö·?ÜýžÂ=·©jy$Ó©ƒ+v×°ó{[;J;¹Wú¾õÛ‹0Ð † Å‚¶BçcÒ?Gd6@C5@=ш¬M5¡”—Í›E +ñÌl[ÖìM³eѪ[ñ¢f¢êôo–Œ§l_ê&†©nYè);„1å®H”¡Ö(ÐsÓEWܦÍ'ðí¡G~?倘¯êI!\)à“<ÚÝÒvt8Ü4xŠ›*aàâA%‚,•žJƒ¸¸¥*±” Z †èª¹)[Úl¡âúɵéô6aLX:€Î7~£èŽs+ Ü®9I&ÆIhlg ’éÂËnöªG À™;W,¹Ö´“ºJ‘ÆTäÒËaÞi÷¹÷ÑuÛá¨9»? “½D\Cy`2.„_+„hs( ²Ô4Q]wǨ&ê[£ “YƱùL–p©7Íè4ÓcöcrÿbÆÛ8’xþ6ôt:¸k cêšôº±R@ äKaLù*Üä†$Ó£“W;á5ÓÃÃä›FÝ…+¦ßø‘Åc_šnx@¥Øò-t•JWLØfÇISû* H¦=å x>¼pÔ_ý[Fз»¶Šaâ‹°× ôY1lD† ×#—Fdí« ¥¼r®,Z¶RÃ~»–,ZYj]ÌDb˜²„Ž‘¹S@SîŠDj½‡1UœÙÄ:C‚«›CŽü~VWIŒìVßdRKâž0œÄ=¢”F)¥‚JˆH<8Ç»R=\)>6\Lx8¢Ku-q—ÿÔ&Œ‰oüF]ç¨`•ø«ÅNNHf„46è±)Ë$Ó—Ý\õÀDçþ@:i)˜bÉeVÇ”SaLå,×n>í>¿=Ãâàm[i„mQf«ü0áiñšÀº4l¸†×É‘&FšCA;a·rWŸ¢+@Õµ·r=/†ßû‘é“&&Eû8£WÐÍè¶äÆtìä„ ‘&lã[$l`ApÑÕî•ü cê•’ÖsJ) ¤@„1©Š$)@’é‘I‹ëúh¢ºzèȘ÷¾_ß (oŽaB6±Ì—ñ ðÁz_F‹ƒMôæTEŽ‘æød˜$:jÒ§ c*F9)—R@ H)ÐvVì¸é®¾½Þýæ¶ßI7(¦$™zb¡3è‹Y=Ø(Ã1ÐÁ6G§ìNù)ãÇ‘Jq{Úô½D¯“jÝ&Kª'ùŽ”’})ÑõÎoüÌñ«”Â*ù˜K°jÄ[»oiQǽ 4RÓÙ.4Æ„¶$ÓàKo¤÷,׃¦|7¼Ê]ÆÔA±{ðV´û {hªµÃîûH SV‰¶>2MTCn[ßÄ0µUüR]\S©ŠS#¤€Í+ Œ©yízéL’L#&.¹ááЯ¡Xr½$[IžÕ#™~zv¬ÝU SIʸ‡C­~KÌDb˜JPôR`0&U‚’*Ћ“‹…¶1}ûˆcSHó”ê6©–äFKã“,p˜7‚rS%œ*ù\‹X¥TB«èI¦sþíF‹&C3ŠbÉ•´ÅÖc5®€0¦Æ5Ó )@»Ïí#§„Úa1L ɨƒ3*@Õ·ŒÕ71LÔaž˜T¤€R@ ø cREȨI¦',­¢ÔQÀB’餟þ v·ôÅ0ºL•yS@­T†~š‰Ä0• è¤€§€0&Õƒ’*Ðs‚pÑ×Q(ù.޶âÛoq,·[‘ŸI n“B¾”ÂpRmÜ·ZD)B)XêU§J=ë‰íH¦³}£‰ †©¤Íµ«)„15%›NjHÀî3bеÃb˜P7¤MT˜2±ú&†©!u°0&Õ) ¤€T@“jBvH2¡ãmp1LÙÕ+ú‘ ™Nüɯ¬èÅ0½@•WY´JPš6‰a*Aéë¤@ €0&U…’*Ðs"p±Øâ"²áÛo~ll˜¶†vÆÓHæ<Éñœ2‰©ë-.â›Ï' QjšUJ9±Þ˜Ø4É$†©¤mµ«Y„15«œÎkH×î#†©!étp ¸&*1LMØë§ÈS¯×=¿R@  cRUhH—dÃÔt%8ØH&1L%(M=BHY´JP%š0‰a*A¹ë¤@UaLª %U ç0¦s.½1…1·À˜ªÄñF¹µ’Ë$Õ†u« ñ&2©dRC×, Æ„ $ÓÏué~yâÔùë¶¼›’ÔI-i{®ÇŠS@“êE§ðì>_ßx|áKKWoNi„¬Þ¹û÷u*_ºO9 ‰êç_ùùœ³`Uú{_õ­œ• é§ÆÔ´t:Q H) Ê¥€0¦r•g'ž†$:áß<øðU^Oé„oÙùþï?Ô ¯…Ò±{€d:öG§øÕoß;r\úøkÇ›t,Wº‘h‰$™<‹Ö_–E«%’vþ" ™‰4=ÔùÒ¥@{ÆÔ^}uõ®)Ð[Ó¥—^º—>R AþÓú‹©súÜê¦íïuí'›zãŸýð1Lù,åªk cêšô½xã7fÞ{ì?ü—¥ÓžÃÔ‹ÅßñgÞ´sÎü/#§Ý,†©ãÚü†Â˜ ^€Ê¾R@ ´JaL­R²§®’験ŽÃÔS…nûëß\.†©7‹¾ž$Ó±Çý@ S¡Ëzç;›²˜‰Ä0º”•y)¯€0&ÕŒ’*Ð[S´Ó'~ô­ˆU ·ÓžË÷ß1‚ü0•´¹Öc5¥€0¦¦dÓIM*ðÌýúùܲdNR;,?LM «ÓâØúîì;—ü‡ùF¤¼÷å‡Iu'FaLªR@ H) |ˆ1¡O%=¤@vví^þàò½_yí­¤N¸ü0e³ˆG¾ñÎïSÆ_òÃTÄ2UžM?ýùÏhÁdÑ*n•x÷›êš‰Ä0·|•s)¦€0&Õ’* Œ)-ö– )P$Œiùã{ð®Éôæ±ÙV'µ¤Í¸+UaLª Tàíí{ÖÎþÓ¿¿k÷ÃÔÉ¢è…{aÊ o«wÞ¿íx;£¦^¨Í<£0¦fTÓ9R@ H)PB„1•°PÛÿHS×…Nøòm·ÄúÄ0µ¿º‡$’I S÷ËF9è·I$“,Zý–¶Æ”n&ÒôP'ŠA÷]Q@SWd×MÛ¯€0&aLR arêéòý=Œ iùãQ’IÔö7§ºC.Æ”Ëb)z¦VºìÞ!ѧØÚ7ûíWÖbÔî#‹OÑ =‡ù‡}ªoÛov½¿õ-J2‰aÊa‘å%K˜òRʇR@ tYaL].€Þ®˜0CŒ4âùýþÃ÷C$“¦i“YŽ’Lb˜š”R§åOY´òW&Ysô‡ÞJ1iz(«Ž:N QaLE,5å9ƒ˜FXä H äc¢+&&ðL{ö¸$“:©CRR„1•´`»øX˜æ^6襧FDó0aЀ«û¸ßµûˆaêby•æÖïýá½”g ‘Lb˜JSîmyaLm‘U•R@ Hâ) Œ©xeÖíÓÓŠ7ýñ£j&1LÝ.œNßß%™Ä0uZ}Ý¯Í È¢Õf;qù™HÓC]÷]T@SÅ×­Û©€0&aLR aòˆ1™+¦ŠC&´$™ÔImgªkç^aL¹/¢beΖÀ*Ãhɸ%<È#÷ããp?í>Ï®zLIèÈb=µrÛu&¬™0h ôl˜‰J S×Ë+ïÆ”÷Rþ¤€R C cêÐe¹¹b2‡Lýé’Lb˜ÊRÈ=I&1L©¦£ ¢€kÑ*H–{.›î°í½m)mf"Mõ\åÐ÷ ˜z°Ð{ã‘{cÂ+CŽ”´uçîo~Œ¾-“¯½ùÁö7v§?Qîz~®+&Ç!ºªšËì–\O™¬€0&ÕŽ–*€pr`•àéÃÝïgZpó`lcc÷Îm$œp·©ƒb?ŽD;¼c=”ôá„-ÍŽ.Ö ÀÓàiƒ‡Ìóâ®ÝåE-ìÛæ9ýâ6>f·B}{öå>~«HT@“*‡R@ H_aLª )àºb2‡L¸H¦ßøQC—ÒÁ¥Qàß?øcižE"B ÀÂðþïÕ¸å´^Àò³ß­ûÑ.„¿° ᯙ‰Ìd„B|~Ûœ<åô!•-) ²+ Œ)»V:²P ô:ÆT¨ÂRf¥@‚!WLŽC&I&z]aL½^ZüüÆ*aãå¹xuÆ’ƒ‹&€Jøô]4yíªikßl;²ÅÒåz@Ù›fÃ8’ <Û |d <3a§ùgÂNؤ`®Âh'ìÇÁ= Œ±Y„15«œÎ“R@ H’) Œ©dÚÖÇ ¹br2µõ¾º¸R@ H¨0ûÀ4tñPX‡`&B‚9Èü3ÁF„mœ’û•Ä”R œ c*g¹ê©öcR%W êŠÉqÈTðgSö¥@¿ÆÔo uWc•*Obb,9xZb°9àM›°¨¼4áÛБ’T 4ª0&ž‚ :[‚ æ*Û‰ TDX¯¸‡æ*}¤@¼˜T3¤€R@ ø cREÈ®@Ô“ë)ûut¤R@ Hþ+£vƒg²Enf;‚½ß’pâ½F8Ò8IN)][E‡ ³@Ñ.B'LpsWày`]{Ê~ÙC cê¡ÂÖ£J) ¤@š˜T?2*ëŠI™2ª§Ã¤€R å ˜QŒ%g¶#lsð&ºôF¢÷î–gC”R / cÊKI(-V@Þ˜Z,¨.':ªÀ‡ì¥Á´äá=xWÝÿ£êží/v43º™È¡˜rX(EÎÉ$<@0IôÉDP‰>™W û1á+ìÁ·ØF\9lc*ráw-ïXEÇ q¶ØÛ*1Ša&fHÓ„5AÄîeZ7γ˜ò\:Ê›R@ tPaL»Ø·z÷›¶¾;›iö¦`Z÷æÃ¶ç½UìÇSR h ¸N»™÷ɦ!ÐKf2ÞE{PåW Hl cʦ“Ž*œ˜ WdʰHP`×&cšx©’R ª€0&Õ†–*°ìÞ`é`&lƒO2LØæ­°Á¯ø/œ0á_$L-Í‹.Ö+ ÀEŒ (z`‡Ñåà;ñ{€1Á,…õvØÆÔ+•£¹çÆÔœn:K H) J§€0¦Òi'¨oë¥À˜6uâfº‡R@ H8hr—´Ñv„Øà:7‹è´ÉöHK) J«€0¦Òm¯?˜0¦^¯zþò( Œ©‹F¹’mW@SÛ%Ö º£€0¦îè®»JÖ+ Œ©õšêŠÅW@Sñ˰HO Œ©H¥Uø¼n}wö]}{aú­ðO¢è°˜:,¸n'¤€yU`Ó[£7…>U^3¨|åQaLy,åI H) öìy÷›d&RE=ª€0¦-øò?¶0¦ò—±ž°WÆÔ+%­çlDaL¨¥cû«€0¦þ*¨óP@SbéPWaLªR@ H) |Ø›ƤêИ’KK) ¤@ÇÆÔ1©u#);„1å®H”¡Ö( Œ©5:ê*R û cê~(ùS@SþʤÌ9ÆTæÒÍݳ cÊ]‘%C˜ŠRRʧR@ ´YaLm¸œ—ÆTÎrÕSI) Н€0¦â—¡ž@ 4«€0¦f•Óy9W@SÎ HÙ“™Æ”Y*ØC cê¡ÂÎÁ£ cÊA!ôN„1õNY·øI…1µXP]N H) Šª€0¦¢–\Wó-Œ©«òëæR@ H)¨€0&U)л cêݲ/ù“ c*yëñzHaL=TØzÔÌ cÊ,•l˜Z ¢.‘UaLY•Òq!„1©JH) ¤€ðƤŠÐ„˜šM§H) ¤@ÆÔ‘u )S„1å´`”­þ* Œ©¿ ê|)>ü`ˆ ÀLúH)` cRe褘:©vÏßKSÏWfÆÔ¬r:O H) J¦€0¦’hgGSgtÖ]¤€R Q„15ª˜Ž—åQ@SyÊROR£€0&U)P0^zjIJ{‡|¸û½P¾wïÜöòÜ {eW ´[aLíVX×wƤúÐA„1uPìrÝJS¹ÊSO#¤€M+ÀÞÔ«oOnú :±ÆÔƒ…®G–R@ BaL…(&eR ´EaLm‘Uí¾˜º_ÊÈ®ÀÎÕ} É=lRöKéH)Ð cê‰bÎÍC cÊMQôBF„1õB)·å…1µEV]T H) Ч€zSÅ+³äXS AYR@ H„1©ZHÞU@Sï–}ÉŸ\SÉ XW&àiÁ̓‘èŠéíWÖ‚j‚&>#ð&üÝ=ØÏ¯ô‘=§€0¦ž+ò®>°0¦®Êßk7×Ä[¯•xËžWSˤԅ¤€R Ø ¨7UìòëRî…1uIxÝV H) ê( ŒIUD ô®˜z·ìKþä˜J^Àz¼2)°µoö#÷Æ„¹— B‚û%ÐKŒ%‡¯ð{¸ÿâ0ìÁ„Ÿ°Q&5ô,R “˜2ɤƒZ¤€0¦ ©ËdQ@oYTÒ11 cRµR@ H)à+ Þ”*B cjB4"¤€P@SDÖ-¤@NƔӂQ¶ú«€0¦þ*¨ó¥@' «oL«Få}K>™H)á/¿ÄäFšÞ$ŸL,,Ý+ cÊE1ôL&„1õLQçáA5ñ–‡R(d„1²Ø”i) ¤€h½êMµ^Ó¸¢0¦(d=¢R  c*d±)ÓR % cj‰ŒºHþÆ”¿2Qޤ@‚Æ*áû©ƒ2Ñëý3a?"Ía§ë¢ Û<Ò¢ÎI`)ÐC cê¡ÂÎÁ£ cÊA!”; »?ÜþÄÚƒ˜Æ®Þÿ®¾½F¯úÛóêÛ“Ëýøzºæ¸ç¸=7¤ÓÿbϹ«þ;ú¬æ/«3¥€R@ YaLE.½®å]Sפץ€R UaLª R wÆÔ»e_ò'ÆTòÖã•Ic•À$™7&ÀIÀ›àu {È3á‘~ø ×MÁN)“&z)PGaLª"T@S'ÕîÕ{M]è¥hñüÇ>úÓ½ªŠž»ž3nÚ‹FlZþx½“õ½R@ Hr* Œ©œåÚæ§ÆÔfuy) ¤€hRaLM §Ó¤@ ÆT‚BÔ#Ä) ŒIõB F²JÈ.1&Dˆ[pó`âJô´ôÒS#¸ñòÜ ÜMŒ%‡¿8¸0ªŒJV) Œ©UJê:YÆ”E%Ó?ví^‹1­ØqSÿ.¬³K­À‡ìü±ŒéòýKýØz8) ¤€i cRýhBaLMˆ¦S¤€R  cê€Èº…È©˜rZ0ÊVÆÔ_u¾è˜ ”̵&$úaBøc_q€'ìÁþŽåS7’9R@SŽ £²"Œ© 9uÈ$WLy(—¼ç!Ö!“\1彨”?) ¤€h£˜Ú(ny/-Œ©¼e«'“R@ [aLÅ.?å^ ôGaLýQOçæXaL9.eM H) ú©€0¦~ ¨ÓR@SCréàfˆ:d’+¦fµì¥ó¢™äŠ©—Ê_Ï*¤€Q„1©V4¡€0¦&DÓ)R@ H)Є1u@dÝB äTaL9-e«¿ cꯂ:_ H) ò«€0¦ü–Ms&Œ©Œ¥šÏgr2ÉS>Ë(¹ 9d’+¦<’ò$¤€S@Sç´.Ñ„1•¨0õ(R@ HR) Œ©TÅ©‡‘ ) Œ©!¹tpqÆTœ²RN¥€R Q„15ª˜Žï˜ú£žÎmD×!“\15¢\oë:d’+¦Þ® zz) ¤€€˜T šP@S¢é) ¤€è€˜: ²n!rª€0¦œŒ²Õ_„1õWA/ò¢À®M{ð®šxi^ò£|H<( Œ)¥Ð;yÆÔ;eƒ'¥C&¹bÊAQ* æI®˜ UnʬR@ ´CaLíPµôׯTú"ÖJ)  ª€0¦‚œ²-Z €0¦ˆ¨KäQaLy,åI 4£€0¦fTÓ9eW@SÙK8_Ï'Œ)_åQòÜÐ!“\1•¼˜[þxtÈ$WL-V”R@ H* Œ©€…Öý, cê~(R@ H)§€0&Õ )л cêݲ/ù“÷ÆôÖ[oÍ®÷yâ‰'ê¢ïK¥@–ÿàƒ ÐìÚ´ý$yc*@A)‹U@SGåîù› cêù*Ða&ôýð£?¡‹Òa]t»TÞå‹•HR@ tWûï¿ÿÒÔÏ™gž™~€¾m«_|ñ9眓~‹Ç¼»µHw￘ú¯a^ASºY H)P„1¢˜”I)Є1µEV]´û ôÆtÊ)§ü?ûý¿_üÒWÜtà—¾bi¿ÿ÷ÿ÷Wûë¿ôåÄôÅ/øÅ/¡ÁtÀ¿¤¿|@bpÀAúüâÓ|>.}î 2¥|­¦/}ö€úé3|ÉKŸÏš>ýù/ŤÏ}éÓAúâ§?WMŸúÜ3¥Ï~ñS~Ú¿‘ôÏŸý¢ŸüçϤ¥ÿôÿÇ?~ò³8擱éÓþÕ_ï}ÕUWuÿÇZ/Ë—,ú»ÿ¾ß¥?ÿ~½õ½è%„1õRiwÿY…1u¿ z(“'Oþ›ï‹‰ðzf=j¿À¢ôÿ:ê¨b0úý~^]@ äSM›6ý·ÿóÿ<缋™ÎvÓ¹Ÿ}îEH8`ÐÏNÿÕ¹UÓà‹~5ø¢³"éÌÁžyNM:㜠ƒtö…gTÒ/Ͼ°’.øå¯¼ô‹¸túYÔ¦óO;ËOgVÓ©gž_MgœêçŸRMçrF~þËóBég¿<ÏK¿°tîOá¤ÓÏýééçþ$. :í\? ¶ôãÓ{éÔjú×SWÓ)ƒÿõ”sNަŸŸó£HúáÏÏùáÏÏþáϪé?;û‹}û¿ÿÄÆ~꥓ÂéW'ýäW{íÕ[ö´|þšú™+aLý°7OÆÔ›å®§–R@ ä_aLù/#åP ´KaLíRV×í²½ev9ùä“oºí®­»ÞÒÎ÷·î|‹—v3ÝxÛ]ÇwÒæ×w»éÕ×w{é5¤ÅM;þýe'mÚþž¥ÛßóÒ6/mÒ»¶¾»ÞIë¶¼ké¥-ïxi³—ÖZzõ5Az{Í«o¿øJ5­~åm/½ì¥^~+H›ÞZ夕ßZ¹ñM¦H‚ôü†7½´é眴|Ý––­{cÙK»˜–2­ÝÕWM;—¬©¦ÅkvzéE/-òÒë^ZýúB'-xáu?½†ô,Òª =³ê5/­ôÒü•;‚´bÇÓ•4oÅŽyÏ#mGšké¹ísœ4{ù6K³–o›µ,H3—móÒÒ­H3,õm^M[¦õmù«¿ÞgÄÄÓ–l™Ê´ØKS¼´ÙK‹6Ÿø“_af—©õn¿|ùrjó–n„¥8ÿ¹­÷4ú^ ´NaL­ÓRWª¯€0¦úéˆÖ(†éëßð8ùdêÕ‘é¹=†é Ä• Ö]¼U$S&ñth½À˜@)ÕØ%<ßÏžûgã–pÀ3}/Dm›BôRªè°ñÁ]:õê;®ÙÁ|?§{}6—Ïa†©ÖÈuÅd Se}Ôξƒç¶¹bª.‚JrÅ´¬fá7“ïŠ)ðÆäºm^ä­wÆÔúßFǯ¸ãßÜշך]÷wüκaÆTàÂSÖ¥€¥V@S©‹W'RƤ RRzcºþ–;c(¥J¨8|û½ïŸä®q´í·L®Ûv]B¹°ï¥½´Î !—â©™@r›H.ˆ%ç[K®_~˜úÁ0erÅä"W.Q®ÖS ôÕüÃcNŒ)N¦ÉœcLd˜žyn–Àr:b„ÿCÔ¿Ÿž.’©¤Í¶«!„15$—ú) N¯§¦%/n¾÷E2Õ¯w¿¦'çZµ!õŽîâ-÷È'SïV =y Æ»zÊPá€ùK^ 9ÂE—B†ˆ¬!ìã}?ǯw#×',—ê7Äkl89ß»sBxz‹(uÅdáä<‚늩֑s4}’+&cºÑ *—QކaL]üµêÖšík•’=uaL=UÜzX) ¤@PǦ@…¥¬J+ Œ©Å‚êryQ 1¦XJ‰;1óýÝ q¶@K•ÅŽà–ê¢KÙé¥Ê:Èw€.…è%,‹´‘pÂô‚9a ™€ie,ÀT× Óº]˜Ò`Ь•ô쌮©Ó‹‘ÒcÉå€aJ'G£dÆDÓ$1¦³Ï½xËÎ÷-íxóƒ?ýùÏ]ÿ“azö¹M+¼Âõ0&xì7Œ ¥ó“ÓϽð¢_w=ŸÊ€è¦˜º©~ïÝ[Sï•y'Ÿ Ó7¾uXß‹Ûý÷¾ïS§ö½ØÀã†Ýõ»¦³Ô×××ô¹ž¸víÚÐ)MÜ=z‘F³Ñòãßó?¸lRÞ}pÈÒÏÇ$Ã4æÉ¹^µ‰Pïè.Þ|÷#‡ñÝï¿ßœÈ¹­èà~ú© ³Ê*×’KEŸ½‰ËòÛ*£.žˆ1EíÞÒ©Š³¥½÷Ù÷éÅ/Б}UßÏk<ßÏõ¦Z—϶VÊ55TbÉÅG«Æ’sÖGµ’aš¿¢•ÞI¿i.S\89oùÓ² ySm zºbB ŒépcŠqÛ\1cr­Ø~w÷‡ù©fÊI4Û—E%îµn½N¼Py¤ŒR@ H\) ŽM®ŠC™‘U@SGåÖÍ:§@ÏaL×Ý|g,¥Dãàµ7{SÈJ!–K¶¾ P)”\»¡¿ýÎKɾ—êÓK`˜ê†ëÀÄ9°T€©f­d0U¦E/ú+&ýE“5ë&ƒ@rÍÄ’k•¦, ScJpÅDŒé—g_*Ù?~ÔeŒ‰ Ó‚ç_ÆZØÐÚzg€ÌP( W¿>è´sÏ»à’ε(º“È›˜òV"åÎ0¦r—oWŸŽ ÓÒ5;Òßû‡Õ$Éêb¿ýö1bD Ÿr„ I0Ç€BÄîÞЭq:.ÒÐ)éoÛ¶­ÿ?Äÿ¤ä-ûƒC:ÅSF†iN#áäÀ0Áss ÆTk+°õNÀ˜BV¬wj®Jè¬n) Ù¾n)_èûÊS¡‹O™—R@ ”XulJ\¸z4)PGaLª"%U ç0¦koº“XRœô¾ýî÷Oô³¿¤­1â ]Š@K©ÜÒæwÀ-…Ð¥xßKè¥UQz)B.ÕS<Àäǘ¨ÃSkœ0­z확¯Í_¹ÃRøøÈ2Ê9XR™!–\F† k+=oL ¢Ü/möRey¥ycÊÆd S0)·¶žÓ‚^ûñiƒE2•´×ceP@S‘tHËÆÔ2)u¡ŒaªÀ(áH²€QH“ã½hS$ø 3­ƒôÄ–evš'©*´c‘á–Ô¼–`Là` «ŠÊ•%Ÿa†©Ò]dD9—zGµ¹ñ·› ™CÔœF´ôÌÇnÑrبµÙÎR"IulèСfágتz˜%K:¦[ cªÄƒƒñ!šÞÅs®Š_:UË-Á(á.Z ³ƒ¥]J£—V›¿ç—ß‚‘ÁRš¦Z; –2:a"FÉdË¢ðc2€ ­Sç¦é}žÏfbLæŠÉlÆ01¨œ0¦nýˆZu_ÍöµJÉžºŽ0¦ž*n=¬R @ ¨cS ÂRV¥@‹ÆÔbAu¹¼(ÐsÓ57 ‹ºP²=øö»Çžv°±VlUaOK/m~)d7ŒrK  Kµ¾ÜiR Ûãé%o~ËMaÛbrÙ&ß “YƒcÛœ0=·Nà-Í 9„‡Oøe[k¦¥Oxz†ÇªJ’c¢Q’SÔCoL`˜>ïûaBM»dpÖÖ£h`ÿ…Ù÷™U¯ýøT‘Lyis•N+ Œ©ÓŠ÷öý„1õvù·éé†)òÞ÷aó©ã½÷}XüÐ#¿ßht9Løkþ“H5Ñ!¾°‚m×3·±“´ ¶bغwâí\søÄ+ã`ÛcLIè²®ªîW Bp ogô•À=ÀAyÞ‚“žÿ?ªP¶é‰ù™={6.Å=Ì1”7¦V=82Öh20Lè.>öÔ<Œè@%6!{òì.Þ0lT£$žR@[€8T¦n=±zEÅPŽtAD%Y‘¢ŽÁb1&«rv<2–³*A6þì׳ªN–1œB‹BµGòIæ)TëìÑà¨,”O«ç8ÝÄlS“¢ËæAbL)v |…æ,\·nªZ › ê­›rÖ¿•°~càÉk=*Ö† „\€É R_Ï “Ï0ÕúuŽ:aò^mLÎj¨š¥PÏ'Æ’kÔ¦ŒÉYïä2L˜òðSê8Û·|ûUý¿”®Ð; cê²Ö“J) Š¥€0¦b•—r+Z©€0¦Vª©kåHÞØnk äÎknvô±'ÚÁ¢ÆÚ¨p4†q¥Š§¥,ÐÒ‹p¶ÄŒÃ†cCLD—jݹ'ÐK˜¢H¢—RÜ/¥x`Bx2/EÖJö`Z¹£íN˜j¦-.Ãd«*á„ ÓƒÆäùa Ù%sè‰ ÓÂç_ö6NJE\2T"ÊÙt&œíÿkf’‰ó‚n+•´Zsu9jϺLJÕÍ‚D«+Q‹ÆÔbAu¹T„1©‚´Zc˜êÀ(Œ˜ë…·Kt±i„d¢OäݼÂ`EÅÂW€?Ð`¬+¼Èð¾3n{ÙË ~Áƒy$=èð Ø07Ev°õ:xJô²¦¨}…l0˜K>á_ò4<×§çsrcùG&q…袞rb³M8_áv”‚w´GvƒÊµäÁ ë4T³\†)ä¹3ÎS@¿¡æ\×ÉD$3À+¥ž°ÔBõ eá–# ž$oLDøaM³ RA܃rÁ+ƒ‹l²=v_V7Üc? ^ÖíñF+žŽ(³aõÉ áŒ‹_4U±€iCÈ!ÕÚaˆlÔ ÓŒª-²ÆiN˜`‘¤Qò¯þzocª $çòL'þäW9 *Ã0…ãƒì¢K×§3¡íɧœ“%ºœ0¦¦[n›ñM¹‚0¦¦åmòDaLM §ÓšR@SS²é¤$\†)Ä.Œ’òÞ?ä;Y}2”1ßEÈOèm’æ2%`5€•`Y%|ˆŒ¸Aåp€¹áᡃ‰E/kâ.±Ý,áFäZˆÑç ‘£Oû é;*z£Xz&”mþ‹Ó ÂÕ쎦››·~>¸Kbeü¥Ôa˜j=w2!|œXwñºÛ³údBÞÈ÷àA ~l=qKGR|:Ó·ia›{Xj¼2· ‘7‡D[%Ø ‘÷n5ã¥ÜSŒ|â5ù/ïË\`ú9ÄÖR`I/E8É®ªuöhx>¾ëx ·³Ö2>¤¡KQgϼ¥2.½”´PÊ‹Wññ¼Ñ*™ªêwö%Ú^§¦8¿Î‘(r)N˜üAn¼ ayÕ€`.œ=€)™a ­z:çß<Œ)6–œÙ T®¸¿A˹0¦bçASç5×¥€R ‹˜²¨¤c¤@9ÆTÎrÕSíé9Œéªî ù/”¸~ßüÞ‰•µŒaD‰ R «TÅ•j<-Å8[zÁJþòÇ*·äÍW9^Ü«–Ä`5d×¥xt †Å—v1¹†Åï¥z)ê~)bg\ø‚³ÌO¯!!X2¯ïî¢INXr—Nö`ª $˜œ%•®&³Hcz`ü‚X?L¹òƆés~,¹ª&c˜Ö½ò…Ç~o.3êŠÉ—ph°ý¼>É”„1a¢…kè1ÅÂ)@›Ôá‚uNX2$‡¹CÀtãn˜ó¶»<8€§ÛÅÝé.;˜á”'Æõ]fˆËëÝ+Gs‹cx=…ùç1œ3‹îáSóNnñFÔ„3R<‘ǘŒ>û۔ª^AP@S'TÖ=* cR]h1 “Ë.»0ŠãŠÉëwaZ·òÞ?8ÉDŸ:ˆð•ír8 „§ÐûN+ ‘I8‹8$!ìâÂ"䜨O4Œ)J«ØaÖCÀ¹!î×çë/\{¢}‚ý<†ÐUèFQŒ)šmæ–!êØ!Á‡TM¬7¦þ?¸õ—2Ö,0Lè.2–\ØS†î":äè.^sûCY¢ËáéЋc±²c[OÜRC‰àH«l,Gë±Ch˜¢ýÃtŒ‰™qƒ$²Üí:é“)Ûnç-ZyP:¤ôX1\ÜZªc¨«ì6³p‘=…“ËXÏKp1¦¸õQ4Ax Ì|v…™ Z¸bjerœz'rœ‰²)÷Káðô¶8jÛÀª`Š"‡·[¬%!º*Ñ S(½c70†É,À˜¾éaL‰>›å©¿D<‚0¦r”c‡ŸBS‡×í¤€R £˜2 ¥Ã¤@ ÆTÂBÕ#y ôÆtåõw˜‡¤è¾ø½RÖ5ÆxWаJŒ·ÉKQb)êl© -ÅF‹ó½¸‡,‰uÑ¥tzÉu¼Dü%&xœodlØý’¿b²`rlŽžg ï÷=0®à}+d“ëN˜ 1¥0Lð¶UYöêyÒJrÅDïú0éÖ%™’0&.aÇDÀé% ºÁý6™‡ .+Ç)øp®‹S•œ­äL&o8ÊI,Î0¹Í3 5e¡:èõÁæ¥BÓEœ Šæ×áyæÙa²é[柹â1¡=ä´xG|Å9Z›³‰(; Ïhn¨ g4õþ霘:§µî´g0&Õ‚)` w²ììøÁûE<»\ëSÇ{ïû¾(¾]d²WóÎwwè Î75_‘ Ëe/D¾Úx_yá Ç˰ÐZ3+z°a@|ÏÚeMÑÐ+8Š1‘ÁñìfÐ3“½sÙÁ·ÄS¢ùwyÞ4šm>>ö³¾ 9cêÿƒ»½º•‹ ÓØ8†É«9—”jw1âŠ) ÞQm®Z‡dŠºb¿(©ž°ãdõÊ*’u¨Øû"e`“=rÈ«bc²N#Š˜49/Å*Án›Û‘³‹„ª“ubÉðá\·ó­‚1Rn­³G³N)q>&;ÌuKY”CbL)f|…f<³"ìÝ9}¹T\xzÏòÌ-Õ¬•Šêûx^›Ñý’0Õ*k¢¼eQîš([…EPAJ˜|GÎEnÎòmÆ0etÂä’3† Kž|Œé{)>›…1•ãÇ(Œ©åØá§ÆÔaÁu;) ¤€Ȩ€0¦ŒBé0)PB„1•°PõHžY1¦èú×"êwòÉ'¹þŽ0Šä˜ñíÀcNXý2˜$7½µšLRlòA¥$VÉ1Ö¸YŠzZªñÜø[Šá–Ð¥ÀåR£Ž—zéE}a ÖGF}/y!'Ý/¦Æ(½Të~)`ŠÄs°Bšý±B/Á|ãÓ/„\`¢³¥ücLÆ0ÕÆ™ËŒ™” ¹d¨D”#Ãäk¸õ‡?;;%º\ Æä΢ Ácñ;Ü .µw²Óö¢›à‰ˆr'®l›¥¡ˆ!ø6Ê$…f.q ïhüS,Æd3I\cB{¢ËúÝñ`›îâ|*‘&c³}¦ˆígQó,Œ©¨%WÌ| c*f¹å-×Ãä;欼÷'-ÜüؼMcçnD3wãs6]ŒòøÓ›<ßµ®˜‚÷þÒ­ß>âØawý.é1É»ßb]ÈÐ ab¾]Gƒ|±A2‰Çð‚dV,ì/Åw%Y(÷`{á†.ëf̸̮^éÆyæéø;ͽ¹‡4D&t#$<×˜¡þ1W‹äZ%ÞÑò½B£žÝ“1Lè.†Ð·qó6=T›Aµñ»‹?ýrPmBÝÅå^Ü¥«n™â“É5“ Y%Á­'ÜÃá¤yßdwˆ}$À=Ñ‚ÀN|‹ÃìcµÈª®/åV'þKàŒB4O¡Â¡êdCy$»µ¡ªèV~ÆSèÓ®ªuöhæ¶ÓNĹòÆ”·¦¸­ù!Æ1;ÔX!pÀôùϧ[!žœµ$ÆÇ³-=9sIÔòðÈ„YO˜5qÆÏ÷Rè’ÏD&s- t¿ôàØéxUÍîÛ„Ä(r4,Œ~êY`rM IÓCŸ¹çá©Hwûiʳë€)ˆ"7é™uO=³ÃÞáÏ ‰kŸ¶Ü7n‚ÎGãÎà 1¦ŸÍ˜ÚúéØÅ…1uLê2ÝHS™JSÏ"¤€(“˜ÊTšz)И˜ÓKGçQØÕ¼õ1&Î@ðÓЂàjàcL·'š_~kÈu·uÌ Ä’RȤäxpaV)ÖÇÒ7¾uø§>û¤¯ëpºmÿÑO±ï'þ{FŸežÛg<»úëß:,´{ŽúÞIXˆObéô³/FŠ wã°‘ˆ2†€q3î o6ü±qèRÕ»{ÈñÒNÿê¿j‘ãâJÆÑK®Ë÷XzéÊ[ÀºÉš¥“>g㦽÷ý;X™0›â§VLýǘÐ5\´å‚¶Vu2LÏ>·Éf¤`k&Íöƒ+gtÖøƒÎäÅ“O2câÿŸ½?º¢:÷}aîýƽgŸ{î9ãܱ¿s’½wº}ÌÞ÷ËÞÆ£QQ‰‰‰½ ‰ ˜Ä„hì[T@ FÁ^x;}餕¾WîDD@Pà[DQùþUOÕ³æªnÕê«ù¯1ǵjÕªšó?çš5k>¿ù³÷ô3zO¿ÌË–øîU5gÎiÛõ›‹£H&'d:ŠqHŒvhÿߊí/ùVÌ6b1bCò¯§—_ɲ~UX+c2M‰9JÏ,§îJ®%†Iÿ)«ê¥øú2e11&9À¼¶‰1Õõ/ã=91¦†Êû‹cÊ}¨^a˜Ú6îV€IïûgÝ:÷}ÜôϺe:R·¾sq߇©7ý€û¾íŠ c§¹«vá¾ÿ‹Ó£H¦ê³í¹•×ä„< xiǵû¬))…0Lãž!yw›Ór&/ÙÜlìˆræp±ßÀ(’©d®â`Ž‘âß°c0F5ñý´?7L7^(¦‚1æ%Üùs"Ìzqm _gÙÙû/÷~ÄǪô?ûåéc¦Ì—Àô]|¥Ì9 9Ä’=óðì¤ù:tЯ0 )ˆÒ^—¼è’7rœxvWFûæ·¿‹GÔK¯í}é5½1±Ðí÷—cVᩱ³OøÙ©’>0}`0úCxäéš^wY“}¿ÓÔýŠžHŽœùï‡)³¸j Q¢È=òÌtc2LwN˜®¿SÌæœîÈ1¥»þš”{bLMž—¥T€ P cb¡ùU€S~ë> %Ÿ)òò”§4Æ$øñ3Læª?¥ªcê{ÿ#Søö¬_uµ§=ÉZÖ˜d–ÐI[­ófJ©(myOp%IàQú=8¤Ë¯/Ä>â+™C|bÄ™[´ˆ%Z·tØ~‚©F J‚.]qÝ-H6®¤Éá–-™aã0î°õÌø¹þ¹Eº¤ë#1É8lìì~”éã½0ÏX¦ï% ¦1‚Çwâ)¾ßM÷K‚1ÓK¶MÎH;1)+)=‹)=0™«*+óÆôþ'o,Ü~ÑcmF­ûNýþÂ0-yy[ÁY×–w5¦ ™ðÇ€ªGEß5bu·¾sPwƒ'¿ÚµïÌcÆöø«'M}éMÈnºbs&Tº0œdÀHÊ¥QÞün‡tðI~Œ ¿ÕÅñâ~'D—"=‘¬†0„í0ŒIŽ—ðDöx47/-Çûs‹ HW&ûbR’[ÿdXý:H©=Â:{½¯N楾ê×lxæ"ˆ1±A4RbLT;‹×Ã`}%&wô(t»8_Ä}ÿÏO­<] $™¶O5K‰I|;ù1&ìÔÜJ08n%“ré=?hÉÌ­I¦M˼}.òéQOöˆ'*zcjèM„SCåÎýň1å¾ T#€Å0Aß°[¢ü(ÀdÞ÷o{j…É0á¾Â5“0v5w3¢†É}_`Ó“ pßG|œˆèrÕdž¿­“‚1I „™,†é¨Žc§. .âñ“É0*@³Y Íæ§Ùˆ‡TÓ“ï|¸5"º\ ÎÓRl+Œ ”R輄M&မ‹^ö¬’RÈ~Á'¹¬Ò{Ø:ÒZ¥Þ'ÏY!÷‘‡µ0&å–FM´0&](5rÂ<™sÀ»$t˜‹@Âö÷vV¦°, ó xöÄœ¶‘0« aãdzSHèdž_´˜UÀ;æ%0±€é¤3ÎIoLxb:fö¡‡%“ ‡NÀ Û§Ýó ˜1ù+ÙŽœcRßK­“c'fþã°#Oí|V@u¿âf¤Á#ŒI6Žýé)x¤u:nˆ÷?:ÎÚÓéd¼[“2LÅÓƲýÔÒcÊIE×¶˜Ä˜j«'ÏF¨ µR€S­”äy¨@ú Æ”¾:cŽÄÈ.®Rü¢”Ƙ`ׇé§À†‡JÆÀ˜î¸¯%ÀC’»äßžuNW¿ÿ$“€%I „“ü;=ŽÙõã•×ߊyCàJHVx8{Ƴ‡ØÙÃæ º„ |,ö´„Žj0èÒY¿ê†ùDÁ˜°ayZzÎò´„ DÌ*b£ÓÏO³Ö[KÚ`%Ì!7 S‡x_°r6n¸õØÀÎ8§ë ·ÞÉDìÁ;¸%Ì*þùžG°YE01ØFÌ3ZBÂfo»«óŒ˜pÄD$J^×ënÌ6úœ½Ï\º³€“îzx8VLâ`¼Ïxi‹½1ÓŽø ïýŸiÇi‹7ÇÉǾý‡Ã<&8èuç@`L (m'L•»_òÀLñ1&ÀTWŒ ÓGu\¼z›69iB2ãŒæ†€2×?²äÖ¡+nº Ó)¯Â??6þøÀBD”;£×ô«¾è1J©+&kºÖž¨ #™ðﲓx1~7åkRe xfŠuY/ˆ1ÕKYž7HbLl•* ÓŠWw{ïûöMFe¹ïƒ>Áû™H½§_üà"Ü÷±§ësz=±,ü¾oßð3!ã’L•VQs~gbL~˜ †‹Ãä>¡ø‡‹@ÌfsI`³ ñÜi[÷­fC’©9ÕÏ«fWÁ˜"æ%ð˜±ðåÀYˆßýñJxt_Î:¿¿…1MôFˆÃ´Ãã#&KHz$Ì<`:BbÓ#aÂA¼;c¡Të„yè10Ï 3 H˜Àr)ì¹ìº[0ðpÕvL2`”ÐK˜aÀF[ï‘qêŒ9‡acçÈô‚,‹²0¦õÆß&½„YL&`Mfð޹øÄdÂu½îÂdÂÐc®À CoF”Ã|æ0{€9 @/‹ þpÅÍHB/aÞï<6\æè«ÿé›ÿŒ"ö´<3ýÛ7öýþaGʪ'ÿz'bLÙýÿ•ŒSN*º¶Å$ÆT[=y6*@¨¨•Ęj¥$ÏCÒ§1¦ôÕsì( <€À“ˆSubaLr´ø2Iµ®ÆtoK‡„oÏ<ç‚À°$ÿ~' œ N' ±ñâËoÎZòª€J˜4|¼u²ƒ.Ù*lÛ³‡Ö6p%ÀI¦Ïö®dsK<ÒzÙµ· yz’ -a¢SŠX ©ŽÜeC¦‘°»’¬ŒÔYEY‰¹E¤–§&N’Å‘xÿÆ·¿ ßKH`˜0½ˆyFk’‹þmŒ èVÿ?þì,L,Âñ¦/¾²ç¯´6àx öËŠÉó~{Ùc6ÆÔÑv½„ÉG$ñÀ„YÅ!#f½$~àK³ýÀ¹‚šˆ¬ÆÓõ¾ÜôÀ¤Ëâ±ñäê¿›º©SmÓ€IGqÔ±/®~CâÈ8){ÞYm™h 0dö÷ ü0 Ÿ¹ F)X4Q•˜`Ë´ý1ìAP¹1 Þû˜Ø-0L¶K$‚dJõÿ½ÜÌ×c*7<¾. cª‹¬r0 Í$a—qßâe—Ý0²æ(øòYÝÿ}ü+§T9\áÏ @Æ4~ÃaÓ^x¨S§NÓ®‰.â!“<&`¸h5›õn³±£Z“}Øì…2\TÏÒxiyÔ!ÿôÚ§IŒ‰ ÄWàÏÿvSiŒñU¬€…1ýÓ·Âæ%dþÉ3WˆéBAO:tÚM·Ýc:iÇG+ Ük{®ÞnqK.±\  ál·í˜C|ÚC¼ôÚÞ˜mÄ;&±!3‰}D+ÈÈÏO·ò q¶$I1&kA¤mú²0&{nQfÅëf‘àŠéºÞwËôâDY%¹v7/ÁÁ&1]BÒyFÁ˜né;èÔÎÈl#0&Y.‰ G˜FÄëû‘3AÕ`VÓŽˆ‡iGñ½Œ©çO9ë‚«nê‡ùÇ)/lÂD$f5aQ¸“|¾—* —Ôž?¨Ü ›‡øa&û¨Gc‡c D[·«¸9†L44 pKXU/ &ñÇWLWZŒšÂ´¯åiþVÃ(µË1J¯­ô~ë;›w~ôգ,<'h¦Ęš©~þ®MŒ)u^«ƒdr† …¥3tœ]îû×µ,†&Üô­4w3†pˆ${ÇðU˜ xnðå’0 ¦«®ï…›>ÒG>¯Uþyž:)à*€iÛûår !@2M]°Z½uš¼»4<>`ˆ(ÃEa˜œfóô* šÍfµ0LÃE‹a:ú¸Uv Ù´¿ûÉ—_}U§òò´YS€·ÅŒ)zÚ8ÿî õQxH„gO zYeM>ØXæ-!!0œrK‚1霃ÝQX}…åÑÙî1°JJ–H-°&L5`ÂáŒsº¡×%v_Ë3ØoM5Øâúh$z{†‹£0«€¹Ì'ˆ×%ñå,âËyÖÒ-O<; ¾—]º¥_ fú=l…Ã3,ÞųD¢½$3 H–çæ‘30 Ì¥øo¾ã¡aè¸ðncL;ùÍHˆ2LR:“dÂ_Æ¿¤·2_UºDŠYŠf•·ÁòæîrĘrWåM-0íµM•?í’IoúâyQIÜ÷/¶È"á¦/iü¢7àÊ¢ûý .ŸÇì’ì²É0‘dJEƒ11&`ÒÌ É4eþê€áâFk¸ˆÔµï,lÇŒÿe¸èm6áÃE“a’fC’)'™äm1¤cŠœv؇ä¯íMöâ($ÀIgýª›9B,=0¸ÕŒ ,Iq%8uÆ3¦Î9Ès¥ørVïÎð·$s –$}×ß_ŽÉk>aìlL5\ËÝòÐ:–gŸ_"ÐÒõ½ï5u ú£Ç´öŸvvWܪ®ëuf°& “𺄠L&<7÷e|”Ô:i±L&`C¸%lKä8õ½4|‹0 vùÀcã홄“.|ÖO=÷•7õ½â¦¾wò™È츥ïöc¼?9n‘Ì`éw—ÝôË3Ï'Æ”ˆ¾¢y™ ÆÔ<íS|ebL)®QlEɆ–< – +­Ý#k"%Tœ“lKHB,Íxi‹l,´GšÉ\%)sŽöl£3á¨Ë%9G;fœ‘ŠbÆÐ¥…‹FÊŘÄ~³á§Ä°T?Œ Í$¦¯Ýé6§B›1WÕŒRvLTÐä%Û j”rÂÊìT5$–œøa2H&‰ )/ Œ­­­1ûô5ñ‘#ÿÁø-vÂëÛ‚ ôŠÕ‡³DJæ˜&xM\›W/ùCtˆ1%½†²•?Úk³UŸ/ H& Dul)ffÊðO¼é80Š{ß/ ‡Qü I¦ÆWq¹W”Ñf À¤§’iò¼Õq‡‹v,9Þ»ÃÅvÇ“}Xú&’LåVb®çm1¤úñ·ý‡úfô´˜2oµyLaÂõß2ÿ`L>Øsž™sÚÁ†>p¶Á?Ïà™džaXku5þ¹g>!hVÁœRLŸFöÜ\é§ëo{è¤Ó=“СCÏ£ôž÷>Íõ_>……'Æ”ÂJk~–‰15¿˜*@¨R€ÛȯĘò[÷/yî0¦?ß5È?Ù§{ð­e=òM º4R“¤|’1E1QX˜4´cÀùç £Y%1_’Í*àJB/EBK2«hN,>þ¬N¡¥ˆFËæ!Éuð^‚[ÂrÉ$¡KætdeÓß¾°¢i¼¶oØÔMÂ:‰Mû6UßX$ÓÏNyqÍÓ©aAœª·+ZªÒ†Ì‚RÖjTw7Œa’yX¸àR¿mð²^Ý┤dL×G8›ÿ`ðCÀ‰ÀNµ´´èå€1ŸÂEåŠB}Æ),I‡ĘÒQOYÉ%íµY©É&–CH¦â›~!˜‚Ë!÷}×ÿ¢Ë.ë}?Œa $™j2€i¢†Yºô¬-5„\D¹„dš4gUŒá¢…¼2LÆä‰>Æ0’L‹îè>¹{ÇÞôŽ~wµ-X=´(¨y–*ˆe)¡o‹! Æ1/¯pÀ¤¹«ÖD…Ì?xÖD…³J%ÖG•„–„£5“.‹òÏ0˜k¢dz!b5TÄ:(ï"(èyOÜùJé%( Æ”“þSN*º¶Å$ÆT[=y6*@¨¨•Ęj¥$ÏCÒ§1¦ôÕsKÜaL·õ¨ëýø¦£ˆÀÒ_ÀIÂ*9¾”Š(¥ §J^PÉ¡Éë])W’€âfÉN^hIlž‰ÅÖÉK-9Ü’-ù¹¥R.—à~©™^—ÂVRVƒ1EüɺŒî²`Û‚XÿÂR É´hõgu¬Ë±œ13LŽ-Óo”Šf˜FO^pÂÉç~ðñçš/u°Ex©c7pHp_${€á0OØ–èlدl¶x<÷NæÁz! SâÉã ?‘S)`„c䣻ԼÉ1MS~¥Þ˜ôñ/%ù÷¸›ÂW8¬Tðûô(@Œ)=u•…œÒ^›…Zl~@2Öù|Çí¢ëI™ug€g(~ÿ‹€QF'&Ã$HÊÇŸþMJ^ÃLó¥ÌS@EÛñø ³W9ì4|wE#ïå2LÒlÔïX%`LöPïKî±~LOÏS°¬ò¶Ò cŠž[Àç¬*9ÿà[å|p|9ûfŠp%cÎ!®;çÀIßô‚®± säÛ…sÑL‚ãxÉï¼¹jz‰SÞz.bLy«ñš”—SMdäI¨ T æ cª¹¤k¾ߺv#¿«$ÝS$yc½…D|ÓÐo”RP)ĵ’,‚ Ä•Šü·KgK¾q‘ΖBâÄø[*Í-Yþ¬´ÃIµ›vŒvÿ^+oLaÿ¶–-‡ <¤Çìûÿºòk“[×¶b¨&›ðQ~‹~/ôÃ1ÑÜIS¦ÿ³S®zËšnvc:µ/µ­6aV!ËT¯;>þ¤ÎânÊ|R'IÂ*ŠH<6aC,áA‘€ÉWêcIÝÅtÝ ÊäðÑ$$W¸€$É­€Sš[ý9öhXMœÐÌ¿g–¯ÊëGyt’ Æ”äÚÉ^Þh¯Í^6©DC{#RgÐç¾aØ*+\ïlŸCh?L£ìÜûÉ—_Y÷}ÀÈ6Æ-¥`0¶ÁW:ži’N¼l‘›6oùá}nV[Ðp±(œ'–\e šÍgŸ€ašÕ£ 6ðÐÜ/½>Í I M{7XD»g¿xi¢£¦Œ7bÞC*X0¦ˆy |…\0Ñ»&Ê»2*dqTÙ룂|9»ìlaYTD z7}”Ë¥Âj¨U»°ʳ*Vèyã¥;â?ûÇ?’Þ˜2Þ;¹Å#Æ”“Š®m1‰1ÕVOž P*@j¥1¦Z)ÉóPô)@Œ)}uÆÇR wÓ-}˜D‘gߊÑ(~ò®b ŠøV—’xTŠ•"X¥2p%+ÜX»Ç‹»|ô„‡3<- %¯³¥ª¸¥&£KõƘÚÚÛ:>Õï0òaCL€ˆ´¡ 'üAñìrpI×MÉtâ)óÛÞT7þâdKƒj=JMÚ2£ý0‰-óÞ‡Ÿ8îø€HyÀƒ4´x }IO#Œ”L·LòêСƒDmÓxsæÁ äT¦&³÷2ƒÊá0@Kx×ó‹£&/çoOò½œøgÒüˆ&9‚MrEùm¬¾“¥EbLi©©lä“öÚlÔc2J’éÔ³Î3LJN,`\vÈ®Á8­=â¾_Ärë¦};Æ*º€´ö`jc'Æ;9ÉŒ¹°’iܬ•Þá¢ÄvÃ9E#ïѱä}† ¯Ïì«nI6€+[‚s&qÂ4º‹5è•Ø/Gn_4Yð&ìÿÄÊˬ¼-†T­`LÑs8T¢ÿ˜ÐùÃ…shÐy{ÚÁN?úcÃN5…žŠçŸ^ˆr¹d?·©¤×%w&¡Î+ ˆ1e¶_*.1¦œTtm‹IŒ©¶zòlT€ P*P+ˆ1ÕJIž‡ ¤ObLé«3æ8–yĘŠ&þŠ'û€1zÖùf7ÿvpX7E‘ü¯ìY²®Ñœ@t& }1à“•xÜÑäzkW„Å;™+Z*Ž Wnµ³&²2h AL<Þ]K â–56f*æ–l?‚¶+AI¡ãà¹Îè’9Q@Œ)›’¯T>ßýX[P)9)/‹Yˆ1ÕDFž„ P*@j®1¦šKÊRÔ(@Œ)5UÅŒ–§@î0¦Þ}DÌâ[ká» I [ªgL*ÀIEÎØƒ%#æ CA¥p×Ja–Â|,Kñ<-M2Ú–3Iž8qœmŒï%^¬Æ&I°$µüa[<0á%ßÂì‡oñ.)fX›d:yÎòíE“¦I 9Ǔϖ“a’Xr yè®$TÈ!Ù)qâðnb@Š1Ià9|3„ éˆ1i”ºˆ~ËãIü6álà$«TIP9É›xf’ÜjÌxÏã‰áäÊ»¤âhbL©¨¦Ìd’öÚÌTeb "$S4Àdù_´ïûÖÌ5ñVÀ0éźéÏî’Idð `$ðœ`”ÉNŒf̈C2™¾¢äpÑj9úV䬒8[±€ `>Âñx&©Ù‰8‡Në,³ ð¶Rµ‚1‰¿½°É‡¯ÿã7ÇÍ\gÚÁëN)deT˜çÐ9‡xŽœ]OKQ^œ£¹¥Â¬BÐ|Bø5ù 1¦ÌöK¾‚cÊO]ת¤Ä˜j¥$ÏC¨ µU€SmõäÙ¨@š Æ”¦Úb^ËP wS¯;ÑE˜ã3¾uV½ËN+h—?Y â#R‘Û¤p/JQ|’„ ‰*¹VªW‚S÷HæšHïÊÈ0h©±K$k2AYŒI"Ê™–?ñÀ$M !³Ÿ± 1ÿ¸ ™:þôäYË·¢Èe¬ŠóÙ2Ëb˜$à{$ €$%TÅ9Ž?¤’0C À„ÃäçÂá…„üG”Ýt’¤WÄ%äüÂ!!‡’1œYÏa§äÖD²°G²äÏ?ާ7¦˜-0e‡cJY…¥<»´×¦¼“™}L'Ÿyž ©›äŒû~ÁMEe “ QdƒMû¬Û·cº“”°¹ÉÔ-ç¹’èrÏN[2\4Ð7×}We tVV ¢Åaü-‰&@Kø‘ã$Àœì‡O&õÀ´«mð¦œWV–‹ÏÛbHíc¥0/aL>à€±3Ä­ZÀR(s:"xþÁðß¹2*À»RŒeQá.œ½A⬹ÏÄBˆÿæð&h¥º\Š˜O Ɣ宩¸lĘòS×µ*)1¦Z)ÉóP*@¨@m ÆT[=y6*&ˆ1¥©¶˜×2ÈÆÔóއ#0#|k-y÷°G>÷H²`Ñ“¼aÝE ÜYÚ(3†…yCPJq@%#\°k¥`ïJ¡¸R¤›%#<\b&«á™ê„1Á,i¶@¸.€µû…g‚ÙOöà˜r=É4sÙ¶bC¦e‘ò¬ª‡20Let!<” $\bL ¯ ŒeöÚŒUhbŠ#$“x^Ô(râ„É߯˜aBq1DÁ@êÉ?€‘oqF/Šh'F*f¤ €L£ž_®ÃEÇggy/à3L¸ž°J²ÈqÀ’ð.“«„ØÌsòQ£Ë±ò2¨o‹!•*SÔò§µ»q|ªÎ<”ðÙlÎ?¬Ù½0ræ!ÖlÃ*Zòó>¶aJÁ“"WC…øo®æq¾N¿%Æ”Á)¤HÀ˜–ï왟ò²¤Õ+@Œ©z y*@¨¨‡Ęê¡*ÏIÒ¡1¦tÔsY¶yĘ"x#`L°•’Ö´GOš(’Ûš(Ô´ÚŠæO†cvÛ^%É= •BY¥²q%70\Öˆ¥À)Îz`LíûÛÅ™éc †@Ù)ïxÉaâí ÜH¦c;<}é2q,+\­…­Fd2LåªÊã3¨1¦ Vj‚‹D{m‚+'íYÉôË3Î żïK$_áTÃ0éÈæàÄ?€TñßKÿôIDAT‘ÁŒŽgÒ®m†ó/$Óˆ©ËÜ–<\¬†a‚z&‡„@rHØi¾ã#<0éW"¸çc†k!×Eãm1¤úcŠžvÀ£%4¤…"• ‘§ œi‡Òs±f|¸’ëfÉ~5Sˆ³%cn!þ–¢ù'bLù黀1-Ü~Q~ÊË’V¯1¦ê5䨠T  cª‡ª<'H‡ĘÒQOÌeÙ äcºù/ý#0#|«a;‚#Å€bI€“‚ù¤(Dɦ”‚Ö;ŠAË ç›FŒˆ†+%Ä‘{VzN[Œ©ì?bE?’éù—¶š“YwôÃT‘®üQ¶ Æ”­úLzih¯Mz ¥; ™~qƹaà2†7U2LéV‡¹Q@H¦Ö)KMß]æp±J†‰ÂS(x[ QG0¦èåO8q!K®€*µ&Êv0ÖD•¿,Êv°4ÏP –Ü ó6\[´ª1õ5¿ 1¦ütnĘòS×µ*)1¦Z)ÉóP*@¨@m ÆT[=y6*&ˆ1¥©¶˜×2ÈÆtÓíý#fúðí/Ï<¯Ø’ GžäzHòùI2}&•`’€%iŠâ“bQJÞ0pî4"@¥`VÉŽ—+\)lf3½þè ™ŽétòÔÅ[á‰ÁtÆ@?Leô‚<4Û cÊvý&­t´×&­F2—‹d:ý\ñ¼èÅ‘aÊ\m׬@B2=3y©¸H†©f*óD ð¶‰1EO;c)A!ÃW@•=ùNCÂ…²J¹Š8¯“ĘòÓ«cÊO]ת¤Ä˜j¥$ÏC¨ µU€SmõäÙ¨@š Æ”¦Úb^ËP wÓ·÷/ÀC&Hdoã[ ØQI²Q¤H‡I:EX˜+,éE)À—’;L¥(PÉgâªù"Å œ0Õ“C2ðËÉ/n1ë‚~˜Êèyh¶ Æ”íúMZéh¯MZd1? ™N:ýמ¦,Vu-Ë$$ÓðIKÍ–C†©–ó\ĘÊiâ)zÎHDÈÐTz)TÑ´ƒãQ)Žóæ’k¢Ò®Ê™ bLå´ètKŒ)Ýõ׌Ücj†ê¼& T€ ”V€SixȪƲZ³¹/Wþ0¦>ýílÁéÆ>ý­#â÷++‚›¦Â„`ˆ¯uA‘ü©È»ÀIÅ3†ÅˆR‘ovYNMJUÎNâçiǘ„d:Ú ™È0å¾c§†ĘØ©1¦FªãkyH&2L9n eÝC2‘a*C;Z±¼-†HŒékÿøÍèi0bÊ2ãgþ¡‚ɇ€icA”á¼¹xÂ!ßΛ‰1Uü¿O݉1¥®ÊšžabLM¯f€ P*@ ÆÄ†Aò«1¦üÖ}ÆKž;Œ©GŸ‡Â "ìÇ·Õq@@ì6ÅüÅ“ƒ>ÏI˜% "“È'5vqg0&“d"Ôñ>›Å+WbLå*Æã«Q€öÚjÔãoËQ@I&2LåÈ–÷c•d"Ô÷¦Ð°òó¶1ýÃ7£§¾ößl²4îüCÐ̃=Û É^åI}î®~R#Ï@Œ©aýDÓ/DŒ©éUº cJ]•1ÃT€ Pœ(@Œ)'ÍbRˆ1±YdTÜaLÇœpò…_–àÒæ_¾÷ýˆܯ®»ðâØé×]h'Ø™˜¨Àù¯ÿ­óyÝ#2vèáG_u}¯Í;?2Óß¾ø*i}|2!«'|úú­ïxrk~ܹ÷“f>ib2?ÙQ€Svê2 %¡½6 µ”™<üèw¿÷ý«.¹$⦯pßÿò«Ä Z2S ©+H¦;ì_ýñ÷VmØ=\üìó/RW:f8q ð¶Ž1ýŸÿç:ôGGG$ðoÿqxô1Þo?σL5Qà›ßþ_ÿÏßÿèSuèÐÁÓ‘îyïÓÄý ™¡R c*¥¿÷*@Œ‰m‚ P*@’©1¦dÖ sE¡1¦F¨Ìk4A|aLkÖ¬éSüžb¦K®¸îüßüÁ³“³­ÀÙ¿îV²€ —®O>Æ„þcÁW®ß´‹ SºR^2± cJlÕd2c´×f²Z[¨M ÿê¿lž>2ú¾O†)±جŒ=4ýŸL½™ S³ôÏ×uy[ ¯ï¥K—.0^S¦Í1nš™ú~ʳ']‡Íºä™ÉƒÒ•g3·ÃFM|ä‰ÑùŸ2k11¦ ôiĘ2P‰ .1¦ ÎËQ*@¨@Lˆ1ÅЇQ *@Œ)ƒ•Ê"Y ä cò×yôúu~KÂH¢C£w¼âïÌ–gúab¯ŸGˆ1å±Ö›WfÚk›§}¯¼cÍÁ:}´jFÄ}Ÿ SF©2Z÷9[º/Y¿7°å`¸H?L¥$ä÷±àm1¶Tï~øY–½7íxgøê¯MXz– §,ôÆ»É'è@bL ªŒ”d…SJ*ŠÙ¤T€ äNbL¹«r˜ ¨ĘØ2ª1¦¢Haqf¦x €IĘÆ\{÷ª_?°ÿc‘aÊhÎb•R€S)…ø}- ½¶–jò\qøèÀç÷}2LqÌÙqÀ˜n¿¬’Ÿd"Ô³¶Pÿâò¶[ãŒaLó7Ý4iÍ6¯¿¢lO&cŠÝät 1¦UFJ²BŒ)%ÅlR*@r§1¦ÜU9 Lˆ1± d]bLʨ@% $c²]1YÒÜþ>ûœ &Ôõžœå W€[G# ½¶‘jçãZö¶OîÞéƒ77yJ¼èŽî»ÚÈNÉ„û>¦|4ªJé!™È0U¥&¨o‹±F–0&qÅ$SÞ2cŠÝät 1¦U³B¨ T€ T¡1¦*ÄãO©@Ê 7¦”W ³¦1¦J–l¯ déâ(8ŒI\1IêñõƒŸª$&Þr­1¦\Wà O{mÃ%Ïü_ŸÖºôáÅÛÈI¿R’‰ Sæ[Eü¶µ·E¬$¦øªòÈ2àm1¶XY˜ÔS2cŠÝät 1¦UF"³²iŸw-A"³ÉLQ*@¨8HŒ‰€ äWbLù­ûŒ—<ïÓÖöý˜µH¯lý`óÎÇDŸß¦K7÷X¹éÝèNVV3Þ£²xÉS€Sòê$Ë9¢½6˵ۄ²aÝåàJØ€7¦Y=º Á “d_áÝÜ’é­w¬ÚOŽÜ»¡ÂÒ„"ñ’ TV·ŽOu,yALÛvïÇ{É#y([ÞcKöÁÇáAÍÕ5¯½õáKë߉³Þ¦¹Ç˜®˜2æiù†}¯nÇìPÔB8àh±ëœ&EbLI©‰Dæ£Ëè. ¶-HdÖ˜)*@¨ ^ˆ1±MPü*@Œ)¿uŸñ’çcáñÉg_D¤?ý[ôü6{ ”¬ôÄYzLWL†C¦Œ÷^,ˆ£1¦8*ñ˜Z)@{m­”äy\À0 ¤pδzh?ìÄì®´}ÑdloZ?¦_ ç¤PË|*°ÿ¯û{ÌîŒ ¶7$¸ejYÑ‚~/ôA9‰Y®};v"ÑÙ@>›J}KÍÛb}õMâÙ_ÙÓ_è%3í;°&‰yež¨€­1&6„00v:dà!PáGÉÈJ~‚²Ñº¶C)ýHI© T€ 4EbLM‘¥‰P€S"ª™¨½yǘj¯(ÏH¬€ß“á©Áyáå¨@â Æ”¸*Ét†h¯Ítõ6¥pâr /`IH ”À- ®„„ý šÄ]“†ãwµ-ƒ…sâ+· tŸÜæ4ðLØ€/ØLÿLblÃÔiòk“‘â¸nÊ­˜,x… ð¶X¡piýÙ_~Úºöë~ŒiÖ–Îi-óˆ1å ’+,"(pŒŽðŽñx& ¨0^»bL؉SƒsÂN†wåÅ+¼$F¨ T  ˆ1U!JR®1¦”W ³¦1&¶ *rü®˜è)åUÊì×RbLµT“ç*¥íµ¥â÷e) ((%0I —dÞ͘qà–ðQöcÂI9§²®Èƒ³¤ oâ` 66±·á6)£˜åðx“ì{²¤ËÒ|x[l~44®˜„j¢C¦†Ö/VŽĘÊQ+_ÇbàeÆ`I6dª 9 ._×Ãò¥KK¨ ÉP€S2ê¹ ÍP€S3Tç5 1¦ˆÌKPº)ðù§œ|ðÁNVºç'ÿÔá`ïï8±gýŒº]˜'¦)Q€SJ**#Ù¤½6#™”bˆ×%äF#Ê ¨${ðŽoáI²+ûñþùýØÀoõ«¤”‡ùh¬â!/µ®TÒp'ò-Þao“¤ØSc³É«eZÞ3]½þÂÍ}ãü©›:IºúùïúqÍî»s&‹›ˆ1¥¦ªžQ‰º‹Ëb¥Ø·Ž¯ä[ <§£)åÅžY^ P*@¨ÀAbLlT ¿ cÊoÝg¼äĘ2^Á,^ŽØ·í îUSúä¨È,*(©1¦’ñ€*@{m Åä©\tGwxZ‚â .—@&T:°·]0&ÙWL-IŒ9ÙI ó¬€x€Ø0ýˆ¿%˜âä[õ( ±çò¬Ë^x[¬‹¬é8é¨ußÃ”Ž¼2—ùV€S¾ë?ªôâºRÆKâáRÇW²îš0¦Ò¨&7GU© T€ 4^bLלW¤IQ€SRj‚ù¨±Ęj,(OGš¦1¦¦IÏ 'XbL ®œ föÚ V*‹DR©ÌlKNüHÀ3Á€&ìÁ·0ÂÉ»ºHe™éd*ÀÛb2ë¥!¹"ÆÔ™y‘(@Œ©"fôaԄ©&ÀLØÆÀ ûÕÛ%öà#`&Ý“Q=X,*@¨HºĘ’^C̨ŸĘê§-ÏÜTˆ15U~^œ ÔPbL5“§ÊŒĘ2S•©(íµ©¨&f’ äCLð±„d;a3÷ã#v¶ïoχ*,ecàm±±z'êjĘUÌL„ĘØ<ÂÀèH¼1‰+&yÉÀ ò./l›)) T€ P¦(@Œ©)²ó¢T  cJD50µW€Sí5å©@s ÆÔÝyÕd+@Œ)Ùõ“µÜÑ^›µey¨ T  x[¬B¼´ÿ”SÚk0?ùrõß-Ü~Q~ÊË’R*@¨ YU€SVk–墥 ÆTZ#‘Jˆ1¥²Ú˜i* €`Lv:øù§Ô‡ PGbLl T€öÚFªÍká¾?õöƒo­¡T€ P„*ÀÛbB+¦Ù"ÆÔ•yZ(€¶JŒ©BòT€ P*@¨@“ ÆÔä àå©@ ÆÔDñyéz*@Œ©žêòÜT ‘ €^úó¿Y$ìš|Q* cbKh¤´×6Rm^‹ýÛ@E ¼ýñÒ÷?ÝXÑOù#*P¦¼-–)X–'Æ”¥ÚÌvYÐV§o>9Ûedéj«ÀGŸmÛõÑ‚/¾äÂÚêʳQ*@¨@µ cªVAþž ¤WbLé­;æã%'Æ”ñ fñò¥1¦|Õ7KCšùcˆÄCj¦íµ5“’'Š¡û·"ñ¿T† 4BÞ¡rB¯A4$¡Ãlù`[e£(WbLå*Æã© T 1 cjŒÎ¼ H¢Ę’X+ÌS àv Dä)¨@R Æ””š`>£Íü‰©Š\d„öÚ\Tsb Éþ-1U‘®Œ,Ü~1¦tUYŠsËÛbŠ+¯Ú¬ ©VAþ¾Q °­6Jéì\‡Svê’%¡T€ dKbLÙªO–† ”£1¦rÔâ±)R€SŠ*‹Y¥¥ ÆTJ!~Ÿ;hæÏ]•7µÀ´×6UþÜ]œý[6&ÆTy–8 ð¶G¥ŒC4$£›Áb±­f°Rë\$bLu˜§§T€ P  ÆT¡püÈ€Ę2P‰,BĘØ.¨@†€©àN?Ü¡"±(T :hæ¯N?þº<h¯-O/]ìߪÓ/·¿&Ɣ۪oBÁy[l‚èI¹äÜ7ÎiǵIÉ óAÂ`[eë(WbLå*Æã©@SX°`A?ûÕÞÞÞ” Ä¿èþýû[ZZâäP(][[›ù“M›6ÉWØ0÷·¶¶b§ž_Ï Ë©â\:Î18[ ‹sªÆƒ&”–¶DŒ©1M‚W¡IT€Sk…yªĘj "OA¨  U€fþ„VLF³E{mF+6¡Åbÿ–ЊIz¶ˆ1%½†²”?Þ³T›,  T€ Ø cbC ÉW G]ºtôäC™™ð•)‘žÇà‡òÑS=FÔÓÌ›ê…Iç9•ªóxÄ—#¥RÌz׋ªtšëiµîô`ˆ,µæ©M³.—¦½6—ÕÞ´B³kšôé¾01¦t×_ºrÏÛbºê«üܽ ÐCÒº¶µeE R—Ñ]°Ý}rw|…óµïoÇ66à_É·å_‡¿ Õ*€vˆ†Šˆa.İ« R¾’o¥­V{Iþ>» cÊnݲd™R@(Ð*@O„ãш`Àt„¤Á»øæ›"!lð+lãxuVGX"=XeÒH>â*Âɵôø­„´3}#éaBÕèWÂåÈy«òXR"ez$cz ͘ž'ƒŸà¥‘æôþú–̘…Õ‚èÁz9Âd¿ê)ù·OâúH&9L+B¤Võäç8›†ÿócLòάgÃÏE@óü‚%ÉåÔO•Ö¦‰1IÕ›d’Ô¾çüfÁM ýê%a1¦$Ôó@š£1¦æèΫÖ]bLu—˜ 5Tàóû…UÚ»¡ 0>bø({ð`?’ÐN —^ŸfM¯Óž©†™á©¨@  ™?•”¡,Ò^›¡ÊLAQØ¿¥ ’’˜EbLI¬•¬æ‰·Å¬Ö¬Q.0¨KÈpKØ/"‡,ضà´Óþ¿îG†Ãh¤huâ6 €Ú'&´F´XõÏ$ß*i‡„Àã‹ ø¨Æc¹²b;OµÚ@*6ðã‡~o1©Vƒ™O”Â3Yã“â—é‘H0áH‰kÖ¡Cópù¹§\8³8ûÁKøÿ%Äð`Læ¯<¾ #¸’¸Ò—8 Âñf´@oL7NÂ3éŸ4,¨œ`L& „Kk$úQ‘ G$’â˜P!)Ž HêIKg:sò\ÅQSdù¡y~%Òä‡&_¥ÕdÖ¦§tžJTN î©*îâ<ͦ®‰1ÕU^žœ $ZbL‰®f®rˆ1U®I¯€²J¸4¶wµ-€+&pKÀ•°!n™@/WÂWØÆ~…œp<25¾ÊxÅ&(ðán+–œ¤yýb 7áæÂž}Ûš%^2' Ð^›“ŠNH1‰1%¤"Ò}Öìúh¤é›O~¬­ƒ~ÄÆ_~š†B0)Q-†a†acºƒ4¾²¥€bI@C„OR^Û=f÷Mx/‚4„½²ÕÒQq†¼š|’ÆCi‡V*ÞŤ¡"Ñ!S:ª¶¹¬Æ$h…àx™„A3ŠUí5áפb˃T›þ>÷ x(èáaY°G}©Zâ•Gý!™ÿ`ù• â‡NO(¿ªc¿I\1‰S(Ol5Ø„Ã$œYíRÓ±Y‹Æ˜T19§ ]zþ8“,°¦BŠ`˜ÌŠ0)(‘Ýì üLNÈ^žó›ÅT:-Г–NF†ýç—ÃP¹Š¬%ùFŒ)ɵüQú*@Œ©¾úòìMS€SӤ煩@ («P n–'‰& JØ–sb?襥÷ÀñuN2UpQþ„ ¤LXÈ®ø;Ël˜ÞZ“²â0»)R€SŠ*+Y%Æ”JlT^ÙÓèR`¿á°Få‚×ɇh…Á°ŸÃ°Ìµq¼d¢KÊ‹`¿@!81¼$l‚œÌÉÀ%]!êKqæi´øVÚ'Ð%m«r<_TÀ¯@m1&=¿I€?0ñØÎÅÞ¯$îÑxX²¡,΀ î€_y~î9¿æûÁà`lÈNÙ#|’^T¾2Y l›“çüz¤rž »€_iqQúg⿯€ÅW„A ^†wl£± ^ƒ=&u$’6~‰Œ&ˆ¡ü<ÐÃ$ò_¢,ŒI.*ð N+DŽ!òcLÖÝ­{w)¯dXq%‰%'ÿ/u†„ã#0&¿³€•8 %RDR#%1&QLtƶÀaøh†ç“>ÄãI*CÎÍN@/*âàHþókÝáºr Ù#1ædÖ¦\T[…ÿüRjbLÕüù[*@¡1¦F¨Ìk4AbLM—¤+ ¬’ KxL’Xrò޶/²´Šß&ødRLÀžä+¾¨@ösm° mpçì—%l¢Ęš(~/MŒ)‡•^i‘áo©uí×1¦mïO¬ô¬üQí@’‰Ã°Ì5 JâÏF‚ÇIù„‘9áGôøÌ)Á%]!ê¤5ŠÛ0màêÐPñQ|2II4ZbÒ Æü5CÚbL~oLŠAȆØÔ…»»Çèn5l_Ô*ìû=~Ž_á' xÎoJ¨ÄƒÚþeÌÿzQÅ5„™ÀÏ£ 䄞_ýKyü øK¤ À"R¢fÔ-¯™)ÐV¥5*™„âIÄ1õæA‚üq°þÜωç&è¹>z(Ck°ä†Š8F)@!üðQQ? aqë)°¼RdáŠÌâ8”Pr¤¸&ò{YÓ™dœMÏéù­ ÊbÊaæÏUd)¸ðFf1õ¢ÒçˆòZ"Ïù¥txéiå'xaC~e_ðMÝã?¿'·IþŸÐS’k‡y£õU€S}õåÙ›¦1¦¦IÏ S V /0IØ¢—Kx?°·]¾¨ {ð>™°G¶Å9SWäO¨@*sÈD©¬ÎôdšSzê* 9%Æ”…Zl\2ÑSã* WW sÈÄaXæš‚pÿ€û%pKx—òM~m2H $'Pöà0l+J’9%X ¤+€æ'­QÉf’f WLJ/I+EÂΤ‰ùkž5ĘÀ÷ÀT6Ô‚Žmq©"îR$ª”Éa(´ ÑĘü˜Äµ‰çü¦Êù#1©wÁ•Äý ®®yPŒÉôX#Žd<SX‰ôHœÜãý¥yµÍ+S(Lö…JU¯€@“8cªþä991¦œT4‹I ÆÄf‘Qˆ1e´bY,*@¨@Îð;d¢€œ7‰ŸSDæ%TbLl å(艮˜Ê‘Ç–£€ß!‡aåèÇc© T ± ÔcRw#JЬl“N€~à)ßb¿crBBQDcLŸ+þó«Ô&<$WÑkIfô%¨ä_ÞcBnM*’1Æ„ƒ=%Òü‹‡'¨æo&±­‚˧ø#øåSŠZ•Z:C¼V²2I‰1U¦E² 1¦,Ô"Ë 1&6 *@¨È¢~‡LôÅzNV™ˆ1%«>²žbLY¯áš—Ï㉮˜j®0OXPÀï‰Ã0¶*@¨È„õÀ˜ Œ¸;  A…—„@ô#÷Á»îîG1 ua¢{$¾•ü\b0yÎoÖ‰òFz݃ éE5º“DªŸL¦7&Í¿‡…’ð[%ßQÂ0™ T&š A¨hĘ$4/C¨1¦V ³T ˆ1ÕBEžƒ P*@¨€é‰>XAÙË1¦ìÕi’KDŒ)ɵ“ȼy2ÑS"k)C™22q–¡ŠeQ¨ 9W N“F¬&Aâ€ûèB¾GŽ”d|…wÀFê!IÀ ý9Î _ùϯ*ŸälâI1&q³„¯ô<ø;;tè G*ÆdfF*œS€'9¹¿D ]É•»ÊyKcñ© å*@Œ©\Åx<ÈŽƲS—,I‘Ä˜Ø ¨@†€Esêí?y?CEbQ¨@ ˜™è  !ùÓ¸ cŠ««…Ęj¡bÞΡ™èŠ)oUß„òš™8 kB4ù’o¼tß5MÎ/Ob(À¶C$R¤@­0&¸,òDMÂGñc$þŠÌo )–„@;yöèGù•çÌžƒýç— G…ƒñ.{<±dîñ Å Ì¿:j2³d)‘騿¨ T ˆ1U B2¢1¦ŒT$‹áU€ÛÈSúÄíjß¶ ‰E¡Õ) ™è :ùë¸ cŠ««…Ęj¡bÞΡ™èŠ)oUßœòŠC&Ú£~“¯:jÝw¦nêÔäLðòT †l«1Dâ!E Ô cJ ¬ê{©)y#%›šru^” P*ˆ1e Y*P¡Ę*Ž?KºĘ’^CÌ(CbLeˆÅCó¡€8d¢€|ÔvóKIŒ©ùu§cÊSm×°¬pÈDWL5Ô“§ŠR@2q–ËVB4$—ÕžÊB³­¦²Úššé cLñ­Y/¸€jnšUp^— P*P+ˆ1ÕJIž‡ ¤ObLé«3æ8–ù˜ž}öÙN‘¯Ÿüä'ÿþïÿ} ¿Í’Çü÷¾÷½è|òÉ»wïŽõjöAïï3¤#½15»Ru},w‹nÿÇsLÉÿHÂû„›N;4á9ŒÎôG-Dƒ»[ªÚ]v3KŒ)»u›Ä’cJb­¤ O[¶¾vû=W¤ £ÌbúøôÓOû_}AúËÁT¢À¥}ÿ¿&QÉ/ù*ÐXz=úÍÛŸ<´±×äÕÒ­À ›útëÕ¦âtƒ¹/_aÆ͘1£üßñT  `èÞ§O¼§#»ÌeĘØ.¨@~ ƔߺÏxÉó…1]tÑEW^Ócüä™iÒÌq“f^qõ N< Hc'Ò˜‰3Ý4cÌD#M˜1ÚHÏ>7]Ó¨ç¦[i¼™¦?m¤‘FŒ›¦©uÜ´Ö±ÅiÌ´gœôü3cžÚHÃÇq°‘>QSËð‰-ÊÓS[žš8è© N:a ‘ `§ç éÉç6Rÿ'Ækzè‰ñ=||¼“ÿ@!ëÝoðÿó÷ÿãþGÇÒq÷wŸ•ÆJúî÷¾Ô#ù=Áûï¿ÄQÇþê‚ßã‘#ù¹e¢ZËyüÆÛ%Ú} ¤ÛûÞ÷ý?TûCO¨}à³fu€Å½Ÿv}#Æ;ýžÕéyú½ Ïß×iG÷Ô³á½\Pçسi·Ô§y{³Ð~¬¸Ó,¢ï*ê¸|½–Ù_ýË÷¾Ù ·ßÿ˜ÑM¡Ë2º©swîn iQyÏ1¦¼·€Æ–ŸScõÎÆÕ¶mÛ†áb·‹.åp1šäRÀÒ¹sg46ŽR’\MuÊ ½gžsz›5kÖÔé<-¨‰ ~zÒ©HDj¢gN™·<Ôr`åÖÆî"· óÇÐýÄ“NýÓU7aO’)½ÕMŒ)½uÇœSj ÆT­‚ü}BÈÆôРÇvîýÄNüé¡ýúü w¼s@Ò[’ÞFúéM3íùx»‘¶íÞ¯éÝû­Ôn¥­NúhkûG[w}´ÅH›w~ä¦_ßùáë;œ´iLJNzëÃ׬ô¤oÒ†7?ذ]Òû¯JÚöþz#­Ûöþº7ÞCzEÒV+­Õ´åÝ—´fó»šVo~wõëû$­Ò´i_[!í]ùZ!­xmïŠNZ¾ñ+m°Ò2M¯¾³ÔIo/}õí—Ö;iÉú·­´îíÅëöhzñ•=š^xeÏ k‘v#-’ô²•iÁšvMó×´Ï_í¤y«Ûç­Þ5o••æjjÛ5ÇM³Ûv¶NYúµøæì•;giZ±s¦•vHš±|Ç¡‡|ŒÉžIé8fêBÔ#9hšJh›¼l¡©\ã-þÎpÇ^§Àtô±Ç™¡ö„}`@hö{»´ßûHû=ÔÝôuE½\xçïÜœž-¬O³;´åVòöfÚ•i?æïÄŠz0³û*î»ü½–vYÚ_IgõƒýÀcãÐMI²:«VÒžêúÛ¢0)ÿ-bLI©‰|äƒS>깆¥´¦ŽÓ®Áñk¨,OåS@¦Gž‹Ævû=ƒ8PÉU¡÷¬sºb¶aѪ7~D’)WuŸ¶Â]:ñ¤Ó–¿Ú¾|}{§Ÿ“dJ[ý5#¿ žykkkëÒ¥K`AKÎRêo±Ñ±cGœï%Õ QÓqM½µ-cw‘Žc.ËSÀf˜N“¡{Ë“cH2•'_’Ž&Æ”¤Ú`^¨@c ÆÔX½yµ†)?ŒiàcJ)y6`§ÐƘb¢K0áoC*0dŠ˜lC¾Ë0ù&‡aÚh0LÀä2LÀ›a*`L[Þ[Á0m®˜a²­þ¶á¿À0m(Í0U…1 °€b†©ÝË0­*0L€0¦b8`æòt`L˜IùñO:Žº“ÅxÞ¢qÉ•$™Ö‹¦ûBÀ˜®»±·¿Wt¸¥wÀýÒÑÇâ &8ƒØÍ€~Ï 6+a˜<¤fPÿ¦€¦2L«‚0&å2ý½™Ÿa‘1)…€`šð¥I^c—Š1ÁSaò`LËwcJПS‚*#Y!Æ”ƒJ®aÁ0a¸8cÑË.ÖPUž*Pa˜' kcúÜM’)/E ½k·¼'U¿°m뎤O¦¼Ô~ºÊ) ÓŠWw[muó»K×í"É”®l|n›2ó¶iÓ&IA&õë×/Z¡—pŒÒKØsÈ!‡4^· \±èÖÆî"5Ê"+`1L¿8ͺ"É”ÚFBŒ)µUÇŒSª ÆTµ„7“Ãn=aQ7hD޳z?¿ç¹¢ß+t}Žû%7næ›h ¹˜N˜LR³ÏV²Ÿ·5¡[“T~,9ÇSÕ ÓžàIÒˆ+&ÇÜ|7æ¼ÕíóVï2]1®ãvaLÅ=•xŒÆtö¹ÝÌ> Û$™šóß'ÆÔÝózUbLy­ù²Êí2LkÙ.ÞÔóÖ²N«c„Ö°áÆ–žkù÷TVŠø¿ÒAoÉ`.ñÏ=Æ#ŠéÏFDÆ`×Ä·bݬÇK¦G‡x6¹­ßÀsÏ¿ð˯¾*+ò /Øn#ì”uÂì>*yÑT?×¢™Á0i0wùæÃ|ìò•«Jêà9@Ÿ+aà÷4`QÌ|êDÛ(÷¿³¦äŸXVæ+è ¤Œx‰;¾ê¡€0Lmwk[Å3£x(Ä|Úê‹kvÿ³S&M™VîÕÍnJýß ›S%ÒÞ°Ó3ß"ÇÔ»—.·D<^¨ßÌ0# EÒLïJØ–;†C‡€=8RÛ’bLدm Ûr¤d[Ð(­Dü\)¾â+࿵դ»ÐQ þò¨J³Ã—»^ž¡Žt: 6ÇEr¼|•êDüzᑵR@¦è¡ûÃ>ùÔ3|òI­.ÊóÔ[bLõV˜ç§ÉU€Srë†9«JÜaL÷=ühÁ¯~•\Ûü}ý-ŒI‰%ÃN_ –¶ìZòsK›w~Š.‚(9V|ï%XôÕ–¿a{‘û¥W‹&ÛýÒ{’0e,î—"<0ÉÊH¿¿0Ùþ´1‰ã&ÀH®ˆazõõ\²ôÕ·5ÓK@—$­³Òâu{4© l¼€´Ö"‚!;0Sd,¹X~˜À0!=#Aå¦@Œ „GU»ZüXgRÌÉbϵTJ÷Ë{”K2áAÚœ )9,Íf±0?âyêÆŠéËû÷„ # Ëäܳž¬ZæúÆtC¯¢^Ñ@6ÑŽ?ý¨cŽó@Kþn0]Bè£—Ìøqf¿gõx.²ÈkvtÀd»"óL& ‰‰i+ÝZ[—éÇ´ÿ8š*òÃTÃ4·à:Îò'“ºb2ÃÉE`LðÌ”ë–ݬÂcj–òù¼.1¦|Ö{9¥v¦׺ÃEð5íµ.âN‡ábe$f5P¢QŒµþ¶j¼bˆy-Sa˜V½¶'°­¢§’njÑêJH&Ôš¨´(ÁSdÒÃì¯8ÀÖž »Þ½tL‰x˜GºÎ¼¡yh›A“þMú1cÂNuÔ$¬R Æ„3€ž4û@óŽSóÑZæ›Jô­­šîÂÕ˜Õ-q=}ˆt#r’N @1&ívpKõ@"óÍ)T†©äнÿcÏ’dJ` †e‰SŠ*‹Y¥5V€Såé’¢@þ0¦þz})‰G%;Ý×È9çv •‰¥üÐR‘Ë%›[rí÷‘èRˆï%/½ä`2é¥`L>€Ékéw¦:aZüÊžò&× `&ug2ßrgb§UENM `—Æ’† X€bLJÌ´½›˜Éï©éfRŽ´ý0훀Cav)Ðc¸¬<’)ÌX‚™s©¦H°G׌â+6&Y3mBK{ô·²ÎU®%=¥¹ì,>ü””^6ÙùÆtõ ½´,l¸ñ1GŽŸvÔÑÇiïÖ VLmFÓKa®æbLïÍ s/Wä[n£eW3û4À„ÿQÇT3ÄT ³b?L† =UcZ±3°§ ôÆDŒ©9ÿÊËs†Àæöç5ôF­®±ÑŒ¨g-}ý‡e’LÒ!HoãéjÐ0Ðÿ˜t£ Vzþn°þêÏÍ>GþÔžz÷Ô8> DåwÈd¶.ó/o¶.O#D6ôTfï$Î6¤=Ä«bÞ x˜*  S¨ÉÖŘÐV®zë¸ËóÉ„~Éì½¥› Ę´ "q’ðöYï™7ô` bÊR@ôþ rB¹‰VÒ%â%{tȤñæt†™K¸ÈÉÌž÷Öæ‡³îbA™Ý…gT#(jÙëË]ÏB+l»f·Ã‰Ód¶¥dæJ¦øC÷%ɔ̚ È1¦ÔT3Jj®1¦šKÊ&CÜaL÷öâ·Çë|ëÍS©Çõ±d8) –bIR!j’Á-½Uˆ$A”L$Eaã?.8r\±ï¥ôR€û¥!ä¬dÞreL®É†ÿõNªÐ “Œ ¾— iM{‘¦Õí —$iT&30“—a²é%e˜,Œi²å)‚aJ 7&™IynÚ 6áQðÛ_äŠÉx¢F-€·ø}9$“ç9YçÖež“ñ€-Çèê1Y¤óÈ:u"È#™Ôóì‘)i™ƒ–‹òHožM{KY[Fû5¼}XÓõ½(%70"*cò,s %¿¿%·÷‹¦6Kú^²Ú¶Ý¼ ~æÜ¾®l€©'LÑäLrážäŠÜÈ}WÁ‡\D,9?ÄþêPñÆÂ0…•#ÆTÿI§"ÆT†X<´jˆ1U-a†O† ÃÅÙ/®5†‹A®˜\¶cu.–E2 À$c9Óש ²¾ÈxO{22ÄÐ;Ù“™âB‚¡˜KÏ^ÁÏu1ºYý§Õʸ"Î&¾Udä©™D¡äÒj~FõºÂˆíÙ?j5ëñ| ƒ[üDx3Ú ~…¯Äâh’‚2h1=g0ÕÓ²ÈEýlÄo'«òà0LO[ “çÙÄÊ%NSáÙÄÂ˜à—·÷eLƒ xBe©Úø(„Šh+ÇCaSù‰I‡(d 58Þl-øè?¿jåùJRp9¹¢Fèµ¥NÅ“4oiuÒ¼=fËt=ï†^.é'Ø^µ3Ï|iSY$“ô¨tyÞ4A"©M©;H*–~©VÏŸE üòsóOŠ?<ޚϞ¸œÇiÎŒ#=W|Œ•çYù§ë?×Ó,qÁ¤ahïgþµIWù÷äÏUƒaŠÛVç·½YÉT%ÆT¿^šÍ 20ó&÷üße"éÐdX¢Ý‘ƒwéÐÿȈHçåð­ÜeŒ[êJ0W¦j*~UÁ­­¬îÂ3ª‘q‹ÜL}„i“Á¾ $ªÍnG›®D*šDÆ2é0LeÝ2Š>™Rш1¥¢š˜I*Pˆ1ÕEVž´ù äczhˆaÿ°àEÉŽwÏCƒ1Yz7’gÃA””UòºY*KV¼$´äã–Œ€q6·€.Åt¼TVIâ+Åt¿Th©ÙSh ¹r0­‚ï¥BB`&ÀdEhZ±óicÚ1s…× “:dJ”7&g&eºÁ0¹«‚ÄN šåZF–;ۓŰKÁåÕï/½!ft9L|tèÐÏÃò’fa—éxu’)xéÏô+™nöì÷ï1§hå·æÙLóºÙo~Ç™¡cºêú^è d’Ä´7ZÇcêhö„Þn0ÈÕ\Ü@™>^Ó<.’^ ‘é„‹0m|'` tÂdÄTOr¡0•a „/•¼œ»j—$£Ë²bÉ)piaLCÆEЖôÆ” $1¦UF²BŒ)•\Y¦ á¢„Îï8æp1>ɤã48[s\‡~bÔÇ Ûbu“ê${„KP¼FMt¿I†ˆæàSL>²'ð´r•è+"KþLŠíG²¤lŠƒåºøJ1&ëʳ8ŒIWÏ›pƒDA‘‘U”WmTz~†ðŸA/gêé©QOe´xUÖÒð«†ÉllÅ ‹øãÑÆÖ뎇cF—ƒ泉È%jˆ†ÑÁ‘T¤¶"GÔL("C9Æl-8‰ Gžó«Pþ¯¤ ð’ a#†ImR5x&OlÕZ;ØN×óŽzÅ —×Þ…(D®ôlpÆ<}ɦΈ]N°Ù’ERQÿAùkˆE_ªÕÿg‘¿’4Q^H5Ï“lüÿ‚ÿ1Vš“¢úO÷4Kyà•ƒ%Ÿê»K®.'‰ŸYRe˜L´Wž%£ÛêÜ• ™Nž4eZÉKHÓ’N@^rwÀ†‰&H£•³is5OŽž¤¶½tœœó¿™y«•ò~Gqµ:sÏSñ­-~wNÀì.䮤£Õ\o"‚YËô¬çîàï.Ò5Èakz‘¦ØC÷û“djz–Î1¦Òñ*Uˆ1eµfs_®ÜaLw?48Er±$|{ö¯»°ÍóÅñà*±Ja¸RX*ĉûÀïoÉÏ-¹A”bx]²' e®P“]zwµß÷’mÝ7è%¯û%Y2+–ìXKHïXiƒeí0,vzÛ±÷Wàé•=/¬E*raâqÂT \‘&øa²¢È•å„ “¸6±1¦oD0L‰òÆäIyã=x¦‘Ù·Õ¥&à€Y ÊÕEñH&ÓJ$¤‰É cR LÌ)¤“t2qlNÛ©UFžÆå¥3þr]sõ×Mçɹï½k#0¦+¯ëÑ+c:òèŽA=áèý4‰{93Åw5g;^*Ã÷R½+„œÛ³vkn‡EÎöÓ S¡3øKoÌâ^«ˆa*vŒé> c ¥-‰1ÕæÏP“³cª‰Œäão„/×s§9\,I2aȧ»¬ü†¼¦ýU!‘{F˜2ðSÐÄÃ"˜žœä´æÏ…°—=§Õ±¥iò\Q‡¦:ŽH&ûâ9¿ønÑlûG­ú[ÕD[¾’A¯™a¡XÄàIÕòdbRz¼ÿ ~õ´"<lɆiM¯òïà0LÃÝXr³ÄÂ÷lâqÅä4¶—wßü—þ%}2)Æ„<‹ã%)YÃaAÄΧfB))öHõÅÁ˜Ä9–ÿüfmê¶´+yÒG%l´ýËÙµA)„rö¦VÌ´<ï˜w†©.éÄ@ZV×ÀkéÔ^‹ã“Ƀ1A:é 4rd4ÿG¢³ÿψ1yº©²ÿc¬Ô¯ß“§YJÏ#]4a³d[ÖŒGjšNæJÑK^ßrÅ[€W9¯K¹õo{pLõÀ0 &¨iM»2LÊ_ÚQäÚ=®ã"œ0‰Ç8ôT‚1EЖĘù—)q-bL ªŒd…S*¹¬"*Ã$Ïò@¡O þèÊ•X \WL¸—9ÃÅK® ™üŒŽ 8:®«¼gà'e< S®Xv1ü I!9FÌ6Ø/ŽLÄÅ…l/2@‡£þÓªtW”o&ðgוK#cx†Á’m¼ûG­ø‰üV|ð˜5ˆÂrIdùJ\òÑ" ÈuÍQ±‰1yÎàWOÎì`Ëåje †éÑCˆNÎ _hû¶T8@ÛM·— ™<?e>Tm݃š’¦"Ð’ì×VäiEE–ÊUšD+ÐÐ~­PÏWP°$%lp9T«<éˆÝQ.!­-Y*W·¤ÂúhzíõWFW#¾QÛ6Ù¥&bT‚ µ?yÑk?øÑÑËW®Šèë<“y¤þ¡›þcòüYp0ZªFëNz!¿7&Ç•Eàc¬8RŠÎì Ìf)ûÑT$øhZ©‰1•uã‹>X&gÎÍl«®7kA{-äe5¤­Î\¶íØN%|2bLr»”ö`vør"ÆTÃê®É©<óV“<ó$5Q êÖVÜ]H¤‚jº‹@ŒIî².T†1Š+¡£Ð!±ŒO´ÈĘjRûy8‰0L…¡»¬–wcß숅ÈãAC÷{ZFdJl³!Ɣتaƨ@Ý ÆTw‰yæ(PcÂèÙ|5'›5ºêE]ÔïÁ®Ï¤÷Á!ic|¿éü«®†y%–lD)TŠÀ•‰%´äŒ#ÍPqbèûÀ5ç?1bJÏ>÷Í~éUE—o|çýCf-yUó(ºtùu·˜iÑêí˜Uô8^²#ÇYþ…«¶Ýxë=&½´ mÛ ·ÞcZú[†OD‚¥_Ò’õo· ›ˆäñ½à~)Fü¸…†ùßãÉJ„ ˜” €I˜€ê1¦¿~ñ~šgèit&Å?ûÖgØÊ?[4nÑsÚvÊdñèù[ž·eÔ¼ÍH#çn;02ÂûËo.‰"™§nÍéxäÕ<Ù˜‡•)`™…×)xÙ/f-ñ¥äß#Fý­9u‹ _Õ%Óúõn 5?¿1Ýìé Í>pøè©@èbú–sz¿â q½ÿrŸv}CGMé}û}ó–nTsS殼ê†[§ÌYá Žyåõ·Îyiƒôx@—zö¹wñËoJw縗‹ŒŒ9ýÅõ—]{‹Ó¡—B¼Ê½Ùj+™“Ç™\„&ûÏõÇ+{: “‹`bOt¹¹m»\†i§b—³Vî´RÁiœ\Â!ܽÕ`L›æÕ¼Ùð„¡ cbãh¤Ę©vâ¯e0L^°`äÜ-Öpñ©·Ù鮫124‡‹Ï½ðFa¸hßÈt¸F2a8ç1ó Î0®3±"jÈ$qM¡cŒ[ûbè5Yɵ[,\òÞQ/˜»E&p!ÏÌ~ýéY¯cìmw5Öc騹›GÎÙ¬®˜„`CtøI 7F“Lª‰_ÙÓþYäÿ%j›pó_,—ˆ‰1á<ž™ùÿÒN ‡é_[›%.$ÖßÕ˜ù‰ù—Ì×aû¶Å,¯0Lm÷HOeÛk´O—÷ŒZƒù+´Õ± ·Ž]°uÌü-ÒV%ʪ,_WLÚV§/}#šd’J÷gO€,ÓŽ‡É‹çøˆ^:fÁy˜WØý[ÄÌ&%pk31Í[‡.Ÿ´x»yw.®Ì™7VV}ˆ]õE·¶âî·6Ô¬éü^» ¹µÉÂѲº ÿ¨FuÀmBX[s.TnB¾šcì÷w;MHÔ·.yö0tÿâËOãH£ “è³Â½£Ö˜‡ÏÜ3šðhýºšdè~×@’Lq´oÂ1Ęš :/I¢1¦„T³Q¾êu[`$›•3•À˜Ä·¿¼0ŬKÊÏF"~Œ©ïýxb™ñ-få"(6ÒøUˆ00*\@l8{¾~OKΖ:ÿúÂÃŽøÉêÍ–ÿ·Ý¯ÀÇ+®¿å°ýD¸¥ŸžtZç_]\ {f.~UfÛl\é›ßþ®bL—]wËÂUÛÅ´o£K½„F1ð7燅 áî‘ÆL[zÆ9]ÍÈqº¦7è%'­{û’«{!©Ï3x\\÷KÅñãdªHS °8  €ÌÀ<˜L§&Õ`Lû¬™µ¥óÂíÕµqËLʸçéRW}ÃLJ§k'‰àúG–œpͤ§gmš¼xû™½§#Ñ{úñ×L:£×tÿd±±úÍÅ%|2Õµ\^¦!ÃÆ‰Ç/Ó¯ƒ—œuË il—<´è¬[¦c$VÔÞ®žtõ Å…Ææ2sx6éÑç¡’Ñåb–…‡•­@¯ï~ÑÁR€ ½gY S•T| õnÙøíñ9Æä·]!6~ï“©aã3ª~Âü p>í“©ìñYUmupçƒo­‰.&ÿÒÖcJùdʪð).×”>ï<ìàš‰ÑEˆžyü&ßÔÕÚÌ%.šø¢ÕÅaæÍš|»Úš|+J­–¡gÞš×vª¾µ¡Þe%€ÜÚdp·¾sÌ[Ûó/½é‡³­îb »‹æU}>®ŒA{ëÚ¯¿²§4Ì$ †îaf³sƒ=wÃ[†.Ÿøâ6§ëeõo§÷šæ<'C÷~$™ÙÒˆ1%²Z˜)*Ј15Df^¤ `Õ$‘̰ì¸\\ë&`(ÓÛy=2Ú€sZÓ}øcº {„Ô÷¾™˜ LN$™¶s'ïdöÖLêe¤°a³J¸R ±¤HZBê?d¬øHâ†~1çßqÿ³~u!¸%Øû-niÓ^!–L£>lùÊ-©×¥i/¬{zÜœqÓ—Š]¬½†iØX cº4lìlÇÆÿêÛ£ŸIü”<5v6’…1]Ý[|/ 3I0&¡—FM]òäèÙ“æ­•àq#§,ÁÝãÏÎ1e é½Áãüô’0…º_²ç4™ñã SÁI!„œ?*SeÓ+o-ÀôX[¤ºbL2“2 “¸{µ#ƒèì›5“rMa&E&‹%>*kþªvL¦ž¨µõN„ºðâ뢣Ë5à_ÉK4W`L—]ssX§‡ýOš‚F¨x»ÁÈÞ^—À'¡¿’v«ýöHw7iö x›3Ãb ÆtsŸ{¥¯Cï×:až K­ÏÍ}æ¹¹ÒËÝqß`KJg*š‰~ŽåÎ<§›I/¡3í%¥—г¡CSsÊüWЛ=ûü‹a²»2thèÍFNE'¶gÖÒ-‡þðHteÒ=>jRëä%Æ´¦ÐÒø9k5sÜœ5B/aLcg­>Jׇmø–9ÑêÊÀh±\ßû‡h'ÜÒ·¾ýÝ ³–ã}æâõèëг]znæ2l€Ô<óWÝ:ýü44{0Lذ¼.¹]æ•ÐÅ À„NÌõ*÷ú7 ˜gœmunx Gß…"ýÛäùko»»èÇЭÝvW z³Cx¶/¾ªçñ'žrþï.0ô9tbèÊðoúyÞï.CØ8°JèÖà¸O<¥ûÖž;ûÀôOÀ˜VíêyçÀ?ìÈ?\qsÇŸžÒóŽÂ0™äe€Ó87äee¦/®ý€‰SƒÿƒÄ˜,xÎ/GŒ)ç @¦£:ÎXô²=\´ aÿpQ 0ÞKܯ*Vä=0—¸bÂp>Mq?Âp±®$k2 ¨-$ f†ið°qaÏ&æn¼D½cºí‰BއG€,㾲ȳÉõ·‘djFsP[oÌd1LçtužÌ~S6Œ µïÄçZ°åº–Å– Ì6ôÂÆ¯O¦ö€BäJ]]ƒ0Êãç¾J’©uŸ¶kzÚªf²¦“N[±a·Þ «í¶* c,ŒiÁVa˜ðÀxñƒ ï|f•N.€G±M¶h«“_Ür4I¦5ŘB`¦83oh6ðP‚µšh90ó†RöÝÍê↷qæ-q¢ê[êÝE»È£â¹ŒY‹z ÊlÞÚØ]$®Ud(Cž¡»f²¦“N‹º  ‰0Ðp¡jq½ÞÄ!\ï'—«oÂî÷/üËð63άÏT³Â“dJV«"Æ”¬ú`n¨@# ÆÔHµy­ú(†ÉQ׉…1!|{ÚÃɉ¤À˜î¸·E©#ÿ¾=ëœ <Š¿†(é~‡Ur½+âJ²,Ì5É ×:a.’K°å+º$Û-Ÿaø‘ÆÍXjrK0äkêôóSÅ´?å6<}Í_ù†mæþ{=#þ–°-îI`ì‡ÿ©1Æ%x—@K ™`쇫˜ù%fÜù]t Ž—`æ·\•¬Ý}×€á°ôcê{f¼´ãÝkzÝ«¿]’ùÁã¬èKz©8x\P®û%Ìß“`’)þé›OÞõÑ‚š§o¯=â¨cÇN]èÁà¤åèìfRºõ›+>± §Öb'˜¶ôM{­³±ˆÐ³¶Þž€5H2Õ§ËMÇY1]zõM½¢´½'GNAS,ÙúûÀ+¯¿µgŸûÐõcB£ió—Ò€N‚ÄuèÐáŠën‘€“ì9e; æ&+&º»›n»§ÓI§aC0&K<Ò*1Ñ›^‚W¹Ë®í­.—dㄟŸúÈð‰èÙ@dÞpëÝøS€ÂìsÏ#Ò³f‚&œ_:´AOM4tz*q¿4{ÙVlã¿óîÃ¥C³z¶—wƒÈDW†íšžý¤CŸÖýÊžâ{iÚâÍ —îì? Üz0`Lx¶Çû° /â Ê ¯c;`òz`2{ª˜Þ˜‚&™«}Sƒèÿ3Gðyý2Qz+ðìV{›p³å–‰)— l[ý"îÑÓ®1é%Ü‘•w—»* 0%jzvÞf.Þ?æe`"‘Û  ÃEL5ñò„ÉQ`ÙΛͥ˜Éa˜žñlã®s²˜Îx²ô`[yïýr÷ª•ã( œ †ãÙÄ!™Ú7°gkœ=¾î…à ÏL6ÃT˜$ñ@!v 9Ë· :3>j_&÷ÉÔrhê\©f0Œ~’iáìÆ<—÷ŽtËØV]˜Éf˜N]þj{Ô[|[”E€h«cl†iÆò·¬pr¶»ñ”à²Z0Ù¢­:hÂø±é3'íØïú7×3¦83oh3VØÁ[¦cò -–Å%tá½(œ\É™7„D̉òM/fÕ·6Ô»‘yè EÍ•áät%€ÀÙÚ]ŒŸ469C>æ$ Ýf²¦S‰ºã9QM¼ƒaÂs_×¾sÀ0!É ~45œ\ÄÐ]H¦û–eCØ´—bó{Ïâ9®d ðt-˜K*@ÊR€SYrñàä)ÐÚÚèØ>Æ„@tžXtÉ+`¬ Æä™è7­ï¹·å̳/(É$ù|)ÁR°G%…N ŽF VI¦üŠ“e¿o³'V4dÒY¿êû=b'Á?~æ²gÆÐ%lÿàGG9Ð’½ÀúGž‡dõÕ‰Ä@L%€•‘VZoL‚.Ip%¼ƒ^Ò€q@—e $Ð’DYÆô„½Î~àx >Kn Pìýš0M‰mD\Â`á–c’ K’""ÇÅ¢—l¯BEî—|¾Lý0ÉÎ8ÓáG5tÑñþi}Ùóøª‚g¦°c*Øÿ‡ñ̸YEœø?·ÛÚŒ4ëIÃ]X?xò«Öì›m'¸fÐâ«-FÕè‚WKjÇUam½*sÚÙ¿¹÷Á±þE<([ cúÓU7EtzOŒ°0¦ˆìÞÏÛζ}ÈOBÆ$VXL›Ô—r¦c9“Δ¶mEôÍ`@—n¼íttOŸcù–³]Ê¡‹ƒ'9$„—rnz{êÂWp¸%$q2‡?:1™Ò³I4Lì‘M’Ùqa½ % ‚ (!ä°Gè¥Þ}aû?;ô<0¡tIøK˜@/a»¾ùÏ<3]Ý/Åïµâ`L›ÿ÷“³TŽT€ P*9Þ¿¨Ãßÿÿ9qÖ²€á¢‹‹_#î°ë‡ÉuóĴׂ±×ç„9Š>éô_wíýW0¬åOR¡À£†»YO†fî—§Ÿ}Oÿ'<ÍæÐØ®d‰˜ú0TëŒéÉå]ïœ_®VÞ'¦mT'òlâ·öI“ûýå=¯üáÿýå%ÿ‡7MW`A¿ßyž SFW(Ä4ôŠ LÆÞÖ“éÀ‹½p›K ÉôµøÆžßÿ§¦œHï?ÿ_ÿßÿX¾¾½ÐS¹kÀÜ™7ë1Sž1Á£Œž¿E¦È®´©À0™Þ¬ChKA¾û½ï¯9ï?§N(f¸ À‡ÅœyC›Áä›Ä’ôۃcת«̼¡‹+cæíøÿÆ*hº1omÁ£h3Hn9ÝÅŸÇüçT ™É´(1tÌtÞ…§ÁÈÓ¬@søÌM}[W?5cÆo½žX†¡;ð&tnVÿfûÑô Ýá²W@=IX„ðãSþ¯GWþoiQ/óù|å퇳e¾`i¨ˆ¡1¦"ñ$+oJ*çÏa,Œ)ÐS’K–7`L·ß;ÈŠà˜^ßwû=ƒ€1™®’¶‹°$åK\Ê$Щ’éhÄÃ*)´$ÖÄŠ=·‚4äéI—]{ R·?\Û<ÌùÓ^Xg¡K¶-Èð‰ˆôü¢uA F}˜íM£>~¥Ð¸%$ì¯$bÝŸ2ÿÁ•Ôº/sÍ×õ¾Ž—`’w a±bûÖ»Z-]²ü-ÁUÉË»oéׂXK0óc6nÍnpKkI ÿŽš {¿—^² ÿñ#ÇEù^Š F2ÅÁ˜À´N1}ãåO¬ú;ÿ0÷¹ ‡µíêSó4dÔŸ~ ×Yëv9æ—^R€IZfRd!fßf,{ ÕN`…lXðê."4äz¤uæQG·jÃŽ=ï}šÆÿ5ó\‚1Ƶ”Þá,aºð÷„¡}  *½¸æMxW’„ÀpxGl8€˜Âh>úÌ$Йˆ'.—ÔÉ\`4Ìi‹Ö‰?9éÜð.}ÝçtësÏàacç\z 0&‡ËDÿgK‹)]Ü:«‹ƒ¿%íâ¤gS.}ÜÈÁë’z’CŸ†® ÿôf­“—ØÓ‘N?&Ó3£[7{ è%ôiݯ¸Y}/Á7|‹@š`B8ËÓJ Dj†©»Œ€,Ë *·ÿ¡3þéžìõíƒL SàÖCÞÜÁN`¢P`À/>wóAË`Ê¥ï¿!d¸è,‡ë­pŠ3t¹ ÕyÞ㯞äGÞ=aôf„U¶'þâçã—ß³àõ~5÷ò„IP`æ–³'ô§nê„EÉkÖ¬Á€pQÛVÿ³ låöéY¯ƒ qš46B,ŒÉFÆÑÞŠžMV Ãðl‚´£Ž:zá#··»çË\þµ›Ð¥_ó߯ǃh¹¶OkÌ“-Ð*f% AW#O¦˜|°0¦'œ¥ügôš6váŽ&ÓO‰ƒKZ‘+5—¼·× ›G=ðÙ¤¿4A¶·ä+ØVásenÿƒŸê<Û*½T˜E)ܵ‰òì¼-²´ÝÔs/¼aûa ñfmDYÕ¶ ŸÖWuÿÚê‰w²­&Z<—²ì¶/xðŠ3ó†fƒÙ6JÁÌmø™3¿ÕÅ-p»¸¡2óväOV=yçžqw'Z±ä÷1sXÅ­ÍØØät­aRϽcøªž[êÖ†î¢ûU¿›²æ%ÛîLÂyȆaC÷Y[:ï;°fÛ¶m:uz~Áꈡ»šÀ0!¸ª,Ä$¾ áŠiÌ‚7†)rè~äÑÇŸÙoöÆ{V쬽‰$õÕ°RŒzå;x¦ÛùÑÜjŒü- ©T€S*«™.(pÈ!‡Ê c ûqê– ¸ ßžqö !ù7|Γ‚|)Ù‘·›ü…ƒa¦Ä¶?fŒ P*@ªS@†‹/E%¶—<hМÖ9›ax ÅJЇ‹`˜N:ùôõ[ß‘{Í»~V]®ùë$*€ÐŒI&Í+H&Œ ®Üñl‚P;0ôm]5jÞfx79þšIbiýºÆ¤w¼áäÄW.ÖW,\º^[û»Ÿ|ùÕWIÔ+cy±dšù]€IKiM¤Ü=(´ê7ZPˆà’2ó†ÉµYO¦Â0ù—ò›‘+QûÃôЩz¤Ï>ÿ"c2³85PÀÓV]€IÏl=Þ^y“¹†Ð™E±¹^‰ %uÐMɺôT†©d[µ¦ë{i[=ðÛj ê¶^§òâÁ˜Ü(„rÅ83oVäz crppôop1(f~íâì»›Aèræ­^5û¼eÞÚË–)zé.pkÓ0[¸µ þêµÿÌì×cÞÚØ]Ä®0Xžþ¡»Lz!™¦Î_mV@]¢cU0&tnxNDÿæ2Lº—W;Mü- ú—Ì\ºô’W½\ –þ‡Ÿ|N¼.á#,ýýŸ/S“ݯìyîo/ëÕwÐKŠ.=ÿâë°úcºڬ¸F*B— Ž—üa㪦—”g* c’Y*ÀL3_»âÉÕŽg¦úaL:Ÿ²díNu~.ÏÒÂyXOÔ6À$«]åqÚö˜µû/ÃÛœ¯¦À·àÕÃ0‘djvÕ„ëÛó¼7FôŠ=3 &«²;@{ÞGœÉ¹Ó@{Á*Áub_*  D ö×Ûïlv}èèlKާ1xs“_ÏÀÿW’eOJÞ`ë ˜4“˜Nùó]ƒJV½„T.Äç‡Éf˜Šý”2LU’Lh ý*IRZ]eù@C ˜ô”ÖCî7–ÛV ¼]¸O@(muå‹ËwoyReµZß_ Æ0饛5ó†{Y=F†õ•4-g¯ç­-Ï-¾µ…uÓÒ‚žOº‡Lšy!™&Ï]]òž¨K£=f Ýí)Ъ†î 3KÙ#Æ”¥ÚdY¨@y c*O/r‡1Ýv×À"7H¦K¤ïà[`L¡I%±¤"Ë}œä¥”ŠX%Ãr+•M,•-ɃY\n)0Zœ3Ø-×ë’‹.Uä¼$>1P1Æ$qÀLo}0#ìïÞï…~5é ìù”S^X³Ã];h-tÀ{U½9S\Ä‚É6"&’L5©µ´œ3¼ÔÞâþPzÂ!OO<üÈcõq×Ãeªc°0PÉh´á€fq§WDg†¡™®³%¥—?ýøŸ²hõ[‹TÑL±Ç ºm”*8B7<—d˜ð\½dÝ;Ÿ}þEûž.y ˜Ó»]ßàáÆäÿ*¼tú½hOr–⣙gK¥=ÉE☊.•t çéÊ|˜6Nç­âtAqŽ©cJ^«cލ ùT`ý˜?x!RÀâ^½&“¦Ls†‹.UàÜX€©Èg§,ð¯¯-É0a¸øæžÿöÅWšóÚŽ~«„g¨Ÿ«V¯>üÇÇÎYözégÃéWÃdx,(É0yb6…ý_"þbõ“"‡g¾ Ûoní7 PõF”%›• êjô±Ôµ¤æ’ jÏ{±°­ P¡a@I®ZìM=oí~y[u—•h«žÐ9ŽU¹àçÒMíx瀩0Û[êÚ[ƒgÞ@¿½4gAàÌ[MF†©Ó¿‰»µÅì.lƒ… ¹Ý…bLíï~ÒÄòVpiŽó+-9?ÙúÆ?9æ¸ ³ÛJÝ5°gùAECw6›Æ·bLלW¤IQ€SRj‚ù¨±¹Ã˜0ã¦t‘ßžÖù|ÿ~k˜‚<'™ˆ’NŸ$ÛÅH4¥¤^vãÁãJAQá"cÃiï œ-yãÄaRÒ*®4·äñYRsÃ8ÇÔ cj]ÛzÈÀC:>ÕQ–´¬hé2º‹¹¡Çìøˆ3ôø ©­= ˆùwÓÔ‚Uo)êa®ª×…Îžà ŽQÊx؈Ã0-Ý°×³Ž°ÆO—€1an7¢W|Óñâ˜Ú†÷½_©N/ª¯+3üåÂRnä"Ð%3`œõ²½Sh å/ÝEº1;Ÿø‡cJÌß…¡T€ T®ÀëÓZa‘‚e€™°!epF8g‹;‡È~¼‹Ç&9F~çÚ&M-. Àä:aò Þ½2†içÞOLÛ9úÅÈ`Œ„1¾Å¶ä\‡»2ôÅ·øIœBñ˜d*°|åªþø˜YK_÷=›sÅë+Ê7„|tàsÑÿü•ä¿£áÐBþ)žýØ©ÿ¬dŠ™º\×õ7·ôà­zÓß›àk>\N$Aw؇a‚¡÷˯ ¸dI­ÄÿxcžÉìE¥‘H¯+mI<6I·Œè¥äEy@bÉô‡Ë{VËß%Ô¸´U+ĪÁÛy¢^F@ Q€1á}ݲ•“þxœ¿½±SJlóÌXÃfÞÆÜ~ã½?ýÞÔÏG¯U¿‘aºÄonn=·6`*ÿÖ“a*ëÖÖ\epuŽó›^Õg`Ë–7Ž>öøñ³ÚÊ4+xcÇ\~€¡;›MõµVÁˆ1U B2¢1¦ŒT$‹áU w¦Û<žÌøS({¤’gÃ`’J“I&ÉÉoÂ7<Ž@¥ïJ‘–Â|,éd ækÌä±îÇ–ü–~¿¿%/·Tçhq1:aLøŸÁ6³ÿ¯û±ž ж3©&|Û¾¿%ôl<ØS²Â|Êq'ž2å› 0YNhì©7'.»Ì¾­5J‘a*)rÞŒ)Â?\˰‰°QEõŠÅ Ó¿iGçÙˆì÷<áÊð$烖üý›Ó³­ÚàrÉû2(`\ ë¸º¡KfFŒ)oÿJ–— P¬* pÒ®¶ê“ {`eÇa2ðQ ꫇öƒ¡Öt8rÀÇÏì* $†‹óìá¢`ÒábQl¯òcÉa¹‡a’*àW7Q2àÊXWø~l`lgô›ÕÆr É4sÉ&÷ÙĈZh“ÁN¿ª`˜ ›ü5ôo"JŠ× üM` VO<øãàŸ¥˜ üDþS|U¯Ì½½ûðT½iÏ—å€Yºõ`˜¤\ ´ É„=Ú*¤‘ %H?ŒîWVz mT¯Ï,’é²N[ åz‹C^Ú~ÚV£¡„ycFƒGÁmqá loì”’Óbæ¤13oëÖ¿1îâŸKGTבaÌRó0(Pý­-“ “´ Žó3ð’iÜÌ•f…ú ÝÙlßlˆ15^s^‘ $EbLI© æ£Æ äcÂ\[„•ßžzÖy%Ìð™ç=ˆ’Ã'9N××ëb³×´HÜ)izÙV$É¢±€dËwÌù6àR’XŠ-E:[ ‰§s@1£ÆV'Œ ˆ’fàrI‡ì0Û,ضÀ|üÃW؆)&Æ„ßÊ|ÊÜÛ SÑ“FÔ B2L5î>3q:`L˜Õèô=5ªÒ½b .3̇\¸’Kì•øÒß³År¹TÔ›Ùãê3®d_GŒ)5‚ P*Pˆ'tqÆBÑ ñØkº¸bÂ6¾’cÂ…dÂpÑzŽp ¦$j¸'–\ ÄA¯Œ~Ía­z`Ò±1F¿Â6!cÊÀ¿BH¦é‹7•|6ñ;ýŠ¿˜Û ÿA‘FÁÿEþJò—‘#Mo(ò_“ÿ¶ñžÙR˜{{Ýñ°Ü9ji®ã/Ü©Ãq„UÂÀPÔ¸´•¤‘ˆÇ&ì= Çã[i$Ø)$ _YR$Óï/íÝVçÚ+[d=^YÁ¡&Üç‚gž€c•°öÆN)m©Þ3o ·,[(;^õ¦± š•çjnmf˜8ÎoVƒ¬ùu…d;cEÉ¡»x¦7¡Þr‡îl65¯¾8'$ÆG%C²©1¦lÖ+Ku0ÓÎ’ÁÀèE½ïpÊYç…6*ÜÍYñ,LR0™ìHÉð¥T‚R²LøÖªÖ°$®°Ãq%ËOx" À•‚bÃÙ–~oL% ®äDVrÍü®³%kÉZ³Œý%iÿu˜'I ¬D‡+&éiÄ6ð­DÙ0 9ꨩd·dͧüôäÙË·«Ÿ-Ǻí„Igß<d˜J ›Ï€1ýÞ]œØÅ jaL½bʬ-—i‡cLþŽ®|r!¡â¼šÓ›UзÔð'Ęòùßd©©Ș°‹«Ë%@•à*F]Èà[|DSö‹ó¼‹»&ñÒÿe‘L2\tï§¶ÃÎÀ¤ÆZsnºb†I½âdÔô?ª4?¾¤IÆÀHO~­¼BÅ/>l¤ ™;â˜ç_ÜõlRµ!DK$„ þA ÿAO„öÿ|ÄMb2Ê_ ò/ã«V ÀÜÛóŽ‡Í€õ¾®Æ™:0¹º2L(št­¦SÚƒÐoÚHrrÛÒåj#©•8ûB)v¹[Õ{d¿à<²²[[œî¢Ü0©É© Žó“SÕçDH¦ÑÓW”eV(—aâãaõ5UÙˆ1U¦E² 1¦,Ô"Ë @î0&Y/–ð-0¦ˆœõ[?Iþ†ç¤Ò.”Ô¯R¸Ù^mù–ý¾V)WòFP²–Å"–R-5 cÒ`˜$¦^jÈG %ì‘Às°÷(í§£Â|JÇŸžkyk¸Ó¸ NÏÛ㉩՛p¥Ð^.!/µË"Æ”ÞÿsN¨hºɤÃE70´8 ÔMõ SÓ‹É $AL?øÑÑl4ŸM<Kņ$yˆPæÞoﯓ²’º´¦~˜XAT ŽÉtÉõÑm5”†é˯¾ŠsE“vj5óf2Li×$'ùsk‹Ó]¤aÊIuç°˜B2˜²ŒC÷,Õ>1¦,Õ&ËBÊS€SyzñèÔ(;Œé¦¿ôW;º‹1EPò«b ɉààÇ’N ‹øæØïÛvÍ ¶ÜÇ€+v: *¹K!1œO\)ÌJª1&t3˜O9¦ÓÉÏ/ÙªK]Í™b2L©é‰›—QÁ˜"z¶‡·0¦v}Á”’pK¡=žÎ××ù},wqIŒW[&bLÍûðÊT€ P,(’É3\4oFd˜²Plj)ƒLæo|6!Ô˜ŠªKF`îíÑç!`*b%É0ÕEqž´R@2ýæâë ÁU ®m5”@†©RíÓú»êgÞÈ0¥´î£omqº 2L)­úœd[H¦Ö)K9tÏLcÊLU² T lˆ1•-ò‡1ÁÛ¹¸;2“ cúåç*cTr#ÊâP¤™ Qr‚Aœd&›R 6äïRÖ]+UÀ¤crH¦Nž²x‹ 01–\::àäV£FôuÀ˜`ŽòP^ïW‚ȬÄ{œAdº¸RF»8bL ø£0 T€ Pt+`‘LAÃE2Lé®×Dæ$Ó¡?:zü¼WM_x6!ÔÈêªq¦`î½áÏyªž SUæéj¡H¦ /¾ÞßVã@ d˜jQé;‡E2U:óF†)}õmä8ìÖ§» ÔêªÏIæ…dzzòRYC÷”6bL)­8f› Ô@bL5‘§H¢¹Ã˜àê<ÂúŽo1‰SO²NWœvÎW"AEÔR”#%°J¢êQɶâ{ÆÀ=ùùI0&!™Ž>á—“_Ü¢G?LIìn™'Á˜B{Ŷ]>faL±ùKO'·ë‹Adæ(Ø¥§&Ɣȿ3E¨H™ ™<ÃE2L)«Âôd×"™?züÜWuHCCHzj¯ÚœÂÜ{ým™£Ù“Nÿõ½ ?"ÑÐ[­îü}ù €d…`¶Õ8P¦ò•ÎÎ/*›y#Ô࿵Åé.xkË@Õç¤B2a¸Î¡{jœS*‘E *@Œ©Báø³¤+?Œ©ÏC ŠÌT ‹Úv ú/Î8×Ü<ò£H%˜¤â(o&¢4s¬õ’ #º½|G~£”4“‡d"Ôô~7IùÆô›K®èô\ìòþÇÆcª¬'ôÂI>“Dfœ^ŽS’þ1Ì  T Å ˜$¦Wd²n’Ld˜ÒPcµÌ£iî%ÃTKey®Z+`’Lq 2Lµ®ôÏ$™â̼‘aJ_‡äؼµÅé.È0e¦êsR“dâÐ=Õ•NŒ)ÕÕÇÌSª ÆT•|üqrÈÆtCŸ‡,ën\6|û‹ÓÏ8@B—LŠÉ$¹Þè?)Ž-¿ÇdcR’©ÿÐÉG}ܪ ;"V».ݰ÷Àg_$·[bΨ0&¸Óèôît"ƒ„¯ôw†¾Þ/Çd§¿C#ÆÔÀ?/E¨ȸB2ýù¾'O:ùôõ[߉.ÂXûÙç.f¼=ÔµxB2‰•wáÒõÑÎx>:ðy]3Ó7X1÷’aj°ì¼\ ÉJ ÃT¼™ü‰LqfÞÈ0e¬È­-NwA†)cUŸ“âÉtﱺ§ºÆ‰1¥ºú˜y*P•Ęª’?N®ù˜®½öÚ|Qò˜2k±9ó¾m÷þdþ§1ŸòƒÃ'ÔÌÚIf®† Vþ‚¿HœW]ßËcü„¨b2ÿrÌ T Ù €d"ÃÔìJÈËõg¼ðô?þË7ïi2Ly©r£œ0÷2–\ë=EÉä˜òôZd˜ÒX³õË3fÞ;üÇÑ3od˜ê§Ï|Þÿáª_Æ0©M¬^º® l™ùôÑÿøŸNÏ¡{]u®ëɉ1ÕU^žœ $ZbL‰®f®rò…1ùuŠ–ñ[*¨@b1¦ŸïûJ'úaª¼Gä/Dóæ? câ¿™ P*@€çúabóh€»>Z0xùšûêȈöF?L ¨ˆf]bÏ{ŸFT=U4«^x]¿ï~øYômñ˯¾¢nTÀTΣ' è=› ¦×wöÜ×™·¶lV.K– ûÛŸþ+rèžÞæ@Œ)½uÇœSj ÆT­‚ü}B ÆôQÌÕ,BƒH,ÆôÒŽkkë°ñíI‚0–\B»á„e‹Sƒû“:]ŽSÂþXÌ T Y „‘LŒ%—¬zJyn€1áÙdÝžáa£2L)¯áÒÙ#™È0•ÖŽG4V0’‰~˜[iºZÉD†)MYV^{}çàƒxk+K3œ&– ;xI‡¿m\ˆ{_àèC÷ä×&1¦ä×sHê¥1¦z)Ëó6YbLʨ@Ù $c‚+¦'WÿLã7æŸO!ÃÔä¾6=—'ÆT'®¨Á§%Æ”žÿsJ¨hŽ~’‰ Ssj"»Wýè¯ÛÚÚoß÷ÉšÏ>ðZACHvk¾¨d~s/¦œT}êŠé'™È0¥®œá@’‰ Sƒk¡¡—³1&\‘·¶†Ê΋5L·ÖœzûÁ}ÛþöÅW~’‰C÷†ÕC5"ÆTzü-H·ĘÒ]Ì}¨ĘÊFXlŠæå¨@21&qÅ$iÛûÍù2L¼ ÄW€Sûœ ²DŒ)~›ç‘T€ PÜ*`’Ld˜rÛ SpÉDCHcdOÈULs/¦„T ³¨€I2‘ab#‰£€‡d"ÃG´ãbL’‰·¶×i^³¾wCÛçöûKý²ÓC2qèž––BŒ)-5Å|RÚ+@Œ©öšòŒ‰P€1&*P¶ ĘÔ“`LpÈ„FæSÈ0%¢¯MO&ˆ1UÀ %ð'ĘÒóŸcN© ÍT@H&2Lͬƒ¬\»Çì›ömŠ(’L4„d¥ÎË(‡L4ô–!m’B2‘aj’ü©¼¬’Ld˜RYeeÚÀ˜ð;ÞÚÊ'GÑ]YtG÷í‹&{²ôÁ››&wï¨;•dâÐ=9uW2'ĘJJĨ@f Ɣ٪Í{ÁòŽ1á‘ÓiÓ[mÛóqô1ü6K  ºQéÑ%Ú÷ágIë9LWLê ™Ä4 gR’VY ÏÏ{ý5ºýoÙµÿÝû³ô¯OWYÞzçÀÆ·>ŒÎó®½0Ýð–ÆìQ*@¨@BÀÄ4ø’„d†ÙH¯‡ <¤dæÑÒh)©RVøàãÏ¿üŠÔ¬Vo¦ÊõÁÇe[ÍTÖ¿0œy«¿ÆÉ¸B1Æ„<ñÖ–ŒŠa.ÊPþ–LVÉüåú1-KîaîÁÔ"‡îeˆ›€C‰1% ˜*Ð$ˆ15Ix^¶Þ äcª·¾Œ)}E`Žó­€ø[oLÂ3ÍêÑï¯Ok…0؉{Ûe?M`›° ä[¿”žS *‰Y¤uR€S„åi›­1¦fׯOªVÀïŠÉtÈTõéy*@¨ T€ P*@¨@¨À•-ák¼QÚÿ×ýØÆ¨&l´ïoǶ¼Ë)L‰²R*@¨ T  cJA%1‹%V  É„ õÏP œÓê¡ýÄ'Ó®¶r°ÒK`›p%N²Ę’\;̨¯Ęê«/ÏÞ4ˆ15Mz^˜ ÔD@WLtÈTmy*@¨ T€ P*@J*€õÚ ¶-Àa•d/ 3'LpÎÔc¶µ¬¶{â‹ P*@¨ éP€S:ꉹŒR@X%OK –Ä“€Jp¿„wñØ„ýÀ˜ðQ¾Å‘r°O|%VbL‰­fŒ Ô]bLu—˜hŽĘš£;¯Jj¥Àž—¶íê#I†ª/½uîäT« ñxs“¿ØŸâR1ëT ZbLéo!ĘÒ_‡,¨TbL•*Çß%\bL ¯ f ”¡1¦2Äâ¡T€ P*@¨ T€ ÔSQë¾Ã rõ˜ç¦T€ P*@j¬À¬]–>ÜÃs^€M“»w¬ñÅx:*ˆ1%§.*Í 1¦J•ãï¨@ú Æ”þ:d  ÆÄ†A²£1¦ìÔ%KB¨ T€ P*@R®1¦”W ³O¨ T w ŒîrH`™×iñ³M¹S‡ΰĘÒ_¹Ä˜Ò_‡,¨TbL•*Çß%\bL ¯ f ”¡@ûG ÚÚoÿëï—ñJ¨ T€ P*@¨¨ƒÀ˜fmé\‡ó”T€ P*@¨¨½ðÃŒ ïˆßKØÀûëÓZq¥Ewt— qׄýB5a§Yû ñŒT a cj˜Ôu»1¦ºIËSÄ+@Œ)ñUÄ V¦1¦Êt㯨 T€ P*@¨ T€ PP€1MÝÔ‰Q*@¨ T  €I®„¬â$6„gÂÞWN?~~`?`¦{Û5ÒÜê¡ýà±)Åd&©@€ĘÒß,ˆ1¥¿Y*P©Ę*UŽ¿K¸Ę^AÌV‹ƒ(  T€ P*@¨ T ± cJlÕ0cT€ P*@¨€_8Xiû¢ÉÀ’Äë’€MlÎtÑ„ãñG"aïT• ¤UbLi­¹B¾‰1¥¿Y*P©Ę*UŽ¿K¸Ę^AÌP ­½[ T€ P*@¨ IV€S’k‡y£T€ P*@< ˆË%0LØoL6©&Ù¹«mÀ~ 9‡HØ€‹&JJÒª1¦´Ö\!ßĘÒ_‡,¨TbL•*Çß%\bL ¯ f xØ´oSǧ:"µ®mí÷B¿³{`»eEË!‘C±ýدºO¶– ñE¨ T€ P*@¨h˜ã7Æ r S›¢T€ P*@ªT@\.‰k%lN¼ƒXOKòâ{ ûÅW“€MU^?§ÍT€S3կ͵‰1ÕFGž… ¤QbLi¬5æ9†ĘbˆÄC¨@€+&8dB¦€(UÂ>b[² hiÁ¶€œ”^Âñ€ŸVf‡ P*@¨ T€ P,+†‰S–+˜e£T€ P*!ìm& /„Š“hqØÿL€–*a?5ÉWz$6dË,Jþ Æ”þ:'Æ”þ:d ¨@¥ cªT9þ.á cJx1{T @u¼ä÷À„£Á3µïo'LpË„¤ØÕ¤T€ P*@¨ T€ ÔOWßÒ¶«¤Q¯|I?â«ú]—g¦T€ P*@¨ T  ÖÏ8ø`''ýùßþ©ÃÁ;+ìÁ·|¥JbL©ª.f– ÔTbL5•“'KŽĘ’SÌ ˆ¥€ J8T¢ËÉo*Á6ð­°Mx‡‹&IðÌëÔ<ˆ P*@¨ T€ P*P…¯ìéÿX[‡À„¯ª81J¨ T€ P*@¨@íøüÓƒ=¾~ÆoÂ~|ËWª Æ”ªêbf©@M ÆTS9y²ä(@Œ)9uÁœPX hü8ÀIQ/ðLf{€4aï-+Z°wÙàT€ P*@¨ T ® |ñå§­k¿îǘ°_ÕõÒ<9 T€ P*@¨ e(0·0Æ„ý|¥MbLi«1æ— ÔNbLµÓ’gJ”ĘUÌ (­€xcÃ>I<0á…`•&¿6Yè%øj’=-Wú¤<‚ P*@¨ T€ P*P <Î1ÑS-¤å9¨ T€ P&)ðÄùÇ^Û¤kó²T n :d¢+¦ºé]×cª«¼<9H´Ę]=Ì\å cª\;þ’ P*@¨ T€ P*@¨ð(0~Ãa&ÉDWLl!T€ P*@¨@ºèõƒvJw˜{*¨€ß!]1¥³©cJg½1×T  cª…Š¿øåϰš(ó%e© T€ PŒ+@Œ)ã\¯âuîÜùûÿq¨X£ ;TÁüô¯ÿöÿûÚ×ÿ¡¤É)ĺbN2LH¡f£"S‘e$úé1G™Ö¢h«P‘ ¨Øîjî)eÙSÎßÿ¯}ç_þÕcÐ1 7ßüÎÿºôÒKëUai>/1¦4×óNªS€Suúñ׉U _ÓE]ÔÐc»ö}RH{?Ùµ÷“V:€ôРÇÎ=ÿÂ{ìx§Þz瀕ÞFúéMM{>Þn¤m{öoÛí¤7vï·R»•¶:飭»>Úb¤Í»>Ú¼ÓI¯ïüÐJ;¬´IÓ[¾æ¤^{ëƒoÒ†7?°Òv¤÷_Õ´íýõFZ÷ÆûëÞxOÒ+H[´vë{VÚ‚ôîËFZ³ù]M«7ï[ýº“V½¾ÏJ›¬Ô椽+_+¤¯í]±ÑIË7î]¾ñ嬴ÌHK_}ÇNo#½„´ÞIKÖ¿m¥uVZ¼n“^Ùó¢›^xeÏ k‘v#-Òôòî…FZ°¦]Óü5íóW;iÞêv+­Ú…4WSÛ®9…´³uÊÒ¯ýÃ7g¯Ü‰4KÒŠ3´cæŠ3–ï8ôð£±J ±ÿaÍØŒ3~zÒ©g-ÃóƶmÛ’Ÿaæ P*@¨ T€ P¬*†éÒ«ozdèXoH2eµ–Y.*@¨ yQ€S^jºÆåìÔ©ÓøÉ3Å¥F(Ø¡ÔüôàÀÇ~}þ…ŽÉÉ56mÛó±XšÄÆä˜\ӒڕĢ䘓\C’X‘\ãÑ–ñ¨ÈfT°¹v"ÇH$¶¡ÕH¶aHLBŽ=È5‰%Hm@b»}ÄÜ#†ž‚•Ç6ñXöŸYG :óV[vœ_žqî·÷w-8–ÕÆ1ܸ&›n{f¾×S&NGŒ)ÕÈBPŠ ÆT‘lüQòÈÆPIˆ%M&´ô=jÄ ÒA—bÐK ™”^rF–.ÀÅ0¹H¦*&{*)šar1&gljaL “3TuF«>†©mS0ÆäŒ_mŒ)ˆar‡³.Æä0LƸÖ3ºÅ07cz¹h°»pÍîHŒÉûš“Á0íšÝVÀ˜”ar1&‹aJƆéÄ“N[þj;6ž_°Þ³H2%¿ÿe© T€ P*@¨@&°¦›±l'ƒžC’)“µÌBQ*@¨È‘ĘrTÙµ,*0¦q“fŠ)Ê´C¹+ç?~`À£‚1é‚ù¢¥òå2LîbxÁ˜<–#Y÷®+ÞÅT¤ ÝMŒIW¶Û“± Ý^Í.ëØÕTcROÆäšudQº½"Ý‹1Á|CŒ)~s$Æ_+I²¦1¦¬Õ(Ëã(?ŒiàcŠºX%×ßÒƒ,Œ©Èå’ø^*v¼$cJ“^òLLí>'L!“œ‡+&Ë S€&Ë S9~˜ªd˜Lî¾xØ ŸLÅ®˜Þ pÅäøaJ¢+¦ÒÓòtxc²¦_œ¶bÃn±à1cÊ|’Lìå© T€ P*@¨h‚`˜.»úf8Æã Ösãñd I¦&Ô/I¨ T€ ÔNbLµÓ2WgÆ4vâÌ";”ôC#~cúÕyzìMëÃ63 L%ü0Å`˜c tÅdyc*åŠÉƒ1i‰¿áºb*òÆdcLn¨ ×S!¼†bLv< ËSÇ“`LÅ14v\OoL!!bL¹ê[XX*P¤1&6ˆŒ*;Œ ãÂBT83Bœ½íÀïAÐ’Å-aã ^=}/ùé%#„\LLáäB0!¨\‰XrUùa*Bïc1LŽOÑJ¦x®˜ áä0ðÕpr&¿አƒ` *áŠ)ùAå„aZ¹a·i'À:‰)óH2e´Ûf±¨ T€ P*@¨@R°¦knFLs8C0&¬áø}2%µÎ˜/*@¨ T ¤ĘJJÄ‚Æ4fâ ¯AÊ0? ÆäñÀäFù(Z!£’iWòÆ’« ô٠'WXÙ^­+&ËÊ+¢\»Øq Œ)À¢gc û«cb'Dò«1¦üÖ}ÆKžGŒIýsú7œQ£ÏÓR´À-ÙP¼]ÚRŒ.y襂û%0vB;˜6ºƒNO$ã‚#P_¹€©'LvØckZÀícÇ’s|Û•hQ8¹rý0Á’ã1LÅáällßãƒ4šaòcL3ÝËNNÒ¡‡=eÚìw?üLÓÇŸþ-!¦Ÿýâ´¶»a'WL–ÀvšGY“æ®:üÈc·ly#!¹e6¨ T€ P*@¨Ȱ`˜.Ãô†ŸÂóxòðã£Ï<ó¬Ÿ|’aX4*@¨ T › cÊf½Ö½TÀ˜FO˜á±Cm3ÌO÷? Œ©›å~©ÝJå¦%M09Ö%Ø’$9¥¢h±äJûaŠf˜—à 'WQNÂÉ!»bÚ³x•`âq­z)ÂýÒpKš¶½hÉL^L¥&á]4ÁÏ¿`*HζF®ÅáÙõ&Ú(?L†+&£l2LsÛvÍ)$äÆôŒzcr¦˜L†I0¦㦙Պ6ÓÜÿ­\Ýe˜öxìpÅ$¾²ãoâœU‡ÿø˜ÊH¦ÖÖÖC9$º¤ ,ÀýìWLMÚÚÚºtéó`=Ls‚ßv´_ñ¯Xîµx< T€ P*@¨ å* “e +&w•…íŠÉ~<ÍcÃ; ™N>õŒ²H&óAÛxHÑŒáÑÀóÀ‚=aÏ›6mÚ¿?à9®¬g&a¿ »~ÎÇ™rÛ§T€ P*ˆ1%¢Ò— `LÏ>7Ý´@9ã\ÛÓ}ý=ç¼nžàq3Óë;-»RÁ´0©IGj9Â]FéVÚò.,D¦‘H–¸cèn%ktQ\B&ËúS`˜Ö#–œ?œœQÎ '·p³:}¾mÓQk&¤_8AåŠ\1Ͳl7ŽÕÓÙçvóØà>:ðyúG­sLŒ©ÖŠò|T = cJO]1§e);Œ ãBa’Ʋ1¦`€éåâ@r^'LVå"'L«L'L»Ô©‚c Œ%g•KÆäe˜‚"ÊÁ“Ø Pãg•M2µ··Ã ïÒGgR¤I–8Ëêg˜ 0õyYX¬VÙƒN‚ƒñ?Ç`°-?—vÊ™qÙ£“þ=zôÀG/F “[¯mMíQyq*@¨ T€ P*;,†éZ‹a uÅd{еO¬ÇÇ”A2Ƀ :tèàñ´$.Zu'žDðà Ï/xpÐg <5à£NØÐ¯tI†ÿYF«Pj°Ä’>Ýà·ò|äy™™¢½1ÉÓ„ä´°!}ú§}QoL8^–CàéC–dxže´¼ê›VO‹G$ìÄ™å*âÉ Ï2òQ8'Ù/—ÀµÄ]®e2L|œáߊ P*@¨@Ê Æ”² KJv1yH›Ö(@K÷<4©€åñNä8ÇÆ´1€^òº_’@rûQQ¹÷œ09F"'\!–œ’3íAb rÍ@޵랰/¬ucÉÙ¡6$ÎF ä‹ÒÁ0™“é‡É4Üc kÜĘ’ò·g>¨@ã ÆÔxÍyņ(;Œ ãBú7¬Q㯃F‚(izëÃM…qdibÉïo©(ZœÍ-x]*F—"é¥w5žqˆï¥xî—loÿšt¨Zˆ|\€Ér.ŠdkC£ÈÅsÂdúa’Q¯›œPÊŠßvFŠô´…1}Ãb˜ŠÉ)ÄC?:9Þ˜”a*¬uÞb=„X¶Z{Qq¦+&Á˜ óØ+‹M2a"“õ˜|Ç„»ÐEf´?Æ$Ë‹ñNfÄYô¬Î“<“bRÂ9ÉUÄÉ“éoÉ„–ÔÑN’¡T€ P*@¨ T Xƒa²–XXklìg¤Ãäy<±#ŒãðþÁ±H&Æ„' Y!òÀ"+(Ä««>8àHðFXž¡È‘M…ç1Gže´¨¸´<žÈŠz™ÕðÖò•<þ NÉ95‡È²gž–3ü;Q*@¨HŸĘÒWg‰È10¦Ö±Ó RblºÛ6HYÛÅÜ’µ0Þƒ.ÁýÒv+9ÁãŠÇ…ú÷ €É2%(Àä.q0 É‚öâ¥ì…°;ØN˜¬á½ ü±äÊb˜æ´íüÅé–7&a˜lWLÞÅçĘÂZ61¦Düç™ *Ј15Ev^´þ äc¸ÐC#a€¨éîwùu7Û‘’'}€£™ÌA¤ºñ,8ótÇ”2²ôBK!Ü’ ¦\.ù¹¥²/Ù‘ãœñh‘ï%ð8?½äw¿T<`õ ÷•…«`r'¯¶¢È’óLve?Àd’Û!“ -ù·“ƒ10Lf89s­³²A&€bˆÓ7zz,’I–{¦ìãcL~PIöÈT¾ù-vj:lÃÆ •}¥ÛާXëIÐ^–}ß#¥I&Æ$aãÌ•xpT/}ÖÐPnoLžGAŽÌ%fÜjcÂ1êWɃ1á$ ”ÄQ“ÐNŠ1á+ u‡ýX%""òq†'*@¨ éS€Súê,9¶0¦1ÓL ”Çðd¤ºŠá)Â̈.yÌI?®`BÚòn L;ÑÞ6wq{i'Lvh$—a²&e˜t½:,í—Ë0ÁˆŒé`L! l7ĘÂZ61¦Düç™ *Ј15Ev^´þ äczp°—F2ˆw=`=ãÅàác!ö°CÁGàJ~OK®‡Ïr¸%{a«=ýcPYój¡Kþ°qöÔ9NǦâ~É¡ÑKUij1| ‡ìñ=ôRLL/ÙŒš 0E‘+PüÈÿô¤Ô`Lf,9 qC{P†)b­³ëŠ :‹ãÖQÓ–ÿ ”O&1hÿ£N’€É½zc’=þ©Ô û1&œV~./|”0v²ÅÓºÓ½Sý;F^ P*@¨ T€ P(,†éš›±Ž&ƒa XbñŽeí°×j Æ$'÷´ŒŒŽ.W2¨r)`6”RÒ_™@" `-ÃSŒ®£=æ: ó£F‹ÃÙüAåÄç“yœ×Ò_á+¹› T€ P*Vˆ1¥µæšœo`LOyÞZÄꤩ ^{Óû‘è’7xœA/¸_²ÍF–û%¿&ÓHäF‘³ C>'LÖRv˜Ü}‘&{ï˜{Ü@rKnþšö‚eÇX—aaL¶0&¿&YNŒ)¬Mcjò¿—§MT€SÅç¥ë©@î0¦~ vF„2.,Nø¶Ë¯ºº.”L>Éò¨àT ~•\×Ja¬’5±ë¸Y*ò´TÂÙ’ ©Äá–¢½.yÑ¥bÇK½d9. uå{ ñßvÜ/ÙÃV½wüz)ØýR1˜ï “lÑKî·¶“D‘žŒÉ`˜Þs‚5ø¦6»rCÖ:[®˜ä™2Žœºì?:zË–7Âú3$Ž‘H’eÍ2õÒH¢'˜“¬-–ŸÈ‘fˆ1-È1z6|”¸uúÓ `^Q2ÌåËõ¼)ðÜT€ P*@¨ T „q&;œL K_}ç¥W½®˜ôñäžA#"H¦ŒIŸ ðø Þ[åYCäá_ɰdBBW ؤ5þg-¼@Qò’ÀpòX„pZÒËÉÕõZÒN¾Õ¸r|œáŒ P*@¨@ú Æ”¾:KDŽ1 ó|‘Ê ßáØžÄ U –Bâxñ0/ù I²âÝ´!ⳕ6íksR`¹S˜&{•‚íoU’Ë0Á!ÉÃ0Í]µK’0L³Ýxˆ%'SÃDŒ)¢YcJÄž™ MQ€SSdçEë¯@iŒIfî0ßgúM©Æêr…‹.º¨ß …Cr¾í,£ÆmEIœ'E§0V©€+ÙKTÍdJš¶XÐÒK¯¼õ­ï|W-ø‹Óðï:ôÄFÿGG^qý-‚Ï+DÃFL˜§^—~zÒi­æmºÅLq/ >‘ã.½¶÷¥×ôƤ³JÓKßøöwÅ÷Òb7²ÙÈx|—^úÆ·¾+è’•Üq­gtëÆkŸW"„\,L0IªcÚ·íàŠgëÒX“ ÃÔ¶q·:a’˜Öh ®d¥k&]ØoîŸZd1Lß=Ë™½§Ÿpͤk-ÖµÎÖÃÚÝx`˜·ºO#¦” ™ê](žŸ P*@¨ T€ P4* “óœk,¿ÁãɈ9›ñ`‚ǤnýæNYò¦,ã¾®e1OÎè=}äœÍv¤‰Â <âáñä®Q$SsU’Xr|Q*@¨ ¹V€S®«?²ðî>8·ÿÁÏ? <ȘFOõ¤ ÛSßû-ƒ”ÇðdCKEKâ—­ßñ­ïü‹ÆŒ;ñ§ã#ÞÍeðKÖZv%½„=7÷¹·Øf4WMEf¹yÆãé›ßþ®™ž;Û^ÁnyWï„IƒlÀ*ÑýŠ›‘L€ÉÃ0Á ÓI.ƤϽ1…5GbL쥨@~ ƔߺÏBÉeµ¡zE1‹TcR·êfȧ”ªŒ ãÂÉ3j4È$ïÀ“¶f²ähŠ`•ÜIÞ@7K‚. ·$ÃÍο¾°gŸû'®gŸ{±-Ķq0&%è¢ÿÖ·¿ksKض‚ö££žy®xH/ff™‡#ôÞ‘°pÖJ1|/ =[¸¥bzÉð&ZÌã]²0¦5–— 3‰ã%ÃýR»7~œ‹êœŽºÌ>"(Ûw’DÙñAjLÕbL˜†_t°þ÷0Lh+7îÖ§i'ÖZŠ×÷a²kßÂÔ.ypÑ]#V£úÀ0š·Ñ©ÿøÀÂ;ž^%Ë t­3”´:ìl²ôÐHŸL)ý›3ÛT€ P*@¨ T€ ÔI0L—]s³:ˆÕ8×x<™¶ì-<ž´ÎÙ,'ýǽt 'Ž}åââñdäÜÍÇ_=Éz<±±ˆI'b½è—`’©Nbò´T€ P*@¨@j Æ”šªjxFa&€ Ç×a&`LÞhV©ï}œõ«®–&ÃÆ„!·pK¾£Ë¯/ìuû}0àÛºú]ìJ…Èq¶ï%ØŒf.~U†èb3RzIE‹ÿÔN??Cw$]І©‹#ÀTÒ Ó®¸I0ÁBSNÁšc’Æôën{(Œa¢7¦ˆöMŒ©á~^ $Fú›ªSTf$k ˆãs, Ä >•Ê,aiŒ ¿‘Õ‡â2=ÕòXÓ}-I?b*öÎûZ0j,b’N*&“B=*ù\+©S%ÿ†é]I·-ýöWêpS6WÂ6Þáo©ó¯.üM÷+.¿îõÿ)܆•&·$CÒñ3–]ví-gžÓ­ÓÏOëö‡ËeTzÙµ½1*EêöûË10;})—KgœÓmÌ´—Nøù©8[Ÿ{ùÓ5½Ï8»ë ?;õÐÃúó=`êéOW÷>þg§" zj¸ûë{ß}Û]-‡þð¨»>˜¬oOD:åÐy]¯»ÀÐÜ5`øq'ž‚tK¿q¼tÞï.ÃÇS;_ðoý³ß¹heî—Ì!¯>YÒ+˜ÌApÞ˜¶¯_¿H7ëáD`¦º½,†é¤ÓVnØíxír&a˜Ð°ÊYcÉÝ:tù-C—£a-€€¨šk-îùIJÃäºb²ì ½Vì|zòÒCŠ.W·’ñÄT€ P*@¨ T€ ¤L‹aºúf<Ë㉮¯Ç“Kû¿p÷È5…P×ßyhÜ+x<éûÌ*q;·m0¦¢%¶+&}<éûpkDt¹”‰ÅìR*@¨ YR€S–j³¶eŒI’fÆôÔ¨)¦ʳÞ2HÓUíMEá;,hÉâ–€+ýζÉð[×ÀcnÙ6;KßÛý 1!©ï%Yú~Óm÷t‚‰ÁŽ×aÙŒÆÏ½ßKb!êqë=ÖºèsºÁÛ‘Ã^ÐŽ=–=¨`:ýì®bš8o-Ö'ÀÄ#Qä®éuÖ«ÃâóÇ+{v<ñ”Ž?=E¬<=>ÛH§t¾à—ßì$;…mͱì8À˜ào‰S”S¢ñ'T # ÔÙT•XŒD*n “dM=+iNKcLêÊ f mÛ°q_Ë3°)`e»FäÕìø-L?’®ë}·,_¿õ®€ð‹&+Ô†½j$ òaîéÕw =€–B¾Wÿé[ÿ0ÉcɇœÒ§æiÆ¿ÿéI§.µ]âÇy&ÛÐàxiì‚­clÁBç®}ç\ײ•#Áýc^1gs÷ûö|li!^CñZg±dÊõÍ…§T€ P*@¨ 1°¦›<ËuÔs°K¬g“…[…a¶¤ÞO.`ÌÚ îœƒÇ“AÖÞkš?ÚµxŠUºÉÔ©ãñ·Öü!‹'l´o­‰Ñ¸x T€ P4(ŒéÚÿ~ðÁNLTÀ«À=?)xcR·L®g¦N'ÿäÈ)% Ra&'ؘ~ú‹Óf/yUˆ%~›.—„[²íJë%^‡šÄxdaL÷N{a6¦-Z'6#؉à„I¢s<2|¢0­9ðnº_úF1Ƥ‹ØÅOëä%Æd/Që =Öªu× BÈ`½$˜zÞ1ð÷—ß\$gÓP« 1¦Š;DbLKÇRÔ+@Œ)õU˜ßˆ7¦ €D’ S‹“üF~ ÑéR-$¼1ýåÞ– ßžyö‘þ“lJÅ^”NÒ$1à¼iS‘3Oׯ’£X!á6ím0CI¸÷DêСƒøùX^’Œ8%!N’C,Ù¡‹‘d *Ä’õ±ài CÒ·/½¦7襖áqª®]Ž˜qê{ ˆ’ŒP±1tÌl$¡—„µhI\.áÝöºÐè%M‚.)}Q¬?ÎÂ*ÆÔýÊžW÷ìtéёƄ¸ð& $_ãj’¡­›vÎv!}O¼ä˜ÁãÂÜÆÄ˜¶Þþóà§óɤ¦Û¿ûÿyhp«—^²W9K›±V9Ûª^CVã㨹›1¡¾PAS^Ú;ž"àï*p­³ÊÒùü?Þrû=ûâ«TÿÁ™y*@¨ T€ P*@j®Àûï¿Øa‡M[¸Æ gÇ+˜¬õHÝúÎÅâ }<Ábn<˜ô~b9ÞÁ0áñŒXhqϨ5ö“ NÎuÅ$'“_ܱSÎþÚ—úßüÆËÕXzF`¯y;ç © T€ D)ðÄù5¾KÖt&™yK¨wÖéÈÞ1% u»m ´7ÁÀ4bÂ<@K ”`3»¹^¸%è(²+ýü41!‰ñ_ÉøÜbtHtŽ3Îé Ûø^’%î° c²ãÇY Ú‘`_€­Ç²2X†ËÖ0aÞË–¦—­Q=V&`û±Q3-‰õ¡û=‘`ƒ€ï%1ô`²0¦Vc‚}ç‘g¦cše¯aÐ(rà 1¦Š»bbLKÇRÔ+@Œ)õU˜ßÀƒ’:Q‚[%øT2µ(1ÒXr“'Oö{sJ—®À˜n¿g‡:2?â[kÔÈ!EÂIf¼ábDÉ¡”„UÂÈÒ ®ˆŽbÉeä±oŸ<ÒŠáæ§­HpÖÐÓ&–.»¶÷¥×öVbI6º½@ôÀ•0BºdzZB„8‰†Iý‚>eCK —dx ÄÑâ€+ÁÓ©‚1YCUczâÙYÇŸxÊu½îRâ1ã.¶A{ñ*ô=ü-÷ÛË0~•'¢Ø#¾—0–ÅG8Ì„áìó/¾Žqm^*B—À09þE‹Ð¥Â0× ‹V–ï%?Ìc1nZpD¹ºÝ>ýôÓÎ;zrŒÃÃ9ôR`ÒUάáÎgVÁBðÜ oرäö Ž<·îü;fK¼¨m3a–¤æZghÒí×]u}¯Í;?B"É”®>¹¥T€ P*@¨  P`Û¶mˆˆ1uÁêâÇçñVcŸžµ Ë*†ÏÜdÅ’[ÿöôeoác¯'–ÁbÉáñŒXe1zþÖ‹¶0cH´ke˜Ž>á—CGLÀ³ÉνŸ|ùZ4 zës‰º=,×'»<+ T€ P*@*RÀTN8¬™ˆÓaýxëäˆeð0Hqö:Æ3“»’YÖ3;&8^[À?8¸Cž™„m]ú¾Ü¶+© IlFسÌ6!ÁëX(Xˆn¸åî3Îî*¢ÓÏîz}ï»%‡ÐK’Ô÷’µÁ¿ëÏã£faT?~Θð>mñfO91÷`B¹13WÓØw~uá¥]v³».}‡zc5­6Ę*j…Öˆ1U,HR¯Ÿ¾S_…ù-@KK‹¢K=zôÀGS‹ÒAåð‰H‡¨¦T iaLw  Z#Â>w[£F‡¤ãÅ¢£C&EÂI”’=ÃëIb\+¹ŒÂ`$ô¸%$‰„^‚mÛê{ &!Xˆ$‡¬`GêÿÄxµ a±:ìçþö2ØwÎýÍ¥ð½„A>V­‹¡gp«å{ öˆ›ïˆŽítòÉg^ŒÉZ—î®aðÛeˆ1Uܦ‰1U,HR¯Ÿ¾S_…¹.œ( †ä÷¦TcåÒ0I)€1a\æ ûñíé]Î8ÀüJý9>8ÉáMJÉÙ¶ý* Œœ\L~êÂu~bI†žfV iôó/I„8Ó ¨º]ìõJÖ®A-ï ’ÄÞ§ª§P°bC-é|‡ŠË%IÖô´,À0N3ÇŒ t¼d 8ÑøQœoËŘd2}ÇÆW‚^ß¿uØÐb’é‰1B/™“:a’ÕêëUê4fþ–CWÃT¯ÁôÃ$E#É”ë{ O¨ T€ P*@ÂpH¦y«K>žL[ú¦3)¦Aª`o XoEˆ3íJÏ/ZWdTrmIºâ=ÀrdÅŒ+ gú^’Èq¦ï¥‚1hMÁ¤6 5ý…Ú(Ùð„‹˜ä¡€SÅÿbLKÇRÔ+À§ïÔW! p°½½Ý¯B\Œ)úcúó]ƒüÎt¾Æq€í6I’1p4·]8©¢$èRapé8öT×J#ï’ò¸’Ã-Ù¸R0±dx -¹Ü’I,ÉvIn©€.­ B—¼ãv5 ]2ñ¦Ê0¦m»÷[ÿ<¢€a ˜^ŸÖºzh¿Ï؇¯]m >x³<—fB2=üøhõÀ$“ÕB\³Ÿ=_¯.ÄÐ~Ž‘`µá‡©8^CÃD’)ÝKA¨ T€ P*@j®€L“æ®Ò9ºäÆóxb¯ävVo˳dÄ ¿¦rI&©(\¥äó«äÌÿºÞ•âàJ>–7KÖ`T’ÏÓR8´´Ðžhö$¿¥Ü’Ïå’5À ÉΆx]*ÉæÇñ·}LU“ü§>ÿÔóßÚ»¡mr÷Ž ™üÿ9ìÇ·åöF ™Î:Ë"™-Â0 ”aj³¬g×_k4ÃD’©Ü:âñT€ P*@¨ T ' €d:þ„&ÎYå,®(^_á:aªÃ3ºÜè.‡àÌ¿hlRNª&YÅäDj²êƒ¹¡T€ P*@š €…1 Ÿf‚í ©Óºœ¬£d¤ Óá.w/pKºþÙYíÚBÑ¥âÕìž—¬ØÐAôRÑzuÃýRy½1UÙ@‰1U) NR¬Ÿ¾S\yÌz”yÄ˜Ä ’&]çVŒ;Ÿoî‰Ü~ÛtžTp×).”‚))_Yš¬R¤_%fúU*rûéÕŠ£ááá,¾¾,hÉgŽYôÞërÉË-`ŠF—ª'“Ê:C 0¦âÿ<0-}¸’¸bÂ4:¸%¬–£0·.žý؃Ã"§Ÿ|rò©g<ôè³æg& S°ÐÙFǬ¥å0LŒÝÀ[ T€ P*@¨  lÙòÆÑÇÿܬ6ÿ㉳¾ÂŽs-'0~X!'ìåÚX¨-„ºÄ"Ú“údÚóžwõˆ™1LX1" ¾ð`¥<“®$ñì/ùƪ¯VN¤V« O¨ T€ ¤^`Lƒ‡O ÊáDç0 R^c“e`ZïMEv%'FG´äá–ÜõÏ^—ÄšàÄa.e·#Ç…ÒKÖªuwÉzÅî—<Özcª¸ÑcªX:þ ¤^>}§¾ Y€`r‡1ÝÒo@12y#{ßcòKî Æ’Qrù¤°Ðo‚(EƒJ×JÕàJ!Ä’L.û’™œAª;Nõ°ö·ä‹ç÷·T’[j€Ë¥°©æ¢€UÆ„EwtGÂÚ_L#fÒ±?"öÈ~)aæ°_vâ‡a}•LyÖl'âdËyä@r>#Ã0¹Ž[ãøa"ÃÄ; T€ P*@¨  É4~V[ñ㉓BÌ!…8×õe˜°€dV.HëÇ´Ïd>[ÉJ}§¾ Y€`ò‡1õaÔxjçó=N8eŒèO&{kû+øWt2F™Eaà¼~• ×JžÑg`èâ’±á áá OK~gK:T56Êö·Ô\nÉ3z®9Æ„ÿ™L”c2Óèò·“@˜R¨$3æò&Ó‘0áŽw92z]H¦†Œ²˜6˜ŒUÎÃä.ð.t&ÃÄ[ T€ P*@¨ 5U@H¦q3WЦÀdúˆµã\×Ï“H©ôL"}Ó¹’GbŽ1#Íá­‚Àß52£'ãDjF+–Å¢T€ P*@â+`aLÃ&FØ›,ƒÔYçÛ«ß½N•<&'¿]©Ø–T -¹ö£‚µÈ]fPà–Š—µÛô’….† £—,«+vX©:z‰SüFv$1¦ê5ä¨@ZàÓwZkŽù.¡@î0¦Þ}D GøöԳΠ8 ~ N*€ðÎ$¯Lõ:¾6’R”^¶–±J*nší®aÉï`ÉÀ• £Ò7KÁž–ÀÚ—†–\îÞ¿Ön[¿ý«šcL:Q.“é’ÄëVú‚dÂ~¸_ÂNqÑ„ãñ­ydô_VH¦ûÒVáD‘s&ÇBàÖ臉7*@¨ T€ P*@j¨€Lcf¬ð>ž¯¯xv,9ÇÂQ“XrZ!–ðÏ\òl%ΖÄE®† }§µæ˜ï äcêyÇÃ?0·5Fà|UÌ!©Ï¤ž“C @”Ì®ÈÁ’+KªÖåoÆJI×õiB¤9Þu0þˆ²,X¾ÂG9I¼4Å|9$Ó xðZž]ˆÔPXèL†)¦ž<Œ P*@¨ T€ PŠ’iäÔe…ÇY_a’Û©’5÷Ä «¿[l`’+qÂ$!ääÏ3—)Q¿ùª‹œH­‹¬<) T€ P*&€1=üäs± R–¥iwXPŽèEïq9Š %¿¿¥Ü’»ŽÝö¥ÚÈDŒ©âöMŒ©béøC*zøôú*d‚ÈÆtó_úGŒñ-0¦¸ƒE@H’l·ù1“1¦Ô¸oÖrUOòŒ2ÃIù P©x *îyrŽ+… µkî©‘=Lw ¡“¹ÊYŠÜí×]u}¯Í;?ŠH;÷~òåW_52ç¼ T€ P*@¨ S@H¦S–…=žÔƒaʘ†™*'R3U,  T€ P*P‰À˜ú?1¾¤AÊ13•µèݵ(’ŠV¶»±8¹%3Zœ†n$ºd^‹S%íÌþ 1¦Š¥ã©@êàÓwê«V wÓM·÷àð-0&ÿAì‘BH®«$Ÿ·$“LŠÂ’‚=yzø$ùh»S ¡”¼ R°k¥¢xpÙó®Tîð:ÕþÓB2õ8B&O…’abÇO¨ T€ P*@¨@Ã’é™)Ký'd˜V I¹'R“RÌ T€ P*Ð4€1=ôøx½É46Á õË3Ïs÷Ø9|q9BMK^\É0!¹+Û½ëÛWH¸gI;$•kR©ëñĘ*n¬Ä˜*–Ž?¤©W€Oß©¯B€ÓÁƒ]tÆ…JùÇ7bÔxƹ±#3Ž›»m×ÜàAd œdñI%¥J)¨äC[ê:ÊLÝÉÓŽ1)ÉÔ÷áVød˜ØëS*@¨ T€ P*Ð`„dzzÒRóñ„ Sƒk!—ãDj"ª™ T€ P*@š©0¦aoŠ2HE˜\sR1®TdB²‰%?´”ð•íĘ*n¯Ä˜*–Ž?¤©W€Oß©¯B€“1ÝØ§¿íÖ(8áÛ_œqnÄ!_Y£Æ‡TÊg’Fy ˆõ2I’;Ê,kaòÊË'|è™d¶)“’Lw$&vùT€ P*@¨ T€ 4E!™ð¨%O‚d˜šR Í¿('R›_Ì T€ P*Ðd€1=ðØøØ)Ÿ™ÉG)X” C’ÇÍ’?zC’-5’7bL7YbLKÇRÔ+À§ïÔW! @ŒÉƘzôyÈC™ñí/N?7â€X’¢H!LR™TëÍõçI>©Þël`L’‰ û{*@¨ T€ P*@š¨€’Ld˜šX M¾4'R›\¼< T€ P*Ð|€1Ýÿ踘)g}{¤uÉ•|æ$›Ê@"ÆTq«%ÆT±tü!H½|úN}²Ä˜lŒé˜N¾ðâëÃÒÑ'üò_¾÷ýˆB¾ºî‹c¤?^wá¯b”:Ÿ×ý¿ü×ÿŸ¯ýÃ7FŒ›¶yçGš¶íÞŸÀåÀ'Ÿœ|ê'œtæU×÷2sëßÞ¹÷“/¿ú*E`–¨ T€ P*@¨Ȇ ™Ž8úð#Žî4tÄ„èÇ“=ï}š"³E p"• ‚ P*@¨ȽÀ˜°l¾ƒT¨™)9&•ºæä»ßûþÑÇÿ"â0á}n7ÏóÅG>Ï}[;HŒ‰m€ äW>}ç·î3^ò/_qñ,XЧøàÃL¿ûãågÿº›g'?fX˯¾ñ—§U²€«6ìH>ƄƒiHï+È0åª[ca© T€ P*@¨@2ùÂy—?ü?É0%³vêž+N¤Ö]b^€ P*@¨Hº% R—\q R¦uj@“h{gÍ97ˆ1áŸ@Œ)éÝóGê§Ÿ¾ë§-ÏÜTò…1ù¥ŽžQå·T Pdzc²š÷š‰_^ñŸÛß|3¬â臩©ý-/N¨ T€ P*@r¤ÀÂí Yñà$ìñ„~˜²Ü8‘šåÚeÙ¨ T€ P  Á¥ cBs$ÆTá’?£P€OߨD!HbL…Haõ?ñœ™T ¹Ó‡¼¤Ã—c®m7ÀT@†‰w*@¨ T€ P*@¦0¦ÇÚ:ü틯I&2L «ˆæ\ˆ©ÍÑW¥T€ P*@­@&Í%M/1&bL‰þÛ3sT Þ ðé»Þ óüMR€1&*P¶ ŘÖLÃd¥+þîËÚ=$¦&õ±¼, T€ P*@¨È©ïºq×G Px?ÉD†)ûm‚©Ù¯c– P*@¨([¦?™Ì1&bLeÿù*%øô¥ÚdY ˆ1•°drœÇB•¥@B1&Û““Æ\ûåW_)ÉD†‰Ý> T€ P*@¨ õS }ûþ¿î8¿I2‘aª_E$èÌœHMPe0+T€ P*@¨@R(Ë Áƒc*@Œ‰SRþáÌhŠ|únŠì¼hý ÆDŒ‰ ”­@1&uÅä:d:øán!™È0Õ¿#娠T€ P*@¨@®8dà!%Ë’iÇ;È0•*#p"5#ÉbP*@¨ µT &—ÃÃÊR€1¦ZþKy.*:øôº*c†ã)wŒé¯ûò“ϾˆHø[ôü6c |üéߢ …fïÿÕÀ£LWLB2¹—É„ÔÀ|ðRT€ P*@¨ T€ äK~/ôÆÔ²¢™&¿6¹um+¶l[€$Bà£l \öÆ1ù(Ÿ¥åDj>륦T€ P*@"(i*i›È˜9¦dqâÂF¦¾vÂcmvü"Õ T w ðé;wUž—çcÊK=³œÙVÀãŠÉpÈ”ír³tT€ P*@¨ T€ 4]PJÝ'wß´o¦ŽOu¨€ {c_Mø G¶µ·aC¿jzæ™z)À‰Ôz)ËóR*@¨ T€ P¯ĘØ&¨@~àÓw~ë>ã%'Æ”ñ fñr¡€ß“á) °T€ P*@¨ T€ 4I³{ˆ¿% K`˜$`•Ú÷·cC¸%NøV¾‚7&=¬IYæeë¯'Rë¯1¯@¨ T€ P*@DbLl T ¿ ðé;¿uŸñ’cÊx³xÙW Ð2e¿âYB*@¨ T€ P*@)UBV]¶x` ÄR—Ñ]ð-Þ%i˜¹D€™¨‡œH­‡ª<' T€ P*@¨R€Ûȯ|úÎoÝg¼äĘ2^Á,^¾˜Òç nWû¶å«Ô,- T€ P*@¨ ÍS@‰%ÝL’# !WLpÈ${°½ÿ¯û›—_^¹! p"µ!2ó"T€ P*@¨ T cb3 ùU€Oßù­ûŒ—œSÆ+˜ÅË—ĘòUß,- T€ P*@¨h¾ —à] èÜ,In6íÛ„p„xsÂ3d’=8F£Ë5?ëÌAýàDjý´å™© T€ P*@¨@±ĘØ"¨@~àÓw~ë>ã%'Æ”ñ fñò¥1¦|Õ7KK¨ T€ P*@š¯ %$äÃô±„=iNÞñjßߎm9’¯ì+À‰Ôì×1KH¨ T€ P*ˆ1%¥&˜*ÐxøôÝxÍyņ(@Œ©!2ó"T 1 cjŒÎ¼  T€ P*@¨ T€ D(À‰T6*@¨ T€ P*Ð(ˆ15Ji^‡ $O>}'¯N˜£š(@Œ©&2ò$T  cJF=0T€ P*@¨ T€ P\+À‰Ô\W? O¨ T€ P*ÐPˆ15Tn^Œ $J>}'ª:˜™Ú)@Œ©vZòLT é cjz0T€ P*@¨ T€ P*À‰T¶*@¨ T€ P*Ð(ˆ15Ji^‡ $O>}'¯N˜£š(@Œ©&2ò$T  cJF=0T€ P*@¨ T€ ,Ü~ÑcmœsÈkCàDj^kžå¦T€ P*@¨h¼Ę¯9¯H’¢Ÿ¾“RÌGà”båé¨@3 ÆÔLõym*@¨ T€ P*@ cÊukàDj®«Ÿ…§T€ P*@¨h¨Ę*7/F¥Ÿ¾UÌLí ÆT;-y&*Ðtˆ15½ ˜*@¨ T€ P*@lˆ1åº!p"5×ÕÏÂS*@¨ T€ 4TbL •›£‰R€O߉ªf¦v cª–<h®ŸzðÏÿv·«}Ûš›^ P*@¨ T€ P*@Œ)×m€©¹®~ž P*@¨ T ¡ cj¨Ü¼H”|úNTu03µS€Sí´ä™¨@s½„{Õ€“›› ^ P*@¨ T€ P*ˆ1åºp"5×ÕÏÂS*@¨ T€ 4TbL •›£‰R€O߉ªf¦v cª–<h®‚1!®_T€ P*@¨ T€ Pf+@Œ©Ù5ÐÔës"µ©òóâT€ P*@¨ ¹R€S®ª›…¥E ðé› "£ cÊhŲXT€ P*@¨ T€ P*@š§1¦æiŸ€+s"5•À,P*@¨ T€ äDbL9©h“ (ðÿgïO å¨ÎtM˜î¿‡ªÕ]·ïß÷ïUU]¶Ëö-nßÕUEácd—'fmflcËÌ3¶0 FƒBLˆQbš%40‰£Yh@H$el¶þ7â‹Ü¹3"r:'2OfÆsÖ^gʼnŒŒáÙ‘ybïýìï£õÍmÑ¡И:´b¹¬%°{{÷ÄýT>xs]ì_›“"-É^2WÉÐØzm©õZp TÁqÍ€ @€@SìþÓ¶{—üUªÆ´âíáM9ÒèHmzà, @€ò@)µÌ5B ­oîŒ%€ÆÔ¡Ëeu"s•teI!—$-9]i÷ön[¯ßæ3½1o¢6°5d”ëÄ›‚k‚ @€@kH ÈD(¦Öª¤&œ ©M€Ì! @€ @câF€@~ ÐúÎoÝwø•£1uxsy€ @€ ¦H ÈD(¦¦ño•Ñ‘Ú*5Áy@€ t>4¦Î¯c®åÐúæÞèPhLZ±\ @€ @ /Ä2Š©/*¡¯IGj_×LJ @È4¦üÔ5W 8ZßÜJ©C+–Ë‚ @€ ôX@&B1õE%ôõ1éHíëàø€ @ù!€Æ”ŸºæJ!'@ë›{¢C  1uhÅrY9$ð§÷¬›³gǦ^:— @€ ´‰PL-U/Í;:R›Çš#A€ äSÞï®?Ïh}ç¹ö;úÚј:ºz¹¸\À¤ÿU“†æê¢¹X@€ @  ¸€L„bjÁÚiÆ)Ñ‘Ú Ê€ @4&îä—­ïüÖ}‡_9S‡W0——#hL9ªl.€ @­N@™ÅÔê•Ô¸ó£#µqlÙ3 @€J  1qG@ ¿h}ç·î;üÊó¥1Í™3ghÅŸK/½ôg?ûYåmxµœxâ‰C† ©|!›6mj³OÿŽMSÞëã'†´Ùisº€ @€@'è~wݘ§/èÄ+ãšj @Gj Ø€ @™@cÊ#;@[ õÝ–ÕÆIW'/éä“O>èÃ/ºdˆ• ýrñ /òƒƒûçÙç‹/S¹ Y^vÁÀËÎ/SÎxÙy N–s/• Ÿë•s.ì•Aç\•³/”,g?(µœyþ¥Q9ïÒ3½rÆy—–”s/=ãÜKO/–KN?·XN;ç’Ôrê9—ål¿\|Ê٥嬋O Ë/Ë”g^–~ùÅ™£rÆÀ_xåçg ,)§üù驜œV~vÚE©å§§]ôÓÓ.üé©ñò“S/tåÿ›ÿÔÿ¸_þä” OŠ— N:å‚“~yÁ>_Ü_’SõP+m1zôè¾ù£~ðí?þ¸•΋s @€rG`çÎ_Þó;S§NÍÝÅsÁ"@G*· @€šE©Y¤9Z­ïÖ«Î(¹Ó˜†ß>jëößo‰Êî-ÛKÊÍ·:ú¸“6¿»ÛÊ[®¼ó»·ÞùÝ›®¼ý»7J˦m»\Ù¸mWPºƒ²!*mØúÑë^Y¿å#W^Ûòák›£²nó‡QyëõAù@eÊ›QYýæAy#(¯¾±3*›v®òÊÊ;Wn|ßÊ • QY¾áý ¼®òÞ²BYºþ=W–¬oÉúK^ ÊbWÖíè*–í¯¬-–Ek·/Z•…kÞ Êêw_öÊ‚Wß Ë;*/©¬ŠÊ‹«Þ ÊÊ ¼°òí¨¬xûy¯Ì_þöüåÛTæYY”¹^™³´Û•ç–t»2{I÷ì%[g/Þ:Ë+3»¶Ê–][þöï?=vÒ‚¯l™neQP¦e³ÊÔ…›Oüåí¥1Éa:òG'¨*GÜûøQG…É”É÷#; @€z@ t˜ú=þÌÜ…«ºüî!˜L=`Øöo¡#µí« € @hhLmSUœ(2'@ë;s¤ì°5äNc’¨ä,¥äÂM·S`/½£Rª.ÉaJÚKoÿ..0…öRSÁaJL‡© 0ÉdÊÀa 4¦¢Ã$™)®1…SQcªÓa*§1¥8L¡ÆTt˜V–:L+ä0UÒ˜J¦¥1‡©[S‰ÆTt˜$35¦T‡©5&s˜T³ªMÕÝí˜L­ñõÊY@€ @ ‡ä0}åkýÆ=3ÏÚ› VnÅdÊám@4¦ö¤x¸ÒK ¿¥+dŽ«{I‰äÖ«ÄRÈ¥E`ª"0Õ”H.Ê%$’+ä’‹É…ScrÉõÐaª#\˜Q®l:¹x(¦ S¥PL¯l1éAÓ˜JÓÉM ¦6J*g“ªÛiL$P@åþ»õnL¦†|i²S@€ @ •€9LãŸ§Ìæþ,‹®uÛ_X¾å[ß9˜ìr9ºsèHÍQes©€ @}L©+€ÃC  ÐúîCøº‘ò¨1ù–Ò&)Jž¥tã-Ò˜NŒç‰sÞRR»ÉdÝåê=wZ’þÔ)G69X=ø‰,‘œ~4KXÚ€…JÒJ­‘d{Ó^ÕJ[ÐÐoÛ¾0u,Û³ÖÛqmcûm“ûqbSû|Ór¦€ @èLr˜¾úµ~ONžη)›ðÚͲPóä¹®7¿QÉdµÔXжBãEñ“¬A¡v‡ ïjo·iö’š$Ú‰Z%®ybRlâ„iLjªÄÐZÇ '½Ë5U´¥­±ý¸HNÚ^'f (ý¶íÝ™ø·ˆ­l㛆ŽÔ6®Ý™tèw2—@€ ö ‡Éw˜^ šœQ¤ØBÂk›e¡É-ŠÈ;sÑý¾]“ÉÓ˜,–’~L9²æF²ñ¢ JÖ/ÚÆiL±6Ej›¥–:°´îÇeÁ¶Pµ®Md‡¶ÓpiéÜÆ–ÂÛ¢4Ù[,n-'ÐÒÛБÚÒÕÃÉA€ t4¦ŽªN.u õ].6n¹Ó˜®½éε%éÞ$$Y ¢(éÕþGŸ`Ë~Y“È秇‹,Y¤¥ 7œ•¯ÆJš´Tˆ·”ð–ÊG]Š©K–PÌ/å2ÇÅb/¥ØKa22+Šù•Õïjâ¬+šA[(ï,xõ—TVE% ¿”H!×ËLJ'—šE®$S,‹\™ L˜,‹œ4¦1øá—bË'þò‚s. ÜõŸü¥?Ú~¦(YCíƒ+ÞVª¾¹Ë¶]ÇÃU³Ë¹N|›OìkLþlãÔhLþ€u¾×®19¶æK¹pM±N|›âÌ @€ Їä0}åkýžp¹ä¼l×jœé˃¸¿Ûâ·N®ŠÉfY(“øŒ…5™LÉhLj2X°Ø 5d,’k\¤jLÚ¦7“Ó•Ôl±ltnâ‡ÉEx²H·ÚÌÚY.“µ³ÕÝ™÷a÷öÐt¤ö– ï‡ @€@­Иj%Åvè<´¾;¯N¹¢@î4¦k~{§o Å–õª4¦²ŠR‰¥TÆU2u©Œ±”*-Eñ–ÊzKïWõ–,§˜²Å¹ô[)Iô#WÈWÁ^²a‰ÛK5†_ ºªÃI·ê°ú¬­TL!×I“Œ¥¶Ó˜<‡)J,¸<Õaª8H0wé6!½nD“Éuâ«K]=éJ*§o ’LcÒ‚VÚK±hL¶¥¨_>– ¡B4&õþÛž]·¾[˧€ÆÄ?/@€ ô-¸Ã´á}×< §‡) ÅΊ æÀ¸PL…YjžL{yÓV‰ÉT5©œh$/¦1©‰¡…/rŒ¬¥c™²]§ÜÔ‹ZÚ6ãB{³=kÁ2kë|th•LNRcG§ášT¶^Û«I¥Í´ÞO¥ÆÔ··7G‡ @€@Û@cj»*ã„!4¦ÌP²£Ö"P“Ƥž8SÚýçä“OöÛ;½€I~ð¤`yØoïèÿãR)¥ÅUJæƒKË Wf)i,)I\Iž¸ ï¾âç-Mœ¹èì‹.×oriÂŒEg_x¹~Þ’§.uá+=5{ú ¯V¼¤Þä¹KÞ¸øW×/dÏ8ÿ2+W\ç˜ñ3á— öR-á—ªæ«&0=—]¦éA¦(“ ¹Ô^SÌaÒÁò׃\r×?²ì×£_ùõèEcg®vÁ›n@ªÖÕc?5S”¯Á$óñm½öö‡*Ädò;Í]ß½zám2±´R_úZp?¶Þ6Ðof°/ o¶}l¥¿gõìûÓŽíX±ïŸZ†Úý›Šó‡ @€@Ëp“K€î;LÍ\ÿëûýêþEÎxÍæÉ¨i©†ØÕ-—ðZZl–…Ò…OY°±²ÉäÚnÁÁ©Ðx‘cd ½ËotX‹CÚ³£RÛ,5¶;$EiK5d¬¥£F °dõ›TZví›bo±3±`N±æRËÞÕOŒŽÔêŒØ€ @Ù@cʆ#{@; õÝŽµÆ9{Ì:H"©®1ij &ªOͦ-¶5Õ@cºñ •äŠï]}ãGýøM¹å•å'¹ò¾:pý²B¡•¬„–’+€â—׃HK~°¥a7üÌg?oÒÒ-w=ü…/MÒ’~kYÒÒð»Þ÷K_“«¤ßÃG>ä‡\úÌ?~þÌ †¨üdÀYZ5vB,g\à¸x9ã|bÖ¿}i?—6náêw?ýŸ?ñçgž~þe*‡ÿèDýY%öR2y\©½f (~éÿ~°rœei·:¯]ñ&õh‡ekIþ¸Å[gÕ‘B..0™ÉÔcé“?¼âíáÖ|­i9LGþø„ÀnÝ!G™zÑ/Ú Á‘C¦\~ß"Uè˜ië¾uÞ„Ëî]øËßÎUqùÜ Á¬Å[gvmv[%“©iWÇ @€ 6"`Óøgç¹<×6ŲœŸ4l–Šš'ÖB9õ¦yr˜F—¶PÔH´„×|×Úz“_Úðõj1™Úˆ§ #•û€ @Í"€ÆÔ,Ò­G€ÖwëÕ gT; HšKÍdo¯¢1Y`vÛT³-(zûþHcºú†;J $ßFÚyõ #L©\ÊYJÉÐJ‘´”ЕÔÏëŠuøªÌ|iµŒ%iL–$nß/íé Æ‹¯Ê[’´¤ßOÍX¨Å[Òr——0Nê’Kg>“%{bÚË2–T —Þ?uÁOÌ9æéûâ~.ä’ä-7Ó©Kzuèuw(ì¿Êýãf¨¼(o)T—Tî{|ƣϾ8sáͦÕï/o.£rïc3œ½tÏ£ÓU¢äqË·=4ñÅ»™þä¬eê°Ö¿~á«c'¼j/…ƒÂ²8.0É¿ñÊ–][f¼•é¯l Ê¢ ¸ðK–B.Yz 1­Ûüî²î›Ç.ÿ»Q]{=²ò³Íù˜Ãd>œ Âdw‹n iLãçm´z7gÃC¦¨O¸zæMã–«¦T5‡ž2~îÆ’A‚%Á ÁÌÛÕ·b25§9  @€:€9Lãžç" [«Ö°×?²ôô›ç«•jSh4ÅâˆË¦(êRÔBYYl¡˜Ãd¡˜l–…š'ϼ°áëßúÁ„I“;× t¤r@€ @ YИšEšã@ õÐún½:áŒj$ ˜åЦdÇR6iM©««K”½Ù_®ñØ­¶™4¦«n‹äÿ©WüÑ ©Ä)¥Uòã*ù¢’ëÛuÆ’¿àÒÃÉLzø©ÙÒ˜d¨ÈUÒBoiÝŽÐRŠ~›½¬ E%+’lAýÅGüèÄß\§¼¥“~q––•'îÀï¢HK ¹¤eùIŠ·¤ß¦1…Þ’Ê;¡Æ4ã¥0gÜìEõçˆÑOˆÙç‹ûpò™*ßúÎ!2cT´æø“Ï<ì‡'ìó…ýä-zî`•ùaì¥O}æóó—o{xÒ‹²”N9gСýOPQÏõ/Ï–õ[ë‡Ý2æ¼AÃ>õ™Ïé·MÀu¥œ½T~i«o/©¿».©ј$0=·îº1KþV“•æhLÃô£ &\ä½ÙÝ!¡Æ´ÁrÉ]óÐÍuVUj¨à‘Ù냚ZhL÷L^Mt.$49^WÝ2¶Bv¹Vûür>€ @€@_¦ýú{fž›_á‚0¹æ‰²];‡IÍϰ½ùNÐB™´P4ãåðÁ“ïy¶ÐB)„b²Yš‹2ñù×÷Çdê« Îü¸t¤fŽ”B€ @  4&n ä—­ïüÖ}Û_¹ÒÁéÇ.C 2™üKªžTNј,Þé"3µ)iLWÞ0"EH ¢%ùÝ®¼^Óñ–è-–î-©%ÅÖ¤*Jneä*­ß¡ÞX1WI©â.zýâÐOÒïTiɹJÎ[ òÄ…‹^:𻇪(Uœ–rI“_/¾ü:ë;3~¦IKzé¹W6Iv¹aăZ£>åÀ[ Õ%½äŠD¥ÓλLQ—.¼ìZéJf/I]’®tÁe×jÁb/Icºç±§œ3XÆ’ì%Eý‘ƤßJ7dØË'oÉb/™´4åÅõ*Zè÷íƒãöR˜<.–?®žðKQþ¸iiá—b™jŒÆ”˜š¦1ES!jWñF ï»C”¦AåÄ«g)“ÉÝ4n…*ÔÒÉ©¾î¼ö›çN4jA,_ƒ$0&˜LmúmÆiC€ @ iä0}9p˜æÆ‚ [ÛV-5O9˰䖥™´dÞ’~/ Ê»*úSÆ’IK7Þ(JZ¸sÌÓŠÃd—LZÒf‘º´êEW²œq–-N/Ýÿø ©K¿ºöŽOýãç'>·\*Œ¼%™I®|ó;‡hÍ)н´\±—¶É^RÚ8ýV ’Ç- 4&S— oùœ¢.)Ó¨G¦…+?'{éÁ§_À¤?öRÝöR2\ ö’“™jј†Ž<ÈÀäB1 ‹£°L%+ ±šz¿ò—×ìuÐa?Œ‡ìò&K$'‡I¹äTûªk]šL¦©/¿¥<ïöŽ¿jæ¹·=¯òàô×,äÕì(\¯!Ì»W̵'“éÛßùÞŸÿò—¶ÿ¶ã @€ ¬ |üñÇûìûåÇ&Í-i¡&kÕúÍ5KÍaR E“Ú•®…rÎmÏ?0}¥“S0H'ׄ×õ›'2™¾¼ÿçßùW½oXuÞ_õß³®Þ†íŽÔ†¡eÇ€ @ˆ@câ–€@~ ÐúÎoÝw•;ÖL$-¸ÈLvaÕ5& Ť-¸ìtmJEј®¸~„g…ù¹¼¢W¥1•³‘ÊRªj)™«ä•íÒPü”pó–¼qæC¬H':ã‚!Ò•öýÒ~Sæ¯2iIË2–iiòü•æ-IK2iÉŠÞe Š´ôÌÜ•¡®¬¼cÌÓò–î7CÛ[È%S—&ÍY¡KÀ´2(êY–ºtßã3,ð’\%Kš/«‹½¤œqOÏ^þôìeEiiù6å‰S¤¥SÎ$QÉb/ÓÒnKÃïyB}Ó*˜4Ñö®‡§Yì¥s û—}¿*¥&Иoå—® Û+[üäqQ渤½äé8±Kþ¬Ecºà²s§¬9óžÅ)½çc–ýç®­CW&½|Þ׿ñÅgç,q“›]&˜,‘œ‚0=þÜëVé ©¥A%k˜¼àMåà³àX‡ ž<á…M%ƒ¢ô½Ã޾þæ‘Ýïý“©M¿Ù8m@€ 4”ÀСCO;ç×"öš'jçFÉÍ/¿o‘ò\—­ÎÃ/›2øž—Ÿ}éMµò‚ʲB ¥˜N®0Ë›”rÇØi_øê>οêÅMW5®ÍÕŽ{~bõ¾³ZÑYÔ,i²/@€ T"€ÆÄýü õߺï„+W@%» å…“Éä_Rõ.0 PŠÃd1™œÒÔ¦TéºÛS¬£B´$½zø/Ù 6É‚'¹øI 3©’¥dÞI¬¸|p&*¹ÄU E¥3οìˆøÀø™ú­euŸ®Q†8ýÖr¡ƒ8°Xô®Óϻ̊Œ¥N>Ó¤¥ëoP“ÃiYÒ’ÖkYQ—$'Ic2i)(+Þ–tïc3,[œ%Œ»`ðµR—öùÂW¯½uÌ݉᮹uÌS³– ·Œv˽E“òÇit¥cz†â-I]ÒKZ#uéêáÚæsãg,=ø¨ãùé#šzî¥Ã´,{é>ó¹+ohL¥ö’¯.qƒ¬,ŠÊ´0Œ•Ú¥¥ä–µhLç\8xý–V½µ>)3=²ò³þlÚ´éÀ|æ¹%Þ-W˜Â@\ïqÙ” F¼ YΖ¦AƒªÊ[6àÆ¹ÎxíŠ1]Ç]9# Åêb–N.Åä ˜Ã¤+UÁdjtµ²@€ ´)™L§ž}IJó$œb´aW-”®žyÓ¸åÊ%§Ê7Ï› T×7X ezÔB‰GŠ- Å$‡i¿ý¿±xõfk¡ìþÃ'mŠ«§=÷“ј–}B€ @ Ý  1µ{ rþè94¦ž³ã}L@¹ä$ IC’ŒË(§3«®1éý²ŸôÓî“®VÓÐko¯` éÕÃx\*É/kK"'¥:Iµ[J¦+¹dpf,Y>8+æ'Y¹âú;e, ¼ü:‰JV†^wçá?:ñ¢Ë¯UŒ¥(=Ü«Á<×Óλ̕£Ÿ¶ù‹>˜»ÿ´mé¶k+B‡Í–ÕÐ/ÿôIDATGØL¦ 3Û LÎar#æ0F ƒ–K.ŒÃ8LʼnÎå&L¦¬*Žý@€ @ # ÈdúåY{ÍoŠ…Mªñ¦XTq˜ ¹Â+8L©&Óĵ×íXבx+\SÞjœë… @€@ИjÅfè@hLX©\R@ wÓ¯†Ý–ŒäÖèÕCûWaƒØKiZR”ýÍ÷“Šá”ÊXJ.¬NZh¥”èJUt¥(ÌR¥HKµHK Sê-ã-Õê-É¡iuÉ÷™zÉ4¦ª?]Ý]ýîïWu³Ú7É´ÿß|jÆb‹ÀÝ-%#i“4²R‡É™a•&'xïÃ?Ô~†l @€ ä‡ÀàË~5àÌ‹£v®Åˆ-Dv‰äâab“q˜jv˜Ô<™·üí?ÿ¥ØÛû¶½óCÛ])S+K† @€@-Иj¡Ä6èLhLY¯\Uþ4¦Ë‡ÝVÆ= ¢"]>ìÖC:.f •’ÊOª”ú­ÐÉk àÂÞÞ2¢RakjJ¸BïpIb¸ÔÜp)ÆRt,ž!.UZÊÒ[R@ EQQX i‹6GeáæÌƒ-UÝaã4&Í –ä^õ±ËÇŽX4B¥ÿcýµ¬ßö}£yÃZi Zi¯Vý*zýõ2™ž˜ÞU!°)Î~"9ËÔšg–ÑÏâ0©À œkq˜ºßû½?HPõôØ€ @ÈK]þ‹3Æ&—ç:&¶Ûš'Å\rõ8L Voßý‡O^µ¡Ôà0q€_g Ô‚‹ÏÔ½«[ËZПÖàÒ6Q5hLQ\ @€2'€Æ”9Rv¶!€ÆÔ6UʼnÖG wј†\}kjÖ6[©W¥1U—LEŠ•‚–T]N’Ÿd%4Q*”@RI„VŠ»Ja*±ô¬p^Š1 .±’Œ´T]ZJÉW>ÞR+yK1±©q“>ê4—¢¤ë4W7º¹MöÑTº¼¥9›æhÍ®?îRÑ‚¶©úÁ5“iüôWì†qSr„Àw˜,—œŒ1#€ÃT•3@€ @µL¦3ºV­ª.Ïõ\ŠÅ’hŠE&“NLí)3“4?D)µ­Ôªrñ™ô§iLzIr­VËÔ‘Z.¹o·Acê[þ€ @-K©e«†ƒ@à  151èyÔ˜\$Ï7²Hï\võ­‡ylä9Ù¨®…jf’“–J¥b8ëü­à*¥GW*`) Ï“È —4–Ì}‰—`¾l¬Ä“Ä)Ø\™¨¤Æ[*84Uƒ$5mƒ†jLNKROºùI®ŸÝ:ÓmZ°úÜÕ«®¢^uë^¯úc&Ó¸©¯D·G¨©Í]êa Gz“KŽ8LUk @€ # “éçg L LA;T1bý0±Ê6NtqS,î;m¿ý¿±xõfËjZbq˜ì NKr¡mÕìòçXX\kg©¨96lþ°¨24¦¨D.€ @ €ÆÔªìíA©=ꉳ¬›@î4¦Ë®ºµBô#½zð‘ÇVŽT)Å[Ið¤xº·²~’Â)y•ÊZJC+Õ +©y«\%+)ÆRä¿ÇÒR牫Kj¨Ædó€ýžtú¯½ªßêI·¢™Äš=\ãg×L¦Ç§,rSr„ šåL.¹™² @€ ÐS2™N>ý¢ yF`*æ¹.b‘•äӴ™!¶`g-QÉ"0ÙJ©Kú­v–kp)DSO¯¯…Þ‡ÆÔB•Á©@€ @ • 1µRmp.h.4¦æòæhM#;ið•·Î_n‚Q¬_y‹4&çU^ܣʥë­rÒ7ëðõ»}“ àÜšÔLpšçêEWª®+ÍJ‰±TÈ ΑõK™HKž´ÔzÁ–ª*MÓ˜¬Ç\`—ËÀõ¤kAÝèöªå>Ђ۾öϼ™LN^X˜ü‚Ä,grÉÕΖ-!@€ z ÈdúÙiyS·Ës]2Å¢Ðrìq&;1—?ÎiL¦+Y+Ì^5‡I –Å»öy#õ^{3·Gcj&mŽ@€ 6"€ÆÔF•Å©B chLew­B wÓ +oqRQrA¯|ıå6ð}£:–à ©µ”@QJËþf–R9Q©\h¥ ÞR])èJNèJ%¹áÂhÿV¦Ee³‚ÿeáæª’PëoÐ8IÓ‚Õoni ôÛ>èêCW×¹%’³Îô‰k'j3­±¹Âõ~˜Éôð³ aËe‘s#~¦¦zÙ²= @€ P/3™ü,rÊNnÓc¬yâ’½t˜tbjIYÂ8IÍ+×àR#KÛXp\kp¹vY½ÕjÛ£1µZp>€ @hhL-Rœú€S@çÍ G)n -íž[(ƒ~3ü #Ž­E9ªe›HKªh&%ü$ÅR* §T!\yQÉÃ…®RͺRÁX*èJ$-%µªÆiLÍøÔ†Ç0“é¡g^Žê:m„‡©iÕÁ @€ s2™~zê…aód«µCÙ7œSœ Ó{‡)Ïјò\û\; @€*@câö€@~  1å·î;üÊs§1]ò›áE»È¢yå’+ÉE?êñB¨"ÅÊV’bÅBé”-éá”ÌR D¥rq•â¡•¼èJ)–:%ÆRíQ :@cr&ÓØI RGp˜:ü˛˃ @€@‹Éô“S/ŒZ£¥A˜Ô<Áaêeu¡1õ o‡ @€@§@cêÔšåº PSuFlÑ–ò§1]1<Í1Šb IcúÁÇ(QW±¤¹Gõ©HIK©«\º7ç'yŠRZ8¥(88½µX iàhLõñbë¶!/éôÓOÿôgÿiŸ/í_®|ö¿þ?ÿåÿúÛ ¤¿ôÅý÷¡´¿þëÿíÿý×/W¨5yNC®¸ný–üòŸü¥•?Ù2™þë?ýÓõ7ŒvìÏî÷~ÿç¿´ô…´2dÎ € @¨‘À%?þÖ¾ÿ÷ß,^½¹B eÁêí»ÿðI;ÌùfhL9¿¸|@€ ”#€ÆÄ½ü@cÊoÝwø•çKcÚ¹sçœÒŸ‡ÆOŽ•Ñ<\Éš#PK-'»Ú[\cÒwÕÄ•G­zkq…A¦ÿFçò @€ Ð:ÆœÜ}Êÿ‰Ã”U… 1eE’ý@€ @ Ã 1uX…r9¨ƒS°Ø´äKcJÖLå¸5¼ 6ŠÆ´c÷ÒQ]{M}íG[¶ÿ>µâp˜Úé»™s… @€@»sòžS÷zïÃ?¤6OˆÃToõ¢1ÕKŒí!@€ hL9©h.)И¸-:”SIÖ0¬T Ðâј¦¿~”4&•·?Zš4™p˜:ô;œË‚ @€@«˜vݞߨ“KšL8L=¨34¦@ã-€ @È4¦<Ô2×thLÜJ µheÉB1Y‘ϤSõM&¦ýç² @€ ÐÇ>xsÝöÕ]É“Ðz¥o2á0õ¬ÎИzÆwA€ @ ã  1u|s(K‰›£C  1Õª°¦­¬1¹PLf2Éjr&S‡~{sY€ @èc«1q@¿yWHžÇcý÷Ž­4“ ‡©Çu†ÆÔct¼€ @M©³ë—«ƒ@%hLÜJ ï“ ­©PÖ¼õá†î]•·áÕv'ðÖ»»WlÜYù*¶nßýç¿ü¥5¿üPL. “NU&Ó»;ÿв§Ýš09+@€ @ FÓößÚ5'¹±B1IoJ®ÿ£?îþÃ'5îœÍbИ¸% @€ ThLÜÈ/4¦üÖ}‡_yÞ5¦¯^./b¡˜\@¦|\=W @€ ôaõ¥½d2IZÒo©K n¨SymòX Ѥ?µRE¯êO¥Ÿ³eýŽeëƒ h·C¢1µ[q¾€ @h4¦&æ0hAhL-X)œRИ² È> Ðw’¡˜ü€L}w^€ @èd»·w[È¥%÷ “·d—j¹äd/)ßœýù§Ý»´ «ÉB4ÉdÒŸŠádb?µ@cª[B€ @ WИrUÝ\,J 1qCt(4¦­X.+7RC1)7õÏ…B€ @ o8I~’L&‰J2“LcrÁ–,“^ÕJm¯Wµl%5ë\ß\I›©M*ŠÓ„ @€@³  15›8ǃ@ë@cjºàL2%€Æ”)NvæøäÏwmj奷Γ½¤§U·æ­¦6÷t8 @€ R‘rI1™$'½1o¢.[¿-Æ’ÉL–6N˜ádª“¢1©hK ËÄOíИjgÅ–€ @È4¦\U7 hLÜJ©C+–ËÊþ¸I“¦ü]:W @€ 4›€eˆS±¸JJg—,yœÖH]²Ôr’–,>“~k3ËF‡ÆTo…¡1ÕKŒí!@€ hL9©h.)И¸-:”S‡V,—•?hLù«s®€ @}FÀ/éG™ã´¬HKŸIÒ’e‘“·¤õV,2“ÖÛŸ½‰Ÿº 1Õ…‹!@€ hLù©k®qhLÜJ©C+–ËÊ4¦üÕ9W @€ ä…S^jšë„ @€@ИêÆæè hLT™\ŠO‰ûB©C*’Ë€ @€ €ÆÄM@€ ¤@câÆ€@~  1å·î;üÊј:¼‚¹¼ü@cÊO]s¥€ @€@Þ 1å­Æ¹^@€ ÔH©FPl$€ÆÔ•Ê%И¸ Ð!И:¤"¹ @€ teöV$€ @€Z—S¦uƒÆ”)Nv@€ Î!€ÆÔ9uÉ•@ ^hLõcû6!€ÆÔ&ÅiBÀ#Ðïþ~]Ý]  @€ кИ2­4¦Lq²3@€ t4¦Î©K®õ@cª—Û· 4¦6©(N&Øëнú?Ö_&“–¥4é÷°ùÃF,a›ì}ÛÞú­pMzI›é7ð @€ 4›S¦Äј2ÅÉÎ @€ Ð9И:§.¹ÔK©^blß&Иڤ¢8M¬Û±ÎÌ$©KZØõÇ]Zvñ™ºwukÙ~Û;|à Š€ @€šD)SÐhL™âdg€ @èhLS—\ ê%€ÆT/1¶ohLmRQœ& uiàŒúK¢ÒœMslµE`Ò‚0)8“6P& L*ZÖoøA€ @h*{ŽÛ£Þ4~2"ÐÓÔk÷LUýUûÿ\ôhFØ  @€ '€ÆÄ=ü@cÊoÝwø•Ó¥ØáÌåuYJr•t]N]rñ™´R¯Ês’á¤m”uNE ±‰@€ @Í#0ø³{~ýß›w¸N?RhLŸˆk©eéÓ^?\ @€úŒSŸ¡çÀèshL}^œ@c 15†+{…@ÃXþ8?mœþ´r Î$·IV“L&ùL¶Æe—kرc@€ @ Ò˜n:.YhéÃm{Îú«Ia™ø @€F©ahÙ1ZžSËW'Ø3hL=ãÆ» Ðg,aœ\%?UœÖ¨8{I''ÉVjË>;W @€ ä–S¦Uß“®75 ¡˜2½Ø @€bИ¸% _hLù­û¿r4¦¯`.€ @€ ÐИ2…ÞS2 ¡˜2½ Ø @€’И¸+ _hLù­û¿r4¦¯`.€ @€ ÐИ2…Þ“.9‰PL™Þì € @IhLÜÈ/4¦üÖ}‡_9S‡W0—@€ @èhL™BoÉÈD(¦Lïv@€ ThLÜÈ/4¦üÖ}‡_9S‡W0——»ÿcÛ3ë\·ct~.™+… @€Z—S¦uÓ6“®Úd"S¦÷;ƒ @€@*4&n ä—S~ë¾Ã¯©Ã+˜ËËþ¸iT×^][‡æç’¹R@€ @ u  1eZ7í¤1Y@&B1ez°3@€ ”#€ÆÄ½ü@cÊoÝwø•£1uxsyù!€Æ”ŸºæJ!@€ ÐИ2­¤vÒ˜tá ÈD(¦Lov@€ rИ¸7 _hLù­û¿ò|iLC‡Ý‹ÔIàù_þ×5kÖ´þ7Á;;ÞØgß/|ä´Ö?U΀ @è|hL™Öq{iL'ŸtÂèÑ£3ÀÎ @€ thLÜÈ/4¦üÖ}‡_y¾4¦“O>yøí£¶îø}IÙþû-QÙ}óí£Ž9î¤-Ûwo~·XÞzwwPÞQùÊ›®¼ý»7¼²éíßmÚ¶ËÊF+ÝAÙ•6lýèu¯¬ßúÑú-QymˇAÙ”u®¼õáÚ¨|°ö­Ö¼Y,«ßü (oåÕ7vFeÓÎU^Y¹qçÊï[Y¡²!*Ë7¼•×ß[æ•¥ëßseÉúK^‹Êâ×ve]Pº¢²ý•µÅ²híöEk¢²pÍö…kÞ Êêw_öÊ‚Wß Ë;*/©¬ŠÊ‹«Þ ÊÊ ¼°òí¨¬xûy¯Ì_ñöüåÛTæ¹²lÛ\¯ÌYÚíÊsK»Ÿ[•ÙKºƒ²x«Ê,Wº¶Î,–-c'-øÛ¿ÿôŒW¶¨L·²((Ó‚²YeêÂÍû|qÿ9sæ´ø7ÁÎ;¿¼_¿ÇOÿö÷™:uj‹Ÿ-§@€ t>4¦Lë¸4&õ½\yýˆ#~x<&S¦·;ƒ @€@:4&î ä—S~ë¾Ã¯ö¤0ÒR<ØRª·äE]JW—zf/¥D`zÓ"0}𪠴©·A˜ÌzqEñÞ{ŸK®Wq˜êv˜êK'7«k«Ë(§8Lr˜’Ó´E[²ÙÒÉYÙç‹ûOš<ã½ÿàÊïÿðI+|1˜Ã4þÙy+6¼¿üõHcZüZ:K=Å/,“Étð¤g&·Â©r€ @€@î 1eZå-®1Éaºú†;‚ÆiAcrÓEk“é¾ûîÏ”;ƒ @€"hLÜ È/4¦üÖ}‡_yî4¦o¹+QÉÿS¯þøØ7*º’+Ý»ä*¹²¡[º’•,ä’Š\%¿¬/ ¼eŽSþ¸ÍQY·ùè¼õáÚ¨¤ä[#u©`/ŦUug‘“æòž¼%WªL‰ L]k‹¹ä­Ý”5AY”wƒ²:(/»òê» ¢ò΂WßyIeUT^\õNPVå…•o»òüŠ·]™¿B‰ä‚\rÅtr˶Í[¶m®+K{î0Í,8L%Ó¢-Ó=‡iZÁa2é¡ñ“ý`Zºgúü‹Á¦'&Ï_& t¡˜Â €Ae©Ræ/ÝüÍï5mÑf•T‡©¥’Ê¥8L~7qi(&7ÛUÝIJÄf-zãß>h¤ɵ|WX¥ueZ?oì]®CÓúUõªõçZ±›„j›9ÉY2fähÏþ,Xmæzrõ.ëfõ«>VS…R5&¿Õú¸M2wÇâ0Ù!Ü,FQ…ƒV>ØôãkL®ÛÚÎÁQ#OwJæŠé¬Ûzí“§”ª1¹s‹u=k}lÿFØj¹7Ø€ @µ@cª•TMÛµšÆTâ0ùéäÖ¿W'8Lwô¬ ’ËS˜–×d2¹–Žßäq¤ÊiL®]c-Jÿ½z‹YDÖ@³¬íÐ#ßêÔö§köº $î]î¸H)Y£¦i?. ¯Ó˜\£Lkü¶9?6-Ç®%Ö¾K¾¤f£VÆ®Ô<-ÛÉ5Òmc¥Ø³9LÉ~€šnS6‚ @è hL}AcB 5 1µF=p™ÈÆtíÍw¦kIaê·ko 4&-”FTŠ[JciM])ÍX* ¶TFZ âë”&Œ ÂíXÙ• ƒ˜+ÕÕ¥÷z`/U¿Ô{©îLõg‘+˜¶¦a’ÀF`*hLiA˜œÕÔ"јü\rvcèN°\KünâµA¾¿°›ø] ÅTè)Þ6cáýj3™\ߨÅRgÌqñ5&ëÜLjLNJÕ˜,,ë0µ·ûF‘uຯ<; '¹®g{£‹½dÛ[Ÿ²¥rs¯J²xûNcÒ²u1»^æØA+Ÿ¡ËUg-§1Ùz;D-<-î”ýXG³MÀ5¥,yJõjLÉýëº:©3ÿÿÊ!@€@Þ  1ez´”Æ”t˜lnUÐ> Ök–T<SQc rÇtD•ìrIÉkVÕ˜¬qÓ˜¬B¬µå+A¶Æ×˜Re#¿ÙkÍdýXcÊ5™]ÐNU»M¦h÷Û¡î4ìþ®ìlµ;–ü½¥¾ä·ß]SÔšÆÖ¨´ íÜR–;¹ÊVºÀ™Þ¿ì € @ И—]C Å  1µxqz=%?é¦;]¢·äÂ57ÝÙÿèRc)ÅVF¡•,ÆÒ~ñrÃYž¸0ÌR2Ò’E]ŠÅ[JzK˜ÖSï0Z6ºäþ{ú¿ƒ÷A€ @ 4¦j„êz½u4¦Àaº±K.½qº#Ö8æØ„¡˜¬qªÆ~e“)©1ù¸\67­´E¾×éDU5&méhÚ›ZL¾¾ãÅ6#Åþ´ý[KÓNFµÐ¹nM2“Äu'ov]³1¦1ù»Òé™n¥ ´·ûû±³Š½d F×î³£h?&?(-XcV+¿ó®êºKÙ€ @ O 1õ v – €ÆÔÕÀIdO wÓ°ßÞYb ¹\oá‚^•Æ”0“*ZJæ*•°éJiÆRi)ðTR¼%›àXš0®’ºK×µ¶ræ¸ –eŽ‹Å^z9™<. _%\4Þ•ùa¯åüåÛ¬¨û2(Ë‚¢~LW|{IËÏ-)–¬&Ë"7¦4&ç0…Ò[—+Ía*t— ÅdÝÄRÁ¦¾¼é€«d—³žMs’Ô¿©ß&è¸×Óê¢ø¨?×zB-¨¾ýX€Û‰ÛÀú^­ûU½«¶¥S‚lþŒÅ²©±¶ÞwƒÜnMÓ±W]'ó~t ê!ìŠÊ4y†4& ÈËRgWa徭§Ã嘫[Ù]—u1'¡9à.o‚»XëgwÐ’û7DcÊþ¿+{„ @@cÊôhIÓÕÎaJ6N]®óXœàÒPLs—íSµîpø1#Gݛʩ²ÆäÚ_¹ÖæÃÔ¥1Yê4µÔ¬…¥·›Bdk*hLÖ(³¦Ÿk~º5j[Åd#×Ôzkšùâ˜ÆÛ¹NÉšØvVnÚ‹½dL\*: ¬k,kÁµ‹uÚ•¶´†§]ˆ«½„É”ég—A€ †@cj8b–%€ÆÔ²UÉõŽ@IÝ.Óõ¹Ô½;nß¼ÛžGÖ‘Ó¼½zÔO(nP¤T!œ’YJ•]¥ïüà°(7ÜÆ÷/»â†ï|ÿ0ý¶ç¢Ë­ ¾â‹¯cåß¿hÿ£O²e“–´fÐÐ,‰XP¼KÓ_|ÕB.}û{‡Ê[ª¬.¹ÀKGüèÄ'¦¾Äï Õ¥ñSøÝCætmR,+úS¹É åøyÉJ{éÔsöÃ,“Ô%-?òÌ‹*Zð¦È^J LaW¦+~ø%™L¡À´µß·îe&˜¬ôVcÚ½sϺ9 ½›ÍaÿìüHzÛðþO®™}àùTŽº|êIÃf=ûò[ ²eu:ý•Í'^=3H'†b:ïö¾yî„ÃO~pÆk‘Ɔ°šüÒÆ¯W3™zyQnJh/÷ÃÛ!@€ v%€Æ”iÍ5NcšûF·êùšÃä§gÜ2ÿ†G—¹\r×=²ôÚ‡—ZãT= 7_ñôóoXœà'çoüåoç¸qýÆ©"+¿¼ÉädšrV †äÎÜ-»6©[ãz·LôÑ[,€“[ïÖh½ _d[ºmü½iž‰…ε·«Ôæ°^Õ©&ÏÁ?º{£íÊíÜÂ&¥Bð_ÒÛÝ[´`—YîJý¾>ÿt!8LU?l@€ZS«Õçæ@cjkŽ”1?ñ‘‹“â‚•TÒ˜ä0íµ×^®;ÃÅVÑÄ,÷þŒO¶Á»s³}÷È_Vœ4¦Ø«+‹”,Üû©Å‰JÁB¨(Y9ù”³?óÙÿj‰áä*õ?æ¤G'>'?IËêì{dÂs_øò×ξèriL~¤¥Ï|öó*&0IZzzÆBUÇY1{©˜*NËë{ÉÆ}æ?¯lqé ãÂŒc®¨Wñß¾´ßOÌt—ÆŒŸ©CÈmr—>ýŸWŸcd/yêÒiç]vÿ¸ꋌeŽÛç‹û}ê3ŸŸ0{¹…_Úç ûÝóØŒ{±Ï¾ZŒ½TKø%/“~I Î?|æsQ ¹®­åRÈM/“BΘz«1I`š4tÏùÿyϘ“wÛ¦yvS…A˜Þ—½ôÔüMÁ]ñÚuËd²n⦯;â²)*ÖMüÛÇ—«›XöØØ¯6x²…bLÑ·g_ÜðõoU‰ÉÔ¸ëbÏ€ @€@ç@cÊ´Ž§1êÚëžÅÿSU™)èQ¹aD¬q:tô+Ö8Uůî_¤¢Æ©ºîšôê·Î›ðèìõ–Nîð˦ÜþôªÛŸZ©Æ© ÅdS¥€ÿþaec2eŠA€ @ 3  1uf½rU¨…S-”ئÅhò•& ÚâXÛ\,-Ø­²“f‰YXiÓ˜,¶¶] ¦»Å.¹ÊéX§[9Iëõê‘?>Á6(Ñ’ìOONŠ-›¥/¯¿wßÓBI6’U’±4ë¥Õ¶lŠÒÙ^n–\‰"-­ß¡ Ž:ú¤«oi‚?p–\%iLlé’__æCnùÔ¥Qc'È^ÒŸÒY$Ýõà-_ò«ë¬÷pÊüUgœ?DeüÔ—]Ô¥3οìâ˯û·/î'uÉÅ^=n¦Ö¨Ü0âAS—´7 ¼4ôº;¤.]8äZù1³nüÖw9þä3g.Ü`—^¥¥Ûî{ê›ß9D™N9w°Å^’½tÏ£Óï~tú¿~á«–<îüÁ×üòìAÃn£ù—úýäÌ¥Òkž˜¹ô¼AÃ̳9wÐ0^?c逳©<ðôóR—T®¼yô/κtÐU·Icòí¥™][f¨¼•²S!ü’‹ÃÔciÃë›w>28˜ô¡‘ÿÌa÷Ì<'0Ù#éÉù›mÝŽñó69dŠU´â0i¶«4&ë&>þª™÷N^Øc˶©§X’SÑʺ‰»¶Ô¤^ßÿ[?˜0ir{}Š9[@€ @ = 1eZO Õ˜d2U–™Ôr•¦Âì×8ýõèW¬ËB]r˜.—Æ´fû5c—¨}ªÆé#³×«áÆÇ—slÂÆé9·=ÅèW¬qjLA[~Ú¢-ß;ìèrÙå2¥ÈÎ @€ ÐИ:°R¹$ÔH ‘CÕ5ž›A ^5ÉiL“_Év"CI?Z¨’TÎiL¾ºÔÖ“õ»%‹HWJcúÑ éN’³”^WDœ÷\q9à’ /­xKÞÒ‹ËßrA•Ü‚¤%-ËXúö÷•œ¤å}¿ôµ‡Ÿší‡YÒJYJ–$N‚Ú@&“ü$EZÚ÷KûÉRzðÉY~ïÐ+o¸sÞ’7´FJg‘x¤pJ>1ëÀïzñ¯®›<¥B.ýöŽUôÒ¸) ž·R 7ÞñàÀ˯Sì%©K.gÜèq3ä0=öìKÚ`ö¢²a´ >ÇN>SYáî|†~[Î89L¿ºv„…\rEÓ­÷=õôìe.ö’ì%9Lw?hLò–ôû¼ÁרŸò–TŽýé²—ŽùéŸúÌçÌ^ú×}¿:nÆR¹JWÝ<ú滟ø—}¿:æ©çe/iáαS>òx§1ùö’ú=#iÑ–é‹‚>P^²ó–z£1I`zïáÁ>÷ÿˆ¦FjLr˜¾¼_à0)ü’K5h®Û‘C¦^tç‹¿ç¹Êaºë™Õ&ÔTWõ«ÊTG‡ž2vÆzÙc"/iÌ´uJÉçf»†”6O|“©ÞïU¶‡ @€j#€ÆT§·j‚ÆTNf’äޒ0Q“Št%“–T~sÃZÖdGIKú½pM 1YÈ¥‘cž>ñçgž~þe*oéŠëï”átúy—©„êÒ;ßúî!Ê §¨KrIËÒ˜$Á(ð’t%EôÑÞÔçø©ð·å‰SÎ8…\º÷±˜‚¨Kaà%M¬T:¹ äÒò@WºõÞ'ÕqhLD“ÙK’–,ü’–Çë÷¾_•½¤ßý¾}ðȇ§ ¾ú¶g]ªrðQÇßùÐT-ó“ÓÍa² LÒ˜\ì¥4{© 0• ¿Ô3iÜ#ãR&Ó˜®Ú7È.—iÙùè¥_Þï€ÇŸ™ëwaºÂI®ê)¾åÉ•ãçmxpÆk§Þ4ïˆ!SÌaRªX±úUMªiLÚ@ÝÄ.iô´uE‡)˜í ^˜LmÿÏ@€ @ 5  1eZ/¦1i|"óböR¬¸4sÃTèH)†‘.4N¥1™Ã¤8L'^-i¡5NÕàÆéóÖ+xó @cZ Æ©ÒÉÓ] ü8Áš†äÚéÉô«s³m_³7T"°nN¦Sv@€ú†Sßpç¨hhL­P œC 1±©÷í7ר` éÕ#~x|… ßÞ“œ”PNJ-’“$*)œŠ-HQ2QÉ\¥ÐOrÒÒv‹±$3I‰á¬H!ÒoÙKr•NúÅYOL{ÙrÃ)Ò’^ÒÆ ³¤ràw‘´ü]½dÒ’²ÅÉI’¨fˆ º-Ø’%ó–´ uIÞ’-ï#ieËG Š·$éÑg_”ºäB.iùžÇf(mÜ=κ„…‹²ÅIcúÆ¿¬"EI¿-üÒ¨G¦©Xø%Å^RÚ8yK*~I~ÒO¿ ‡éÜK‡É^Ò‚b/)yœ\%½dE˜ôûޱSÌ^:àÀƒŠöR8q³®ðK=ИøÊWÞº|ÿ’L&05¬Œì·×ÿ¹Ý‡f/EaºÂF˜ÆÍÝ`‰äTõšáúØs¯IW½c“ée‡žüàô×ÔMhLƒ&žºÖEìˆyš×ðû&îûůìþÃ'=ú†áM€ @€Ò 1ez_,Ü2(Õ7jèÊkü7ͱñí%C:lœN•À¤Ž kœÊarßBs˜ÔÃhL3׫}*‡iШ@cRãTÓ%w½‹ìÚéOÌzõþÓÿ²ùçÓ¸æ6{†@ }Mñ@€ÚŸSû×!Wž@cê)9Þ×ç²Ñ˜tÚÑ®]»´ PNJP×çÖƒÆtÅu·Wpôª4¦ØŠS¥„f’+NNûÔl+2–Æ>5ËD¥§¦½¬>¾©Ï¯Ò²”N)á´ ß27%ìT þ\³ý‰©/+Ò’t%õ žqþe*ã§,dÒ’2Ä)7œ¤1Ù”G½Ë—–x鄟Ÿiñ–$-)=ÜEC®Õoó–¾õC”*μ%•û4&‹åóÈ3/JKRѲ~OyCr)X–ºtÊ9ƒ”-.˜–ÅŒ¥±_ ¦W3,KÉB.9鮇§Yì%˧ù—xIÞÒ¸éKMZR¼¥s.vôONc/m¹qÔøï/ué77ÝoöÒ?|úsžºTkò¸r©åÆLXð·ÿ©Ê‰çöùâþŸ¼åÅÉ¿¿æ)ý}·´G³÷üòá¶Üœ±· :ôÔs.‰n¼‚ú¦[(0Û¤1ÍÙ`1·$0}ë¼ S¾eÝÄšêª LÆ´|ÛoÆtsÛóê&žúòæCMN Ť ¿cì´ýöÿÆâÕ›×où“©÷Ç @€ ˆSÖ·ÂÔו´´âíáÙ–Tê±Uÿ´íwÏë F­~’b¯H4+jœ*“9Lê‘Ã4äÞ…Ö8µDçÍ\¯Æé=Ï®9îÊjœª7àç7Ì9iµÚûÖÀ÷ÁËaRãtÒ„Éë_šóÑŠÒVv¬ÑÍŸÈ„€¢k£1eý5Åþ @èhL}‚ƒB % 1µD5p=!à4¦uëÖõë×ÏvÑ¿ý©…½*ïRÛuuuÙ6cÇŽÕûí§''Òï 4¦ko÷•£Ø²^=ü‡Ç{A’Š)ÞÒV!”Š¥EÉ…SŠÅUÒŸ¿½s¬ì¥3.¢ß¿½c¬:ûf)Xsþ‰JJúfnŠ• =ÜêwU´ ôpêtâ”îð0=œ|¦¡×ÝiéáÿÑ ³_Ù¨ý q³m”™$oIE/Mzn…¤%­9þä3U´ uɼ%å‰s—Îç”s;iiŸ/|Uê’b,÷³3ä-rö )J·Üû¤yK˜ä-YÂ8+‡(ÜOÏ·${ɦÙKºlIÒ’Ô%éJWÞéôŸŸlyß“óU´pò—tÄñÒ˜s^}A©-s\K©vI–JŠÌ4æäÝÚÉtö%áè2ÅMú¥.YQ(¦›Æ-wÝÄê#>þª™Aˆ¬°^ÔS¬8Lr˜®yxIj7±ï0Ùb25¨6Ù- @€rG)ë*·¼rYïuOLcr“;L¦BWIÐb}jŸjŽ"0¹,çr˜.»w¡9LÊ%'iìŒ×¬qªDçgßú¼ŠÚ§Aã´+ˆµì§“‹¦é/XËTå£ÝÊüJÙ!JÜt · @A©3ê‘«€@O 1õ„ïi NcÒÙ 8Ð4¤ØÉÕÝÿÕÝÝÝ—Õ£“Æ4ôÚÛ“š‘[£Wë\… ’/Eñ“,ŠR!’…SrEiàÓƒŠ“ç¯”®4~ê‚ÀU -%EWÒšqSX28W”Î,=>yXzî•*’–T”îú>3g…IK*–ÎO÷س/Y¤%¹J¦+Y1cIñ–f¼¼Áe‹“·¤`KOzÑRÅY¶8r顉/ÞýÈôb¼¥eÛôç”×›´¤…±^p ã4Ãrò ë|ú%Œ“½¤¨K<õ¼~Ë[ºó¡©*н4+¶s˜xéþ§æ[Ú8+#œ¢8Lši±—™²äö§<2eñ}OÌë½½äĦz5&ëNݶ`ÊõvYR¹†iLºÇe2röÅîÖŠ·ð& o‰ ÞƒÀZa-[.9ç0ÙT×§žßÅa*t;zI‡ “©Gß+¼ € @H#€Æ”õ}Ñh))0¹+Éd½%®ßCíÓ‰/¼!KÉú+zŽ¢//îv¥ÆÏÝhSÐ8]Ú}פÕ*%¹Îm¶¶yÒaÂdÊúÞaiИ¸/ @èhLR“\ê'Ðà¡êúOˆw@ ukLÙ¶ö"é××ÜsŒü?õª:æ*là^rZ’?©¸úI®Äü¤ØŸÖåç•ÀR²$ƒ³Rp•lÁRÂËÊ@dq¹áœ®ä¤%ç*Ť¥0O\QZ ’ÄòÄYocIYt>ÆŠ¯.I𠤥 l•´dE}”ÅRP—L`’ºdS0] ¤%+¡ºTŒº”Eà¥Ô˜L=Ó˜6m ²+‰äÔç•Иvoï^rß°U§$^L]YùÓ “é—g]lÒ›Ý9‘ÀTp˜\-[múÝĪ s˜Ô!U±¿œÃ„ÉÔG_N€ @G)ë*mœÆTA`ra&S¢qLU&Ø, ; ÂÎ(N°×8-ç0%M¦lÛÚYWûkChLmXiœ2 @©И¸1 _hLù­û¿òÜiL¿ºæ¶¸xäùF¿v[Ð+W*!Õh#¥¸Jq?)Pœ¥TATJq• ;t%ÅlOêJQ„ž0Ò’3–,ÒRi)œ1™"-…1~\©Ó[ŠBÇWS—2ËW!œ½Ô+ɾ>Üû’˜8 Ÿt¥7æMŒ­ß¾ºK/õàÅL¦‚èim~¦ –à 5íÌâ0yÝÄõ9L˜L=¨#Þ@€ Ä  1e}O4HcÚö»çk“ú[„É¢.9QÉÉi¥â6ÙW‘f—Öò$“éäÓ/²LIIq˜¢:"S-4Ù€ @h4¦¬Á¶”Ƥ‹“ÉtÐÇú)ÎÃŽˆh~”5NcA‚Ÿ˜õê~ûcÒô\NóÔ…÷>üC ^ÚÚYWûkyhL-_Eœ  @5@cª›A   1u`¥rIÜiLƒ¯¼ÅwŒb²Ñ +o‰fšiTK sº%Kz–·dê·òyß\2¸ \˜/,µÌz ­”„V²äbµXŠU6– éáÚ(ÒRå8Löjæ“å3Iê’%u¶JW²¢—ô§t%½$I ’œ´FêU®©ê—“L¦ŸvQÁTóúˆ-S0ÏuË´ðUÈ%W•'@€ @Ù@cÊši«iLº>3™ 3©‚N‰’,祉Î{ì0é@Íikg]c쯵  1µvýpv€ ÔN©vVl N#€ÆÔi5ÊõDr§1ITª éU›JØ“²t[…änÎIŠ-TV”J#*Õ&*• ­´µ^])ÅXZ´ÙÉ1µHB­¿M¶ÓŸvïr•$0ÉL’¥´µkŽŠ¥I;ý6¥ÉrÏéG ú³ÆPLî«K&ÓOO½Ð4µ¨fó\q˜ø¦‡ @€úŒSÖè[PcÒ%ÊdúÁÇxSI&ׇЇ©™mí¬+ýµ04¦®N € º 1Õ…‹!ÐQИ:ª:¹˜"ÜiL—þfx9£Hëõª4¦ $_Š<$ ˜T>fR,’B©H©–XJ.ºR—™+©%Ì—Z©$œ])ºR9¡*[©É_-2™~rê…Aî?˜,Ó¢(S“«ƒÃA€ @%И²¾!ZScÒUÊdúþáÇYäüÁ^ã´7SÖÙ И¸ @èhLR“\ê'€ÆT?3ÞÑr§1]rÅðrÙÙ´^¯ºpè5$qsÙÜü…­Éänš•h%%Ë[le×ÖY•%/¢R-¢Rº«˜.ÅRH=Öú‘“q†m­1é+&0™N¹0)0á0µÅ÷/' @€ N&€Æ”uí¶¬Æ¤ L¦ÃŽQã4œ(Uȇ)ëýeD)#ì€ >'€ÆÔçUÀ @ Ï 1õzÜXyÔ˜œT”\ÆôƒÃƒXèµZG•ͤšœ$?¢R¥@J.âNÐ-è—EA/¡•0O’W©í©Ý5&}=Èd:é” b{ÇØiûíÿÅ«7¯ßòQ…²ûŸ4ö †½C€ @¹%€Æ”uÕ·²Æ¤k•Éô½ÃŽŽe¢ÇaÊú.`Ù@cÊŽ%{‚ @ o  1õ-޾$€ÆÔ—ô9v äNcºxèðò騶êU „Þ‹²EI¾‚<_®„ ¿ª–¸œd¢’§(U²”Jg:Ö¢ï°èI_2™NüeÑdÂajàW&»† @€j$€ÆT#¨š7kqI×a&“ëpÀaª¹nÙ°/ 1õuŽ @€@# 15‚*û„@{@cjzâ,ë&;iàЛ+EzUQЫ*G©¤{HeÂ&¥ÅOJ‹¢dÙßò÷­¡ÆUghLúÜ;“ ‡©îoAÞ@€ 4‚SÖT[_cÒ;“ ‡)ëúgY@cÊš(ûƒ @ ¯ 1õyŽ ¾'€ÆÔ÷uÀ4„@î4¦cO>ëÆ»ÆedJ9ö§g}yÿS_Š­¼aäø2eÜ #«—ëGŽ£´AWßñÿý/ÿWå3ùüûç‡ÆOöS³mÚ¶«!ÇÞíT&Ó¡?ü ¹äzG‘wC€ @@cʤÛM[hL:[3™¾´ß—&M¡r¢ó÷>üCÖØj&€ÆT3*6„ @ Å  1µxqzh 4¦Âe×}I _Ó£>z`霿ì³ï—þiïÿ[ÉŸLà+ûðéÏ|¶ò~óÀï¾´t}ëkLú"ùí…¿\¼bCånâÝø¤/¿r86 @€ hLYWt»hLºîŸþêo®ø'8LYßì/ShL™âdg€ ô!4¦>„Ï¡!ÐÇИú¸8|£äKcJR¬Ü§Æ«H%Кјöüéã=ÿî½É·W¨5¦F}•²_@€ @ F)ë[¢4¦Q]{M[{Z…Æ)q˜²¾;Ø_ýИêgÆ; @hMhL­Y/œšA©”9F@cúSõhQiÖð=ú_%“é½S¯‡©¾b9$ @€rK)ëªo/IgûÑî?¥6Nq˜²¾5Ø_ 1õo‚ @   1µ`¥pJh4¦&æ0Í&€Æ„ƺ ´¢Æ†b 4&•YÃÕ)ë,Æajö—+ǃ @€@Î  1e}´‘Æ´õ£9;?^#I“ ‡)ëû‚ýõ”SOÉñ>@€ZS«Õçæ@cjkŽÔThLu+,õFîaûÎ#Њ“…b²"ŸéOû&SS¿V9 @€ hLYßm¤1ù—î›L8LYßì¯Иz·B€ ÐRИZª:84•SSqs°æ@cBc‚@ÝZNcòC12é[ÄL&¦æ}¡r$@€ @À@cÊúfhA©{Ww¿ûûU½P3™p˜ª‚bƒ¦@cj*n@€@  15.»†@‹@cjñ âôzJ ïÓï>þõ£U(o¿÷ûím(9! ê~çý*5®Û¦§Ÿ¸Æ¼ÏÅädÒÁþã“¿4æì€ @€@EhLYß -¨1]>¶ÿcýwýq—•u;ÖéwWw—»týiË ÞzÅ_Ÿ5öú  1ÕÏŒw@€ КИZ³^8+4ƒS3(sŒ> w©sHdK ŠÉ È”í¡Ø @€ Z  1ÕJªÖíZMc’¢$‡iÀÄs6Í8c -O\;ÑÅg6˜Š.Ok´J-¡›jÅÁvè%4¦^äí€ ´ 4¦–© NM'€ÆÔtä°9ИšÃ™£@ a’¡˜J25ìÀì€ @€@yhLYß­¦1éú¤%YŒ%-ŒX4B úS>“]ºô§“™´Fž1™²¾/Ø_O  1õ”ïƒ @ Õ 1µZp>h4¦æ±æHM%€ÆÔTÜ (Љ€Lƒfw€ @€@ИêVuóÔ˜ö¾mo;m·àKK¶R¿%9IiRqÚSÕ‹e4œSÃs@€šD©I 9 ZS V §”4¦,(²´›öèÕ¤¡­p.œ @€ whLYß­¦1­Û±Î’Ä)À’ËçD%ešs“ÒÏ ‹ØÄZ‚SKT'@€@И2€È. ЦИڴâ8íjИªâu´ 4¦v©)΀ @y €Æ”u-·šÆdö’%ÉI Âd—«5c—•äüq*Zc ÚX¿Î˜5öž@cê)9Þ@€@«@cjµá| Ð<hLÍcÍ‘šJ©©¸9H©pÙ5 @€ P'4¦:UݼÕ4&°ì%K*Ý»ºíü¢I+%6iAëm¥yNÒ›ª^#@ yИšÇš#A€ ÐXhLåËÞ!ÐÊИZ¹v8·^@cê<Þ –"€ÆÔRÕÁÉ@€ @ çИ²¾ZPcÊúÙšH©‰°9 @ %€ÆÔP¼ì-M©¥«‡“ë94¦ž³ãh-hL­Uœ  @€òM)ëúGcÊš(ûË74¦|×?W@è$hLT›\ ê#€ÆT/¶nhLmSUœ(ª@câ @€Z‡SÖuÆ”5Qö—ohLù®®€ ÐIИ:©6¹ÔG©>^lÝ6Иڦª8QT!€ÆÄ-@€ ´4¦¬ë¢4¦Q]{él³Àþ )4¦Lq²3@€úSÂçÐèchL}\¾QИE–ýB ÙИšMœãA€ @å  1e}w 1eM”ýå›S¾ëŸ«‡ t4¦NªM®õ@cª[· 4¦¶©*NU 1q‹@€ @­C)ëº@cÊš(ûË74¦|×?W@è$hLT›\ ê#€ÆT/¶nhLmSUœ(ª@câ @€Z‡SÖuÆ”5Qö—ohLù®®€ ÐIИ:©6¹ÔG©>^lÝ6Иڦª8QT!€ÆÄ-@€ ´4¦¬ë)k¢ì/ßИò]ÿ\= @ “ 1uRmr-¨S}¼Øºm 1µMUq¢¨B‰[€ @hhLY×SÖDÙ_¾  1å»þ¹z@€@'@cê¤ÚäZ P4¦úx±uÛ@cj›ªâD!@€ @mC)ëªBcÊš(ûË74¦|×?W@è$hLT›\ ê#€ÆT/¶nhLmSUœ(ŒÀ¼+LÐïƒ7×Å€líš³ä¾aP‚ @€ ÐИ²®4¦¬‰²¿|@cÊwýsõ€ N"€ÆÔIµÉµ@ >hLõñbë¶!€ÆÔ6UʼnB@ä*IcÚ½½;IcÁ-W=>J€ @€Z‚SÖՀƔ5Qö—ohLù®®€ ÐIИ:©6¹ÔG©>^lÝ6Иڦª8QÈaš>°¿ŠDCÒ’Â/½6y¬‘Qˆ¦í«»’ë哤%½ªtr–`έזŠÌdk™©m/‡ @€ÚÀÒ§Ëv¥é%~zG •5&]ÙŠ·‡—GÙ±{iï.wC И•]B€ ÐL÷.ùëÔ'ð±Ëÿ¾™§Á± f˜5<½ï嬿Úóá¶fŸ ǃ@c 15†+{…@˜«¤kAN’¢.é·iLiik×ý©õÚÀrÌiY öÛe—kÀ©±K@€ @!Ô€LZÉO¯ ´¸ÆT. Óô×êõ¥³4€S ²K@€šI \@&B15³8ú€@¹€L„bêƒÊà"€ÆÔ(²ì™ðSÂ)‘œŠáÿÖŸŠ½ä^²л´Æb2ñ@€ @ ±R2Š) è-®1éS2Š)‹Êg €ÆÔ¨ì€ &Hd"S“«€ÃA o$2Š©oj‚£6ŠS£È²_@€ @€@ Ä2Š)£› õ5¦d@&B1eTùì¦И•]B€ ÐdÉ€L„bjrp8ô d@&B1õMMpÔF@cjYö @€ @È#X@&B1et´¾Æ¤ d"SF•Ïn@©PÙ% @Í'àd"SóùsDô? ¡˜ú¬8p£ 15Š,û… @€ 䔀 ÈD(¦ìИü€L„bÊ®òÙS 15*»„ @ ùü€L„bj>Ž>#àd"SŸUn4¦F‘e¿h6›öœº×žIC›}\Ž@€ @ FÀd"Sv÷F[hLº\‰PLÙU>{j4¦@e—€ ô  ÈD(¦>ÏA!З, ¡˜ú²8v£ 15Š,û…@³  15›8ǃ @€ÊP&B1ezƒ´‹Æd™Å”iå³³@cjTv @€@Ÿ°€L„bêø}IÀ2Š©/ë€c7Š@¾4¦¥K—­øs饗žvÚi•·áÕ#ð³Ÿý¬ò]{íµüq£>‚îwǦGíõñC2Ü%»‚ @€ Ð3›&Ú9ÿ¡ž½—w¥hI'?ñ…Á[ß[H=B ¥  1µtõpr€:Àœ9sªk8IÃs¤«ü óuÂÍÑ€k¸æÁkÀ^Ù% ÐêÜyÉÇï¼ÑêgÉùA ~ùÒ˜N>ùäƒ9ü¢K†X¹0V.òƒƒÿçÙç‹/S¹ Y^vAXÎ/Sλhpj9÷¢ÁQ¹pð¹^9çÂÁ^tÎQ9û‚AÉrÖƒÎ:?¥œyþ¥Q9ïÒ3½rÆy—ÆË¹—žqË%§Ÿ[,§sIj9õœK‚r¶_.>õì‹O‰•³.>嬋Y¦ 8óâ° Œ•_œ90(gÄËÏÏXRNøóÓ/R99­üì´‹RËOO»((§^+?9õBWúÿËÿýoþÓON¹På¤x¹à¤S.8é—üíßJíú?\Í~ÇÔ©S¿¼ßG}·_{HWÍÆÃñ @€ æØ´i“š'xàÎ;›wÔN?R»hL[Úgß/uÔQ4N;ý–lóëCcjó äô!´>= {üOJ†¢.â?}ÿàÃ4 •rŠ 3ÅF— ƒJ)ÃI±Q¤ØÈQqÀ¨8TÅÆ†J‡„¼Á ÄPlÜÇî)â‰îÄÆtl(ç¿þ·>àÀGpâ7|ý[?Ð0_ëW}óÏPXÔþ=ztóÍ!>$ ÓúîÃ:àÐ #;iøí£¶nÿ½Ê–¨ìÞ²½Xn¾}ÔÑÇ´ùÝÝ®¼õîî ¼£ò;•7]yûwoxeÓÛ¿Û´m—+·íÚØ• Ý»Âòц­½î•õ[>råµ-¾¶9*ë6•·>\”¬¬y³XV¿ùÁê7¬ì|Õʦ ¬òÊÊ;Wn|ßÊ • QY¾áý ¼þþ²×ßseéú÷\Y²þ½%ëw,y-(‹]Y·£«X¶¿²¶X­Ý¾hMT®y7(«ƒò²+¯¾» *ï,xõ—TVEåÅUïeeP^Xù¶•çWËüoÏ_®²Mež•eA™ë•9K»]yni÷sK¢2{I÷ì%[g/Ê,Wº¶Î,”][ÆNZð·ÿé¯l™îÊ¢-Ó¢²yÚ¢ÍSnÞç‹û·¾Æ¤Tÿþ½C®êqïãt7ì “C€ @Õ „S¿)s—>6i.&Su^5oÑ“&ÕþóK6ޏoÓšë– û‚S_P瘀rE@OÂOL˜E¡ü±§›n ¤¢Q§ÂxSl˜)6ºT²±$7d£H…ñ£häȆ܀‘Ɖ¢A" ƆÜÀPa<È ÙH² pè§8ècÃ=±â±Áhdgé6Ó±7”óƒÃ¹øŠá…œ-¸‰Æn C6ýêf4¦ä‡HL®¼~„jðˆÉ”«/.6çŠCô¾s~+tèåçNc’¨´y{ÑRò%-ß|[ðÔXV]’ÃTj/ÉdŠÛKµL[K¦¤Ã L t˜–{“d¦R)r˜ŠÓº‹=‡©+æ04¦…‰GXïA6x–­Åaª[cò¦à©·à0ùϾ¾Æä&-¤hL‹¶L÷¦i ÛCc²T‹^íZ¯í¸“©C¿¯¹,@€ ´>9L_Ù¯ßÔ¹ËÔÒÔ@È#1™2«´Öטä0©ö_X²‰ÆifµÎŽG©qlÙ3 „¤1›0-6å?ýöֻɟ0ΖæÉ‡#Mµ8Lë óáÝLxÓ˜l¼›ún“›ñîÏu÷¦¸{“Û£!¡hB»›ÍnóØ£Iì…éë6qÝÍZ÷5&7SÝטŠóÒÃTIÃ7IéB4¦Ä‡+p˜naÃ| Lp8&ß?Ȇ†óQϹ¾ÊÜiL7Ý6*zLŒb,#-)ØRôÔX>ê’E`J‰½”j/UÀT)Sä0Ń0â0EA˜Â8L%A˜<­¾\¦¾p˜ J~!SôDë¹ùMÅ43|¶hLB1µ~4¦àÕ÷]´z›=§òÙº·ÝCL¦\³sñ€ @èÃôµ~Óæ-S«Ó5O™0‡˜L™TG‹kLÃôµ~/.ÝTÒ8ešM&uÏNA©TÙ' xô üøÓÓ é>R2~h@êÇÇžä9• LA–—âÃâ0¹Ì±œ©“<*†b ³vX(¦X²ŽÔPLnN{!S© 1Y(¦`úºÓ˜i7B©˜jâ1ù¡˜")̧DcEc*:LʤL>²g 1Å>ar˜®ºa„Õ¦iLJ«rXÿãˆÉÄW:›@úÐ0­ïήõü]]î4&=ÃyâLxwO~¸XÈ% ¿äž&-y\!s\Jò8=e®÷Â/EšÉO!W°æë˜ª$’+ä’‹„¹äЉäA˜Š¹ä²ŽÃ”‘Ãäõvc¼y¿»B:¹ÀaJjLi¡˜Z\c²T¯¬Ù{NU ×[ïÆdÊß7:W @€ ¾#9L󗹿‰Í²èZ·ý¡§1™2¨˜VÖ˜"‡iÙ&¿ö5ˆBã4ƒŠg "€ÆÔ °ì€ BiªË—Ìõqã-Ò˜N,9• 6Ŧ¸ÃT´ö­ ‘œŸN.š_˜Ÿê0¹¡¢b(¦D:9=Æ[F¹*¡˜B©öPLs]F¹ÒPL¥SJ(&4¦¤Ãtõ #/íõ÷-' iLª2L&¾‡ ÐÁîàÊåÒ|yÔ˜bŠR¤º¿ÈIþScIâÊÞR"ê’ ò.Kq¸ð¡Óä_ ÓûS˜º¸`/yQã´Lõ LÕ¦ð!µ(0EÝÍÁCOX¢ÖØck˜ 9ž¹4—\k8L‹·ÆÒÉ™Ë_ŒÆTÆa2é¡ñ“ýÚ|wçZá{Dÿ¨¾óýC»Öl ŸS£ÜÕî9UUsËÝ|è»ÿûz϶««Ë‹ý¹k×.-ØÿªÖë§ÞC$·í¶Þ®[·®—{¨÷ˆl@€ 8æ0MŸ¿Ü¦wû³ƒ‘5ÛÇ>õÜý¾ùÞûï× Í5Cl¡7­µ*Ýß@Çòÿ´Qìíõ¶AʵžbÇ*w’-«1™ÃôÒ²M6ˆ’¬}5N9¬WÓîîîmÕŽ3dÕ2uð]CØÅn¿ªw‘öº5Zu!îµìªö;¶ÞO–moç¤WgO»Æû¼gÒ“w¡1õ„ï :Hczì©©©)>løé†Pc**ÿцpt)6ÆT6Sa8ÉÉ­É%sɉ;¼8L•¦âÀPqHHóáH—NnµÆ} C?‰PLϯxÛJ]¡˜|Éf¡Gi4‚PLA4& Ö(Ó9±tèí£?þǟ먕NÙTq˜®¾ñe LÎ!‘v¦Ê:´ÿq#GÝ[ï妎UÞIò±¹ÞƒÚö-÷¬Ø³Ëà]h0Ò¡á õí+Œ…¡áÃëntûºÁTŠ»g°¸i¨›p ÜiL•б”œœTXðŸíÙ±4ÒRl©Œ´”ð–Âðžå쥷>ŒÇ^*o/¹GÏà´4…œÒÉ9•>J!—©'S8e6˜\àÐ4‡é]{x-¦CІ°…€¢…˜¢E%¿Þ\r½ŒÃTÆaÒsðƒ–T.æ0…Ä®$5&ÝBMøpV>„ý£Z¼öí Ï©ªˆá£;èúþ]éaqï½÷ön6L ýŸþýûkyâĉ¶^?þö±?kd;hï²Í  S8p v2gΜºÞËÆ€ @€@/ DÓóËm€¤˜Q®08öXýîƒO>·ÿõ™Ljžìµ×^Ö ±Ÿ#Fèlõð_ï9kWj5T~—öo½ðjbhÙoÚhYg2vìX·k€¤îPm¥TÕ#ÙzÒf:v¥s«zz­©1™Ã´`ù©Su#¨Ó gS±5ÂR´㓬 ž5EËÝ®!l»µÛOíͪդ[H[ÆvëßÃv÷ÖrCV½Éu2õºtÉÓRÛõåxºIòôÊ}0ëºÏ«^uf 1e†’A€@:iL<9%Êì‘6Uþ†áwýèØ“CNNÓñ˜bYä\¦@` ¦X¦pðèýhب|.9Ëí'èˆMk/:L=J'e” Ók¸trʰ¡¬…Ä[•XC“Ê÷£¤r願ÊiLíþSÞnAs˜¢ÆWÚ{?ô¨úL&¿ñec@µ4»b͵ׅò­yբϊµ_ [B Y74l-VwÉb³.±WÇa°¸WøZï͹Әô\è%€ó“ÁŠÒ ÃGº§Fßywò{Ñ‚[*¤%.d‹SÈ¥òQ—¢ÀK~´ÏbÌÏBì¥Úí%ÿIÔ%6É•¦KÉ"—©D`Ê.“VôE/Aò +#1ßÓóƒdÉ~¾äy…gÜØ“nð°[xÞ-›K®¼Ã$—ßiL¦ó[ñ¦ÔhL}®1¹T…A‚”Ù®öœª¼Ô7Ýõh]&SÉÿ¦~yû3ùϬj¯nê7a5&{Ƶ}º³j½/[΀ @I î0ºÑ]F9› lÍ“ž˜]—É”lžÄž5:ªV€ó3’¢†>1ÓHÛ”kÅhãT¹$µõäÔ¨ vˆy jLÎaŠ ¢¨ö-Ÿ…_û7×Ù8Õ%árbPÌ3k„Æäî™Ú[¬É³•{§îTW=hTõ®wƒrw]…në 7j¹¦Ö×~Ÿ×{ =ß©çìx' ÔD Иž˜R: Í“·á§ë5 ủÉäUì%?SY©Äa F‹ Q35N䆊ãè0­³|Ð%©9êq˜ÞÑXî ã0=óü9ê.œ¯1&åÓ5¦›-“†Š©8j“)o“¦a7Þ!M->‹ t‰ hTîzL¦XãKá9ky®e›ÔŒÉôÖ¸kÅgÅš>ålæhèаiL®MÝŽƒÅÍ»›u¤ÜiLz.L:InM¹§ÆXŒÊ(C\i¤¥¸´¤´qQª¸b¸¤·KS—*Ç^*o/U ¿d)ríÙ4–B®—ÓËQ¦ ‚0•u˜ ¹˜Ò¦@Ûwæ~àïwù¹ä¶X$Rÿ!øÁ‰A4¦ S jLÞ?ªÄsj¡así9UI©oùHí&S/5&=nºi²ZÖ¿==ƒê·EÎO®‰u [‡¯½Åâ*iÙüYíÖžem'¶Y¬“T/5h<£YßÉ€ @íD@ÓW¿ÖoÆóË­½\Âk ßûÒ«AódôøYµ›L©“j˜bâ RŠõÁiKüÆ5%´“˜Mb~†í_Ëþ«êÅóÃ/é%ÛÌoæX›E/¹·û ­×N\{Ç÷Z¬Ê“ç»ZMcò¦QÂÚ¯«qꘘ1#æ÷±jKëfµêóo ^²ÀWÚ›5Qõ§Ý*¶s­täO+×[‹ËBY“Ó¯YSÖÔ€uïÕ‚_wÖ†uéä쾪pCº†s¹c¹Û)Ù|»jÿ¦•>å&ÐkAº=»öµÝó®“ÚnÑäÇGGtŸ,½×.9öéó?˜1°>ª÷yó¾јšÇš#AÈ)iL?19u@ʆœ®¿y¤K‘æÒÆ•Œ4EcLhhÉ]*¤KÀTs¦õÞ ‘Ëα6Ê%'=c‡iٶذÎì%ÝÅÑœp(GÓ@_còÒÉÙäs4¦Àaúmà0•âîÍ! †‡V¾sð‘ÇÖ˜].Uc²‡X÷àgc4å›]cJO†ÉæXãÈôqß-ô¬˜Óï-.»E TÆà«»7CÃ6&ë>€®…èêZ Ú¨5X~û×õœh³ä—€û&q U·ÆIÖØtíe#¶&¼kfºÇ®!›HÆ`q‹ÞÇužVþ4¦›G&œ¤ày±ðÔx§ž‹ÉàJC+Y€¥])n,yÁ–JSÅ¥…\*AÉOŸû`ú]Æ©s-÷yåOA–¯¢1eI“}A€@ iLŸ*?mþðº›ïüáÑ'–OëªKÞSÜ^ G”ô0feåÆtÉeíÐ ‚•’ L¯¥aò¦pB‚MœV€UMNЃ}”#x¼¯!Se‡©RÃiLA(¦‚ÃäÜä\c*q˜6¶,°–÷EÁPÝ÷pÅǪÑdJ6¾¬µ¥':÷dhC0å›í)ÚeS˜ýÆ‘=…úŸœÖzVä[ -CÀ.(ŒQ\½´¡a¯õ]óа5 cyxüÆ©µò\šu7;Hïò»2üNØ—€k[S×¾[¬nßNÉ[ÖÇš™ÖzMm)3XÜ2wnoO$w“ž ”t’® Ÿ£Ã’“\y+­T]©è*E"|š±”¶¤Å¡®äJš·ä?q³‡[­D!@£@ ÁW•_ÜÃhì‘4~) … 5UÓçÚÇŒ{›D[úØ=¼úϯÅr…~j (”½Ê"ç²&Çr'ׄIOÀöü@éSÉDr­©1¥ý£òžS“¡˜¼çT¸ºñŽšL¦ “û7æ&nÚ?›ä³¦Öû½œúÓÞâÿ3‹õÚ›Kë÷öºYgÑêÿ¢vâ*üÿyv·eo¿y? @€ P‘@‡©´Ý2ʹnt%˜¸ïñšL&kž˜Œb?vR.«:­Ô±4ë>sG¬©â[#¶“d¿yLcR‡šíDñ¶à÷ÙYÄveaoôvkÑ8)ÖêñOÉ:éìí~O_ê­£1Y¦‡©ü J¢ökmœ:Â®î  µ@cšš­uŒÚ=ãš™®:lc'¥ÙÍ`Õçî1W•v¸˜ÆäOò‘ig!¸\ÝY÷®»gÜz‹È¥-õj¹2ÖεCÛ¹éÇŽåvh'ì‚"».àØ™¸û6y¯Ú’ôìüÝ~ü[W·ºQŠ}úÜÓ®ÑNX îÓZã}^á#ñKhLew€ ' iì¸ÉeçÆoþðÚ›‚©µÅ´ñ¨K±&\©‚½TB*ŒU˜vtÕ„)ÕaŠÆ}äÊæ«o‹ç’«ÍaR2ïDc*q˜A˜\ɳÆä9LQ$T jV³•<†•o+ÁŸRûtDõ˜L~ãKrþŒ÷8ª§;³öS›cÏÞ±‡ØXã(Ök¹gE¾Ò ÐR††ýÖwFCÃîCmÚ¢k!ú­Qû[KÙ¾"lÄÖ%…´Î ×L¶d­…¨·X¿þtA‹íî4Ü—‰[ãïÙj¦\K™ÁâÖ¸s38‹ÜiLz.ô -Ý[±èÕþGŸ`ZR¬øÎ»UòK`Á»ò†\%+¥ÆR™`K´ä™ò©ÞROÔ¥BDÐò™ã‚©±)öRA´¢ÏYì¥dø¥È»÷òÇü¢À´2šhë&{uÅeG.›BnÙ¶¹aò8Wž+¤L–ÃD ƒŽ–Lmßâ0%³ÈÙ°ùMcòŸƒ“Ëû|qÿØœ‰MÛ—¼É?UþQùƒklbD8B3!”…:|N»lÛõw<\Kv¹¤`dÿ{\ç¯=ÎÚ—ä71ÚuVÚ¿¿çÔÖø íO¥ç»·zÕW}õ§í·Ø €&W ‡ƒ @€@> Èa’Å2=Ì%ÃT¡½0Xm@5OîylfÕìrÖôHB¶¶†…7W»ÀfDhcËœeÛÇ‚-e¢1i·:f(ZŸ¾ëÅ3Æ·m¬[ß?y'‹Øéù]ÿjËÔV¶E4&—K®¾Ú§éƒ[õ7N}°®kŠZuû'±Jñ«ÃÞëß-Ö\-7ãÞëßEVãö«ë˜ÆäÛuÚ2æ ¹›Äîÿ¬©›jò%ï"]‚%Ôó?/¶Ò€.0†¥ÇSòÓ§ãÚÑ­ƒãîíïóæ}©¢155G‚ SÒ˜||rb@ª8ödRéƒM…a¦Tu)6Þ’;'í% ÕS1SI‚›Ü¾Ð†A˜lÄÁ²¡ŸÒŸm‰Šw¬,­˜K®0 cC9Ò˜.’Æäâ0•:LyN*8L7rÉryC1•z ÉYVUM¦XãË>Ör±üPö£95jL˜í%§;è(-÷¬˜Óï-.»µÔ?4\ ÅT×аûP뮨ÉLÖ8}m:µ1õÛÒ¸˜Æ{¯µpÕi£CØø¯k-Zó¼FI]@vž©ûg°¸µnâ^œMî4¦k~{gRBrkôjÙ§ÆK©Œ«T>=\Û3!-%SÅ%½%ùÓ^J‰ºä©KUì%/ð’Ez÷Ã/Õ`/ySøä ¿d™R¦À^ :.ëH!D`ê…Àäg‘󟀄iÌ„öИbIOíöˆRË ”†b žSÃÃu#ª›Lêy´Nyý'pÝ ¾Æ¤—´ë ôŸ5]w¼´þ\ml±ëcküï.7`Þ® ]è?Ûm Âž•ýµôû÷âÛ’·B€ @ S”Ñ J7z4ËBÍ“»­b2YOºß3eýjX„$×r±‰6ÕAM{£ßTqvHÌñ+Õµ>üfH¬3΢.Ùi¸É–7Á^²ž;³©, ¬,Ѷߣç¢Æ¶L+hLÎa²¬%ÉÆ©% úÒòY³˜ÂA”§F8föX¨®­Ò­ýhÝ þ–U5&kuZÝYMé-Öãé†p\•ÅÎÄÕ¬ÛÒ¯ëXO®3~´gë«­ÉnokJ[Œýä±ÜMk[jaÒï˜Æd{s÷¼b÷ª¯1Åí|ì“¥÷ºQ«ä§Ï}0ÝÆîì„k¼Ïýdc—јË—½C€ÀiL<þl…©aနKŸŸHåáÒÆE#J±ô¯CÉñ£%…a#Åì Š—£#™#M`ª3‘œç0'¨/é.¦×X¼u–•p.º?=И~}³Òhhì&5‡F>£1ÉaºÚs˜‚l-aE§¤“‹¦¸Óy»Y–çäG3rÔ½å>œ1Éž±­ÙeÉö(hFS›ý§ñÊÌzUû¶AË=+ò¾&à —›?¦Ö·Æ÷í«[y?•ôÓ ƒ]GëÛï Ðg_a€­=èÖ[ËTk,°uth!Öõ;=b_Öt5¨öMbcÇúÓ†õ[X_Šë]q'k“êíåZÊ|™ôõ›Ùñs§1é¹°*ÉÅL*.O?>AQ”R)¥%ƒó›¢4gáÚb0ÏPWzîåµ`É•Ù/¯ ìx/IÜ3³^ytâs*“f½>‚DO!•³ÅE9ŒS£.…£Þóhx©¼ºôà³"Å>ü¦?e¥3~¦•0çq1yÜc“_2uÉì¥ûÇÍÊãA¹/,1 ß (Zj/…O´*c'¾¹ù…ø¢ÉÜB¦ üR˜*Lu©-4&ïUpÛÈÄzúùMO=¿Én€BÃ#ê&ž¾hs,Ó3/½i¡˜ì9uö’­×ÞþPÕ˜L¦ÐêÇ=Gê?GÌ`µ ¦Z \o“þOØ|Vý¸7&׸/3ûïeÿ¥ìÇþÓø¾íÇþ9Ù?3ׯJ4¦Ìþ-°#@€ ”'à&7v¢6¬Âè>5“J0&‰,–5調t¥²«m8ó•-QódiawÔ#3*Äd2çÃÿ±FM·pÍ›)h 39´Æ¥¾²«qM×qf³ýku­äT`×ð±öˆ½Ëthk¡¨#ÏÖXÿšõ빎–ýÖS¬¥SKG[ŸkLžÃ5NÕ“àfù[-¦Xœà•o?ûÒ›ŠÉ¦*ÕÒ85žåš{æ!©»S¿Íãñ·mýé¯qç*ºbõãš–6c' `ÜinËä™hŽëš®®®Ý Žk™É”zªÉÒºwõãy$e;·»Èµ‘ý“qG÷û‘“÷ªíÁ]¦;t²¥o··±Ò[R?}n”m¬KnéöhLü³ƒ Æ4æ±gÓ¤¢<Ã~{ÇQ?>!Š·”–¢Yñ¡;þÜËkb“ᣱ¤‚Ñ2ë¥Õ6œ” ¿4ýÅWzjöSÓŒJ†ŠÜüvwA˜ÜxÅõ˜÷س/i (œ¾Í`wA˜îyl†žñÊ%’³Q pÇ&˜|‡I™4 Óæi^"¹œ'•3‡ÉM!ã¥:rSè+¼c¡ TƒáØPY!¨…Å[¿xY“Éo騇ø5¥@xöÔm/%›cÏíå˜íXR”íÁ²mð‡’ÝC mƆ5Mèé‚¡a}©6bh8ÖâB[ Ñ,¶–¯¥ëÑ»Üw‚‘5$c_®Ak€»ïëÒŸnHÚ?1×&uiì’_2 ·Í-ž¨Ë*èNÛ_SEcRõÛ 0÷“\ÓF8,î¢Ü£Ô¢‡B= è©ÑyH• ™àWÉ)J_üòןôœ{ ¼ï‘I_øò×,ž§+Z#c)Е¬¼þžÖ|泟×oWì¡3o)é-U ¹”¢.ÙÓÌçÑ÷ ¼ôéüüãgº'Ôûâ~½4n¦tK-«|뻇h›~~¦Xõ´ª5z<²¢ç×}¾¸ŸÊ§þñó*Zøæw)—<.5ÜÝLÿ×/|µzþ¸% ©ð¤›L!WU`ê½ÆôÇOvvmúÒæóúÐ?ªÿþ¡]k¶™÷¦æ¨Ë§Z9éšYž?áîg׸n⦯;â²)Ñ A˜¯áÞÉk<Ù…bÒ µ†ÝVÝdjèuõxç Ê=(ÇFz¼[Þ@€ T%9L󗹉€š„sÆðùÖB9rHPÆÏÛèºÑ‡Ü·pȽ ý逃î~yÐÝ Š³,Â1Œ‘L¯š]®ê¹ÙêAsÝa6¹¢Æ7¶Åf}«1™ÃôÒ²M~ãtè˜W¢žŠ×vüúþE¿º‘3ØN¼z棳_·¹Ojœj¶ý7ÏàB1Ù J[7NÛâžá$+@câþ€ 4¦GŸñG£bCN±©p¤©8ØdÃL'Ÿr¶6²¥knºË­1uI#¶æ¨£OÒð¶†ÜÈ‘Öìû¥¯Yùö÷M ¿”šB®É Ù0Ðñ'Ÿi£?§ž;ØÒn|ê3ŸïY"¹™a"9(ç{a4&ß[Š-WˆÆ´õ£9Ϭ;ð£?njp­6u÷Ãtƒ¦(,‚rq˜ôø­e\ýnø¾>šCæE9îÊNÍÍ"°á!ébb25õ 9òFàì¿ÞóÔ ª¾bÌ+:^ }/5 »´¾«Bgƒ¦°Ì€þackÊjL滹 PÚErMÓ/§·,üË·gÁ”¢‚#|B,xRêŸQ8¥Ò J?<æ¤Ï|ö¿>6ñ9ÓMιèrý©gG§+ÉXê´¶ùü#žó#-i›³/¼ÜIK?ýåÙ*U¤¥”xK¡·o÷K,aœÔ¥¿{H”6® ×KQ’·d˜$ÁÈR=næèq3´Þ\{•Ù‹6êO‹½¤§Uy÷±Ìqû|a?=¹–&BŽb/¥ÚK.5ò¨G¦Ic²ðK~ò¸‚¡tnÆÂ/¹p£¡À´Å'—<ò¾²EQ‹JRÈ¥ùû=‹Æ´¾{‹¦ÑKÿ󨮽ÔÜÛû²üûíÕ+r˜"ã-ˆ «ÿRÑ,ç×vÈa:rÈë&¾ü¾…ß:o‚4&7H0øž—ÕM|ØàÉ~(&{N««omW“ÉÄrŸ=C€ @>s˜¦Í_fSt,ÏõÅ#_:}ø|,Ñôî[ž\©ŠM>õ¦yj¡Hc &ÀhÒöŠ·üv®Z(—ŽZPèFfY¨yrçC™™L0Fíɦcê±5&s˜^”ÃT˜‘eÓ¡£_q3AÝ ÊÄßPËTµÿÈìõæ0xzÕყ¨ö½Æi±ö‡µmã´cn­œ^SN+žË† Ð<Ò˜îä™ÄPT1qÇÕ7ŒpR± öÐ5{Á1-X¹Y“~ö˳_qƒžÁ4ÀôÒŠ·4~¤A%•«;òÛß?Ô2ÇÉUzjÆBKà ¢LŸùÇÏ»1£#|â%¿º®$üRɆll(,ï¸Q!=Ëi0è××Þaù7T4‰Ý¦oþû!6îhLaÖ`+±<šY­œÅñ´ Lnç{‡-Q©^iýö™˜4X£ÒI“4¯ºa„k|Y"9›@òëÑ‹TË ‚«'ðË¥1­Ù>ñï <Œ˜õļšâ®'ðHc*Ì"Ðhš_ 5&Só¾ 8S÷Ú£RQfJÖ "}ö#EuÝŽÓnž(Œõ Óúæfl.º¶;Ÿäš²“6µ(è.SrM‹\gí§ý×7÷È/…PIz&8òG'Ä‚'ùC(¹XJ…)ðzޔ䥳/ºüÞ‡ƒhLÎXvÓHùIÁ6O?çGZÚ÷Ë_;ëÂË]ŠâŸ8+°æ_ÛqÕ#Í‘×o{î<ó‚!&ÎÿdÀYZûÔ,gÐø½C|r–Œ–“~qÖ¾_ÚO刨¯°)óWýÛ—ö“º¤ßW\§Šl$ýéžM_~5ˆÆ$oÉžPU¤1Yž¸@c*D]šjL“ž[¡œqzru­Î[2É|=¿÷³3öùÂWå'ÚÿËwìÏÎП¶fîÒâã¬iL¾À¤GÛ~ß>Xå_öýꀳ.•yó‹³.=æ'§Ûšƒ<ÞÂ/iù€ÒïøôçîxpŠž½‚R´—¢ Êåö ©ÜšÍ›g¬|ßâÿÞ‰ª1ÿ¨¾wè¢ÕÛ,Ï  «TOÎÛh©w?»úÄa³,ª–&:žDcrƒҘF“µ\(&›ß ÜÒWÝ2¶jv¹Ú?_l @€ t*ÀaگߴyËbÍM|nÉÖBªë —ܤ—ÞTóDÝè7_!‡é2iL…nô[6hÔ‚Hc*t£k^Š5Oî;-«˜LZ }¥1Ó~ý^\º)Ù8µ”0AÉvDQíß5éUkœSXûjœŽŸ»1И®ŠÉQhœvêÛê×…ÆÔê5ÄùAh{Ò˜”¯£Âx“ H¥Œ:½þž9+~ј‘Œ% -i€ÉæÀ?üÔl ¹ÀKÏ/{SN{áU „eûÔçWiLç®'X´Ô¹‹ß°¡„q¦eáÐR0Nôê»'þ;oåÀ˯ӂ¦‚VyKz–•´d§*NcRR9‹êâ…ê(И¾°_2mœVžrÎ ð‡\3ÂÙKZ8oð5C†k,sÜ!GÞ aQø¥%Ýw=_cJÈL±¡aç/곯Djw[d•ptx}ök6…‘Ö7·dëˆ%•Ó‰ùkò§1]?¢‚“äžýgÄZ–å0=üôszŒÐ£¤¯(¹gJ}ÅÈCÒc¥zxõd,„Ñ•¬Xt¥±O;ä××ëYó©é/K¥”¢¤‡K‹«dšEiiÍö‘L8ãü!ò–ôÒÂРW°¥ž˜)iI[šJoϦã¦,°5§ŸwÙ3sWª+Y¤Q\ÐBÂ8Ó˜¿>,’–î|†t¥OýãçõÛÂ/¹œÇ÷>hLÁ3k!ð’©KЍ$É/ÉX’·dO±w?2]/I]ºìêÛM]ºKá—BoÉÊȇ§ÉU²Ìq¦ÚèÏqÓ—Zú3 L®Ø3®"0é·¶qá—´|ûƒSaßJZþ¸T¥©–¤r_é÷•Ñ3Oð#0ùvÿÝ‹£°LþÊ^.ÿlè^ßþÞ! Wu»{/ÊÑNrÕsêøylþÄðñ+ô¿ªîõMuÕsª?H`“)b.\£µèxa2µÎ÷5g@€ V#:LL™»ÔoÛ„ÍèU?šFMÔ¹^4¦"v)Ìz.,šËæ/{åŠð©1x@´â=&VXÖ¤­XP¥ ýpè'ùÏ”ÅmB9É\¥®°¿O*´’õý)9±X2iI¢’_ä*ÙsçÈž–±ôÀø™zô´ôpZ3~¦C{Iâ¬<>yå‰=nÆ ??Ó’ÄéÁÔ¥Šó½%—'NO«½ôØ =ú9㮽íõ>ßó¨4¦¯šº•P]’«ô˳™º¤üq.ÞÒð{žÐí±?=ãÜAÃÌ[ºùî'"?LŠ<ò¡à)Öb/%Ì7ú©ç-sÜÑ?9]Q—~~æ¥*– M“~k›ûž˜oáFÿy߯SÍö’ûš®EcÚç‹û?ðÌu垌Ǯø;å]ζÜ:áËê)~vîR»ë‚ýQ”þ T Æ4ÅÙ¢¿jò„f¸>:ûuKV­©®zNõ dãê9µÂ PœøË ιpp÷{¿ÿó_þÒ'_R€ @hY;wîÔÌ£“æúƒ(®…¢æÉƒ3^ "‡-µL5ÑBs­É)‡I%öÚ‰êF4¦»TèF—ÈòµoÿËý/5ií·³mguÆÞnÔÌ[E›jß5N£öi”¦DÓõ¢ºÚ—ä4‚f°Ù Š^8ƒMµ/Éæå‡ý’8ÁÖH¿ðW7ÿð€}ºoìÿg…É¡@ ÑÎøŸöœþ?5óű @ oôuÏC“¢8:%CQÑðÓ×Ý H•êJÑp@aPàªGZ’¸PZúšÆ•\Ê !ø½CŸœöòÈ'èi\ESßUlÉ/iÀÈÆäškÀȦ»k¨HÓÚ­<öìK§{Ù 'ŸiÚUyæE~éáIA ¹h0(Òôõ@`ZhL6k]“?_}ÀY—ó“ÓIö’Šzî;%ИÂÁ c:¡À”ȧQ‹ÆtìOž±vp¹içÖ~­Ýû/¾a?ÿ®(7<¤JQËëÔ›æé Ü¿5Àwø`{¦P2;lÐäÑÓÖ–›âþĬW÷ûÒ—&]xÄG7ÜÉßgýÕ=øÿŸ)è{å¦d\õ…M ¦ú­ïØg_Mï [ahØ9L5 ûYz¬õ­¡á£Oí÷PWÿIk3ãn÷/á k¾&jíŽÑy{hé“ëEc*јô\Xòè‘pA¯þÃãS6ð"'¹J…Ö‡2*zŽÔÓdà'…el¨"ùaÁ!S„I™4ÅyØØ%zTU][¦jÅ Õsªë&VEÓ É ÌaÒÕ©`25¢*Ù' @€Ú€™LLœkÍa¿yr×3«Õ$¹yü 5WÕ:Sºþ|jþ&ëF—Ã4H“×.‡é’»^*v£'¦~ï ÃVmxWÍ“-Û™hÑ7Ž™LÏÌIoœj¨ ’©›Bµ¯ø[Á JØÛ ÆéØpÅ 6µO)Êu¾5Ç*8LÇœHã´%j=''¡¡,4¦œÔ5— @ è!êî±+ H]HŸ±K›lŒÉÒtX¤%7À¤$ ýæú;•¸CIsošÛµIcCR—Ì[Ry66RÎ8‰æÏÌ]qøOÐhшÑOk»F‹ô̤»ìÚÛïJkf¼¼A£BZ£"›‡`ö’2o¨<9k™ên¹÷IIKš¸®G; )ü’&­1UÝznºû ý¶råÑõ; 4¦ÊS½IåÖlÞœ*3}ôÇM}TÛYvôèщ# €ªÛ`È—ÅûΉ¯*®žÀ­ñõŠð |ÆkÎaÒðÜ¡ƒ&ß?u­¥óSøêXà0íÿIÓ_°'ðvÿ)Ëkh©} þl iñV Ô˜®úž-ËíÔ¢ÖwÚа‚0éãïZßAÉ2CÃj}§ {æ(CÃîýAcjÚg¥WÓ€Ö­[çŸkrMÓ®¤÷R4¦¡×ÞžªÙJ½ª‡'!¥,„“*=GJ~wŠÒÓ^>âÇ':?ÉôpùÄÔ—-œ­Q¨OuüY‘œ$iiN×&KZУ§6p¾¼RÂi~Ëš×Ó§b/iYE çÕcd2þÎ!zîÔ ¶¤GO­‘¨tÝm˜´¤W}6rêͬV~a?‰JÚLнžPõû›ÿ~°r鸟qÊÙƒÆN|Q­‘½öEZQÚ8‹À¤g#=¼*ö’t% "jO±ç^­ùÅY—ºÀKz~’·d!F­˜ÀtôI§KWR¹â¦ûÕ¹yÖÅW«˜¤oö’žkvÆ%_?ð û݇Io©Kc²‡9ÉLãW~ÃE¥kÆdÿ®¾ôÕ&=·$ ÑÎoV‘_¯LVN¹i®X7±’"¸q®å<¶nâÇfoøù sʹöþ?*:‹{ÿ à @€ Щ"“iÂ×v1x˜¶îÄ«gºÊ”—߲扚™W>°øÊ1]Ånô%ÝCG¿òëû_ ºÑéرæÎa²æ &S‹ÜNÖ—ê§QGØ8½fì7 ôê_õàbWûjœŽŸ»Ñ¯ýc3£œÁæ;L4N[¤Þ;ÿ4И:¿Ž¹B@}L@OP£ÆNL HEsà5ü Hõ?ÎRv¤=rÿöα~÷PM}× ‘ ŒŸŒI]ÒØÙäšñ®1#ËføU rt¨HZÒØ½ ­ †~uí iH£B6<ô«kÂ5_Øï”sqf°kúº¤%éJŠÀ$‡Éb/iÜG£9<ý¼Æ€l¸gÌSÏ|äñzÔtåm|û ½ª zæ¿ïÉùq|¹LþÈN-јœø®‡F“™î_òŸÝxMghLºqC“é¸dãKOà^(&“:ÿöôn“êQOàãæl´8L–ÍYÃCÏzÝ"¡úéäbS‡›LhL}ü]Èá=¾Æä Ln‹XëÛ:^T®yh‰>þ~¦:††Kû^®|G¢15óÛ¿ÿØáü5{5óTúüX¦1UôêaýKŸ ¼˜I.xRLKJþé+JÎUr–’=Y–+…§L{Ö,>nÙ­¬ Šž8Ub¹áì;ËŠ‹´ä\z8¡l)’ë“©âb!—ì(VÌ[r%–‚$Œ³RL挳lq…²Å%EÖƒT1²høPåÇ ¢Œziã~tâi×§gܧæ®UĦ¦iLzžÛ´m—’b*,žŽ§19“iâ¬%QœÀÂ$W»7ìfp¢}”ðØs˜T#ª…rÝÄÉTt÷ùw'@€ –%`&ÓCOϱ&°›˜Úf©®ý8Laó¤;jžй&žrÉÅ&L¦–º¬/5Ù8µÚ/iœ†[1—œ ¢øÓh"ø׊O:L4N[ªö;ödИ:¶j¹0@­B@Ow=8¡‚¢ôëp@*x*$ëpãM%ÃL…9ðñq¥h©8ä†J‚£â˜QÚQ{)˜Öîgáðæ±»a hÈúIî±ðKRÈ%ÇtêÕ˜ì¡ñ½]ïvm:zi 3uŒÆd&Sp{ÔØø hùq˜,¸@ê÷T‡©“M&4¦VùRä<öì1)M`Š™L ÷Õí‚ÆÔWä“ÇÍÆôëknYGá³`T~uMðÔX Ñ’ÒןTANr/%,¥4Q©à*™±dÅâ*¹¢tÅ*©º’3¯cÞR`,E]ÉuHKÔ§²·dýѾºTâ--ŽyKú³u)ÊŽì«Kþsí½ãçýó¿}Eq˜ôûâ+nm²ÆdŸ%ÉL¯¾;2õó”:4l£ù©3ˆÜ8{††ú×;”z7S£ÈÖ¿ßÜiL¿v[ÙH¯ê=Ô¢%½\òìèB(¥ÄR*†SJ³”Râ*U ­ÅX ;ˆ“¥Š±JÙV¢ÜpÞBRZryâ*„\ŠyKUC.Õu©g~RïêAR9‹ÆTõ³¶÷m{WÝ¦Æ “é+<5c± ¤”ˆöÉT¢„l-´*ÿ£²GÕw?ø¸ÆÓc3@€ @ ?d2Ðï›>ù\r~EÔ‡î;L ‹¥^‡É™L>aÍéw¿ü0o+Uãôëý¾5Ncúš x³ÀS{Q£dƒ­²ÃdµÿöûAãTc$«¡q”$ÇúgÖúnÔœI3 15ƒ2Ç€ kÒ˜îót}R)ãMQz8?ÌR|ê{” £$GGÊ,÷0Zj,#‡?Bä UнT2q=ȰQ̳Qgø¥Ø8No4¦>¹Õ4¹¢Ñ “ûî»ÿÐ£Ž³Ì-nÑ L)Hzç0Ùøþô‰ñ¬à*i.^íìu©nd¼¡ï ­ï ­ïž û3ˆz04,‡ ©ïo…ŸAî4¦Ë‡Ý–)²Žôª{ pɃË-D)ÞJs½ùñ“*ÄRŠ‚*À• ªT©S]¥¨‹0`©ä1´¢±”i©i)ž'.%UÜÖXª¸2ÞR!äRi¸%¤ÞoÖ ©¿ºQoÛ{ÀÄê^8c ¬X|¦î]ÝZÖ‚þÔ–*Ú¦ò·Ðºõ¯ñ+_bz—‹ÀMqNÎr6ÙÖ Mä<®åÕ–í¿ÿó_þ’ã/F.€ @(Kà½÷ßßÿ€o>ðÄìbó$TX\ºËe›bÑc‡Éu£ëœvýq—P-˜³iŽŠFF,¡×¹¦v–þ´–—uºe(—¼þúFÕþ“~ã´¶Ú·.‚0«ÈfkË×â0©qúŸüE“Ù2™uI&Ó’û†©lí jyûê.Í×Bl½ÖhXE›é½ÔÒ  1qg@€@ƒ HcºcÌÓt\>ìÖp@Ê•ªÎ/ *ùIâ|©Å%æºÞRqÌ(1¹=U]*æßð3ÇU°—¢Ç¼*6ªè´—Æd“+44vùX5IT4Ö£eý¶;K);´Òl$H¯öà¦9ê^Ý'i¯âüvo AÏã0EIú>üƒ¤§õ®‡m-¸Ø¨²—¢« C4%׿1o¢EQm!É ©·oiÖú®04ìç‘L.´¾{04¬ï+}¿é[NßuÔ¶¯8[66꙱έ±¯¸`–Á))ˆí"wÓ«o-gi½^ÕÓ@걜neÿôÌ$ÉI•ý¤Ê•›z")&ƒ‹[ó•u%[JË —j,%3ÄÕ"-%óÄ%½%? ²:.]ßeՇׯmÐ I_îf&ékݺ×ÕÕîâ3éOû–×K– AV}~•Éô…¯|}üôWbSRË›åì u÷àUF_5ì€ @èf2?Ëš'±DQzé‹L&#h=hjdYg™S~|&yKzU“\0Piô éΩ×Ú®ÄúR]ãÔôµ`lÌÂ<[ã46 ¼“NJ®’FPôÛ²ZhhÄÖhÔÄ”&mcëU´^›ÉyÒ‹6ÓoÛ€Ä  1qO@€@ƒ Hc1úéªR)ƒM%àKb,¥K¥3ÞK½%÷V&#‡‹ºòóo$3ÇGz~©Ý£1©=¢æ†î#ÂWÄo˜hHM©=¢Æ‹Š´Mî;™L‡y¬…¿-6¾¼,ÞþÕªÌêÈ ÃUÍ%s˜ì$õŒ­'jAÙötm!Q¥+é \ zêÖüÍ4Ð[4÷@E ©±T{pù½} So òþ>#k}Gñc­oŶH oÑ ‡É.ؾ»´ n}¡iY-n ™}¡9AS/9éÏxeq`4¦,(f³µú®77_›IcRѳl-qùÌd7õ•hòD¡áaÕmµiuç=¤ŸSq˜²ùÖd/€ @€Àž=f2Ý7nV‰Â²,PX\ó$%Ll¡íª[Æ~ï ÃVmx׺ËS‹"ñøq˜u›h]ixÉͱŽ65²ü¹"j‚Ù~²"`}©ã¦Ó¢ÀTsíׇÉNØ…\²hLnÖkàÄÂ2iÅ/Ém2ÛÉÞ«·h›¬.œýt4¦ŽªN.€@+4¦ûŸö‡¢ÂJV‚ѥ˂©ÀMI-5ä舌¥Xž¸äàQlÀ¨.u)6ƒ= Blö6öRrúz{Ec²¦‡iIj˜Ø‚›ân¯ZF ÙH õìf•Étð‘ÇZ°ƒy‰)~ –hI¯&{Æväzö–À¤Gk=u»çsYM®É6s¯ÚtS úþ©ïë€3è9¨õ]Ïа¹ÇCÃn\[ßc.N‡¾Ä¬ƾ÷LÜ´ï7•ÎÈ„ÆÔó›5ëwæNcºìª[Ë=üi½^Õs@… ª¾ê”–T4“R¢(Åó¾;ô|銟“8¾ö —+þ3¨ž]¬&fTŠºRб”–.zN­UZê㫤yM±ˆ¦ÇØ‹X˜ØÞ8LÖYfcsE\WšmcS¢U\­C¸·ÆeX_j²qö?D³kÜ›žå’sª‘ èO h˜Ä,Ù˜ŠÓ•¤.i½VjKBgÉ,T\æ‹Ö ÇY´ 4¦–© N€@§ÆtÛ}Oõ`@ª8Ì8+%9:Å•ÂpRlü(9r3 ‡ŠRæ´»¨KÑ<öÂ$v§.•L\/ =Ô5"Syã¶Ó˜¬aâOb÷gSØ«úmÃ@6d¡Mzö˜LGUw!K4üçæ·' ö,“ÎйJöîì%­×²‹xªIzä¶Çr=„[´TK ݳ+Íø]hLewÍ&P®õíaÊ|hXÃÖ¦%ÅìLS6-Μ¾Ö´ûг4šíþƒÆÔ:5˜;ið•·†}éE¯tæt÷È&ÆJɃ£ÿ™&'™¥TQQR öJ–R¹LpYèJ5„YŠGZj'i)ùˆÜ )Ù«n_âöÍn¯šÃ¤ %Zûë™LN^XœâöGA˜¼‡T¦ÖùªåL @€ БÌdºç±™®¡Z¶-‹8LbhsBlÁMõs »Õ¿f¯º‰Ñ–{®#á÷ùEY_jÔ8-Dv!¸R{QëÃd×(É…\²±KW¡û­ „I JiaÓÁº¤{/?ˆ@c➀ Ætë}O¥FEcLƒ¯¼%J ª”p•ÒÇ• .‹¯.¥IKQÊ¡øÌö®`H¨¶œqÑHP†ÒR»Gcr “dhXÝYýq ›Äî¶ïÍ}'“é #Ž-ÓøŠÉùSzì0é$«äRËYfg÷|n®’]Ž›c`ÏÞNêÍÅfö^4¦ÌP²£>#PÒúŽÂ—$††ÃlY »qmËiWÍ^rª“^rI6ûŒQFFcÊd»ÉÆ4èÊ[Ruu³‹ôª\f?$Rêr% ©œ¢´´ºœEÖQß_ØýW®”‹«”Z)=º’=˜¦d…+¦4óæêqÇJ Ô3–¼ïÁ†>¶6zçÓ˜,:¨ë.W‚d=³ZøPëj7Cßf»5~¦ÍdzøÙ…6ÉÕ&×Gì?¤‡©F¤l@€ ôŒ€™Lw?:³T`J ¤æI/ã0é Õβ\rê2sSýÔ°RÏš+Ú̆ ìw½ ®žqÈ绬/õ‘°qê Léµß3‡I`5pb¹ä´ ‘Kf¡e›ù­õZ£?õ[ö’ ¥hE úÓ…kÊgqÕ• 1q@€@ƒ „Ó“–ÿ+µØ€Tõñ¦4W©8œT:–TLÊ‘o©0”àÔ¥’A¢DÔ¥f¨KþP{Ec²DKjk¨ÑáZj’¸‘ ›Ç®±!‹ë¦^ôò¾3“É5¾Jæ·CPkFµ7“NÒÍ%°hLzðÖ¶Ó•ô|n©œíÉÜÂ5©À¢¢:ó©—›ÍÛј²áÈ^ú˜€µ¾mh86}(;“¡aõ·¸Ì˜I?öýf=0–"Ó¾Ü,QÊèðhLÌ`7yÔ˜*<ê©QÿþçÊ‘•*$ws/ZR59©4ï›%€+Éþ¦¯¤úE¥‚«”ÈWNWê`c)ÕˆjÆ”ÁG³Ú.d2ýÛ—öè™—mª„Ÿ¦Á=¤fòªÚ‰ð: @€ wf2zdFÔ<±±¥}è™8LZeб‹h«•Hð×ëO­tÝmy¯¤†]¿õ¥§ej¿Ç“N\“¹ÝékÙ/é·"3¹DúÓ½dëOÿ ÀŽÛ–SÛV'@ ]HcºåÞ'K¤ŠcOÛ4~téo†[d ¥ÂÐRUc)!-Å'·GÞRaB{ÉTö䌫:k½½4¦>¼e2ýàðc*Ïoï¥ÃÔ‡W—ý¡Ñ˜²gÊû†@¼õ¦þLö½œøË ιpðú-U([¶ÿþÏùKß\Fk©uê'w“ž S좂ftIøÔX´Ž*FEª0)‘ßÍ´¤ÐLJ““ÊúIa Y¥=ý ŸÅ Ji¢RÜUò¢+åMW*÷|ܾ“¾DÌd;iATÑžeo×Ë?ªÖùªåL @€ ÐÙÌdùÈt¿yâ‚™gè0u6Æ6½:ëK­Ð8íÃÔ¦L8í6 €ÆÔ•Ä)BhoÒ˜n¾ç‰’ñ¦Òï—\H•IÍáååHZ², ~IŽ%3r¤yK…,}á-ÅnИj¿ãe2}ÿðcJæ·{5ˆÃTB©ö‹-[ž@ÕÖ7Cý¬C4¦^Ìðí¹Ó˜ô\Xúðç£`A¯þÀ‚1:åÈÄ£2î‘EHòKòÙ1}MWU9)J=h–±”j•J“ÁuJ>¸ªæ~-´µÆd&Ó>_ÚÿÁ‰ üt§8L~E²+@€ @ Ff2ÝùÐôdó¤÷¹äj<6ë+Ö—šÚ8Åaê«Já¸U 1q‹@€@ƒ ÓÝO¤ HE£Ná€Ô1õ 3¥OzsÃ%F‘*IK-9N„ÆT×-˜L‡ãg‘Ë$—\]çУ1µG=q–µ¨ÐúÆaªbùíИzÏ0«=äNcºøŠáL#½j‘Ë–P?²’pÛk\Sx ,o&™@¢(•†Sò"*!*E¹~kQ—ümÚ]cÒA`2}q]ˆ]ü£Êê+’ý@€ @µ0“鎱Óüæ SíÛzKëK5Nq˜ÚºN;üäј:¼‚¹<@}O@ÓMw?QÓ€Tõ!§-f¼u%o)´[¼‘£¶Tuø©Þ»V&“ ù`‰Ã”©ދí[ž@j뛡áLê )Œ™ì$ÓÐáô£‹‡WFËÔ+‘ÌnJ{ ’S‘ü…’§É0]eTm‘“ä—Â#f郦y+íðÄYõ‘´6è)i2ñ*“/Gv@€ ô€@ÌdÂaêÃö}K¬/‡©}«2gŽÆ”‹jæ"!ô%iL¿õ„7 uºxèÍA^°Ú†œR]%o®{að¨ÇИzp¿ú&S:@4¦ÜX¼¥å ÄZß gUchLY‘ìý~r§1 zsL0òþ.ÒSãaÇ”•|ñ¨¢„TŸ“äÉIøIMv›:CcòM&þQõþk‘=@€ @½!àL&¦Þ`lÓ÷º¾T¦6­Á6SŽ*›K… Ð7¤1Ýx×ø²™7^Ù’2 •˜ñž«¤hL=»SÍdÂa*K©g7ïjy®õÍÐp†u…Æ”!Ì^î*_Óé§ŸþéÏþÓ>_Ú¿\ùÌçöþ/ÿ×ßVØ ÊK_Ü_é½(mDàÿý×/ÿ¯õוOøû›ÿ4~Òìõ[>reÓ¶]½üà5âíÊ.÷ùÿöÏç\8Ø?Õäò–í¿ÿó_þÒˆ`Ÿ€ @€Œ@`2ý?ŸúÞ—þßUÞ­ÐBQóäúhF@}©ÿô¯ÿç÷ŽÜ¿jãô?>¡qÚa•ßV—ƒÆÔVÕÅÉBhGtÐýoÿÜé\Ž4ý—ÿßßj®ÂxøŽÿÉ€ØCæG»ÿÔŽ·G¶ç,“é>õ™IÓ_¨üþÞ‡Èö¸í±74¦ö¨'β'Ôúþç¿ýßÎ9úભo††k䋯T#¨&l–/içÎsJ?9Vî3.¹’5L jÇ&ý'hMIßOt3gùúʃü£jÂ+‡€ @€Þ»ð³®9 ‡)ŸwÂõSÿç§–ŸW¹öq˜òyo´ÐU£1µPep*€:“À¶mÛªkh©ê`ö¶xõf4¦äæ“?¸êñö~Ú€¦] úRå3IZÒ²d&ŸI¯vïêÖŸ&6ÉaÒšv¿dοs 1uN]r%€ œH†bò2åJò²Ñ˜¸Ú™€æ‰©kE“Ô‘¢¢þõ±Ø,2¿[Fëõ§6Ózm`òS2Tv;Ãhƹ£15ƒrmÇ@cª[A U $C1©UëŠó‚ @€@ç°¨æºYJZ–Ÿd]fÖ_fsþ´ .6ëD“Ædë­©n)J¦%)ä’4&»"Ks65®[©ßZ#‡ ©*½£.©£ª“‹ äŽ@j(&2¥ÜhL¹ûptÚ[O‹ú^4%Ì®ÍrÉ)&“uËè·½¤î?ÓœúdˆÉT× ÆT®†nŒÆÔP¼ì%°ûOÛžYw • k¾¦'ÔGV|Ö­Y»ctcÏÞ!@€ ¼pýb6ÉO=e2™¬ͺØìÇVjK“.ÑÒÏiA¿ºÉ.š)dõV>S½Ä·=SãØ²g4•SSqs0@€ 䛀³—Ü$?Ó˜~ɦJTRß™MþÓJ­±e ΔoxrõÒ’oIåd,Y&ýhþT‘±¤PLZ£­´õrå\Fg@cêŒzä* @؃ÆTñ&@câ3ÒÎ\4kÓ˜4OL=*¦+Y¤%‹­ë„ÑzõÉX.9ý¦û¥ÞÊGcª—Xã¶Gcj[ö ¦@cj*n@€ @€@û@cjߺãÌ!@(%@4¦JwŸ—v& KÉ…V’Òd1°õ[×d¿õ£mÜK¶F“M3kçKï›sGcêîiGEcjºàL Ð+hL½ÂÇ›!@€ @È4¦üÔ5W @èthL•j©Óï®@cÊf/w…ÆÔK€¼­B©Uj‚ó€ @€ @ Å  1µxqz€ ÔL©*4¦šo$6„ИZç@cjºàL Ð+hL½ÂÇ›!@€ l ̺eÏKc²Ý%{k[?š³óã5ír¶œgN  1å´â¹l@€@@cªT©hLxËsIh4¦F‘­¿hLõ3ãhIhL-Y-œ @€òJ€Îâ¼Ö¼®{T×^sß89Ǹôv €ÆÔµÄ9B€ P 4¦J”h™Ör±Mû8u¯=ch}gVhL™¡ìõŽÐ˜z@ 5 1µF=p€ @€@H€ÎâßhL9®üö¹t4¦ö©+΀ ÊИ*ñ¡eÊç§³  1eZ¿hL™âìÕÎИz…7C u 1µN]p&€ @€Sžï4¦<×~Û\;SÛT' @€@hL•¡1ñêlhL™Ö/S¦8{µ34¦^áãÍhhL­Sœ  @€ €Æ”ç{)ϵß6׎ÆÔ6UʼnB€ P…S%@hL|€:›S¦õ‹Æ”)Î^í ©Wøx3Z‡SëÔg@€  1åù@cÊsí·Íµ£1µMUq¢€ T!€ÆT  Î&€Æ”iý¢1eгW;Ccê>Þ Ö!°û?¶=³îÀu;F·Î)q&€ @€@~ ÐYœßºßƒÆ”ãÊoŸKGcjŸºâL!@¨L©Z¦|~:›S¦õ‹Æ”)Î^í ©Wøx3 @€ @)è,ÎñmÆ”ãÊoŸKGcjŸºâL!@¨L©Z¦|~:›S¦õ‹Æ”)Î^í ©Wøx3ú„ÀØåcUúäЀ @€@Mè,® Sgn„ÆÔ™õÚaW…ÆÔaÊå@€rL©RåÓ2ÍñG#—ŽÆ”i5£1eгW;Ccê>Þ >!Ðïþ~]Ý]}rh @€ @ &tׄ©37BcêÌzí°«Bcê° år @9&€ÆT©òi™æø£‘‹KGcÊ´šÑ˜2ÅÙ«¡1õ o†@ó ˜8`¯+öêÿX™LZ–Ò¤ßÃæ±h„ÌÞ·í­ß פ—´™~7ÿ$9" @€ wtçø@cÊqå·Ï¥£1µO]q¦€ T&€ÆT‰-S>?M)ÓúEcÊg¯v†ÆÔ+|¼Í'°nÇ:3“¤.ia×wiÙÅgêÞÕ­eûmçæNÍ?[Ž@€ ä”Å9­øà²Ñ˜r\ùíséhLíSWœ) @•  1UâCË”ÏOg@cÊ´~ј2ÅÙ«¡1õ o†@ó (êÒÀu\‰Js6ͱ°LúQ&gÒŠÃ$IEËúÝüó䈀 @€@® ÐYœ³êßúÑW¤1MYûsÇî¥9ƒÁå¶*Eí™=<*gÿõžÓÿÇâŸZÏ @hOhL•ê–i{ÞÕœu­Иj%Uv;©KúµòÒ[ç©CcúëGº5o}0µ×G`=!€ÆÔj¼}H@–’\%€S—\|&­Ô«òœd8ieSÑ‚El†@€@óÐYÜ<Ö-q¤é¯¥Î¾Ô²âíá-qŠœî|/~ P'£Ž:ª'Ÿ­¦¿çÃß½ýÕü›unÓÌ!@€ $ÐYœã›bèUNž21Ǹô6 0uÂמrœ(§@€ª@cªDˆ–iµû‡×Û›@s5¦9sæÔ9ÌÞ~›ÿ—ÿ»ýιÞ3>ÿüó[ÿ¶Ï—ÆtòÉ'¿}ÔÖ¿—í¿ß”Ý7ß>ê˜ãNÒÂf•w‹å­wwå•ß½éÊÛ¿{Ã+›Þþݦm»\Ù¸mׯî l(–^ßZ,ë·~´~KT^ÛòaP6e+o}¸6*¬}ëƒ5oËê7?ÊAyõQÙ´s•WVnܹrãûVV¨lˆÊò ïåu•÷–yeéú÷¬, ÊŽ%¯e±+ëvtËöWÖË¢µÛ­‰ÊÂ5Û®ywáê ¼ìÊ«ï.ˆÊ; ^}ç%•UQyqÕ;AYùÎ +ßvåùo»2ÅÛó—«lS™geYPæzeÎÒnWž[ÚýÜ’¨Ì^Ò={ÉÖÙ‹ƒ2«PfvmueF×–Ÿœr¡ÊŒW¶L·²((Ó‚²9( 7™°à³Ÿýlë’?þøcéV× ¿çËû°téÒÖ?a΀ @èptwx—½¼¡C‡þâôó¿ý½C¦NšW\w«ÐÍ©[ô积۵ÕÏ•óƒ @Õ 1U"DË´ÚýÃëíM ¹ÓèÑ£9þ'%¢EÁ²_¡²`ÉêO}úͲ(øérŦ·Ëk¾PQÁ¦Hó(’…Ó'VnJq' âDÑš(Q&|_bÝŽÅi²„3%G"Ô$œ#á gG85·#J½ˆ)Â%:DèB„"DwR„øþáÇ\<ôfYò|Âù×wà¶þmŸ;I¢’}Šbż¥›ouôq'•|´’ö’4¦RI2SªÀä9Lmð>o’™êv˜<©f‡)ú(¦8LÆ”î0ESø™,jL¥Ë.Ïa’ÏTª1Å?Ÿú Vq˜z©1Ur˜"É9LZð4¦-£1™ÃtçýãT}óº6|高L­ÿÝËB€ @ Ó ÐYÜé5œz}’BN?÷R5N_^Õ}àw1™ry´üEËaú÷ïºðÕnݨ§žs &SË×'@€@hLhL|HòK ùSÆ/~t˜‹©zt˜Bh˜ .LIh˜§ÂE„ÑB<"LmÓ«i!`œ;á‚¿”üRêKb¾”| £½¤†z© 1¥‡wIÄvIjL.¤‹‹çR!Â`.‘Æ:LhLmóÍ hL•ü0KnÙ|À›BÉ¢.•^ Õ¥êöRácV£Àä䲎Ãä9L…PLÑG±W“b2UÅ9L ÅFcêq(¦Y^(¦™¡„X9ÓÔvˆÆdÓÈÑãõ Xh¯í˜û &SÛ|)q¢€ @èXhL[µe/L:Èç^ªySÖ8]°b+&Sþî‚V¿bs˜­Þf½( C~êÙ˜L­^kœ @•  1¡1ñÉ/¦kL."L̲ýŠÝ/u½*©–ÜV iW<(Œ‡)LiU´)Ê9LQ2«”LV.Uà0Å܉rÙ«²ŤtUÉDUÉU)ù©ü¨.‰´T±œTÒ˜*S©ÃTÌFµp3јZñëBÓM·ÞeŠ’+ÅÒ;¿ûí­w鳬I“–‚¨K¥—„ÉÿŒU°—‚L…[d/²ÈU˜ÊaZí%’ó-BEE«’K®SZ:¹ª¡˜V–f”óÒÉéCf” "§•Í(W9Si:¹d(&§1•Ë(×ú“s˜ä¨9I*ès‹^'&S+~qN€ @È4¦üÔux¥ÃtÞ¥~ãTáÖ_Z±å[ÄdÊÙÐÊ—8Lß?ô•ÕÛœl'IöN9ûbb2µrÅqn€  1õü eÚsv¼³ô…Æ”FrEX^ 5&9~‰gµ* ¿´kCw"«UõDr®}ë•5oF%™K®r¦R&¬Tt˜üÔUÉPL^:¹H“péäütUÉŒr…b 2ÊÅB1Y4¦¤Æä2ÊI~@cjŶ4&‰JÉ JW|ìIîOÿCå–ËxKág,ñ1‹ÙK1iÝæ‹%ÒãŸ:}üü,rEI&“-E`J ˜.©QÑjÈ%×8L~ÞG}bo˜Ã´dkÉG·$ÜV—RјN:åÂ@cZ÷ž¶p³>Ʀ1ýã?~ö÷øÄ/þË_Záþv“}Õºy„úU²¿Ù‹^ÿâWX¼dI+œ*ç@€ äŽÅyªrs˜4£1Ù8}aÙ–o}çà)S¦ä‰×ÚŠä0}GÓšm1ÙN“zŸyÖÅ¿:´Ï›s‚ @Õ©!Z¦Õî^ooMט|•"¦+éÏ^ 4¦˜bQcP˜ra"›¢²JñÆ~‰®”ÄaÚð~Q`ÊÚaòÓUÕ’Nî/¼‹‹íâB1“S• ÅTÏE“§1¥„q åiLßüæ·bòC ~ öjÁsjÜ)Icºñ–»Rå$[©W|쉶}¢¼™ºn*6† ô€S%h´L{pKñ–6"ÐS¤R¤óIcúL¥ 0[?’Já—*öRÒ¦ð#0EYä>pEY©|"9_œpÖ„ó%gº–8L5:L¾‘y:¹PcÚòýâhLÉ0.ÃEÓ~û#&?|´ûO­v×çNcºaø]f#¥½*iC·%¿„a–Ò"-Ùgl}i¸bÈ¥Ô´q‰›ñÌBŸÕ~©ÆL=˜ü¤&¥©ÛÑ•R©¶DrÒ˜V%J÷¨…•ï¸hi)A˜z™K®¶8Lr˜ôéuS1“ç0•Ó˜Þûð}ûIö¦þl×@D³nâµAÕH,›ùòk_üÊ×k7™ÔµäzÙ’]c}xÕÖI×ÕÕ¥ŽÑÚOcï½÷¶ÎDëŠUï³Öø]õïŠ-!@€ úÐY\¯vݺà0¥4N-È5Nç-©ÃdR»O­¿ºˆhû¤õ¢ µ íG~Ì^{íUUޱ£KŠ2áIŽ;VV}c²ÅZ¡ùé6¶…Øõê´ý5=Rž;´.ÐÜ/;œ»ä ïõ; l3khë·ö pýÙãID¶7íD y :uÝå66‡iñÚ·Óf‚E²:5oÀ™ë2™Ü «2»s´ÒéhIt=»4Û­W–ë*ÑAS?J½9™r•[áXôÉô¬®y @ vhL•XÑ2­ýNbËv$ÐS9ÑB~ż…ÆŠ‘\±!é-•š¯I¨Hu*ª‡_ª-S\`*É^U)ì‹'0u¥É -ÚËê ÓÕ q˜êw˜¶Í)„bzni·‚¹¤Çs)Äa’Ã$ÿÁ4&ŠÉO'‡ÆÔºqEcºaøÈècóÿgï?Àæ¨Î}O”û²oéZYïè#­ ÕlF‡eí#­£‘5-˜;¥/½cCcú–Æììë¶ ggµÛ²ÞÑÊV7½ì8¶­ùÏݪJö­ôž¡¨ @€òD€Áâk;îú7tµî>Rs¢—íÑzgÛ¬k²Gè¬íVÛoHÖ1t¦‹93É);¡1ÇÙª§-›‘c‘ Miš”­µãÉs˜ª†Ež“l§'ÁÔK•5üM›L6Èàú•tCFÌ1 õ=ëZþÈItT$´YpÃÈÌèa"ª~­×™~dG‡{Ìí"½£— ¿øš5Ðz……ÒíË?6Ý–“i­ó-@€@3Иâ(qeÚLbìè¾ÆTÊS/ùËŒ¹+>½û5äŠoË©°²Æ/UZEÅ©¨L×3UÙ^z«¡½T–(B…g/µ&0ù¾D©‰$L=Uy“›HN ³–†s»ô$v©$a ŒˆR¦Æy˜*"„²1S‡‰IåRz¬Kcºê†!U6’9I•¢O¿ÿ£ãÝQTûpr‡V鸪i,Õ”–¢ÞÒ*eZreC¬KÍ&^ZW%FÂ{)&ýR“Sã Li¶§Gi­µI˜¦…¦ŠÀä;L:€KÓ9õ¦´ec ;Lëß\ê¿8¡n˜Øžvµ8Až0{Í>_j<»œdÙ«{‚ÓdІÆü1e23iÉÏÚ:nœW ö0ŸjpF‘¶5ó¨lU öXgtR9½zÖªá×Í—–l¼LÛLéé‰jA€ @ g,ÎY@«›ã9L±vH%“=c£‹Óióe24fÜøõ5&[ÙÆôr©›ÌÜÒWtµîl*·em'd5µp<9‡)š0¬V*¦ò“`6Šrâ)ç53»œ£}hÊ0*M‘=sU¯ï¹ŽêSŠŽŠ¸æÛf]–/n­=L¬·û}Ì2jGÇyü¾ˆöbÚ“ ®Z¤w\ª3{ß*:6mˌɴÐù  @ yhLq¬¸2m¾'±f t]cRF˜°ká)JÓç.ÿôgö¨¡+™_QKZj4‡U]u©†G¶—ÂEür530U LåYäü‰äšMÂäMQV#^Øê{n"¹°ÃTÏejõ\r.“K 1ýy˜ÈÆ”ÞC\Ó•7 ©Rüª?}*É¡ˆ¢¤¼J=©•zr,Uû€föK^r³*i©4U\t¶¸ÊñÖDÖ¥@]j`/‰—T^ªNƒVJš²—bÒ/Yx“ ëLîX ¹Ø L}˜|ë°·I˜œ(‡IÅå^Š.¤'SM‡I¹ïì„»¨ä0UçB/ ÀU4&ÍÓ÷Ô³M&SˆÜ“‡Æsý!6÷© L¦Ùx«]º¼è˜rhŒÕFÜløXiÁ^VŸ¨ÆdµÒûN·²¯ûcµî¡[Û‚[3½')j@€ Ü`°87¡Œ4$ä0)¢_OÔU•ŠÉ{ÆF§Sç½²ÿ7ãL¦¨Æ¤«?½ij‹)5¦%Ù5 åî5½F—“ör¤öì.WJ"çÆŸͬ gç„Ìëã®UmÁ%-6HþE¨þ´Ô5vaëŒ+[3ª1…jî;OV_F±Jú“aÑËVö­[ÍÇêjšÓ˜üKr“ºÜÆm§f,Ùµ(”ZêOÿð9[mý}Y(-¸n-F5¦¦ŸÓC±DnÆd iL>‡×ROYÛ£}ÏuTë.X®§ it³îq2—TL_&¡Îì`ún5#bSÚätî»–êLï;wÍ:mèØt‡c2-wf¾@hH)W¦ ;+dš@÷5&©¡ŒJž¢ôÌsÆTr*\)çX*Ï^Uˬf‹ëq*f°8§ p˜ÎºÐ†m²û*‡ÉÏ\ŠI‰™õÄ¡]œNž·!ÆdŠjLN¡°ÉÇ¥S¸9Úlž¸è“3Âo—„ºÔu¢]®Úå­ïåØýëÐølLþ%§¾e¹vLïˆÊ7¶åš!ª1ù«¹kj½i»Õ+I»]¶GëYScò[¡ªþþ;ÑlL¡©ßŽÉç잃2z¡—ðÍ:L/OPªR1I¶S/ÕHÔÏÝ 'SHcòƒèwcQ2[.Ú÷\Gu#'5GEÜ–Ýfµ ~âwŒÐabHM5sZ˜z…ŽvTc EÄ=rf™ÙwµM×Ál ¶¯è±i5ïc@sz6¥Y€ ¶@cŠCÉ•iÛ:J%®kL¦RÔ+Óæ,“Æu*šÍSÓ[*?H¢° D”Æ"¬wÌ­TÏ™<.’ù¥JœØéç|ñ•‰ø)ä|S¢¦#Q%0óSmUÑÀHPšL´xs|.›œ 1yÁ¦ ÌÊwËÙ˜j;LL*—ÊÃøã¥1]qݘ#gÐuÆT6þª¼¿@NòJµXí*Õ̱dž`é«%-y[Ô[Š?êÌô³.Å«K&»´Ç^ò¦ò‘?.$zóÇÕ;Jm¨È•g¼Iëf`ê½À4i^pôÊaJ¿ÆdÓíÎaòÎÅe‡©Æ0qí8Á;óÅÏ}q¿y Õ ec qöéÙ.Œ›¥óiÈ°Þ Îa*p—FQÊUg³¶'Á‡©*aXY¶³þ?;ùܘÙåšÔ˜ÌE3tѾW’?*âë¢ædü¾:LÜâÇÔ¥%³m†4&×O\D쳚ûŽš?tc—­:6m/ŒÉ´ÜŸù" @ hLq”¸2m¦±Nv $¡1…\ ߬˜ZÒ˜ªµŠ:)`jK5…Š·Ô;uimyÒª}¢¾½T#ýRiº*=úâJüru30U‰š“ŸØE¡VžJ 0ùSÝ$L%‡ÉÒ¸|÷°÷Ûb¦¢ÊI6&]»ºÿ˜°L'õž$Kÿ.iÐu·­tÖQdAŸõÃãj¬PšÎ•Pî²Z©Ìº’sŸ_±ñÌó.±rñï¯1=pÀï¯ùÖ÷Ó¿þfö!G[}¬Ö8\§µ*0ÙÑÛWéí­«tòå&7úvêM³Žºd¢Jÿ¡Ï]ýð›NÎN¬BÏ<Û À]ûØ Çþqê™·Ì~|Æz“³ޢͣ§¯®g2idÍ=u§fiÙž¥soú'Øu­×:.I¾[-´‚Ê}äÛEþm˜Ì^ö|¡Ü ~­B5±•Mir[Àaêd?eÛ€ @ˆ`°8w¦òãëÞÔÅé5¼à’_õð’+Zbs˹aIJ1³_у‰zêéž /þêºý®›q˨åþÅ鄹ëkšL6Iœ{HwÝç®%íÿ:4tݽêŒ^Hús½i}m!tý½¼ÕWLœò¯7CW¬Íßm¹ÞåªöbÉ¢¶VÉšWë1—íÖ]YG›æ¿#»+Ǿ븊é#›ÝÌÞq«9&º„·¼>!a&k¦7ƒTë˜Ã´põ¶‡©4ãáO¯˜¦'ƒ„奲so›ã²Yß7iÍI×ÍP¼’ŠIO‚iàXãN?­o2ù½1TÃPÓ¡ uÝz”üQ‘š} æ Œmͯ˜í×ßiÍžãïÂH¨ÆŒÆhÑ}Ùf“i²³ @ 5hLqܸ2m­Wñ­¬èºÆT[¥¨HSf/•ÆTv-*rEŒYÑL ˜ž|K¥”K~þ©r'~ö«ßŒ™2ß2¿ÜxûCßÔ;ýN—>á ŠQSæýñÚ¡q¢äN”r¾L|vÅ ¿<}Ÿ/î{àw½î¶áÁEbPv¥¶½ÌUåOTÕL¦‡ÆÍ9ôèã L•Ä.%©î,rSÖNÂ䦢’ÆtnF4&7á’Ž6]ÿÚ³4.ïoܤrZÉæ¹·ãTÔØD(_tVŽbÕSÓå×Þs¨èS{õV¨H5’*U%1«NeJhöÈØg>ÿ¥¯œqÞ%*ò–4’ò›ó.9úG'<<æý«eÔÁ¦Õ~sî%=É–Js‡íñÙ=÷ùâWÜQ§åG=­!˜Ò(Œ_v~ó»‡ú)—xbšÂê9ãj«K¦šºtÊY«Ô9®Qî¥Ú“Ç-ÝzçÓOúÍE»tÅO¿dóÇÝþФÝçËÙ°,0ið¨§xóÇùG¬æ«7…œe`òKë“ì¥ÇÎþøôO|ÜôPZ GŠ9LCïQNÔ_ÊÕ/I#¿£fmxbæúSnœõëf™Ã¤™ãN¾~æOâµbûu-=üâ N]{ë¨å‡ oTmNªæ¨gVí]?'S Uå+€ @€ª0Xœ¯!‡éÔ’ÃäF9tqzé°.Iðoï¯bsß>nå7ÎóÈÓkuq:aîkœ5æÖÑ+†OyI§w>¹Z×§îâô©9ë¾Z''S¾øÑš¾¸þÀ`žÊ9÷ÅoE“†°®Þꢔ<ðì1ÎaRGUÿ´éä4F¤åÛÆ¬|hÚÚÃL¸küê a˜÷$˜†P”¨ÿ„“âr2õ­m|€ ô•SA®LûÚ¿ø~º $¡1Ÿ“Ÿ 4&·Âòž¹ªª¦« ›•â"“VÕ˜*Îå¹üº¡²)ýŒÔ¥}¾èwkîÄ…—^-S ŠQ“çéÍÓΚ±j³+vÿÇ=ÏÿíUŒœ6ôþ1Ÿûâ¾×Ýö@ïì¥Û}æÅ÷<6eöòmVª¦[ZžBîÎG&ÿë翚B®*S›&S ²¢1)¡¯ËL¬Gt´,7I&’Ë\Wc’±d¹ ÝsZ.Ÿ³}?݇líÚÓ5ƒÝÔ‰Ñ}zäóß/§)só,VÏþæ¦] T=³0†­@‰Jf/¹4K:À¦>·Êt%YJúwô”ù:Ø”iéôsš*è¼%­ ÷Úïtó–tÔ õ´&Í^¡ÃOEY—4hxÁo¯²Ïe]Ò(I áÐûG˜8÷üK®:õì‹5^símœröÅúWË· ýØø¹¦.=9c™\Â_Ÿu±Š†Ÿœ¾Ì–}ê9e]š6oý­÷Žú핃O>sÀ#OÍQÑÂ9_iç-÷Œ:éÌ'1Àæw¼ùž'7çìWH]zpì ýäç§~ý[ßt÷:Do¼kä¯~s‘Šy6ò–μhP¿Ó/pù­ÿ²Ï—£ÙÒBé—B“?õ£Kž¦üiQ©ålLë׬}oøÀ¤•ŽiL=Sy¹àñA?1kCÐ%Ö¼>bæú#N°(K`R*&ý«x)FzŽpäÌõÁÌ}/lÕHñý“×X*¦À`‚Ì‘O¯Üû ug—ËâN!@€ `°8EÁèkUÌaêú¨\œ^z߯и„iLº8½âÁÅÇ_>U§?½V&*Oðe÷/Òƒ7zôðÂ;æªø§z iÜìuû}ã߯Œß×ZòýÆdƒ0õe&s˜¬ÚZî¨^vsõÒ@c*åa:~Ð4=&uÉá»þñ¥|`‘ 7_t×óÝ9·ì0y²]ð°ÜüM'üꜘÙårÌž¦A€ ~hLq1âÊ4ý=˜ö…@×5¦JÒ-&ÏzáSŸÙ#ìWx–R(ÿKO¦¥—kKþ¤UfSÔœ´Ê쥣~x‚˺¤wFM~^E‚„f¬’Daù_œ;qÄŽ—,a‰—T† }ü/NÓuâï¯rÍàÎ+MW%wÂÉÁý÷ÛwÕmÁ;g^,;bê¼u|ûcOoÒ’\ê³ûGLýÜöÕ±'iI ò–4[œVÖA¨CQ ò–d/飫?péU·évdŽ›¾L^}ËR—öþ¾:,å~æ÷Ôqxå-÷f=u|Þý蔽?¿ï%W ¾òæa{þËw=2yàÁ1©aJÙKZtÓ°³\¡•u”¼üÖŸüìÔ sÖêM}tûÓ$-Yî%M$wðQÇ}h¢&•¾¦_ª/0µ 1I`zëžÓ>:­"0uRc2‡iÈ}#‚ÞèIoêBGœxóË¥(Éaúõ 3/) ›úÈÓ/k¤XçP€³aâ±s^9àLuµ £•I`6§“ÚÈi˜LIØ/ @€òN€Áâ¼DXÓ)g^Xº8-?]c£º8=aдߕì%Ù!—Ü3_#€z–Fƒ}¦1•/N—§ Ð36·?¹Ê¥b²Ñ7]œŽ}öeL¦¼ô—δÃiLud¦Àaúî¡óWmµÁ:7Ò­a7g;ð¬1öè­†JÔK¥1•ÒÃÐzÌ:êáÆßõÔêK¶Ú•ž³TLÖK5ޤ”Þ˜L 0[… @ OИâðqeÚ§ÎÅ—SO ûÓŽ«éZ˜_1qf 1Õv-š0+|§"$-9›Â©–pWeÒì•2(Jù_ö>jšMg…yK§ž=PÅ&­*Ï·z‡ä‡a#¦Ú,Uþ\UzÿðwÞ%W^}ë'î}|ŠÔ% ºx<÷â+ûþqÒ$”êE¦„®"åHÈ^ÒÂ1'ž¦™ã$HóóSm 9ý«¢)ªäBSéJÓ³—*Óf]~Z.+º­”ž)äüÙ¨ÜrÑL.™Ð˜ÌDr“˜5ÎÆdkG5&ÉPMŤæHcºìêÁõd#½¯OøÁ±1+ÄøI5«Š šX¹èÒ«GO™§…‡F=-iI˜ýkGšcV,»Ri¹îRv•ÝÒR?ÑHñyCæhŒøÜÛæhÜMÿZ 5§1bM$¤­“ÃhL[ÅDÃÄW=¼Ä&Ñ À‰&SêÿB!@€ M g3n¡Z—¦ ¢§Ö0É&=`süåÒ˜æÙÅ©ÆtqªYºtqZzÆ&ÈÜïš¿¼fº³C‚äʲɮÓË&Óýw†/±CWÜüYLܧœÉ†bªe&9Lßüî!óVnñ;ª˜ìÉ@ŸØŒ‡6—\IcÚnÙ¬Íaêwí •žéäBO‚•ziÙd:÷z) PP¯-ÉÅo;€rH )‡Ýš&5I ëS¼J1aÆiLÍd~‰šÁEÜÚ²Pš®Ê©.óKE¨Ø9kÉ+ò%.»fHH]2‰¢t (éâ ñR)ë’“–Lc*=ßb%P&T,Õ‹ŠÔ¥s^yïcST´¬l/Jõb×Jï"AB šŸê®G¦hÐCj~*Í'A²ºØ¿*ÃÇÌ6AÂÍL˜ü¬.5&6ª)[“ÊÕÔ˜”¢ÉMW7SMI_Ë®ÃdÓ®\Ï7Òûúôˆï³‚—©L’•ðáTû¸ªˆJ~v%›ÎS—vjÙš©˜Æäþ Rœ•4&SOøåé*š¦ñþ‘Se,Ùd*NWÒ›ÁqX9öî{<Иt*åR0OÜÊíò–ôŽ%@Ó±g“ŽCÁ1{ÉiJ¶dE&Ó]¥ÜK–MÉ( ².Ic*%^òËY rsÆéàÜÿ[Ë^’´¤iãtˆZÊ%Wθp4¦ò±ºpó×¾y°;VÛk/9™IÒ©„Ü&ÿÏacæ~ïŸ?ùá™ÿ{ñ2쬭Ë7î·Ûñ'žÒ#™z³ ꤬‘âÇg¬s£oz3û•`˜xÅö²ÆT&~`òKœ9F“—±¿’Š©2§ÆÞ6|Òûç½ßÿÛMþ ² @€ ÆИ3JûÓ§OÿÒ¾_«z²’@Zƒº8•Àd6J ‘Ã4ðžyæ0iœÁ4&ç0雲ÃÉì®Áõ˜ÍßÿÃg¶üâÿÓÍ pö• ¿öì¥ê˜·.ßÿSŸÞcÖ¢õ=Cvn¥ü `0ȦÁç0©—êOßaR¦‡)4\%“ë¨{a¿qGüÇlpkëhM†ooMû7õƒ I ©ŸF—t_cŠU)ÆKcúôu¥ºfEÙRr•4K.ù‹“–,É®+Ê·$wâ× ±©âL]²¹ªL¢0}BsU©„².I“PÎS—Ì[ÒtUÍÐ-k¯ô ¿h–ª[î%ABÉ)÷’ Kò"uIš„þô‰ácç|fÿâr/‚Dlú¥¸ùãJ“,ùÉ\bÄ}”‰lLvô†²1ICr“>í…ÆäÛO=1HcúýU·ú9ÇBËúTS½jB‘ÃÉŸ.rhy•¾ùÝCg-~EG×ÌůXj%QOLz^ 67œéJ:Òªó›•Sœé+nŽF]æ êÀ³É%-ÉRÒr0"óC$-9sÐIK.å’Þ  -/‡Ê´$iI™–,—B‰„¦1é°ÔÑXÊî³M"¡ŠR¢Ù„qvXê©J¹„¦+}ý[kª8;,å0iæ8½ÙO¹—Jçþß ŽÒ¡Æt¡’éÏ?ÞpŸyKr˜ž|ö%iLãf½${é¾R6¦ÙK½Ò˜>½û½ËÆÔŽ'#OüÙOÕ{ºœ7ôväÀ Ò˜lôMä5ô6úÙ ¦£iŒøðl˜øñéë5L|ÿä5áéäªàäií»ß×gÌ]±vÓ;˜L=³Qm@€ ¤‘S£Òë:)ӯϸ 'g{%´Æ7tqZžå|u0,(‡iàÝóìâTC Ò˜œºÖò0Y’`=ÔNÎ]ž[6¦{† ]ûÜôwWÌ(hžvŒ'ä]ÃlLz–oùæÈºåÑm ¡hðÄ¥²Ö µþôæ’›põ£/X&—Í:”0Ìec:ã7g©—¾±¤:37±ƒrO`؉ÁmÂ×7ôú§”/@è<4¦8Æ\™v¾²‡$ $¡1ŸOM_,©öp½Ð*vúsUùÞ’=Ie9_FN|^fÅý·´ÃЉó/¹Êt%›¥ÊŠô K¹Tv'Vl—2qø÷+bh¸W~ãÛ‡H“Ðlq,±|›t¥+o¹ß&§’,1åùuÒ'®¼ù~?Ï‹2¼(ý’å^šøÜËv])5BÿJc?g­nÓ?0z¶æ§ ®4‡'óí¥à Ô›“Êe`j˜~)d5eTc’äIáüC©YIOàí¶Ûnú¾½|*É#³—û4¦+ouù¢ úôðïë'Lª¥"•'}ó>*KV<0tPÙŸJ¡¤#êÔsêß?\=DÇØu· Þ9;xGËîHsùÍüIå-¹?o6ZAQš¥glС¨#SE+<9c™9-wâiîØsÒ’æ‰Sѱ'oI“‡NZÒ1&“Iù–tdÊ[:録u4îýù/k*G›3îÁ±slÂ8Ë„VN‰V:&U,1š~ü³SuLêàTâ%•ÒÁhL²—†>8Qº’¼%›9î—§]ø£Ÿž¢ÙK]v‹~qÚ…_;ð @cZ$™¤JSÚùAñR Å‹‡õ>m&“4&)>*µe&]¢wæ¥îzé•·–g¬¸¥:5k¤ø•‹Ëå¤ëgX”LJ¦“ sÙ”Î}ØEã-•‡¦½¬sŸHºŒýbâ;LÖFL¦Î“­B€ @ x,ÎKÌe2ü› ܳ6¸a§ÊÀäÔ9Lß=Ï.NUtq:|ÊKzöéÂ;æ§Ê§¿»g³CÜE}Ùazp”]™ª¼û> ƒóÒÚÒŽë¬J£ÓËœûü k^9e%nÙfEq½ÔžS‘·Tžñ°4„¢?m.€‹î|^y¬Õ?­\zß [éY;PãQóƒ(ÿY¸3Îàzéo¿ß–Ʊ@ Æ]ŠÆ”HQK’S\ع2-äAQ Fw]còUЍkñä3ÆëW4«U¸Ì/&-Y±LKVt (BŽ„•Ç'Ì}jær-ÈX:üÇ[Úó–,É‹¥\rîDpaøíCT”ÒEj„¬‰`θeÛl¶8•‡Ÿœ#ƒBÓÆóóÓdJèþû¡G§"_BY]´šR.ɈqÓ]O\|ù­&HrÔ±*$è}¾,GBv„œ»Òt¥æäqµ¤ˆ^YÔ˜ ¤ÌLÎD¦¦~ÔðÍò±ä9€þAåZ;GLœûû«‡è_—WiüÌåzGG—o,M_¸AÅY\Qr3;ÞL|tüs¤<õX*ã¦/³âìñ2›¯qê¼u*îðs ´t¦¤%Íà8Y%Pa–n4÷e91*R—nºû S—‚yÇαÇÔîxx’-È(4©pÄ”%7Ü9R3Ç™ºôÔì—žzö%;8å-Ùñ©å[Ò!úؤ%×Ý1rÈð N0¼÷‰Y·=0AÂÍ=O̲$i~ž´¶ØK½ÍÆä†¨LfzoøŸþ‰òZÇ4&\Öc}±T}fììW}æåGžVY;qÞköœ«¾©Œ˜±Þ’c)Ó°Ékî›´æÞ‰/Þ;áE&HVܯ¨Ã„É”­µ… @€@ª 0Xœêðô®r2™NúÍùÑ‹S]~–Õ•Û§—r0[‚çòÅéÒàâô±gÖéúT§÷éâtâ‹O=÷Zȉ:L˜L½ OÖvSD`r­7“iÎÒMn°Û†¶m¨M£(ÁHš{ ¬<ãá¶Çg¬`òK*Á(ʤ5æ¾Öã0Ug³Öƒp¾Ãd½“©½6B L‰®¤˜S\p¸2Mq×¥jm Ð}éècL®¨éNŒ{zñ?|z÷†ZEyx¡ŽVá»JΦ°g¨ü¢«T”ðÅŠ“–47œ” gPhaÚüõ*vK݉NŸP¦%MQe÷ÙUîztŠæ§²”K£Ÿ~A³TÓÆ•d ó%,ý’oJhr*™ʺtùÃôoi¢¤ ÷Òý£žUn_蜽ää‡ iL’ìzä›H“ôf© Oš6!)äwWÞZåÙáQ)úTST?Šy§t õxNôªèq:Ì|Q©²Üã*ù“2F=Á²·T:êBž~6€*Á q¥Iâì ´"yP%˜*®r(:iÉÜ ŽnA9áÝTŽ•c²'%ZÈ+¬NŒ¦'Ûªr£õ†‘)Û«.ù™™z•©êy;̓þØÙÌT_czw疫ʇŸüíÝ]*Mê´¿½â–r¿*­‡Ø<¾ÃT h;‹”¥ë¯5{oáC d‡SvbEM!P@hLqAçÊ´€‡D¡šÜu)P)œ\áåI2›bì´@cªgVÔÕ*VWpVB…û³Ú¦¨ö(*i–Bɖ̈ê ­‰@–¨øU²DéâÑ/54‰EÁÌq~â¥ffŽ«JéÒ·Ù¨2¤1Å©…Ó˜zŒJÂ1_<Ò§:öB’;lü…z‡PôýZŠR9ƒ™ŸWɬ”hqÙ•ëJ•|<µ¥¥ÀXª’–ÊG '-)Ù’ŸoiFõqhÇdï¼¥RîêÒŒºÔ¶9ãÎ4׺Æd–d&•Z/ N=zô^3/ë'™)ôùäþG÷jŒ50™ÝÒ3ôV{ôm›Ok9LáDèñ&S¡þ{Cc!@€ Ð) wŠlbÛ•Éô«ÓÏ÷’FW«!¥A yð/N[v˜B&“.¥UæÞÔ?Ô~]}í·bPØqw4 »d2¦êÓ•;ž÷æt«ã$…µ$7é[9‘REÉŸ|±GWªˆµS+ÕO°Tˆ‰äX²ÇË¢ÒR(ÓR]i©Wù–d6ò–Bgç&Œkè0i…¾jLõû›Æ§¢£«¶º†´z{üü丟^2èæ‡´2Q`Ïè[ø B—‡)ü¨k3“ãÞy÷o½­$ëC€ @è!À`q{Ãù ìwZÿPz`7ËyOz›I‚{—‡É9";Þz?þR:æê; M Œ7þ€o=øÈŸÄ¬Ð“ŽÌ²%¹²ÔÒ&ÕÐ’êÊIì«V”â,¥:GZYa±L<‘ìJÞ×3+\m]©Nš¥&3-…“-%:O\3°[§C“ŸÒh©¤l ˳ô¯>Õ“y*zSUrµÇFõ¯Šȳ,Mõ^2™.ºì&Ën“KÂäžs †‰½'q˜2y¢Ò€ @È4‹3¾&*/“éÄSÎë¹8õ2—/N#Ø´æ0¹ j=ä¦âÒ…³iö ùº ÖŸ2Hlºv»Ê¶ì8M4ˆUrH@&Óþß×?£cA¦Ü™·dR=̦÷-͘þµtM¼ ô@cJol¨ ð1S\'àÊ”C$ß’Иb\‹Ç'ΗÆÔدˆ8á©ßBBEå¹'B¥/©^J·×«JÝdKiõ–BþS&xiLJc#éÓƒŽøIƒã¤¦‡ä¿¹dKÍe5«˜yß"ó/ÚDŒ›ƒRšˆ±®¨T;µRYs©™`©JWòÂì¦Yj2'S‡4& ›Úv6&¥"IÿêÉQ³—ô²ø*–{É$µ¤÷Í]2™.øýžÀŒ»Ñ·I•ù5q˜šÉ:€ @€@û 0XÜ~¦iÜ¢L¦Ÿýú¼ª‹ÓZØôÅaò/¥m¶8{þGæ‡þ”¨ä_SG/ºíòœW‘ ÈdúÚ7š8w½ž =æ§²î‹ÃdМ¤ÐXÞqŠ’MçÔ9íO×o‹&Ú´@cJ{„¨ M).ü\™úà(@ã»®1Å«N4¦f]‹%µç}kRTªž–ªñÌTQc©lMÔœ!.&ÃKå.|“6B—WCcÊäa/I9lêéDz_ŸêØ‹Y!æ£ò´nõçwsZR%‰ŽiI®TùI ,¥’¨ÉiæTÁMõ\¥FºRNr,5:èÆÔÃC&Óù—Þ<äZkŒXp˜ºö@€ Ô À`qaº…L¦Ÿž|®qRCúâ0†" í,Àd:ð ñÏ­·<ÖÑÇÀúè0u¶ölH4¦4D:@u 1¡1qp—@SŒ/ñÈøyÒ˜šq-ÊfEdÒ7_¨ˆW)ì1•%’`©<£QkÓR¥[ZŠJhL™<HcR›Näÿ©O¥1ŬP'CRHHªäLòÒ&¹üIq)”Ü‘VûèòšÅ‰J1®R%»Rát¥zbS¦5&„2™ú_zC0ñŸ—¨ß‹Ã”É“•† @€@n 1å&”M4$0™N:×]œº Áº8Åaj‚«tƒ€L¦¯xÐSsÖ¹Ôãþ`QËsÉu£êìH4¦4D:@hL-ô®L[€ÆW2D )F¥xø©@cŠ®P-$5ÈóÒØ¦¨«RÔ5(‚ñ Wæ7ÖójM 1eèðí©ªiL¾QZÖ§ÿvøk®PWè«'úùïÇeN M¸X9ºjù€ö¸XØRªž®ö!7£ÆýaÄæóå{ͬkLêÜ2™ÎûÝ ¡àâ0eò E¥!@€ ' ç)šM´E&Ó '3i~ð\+8LMc•îL¦o4nöË¡Á.¦îÅ€=A »И²;j S\¹2-À!Pè&v]cª§R˜_ñГÏKcjì!õ.‘RUª—`’¢:E•«3+\IœÈ«Æ”É‚4&MÂeÓ±ùÅM…¨O¿wøkÍŒ’šù3’z¦TŒÕ’êúIu¥êtJ:Ø•Z:Ýä@c2“éÜßÞàζ8L™<=Qi@€ 䌃Å9 h͑ɤ«l¦&P±Jbd2í÷“`ç:*SbÁ`ÇÈ4¦lÅ‹ÚB `ИИ Öåi®G )F¥xpÜóÿ©Ý{éZôB¨¨'*yy^ÂsRåØXªib¡1eò!I3p•½Z^‘>ýÞa?vRQË áC¨Vš2KVæÊ¤`R0+%')TÈ¥Ô’¥ÔУ̇Æä›L8L™<7Qi@€ äSþbÚD‹œÉD¦&h±J2|“ ‡)™°Wd‘S£F!PhLhL…éì44B ë“2ÂÄÃÇÍýûؽyÅ¢®SQíQÔµ”Èó1(И2yšÆô“O¿ööõÊO~~ú—ö;ðÚ¡#z[®:"R¿fhãrõÐÇ) øÎ¡?R‰©ÀE—ßöéÝ÷X»é¿¼ñöû)<”“é§]´ï~_Ÿ1wE¨Â¡?ßy÷o)¬?U‚ @€rE)WáìEcd2ýøç§+áÍ=ŽŠ¿8Ýöæ{½Ø.«B }ÌdRG=ãÜñ½tÓο|øÑGíÛ3[‚2K)³¡£â(4¦¸(seZ„c ÈmìºÆ¨!×Â3+.¾|ÈÿñŸþsŒhQË©eQשHÐ"Èè® ýì´˜ÊÿúœK¥¤_Ø­PÇõСC¬~)H~ùçÙç¿ìù‡ÞäÏø§ÿç¿«Ä7ðØŸö˄Ƥcù¤ßœˆÃT¨s… @€@z 0XœÞØt¼fGœòÜò¦Žƒf} ð»;÷;âä=q˜ú€¯B `И pš l@cBcÊV¥¶í$Ð]iîܹ!×b¿¯àßgÿû~íSŸÞ=ÇjAú›&×eï}¾_Ï¿¿ ©‡a'¶?ZÁ§¨I Ù˜t€Œ\µÏÂWÆÆDuƒ @€Ú@€Áâ6@ÌÀ&výuW|-}“ ‡)-d}“ ‡©]€FC  hLM@b@ )hLhLIõ=ö›<4¦vH<½Uò·~ ]4&4&ôš@ 5&—ŠÉ%dr&S Ï;Éÿ¨S@€ @ ÓИ:M8Ûï?¥ÿð¥ÃVÄL&¦† X¡Cö¿wÿ-»¶ÄoÜL&¦…€ÍB ИòEÚÜ@cŠ -W¦¹íø4¬D ©R¨]cRH4šS6ï|wçŸÞ‹_‡OóD`Sÿo¤ê·ÑOÅä'dR%ÿò~ºªš*nT€ @è ‹;7›^óúÙ!c_«Ú,ܲÐþUr&—ŸI+XEeÌ~eû3µ§…! n¹×-{Y÷Ó¿êú×ïnyÙ–l^ØPx* 9 T@c¢G@)&€Æ®LSÜu©Z$­1éNt¼' ÑbëïæÉ%È\[¤»4¬ó‡}Ô†ÞØÖM]cj+L6d„R1ù ™’©{… @€ À`qÞûÀàùƒe‡ š5H •Ϥ¢äL~~&}ª”®Ii5ç<å íKõIõ=u×é¦ýèÑ*ÖMW’ä¤e-ôÛOÅÿ(]Í 6€@âИ€ê@cŠë\™rìä›@ÒS¾éÒº  1%Ÿ]C  ¢©˜B ™Ú°6@€ @ ·,î-±¬­ïüÙ!&‚襗öÆÞÔ¿–ŸIÖˆ ’¬µ’úfž€Ì$“íä3IT²ö˜c§—ô&}j†“½#ñÎÖç@ ŠH14¦¸àpešâ®KÕÚ@© ÙD  1¥1*Ô Í¨™Š‰„LÍdM@€ @ #,îÖmÔÙ!Z b5óíË̤w,Ž•5€ªƒ€D:›ôÐ9vÎÀÓ›ê“r˜¤7éS뢖<¬lh% ÐhL½¡Åº€@—  1ÅçÊ´ËÝ‘Ýu™S—³»n@cêiöøàÃ÷6¿3ÝÊÚ7‘½4}ÃÏÝ;o½·ºûd“€ @€š À`q2½Šùj‚ÓDBvˆ&éM’™¬™c_k‰šxA ›œZ眧jèM˦þiµrN^7+ɾ @cÊ@¨"ŠK).ö\™÷È(FËјŠç¶©€A§Éù$ðÎ_7HcÒÿVóÙí’/C¹$€Æ”˰Ò(ä…S\$¹2ÍK?§µ  1Ñ3rJ)§¥YÅ#€ÆT¼˜Ób@€ ¤˜ƒÅ)N[ª&9ÉæÞ2™É^˜ô¦™LöŽ26Yò¦¶`g#½% ®¨²ë¯»,y˜½\ŸtUÝØŸ±·{a}@ ÿИòcZ @cŠ W¦îÚT½ hLM@b•,@cÊbÔ¨3j@c¢[@€ @)"À`qŠ‚AU @è4¦¾ñãÛ€@G  1ÅáåÊ´£'N)ñPÎ@cê W¶ ®@cê:rv@€ Ô'À`1½€ Ü@cÊM(iòH).ª\™æ±ÏÓ¦hLô†œ@cÊi`iVñ 1/æ´€ @)&À`qŠƒCÕ @è4¦Þñbm@ «ИâpseÚÕÎÈκN©ëÈÙaw 1u‡3{@Ç  1u1;€ @€š'À`qó¬r·æ“k|aÛU¹k Êç6ž=mý1¹j:J©£xÙ8 Ð7hLqü¸2í[ïâÛi'€Æ”öQ¿  1µޝA mИÒê@€ B`°¸Àá¿cán3^9±ÀhzH¶{xùg3PQª¤„SJA5 ZИâúW¦5ù&€Æ”ïø¸uhL>MÏ4¦|Å“Ö@€ @ ã,ÎxûR}4¦¾Ðã»Ý!€ÆÔÎìù!€Æ”ŸXÒäS\P¹2Ía—§I4&ºCN  1å4°4«xИŠsZ @€ `°8ÅÁétÕИ:M˜í÷Sß²‹S±âMk!1hLqãÊ4cÝ™êö’S/±zV 1e%RÔ l~gºFŠWî )@€ @É`°8ù$V4¦Äг㦠 15Š!4&: bhLqÁáÊ4Å]—ªµS ²‰4@cJcT¨Z `Ó‹¯ß×Âwù  @€ 6`°¸Í@³´94¦,E«¨uEc*jäi7Z%€ÆÔ*9¾tSd®L»ÐÙE‚И„Ï®;I©“tÙ6ºHàýÞ’Éôîß¶vqŸì € @€@ ¸k 18ø™i:SfBEE!hL) Õ€j@cŠë\™rÔä›S¾ã[àÖ¡18ø4€ @€ Ð! wl6‹Æ”…(½ŽhLEï´½%€ÆÔ[b¬t‘Sl®L»ØÙUИ€Î.»A©”ÙÚK`ÿ{÷ß²kK{·ÉÖ @€ ´“ƒÅí¤™±m¡1e,`…¬.S!ÃN£!ÐhL}€ÇW!N@cŠ#Ì•i§ûÛO–S²üÙ{Ç 1u -†@g,ܲp¯[öZóúm^ÿÊgÒ¿ö§½Ü²´2ÂSgâÀV!@€ X ¸ƒ 18ø™i:SfBEE!hL) Õ€j@cŠë\™rÔä›S¾ã[àÖ¡18ø4=›úOé¯lLƒçž¾aúÑ­2hÖ —ŸIÞ’–Õ²~cû©øe³¹Ô€ @È&‹³·¶Ô©-ÙHG  1u/‡@  1å0¨4 ù!€ÆK®LóÓÓiI-hLô‹œ@cÊi`iV~ ÈLRQûä3IT²†*?“-HoÒ§f8Ù;×·õyA€ @è‹»Ç:u{BcJ]H¨P„è4¦Þñbm@ «ИâpseÚÕÎÈκN©ëÈÙaw 1u‡3{@Û(Ù’R.isZ°ùã\&-Ë^’Ã$½IŸZ®&- 1µ>‚ @€š$À`q“ ò¸S£š‡6-Ùz¥ì%+ÖüÝ=‹?áþœ¶þ˜<´6@í%0羯?°\.þìÇ¿Þí㫾ÒóÎÛ[Û»7¶@ ehLqè¸2m¹cñÅL@cÊD˜¨dï  1õž߀@¢\â%·àò3©^zsË®-²—ƾ8Öª©üL‰Ö—C€ @…$À`q!ÃnFc*pðSÝô×ß]¢ÎY³,Ûvcª«Nå DHT:ýëî`´ 9*‘±S@5  1Åu ®L9lòM)ßñ-pëИ |šžM•”~Iy˜”fÉZ IÌéM-Ø›šHÎ’6¹w²ÙVj @€ d–ƒÅ™ ]ß+ŽÆÔw†l¡C&¿|TTc¾ô“|ø^‡öÈf!lxììÚÓkK²Ý.jä‹S\<¹2ÍWo§5ahLô‰œ@cÊi`iV~ (»’Ê®¿îÒäq®•–Iy˜\î%™Lz‡TLùí´ € @é&À`qºãÓÑÚ¡1u/ï š ™HÅÔ¤|9'P3!©˜rušì@cŠ‹W¦ÙëÑÔ¸7ИzC‹u3D)CÁ¢ª€ @€ Œ`°8#êD5ј:A•m¶‹@(!©˜Ú–í@ ·¢ ™HÅ”Û`Ó0d•S\ä¸2Íj¿¦ÞÍ@cjŽkeŽSæBF…!@€ @©'À`qêCÔ¹ ¢1uŽ-[î;PB&R1õ)[€@Î „2‘Š)çñ¦yÈ$4¦¸°qešÉNM¥›&€ÆÔ4*VÌ4¦lÅ‹ÚB€ @€²@€Áâ,D©CuDcêX6Û..!©˜Ú…”í@ çü„L¤bÊy°i2I).l\™f²SSé¦  15гE)[ñ¢¶¨K`ó;Ó5Rüâë÷Á€ @€@ò,N>‰Õ)1ôì¸9.!©˜šÆZ(<—‰TL…ï €@:  1ÅÅ…+ÓtöZjÕ.hLí"ÉvRF)e¡:h•S«äø @€ Ð wjV6‰Æ”•H¹žJÈD*¦"wÚ^°„L¤bê58¾tƒSe®L»ÑÙGrИ’cÏž;J XÓ† .} 8ð¼ó΋_‡OsFଳΊoÑ7ÞØÑƒ°]—ÆtÅ8²1µ 'Û @€úF€Áâ¾ñËô·Ñ˜2¾‚T~óóžYvYAK3ÛH`ëÖ­mܛʷ·n½î¨,U˜ºBE"€Æm®L‹t,±­hLEŒz!Ú\,éÄO<èÃÏ»` +ç^0°§œ?ðß>üŸÿeïsÏ¿ØÊ9ÑÒÿâsú_|vrVÿgW£œyÞ€r9wÀ™^9ãÜ^¹èŒsÊå7ç\T³œ~öEÑrÚÙ–ËYžæ•SϺ0\μðÔ3/<¥§\pÊ™=å×g\P³œ|ÆAù_Î?ù7çŸ*§ŸÒéçÿªNéwÚù¥Ò?T~yZÿ œ.¿8µU9¥ÿ/N9OåÄZåç¿>¯fùÙ¯Ï ÊÉç†ÊOO>ו£ýÕÿ÷û?=é\•ÂåœN:ç„_ó÷ÿð™éÓ§§ÿ|0æÉ‡?»ç^ý/î—þªRC@€ @ ÿ,Ό붩ÀÁÏFÓß{ï½£Ž:ê_÷ù’žxÌF©e:èIH ¾-Y²$Õ¡]%@ô»Š›A½$€ÆŒ+Ó^v'VÏ4¦ŒŒê6K pÓ·Þ±ùõ¿egP6å]Wn¸õŽsÂÆïºòÚŽwƒ²]åÏ*¯zå•möˆ­»\Y¿uWP¶e]¹¼³nó;/{eí¦w\yiÓÛAÙ”5®¼öö‹åò§_ûÓêW{ʪWÿ´ê+o­teÃ[+¼²|ý[Ë׿ie™ÊºrYºîÍ ¼¬òÆ ^Y²ö +‹ƒòúâ—‚²È•5¯/ì);¼ØS濸sþêr™·zGPVåy¯Ì]¹£T¶«<§²¢\æ¬Ø”åA™½|›•g—õ”Y˶ÍZª²Ue¦+/lá•éK¶¸òÌ’-Ï,.—§oyzñæ§eš+ 7Oí)›†›û÷ÿ°û”›&»2Ó¤rÙ8iþƉó6îý…ýÒ¯1Mœ8ñ[ß=dÞŠ-rÑtQÝì €õ @€ tˆƒÅ›…Í¢1e!JÅ­£9L·ÝûøøK¾¸ï×0™ŠÛzÙr ¸é‰ÐY‹Öi߯a2õ^æW'ú™! €@Þ  1ÅE˜+Ó¼÷ÿ¢·©è= ·í/œÆ$Qɤ¥*ž®dË7ÜhL1êR 1…ì¥mî­À$™És˜z¦ZS 0µßa 4¦ÚSIc*;L=Óš×yÓÂÃTјæ­Þé4¦^8L%É9L5¦¶Îô5¦%[«4¦ŠÃ$™©¦Æä9L›§,ŒhLó7Mö¦Ió²¡1•¦Cç­Ü„ï¥×•: “)·çl@€ ¬`°8+‘ê@=ј:•M¶‡€9LCî¡Gû4ŠòäôÅ_ü2&S{Øæ{+%‹åBë63®S·ÁdÊwÄýÖýâÄš–B »ИИ²Û{©y_  1õ• ßO)ÂiL×ßrGÙR²4KåLKådK×ß|»4&?åRÔ[² L¾º¤åZé—”‡)’©J`zÇe`êE¦J&? ÓÊ^åajà0LU*¦Ã´¦q*¦ZSŠ)ÈÃTIÅTÎÃÔG‡é…j‡)œŠiK|*&%a gcªÖ˜”Š)ýÙ˜‡é{‡Î_µÕFR;åÍÒ”˜L)=éR-@€ „SA]«™hL~ª›nÓÐûF(I¹FQ”\iÈÇ=ƒÉ”ꨥ¡rd;õÌ •ÞÞßÔm¦/ÀdJCdºQ‡ úgýn f€@_ 1¡1õ¥ÿðÝl@cÊvü¨}]…Ó˜®»ùö°¥äæ‰Ûög}úßœš-.–"ÞRH]ªš<.b/U§_*ÙK•)䚘4£\+ÉUæ’+O$˜ìÚÛ›N®y˜4¯\ãéäÊsÉ5;ÜìvN'q˜ùÓÉ©˜œÆTžQ®V*¦”kLæ0-XµÕI‘Ƥèœt:&§~@€ @ 9hLɱO|ÏhL‰‡€ D 8‡iYi|Ìž+eß9öéÅ_ '¦³XªºMð áÎg濬nCN¦|w/úo–&1$6 ½*údäÊwèi2G )s– ·SÛP²¡t(¢Æµ”Ê –¶ýùÚ@c:>”i©ÇXRÖ¥-=eÝå[²d]R‘®äoæ¸`¹&í¥SÈU20­zå-? Ó / Óò o-_¯ò¦Ê2+ëÊ¥žÃT-0E’0•‡r‚ ³R‰$ajv.¹fó0ùӳ˶ÍRYª²Ue¦•ðtr[jN'WšK®)‡©Jc 9Lóƒ¸ÒÄp×ÜhL¾«dËž±T’–jå[ R.Uϧ.m|{Íko¿X.’ºk/ý©Sȵ 0­m”„©áDr«wÌ[µ£Ö\rÛËsÉ­Øþ\©´8—\Éašá•*):—ÜâÍ¡éä¦.ìIÅdy˜¬<0nîßÿÃîA6¦ù›&•ËÆIžÃdÙ˜1Þ—ÒÔ…?!T¦mõFRæ­"Òï´þ-˜LG}ô^{íÕ|uŨ¯hýzßÚÿýCWÝÑwÜh—>êß¿¿6hÛä@€ d’ƒÅ™ [{*ÆÔŽl¥MœÃ<û¤bê™QÎZëI0kš²è ÿ㫽2™Ü0ˆ†2ôš>}º«²½ãþTzõ½AÚ¦vêß¶íÈßÅØ±ckšÍTFmѰLTF‰o‚ ­¦ >¼æwUÿ~¥—Z}Ø«-˜ÅRî6ÞŒr=ÝfõŽ©óÖªÛôÖdR-pöRóU±zñНsÃ<n…@+Û¾ì¥xí¶ÛnÚ¯{§áÖšh›õw¤î¤wj91}#Z™nö–E߈ZŸ÷O Z%ÿHÑiȈªjì€O}EËÍæÑutÆpS V™f6ÕLLj_Çê]§Þ™Su³1äƾׄ-@ £ИâÇ•iF»5Õn’S“ X-k §1]sãíÕNR•¢¤Oð“ã¨T3Ç’Ë·•–ÖÚlqÞ„qUsÆ5R—Ê3ÇÕɽ´Ò˽¤–§•[È'Ì9€ @H‹S†d*Æ” wö!`Ó÷, ©õ¤bÒ™FÃüœ:%)H">bò‚æM&7H¢*¡{í÷ÐЊÙð3â¸1KªdÚ˜‰ ƒX~7¨â7KoZ{Sb‡­¬e{ß½¸¬*ZpY%U™Ð¸M4‹’ÖÑ·¢AhÇš©mÊSÑún;n5UÏÆ‘lDÈjr5¬-Ú‚Ó³ïËÅrvà0…R1i(µÜmzì· ýüäçzg2EžšñrÃhÁšè\'@äÍ1´¾g©˜ÜíSS^ô©“ÉÜ ‹ ¹eú3´}û®þ…”,÷‘{BÒ*o«…ý:‡z—*:4\£:Ú[b¢_<ætîco£oÌëÒ²?ò)Ô~ú%}d«Y«C[ÇßÎZÁ dúbÍsŽmÊÎö ¹ƒ–Íq¶êÙ¦¬Úþ€°>r'+;ÒݩƣܦBY‡7Î8Xý•̵ËÎ]Ö |¶/÷2›3ñ“€@âИâBÀ•iâ” t”SGñ²ñäOcºa¨?;Xhùê†~ÿÇÇW)J‘ìJJ°α¤4KU™–l¶¸Š´ôÚŸä*ùe•ò-YyÅÊ[=sÆÕR—*öÒ›ºr¶¢§Çô ˆ•žÜKAZìªÜK5ì¥hú%iL=öRp%Ö9I>ÍìåÛÊÅËÀÔ”ÀT„I ™žYÜSž^¼åéÈDrÓª¦ž‰ä4—œ9LšH®¢1•¦y%-EKª&•s“{LAžª?'à"ü‹Sš5™t­hãhî¡]Ú@’7é:Ù].Úµ·{ÐÇ.ueëòQÛ;ZͶàžãqíîj9$-ÙøHrçFö @€ ôƒÅ}ã—éo£1e:|¹©| ‡ÉϪRÒüœ:Jh-I£(#&-øü—šš]ÎÝ;ÞD·q»%oC%zYl#¬q»7ïŒKGäËCQWÃ6ë†n´`6ƒ¶£•m<ÇÒ˜y`÷øM°›šÚJ3’™aõ·aÛ»Û íÚÏcëë[p5Qóý=úGÇÕ\¡GQªÊ«Tž.<1\EWªi,Õ”–ÊSÅyù–Nš3®¬.Õ™6®ñÌqmµ—bÒ/ÕžB®Õ LO/Ú<­Rz%0˜æo6&“s˜–¯[ß(£Ô~ˆp‡ùdþHÊŒ’ö³X“É¿¶Ëf{¢Å`Òµ«]HÛÕ¦?dæ.­môÊ¥>Övì+~êi» ¶Çí9E7D‚ÔÓ_š@€ P$ )Ú¡¶¢18øÉ7ݦۇ Æß4„RÊÃq˜^/O'WÿI0 ¡<üÔ¼Ï}q¿uë××kUHcòWóµ †(]Æ@l ÅnÕkœÄ†D|WÃÌ$}×ÒóÔ›TÎFlÌEð-³o¹)·,㎭l;µ ÖÔ˜šЉãh_6ó”¹NVð¨˜ÆdµgÛ¬’N]Rµý æ’êCÅrÖ…®Û”2ñx“?¡X¹Û”ß*©˜d¿éBu›q3_üÜ—ö‹ÏÉ$\¾fÑqñÒ§¡PšÌd£gÎA1P½Õ˜|¼¾vfѱ­¹Îé"Õ˜b3ÔFBÉn³Ö™ýNXsPÑú†ë]nƒ55¦õ–f£_'WOôg5ˆ~HcòÃáL;„}—+Ç?~R9ÿðwYú'sÈÜËfy³ƒ44'¦ß[L³s'+7®ë¶ìöå¶ýÈl­ÐX±ÚåF•CzVè¬b[Žê€I@Ø/'€Æ®Lï T £И:Š—'G ×“Ë(›\[ßó‰'ž8èº!«^1÷¨FѧGÿð¸ÊGoÕ“ä'¹RÊ«T/»’.z=])7ñË“O/d”Š´ôôÜÕi©<Â2í¹UyfìÔùrV¢ÞRìK£&Ï[Ì5¦²SÅŸ6.”xIóÇ)ëÒˆ‰sg,Úàr/M_¸A¥ôt‘+•ÜK½O¿t×£Sf-Ý6yîË*Á“mV¼ôKÃÇα ~W†™ýÌ’-Ï,.—§o ʢ;½$),0-ìIÂ䦫d` ’0©X²¥LhLžÃô5dô³F=»Á¢¿¨4ŒbÁUg½°Õ쉙ë]*&QI¡ûÙÉçÖœ]Ξtñ0Kamï¸kE´¬—=J¨ut]m_´uì)1½lÂ>µËW½ì"Üå[²+swjû"Së§9¾ @€ ”`°8%H¢hLIPgŸç0é1°Àa*=&‡IC@å„:¥Q”© 7)¹ÆÁlÈkÔ¬ 5ŸÓÔƒO>c2¹¡’hFÐȆ³vܘ‰qßµD#j…콩ђaà˜¸7&cÙtLnpã3ö|šîôÛG6Èãç³±zº4ìFþ0Ž ÙWlâ³he¬ ²lÉróزÛWçòë4lŽ[!d±Œž½Áw˜FÎ\?{ùvJµ¤õê6ÊLoÝæ©ç^µ ^6ª©Á·±3V«ÛĘL_÷ Å+J5nf¡ùí²ïúý-:¸gý*Ê9wÛ‹m\Ñ´=šSRsûÖ ýràüÍêS»›`[ˆ*º¾áïÔÜWƒè-¡èë¤1iÞ¦ž,\Î`{qçäýèŸûj)Û¶æ£ïHF?]Óü@Ô‹ˆñÑËé_¡cÙmÍEÊu wB¨ S4¡ÍEÖV EÁ‚ng½œÓÚ—ë«¡j¸tSwýéêot{·úX9×d·Yǧùƒ5!WhLq‘åÊ4¯ýžv4&zBf „¼£ÐŸ 4&ýGÐ)ív™}æ#CdJÓmÎ=Š. ºö¶£~x\½Jf&…Je28 Ž„]% —œÙÿ’=>ûÿ³ræy—hôäŠëoÿü—¾b%IY÷æ·¾w˜ýyôN0WÉ•£~t‚[ù[ß;´’o©Îlq/½®”K~֥ᣦ}ó»‡ÖP—ê'^úÜö=åì‹5ˆc唳.V)9Lá™ãâ&+Íï™4º¢ûÌ{êªþ¤3.R LºÎ¿óáÉÿúù/;IöÒíMú×}¾lSI` ì¥Ó‚)°—œÀÔiÎ}»´£‡€9L WouI˜Žºd¢•®˜vàÙcî|jµs˜.¹gÞÀ{æ#)+¶ß6zåg9|À„ÃŒ|úzKÅ$Œf}ýô¤Ú&SGÛÂÆ!@€ `°¸@Á7©ÀÁO²éæ0 ½od9åy%•µžÓ(J0)XIGx`ÊKGœ`2ŠF‡Ž¸xÂá¥rí£/„Ÿ[¤pÜÜøœLI¶™}ÇШJ/Y,§žu¡ßm4àæ,–SnœuäÀ‰nðíøË§>úÌË)ÕàÛÙ·Î.¼ƒoe‡©2ø6zz“©‰z•WÑh¾Pü,VÍo¡ˆkö&úÊÂåG_êŒá‹} nã¬1öø¨¢Ü§Zôû];£sÑ/bìh3 Ð4¦8l\™¶Ô©øRf 1e&TT´Š€M¿îÞ2Þ—ïëjL2ÜÍ»7ÉRȺ|¶)™°¼·Ñ–Ætùµ·ÕV‘‚DÓo]~ÍmGþð¸’T[Kò3*•Ó)YR¥êÉà¤+Ùó^Gÿø„›ïxÈt%{ükÏîùܲ×t%ü›ó.QtýPùIæ-ÉX3e¾®‘¬hY++ÝÎâÒëb=]¤k3+z̨\–—Ó&ë©#WjÚKR—zr/IcúÍE*ººsÅÔ¥;žd“K¿$é_öùrmiaU¦)^ú¥) 6E20Õ˜úª1ébXÿõéðoƒ&ur˜*]HýDÒzLÐz‚& ½Y¦“¯Ÿ©kéwϳ0iîîñ/êû–Q˹lŠKÅTÒ˜ÙëL¦ÞžAX€ @hžƒÅͳÊÝšhL¹ iTq˜F¸ÇÀ\6¢HC1‡é·÷Î×àI 1•ÄNº~ÆÅwÏÓ¼`zjî€3Ç”sêT? ¦!”ÆÍÝ;vv¹ *`õä¡îôc+3™Ãê6Ò˜Ìb‘Ãôëf™Å2nΫ’ÞÔyúe ¾Mxþ5=@8máfu›3oyö÷úÁ7=@¨±Ê'žY¥n?»\“aqO“{¦IbÁs§­F_g _|´èß>nÕƒèÛã£×=¾ôØ?N-¥bÚzØ€ñM_ß¹è7ÛdÖƒŠM).þ\™ûèÈë;|«:ÿialfa§1¹ŒÂª‹›^¹®Æ¤/ÛôÆÑ †õü‡¥ ÍÜKÓ¯Öœ‡´þM}zäŽ3 )¦ôhIÎO*[J¨dÅ™I7Ýñt¥»§w4=œ\%³”ݳ¬?g/}mŸ/}eÊs+u…leÊœ•Ò˜î>Ö¤¥g_xÕ’-ý´ßéû|ñ+*Gþð]G)åÒ‘?<~÷ÜSÿîóÅ}-÷ÒÐÆøÝC9íÀï*ÁåWùÜ÷=ð;‡¨h˜æþS¥+iYÿ1ÕŸ3Î4¦À[*©Kr˜iÅö½¿°ï7¾}ˆŠvôÈSsä-ðíCTôþÞŸßW×lZ¾åžQÁÅÛ²mzç¡qs.¹bðÞŸÿò׿u°’0 ¼b°’ëjAêÒ¯~s‘Šô‘ŠÔ%³—nxÒgöø/J¿¤²ÿ7–½4ô¡‰Æ´hóE¼E zSÿ6ž?NÓü L JI`*ÍW³´0©Üö§†þû{WÂV†Ø¡!p˜”LkÕÖ’÷¦›UPÒš*ÎFßî|jÕñƒ¦)Äcç¼rÈer˜‚Ñ·RFëÙ¥XèZZÃ(¿¼fºä0—ŠÉL/‘9þWçÔœ]®C-b³€ @€@0X\ `‡›ŠÆTàà'Ótç0U#ìEÑóE)eÓy]#f—Ü;ÿþÉ/IF±Ñ0{L£(N]«„:Êîæ³tà ¡lÒÒÞ_ØoÝúõÉ´½¶@ÀD+ud¦Àa:óÂÊäƒ=ÝFSÈaÒàÛíãV›´Fçá§×z³nS·Q>ž«^RJ'ßÓm489rÚJu›¶˜L-(ôWúý'<ñÑO?fö+Ò˜ÜIæ“ÓùAÓ˜Ùˆ~¡û‡@  1Å+ÓtQªÐA¼UÝÁj³ébÐ|ÁÊ©ägc2Ê©$=Éf—k0©\Hc²Mze¬4¦Ë®\WBZ÷¦>•Æä†<äŽ8-É™I¡yߢºtJZ‡ô³_ýæ7ç^"{éòë†J]’«d –õ´T$3–.¿v¨Ö”ŸJ³tÃеÎÿ¸§æ†»ìÚ¡ºpºìÚ!ò“ÌU’·tÁo¯zà‰iR‹f,~E—ÓÒ˜FN|^ Güàø¡÷¾äTÙKãg.× Ón&‰;ûâko{@®Òa£5XóäŒà£ž ãVn×Gæ-YÊ%Ó˜ôPšV»ç±)Ö9öÄÓN>sÀ­÷ŒÒ‚å^’´t÷£Sn¾gÔß:DÒÌè§_½¤ øC>nÔ´d/Ùlqò5¦ïù“Ÿj¹—ä-)ñ’Š4&˽tðQÇžyá !Óã“—|zÿò䬗4rtÑe·|í›Û#MºJt%’~©±ÀÔB6& Ló¦NjLæ0Í_¹Õu0ëWê-zS9aÐ4 LºxÖè›kÙè[YcZ ÀÙó@Êä§ {f]p-]€ ¸iÎ`2eôlFµ!@€ v §=B¬Sá²és˜†Ü;Âݹ¡9Ke=²¤1©¬KÙ¬{æe™(¾Ãô«ëfhðäêG_Í e“= ¦!L¦Œõ>_d©%3Éa:åÌ Ý£ƒ6‹œ ¾Ic:å†Yž5æÊ[·qƒo¦1¹GÌX/‹EEƒœ=.ìé6˜LÉt›>DßÎ&>†¢¯‘XÿñÑk}A§Ž3n~–è'eö xИâºW¦,ù&€Æ”ïøæºu!Iy”ôŽ2ÑZ£{§1Ùw4£\FØÓÕƒc<$}zÄŽ ­àkI —KŠRy8—WI £§Ì“¨ô`I]2W©¼\J°¤¢K#eWºàwWk¡<7\)c­ÊÄgW\vÍ)J§3PEF‘–U´ dKJ¹¤e›$îüß^uü/NS¾%}$¯E™–,ß’þ}~e ¹XѧzÇÊn»íöèSϹ ã”]ɼ%]ËXRÑÂgþqOe÷‘#cIïhA¹—N:s€Ô%ÉIw=2YÆŒd/óóSÏp…ì% ýœ5àŠŸüüT—oI–’.ê,“¬šîÙïô‹”cI–ÒЇ&)÷’ì%Sm®¿s¤Þ7iÈð‰ZA V>½û黽ä235™é¹›Ï©!0ÙÈùŸüøúÛ[9á¿ó»‡Ì[¹¥gÜ­4†b=GÒ#f®³ éG,«LÊL¨TLß5Ï9L…;ž\uÀ™£COƒÙ&S®Oþ4€ @‰`°8QüÉî)Yþ…Ú»9L·Ýû¸sP Å¢”Ü4Š¢Yä4ŠŒž­ÚñhIcr)Ul¼ëÉç^)=V53ÔÔÒCtîI°“ià~íbk! Ÿ!—É_(ef*9LÔë6˜~}ÃLu »=>}MA¨o+·.iÚZë6åY_ØúûûüäSüƒ<ñ•‘·²Étî¾if»‡%sRÉ>DD 1Mˆ:LŠ~ 1yÚЫ²à_zß?ÑÏI/*ÚÁ%ùW–  1ÅE+Ó,÷mêÞ˜ScF¬‘RÑlLª¨æ…“Œ¤…^hLn"9M3—Ñ„LÒ˜þpõàIŸñýc+*REHZûº’'ùNRÍåžDJÝDïS•,¥É³W*©Ò¨Éó¤1•D¥×‡zZ9–FM~þŽƘ®d–’-«üáš!§ž3ОùP1]éÔ³ÿËÓ•fÉʈ sm†8]K[Ñòï¯"™I—Ö÷=|dÿÊq±©â$-Icº÷ñ)®Xâ%S—œ·:n†©KV¼Q”`„M£(K±Q iEc)–ReðèÓn6E u&:3”ÿ$˜|”}ÿy¯%ç~éÃë¿É}ú´¨'²œþ‰;ûÄã¢qàò p¤ÛÈV ,–Õ;¯xpqÏ„+ƒTiLM[kƒoW?RÎà¥Éæ½h¼›…Ðeð²Á·±Ï¾¼ß7þíž_øþußI;´Üx}ˆ¾1ÜЫ3Ø}u {|TY¸îzjµ ½^pûÜ nŽèÓ·³Màì¿ &ßä•ehLhLYî¿Ô½oИúÆo'HÀiLšnúôéVÍ7§—z¡1iC˜ô9Pz%ؤ–w-é÷WÝZÓ7²7õéáß?6fs’übfI­²sÒìR—†šfÀðËÓµ IÓÀÙ;ʱ4ô1zGSÂÍXôŠþpõ“–TÆÏZ!ßHN’ÆYÆÏZ®yâN=ûâ¡ÃFËI²âôNÿK®²dK.ÓÒá?8^ßzlüsòZ$*é#Ù-úWËZ8ìûÇ;ðÊo|ûß]y›¤¥{›¤Y*KV”cIÆ’þÕõØ•·Ü¯å‡žœ£y¾µ ‹s%^:錋T$-iˆGӯ飛î~B—mO”–¿þ­ƒuýfÒÒ„9k5gÜvª¦Ó0ÍWÒ˜.TùñOOўͧôK–ué±IK”²[3Ç]vý·•&=÷¦?0AC§_pù×<(x¢¥\6j,É=ÛÔ¤ºä¯Ö¤Æôàˆñk7½ÓåIåüÎ!s—ovö’ÍÅôœ”„é±é/+ ú á‹ƒIÙKÃ( ¨&Å+H‹uÙ”«^¢@\ù𤈪=Dè?d“ÊÉaRëT0™Z>·ðE@€ @ L©À}©ÀÁO éf2=h¾¬Ù:>Dß4&7”¹ME§ýÎcÛ]ãWK|´Ai»^ñÐb¢ßz°øfHaDcJC úP4¦8x\™ö¡kñÕ @cÊ@¨bmNc’ä$J»J/-Xr¥“t%ÙO¶á±cÇj.9}3£“]^zå­õÅ£×õ©4¦êvº)Þz* “\æ¤z × ~àw•Ÿ$‡É䤑Ÿ×Lpîy«wJNúÜ÷UÑ‚ sEÃ+C†–Ëb³¿röÅ6àréUC¾Qzó”³.Öà‹Œ¥ÃpœeZÒ5ÕàûFþýãl’8%^’·¤kl9LR—TŽ=ñ4Ó•øö!š?Nÿ>üäK³äŠì¥½?¿¯„$å[ºòæavY.9IÿjXçÁ±s4UœŒ%½£rèÑÇ)åÒY 2u风½ñ®‘ºz·¬KÊ®¤¢ÄKúW“šÿ.Ú|Æ…ƒTd/٧ʺôËÓ.<ã‚A÷zV _ûæA•~qÚ…nî}bÖAG+{I“Þ”ÌôoGxKV*™™[°—z;©œiLV$3ýû{ôd¥vb‡Î='NTôŸ[¶Éõ.KÍ¥Ñ=fEÃ(£fm°a…õ²û]6l‘"%«L‰Ðe2vÑx%µ~xÚËÁµ´9LÕÓÉ9‡ “©Cqd³€ @((‹ ø ÙhL~2M/›Lc¦÷ØK•ìæz8pììW4–b“†Ë4ò«ëf¸IÁ¤1IGÐÊMO,ïq˜*ÓÉùó‚9‡É†PÔTL¦dâÝä^}‘¥Z`r¨Œ—í%—ÿøË§º‰äf,ÙrܧÊ~3õMG™xlðíæ'–ÿä²)²Xä0•’ñ„ 9L˜LM†® «õ!úcç¼â†^ƒÑ×ëfXò6EÿØ?Nµ¡rEÿÂ;æêÔ¡èWR1ý6ÄM$F)1ômÛ1SJ®LÛÖÑØP*  1¥2,TªRÜjÊÀ$ I/KŤW©™dh»4qôéaGSs…à:6T*i“\þ$A~R©ì¨*ž¥dõK0°*Û5Ôâ&†3KÉ•ò¬pöTPez8óZB%d,XYfsÉÙ´P× ²Ê£(¡2 åçar£C˜LiïŒ&²Ô˜\å5\ü»+oõ»˜Ì{«ÑmJƒo64|ó ¬é0a2u©Û´;úN|´¡W¢ß¥8²›®@cêêŽí)-W¦ëxl8:|«:m¤…$P8éwW”¯KkºGúTSi°Ã•j)¤%•´’P©+'9i©†¥<æŠK­Ô²®dˆÄJKµ¼¥’´Ôo)¬.U{K–e7F]ªØKåÄK}É·Ô)ÉÎ’™tU\ýzeæØÉýžyY‰k¾æ L¦oüì’ÞÐ[Àd²ZÏè[èBzqÈaêÉhíÏ%çÀa2ò‡€FC€ @ ,îÔ¬l)+‘ÊY=Íd>ú÷è ˜z+¢Øã|u¦p6ëzSÍœL‹ï¤A¡—Æ9ðý׿…ÓõQ΀§½9¯ô§‹©­L¦ß^qK¸ÛD¦Òƒ =Ý&þ‡iÉÂÃÏÿõøþ?ŠVID]%í`3Q¿´F¿¦ÇVï¼!Ò- &g">T2uИR’^W)W¦½îP|!SИ2.*Û<ÂiL¿tKŒf¤O=ú˜ÆR4‹Rm3©ü¼W E©2\HT*?âãò*y©•jfWª§+U§YŠË´Ôš´ ÕHýçO¯®!P]&ÐLôCâcL üøè»§Iýè×;oÈikm0¹ËÙ] 1e?ŠhLq1äÊ4û=œÄ@c¢ä”@á4¦ÊitÖ¶à}zèQÇÔ›ÐÍ·‘™“LK*=¦S³¿UÏWWTª“Z©œƒ§gV¸]©æÜp5Œ¥Êìc5fˆ«ž$®-Þ’•Kç'Œkè0i…¶kLzzæÑ£÷²ìôìÜ(•–í}{OÅ liý©4NõÎ3£Æ<)“iú¢×\"kKÂT~¬z¥êBº¤ŽMRFëy H3Ó–7þòáGá‘”œži @€ Ð w†k&¶ŠÆ”‰0åµ’o¼ùæ~_;àþ‘O—GáJy¬«+¥²ž±¤4—œ=¤WžK®‡IRÂ;ïþM0ÿöî.¹J² êqi™ì™·è`‘††lŒy%ñù“ã~:ðò›ktKÂäw›ª)]·)'A·X$0Ývìwd2mÚü†‹¾ËÀ¤þ#Ñ÷ÝXbâ”òZ¦¢_cÊÞEß9LÛÞ|ÏH†Îõ“Cï»3LÌ`r^#E»:E©Sd»·]4¦8Ö\™v¯'²§$ 1%A}v@á4&]ŽÆhFúTS¼ŠT#a’Ÿ<)b&INŠó“4’k)Å»J½Ð•‚š`Êöhy&b,5#-M‹ÌÍ·ÔÐ[êNÊ¥Ÿ©í“®*mdJCWÊú«[Ùs3.K“-è}-ØûZÖ;ZˆI-“éëß:ø™…¯–‡ÞJc(îI ˜Ñ·Ò }8L]8² @€ @À#À`q»SƒŸŠ¦›Ét߈iö XÍÇÀœÃ4mÑæ©¥1®ò09‡Éš­ IHrC=zǬ&ÓS4jdƒEúWE¶ŠÖ”ˆ bcD¼’% —åâËoîñÞ*“KÂT_}+?@Ø0Ï‚gçIcZ=¾‹¾úƒº‡º ÚP¡õ ½¯Õ¬{øcŒÉRÊëÞ»}Ó˜œÃ:oÔL7šLÎk¤hWG 1ukW7ŠÆ‡›+Ó®vFvÖuhL]GλC ˆ“yE5‹4¦CŽ<&ôQpíÚZ) ”4,ABªŒJUI•¢R)ïŽ+ÁÓcÑRzž¬÷ÆRðð™+Ä©*½•–”u©V¾¥Ä½¥ÒÔvÉ¥\²gì4ab“±Ò;ƒ°ge´Ž]ˆÚÑ®7-]S½—™LÓ¼Zî•Ð[¬M>³¨y£oäaêι”½@€ @Õ,.p@c*pðÓÒt3™î}|Ú¬¥åT:å$å–„ÉFQ*C(Áƒy½ŸK.ä0©å.å’ ÙCn–iɆ†ì‘6K¼¤5"äÒ5iMû¯d .ËoŽë6‹Ë#o¾úfž &õiLž|˜Ú¨4<–¦Ýì%³”Ô ôŽËée]ÅŸiÝ­£Ý£ýj}­üìhyè5ýf ¶šSô¼L7z5˜ÜQ\l¸ÆºR­‰áJ‰|4‚“Gi)ªIµ]c2WIn|ÊÄ&˺ä†ì<ÿÁ;-ëI¬†§™Lûó Éó6ØÐ[)âe­»Êè›Ë}uü¯Î9ãÜñ£o[ÞøË‡}Ôpï¬@€ @ ) 7…)Ÿ+¡1å3®l•™Lw?:­Îc`ÁDrír˜Ül6#˜hiÇ ™âr[öýkùx´¦û(ƒ˜sXåÀeùÃMUݦÎà› 66é0Ébq®’ú† jÌÐÍ%g“%a²¹äBFÆçqÏa$’hRç¢m‹o½Áäèy£…Áä$(²Ï¬@cÊZÄ¢õEcŠ‹!W¦Ùïá´ Žý#§ §1ÓD UÞѧҘzVˆ¸Gþ„n¶\{Z·zï/iEÉÍd·®c)…E¥F©•‚LK5²+Y²¥º’¥Ñî)¥¹áj¤YR¾¥tgZj&·S‡4&h0Kɼӈ•eZ’ÆdZÙ¨–†*´‚%mj~ÄÊL¦IÏo°ÄZ6‹œ{Ì‚Pp˜rzö¦Y€ @H7‹ÓŸŽÖ©£xÙx¯˜Étç#SŸ®Ì"g£(öüž†¿,§¸ "µœ‡IUr°iÈF~lPH¹LKúÓžj3=Åì_7»\¯ZÇÊ# —å‚ßßtO`ª9øÖ¼ÃdÁÜ5-Xg°ä:zÇz‹ëê?ö¤j™”] whËŠ~´þî¼3˜:o´6˜Ü5tì(«И²¹žz£1ÅÅ+Óì÷pZG‰þ‘SEÔ˜bÄ#iLñ“+”ô£øyÜœTo¡l&Õ—“*™utyìÊæÐp5ç€3Q©«É®TOWÊ«±TÓjj»ÆdÏKé¥ÙK¶àþµô¾ŠYè¥ý龨ä©F&Ó×:L©Ì:.ǶüØû×ràmøÈ# ™i¥\–óc¥ÛTåîrÏvöÊaŠvØ04¨èº•vÙ¯h'¢¥âŸ7&»¯·6˜œý˜Ð‚N@cê$Ýîl)Ž3W¦Ýé…ì%)hLI‘g¿&P8éÂ?ÜãéSiLá”H–©‘~dR´xNRœœT×O*åÚ‰µ”‚4<õò*9»¥8 –šIÂäÖi»ÆÔá¶jóf2=5g]ÙHó´’‡©›á`_€ @€@‹ Ü!И ü”6ÝL¦Ûž\ï1°¾äaJi›©V;.Ë¥7Ôë6½u˜ÚQ#¶Ñ=¥èßHô»Gœ=%H)AømÚ5SH®LÛÔÍØLJ  1¥40T«¯ §1U²ûz–õé¿ñ“ZâQ@¸§, fòŠ/{ÔL‰Ë¢d3…U¦~«•NÉ®£Ây•”»2\íÔJ¹˜®WºR½•3­1éè—ÉôÕzrö:å?Íñ‡ÃÔ׳#߇ @€úB€Áâ¾ÐËøwј2À|VßL¦!Mög‘ëû\rù„E«<rYλô†h·Áa*B7±è—ØËSOÚIƒè!úÅj#SöãÆ„Æ”ý^L Z%€ÆÔ*9¾—r…Ó˜,p½¢Oÿíð7¥yI’êÏææ<¤èB%’ä¤^ùIR”ª-¥º¢®Réª2¾d]c*›Lßø7]<û-ÅaJù™—êA€ @ ÿИòãº-Dc*pðSÝt3™n>ÉB!Sªc–ŽÊÉe9÷·7øÝ‹%‘éF-ˆ~7(³Ä  1%‚>W)!W¦}î`l ÕИR*×:âiL—ÞXIqTÃ1RžØïþãú+îQyú6ÓIH.[’¿P5¿›iI®xY”ü裮ՊA€ @%€ÆTÐÀÍFc*pð³Ñt™Lû|ùÿùç/}vÜäÙñ£(ï¼û·l4‰Zv…À?ú®Æï~à±øn³íÍ÷ºRvÒUGþè ¢ßUâ쬛ИºI»3ûBcŠãÊ•igz[M 4¦´D‚z´™@±4¦­[·N¯~IOñË}¾í®Coòg¾ Ü8äÞ† M¤ScÒ¹aài«^ýSÌH S›Ï l€ @¨G€Áâ÷ 4¦?3Mdþ×Þÿ¯8L™ X:*ª›ÄýïùOK7¼Ósp˜Ò«öׂ跟)[L4¦ôÄ¢Õš 1Å‘ãÊ´Õ~Å÷²A)q¢–½&P,)Š'~´‚O!P“@:5¦—7ïúÞ…Óyú•zQÃaêõ ’/@€ @-`°¸etÙÿ"Söc˜ÿ<¹æÀ‡–ï¹iç_ꢇ)ÿ ÷-´›Ä붯­×mp˜z53ß ú™ mS ÐRö4¦¸€peš²îJuÚL©Í@Ù\Z 1õ̆²& ¤ScúýË¥1ýäò9¯¿ý>sÉ¥åK= @€ PX 6ôL*WàÐg¨éÒ˜^þÙ?ú¨¦É„Ô¡Pv³ªî&±t¥èàS7cÑý}ýî3gÝ#€ÆÔ=ÖÚS§úÛM?4¦ôLj¶D ½&BÉR1YõìF ·ùƒ)äajéôÈ— @€ >@c꼬•lLY`¡ê5™p˜ ÕZnlÈdÂaj™d¿Hô³5êG)ûý )û½˜´J©Ur|/åИz­°4™°‡ÕrL …“¥b²¢„Lý÷ɄÔò³0Õƒ @€@>  1å3®Mµ ©)L¬Ô-c_»æõ51{óM&¦n…%íû4kPÃ*:—‡©!«Ì­ÒPsˆ~æbJ…ã 1e¿ 1ÅÅ+Óì÷pZG‰þ‘SEטä£ÄÛ6ó_ܹbýŸrläдeëßZ´æõx,¯íx7U'?“KȤjèmóÎw5—ªÚR@€ @ ,.D˜k7©ÀÁOcÓ÷ºe¯†ÕÒà‰F{p˜‚*È ·,ÜÿÞý›i¬\¦f@ek£=zú†é ëLô"b…Ì@cÊL¨êV).†\™f¿‡Ó‚8hLôœ(ºÆ”Ó°Ò¬bðS1ù ™ŠEÖB€ @©"À`qªÂÑÝÊ 1u—7{‹# AS¿±ý”[¥ÿ”þZ°b©V¶ìÚ¢e-èO­©¢uZpê r˜Ôm†/>xþ`u -ë_#£ü^zÓ¬ÛèÓ‚CËSó\EßNZ–ϤÔ\ú׉M}½w}äþÌÚR8hLÙ9S\ ¹2Í~§qИè9%€Æ”ÓÀҬˆ¦bò2 … @€RF€Á┤›ÕAcê&möO@žÓä¦HDØõ×].?“þ4I)ô'J JÝ@Š’8˜¥$ÝÍÜ&#£¥N¢Î£wÔT´ uà––‹Kÿ*¦&Aª3è_§1Ù Ä´H­¦›™‚0phEn  1e?´hLq1äÊ4û=œÄ@c¢ä”SNK³ C šŠ‰„L… > … @€@Š 0XœâàtºjhL&Ìö›'à´$—2Gj‚ï£XºÓT,½JóÛgÍ\pZ’„󓜧e}jé»Ôs¬ÛXÿÉ%Š6Jº’eÞòSp¹.a’“‘Çæ2uMÎ 4¦ì).†\™f¿‡Ó‚8hLôœ@cÊi`iV1¼ùÎ_Ï¿c‰•SoZðoNïwÝ<÷΂ß(Z @€ ¤ƒÅé‹I×j„ÆÔ5Ôì¨!3N´šS—¤&X&{Ó¤%V‘½¤¢—s¥áÆY!¯,ÝŽ¯ªøiºìSýk}ƺ\–¼Ò(Z»,¦jµ¥Ý²æ»nö©M¶ž44¦¤#Àþ;D©C`Ù,ºM©ÛÄÙ @€ C€Áâw4¦Ÿ¦C€ 5hLY‹X´¾hLq1äÊ4û=œÄ@c¢ä”SNK³ŠG©x1§Å€ @H1‹SœNW ©Ó„Ù> @h4¦¶¡LlChLqè¹2M¬c²ã®@cê fvÒ}hLÝgÎ!ÐhLÁÊF!@€ Ö0XÜ·\| )aÌy#^wÉö?ÏÍy#i^» ¼óþ†ÍïLÿàÃ÷Ú½a¶—D?A¢Š-@cj]j¾ˆÆ ®LSÓQ©HG 1u+MžSò1 h 4¦¶`d#€ @€@{0XÜŽ™Ü S&ÃV°J?¹æÀ‡—¶`¦¹}%ÀMâ¾Ìò÷‰~–£GÝ@cjD(ýŸsŽŠ‹W¦éïÁÔ°/ИúB輦SŠƒCÕ ÐhL½¡Åº€ @€@‡ 0XÜaÀiÞ<Sš£CÝŒ=¡Ü$nZn¾BôsJRƒSö»稸rešýN â 1Ñ?rJ)§¥YÅ#€ÆT¼˜Ób@€ ¤˜ƒÅ)N§«†ÆÔiÂl¿ïИúΰ€[à&qƒîšLô‹ýü·)û1æC®L³ßÃiA4&úGN  1å4°4«xИŠsZ @€ `°8ÅÁétÕИ:M˜í÷Sßp Ü$.`Ð]“‰~‘£Ÿÿ¶£1e?Æœ£âbÈ•iö{8-ˆ#€ÆDÿÈ)4¦œ–fSñbN‹!@€ b §88®S§ ³ý¾@cê;Ãn›Ä ºk2Ñ/rôóßv4¦ìǘsT\ ¹2Í~§qИè9%€Æ”ÓÀÒ¬â@c*^Ìi1 @€RL€Áâ§ÓUCcê4a¶ßwhL}gXÀ-p“¸€AwM&úEŽ~þÛŽÆ”ýsŽŠ‹á]Ç|üøÙÙ2-€@hLtœ@cÊi`iVñ 1/æ´€ @)&€Æ”âàtºjhL&ÌöûN©ï ¸n0è®ÉD¿ÈÑÏÛј²cÎQÙ!-€@«ИZ%Ç÷RN)å¢zh–S³¤X€ @è4¦.@Në.ИÒêÕC‰ÞÐn·-7_!ú¹ % ©A)ûÝ‚sÔÜ›úí·ÿäþG‡‚ùîÎ-z?û¦¨O‰Þ‘ShL9 ,Í*9+v~ïÂéú·xM§Å€ @€@ú 1¥/&]«S×P³£–  1µŒ®È_ä&1Ñ篊 ¶ç–SöCË/”\¥¿½»+É—ÆŸyY¿ìG˜@ >4&zGN  1å4°4«x&/Ü*I9™Š×tZ @€ ¤SúbÒµ¡1u 5;j™SËèŠüEn}4¦"÷<·)ûÑ-ø/”’0ÝñÅÝ,Óâ{iAå•™cõ§²4­xlpôý?½ºÆVÓ Ù?-(64¦bÇ?Ç­GcÊqpiZ± 1+Þ´€ @)'€Æ”òu²zhL¤Ë¶ÛC©= ¶•‚ß$.X´ÃÍ%úï9o>Sö\ðs”Œ%ç0Yî%efzôè½´ ,M;W-”´dSËiÙ_ïh}elÊ~ &€ÆTààç»éhLùŽ/­+4¦›¦B€ @ ýИÒ£ŽÕ©chÙpÛ 1µ e‘6Tð›ÄE u¹­o½·zó;Ó­Lßðsýº­}ó÷Î_?x«€Lhr>  1e?®ÿ…R&…Qö’D%iIúÓt%û÷Ý[´ ÄKZПÊÏ${Ikº•³ßhA  18øùn:S¾ãKë D©@Á¦©€ @H?4¦ôǨc5DcêZ6Ü6hLmCY¤ ü&q‘B]n놷Fë­f¾ô“|ø^™Ðä|@cÊ~\ þ e)—F-ÈUÚ¼pºL&-»$Las›”ºÉV3ùÉÖÏ~ &€ÆTààç»éhLùŽ/­+4¦›¦B€ @ ýИÒ£ŽÕ©chÙpÛ 1µ e‘6Tð›ÄE uO[G®Ú§¦Æ´lÛÅB«óI)ûq-ø/”¥\’Éd3Çé¥dKR”$3ÉRÒŸZA‰š´`ö’ý«?õ¦¾bñ‚@V  1e5rÔ»4&ºrB)'¤€ @È4¦|ı¥V 1µ„/u•SWqçeg¿Iœ—0ö®52‘Š©wY;ýИÒ£F5,ò/”æ‰sö’&÷?ZÅ4&ý+“Iðä-ÙG–¢É¾bÚ ¼ ahLU#€ÆDÿ€@N 1å$4€ @ù €Æ”8¶Ô 4¦–°ñ¥®@cê*î¼ì¬È7‰óÃVÚMÈD*¦V8ò4@cJstš«¿PÍqb-ä‘S£J›D‰nœ@cÊI i @€òA)ql©hL-aãK]%€ÆÔUÜyÙ7‰óÉÞµ#”‰TL½ÃÇÚ™ €Æ”‰0ÅV’_¨ìÇ@ UhL­’ã{)'€Æ”òQ=4K©YR¬@€ tS §uhLi õê!€ÆDoh7‰[€–¯ø ™HÅ”˜ÒŠ*hLÙïüBe?†´­@cj•ßK94¦”ˆêA YhLÍ’b=@€ @  Иº9­»@cJkd¨W4&zC ¸IÜ´||Å%d"S>J+ÂИ²ß'ø…Š‹á´›>~nXöƒL P‡]#§ИrXšU<hLÅ‹9-† @€@Š  1¥88®S§ ³ý¾@cê;Ãn›Ä ºk²%d"S‘û@žÛŽÆ”ýèò C®L³ßÃiA4&úGN  1å4°4«xИŠsZ @€ `°8ÅÁétÕИ:M˜í÷Sßp Ü$.`Ð]“•‰TLEî9o;SöÌ/T\ ¹2Í~§qИè9%€Æ”ÓÀÒ¬â@c*^Ìi1 @€RL€Áâ§ÓUCcê4a¶ßwhL}gXÀ-p“¸€AwMÞ°aÃiçü¸Èh{ž  1e?ºüBÅÄpâq»O½«!Fcê*nvÖ=hLÝcÍž ÐQhLÅËÆ!@€ Þ@cê¯\­Æ”«pæ´1hL9 lg›ÅMâÎòMëÖKÓþf,Y²öß_u+&SZE½ú@©ðRòU~¡jBêÒ·¾{輕[æ­Øràw0™Âô·ûîÿ¸iç»~Ù¸ã]+¯•Ê~_ýºì¥W·ÿùÕm~¥T6¨lÝ¥²^eKPÖå—7—ËÚM屮´éí—6¾½ÆÊko¿”?­~µ\V½ú§U¯üiå+o©¬ØP.Ë׿µ|ý›ËTÖe©ÊËo¾ðò*ú ¶²xíë‹_z}‘•5¯/ ÊÎ/e¾Êê Ì[½cުϗÊÜ•V¶?·"(sT–oŸ”m*Ï. Ê,•¥[gZyaëŒR™¾d‹•gåi•E›|òùO~j÷i 7O-•) 7MY°i²•ù›&eãÞ_Ø)%'Fª‘uhLY õ‡@™]€ @H4¦£ÛUAcê6qö×{hL½gÆ7>æ&q;nñþ¯ì?qæ vU7M/½“©€!ïMFcÊ~„ù…ŠÆÐ¦ù+·–Ü—7æ.ߌÉ¢¤ß¸ÏìþÎ[òí¥×¶ÿYEöÒW¤1šhSà0•&ç0•¦]ëœÀ´9˜œÃTÖ˜*“Ó˜|‡ieµÃhLÎa 4¦Àar“â(‡©¬1•¦×–&§1Í«¡1mhL=S¼ÆôL-ɦ©%‡©¬1Í7i#SöϦ´ EИR ª¾@cê =¾ @€ ´™S›fishLYŠVQëŠÆTÔÈ÷©ÝÜ$î¾ ~Ù¦I3_PB§1)ñ&SƒI•c  1e¿ƒð Šaà0}ïЫ¶Êƒ 4¦Ræžç–mú9™x̸ñM‘õVr§G;7ÿ²“ª‘š9£ê§!ôÑü¾zµ¦iL~¦%7g\Ù[ÚºKÓÃ#'¬·Éã‚òŽ›Bî劽žEΘBÉ­zåO+_y+(ѹ䪦ª¹äJÓF¦f¦“Û™Nnûìå¡TL[g-Ý:S¥’Šiú’-VB©˜LcúûOíQÎ¥b2éÁãmr=+¯íx·WqéõÊ'ïöñ°{ý-¾Ô@cJ}ˆ¨ š#€ÆÔ'Ö‚ @€ºB©+˜Ó¹4¦tÆ…ZùИè-à&q вøç0³ÛÔ¹ >oÕŽçWí8èæÞšLº3m:ÎÑGÝ¿ÿ^¸Þßk¯½|{¦_¿~z§!C[G+K{Ò‚þÔ¦´¬wâ¿ë*ãVÓMz}]ÓGúúþûï¯T¥¾;=joÆį`ÍŒVF•\¸paÍïÖû(Æ;v¬¾e&“5¿/4¦ì‡™_(‹¡9L‹^ÜVSB5Ig{m2I-²³«^:¡5<Áº>¥³–Ö׿vFªwFÕûv*ÓXײþm~/­uá’Æ´Çú­»zÊ–]2–¬˜·´o 1÷Õ¥°½´éí—6e•×Þ~1(rÓêWÿT"¹`.9K¿¶^¦f¦Š¦¹Å ë¼ ì°_ç 41ܳË4—\d:¹*ÓÉùÓ¢Ír˜iœiL›4—\y:¹›&ÓÉ3ÊÉaª©1É k-@Í~ ©YR¬—1hL Õ…@=hLô @€ @ EИRŒnW©ÛÄÙ_ï  1õžßø˜›ÄE躧ûeÍ%÷ìÒåëߪw\7Ju‹tîÊÏ­Ø>ðòÞ™Lv \îgû©˜ÄÖ7‡ µÖñ5&ÝÕö})GúÓÄ#­l“ÞÑŸ¶š½c ¶¦‹ m*ª1éÝAw«©ú®Ò‡Xž'· ·eÛc´Vþ ¶5·N´2~UýeÛ²Û”5ÓUƶi$£Sè#cåVy5Ó%¾ò?’4àܲA*oÇSö#Ê/”b覲„ZÉ¥·(˜4˜QÎré•NàÛg,zíëßêEN&‚ü³¨ÎîOÿâΓvÂÑyFg;áØ)Å?‰ÙùÐzŸÖ±_úlÆdíKç5)H°ä—ÍUù–öÝïë¿ÖK¼äç^ªm/½ö'©Ke{IS$ÓŠ ²—)ê0)ý¡e`²¢TˆA6D+ANÄòì®1“~ Ke»~¦UæXY^•‡©ÊaŠOÅTq˜œÆ4Åט*Ó¤’ÄÆÔ—Éw!"€ÆD—€@N 1å$4€ @ù €Æ”8¶Ô 4¦–°ñ¥®@cê*î¼ìŒ›Äy‰dÝv˜Ã4åÙ¥¥;¬õS1Uî‚붨榹ø½0™ÌRÖ KzäO!g¹[ã’i´‚S”ô¾yNv‡[ŸZ^ýiëØ rK餵lÉ„,Ÿ‡mÙî—[Û¸Þ÷qØfu+Ý¿[ïl'}¤ïÚ.”µÈvjwèm_ú¢ÕS«…$-«¤5Á*c[°—ÞtëÛ²¿/·«³­` «BSè#K°ä[bú¢j¨Æše…²ž(4!k!Ïý)ûÑåÊs˜"ªÓ˜”°Ç$Ô•×òÌÂW›4™ìäí&þ9ÄNÎZÍΓv"ÒyFÚ Ç¥í$柜uÒ³}þ‚}¥£}Ó4&eWòKÈX’Ƥ)Ò^RÊ¥JÖ¥u)”{©b/¹ôK½˜–F&ßa* LÕÓêy˜Úì0-ÞütEcÒ\r–©'“s˜*©˜Ð˜:ÚcÙxÑ 1-â´7oÞzë­ûî»ï˜cŽùæ!Ç|÷ÌßüîaZ~ä‘GÞ{ï½¼5•ö@€ @"€Æ”¡`µ»ªhLí&ÊöÚO©ýL °Enç;Èe‡i¶ç0U2yy *é‚™k¼»àÒ˜”ÑaÀe759»œS‚¢™~ì#ÝÆ¶ÜlR!swt{ÛI?v;ܽc¶Ý;7›Çþ4I·Ø]2³y즻…Ò<¡PXmãú–“œ|Én±«†&c9õGËVËDâjå6î*i­óó‘èOW+Û»>uÓØù{ךö§>uY£B$£©á¡”Næ{X_Ÿr:”å¸ ™XyîÿhLÙnÁ¡œÃ'¡ö¤b ré¹y–m›¶@&ÓAcÆï¦%E׉žœ£éNk¡Ó¾ý韜uÞ³‰,}#S'®¨£Ùö~ª¾Oヌ²+•,™«Tm,í»ßþÃ_ž0®ä-ùÓÆù3ÇÕ°—^yk冷+õ209É%aZ\; Óë «'’+Í%çM$WúuV¦¶åaªv˜JÓÜ¿ÿ‡@cš\šK®4ÜF7Ù˜ÚÞEÙ`Á  1¼ÐülÐÎ>ùÉOîVëõ_ÿë;wn¶›Gí!@€ ì@cÊnìú\s4¦>#d'€ÆÔqÄyÜAÁoç1¤=mª‘‡É9Lkß虨tÇÔ&$rwÁg-Û6séÖ‹š3™B÷³åÜèž·^&Ù½m»Yn‰=Ìþñç²Õ|wÇ¥‰jLzG#Çæ$ÙËeiÒfÍæñëàGÙHå ‰Dî‹î}÷-G¡ð¾\¥eÕ94ñœ%ari™´_­£7Mågcòwº÷ýÈ6ë¶æê¯Û¾{9©Kë;*ß=¿Ü:4¦ì‡¹È¿P5¦úªÀ-—^iZ±­Sç½²ÿ7˜LÑlL–²®™“sMÉ?[ï Ê¢ªk':i 1}fEI–’_JÆÒ—÷ÛÿÇÆ¿øÚÛ2–¬¬ö².ù3Çõä^jd/-[÷æR+• Lf‘k<‘Üón"9.¹`"¹Vç’‹8LSn^Ò˜b&²1u¢£²ÍÂ@c*lèix¶ ( Ó‰'žXS`ò߼袋HË”íHS{@€ d”SF׎j£1µƒ"Ûè,4¦ÎòÍéÖ‹|“8§!-7K÷qÿÇWöŸìæ’[Ü[u·Tå0Y*¦ù/–&¯‰¤bÒ]ð™/l±dë…¸±aN¦Ðýl¥ÒÍl½´àdv‘êç’¹,&úøw¸M{ª™)t§ÜöårŠ˜¢ä×!4œU©É2ùwôC½9É ›;å÷+¹ìMÛ”Y¡½‡ª¤,m•Û”¯1ÙGj”s’\5ÌXÒîdkÙwýXr©|wûªÖ¡1e?Ø…ý…jà0¹é䢩˜*ÓŒ¶Nž·!Þd² mþiÁ,OÿT=9›cÚPcÒO§Ð¨‘Ù…^i“ó“¢ 2–4×êý=%]É•U¯þ)(¯Xyk¥+^⥚¹—ØKõ20­Ù¹ ©$LeÃX’qà[­åÛ¬HY ¬µ’¸üjÛw¥L_²ÅÊ3‹ƒòtPªæ’S&9LJÂTÖ˜êäa"S:-»(4¦B…›Ææ‡€fŽkè0Ù §œrJ~šMK @€ ¬@cÊJ¤:PO4¦@e“m&€ÆÔf ÅØ\aoç;¼a‡É˱¤tKµj:¹:©˜t+Ôn^ðû&Sè~¶ÏÖ}$‡ÆI<¦Ý˜ô#ÏFwÍí›!NïØÊz§¦Ædïk­©[ì6›{G·Ø]þ!«‰œË~d[¶ Iõ4&}dÓ'ÙäGúSÛ7s(j)Y%­¶‚›ÎAÐ:ö¦iLZÍ2BÙ›~6¦Ð®})ú‘iLZG»¶zšËeê€qsM°Ê 1åû¨ÏeëŠù å&ÍV¶lý›fɘ„ªYÉ,‘^c µtŸôü†¯—“Ée“S”ªR+Ur,)[á°GŸ\¹á-s•ü"¬TÞ´RC]Z÷æ€ß_ãÔ¥±SçÿæÜKÆL™oª™Ô¥;‡ýãµC-^içÂJú¥Ë®rê9ÿpõ ˆ%{IE¿ÅA©)0•’0ýöÊÁ'Ÿ9à–{F©T’0Õp˜â“0M+ L›§”ò0©h.¹ÆÓ¤ùUœ·ZØû û=8büÚM︲ak‡Óû¼ÛÇÃNléÌÁ— 03ìý—N‰î§1™Jþ)-4”í3áö±{ŒÀÖ­[?ùÉOöJcúìg?ËÔrë&4€ @I@cJ: î)AøìºIhLM‚b5Ÿ@oç»”¦Y/¸º>êÙ G]2ÑËÃôzp üÅ÷O^ó³ÆÓʲä;£‡˜pÑsý»àÒ˜4ïLÿKoh8»\¾ÙÒºŒ@cÊXÀjT·h¿Pr˜¾8L[Ý |Ò¼:{Ÿrã¬ßÝ·à¼!s»§ÉÁ7ÝþÐç¿ô•ÓϽdŸ/~寡J]úæw=ê‡'œ~Î@½3jò<¥Îré—FNz~÷Üó„_ž~êÙøÁñŸû¾e{©ä×ÈÀT™Eî‘§æ|æ÷”ÆtÎÅWªÌZ˜ÎpÅO®‘„©ÎDrÎaR¦ûé3êlõ&²1eñ¡ÎI¯éÏG¬jØ žÎ㬫1It’qï§¿Ó—-©SRád¿o¼±W“­|ë»>üè#B€ @è4¦.NãnИÒêTM‰Ñ¢Ý$nQ†¾bÓ$9L•Én,WĨY޼dbe.¹²ÃtÎm³¸xBIcÚÜ_¤b:ëÖÙ‡ÑsýTLº n Îû&S†ºC᫊Ɣý.P¨_(s˜¬ÚZ>¿LUöÓ+¦]ýð å‰ÉÖ¼~çS«Ž8A)|&/ب¸ÊÅwϳDzr˜ž|îÕÃŒ—Ædó*SIB NàOÎ^÷ÕoüÛ˜qã³ß)Ê-°¾¡•™ôSø©Ïìár)Õ\Ðoå= t1ÏXªš*®Ú[ò猛úÜ*yKÒ˜,ñ’\¥ÑSæÉ^š>y7 RMàÔÿ)5‡)i…@~¡V¯^­ø¼[zNàcF'áÏã T;ë¤ýÈÓÒ˜ýEÓ€»ž/M'÷Ц“Ó üþÉk¤1Ý7i›NΗPÍdÚóŸþùwý/Q(7ï ™úߥ19ž5¤1ÝõสÍjcÉý†Ú/©¼%•I³ƒiã†zZ)—d/)Ù’IKnÎ8-+L÷œö¹/î{àw¹î¶ôo9ýÒÊOβ19{ÉÍ÷orõ-è·XŦ» þµlÛ¬¥Û”{éÎG&«Hc’¦&‡I厇'éÏ obe9iLCšØ3‹\MÉœ6KÂäý¦£1µrzâ;¨OÀiLn:9-è¥9âô¥f³1Y&½†®´LR¢`$Bà“Ÿüd &“ËÆ$iÝæ]ÿþÁG‰TžB€ @E!€ÆT”H×h'SƒŸ™¦£1e&Tiªhn§‰w§ê¢dßÔ½Òå›{î¼–¦³Y䟱N“Ý/%a*%Pâ‡Û8kŒnë^©&›Nî˜Ë¦üäSn·ªç.xé–§s˜n>iß/eÑ}W¿1rÐÇã.¥@ ¥NÿÄǧü¿;uȱݮ(È/Ô¥—^úë3.pù~Lš±Yätê¾ãÉUÎ@6iÍO°>ÊÜ#‡IE¦‹R.Y"=•¯Ÿ9ú‚ÛŸs xl>P_BíwÆÏÇ-¹nΆ? ovË“/~£¦w5ã•W¼ôì§>½GEÉJ%—’¿ éÎácî’g,Ùh¥ì4™læâWN;g  I§ž3P¡Ñ´qf­áÕ;d/)Ùáa£M]ÒÂá?8Þ~sÍ^Òäqƒï$^*EPI˜4sÜÉgP±ÜK¿½bð¡ß?Né—ö.å^²ôKw>-hLø—I ›w¾›ÊÆQ)@€ @ /ИòÉÚÆÔ4¾ÒehL]žÝä&q>‚ß ™LÊú0wÙfwÛU÷\-EÄãÓ×)Ç%÷̨r÷¼Ë‡/2‡I‰8sL)ßÃÖ™/lUš¥v¸àö¹º^/“Gà0í÷õE«6Ú¨ìo¿_¶´1“Îþ;4¦LΫtq~¡d2ü› |oÆNàîì­‰än±LgòÛÆ¬4F'p9LÝù¼L½g, Nà’Z¤1Õ“P•HïŒs¸{jï¾ÿAv{ˆõ ¿H`zç¯Ô¢`R¹OïQ΢TILhé”\ùâ—©ÚU ¼1+?Tôc*iÉ•òlq«wœzöÅGüàxM§O9ûbÙKr•®üÀ}O ¤¥a£-ë’ýìÊaÒ{åmʺ$ué3ÿ¸ç˜§—>üd0CÜ•·Üó=£´pó=OXî%û]Vî%9L.ýR¿ß\¤ÄK ô¿îóå3/4ôÁ‰ÿ²Ï—/»á¾_ž~áÁG;nÖKá)äb&ó™Ð˜²{ Pótp“«^/&•«™u‰TLéŒ4µ*ý/­é²+oô5&-“© †fB€ @ hLÉpOÅ^јR*K‰ÒâÜ$nNæ¾b&Óœ¥›Ü7–ÃcÖ [M`R¹øîy|`‘ÝW⇋‚L=“îŒ*ÓÐq«jN'r˜0™2×CŠUa4¦ìÇ»P¿PºGvÒoÎwú©é2:Ož¿Q'ðã.ŸªøÄç_s“Nàwñ®ñ«}‡IsŠo©˜J xüDz!‡ÉNàÙ5™|É LÖåKÓîÎIªZ¨ÈIÒ˜n`L]]©ÚX*¢4%«Êª ÈU2cÉÊ¥W QÖ¥ó.¹Ê².=9c™Ò,©ø‰—ìgWeì3K%0ðíCôï”ç×ÙÌq›£ÉãTä0É^šøÜËg ¸Â"{ã]#'ÌY«"iI¿Ñ7Ü9RåéÅ›k©K*r˜ñÇ&-ùåi^{Lj&30ù ™Ð˜²²¤é" ôI¡ )“¥bÒ«A6¦t5…Ú@¼uëÖO|â½2™þóþûç–¬ iLï¼û7pB€ @è4¦N‘ÍÀvј2¤ÂW©ð] …ºIÜ  ¬}G&Ó7¾}Èì6¹®•Yäv”ç!ª¤ñæ’[Z•‡I÷GŸ^¼ÅÒxL]Xš‰FsÐTf#ªé0ŘL;W-üÓ«k¢üj¾™5ÌÔ7 И²¥ø:í*0™N?ßM!gŠŒ? ¨eÑ›]š},0P«ó0Im©—H¯¦Ã”i“ÉúFH`²î$é>½»¯(‰”ª‹4¦¡÷ñ³+U¼±Š®T1–LZª*Á$q®”g‹s)—,ë’ÙfN]2ɦ³bö’‚hq J)÷R¹”rkYy¦”dË~ ƒ¢iã\ñç+ýj—§›7…\hF9²1eÿLI 2F)c£º¡C‡öJcºñ¶{CyŒéH€ @€@g  1u–oª·ŽÆ”êðP¹4&:B Šv“¸D™ûJÉd:xÖ’õ¦ð-ðÒ\rµ¦ùÁt3*1SM“irÿ£UæÞÔ?JïÑ£÷ÊR*œIhL™ [U¥ ø %“éW§Ÿ˜ÊfL%‹^y&Ð’ÃT6]Á%ä0õH¨1S=“éèGNy÷ÙüÎt›B.ú2©ìòZ ¥Hù‚4¦a£-µ’K°Ö•d/EŒ%%[2'¸¾·TκԤºäÛKN]ªi/ùSÉ6Êß^*ÉÇ”ÎBŽzK¡wÈÆ”òÞNõrF)g¥9E!pà6i2vä£SQ: í„ @€@RИ’"Ÿ‚ý¢1¥ T¡4&ºH  x“¸J™ûʸ'Çðíƒg.~ÍIˆ,„ \ÖôÝaÒ¨ì«Ûþüï|ä@Õs•”Šil¿ý3Ç“ g’S&ÃVUébþB]pÑ%ýNëè2¡x9 SU½Ê ¼â0•¤–Àb©$Òkè0é¾qÇ»>÷…[¦_cŠéݦ1Õp’¼¤JÒ˜† -K©ZT*ç¾²¹ájK¡dK¡|K5R.ÕʺT/ñ’E3”{©¦½d[N¿„Æ”ý³#-È04¦ ª™€þ{ñ•¯|¥¡ÉtÀßY´jcMéOfR¹"÷ Ú@€ @cê0à4o)ÍÑ¡nF‰žÐbÞ$nTæ¾2f\`2M_ôš»ÉZžÈÆ›¼&šÆ£g.¹¦ó0ivÓο¼ÿ·"åa’ƤõŽ¥e’ºd™™^?|æeýj¾¯ulÍÌ¡¦Â)%€Æ”ÒÀô¢Z…ý…’ÉôËÓú÷(2=ÓU&’³,z–H¯4ŘKÌSJÆSN¤×ŒÃ¤ø‡õH¨k^_³ÿ½û« _:|ЬAý§ô×òàùƒ÷º¥œHOËz_Q´Tú Îêéy™ÆäT¤š _ø_{G©w¼X»D °7‰‹™L_ÿÖÁÏ,xÕ L³J7S5Q9 Sõ-ð¶8Lë\¥Å÷ Ò²¡¶üL’™V<6x窅¦+ýíÝ]R—ÞݹÅÙKúŠV(BthcÇ  1uqÇwPä_¨Àd:µùì˜1Àd'pÏ@õ¦Rnž>:LQ‰¨JȤ)Jr•‚ÿ*lY¨eûTÒÒô Ó%99{IëK~êxohz¦1…æ}ëImUÊPøyiL÷ŽŠJ5]¥èôp=qñ¤¥rŒ*‘Šñ–ü9ã*êRJ_]šV™6Ο9.±•vØKNfbR¹¦;+B  ИڑM@ AúÆ€K.Ûw¿¯ÿ‡ÿøL²—´<ð÷W=·dmŒÃ´nË._O°þì€ @È'4¦|Ƶ©V¡15…‰•%€Æ”(þ¬î¼È7‰³³ÞÔÛL¦ió_q÷¿ëÞ/ÍPãß¿mø$ ÉÖKŠoƒ´¡’Ætã]#k®XJQÉIK=ºR­4KžgVwª¸ZÞ’æÜh¥µtJ}üS>z>­È 4¦¬DŠzB )ï¾ÿÁ†­»¢2“’0½ùÎ_›Ú+A€ @è;4¦¾3ÌìИ2ºU©@Án_S¹IÜ>–Ø’L¦¯xÐSsÖYâ‡ÐÓ>æaÊ@û©b¡ 1e?ÜüBù1”Éôӓέi â0ù Lc %L ý)é†;GÖOªTš}µ"*)–K…e¢’+%±,Tª&‰ë‘–*ù–J?¾ {K!í )û'KZ%hLYŠu…@“$3½ñöûJδå¿háwÿ¦\MM~—Õ @€ ´S fuhLY\‘êÆT¤h·­­Ü$nÊŒl(0™¾qиÙ/û9<ÈÔ‘èQÍÞ@cê ­t®Ë/T(.2™N8éÜhΞãuÎ爟ÕdÓο䆚iLe©ZE2!Iås_ÜOS=9©ÊUª!*™·TÒ•J© ýRž!®Ž´”T¾¥øtMhLé<R«¼@cÊkdi @€ @ 9hLɱO|ÏhL‰‡€ 4$€ÆÔ+D p“¸€½B&Ó~ßø·±Ï¾ìîk’‡©€Ý ÿMFcÊ~Œù…ŠÆP&“¤%ßJÁa Q2)”6)øsaO‘ÆtÝ#kåRr©•6Õ•LZêÑ•ÂÆRO¦¥tJKQ¥ )û'KZ%hLYŠu… @€ dƒS6âÔ‘Z¢1u+m+4¦¶â,ÊÆ¸I\”HW·Ó7™p˜ŠÙòßj4¦ìǘ_¨š1ôM&¦("iLÿ©Ý{$$—6ÉËŸ$éÚÛG„)ÕÍ«ä‰Jš®2+\•®JpŸý(mŸ¢1eÿdI ²D)KÑ¢®€ @€ l@cÊFœ:RK4¦Ž`e£m%€ÆÔVœEÙ7‰‹éH;Ídºñž±ûî÷õE«6ÆÌF¤©ˆÞÿÛ…EóJ)«‘ë©7¿Põbh&SM>Æô»WeK %OZ°ioiLCG˜“*“æËOre£2*õ”yÓf µ¥>hLÙ?YÒ‚,@cÊR´¨+ @€ @ И²§ŽÔ©#XÙh[  1µgQ6ÆMâ¢DºV;o}ð¬=þÛ'æ­XÃTänÛ¶£1e?´üBÅÄð×§žö›s.ˆ9{ë#I¨~ôQö;BïZðÖ[oýÝßýÝn¼ÚJà?ü‡OLž±Ðïo¶îê]`z»öÉ»}<ìÄÞ~‰õ!~hLé5„ @€ dSÖ"ÖÆú¢1µ&›ê4¦Í÷f¹IœïøÆ·NÑ¿íùÿué†ëÝ'S‘»GæÛŽÆ”ù~Ì/TL —m»qÎË·ÆK¨t˜j{çÝ¿Åû^|Ú4¦ìŸbiA2И’áÎ^!@€ @y&€Æ”çè6hSƒŸ™¦£1e&Tiª(7‰Ón×Å¢¿ýõ5ï_â0u;쯽ИÚË3‰­ñ Uú¾7|é'Uv¼õv½8“£‡ÆÔ‚¥Ôð+hLIœÙg 1å!Š´€ @€ .hLéŠGWkƒÆÔUÜì¬%hL-a+ú—¸I\ä°åé ·üþ¯¼õîû„nXâ0¹cä¤íhLÙ$¿Põb¨TLº6QÑÂo¿=ã0ùèИ:I-¬€Æ”ýS,-H†S2ÜÙ+ @€ @ ÏИòÝmCc*pð3Ót4¦Ì„*Må&qš¢‘d]|“ ‡)ÉH°ïv@cjÉä¶Ã/TMö–ŠÉ4&-èOßdÒ ‡)Ä ©K©áWИ’;5²çl@cÊvü¨= @€ @ ИÒ•.Õ ©K ÙM 1õ^q¿ÊMâ‚Ä~øÒá*ñ5“ ‡© ]"ÿÍDcÊ~Œù…ªC—ŠÉ%dÒjf2á0Õ$†ÆÔÐIja4¦ìŸbiA2И’áÎ^!@€ @y&€Æ”çè6hSƒŸ™¦£1e&Tiª(7‰ÓÖeÿ{÷_¸eaÃÈdzÿo4\ hLRƒ*ò ä§bò2iÍ?ýù¯äaªÙ¥þúïJðŠ)¯íxwõkoǯS¨O7lûóÚÍ»â›üúÛïwösòn;±³»`ëH‚SÔÙ' @€ @ ßИòߨ֡18ø™i:SfB•¦Šr“8MÑèT]úí·Ûïw;úÑ£µùLZпƒf <°ír¯[öÒ¿òœÜ§k^_Ó©Ú°]t‡Sw8wr/üBEé†R1ù ™: ¶ ®@cê:rvØhLÝáÌ^ @€ @E"€ÆT¤h‡ÚŠÆTààg¦éhL™ Uš*ÊMâ4E£Su‘“$?I[—¨$cÉÒ2¹üL[vm±OÝ;Ó7L7ç‰2L)ÃÁ+W_¨P £©˜B ™²sZ 4&úBN  1å4°4 € @€ 4¦á'½k4¦¤#Àþ@cj̈5"¸I\„N¡¬Ký§ôWK•Éô² Lz _:\隤.é­`ÅÄ&^È04¦ ¯\u~¡B1¬™Š‰„LÙïé´ 4&úEN  1å4°4 € @€ 4¦á'½k4¦¤#Àþ@cj̈5"¸I\„N!KI®’ZªK–ŠÉågÒ²>•ç$uI úTeì‹cm5^È04¦ ¯\u~¡B1\¹c¨˜X¶äï^öY÷§>Ê~Ài<hLt‡œ@cÊi`i @€ @ AhL ÂOz×hLIG€ý7&€ÆÔ˜kDp“¸ÂÍçr,ÉR²eKÂ$«ÉĦ]ÝesÌ¡1¡cä¼hLÙ0¿P11|xùgõ¿ì™@ 4&ºFN  1å4°4 € @€ 4¦á'½k4¦¤#Àþ@cj̈5"¸I\„N¡‰ä”‡I-U¾%×^½£¢»ç^6l(2Úž[hLÙ-¿P11DcÊ~§±Иè 9%€Æ”ÓÀÒ,@€ @€@‚И„Ÿô®Ñ˜’ŽûoL©1#Öˆà&qa;…¦#~pìøK¾´ï×0™ Û òÜp4¦ìG—_¨˜¢1e¿ƒÓ‚XhLtœ@cÊi`i @€ @ AhL ÂOz×hLIG€ý7&€ÆÔ˜kDp“¸˜BÓ‘?8î…—ßX²ö§¦/þâ—1™ŠÙrÝj4¦ì‡—_¨˜¢1e¿ƒÓ‚XhLtœ@cÊi`i @€ @ AhL ÂOz×hLIG€ý7&€ÆÔ˜kDp“¸€"p˜~xÜÒuošÆ´è¥×Ç=ƒÉTÀŽ÷&£1e?ÂüBÅÄ)ûœÄ@c¢ƒä”SNK³ @€ @ @cJ~Ò»FcJ:ì¿14¦ÆŒX#B€›ÄEëæ0-[÷æÒ—ߔô¸¤1-\óú¸§1™ŠÖòÞ^4¦ìG˜_¨˜¢1e¿ƒÓ‚XhLtœ@cÊi`i @€ @ AhL ÂOz×hLIG€ý7&€ÆÔ˜kDp“¸PBÓQ?¨ôÒ:öÝéÓ§kaÿý÷×.\ÿÝÐî´²¾¢ïê}½úõëçªÚpS}éÚ×àÁƒ}½ÚÕYíÕ¿j~_jRôï¢1e¿ð C4¦ìwpZK‰’ShL9 ,Í‚ @€ $H)AøIï)é°ÿÆИ3bn¤S˜Ã´bÃ[JÅTšQî F¹@cZ½sÞªsWîxbÊÂÏ7m29s(ªÉÂÑË›LHŠî4&SÜŸkÖ¬i©šu;v¬}Q“™LÍl*~_²‹¶lÙRo³¦Ü jr¯4&g/é[Ñ5„À =И²ßø…Љ!Sö;8-ˆ%€ÆDÉ)4¦œ–fA€ @€$€Æ” ü¤wÆ”tØchL±F„7‰‹Ð)ÂS%“?£œR1=_Ò˜ž[±}ääfM&ól”:h·Ýv eZ’Ž# ɽ)ŸI‘Ó˜´lÉ™L÷‘dê}ËÆ¤e}Å” û®éGÒ’lM'Hõïßß¾•~ôŽSˆvíÚeJ“mJ “´Kzä6eÖ«Þ¾¬·¸Úú’–ëH–É5ÜiLnãúº*ã²CùMÓ}ç ©O‡'SŸð¥âËüBÅ„)}”JtŽSçØ²åD  1%ŠŸC€ @€rI)—am®QhLÍqb­$  1%I?³ûæ&qfC×lÅ=‡é­eë{¦“[¼öE/½^žQ®”Š©¤1mŸ³bûìåÛFLZðù/5ž].>“ŸOHZ,"Ó˜œ„$kÇÞ1ßHrÉOöŽþuÙ˜L’¤­fѵ‚ù@æ<… Ø›¶M—„É6¥wlS®’nS6­[t_¡kƒ&fY…ÝË©]6µœÛÕÓv'yKïë_½ô§L,k‘Ÿ)JëÛû¼Z$€ÆÔ"¸}_¨˜` 1¥¨§R•N@cêU¶™hL)U€ @€ äŒSÎÚ›æ 1õ†ë&C)îß+7‰3ÀÕw“7Ü›/ØŒr/½¾h4¦ó_Üé§bš³<Иž]¶íñ‰ó÷id2…4&Y8Òt,Ÿé;rq,e‘Óƒ´ìûF¶šËÒ¤•c4&Khdn“e`ò§l³XüœF’ä9[ÈyEN?²/†f‹î+ÊÚ4,—WÉV°Ö™Ÿdº’5Ð)JªŒ 'ý«¯ë¥W· 7^¾ûgg[‡ÆÔY¾ÝØ:¿P1”јºÑÙG‚И„Ï®;I©“tÙ6 @€ @ ˜ИŠ÷R«Ñ˜ üÌ4)3¡JSE¹Iœ¦h´¹.5&:¹ú©˜ä0ÍZºmæÒ­Nh`2…4&óŠLÙqù“,÷’M—f)ˆœ´¤‡4&Ë“¤÷kfcòÕ"-KòÝ#›ÇÍæ‰Ó¿Ê´dùì¥?m›Qɾ£1پܦÔsô¯MŠç¿›ZÎ5Эi–™‰e¬”YÊס˜N® S &¼ ~¡b€Æ”pïd÷&€ÆÔiÂl?!hL g·€ @€ @cÊqp5 ©!>OžSò1È` ¸IœÁ 5Ue.¹åëß\¶Î›NNy˜œÃJÅTšQ®¤1mñÂÖéK¶<<~Þçêçdj8©œêjb“ülL–-ÉOYd­’£1É…r®V³?M0r–’OGÕS*&{Çí½žÆÚTt_nËfeÕ ƒo ITÚm·Ý´k-8Êef² ï¬ÕZÁUµ©³RChL ¥~~¡bB„Æ”úþKûF©oüøvj  1¥64T € @€ YhL™ ]ß+ŽÆÔw†l¡ÓИ:M8—Ûç&q.Ãê9Lo.3‡éåÊ\rkß0‡É¦“›¿zç¼U;æ®TÙ>§Ça R1™ÆôÌâ-=ùü羸ßË/¯²ŠÑ˜l9}Å-˜Í£ù:–0Iÿšd³³Yv¢š“Ûš%|ÒŸ¶)½ÜŸ~’'ûH)ŽL¢²—ÕÇ6e)‘lµÐ¦\­¢ûj¦·ø“yZÚå ²& ˆmGÛw@Bé—ÈÆÔ êë 1µb›à*&hL ÷NvßihL&Ìö"Ð@cÒÝÔÈ–wÔ^~^ЄjÎn!@€ @H+4¦´F¦ õBcêdvÑGhL}X̯s“8q7‡I˜\¦ÑÏnøéÓ–¬}cqÉaZTr˜”¦ã/Ÿú| 1mnÅö_]7ãð‹'>@eücÓ×Ó’-O/Þ2mÑæÇÕ5™20:õ[&ªM%ûD©OøRñe~¡b€ƔŠ>J%:G©slÙr‡ 8?^ûq.»dœq“&Kãi5ÔŸ²—ô§^Ê;Úáj³y@€ @€2K)³¡ë{ÅјúÎ-tšS§ çrûÜ$ÎYXå0ùÃã,“›HnÔ³ŽºdââÒ\rÎaš²`“¦oœ5F©˜ä0)“¦[G¯>å¥&¿äR1=½hóÔ…›§,ÜôÀ¸¹{×ÉÉ”3†4''И²H~¡bbˆÆ”ýN b  1ÑA2H@Þ¼&?§¦ì%%5ÉTWc’±¤L¡.}¨V5õÉ}3ƒ@¨2 @€ @]!€ÆÔÌéÜ S:ãB­|hLô‡p“¸h©ýJà0ýà8³—T^xù %a5kÑ'º¹ä,ÓÉ×ϼaÄ2iLÏU¦“S¦'Ÿ{õ)‡©’Š)Иlš<Óýcçîý…ڳ˥– +.4¦ìÇž_¨˜¢1e¿ƒÓ‚XhLt Pî%M”Ò˜ä6ù&RƒIå|I² ‰ý73ˆ…*C€ @€ ÐahLœæÍ£1¥9:ÔÍ 1ÑZ ÀMâ ¥ó+æ0SÉ^2)˜Hî¥×GÎ\/i¡7—ܼÕ;JsÉíÆ¤{ù¶g—m1cý̶j:¹3n~ö77?ûôâÍÓlF¹R*¦IóÉ™Lc枣ÎC) —ßx$…‡@*¡1e#Nqµä*†Sö;8-ˆ%€ÆDÉ,?“&…³vô/½´Ð i×®]‚¿ÑÌ’¡â€ @€ t†Sg¸fb«hL™SÁ+‰ÆTðÐZó¹IÜ·´}ë ƒºížÇuɳ—$0- 20IcZwäÀ e‡iU9“æ’{nE 1™Ã4kéVéJr˜”‡é¦‘˽h|ÃTIÅd“Ê7¾{ÄqÿÃÐùÿ“~)E# y"mý¿v}И²§¸Zò C)ûœÄ@c¢ƒd–€o9É%TjVc’å20 J! ªÔ9Yú¡Acê\?èÖ–ù…Š!ÆÔ­nÈ~"€Æ”xvÛwNc’}Ô¯_?Û ô§hLÒ•Ü\rJßš‘®ï•c € @€ äSƒÚl“Иš%ÅzÉÈÒÝåä(±çnç¦K˜ÉtËÝ-\³SÅ&ËÀôØô—•uÉ•ãþ8Õ&åa:àÌ1ÊÃ4si0—Ü1—M9lÀøÃ./©j:¹ùå$L!‡ “)7§ù†d釩ù¸¦uM~¡b"ƒÆ”ÖnK½ÚD©M ÙL÷ øÙ˜d%™‰ä|¦S´º[¶lé~Ø# @€ @Y"€Æ”¥hµ¹®hLmÊæ:@ Kw—;Ð|6Ùn·Æ-ß*›Lw=fö’ŠËÀôüªsWî°‰ää0I`š½¬<—œ9L3–ÓÉ=³xËÓ‹6×›NÎÏÃd&S:{Bçj•¥4¦Îõƒnm™_¨ÒhLÝê†ì'!hL g·&Ðk©Óbû€ @€ džSæCØzИZgÇ7»E Kw—»Å„ý4$ÀMↈ²µ‚™L7Ýù¨æ³)äL`š[˜, “&’+Í%WÎÃdsɵæ0Õ3™nY˜-tÔ¶Yú¡Acj&¢é^‡_¨˜ø 1¥»óR»>@cê3B6NhLéŒ µ‚ @€ d™S–£×Ǻ£1õ _ï,Ý]îvÑn7Ç)KkÉd:òÈÀd*ÛKÕ“9L³ÌaR¦‚$Lu¦M“æ•§“«—‡©^N¦5¯¯ÙÿÞý³Dº6G K?4hLÍÅ4Íkñ 4¦4w]êÖhLm€È&ÒH)Q¡N€ @€ l@cÊvüúT{4¦>áãË]!¥»Ë]ÂNš!ÀMâf(enwÿò—ƒ9ü†Û±)ä,S( “s˜ž åaZ¸iò‚M“æ÷ÎaÚòÆ_>üè#µë¯»úOé/iú†éƒçVZ¦A³éMýk+HrÒGZпzÓ½Ÿ9άp–~hИ²ßAù…Љ!Sö;8-ˆ%€ÆDÉ)4¦œ–fA€ @€$€Æ” ü¤wÆ”tØcYº»Ü¸5¬Ñ%Ü$îè®ïÆL¦ë‡>˜\¦K‚8LÖÐ~cûI`’º$™éèGûâØ-»¶¸üLò–ô©ÞÔ;’œ´¬uºNˆ¶B K?4hL­D8]ßá*&hLéê¬Ô¦íИڎ” ¦ƒS:â@- @€ @y"€Æ”§hö²-hL½Æê ÈÒÝåð°ËÚ¸Iœãža&ÓuC¶)äz&"¹Å[$0ùS_ò09˜ò“”rIêÒ^·ì%™Iï+ñ’Ü&[Áì%[ǽ“ã@ä©iYú¡AcÊ~Ïã*&†hLÙïà´ –$§ИrXš@€ @HS‚ð“Þ5SÒ`ÿ déîrãÖ°F—p“¸K Ú™L×yئSQ¦h¦© 7Y¦¶8Lj«ì%ýë«KšfNY— ƒ>•À¤•„É•„±ÛÞÈÒ Sïb›Æµù…Љ S»,uj#4¦6ÂdSi"€Æ”¦hP@€ @€@> 1å#Ž-µ©%l|©«²tw¹«`ØYn羘ÉtÍm—¦òDrA¦r&s˜4‘Üü“æmœX*ß=ìGWß0tí¦wbÊ–7þòáGEZ¦%½o“ÇÙ –I ×ײ?Çœl'­™û@ä£Yú¡AcÊ~Ÿã*&†hLÙïà´ –$§ИrXš@€ @HS‚ð“Þ5SÒ`ÿ déîrãÖ°F—p“¸K Ý™LW ~è™Å[žV©LSn–Àä&˜úè0©¡Ò•”iIr’?mœ².)!“+ZMïhš9½ã¯–('vÞ˜@–~hИÇ3íkð !4¦´w_ê×GhL}È×ÓJ)­‘¡^€ @€ ì@cÊnìú\s4¦>#d'¥»Ë‡Áš%ÀMâfIe|½²Ét냖)˜ü‰äæ—¦¾;LÆI&Ó®¿îÒÌq>6½©wô¾Š[ÍR4ñÊ ,ýР1e¥WÕ¯'¿P11DcÊ~§±Иè 9%€Æ”ÓÀÒ,@€ @€@‚И„Ÿô®Ñ˜’ŽûoL Kw—·†5ºD€›Ä]‚ݘÉtÅ-:É&’sI˜Úå0¥ ­T¡S²ôCƒÆÔ©^нíò é{‘=%B)ìì´óИ:Ϙ=@€ @€ŠF©h÷Ú‹ÆTààg¦éYº»œ¨ù¯(7‰óc¯…f2 ºåA˜&Uf‘kË\r…"YØÆfé‡)ûÝ”_¨˜¢1e¿ƒÓ‚XhLtœ@cÊi`i @€ @ AhL ÂOz×hLIG€ý7&¥»Ë[Ã]"ÀMâ.NÍnÌdºü¦á~&ò0¥&>i¯H–~hИÒÞ›×_¨FhL;kdšS¦ÃGåë@c¢w@€ @€ ÐnhLí&š¡í¡1e(X…­j–î.6Hék87‰Ó“Ž×ÈL¦?z&ÓwûÑÕ7 ]»é˜²å¿|øÑG¯;H7,ýР1¥»/5S;~¡b(¡15Ó…X'ÃИ2<ªG‰þ@€ @€@»  1µ›h†¶‡Æ”¡`¶ªYº»\Ø ¥¯áÜ$N_LºQ#ßdÂaêñ¼ì#K?4hLÙïuüBÅÄ)ûœÄ@c¢ƒä”SNK³ @€ @ @cJ~Ò»FcJ:ì¿1,Ý]nÜÖènw túv˜LßùÖ—ö;#d€ @€ „ 1¸K 18ø™iz–î.gjþ+ÊMâÜÇxñ=ƒ&÷?ú¥ñã-yY?÷¦o2á0å¾W´ÜÀ,ýР1µæÔ|‘_¨˜P 1¥¦ŸR‘Î@cê W¶š84¦ÄC@ @€ @¹#€Æ”»6ß 4¦æY±fR²tw9)Fì7B€›Ä¹ïcûíÿîÎ-Ñfn^8]z“ÿ¾™L8L¹ï}i`–~hИúét|—_¨˜8 1¥£“R‹Ž@cêZ6œ,4¦dù³w@ÿöþÚ®ªÎ÷ÅwüÇ{õÆxï¾úûƨÆÒ²¼—ûêë^ %jÔÒRA!TÙ ¨h”^ÚУ ,A1ôBГ„.}K’œä¤O šä¤%A"RRHþßµ{ϳöÚÍÙ{Ÿ½ÚùÙcŽÃ:{¯µæœŸßÜk-2?ç7!@€ "@c*bT[ìS‹ Ø-Eyš]NUW`’¸À#â­7.þŨGF¾öÑ1ê¦2)3“më¥m•Èû2™T´>zeÞäákÈÓ©³gé(îPM¢Æ”¥¡J[b €ÆTN™hLYˆm€ @€ ‹S±âÙVoИÚÂÅΩÈÓìr*€¨´&‰‹=.´lœL¦×~Ó§ŸÚÞ»¾GŠ’%aR–&ý*·ÉÞ×O[cNïk½£ el*6z×.<ÝhИÚnööçÕ$&hLÙ°´¨«ИºŠ““e‡SvbAK @€ @E!€ÆT”HvÐ4¦ qHÂò4»œ0ªkL€Iâbs•ÔGû)ŸIÞ’ÞÔ¶²4é§Œ%ýª÷ݧ&3é¥lL–®‰<ÝhИò?p¹C5‰!Sþ8=hJ‰RPhL ,Ý‚ @€ ¤H)EøiWÆ”v¨pyš]¼7ì‘&‰R5æ*é%WII˜¤%ÙÏ7öö›Ì¤—‰M–¢I?mÛŠ[.¥æSmæäéFƒÆ”¹áÓvƒìõÆ[;Û>ÒƒИ<²ß]Dcò;þî=SƒK× @€ @)@cJ |ªEcÊBhCsyš]&–™!€Æ”™Pt¿!ÎU’·¤Eå¬ÉIZ*NEY—”„Éå^²¼MúUV“í©í·Þ8ØýfqÆ<ÈÓ)Ï#ÍÚnw¨ü÷#– 1Å‚•“f‡SvbAKºJ€»ZWqr2@€ @€DÉãa€ÆäqðsÓõ<Í.çjñŠÆTà›«¤jy8YJ’™ô«ò3IW’Õd™–ô«¶õ‘vö¤CôŽ%mr†Sѵv äéFƒÆÔnt³·?S“˜ 1eoÀÒ¢®@cê*NN–hLÙ‰- @€ …SQ"ÙA?И:€Æ! ÈÓìrÂh¨®14¦åRré””xIö’:« ÷Óú®÷í#{IfÒ¯¶/DäéFƒÆ”ÿá‹ÆÔ$†hLùàô )4&HA  14°t € @€ "4¦á§]5SÚ þÁ äivyðÞ°GBИM5(<ÝhИò?äИšÄ)ÿœ4%€ÆÄ)(4¦‚–nA€ @€R$€Æ”"ü´«FcJ;Ô?8<Í.ÞöHˆSB ©… § Sþ‡S“¢1å€Óƒ¦И %€ÆTÐÀÒ-@€ @€@ŠИR„ŸvÕhLiG€ú'§ÙåÁ{à @cJt6«Ù·õPßœCo½™ÍÖѪ ÈÓ)ƒ¨Í&¡15†ÆÔæhb÷¼@cÊ[Äho‹ИZÅn€ @€ ´L©eTÅÛ©x1-^ò4»\<ú¹íSnC׆?}õ!MJfâÖäéFƒÆÔZL³¼S“è 1eyèÒ¶.@cêDN‘EhLYŒ m‚ @€ ä›S¾ã7¤Ö£1 'B O³Ë‰¡’V 1µB©°û 16´qu,O74¦¸FArçEcjÂ)¹HM©@cJ;•ÆO)~ÆÔ@€ @ð“oõÉãàç¦ëyš]Î Ôâ7©ø1nÒC4&¯ÃßIçót£Acê$ÂÙ:©I<И²5XiM×  1u)'Ì4¦lÄV@€ @€ŠD©HÑl³/hLmc÷äiv9O74¦N"œ­cИšÄ)[ƒ•ÖtSבrÂl@cÊFh @€ @ HИŠÍ6û‚ÆÔ&0vO@žf—SÀC•õ  1y=2И¼'ÏÓ©“gë4¦&ñ@cÊÖ`¥5]'€ÆÔu¤œ0И²Z@€ @(4¦"E³Í¾ 1µ ŒÝS §ÙåðPe}hL^ 4&¯ÃßIçót£Acê$Â@ И²ZÑuhL]GÊ !@€ @Þ@còx 1yüÜt=O³Ë¹Zü†¢1?ÆMzˆÆäuø;é|žn4hLD8Ícæl“fõ®»ÿ`ÿÁ?Ìpib €ÆTN™hLYˆm€ @€ ‹S±âÙVoИÚÂÅΩÈÓìr*€¨´4&¯Ç“×áï¤óyºÑ 1uáÔŽ³t̨é£R«>Û~ëáÙn ­ƒ@ Иb€Ê)³@) Q  € @€ b@c*V<Ûê S[¸Ø9yš]N•Ö#€Æäõ¸@cò:üt>O74¦N"œÎ1ÊÃ4â‘#'TÎ!ùL=ý=£ç¶mkÐä“-‘öÔG*é44ZÕYiLB!â0~ÕxmÛ¯Ö½czS;kŸ4šIè64¦nå|!€Æ”‘@Ð @€ @€@ 1(˜ív©]bìŸ<<Í.'O‡@còzh 1yþN:Ÿ§ S'Nç9Ãîfþ6¤4™¯ãò3é;}}zS’œäëhŸtÚšx­ê¬/u_@Ô}‰Jr¹´a  C¡wÌÓËó%%*ŒS P9e 1e! ´€ @€ P,hLÅŠg[½Acj ;§B O³Ë©¢ÒzИ¼hL^‡¿“ÎgýF3ÿžC³n)—sþCgü§_õþ:é3Ç$BÀÖMë?د Ë3$‡Éå²OMf²æ8'‘Ö¥Y‰8XV*ÉL. •ë¾å¦(}j­”ìåU¶ª4cCݱ@cŠ/'OSzì©€ @€ PThLEl ýBcj»¤L ë³Ë)ã¡úúИ¼hL^‡¿“ÎgýFó“ÒÌwÝ"«‰WV X!µNi„œŽã¤%ûT“d&er%«½ér»,•Nª i^FÉ%£²Oõ«e±²âãërS8’$€Æ”$mêJS‚°© € @€ à 4&O]¯›hL?7]Ïúìrn@úÕP4&¿âé-“×áï¤óY¿Ñl_ÕPczê²N:Ì1‰°”BªJ?‚c˜ô’ؤŒD2x\ "y<þ$r܆ÃeÉ« ‘Ë\¥mKgÅ ù&€Æ”ïøÑú†И€ @€ t›S·‰æè|hL9 –·MÍúì²·ÉvÇј²Ÿ˜[‡Æ3àâ>7šº ™HÅ”í±(/G9„$ß„—“ £÷%0é#yKê6Li ï–ížu¡uâ µËR.Ùéô«¶MfrY¬ —!êB­œ©@cJ=4 hLñp嬀 @€ Ÿ  1y}4&ƒŸ›®ç`v97,=j(“GÁ®í*“×áï¤ó9¸ÑÔMÈD*¦N¢è1¶nšVŽsµ*ÕÞÔÏð›zÇöôç¥îpŽ%ÇÁÁ1\aVþ ¢§Å$€ÆT̸ҫChL @€ @€ºM©ÛDst>4¦ËÛ¦æ`vÙÛØd¸ãhLNüMCcŠŸqÁjÈÇ&’‰TL…tð“Qö²hL^†NC€ @€b%€Æ+ÞlŸ)Ûñ¡u|Ì.«Œ@cÊX@’mS²¼ P[>n4‘„L¤b*ÀÈ£ €€oИ|‹¸7ýEcò&Ôt€ @€ 4¦ÄPg¯"4¦ìÅ„E äcv™¸eŒSÆ’lsИ’å]€Úrs£q ™HÅ”ça÷ú¿oÝñúœ<÷ ƶïþýâ}oôÆX§†@ºИÒåOí±@cŠ -'† @€ xKÉÛÐ:„ÆäqðsÓõÜÌ.熨 Ecò"Ì:‰Æäuø;é|nn4.!©˜:‰sVޱ;TVZ“±vLXó^}3Ö(šî@cêKΔ)ÜÕ2@€ @(4¦B„±³N 1uÆ£’$›Ùå$¡P×`И#TèÏј Þ8:—§2‘Š)ŽAà9јšÀFcJp$RUИҠN @cJ2U@€ @€<#€ÆäYÀÃÝEcò8ø¹ézžf—sµø Ec*~Œ›ôÉëðwÒùÝhz§=6ö‚;é$Çd†ÀÓ/ž÷Õ ™ð­Ëï|÷/'™™XÑt›S·‰r¾Œà®–‘@Ð @€ @€@ 1(˜ív©]bìŸ<Í.'‡@còzl 1yþN:Ÿ—Mooï‘GóåO;vl'ýä˜ غu«‚xò©g\}õÕhN¶š0eÊ”O}ö‹â£¡ž­–Ñt‹S·HržŒ@cÊX@h @€ @ И ÄN»€ÆÔ)9ŽKŽ@^f—“#BM-@cjRqwAc*nlcêY.n4%‡iØ +¶ônzõK˜L1 …˜O[r˜†=?·WA<ý—`2…yËaúôg]²®þò-ÂdŠy(rúÔ 1¥†žŠã%€Æ/_Î@€ @ð‘“Q/÷Éãàç¦ë¹˜]Î MoŠÆäM¨ëuÉëðwÒùìßhä0}ø¨a z·®Üüª ˜å/íÃdê$Ò©#‡éÃG›2o¥ âiç`2•CbÓÒu;5¼WlzunÏËú9™R¯T4¦˜ÀrÚ´  1¥ê‡ @€ SñbÚrИZFÅŽ©Èþìrjh¨¸14&¯G“×áï¤ó¿ÑÓÑÃön]µy¿IÒ˜zúö7âë¬.×I¼Ó8Ʀ©óV*ˆÒ˜\¿ÎÅäd ¦Ï»lýÎU%KoÅKû–÷훳l3&SC•:c&€Æ3`NŸ4¦´ÈS/ @€ @ ¸ИŠÛA{†Æ4("vH@Æg—SçCê@còz` 1yþN:Ÿå9L‹Vn]õr ¿8É£§oïÒ{1™:‰wâǘÃ4mþÊÕ/ï›:ÄïíµÉ$‡é3r˜6쌌ðe÷ÎZºùƒädJ|¸Ra¼ИâåËÙS#€Æ”z*† @€ –SaC;xÇИgÄiÈòìrÚl¨¿!4&¯“×áï¤ó™½ÑT¦WVoÙï$KÅ$Éc醽K6ì9vÄ×ïºçÞv»=f̘ѥWOéå·7ÝK»é#ý9ínsæÌiå̓êTýýý¶³6Úmyîö/;L/¬ ÑAÜQ&ÓåWü°Ý®¹ ~8ˆ:O__ŸÖFø´ãÇ×›V½Ü\ìt*½o»ég»Mjws˜z6ì ¯Š¨á3—lúà‡Y²ly»gv= põ×:h/më•:„v»Æþù&€Æ”ïøÑú†И€ @€ t›S·‰æè|hL9 –·MÍìì²·ÉEÇјr¦¸‰ÆÙž7›7s˜¯zeÍ–ýY|*+Ê•5¦õ{¯Ûsì m›LÆ 1b„©ÚÖË¢{øá‡5*¢1éÍHìkws“ûÈìýÖ›¤1I]Ò›RdôÒFij)Ø sS%ˆU+ʹ ¾¸~ÏȳFµk2…ƒ¨hº *‚ÚvÁ9r¤QÕ›ÚÖûÚAä‹‘ýjû+ŽúU»ÉþÑOwlq1‡iùÆ]‚S•Š)õö‘™ñ¢L¦µk2…‡¨uÜ„<ërºâË93M)Óá¡q@cêœGB€ @€ PŸ“Ç#Éãàç¦ëÙœ]Î >_ŠÆäkäKýFcò:üt>ƒ7šÃt 6‹-F¦,>’<¤1-Z»û‹Ç·g2E|³[ÄNòG$¯½ÁZw7Û'ü‘9R‘c-Ó½iI'1ËÃ1r˜>¢µä^XµfKý ÊÔ ñ»g¶g2E‚¨_;yHæúUÌõQø}¹J.'“> ‡XF”£[ún;LáTL‘Цɇ’ç¬#u5&ëQ*º“óä‰Sž¢E[Û €ÆÔ,v… @€ @ %hL-a*æNhLÅŒk±z•ÁÙåb.foИŠ×{…ÆÔ"(v«ÈÚF“ô—W½²vëf©˜ÊÓî…kw/X³ë Ç­õÕå">‡s_ИÂãNÆL+—¥2ÒÍašþªPƒTL½‘|ZÕAüN;&S]Éi®×"lf’¥\ªM1xܵFT·H†¦Á+¼f¢Yzë‚>uQ_[&Ó5¦ t &çÉ4¦œŒæ¶J©URì@€ @€@«ИZ%UÀýИ ÔÂu)k³Ë…\Ì¡13®-ö ©EPìV!©M‡éå²þb‰jjS1™ÆôÂê6L¦ˆãRõHþ¿\ЦÈ`©»›íÉÆtØa‡…wŸÇ-õU¼‘Xv˜„¦š †—T>-ÄïœqQ‹«Ë  ØÚš€ne@mLž<9ŒÔW«ÈIr²p„W‹««1é$Mrn %dÎaª+xÕákv/X½ëù…}GÙêêr2Ê>¥6·žÉ:„¡äØ|@cÊwüh}ChL @€ @€ºM©ÛDst>4¦ËÛ¦fjvÙÛ(ä®ãhL¹ Y7ŒÆÔMš^œ+;7šA¦p¢šê,>r˜æ¯Ú5oÕÎϹ¥œL©gcRŠ °IS¤qV'“s˜¤b 4¦’©3uÄS[3™DÙ9’ôr9–êfcŠ,3g>“ã_Wc²%꺗:STðÚç/[QÎ ^óWí|î…VM&iL¶”ž^ê¯uDY©Â‹†×4LBשrÂ<@cÊS´hkИڀŮ€ @€ ´D©%LÅÜ ©˜q-V¯²3»\,®ï SÁܼ{hL^‡¿“ÎgäF#‡éÃG[^K®®þ²qô'œÅG’ÇÜ•;çôö·b2E4&ç¾$¶¨œ,Ó«“heû9L â4·–Ü–ý«*A´åäÂÙ†–„M³|Z ⼕;çöîüöéƒçdŠÑÀÈ݉HK¶rߘ1c"˜Ünu ž°îÓ-äƒ8LÎÒ‹Œp ^8áÏÌߨJN¦º#Y²´Löa±íÄ t &çÉ+4¦¼FŽvB‰!@€ @€@·  1u›hŽÎ‡Æ”£`yÛÔŒÌ.{Ë?§GcÊiàºÓl4¦îpôè,Y¸Ñ8‡iÍ–k¶ì_ýr•þâ–“kœ¨&ÈâcÓìýÿü¥¯ÞuϽMB(…Å2Óè%™Ã-’?äyØû.WÞ¬}§v7«.²¨\äX§.RcŠ:L¥ ®ÚüêÊͯÊajÄH*&ÄovaóÕåêjL ªàŠ°ÔœHpõ«Þ4ÕÉ­=—ŒÁã¦Ú¾¢’¤ÊL\ºaoCÁ«4Ÿž·ñ?ôÑ%Ë–7áu5&¥e²©.kkÛ%jJ‚GWUºÚˆc£ ј”3ðàÁƒ®ïúU×b—H° Lè @€ @C#€Æ44~¹>)×áó¤ñY˜]öu‘º‰ÆT¤h¶Ý4¦¶‘ù~@L7š}o¬j‘lÈaÚÿðìÍ?·lɆ½æ¾¨<÷âotßÒž¾Êb[öŒ›Ú·x])ÓšÝÏ-þ͵÷/¿ç¹ –Ågvoÿ¬ý3—ïø\S“IIhœ™$©Åµ3¬+9)ò¦v®»›D¹™J™4‘=ó§1ýng‹AtS`¡•D´kÆ-›ÛÛoA”ÃôÓ‡z¬Ù]Ñ6ì¹ãéuå ® ² ýì‘•7=²Ò‚(SÇ‚øÍ¦&“‚Ø(£•b*MGÒR8¸êˆådÒGá¯ÚÜK-ecjNÈa*ÃQOozxåÕc—=8s³KRep&/xEŸj99áOÎßrù=/>>wKYð*Á™4wCs“)<Ô·¤Ìás“vèB‹ãƒÝ `И ¹%àäWëî#º§¸ i3I;…W*uWá°Q›[,4€ @€ Ø 1ņ6û'FcÊ~ŒhaL³Ë€-64¦bÇwÞ¡1yþN:Óf\ïŸ_õW/¿úHó6™Ã´håVç¾ ?² §¿œqóüáçM Òb[§ý|Þ•¿^²hÝî…kwßûüÆ/]þüew¿8ògspë –ŠiÖò2`fôlÿÜqƒädê–oÇŒ;õÐχê›Ó¼ße‡iþJ b) ÓþáçOúæõ3]¦ã¯œòØÜ—-ˆ£Ç¯øòÏ[/ñÜ[œ{ë Ç]þ\$ˆßüþ 9™Ò ˆþ/R|ömmÞ9LŸþܱ=v:8c&®œQw,úÑØegÜ2_d”‡É¦i˶‰Ìó6Û‚‰˜NúÉŒËî^,2¿|rƒ3£gÇSsÖ¿°œLi¡nÔ%€ÆÄÀÈ'IKÊ`çÚ.Ô–£uiíjL²Ÿ¤+…Sä¹)SD¶Í'Z @€ @€@<Иâáš‹³¢1å"Lž72¦ÙeÏ©¾ûhL…q³¢1yþN:ÓF“´TšÈLæ0-”ÃTq_®·ìÌ[æŸpÕ[ikyß>IŸ:gËO'ô–^Γ³Ö¿ÿƒƒ¬.—*†@]hL ŒP?3‘¬íRš¤1Ù¶$%Kï×Pc²•ã\6&-áiI˜ä@á0åp0Ðd@€ @€@‚И„µªÐ˜²ÚSK ¦ÙeP›S±ã;HïИ¼'éFã4¦F2Sà05lAïVKÞcî‹–ÙR‘º4kÅãg¼tám %vH™¿rçÔ¥Ûä0]!iMYò?ý¥ËîZ|͸žHiLS—nŸ²d&S'cÂã4¦2Sà05lʼ•á Z&-É:Ͼø[eÒ’“¤TCÒ˜³yÉú=ÌÞüð¬Mòu,ˆrÑ´& ‚(mÒ‚­á|Z.ˆ'/“&“Ó˜ÈLÃôÙc—®ßY‚ o•[ŸZXz%‡Iv—ò0)s˜ðI ^ÑB{"hLkv?4s“àüê©5‚sã„•¶Öž’W‚WÏöiÁßöÄÌu˜LCáœ04¦„S]7˜¨ä4&[.ÖV§uK”6[TN‡5¦Ã;LGšÏÔÒ ¦Ýèç€ @€ @ Иò³®µ©k(9Qlbš]Ž­½œ8И2†´Æ”ùÜÖÓ&¢1Ed&9LGuÌ‚[Ìí0ñEåGc—ª(?Í õÊðP–šÇæ¼Hë÷¼¸~Ïâu»å0©Hyau«FËÉ=0í¥ïÞ4çk?ž.ói ‹ÏÒ@òÆ„É4¤јªe&9LGÊašÛkAtq”££"IšÎ ­8yôL%Óú²4¦Ù›-ˆÒt¾tÅóD™:Z1íîg7\3vÙ'ÎX•Š)Ä,šL©Zf*9L_\²®¿v„kx[†*·–œFx‰L'ИfnœglúûoMä.D—ܹ8:ÂKÓiH#œƒ&€Æ”0pªë°Æ¤m¥RRN%m ’ÉÉÆdošÉÔ½r&@€ @€ŠE©Xñl«7hLmábçTÄ4»œJ_¨41hL‰¡ÎbEhLYŒJ¦Û4qãÑæ%Vn›ó®÷¾ïðùË·8{IKÈY~9L?¼o鳋£ä=Jásòu3•¥¦"yìÖ2dr˜´™ô—ù«I+‘y˜zû?~îIJÃTITc“•#?:|Òÿ¬¼˜é&”¡xóÆO(ˆÏÍí­ ¢­•¦-WŽ=ñ›·|<Aì½ñäÿuÄ‘KÖö×Âùå“k”l¬,0mÜ«µä´Z¢F¸9L‚#2ÊÃ$8ã§o’½d#|Ü´>Á ¯µç,=3™Þ÷ßÿ¡oÓæL_hhD‰a[aIËÌY?,3“6ZÍÆ¤5æÜ‰Ð˜r;h8 @€ @ hL‰`Îf%hLÙŒ ­ @cb!ýå'¿ÿÙáÃ×ÞÿÓ7&þä¾ ”Ö üäˆú¾—²4íÛ:vìØ/ŸxRmGEPQS&§éèW­%gA´åÒÄù«v~ýÚé7>¬˜¦ ÊÔ¹Ï4& b%Ÿ–LÛÆO=êÃYþ럼þÔuY‰ày^Îù4ï§žzê5?ýU-œ™Ëƒ%ä´œÈHÑSš±+ï]òýŸÏ+ð5ƤÒrr#GŽ´µ­1é˜#Fèr˜l#]£ € @€ d’S&Ã’L£Ð˜’áL-C!€Æ4zÞ‹Æäm胎£1yþN:¿qßX=íx}N'7>¦vQ9˜Ü2™N;ç’ÊêZå¶ä0]ußR˜d{HdQ–múËšÝZiKÓeÒ˜V휷rç¥w-Örrã¦öóËùß¹iN]ý%p˜>ÜÚ—÷HòPyãßñ<Ú‰sí¢r%ÉB&Ó—N<)D9L˜‚¥KšŽD´ëƯÐúhJÂ$‡É–K 4¦R•ŠI9‡Ä&¬0S'p˜–Õ8LýøòõÛ,ˆ¯¿ñV;}ˆmßÈ¢rÉÕ˜L7üªÎ-O¬–¥wóã«•žJ“@MYò[‘±.2ÊÃ$KOy˜äxi­=ÁÑš‰?ºoYÝî&ƒƒÉ[¼9q7 1uƒ"çH…€Ó˜T»Ö‚ÓŠrZNNʯ¤wÉÆ$]éàÁƒ®ÝúU“Ö¥K¥'T @€ @€@> 1å#N±´)¬œ´«ИºŠÓ—“¡1ùéºýDcò:üt>)"0¹VÊdúþ9ÛÒc–¹çþi/Ý?­O/–¢F əᡕ¶îynã=ÏmЧ¶ØÖ z« jý%â0a2µ=>ÂSµÀäN%“é¸_Ñò ]uï Ln­´Ÿ<°|öò~ ¢tœkÇõ¸ ÞùôzYhçübþ“ó¶N/¯ 8°œ\‡)ä0eÈdrSÀäàÈdºú†_Õ¹jŸ¦o\7ãºñË-C•á׎[.‘KÃ{no0¯»L#üú‡VÔ¼"&SÛ#œ&€Æ”0pªë[<Î^ýýýZWN9™d2Ù;ƒhLÝkg‚ @€ @ÀhLÞ„º¶£hL?7]GcÊM¨²ÔP4¦,E#ñ¶ 1%Ž<ïƪ15˜´Àd:ûâò[•ä=%÷eÏ¢ÊBrr_LÑJ[–¥Æ&-C6kEÿÌåZik‡ô[lË-'W×aÂdjo¸šÆÔ@`r§2“)İÃÖtDËÃÔ(ˆá5ë:LY1™ô‘&G&Ó®ÿU½¾»j„¯¶¾³<ÂKSi„ï(ðš$Uu&L¦öF8{'L)aàT—4¦¤HS @€ @ÀhLþ妧hL?7]GcÊM¨²ÔP4¦,E#ñ¶ 1%Ž<ïƤ1Í}edx ¹&”d2}ïì‹e½TÄ—É¥¨i`xT9Lþ²tÛ”%Aiâ0ÕšL¯Ì›üȈÃ'VÛȺoæ=âm´éÃá%äšh&S“ .ˆh:5"ÚŒ’ˆb‡©ÖdjÄy׎ÜÑ3§^·¸ëÜ;½q •}e2ýpô­!8Ó`#¼â0ÕXzM&L¦V‚Â>é@cJ‡;µÆN)vÄT@€ @ðŽ“w!è0“ÇÁÏM×јrª,5)KÑH¼-hL‰#Ï{…1iLma¹üŠŽ<ëb[B.¼ÆV9 “e©©äï‰d©©Õ_u˜äyüvÏzçk¤4I0µ ~co¿ïS;Q¼ëž{=áëA+i´ÌÑ© ¢%ÓH5TÑ:p˜Ä­;Dõ@AT(ÛéJ÷÷=éäo^5úÖ:#¼lw5á–i,,x ê0 Îö½è~78#†Hiˆ9<«И²Ú@€ @È/4¦üÆnÈ-Gc2BN;4¦Ø±4¦"Fµå>¡1µŒŠ@4&5ã’Ë®úîY£Üêc–¼Ç%aê®Ã$Ãã?Þp˜,Ók¿é“Ì4mÔ•÷ŽV“”ÂGÛÚˆ¼¯wd>ÙžŒ¢0;îúõOøú@KKvÄAó0™¦óïo½mµ+‚¨OõQÝ *ÊĽë{ˆã×¾ñÍ+¯ûed„Ï/$gªl-¹åUy˜:p˜œà•@ר­@cj•ûåŒSÎFs!@€ @9 €Æ”ƒ ÅÕD4¦¸ÈrÞî@cêK΄ÆäQ°k»ŠÆäuø;é|F4&5=0™ÎU^}¬¢w˜ÀTÎßÓÛ?«©áÑJ¦°Ã¤Jßzã i.rY$3éWmkC¿Js1ŸI;è}³$¾¼ôÜx½¿öÑ1h:^Üc“éø¯…-4—IË1¬ét–‡)ì05¢…µ6ˆŠ¬ÅÎí@Ld2]qÝ/ËjWÝ®áÔ@$¨"-hLi‘§Þ˜  1Å ˜ÓC€ @€<$€ÆäaÐ+]Fcò8ø¹é:SnB•¥†¢1e)‰·)qäy¯0;“HÊdúΣñ¥²Šœ&¥¨©,$×,KM“j [,ÚV& .ò–¤+™Ì¤}´!åEiÛ½¯THÈT;þe2}áø¯)ˆSËAl7“ÕÞ$ˆÎE Q‡(Ä ¨1É¥e2]~í/«Fxi‰=7ÂgºNŠÆ”8ùÝJ4&¿ãßaïј:WŒÃИŠÇ{‘)Iý–Ét꘸/3zvL¯1<:s˜TÓ\$*©(Í’¼ËÏd?í¥÷%»,þÅ([‰ÌŽRQB¦c•›ª“éË_« ¢­•¶"X+M¥n;s˜š1¼fœ ¢…ØÑrn%ö’ÉtÙµ¿p9Æj½r†ªeÛ§.Ý>uɶ)¥ráo>ñ«'k5½&EIªp˜‹#uB©j“hL9M„ @€ äŒSÎÖÍæ¢1u“&犇S<\ ~V4¦‚¸y÷И¼'ϚƤ>Èdúöé™Þq_ê;LªËi.NZ’™$cé½ý–¤G;¼2o²6,mRø¸ LÒžì#^µd2}þË_ qVE`ª âÒ²¦Ó±ÃÔ$ˆú¨nõ¾-¨ …[vZ”Étéo˜ÂvWÏöÀÒ“À´tSÂq¡ºØ  1ÅŽ˜ Ò!€Æ”wj… @€ ™S‘£;HßИ<~nºŽÆ”›Pe©¡hLYŠFâmAcJyÞ+Ì Æ$¤2™¾uúEJÞr_‚$LÎð°5*Cq˜T‘[PLN’¶¥(IjÑOeîÑ;ÚA¢’”½£Oõ¦Þ±mKΔ÷èÇÚ~3™Z âP¦&At.Zm; bZËÊdºäš[Â驜Ýe“áäaŠu”ròD  1%Š›Ê’#€Æ”kj‚ @€ øBÉ—H×é'“ÇÁÏM×јrª,5)KÑH¼-hL‰#Ï{…ÙÔ˜D50™N»P«Ùd¶\°ÌVÈð¢Ã”÷Øe¿ý2™þùK_-Ñò ÕqˆSö!4j¡L¦‹¯¹¥j„W'ab-¹ü—–×'€ÆÄÈ((4¦‚–nA€ @€R$€Æ”"ü´«FcJ;Ô?84¦Á±G 4&¯“×áï¤ó™Õ˜Ô™Lßüþ…æ¾DRÔ =S'°8¦}2™>÷¥¯6 ¢·“”É4êê›ëÚ]8Lí5ŽÈ<4¦Ì‡ˆvF©3n@€ @€@chL4&ƒŸ›®£1å&TYj(S–¢‘x[ИGž÷ ³¬1‰­L¦S¾¡20M­¬"וµäòµ|µ?0™Žûjm=w˜,ˆ2™.úÑÍác6ÂYK._ƒœÖ¶D©%Lì”?hLù‹-† @€ dSÖ#cûИb„Ë©»D©K ý: “_ñŽôÉëðwÒùŒkLê’L¦“¿w¹8LÄ8ÇÈdúìq_ ‡É…E&“¤¥0¦ ŒYš4¦ rÊ,@cÊBh @€ @ XИŠ϶zƒÆÔ.vN…S*Øó^)SÞ#8¤ö£1 Ÿg_cRTÂ&ÓO~1þ³Ÿ?níË{6m½QÙ¾÷ÿñö;>†3Ã}›L8L‘@…M&¦ bš64hLCãÇÑ™%€Æ”ÙÐÐ0@€ @€@n  1å6tCo8ÓÐr†¸  1ÅM¸çGc*dX[íS«¤Ø¯L “Új&S®®™L8Luƒh&S®G8„C¤ И Xº@€ @H‘SŠðÓ®)íPÿàИgÄ5И¼hL^‡¿“ÎçEcRß¾~æþÇQÿy˜: sfŽ‘Éôÿû‡÷/_¿­y2­ëíÌ49¹†|íƒï:ñÃÿ­ }¤Lcz‡LcÉ…šºI©›49W† 1e(4€ @€ PhL d'Ý@cê„Ç$K)YÞ© © ì¬hLqóø¨iLº'Þ»äÖ’Ëûh}ý·p˜êñò÷îºé„æpp˜ò>þ½n?“×á/rçјŠ]ú@€ @H‡S:Ü3Q+S&Â@#š@cb€t@©hÅ9©8±L¨'ùÒ˜&¬yï«¿û÷ºž‡²ÔüÇÛd©IhØ ±šF&“‚èg¦2ÏÒÿ™îÚÿf£ŽÃ4ÄÇá)@cJ9T4¦¸Èr^@€ @€€¿Иüý!4&ƒŸ›®£1å&TYj(S–¢‘x[ИGž÷ s§1 x­É„Ô»qXk2ùî0)„3qhÑ8ý·Ödb-¹Üp\‡â И Xº@€ @H‘SŠðÓ®)íPÿàИgÄ5И¼hL^‡¿“ÎçQcR?Ã&S'ÏÀ1a“É+‡iïúž×~ÓW½ïÞ ›L8L­4¡ИºA‘sdSƒB“ @€ @9'€Æ”ó¥ùhLC¡Ç±É@cJ†sÁjAc*X@ÛëS{¼ØûPŽ4¦}oôîþýb33™p˜r=ˆÍdòÊaš6j„Êâ_ŒŠNbÓä‘ÃÂošÉ„ÔëNã« 11 J© ¥[€ @€   1¥?íªÑ˜ÒŽõNipFìQCÉëAÆäuø;é|f5¦ƒ<8h^ûý[ÿñö;ƒîÆY& “éßßz;Ë-ìnÛqxÝ®}tL­Û$WïOï0»Ζ4¦ôØSs¬ИbÅËÉ!@€ @^@cò2ìÖi4&ƒŸ›®£1å&TYj(S–¢‘x[ИGž÷ ³©1MÞ8yää‘ygKû!! “ÞTцR4姯´5И%€ÆTÐÀÒ-@€ @€@ŠИR„ŸvÕhLiG€ú'€Æ48#ö¨!€Æäõ @cò:üt>ƒ“¼%Ó’´!WÉze˜´aI˜´®œd&}jÅiO à$EÀR.…WŽ“¨d«ÅY¦%í`&“å^Òû¶‰MI5“z 4¦x¸rÖÔ  1¥@€ @(4¦Â…´õ¡1µÎŠ=Ó"€Æ”ù\׋Ɣëð µñhLC%èÝñÔ˜”uɉS& ‰•l9“™ì#)M“7‰mxA Ë”„Éœ$½lµ8ýj®’~•¨¤÷-9“}d{ÚÂs*Jã”åÞÑ6 NipFì‘KhL¹ † @€ dšS¦ÃoãИâåËÙ»A©½;“w!wÉëðwÒù jL•LcRš%ËÀ¤—­.7~Õx½©ŸzG“„'­+§ 4¦NbÏ1€’$€Æ”$mêJS‚°© € @€ à 4&O]¯›hL?7]GcÊM¨²ÔP4¦,E#ñ¶ 1%Ž<ïfPcR¦%™LÿxÐt%{ITÒ›ú©¢ôŽ’0Yº&™Lyí‡ P|hLű§=Dcò4ðt€ @€ #4¦áfýÔhLYí;t‰QÐ4¦ ç4¦âÄ2¡ždPcJ¨çT@I@cJ’6u%H)AØT@€ @ð„“'®×M4&ƒŸ›®£1å&TYj(S–¢‘x[ИGž÷ јòAÚ_3qhѸât‡ž@ B‰!QPhL ,Ý‚ @€ ¤H)EøiWÆ”v¨phLƒ3bhL^ 4&¯ÃßIçј:¡Æ1ˆƒÿgUΙhLÙ‰-é*4¦®âäd€ @€ ˆÿXìñ0@cò8ø¹é:SnB•¥†¢1e)‰·)qäy¯0G÷ļ6Ú?þÏ”!RlhLÅŽ¯Ç½Ccò8øt€ @€ þ±8&°y8-S¢ä{™²õ}tÔ4¦Ž°å 4¦¢D2±~ 1%†šŠ 0þÏ”!RlhLÅŽ¯Ç½Ccò8øt€ @€ þ±8&°y8-S¢ä{ј|õ©#lE9©(‘L¬hL‰¡¦" B€ÿ3eˆ›S±ãëqïИ<>]‡ @€ ÄD€,Ž lN‹Æ”‡(ùÞF4&ßG@GýGcê[QBc*J$ëSb¨©ƒàÿL"Å&€ÆTìøzÜ;4&ƒO×!@€ @1à‹c›‡Ó¢1å!J¾·É÷ÐQÿј:ÂV”ƒÐ˜ŠÉÄúÆ”j*‚À ø?S†H±  1;¾÷ÉãàÓu@€ @€@LøÇâ˜Àæá´hLyˆ’ïmDcò}tÔ4¦Ž°å 4¦¢D2±~ 1%†šŠ 0þÏ”!RlhLÅŽ¯Ç½Ccò8øt€ @€ þ±8&°y8-S¢ä{ј|õ©#lE9©(‘L¬hL‰8l–ÿôIDAT¡¦" B€ÿ3eˆ›S±ãëqïИ<>]‡ @€ ÄD€,Ž lN‹Æ”‡(ùÞF4&ßG@GýGcê[QBc*J$ëSb¨©ƒàÿL"Å&€ÆTìøzÜ;4&ƒO×!@€ @1à‹c›‡Ó¢1å!J¾·É÷ÐQÿј:ÂV”ƒÐ˜ŠÉÄúÆ”j*‚À ø?S†H±  1;¾÷ÉãàÓu@€ @€@LøÇâ˜Àæá´hLyˆ’ïmDcò}tÔ4¦Ž°å 4¦¢D2±~ 1%†šŠ 0þÏ”!RlhLÅŽ¯Ç½Ccò8øt€ @€ þ±8&°y8-S¢ä{ј|õ©#ly>hí”C²—¬üÛ'išðÑóÞùÝÎ<÷¶ÇN _Ó¯WüÙo1¤cTþÏ4îÔš4¦¤HSOÂИNu€ @€ ðŹQј<~nºŽÆ”›Pe©¡hLYŠF"mùmo .Õ-?9"‘PIŽ äHcêÝyƒÞv¼>'Ǹi:šÐeüž¯C…%€ÆTØÐúÞ14&ßGý‡ @€ tŸS÷™ææŒhL¹ •Ç Ecò8øw©svù=òöêkL½óÛ'Zž iL9jj2±£–¢@ò(ZDéO5F8#¢ И Xº@€ @H‘SŠðÓ®)íPÿàИgÄ5И|u2‘ŠÉÇ¡ÐvŸsä娩m‡ H ƒb`„;¾÷ÉãàÓu@€ @€@LИb›‡Ó¢1å!J¾·É÷ÐQÿј:–ÿƒj2‘Š)ÿQM 9rƒrÔÔG$€äQÀ Ò¥F8á И Xº@€ @H‘SŠðÓ®)íPÿàИgÄ5И<‘„L¤bòt´Ýí¹A9jjÛaàˆ’àØáÅŽ¯Ç½Ccò8øt€ @€ 4¦˜Àæá´hLyˆ’ïmDcò}tÔ4¦Ž°â pB&R1"¤ t"GnPŽšš@ਢ€< Tº"Àg8”SAK· @€ @)@cJ~ÚU£1¥êœÓàŒØ£†“¿ƒÂ%d"“¿ƒ ížçÈ ÊQSÛ@@<Å&À/v|=î“ÇÁ§ë€ @€ ˜ 1Å6§EcÊC”|o#“ï# £þ£1u„­(YB&R1%ž ô#GnPŽšš@ਢ€< Tº"Àg8”SAK· @€ @)@cJ~ÚU£1¥êœÓàŒØ£†“׃B ™HÅäõh»ó9rƒrÔÔ¶ÃÀ$†A± 0‹_{‡Æäqðé: @€ @ &hL1ÍÃiјò%ßÛˆÆäûè¨ÿhLa+ÈAS¦L9úÈ8p  ý¡ñÈ‘”£¦Æ7j("$"F•> `„3 J© ¥[€ @€   1¥?íªÑ˜ÒŽõNipFìQCÉÛA!‡éSŸýâO>|8&“·Ã ÝŽçÈ ÊQSÛûC €äÁ8(6Fx±ãëqïИ<>]‡ @€ ÄD)&°y8-S¢ä{ј|õ©#l¹?HÓ§?{ì’uý½›^}xò\L¦ÜG4©äÈ ÊQS“Šõ‹’G±âIo¢ጉ‚@c*h`é @€ @ EhL)ÂO»j4¦´#@ýƒ@cœ{Ô@còpPÓçŽ]º~çÊͯJcZþÒ¾ “0™<t9GnPŽšÚI$8HŒb`„;¾÷ÉãàÓu@€ @€@LИb›‡Ó¢1å!J¾·É÷ÐQÿј:–ãƒÌaZ¶~çªÍû¥1­(iL=}ûš8‡œL9ŽkRMÏ‘”£¦&=ê)$bÅ“ÞD 0Â%€ÆTÐÀÒ-@€ @€@ŠИR„ŸvÕhLiG€ú'€Æ48#ö¨!€ÆäÕ Ãô™ÏÛ³açê—‡I©˜V¼´oyŸ4¦½K7î?qö'‡uÿ~¯˜ÐÙ¶äÈ ÊQSÛ ;C LɃ¡PlŒðbÇ×ãÞ¡1y|º@€ @ˆ‰SL`ópZ4¦:ê?SGØryPÅaÚµzËþU!I©˜–m 4¦%ö<ðÔìó‰M¦žžž#F´ËbòäÉ‘CF}øá‡Ï™3ǽ?f̽ÓüÌ®vµAÛÚyذa:JgÓ«ù±îVïv¶vŽ9Ò•‘–«…j˜^ÚèëëSóÚê`ÂøñãER/¤¿¿?òiŽÜ 5µ•qÈ>ˆ@ò`L›#¼Øñõ¸whLŸ®C€ @€b"€ÆØ<œ)Qò½hL¾€ŽúÆÔ¶üdÓò»ÖlÙ¯TL«,SeE¹@cÚ°wÉú=‹×í¹ÿÉY-šL’‡$»´Ë¢Ö|’ ¤ó„õ ’šŸÙÕnâŽûõ`éÕüXßÌ'{É ªõuܧnçÈQÚ!õ–« â6jÔ(k­HÚ0&¼ÄAä  d²Ú`åÈ ÊQS;ˆ‡@à’ƒ ØáÅŽ¯Ç½Ccò8øt€ @€ 4¦˜Àæá´hLyˆ’ïmDcò}tÔ4¦Ž°åì ¨ÃToE9¥bz±¤1-Z»{Üã-™Lu5&™=r_ôrn<{Gn<K&¨C´³ó–dÒXz!ÛÇn¦‘}jç7eG;èÌf>i[ò^z_oFZb^Ž^µ“½¯æÕ†ÖvÖ™u~m‡ ¡˜Z®„U‘ö4j¹Z«=­¿ö²mc¢—Zh]8ÜÉ--V-%×AÙ]µšZŽÜ 55gš›H ͈‰#<&°œ6mhLiG€ú!@€ @Å#€ÆT¼˜¶Ü#4¦–Q±cjИRCŸçŠÑ˜ò½–Ú[h9¹†©˜ÊÓî…kw/X³ë¾Çfš“©Vc’øâ%³dÕ˜@£,ßRÝlL&?Ùºr:Äl'ÛÙÔ"—gȽ£³™dc¹Æ¸EåtK¹¤èeRŽò éM÷Q˜ ô;gdMºæÙ˜ºÞr×Në¾d£æ-7…K/ë£õÈ1±žª×¶áN¥w´å^ Sr@ì´µ+æÈ ÊQS[ú&³"<Å&À/v|=î“ÇÁ§ë€ @€ ˜ 1Å6§EcÊC”|o#“ï# £þ£1u„-7…¦ÊrrûWÚŠr/í[Þ·¯§oïÒ{é˜Lczaõ®{3™êfc2OH*’ù1ò`´!ÃÆ-âf“íf†‰G•œçdÚv /-g™ÂI›šhLæ*Ù™-Õ“Ó›tZU^TÎ…Ód©ðòvú(¢1© Ör}GËÍ‹²3kC©my¸ ÖxµÇV¸«ËD;X§²£"” §nnª¹A9jjn.(44S<2ÓuŒð®#å„Ù €Æ”8Ð @€ @€@‘ 1)šmö©M`ìž4¦ ç¿J4¦üǰaê8Láåä^’ôoÙÆ½K78©œŠIÓüU»æ­ÚùëG›ådª›É¤%óÌõ±¥Íœac“<'{Gέ1QÉ,"G¹‚‹šÙ Ãb“ªn6¦° cç<ÚkLªÈ–¨ÓO[º.üŠhL–±ÉšGËÓ¶Ã|Ô*ky¤ µ­0q6јÂ©ŠÚ¤YVKŽÜ 5µÀW!º#$árê `„g 4!hLqP圀 @€ ¿  1y4&ƒŸ›®£1å&TYj(S–¢ÑͶ4s˜6½ºÜ9L R1Í_µsîÊszûï~dF£Õåj5&K}dݰlLzÇ-LæÖ‰S²¥pW@#;Ç--ç²1™odËŸiÃIE:m“lLaÊÖ³sÙžÂ'±f裺™‡ìÓˆÆwËÃík›Kåãš!bRìW·T\#)|*CíD1·ê_óQ˜#7(GMíæ7ŸsùCÉßXûÙSF¸Ÿq÷ ×hL™.B€ @€&€Æ”0ð,U‡Æ”¥hЖúИ@cêZöqS°œÊËûW¹z šQŠ01,aÚÙÔ¨ZJ™lLÙÿšÓBß yø>ŠÞFxÑ#ìmÿјÜJÌzÂs²öüê-2:@€ @€À И<"hL?7]GcÊM¨²ÔP4¦,E£;m1‡©gîÀa* L_ØúÍëgönzuEÃtòu3JÓžëXþ¥+žÊå*ÏüÙܹ½;g÷öÏZÑ?sùŽ;˜LÝiqœg‰d~гª”Ï6ÃÚmJë”r”â(GMm7^ì€’ã ØáÅŽo¡{çŒ#·†²ùHf7Ó˜ä0vØaε7Oß~—{³Ðèè @€ @@cê[1Bc*F‹Ý 4¦bÇ7¦Þ¡1Å6­ÓÊaútà0ítI˜Vm~õ©¶žpÕ”ˆÃ4}Ùv9LŸ'ûß4¦ìLj‰’Çðqpæ 0Â3"؈@DcRŠ&­çvnOc’Ã$“ Ö€ @€ @ 4&Ç“ÇÁÏM×_øÍ¨´Kà×+þìoÈÍ@§¡õ}ôÑ<>Í¥_’½dÓò Ó¾Çç½|ü•Ï/­ÎÃ$‡Iy˜¤1Y¦ù«vÍ[µóçNš´`kt9¹ SÙa2“éØ¿ù/þïìùOí6ö/onÈþ)û1¢…C"€ä1$|œyŒð̇ˆ6"јôkxQ¸ö4¦Úêà@€ @€¢И<hLŸ®€¾Â¬ýoEè }€@=>|ø„Ésu©b/¹Uä›hLZHnÉúòZr‹J“ò0}â¼IÎaztέ(^NnFi9¹iK·O-ÙKVNþÞ?¸ðòMÛ_ß¾÷zçl@cÊf\hU× yt %'Ê$Fx&ÃB£Z!VúúúÂ+ÊéðA4&¥_êééqÕ 1µBœ} @€ @¾@còx 1y|º^hLEˆ"}hJ l2Mšëì¥` ¹R¦GçlVÖ%W¾ñ“ K“ò0)ý’åaš»rçÓ^úúµÓg¯èŸµ¼þrra‡I&C2ËИ²ÚÖH]€È)2L€žáàдæÂê‘”$‰Iáýј€ @€ @€Ú&€ÆÔ6²â€ÆTœXÒ/  1yvï:m&ÓCçöRe 9ËÀ¤²xJ) ÓÚ@` ¯%'‡inïÎr¦!‡©z99—‡É&L&ïFX®:ŒÆ”«pÑØö y´ÏŒ#òD€ž§hÑÖ6 1µ‹]!@€ @h‰SK˜Š¹S1ãJ¯¼!€ÆäM¨}神Lã'ÎvKÈE&K´`õ®ÒZr;-Sc‡i{íZra‡ “É÷—áþ£1e884­<ºA‘sd—#<»±¡eC"€Æ4$| @€ @€@hL 4&ƒO׋@©Q¤­ÉôÉáÃxjv)ýÒ@¦ª$Læ0I`Z$aŠæaêÙ>-Èô}ê’m¦1ÕÍÃÔ$'SÿÁþa÷ k­½ìX 1Å‚•“f‡’GvbAKâ Àƒ*çÌ4¦ &@€ @€ F©`m§;hLíÐb_dŽSæBBƒâ$ðêþý=æ÷?9Ë– L. S‡iú²íÓÚq˜ä3mßû‡?½óŽëÓøUãG<2âàöíëÓ›=ý=î§í£lCÙ§¼ Ð]hLÝåÉÙ2GÉ#s!¡A]%Àï*NN–hLÙ‰- @€ …SQ"ÙA?И:€Æ!È4¦ìÄ‚–$CÀL¦qÏ –[,!W˜’0Y¦Ù½ý³VôÏZ¾cæò3zvLïÙ^v˜–¶š‡©Öa’¢$‡iää‘s¶ÎQN&Ûçg=´Š '}ª }:jú¨d°P‹?Иü‰µ§=Eòð4ðÞt›îM¨}ë(“o§¿€ @€ ø  1ÅÏ8³5 1e644 ­@cj…ûŒ€™L÷=6s@`ª³\ÈaR&ËÃ4‡ÉÊO²K‡ßz¸KÅ$ŸÉ>Õ†ÞÔOyNnÿ‚Á§;©@cJ=4 ^Hñòåìi`„§ê‰SL`9- @€ @ÀchLÉãàÓõ"@c*BéCûÌdº÷±™óVíTú%ËÀdI˜f+ ÓŠr¦ SÉaš:´µä\e/iÛ\%{Ó20Ù¶>Ur&ýÔ§Vl^è"4¦.ÂäTY$€ä‘ŨЦî`„w%gÊ4¦L…ƒÆ@€ @€ A©aì¬hLqã(d„SFA3’'`&Ó¯Y-0 $aša ÉuÏa²ÕâÔÓ°ºäò3)“¤%·v“Ò4yãääÉPc±  1;¾ôî’ƒ ØáÅŽ¯Ç½Ccò8øt€ @€ 4¦˜Àæá´hLyˆm„@ChL Ÿ ˜Ét÷#3J˜ÂS„)p˜B ÉMY²íäï]ðƒ /ß´ýõ&eûÞ?üéwêRU&IKÿxг}ôÎøUãå0œ¥V’®¤ã$*ÉI²bY—,'“6¤7i[ïKuÒþúÔí‰ÆÔ>rŽÈ 4¦¬D‚vÄDÉ#&°œ6#á Íè64¦nå|€ @€  1y<И<>]/4¦"D‘>´O@KÅÉLÒq.å’Ô%ËÏd2“e`² ½ïVšÓ;Ò›$6µ_'G@ И2$øØræ,`„g! ´!hL1@唀 @€ Ï  1y<И<>]/4¦"D‘>´O@f’©H’–¤%YN&[TÎd&åjRѯ˜ô‘$'ÛSò“K×Ô~µô  1¥Z+$XñròÔ 0ÂS ˆ‡S<\9+ @€ @ÀghLGÉãàÓõ"@c*BéCûVÜ;Ú’̤m¹JÚÐÏ=sTì#ýjÙ¯z_¿ªØ’s¼ ShL9 Ín•’G«¤Ø/ŸáùŒ­”Ó ˆØ€ @€ 6  1µ ¬H»£1)šôÅChL.C>@cò9ú^ôÉË0{ÜIF¸ÇÁ/v×јŠ_z@€ @HƒSÔ3R'SFA3 Ð4¦Î¸q œ@cÊiàhv«FÝ‹>£1yf: @€ @H”S¢¸³US¶âAk Ð&4¦6±»Иüˆ³Ÿ½Dcò3îõÉã`{ÙUF¸—a÷¡ÓhL>D™>B€ @€’%€Æ”,ïLՆƔ©pдK©]bìï4&/Âìi'ј< ¼?ÝFòð'Ö~ö”îgÜ=è5“A¦‹€ @€ „  1% ÷Éçè{Ñw$/Âìq'á¿Ø]Gc*v|é @€ @ hLiPÏHhL Í€@gИ:ãÆQ'€ÆTð{Ý=4&¯ÃïCç‘<|ˆ²Ï}d„ûýB÷©Ðá¥s€ @€ T 1¥‚=•¢1e#´@cꇛS±ãëwïИüŽ¿½Gòð È^w‘îuø‹Üy4¦"G—¾A€ @€Ò!€Æ”÷LÔŠÆ”‰0ÐtJ©SrWhhL…¯çCcò|¿ûHűß=d„ûÿ÷©ÀÁ¥k€ @€ ” 1¥> Õ¢1e! ´@cê™S‘£ë{ßИ|…ï?’GáCìyកâv©¸±¥g€ @€ ´ 1¥E>zßþÓ›ãWý¥Ô‡ºeѶóÓhuB­øã¸{ùjô~rÃZ=ûA `fÞrHSƒuËÙvèw; Ö]ºã-4&oC_ØŽ¿õæ¡QÙðþ(ÿoRØÈ{Ú14&O_ün£1?Æô€ @€ 44¦¤‰§\ßê]·Ôu ~½âÏÞx‹‰Þ”£Cõ”À´M'4Ò˜ö½±jÐÃÙÅ$Ðd"œYðb†ÜÓ^¡1yøbw»‘‡Š„Zì¸ûÙ;4&?ãîA¯Ñ˜<2]„ @€ $L)aàiW×(!©˜ÒŽ õC %2‘Š©%|ìT`u'™/pĽì“—a/z§y¨H¨E¼ýCcò1ê^ôÉ‹0ÓI@€ @€@¢ИʼnÊj2‘Š)¡h@Ý„L¤bj {—@݉pfÁ‹p?{†ÆägÜ‹ßëZ µøQ÷²‡hL^†Ý‡N£1ùeú@€ @H–S²¼³P[mB&R1e!.´-¨MÈD*¦ѱ[Á D&™/x¼}ì“Q÷¡Ïµ*ªq÷°hLÝ.£1ùgz @€ @H’S’´3SW8!©˜2V D2‘Š©UpìWl‘‰pfÁ‹n/{‡ÆäeØýètïÄC2<¬ ¡ús{‰ÆäcÔ½è3“a¦“€ @€ D  1%Š;+•…2‘Š)+Q¡h™@8!©˜ZÆÆŽp ™˜÷ ÚvÉà{ÔåŸQÖ˜P=Šºg]Ecò,àþtÉŸXÓS@€ @€@RИ’"µz,!©˜²Ú ¸„L¤bj‘»yAÀ%dbÜ‹x{×I4&ïBîU‡-!ªWA÷­³hL¾EÜ›þ¢1yj: @€ @HŒSb¨3V‘%d"SÆÂBs Ð*KÈD*¦Vy±Ÿ?”‰YpÂíYOј< ¸ÝUB&$TÿÂîQј< ¶_]Ecò+Þô€ @€ 4¦”ß|óÍn¸áꦯoûÛÍwÈø§7Þw쯿(ãlÒ¼K/½ôôÓOoÞþ‰'&ñ=¢¤Aà®g?ÿrÿ‚4j¦N èrÚüz{^é•ú=å'?ºrÆEŸI½j@+ [·nõq0ÑçN ø 1éK1è÷÷k_ûÚ ûø³ƒ.¼ƒ>;¶ÓA—èqsÆÞxà·}‰VIeH’S’´©+AhL ¦*@€ @€€'ИzΜ9ï~Ïß^tÉ•V.tåâ+/ Ê*ÿùÿþ¿Gžvö_1PF]q~½rÞE—Gʹ]^.^~n¥üàÂË+å²\”sjÊÙç_VS.=ëüR9o œyÞ¥åÜKÏ<÷Ò3Ê%gœ[.§ÿà’H9í—åW.þþ9¡röÅß?ûâïÕ”‘g]\*£Âå»g Ê™å;gŽ(gŒúÎZ[N¿èÛ5å[§_ô­Ó. —ožvádžÿóýïÿ o~?(§T• Nùþ#¾þ½÷¾÷½ž|•é¦oz{{<ê˜áÇ8pÀ·¾ÓßTèrúý3Ω¹!wC» ý±«\Ps¬û‹ÞøêÜò"7»È.|«ÜàêßÚÞÔêßËndá[Xó›Wø¶ܰNnXÿçÿõŸO<é{ÁMÊJôVuÁû?øQ™©D“JsJÀI_Šó‰&—={ë ¼Î¥fÔá«Mä1»ùvøjÓäRzœ®sµ©~„nöðylnø´\óyB¶ÇãcJÏÃÚht©qR>ž‡§L™rÌ'>ÃMN¯N4»%hL-ab§ü@cÊ_Ìh1 @€ @ ëИDHÓGùÄŽ½°²=(o¸²mÏ*óî¿]¼|ýo÷¼”Ý*¿ÿM¥¼²ë÷®lÝyÐÊ+ý_.—×_ÞñúæJÙ´ýu+/mÿÝKÛ‚ÒçÊo·1(¯©løM¹¬ÿÍkë_ ʺWe뵕²fë5[ö[Y­òrPVYÙüêÊJéÝôª•*/íSYn¥/(=å²wÙÆrYºqïÒ AY²aOPÖïy±R¯ÛS*»©¬-—…kw/\”kvYyau¹Ì_½kþª*ó¬¬Ü9·Ræôö»2{E¿•Y*Ëw¨Ì¬”=;.¾ú–Ï}é«Ó{¶O_”iV–nŸ”m*ã&-FcÊú%ˆöuD ä0 {aÅ–‡ŸžË„_G9¨mºœ¾¸bCén8pC´»¡Šîƒ² Tì>XÿXsï«{׋Üïìf¹Ó­ÙR¾Í…op‘»[Õ­­öŽºUßËndv ß¿J7¯àþUuçêÝi·­ÖŠà†õ—ýîŸyQw+•ª[Uå>uò÷.@cj{ ú}€'“þ` z©Ù;p©Y´|½žÀËÜ•çí­»~?ð°íž´Ý3öŽªgìòvåéÚ­#ÏÕÕ¡ÇéȳôÀƒ´{ŠvÏÏÕÏKìá¹ê±ywðØ\zf®½ÔèÙ•#ÏÉåKMøj³|ÇÅ×ÜòÏ_úª]jf„ŸŠ+—šû'çàyXÓ§?{ì’uý<Øø}‘+zïјŠaoû‡Æämèé8 @€ @ 6hLÍ4¦oÓ¬IeâÄMÖÚ|­Š&Qõ¬ ÛK¿ ÙKšÄ­˜Â“˜´1T‡é•‡Ió.ó»Q‡i¿›åÕFHc ¦°ÆÔÔa*ÏÄ4ט‚)™ÐpØa æfJÓÀn&¸®Æ4»fJØ9L3KS5e©ä0¡1ÅvàÄ™# ‡éÃG [°bkà ¾´oÂdL¦ÌŨ ’Æ´xÅúÈ=1,òZ2Bw¬² Þ†ònH,pv[ Êžn­¡[ç¾VÏÊ­õq«Ä‚ZiàæenD½5ïV7,4¦B~Òí”'“²»…ŸºÝƒ·ýÍÀžuÆÔèÚu˜*!ÐĘŒüI@Ƥ{T®oL–žƒKMɘ\cʼÖoÓÒuý<ؤ{…¡öØ  1ÅŽ˜ Ò!€Æ”wj… @€ ™SS©X¦¡:LÑTLÎaê©ü)¹2u;S?1æƒ[NÅј\*¦lLKÈÆTäK—·} ¦£‡-ìÝj&b`öí›0i9™¼‰u\“’ „½¥ˆÅkSp §E ç ¬I@É>Ø(ï`ÝTLC JÉ#™#9ëçGq©˜ByëæG)kLO[6¦n»Ô²)ÉÆ”Øè-LEþhLM.5 –Sä‘ÛÒV¶[Ñ%ƒ§ë -8L.³i©˜ú5&ÃSÝÄoÏN8LŸ;vÙú<ØæJEG@cbp”SAK· @€ @)@cj¬1ý±»Eâ6Bü­IM¥„§l#‹Ç…&T´\ÕrÑ L­-$Zó¢´\kÉ5ÊÃÔ5‡)¼¢\“TLnEž!¦b*iL76JÅ4)Å UÇC ì0­ÜªÉT7Û'ïP¢áƒ1™âÎY+¤1™¹YËÉ­wÞE—«„×uðw]AµfíÔÆy˜‚åä­—Zg¥Ôš5R«¬Ü8R1•ò£„5¦ºbÁÔ%hL|»Ú&à‰Æäuk|©y!ИÞÓh½æÅš«’s‹5—tÉ’ÃT½LsÕ+K™M:L›j³™†–cv‹WFbn¶xeýTL•ÄoUÉJK—iLZd¹‰1™eIÓgä0mØÉƒMÛ—È#4¦i[GéÍpíWÍ{…Ï£=¤I5}äfÅt†Ã;¬¶%Vï¨Q£T«±S–×!iL2wîƒvC,Ý í>xîE—«´—z°¡ÀT¹ß5° \r”fÓ`y˜–T¥bªŸ¥±Ày·ñ×ï~ðé¥bj¤1ýÇÛhLQóDc „ÈðSwõ¥fÞ’@cjr© ?i÷é»ú»y&÷\Ý<å[°¨kó$«ÛæºZט4§¥kf»“±ünv°î" ÈÖ7D“ì&æ®ÖGsK¤Õñ š' g ßï*é#wºÚ•RëeFÙ×SJ+d ßÔ*Sw¦ð*¨nýÓÒʧҘƗ4¦ºbSZ#9×õú¢1U„ÈÈǹõìí– nz©©o/ $7máRãþ$À¦AuI—Ç4òülºdÕZrͦæËÉU/µ\Ö˜JÏÆ&÷—ŸŠ³ªõ‡¦î?ؘg£Spô¤!Çå†t ޽cb´%†´¬Eæ?éW=ŸØy&OžìTÌ®Öûa»Ú.).‘¤êuж=äØi%WYKLZ²ýÍ1ŠœSGé}× KHiz–Içö‘9èÚÕd‡hÃÞ´Ú;nÃ:>›5/r6{ÇNâºï.›µÏõ5…Æ£1¥*“ €Æ”eê€ @€ øE©A¼McªU”Ü;š8Ñ$ÊœÅkÂi–”i©*ÙRU¾¥o©‰ºÔhå¸ Es{©:ý’û“ñʤKu¦&«È Ìõ–ÿˆÜ­…ÑúBr Vï’½dÅ9Ló4%Sš•Q)§²XY^#C+eÌÏk±ŒÆkəär‘ecr³5¡O4¦j!2ú·zöÖø/5å¿ ( LåGëR²ÃV]É©tµ©½Ô è’åõ—«“0E˜Ût˜ìÙ¸¼Èr泓â0 ö`£«q+6Nñ±{>qO#î©fÐlLvÍp:TXf²Â“~ kLNZÒŒ-!çòPª=&ˆ‡5&w}²sÚ£Žt+»¹‡4Û¡‰Æä29¹*"SØ·¤˜µgs]Sk];ՆȳbQ.«Éö)YÞÔ–4¦ÄPS @€ @ÀhL BhLG««%¹75‰2sájûµì*U’L˜®TµB\½•,LZФ\Šd]ЍK«šÛK¥?ø{ñªÅãªþjca 15¼ÔÔ·$ƒ›iý´¦›µZk§®äÀBÌ{ÂÓ@¾·JÊ·Ê¥¦j!9—µ´=]²’¦Ôùý¶ÈrƳ“:‡©Ñƒe·Ò:¹C|°qRŽ=̘ m’žsLâÑ£EDcÒ¯zrêe‹4ý(,B¹g•°ßcW§©Fm»³Ù†=eÙu&m;=¨öœúH;kÓŒt;¹=­ÙsZm6&ílKÝYúÕÉ[ö‘ÄZîr>©åµg³§/ÛÙe`BcêÎå©;9Kæ ¢1éÂgKuÚËþÆý©JæzCƒ @€ @È4¦Q0ÉÙHu74‰2}ÁªÜNT åXzvö2ç*ÕJK³_Ü Rë-=õBiñÓª•O¥1ÝhL S¢1µ9Ùý?S“Kž½õ^{© ?o·°"sQòº»CeúÂuîO~ò³;TÂKÈ]{Óí*fÛDþ à±çŸqÞ*åççµ»g-Ýrá•78]òágžvîåÓ_|¹’„©áBrÎõf*­·Îò@vÒ¥Áj•µ%u­?ä0 <Øüjâš«Ç.»õ©5µrö¸©}ö`£ÿãxrÞ–Ëïyññ¹[Z|°q¶fÌÝƒŠ“~ô޶%ú؆~µ‰uKJä1ëHï¸çð¤ø¸3»«’;•ÞÑÃŒö×n–¾È¤%«ÚÞ ·Íš>§•\íj°-Âkga£(ì Ûû¦%ÙI´³m˜3`ÕÙÜ>uÏfMr¹¬¬hLݹ¡1u‡#gI€.áZuñ ÿŸZ3ÉìN÷1&oêþË:D•€ @€ dœ€çÓ£çzúêCo¨’þ­öÃG³ß"ÅM“heÚ «j-¥r‚¥­®øñÏ>xäÑö÷ßV>óÏÇ=òôì@MÐöçŽûÀ‘G[X*îåýOš}Øa‡¹ÞóÞ÷M˜80•Y3.¢.•ü+{­^dÇfyßý·ïÓÏ3Φ^4×{òwÎÒäÁ}Mÿäg¾¨)„r¾ŠHú¥ÒÂU®hÞwþª`2æ}à#árÞå×Soÿ@‹Þþ‘g_¦rçCSÿç‰L3+Ó3¶ŠÜwκTeÚ²íA LšÖ$Í…Cјöm=4îÔC Çfü Jó|#`Ó¢•[À´ª´Ì}ñ¿rÊî[jËÉé÷Éó&™Ÿ¡/é÷þmî—®xþK—??ògs]*¦@c*¥m¸c´AM&ßPÓßZ;^Ÿ3mó ûÞè­ GÓôV5º!êÆwÖy—ª„…Ý[ïžð·ïý¯ºªH]Ò¨¾þæ;ëÜø6ï¿üš›ô~d9'Ýþ¾õ½sœOpćŽ~ð©YáÛœ¾*S^XûcY¡%äÎ<ÿ ÝF¯¹ñvgå꾦;ÝÀ-äãºÙ=LÿŽÒìãŸþ‚4\9Lóž÷iû{ç\¦X•UP;5IE_1ÝÎnÿü€t[ºa™ÆÔ$e _Ãv x¢1éJ¾ÔDž´õì­'ðê¿ ('[ªM¹TÓ´~Ž7»Ãœ‘gŸ}ᕺÔL[¸N—m|säÙ*G|è(»Úhã”ïž­¢ K¿ätI]dþñƒGéAúôó®ÐÆ—Nü†ì%=K¿ÿƒG-X³KåÞG§ë’òÃëǸgæ–’0…V[.¹’Q]²²ÈòW­°<È"Ë¿í=tû ±>ËaúôçŽíÙ°Ó=ØL]²ý„«¦œqËü]vÑí ‡Ÿ7éñy/—LnØsÚÏç]ùë%öc&®ÕƒÍew/>îòçn|xeÙÏŽÿÁÆòuëνԭsrž¼@cÊkä|o·þq,|a´”½z¹Är 5&K(g –Ew¢p.8ßÓ@€ @€j x®1IdÑ?&žÿçµ2“iLk¶(— D¤ìÿkiLóW†-%·­©fÖ²÷¼÷¿j^V3(*ÏÌ\¦m½£4K’–®ÿù#¾zŠ%[úö÷ÎÑ ®Mߪ(ÿ„¦R\ ŠË®&w5¿bS¹Í׌‹¨KVŽ ç¨0©´þÅnËTQk/…Ó/5[?®¤1)wEm¦ðp)CLÿNѼ¯› L;Ü2r˜N5©´Š\Ó"”Ö¢3iïËIqWAc⪘%æ0-”ÃTJNc É•&-$÷Ò>iL?¼o©¾×w>½þËW>/)p˜Öí~jþV9LúnjrTS}L{©’Š©ß Ù·?ˆÉ”¥`g²-Ò˜îê9L¥®Ì$iÚüU5·Â{àÌó.U kºyÝ;áiç[ïzèÓŸ;NCZ7ÁÅk¶éÞ÷ƒ‹®:碫l„Ož±Tw=íI1¨7Uî?Y>)㟚Ukè>ðÄÌ3Ï¿2P *K£ÊÊþO_üä?}ÑnmúŽÈ*ÐÎr¢Ô&4«@yu ĂҚŒº—é׿I˜*VAIcz ИÂ7¬¿ø«¿Q4¦Lö¼6Ê©t%‰>u»gl={ë ¼®±dÜP½`\$¡iðh½©ü\}éÕ7JW²´@g]p¥Ê]ã' ÿì±f/ÿ¯'Ë•¼ãþIÃÿéX»Ô|ù_N6QÒ\ÉÛÆMÔE&œìMöÒn¸Mê’iL¿.Y’úiÒT`*%P,_mÖ¬Œê’ÁÝ<œò­ì÷oël‘å}k—SÌÏÃæ0-“Ãdq)™Ùß¼~æV–ÿ£oßÝÏ®?þÊ祢N[¶íËW<¯rů—èr-nr˜ÆÏØ$\z°Ñãå˜LàÁ&’0rˆ× %grK³ ñTž{hL¹¡0]ÉÙGa5ÓeYj¨1Y.ßp6&[­ÓÎIñä#]ú @€ @€@#hLöÏ÷52“iL–6©ª”&H¬he꼕îת‰“—÷kÊö—w=dZ*M¢hû×=­_e)é_ð­þ­ŠÍà*Û„\%ç-)÷’&nÝÌÊCOͲ'|彿ž¢)–O}öX½íÏnלîOÎÔß…kºE?Ÿœú¢–º°¿WÑD‹¦[”šB&®i]ͲèMº<;o¶5Ëk“»šzÑŸ«èÏÇõëq'~ã¾GƒlLöç㚃ùÄg¾¨ ˜[ï}J‰+´¡_?ñé/êÏʵøNx2ÆiLn>fü¤ÿëˆ ûÔôó 'œ$iäÙ—ªÜ^јnøLÇ|ê .›…ì%m[9õÌKk&›nWczeíÚßÝ~r9Ü1OÛpÉ@»‡é¨a {·ºy>7áê¦ú4Ï'IS}WÝ»dÒ‚WJSy99iL ¸lû'Îôèì-úZ›õ”Z!ð¶ñSÉÉÔn\¼ÚßiLue&iLSç¯,ßC·Bw<óÜKUÂÉËÛ›_•ª;â+§èöçR.éNç¼%MrßrçCº£E<Ý÷üíûî?Yï[ŠAÝÑt³“R ›ÝïÌ^Ò­M·­°R „(áôK<»H75í³`ÍîÈMÓ/ï}êýøˆ².Y*A LA6¦’Ãô7ïù»/žp’eÔêòë~¥»’ngæàêËõ…ãO²[Õ»Þýwcx¾Jº]² É«¯O2õEc:÷ÒðÓud[ÏÞz¯{©ii!抺To‘ÊàR#iIËÆ™Ìd‹ÇéRS*W¨Ø_¸ ¦ö7_ú—oè:œ¾ô‡7ŒÑ£rpÁ)ÙKz`¾ça9L;ËSÉ•´˜Ìõä{+'aªv˜Üãq»ÏÿíYðû›Kày8p˜>{ìÒõ;Ã6êïðó'|»¶ëª®ç™É _‘BªÇ{¥b 4¦5Ƥåä”cRÓÈ›æþà—/ˆLÙaâÁ&™+µtSבrÂø Øj˜‘lLôÒ›¶Øe³EåôqXc’äÃ" –Çß j€ @€ @ oИœÆT-3ékŽóûç\f‰+¬„W”öé/h2F³¿×Ý2.˜’Y±ã]ïù;MÌ|÷ìKULc²µxþí®ÇeZ<2e…f‚õSïØdð?ù¤Sϼ$œ)œÖ¢õi›:SÞ®UÅn¯&]p¬Øâ²²•ÓÒ”æù*«hí•ÆtÕ½KõÕ¶ šö &MKS}çýj&Mø¹UW\Æ‚ ŸYIþÃd*ö@bï"SDf’Æ4eÞÊèm1ðtUWåŒs/QqcØmÈRÒMmÒô¥auI÷>ó–´ŠÓu?»Cª®~ ö`z[w=Ýæl '[ÎI‰—t/»ø‡?µ„(Òp{~ñ¸ÇgèWY?.P œ•û£ŸÞ¦”ß8õ¬ŸÞzÿßÓÀMKÈ•îh¥$‚º£­Ü©UPMcÒÏ»&LU‘}kw1•ǦõêöÌ /ékuÙµ·J½ÕÏÏ’-$g“³ ìV…Æ4ÄÉáµ<јΨ"+×]jžŸÛ«'ðÚKM$ÙR$»Û ÙLKÕ*˜t©‘½dê’]jL` ԥʥF®¤ŠK¿$ÝÿÆ_=Pºwäpú%]gô -WòÊëǸdoQ)¼`eUäê&a ìävµþ:SlÏÃe‡i]äÁæÉy[”ZÒ=ØØZrJ0ùÈìÍ–?OÓ÷,Cý¯Çøé/éÁFy˜T~ñij»,Ç$6\!sI)—a£Ñ°Æ¤ s¦!¹Üu­jLJÎäN$ ª»¹ï @€ @…" )âñðk)3ÓÖ[¿ý©UwŽÄ½ù×ïzÏss{]%·qσOkÖV¿º)ÛÒºÁªp𦕥䤥›ïxÐ2-s·%YAÅŒ%û+p[ÕBÿÄoù–lŠÅÒ,Y‘¤ ]ýtë阺äòRh~W½6ÝR^3(õAoJ` VØY»[³/šz9íÜËU4m ?×êT¶þŤY«ôÓÜÑt¯¦a4Ý«)Íøª(_…2I“1½å¿&×ìï×ýê·¦Z)ÙKý—ÿäV¥_R Íkú!ИκԒ0Íè f]î¥Ã;L3ÁúÕ&ƒoºã1iLVäiEcúäßÿU4##Ðû/‡yÔ1/¬Ø¾˜¸,¥\ûlÈ’Æ´ÄéÒ˜ÌaúÕĵ'];Có£ú2~÷¦97LèÈXPZåÊMvšÉô÷ü/7ÏùO&©P Ð -3wÔð¿–=ÐD8ý—¨ÔÞuû»ûÁÉ2™,¹ mó–´`œ2 Ú¯”uioxÍ8ÝÚ‚T(¥»ž$ÝüÐQ÷?1C?Ÿ›·ÆL>Kˆ2ö±î§»›³rÇÜ71¸ÙMmM à†îhAN˜ô¾3q•‡I Þ·[˜4¦pAÝÂÜÝJÛJ¨bÒí¿žrƯ©l 1êQ9KñFcª#Dºk‹ž½õ^÷RãR™ÖJKöŒm·Ôȥƞ®]*SY5N]¸Ô”®6îRc®d9ýÒšÝÊ÷fÐ&ߨüðú1z~V&]atyðé…Ú?ya‹“[j¹j¹ð"Ë%W²uIÏÃÑ Lq> Í9î°c>ñ™%kû]˜ìÿƒtñ×_5 ?o’]ê-Ù•hëyæáYÒ˜‚ ¸&%aCý¯‡&eiÒeY=ýø¹¦š›ÿ÷ƒ΃M+wó¶ö™°æ½oÿéÍ,]óß4¦üÇÐÛ8ûHÙ”ÜB™ZoN¿ŠI«SxE:åq’ å-P:@€ @€À æÞqèçÃý-ÿe}‹ë'G¬ÿ‰UV©H¡¢I”gç®'R²íË®¾QÓ±¶è[° ÜWN)[J%)–JS)×þìýúÔ´%á9•ž’±¤¹[›Sq3+JAüuø†àŸûµ!KI³¹Ay|ÆÜž Á’M´¨È[Òb:]õSû›æÛÆMÔÊqnºEÓJ¶dê’–3BÛúi“¦ 4㫟ÊTL«vZ¾ [9N“»NfblÆ4¦ðršôÕÔoyEŒÒ”k!9å^R ÍûêO¨å0©Ü6>Е\ ÙKV4üG|Ø&ƒo¼ã±oMczßß¾{ï“?}û‚¿¨èý½¿ƒßç/~Æú~àºaÃ?ô?~z®»˜„sÒè",$WIW0zü ûjßåó&ÙŒéew¿xÙÝ‹mmšŸNèýÎMsl99i‚úŠI Œ¤1þ¥÷_ö/OoüÔ3}Ã)pžXDÝ Î±½Þ³ãê¿ÿ‡*s·ú†ÜûLc ßu7t·?Ý u¿«¬xKºK^ò£ŸºQu#S®A7±­›]ÉÐ f¸ï¸¢Ô[s•©ô-ØSºÙÝ %×|§œ~î¦èîví÷ŸtêYúš¸l‚n!TÝÑdw´Š‰+I÷/»‘ÝñÐT[<®œA°¤ÞJÀÕÍë¶‚rêY—ªAéô_Ýÿ|Dº%á]'à‰Æ\Ijžº¢ôìœz_jÜu&üW•§ëŠ·z®vO×ö\mE¤2]¤2Õã´e6u—š«z›ŠV^¶Kr¼ýè†Ûì)ZEKÈé™Ù&Sÿ?ñé/\uý LºÎXÖR=0k»þr¡ LN`²;xvÈJéR$(­Ö%[_dy÷³w¼uÉ{ê?ßvü¡§¯îb9ðð¥ÃüŸîÁÆÅÅ‚"'û®gÖ›À$Úã¦ö}ùŠçíÁFHå0©ˆ¡®ÕÒ˜Œ˜ŒÒc/{îÉy[=ØüÓñGM[wã²í×ènEé =è‘àõ?níúuÌë¢1yþ|wÞiL£K/ëÌøñãMijUcÒ®R—¤>ÉgÒ‘îDùfCë!@€ @€@× Œ;5ú¯ù?9âPïDÕ£Eå>tÔ1ÑyË™T)šDyfΊð”‰ùIî¾+é%þø[óµãŸš)WéÎ&i‚V?%-©Ì[ñJØX RPT¦Ul×RPØäŠ[!nNÏV›Ð•¨tõOo×\‹&tµ}ã˜ôþ¬¥[LZÒ¼KyÁ¸Òô€å¥Ð¯þvÜ–½Ð$®æ]LcÒì‹fb¦-Þ¬eã‚©—’ºtåè1š€ý‹q¶àÎß¼çïlRAkîhVF“¾®h–÷އ¦Ø¢Vôε7•Q¡ŸÒ˜ôgå–ÁBsÀ¶xÜ1Ã?ÉoÕÜŒ&efÒÒWÿð¾µ4üÏ_Ö²uCÊÆô®w¿gÓö×7¿²§¾Ì´pl×Ç'„@80|øð “ç†sE¸k‚&üî|zÝü•;å-M|á[Å&ø.Ÿ7ÉfLo}jÖ[™¶d»¾•A6¦‡VT­ºšòT³¿z²¾*Û÷þáOï¼ÓAk9¤¨j•3éoP—µ¨ÜÀ-¯únh÷ÁÓ~pÉiç\¾ JT’°«Ië’¶{”Òo Ã=9Sc[Æ’o*KKòwCª®K.6te,)]Ÿ/iC‹¢ê[ðÌœÕÚA?¥1év^ÎÉY¹˜tG{è™…¦äÖÞÑô•‘º¤$‚³{ûϽl´¥_ ndN±•O©¤ÞÚ¨ºsÉ*8û’ëtçúÙÿÙ8w£Š»m…M&4¦¢~SRì—'“.&MžÀŸ™hLÕÙ•Ü“výLKîRö–ÂyL%-ézbËÆ)å’þ@Õz–¾iÌZ-NfI‹ÇÝú€Šý€Ë½¤{±®BzÀþå½OêùùØß0{Iº¿=9Ûc³®6_ûÖ™î™9HYº<0þËÏÌ|\Z1­e©õlLö<¬R_fŠáy¸ü`3©ÎƒÍcs_ÖóŒ²K>:{óͯÖöm“× bKZ˜&ÉÙ–`räMsõT#Ïéêû–}íÇÓ–“ãÁ&þËîþhLÝÇŒÆÔ}¦œ1!Nc²uá´"œeVÒ¿›©ƒhLò–üI÷=9_À*÷>9ÿó_>©ô—åÛ?6üóÊÀ¤Ÿ¿~|ž¦dä0i[嬋¯SÊ¢rnÚÆÉLº0”™)†i›Ü} hpFT&üæ„Ó°Y®Íó)QÊ•¿^âòÍè»|ÒOfXºÍ•^z×b™LÇ]öÜ%w.j´êJØaÂdÊHÜ3ÕŒ°Æ˜¬‘Ò˜J·¼è­ÐÝO;çbyºn ë~7_ôDcÒ•¤ÑuFW˜É³Vè <Ÿ—šêôKã?X(­Í L‘µb;xÞµÿÍà1øò÷Æú<ÜèÁÆþï¦êÁÆœ°&6¥Åõx°Iì’…Æ j4¦X°rÒô  1¥Z@€ @€@¡Hg)-!Wû2©VHªäL 2'ieÒÌåUZ’S”B~R#EÉM܆D¥´uu¥r"–jcÉ–`¨*-zK¥$.UÞ’ì¥ÞòÊÎ^ªQ—¢s0ÁÔoåïÈKöÒÀdÌ€½40û;T{ÉÍÜt¦1Ó6z½õf 3­R¨ñLgb&ðÆÞþÉ#‡©¼ö›¾HU/=7~ñ/F ½~›ðÿÔì°ÈèæùÊ_öòT_`¦Úaê/ça*͆NSª³ŠiÑÈajd2õí뛼qòлÃòE`ß½n ¹Ú–Kcš…Æ”¯ñŸ‹Öú¢1}qõÚÊå|¥vyѳ·žÀ»x©¸Ú´{©)=H7%뺒µé—:s%;ÎÆ¤»ùyXã^2Sƒçá®<ö´ò`SÎkUÊœ×TÎîüÁÆ}ÁyÂiñZ‡ÆÔ"¨övCcj{ç†SnBEC!@€ @È;iLüÈ1áÕmj·5‰2qÆòæûÔ(JU¢Ò€«T])ª+É[*ͬÔ1–*kèDçtKÐÍ·T×[ZYã-ÕɺTO]ø#òª…04SÏ^*Íþ.­Zp§õÄKu÷’Æ”÷JûÓ ÐÄUšwíH}Ú•FiÂïcÇ|â'g—¯¦-VlE·~M–—ª©ÎÃTv˜*_·æ“™Lý¯þ!Üøa÷ ëéïéJw8IaHcj~Ë3©êžXå*Õxº¡œ‚õ¤¥*C7|«Ÿu)âTßÚœ[^uyý ·t «£´ÿBc*ÌàÏNG<ј¢W’êå&u!ÒxÓKM° ¥•HúRËcZNíV~®îê¥&"J6X<.z©ÈTÚÉ£r|ÏÃÝzì l†Ul\ìÁ¦’„)È;èƒMkr¶=Ø xZÕ_`žpZ¼ ¡1µª½ÝИÚãÅÞ¹!€Æ”›PÑP@€ @€òN И>|L Éæb÷hå©é=n¦$²Q^ú­ÆOj¸\ÈUª«+Õ® WþÛå²±ÔPZŠæ[ªñ–ê­¬N¥Õâ" ÆUg]*嫈Lú–fb¬Lm?wE[bS|Ó6y½´?šÌ{dÄáJŤ ecš6j„Šì%«ËR4Õ¾¿âÞѶçÞõmXA{÷íÿè1Ÿ÷ĬˆÀTZo%ÈU0øT_;Óö½ø·ßqÐFNyø­‡xd„ÞÑöèù£µ=fé˜ñ«Êž–}¤|ÚP5½ i¨âçì.iLOM_ÞÄÍyÖ(•*{ Á0² jé–M+ØÄ[Ь…: %¢.…”ܺ« º„(ÝU Ü ©»#³‰€'Óȳ.n”©TW={ë <ÆKMéV[»ìrË—š†iÞê^j:ÈôyZŽéy¸³ÇžWæM¶ÇžˆÛýêþš˜=Ø(Õkéï%ì4Œ’Ë>uâWO6W©Qу͟Þx°i÷ Çžì!ÇÛ+S,¡GcŠ+'MŸSú1 € @€ xB ¤1},¬ÕnkåÉi=îýyY÷wÞáJ:¥FI•ܪp‘¹[÷kðýMŒ¥J¦¥ZiinoxI@Zª›o©â- ®.U’UD².% .…gnbš¶ñd„ÓÍÈU2Émh!9‰JzG†“~jÞNxÚÞ´öÑ1úÈ<'¥CÚªÑL¦±ÏtþbyJÕÖ¯)-þ¨/r g yª/ì0©‘ýû•«@•ä3I`:øÇƒšÉsù™ìS—Ï@S}Îpj«ìœ/Ҙ·¼Ú{¢iLun…¡Û_­®¤{_í]/t¿«– jR.EB ßÝʉ—ª³¡Ø¼¸•ºn\4¦|ð\´ÖiT“'p]ˆôžÀ¥&òD]wyÊÊšqeû?Xg¹Rš‹’ágæ¶$þÚã{n÷±gGÏòÖU´¡5éÂ_+3™ÜƒMD`*?ØÙ%»ð`S×ajý GÏ<ö`£G =ääââÐõF¢1uipB4¦X°rÒô  1¥Z@€ @€€'¤1}àÃsK¹ÕÝø«¿~÷ãÓ–9ýhðÒŸ7/u]¥Ì•D,šY±þÓpÛŽKµÒRdÆ%*-iö¥2Å[™€©J¹ToÁ¸à/¤ƒRYëaˆó1-ß´'ƒœn¶KÀ\%½¤%©X¦%éJÎR’Õdéšl7í¯)=Û¹])¨¥d2ÝûØÌ*©j!¹.LõE&Õ«©;›´ ÏÞ™º¤×œ­s,9“ö‘ؤ¢ý•±©]˜ìŸ;Ò˜ž˜ÖS{7,™IA.¥ïž9J¥Ñ­°C·l,UÝòêÝ隈¹ƒªKA6”¦+ÇuñF†Æ”»Ažý{¢1éJZLÙ®09Ûôì­'ðü]jªWŽëâ:Ëñ=·ûØãŠôØ#»6¥™Lö`ãRKV¯ÛoX`šŠX÷ò0Ù·»•'9Ü&j[ñ6!S,w4¦X°rÒô  1¥Z@€ @€€'Lcj®ý¥4¦©Ë5“–~«J§4°bEtéŠW©®®T›cÉfv#™–j¥¥Zo)ô÷â–£¢·TY0®”¬"u‰lLž|3ØM§"ÉR’“äì%½o‰—¬Íò–4g 4ÿ§÷]é Se“éÑ™aI±ü¥®Ìó¹©>ûV¶µäJ­Ã¤Fj‘8YJÚ¨$iI.?“}*iI3|¶¡¢ ÛW± Hcj~ËûΙ£T¦VªÉ&ØÈÐè¹ÍÝܰ·¹»U¥Bi°þi¬÷24¦b#Ré'SÝ+‰»¶èB¤'ð„/5•Çé: .‡Ÿ¢-µë¥&&©ÝÇ}#Â=»•“©ökR6™Z°©ü„ºÙñZr®­<áØZºö„£bOD¾Ð˜b :S,X9iúИÒ-€ @€ @ÀÆtäÇæ¯’lÔ°hå±)K„Ôh#økãÚRI§Ô(©Ry·´tTÝR«+…Œ¥òÚu2-ÕI¶Ô¦·Tñ$ZÌ™ßn1MÛx2Âéf»œ«äÖX1QIçQÊÙKÒ•4ig§µ÷õÓæðt¬û¨ÝzÍdºç‘¤¸"(³*‹d•¥ÃRº‚p:´§úê:Ljž[-N˜ô޲X6&­.§eæô«9LöŽ>ÒÏvûÅþ¹# é±)Ë܃DJß9ã"•ð­°ù½¯6›`d…¸ºnno©:•`MÖ¥*·”A0æÛSîyöì‹ÆtƨšKÍ@¶6={ë ¼þ߸çíÐcöP/55 SF²–6U—ÊÒ|Ã:sLÏÃ<öèICú5OBi&SäÁf SÉ:íìÁ¦ÑZrî«ÝÊŽe´CäsOÞ,ìá )– £1Å‚•“¦O)ýÐ@€ @€9S^ÆvŽÚ鉯dW’FEÏÞz¯ÿhØ¥¦6Á[(™Ø¥&¦çá{^™7YÏE.'e“o–™Lw•lœÀ¤ƒƒ͠S‹O8¶›o,ñdŽ®Ým*Swy–φÆ VNš>4¦ôc@ @€ @ð„€iLÍæHzé‘ç–JEÔFj˜N©’^Å’¬„Keî¶”y¥2}[w7ô¯ÿQc©vy¸*iii @D¥%%¨¨,ߨLgÅ4mãɧ›ù"`&Ó]¦›•h&b)WÁÀBr]q˜ò……Ö&I@Ó#Ï/Þ7(ºÍ}ûô‹TeH­ÔàÆWk, *-Eîqeo)ñ¬KnahLIŽOOêòGcrIIí NÕöðsKôÞÅK=H‡KäZ¿Ô¤òÓçá²ÉälL`êôÁ¦‡É“«D·º‰ÆÔ-’UçAcŠ+'MŸSú1 € @€ xBÀ4¦ÈI)T4‰2á¹%µR“wBr’ü¤:ŠRQ)˜_‰¦V2oi{]]©nš¥üJKµóÄ9¶ñäD7»NÀL¦;&L+µ«&¦®ç„Ò˜‚[^õ}pà×e©µ;ààznm*ÁÚ;]o)™ rŸBcâKÔužhL"£—šë?áÙ@cjt©©~ÒŽïR“¡”¥ù}6“鎇†ú`ƒÃÔõKNˆÆÕChL±`å¤é@cJ?´€ @€ OHcúÇ#?Vc™{T.šDyèÙk³%™Š)µê]çú–RÙUª] .ºtNh:ºR~Ò,µ˜œ)¿Ó6ž|‰èf× ˜ÉtûƒÓ¦Ö|‡¾–\×[Ë F@ÓCÏ.ip[ \o~¡J{·¿nnÝû]=i©bdò‡ÆT°¯@ºã‰Æô­Ó/ªc#YvÒ;ôì­'p.5îi9×ÏÃf2 åÁ‡)¦KS,`јbÁÊIÓ'€Æ”~ h @€ @ž4¦}´¹{¤I”Ÿy±®Ô mRdÑ·ê\JZ%ª´PTÝ20}[í*ù +5²šr=mãÉ÷ˆnv€™L·Ÿþ^à0u3'¬% ©þ-¯²Ó·N»PŶp,ÝòêÝõªîwy^ü‰ïQ× ø¢1Ù•¤AÑ…HOà-^gÊYÜ }©Éûó°™L=Øà0uý"ãNˆÆ [4¦X°rÒô  1¥Z@€ @€€'LcªYÔ¦ÊCú iLO/¶5ݦIl^¶±±”¢~R¥T_T*ežÈ¢9-fNŠc·¼OÛxòU¢›]'1™p˜ºN˜Ö%hLO¿X}[,ßþì&øÍÓ.T)ß» Öu• &æ¢1ñUê:O4&]I*—šª‹Œ]jÆ?½XOà­Øà0uý >!S,xјbÁÊIÓ'€Æ”~ h @€ @ž0©61RxFä/þêÝ<½¸¾‡d6’J%“DíÆÔ¥Z Çʶ:Å{KiPó©Ó6ž|›èf× 8“©Å©¾ÿxû®·úF@“ìú‹™–îw§|ÿB•F~’» 6¼÷-Ù6èe?_; 1ùöI ¿¾hL‘+‰{¨.mèÙ[Oà‘U&?f׿ï¿ý÷ì?Ëd:úcÃZy°ÁaJàò…Æ d4¦X°rÒô  1¥Z@€ @€€?d2)'“{=õô´.\n»çÁÈ;üš$±&Þ=î±æ5N›Û“ýi¾Sô´»¶mï—¥ÔDcÂaê.pÏ϶uëÖð=qêôY‘˯.Ⱥ,'yÈx]­<$¬}y“ç߬¶ºïƒÆôæ›o†/5Ú~|ÒÔÚ«MÆ¿þ 7oÐçá¹‹×æâyxÚÚ³Öþvyó¦¶.ïŒÆÔ1ºf¢1Å‚•“¦O)ýÐ@€ @€¼% ,>ͳžði.ÉÛ¯p!;®Ä-L&¦BF<;úÿ¿‹k~îI6¦ì ò ¶Ä©{sa7wßñŒ48ƒÏÃo¼µó×+þlê¦Mlp˜».¡1Å‚)¬œ4}hLéÇ€@€ @€ à-4¦ŒÌ» ±œ¶ñö;EÇ»B ®É„ÃÔ¶œ¤ 4¦!ÞŒŽÆÄ÷® 4¦˜¾wž6ƒÏ˶WÏa*{~ß[k2é¦$/hL±ÐFcŠ+'MŸSú1 € @€ xK©s<œ¶ñö;EÇ»E b2á0u ,çAcJþƇÆÄ÷)B€lLq\ˆ²öÔ!€ÆÄ°€ @€ @€ @€€wИ¼ ¹gFcJ7àûÞèUê–'Ö‘nÛ R;SAI7¢И€ @€ @€ @ðŽ“w!÷¬ÃhL©|ÚæêjL[LL½mEhS¢Hê@cbX@€ @€ @€ @À;hLޅܳ£1¥𺠙HÅÔµ¸ 1u %'Ê4¦lŃÖ@€ @€ @€ @ hL @¦Š  1¥ßU]›‰TL]‹ S×Pr¢l@cÊVmiP¦e›ÊgûÊØ±ccÌõO‹Æ”(n*KŽSr¬© € @€ @€ @!€Æ”‘@ÐŒ˜äKcz|ÒT'-ÙÆ6•’·¤ró­Æ4ˆÀ´ë÷USlÓ+“d¦*éåÆTÏa 4¦’ÃÔ\cZºÑ9Le©ÖajQcš¿ZS 1SDcêÝ9 1•¦æÓôŠÆ8Li SLßcNë#4&£NŸ!@€ @€ @€<'€Æäù(|÷ó¥1=6qª“–².•/½ñó_Þ)©nú%åaröR9 SiG9 Sçy˜Zu˜ö»_Ó#OM [J‘í’Ætr8ëR9ñRT]:ørÿë/ïx}s¨(ñ’+/mÿÔ¥{iÛïúBÓÆß¾&uÉJT`zåÀº­kɹ…äÖlÙ¿Z¥ÁZr-æaj×ajq9¹*ËÉ•W”[Ùj*¦™Ëw”KÏ L¥²ÝiLnE¹p*&Ó˜îºçÞ?üûÛ®üû[oÇû5;í°CãN· Î4 1¥A:!@€ @€ @€ *4¦TñSyìò¥1=üäóK)üëM¿4¦-i)šu©V] å^ ¯N¿˜œ½4¨ÀÔ, ÓËûWm~Õ­%ç’ÓÆŠMûV¼”åVúöõ”ËÞ„¦ËÉÍé퟽¢\f­¨¿œœ4&-'g“s˜¦-Ý^Ö˜J©˜Lcºñæ;ÂÒ˜¶ãåhLñòåì©@cJ =C€ @€ @€ @ -hLi‘§ÞdäKcšðÄó&'Õ–—ûÞtËÿòµ“µ$[ª‘–,÷RD  /Ur/5²—Âé—:˜”‡i••ÀÔ, SµÃ´,¼–܆½KK%XH®ÁZræa²Ã$i@cZº}ÀaZZv˜Ð˜’ùRS‹'И< 4Ý„ @€ @€ @€À4&FC± äMczN‹Á…Kxa¸o¹ã_¾zr£¥âL`ªï-iÙ¸•ã~'oÉJgé—ÂKȵ.0µ“„©ä0­Ê‹•²xÝžRÙ½Hem¹,\»;(kv/X³ËŠ–seþª]ZH®¼–\7&Ó˜‚TL &4¦b_Lè]ÂИNu€ @€ @€ @HŸSú1 qÈ—ÆôàÏmRF%+%-)\´ZÙ‰_=Ù½S6–BÉ–ò-µà-•/ýæµõ¯eÝ+Êeë­çÊš­ÖlQÙ_¶—¶ì—º4`/µ©žÀ¤åäöº$LK7–30u„©®Ã4µ¦Ã´r缕;çVŠ–s¥Åµä$0Y 4¦ÆSœ_eÎí4&ïBN‡!@€ @€ @€ €ÆÄ(6|iLãn@Nª^NŠÒOo¾ýįœ¬¨®TÊ´¤²q ”ó-ER.…׌«R—ä0uÉ^êÝôê •—öYYn¥OÞ’+­ LJÅÔI¦ÀaªJÂ4à0õî˜zûÍašeeù•™•2£g‡•é=eI“ò0™Æ45(ÛTä-EÊgûŠl³ˆïWì´Ã;5Þ*8;Ò €Æ”uê„ @€ @€ @€@ªИRÅOå±È™ÆôØsÁêoµ¥d)Ýðó@c ¹JËÃÕ.g Æ­·RÊ·õ–šªKíæ^jd/…¦½=»/0…’ë0 ÓŠ*ifE`š!©â0 ɕ֒“ÆTv˜j&ó™Ð˜bÿJS7И¼ 5… @€ @€ @€@…c¡Øò¥1=ðè³&$Õ9I×ÿÛí#¾ò ó“jKÄX*yK•uâlck4å’VŽs Æ5[6®ñÊqe{iSuî¥Æé—´œ[BnɆ½K6ì Êú=J¼äJ‹˜š L«ªV‘›Û~¦Àaª,$ç& L%iÛÔS±/&ô.ahL §:@€ @€ @€ ¤O)ýЂ8 äKcºÿÑgÃ~RÙLª$U-é_¿áR+U6ª]¥ÆÆR -5õ–VKWreóþU›_]Y]$-¹Rgå¸Ö쥥!{),0Uì%-$·{‘ÊÚrY¸vwPÖì–·äÊ «w¹2UãUäV¬"§åäl¹ÊBr’0 ,$ç&·œ4¦Ú…äÂï)Îo3çö‹À Óøñãûúú ÉÁƒG5räÈ9sæø‰ÞB€ @€ @€ @ XИŠOz%/iÜ#Ïi“”ÑÿvÛ ÿúò§õR+ITrEÆÒì7žúýsNüê)·ÞýK¶¤w>ó¹ãn½ë!IK*OÏ\6â«§¨h#ì-Mž±ôG}ÙÕ79oiÆ¢õGyôÄéKV¼T{©oߥ?ºñ’ÝØÓ·oê‚u=}ÁÊqÃ?{¬~†s/•쥽_þ—“~q£ôKN`ºèÊÞÿÁ£T.¼ò˜Ž;ñ?»°y¦ú óVîœ[)ò–\i&0-ß1£²œ[EN©˜ÂI˜‚ L¥$LhL\b ÐERÜÙ¤$ICÒ;ýýýöf3iòäɇ~xOOí:lذ1cÆèWmè£.6‘SA€ @€ @€ @I@cJ’6u%O _ÓØ‡Ÿ «H‘íë~hLöf%¯RtU¸ðÚpò®¸æ¦G&ÏÖÆ½ž–´ôéÏwù57=lï<ô´¼%mü⮇T´¡ÜKNZš0qö{Þû>½é².]võ’x|jÖòRÖ%yKVκàJ•°½tæWÊ[²âVŽ“½ôÓû_øÈy—_÷„iÁÆe£e/ýÍ{þN?¿ú­3¿xÂIw>4U?Gž}™¦w½ç﮽yìÏï~âñ™L—]{ëŽ?éöñS~pÉuÇ ÿ|‹“ÉLhLÉ…©±ÌDj¤1ÉpÒ§Í•ÓÇNc²m©OsæÌ‘…ÆTÈC§ @€ @€ @€Þ–À„Æäí5„ŽÇG ²¨ÜøÒK&’^ª´ I{['•‹/Zœ€ @€ @€ @ @cJ2U¤H _Ó=>]×F²7,éÄ“";”— ƒ ü¤ÚâR+Y‚¥å}ûTlÛò*•Ô¥òÂp2–¬HW2I?ŸŸ¿vø?+iIÛ÷?!©,-¹¬Kgœ…Šì%K¹¤RÒ˜vëW·fœt%˜L] — ®¸Á¼%•“N=ëûç^>Õ.­g‹Ç]yý§.Ùâqóž÷)ýÒ×¾u¦-!gê’~*ë’ì¥àgiå8+Ò˜ô޼%+Ÿ?þ$ÙKç\r¶ßõî¿û×SΘ¶tûÔ l J)åR“B6¦¿ËT]<áÄI}}}ÒÆŒ#“iEå D8“ —v«Ó=‚ @€ @€ @€@á  1>Äžw0_ÓÝã'×U‘ìÍk~ú+iLn·\t£$*M[°N¢’eWºùŽmû=û>K*J­tÊwϾóIÃ?{¬yKÇÿëÉw<0iéÆ Ç’ÊOÓ’ {/þáO¿ü/'«HZR.%­ç¤%—uéŒó®P){KëvK]’ƤŸr•ÆŒhkÆé¥\Ò;÷>:]+ÇýôÖûÍ[’Ã4ýÅ—µlœ©K¿¼÷I¥V’½”•;•uIÒ’Ô¥R¦©æ-IZºkÂÔÿuÄG¤.©Ü\Z-nÖŠÒ•ä-éç3/¼¤G§ö*ý’r/)Óôží²—”I嚟ßwï“óe/MšÛ'“©E‰lLž_Iè~œÆ¤5æ$0YZQN«Ãi£lLJß${I2“ܦþþþ8ÚÊ9!@€ @€ @€  1%™*R$;ɲ%Õ-Wßð«/x’[÷­f#ð“Ê¥d&IQ’œ¤|KRˆ~~ûx½#uIïœyÁ•–cÉ,éM• ¤¥=å²~ÏýÏ´$QéÙyktøíã&j[ïŒ}lÆmã&êyKJ¶èJëvŸ~Þ*ò–>ù™/wâ7f.Ý¢÷¥.YÊ%-'oÉ–ŠÓšq¿~dú„gjCY—¾þí³Þÿ¸ÄK¦.}ýÛgJZúÞ9—}íÛgÊaºâº_I]Ò;R—¹—†}ê Z-näÙ—Êaºöæ±&0éçe×Þªw¾{Vðþ¥×Þ*{I_9åŒSKïÜûÄüŸÝñø?ñ‘Sϼä_O9ýcÃ?ß<ýRäS²1¥ø]¦êâgc’€$ I2’6¬§ƒhLJß&"õÉì'^€ @€ @€ @€@~  1å7v´¼ùÒ˜îz`’[Ö­vCÓq#¾Þdû(Ȩd¥”TéÇ7ÞnÆ’Š²+=>åÅkn¼ý¹ùkci}Pî7Ñ,¥Hyô¹Å¶BœÔ%eZRyä¹E’–¤+=òì"­÷ÌœÕÚP²%yK*ò–T”lIY—ì§\¥[ï}ʼ%˽ôÐ3 -ëÒÄY+•xé™º¤b ÆYyrF¯ì¥[îy≽ºÔÛÿÀÄ–{IËÆÝñÐT-§rûƒST›Ö+{iFÏŽÛÇOÑO•ûžšÛÏß÷ä|9LÓJeÌÏË^*-¬7áùå·Þÿ¼J[“vFcjåKÇ>h‘@OOOxO­~g©Å:Ø € @€ @€ @È4¦‹¦v@ _SxY7ÂåG×SíûNQ’¥4QÉR+•D%+µ¢’½c®R¨Æ’J`,•¤%W‚åá\)IKr•ªJÉUrEÓ=L7o©*åR=uiniÁ8W¤.™·dêR©ê’Ф%WÌ[²b+ÇY1{)(eu)°—TÚõ–ÈÆÔÁ—ŽC ÐhL]ÁÈI @€ @€ @€ 'hLyŠmmŸ@Î4¦û'6ñ~8úViL­˜IµÆR#W©®®$o©ÖXTZ2{i¾JÅ[ºàòë§.Þä[ªë-­Üö–,ëR»êÒ ©KµöÒRg/êÒÐí%'3‘©ý¯ G@ ChL‚ã0@€ @€ @€ ä—S~cGË[!/©îânÎI’Æt숯×I Ó)U%UªÎ«d –ª\%ýZJ°TGW*¥\ §YrÛaiið|K5ÞR .UR.µžu©¾ºTJ¼TɽT²—– 5÷Rmê&4¦V¾tì®@cê FN@€ @€ @€ <@cÊS´hkûò¥1Ý6nbÔ=r‹»­Û}åè_{Â×k×z ¯ûV¸ê•àš¸Jt¥Pš¥z+Ä5H¶4··Y¾¥æÞ’– /תº4äe㚯:‡ÆÔþW# Ð!4¦Áq @€ @€ @€òK)¿±£å­È—Æ4fìÄh†¤PΤ+¯ûåOøzÝåÞ\"¥F¹”ä' ”ÒêoJ%ÁÒ€®¤4Kå…áBËÃÍ[¹sn¤ÔHK‘uâõ–föt¨.Å‘x©®Ï„ÆÔÊ—Ž} ÐhL]ÁÈI @€ @€ @€ 'hLyŠmmŸ@¾4¦_Ý÷T•ovÖìºBÓñ_«³CS-)¢+–’Ê*+;Ã¥ÊUª$Xª£+É^ªg,5––úg­Ø1kyP”c©ª4õ–¦k8W" ÆÅœu©QN&4¦ö¿‚  1uŽÃ @€ @€ @€ _hLù-o…@¾4¦[ï}ªIž¤+~òË/ÿ5·CYH2-iÀLªã'™«µ”B¢R}W©±®Tk,ÕfZª#-E׉Sî¥íÓU– ”zÞÒö©K·eɶæ+¾%ð)S+_:ö@W 1u#' @€ @€ @€@ž 1å)Z´µ}ùÒ˜~yï“‘ IîWIH—]û iLul¤°¢´r§œ¤p‰.ýV³ÜÜÞ~iIÊìÞ~)Já2k…²+Y)çXj-ÓRi©A¾¥ yK5 ©ý¯ G@ ChL‚ã0@€ @€ @€ ä—S~cGË[!/é¿~²‰u$éó_þÚ Z’YJ½*Íä$'-–R¨dÒR«º’Ö‰‹® 'c©%iiÚRKi)ù–š§tBcjåKÇ>è 4¦®`ä$€ @€ @€ @È4¦‚¯4?¿‚ïPGcŠ—/gOSjè©€ @€ @€ @i@cJ‹<õ&C ×S2ˆ¨%ßИò?Z߃€ @€ @€ @Þ@cò.äžuɳ€û×]4&ÿbîIј< 4Ý„ @€ @€ @€À4&FC±  1;¾ô И Xº@€ @€ @€ ÆИÅ&€ÆTìøÒ;4&Æ@Q  15²ô € @€ @€ @  118ŠM©Øñ¥whLŒ¢@c*jdé @€ @€ @€@cbp›S±ãKïИE%€ÆTÔÈÒ/@€ @€ @€ 4$€ÆÄà(64¦bÇ—Þ¡11ŠJ©¨‘¥_€ @€ @€ @hH‰ÁQlhLÅŽ/½Ccb •SQ#K¿ @€ @€ @€ Ѓ£ØИŠ_z‡ÆÄ(*4¦¢F–~A€ @€ @€ @ !4&G±  1;¾ô‰1PThLE,ý‚ @€ @€ @€@ChL Žbx¦oøÊ]?-vé×N;ìиS½&@ç J© ¥[€ @€ @€ @hL‰Ñ@ ÇИr<šÞŒã€ @€ @€ @Þ@cò.äÅíðä“ûöõ·ô õ 11. J© ¥[€ @€ @€ @hL‰ÑQ‡ßzxaúBG Ð*4¦VI±_Π1å,`4€ @€ @€ @C'€Æ4t†œ! F<2BÓÈÉ#•iÔôQÚ°bù™úök[úU{ªhŸ,4›6@`¨И†Jã3J)£¡Y€ @€ @€ @ˆS|l9s’ƯofÒ˜¥c†Ý7lÎÖ9ÿxÐågÒ¯¦1飞þmèW’d © ±@cŠ+'MŸSú1 € @€ @€ @H˜SÂÀ©.&NKR¦%ó“”IÒ’U'ÃIz“Šv“Ƥ¢}FÏSc8-’#€Æ”kjJ”S¢¸© € @€ @€ @Y €Æ”…(І¡±dëÇ9uI¢’e`²7¥.é§|&ÙK*ÚPЦ¡×Ë 24¦”@õq@cŠ‹,ç… @€ @€ @€@f  1e644¬-ný8§1™®¤“HW²OÍaÒ†Ö›ÓnúÙVì ,@cÊbThS 1u"§€ @€ @€ @€@¾ 1å+^´¶‰J¶`œËÀ4yãd¹JZcNkÉé§´eæ´­Ÿ¶ð/äžSîCHê@cbd@€ @€ @€ @À;hLÞ…œCE"€ÆT¤hÒ—4&† @€ @€ @€¼ pàÍ =;®¶2móñwõ6gë·Ý;úÔ t€@ 1 ˆt¡4&Æ @€ @€ @€¼ ðöŸÞ¿ê/e/Õ½¯O½ @'!€S‚Hê@cb\@€ @€ @€ @À«wÝRWcÒû¾  Ÿ~èé¿æ•×&ùÑWzé%4&/ÃîC§Ñ˜|ˆ2}„ @€ @€ @€@@ nB&R118ŠG@ºÞÜWN-^¿èÊИ %€ÆTÐÀÒ-@€ @€ @€ Ô#P›‰TLŒ”â@c*^LéQ4&DA  14°t € @€ @€ @õD2‘ЉaRHhL… + €ÆÄh((4¦‚–nA€ @€ @€ @ pB&R11L I©a¥SИ %€ÆTÐÀÒ-@€ @€ @€ 4 à2‘Љ1RThLE,ý*@cb(”SAK· @€ @€ @€ И€%d"c¤¨ИŠYúU&€ÆÄP((4¦‚–nA€ @€ @€ @ 1%dzbýú $’S!ÃJ§ 11 J© ¥[€ @€ @€ @hL ··÷¯ßõýŠGàÍ7ß<æŸùÎùG¯kôehL …‚@c*h`é @€ @€ @€½täQÇ<77ø‰ÉÄ0)9LŸþì±·Ý÷Øé?¸äꫯ.XïèÊИ %€ÆTÐÀÒ-@€ @€ @€ Ô# oéÃG {aÅ–ÞM¯ÎëyùCÁdb ‡€9L·ß÷¸†÷ŠM¯ž†ÉTœØÒ“jhLŒˆ‚@c*h`é @€ @€ @€jÓÑÃôn]¹ùÕÀóxißœe˜L ”‚¦Ï{ÇØÇWU†÷ò¾}§s19™ `º&€ÆÄx((4¦‚–nA€ @€ @€ @ š€9L Wn]õò~Ó˜–¿´¯§oß쥛ÉÉÄ`É;9LŸ1‡©2¼eéIcZ¶qï÷1™ò]Ú_K‰QQPhL ,Ý‚ @€ @€ @€@ˆ€9L‹Vn]ýòþr®šŠÆ$ÏcÖÒÍüÈ1K{–à y$Pq˜ž†wµ¥§á½tÃÞï}ñ•Wý(]£Í¨O‰‘QPhL ,Ý‚ @€ @€ @€@…€9L‹W½²zË€äa¹jzúö.ݸwɆ=3–lúà‡?¶dY&Óˆ#/½´1lذɓ'×EÞÓÓ£ê~Ô××wðàÁÕ¨máªG—^zgüøñêŽ^jvÍ£Š¡0‡éÎqO¬Ù²ÀÒÓð.%3iÉú=#Ϻø’Ë®j½" Þ6ÂõÒpmýðøötuÐ*Ôf}ûšï¦Þ zžXwp×Ú9sæÔ­‘/f4¦XÇ%'OSzì©€ @€ @€ @ñpSEò¨ZQÎI/®ß3ãÅ—>ÐŽÉ$ÑǼ½ä ɇ¨ëH¤Ðžu;ªÃÕ,ºB¨‘G>¹Ù!ò–Ô“«ÆŒÓÊ]i!'éŒ@Èa:ÐÄÒÓð^¼N&Ó¨ÖM& †ð¸ÍÎ`ÐàlQþSûý~¥®1¹‹€Ybj°»ª„‡_Ì詳KGežSæCD!@€ @€ @€ Ð)ÃT_ò0É$EkwO[Ô†ÉÖ˜Ô@çyHG°ì5£FÒûaiäÈ‘ö‘Þ×nR(tmD w·ö#D¢ƒ;vv¿ZzI«²´¡$.–PÇ* ·MïH½²wì´¶D5°: Çu“€9Lw{bíÖU©˜B &Z*¦Òß½píîïžÙªÉј4ŒñÆáÁfãG_ 97ü¬Ãnˆšê§3Ø>Î4r#6¬ÚI´g˜šÎ¯—$òE{í`'wûë§åé›bcÞuÊȨ̂Úö¸6X÷urk˜ë¯{'ÜÚÈi#_ô‘}=Õ$ƒãΣm™[|1«¾ê€b“Š:8‡ ‘Àê]·¼ý§7=‰s˜lx›¢wÓÃ+O¸jÊðó'å”]ÚÓ·/Þ‹¢Ã{Áš]'ýd††÷ׯî,½YËwh„³±ÉmÒïvZ;ÅÞl2„œf4hØ¡9ÈŠràª"€ÆÄ€È!S'íeÍ8Çz§¾Æ¾Hš6eRž£]‹¹ìæp0Ðd@€ @€ @€ ‚¨8L[á!½CåÖ§Ö¬¨,¶5ü<ÙÏ/ݸWÓͯ^¼n¦/]ñ¼$9Lã§oÒz[#6÷§z•ŠiÖŠ@ò˜Ñ³ý©Ùëßß8'SÁ±Ò½ø ÜÕsØøUÙ\f’ÃôéÏ{ÇØÇÝð^µyÿÕã–i„K¹“¢'OŠÞ…·-, ï™ÞZNîáY›¾|ÅóÊ4ö½›{íý˵`â5ãz¾{ÓKÅTÞ;¦/Û~Ê÷æd*÷^Ó£ç:ûÏ;uP̧Ѝ•”xEŠ‚ËñÖÊ!~íƒÆäW¼‹ÐÛð—ú‚+›­°i}“˜¤Å^µÑ0“ËÌf“[°VÇ„·‹€Š>@€ @€ @€ @ çÌaZØ»ÕRÔØ2[2<®»LnÇò—ö-ïÛ÷‹'WŸ~ó @€ @€ @€he˜žþµ­ßËÓK‘ðH»Èzâ%Ÿÿê÷^}ÚUч)B±ÓÖóß=¶ò Ó)Ÿ¼!v”‹Gl'˜RÈãÜ Û>þËù~[—vBy’é¼ ¯ßr÷I²zbLÅ0ÓÏúñs8è̶˜ÏË*ü;DmÇ&‰)¢—2LÑf,Êû3W~7õaJå}õÍ÷\ÕŠ1EyoÚ–Uø3"Æ”¶“Û²#:¥ Sí$ÓÀSŠ1ò„ß\|’A z1¦Fü|';ÂE)2H{cJ¹¥|§ÉâŽtñ[±ÍÜ jš2 @€ @€ @€º uÔQ§žþÏ©ýRJ/e{lµZÔDŒés_½ã“—}'ú0þ¹›OûÜÍ‘ðˆœGêÃ]j^vÊå‘aºê¦{â=cŠ„GŒsZ1¦!ÈyÿŽ3ÿœwÖµÿóÀè‰ ”(ðÑ­ÿË™çÿÅþÏüÓ妈1Eg¦Û² S´‹-ä¢JóòŽ S«Âc#¹,ÆåÛÉEŒ©+¥×É0Åç~qóÿûÿýçïvl–X2Ô\àÂãëöß#÷C`´@ôQŠ$R¾_dì+»Ë¥C¢3S|O†n*œâ‘XŠG:Ež‡Z½zujÑäA€ @€ @€ @€@µ±åÖa‡ö¡^E—:l¥5±ÁÖg7Ý ØH.5aúôÆ,Æ!7|èê´ÙV4ªI›mEÎcõwEÈãï?üõ·üú,ÆtýެS!äqÊÖpà!·Þqßí;ü寮vâ®ÞþäS˜¾~×úÕ®˜ã9çœó¢¿,/ï´…\êÀôÆ3¯yÕi_M¦(ïW¾ÿ«¯|ÿ¦¼¼ó Sì–xÔÉ—}ð ·DyǾŠGþãeíòînŦ}÷{ƦͷFyÿè¶~sÖa’Lç¾¼1ì&B€I ÌÏÏG)~MI¤Ý»wïܹ3’Hñ$ñ$¾ŒûcJMœòGä–â­fŠ&Lñb†šä|\‹ @€ @€ @€)ÉtÆG/Èãi­´‹\$<Ž›»ú˜w\;m¿ñö£O¹ü+›øÌ×1rKùˆÍ¶N=Û!Ç9ú0µ[1E†©;äQÌ0EÎC’I5–%PŒ1Lùù#Éô¿¬XÞ©Â#ÀtÜ™WG¦çÅH¦¯|£¯¼oÜuÁ•wD¿±TÞŸºâ»íäväÛÉ3L©¼ôÓ_þæ‡ÛzÃLbLe­ºó 0c‘5*&‘Rï¥<ž”wSÚiƸL— @€ @€ @€À ´“Lÿ|AÊv´÷Øjµ¨‰¦´‘Ü51n¹÷ê[ÒN[Y¦hT“o¶µqëÝ^uçÀF5ý&I¦).—šÝzŠ1 0åwI¦CV••w¾…\k¹TÞ}íΞòN{É-”÷¶·îLå}ù–=Æú3L I¦¸ƒb˜IŒ©fÅãvh˜€SÃÔt @€ @€ @€fT %™>ð‘ÏDû¥ï`ZØi«µ—\ôašß¶36ÛŠÇ7DÂãîhT! …íä†e˜F$™vÿ÷Ý3º ¦½ç£LùùR’©¯¼ïûz'¢ù¼vDoP†iã w·+<í–xÝ]©Ó° SW’)n"…™Ä˜ö|}A€¥ ˆ1-ÝÊ;  @€ @€ @€ÔZ ’L‡¶’L­öKíLƒ»ÔŒÌ0C£3L“Lk.[³î¦uµ–rsuxèW»–x;‘d:xÕQ ù¼îcň^O¦ñ2L½I¦¸Ë‡~¼Ä[õ6C@Œi 4‡ @€ @€ @€¨©@$™^pð Oû§O·ÓK·f[ÈeãæöFrŶ:}˜Ú]j6Ûê4ªYJ†iÇý?ÿõÃäÛؾòã+×{}¼²eç–ôk4gÊû3ÅÒ›wîÞ¿•YSP·U3³ÿé£vT^Þi“Ävy§&L}½® SÖilI}˜R†)ƃýªfn‡cjìÒš @€ @€ @€Àl ¤$ÓûÏþt¾ÇÖײxG!áqck#¹ö^r¶Z{Éíi¦ž S€Ï]7·âŒk¯ZÏ#Ï#š3û3ÅïÆoE»¦ø­x[žyšÍÅ2ë1"ÉtСGuåó:¦¼ SÏV‰Ùn‰QÞ2Lcp;„cš ¶K @€ @€ @€˜ˆ@J2½ïìó‹¦þ„ÇB—š’2L1¹h°ɤx2ç|zx’º.¥^Mé•ÔŸ)z2­ú̪‰¨¸Hs"Éô‚CÌÊ»;À´iÛ€ˆ^»Í˜ SsÖßLh¬€Sc—ÖÄ @€ @€ @€fY %™Þ{Öù±ÇV 0õ'<®¸áîÔ¥¦”>LI;,¥VLñktfJ/¦LñˆWRg¦x%ÒKù˜å•2÷ñR’i¡¼[=Æò&L#"zç~qó¾û=cÓæ[ómã>±—Üxëâ(ì€ÓÞè9– @€ @€ @€@}R’é=gžŸLý B—š®»ë’k³qÊÖpà!·Þq߈Gÿ^r¹B$“¢S|ý–¢3S<Éû3ÅóøÝÈ0¥0S:dý·×§FMöT ’L¾èÈÞòÞší“8,¢'ô§ÈÞO€I ˆ1MRÛµ @€ @€ @€LT %™N=óSWnݹ1F+ÞÑNx6’ÛÐ 0í}†)æé¥*Å“¼SŠ1ů‘^Šc¹ñ$LñÎø­ør¢(.Ö ”dj—w!À40¢'ÃÔ •7š) ÆÔÌu5+ @€ @€ @€I dúÐyy€)Ox\zÝB¦R2Lq¹'¥MåR˜)="À/¦$Sz%:6¥íçd˜ê^ D’éù/:¢PÞ]û$æ=¦½tv8& Æ4d— @€ @€ @€ P¥@J2½óŒóR€)F 0å ²2LUNÒµgX ’LÏ{á—o阮òîŠèÉ0Ípu˜:Ó$ Æ4M«å^  @€ @€ @€Œ'’LkÏ8¯`êJxÈ0Gê¨Z dI¦Cޏ´ÑK›$¦!ÃT«•r3! Ƥ< @€ @€ @€Ì„@J2½ãƒëŠ ¦™XûÙ˜d$™8äðb1¦ÙXy³$@ 9bLÍYK3!@€ @€ @€ 0Z %™NùÀB’)žpà!·Þqßí;6vÜÿó_?ü[õHI&}˜ê¿RîĘ @€ @€ @€(&™d˜fhágfªy’É^r3³æ&J€@sĘš³–fB€ @€ @€ @`)Y’éÀóŠãxÞAú0-EÌ{¦K ’LÏ:àEû>鉛6ß:¢ÍXüÖƒýjº¦æn  Ðl1¦f¯¯Ù @€ @€ @€ ð‹«?¹æ)ÿû­›.µ—œúh¤ÀÇŸÿ[›Ö¾R†©‘‹kR4X@Œ©Á‹kj @€ @€ @€†\sÎo^µÏ=7ÌËyì¸ÿç¿~ø|¦UàUû<ø±Wˆ1éÃ4­+ë¾ h´€S£—×ä @€ @€ @€ hŘ~³}þžýEÔC†IÕL½@”÷¹/¬ÒÀ$“ ÓÔ¯¯  ÐP1¦†.¬i @€ @€ @€Xš@O’I†iilÞUoíó¿Ùu[Üb’I†©Þ+çî˜i1¦™^~“'@€ @€ @€h¶ÀWO^½~õÊŸü`{Ï4·~líÝ[æóó$“ S³ë¡a³{èþQÉ·^0×?¯â‹Å$“ SÃjÀth˜€SÃÔt @€ @€ @€´"¨1¦ˆzô‹ôg›"Ét×}ýúáGð˜(ãˆ+}ÿ«ë{nøþom‰ß*¾˜’L2LÓ²²î“™cšÙ¥7q @€ @€ @€& D†éÒ5«bēԴ¦Øé3«V¤ÉG $^ÿΗ×ýG‰ S¼9½³É4æÖÈ*Eǯi6ñ$^¬áüõÑ‹ÎdñÊÀl_#TL‚Ó- Æ4Ýëçî  @€ @€ @€ øÕC»£!Mä“"±O¢cMŠ}¤GêU½š"Æ”¾ŒwÆ{âI|/Fþ ,: lþÀš¨çH,EIGÝÆ“x%vJïÅ“ôzÔyªçx#^‰×%™ê¼¸î™cšÙ¥7q @€ @€ @€† ¤–K‘gJ‰WJ)¥|Ä+‘íH»ÎÅ{Rì)! ¥gO®†K™Þ äeñ»¼nSͧ”RÊíEaÇ+©Y΋О–cS¸æn™æ ˆ15Í @€ @€ @`R‹š˜x$6âIjB“Bñ<õª‰Gz1RMñþx’ö¡KcÑLyŠ¢Œ£¶S…§Š:O5Ÿ‡ðRyÇ;SÙÇëù;ئh­Ý*³# Æ4;km¦ @€ @€ @€3$ÙŽÔr)oHÑ¥<ä½j¢™MŒxC´«‰÷¤½çP¼SÈc†je:§šZ.¥ø]j¹5Y¥h”Bxy § _¼}›Ò\Så{ @€@ÝĘê¶"î‡ @€ @€ @€@ ‘aJ½j"íÏSŒ#•RO¦È*Å“x=~7½žö˜K_æ»t•p+NA`R§SD—"¢uõœFªüˆ+ÅoEUǓԖ,¾Œßµgâ2,ˆS @ 1¦‚ @€ @€ @€@ÝŠ9¤ˆn¤/‹¿Æ—ÑÌ&~+F~ó=_ÖmRî‡@ˆöKyG¥0E2)RJ‘Ì‹O¢°Sy§HSÊóÅ#žÄ—Z1©"ÔV@Œ©¶KãÆ @€ @€ @€ @€ÌŠ€Ó¬¬´y @€ @€ @€ @€¨­€Sm—Æ @€ @€ @€ @€˜1¦YYió$@€ @€ @€ ° pÍ9¿yÕ>¿Ù>Ï„@3¢¼Ï}y3§fVh®€Ss×ÖÌ @€ @€ @€ cRÍcjöúš cjèš @€ @€ @€Ÿú«¬Ó®Û h ÀOweå}Á85S"@€@£Ę½¼&G€ @€ @€ @` @ì·9xàά¼/>©‘“3)4XÀ& ^\S#@€ @€ @€ 0D@ŒIi4X@Œ©Á‹kj4Z@Œ©ÑËkr @€ @€ @€ ˆ1)Œ ˆ15xqMF ˆ15zyMŽ @€ @€ @€À@1&…Ñ`1¦/®© Ðh1¦F/¯É @€ @€ @€( Ƥ0, ÆÔàÅ55- ÆÔèå59 @€ @€ @€ĘFƒĘ¼¸¦F€@£Ę½¼&G€ @€ @€ @` €“Âh°€Sƒ×Ôh´€S£—×ä @€ @€ @€ cR cjðâšcjôòš @€ @€ @€\àÖK~sñIíqÊ~óª}¾Œ×õ T¦X 8/ï ^Ÿ•÷ûžµðJ¿Ô^@Œ©öKä  @€ @€ @€”"ðÃmY¶cà8ë°R®à$ªˆ2VáQü P{1¦Ú/‘$@€ @€ @€ P–À°œ‡GYÂÎS¡À° ž”^…‹âÒØ1¦=Ñò^ @€ @€ @€S-00ç!ä1Õkêæ‹ƒzRzŠ„S" Æ4% å6  @€ @€ @€”"Пóò(ÖIê Ðԓҫú¸,M@ŒiiNÞE€ @€ @€ @ =9!f,«Yä=A=)=µA€écšžµr§ @€ @€ @€J(æ<„¼ÎSý÷V{¼’|WÍGñ.ûüõÅê¿øÑÈ> Ýõ_þ‡ß~ÔïÿÁŠüõâ'"=ÿÃ?úãôÃT±ÝuÛ*ݬnÛ¥ÛªÞþî­áV畼=«ä®b.ÔóO²znTÒYUg…UuVØÝµ}S§¶óòî­ðV‘wê¼»Ô¿•z»Ú|_Í·Ê>¯ü¼ø;õ¿«]ÿÅÀí@ßag|b\ÑñYxÞ xÓI§u}" Šø\¼ûìÏ>ûÙÏ^ê’{¦D@ŒiJÊm @€ @€ @€Lƒ@„?¢KôR 0eãÞŸEŒé}­S 0eAV dh†©c*f˜òäGÊ0å±ÞÀG+ÆÔõøn;Æ”2L­G'ÃÔcº®ìèÊ0µ"]¦þS'ÆÑ‰1¥èFWŒ©Úè1e&1¦å¬ö,ÆtÔ±]¹¥B­¦ôRTrJ/ 0õ–n'ÀÔÂ+%Ô'óºÂy½¦…ˆÞèS+«7,ÃÔíõåöǘRz¯˜aÊbL­ ßèÓ•}y¾b†i!ÆÔJõµƒ}bLËù¡pnj" ÆT“…p @€ @€ @€MH=lÚ¡¥vt©«“ÍáGf1¦¦¼MjÂ4¬Óè Ó^·bz`¡S+Ætmw7¦E[1å1ެS¡M;ÃTLoä1¦‹S7¦®VL­nLw鯴ŸŠˆ1Eœ.Å•ºÊ5Ë-µ£KQÉyû¥LKÊ0E§±¥µbÊ3L[:-Ç¢à»{‹µbjw +4!ëkÅÔiEÖÝŠiS'É—‡ùÚmÉúZ1¥ÓšèÆÔaÊ[”m¸V7¦åød8'Õ ˆ1U¿î€ @€ @€ @ 1ÅðÇÀM¸^zä±ïýà‡{:0 ØH®» Sÿ\û0 È0µ:Ö¤íäòœÇB+¦ÞíäZÔ lÅôl;¹îVLKÛQn@+¦ÖŽrínL­ÓÀå"®aS¹Ò?)Æ´PŸÅ ã:{F%ÓKùæqÅÎa…-äú:0 0 ÜH.ßqô^r£ú0-9ôØvr½û'ÆFŠ­‚·Ó…M ;ÊhÅtEkwÅa1¦´ÍbŒKĘJÿT8!õcªÇ:¸  @€ @€ @€Fô„?ÚÝk ;ǽôÈcÞóo×îžÈB¦b€iÇO&?ŠÉ}ëû?I{ÉîÃ4*ÃÔ·\ÖŸæ¶ÔŠé¾æH£ôVL…SÿæYí¸FĘæÎúçýô—ùøÉÏ~Õˆb©lcŠ8]O¥žÐRTr¶kw]êm¡÷Roz©ØBìö¦‡u``êjÂtg¶=b]›$f¦¥î%·L¦«o¾':¥qU¶£Ü"ÛÉ-¥S1Æ”ï±XlÅ”bLO_ùÌâç"žÿG©¬ª\˜eˆ1•¡è @€ @€ @€Z=á…üGD@Z),Ætú‡ïØ9*ÿÑþµ÷VW€)ïXÓõøÑ­-·ôaZ,Ãtmw†ió7ïMµÚûjÝrol§•ƀǻ6µÆˆVLcúßý½ó.þưVL׈Ó»O;;21ù½_?,®1þG®c:¦˜Rêj֪ը䔴ëÎÛ ¨ÛžèR1½T á ÜBn`¦b€iŒ&LQä[o`kÞil¡Â³fcCö’³Ó3LC·“ëô$‹BŒÔ‡)u&{Þ!íMå²ÓuÙ(¶bJ1¦}÷{FñsÏ|HÂoüÏ…# ¨ƒ€SVÁ= @€ @€ @€4D`xø£•ÿØùàKŽ8æÝ§ŸÝß{©þèé^³h€i`¦ÖFrí½ä ½j–!ÃÔŽ12LY7š¯Æèd˜6mkǘº6Òj…6Rn£cÚ|ÙõY7¦Bb£ÝŠi`Œ)27bL{óI1¦bJ©»ÁRÔjcJ{ÇÝæå:°nS’&ÏÞõô^*¦—Ší—Æ 0õïØ›Ï‹ S+Àã†4¶Gz)û£ÍX>R¿±¼åX×+n$—…öй½ÂŠYzoi}˜ö4Ãtù–ì³bLy+¦ž “ÓÞÔ¿c ¨³€SWǽ @€ @€ @€L™@„?ú3ÅW^1¦Bo¡,ü1rã­Û~ø“´…\!öÑêÀT0µ:Ö Üo«¯ S'ä1,Þ10Ø‘ö’ëëô„ S§ÓÀ Ó­Æ3cZ×cJ‰j¤ÑßIŒi/?cŠ8ÝèB-VrOËŸ…È]§t÷,ºôƒŸÄNˆ ›!vWr±ýRq ¹½ 0nÂ40ԘڽǺ3LùFrÙ^r7 ÝKn¼ SŠ1ý]Š1õõaJŸ ݘöòSàpê) ÆTÏuqW @€ @€ @€S)áþÌGþJ$–"ÆtêigEì#íùh7^úit¬ÉšÖ H/ýdPzi‘ÓbÉ=Ç;®ûv¡9Mg#¹NgšeÈ0u¶ÐÊcL]‰N†IŒi9>cŠ:Q¨ñ[©’Û1»BØ®·n£€˜o:‡õt]*6^•^ê¤ñÚé¥bS±;þõ¦­ó±Ð]lT¦®&Ly‘lÂTìÃÔ߄难-³ÓÈ S¾b<¹rk{lܺsã½äR¦4Ú1¦!&1¦åø\8'ucªÃ*¸ @€ @€ @€†Dø#(õ>ú©‹c¤Ž5Ñr)Æñ'½'k¹”í±õÀß¼ñÄY·>F–öØþ@JuDÚcËö,äã’¯Ýú„'ïû•Ö¯yš÷ùÉÈvÄxŒlÇ_Þü¬çãÕ¯?!¥:yñÑÏúÓƒžù§ECšñåq'¼+¾Œñ©‹¯‰ñèÇ<ö¿<ñ©ç­¿fÓ»^uô3þë bdŽm;OûÈçW>ç1^pØËVÿÍ›¯hŘ:M˜î¾¬Ø‡©ÐxFŒiòÅ1¦ˆÓõjO­F%w3Ì+6OÚuÕm§t{ö:Ì÷=Œ¬Rp$ðRË¥Èá}ê¢+Ÿó¼ƒ£€SË¥H)wáÆ(æ7¿ýݶúo².b­ôRÔs*é(ã“ßsVD‘¾ºõû]úë7œ# ûs—|#•tJ,åã³_ÙÜÊ-uzŒ}óÞ“N=3Š‘ŽÈsį¿øès¼ëƒçFn#6ÒzåkOyŽHr¼þøµ`zÇÎGd8þãcþàìO]ò/_ûÎ~ÂSÿ2bLí]äºL…ͳR\CŒiò¥žÅ˜^rôèBí­äVÀnDݦÄR±tóç­ìÝòMâ"º¡¥(ãvt©ÕB,ž¯»pã…—^q¥È-Ee7ŒK1¦O~þŠˆ.Å>q×Þ1¦bD×¥´[\”w¼I¦Î¶q÷ýÕëOˆßÊwŽË{/½úu'DµG‘ì‚Ëýû]¿ñ¦h¼u~Ù7îˆ&L‘^ŠöKÑo,ÒKÑr,~ÜRTû®¸1ê?ýzÐa/‹²âçQöÑ{ìßÚг…bO†oLbL“ÿD¸"È»1¥$ÒĘ" •Z1å1¦ /žË @€ @€ @€L‘@„?ò4Ÿ¼è%/‹ÓÀ´G¼˜š-åH/E¼#Û-.¢KÇeÑ¥Ô¢¦Ý{©Ðu)Õä»kEÈ#¥—¢÷R$<"ÞãßÌ‚1ò}µ"Àô¸'í˜Z;jŸ'RéH#òm¼éqO|jt`J[È¥G¾…V4¡YýÚãÓþq)À饔Þ8þ”3þò5onõaÚqÙõÙÈv‘+˜6\—˜Ä˜ª*ìˆ1EŽ.ÔþJV´ÃâJ©ŒÛ{Ãuž¤ S$–Ò>q­'Y¿¥,¥ô…+bĔƋS÷nq÷G=âó—g…ý¤}£—Ø_½á„‘Ì‹>Lyt©¸m\´\ŠwfåFgÛ¸¨ùOÿË5Wß|O¤ô^öò×D³±¨öW¾î-ió¸(ø¨öDŒéµÇ§šSÔ|Œ(øÞñ¡xåÃçoˆôRŒh<é¥h®K€Àr Dû¥|ƒ¸t­¥Æ˜â°ž S,Æ´Ü æü @€ @€ @€Ó+áÑi½øeÿðî¹bV)-u>¶?{lÅÖZ'¿÷ìbt)µ¨I1¦ÈyDò#¢ÿøî³òmã¢?MŒÔx)‹z´¢Kñžè½ÁŽ|ó¸v|ü‚,Æ”6‹©Žˆ.¥HÇ+ÿ6Æñ67Z.E˜#ºÑĈGl¡•bL±…\cje˜"Æã¬óÚ1¦ˆnœµî’ˆ1¥S;½QØE®'±¡Óä«=‹1½øe£ µXÉívJÝ»¼nû³Ji£Ã4:{ÃeON~ïYWZ÷…+R§èÒÂóÏgÅüìç#®ù¤-¥z.v]J»ÅEã¥(ì“N=ë…/9:k¹ãÖ{ãõ¼ëR;¥×I/E…GhéŒ]—¾¸ñ¦¨ö«n¾'ÕyYV怜ÇX|ô‹:O5äûëcŠÛ&Fã±Nï¥VŒé†»£ñXÿ€öK ßÀ߆NŒ¯?À¤Óä?®H€ÀÄ"tÔ“aŠK/)ÆÔŸ~J7-Æ4±Ås! @€ @€ @€©ˆøE1ÞÑQzaĘNýP;±Ô‰zô¤=¢9͆«o Sòˆ¨Ç6|#b©EMä<>É7¾|Õ-‘ÛÈZÔ´r±¯V{|ó¾g=÷ HxD㥬÷Ò­÷¾ðÅGG€)¶‹í´Rï¥gþéAúø…cŠŒ'›nø~4[ÊBKÜRöB=· ;byç|öòVã¥{S2/Jú3ÿòõ<º”vEŒò.6^zÛ»æR…§ ã"À•Ü[Þ—bDyŸwñ5Ñx)FÊêEŒ)~ýÈù"½ÕûÇÅæq©÷R<ÿÄEWgeßé½e饈1|Ú9­ÊÏÆ¢í— 0‰1MþáŠLF G±)\ÿµ1ÍÏÏÇ–âøô(&¡Ä˜&³x®B€ @€ @€ 0ñ¯lÅö3ýÏ#ÆtÒ»>4,ê‘g>}é1‘ÏÈÇ_¿áÄH{󗯉´GŒØ$.rKñkñ=­ ã²GŒ”íH#/ÍsQj¼1¦x#žD¶ãmèÒ3ÿëA±—V¤:b/­v¤‘ÒKñ$‚1âIJ/½îøµ±…Ü[N9#ÂéHãø“ÏˆGüÏŸþì<4ß¼yÑ“M媪ðˆ1EŽ.Ô!•ÜÊ' J)KéyWŠÒ¦b¹¦ø]´\Š|RŒx÷YÅÜRk{¸(æ4²’Žd^4XÊ«:j8bLQÛ¯~Ý ñ<ÂIíÝâ:­Å¢¼ÏÿÒ5ÙëOÜ7Fd˜ÞõÁs£È/Üxcªêøõ¨?ÿë(òÔiiÓ¶]‘[Š×ã×è:¡½È-EÁGû¥ˆ+Eañg¡½xž÷^zús^eÿ·Ÿ}"Þ|ò]íÇ|í ßÓKyÂϦrU}:\—eX»vmÄ•ò$ÒÜÜ\~¡ÅcL»wïÞRxlß¾=?¸ø|™nÝi  @€ @€ @€L©@„?úóÅWYuTĘòWz¢)ð±°C\¡?MOsšžGÚT«]Š„Gj¼TÜ6.u¦I;j]uSŒ¬'MÚN+ß<î’¯7E:bDÔ#¶ÐJÝh6fãîHr¤ý³bD†ã⫾Sì@“µ_j86ŒìÀ¤Sµå1¦¨ÃÑ…:¢’ÛEÛê¨4p\{ÛýíÖJ…îjVhö¥M·ôsÖB¬»žó­âRUçý–Öv¡¼ÛÑ¥¼Èó:Oí—Rç#•zOÁk>•ýô^ºî®aÛÆ~]Œ©Úψ« Pº@ÄŠI¤&å—ˆ×óçû”~a'$@€ @€ @€ 0³þ–íH¯G|äíïüP+¨48ê10í±hÎ#‹w Jxä¹¥aÑ¥bª£+ϱ- sD+š³?µ! 0ÝP0-Ä8vä[h`Ò©ªIŠ1.ÔžJn•k_Ñv§”†•R¯Pà =–Ú‰¥!¼!%¢KÅÂn×v!™W çõä–òˆÞBt©Uê…èRwµB{ôÒBÙ·wNìï½4nzI7¦ª>®K€@MĘj²nƒ @€ @€ @  þˆ0ǰaŽƒWõ¶µgô´VÊ¿ìŽzd{i-’óhw¦Yh¹Ô“ðȺ.eñŽB×¥Bã¥þ†4=yŽO\øµžöK)ÉÑŸ^ZèÀtížµŸùG=úÜ/nÑ™&ÚÒ¼û´³oßñ`>îܵû×?Ò„r©h)Æ4¢Pã·¢’‡UéÀ×ûRJƒ²J#z,uBxý–úCKýý–ÚÍ–ZµFªíöètÞu©]Ñxéò-“H/‰1Uô™pYê" ÆT—•p @€ @€ @€ ÈÂß¼/ýÙŽƒ;ê­kÏè¼Þ* ‹+uí¥µÐl©+´4$·´'Ñ¥Þn4];ÇwÑÊÓKí&4×íÙþq³JbL“/ûˆ1EœnH“¤vÛ¤¨ä!ɤxິ\Úå°Ý*,ÒÊÞ Œ+ L,õ‡–š- Í-umé¥+ E^Ü!±'·Ô³gÜàèRï¥=Œî-e›9›ÊMþsáŠÔA@Œ©«à @€ @€ @€"ᯧQ´ ¿uó=ýÜ•UWÖf)K,í*òÒóžfK~Kƒ·ŠÝr©˜Õ‹­vKl…ö–ÒH©”÷ˆ1MþsáŠÔA@Œ©«à @€ @€ @€"áÑ!zä §|pDÂc¡ÁR;çÑ×fx£'Þ1h#­ÑÑ¥Á—ŠIŽR"Å“ˆ1M¾ô³Ó¡GŽ.Ôv%ß|ÏÕ#I+9먔F__¥®ýà •=–ºxéËA‰¥Q¡¥N³¥=Ú*n!·ÔÕr©œfcc^Ę&ÿ¹pEê ÆT‡Up @€ @€ @€ ˆðGoË™<ÒÑz1¦·œüÁñŽÞ„G„<öXžð‘[ê vº.-]ZÖ&4bL“/ýˆ1EËÒ¥RTr_ip,iÀÖo©t ªzRJí2TêÍ*uº+ Ž+Mg¥%f˜âmbL“ÿ\¸"ucªÃ*¸ @€ @€ @€†Døãò‘yŽçEŒé¤Ó;ïÉz)-;†d;†µ¢éo³ûg-='Q“wŠ1M¾ô#Æu8ºP«ä¾ÒÒE)ª7—F2©gt† ,æ´\ŒšÔê$oCŒiòŸ W$@ bLuX÷@€ @€ @€ ÐsýÏŸwÈkN:-½> ÕQè@Ó½\aÛ¬Èv4¨ÓäK?‹1rÄèBQɃë6¯çB2©¯†ûʸA•\nÈIŒiòŸ W$@ bLuX÷@€ @€ @€ ÐûÊ7ŽøG¼ß³ž_xÃqǾrÐxÅqÇÌÆø·ÿî·;rõˆÉ>öþøÝ§}ûŽóqç®Ý¿~ø‘†TLÓˆSÔáèB]´’×m^̯8îØÙ(àeúœFÙï÷Ìç8yäœöÝïÅÏE<ð¡_UQP®I€ÒĘJ£t" @€ @€ @€§Ÿ~úI…ljo}ûß¾ñ-ÅñâÃùóW¼¦çÅYþòùúš×½i´À¦Í·Š1•øáºóÎ;‹UÏßø¦{–à¹Ï?x–˲ò¹/åÅY=_Œ©ÄÏ…S P1¦:¬‚{ @€ @€ @€h¦ÀÏùpOÎÀ—{/ S韖÷ÿ|ï×Å*Щô† 0a1¦ ƒ» @€ @€ @€À ˆ1-G°CŒ©ôÓrêäÏ)ÆTúGà ˜°€Ó„Á]Ž @€ @€ @`†Ę–#É!ÆTúGHŒi9 uòçc*ý£á„LX@ŒiÂà.G€ @€ @€ 0CbLË‘äc*ý#$Æ´…:ùsŠ1•þÑpB&, Æ4ap—#@€ @€ @€˜!_ü÷‡'ehüï¸{÷¯~d†Êhù§z÷ý5¾lfa‚bLËÿYq–W@Œiy} @€ @€ @`Æ"É=™FŒŸýâ×£ß0k¿»(È/õðŒUéÓXØ¢e¶èº,zoØ¥ø—^NH€ ˆ1MÜå @€ @€ @€ @€ècR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X@Œ©âpy @€ @€ @€ @€ĘÔ @€ @€ @€ @€ ˆ1U¼.O€ @€ @€ @€ @€€“ @€ @€ @€ @€ @ b1¦ŠÀå  @€ @€ @€ @€cR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X@Œ©âpy @€ @€ @€ @€ĘÔ @€ @€ @€ @€ ˆ1U¼.O€ @€ @€ @€ @€€“ @€ @€ @€ @€ @ b1¦ŠÀå  @€ @€ @€ @€cR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X`‘ÓöíÛ{n°ÿ•Šgàò @€ @€ @€ @€Ô[`gëQ¼ÇžW†Æ˜Ö¬Y³²óHÑ¥þWê=wwG€ @€ @€ @€ @€@õ«V­Ê“Hénú_cЬS™ŽY¿~}ÖÿJõós @€ @€ @€ @€Ô[`ݺu«W¯N÷}”æææú_‰ßÚ)ß<.Řâ­ý¯Ô[ÀÝ @€ @€ @€ @€ P±ÀîÖ#ÝDŠ1õ¿¿54Æ”ß~´ešŸŸ/Φÿ•Šçêò @€ @€ @€ @€Ô[`Ë–-+V¬(Þcñ•Q1¦h¿‰¥hâ”ÜÿJ½çîî @€ @€ @€ @€¨^ v„‹$Rä–ò[éyehŒ)މ#ãÝù‘ý¯T??w@€ @€ @€ @€ @€@½¢R$‘¢ƒR~›ý¯ 1E§Øˆ.¢KñH§è¥ÞÓww @€ @€ @€ @€T,0??¹£ø5%‘vïÞÝÿJÜâàSjÙ”?V¯^ÝÿJÅósy @€ @€ @€ @€j/°fÍšb):+õ¿“Ú©ötƒ @€ @€ @€ @€4D@Œ©! i @€ @€ @€ @€¦W@Œiz×Î @€ @€ @€ @€hˆ€SCÒ4 @€ @€ @€ @€L¯€Óô®;'@€ @€ @€¡÷ð5K¾IDAT @€ Ð1¦†,¤i @€ @€ @€ @€˜^1¦é];wN€ @€ @€ @€ @ !bL YHÓ @€ @€ @€ @€ 0½bLÓ»vîœ @€ @€ @€ @€@CƲ¦A€ @€ @€ @€ @`zʦwíÜ9 @€ @€ @€ @€†ˆ15d!Mƒ @€ @€ @€ @€Àô ˆ1MïÚ¹s @€ @€ @€ @€ cjÈBš @€ @€ @€ @€écšÞµsç @€ @€ @€ @€" ÆÔ…4  @€ @€ @€ @€Ó+ Æ4½kçÎ  @€ @€ @€ @€4D@Œ©! i @€ @€ @€ @€¦W@Œiz×Î @€ @€ @€ @€hˆ€SCÒ4 @€ @€ @€ @€L¯€Óô®;'@€ @€ @€ @€ Ð1¦†,¤i @€ @€ @€ @€˜^1¦é];wN€ @€ @€ @€ @ !bL YHÓ @€ @€ @€ @€ 0½bLÓ»vîœ @€ @€ @€ @€@CƲ¦A€ @€ @€ @€ @`zʦwíÜ9 @€ @€ @€ @€†ˆ15d!Mƒ @€ @€ @€ @€Àô ˆ1MïÚ¹s @€ @€ @€ @€ cjÈBš @€ @€ @€ @€écšÞµsç @€ @€ @€ @€" ÆÔ…4  @€ @€ @€ @€Ó+ Æ4½kçÎ  @€ @€ @€ @€4D@Œ©! i @€ @€ @€ @€¦W@Œiz×Î @€ @€ @€ @€hˆ€SCÒ4 @€ @€ @€ @€L¯€Óô®;'@€ @€ @€ @€ Ð1¦†,¤i @€ @€ @€ @€˜^1¦é];wN€ @€ @€ @€ @ !bL YHÓ @€ @€ @€ @€ 0½bLÓ»vîœ @€ @€ @€ @€@CƲ¦A€ @€ @€ @€ @`zʦwíÜ9 @€ @€ @€ @€†ˆ15d!Mƒ @€ @€ @€ @€Àô ˆ1MïÚ¹s @€ @€ @€ @€ cjÈBš @€ @€ @€ @€écšÞµsç @€ @€ @€ @€" ÆÔ…4  @€ @€ @€ @€Ó+ Æ4½kçÎ  @€ @€ @€ @€4D@Œ©! i @€ @€ @€ @€¦W@Œiz×Î @€ @€ @€ @€hˆ€SCÒ4 @€ @€ @€ @€L¯€Óô®;'@€ @€ @€ @€ Ð1¦†,¤i @€ @€ @€ @€˜^1¦é];wN€ @€ @€ @€ @ !bL YHÓ @€ @€ @€ @€ 0½bLÓ»vîœ @€ @€ @€ @€@CƲ¦A€ @€ @€ @€ @`zʦwíÜ9 @€ @€ @€ @€†ˆ15d!Mƒ @€ @€ @€ @€Àô ˆ1MïÚ¹s @€ @€ @€ @€ cjÈBš @€ @€ @€ @€écšÞµsç @€ @€ @€ @€" ÆÔ…4  @€ @€ @€ @€Ó+ Æ4½kçÎ  @€ @€ @€ @€4D@Œ©! i @€ @€ @€ @€¦W@Œiz×Î @€ @€ @€ @€hˆÀ¨ÓüüüÜÜÜöíÛó¹Æ+ëÖ­Û¹sgCfo @€ @€ @€ @€,¿@„ŽzrGñe„‘ò+1­ZµjõêÕk×®]¹råúõëã€â+’LË¿v®@€ @€ @€ @€ @  +V¬X³fMJ"¥ÜQz%ñJšáàSt`Êß±eË–t|ĘÒ1qÆx4AÈ @€ @€ @€ @€XNØ.âJé )w=•òW"˜ñ¤ø­Q›Ê¥ƒãDÑ–)¿ÕÈ3ÅÁņNË9 ç&@€ @€ @€ @€ @ !CнäòÉDi‘nLù[#ëœò-äR—¦xÄ“†Ø˜ @€ @€ @€ @€Ë/¦<´WK_æÄêÆo SêÚT|D[§â— ®@€ @€ @€ @€ @€À Ä.rGñzl3cJq§¼S<É·–‹`“Ó…['@€ @€ @€ @€ 0AÈåÑ£¸l4Qš››K× Ó¨S„–¢SÊ:Å#Ñ¥x’2Lé` @€ @€ @€ @€ŒH;Â¥R<æççS6)ÂLñˆ'ñJ>¸Sü^~dcŠããy£âÔè  @€ @€ @€ @€ °¨@dŠI¤ZŠ_£ÅR<Ò—ñº©Ü¢ð @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ ¡1¦õëׯ\¹rÅŠ«V­*^i~~¾ç•RîÃI @€ @€ @€ @€h¤ÀÚµk#‰5kÖ'¯Ç#½24Ʀ-[¶Ä;æææV¯^Þ½{÷îx=ÎØH/“"@€ @€ @€ @€ @ \èšq£ÈÅi#†´nݺtþx=’H‹Ä˜â°H/¥"Ì”ç–âDñºS¹Kål @€ @€ @€ @€š*q¥x¤ÙÛ/¥æL‹wcÊ]b ¹”ŠSYL55Õμ @€ @€ @€ @€(W m·sçÎ8mtSZ¿~ý’6•K7¤åâøÈ3Å1¦r—ÇÙ @€ @€ @€ @€4^ ÒGÑ~)uSŠStSŠ'K1¥ÆMÉ(މ/#É¿F**e›< @€ @€ @€ @€ 0Z 'Eâ(e˜â‘2Hñk¼˜¿¾Ï°SÄ[c¹þßÕIÙ @€ @€ @€ @€ °DèÃY¥õ¿ñnL}JY§ôHÛÉ¥Gœ±øåïÆÛ @€ @€ @€ @€˜AØö­˜DŠèRްxŒi½L™ @€ @€ @€ @€ª†n*WÕ ¹. @€ @€ @€ @€³& Æ4k+n¾ @€ @€ @€ @€j' ÆT»%qC @€ @€ @€ @€fM@ŒiÖVÜ|  @€ @€ @€ @€ÔN@Œ©vK↠@€ @€ @€ @€Ìš€Ó¬­¸ù @€ @€ @€ @€¨€Sí–Ä  @€ @€ @€ @€˜51¦Y[qó%@€ @€ @€ @€ P;1¦Ú-‰"@€ @€ @€ @€ 0kbL³¶âæK€ @€ @€ @€ @ vbLµ[7D€ @€ @€ @€ @`ÖĘfmÅÍ— @€ @€ @€ @€@íĘj·$nˆ @€ @€ @€ @€À¬ ˆ1ÍÚŠ›/ @€ @€ @€ @€Ú ˆ1ÕnIÜ @€ @€ @€ @€Ycšµ7_ @€ @€ @€ @€µcªÝ’¸! @€ @€ @€ @€³& Æ4k+n¾ @€ @€ @€ @€j' ÆT»%qC @€ @€ @€ @€fM@ŒiÖVÜ|  @€ @€ @€ @€ÔN@Œ©vK↠@€ @€ @€ @€Ìš€Ó¬­¸ù @€ @€ @€ @€¨€Sí–Ä  @€ @€ @€ @€˜51¦Y[qó%@€ @€ @€ @€ P;1¦Ú-‰"@€ @€ @€ @€ 0kbL³¶âæK€ @€ @€ @€ @ vbLµ[7D€ @€ @€ @€ @`ÖĘfmÅÍ— @€ @€ @€ @€@íĘj·$nˆ @€ @€ @€ @€À¬ ˆ1ÍÚŠ›/ @€ @€ @€ @€Ú ˆ1ÕnIÜ @€ @€ @€ @€Ycšµ7_ @€ @€ @€ @€µcªÝ’¸! @€ @€ @€ @€³& Æ4k+n¾ @€ @€ @€ @€j' ÆT»%qC @€ @€ @€ @€fM@ŒiÖVÜ|  @€ @€ @€ @€ÔN@Œ©vK↠@€ @€ @€ @€Ìš€Ó¬­¸ù @€ @€ @€ @€¨€Sí–Ä  @€ @€ @€ @€˜51¦Y[qó%@€ @€ @€ @€ P;1¦Ú-‰"@€ @€ @€ @€ 0kbL³¶âæK€ @€ @€ @€ @ vbLµ[7D€ @€ @€ @€ @`ÖĘfmÅÍ— @€ @€ @€ @€@íĘj·$nˆ @€ @€ @€ @€À¬ ˆ1ÍÚŠ›/ @€ @€ @€ @€Ú ˆ1ÕnIÜ @€ @€ @€ @€Ycšµ7_ @€ @€ @€ @€µcªÝ’¸! @€ @€ @€ @€³& Æ4k+n¾ @€ @€ @€ @€j' ÆT»%qC @€ @€ @€ @€fM@ŒiÖVÜ|  @€ @€ @€ @€ÔN@Œ©vK↠@€ @€ @€ @€Ìš€Ó¬­¸ù @€ @€ @€ @€¨€Sí–Ä  @€ @€ @€ @€˜51¦Y[qó%@€ @€ @€ @€ P;1¦Ú-‰"@€ @€ @€ @€ 0kbL³¶âæK€ @€ @€ @€ @ vbLµ[7D€ @€ @€ @€ @`ÖĘfmÅÍ— @€ @€ @€ @€@íĘj·$nˆ @€ @€ @€ @€À¬ ˆ1ÍÚŠ›/ @€ @€ @€ @€Ú ˆ1ÕnIÜ @€ @€ @€ @€Ycšµ7_ @€ @€ @€ @€µcªÝ’¸! @€ @€ @€ @€³& Æ4k+n¾ @€ @€ @€ @€j'0*Æ4???77·}ûöt×»wïÞÒyÄóÚMÅ  @€ @€ @€ @€ PKu­ÇÎ;ÓÝE$)O"¥W†Æ˜V­Zµzõêµk×®\¹rýúõñÖx¾bÅŠø2oªå|Ý @€ @€ @€ @€õˆÐÑš5kR)%™R)=R—¥Á1¦ø½xGšMäžÒó6ÅózMÑÝ @€ @€ @€ @€ Pcè—¦tƒ‘dŠG<‰`SÏ-ÚT.½5Nm™âI„™âŒñk:— @€ @€ @€ @€–.1¤´µ\dây¾M\œa‘S´_ŠèSjåݘbw¹x%N‘'¤–~ÞI€ @€ @€ @€ @€ÀÌ D€)m ;Å¥}áÒ6qIŠGŘâÈÈ0õo$©¦þ¶N3ëkâ @€ @€ @€ @€ŒH»Àõ¿'JiŠ×‡Æ˜Rú)õaŠÇîÝ»ó½ä"%Ƥò @€ @€ @€ @€XŠ@lþüóóó‘MJ_ÎÍÍ¥ßcJý–"Ñ¥xÄ»ã­ñJ¼‡ @€ @€ @€ @€ÙH;Â¥R<"Ãx%ö’‹G$‘¢§RÈ Ž1Å[ó#óSd›ây¤ŸÒvt @€ @€ @€ @€-1¦b)‚Iñþø5Z,Å#e˜â1tS9¾ @€ @€ @€ @€˜Œ€Ódœ]… @€ @€ @€ @€¡bLŠƒ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X@Œ©âpy @€ @€ @€ @€ĘÔ @€ @€ @€ @€ ˆ1U¼.O€ @€ @€ @€ @€€“ @€ @€ @€ @€ @ b1¦ŠÀå  @€ @€ @€ @€cR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X@Œ©âpy @€ @€ @€ @€ĘÔ @€ @€ @€ @€ ˆ1U¼.O€ @€ @€ @€ @€€“ @€ @€ @€ @€ @ b1¦ŠÀå  @€ @€ @€ @€cR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X@Œ©âpy @€ @€ @€ @€ĘÔ @€ @€ @€ @€ ˆ1U¼.O€ @€ @€ @€ @€€“ @€ @€ @€ @€ @ b1¦ŠÀå  @€ @€ @€ @€cR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X@Œ©âpy @€ @€ @€ @€ĘÔ @€ @€ @€ @€ ˆ1U¼.O€ @€ @€ @€ @€€“ @€ @€ @€ @€ @ b1¦ŠÀå  @€ @€ @€ @€cR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€Š†Æ˜vîܹfÍšU«VÍÍÍå÷Ï{^©øö]ž @€ @€ @€ @€z ÌÏϯn=Ö¯_Ÿît÷îÝ)›”¿24Æ´råÊ-mÙ²%Ž_»vmOâàâ+õž¾»#@€ @€ @€ @€ @ b覴bÅŠˆ+Eî("IiŠŠ'ëÖ­+¾28Æ´}ûö-¥¤wÇéâ×|Nñ†Šççò @€ @€ @€ @€Ô^ âJùvpÑM)ñJžMŠTRtfŠI íÆ”O0:0ÅÁ)Ì”Z9åg©=‚$@€ @€ @€ @€ @ .©S„‘"€1¤x¤mââ±HŒ)¢O© SĘ¢¹Sêé”vª«ËäÜ @€ @€ @€ @€µÈCG]J»ÃE¦´»\Üû¨S™o$—º1¥ÉŸ×~ún @€ @€ @€ @€Š"z”7NJ[˥ʟ1õ´\ŠôStcJGO¦<ÒTñü\ž @€ @€ @€ @€z ä-—ÒmFû¥ØN.=_³fMŠ4 Ž1EPiŸ}ö‰ãÓ#%¡â˜x’z:¥Ýå< @€ @€ @€ @€ 0B âFÑ>)O"ÍÍÍÅ›ãË#Å#žÄÖrñÊàSü^ì—?¶oßž®OâDÑ™ = @€ @€ @€ @€ˆÄQ1‰”BKñˆ>JÑ–)?|è¦r‹^À @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Â8ÎIV­Zµ}ûöqŽt n¨¥•­ÇÚµk×­[‡‡$°sçÎ5kÖÄG#>#ëׯÇB`ùÒ÷áø5¾ÏÍÍ-ß…œ™@.ÿ×?ý °zõj8FÄ·¦T* FLF þƒ˜ÿ e2Wt•:ÄŒŠ?Ås?Õa]ÜÃ0¨X/7 'dâ§MÅ“ ô|C‹¿jðã÷¬•‡OĬ­øŒÌ7¾•õÔ¶ïoÓ¸ô±ˆóóóùû §¸ˆñ#M€¤¿7+*MãB»g=©¶ãߺã/aüÑF…4O@Œ©š5¬‰pª†¾‰W]±bÅ–Ö#~‹º’djâ"›Ó D†)>ñWùGC’i°d(¶øÞ›Š-ýùaɇz#1òªK?ø“꘎3sXüuFü¥Fª33Ë^ÍDwïÞß ¢äR±ùÏb5ËPÑUÓÿZ“_<ž¿¬è¦\–ÀP¨Øø6h @ÈÄ7s8¿¡õÿ«?¨Yð‰˜…UžÁ9Æ £¶‹ÙŽøÒ_jM]%ô¬šŸpòŒÈÿö,>uëë† H¦ôw/ñGï¨öøG1\š$ ÆTÍjÆ7—”8©æò®Ú,â¤ýMq³ÖÖlƈ¿X,þ«I|ËéÆ?# ŒHqÒü-¥êe=U7+ºÄT øqª—oºn>~âêù¡+~*‹lÓtÍÂÝŽ' Æ4ž›£ªð|#äŘzpò¥â?jú0Uõ™­öºbLÕú»ú2 ¤Ï¿­Å_Ÿ¦ÆÏËt9§]&ø‹˜ÿ)ÌO8Å¿¡-¦ôâÿôÍ|™ŠÐi+èù¸Ï~%«à¢Ë* Æ´¬¼ƒOÿ±L? ÆÏçT°»dO7&½1·Â&4Ž€àGÍ1ã ôÔ›¸À¸ŽÛžnL"{`7“oíéÆ4“&=!q6!èZ^&V?í±›éy-ïÔMÈ|¿QbL=8éÛšƒ³ü½Ã¿|Ïòê7xîé¶ÏË;ýs•ÓÔ­x¬`ü¥PZM?áäË70´äÇ¿©+o7õçêf-¯ÙŒ)Ðÿg ¿1)¶žSÏž†K8·ØcaÍ=&›ít‰›íõŸèìóÿ 8ýÅqú»c-y&ºÕ]¬g­}ç©n)\yIþk“SNú_ãÅÔ¶$þòmIEæM ð×­ ZLSYHÿ)Œ¿2oqñý-þ߃Éd5È¿A¥ ¾ý„“¯Wÿ·níjj^ÌnoüeËqyó4 ˆ1MzÕâ‡ÂH/åWÍÿ<éûp½ +¶mÐM…À ô|w?‡¿÷îñé@`¤@1P’:¸ú{m%³ÜbLË-ܰó 4lAë<´Eq§K³Vçõ*÷ÞĘÊõt¶åð|ýÂñçô¿qûgìœâRA䯖ûãYÃó‹1ÕpQÜÒÞ äÿ)L=5ãï²|ÿß{ÕÉŸ¡ø *ug‰uœümÔðŠ=›\û‚®‘[ÚÙ²7zŽ 1¦I/Sü‡³ØDïœI/@¯WÜ"$žk9ÓÄE6§qRÓ»”gŠél 3¢c–&г½—ïÃKcó®½è©:ÿ”²Wš3p°Ó ,r¦ÿ¾›vÞIOÒ¿ˆÔèþÜʲ ˆ1-­/‹€S?kú[ÊÔÈA#½¢OÏR|–å3Yï“ÿüå_õ^+w·ù Ó߯‘bL{ÀW›·öü_îûì³S¾8)¢çjS­n¤L?‘–©é\µcšô²ôÿáGŠI¯Aã®—6kHÆM΄ì•@D—R?ä½:‹ƒ ,&àûðbB~¿|bÕù |߯1Zã»ã4n~&T;ø‡ðh¹^9òÚ­ÍrÞP,wñ[ï<ˉíÜ%ø51¾Ç¢áôàô|C‹/ý=C ©:EÏŸ¿¦êÞÝ,¡ùwûø¶–ÿþ0uÓóŸ$+س‚á㦮ªÝðRzþ¾”C¼‡Àt ˆ1M×z¹[ @€ @€ @€ @€ cj࢚ @€ @€ @€ @€écš®õr· @€ @€ @€ @€(ðÿ×Q’úšê÷IEND®B`‚rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/trace/wmtrace.css0000755000177700017770000000275312633765070031631 0ustar michaelmichaelbody { margin:0px; padding:0px; } canvas#v3map { margin-top:2em; z-index: 1; } div#sizetest { width:100%; } div#zoompanel { height:2em; position:fixed; z-index:10; } div#preview { position:absolute; display:none; background:#dddddd; border:1px solid #999999; } div#preview ul { padding: 0px 0px 0px 0.5em; margin: 0px; list-style: none; } div#infopanel { z-index:20; background:#dddddd; position:fixed; top:0px; right:0px; bottom:0px; left:75%; min-width:30em; padding:5px; } div#infocontrols { position:absolute; top:0px; bottom:0px; left:-5px; width:5px; background:#999999; cursor:ew-resize; } div#infocontrols div { position:absolute; left:-15px; width:20px; height:49px; background:#999999; cursor:pointer; } div#infocontrols div.selectedtab { background:#dddddd; border-top: 1px solid #999999; border-left: 1px solid #999999; border-bottom: 1px solid #999999; } div#requesttab { top:2px; } div#responsetab { top:54px; } div#decisiontab { top:106px; } div#requestdetail, div#responsedetail, div#decisiondetail { height:100%; } div#responsedetail, div#decisiondetail { display:none; } div#infopanel ul { list-style:none; padding-left:0px; height:5em; overflow-y:scroll; } pre { height:40%; overflow:scroll; } div#responsebody, div#requestbody { height:70%; overflow-y:scroll; } rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/templates/0000755000177700017770000000000012633765070030343 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/templates/priv/0000755000177700017770000000000012633765070031323 5ustar michaelmichael././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/templates/priv/dispatch.confrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/templates/priv/dispatch.con0000644000177700017770000000006512633765070033624 0ustar michaelmichael%%-*- mode: erlang -*- {[], {{appid}}_resource, []}. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/templates/src/0000755000177700017770000000000012633765070031132 5ustar michaelmichael././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/templates/src/wmskel_sup.erlrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/templates/src/wmskel_sup.er0000644000177700017770000000417012633765070033655 0ustar michaelmichael%% @author author %% @copyright YYYY author. %% @doc Supervisor for the {{appid}} application. -module({{appid}}_sup). -author('author '). -behaviour(supervisor). %% External exports -export([start_link/0, upgrade/0]). %% supervisor callbacks -export([init/1]). %% @spec start_link() -> ServerRet %% @doc API for starting the supervisor. start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). %% @spec upgrade() -> ok %% @doc Add processes if necessary. upgrade() -> {ok, {_, Specs}} = init([]), Old = sets:from_list( [Name || {Name, _, _, _} <- supervisor:which_children(?MODULE)]), New = sets:from_list([Name || {Name, _, _, _, _, _} <- Specs]), Kill = sets:subtract(Old, New), sets:fold(fun (Id, ok) -> supervisor:terminate_child(?MODULE, Id), supervisor:delete_child(?MODULE, Id), ok end, ok, Kill), [supervisor:start_child(?MODULE, Spec) || Spec <- Specs], ok. %% @spec init([]) -> SupervisorTree %% @doc supervisor callback. init([]) -> Ip = case os:getenv("WEBMACHINE_IP") of false -> "0.0.0.0"; Any -> Any end, {ok, App} = application:get_application(?MODULE), {ok, Dispatch} = file:consult(filename:join([priv_dir(App), "dispatch.conf"])), Port = case os:getenv("WEBMACHINE_PORT") of false -> 8000; AnyPort -> AnyPort end, WebConfig = [ {ip, Ip}, {port, Port}, {log_dir, "priv/log"}, {dispatch, Dispatch}], Web = {webmachine_mochiweb, {webmachine_mochiweb, start, [WebConfig]}, permanent, 5000, worker, [mochiweb_socket_server]}, Processes = [Web], {ok, { {one_for_one, 10, 10}, Processes} }. %% %% @doc return the priv dir priv_dir(Mod) -> case code:priv_dir(Mod) of {error, bad_name} -> Ebin = filename:dirname(code:which(Mod)), filename:join(filename:dirname(Ebin), "priv"); PrivDir -> PrivDir end. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/templates/src/wmskel.erl0000644000177700017770000000242312633765070033141 0ustar michaelmichael%% @author author %% @copyright YYYY author. %% @doc {{appid}} startup code -module({{appid}}). -author('author '). -export([start/0, start_link/0, stop/0]). ensure_started(App) -> case application:start(App) of ok -> ok; {error, {already_started, App}} -> ok end. %% @spec start_link() -> {ok,Pid::pid()} %% @doc Starts the app for inclusion in a supervisor tree start_link() -> ensure_started(inets), ensure_started(crypto), ensure_started(mochiweb), application:set_env(webmachine, webmachine_logger_module, webmachine_logger), ensure_started(webmachine), {{appid}}_sup:start_link(). %% @spec start() -> ok %% @doc Start the {{appid}} server. start() -> ensure_started(inets), ensure_started(crypto), ensure_started(mochiweb), application:set_env(webmachine, webmachine_logger_module, webmachine_logger), ensure_started(webmachine), application:start({{appid}}). %% @spec stop() -> ok %% @doc Stop the {{appid}} server. stop() -> Res = application:stop({{appid}}), application:stop(webmachine), application:stop(mochiweb), application:stop(crypto), application:stop(inets), Res. ././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/templates/src/wmskel_resource.erlrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/templates/src/wmskel_resour0000644000177700017770000000052512633765070033760 0ustar michaelmichael%% @author author %% @copyright YYYY author. %% @doc Example webmachine_resource. -module({{appid}}_resource). -export([init/1, to_html/2]). -include_lib("webmachine/include/webmachine.hrl"). init([]) -> {ok, undefined}. to_html(ReqData, State) -> {"Hello, new world", ReqData, State}. ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/templates/src/wmskel_app.erlrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/templates/src/wmskel_app.er0000644000177700017770000000076612633765070033635 0ustar michaelmichael%% @author author %% @copyright YYYY author. %% @doc Callbacks for the {{appid}} application. -module({{appid}}_app). -author('author '). -behaviour(application). -export([start/2,stop/1]). %% @spec start(_Type, _StartArgs) -> ServerRet %% @doc application start callback for {{appid}}. start(_Type, _StartArgs) -> {{appid}}_sup:start_link(). %% @spec stop(_State) -> ServerRet %% @doc application stop callback for {{appid}}. stop(_State) -> ok. ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/templates/src/wmskel.app.srcrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/templates/src/wmskel.app.sr0000644000177700017770000000057412633765070033567 0ustar michaelmichael%%-*- mode: erlang -*- {application, {{appid}}, [ {description, "{{appid}}"}, {vsn, "1"}, {modules, []}, {registered, []}, {applications, [ kernel, stdlib, inets, crypto, mochiweb, webmachine ]}, {mod, { {{appid}}_app, []}}, {env, []} ]}. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/templates/README0000644000177700017770000000174412633765070031231 0ustar michaelmichaelProject Skeleton for the {{appid}} app. You should find in this directory: README : this file Makefile : simple make commands rebar : the Rebar build tool for Erlang applications rebar.config : configuration for Rebar start.sh : simple startup script for running {{appid}} /ebin /{{appid}}.app : the Erlang app specification /src /{{appid}}_app.erl : base module for the Erlang application /{{appid}}_sup.erl : OTP supervisor for the application /{{appid}}_resource.erl : a simple example Webmachine resource /priv /dispatch.conf : the Webmachine URL-dispatching table /www : a convenient place to put your static web content You probably want to do one of a couple of things at this point: 0. Build the skeleton application: $ make - or - $ ./rebar compile 1. Start up the skeleton application: $ ./start.sh 2. Change the basic application: edit src/{{appid}}_resource.erl 3. Add some new resources: edit src/YOUR_NEW_RESOURCE.erl edit priv/dispatch.conf rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/templates/Makefile0000644000177700017770000000034512633765070032005 0ustar michaelmichaelERL ?= erl APP := {{appid}} .PHONY: deps all: deps @./rebar compile deps: @./rebar get-deps clean: @./rebar clean distclean: clean @./rebar delete-deps docs: @erl -noshell -run edoc_run application '$(APP)' '"."' '[]' rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/templates/wmskel.template0000644000177700017770000000236112633765070033404 0ustar michaelmichael%%-*- mode: erlang -*- %% Basic Webmachine application skeleton %% Variables: %% appid: name of the application to build %% default = "wmskel" %% webmachine: path to webmachine from this template %% default = "../.." %% prefix: path where the application should be created %% default = "." {variables, [{appid, "wmskel"}, {webmachine, "../.."}, {prefix, "."}]}. %% main project files {template, "README", "{{prefix}}/README"}. {template, "Makefile", "{{prefix}}/Makefile"}. {template, "rebar.config", "{{prefix}}/rebar.config"}. {file, "{{webmachine}}/rebar", "{{prefix}}/rebar"}. {chmod, 8#744, "{{prefix}}/rebar"}. {template, "start.sh", "{{prefix}}/start.sh"}. {chmod, 8#744, "{{prefix}}/start.sh"}. {template, "src/wmskel.app.src", "{{prefix}}/src/{{appid}}.app.src"}. {template, "src/wmskel.erl", "{{prefix}}/src/{{appid}}.erl"}. {template, "src/wmskel_app.erl", "{{prefix}}/src/{{appid}}_app.erl"}. {template, "src/wmskel_sup.erl", "{{prefix}}/src/{{appid}}_sup.erl"}. {template, "src/wmskel_resource.erl", "{{prefix}}/src/{{appid}}_resource.erl"}. {template, "priv/dispatch.conf", "{{prefix}}/priv/dispatch.conf"}. {dir, "{{prefix}}/priv/www"}. %% dependencies {dir, "{{prefix}}/deps"}. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/templates/rebar.config0000644000177700017770000000015612633765070032627 0ustar michaelmichael%%-*- mode: erlang -*- {deps, [{webmachine, "1.10.*", {git, "git://github.com/basho/webmachine", "HEAD"}}]}. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/priv/templates/start.sh0000644000177700017770000000015412633765070032034 0ustar michaelmichael#!/bin/sh cd `dirname $0` exec erl -pa $PWD/ebin $PWD/deps/*/ebin -boot start_sasl -s reloader -s {{appid}} rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/start-dev.sh0000755000177700017770000000015512633765070027636 0ustar michaelmichael#!/bin/sh cd `dirname $0` exec erl -pa $PWD/ebin $PWD/deps/*/ebin -boot start_sasl -s reloader -s webmachine rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/0000755000177700017770000000000012633765070026154 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_error.erl0000644000177700017770000000354012633765070032175 0ustar michaelmichael%% Copyright (c) 2011-2013 Basho Technologies, Inc. All Rights Reserved. %% %% This file is provided to you under the Apache License, %% Version 2.0 (the "License"); you may not use this file %% except in compliance with the License. You may obtain %% a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, %% software distributed under the License is distributed on an %% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY %% KIND, either express or implied. See the License for the %% specific language governing permissions and limitations %% under the License. %% @doc Default HTTP error reasons for webmachine error responsesf -module(webmachine_error). -export([reason/1]). -spec reason(pos_integer()) -> string(). reason(400) -> "Bad Request"; reason(401) -> "Unauthorized"; reason(402) -> "Payment Requested"; reason(403) -> "Forbidden"; reason(404) -> "Not Found"; reason(405) -> "Method Not Allowed"; reason(406) -> "Not Acceptable"; reason(407) -> "Proxy Authentication Required"; reason(408) -> "Request Timeout"; reason(409) -> "Conflict"; reason(410) -> "Gone"; reason(411) -> "Length Required"; reason(412) -> "Precondition Failed"; reason(413) -> "Request Entity Too Large"; reason(414) -> "Request-URI Too Long"; reason(415) -> "Unsupported Media Type"; reason(416) -> "Request Range Not Satisfiable"; reason(417) -> "Expectation Failed"; reason(500) -> "Internal Server Error"; reason(501) -> "Not Implemented"; reason(502) -> "Bad Gateway"; reason(503) -> "Service Unavailable"; reason(504) -> "Gateway Timeout"; reason(505) -> "HTTP Version Not Supported"; reason(Code) when Code >= 400, Code < 500 -> "Client Error"; reason(Code) when Code >= 500 -> "Server Error". rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_decision_core.erl0000644000177700017770000006357412633765070033666 0ustar michaelmichael%% @author Justin Sheehy %% @author Andy Gross %% @author Bryan Fink %% @copyright 2007-2009 Basho Technologies %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% @doc Decision core for webmachine -module(webmachine_decision_core). -author('Justin Sheehy '). -author('Andy Gross '). -author('Bryan Fink '). -export([handle_request/2]). -export([do_log/1]). -include("webmachine_logger.hrl"). handle_request(Resource, ReqState) -> [erase(X) || X <- [decision, code, req_body, bytes_written, tmp_reqstate]], put(resource, Resource), put(reqstate, ReqState), try d(v3b13) catch error:_ -> error_response(erlang:get_stacktrace()) end. wrcall(X) -> RS0 = get(reqstate), Req = webmachine_request:new(RS0), {Response, RS1} = Req:call(X), put(reqstate, RS1), Response. resource_call(Fun) -> Resource = get(resource), {Reply, NewResource, NewRS} = Resource:do(Fun,get()), put(resource, NewResource), put(reqstate, NewRS), Reply. get_header_val(H) -> wrcall({get_req_header, H}). method() -> wrcall(method). d(DecisionID) -> put(decision, DecisionID), log_decision(DecisionID), decision(DecisionID). respond(Code) when is_integer(Code) -> respond({Code, undefined}); respond({_, _}=CodeAndPhrase) -> Resource = get(resource), EndTime = now(), respond(CodeAndPhrase, Resource, EndTime). respond({Code, _ReasonPhrase}=CodeAndPhrase, Resource, EndTime) when Code >= 400, Code < 600 -> error_response(CodeAndPhrase, Resource, EndTime); respond({304, _ReasonPhrase}=CodeAndPhrase, Resource, EndTime) -> wrcall({remove_resp_header, "Content-Type"}), case resource_call(generate_etag) of undefined -> nop; ETag -> wrcall({set_resp_header, "ETag", webmachine_util:quoted_string(ETag)}) end, case resource_call(expires) of undefined -> nop; Exp -> wrcall({set_resp_header, "Expires", webmachine_util:rfc1123_date(Exp)}) end, finish_response(CodeAndPhrase, Resource, EndTime); respond(CodeAndPhrase, Resource, EndTime) -> finish_response(CodeAndPhrase, Resource, EndTime). finish_response({Code, _}=CodeAndPhrase, Resource, EndTime) -> put(code, Code), wrcall({set_response_code, CodeAndPhrase}), resource_call(finish_request), wrcall({send_response, CodeAndPhrase}), RMod = wrcall({get_metadata, 'resource_module'}), Notes = wrcall(notes), LogData0 = wrcall(log_data), LogData = LogData0#wm_log_data{resource_module=RMod, end_time=EndTime, notes=Notes}, spawn(fun() -> do_log(LogData) end), Resource:stop(). error_response(Reason) -> error_response(500, Reason). error_response(Code, Reason) -> Resource = get(resource), EndTime = now(), error_response({Code, undefined}, Reason, Resource, EndTime). error_response({Code, _}=CodeAndPhrase, Resource, EndTime) -> error_response({Code, _}=CodeAndPhrase, webmachine_error:reason(Code), Resource, EndTime). error_response({Code, _}=CodeAndPhrase, Reason, Resource, EndTime) -> {ok, ErrorHandler} = application:get_env(webmachine, error_handler), {ErrorHTML, ReqState} = ErrorHandler:render_error( Code, {webmachine_request,get(reqstate)}, Reason), put(reqstate, ReqState), wrcall({set_resp_body, ErrorHTML}), finish_response(CodeAndPhrase, Resource, EndTime). decision_test(Test,TestVal,TrueFlow,FalseFlow) -> case Test of {error, Reason} -> error_response(Reason); {error, Reason0, Reason1} -> error_response({Reason0, Reason1}); {halt, Code} -> respond(Code); TestVal -> decision_flow(TrueFlow, Test); _ -> decision_flow(FalseFlow, Test) end. decision_test_fn({error, Reason}, _TestFn, _TrueFlow, _FalseFlow) -> error_response(Reason); decision_test_fn({error, R0, R1}, _TestFn, _TrueFlow, _FalseFlow) -> error_response({R0, R1}); decision_test_fn({halt, Code}, _TestFn, _TrueFlow, _FalseFlow) -> respond(Code); decision_test_fn(Test,TestFn,TrueFlow,FalseFlow) -> case TestFn(Test) of true -> decision_flow(TrueFlow, Test); false -> decision_flow(FalseFlow, Test) end. decision_flow(X, TestResult) when is_integer(X) -> if X >= 500 -> error_response(X, TestResult); true -> respond(X) end; decision_flow(X, _TestResult) when is_atom(X) -> d(X). do_log(LogData) -> webmachine_log:log_access(LogData). log_decision(DecisionID) -> Resource = get(resource), Resource:log_d(DecisionID). %% "Service Available" decision(v3b13) -> decision_test(resource_call(ping), pong, v3b13b, 503); decision(v3b13b) -> decision_test(resource_call(service_available), true, v3b12, 503); %% "Known method?" decision(v3b12) -> decision_test(lists:member(method(), resource_call(known_methods)), true, v3b11, 501); %% "URI too long?" decision(v3b11) -> decision_test(resource_call(uri_too_long), true, 414, v3b10); %% "Method allowed?" decision(v3b10) -> Methods = resource_call(allowed_methods), case lists:member(method(), Methods) of true -> d(v3b9); false -> wrcall({set_resp_headers, [{"Allow", string:join([atom_to_list(M) || M <- Methods], ", ")}]}), respond(405) end; %% "Content-MD5 present?" decision(v3b9) -> decision_test(get_header_val("content-md5"), undefined, v3b9b, v3b9a); %% "Content-MD5 valid?" decision(v3b9a) -> case resource_call(validate_content_checksum) of {error, Reason} -> error_response(Reason); {halt, Code} -> respond(Code); not_validated -> Checksum = base64:decode(get_header_val("content-md5")), BodyHash = compute_body_md5(), case BodyHash =:= Checksum of true -> d(v3b9b); _ -> respond(400) end; false -> respond(400); _ -> d(v3b9b) end; %% "Malformed?" decision(v3b9b) -> decision_test(resource_call(malformed_request), true, 400, v3b8); %% "Authorized?" decision(v3b8) -> case resource_call(is_authorized) of true -> d(v3b7); {error, Reason} -> error_response(Reason); {halt, Code} -> respond(Code); AuthHead -> wrcall({set_resp_header, "WWW-Authenticate", AuthHead}), respond(401) end; %% "Forbidden?" decision(v3b7) -> decision_test(resource_call(forbidden), true, 403, v3b6); %% "Okay Content-* Headers?" decision(v3b6) -> decision_test(resource_call(valid_content_headers), true, v3b5, 501); %% "Known Content-Type?" decision(v3b5) -> decision_test(resource_call(known_content_type), true, v3b4, 415); %% "Req Entity Too Large?" decision(v3b4) -> decision_test(resource_call(valid_entity_length), true, v3b3, 413); %% "OPTIONS?" decision(v3b3) -> case method() of 'OPTIONS' -> Hdrs = resource_call(options), wrcall({set_resp_headers, Hdrs}), respond(200); _ -> d(v3c3) end; %% Accept exists? decision(v3c3) -> PTypes = [Type || {Type,_Fun} <- resource_call(content_types_provided)], case get_header_val("accept") of undefined -> wrcall({set_metadata, 'content-type', hd(PTypes)}), d(v3d4); _ -> d(v3c4) end; %% Acceptable media type available? decision(v3c4) -> PTypes = [Type || {Type,_Fun} <- resource_call(content_types_provided)], AcceptHdr = get_header_val("accept"), case webmachine_util:choose_media_type(PTypes, AcceptHdr) of none -> respond(406); MType -> wrcall({set_metadata, 'content-type', MType}), d(v3d4) end; %% Accept-Language exists? decision(v3d4) -> decision_test(get_header_val("accept-language"), undefined, v3e5, v3d5); %% Acceptable Language available? %% WMACH-46 (do this as proper conneg) decision(v3d5) -> decision_test(resource_call(language_available), true, v3e5, 406); %% Accept-Charset exists? decision(v3e5) -> case get_header_val("accept-charset") of undefined -> decision_test(choose_charset("*"), none, 406, v3f6); _ -> d(v3e6) end; %% Acceptable Charset available? decision(v3e6) -> decision_test(choose_charset(get_header_val("accept-charset")), none, 406, v3f6); %% Accept-Encoding exists? % (also, set content-type header here, now that charset is chosen) decision(v3f6) -> CType = wrcall({get_metadata, 'content-type'}), CSet = case wrcall({get_metadata, 'chosen-charset'}) of undefined -> ""; CS -> "; charset=" ++ CS end, wrcall({set_resp_header, "Content-Type", CType ++ CSet}), case get_header_val("accept-encoding") of undefined -> decision_test(choose_encoding("identity;q=1.0,*;q=0.5"), none, 406, v3g7); _ -> d(v3f7) end; %% Acceptable encoding available? decision(v3f7) -> decision_test(choose_encoding(get_header_val("accept-encoding")), none, 406, v3g7); %% "Resource exists?" decision(v3g7) -> % this is the first place after all conneg, so set Vary here case variances() of [] -> nop; Variances -> wrcall({set_resp_header, "Vary", string:join(Variances, ", ")}) end, decision_test(resource_call(resource_exists), true, v3g8, v3h7); %% "If-Match exists?" decision(v3g8) -> decision_test(get_header_val("if-match"), undefined, v3h10, v3g9); %% "If-Match: * exists" decision(v3g9) -> decision_test(get_header_val("if-match"), "*", v3h10, v3g11); %% "ETag in If-Match" decision(v3g11) -> ETags = webmachine_util:split_quoted_strings(get_header_val("if-match")), decision_test_fn(resource_call(generate_etag), fun(ETag) -> lists:member(ETag, ETags) end, v3h10, 412); %% "If-Match exists" %% (note: need to reflect this change at in next version of diagram) decision(v3h7) -> decision_test(get_header_val("if-match"), undefined, v3i7, 412); %% "If-unmodified-since exists?" decision(v3h10) -> decision_test(get_header_val("if-unmodified-since"),undefined,v3i12,v3h11); %% "I-UM-S is valid date?" decision(v3h11) -> IUMSDate = get_header_val("if-unmodified-since"), decision_test(webmachine_util:convert_request_date(IUMSDate), bad_date, v3i12, v3h12); %% "Last-Modified > I-UM-S?" decision(v3h12) -> ReqDate = get_header_val("if-unmodified-since"), ReqErlDate = webmachine_util:convert_request_date(ReqDate), ResErlDate = resource_call(last_modified), decision_test(ResErlDate > ReqErlDate, true, 412, v3i12); %% "Moved permanently? (apply PUT to different URI)" decision(v3i4) -> case resource_call(moved_permanently) of {true, MovedURI} -> wrcall({set_resp_header, "Location", MovedURI}), respond(301); false -> d(v3p3); {error, Reason} -> error_response(Reason); {halt, Code} -> respond(Code) end; %% PUT? decision(v3i7) -> decision_test(method(), 'PUT', v3i4, v3k7); %% "If-none-match exists?" decision(v3i12) -> decision_test(get_header_val("if-none-match"), undefined, v3l13, v3i13); %% "If-None-Match: * exists?" decision(v3i13) -> decision_test(get_header_val("if-none-match"), "*", v3j18, v3k13); %% GET or HEAD? decision(v3j18) -> decision_test(lists:member(method(),['GET','HEAD']), true, 304, 412); %% "Moved permanently?" decision(v3k5) -> case resource_call(moved_permanently) of {true, MovedURI} -> wrcall({set_resp_header, "Location", MovedURI}), respond(301); false -> d(v3l5); {error, Reason} -> error_response(Reason); {halt, Code} -> respond(Code) end; %% "Previously existed?" decision(v3k7) -> decision_test(resource_call(previously_existed), true, v3k5, v3l7); %% "Etag in if-none-match?" decision(v3k13) -> ETags = webmachine_util:split_quoted_strings(get_header_val("if-none-match")), decision_test_fn(resource_call(generate_etag), %% Membership test is a little counter-intuitive here; if the %% provided ETag is a member, we follow the error case out %% via v3j18. fun(ETag) -> lists:member(ETag, ETags) end, v3j18, v3l13); %% "Moved temporarily?" decision(v3l5) -> case resource_call(moved_temporarily) of {true, MovedURI} -> wrcall({set_resp_header, "Location", MovedURI}), respond(307); false -> d(v3m5); {error, Reason} -> error_response(Reason); {halt, Code} -> respond(Code) end; %% "POST?" decision(v3l7) -> decision_test(method(), 'POST', v3m7, 404); %% "IMS exists?" decision(v3l13) -> decision_test(get_header_val("if-modified-since"), undefined, v3m16, v3l14); %% "IMS is valid date?" decision(v3l14) -> IMSDate = get_header_val("if-modified-since"), decision_test(webmachine_util:convert_request_date(IMSDate), bad_date, v3m16, v3l15); %% "IMS > Now?" decision(v3l15) -> NowDateTime = calendar:universal_time(), ReqDate = get_header_val("if-modified-since"), ReqErlDate = webmachine_util:convert_request_date(ReqDate), decision_test(ReqErlDate > NowDateTime, true, v3m16, v3l17); %% "Last-Modified > IMS?" decision(v3l17) -> ReqDate = get_header_val("if-modified-since"), ReqErlDate = webmachine_util:convert_request_date(ReqDate), ResErlDate = resource_call(last_modified), decision_test(ResErlDate =:= undefined orelse ResErlDate > ReqErlDate, true, v3m16, 304); %% "POST?" decision(v3m5) -> decision_test(method(), 'POST', v3n5, 410); %% "Server allows POST to missing resource?" decision(v3m7) -> decision_test(resource_call(allow_missing_post), true, v3n11, 404); %% "DELETE?" decision(v3m16) -> decision_test(method(), 'DELETE', v3m20, v3n16); %% DELETE enacted immediately? %% Also where DELETE is forced. decision(v3m20) -> Result = resource_call(delete_resource), %% DELETE may have body and TCP connection will be closed unless body is read. %% See mochiweb_request:should_close. maybe_flush_body_stream(), decision_test(Result, true, v3m20b, 500); decision(v3m20b) -> decision_test(resource_call(delete_completed), true, v3o20, 202); %% "Server allows POST to missing resource?" decision(v3n5) -> decision_test(resource_call(allow_missing_post), true, v3n11, 410); %% "Redirect?" decision(v3n11) -> Stage1 = case resource_call(post_is_create) of true -> case resource_call(create_path) of undefined -> error_response("post_is_create w/o create_path"); NewPath -> case is_list(NewPath) of false -> error_response({"create_path not a string", NewPath}); true -> BaseUri = case resource_call(base_uri) of undefined -> wrcall(base_uri); Any -> case [lists:last(Any)] of "/" -> lists:sublist(Any, erlang:length(Any) - 1); _ -> Any end end, FullPath = filename:join(["/", wrcall(path), NewPath]), wrcall({set_disp_path, NewPath}), case wrcall({get_resp_header, "Location"}) of undefined -> wrcall({set_resp_header, "Location", BaseUri ++ FullPath}); _ -> ok end, Res = accept_helper(), case Res of {respond, Code} -> respond(Code); {halt, Code} -> respond(Code); {error, _,_} -> error_response(Res); {error, _} -> error_response(Res); _ -> stage1_ok end end end; _ -> case resource_call(process_post) of true -> encode_body_if_set(), stage1_ok; {halt, Code} -> respond(Code); Err -> error_response(Err) end end, case Stage1 of stage1_ok -> case wrcall(resp_redirect) of true -> case wrcall({get_resp_header, "Location"}) of undefined -> Reason = "Response had do_redirect but no Location", error_response(500, Reason); _ -> respond(303) end; _ -> d(v3p11) end; _ -> nop end; %% "POST?" decision(v3n16) -> decision_test(method(), 'POST', v3n11, v3o16); %% Conflict? decision(v3o14) -> case resource_call(is_conflict) of true -> respond(409); _ -> Res = accept_helper(), case Res of {respond, Code} -> respond(Code); {halt, Code} -> respond(Code); {error, _,_} -> error_response(Res); {error, _} -> error_response(Res); _ -> d(v3p11) end end; %% "PUT?" decision(v3o16) -> decision_test(method(), 'PUT', v3o14, v3o18); %% Multiple representations? % (also where body generation for GET and HEAD is done) decision(v3o18) -> BuildBody = case method() of 'GET' -> true; 'HEAD' -> true; _ -> false end, FinalBody = case BuildBody of true -> case resource_call(generate_etag) of undefined -> nop; ETag -> wrcall({set_resp_header, "ETag", webmachine_util:quoted_string(ETag)}) end, CT = wrcall({get_metadata, 'content-type'}), case resource_call(last_modified) of undefined -> nop; LM -> wrcall({set_resp_header, "Last-Modified", webmachine_util:rfc1123_date(LM)}) end, case resource_call(expires) of undefined -> nop; Exp -> wrcall({set_resp_header, "Expires", webmachine_util:rfc1123_date(Exp)}) end, F = hd([Fun || {Type,Fun} <- resource_call(content_types_provided), CT =:= webmachine_util:format_content_type(Type)]), resource_call(F); false -> nop end, case FinalBody of {error, _} -> error_response(FinalBody); {error, _,_} -> error_response(FinalBody); {halt, Code} -> respond(Code); nop -> d(v3o18b); _ -> wrcall({set_resp_body, encode_body(FinalBody)}), d(v3o18b) end; decision(v3o18b) -> decision_test(resource_call(multiple_choices), true, 300, 200); %% Response includes an entity? decision(v3o20) -> decision_test(wrcall(has_resp_body), true, v3o18, 204); %% Conflict? decision(v3p3) -> case resource_call(is_conflict) of true -> respond(409); _ -> Res = accept_helper(), case Res of {respond, Code} -> respond(Code); {halt, Code} -> respond(Code); {error, _,_} -> error_response(Res); {error, _} -> error_response(Res); _ -> d(v3p11) end end; %% New resource? (at this point boils down to "has location header") decision(v3p11) -> case wrcall({get_resp_header, "Location"}) of undefined -> d(v3o20); _ -> respond(201) end. accept_helper() -> accept_helper(get_header_val("Content-Type")). accept_helper(undefined) -> accept_helper("application/octet-stream"); accept_helper([]) -> accept_helper("application/octet-stream"); accept_helper(CT) -> {MT, MParams} = webmachine_util:media_type_to_detail(CT), wrcall({set_metadata, 'mediaparams', MParams}), case [Fun || {Type,Fun} <- resource_call(content_types_accepted), MT =:= Type] of [] -> {respond,415}; AcceptedContentList -> F = hd(AcceptedContentList), case resource_call(F) of true -> encode_body_if_set(), true; Result -> Result end end. encode_body_if_set() -> case wrcall(has_resp_body) of true -> Body = wrcall(resp_body), wrcall({set_resp_body, encode_body(Body)}), true; _ -> false end. encode_body(Body) -> ChosenCSet = wrcall({get_metadata, 'chosen-charset'}), Charsetter = case resource_call(charsets_provided) of no_charset -> fun(X) -> X end; CP -> hd([Fun || {CSet,Fun} <- CP, ChosenCSet =:= CSet]) end, ChosenEnc = wrcall({get_metadata, 'content-encoding'}), Encoder = hd([Fun || {Enc,Fun} <- resource_call(encodings_provided), ChosenEnc =:= Enc]), case Body of {stream, StreamBody} -> {stream, make_encoder_stream(Encoder, Charsetter, StreamBody)}; {known_length_stream, 0, _StreamBody} -> {known_length_stream, 0, empty_stream()}; {known_length_stream, Size, StreamBody} -> case method() of 'HEAD' -> {known_length_stream, Size, empty_stream()}; _ -> {known_length_stream, Size, make_encoder_stream(Encoder, Charsetter, StreamBody)} end; {stream, Size, Fun} -> {stream, Size, make_size_encoder_stream(Encoder, Charsetter, Fun)}; {writer, BodyFun} -> {writer, {Encoder, Charsetter, BodyFun}}; _ -> Encoder(Charsetter(iolist_to_binary(Body))) end. %% @private empty_stream() -> {<<>>, fun() -> {<<>>, done} end}. make_encoder_stream(Encoder, Charsetter, {Body, done}) -> {Encoder(Charsetter(Body)), done}; make_encoder_stream(Encoder, Charsetter, {Body, Next}) -> {Encoder(Charsetter(Body)), fun() -> make_encoder_stream(Encoder, Charsetter, Next()) end}. make_size_encoder_stream(Encoder, Charsetter, Fun) -> fun(Start, End) -> make_encoder_stream(Encoder, Charsetter, Fun(Start, End)) end. choose_encoding(AccEncHdr) -> Encs = [Enc || {Enc,_Fun} <- resource_call(encodings_provided)], case webmachine_util:choose_encoding(Encs, AccEncHdr) of none -> none; ChosenEnc -> case ChosenEnc of "identity" -> nop; _ -> wrcall({set_resp_header, "Content-Encoding",ChosenEnc}) end, wrcall({set_metadata, 'content-encoding',ChosenEnc}), ChosenEnc end. choose_charset(AccCharHdr) -> case resource_call(charsets_provided) of no_charset -> no_charset; CL -> CSets = [CSet || {CSet,_Fun} <- CL], case webmachine_util:choose_charset(CSets, AccCharHdr) of none -> none; Charset -> wrcall({set_metadata, 'chosen-charset',Charset}), Charset end end. variances() -> Accept = case length(resource_call(content_types_provided)) of 1 -> []; 0 -> []; _ -> ["Accept"] end, AcceptEncoding = case length(resource_call(encodings_provided)) of 1 -> []; 0 -> []; _ -> ["Accept-Encoding"] end, AcceptCharset = case resource_call(charsets_provided) of no_charset -> []; CP -> case length(CP) of 1 -> []; 0 -> []; _ -> ["Accept-Charset"] end end, Accept ++ AcceptEncoding ++ AcceptCharset ++ resource_call(variances). md5(Bin) -> erlang:md5(Bin). md5_init() -> erlang:md5_init(). md5_update(Ctx, Bin) -> erlang:md5_update(Ctx, Bin). md5_final(Ctx) -> erlang:md5_final(Ctx). compute_body_md5() -> case wrcall({req_body, 52428800}) of stream_conflict -> compute_body_md5_stream(); Body -> md5(Body) end. compute_body_md5_stream() -> MD5Ctx = md5_init(), compute_body_md5_stream(MD5Ctx, wrcall({stream_req_body, 8192}), <<>>). compute_body_md5_stream(MD5, {Hunk, done}, Body) -> %% Save the body so it can be retrieved later put(reqstate, wrq:set_resp_body(Body, get(reqstate))), md5_final(md5_update(MD5, Hunk)); compute_body_md5_stream(MD5, {Hunk, Next}, Body) -> compute_body_md5_stream(md5_update(MD5, Hunk), Next(), <>). maybe_flush_body_stream() -> maybe_flush_body_stream(wrcall({stream_req_body, 8192})). maybe_flush_body_stream(stream_conflict) -> ok; maybe_flush_body_stream({_Hunk, done}) -> ok; maybe_flush_body_stream({_Hunk, Next}) -> maybe_flush_body_stream(Next()). rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_log_handler.erl0000644000177700017770000000746112633765070033330 0ustar michaelmichael%% Copyright (c) 2011-2013 Basho Technologies, Inc. All Rights Reserved. %% %% This file is provided to you under the Apache License, %% Version 2.0 (the "License"); you may not use this file %% except in compliance with the License. You may obtain %% a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, %% software distributed under the License is distributed on an %% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY %% KIND, either express or implied. See the License for the %% specific language governing permissions and limitations %% under the License. %% @doc Default log handler for webmachine -module(webmachine_log_handler). -behaviour(gen_event). %% gen_event callbacks -export([init/1, handle_call/2, handle_event/2, handle_info/2, terminate/2, code_change/3]). -include("webmachine_logger.hrl"). -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -endif. -record(state, {hourstamp, filename, handle}). -define(FILENAME, "access.log"). %% =================================================================== %% gen_event callbacks %% =================================================================== %% @private init([BaseDir]) -> webmachine_log:defer_refresh(?MODULE), FileName = filename:join(BaseDir, ?FILENAME), {Handle, DateHour} = webmachine_log:log_open(FileName), {ok, #state{filename=FileName, handle=Handle, hourstamp=DateHour}}. %% @private handle_call({_Label, MRef, get_modules}, State) -> {ok, {MRef, [?MODULE]}, State}; handle_call({refresh, Time}, State) -> {ok, ok, webmachine_log:maybe_rotate(?MODULE, Time, State)}; handle_call(_Request, State) -> {ok, ok, State}. %% @private handle_event({log_access, LogData}, State) -> NewState = webmachine_log:maybe_rotate(?MODULE, os:timestamp(), State), Msg = format_req(LogData), webmachine_log:log_write(NewState#state.handle, Msg), {ok, NewState}; handle_event(_Event, State) -> {ok, State}. %% @private handle_info(_Info, State) -> {ok, State}. %% @private terminate(_Reason, _State) -> ok. %% @private code_change(_OldVsn, State, _Extra) -> {ok, State}. %% =================================================================== %% Internal functions %% =================================================================== format_req(#wm_log_data{method=Method, headers=Headers, peer=Peer, path=Path, version=Version, response_code=ResponseCode, response_length=ResponseLength}) -> User = "-", Time = webmachine_log:fmtnow(), Status = case ResponseCode of {Code, _ReasonPhrase} when is_integer(Code) -> integer_to_list(Code); _ when is_integer(ResponseCode) -> integer_to_list(ResponseCode); _ -> ResponseCode end, Length = integer_to_list(ResponseLength), Referer = case mochiweb_headers:get_value("Referer", Headers) of undefined -> ""; R -> R end, UserAgent = case mochiweb_headers:get_value("User-Agent", Headers) of undefined -> ""; U -> U end, fmt_alog(Time, Peer, User, atom_to_list(Method), Path, Version, Status, Length, Referer, UserAgent). fmt_alog(Time, Ip, User, Method, Path, {VM,Vm}, Status, Length, Referrer, UserAgent) -> [webmachine_log:fmt_ip(Ip), " - ", User, [$\s], Time, [$\s, $"], Method, " ", Path, " HTTP/", integer_to_list(VM), ".", integer_to_list(Vm), [$",$\s], Status, [$\s], Length, [$\s,$"], Referrer, [$",$\s,$"], UserAgent, [$",$\n]]. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_router.erl0000644000177700017770000002157212633765070032371 0ustar michaelmichael%% @author Kevin A. Smith %% @copyright 2007-2010 Basho Technologies %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% @doc Module to add and remove dynamic routes to webmachine's routing %% table. Dynamic routes are not persistent between executions of %% a webmachine application. They will need to be added to the %% the table each time webmachine restarts. -module(webmachine_router). -behaviour(gen_server). %% API -export([start_link/0, add_route/1, add_route/2, remove_route/1, remove_route/2, remove_resource/1, remove_resource/2, get_routes/0, get_routes/1, init_routes/1, init_routes/2 ]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). %% @type hostmatchterm() = {hostmatch(), [pathmatchterm()]}. % The dispatch configuration contains a list of these terms, and the % first one whose host and one pathmatchterm match is used. %% @type pathmatchterm() = {[pathterm()], matchmod(), matchopts()}. % The dispatch configuration contains a list of these terms, and the % first one whose list of pathterms matches the input path is used. %% @type pathterm() = '*' | string() | atom(). % A list of pathterms is matched against a '/'-separated input path. % The '*' pathterm matches all remaining tokens. % A string pathterm will match a token of exactly the same string. % Any atom pathterm other than '*' will match any token and will % create a binding in the result if a complete match occurs. %% @type matchmod() = atom(). % This atom, if present in a successful matchterm, will appear in % the resulting dispterm. In Webmachine this is used to name the % resource module that will handle the matching request. %% @type matchopts() = [term()]. % This term, if present in a successful matchterm, will appear in % the resulting dispterm. In Webmachine this is used to provide % arguments to the resource module handling the matching request. -define(SERVER, ?MODULE). %% @spec add_route(hostmatchterm() | pathmatchterm()) -> ok %% @doc Adds a route to webmachine's route table. The route should %% be the format documented here: %% http://bitbucket.org/justin/webmachine/wiki/DispatchConfiguration add_route(Route) -> add_route(default, Route). add_route(Name, Route) -> gen_server:call(?SERVER, {add_route, Name, Route}, infinity). %% @spec remove_route(hostmatchterm() | pathmatchterm()) -> ok %% @doc Removes a route from webamchine's route table. The route %% route must be properly formatted %% @see add_route/2 remove_route(Route) -> remove_route(default, Route). remove_route(Name, Route) -> gen_server:call(?SERVER, {remove_route, Name, Route}, infinity). %% @spec remove_resource(atom()) -> ok %% @doc Removes all routes for a specific resource module. remove_resource(Resource) when is_atom(Resource) -> remove_resource(default, Resource). remove_resource(Name, Resource) when is_atom(Resource) -> gen_server:call(?SERVER, {remove_resource, Name, Resource}, infinity). %% @spec get_routes() -> [{[], res, []}] %% @doc Retrieve a list of routes and resources set in webmachine's %% route table. get_routes() -> get_routes(default). get_routes(Name) -> get_dispatch_list(Name). %% @spec init_routes() -> ok %% @doc Set the default routes, unless the routing table isn't empty. init_routes(DefaultRoutes) -> init_routes(default, DefaultRoutes). init_routes(Name, DefaultRoutes) -> gen_server:call(?SERVER, {init_routes, Name, DefaultRoutes}, infinity). %% @spec start_link() -> {ok, pid()} | {error, any()} %% @doc Starts the webmachine_router gen_server. start_link() -> %% We expect to only be called from webmachine_sup %% %% Set up the ETS configuration table. try ets:new(?MODULE, [named_table, public, set, {keypos, 1}, {read_concurrency, true}]) of _Result -> ok catch error:badarg -> %% The table already exists, which is fine. The webmachine_router %% probably crashed and this is a restart. ok end, gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). %% @private init([]) -> {ok, undefined}. %% @private handle_call({remove_resource, Name, Resource}, _From, State) -> DL = filter_by_resource(Resource, get_dispatch_list(Name)), {reply, set_dispatch_list(Name, DL), State}; handle_call({remove_route, Name, Route}, _From, State) -> DL = [D || D <- get_dispatch_list(Name), D /= Route], {reply, set_dispatch_list(Name, DL), State}; handle_call({add_route, Name, Route}, _From, State) -> DL = [Route|[D || D <- get_dispatch_list(Name), D /= Route]], {reply, set_dispatch_list(Name, DL), State}; handle_call({init_routes, Name, DefaultRoutes}, _From, State) -> %% if the table lacks a dispatch_list row, set it ets:insert_new(?MODULE, {Name, DefaultRoutes}), {reply, ok, State}; handle_call(_Request, _From, State) -> {reply, ignore, State}. %% @private handle_cast(_Msg, State) -> {noreply, State}. %% @private handle_info(_Info, State) -> {noreply, State}. %% @private terminate(_Reason, _State) -> ok. %% @private code_change(_OldVsn, State, _Extra) -> {ok, State}. %% Internal functions %% @doc Remove any dispatch rule that directs requests to `Resource' filter_by_resource(Resource, Dispatch) -> lists:foldr(filter_by_resource(Resource), [], Dispatch). filter_by_resource(Resource) -> fun({_, R, _}, Acc) when R == Resource -> % basic dispatch Acc; ({_, _, R, _}, Acc) when R == Resource -> % guarded dispatch Acc; ({Host, Disp}, Acc) -> % host-based dispatch [{Host, filter_by_resource(Resource, Disp)}|Acc]; (Other, Acc) -> % dispatch not mentioning this resource [Other|Acc] end. get_dispatch_list(Name) -> case ets:lookup(?MODULE, Name) of [{Name, Dispatch}] -> Dispatch; [] -> [] end. set_dispatch_list(Name, DispatchList) -> true = ets:insert(?MODULE, {Name, DispatchList}), ok. %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). add_remove_route_test() -> {ok, Pid} = webmachine_router:start_link(), unlink(Pid), PathSpec = {["foo"], foo, []}, webmachine_router:add_route(PathSpec), [PathSpec] = get_routes(), webmachine_router:remove_route(PathSpec), [] = get_routes(), exit(Pid, kill). add_remove_resource_test() -> {ok, Pid} = webmachine_router:start_link(), unlink(Pid), PathSpec1 = {["foo"], foo, []}, PathSpec2 = {["bar"], foo, []}, PathSpec3 = {["baz"], bar, []}, PathSpec4 = {["foo"], fun(_) -> true end, foo, []}, PathSpec5 = {["foo"], {webmachine_router, test_guard}, foo, []}, webmachine_router:add_route(PathSpec1), webmachine_router:add_route(PathSpec2), webmachine_router:add_route(PathSpec3), webmachine_router:remove_resource(foo), [PathSpec3] = get_routes(), webmachine_router:add_route(PathSpec4), webmachine_router:remove_resource(foo), [PathSpec3] = get_routes(), webmachine_router:add_route(PathSpec5), webmachine_router:remove_resource(foo), [PathSpec3] = get_routes(), webmachine_router:remove_route(PathSpec3), [begin PathSpec = {"localhost", [HostPath]}, webmachine_router:add_route(PathSpec), webmachine_router:remove_resource(foo), [{"localhost", []}] = get_routes(), webmachine_router:remove_route({"localhost", []}) end || HostPath <- [PathSpec1, PathSpec4, PathSpec5]], exit(Pid, kill). no_dupe_path_test() -> {ok, Pid} = webmachine_router:start_link(), unlink(Pid), PathSpec = {["foo"], foo, []}, webmachine_router:add_route(PathSpec), webmachine_router:add_route(PathSpec), [PathSpec] = get_routes(), exit(Pid, kill). supervisor_restart_keeps_routes_test() -> {ok, Pid} = webmachine_router:start_link(), unlink(Pid), PathSpec = {["foo"], foo, []}, webmachine_router:add_route(PathSpec), [PathSpec] = get_routes(), OldRouter = whereis(webmachine_router), exit(whereis(webmachine_router), kill), timer:sleep(100), NewRouter = whereis(webmachine_router), ?assert(OldRouter /= NewRouter), [PathSpec] = get_routes(), exit(Pid, kill). -endif. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_log.erl0000644000177700017770000001646312633765070031635 0ustar michaelmichael%% Copyright (c) 2011-2012 Basho Technologies, Inc. All Rights Reserved. %% %% This file is provided to you under the Apache License, %% Version 2.0 (the "License"); you may not use this file %% except in compliance with the License. You may obtain %% a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, %% software distributed under the License is distributed on an %% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY %% KIND, either express or implied. See the License for the %% specific language governing permissions and limitations %% under the License. %% @doc Helper functions for webmachine's default log handlers -module(webmachine_log). -include("webmachine_logger.hrl"). -export([add_handler/2, call/2, call/3, datehour/0, datehour/1, defer_refresh/1, delete_handler/1, fix_log/2, fmt_ip/1, fmtnow/0, log_access/1, log_close/3, log_open/1, log_open/2, log_write/2, maybe_rotate/3, month/1, refresh/2, suffix/1, zeropad/2, zone/0]). -record(state, {hourstamp :: non_neg_integer(), filename :: string(), handle :: file:io_device()}). %% @doc Add a handler to receive log events -type add_handler_result() :: ok | {'EXIT', term()} | term(). -spec add_handler(atom() | {atom(), term()}, term()) -> add_handler_result(). add_handler(Mod, Args) -> gen_event:add_handler(?EVENT_LOGGER, Mod, Args). %% @doc Make a synchronous call directly to a specific event handler %% module -type error() :: {error, bad_module} | {'EXIT', term()} | term(). -spec call(atom(), term()) -> term() | error(). call(Mod, Msg) -> gen_event:call(?EVENT_LOGGER, Mod, Msg). %% @doc Make a synchronous call directly to a specific event handler %% module -spec call(atom(), term(), timeout()) -> term() | error(). call(Mod, Msg, Timeout) -> gen_event:call(?EVENT_LOGGER, Mod, Msg, Timeout). %% @doc Return a four-tuple containing year, month, day, and hour %% of the current time. -type datehour() :: {calendar:year(), calendar:month(), calendar:day(), calendar:hour()}. -spec datehour() -> datehour(). datehour() -> datehour(os:timestamp()). %% @doc Return a four-tuple containing year, month, day, and hour %% of the specified time. -spec datehour(erlang:timestamp()) -> datehour(). datehour(TS) -> {{Y, M, D}, {H, _, _}} = calendar:now_to_universal_time(TS), {Y, M, D, H}. %% @doc Defer the refresh of a log file. -spec defer_refresh(atom()) -> {ok, timer:tref()} | {error, term()}. defer_refresh(Mod) -> {_, {_, M, S}} = calendar:universal_time(), Time = 1000 * (3600 - ((M * 60) + S)), timer:apply_after(Time, ?MODULE, refresh, [Mod, os:timestamp()]). %% @doc Remove a log handler -type delete_handler_result() :: term() | {error, module_not_found} | {'EXIT', term()}. -spec delete_handler(atom() | {atom(), term()}) -> delete_handler_result(). delete_handler(Mod) -> gen_event:delete_handler(?EVENT_LOGGER, Mod, []). %% Seek backwards to the last valid log entry -spec fix_log(file:io_device(), non_neg_integer()) -> ok. fix_log(_FD, 0) -> ok; fix_log(FD, 1) -> {ok, 0} = file:position(FD, 0), ok; fix_log(FD, Location) -> case file:pread(FD, Location - 1, 1) of {ok, [$\n | _]} -> ok; {ok, _} -> fix_log(FD, Location - 1) end. %% @doc Format an IP address or host name -spec fmt_ip(undefined | string() | inet:ip4_address() | inet:ip6_address()) -> string(). fmt_ip(IP) when is_tuple(IP) -> inet_parse:ntoa(IP); fmt_ip(undefined) -> "0.0.0.0"; fmt_ip(HostName) -> HostName. %% @doc Format the current time into a string -spec fmtnow() -> string(). fmtnow() -> {{Year, Month, Date}, {Hour, Min, Sec}} = calendar:local_time(), io_lib:format("[~2..0w/~s/~4..0w:~2..0w:~2..0w:~2..0w ~s]", [Date,month(Month),Year, Hour, Min, Sec, zone()]). %% @doc Notify registered log event handler of an access event. -spec log_access(wm_log_data()) -> ok. log_access(#wm_log_data{}=LogData) -> gen_event:sync_notify(?EVENT_LOGGER, {log_access, LogData}). %% @doc Close a log file. -spec log_close(atom(), string(), file:io_device()) -> ok | {error, term()}. log_close(Mod, Name, FD) -> error_logger:info_msg("~p: closing log file: ~p~n", [Mod, Name]), file:close(FD). %% @doc Open a new log file for writing -spec log_open(string()) -> {file:io_device(), non_neg_integer()}. log_open(FileName) -> DateHour = datehour(), {log_open(FileName, DateHour), DateHour}. %% @doc Open a new log file for writing -spec log_open(string(), non_neg_integer()) -> file:io_device(). log_open(FileName, DateHour) -> LogName = FileName ++ suffix(DateHour), error_logger:info_msg("opening log file: ~p~n", [LogName]), filelib:ensure_dir(LogName), {ok, FD} = file:open(LogName, [read, write, raw]), {ok, Location} = file:position(FD, eof), fix_log(FD, Location), file:truncate(FD), FD. -spec log_write(file:io_device(), iolist()) -> ok | {error, term()}. log_write(FD, IoData) -> file:write(FD, lists:flatten(IoData)). %% @doc Rotate a log file if the hour it represents %% has passed. -spec maybe_rotate(atom(), erlang:timestamp(), #state{}) -> #state{}. maybe_rotate(Mod, Time, State) -> ThisHour = datehour(Time), if ThisHour == State#state.hourstamp -> State; true -> defer_refresh(Mod), log_close(Mod, State#state.filename, State#state.handle), Handle = log_open(State#state.filename, ThisHour), State#state{hourstamp=ThisHour, handle=Handle} end. %% @doc Convert numeric month value to the abbreviation -spec month(1..12) -> string(). month(1) -> "Jan"; month(2) -> "Feb"; month(3) -> "Mar"; month(4) -> "Apr"; month(5) -> "May"; month(6) -> "Jun"; month(7) -> "Jul"; month(8) -> "Aug"; month(9) -> "Sep"; month(10) -> "Oct"; month(11) -> "Nov"; month(12) -> "Dec". %% @doc Make a synchronous call to instruct a log handler to refresh %% itself. -spec refresh(atom(), erlang:timestamp()) -> ok | {error, term()}. refresh(Mod, Time) -> call(Mod, {refresh, Time}, infinity). -spec suffix(datehour()) -> string(). suffix({Y, M, D, H}) -> YS = zeropad(Y, 4), MS = zeropad(M, 2), DS = zeropad(D, 2), HS = zeropad(H, 2), lists:flatten([$., YS, $_, MS, $_, DS, $_, HS]). -spec zeropad(integer(), integer()) -> string(). zeropad(Num, MinLength) -> NumStr = integer_to_list(Num), zeropad_str(NumStr, MinLength - length(NumStr)). -spec zeropad_str(string(), integer()) -> string(). zeropad_str(NumStr, Zeros) when Zeros > 0 -> zeropad_str([$0 | NumStr], Zeros - 1); zeropad_str(NumStr, _) -> NumStr. -spec zone() -> string(). zone() -> Time = erlang:universaltime(), LocalTime = calendar:universal_time_to_local_time(Time), DiffSecs = calendar:datetime_to_gregorian_seconds(LocalTime) - calendar:datetime_to_gregorian_seconds(Time), zone((DiffSecs/3600)*100). %% Ugly reformatting code to get times like +0000 and -1300 -spec zone(integer()) -> string(). zone(Val) when Val < 0 -> io_lib:format("-~4..0w", [trunc(abs(Val))]); zone(Val) when Val >= 0 -> io_lib:format("+~4..0w", [trunc(abs(Val))]). rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_request.erl0000644000177700017770000011474712633765070032550 0ustar michaelmichael%% @author Justin Sheehy %% @author Andy Gross %% @copyright 2007-2012 Basho Technologies %% Based on mochiweb_request.erl, which is Copyright 2007 Mochi Media, Inc. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% @doc Webmachine HTTP Request Abstraction. The functions in this module %% can be invoked using either parameterized module syntax or regular %% invocation syntax. Since the Ericsson OTP team is removing the %% parameterized module syntax in version R16, we encourage you to write %% your applications using regular function syntax. %% %% To use parameterized module syntax, you create an instance and then %% invoke functions on that instance, like this: %% %%
    
    %%   Req = webmachine_request:new(ReqState),
    %%   Result = Req:some_fun(Args),
    %% 
    %% %% where `ReqState' is an instance of a `#wm_reqstate' record. The runtime %% then ensures the `ReqState' variable is implicitly passed to each %% function invoked through the `Req' instance. %% %% To call functions using regular syntax, simply explicitly pass the %% `ReqState' variable yourself; note there's no need to call %% `webmachine_request:new/1' to perform regular invocations. -module(webmachine_request). -author('Justin Sheehy '). -author('Andy Gross '). -export([get_peer/1]). % used in initialization -export([call/2]). % internal switching interface, used by wrcall % actual interface for resource functions -export([ new/1, trim_state/1, get_reqdata/1, set_reqdata/2, socket/1, method/1, version/1, disp_path/1, path/1, raw_path/1, get_req_header/2, req_headers/1, req_body/2, stream_req_body/2, headers/1, resp_headers/1, out_headers/1, get_out_header/2, has_out_header/2, peer/1, get_header_value/2, add_response_header/3, add_response_headers/2, remove_response_header/2, merge_response_headers/2, append_to_response_body/2, send_response/2, response_code/1, set_response_code/2, set_resp_body/2, response_body/1, has_response_body/1, do_redirect/1, resp_redirect/1, set_metadata/3, get_metadata/2, get_path_info/1, get_path_info/2, load_dispatch_data/7, get_path_tokens/1, get_app_root/1, parse_cookie/1, get_cookie_value/2, parse_qs/1, get_qs_value/2, get_qs_value/3, range/1, log_data/1 ]). -include("webmachine_logger.hrl"). -include("wm_reqstate.hrl"). -include("wm_reqdata.hrl"). -define(WMVSN, "1.10.0"). -define(QUIP, "never breaks eye contact"). -define(IDLE_TIMEOUT, infinity). new(#wm_reqstate{}=ReqState) -> {?MODULE, ReqState}. trim_state({?MODULE, ReqState}) -> TrimData = (ReqState#wm_reqstate.reqdata)#wm_reqdata{wm_state='WMSTATE'}, webmachine_request:new(ReqState#wm_reqstate{reqdata=TrimData}); trim_state(ReqState) -> trim_state({?MODULE, ReqState}). get_peer({?MODULE, ReqState}=Req) -> case ReqState#wm_reqstate.peer of undefined -> PeerName = case ReqState#wm_reqstate.socket of testing -> {ok, {{127,0,0,1}, 80}}; {ssl,SslSocket} -> ssl:peername(SslSocket); _ -> inet:peername(ReqState#wm_reqstate.socket) end, Peer = peer_from_peername(PeerName, Req), NewReqState = ReqState#wm_reqstate{peer=Peer}, {Peer, NewReqState}; _ -> {ReqState#wm_reqstate.peer, ReqState} end; get_peer(ReqState) -> get_peer({?MODULE, ReqState}). peer_from_peername({ok, {Addr={10, _, _, _}, _Port}}, Req) -> x_peername(inet_parse:ntoa(Addr), Req); peer_from_peername({ok, {Addr={172, Second, _, _}, _Port}}, Req) when (Second > 15) andalso (Second < 32) -> x_peername(inet_parse:ntoa(Addr), Req); peer_from_peername({ok, {Addr={192, 168, _, _}, _Port}}, Req) -> x_peername(inet_parse:ntoa(Addr), Req); peer_from_peername({ok, {{127, 0, 0, 1}, _Port}}, Req) -> x_peername("127.0.0.1", Req); peer_from_peername({ok, {Addr, _Port}}, _Req) -> inet_parse:ntoa(Addr). x_peername(Default, Req) -> case get_header_value("x-forwarded-for", Req) of {undefined, _} -> Default; {Hosts, _} -> string:strip(lists:last(string:tokens(Hosts, ","))) end. call(base_uri, {?MODULE, ReqState}) -> {wrq:base_uri(ReqState#wm_reqstate.reqdata), ReqState}; call(socket, {?MODULE, ReqState}) -> {ReqState#wm_reqstate.socket,ReqState}; call(get_reqdata, {?MODULE, ReqState}) -> {ReqState#wm_reqstate.reqdata, ReqState}; call({set_reqdata, RD}, {?MODULE, ReqState}) -> {ok, ReqState#wm_reqstate{reqdata=RD}}; call(method, {?MODULE, ReqState}) -> {wrq:method(ReqState#wm_reqstate.reqdata), ReqState}; call(version, {?MODULE, ReqState}) -> {wrq:version(ReqState#wm_reqstate.reqdata), ReqState}; call(raw_path, {?MODULE, ReqState}) -> {wrq:raw_path(ReqState#wm_reqstate.reqdata), ReqState}; call(req_headers, {?MODULE, ReqState}) -> {wrq:req_headers(ReqState#wm_reqstate.reqdata), ReqState}; call({req_body, MaxRecvBody}, {?MODULE, ReqState}) -> case ReqState#wm_reqstate.bodyfetch of stream -> {stream_conflict, ReqState}; standard -> {ReqState#wm_reqstate.reqbody, ReqState}; undefined -> RD=(ReqState#wm_reqstate.reqdata)#wm_reqdata{ max_recv_body=MaxRecvBody}, NewReqState=ReqState#wm_reqstate{reqdata=RD}, NewBody = case get(req_body) of undefined -> NewB = do_recv_body(NewReqState), put(req_body, NewB), NewB; B -> B end, NewRD = RD#wm_reqdata{req_body=NewBody}, {NewBody, NewReqState#wm_reqstate{ bodyfetch=standard,reqdata=NewRD,reqbody=NewBody}} end; call({stream_req_body, MaxHunk}, {?MODULE, ReqState}) -> case ReqState#wm_reqstate.bodyfetch of standard -> {stream_conflict, ReqState}; _ -> {recv_stream_body(ReqState, MaxHunk), ReqState#wm_reqstate{bodyfetch=stream}} end; call(resp_headers, {?MODULE, ReqState}) -> {wrq:resp_headers(ReqState#wm_reqstate.reqdata), ReqState}; call(resp_redirect, {?MODULE, ReqState}) -> {wrq:resp_redirect(ReqState#wm_reqstate.reqdata), ReqState}; call({get_resp_header, HdrName}, {?MODULE, ReqState}) -> Reply = mochiweb_headers:get_value(HdrName, wrq:resp_headers(ReqState#wm_reqstate.reqdata)), {Reply, ReqState}; call(get_path_info, {?MODULE, ReqState}) -> PropList = orddict:to_list(wrq:path_info(ReqState#wm_reqstate.reqdata)), {PropList, ReqState}; call({get_path_info, Key}, {?MODULE, ReqState}) -> {wrq:path_info(Key, ReqState#wm_reqstate.reqdata), ReqState}; call(peer, Req) -> get_peer(Req); call(range, Req) -> get_range(Req); call(response_code, {?MODULE, ReqState}) -> {wrq:response_code(ReqState#wm_reqstate.reqdata), ReqState}; call(app_root, {?MODULE, ReqState}) -> {wrq:app_root(ReqState#wm_reqstate.reqdata), ReqState}; call(disp_path, {?MODULE, ReqState}) -> {wrq:disp_path(ReqState#wm_reqstate.reqdata), ReqState}; call(path, {?MODULE, ReqState}) -> {wrq:path(ReqState#wm_reqstate.reqdata), ReqState}; call({get_req_header, K}, {?MODULE, ReqState}) -> {wrq:get_req_header(K, ReqState#wm_reqstate.reqdata), ReqState}; call({set_response_code, Code}, {?MODULE, ReqState}) -> {ok, ReqState#wm_reqstate{reqdata=wrq:set_response_code( Code, ReqState#wm_reqstate.reqdata)}}; call({set_resp_header, K, V}, {?MODULE, ReqState}) -> {ok, ReqState#wm_reqstate{reqdata=wrq:set_resp_header( K, V, ReqState#wm_reqstate.reqdata)}}; call({set_resp_headers, Hdrs}, {?MODULE, ReqState}) -> {ok, ReqState#wm_reqstate{reqdata=wrq:set_resp_headers( Hdrs, ReqState#wm_reqstate.reqdata)}}; call({remove_resp_header, K}, {?MODULE, ReqState}) -> {ok, ReqState#wm_reqstate{reqdata=wrq:remove_resp_header( K, ReqState#wm_reqstate.reqdata)}}; call({merge_resp_headers, Hdrs}, {?MODULE, ReqState}) -> {ok, ReqState#wm_reqstate{reqdata=wrq:merge_resp_headers( Hdrs, ReqState#wm_reqstate.reqdata)}}; call({append_to_response_body, Data}, {?MODULE, ReqState}) -> {ok, ReqState#wm_reqstate{reqdata=wrq:append_to_response_body( Data, ReqState#wm_reqstate.reqdata)}}; call({set_disp_path, P}, {?MODULE, ReqState}) -> {ok, ReqState#wm_reqstate{reqdata=wrq:set_disp_path( P, ReqState#wm_reqstate.reqdata)}}; call(do_redirect, {?MODULE, ReqState}) -> {ok, ReqState#wm_reqstate{ reqdata=wrq:do_redirect(true, ReqState#wm_reqstate.reqdata)}}; call({send_response, Code}, Req) when is_integer(Code) -> call({send_response, {Code, undefined}}, Req); call({send_response, {Code, ReasonPhrase}=CodeAndReason}, Req) when is_integer(Code) -> {Reply, NewState} = case Code of 200 -> send_ok_response(ReasonPhrase, Req); _ -> send_response(CodeAndReason, Req) end, LogData = NewState#wm_reqstate.log_data, NewLogData = LogData#wm_log_data{finish_time=now()}, {Reply, NewState#wm_reqstate{log_data=NewLogData}}; call(resp_body, {?MODULE, ReqState}) -> {wrq:resp_body(ReqState#wm_reqstate.reqdata), ReqState}; call({set_resp_body, Body}, {?MODULE, ReqState}) -> {ok, ReqState#wm_reqstate{reqdata=wrq:set_resp_body(Body, ReqState#wm_reqstate.reqdata)}}; call(has_resp_body, {?MODULE, ReqState}) -> Reply = case wrq:resp_body(ReqState#wm_reqstate.reqdata) of undefined -> false; <<>> -> false; _ -> true end, {Reply, ReqState}; call({get_metadata, Key}, {?MODULE, ReqState}) -> Reply = case orddict:find(Key, ReqState#wm_reqstate.metadata) of {ok, Value} -> Value; error -> undefined end, {Reply, ReqState}; call({set_metadata, Key, Value}, {?MODULE, ReqState}) -> NewDict = orddict:store(Key, Value, ReqState#wm_reqstate.metadata), {ok, ReqState#wm_reqstate{metadata=NewDict}}; call(path_tokens, {?MODULE, ReqState}) -> {wrq:path_tokens(ReqState#wm_reqstate.reqdata), ReqState}; call(req_cookie, {?MODULE, ReqState}) -> {wrq:req_cookie(ReqState#wm_reqstate.reqdata), ReqState}; call(req_qs, {?MODULE, ReqState}) -> {wrq:req_qs(ReqState#wm_reqstate.reqdata), ReqState}; call({load_dispatch_data, PathProps, HostTokens, Port, PathTokens, AppRoot, DispPath}, {?MODULE, ReqState}) -> PathInfo = orddict:from_list(PathProps), NewState = ReqState#wm_reqstate{reqdata=wrq:load_dispatch_data( PathInfo,HostTokens,Port,PathTokens,AppRoot, DispPath,ReqState#wm_reqstate.reqdata)}, {ok, NewState}; call(log_data, {?MODULE, ReqState}) -> {ReqState#wm_reqstate.log_data, ReqState}; call(notes, {?MODULE, ReqState}) -> {wrq:get_notes(ReqState#wm_reqstate.reqdata), ReqState}; call(Arg, #wm_reqstate{}=ReqState) -> call(Arg, {?MODULE, ReqState}). get_header_value(K, {?MODULE, ReqState}) -> {wrq:get_req_header(K, ReqState#wm_reqstate.reqdata), ReqState}; get_header_value(K, ReqState) -> get_header_value(K, {?MODULE, ReqState}). get_outheader_value(K, {?MODULE, ReqState}) -> {mochiweb_headers:get_value(K, wrq:resp_headers(ReqState#wm_reqstate.reqdata)), ReqState}; get_outheader_value(K, ReqState) -> get_outheader_value(K, {?MODULE, ReqState}). send(Socket, Data) -> case mochiweb_socket:send(Socket, iolist_to_binary(Data)) of ok -> ok; {error,closed} -> ok; _ -> exit(normal) end. send_stream_body(Socket, X) -> send_stream_body(Socket, X, 0). send_stream_body(Socket, {<<>>, done}, SoFar) -> send_chunk(Socket, <<>>), SoFar; send_stream_body(Socket, {Data, done}, SoFar) -> Size = send_chunk(Socket, Data), send_chunk(Socket, <<>>), Size + SoFar; send_stream_body(Socket, {<<>>, Next}, SoFar) -> send_stream_body(Socket, Next(), SoFar); send_stream_body(Socket, {[], Next}, SoFar) -> send_stream_body(Socket, Next(), SoFar); send_stream_body(Socket, {Data, Next}, SoFar) -> Size = send_chunk(Socket, Data), send_stream_body(Socket, Next(), Size + SoFar). send_stream_body_no_chunk(Socket, {Data, done}) -> send(Socket, Data); send_stream_body_no_chunk(Socket, {Data, Next}) -> send(Socket, Data), send_stream_body_no_chunk(Socket, Next()). send_writer_body(Socket, {Encoder, Charsetter, BodyFun}) -> put(bytes_written, 0), Writer = fun(Data) -> Size = send_chunk(Socket, Encoder(Charsetter(Data))), put(bytes_written, get(bytes_written) + Size), Size end, BodyFun(Writer), send_chunk(Socket, <<>>), get(bytes_written). send_chunk(Socket, Data) -> Size = iolist_size(Data), send(Socket, [mochihex:to_hex(Size), <<"\r\n">>, Data, <<"\r\n">>]), Size. send_ok_response(ReasonPhrase, {?MODULE, ReqState}=Req) -> RD0 = ReqState#wm_reqstate.reqdata, {Range, State} = get_range(Req), case Range of X when X =:= undefined; X =:= fail; X =:= ignore -> send_response({200, ReasonPhrase}, Req); Ranges -> {PartList, Size} = range_parts(RD0, Ranges), case PartList of [] -> %% no valid ranges %% could be 416, for now we'll just return 200 send_response({200, ReasonPhrase}, Req); PartList -> {RangeHeaders, RangeBody} = parts_to_body(PartList, Size, Req), RespHdrsRD = wrq:set_resp_headers( [{"Accept-Ranges", "bytes"} | RangeHeaders], RD0), RespBodyRD = wrq:set_resp_body( RangeBody, RespHdrsRD), NewState = State#wm_reqstate{reqdata=RespBodyRD}, send_response({206, ReasonPhrase}, NewState, Req) end end. send_response(Code, #wm_reqstate{}=ReqState) -> send_response(Code,ReqState,{?MODULE,ReqState}); send_response(Code, {?MODULE, ReqState}=Req) -> send_response(Code,ReqState,Req). send_response(Code, PassedState=#wm_reqstate{reqdata=RD}, _Req) -> Body0 = wrq:resp_body(RD), {Body,Length} = case Body0 of {stream, StreamBody} -> {{stream, StreamBody}, chunked}; {known_length_stream, Size, StreamBody} -> {{known_length_stream, StreamBody}, Size}; {stream, Size, Fun} -> {{stream, Fun(0, Size-1)}, chunked}; {writer, WriteBody} -> {{writer, WriteBody}, chunked}; _ -> {Body0, iolist_size([Body0])} end, send(PassedState#wm_reqstate.socket, [make_version(wrq:version(RD)), make_code(Code), <<"\r\n">> | make_headers(Code, Length, RD)]), FinalLength = case wrq:method(RD) of 'HEAD' -> Length; _ -> case Body of {stream, Body2} -> send_stream_body(PassedState#wm_reqstate.socket, Body2); {known_length_stream, Body2} -> send_stream_body_no_chunk(PassedState#wm_reqstate.socket, Body2), Length; {writer, Body2} -> send_writer_body(PassedState#wm_reqstate.socket, Body2); _ -> send(PassedState#wm_reqstate.socket, Body), Length end end, InitLogData = PassedState#wm_reqstate.log_data, FinalLogData = InitLogData#wm_log_data{response_code=Code, response_length=FinalLength}, {ok, PassedState#wm_reqstate{reqdata=wrq:set_response_code(Code, RD), log_data=FinalLogData}}. %% @doc Infer body length from transfer-encoding and content-length headers. body_length(Req) -> case get_header_value("transfer-encoding", Req) of {undefined, _} -> case get_header_value("content-length", Req) of {undefined, _} -> undefined; {Length, _} -> list_to_integer(Length) end; {"chunked", _} -> chunked; Unknown -> {unknown_transfer_encoding, Unknown} end. %% @doc Receive the body of the HTTP request (defined by Content-Length). %% Will only receive up to the default max-body length do_recv_body(PassedState=#wm_reqstate{reqdata=RD}) -> MRH = RD#wm_reqdata.max_recv_hunk, MRB = RD#wm_reqdata.max_recv_body, read_whole_stream(recv_stream_body(PassedState, MRH), [], MRB, 0). read_whole_stream({Hunk,_}, _, MaxRecvBody, SizeAcc) when SizeAcc + byte_size(Hunk) > MaxRecvBody -> {error, req_body_too_large}; read_whole_stream({Hunk,Next}, Acc0, MaxRecvBody, SizeAcc) -> HunkSize = byte_size(Hunk), if SizeAcc + HunkSize > MaxRecvBody -> {error, req_body_too_large}; true -> Acc = [Hunk|Acc0], case Next of done -> iolist_to_binary(lists:reverse(Acc)); _ -> read_whole_stream(Next(), Acc, MaxRecvBody, SizeAcc + HunkSize) end end. recv_stream_body(PassedState=#wm_reqstate{reqdata=RD}, MaxHunkSize) -> put(mochiweb_request_recv, true), case get_header_value("expect", PassedState) of {"100-continue", _} -> send(PassedState#wm_reqstate.socket, [make_version(wrq:version(RD)), make_code(100), <<"\r\n\r\n">>]); _Else -> ok end, case body_length(PassedState) of {unknown_transfer_encoding, X} -> exit({unknown_transfer_encoding, X}); undefined -> {<<>>, done}; 0 -> {<<>>, done}; chunked -> recv_chunked_body(PassedState#wm_reqstate.socket, MaxHunkSize); Length -> recv_unchunked_body(PassedState#wm_reqstate.socket, MaxHunkSize, Length) end. recv_unchunked_body(Socket, MaxHunk, DataLeft) -> case MaxHunk >= DataLeft of true -> {ok,Data1} = mochiweb_socket:recv(Socket,DataLeft,?IDLE_TIMEOUT), {Data1, done}; false -> {ok,Data2} = mochiweb_socket:recv(Socket,MaxHunk,?IDLE_TIMEOUT), {Data2, fun() -> recv_unchunked_body(Socket, MaxHunk, DataLeft-MaxHunk) end} end. recv_chunked_body(Socket, MaxHunk) -> case read_chunk_length(Socket, false) of 0 -> {<<>>, done}; ChunkLength -> recv_chunked_body(Socket,MaxHunk,ChunkLength) end. recv_chunked_body(Socket, MaxHunk, LeftInChunk) -> case MaxHunk >= LeftInChunk of true -> {ok,Data1} = mochiweb_socket:recv(Socket,LeftInChunk,?IDLE_TIMEOUT), {Data1, fun() -> recv_chunked_body(Socket, MaxHunk) end}; false -> {ok,Data2} = mochiweb_socket:recv(Socket,MaxHunk,?IDLE_TIMEOUT), {Data2, fun() -> recv_chunked_body(Socket, MaxHunk, LeftInChunk-MaxHunk) end} end. read_chunk_length(Socket, MaybeLastChunk) -> mochiweb_socket:setopts(Socket, [{packet, line}]), case mochiweb_socket:recv(Socket, 0, ?IDLE_TIMEOUT) of {ok, Header} -> mochiweb_socket:setopts(Socket, [{packet, raw}]), Splitter = fun (C) -> C =/= $\r andalso C =/= $\n andalso C =/= $ andalso C =/= 59 % semicolon end, {Hex, _Rest} = lists:splitwith(Splitter, binary_to_list(Header)), case Hex of [] -> %% skip the \r\n at the end of a chunk, or %% allow [badly formed] last chunk header to be %% empty instead of '0' explicitly if MaybeLastChunk -> 0; true -> read_chunk_length(Socket, true) end; _ -> erlang:list_to_integer(Hex, 16) end; _ -> exit(normal) end. get_range({?MODULE, #wm_reqstate{reqdata = RD}=ReqState}=Req) -> case RD#wm_reqdata.resp_range of ignore_request -> {ignore, ReqState#wm_reqstate{range=undefined}}; follow_request -> case get_header_value("range", Req) of {undefined, _} -> {undefined, ReqState#wm_reqstate{range=undefined}}; {RawRange, _} -> Range = mochiweb_http:parse_range_request(RawRange), {Range, ReqState#wm_reqstate{range=Range}} end end. range_parts(_RD=#wm_reqdata{resp_body={file, IoDevice}}, Ranges) -> Size = mochiweb_io:iodevice_size(IoDevice), F = fun (Spec, Acc) -> case mochiweb_http:range_skip_length(Spec, Size) of invalid_range -> Acc; V -> [V | Acc] end end, LocNums = lists:foldr(F, [], Ranges), {ok, Data} = file:pread(IoDevice, LocNums), Bodies = lists:zipwith(fun ({Skip, Length}, PartialBody) -> {Skip, Skip + Length - 1, PartialBody} end, LocNums, Data), {Bodies, Size}; range_parts(RD=#wm_reqdata{resp_body={stream, {Hunk,Next}}}, Ranges) -> % for now, streamed bodies are read in full for range requests MRB = RD#wm_reqdata.max_recv_body, range_parts(read_whole_stream({Hunk,Next}, [], MRB, 0), Ranges); range_parts(_RD=#wm_reqdata{resp_body={known_length_stream, Size, StreamBody}}, Ranges) -> SkipLengths = [ mochiweb_http:range_skip_length(R, Size) || R <- Ranges], {[ {Skip, Skip+Length-1, {known_length_stream, Length, StreamBody}} || {Skip, Length} <- SkipLengths ], Size}; range_parts(_RD=#wm_reqdata{resp_body={stream, Size, StreamFun}}, Ranges) -> SkipLengths = [ mochiweb_http:range_skip_length(R, Size) || R <- Ranges], {[ {Skip, Skip+Length-1, StreamFun} || {Skip, Length} <- SkipLengths ], Size}; range_parts(#wm_reqdata{resp_body=Body}, Ranges) when is_binary(Body); is_list(Body) -> range_parts(Body, Ranges); range_parts(Body0, Ranges) when is_binary(Body0); is_list(Body0) -> Body = iolist_to_binary(Body0), Size = size(Body), F = fun(Spec, Acc) -> case mochiweb_http:range_skip_length(Spec, Size) of invalid_range -> Acc; {Skip, Length} -> <<_:Skip/binary, PartialBody:Length/binary, _/binary>> = Body, [{Skip, Skip + Length - 1, PartialBody} | Acc] end end, {lists:foldr(F, [], Ranges), Size}. parts_to_body([{Start, End, Body0}], Size, Req) -> %% return body for a range reponse with a single body ContentType = case get_outheader_value("content-type", Req) of {undefined, _} -> "text/html"; {CT, _} -> CT end, HeaderList = [{"Content-Type", ContentType}, {"Content-Range", ["bytes ", mochiweb_util:make_io(Start), "-", mochiweb_util:make_io(End), "/", mochiweb_util:make_io(Size)]}], Body = case Body0 of _ when is_function(Body0) -> {known_length_stream, End - Start + 1, Body0(Start, End)}; {known_length_stream, ContentSize, StreamBody} -> {known_length_stream, ContentSize, StreamBody}; _ -> Body0 end, {HeaderList, Body}; parts_to_body(BodyList, Size, Req) when is_list(BodyList) -> %% return %% header Content-Type: multipart/byteranges; boundary=441934886133bdee4 %% and multipart body ContentType = case get_outheader_value("content-type", Req) of {undefined, _} -> "text/html"; {CT, _} -> CT end, Boundary = mochihex:to_hex(mochiweb_util:rand_bytes(8)), HeaderList = [{"Content-Type", ["multipart/byteranges; ", "boundary=", Boundary]}], MultiPartBody = case hd(BodyList) of {_, _, Fun} when is_function(Fun) -> stream_multipart_body(BodyList, ContentType, Boundary, Size); _ -> multipart_body(BodyList, ContentType, Boundary, Size) end, {HeaderList, MultiPartBody}. multipart_body([], _ContentType, Boundary, _Size) -> end_boundary(Boundary); multipart_body([{Start, End, Body} | BodyList], ContentType, Boundary, Size) -> [part_preamble(Boundary, ContentType, Start, End, Size), Body, <<"\r\n">> | multipart_body(BodyList, ContentType, Boundary, Size)]. boundary(B) -> [<<"--">>, B, <<"\r\n">>]. end_boundary(B) -> [<<"--">>, B, <<"--\r\n">>]. part_preamble(Boundary, CType, Start, End, Size) -> [boundary(Boundary), <<"Content-Type: ">>, CType, <<"\r\n">>, <<"Content-Range: bytes ">>, mochiweb_util:make_io(Start), <<"-">>, mochiweb_util:make_io(End), <<"/">>, mochiweb_util:make_io(Size), <<"\r\n\r\n">>]. stream_multipart_body(BodyList, ContentType, Boundary, Size) -> Helper = stream_multipart_body_helper( BodyList, ContentType, Boundary, Size), %% executing Helper() here is an optimization; %% it's just as valid to say {<<>>, Helper} {stream, Helper()}. stream_multipart_body_helper([], _CType, Boundary, _Size) -> fun() -> {end_boundary(Boundary), done} end; stream_multipart_body_helper([{Start, End, Fun}|Rest], CType, Boundary, Size) -> fun() -> {part_preamble(Boundary, CType, Start, End, Size), stream_multipart_part_helper( fun() -> Fun(Start, End) end, Rest, CType, Boundary, Size)} end. stream_multipart_part_helper(Fun, Rest, CType, Boundary, Size) -> fun() -> case Fun() of {Data, done} -> %% when this part is done, start the next part {[Data, <<"\r\n">>], stream_multipart_body_helper( Rest, CType, Boundary, Size)}; {Data, Next} -> %% this subpart has more data coming {Data, stream_multipart_part_helper( Next, Rest, CType, Boundary, Size)} end end. make_code({Code, undefined}) when is_integer(Code) -> make_code({Code, httpd_util:reason_phrase(Code)}); make_code({Code, ReasonPhrase}) when is_integer(Code) -> [integer_to_list(Code), [" ", ReasonPhrase]]; make_code(Code) when is_integer(Code) -> make_code({Code, httpd_util:reason_phrase(Code)}); make_code(Io) when is_list(Io); is_binary(Io) -> Io. make_version({1, 0}) -> <<"HTTP/1.0 ">>; make_version(_) -> <<"HTTP/1.1 ">>. make_headers({Code, _ReasonPhrase}, Length, RD) -> make_headers(Code, Length, RD); make_headers(Code, Length, RD) when is_integer(Code) -> Hdrs0 = case Code of 304 -> mochiweb_headers:make(wrq:resp_headers(RD)); _ -> case Length of chunked -> mochiweb_headers:enter( "Transfer-Encoding","chunked", mochiweb_headers:make(wrq:resp_headers(RD))); _ -> mochiweb_headers:enter( "Content-Length",integer_to_list(Length), mochiweb_headers:make(wrq:resp_headers(RD))) end end, case application:get_env(webmachine, server_name) of undefined -> ServerHeader = "MochiWeb/1.1 WebMachine/" ++ ?WMVSN ++ " (" ++ ?QUIP ++ ")"; {ok, ServerHeader} when is_list(ServerHeader) -> ok end, WithSrv = mochiweb_headers:enter("Server", ServerHeader, Hdrs0), Hdrs = case mochiweb_headers:get_value("date", WithSrv) of undefined -> mochiweb_headers:enter("Date", httpd_util:rfc1123_date(), WithSrv); _ -> WithSrv end, F = fun({K, V}, Acc) -> [mochiweb_util:make_io(K), <<": ">>, V, <<"\r\n">> | Acc] end, lists:foldl(F, [<<"\r\n">>], mochiweb_headers:to_list(Hdrs)). get_reqdata(#wm_reqstate{}=ReqState) -> call(get_reqdata, {?MODULE, ReqState}); get_reqdata(Req) -> call(get_reqdata, Req). set_reqdata(RD, #wm_reqstate{}=ReqState) -> call({set_reqdata, RD}, {?MODULE, ReqState}); set_reqdata(RD, Req) -> call({set_reqdata, RD}, Req). socket(#wm_reqstate{}=ReqState) -> call(socket, {?MODULE, ReqState}); socket(Req) -> call(socket, Req). method(#wm_reqstate{}=ReqState) -> call(method, {?MODULE, ReqState}); method(Req) -> call(method, Req). version(#wm_reqstate{}=ReqState) -> call(version, {?MODULE, ReqState}); version(Req) -> call(version, Req). disp_path(#wm_reqstate{}=ReqState) -> call(disp_path, {?MODULE, ReqState}); disp_path(Req) -> call(disp_path, Req). path(#wm_reqstate{}=ReqState) -> call(path, {?MODULE, ReqState}); path(Req) -> call(path, Req). raw_path(#wm_reqstate{}=ReqState) -> call(raw_path, {?MODULE, ReqState}); raw_path(Req) -> call(raw_path, Req). req_headers(#wm_reqstate{}=ReqState) -> call(req_headers, {?MODULE, ReqState}); req_headers(Req) -> call(req_headers, Req). headers(Req) -> req_headers(Req). req_body(MaxRevBody, #wm_reqstate{}=ReqState) -> call({req_body,MaxRevBody}, {?MODULE, ReqState}); req_body(MaxRevBody, Req) -> call({req_body,MaxRevBody}, Req). stream_req_body(MaxHunk, #wm_reqstate{}=ReqState) -> call({stream_req_body, MaxHunk}, {?MODULE, ReqState}); stream_req_body(MaxHunk, Req) -> call({stream_req_body, MaxHunk}, Req). resp_headers(#wm_reqstate{}=ReqState) -> call(resp_headers, {?MODULE, ReqState}); resp_headers(Req) -> call(resp_headers, Req). out_headers(Req) -> resp_headers(Req). get_resp_header(HeaderName, Req) -> call({get_resp_header, HeaderName}, Req). get_out_header(HeaderName, #wm_reqstate{}=ReqState) -> get_resp_header(HeaderName, {?MODULE, ReqState}); get_out_header(HeaderName, Req) -> get_resp_header(HeaderName, Req). has_resp_header(HeaderName, Req) -> case get_out_header(HeaderName, Req) of {undefined, _} -> false; {_, _} -> true end. has_out_header(HeaderName, #wm_reqstate{}=ReqState) -> has_resp_header(HeaderName, {?MODULE, ReqState}); has_out_header(HeaderName, Req) -> has_resp_header(HeaderName, Req). has_resp_body(#wm_reqstate{}=ReqState) -> call(has_resp_body, {?MODULE, ReqState}); has_resp_body(Req) -> call(has_resp_body, Req). has_response_body(Req) -> has_resp_body(Req). response_code(#wm_reqstate{}=ReqState) -> call(response_code, {?MODULE, ReqState}); response_code(Req) -> call(response_code, Req). set_response_code(Code, {?MODULE, ReqState}=Req) -> call({ReqState, set_response_code, Code}, Req); set_response_code(Code, ReqState) -> set_response_code(Code, {?MODULE, ReqState}). peer(#wm_reqstate{}=ReqState) -> call(peer, {?MODULE, ReqState}); peer(Req) -> call(peer, Req). range(#wm_reqstate{}=ReqState) -> call(range, {?MODULE, ReqState}); range(Req) -> call(range, Req). req_cookie(#wm_reqstate{}=ReqState) -> call(req_cookie, {?MODULE, ReqState}); req_cookie(Req) -> call(req_cookie, Req). parse_cookie(Req) -> req_cookie(Req). get_cookie_value(Key, #wm_reqstate{}=ReqState) -> get_cookie_value(Key, {?MODULE, ReqState}); get_cookie_value(Key, Req) -> {ReqCookie, NewReqState} = req_cookie(Req), case lists:keyfind(Key, 1, ReqCookie) of false -> {undefined, NewReqState}; {Key, Value} -> {Value, NewReqState} end. req_qs(#wm_reqstate{}=ReqState) -> call(req_qs, {?MODULE, ReqState}); req_qs(Req) -> call(req_qs, Req). parse_qs(Req) -> req_qs(Req). get_qs_value(Key, #wm_reqstate{}=ReqState) -> get_qs_value(Key, {?MODULE, ReqState}); get_qs_value(Key, Req) -> {ReqQS, NewReqState} = req_qs(Req), case lists:keyfind(Key, 1, ReqQS) of false -> {undefined, NewReqState}; {Key, Value} -> {Value, NewReqState} end. get_qs_value(Key, Default, #wm_reqstate{}=ReqState) -> get_qs_value(Key, Default, {?MODULE, ReqState}); get_qs_value(Key, Default, Req) -> {ReqQS, NewReqState} = req_qs(Req), case lists:keyfind(Key, 1, ReqQS) of false -> {Default, NewReqState}; {Key, Value} -> {Value, NewReqState} end. set_resp_body(Body, #wm_reqstate{}=ReqState) -> call({set_resp_body, Body}, {?MODULE, ReqState}); set_resp_body(Body, Req) -> call({set_resp_body, Body}, Req). resp_body(#wm_reqstate{}=ReqState) -> call(resp_body, {?MODULE, ReqState}); resp_body(Req) -> call(resp_body, Req). response_body(Req) -> resp_body(Req). get_req_header(K, #wm_reqstate{}=ReqState) -> call({get_req_header, K}, {?MODULE, ReqState}); get_req_header(K, Req) -> call({get_req_header, K}, Req). set_resp_header(K, V, Req) -> call({set_resp_header, K, V}, Req). add_response_header(K, V, #wm_reqstate{}=ReqState) -> set_resp_header(K, V, {?MODULE, ReqState}); add_response_header(K, V, Req) -> set_resp_header(K, V, Req). set_resp_headers(Hdrs, Req) -> call({set_resp_headers, Hdrs}, Req). add_response_headers(Hdrs, #wm_reqstate{}=ReqState) -> set_resp_headers(Hdrs, {?MODULE, ReqState}); add_response_headers(Hdrs, Req) -> set_resp_headers(Hdrs, Req). remove_resp_header(K, Req) -> call({remove_resp_header, K}, Req). remove_response_header(K, #wm_reqstate{}=ReqState) -> remove_resp_header(K, {?MODULE, ReqState}); remove_response_header(K, Req) -> remove_resp_header(K, Req). merge_resp_headers(Hdrs, Req) -> call({merge_resp_headers, Hdrs}, Req). merge_response_headers(Hdrs, #wm_reqstate{}=ReqState) -> merge_resp_headers(Hdrs, {?MODULE, ReqState}); merge_response_headers(Hdrs, Req) -> merge_resp_headers(Hdrs, Req). append_to_response_body(Data, #wm_reqstate{}=ReqState) -> call({append_to_response_body, Data}, {?MODULE, ReqState}); append_to_response_body(Data, Req) -> call({append_to_response_body, Data}, Req). do_redirect(#wm_reqstate{}=ReqState) -> call(do_redirect, {?MODULE, ReqState}); do_redirect(Req) -> call(do_redirect, Req). resp_redirect(#wm_reqstate{}=ReqState) -> call(resp_redirect, {?MODULE, ReqState}); resp_redirect(Req) -> call(resp_redirect, Req). get_metadata(Key, #wm_reqstate{}=ReqState) -> call({get_metadata, Key}, {?MODULE, ReqState}); get_metadata(Key, Req) -> call({get_metadata, Key}, Req). set_metadata(Key, Value, #wm_reqstate{}=ReqState) -> call({set_metadata, Key, Value}, {?MODULE, ReqState}); set_metadata(Key, Value, Req) -> call({set_metadata, Key, Value}, Req). get_path_info(#wm_reqstate{}=ReqState) -> call(get_path_info, {?MODULE, ReqState}); get_path_info(Req) -> call(get_path_info, Req). get_path_info(Key, #wm_reqstate{}=ReqState) -> call({get_path_info, Key}, {?MODULE, ReqState}); get_path_info(Key, Req) -> call({get_path_info, Key}, Req). path_tokens(#wm_reqstate{}=ReqState) -> call(path_tokens, {?MODULE, ReqState}); path_tokens(Req) -> call(path_tokens, Req). get_path_tokens(Req) -> path_tokens(Req). app_root(#wm_reqstate{}=ReqState) -> call(app_root, {?MODULE, ReqState}); app_root(Req) -> call(app_root, Req). get_app_root(Req) -> app_root(Req). load_dispatch_data(Bindings, HostTokens, Port, PathTokens, AppRoot, DispPath, #wm_reqstate{}=ReqState) -> call({load_dispatch_data, Bindings, HostTokens, Port, PathTokens, AppRoot, DispPath}, {?MODULE, ReqState}); load_dispatch_data(Bindings, HostTokens, Port, PathTokens, AppRoot, DispPath, Req) -> call({load_dispatch_data, Bindings, HostTokens, Port, PathTokens, AppRoot, DispPath}, Req). log_data(#wm_reqstate{}=ReqState) -> call(log_data, {?MODULE, ReqState}); log_data(Req) -> call(log_data, Req). -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). reqdata_test() -> ReqData = #wm_reqdata{req_headers = mochiweb_headers:make([])}, {ok, ReqState} = set_reqdata(ReqData, #wm_reqstate{}), ?assertEqual(ReqData, element(1, get_reqdata(ReqState))). header_test() -> HdrName = "Accept", HdrValue = "application/json", ReqData = #wm_reqdata{req_headers = mochiweb_headers:make([{HdrName, HdrValue}])}, {ok, ReqState} = set_reqdata(ReqData, #wm_reqstate{}), ?assertEqual({HdrValue, ReqState}, get_header_value(HdrName, ReqState)), ?assertEqual({HdrValue, ReqState}, get_req_header(HdrName, ReqState)). metadata_test() -> Key = "webmachine", Value = "eunit", {ok, ReqState} = set_metadata(Key, Value, #wm_reqstate{metadata=orddict:new()}), ?assertEqual({Value, ReqState}, get_metadata(Key, ReqState)). peer_test() -> Self = self(), Pid = spawn_link(fun() -> {ok, LS} = gen_tcp:listen(0, [binary, {active, false}]), {ok, {_, Port}} = inet:sockname(LS), Self ! {port, Port}, {ok, S} = gen_tcp:accept(LS), receive stop -> ok after 2000 -> ok end, gen_tcp:close(S), gen_tcp:close(LS) end), receive {port, Port} -> {ok, S} = gen_tcp:connect({127,0,0,1}, Port, [binary, {active, false}]), ReqData = #wm_reqdata{req_headers = mochiweb_headers:make([])}, ReqState = #wm_reqstate{socket=S, reqdata=ReqData}, ?assertEqual({S, ReqState}, socket(ReqState)), {"127.0.0.1", NReqState} = get_peer(ReqState), ?assertEqual("127.0.0.1", NReqState#wm_reqstate.peer), Pid ! stop, gen_tcp:close(S) after 2000 -> exit({error, listener_fail}) end. -endif. ././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_logger_watcher_sup.erlrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_logger_watcher_su0000644000177700017770000000227712633765070033774 0ustar michaelmichael%% Copyright (c) 2011-2012 Basho Technologies, Inc. All Rights Reserved. %% %% This file is provided to you under the Apache License, %% Version 2.0 (the "License"); you may not use this file %% except in compliance with the License. You may obtain %% a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, %% software distributed under the License is distributed on an %% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY %% KIND, either express or implied. See the License for the %% specific language governing permissions and limitations %% under the License. %% @doc A supervisor for monitoring webmachine_logger_handler_watcher processes. %% @private -module(webmachine_logger_watcher_sup). -behaviour(supervisor). %% API -export([start_link/0]). %% Callbacks -export([init/1]). start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). init([]) -> {ok, {{simple_one_for_one, 10, 60}, [ {webmachine_logger_watcher, {webmachine_logger_watcher, start_link, []}, transient, 5000, worker, [webmachine_logger_watcher]} ]}}. ././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_perf_log_handler.erlrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_perf_log_handler.0000644000177700017770000000746612633765070033646 0ustar michaelmichael%% Copyright (c) 2011-2013 Basho Technologies, Inc. All Rights Reserved. %% %% This file is provided to you under the Apache License, %% Version 2.0 (the "License"); you may not use this file %% except in compliance with the License. You may obtain %% a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, %% software distributed under the License is distributed on an %% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY %% KIND, either express or implied. See the License for the %% specific language governing permissions and limitations %% under the License. %% @doc Default performance log handler for webmachine -module(webmachine_perf_log_handler). -behaviour(gen_event). %% gen_event callbacks -export([init/1, handle_call/2, handle_event/2, handle_info/2, terminate/2, code_change/3]). -include("webmachine_logger.hrl"). -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -endif. -record(state, {hourstamp, filename, handle}). -define(FILENAME, "perf.log"). %% =================================================================== %% gen_event callbacks %% =================================================================== %% @private init([BaseDir]) -> webmachine_log:defer_refresh(?MODULE), FileName = filename:join(BaseDir, ?FILENAME), {Handle, DateHour} = webmachine_log:log_open(FileName), {ok, #state{filename=FileName, handle=Handle, hourstamp=DateHour}}. %% @private handle_call({_Label, MRef, get_modules}, State) -> {ok, {MRef, [?MODULE]}, State}; handle_call({refresh, Time}, State) -> {ok, ok, webmachine_log:maybe_rotate(?MODULE, Time, State)}; handle_call(_Request, State) -> {ok, ok, State}. %% @private handle_event({log_access, LogData}, State) -> NewState = webmachine_log:maybe_rotate(?MODULE, os:timestamp(), State), Msg = format_req(LogData), webmachine_log:log_write(NewState#state.handle, Msg), {ok, NewState}; handle_event(_Event, State) -> {ok, State}. %% @private handle_info(_Info, State) -> {ok, State}. %% @private terminate(_Reason, _State) -> ok. %% @private code_change(_OldVsn, State, _Extra) -> {ok, State}. %% =================================================================== %% Internal functions %% =================================================================== format_req(#wm_log_data{resource_module=Mod, start_time=StartTime, method=Method, peer=Peer, path=Path, version=Version, response_code=ResponseCode, response_length=ResponseLength, end_time=EndTime, finish_time=FinishTime}) -> Time = webmachine_log:fmtnow(), Status = case ResponseCode of {Code, _ReasonPhrase} when is_integer(Code) -> integer_to_list(Code); _ when is_integer(ResponseCode) -> integer_to_list(ResponseCode); _ -> ResponseCode end, Length = integer_to_list(ResponseLength), TTPD = webmachine_util:now_diff_milliseconds(EndTime, StartTime), TTPS = webmachine_util:now_diff_milliseconds(FinishTime, EndTime), fmt_plog(Time, Peer, atom_to_list(Method), Path, Version, Status, Length, atom_to_list(Mod), integer_to_list(TTPD), integer_to_list(TTPS)). fmt_plog(Time, Ip, Method, Path, {VM,Vm}, Status, Length, Mod, TTPD, TTPS) -> [webmachine_log:fmt_ip(Ip), " - ", [$\s], Time, [$\s, $"], Method, " ", Path, " HTTP/", integer_to_list(VM), ".", integer_to_list(Vm), [$",$\s], Status, [$\s], Length, " " , Mod, " ", TTPD, " ", TTPS, $\n]. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_dispatcher.erl0000644000177700017770000005631112633765070033176 0ustar michaelmichael%% @author Robert Ahrens %% @author Justin Sheehy %% @copyright 2007-2009 Basho Technologies %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% @doc Module for URL-dispatch by pattern matching. -module(webmachine_dispatcher). -author('Robert Ahrens '). -author('Justin Sheehy '). -author('Bryan Fink '). -export([dispatch/3, dispatch/4]). -define(SEPARATOR, $\/). -define(MATCH_ALL, '*'). %% @spec dispatch(Path::string(), DispatchList::[matchterm()], %% wrq:reqdata()) -> %% dispterm() | dispfail() %% @doc Interface for URL dispatching. %% See also http://bitbucket.org/justin/webmachine/wiki/DispatchConfiguration dispatch(PathAsString, DispatchList, RD) -> dispatch([], PathAsString, DispatchList, RD). %% @spec dispatch(Host::string(), Path::string(), %% DispatchList::[matchterm()], wrq:reqdata()) -> %% dispterm() | dispfail() %% @doc Interface for URL dispatching. %% See also http://bitbucket.org/justin/webmachine/wiki/DispatchConfiguration dispatch(HostAsString, PathAsString, DispatchList, RD) -> Path = string:tokens(PathAsString, [?SEPARATOR]), % URIs that end with a trailing slash are implicitly one token % "deeper" than we otherwise might think as we are "inside" % a directory named by the last token. ExtraDepth = case lists:last(PathAsString) == ?SEPARATOR of true -> 1; _ -> 0 end, {Host, Port} = split_host_port(HostAsString, wrq:scheme(RD)), try_host_binding(DispatchList, Host, Port, Path, ExtraDepth, RD). split_host_port(HostAsString, Scheme) -> case string:tokens(HostAsString, ":") of [HostPart, PortPart] -> {split_host(HostPart), list_to_integer(PortPart)}; [HostPart] -> {split_host(HostPart), default_port(Scheme)}; [] -> %% no host header {[], default_port(Scheme)}; _ -> %% Invalid host header {invalid_host, default_port(Scheme)} end. split_host(HostAsString) -> string:tokens(HostAsString, "."). default_port(http) -> 80; default_port(https) -> 443. %% @type matchterm() = hostmatchterm() | pathmatchterm(). % The dispatch configuration is a list of these terms, and the % first one whose host and path terms match the input is used. % Using a pathmatchterm() here is equivalent to using a hostmatchterm() % of the form {{['*'],'*'}, [pathmatchterm()]}. %% @type hostmatchterm() = {hostmatch(), [pathmatchterm()]}. % The dispatch configuration contains a list of these terms, and the % first one whose host and one pathmatchterm match is used. %% @type hostmatch() = [hostterm()] | {[hostterm()], portterm()}. % A host header (Host, X-Forwarded-For, etc.) will be matched against % this term. Using a raws [hostterm()] list is equivalent to using % {[hostterm()], '*'}. %% @type hostterm() = '*' | string() | atom(). % A list of hostterms is matched against a '.'-separated hostname. % The '*' hosterm matches all remaining tokens, and is only allowed at % the head of the list. % A string hostterm will match a token of exactly the same string. % Any atom hostterm other than '*' will match any token and will % create a binding in the result if a complete match occurs. %% @type portterm() = '*' | integer() | atom(). % A portterm is matched against the integer port after any ':' in % the hostname, or 80 if no port is found. % The '*' portterm patches any port % An integer portterm will match a port of exactly the same integer. % Any atom portterm other than '*' will match any port and will % create a binding in the result if a complete match occurs. %% @type pathmatchterm() = {[pathterm()], matchmod(), matchopts()} | %% {[pathterm()], guardfun(), matchmod(), matchopts()}. % The dispatch configuration contains a list of these terms, and the % first one whose list of pathterms matches the input path is used. %% @type pathterm() = '*' | string() | atom(). % A list of pathterms is matched against a '/'-separated input path. % The '*' pathterm matches all remaining tokens. % A string pathterm will match a token of exactly the same string. % Any atom pathterm other than '*' will match any token and will % create a binding in the result if a complete match occurs. %% @type guardfun() = (wrq:reqdata()) -> boolean() %% | {Mod::atom(), Fun::atom()}. % This function or tuple representing a function, if present, is % called after a successful match of the host, port, and path for a % dispatch entry. The function should take a single argument, the % request data object, and return a boolean. If the return value is % 'true', then this dispatch entry is used to service the % request. Otherwise, webmachine will continue with the next dispatch % entry. %% @type matchmod() = atom(). % This atom, if present in a successful matchterm, will appear in % the resulting dispterm. In Webmachine this is used to name the % resource module that will handle the matching request. %% @type matchopts() = [term()]. % This term, if present in a successful matchterm, will appear in % the resulting dispterm. In Webmachine this is used to provide % arguments to the resource module handling the matching request. %% @type dispterm() = {matchmod(), matchopts(), pathtokens(), %% bindings(), approot(), stringpath()}. %% @type pathtokens() = [pathtoken()]. % This is the list of tokens matched by a trailing '*' pathterm. %% @type pathtoken() = string(). %% @type bindings() = [{bindingterm(),pathtoken()}]. % This is a proplist of bindings indicated by atom terms in the % matching spec, bound to the matching tokens in the request path. %% @type approot() = string(). %% @type stringpath() = string(). % This is the path portion matched by a trailing '*' pathterm. %% @type dispfail() = {no_dispatch_match, pathtokens()}. try_host_binding(_Dispatch, invalid_host, _Port, _Path, _Depth, _RD) -> {error, invalid_host}; try_host_binding(Dispatch, Host, Port, Path, Depth, RD) -> %% save work during each dispatch attempt by reversing Host up front try_host_binding1(Dispatch, lists:reverse(Host), Port, Path, Depth, RD). try_host_binding1([], Host, Port, Path, _Depth, _RD) -> %% Host was reversed inbound, correct it for result {no_dispatch_match, {lists:reverse(Host), Port}, Path}; try_host_binding1([Dispatch|Rest], Host, Port, Path, Depth, RD) -> {{HostSpec,PortSpec},PathSpec} = case Dispatch of {{H,P},S} -> {{H,P},S}; {H,S} -> {{H,?MATCH_ALL},S}; S -> {{[?MATCH_ALL],?MATCH_ALL},[S]} end, case bind_port(PortSpec, Port, []) of {ok, PortBindings} -> case bind(lists:reverse(HostSpec), Host, PortBindings, 0) of {ok, RevHostRemainder, HostBindings, _} -> %% Host was reversed inbound, correct it for remainder HostRemainder = lists:reverse(RevHostRemainder), case try_path_binding(PathSpec, Path, HostRemainder, Port, HostBindings, Depth, RD) of {Mod, Props, PathRemainder, PathBindings, AppRoot, StringPath} -> {Mod, Props, HostRemainder, Port, PathRemainder, PathBindings, AppRoot, StringPath}; {no_dispatch_match, _} -> try_host_binding1(Rest, Host, Port, Path, Depth, RD) end; fail -> try_host_binding1(Rest, Host, Port, Path, Depth, RD) end; fail -> try_host_binding1(Rest, Host, Port, Path, Depth, RD) end. bind_port(Port, Port, Bindings) -> {ok, Bindings}; bind_port(?MATCH_ALL, _Port, Bindings) -> {ok, Bindings}; bind_port(PortAtom, Port, Bindings) when is_atom(PortAtom) -> {ok, [{PortAtom, Port}|Bindings]}; bind_port(_, _, _) -> fail. try_path_binding([], PathTokens, _, _, _, _, _) -> {no_dispatch_match, PathTokens}; try_path_binding([PathSpec|Rest], PathTokens, HostRemainder, Port, HostBindings, ExtraDepth, RD) -> {PathSchema, Guard, Mod, Props} = case PathSpec of {P, M, Pr} -> {P, undefined, M, Pr}; {P, G, M, Pr} -> {P, G, M, Pr} end, case bind(PathSchema, PathTokens, HostBindings, 0) of {ok, Remainder, NewBindings, Depth} -> AppRoot = calculate_app_root(Depth + ExtraDepth), StringPath = reconstitute(Remainder), PathInfo = orddict:from_list(NewBindings), RD1 = case RD of testing_ignore_dialyzer_warning_here -> testing_ignore_dialyzer_warning_here; _ -> wrq:load_dispatch_data(PathInfo, HostRemainder, Port, Remainder, AppRoot, StringPath, RD) end, case run_guard(Guard, RD1) of true -> {Mod, Props, Remainder, NewBindings, AppRoot, StringPath}; false -> try_path_binding(Rest, PathTokens, HostRemainder, Port, HostBindings, ExtraDepth, RD) end; fail -> try_path_binding(Rest, PathTokens, HostRemainder, Port, HostBindings, ExtraDepth, RD) end. run_guard(undefined, _RD) -> true; run_guard(Fun, RD) when is_function(Fun) -> try Fun(RD) == true catch _Type : Msg -> error_logger:error_msg("Error running guard ~p: ~p~n", [Fun, Msg]), throw({error_running_guard, Fun, Msg}) end; run_guard({Mod, Fun}, RD) -> try Mod:Fun(RD) == true catch _Type : Msg -> error_logger:error_msg("Error running guard ~p:~p/1: ~p~n", [Mod, Fun, Msg]), throw({error_running_guard, {Mod, Fun}, Msg}) end; run_guard(Other, _) -> error_logger:error_msg("Unknown guard type in webmachine_dispatcher: ~p~n", [Other]), throw({unknown_guard_type, Other}). bind([], [], Bindings, Depth) -> {ok, [], Bindings, Depth}; bind([?MATCH_ALL], Rest, Bindings, Depth) when is_list(Rest) -> {ok, Rest, Bindings, Depth + length(Rest)}; bind(_, [], _, _) -> fail; bind([Token|RestToken],[Match|RestMatch],Bindings,Depth) when is_atom(Token) -> bind(RestToken, RestMatch, [{Token, Match}|Bindings], Depth + 1); bind([Token|RestToken], [Token|RestMatch], Bindings, Depth) -> bind(RestToken, RestMatch, Bindings, Depth + 1); bind(_, _, _, _) -> fail. reconstitute([]) -> ""; reconstitute(UnmatchedTokens) -> string:join(UnmatchedTokens, [?SEPARATOR]). calculate_app_root(1) -> "."; calculate_app_root(N) when N > 1 -> string:join(lists:duplicate(N, ".."), [?SEPARATOR]). %% %% TEST %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -include("wm_reqstate.hrl"). -include("wm_reqdata.hrl"). app_root_test() -> ?assertEqual(".", calculate_app_root(1)), ?assertEqual("../..", calculate_app_root(2)), ?assertEqual("../../..", calculate_app_root(3)), ?assertEqual("../../../..", calculate_app_root(4)). reconstitute_test() -> ?assertEqual("", reconstitute([])), ?assertEqual("foo", reconstitute(["foo"])), ?assertEqual("foo/bar", reconstitute(["foo","bar"])), ?assertEqual("foo/bar/baz", reconstitute(["foo","bar","baz"])). split_host_test() -> ?assertEqual(["foo","bar","baz"], split_host("foo.bar.baz")). split_host_port_test() -> ?assertEqual({[], 80}, split_host_port("", http)), ?assertEqual({["foo","bar","baz"], 80}, split_host_port("foo.bar.baz:80", http)), ?assertEqual({["foo","bar","baz"], 1234}, split_host_port("foo.bar.baz:1234", http)), ?assertEqual({[], 443}, split_host_port("", https)), ?assertEqual({["foo","bar","baz"], 443}, split_host_port("foo.bar.baz", https)), ?assertEqual({["foo","bar","baz"], 1234}, split_host_port("foo.bar.baz:1234", https)). %% port binding bind_port_simple_match_test() -> ?assertEqual({ok, []}, bind_port(80, 80, [])), ?assertEqual({ok, [{foo, bar}]}, bind_port(1234, 1234, [{foo, bar}])). bind_port_matchall_test() -> ?assertEqual({ok, []}, bind_port('*', 80, [])), ?assertEqual({ok, [{foo, bar}]}, bind_port('*', 1234, [{foo, bar}])). bind_port_match_test() -> ?assertEqual({ok, [{foo, 80}]}, bind_port(foo, 80, [])), {ok, WholeBinding} = bind_port(foo, 1234, [{bar, baz}]), ?assertEqual(2, length(WholeBinding)), ?assertEqual(1234, proplists:get_value(foo, WholeBinding)), ?assertEqual(baz, proplists:get_value(bar, WholeBinding)). ind_port_fail_test() -> ?assertEqual(fail, bind_port(80, 1234, [])). %% path binding bind_path_empty_test() -> ?assertEqual({ok, [], [], 0}, bind([], [], [], 0)), ?assertEqual({ok, [], [{x,"a"}], 1}, bind([], [], [{x,"a"}], 1)). bind_path_matchall_test() -> ?assertEqual({ok, [], [], 1}, bind(['*'], [], [], 1)), ?assertEqual({ok, ["a","b"], [], 2}, bind(['*'], ["a","b"], [], 0)). bind_path_fail_longer_match_test() -> ?assertEqual(fail, bind(["x"], [], [], 0)), ?assertEqual(fail, bind([foo], [], [], 0)). bind_path_with_binding_test() -> ?assertEqual({ok, [], [{foo, "a"}], 1}, bind([foo], ["a"], [], 0)), {ok, Rest, Bind, Depth} = bind([foo,'*'], ["a","b"], [{bar, baz}], 1), ?assertEqual(["b"], Rest), ?assertEqual(3, Depth), ?assertEqual(2, length(Bind)), ?assertEqual("a", proplists:get_value(foo, Bind)), ?assertEqual(baz, proplists:get_value(bar, Bind)). bind_path_string_match_test() -> ?assertEqual({ok, [], [], 1}, bind(["a"], ["a"], [], 0)), ?assertEqual({ok, [], [{foo, bar}], 4}, bind(["a","b","c"], ["a","b","c"], [{foo, bar}], 1)). bind_path_string_fail_test() -> ?assertEqual(fail, bind(["a"], ["b"], [], 0)), ?assertEqual(fail, bind(["a","b"], ["a","c"], [], 0)). try_path_matching_test() -> RD = testing_ignore_dialyzer_warning_here, ?assertEqual({bar, baz, [], [], ".", ""}, try_path_binding([{["foo"], bar, baz}], ["foo"], [], 80, [], 0, RD)), Dispatch = [{["a", x], foo, bar}, {["b", y], baz, quux}, {["b", y, '*'], baz2, quux2}], ?assertEqual({foo, bar, [], [{x, "c"}], "../..", []}, try_path_binding(Dispatch, ["a","c"], [], 80, [], 0, RD)), ?assertEqual({baz, quux, [], [{y, "c"}], "../..", []}, try_path_binding(Dispatch, ["b","c"], [], 80, [], 0, RD)), ?assertEqual({baz2, quux2, ["z"], [{y, "c"}], "../../..", "z"}, try_path_binding(Dispatch, ["b","c","z"], [], 80, [], 0, RD)), ?assertEqual({baz2, quux2, ["z","v"], [{y, "c"}], "../../../..", "z/v"}, try_path_binding(Dispatch, ["b","c","z","v"], [], 80, [], 0, RD)). try_path_failing_test() -> RD = testing_ignore_dialyzer_warning_here, ?assertEqual({no_dispatch_match, ["a"]}, try_path_binding([{["b"], x, y}], ["a"], [], 80, [], 0, RD)). %% host binding try_host_binding_nohosts_test() -> RD = testing_ignore_dialyzer_warning_here, PathDispatches = [{["a"], foo, bar}, {["b"], baz, quux}], ?assertEqual(try_host_binding([{{['*'],'*'},PathDispatches}], ["quux","baz"], 80, ["a"], 0, RD), try_host_binding(PathDispatches, ["quux","baz"], 80, ["a"], 0, RD)), ?assertEqual(try_host_binding([{{['*'],'*'},PathDispatches}], ["quux","baz"], 80, ["b"], 0, RD), try_host_binding(PathDispatches, ["quux","baz"], 80, ["b"], 0, RD)), ?assertEqual(try_host_binding([ {{['*'],'*'},[D]} || D <- PathDispatches], ["quux","baz"], 1234, ["a"], 0, RD), try_host_binding(PathDispatches, ["quux","baz"], 1234, ["a"], 0, RD)), ?assertEqual(try_host_binding([ {{['*'],'*'},[D]} || D <- PathDispatches], ["quux","baz"], 1234, ["b"], 0, RD), try_host_binding(PathDispatches, ["quux","baz"], 1234, ["b"], 0, RD)). try_host_binding_noport_test() -> RD = testing_ignore_dialyzer_warning_here, Dispatch = [{["foo","bar"], [{["a"],x,y}]}, {["baz","quux"],[{["b"],z,q}]}, {[m,"quux"], [{["c"],r,s}]}, {['*',"quux"], [{["d"],t,u}]}], ExplicitWildPort = [ {{H, '*'},P} || {H, P} <- Dispatch ], ?assertEqual(try_host_binding(ExplicitWildPort, ["bar","foo"], 80, ["a"], 0, RD), try_host_binding(Dispatch, ["bar","foo"], 80, ["a"], 0, RD)), ?assertEqual(try_host_binding(ExplicitWildPort, ["quux","baz"], 1234, ["b"], 0, RD), try_host_binding(Dispatch, ["quux","baz"], 1234, ["b"], 0, RD)), ?assertEqual(try_host_binding(ExplicitWildPort, ["quux","yes"], 81, ["c"], 0, RD), try_host_binding(Dispatch, ["quux","yes"], 81, ["c"], 0, RD)), ?assertEqual(try_host_binding(ExplicitWildPort, ["quux","no"], 82, ["d"], 0, RD), try_host_binding(Dispatch, ["quux","no"], 82, ["d"], 0, RD)). try_host_binding_fullmatch_test() -> RD = testing_ignore_dialyzer_warning_here, Dispatch = [{{["foo","bar"],80},[{["a"],x,y}]}, {{[foo,"bar"],80}, [{["b"],z,q}]}, {{[foo,"bar"],baz}, [{["c"],r,s}]}, {{['*',"bar"],'*'}, [{["d"],t,u}]}], ?assertEqual({x, y, [], 80, [], [], ".", ""}, try_host_binding(Dispatch, ["foo","bar"], 80, ["a"], 0, RD)), ?assertEqual({z, q, [], 80, [], [{foo,"baz"}], ".", ""}, try_host_binding(Dispatch, ["baz","bar"], 80, ["b"], 0, RD)), {Mod, Props, HostRemainder, Port, PathRemainder, PathBindings, AppRoot, StringPath}= try_host_binding(Dispatch, ["quux","bar"], 1234, ["c"], 0, RD), ?assertEqual(r, Mod), ?assertEqual(s, Props), ?assertEqual("", HostRemainder), ?assertEqual(1234, Port), ?assertEqual([], PathRemainder), ?assertEqual(2, length(PathBindings)), ?assertEqual("quux", proplists:get_value(foo, PathBindings)), ?assertEqual(1234, proplists:get_value(baz, PathBindings)), ?assertEqual(".", AppRoot), ?assertEqual("", StringPath), ?assertEqual({t, u, ["foo","quux"], 80, [], [], ".", ""}, try_host_binding(Dispatch, ["foo","quux","bar"],80,["d"],0, RD)). try_host_binding_wildcard_token_order_test() -> RD = wrq:create('GET', http, {1,1}, "testing", mochiweb_headers:from_list([])), Dispatch = [{{['*',"quux","com"],80},[{['*'],x,y}]}], ?assertEqual({x,y,["foo","bar","baz"],80,[],[],".",""}, dispatch("foo.bar.baz.quux.com","/",Dispatch,RD)). try_host_binding_fail_test() -> RD = testing_ignore_dialyzer_warning_here, ?assertEqual({no_dispatch_match, {["bar","foo"], 1234}, ["x","y","z"]}, try_host_binding([], ["bar","foo"], 1234, ["x","y","z"], 0, RD)). dispatch_test() -> RD = wrq:create('GET', http, {1,1}, "testing", mochiweb_headers:from_list([])), TrueFun = fun(_) -> true end, FalseFun = fun(_) -> false end, ?assertEqual({x, y, [], 80, [], [], "../../..", ""}, dispatch("a/b/c",[{["a","b","c"],x,y}], RD)), ?assertEqual({x, y, [], 80, [], [], "../../..", ""}, dispatch("a/b/c",[{["a","b","c"],TrueFun,x,y}], RD)), ?assertEqual({no_dispatch_match, {[],80},["a","b","c"]}, dispatch("a/b/c",[{["a","b","c"],FalseFun,x,y}], RD)), ?assertEqual({x, y, [], 80, [], [], "../../..", ""}, dispatch("foo.bar", "a/b/c", [{{["foo","bar"],80},[{["a","b","c"],x,y}]}], RD)), ?assertEqual({x, y, [], 1234, [], [], "../../..", ""}, dispatch("foo.bar:1234", "a/b/", [{{["foo","bar"],1234},[{["a","b"],x,y}]}], RD)), ?assertEqual({no_dispatch_match, {["baz","bar"],8000}, ["q","r"]}, dispatch("baz.bar:8000", "q/r", [{{["foo","bar"],80},[{["a","b","c"],x,y}]}], RD)). guard1_test() -> %% Basic guard test. Match everything. Guard = fun(_) -> true end, DispatchList = [{['*'], Guard, foo, bar}], ?assertEqual( {foo, bar, [], 80, ["test"], [], ".", "test"}, dispatch("test", DispatchList, make_reqdata("/test"))), ok. guard2_test() -> %% Basic guard test. Use guard to prevent all matches. Guard = fun(_) -> false end, DispatchList = [{['*'], Guard, foo, bar}], ?assertEqual( {no_dispatch_match, {[], 80}, ["test"]}, dispatch("test", DispatchList, make_reqdata("/test"))), ok. guard3_test() -> %% Check that path_info and path_tokens are passed to the guard... Guard = fun(RD) -> ?assertEqual("a", wrq:path_info(a, RD)), ?assertEqual("b", wrq:path_info(b, RD)), ?assertEqual("c", wrq:path_info(c, RD)), ?assertEqual(["d", "e"], wrq:path_tokens(RD)), true end, DispatchList = [{[a,b,c,'*'], Guard, foo, bar}], ?assertEqual( {foo,bar,[],80, ["d","e"], [{c,"c"},{b,"b"},{a,"a"}], "../../../../..","d/e"}, dispatch("a/b/c/d/e", DispatchList, make_reqdata("/a/b/c/d/e"))), ok. guard4_test() -> %% Check that host and port are possed to the guard... Guard = fun(RD) -> ?assertEqual("0", wrq:path_info(x, RD)), ?assertEqual("0", wrq:path_info(y, RD)), ?assertEqual("1", wrq:path_info(z, RD)), ?assertEqual(80, wrq:port(RD)), true end, DispatchList= [{ {["127",x,y,z], 80}, [ {['*'], Guard, foo, bar} ] }], ?assertEqual( {foo,bar,[],80, ["a","b","c","d","e"], [{x,"0"},{y,"0"},{z,"1"}], "../../../../..","a/b/c/d/e"}, dispatch("127.0.0.1", "a/b/c/d/e", DispatchList, make_reqdata("http://127.0.0.1:80/a/b/c/d/e"))), ok. make_reqdata(Path) -> %% Helper function to construct a request and return the ReqData %% object. MochiReq = mochiweb_request:new(testing, 'GET', Path, {1, 1}, mochiweb_headers:make([])), Req = webmachine:new_request(mochiweb, MochiReq), {RD, _} = Req:get_reqdata(), RD. -endif. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/wrq.erl0000644000177700017770000003266212633765070027502 0ustar michaelmichael%% @author Justin Sheehy %% @copyright 2007-2009 Basho Technologies %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. -module(wrq). -author('Justin Sheehy '). -export([create/4, create/5,load_dispatch_data/7]). -export([method/1,scheme/1,version/1,peer/1,disp_path/1,path/1,raw_path/1, path_info/1,response_code/1,req_cookie/1,req_qs/1,req_headers/1, req_body/1,stream_req_body/2,resp_redirect/1,resp_headers/1, resp_body/1,app_root/1,path_tokens/1, host_tokens/1, port/1, base_uri/1]). -export([path_info/2,get_req_header/2,do_redirect/2,fresh_resp_headers/2, get_resp_header/2,set_resp_header/3,set_resp_headers/2, set_disp_path/2,set_req_body/2,set_resp_body/2,set_response_code/2, merge_resp_headers/2,remove_resp_header/2, append_to_resp_body/2,append_to_response_body/2, set_resp_range/2, max_recv_body/1,set_max_recv_body/2, get_cookie_value/2,get_qs_value/2,get_qs_value/3,set_peer/2, add_note/3, get_notes/1]). % @type reqdata(). The opaque data type used for req/resp data structures. -include("wm_reqdata.hrl"). -include("wm_reqstate.hrl"). create(Method,Version,RawPath,Headers) -> create(Method,http,Version,RawPath,Headers). create(Method,Scheme,Version,RawPath,Headers) -> create(#wm_reqdata{method=Method,scheme=Scheme,version=Version, raw_path=RawPath,req_headers=Headers, wm_state=defined_on_call, path="defined_in_create", req_cookie=defined_in_create, req_qs=defined_in_create, peer="defined_in_wm_req_srv_init", req_body=not_fetched_yet, max_recv_body=(1024*(1024*1024)), % Stolen from R13B03 inet_drv.c's TCP_MAX_PACKET_SIZE definition max_recv_hunk=(64*(1024*1024)), app_root="defined_in_load_dispatch_data", path_info=orddict:new(), path_tokens=defined_in_load_dispatch_data, disp_path=defined_in_load_dispatch_data, resp_redirect=false, resp_headers=mochiweb_headers:empty(), resp_body = <<>>, response_code=500, resp_range = follow_request, notes=[]}). create(RD = #wm_reqdata{raw_path=RawPath}) -> {Path, _, _} = mochiweb_util:urlsplit_path(RawPath), Cookie = case get_req_header("cookie", RD) of undefined -> []; Value -> mochiweb_cookies:parse_cookie(Value) end, {_, QueryString, _} = mochiweb_util:urlsplit_path(RawPath), ReqQS = mochiweb_util:parse_qs(QueryString), RD#wm_reqdata{path=Path,req_cookie=Cookie,req_qs=ReqQS}. load_dispatch_data(PathInfo, HostTokens, Port, PathTokens, AppRoot, DispPath, RD) -> RD#wm_reqdata{path_info=PathInfo,host_tokens=HostTokens, port=Port,path_tokens=PathTokens, app_root=AppRoot,disp_path=DispPath}. method(_RD = #wm_reqdata{method=Method}) -> Method. scheme(_RD = #wm_reqdata{scheme=Scheme}) -> Scheme. version(_RD = #wm_reqdata{version=Version}) when is_tuple(Version), size(Version) == 2, is_integer(element(1,Version)), is_integer(element(2,Version)) -> Version. peer(_RD = #wm_reqdata{peer=Peer}) when is_list(Peer) -> Peer. app_root(_RD = #wm_reqdata{app_root=AR}) when is_list(AR) -> AR. % all three paths below are strings disp_path(_RD = #wm_reqdata{disp_path=DP}) when is_list(DP) -> DP. path(_RD = #wm_reqdata{path=Path}) when is_list(Path) -> Path. raw_path(_RD = #wm_reqdata{raw_path=RawPath}) when is_list(RawPath) -> RawPath. path_info(_RD = #wm_reqdata{path_info=PathInfo}) -> PathInfo. % dict path_tokens(_RD = #wm_reqdata{path_tokens=PathT}) -> PathT. % list of strings host_tokens(_RD = #wm_reqdata{host_tokens=HostT}) -> HostT. % list of strings port(_RD = #wm_reqdata{port=Port}) -> Port. % integer response_code(_RD = #wm_reqdata{response_code={C,_ReasonPhrase}}) when is_integer(C) -> C; response_code(_RD = #wm_reqdata{response_code=C}) when is_integer(C) -> C. req_cookie(_RD = #wm_reqdata{req_cookie=C}) when is_list(C) -> C. % string %% @spec req_qs(reqdata()) -> [{Key, Value}] req_qs(_RD = #wm_reqdata{req_qs=QS}) when is_list(QS) -> QS. req_headers(_RD = #wm_reqdata{req_headers=ReqH}) -> ReqH. % mochiheaders req_body(_RD = #wm_reqdata{wm_state=ReqState0,max_recv_body=MRB}) -> Req = webmachine_request:new(ReqState0), {ReqResp, ReqState} = Req:req_body(MRB), put(tmp_reqstate, ReqState), maybe_conflict_body(ReqResp). stream_req_body(_RD = #wm_reqdata{wm_state=ReqState0}, MaxHunk) -> Req = webmachine_request:new(ReqState0), {ReqResp, ReqState} = Req:stream_req_body(MaxHunk), put(tmp_reqstate, ReqState), maybe_conflict_body(ReqResp). max_recv_body(_RD = #wm_reqdata{max_recv_body=X}) when is_integer(X) -> X. set_max_recv_body(X, RD) when is_integer(X) -> RD#wm_reqdata{max_recv_body=X}. maybe_conflict_body(BodyResponse) -> case BodyResponse of stream_conflict -> exit("wrq:req_body and wrq:stream_req_body conflict"); {error, req_body_too_large} -> exit("request body too large"); _ -> BodyResponse end. resp_redirect(_RD = #wm_reqdata{resp_redirect=true}) -> true; resp_redirect(_RD = #wm_reqdata{resp_redirect=false}) -> false. resp_headers(_RD = #wm_reqdata{resp_headers=RespH}) -> RespH. % mochiheaders resp_body(_RD = #wm_reqdata{resp_body=undefined}) -> undefined; resp_body(_RD = #wm_reqdata{resp_body={stream,X}}) -> {stream,X}; resp_body(_RD = #wm_reqdata{resp_body={known_length_stream,X,Y}}) -> {known_length_stream,X,Y}; resp_body(_RD = #wm_reqdata{resp_body={stream,X,Y}}) -> {stream,X,Y}; resp_body(_RD = #wm_reqdata{resp_body={writer,X}}) -> {writer,X}; resp_body(_RD = #wm_reqdata{resp_body=RespB}) when is_binary(RespB) -> RespB; resp_body(_RD = #wm_reqdata{resp_body=RespB}) -> iolist_to_binary(RespB). %% -- path_info(Key, RD) when is_atom(Key) -> case orddict:find(Key, path_info(RD)) of {ok, Value} when is_list(Value); is_integer(Value) -> Value; % string (for host or path match) % or integer (for port match) error -> undefined end. get_req_header(HdrName, RD) -> % string->string mochiweb_headers:get_value(HdrName, req_headers(RD)). do_redirect(true, RD) -> RD#wm_reqdata{resp_redirect=true}; do_redirect(false, RD) -> RD#wm_reqdata{resp_redirect=false}. set_peer(P, RD) when is_list(P) -> RD#wm_reqdata{peer=P}. % string set_disp_path(P, RD) when is_list(P) -> RD#wm_reqdata{disp_path=P}. % string set_req_body(Body, RD) -> RD#wm_reqdata{req_body=Body}. set_resp_body(Body, RD) -> RD#wm_reqdata{resp_body=Body}. set_response_code({Code, _ReasonPhrase}=CodeAndReason, RD) when is_integer(Code) -> RD#wm_reqdata{response_code=CodeAndReason}; set_response_code(Code, RD) when is_integer(Code) -> RD#wm_reqdata{response_code=Code}. get_resp_header(HdrName, _RD=#wm_reqdata{resp_headers=RespH}) -> mochiweb_headers:get_value(HdrName, RespH). set_resp_header(K, V, RD=#wm_reqdata{resp_headers=RespH}) when is_list(K),is_list(V) -> RD#wm_reqdata{resp_headers=mochiweb_headers:enter(K, V, RespH)}. set_resp_headers(Hdrs, RD=#wm_reqdata{resp_headers=RespH}) -> F = fun({K, V}, Acc) -> mochiweb_headers:enter(K, V, Acc) end, RD#wm_reqdata{resp_headers=lists:foldl(F, RespH, Hdrs)}. fresh_resp_headers(Hdrs, RD) -> F = fun({K, V}, Acc) -> mochiweb_headers:enter(K, V, Acc) end, RD#wm_reqdata{resp_headers=lists:foldl(F, mochiweb_headers:empty(), Hdrs)}. remove_resp_header(K, RD=#wm_reqdata{resp_headers=RespH}) when is_list(K) -> RD#wm_reqdata{resp_headers=mochiweb_headers:from_list( proplists:delete(K, mochiweb_headers:to_list(RespH)))}. merge_resp_headers(Hdrs, RD=#wm_reqdata{resp_headers=RespH}) -> F = fun({K, V}, Acc) -> mochiweb_headers:insert(K, V, Acc) end, NewHdrs = lists:foldl(F, RespH, Hdrs), RD#wm_reqdata{resp_headers=NewHdrs}. append_to_resp_body(Data, RD) -> append_to_response_body(Data, RD). append_to_response_body(Data, RD=#wm_reqdata{resp_body=RespB}) -> case is_binary(Data) of true -> Data0 = RespB, Data1 = <>, RD#wm_reqdata{resp_body=Data1}; false -> % MUST BE an iolist! else, fail. append_to_response_body(iolist_to_binary(Data), RD) end. -spec set_resp_range(follow_request | ignore_request, #wm_reqdata{}) -> #wm_reqdata{}. %% follow_request : range responce for range request, normal responce for non-range one %% ignore_request : normal resopnse for either range reuqest or non-range one set_resp_range(RespRange, RD) when RespRange =:= follow_request orelse RespRange =:= ignore_request -> RD#wm_reqdata{resp_range = RespRange}. get_cookie_value(Key, RD) when is_list(Key) -> % string case lists:keyfind(Key, 1, req_cookie(RD)) of false -> undefined; {Key, Value} -> Value end. get_qs_value(Key, RD) when is_list(Key) -> % string case lists:keyfind(Key, 1, req_qs(RD)) of false -> undefined; {Key, Value} -> Value end. get_qs_value(Key, Default, RD) when is_list(Key) -> case lists:keyfind(Key, 1, req_qs(RD)) of false -> Default; {Key, Value} -> Value end. add_note(K, V, RD) -> RD#wm_reqdata{notes=[{K, V} | RD#wm_reqdata.notes]}. get_notes(RD) -> RD#wm_reqdata.notes. base_uri(RD) -> Scheme = erlang:atom_to_list(RD#wm_reqdata.scheme), Host = string:join(RD#wm_reqdata.host_tokens, "."), PortString = port_string(RD#wm_reqdata.scheme, RD#wm_reqdata.port), Scheme ++ "://" ++ Host ++ PortString. port_string(Scheme, Port) -> case Scheme of http -> case Port of 80 -> ""; _ -> ":" ++ erlang:integer_to_list(Port) end; https -> case Port of 443 -> ""; _ -> ":" ++ erlang:integer_to_list(Port) end; _ -> ":" ++ erlang:integer_to_list(Port) end. %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). make_wrq(Method, RawPath, Headers) -> make_wrq(Method, http, RawPath, Headers). make_wrq(Method, Scheme, RawPath, Headers) -> create(Method, Scheme, {1,1}, RawPath, mochiweb_headers:from_list(Headers)). accessor_test() -> R0 = make_wrq('GET', "/foo?a=1&b=2", [{"Cookie", "foo=bar"}]), R = set_peer("127.0.0.1", R0), ?assertEqual('GET', method(R)), ?assertEqual({1,1}, version(R)), ?assertEqual("/foo", path(R)), ?assertEqual("/foo?a=1&b=2", raw_path(R)), ?assertEqual([{"a", "1"}, {"b", "2"}], req_qs(R)), ?assertEqual({"1", "2"}, {get_qs_value("a", R), get_qs_value("b", R)}), ?assertEqual("3", get_qs_value("c", "3", R)), ?assertEqual([{"foo", "bar"}], req_cookie(R)), ?assertEqual("bar", get_cookie_value("foo", R)), ?assertEqual("127.0.0.1", peer(R)). simple_dispatch_test() -> R0 = make_wrq('GET', "/foo?a=1&b=2", [{"Cookie", "foo=bar"}]), R1 = set_peer("127.0.0.1", R0), {_, _, HostTokens, Port, PathTokens, Bindings, AppRoot, StringPath} = webmachine_dispatcher:dispatch("127.0.0.1", "/foo", [{["foo"], foo_resource, []}], R1), R = load_dispatch_data(Bindings, HostTokens, Port, PathTokens, AppRoot, StringPath, R1), ?assertEqual(".", app_root(R)), ?assertEqual(80, port(R)), ?assertEqual("http://127.0.0.1", base_uri(R)). base_uri_test_() -> Make_req = fun(Scheme, Host) -> R0 = make_wrq('GET', Scheme, "/foo?a=1&b=2", [{"Cookie", "foo=bar"}]), R1 = set_peer("127.0.0.1", R0), DispatchRule = {["foo"], foo_resource, []}, {_, _, HostTokens, Port, PathTokens, Bindings, AppRoot,StringPath} = webmachine_dispatcher:dispatch(Host, "/foo", [DispatchRule], R1), load_dispatch_data(Bindings, HostTokens, Port, PathTokens, AppRoot, StringPath, R1) end, Tests = [{{http, "somewhere.com:8080"}, "http://somewhere.com:8080"}, {{https, "somewhere.com:8080"}, "https://somewhere.com:8080"}, {{http, "somewhere.com"}, "http://somewhere.com"}, {{https, "somewhere.com"}, "https://somewhere.com"}, {{http, "somewhere.com:80"}, "http://somewhere.com"}, {{https, "somewhere.com:443"}, "https://somewhere.com"}, {{https, "somewhere.com:80"}, "https://somewhere.com:80"}, {{http, "somewhere.com:443"}, "http://somewhere.com:443"}], [ ?_assertEqual(Expect, base_uri(Make_req(Scheme, Host))) || {{Scheme, Host}, Expect} <- Tests ]. -endif. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_app.erl0000644000177700017770000000325512633765070031627 0ustar michaelmichael%% @author Justin Sheehy %% @author Andy Gross %% @copyright 2007-2008 Basho Technologies %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% @doc Callbacks for the webmachine application. -module(webmachine_app). -author('Justin Sheehy '). -author('Andy Gross '). -behaviour(application). -export([start/2, stop/1]). -include("webmachine_logger.hrl"). %% @spec start(_Type, _StartArgs) -> ServerRet %% @doc application start callback for webmachine. start(_Type, _StartArgs) -> webmachine_deps:ensure(), {ok, _Pid} = SupLinkRes = webmachine_sup:start_link(), Handlers = case application:get_env(webmachine, log_handlers) of undefined -> []; {ok, Val} -> Val end, %% handlers failing to start are handled in the handler_watcher _ = [supervisor:start_child(webmachine_logger_watcher_sup, [?EVENT_LOGGER, Module, Config]) || {Module, Config} <- Handlers], SupLinkRes. %% @spec stop(_State) -> ServerRet %% @doc application stop callback for webmachine. stop(_State) -> ok. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_multipart.erl0000644000177700017770000003311312633765070033064 0ustar michaelmichael%% @author Justin Sheehy %% @author Andy Gross %% @copyright 2009 Basho Technologies %% @doc Utility for parsing multipart form bodies. %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% http://www.apache.org/licenses/LICENSE-2.0 %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. -module(webmachine_multipart). -author('Justin Sheehy '). -author('Andy Gross '). -export([get_all_parts/2,stream_parts/2, find_boundary/1]). % @type incoming_req_body() = binary(). % The request body, in "multipart/form-data" (rfc2388) form, % @type boundary() = string(). % The multipart boundary, as taken from the containing message's content-type. % @type fpart() = {fpartname(), {[fparam()],[fheader()]}, fcontent()}. % A single part of a multipart form. % @type fpartname() = string(). % The name from the form field of a form part. % @type fparam() = {binary(), binary()}. % A key-value parameter from the content-disposition header in a form part. % @type fheader() = {binary(), binary()}. % A header name and value supplied within a form part. % @type fcontent() = binary(). % The body content within a form part. % @doc Find the multipart boundary for a request. % @spec find_boundary(wrq:wm_reqdata()) -> boundary() find_boundary(ReqData) -> ContentType = wrq:get_req_header("content-type", ReqData), string:substr(ContentType, string:str(ContentType, "boundary=") + length("boundary=")). % @doc Turn a multipart form into component parts. % @spec get_all_parts(incoming_req_body(), boundary()) -> [fpart()] get_all_parts(Body, Boundary) when is_binary(Body), is_list(Boundary) -> StreamStruct = send_streamed_body(Body,1024), getparts1(stream_parts(StreamStruct, Boundary), []). % @doc Similar to get_all_parts/2, but for streamed/chunked bodies. % Takes as input the result of wrq:stream_req_body/2, and provides % either the atom 'done_parts' when no more parts are available, or % a tuple with the next part and a function. That function will % have 0-arity and the same return type as stream_parts/2 itself. % @spec stream_parts(wm_stream(), boundary()) -> % 'done_parts' | {fpart(), function()} stream_parts(StreamStruct, Boundary) -> stream_form(StreamStruct, "--" ++ Boundary, []). stream_form(_, _, [<<"----\n">>|_]) -> done_parts; stream_form(_, _, [<<"--\n">>|_]) -> done_parts; stream_form({Hunk, Next}, Boundary, []) -> stream_form(get_more_data(Next), Boundary, re:split(Hunk, Boundary,[])); stream_form({Hunk, Next}, Boundary, [<<>>|DQ]) -> stream_form({Hunk, Next}, Boundary, DQ); stream_form({Hunk, Next}, Boundary, [H|[T1|T2]]) -> {make_part(H), fun() -> stream_form({Hunk, Next}, Boundary, [T1|T2]) end}; stream_form({Hunk, really_done}, Boundary, DQ) -> DQBin = iolist_to_binary(DQ), FullHunk = <>, stream_parts(re:split(FullHunk, Boundary,[])); stream_form({Hunk, Next}, Boundary, [Single]) -> FullHunk = <>, stream_form(get_more_data(Next), Boundary, re:split(FullHunk, Boundary,[])). stream_parts([]) -> done_parts; % browsers are fun, and terminate posts slightly differently from each other: stream_parts([<<"----\n">>]) -> done_parts; stream_parts([<<"--\n">>]) -> done_parts; stream_parts([<<"----\r\n">>]) -> done_parts; stream_parts([<<"--\r\n">>]) -> done_parts; stream_parts([<<"--\r\n--\n">>]) -> done_parts; stream_parts([<<"--\r\n--\r\n">>]) -> done_parts; stream_parts([H|T]) -> {make_part(H), fun() -> stream_parts(T) end}. get_more_data(done) -> {<<"--\n">>, really_done}; get_more_data(Fun) -> Fun(). make_part(PartData) -> %% Remove the trailing \r\n [HeadData, BodyWithCRLF] = re:split(PartData, "\\r\\n\\r\\n", [{parts,2}]), BodyLen = size(BodyWithCRLF) - 2, <> = BodyWithCRLF, HeadList = [list_to_binary(X) || X <- string:tokens(binary_to_list(HeadData), "\r\n")], {Name, Params, Headers} = make_headers(HeadList), {Name, {Params,Headers}, Body}. make_headers(X) -> make_headers(X, name_undefined, params_undefined, []). make_headers([], Name, Params, Headers) -> {Name, Params, Headers}; make_headers([<<>>|HL], Name, Params, Headers) -> make_headers(HL, Name, Params, Headers); make_headers( [<<"Content-Disposition: form-data; ", Names/binary>>|HL], _, _, Headers) -> {Name, Params} = extract_names(Names), make_headers(HL, Name, Params, Headers); make_headers([H|HL], Name, Params, Headers) -> make_headers(HL, Name, Params, [cheap_parse_header(H)|Headers]). extract_names(NamesString) -> Params = [{K, V} || {K, [<<>>, V, <<>>]} <- [{K0, re:split(V0,"\"",[])} || [K0, V0] <- [re:split(N, "=", [{parts, 2}]) || N <- re:split(NamesString, "; ", [])]]], Name = hd([binary_to_list(V) || {<<"name">>,V} <- Params]), {Name, Params}. cheap_parse_header(HeadBin) -> [K,V] = re:split(HeadBin, ": ", [{parts,2}]), {K,V}. getparts1(done_parts, Acc) -> lists:reverse(Acc); getparts1({Part, Streamer}, Acc) -> getparts1(Streamer(), [Part|Acc]). send_streamed_body(Body, Max) -> HunkLen=8*Max, case Body of <> -> {<>, fun() -> send_streamed_body(Rest,Max) end}; _ -> {Body, done} end. %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). body_test() -> Body = <<"------------ae0gL6gL6Ij5KM7Ef1KM7ei4ae0cH2\r\nContent-Disposition: form-data; name=\"Filename\"\r\n\r\ntestfile.txt\r\n------------ae0gL6gL6Ij5KM7Ef1KM7ei4ae0cH2\r\nContent-Disposition: form-data; name=\"Filedata\"; filename=\"testfile.txt\"\r\nContent-Type: application/octet-stream\r\n\r\n%%% The contents of this file are a test,\n%%% do not be alarmed.\n\r\n------------ae0gL6gL6Ij5KM7Ef1KM7ei4ae0cH2\r\nContent-Disposition: form-data; name=\"Upload\"\r\n\r\nSubmit Query\r\n------------ae0gL6gL6Ij5KM7Ef1KM7ei4ae0cH2--">>, Boundary = "----------ae0gL6gL6Ij5KM7Ef1KM7ei4ae0cH2", ?assertEqual( [{"Filename", {[{<<"name">>,<<"Filename">>}],[]}, <<"testfile.txt">>}, {"Filedata", {[{<<"name">>,<<"Filedata">>}, {<<"filename">>,<<"testfile.txt">>}], [{<<"Content-Type">>,<<"application/octet-stream">>}]}, <<"%%% The contents of this file are a test,\n%%% do not be alarmed.\n">>}, {"Upload",{[{<<"name">>,<<"Upload">>}],[]}, <<"Submit Query">>}], get_all_parts(Body, Boundary)). body2_test() -> Body = <<"-----------------------------89205314411538515011004844897\r\nContent-Disposition: form-data; name=\"Filedata\"; filename=\"akamai.txt\"\r\nContent-Type: text/plain\r\n\r\nCAMBRIDGE, MA - February 18, 2009 - Akamai Technologies, Inc. (NASDAQ: AKAM), the leader in powering rich media, dynamic transactions and enterprise applications online, today announced that its Service & Support organization was awarded top honors for Innovation in Customer Service at the 3rd Annual Stevie Awards for Sales & Customer Service, an international competition recognizing excellence in disciplines that are crucial to business success.\n\n\"We have always set incredibly high standards with respect to the service and support we provide our customers,\" said Sanjay Singh, vice president of Global Service & Support at Akamai. \"Our support team provides highly responsive service around the clock to our global customer base and, as a result, has become an extension of our customers' online businesses. This prestigious award is validation of Akamai's commitment to customer service and technical support.\"\n\nAkamai Service & Support professionals are dedicated to working with customers on a daily basis to fine tune, optimize, and support their Internet initiatives. Akamai's winning submission highlighted the key pillars of its service and support offering, as well as the initiatives established to meet customer requirements for proactive communication, simplification, and faster response times.\n\n\"This year's honorees demonstrate that even in challenging economic times, it's possible for organizations to continue to shine in sales and customer service, the two most important functions in business: acquiring and keeping customers,\" said Michael Gallagher, president of the Stevie Awards.\n\nThe awards are presented by the Stevie Awards, which organizes several of the world's leading business awards shows, including the prestigious American Business Awards. Nicknamed the Stevies for the Greek word \"crowned,\" winners were announced during a gala banquet on Monday, February 9 at Caesars Palace in Las Vegas. Nominated customer service and sales executives from the U.S.A. and several other countries attended. More than 500 entries from companies of all sizes and in virtually every industry were submitted to this year's competition. There are 27 categories for customer service professionals, as well as 41 categories for sales professionals.\n\nDetails about the Stevie Awards for Sales & Customer Service and the list of honorees in all categories are available at www.stevieawards.com/sales. \n\r\n-----------------------------89205314411538515011004844897--\r\n">>, Boundary = "---------------------------89205314411538515011004844897", ?assertEqual( [{"Filedata", {[{<<"name">>,<<"Filedata">>}, {<<"filename">>,<<"akamai.txt">>}], [{<<"Content-Type">>,<<"text/plain">>}]}, <<"CAMBRIDGE, MA - February 18, 2009 - Akamai Technologies, Inc. (NASDAQ: AKAM), the leader in powering rich media, dynamic transactions and enterprise applications online, today announced that its Service & Support organization was awarded top honors for Innovation in Customer Service at the 3rd Annual Stevie Awards for Sales & Customer Service, an international competition recognizing excellence in disciplines that are crucial to business success.\n\n\"We have always set incredibly high standards with respect to the service and support we provide our customers,\" said Sanjay Singh, vice president of Global Service & Support at Akamai. \"Our support team provides highly responsive service around the clock to our global customer base and, as a result, has become an extension of our customers' online businesses. This prestigious award is validation of Akamai's commitment to customer service and technical support.\"\n\nAkamai Service & Support professionals are dedicated to working with customers on a daily basis to fine tune, optimize, and support their Internet initiatives. Akamai's winning submission highlighted the key pillars of its service and support offering, as well as the initiatives established to meet customer requirements for proactive communication, simplification, and faster response times.\n\n\"This year's honorees demonstrate that even in challenging economic times, it's possible for organizations to continue to shine in sales and customer service, the two most important functions in business: acquiring and keeping customers,\" said Michael Gallagher, president of the Stevie Awards.\n\nThe awards are presented by the Stevie Awards, which organizes several of the world's leading business awards shows, including the prestigious American Business Awards. Nicknamed the Stevies for the Greek word \"crowned,\" winners were announced during a gala banquet on Monday, February 9 at Caesars Palace in Las Vegas. Nominated customer service and sales executives from the U.S.A. and several other countries attended. More than 500 entries from companies of all sizes and in virtually every industry were submitted to this year's competition. There are 27 categories for customer service professionals, as well as 41 categories for sales professionals.\n\nDetails about the Stevie Awards for Sales & Customer Service and the list of honorees in all categories are available at www.stevieawards.com/sales. \n">> }], get_all_parts(Body,Boundary)). firefox_test() -> Body = <<"-----------------------------823378840143542612896544303\r\nContent-Disposition: form-data; name=\"upload-test\"; filename=\"abcdef.txt\"\r\nContent-Type: text/plain\r\n\r\n01234567890123456789012345678901234567890123456789\r\n-----------------------------823378840143542612896544303--\r\n">>, Boundary = "---------------------------823378840143542612896544303", ?assertEqual( [{"upload-test", {[{<<"name">>,<<"upload-test">>}, {<<"filename">>,<<"abcdef.txt">>}], [{<<"Content-Type">>,<<"text/plain">>}]}, <<"01234567890123456789012345678901234567890123456789">>}], get_all_parts(Body,Boundary)). chrome_test() -> Body = <<"------WebKitFormBoundaryIHB9Xyi7ZCNKJusP\r\nContent-Disposition: form-data; name=\"upload-test\"; filename=\"abcdef.txt\"\r\nContent-Type: text/plain\r\n\r\n01234567890123456789012345678901234567890123456789\r\n------WebKitFormBoundaryIHB9Xyi7ZCNKJusP--\r\n">>, Boundary = "----WebKitFormBoundaryIHB9Xyi7ZCNKJusP", ?assertEqual( [{"upload-test", {[{<<"name">>,<<"upload-test">>}, {<<"filename">>,<<"abcdef.txt">>}], [{<<"Content-Type">>,<<"text/plain">>}]}, <<"01234567890123456789012345678901234567890123456789">>}], get_all_parts(Body,Boundary)). -endif. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_resource.erl0000644000177700017770000002062412633765070032675 0ustar michaelmichael%% @author Justin Sheehy %% @author Andy Gross %% @copyright 2007-2012 Basho Technologies %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. -module(webmachine_resource). -author('Justin Sheehy '). -author('Andy Gross '). -export([new/4, wrap/2, wrap/3]). -export([do/3,log_d/2,stop/1]). -include("wm_resource.hrl"). -include("wm_reqdata.hrl"). -include("wm_reqstate.hrl"). new(R_Mod, R_ModState, R_ModExports, R_Trace) -> {?MODULE, R_Mod, R_ModState, R_ModExports, R_Trace}. default(ping) -> no_default; default(service_available) -> true; default(resource_exists) -> true; default(auth_required) -> true; default(is_authorized) -> true; default(forbidden) -> false; default(allow_missing_post) -> false; default(malformed_request) -> false; default(uri_too_long) -> false; default(known_content_type) -> true; default(valid_content_headers) -> true; default(valid_entity_length) -> true; default(options) -> []; default(allowed_methods) -> ['GET', 'HEAD']; default(known_methods) -> ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'TRACE', 'CONNECT', 'OPTIONS']; default(content_types_provided) -> [{"text/html", to_html}]; default(content_types_accepted) -> []; default(delete_resource) -> false; default(delete_completed) -> true; default(post_is_create) -> false; default(create_path) -> undefined; default(base_uri) -> undefined; default(process_post) -> false; default(language_available) -> true; default(charsets_provided) -> no_charset; % this atom causes charset-negotation to short-circuit % the default setting is needed for non-charset responses such as image/png % an example of how one might do actual negotiation % [{"iso-8859-1", fun(X) -> X end}, {"utf-8", make_utf8}]; default(encodings_provided) -> [{"identity", fun(X) -> X end}]; % this is handy for auto-gzip of GET-only resources: % [{"identity", fun(X) -> X end}, {"gzip", fun(X) -> zlib:gzip(X) end}]; default(variances) -> []; default(is_conflict) -> false; default(multiple_choices) -> false; default(previously_existed) -> false; default(moved_permanently) -> false; default(moved_temporarily) -> false; default(last_modified) -> undefined; default(expires) -> undefined; default(generate_etag) -> undefined; default(finish_request) -> true; default(validate_content_checksum) -> not_validated; default(_) -> no_default. wrap(Mod, Args, {?MODULE, _, _, _, _}) -> wrap(Mod, Args). wrap(Mod, Args) -> case Mod:init(Args) of {ok, ModState} -> {ok, webmachine_resource:new(Mod, ModState, orddict:from_list(Mod:module_info(exports)), false)}; {{trace, Dir}, ModState} -> {ok, File} = open_log_file(Dir, Mod), log_decision(File, v3b14), log_call(File, attempt, Mod, init, Args), log_call(File, result, Mod, init, {{trace, Dir}, ModState}), {ok, webmachine_resource:new(Mod, ModState, orddict:from_list(Mod:module_info(exports)), File)}; _ -> {stop, bad_init_arg} end. do(#wm_resource{}=Res, Fun, ReqProps) -> #wm_resource{module=R_Mod, modstate=R_ModState, modexports=R_ModExports, trace=R_Trace} = Res, do(Fun, ReqProps, {?MODULE, R_Mod, R_ModState, R_ModExports, R_Trace}); do(Fun, ReqProps, {?MODULE, R_Mod, _, R_ModExports, R_Trace}=Req) when is_atom(Fun) andalso is_list(ReqProps) -> case lists:keyfind(reqstate, 1, ReqProps) of false -> RState0 = undefined; {reqstate, RState0} -> ok end, put(tmp_reqstate, empty), {Reply, ReqData, NewModState} = handle_wm_call(Fun, (RState0#wm_reqstate.reqdata)#wm_reqdata{wm_state=RState0}, Req), ReqState = case get(tmp_reqstate) of empty -> RState0; X -> X end, %% Do not need the embedded state anymore TrimData = ReqData#wm_reqdata{wm_state=undefined}, {Reply, webmachine_resource:new(R_Mod, NewModState, R_ModExports, R_Trace), ReqState#wm_reqstate{reqdata=TrimData}}. handle_wm_call(Fun, ReqData, {?MODULE,R_Mod,R_ModState,R_ModExports,R_Trace}=Req) -> case default(Fun) of no_default -> resource_call(Fun, ReqData, Req); Default -> case orddict:is_key(Fun, R_ModExports) of true -> resource_call(Fun, ReqData, Req); false -> if is_pid(R_Trace) -> log_call(R_Trace, not_exported, R_Mod, Fun, [ReqData, R_ModState]); true -> ok end, {Default, ReqData, R_ModState} end end. trim_trace([{M,F,[RD = #wm_reqdata{},S]}|STRest]) -> TrimState = (RD#wm_reqdata.wm_state)#wm_reqstate{reqdata='REQDATA'}, TrimRD = RD#wm_reqdata{wm_state=TrimState}, [{M,F,[TrimRD,S]}|STRest]; trim_trace(X) -> X. resource_call(F, ReqData, {?MODULE, R_Mod, R_ModState, _, R_Trace}) -> case R_Trace of false -> nop; _ -> log_call(R_Trace, attempt, R_Mod, F, [ReqData, R_ModState]) end, Result = try apply(R_Mod, F, [ReqData, R_ModState]) catch C:R -> Reason = {C, R, trim_trace(erlang:get_stacktrace())}, {{error, Reason}, ReqData, R_ModState} end, case R_Trace of false -> nop; _ -> log_call(R_Trace, result, R_Mod, F, Result) end, Result. log_d(#wm_resource{}=Res, DecisionID) -> #wm_resource{module=R_Mod, modstate=R_ModState, modexports=R_ModExports, trace=R_Trace} = Res, log_d(DecisionID, {?MODULE, R_Mod, R_ModState, R_ModExports, R_Trace}); log_d(DecisionID, {?MODULE, _, _, _, R_Trace}) -> case R_Trace of false -> nop; _ -> log_decision(R_Trace, DecisionID) end. stop(#wm_resource{trace=R_Trace}) -> close_log_file(R_Trace); stop({?MODULE, _, _, _, R_Trace}) -> close_log_file(R_Trace). log_call(File, Type, M, F, Data) -> io:format(File, "{~p, ~p, ~p,~n ~p}.~n", [Type, M, F, escape_trace_data(Data)]). escape_trace_data(Fun) when is_function(Fun) -> {'WMTRACE_ESCAPED_FUN', [erlang:fun_info(Fun, module), erlang:fun_info(Fun, name), erlang:fun_info(Fun, arity), erlang:fun_info(Fun, type)]}; escape_trace_data(Pid) when is_pid(Pid) -> {'WMTRACE_ESCAPED_PID', pid_to_list(Pid)}; escape_trace_data(Port) when is_port(Port) -> {'WMTRACE_ESCAPED_PORT', erlang:port_to_list(Port)}; escape_trace_data(List) when is_list(List) -> escape_trace_list(List, []); escape_trace_data(R=#wm_reqstate{}) -> list_to_tuple( escape_trace_data( tuple_to_list(R#wm_reqstate{reqdata='WMTRACE_NESTED_REQDATA'}))); escape_trace_data(Tuple) when is_tuple(Tuple) -> list_to_tuple(escape_trace_data(tuple_to_list(Tuple))); escape_trace_data(Other) -> Other. escape_trace_list([Head|Tail], Acc) -> escape_trace_list(Tail, [escape_trace_data(Head)|Acc]); escape_trace_list([], Acc) -> %% proper, nil-terminated list lists:reverse(Acc); escape_trace_list(Final, Acc) -> %% non-nil-terminated list, like the dict module uses lists:reverse(tl(Acc))++[hd(Acc)|escape_trace_data(Final)]. log_decision(File, DecisionID) -> io:format(File, "{decision, ~p}.~n", [DecisionID]). open_log_file(Dir, Mod) -> Now = {_,_,US} = now(), {{Y,M,D},{H,I,S}} = calendar:now_to_universal_time(Now), Filename = io_lib:format( "~s/~p-~4..0B-~2..0B-~2..0B" "-~2..0B-~2..0B-~2..0B.~6..0B.wmtrace", [Dir, Mod, Y, M, D, H, I, S, US]), file:open(Filename, [write]). close_log_file(File) when is_pid(File) -> file:close(File); close_log_file(_) -> ok. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine.erl0000644000177700017770000000566512633765070030776 0ustar michaelmichael%% @author Justin Sheehy %% @author Andy Gross %% @copyright 2007-2009 Basho Technologies %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. -module(webmachine). -author('Justin Sheehy '). -author('Andy Gross '). -export([start/0, stop/0]). -export([new_request/2]). -include("webmachine_logger.hrl"). -include("wm_reqstate.hrl"). -include("wm_reqdata.hrl"). %% @spec start() -> ok %% @doc Start the webmachine server. start() -> webmachine_deps:ensure(), application:start(webmachine). %% @spec stop() -> ok %% @doc Stop the webmachine server. stop() -> application:stop(webmachine). new_request(mochiweb, Request) -> Method = Request:get(method), Scheme = Request:get(scheme), Version = Request:get(version), {Headers, RawPath} = case application:get_env(webmachine, rewrite_module) of {ok, RewriteMod} -> do_rewrite(RewriteMod, Method, Scheme, Version, Request:get(headers), Request:get(raw_path)); undefined -> {Request:get(headers), Request:get(raw_path)} end, Socket = Request:get(socket), InitState = #wm_reqstate{socket=Socket, reqdata=wrq:create(Method,Scheme,Version,RawPath,Headers)}, InitReq = {webmachine_request,InitState}, {Peer, ReqState} = InitReq:get_peer(), PeerState = ReqState#wm_reqstate{reqdata=wrq:set_peer(Peer, ReqState#wm_reqstate.reqdata)}, LogData = #wm_log_data{start_time=now(), method=Method, headers=Headers, peer=PeerState#wm_reqstate.peer, path=RawPath, version=Version, response_code=404, response_length=0}, webmachine_request:new(PeerState#wm_reqstate{log_data=LogData}). do_rewrite(RewriteMod, Method, Scheme, Version, Headers, RawPath) -> case RewriteMod:rewrite(Method, Scheme, Version, Headers, RawPath) of %% only raw path has been rewritten (older style rewriting) NewPath when is_list(NewPath) -> {Headers, NewPath}; %% headers and raw path rewritten (new style rewriting) {NewHeaders, NewPath} -> {NewHeaders,NewPath} end. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/wmtrace_resource.erl0000755000177700017770000003120212633765070032232 0ustar michaelmichael%% @author Bryan Fink %% @doc Webmachine trace file interpretter. -module(wmtrace_resource). -export([add_dispatch_rule/2, remove_dispatch_rules/0]). -export([ping/2, init/1, resource_exists/2, content_types_provided/2, produce_html/2, produce_javascript/2, produce_map/2, produce_css/2]). -include("wm_reqdata.hrl"). -record(ctx, {trace_dir, trace}). -define(MAP_EXTERNAL, "static/map.png"). -define(MAP_INTERNAL, "http-headers-status-v3.png"). -define(SCRIPT_EXTERNAL, "static/wmtrace.js"). -define(SCRIPT_INTERNAL, "wmtrace.js"). -define(STYLE_EXTERNAL, "static/wmtrace.css"). -define(STYLE_INTERNAL, "wmtrace.css"). %% %% Dispatch Modifiers %% %% @spec add_dispatch_rule(string(), string()) -> ok %% @doc Add a dispatch rule to point at wmtrace_resource. %% Example: to serve wmtrace_resource from %% http://yourhost/dev/wmtrace/ %% with trace files on disk at %% priv/traces %% call: %% add_dispatch_rule("dev/wmtrace", "priv/traces") add_dispatch_rule(BasePath, TracePath) when is_list(BasePath), is_list(TracePath) -> Parts = string:tokens(BasePath, "/"), webmachine_router:add_route({Parts ++ ['*'], ?MODULE, [{trace_dir, TracePath}]}). %% @spec remove_dispatch_rules() -> ok %% @doc Remove all dispatch rules pointing to wmtrace_resource. remove_dispatch_rules() -> webmachine_router:remove_resource(?MODULE). %% %% Resource %% ping(ReqData, State) -> {pong, ReqData, State}. init(Config) -> {trace_dir, TraceDir} = proplists:lookup(trace_dir, Config), {trace_dir_exists, true} = {trace_dir_exists, filelib:is_dir(TraceDir)}, {ok, #ctx{trace_dir=TraceDir}}. resource_exists(RD, Ctx) -> case wrq:disp_path(RD) of [] -> case lists:reverse(wrq:raw_path(RD)) of [$/|_] -> {true, RD, Ctx}; _ -> {{halt, 303}, wrq:set_resp_header("Location", wrq:raw_path(RD)++"/", RD), Ctx} end; ?MAP_EXTERNAL -> {filelib:is_file(wm_path(?MAP_INTERNAL)), RD, Ctx}; ?SCRIPT_EXTERNAL -> {filelib:is_file(wm_path(?SCRIPT_INTERNAL)), RD, Ctx}; ?STYLE_EXTERNAL -> {filelib:is_file(wm_path(?STYLE_INTERNAL)), RD, Ctx}; TraceName -> TracePath = filename:join([Ctx#ctx.trace_dir, TraceName]), {filelib:is_file(TracePath), RD, Ctx#ctx{trace=TracePath}} end. wm_path(File) -> filename:join([code:priv_dir(webmachine), "trace", File]). content_types_provided(RD, Ctx) -> case wrq:disp_path(RD) of ?MAP_EXTERNAL -> {[{"image/png", produce_map}], RD, Ctx}; ?SCRIPT_EXTERNAL -> {[{"text/javascript", produce_javascript}], RD, Ctx}; ?STYLE_EXTERNAL -> {[{"text/css", produce_css}], RD, Ctx}; _ -> {[{"text/html", produce_html}], RD, Ctx} end. produce_html(RD, Ctx=#ctx{trace=undefined}) -> Dir = filename:absname(Ctx#ctx.trace_dir), Files = lists:reverse( lists:sort( filelib:fold_files(Dir, ".*\.wmtrace", false, fun(F, Acc) -> [filename:basename(F)|Acc] end, []))), {trace_list_html(Dir, Files), RD, Ctx}; produce_html(RD, Ctx) -> Filename = filename:absname(Ctx#ctx.trace), {ok, Data} = file:consult(Filename), {trace_html(Filename, Data), RD, Ctx}. trace_list_html(Dir, Files) -> html([], [head([], title([], ["Webmachine Trace List for ",Dir])), body([], [h1([], ["Traces in ",Dir]), ul([], [ li([], a([{"href", F}], F)) || F <- Files ]) ]) ]). trace_html(Filename, Data) -> {Request, Response, Trace} = encode_trace(Data), html([], [head([], [title([],["Webmachine Trace ",Filename]), linkblock([{"rel", "stylesheet"}, {"type", "text/css"}, {"href", "static/wmtrace.css"}], []), script([{"type", "text/javascript"}, {"src", "static/wmtrace.js"}], []), script([{"type", "text/javascript"}], mochiweb_html:escape( lists:flatten( ["var request=",Request,";\n" "var response=",Response,";\n" "var trace=",Trace,";"]))) ]), body([], [divblock([{"id", "zoompanel"}], [button([{"id", "zoomout"}], ["zoom out"]), button([{"id", "zoomin"}], ["zoom in"]) ]), canvas([{"id", "v3map"}, {"width", "3138"}, {"height", "2184"}], []), divblock([{"id", "sizetest"}], []), divblock([{"id", "preview"}], [divblock([{"id", "previewid"}],[]), ul([{"id", "previewcalls"}], []) ]), divblock([{"id", "infopanel"}], [divblock([{"id", "infocontrols"}], [divblock([{"id", "requesttab"}, {"class", "selectedtab"}],"Q"), divblock([{"id", "responsetab"}], "R"), divblock([{"id", "decisiontab"}], "D") ]), divblock([{"id", "requestdetail"}], [divblock([], [span([{"id", "requestmethod"}], []), " ", span([{"id", "requestpath"}], [])]), ul([{"id", "requestheaders"}], []), divblock([{"id", "requestbody"}], []) ]), divblock([{"id", "responsedetail"}], [divblock([{"id", "responsecode"}], []), ul([{"id", "responseheaders"}], []), divblock([{"id", "responsebody"}], []) ]), divblock([{"id", "decisiondetail"}], [divblock([], ["Decision: ", select([{"id", "decisionid"}], []) ]), divblock([], ["Calls:", select([{"id", "decisioncalls"}], []) ]), divblock([], "Input:"), pre([{"id", "callinput"}], []), divblock([], "Output:"), pre([{"id", "calloutput"}], []) ]) ]) ]) ]). produce_javascript(RD, Ctx) -> {ok, Script} = file:read_file(wm_path(?SCRIPT_INTERNAL)), {Script, RD, Ctx}. produce_map(RD, Ctx) -> {ok, Map} = file:read_file(wm_path(?MAP_INTERNAL)), {Map, RD, Ctx}. produce_css(RD, Ctx) -> {ok, Script} = file:read_file(wm_path(?STYLE_INTERNAL)), {Script, RD, Ctx}. %% %% Trace Encoding %% encode_trace(Data) -> {Request, Response, Trace} = aggregate_trace(Data), {mochijson:encode(encode_request(Request)), mochijson:encode(encode_response(Response)), mochijson:encode({array, [ encode_trace_part(P) || P <- Trace ]})}. aggregate_trace(RawTrace) -> {Request, Response, Trace} = lists:foldl(fun aggregate_trace_part/2, {undefined, 500, []}, RawTrace), {Request, Response, lists:reverse(Trace)}. aggregate_trace_part({decision, Decision}, {Q, R, Acc}) -> BDN = base_decision_name(Decision), case Acc of [{BDN,_}|_] -> {Q, R, Acc}; %% subdecision (ex. v3b13b) _ -> {Q, R, [{base_decision_name(Decision), []}|Acc]} end; aggregate_trace_part({attempt, Module, Function, Args}, {Q, R, [{Decision,Calls}|Acc]}) -> {maybe_extract_request(Function, Args, Q), R, [{Decision,[{Module, Function, Args, wmtrace_null}|Calls]}|Acc]}; aggregate_trace_part({result, Module, Function, Result}, {Q, R, [{Decision,[{Module,Function,Args,_}|Calls]}|Acc]}) -> {Q, maybe_extract_response(Function, Result, R), [{Decision,[{Module, Function, Args, Result}|Calls]}|Acc]}; aggregate_trace_part({not_exported, Module, Function, Args}, {Q, R, [{Decision,Calls}|Acc]}) -> {Q, maybe_extract_response(Function, Args, R), [{Decision,[{Module, Function, Args, wmtrace_not_exported}|Calls]} |Acc]}. maybe_extract_request(ping, [ReqData,_], _) -> ReqData; maybe_extract_request(_, _, R) -> R. maybe_extract_response(finish_request, [ReqData,_], _) -> ReqData; maybe_extract_response(finish_request, {_, ReqData, _}, _) -> ReqData; maybe_extract_response(_, _, R) -> R. base_decision_name(Decision) -> [$v,$3|D] = atom_to_list(Decision), %% strip 'v3' case lists:reverse(D) of [A|RD] when A >= $a, A =< $z -> lists:reverse(RD); %% strip 'b' off end of some _ -> D end. encode_request(ReqData) when is_record(ReqData, wm_reqdata) -> {struct, [{"method", atom_to_list( wrq:method(ReqData))}, {"path", wrq:raw_path(ReqData)}, {"headers", encode_headers(wrq:req_headers(ReqData))}, {"body", case ReqData#wm_reqdata.req_body of undefined -> []; Body when is_atom(Body) -> atom_to_list(Body); Body -> lists:flatten(io_lib:format("~s", [Body])) end}]}. encode_response(ReqData) -> {struct, [{"code", integer_to_list( wrq:response_code(ReqData))}, {"headers", encode_headers(wrq:resp_headers(ReqData))}, {"body", lists:flatten(io_lib:format("~s", [wrq:resp_body(ReqData)]))}]}. encode_headers(Headers) when is_list(Headers) -> {struct, [ {N, V} || {N, V} <- Headers ]}; encode_headers(Headers) -> encode_headers(mochiweb_headers:to_list(Headers)). encode_trace_part({Decision, Calls}) -> {struct, [{"d", Decision}, {"calls", {array, [ {struct, [{"module", Module}, {"function", Function}, {"input", encode_trace_io(Input)}, {"output", encode_trace_io(Output)}]} || {Module, Function, Input, Output} <- lists:reverse(Calls) ]}}]}. encode_trace_io(wmtrace_null) -> null; encode_trace_io(wmtrace_not_exported) -> "wmtrace_not_exported"; encode_trace_io(Data) -> lists:flatten(io_lib:format("~p", [Data])). %% %% HTML Building %% -define(TAG(T), T(Attrs, Content) -> tag(??T, Attrs, Content)). ?TAG(head). ?TAG(script). ?TAG(title). ?TAG(body). ?TAG(h1). ?TAG(ul). ?TAG(li). ?TAG(a). ?TAG(canvas). ?TAG(select). ?TAG(pre). ?TAG(span). ?TAG(button). html(_Attrs, Content) -> [<<"">>, <<"">>, Content, <<"">>]. divblock(Attrs, Content) -> tag("div", Attrs, Content). %% div is a reserved word linkblock(Attrs, Content) -> tag("link", Attrs, Content). %% link is a reserved word tag(Name, Attrs, Content) -> ["<",Name, [ [" ",K,"=\"",V,"\""] || {K, V} <- Attrs ], if Content == empty -> "/>"; true -> [">", Content, ""] end]. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_error_handler.erl0000644000177700017770000001046412633765070033675 0ustar michaelmichael%% @author Justin Sheehy %% @author Andy Gross %% @author Jeremy Latt %% @copyright 2007-2008 Basho Technologies %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% @doc Some fairly minimal error message formatters. -module(webmachine_error_handler). -author('Justin Sheehy '). -author('Andy Gross '). -author('Jeremy Latt '). -export([render_error/3]). render_error(Code, Req, Reason) -> case Req:has_response_body() of {true,_} -> maybe_log(Req, Reason), Req:response_body(); {false,_} -> render_error_body(Code, Req:trim_state(), Reason) end. render_error_body(404, Req, _Reason) -> {ok, ReqState} = Req:add_response_header("Content-Type", "text/html"), {<<"404 Not Found

    Not Found

    The requested document was not found on this server.


    mochiweb+webmachine web server
    ">>, ReqState}; render_error_body(500, Req, Reason) -> {ok, ReqState} = Req:add_response_header("Content-Type", "text/html"), maybe_log(Req, Reason), STString = io_lib:format("~p", [Reason]), ErrorStart = "500 Internal Server Error

    Internal Server Error

    The server encountered an error while processing this request:
    ",
        ErrorEnd = "


    mochiweb+webmachine web server
    ", ErrorIOList = [ErrorStart,STString,ErrorEnd], {erlang:iolist_to_binary(ErrorIOList), ReqState}; render_error_body(501, Req, _Reason) -> {ok, ReqState} = Req:add_response_header("Content-Type", "text/html"), {Method,_} = Req:method(), error_logger:error_msg("Webmachine does not support method ~p~n", [Method]), ErrorStr = io_lib:format("501 Not Implemented" "

    Not Implemented

    " "The server does not support the ~p method.
    " "


    mochiweb+webmachine web server" "
    ", [Method]), {erlang:iolist_to_binary(ErrorStr), ReqState}; render_error_body(503, Req, _Reason) -> {ok, ReqState} = Req:add_response_header("Content-Type", "text/html"), error_logger:error_msg("Webmachine cannot fulfill" " the request at this time"), ErrorStr = "503 Service Unavailable" "

    Service Unavailable

    " "The server is currently unable to handle " "the request due to a temporary overloading " "or maintenance of the server.
    " "


    mochiweb+webmachine web server" "
    ", {list_to_binary(ErrorStr), ReqState}; render_error_body(Code, Req, Reason) -> {ok, ReqState} = Req:add_response_header("Content-Type", "text/html"), ReasonPhrase = httpd_util:reason_phrase(Code), Body = ["", integer_to_list(Code), " ", ReasonPhrase, "

    ", ReasonPhrase, "

    ", Reason, "


    mochiweb+webmachine web server
    "], {iolist_to_binary(Body), ReqState}. maybe_log(_Req, {error, {exit, normal, _Stack}}) -> %% webmachine_request did an exit(normal), so suppress this %% message. This usually happens when a chunked upload is %% interrupted by network failure. ok; maybe_log(Req, Reason) -> {Path,_} = Req:path(), error_logger:error_msg("webmachine error: path=~p~n~p~n", [Path, Reason]). rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_sup.erl0000644000177700017770000000440412633765070031653 0ustar michaelmichael%% @author Justin Sheehy %% @author Andy Gross %% @copyright 2007-2008 Basho Technologies %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% @doc Supervisor for the webmachine application. -module(webmachine_sup). -behaviour(supervisor). %% External exports -export([start_link/0, upgrade/0]). %% supervisor callbacks -export([init/1]). -include("webmachine_logger.hrl"). %% @spec start_link() -> ServerRet %% @doc API for starting the supervisor. start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). %% @spec upgrade() -> ok %% @doc Add processes if necessary. upgrade() -> {ok, {_, Specs}} = init([]), Old = sets:from_list( [Name || {Name, _, _, _} <- supervisor:which_children(?MODULE)]), New = sets:from_list([Name || {Name, _, _, _, _, _} <- Specs]), Kill = sets:subtract(Old, New), sets:fold(fun (Id, ok) -> supervisor:terminate_child(?MODULE, Id), supervisor:delete_child(?MODULE, Id), ok end, ok, Kill), [supervisor:start_child(?MODULE, Spec) || Spec <- Specs], ok. %% @spec init([]) -> SupervisorTree %% @doc supervisor callback. init([]) -> Router = {webmachine_router, {webmachine_router, start_link, []}, permanent, 5000, worker, [webmachine_router]}, LogHandler = [{webmachine_logger, {gen_event, start_link, [{local, ?EVENT_LOGGER}]}, permanent, 5000, worker, [dynamic]}, {webmachine_logger_watcher_sup, {webmachine_logger_watcher_sup, start_link, []}, permanent, 5000, supervisor, [webmachine_logger_watcher_sup]}], {ok, {{one_for_one, 9, 10}, LogHandler ++ [Router]}}. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_deps.erl0000644000177700017770000000726512633765070032007 0ustar michaelmichael%% @author Justin Sheehy %% @author Andy Gross %% @copyright 2007-2008 Basho Technologies %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% @doc Ensure that the relatively-installed dependencies are on the code %% loading path, and locate resources relative %% to this application's path. -module(webmachine_deps). -author('Justin Sheehy '). -author('Andy Gross '). -export([ensure/0, ensure/1]). -export([get_base_dir/0, get_base_dir/1]). -export([local_path/1, local_path/2]). -export([deps_on_path/0, new_siblings/1]). %% @spec deps_on_path() -> [ProjNameAndVers] %% @doc List of project dependencies on the path. deps_on_path() -> ordsets:from_list([filename:basename(filename:dirname(X)) || X <- code:get_path()]). %% @spec new_siblings(Module) -> [Dir] %% @doc Find new siblings paths relative to Module that aren't already on the %% code path. new_siblings(Module) -> Existing = deps_on_path(), SiblingEbin = [ X || X <- filelib:wildcard(local_path(["deps", "*", "ebin"], Module)), filename:basename(filename:dirname(X)) /= %% don't include self filename:basename(filename:dirname( filename:dirname( filename:dirname(X)))) ], Siblings = [filename:dirname(X) || X <- SiblingEbin, ordsets:is_element( filename:basename(filename:dirname(X)), Existing) =:= false], lists:filter(fun filelib:is_dir/1, lists:append([[filename:join([X, "ebin"]), filename:join([X, "include"])] || X <- Siblings])). %% @spec ensure(Module) -> ok %% @doc Ensure that all ebin and include paths for dependencies %% of the application for Module are on the code path. ensure(Module) -> code:add_paths(new_siblings(Module)), ok. %% @spec ensure() -> ok %% @doc Ensure that the ebin and include paths for dependencies of %% this application are on the code path. Equivalent to %% ensure(?Module). ensure() -> ensure(?MODULE). %% @spec get_base_dir(Module) -> string() %% @doc Return the application directory for Module. It assumes Module is in %% a standard OTP layout application in the ebin or src directory. get_base_dir(Module) -> {file, Here} = code:is_loaded(Module), filename:dirname(filename:dirname(Here)). %% @spec get_base_dir() -> string() %% @doc Return the application directory for this application. Equivalent to %% get_base_dir(?MODULE). get_base_dir() -> get_base_dir(?MODULE). %% @spec local_path([string()], Module) -> string() %% @doc Return an application-relative directory from Module's application. local_path(Components, Module) -> filename:join([get_base_dir(Module) | Components]). %% @spec local_path(Components) -> string() %% @doc Return an application-relative directory for this application. %% Equivalent to local_path(Components, ?MODULE). local_path(Components) -> local_path(Components, ?MODULE). rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_util.erl0000644000177700017770000004603412633765070032026 0ustar michaelmichael%% @author Justin Sheehy %% @author Andy Gross %% @copyright 2007-2008 Basho Technologies %% (guess_mime/1 derived from code copyright 2007 Mochi Media, Inc.) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% @doc Utilities for parsing, quoting, and negotiation. -module(webmachine_util). -export([guess_mime/1]). -export([convert_request_date/1, compare_ims_dates/2]). -export([rfc1123_date/1]). -export([choose_media_type/2, format_content_type/1]). -export([choose_charset/2]). -export([choose_encoding/2]). -export([now_diff_milliseconds/2]). -export([media_type_to_detail/1, quoted_string/1, split_quoted_strings/1]). -export([parse_range/2]). -ifdef(TEST). -ifdef(EQC). -include_lib("eqc/include/eqc.hrl"). -endif. -include_lib("eunit/include/eunit.hrl"). -export([accept_header_to_media_types/1]). -endif. convert_request_date(Date) -> try case httpd_util:convert_request_date(Date) of ReqDate -> ReqDate end catch error:_ -> bad_date end. %% returns true if D1 > D2 compare_ims_dates(D1, D2) -> GD1 = calendar:datetime_to_gregorian_seconds(D1), GD2 = calendar:datetime_to_gregorian_seconds(D2), GD1 > GD2. %% @doc Convert tuple style GMT datetime to RFC1123 style one rfc1123_date({{YYYY, MM, DD}, {Hour, Min, Sec}}) -> DayNumber = calendar:day_of_the_week({YYYY, MM, DD}), lists:flatten(io_lib:format("~s, ~2.2.0w ~3.s ~4.4.0w ~2.2.0w:~2.2.0w:~2.2.0w GMT", [httpd_util:day(DayNumber), DD, httpd_util:month(MM), YYYY, Hour, Min, Sec])). %% @spec guess_mime(string()) -> string() %% @doc Guess the mime type of a file by the extension of its filename. guess_mime(File) -> case filename:extension(File) of ".bz2" -> "application/x-bzip2"; ".css" -> "text/css"; ".eot" -> "application/vnd.ms-fontobject"; ".gif" -> "image/gif"; ".gz" -> "application/x-gzip"; ".htc" -> "text/x-component"; ".html" -> "text/html"; ".ico" -> "image/x-icon"; ".jpeg" -> "image/jpeg"; ".jpg" -> "image/jpeg"; ".js" -> "application/x-javascript"; ".less" -> "text/css"; ".m4v" -> "video/mp4"; ".manifest" -> "text/cache-manifest"; ".mp4" -> "video/mp4"; ".oga" -> "audio/ogg"; ".ogg" -> "audio/ogg"; ".ogv" -> "video/ogg"; ".otf" -> "font/opentyp"; ".png" -> "image/png"; ".svg" -> "image/svg+xml"; ".svgz" -> "image/svg+xml"; ".swf" -> "application/x-shockwave-flash"; ".tar" -> "application/x-tar"; ".tgz" -> "application/x-gzip"; ".ttc" -> "application/x-font-ttf"; ".ttf" -> "application/x-font-ttf"; ".vcf" -> "text/x-vcard"; ".webm" -> "video/web"; ".webp" -> "image/web"; ".woff" -> "application/x-font-woff"; ".xhtml" -> "application/xhtml+xml"; ".xml" -> "application/xml"; ".zip" -> "application/zip"; _ -> "text/plain" end. choose_media_type(Provided,AcceptHead) -> % Return the Content-Type we will serve for a request. % If there is no acceptable/available match, return the atom "none". % AcceptHead is the value of the request's Accept header % Provided is a list of media types the resource can provide. % each is either a string e.g. -- "text/html" % or a string and parameters e.g. -- {"text/html",[{level,1}]} % (the plain string case with no parameters is much more common) Requested = accept_header_to_media_types(AcceptHead), Prov1 = normalize_provided(Provided), choose_media_type1(Prov1,Requested). choose_media_type1(_Provided,[]) -> none; choose_media_type1(Provided,[H|T]) -> {_Pri,Type,Params} = H, case media_match({Type,Params}, Provided) of [] -> choose_media_type1(Provided,T); [{CT_T,CT_P}|_] -> format_content_type(CT_T,CT_P) end. media_match(_,[]) -> []; media_match({"*/*",[]},[H|_]) -> [H]; media_match({Type,Params},Provided) -> [{T1,P1} || {T1,P1} <- Provided, media_type_match(Type,T1), media_params_match(Params,P1)]. media_type_match(Req,Prov) -> case Req of "*" -> % might as well not break for lame (Gomez) clients true; "*/*" -> true; Prov -> true; _ -> [R1|R2] = string:tokens(Req,"/"), [P1,_P2] = string:tokens(Prov,"/"), case R2 of ["*"] -> case R1 of P1 -> true; _ -> false end; _ -> false end end. media_params_match(Req,Prov) -> lists:sort(Req) =:= lists:sort(Prov). prioritize_media(TyParam) -> {Type, Params} = TyParam, prioritize_media(Type,Params,[]). prioritize_media(Type,Params,Acc) -> case Params of [] -> {1, Type, Acc}; _ -> [{Tok,Val}|Rest] = Params, case Tok of "q" -> QVal = case Val of "1" -> 1; "0" -> 0; [$.|_] -> %% handle strange FeedBurner Accept list_to_float([$0|Val]); _ -> list_to_float(Val) end, {QVal, Type, Rest ++ Acc}; _ -> prioritize_media(Type,Rest,[{Tok,Val}|Acc]) end end. media_type_to_detail(MType) -> mochiweb_util:parse_header(MType). accept_header_to_media_types(HeadVal) -> % given the value of an accept header, produce an ordered list % based on the q-values. Results are [{Type,Params}] with the % head of the list being the highest-priority requested type. try lists:reverse(lists:keysort(1, [prioritize_media(media_type_to_detail(MType)) || MType <- [string:strip(X) || X <- string:tokens(HeadVal, ",")]])) catch _:_ -> [] end. normalize_provided(Provided) -> [normalize_provided1(X) || X <- Provided]. normalize_provided1(Type) when is_list(Type) -> {Type, []}; normalize_provided1({Type,Params}) -> {Type, normalize_media_params(Params)}. normalize_media_params(Params) -> normalize_media_params(Params,[]). normalize_media_params([],Acc) -> Acc; normalize_media_params([{K,V}|T], Acc) when is_atom(K) -> normalize_media_params(T,[{atom_to_list(K),V}|Acc]); normalize_media_params([H|T], Acc) -> normalize_media_params(T, [H|Acc]). format_content_type(Type) when is_list(Type) -> Type; format_content_type({Type,Params}) -> format_content_type(Type,Params). format_content_type(Type,[]) -> Type; format_content_type(Type,[{K,V}|T]) when is_atom(K) -> format_content_type(Type, [{atom_to_list(K),V}|T]); format_content_type(Type,[{K,V}|T]) -> format_content_type(Type ++ "; " ++ K ++ "=" ++ V, T). choose_charset(CSets, AccCharHdr) -> do_choose(CSets, AccCharHdr, "ISO-8859-1"). choose_encoding(Encs, AccEncHdr) -> do_choose(Encs, AccEncHdr, "identity"). do_choose(Choices, Header, Default) -> Accepted = build_conneg_list(string:tokens(Header, ",")), DefaultPrio = [P || {P,C} <- Accepted, C =:= Default], StarPrio = [P || {P,C} <- Accepted, C =:= "*"], DefaultOkay = case DefaultPrio of [] -> case StarPrio of [0.0] -> no; _ -> yes end; [0.0] -> no; _ -> yes end, AnyOkay = case StarPrio of [] -> no; [0.0] -> no; _ -> yes end, do_choose(Default, DefaultOkay, AnyOkay, Choices, Accepted). do_choose(_Default, _DefaultOkay, _AnyOkay, [], []) -> none; do_choose(_Default, _DefaultOkay, _AnyOkay, [], _Accepted) -> none; do_choose(Default, DefaultOkay, AnyOkay, Choices, []) -> case AnyOkay of yes -> hd(Choices); no -> case DefaultOkay of yes -> case lists:member(Default, Choices) of true -> Default; _ -> none end; no -> none end end; do_choose(Default, DefaultOkay, AnyOkay, Choices, [AccPair|AccRest]) -> {Prio, Acc} = AccPair, case Prio of 0.0 -> do_choose(Default, DefaultOkay, AnyOkay, lists:delete(Acc, Choices), AccRest); _ -> LAcc = string:to_lower(Acc), LChoices = [string:to_lower(X) || X <- Choices], % doing this a little more work than needed in % order to be easily insensitive but preserving case lists:member(LAcc, LChoices) of true -> hd([X || X <- Choices, string:to_lower(X) =:= LAcc]); false -> do_choose(Default, DefaultOkay, AnyOkay, Choices, AccRest) end end. build_conneg_list(AccList) -> build_conneg_list(AccList, []). build_conneg_list([], Result) -> lists:reverse(lists:sort(Result)); build_conneg_list([Acc|AccRest], Result) -> XPair = list_to_tuple([string:strip(X) || X <- string:tokens(Acc, ";")]), Pair = case XPair of {Choice, "q=" ++ PrioStr} -> case PrioStr of "0" -> {0.0, Choice}; "1" -> {1.0, Choice}; [$.|_] -> %% handle strange FeedBurner Accept {list_to_float([$0|PrioStr]), Choice}; _ -> {list_to_float(PrioStr), Choice} end; {Choice} -> {1.0, Choice} end, build_conneg_list(AccRest,[Pair|Result]). quoted_string([$" | _Rest] = Str) -> Str; quoted_string(Str) -> escape_quotes(Str, [$"]). % Initialize Acc with opening quote escape_quotes([], Acc) -> lists:reverse([$" | Acc]); % Append final quote escape_quotes([$\\, Char | Rest], Acc) -> escape_quotes(Rest, [Char, $\\ | Acc]); % Any quoted char should be skipped escape_quotes([$" | Rest], Acc) -> escape_quotes(Rest, [$", $\\ | Acc]); % Unquoted quotes should be escaped escape_quotes([Char | Rest], Acc) -> escape_quotes(Rest, [Char | Acc]). split_quoted_strings(Str) -> split_quoted_strings(Str, []). split_quoted_strings([], Acc) -> lists:reverse(Acc); split_quoted_strings([$" | Rest], Acc) -> {Str, Cont} = unescape_quoted_string(Rest, []), split_quoted_strings(Cont, [Str | Acc]); split_quoted_strings([_Skip | Rest], Acc) -> split_quoted_strings(Rest, Acc). unescape_quoted_string([], Acc) -> {lists:reverse(Acc), []}; unescape_quoted_string([$\\, Char | Rest], Acc) -> % Any quoted char should be unquoted unescape_quoted_string(Rest, [Char | Acc]); unescape_quoted_string([$" | Rest], Acc) -> % Quote indicates end of this string {lists:reverse(Acc), Rest}; unescape_quoted_string([Char | Rest], Acc) -> unescape_quoted_string(Rest, [Char | Acc]). %% @type now() = {MegaSecs, Secs, MicroSecs} %% This is faster than timer:now_diff() because it does not use bignums. %% But it returns *milliseconds* (timer:now_diff returns microseconds.) %% From http://www.erlang.org/ml-archive/erlang-questions/200205/msg00027.html %% @doc Compute the difference between two now() tuples, in milliseconds. %% @spec now_diff_milliseconds(now(), now()) -> integer() now_diff_milliseconds(undefined, undefined) -> 0; now_diff_milliseconds(undefined, T2) -> now_diff_milliseconds(os:timestamp(), T2); now_diff_milliseconds({M,S,U}, {M,S1,U1}) -> ((S-S1) * 1000) + ((U-U1) div 1000); now_diff_milliseconds({M,S,U}, {M1,S1,U1}) -> ((M-M1)*1000000+(S-S1))*1000 + ((U-U1) div 1000). -spec parse_range(RawRange::string(), ResourceLength::non_neg_integer()) -> [{Start::non_neg_integer(), End::non_neg_integer()}]. parse_range(RawRange, ResourceLength) when is_list(RawRange) -> parse_range(mochiweb_http:parse_range_request(RawRange), ResourceLength, []). parse_range([], _ResourceLength, Acc) -> lists:reverse(Acc); parse_range([Spec | Rest], ResourceLength, Acc) -> case mochiweb_http:range_skip_length(Spec, ResourceLength) of invalid_range -> parse_range(Rest, ResourceLength, Acc); {Skip, Length} -> parse_range(Rest, ResourceLength, [{Skip, Skip + Length - 1} | Acc]) end. %% %% TEST %% -ifdef(TEST). choose_media_type_test() -> Provided = "text/html", ShouldMatch = ["*", "*/*", "text/*", "text/html"], WantNone = ["foo", "text/xml", "application/*", "foo/bar/baz"], [ ?assertEqual(Provided, choose_media_type([Provided], I)) || I <- ShouldMatch ], [ ?assertEqual(none, choose_media_type([Provided], I)) || I <- WantNone ]. choose_media_type_qval_test() -> Provided = ["text/html", "image/jpeg"], HtmlMatch = ["image/jpeg;q=0.5, text/html", "text/html, image/jpeg; q=0.5", "text/*; q=0.8, image/*;q=0.7", "text/*;q=.8, image/*;q=.7"], %% strange FeedBurner format JpgMatch = ["image/*;q=1, text/html;q=0.9", "image/png, image/*;q=0.3"], [ ?assertEqual("text/html", choose_media_type(Provided, I)) || I <- HtmlMatch ], [ ?assertEqual("image/jpeg", choose_media_type(Provided, I)) || I <- JpgMatch ]. accept_header_to_media_types_test() -> Header1 = "text/html,application/xhtml+xml,application/xml,application/x-javascript,*/*;q=0.5", Header2 = "audio/*; q=0, audio/basic", OddHeader = "text/html,application/xhtml+xml,application/xml,application/x-javascript,*/*;q=0,5", Result1 = accept_header_to_media_types(Header1), Result2 = accept_header_to_media_types(Header2), Result3 = accept_header_to_media_types(OddHeader), ExpResult1 = [{1,"application/x-javascript", []}, {1,"application/xml",[]}, {1,"application/xhtml+xml",[]}, {1,"text/html",[]}, {0.5,"*/*",[]}], ExpResult2 = [{1,"audio/basic",[]},{0,"audio/*",[]}], ExpResult3 = [{1, "5", []}, {1,"application/x-javascript", []}, {1,"application/xml",[]}, {1,"application/xhtml+xml",[]}, {1,"text/html",[]}, {0,"*/*",[]}], ?assertEqual(ExpResult1, Result1), ?assertEqual(ExpResult2, Result2), ?assertEqual(ExpResult3, Result3). media_type_extra_whitespace_test() -> MType = "application/x-www-form-urlencoded ; charset = utf8", ?assertEqual({"application/x-www-form-urlencoded",[{"charset","utf8"}]}, webmachine_util:media_type_to_detail(MType)). format_content_type_test() -> Types = ["audio/vnd.wave; codec=31", "text/x-okie; charset=iso-8859-1; declaration="], [?assertEqual(Type, format_content_type( webmachine_util:media_type_to_detail(Type))) || Type <- Types], ?assertEqual(hd(Types), format_content_type("audio/vnd.wave", [{codec, "31"}])). convert_request_date_test() -> ?assertMatch({{_,_,_},{_,_,_}}, convert_request_date("Wed, 30 Dec 2009 14:39:02 GMT")), ?assertMatch(bad_date, convert_request_date(<<"does not handle binaries">>)). compare_ims_dates_test() -> Late = {{2009,12,30},{14,39,02}}, Early = {{2009,12,30},{13,39,02}}, ?assertEqual(true, compare_ims_dates(Late, Early)), ?assertEqual(false, compare_ims_dates(Early, Late)). rfc1123_date_test() -> ?assertEqual("Thu, 11 Jul 2013 04:33:19 GMT", rfc1123_date({{2013, 7, 11}, {4, 33, 19}})). guess_mime_test() -> TextTypes = [".html",".css",".htc",".manifest",".txt"], AppTypes = [".xhtml",".xml",".js",".swf",".zip",".bz2", ".gz",".tar",".tgz"], ImgTypes = [".jpg",".jpeg",".gif",".png",".ico",".svg"], ?assertEqual([], [ T || T <- TextTypes, 1 /= string:str(guess_mime(T),"text/") ]), ?assertEqual([], [ T || T <- AppTypes, 1 /= string:str(guess_mime(T),"application/") ]), ?assertEqual([], [ T || T <- ImgTypes, 1 /= string:str(guess_mime(T),"image/") ]). now_diff_milliseconds_test() -> Late = {10, 10, 10}, Early1 = {10, 9, 9}, Early2 = {9, 9, 9}, ?assertEqual(1000, now_diff_milliseconds(Late, Early1)), ?assertEqual(1000001000, now_diff_milliseconds(Late, Early2)). -ifdef(EQC). -define(QC_OUT(P), eqc:on_output(fun(Str, Args) -> io:format(user, Str, Args) end, P)). prop_quoted_string() -> ?FORALL(String0, non_empty(list(oneof([char(), $", [$\\, char()]]))), begin String = lists:flatten(String0), Quoted = quoted_string(String), case String of [$" | _] -> ?assertEqual(String, Quoted), true; _ -> %% Properties: %% * strings must begin/end with quote %% * All other quotes should be escaped ?assertEqual($", hd(Quoted)), ?assertEqual($", lists:last(Quoted)), Partial = lists:reverse(tl(lists:reverse(tl(Quoted)))), case check_quote(Partial) of true -> true; false -> io:format(user, "----\n", []), io:format(user, "In: ~p\n", [[integer_to_list(C) || C <- String]]), io:format(user, "Out: ~p\n", [[integer_to_list(C) || C <- Quoted]]), false end end end). check_quote([]) -> true; check_quote([$\\, _Any | Rest]) -> check_quote(Rest); check_quote([$" | _Rest]) -> false; check_quote([_Any | Rest]) -> check_quote(Rest). prop_quoted_string_test() -> ?assert(eqc:quickcheck(?QC_OUT(prop_quoted_string()))). -endif. % EQC -endif. % TEST rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine.app.src0000644000177700017770000000041512633765070031546 0ustar michaelmichael%%-*- mode: erlang -*- {application, webmachine, [ {description, "webmachine"}, {vsn, "1.10.3"}, {modules, []}, {registered, []}, {applications, [kernel, stdlib, mochiweb]}, {mod, {webmachine_app, []}}, {env, []} ]}. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_mochiweb.erl0000644000177700017770000001477012633765070032650 0ustar michaelmichael%% @author Justin Sheehy %% @author Andy Gross %% @copyright 2007-2008 Basho Technologies %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% @doc Mochiweb interface for webmachine. -module(webmachine_mochiweb). -author('Justin Sheehy '). -author('Andy Gross '). -export([start/1, stop/0, loop/2]). %% The `log_dir' option is deprecated, but remove it from the %% options list if it is present -define(WM_OPTIONS, [error_handler, log_dir, rewrite_module, resource_module_option]). -define (WM_OPTION_DEFAULTS, [{error_handler, webmachine_error_handler}]). start(Options) -> {DispatchList, PName, DGroup, WMOptions, OtherOptions} = get_wm_options(Options), webmachine_router:init_routes(DGroup, DispatchList), [application_set_unless_env_or_undef(K, V) || {K, V} <- WMOptions], MochiName = list_to_atom(to_list(PName) ++ "_mochiweb"), LoopFun = fun(X) -> loop(DGroup, X) end, mochiweb_http:start([{name, MochiName}, {loop, LoopFun} | OtherOptions]). stop() -> {registered_name, PName} = process_info(self(), registered_name), MochiName = list_to_atom(atom_to_list(PName) ++ "_mochiweb"), mochiweb_http:stop(MochiName). loop(Name, MochiReq) -> Req = webmachine:new_request(mochiweb, MochiReq), DispatchList = webmachine_router:get_routes(Name), Host = case host_headers(Req) of [H|_] -> H; [] -> [] end, {Path, _} = Req:path(), {RD, _} = Req:get_reqdata(), %% Run the dispatch code, catch any errors... try webmachine_dispatcher:dispatch(Host, Path, DispatchList, RD) of {error, invalid_host} -> handle_error(400, "Invalid Host", Req); {no_dispatch_match, _UnmatchedHost, _UnmatchedPathTokens} -> handle_error(404, {none, none, []}, Req); {Mod, ModOpts, HostTokens, Port, PathTokens, Bindings, AppRoot, StringPath} -> BootstrapResource = webmachine_resource:new(x,x,x,x), {ok,RS1} = Req:load_dispatch_data(Bindings,HostTokens,Port, PathTokens,AppRoot,StringPath), XReq1 = {webmachine_request,RS1}, try {ok, Resource} = BootstrapResource:wrap(Mod, ModOpts), {ok,RS2} = XReq1:set_metadata('resource_module', resource_module(Mod, ModOpts)), webmachine_decision_core:handle_request(Resource, RS2) catch error:Error -> handle_error(500, {error, Error}, Req) end catch Type : Error -> handle_error(500, {Type, Error}, Req) end. handle_error(Code, Error, Req) -> {ok, ErrorHandler} = application:get_env(webmachine, error_handler), {ErrorHTML,ReqState1} = ErrorHandler:render_error(Code, Req, Error), Req1 = {webmachine_request,ReqState1}, {ok,ReqState2} = Req1:append_to_response_body(ErrorHTML), Req2 = {webmachine_request,ReqState2}, {ok,ReqState3} = Req2:send_response(Code), Req3 = {webmachine_request,ReqState3}, {LogData,_ReqState4} = Req3:log_data(), spawn(webmachine_log, log_access, [LogData]). get_wm_option(OptName, {WMOptions, OtherOptions}) -> {Value, UpdOtherOptions} = handle_get_option_result(get_option(OptName, OtherOptions), OptName), {[{OptName, Value} | WMOptions], UpdOtherOptions}. handle_get_option_result({undefined, Options}, Name) -> {proplists:get_value(Name, ?WM_OPTION_DEFAULTS), Options}; handle_get_option_result(GetOptRes, _) -> GetOptRes. get_wm_options(Options) -> {DispatchList, Options1} = get_option(dispatch, Options), {Name, Options2} = case get_option(name, Options1) of {undefined, Opts2} -> {webmachine, Opts2}; NRes -> NRes end, {DGroup, Options3} = case get_option(dispatch_group, Options2) of {undefined, Opts3} -> {default, Opts3}; RRes -> RRes end, {WMOptions, RestOptions} = lists:foldl(fun get_wm_option/2, {[], Options3}, ?WM_OPTIONS), {DispatchList, Name, DGroup, WMOptions, RestOptions}. get_option(Option, Options) -> case lists:keytake(Option, 1, Options) of false -> {undefined, Options}; {value, {Option, Value}, NewOptions} -> {Value, NewOptions} end. application_set_unless_env_or_undef(_Var, undefined) -> ok; application_set_unless_env_or_undef(Var, Value) -> application_set_unless_env(webmachine, Var, Value). application_set_unless_env(App, Var, Value) -> Current = application:get_all_env(App), CurrentKeys = proplists:get_keys(Current), case lists:member(Var, CurrentKeys) of true -> ok; false -> application:set_env(App, Var, Value) end. host_headers(Req) -> [ V || {V,_ReqState} <- [Req:get_header_value(H) || H <- ["x-forwarded-host", "x-forwarded-server", "host"]], V /= undefined]. get_app_env(Key) -> application:get_env(webmachine, Key). %% @private %% @doc This function is used for cases where it may be desirable to %% override the value that is set in the request metadata under the %% `resource_module' key. An example would be a pattern where a set of %% resource modules shares a lot of common functionality that is %% contained in a single module and is used as the resource in all %% dispatch rules and the `ModOpts' are used to specify a smaller %% set of callbacks for resource specialization. resource_module(Mod, ModOpts) -> resource_module(Mod, ModOpts, get_app_env(resource_module_option)). resource_module(Mod, _, undefined) -> Mod; resource_module(Mod, ModOpts, {ok, OptionVal}) -> proplists:get_value(OptionVal, ModOpts, Mod). to_list(L) when is_list(L) -> L; to_list(A) when is_atom(A) -> atom_to_list(A). ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_logger_watcher.erlrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/src/webmachine_logger_watcher.er0000644000177700017770000000477612633765070033700 0ustar michaelmichael%% Copyright (c) 2011-2012 Basho Technologies, Inc. All Rights Reserved. %% %% This file is provided to you under the Apache License, %% Version 2.0 (the "License"); you may not use this file %% except in compliance with the License. You may obtain %% a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, %% software distributed under the License is distributed on an %% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY %% KIND, either express or implied. See the License for the %% specific language governing permissions and limitations %% under the License. %% @doc A process that does a gen_event:add_sup_handler and attempts to re-add %% event handlers when they exit. %% @private -module(webmachine_logger_watcher). -behaviour(gen_server). -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -endif. %% callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -export([start_link/3, start/3]). -record(state, {module, config, event}). start_link(Event, Module, Config) -> gen_server:start_link(?MODULE, [Event, Module, Config], []). start(Event, Module, Config) -> gen_server:start(?MODULE, [Event, Module, Config], []). init([Event, Module, Config]) -> install_handler(Event, Module, Config), {ok, #state{event=Event, module=Module, config=Config}}. handle_call(_Call, _From, State) -> {reply, ok, State}. handle_cast(_Request, State) -> {noreply, State}. handle_info({gen_event_EXIT, Module, normal}, #state{module=Module} = State) -> {stop, normal, State}; handle_info({gen_event_EXIT, Module, shutdown}, #state{module=Module} = State) -> {stop, normal, State}; handle_info({gen_event_EXIT, Module, _Reason}, #state{module=Module, config=Config, event=Event} = State) -> install_handler(Event, Module, Config), {noreply, State}; handle_info(reinstall_handler, #state{module=Module, config=Config, event=Event} = State) -> install_handler(Event, Module, Config), {noreply, State}; handle_info(_Info, State) -> {noreply, State}. terminate(_Reason, _State) -> ok. code_change(_OldVsn, State, _Extra) -> {ok, State}. %% internal install_handler(Event, Module, Config) -> case gen_event:add_sup_handler(Event, Module, Config) of ok -> ok; _Error -> erlang:send_after(5000, self(), reinstall_handler), ok end. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/rebar0000755000177700017770000035065412633765070026423 0ustar michaelmichael#!/usr/bin/env escript %%! -noshell -noinput PK’KAžxè[Ø getopt.beam…Y}pezßõêc-ü&+­ˆCaaȎב’H&†×–e%!!9áø”eimË‘%¡]rœIL.)_æó88îRwwŽÏ+Ü•@{ý§Ó)NgîZÚaÒá¯ëL™ÞL;ÓÎÍô÷ì®…äZϼ»Ïû¼Ïû|üžçýXylï-‚pég#Ùá=ÃvcN¤Aؘ6íFÓö7K-Ë ˜­Z©>Ý1S Xv«ZŸØfÝòÛ3­Æ½~³Õj´üµªe[Á–yÐÄŒŽÆÿÁRmÞãþ©RÍ2ÃŽ¢b­QŸ.BoµQ0MUë•ÎùzÅaVVUë˜S­xΛR,YVu’ÅRk:r®´Ã²šµª}ŽÔºó•ÔÍûlòÙ­y3âŽ[3–í ø§ª-Ëö‘Ø¥ç®LWÉùbœ³ˆ}kJͦ >B*Í×–'YvΜ›4[j©²âò½U{†¦­?×ÁyƒÕ9DY®:N«uÛœ6[ÁÉF£f–ꑹ*¦¶Öš¾öίÖË-sάۥɚI¢ ­h5ÍrÑ>Ô4ƒvÃyû§j’˜¬ÖK­C¾Šd5庈aÏ:[î;’«–{å.Í”ñ®5î5[ÉRÖ.ªZd¸H©†‡º¼¾S3ÔqS ÖjtÚ#—ê {x^àÄ¢®çu× [w6ÝÎŽ¶±‰éŸ·JÓæ*Ë.ÕáV¥è”tGµ˜j´æJ¶ªQ«Ô‚Sµ’m›õUŽp±ÇBÿ–¾©ùzŸÑ'dS"b +‚ûw íS´Qéˆ\©‰Ú*M›‰îã’/´EPõ¾-:W%žÔ ¦ eE=‘ó‹ Þ¡r)Ã}RØçË?\F4UÌÏFã¦ÔJ›ê ©j#ªQ•LÜLN›™A3£a>ÉMÔt•ÞMÍ‹ ©È g åÔ{…á‚u$þžÕÙ—zïÈð‘§OÆ_}º³/ùìÉ.­Éu/G}ËK:ª0Îõè1E j†2¡ŒijΗ“Æ4)÷vN(ª¸ÄË~²h2EÍÂÒ y_†÷ex´À“ ò}TçÉ¿ÀÖ@Q˜Wt>€ú‚F>ÍTL‹Jy7hM‘ŒDœE¡pœEuŸ¢iY  : ²B¡@KÄ>ˇŒT Ñ v%†U ˆ b ErQ êpN•• ŒF–|qG$¤.ˆòš®…®V¸>îx¥S|òBŒg’<1ÊuÛqµ®®#W5¸jèq¶Nö²µzÈ É/+Ç8Gzná.ú€7æ¡ÏE¹¤3CìQ^»ìY4;뜹ä¬Ëç¬#—/…Ë+¢¼ž‚¤ ¶A”/#¦!ÊRLS‡ÕD&Î.Otu)y*™Œ“[ÃÉ­”óÑ2@^åË-ŸMè:ÏxZ´$»LÅÀжfB”¯L³+ ƒhù®…‰°o¤ Ø#âü[È éìeWÅ:B~!¦¢¼ ¶QºNb»ù¦‡ºÙU¢¬§XOl8&©31ãªî•Ò¨Òòª(y¸YÈÙ9)[Xɹrö…“áÑðx¸B+>Y€§±ÙX/»Z:L+šúW¡Âã<Šeb3òP¸ÿl–A^”¯V–‚Ö¦¢pR ƒtÏŽ˜(o$¸¯kQ.×ò²ÅC—” ¬W”ãÄ…\oŠ%¬®¥…aëˆ Š+œú9"ñ²¯ ¢ —úÙŒúÙ²\êŠWê}N©oÑ—K}eÝÀ"`[îÚé]å>G2É6Ù$IŒ£ì1ËW&©&Û©M0Èm•'$€p(Îú¥P7õÇu hóE ´x̘ }ä,Bã+Û„Üg†/t ©]$èÇË„æeãkÜ;DyÀ)òy wBëʤ®ÝëÍðš ?)ʉ$‹[ü✼àâ„ô‚~+@¾ÐoK³­(í(Ã¥&ŠÐB9^ª@*KdÁZìeƒªÁŒŠ4¸ex=•áõT†)”á (§Rlh¹ Ó(=Ç]ì‚vØ×V…‹çTaÔ©Âè¹U¸„ªKSnw«úƒqv‹ƒutësª± ëë. yÇ%·{u»˜³Ï¯[à6Du{=wÀ[¯‰2O±Œ4,é‰4ÑÑò#º’ѵBœd¨ìF ôVEÅ0HÙ§91 ?àçM5LÀ±$Ê#+T&Énø R£°²V²)¶Ó³²VvVŒÈÝŽ‚ÖÅ'F гä¡5ã,y쯉dÐXˆ³1lÔy§°fUŸ4Är¢<†­A”sÀyë;\?²¢¼3ÉF‘2òcüаÿݘf»°ÀvIù®¼56Šõ•áR̳GyNÒz0Xž*"ßÍQ»Ï°›Dy7*aëI)œ\©57Š€?Hu†öPª÷º©¦þM´åÇÈ·ýØVözé½Ð¶‚ñà^{6o°Yj8e\;Ãê¢\ÃÂt¤æÜ•Qç¡IV¾@4 ª>\zC›Ñ¹§—µ¤œâ<5çi8Oî<óqfI9l8-h&5ÖEþ¯¤\“H’Ð0ßËJ¹ç¹ähØô¥Ù7Þƒ+èåoè#¦»'€Ö·€Þý@ñQþâ (ì¨(ßïRO‰ò.õ¸(?èYù6To…ê…4{ªWTã°~È@ª*; õGDùp—@@ÍGB~Y‘¤ˆ5GV¸GÛ¸‹î¦÷0l¤ÀÑU¸û¯$È`ÇIùq:d¾ƒtåï Q~¤ ²Çœœ÷.a¡m\nZþêÒx?’bbUq§|TíìÃÅÍ íQ÷õÄ!öxŠ-9bÙj§ggZ]~Âuq)É“ë*y.Éž\Vò](Ù\Ÿç¡!·ÅDù{ÄÂ>ö‚Á^Ô» 8О¥Ç€ÆË+_è¼ÏŠ¬Ô‘Èú‰l4¡óÜW´gʆÆô¡1àì%Qþ>iÄ^õ’Á~èâœ4âóˆ>•’ç+]p•F®â)–Ú¿I3Ôüš3<Ãû!iÆ|¢k"˜D”Î=ÉÕQžŸÈPù„íöM²Bg¯tLãACŽ´[}¹ýk)¨ÈêÿïÅŸÂôàP‡¯ˆòIâËWRì§Þ¡y‡æI=ßep\³“S)àŒ.ãµÜƒ Î~l…½ìUœÖÊÂD¶“ÃR¶³OÂãIÏvj:ÎÌ×EùÕ^ö£2dN4³å6™óÄ;\âǽì5h¥c§€¸ä(Ê2+åäfl§i¾6%*Xª;÷µ^ö“²;·ìΕ•ÿkòù~‚¹ÎÄ gžêÌsÇEùu|·d¥¨wľ‚rùi’”ÜÕ‰ÈH Ê?¢£Àø.A̔ųƒ§0˜Üo¦Ø»ܧ÷)îsÁæ}‘[.Þ?/Ó½è-ÇCîzç¶“óïˆò[ _È:€jŸîr~goSŠÀïì+· ¼­œvXË .½x$WJ”ßá>úaᘦàZþ¾[jûMDön’òî:ï!ž1 ñþ6ö µ­‹/ì­ªÉûýŠ|±¤>àךkTµ‡} ªÊ6ME+©=Bé¡ånÓß#ô(=BÑâŸèh¯û?©5yrZÉÆrrTÍJª—<Í}¨Y5*E xñ"G–¥žTÝp¢Ny=⫺;çØaðú3°1}HŽv»ŽÂPûH”@s5LR¹ÑþÂ7"‹¿âœŒòZQþsâ`úǘšŒéÓ`îA’?I³ÓØ÷OŸ½,Ð0îœ úÆ}_„‚ݧŸvÎ5ñ·ƒ\‡†Á‡&¢ùÑhhh!¿Lwxò¬MFñxÔ‚ž<Ñ—µÉ\Þ&ÓÛ&Ó×Foj£ûÛü1Úørhóg›Ç¿íGvy=Ü67ÓFçÚbÜѦsW›Ìî¯ÑÙûC‡&¼nôÆ?öhúûÚvÛ—<šæ¿àÑdçyïí´±ù:é\ïéÚãñ?ñô ÒágGwWm’ù.Dü÷}ßß …>åŠÿ‹¿[ûû“/½¶4ûĉ7²õÒ÷&¯z'ÒõÎyåcuÿ×5® <÷Ä¡ÇgnýíïÆŽÇwÁî¿øÃ'ÍÐßþ:·ÿŸ;y>÷Ðþü_éúàà¿ÊQ¾îþ7?>5ñï±Üõ³ëîý0ðû÷ÿ~çoÅßH/¾óßñ~^8üÉñ×FÞýŸG>ýakò?ïùçß¼¾õ™ÆïÂÛ6 »eª­%øxÅ×bØéÅõ!Ú˜‡ÅûhYOæM´QOæ ´ÿŠGÿe;ª‹h×yü§Ð=úq´´G?‚–òè£h[= h[<úZÒ“™GÛìÑ÷ môd*h=¿„vµÇ¿íJÞïÅLqÝ‚¦y4ÕÃO&ëå—hŽv©à®ªßµ‚[ß½MükÑÖx5Fv.ötnðhÑÓ§zsIvµ7WñìVò°m·ðÞ{¤FÜ™ŽŠ ´êÔëŠðo¿\õÚ+Ÿüú_Þ¸ûÔïݺq–¥y{¦Ñrd*‚:;_ªÏ6x¹1gÖj%kS£5=;+dvÖ§0¾ÎÑë£iAï—ub+s~¶/Zóss¥Ö!GocÞ®T[Ÿ9Y­G¬‚Õz¹6_1+ÂÙ>ÍH«T„ÐȾ»G‹ã;÷d«7›ÔÀÖâ@bs*™^’÷g Å7í= \4]µµr:5µµ¼2¼w<ï nHŽ 'È ýúwþä¦m›’ÄóÙÕ9s&0 ÿ?/É%¥ÄJëKŽëVc¾U6×ôχþJ³ÔšªÚvÿdÉšiô·ÌÉR«ßj•ûÝÿÔm2[µYl<“–Më÷PK’KAß±«F p mustache.beamX påÞ½ï~ö.·d/{!lØ„Ÿ„$›ìåçÀ/wIŽð"œhõr¹Û$G’»soO°`¡CUF™Éˆ(Zi¦Ò©"Ž"ŠÔ:δ ÈT¦bu *ˆ˜ѪUû~{{ÉU°6ûûÞû÷½?Ï·ß²+VÖR?àko]Þª%†)Šþ”¢¨EÌp:¥…#Š-’NƆFQ‡B©H8nMij,ÞoJ Ú‰(VSJž~ )ë“jJ7Tî9ãʺPo,ë”™è, M+æH"ªX’iµ_±%ÂÑP„·'¢é!ÅLx»ªR“ªØT%9Ž€ä£)öt<ªôÅâJÔª*Àªæh,¢!XÊ AŒPÈ’ÒªbŠ¥´”­o(¬iJy/[,ƒZ|2µÊ'sPø[ý©- H"%øRÔˆ/ÅíÅ–Ö-£ÇA1 ŠQÁ7Jörç=lñqìâñ*kGÌXtã‘2¼×ƒO·áóA›4v¯ºî6ó÷Z†ãÁ¹·rI…ZWFI„2.Aˆå2—;ëåÉ(Ú2ЍËãjFm8¨#Uè†ÎÐ}yìqXµ¹ÊÌ;`ÆCŒ°èÙ* ™N$æ6síö5Hl· "\6Š:Çðë)¢t½¾˜"h(rÌÆQÊ·@2›i¦x j \w’f¦ÂÈæÀü¦yÙ±ûDJö‰œ¿’-‘n§Ôm`rå±ß­ç p#€¥c `‹áÀ1‚™,ƒÆ™Ð‚Æ3•‡‚¶&ol&€–Ža ¡† zÙY0„Y¼C(§|û-Üd;*ø–ÝkÁ 'BÙ²Ø%ÑL9xÏxÏnbç¡V$û«Ør¹EfË‹°½”cßÀÎ¥™9¶ÜiM#!æ’“8ÉËVÀ~¨Ð÷‚ýËUÀÃË€{³ŽûSÂÿ¾¦ šWÉ–#GåÿwÆÆiÄ­0žÀÍTB©UpŸï¤à¤&ÏfFáR*ÃeÏà$ØWQ t³º‘­Aä Cnr‘¥Æíe%@°”‹` ŽØê"Ùê…Ø-ÂQe‘Ø:Qóÿº›yýäÓ$rLÔ’$`(u¬ŒŒs’Ï,@NÉì²S2TðüÉÄ÷@|on|¯þaáØˆçßÈ!Ç­ …“•™,¨±Þ"ìÙz‡‡m ™z’R9á”KrÄZÓ@ühÑ徑g#x6ÑL#±1ën”áÖ„M¨@àx n›¡´zBK»ðËÑÌ‚jv!"ed"3Q—ÀÓÌB‰]D, hfxߎ^pÄØÄ[ÖG3­Dmð5±€®(7±ð ñ¯ªb;ü-~¶£¨Ç¾€õÛ±möÙl;Íø=lÇ*'¼Á˜2DÞ™xÎ/>¬b·M”ßР}Â`ö :à©]äa{¡L’Û ã'…L¥™År ˜u6±‹!e^ô°‹E'¼ºÁó¦kæ…Èstp›xF`¦Aÿ–€ÏB¸/Å$J Í,#ˆ²œ,]@Ú5QÔ*M ’êÎá$Üé!`g†2Ñ@V ›Á3@vãœð ˆ5l?ÉàÉûºËà €x#nP±‡ðS5§•䨛 "9ÍÌá…›Y†œÄ-3â›òïȳ¾ssò¬6x’ƒ”cSkÈ _—³Á75ö$çæïðÄfAŽ ñ]”“ð¦öõ¤çúÿeò€úåOþ–µòN ¯Ác #¯:ƒ7õL6äùo2âO6|í9}µw"7-‹i |Qzý“é•ÿXñw‰kèvœÃSOÿ¬aøôv©tš¯ñ3Ï‘}…{>Š%6 ÉþÔ5RÓW\‹;¿<µicþº‚ÞüíW®|uôêº"Þ7·ôÂÕŠ!û©.ljGÝϬÚï³Þ\qâÛÞ7†~û^ôøKÇ~tâ_çÚ¾žÿ—ý &¥w-½å½g…ß4U¼‘xeÝŽ£õ¼”'¾‰wþÙýH„E/|àÒ®í›êßž78µiß¹Qׯ¬É{ªô}¤¾½ºpás5îýqwþ‡>ìTk×>!?£í8ÌÖÞñú‹_ܹ?io}üTeÑsSžÌw‰|»´ú½èŠH㥷ñmþxŠ×öß~áÔ_ÕCw>ôÔËWøwÜZ½q[ÞÅC÷_Üùe÷ýor‡~î¸zyûê%³·Ÿ©n;;\²|CëÎ9·ßüþyc£Á×6XnÛòÏ_>ðê]ᇦvðøsW¾îY»ù‹[O‡ÚŽ^*¯{ºó@êÝ~oûçÕ¸Šß¸æ§­ï¡Ç>¾väêÚWç#OXb“Þº¯î¾_ýþ̦m—ÜwYÜÇmêx¨öÑǧõï°4ß³ýµíwõþnÃÖ‹KŸÞÛ0ï®-?™»A~öƒª^8ôùó‡Æ>[;µ¹{wý®ÃçÏ\>ûÀ«——=Ò2mÆé1WÇÇ;8ãÑŸvŠw¬9ñòî¹z1ðoçÙ®?¹ öýaבçj~úðŠÞ3¡We~w¬kýáÖ$^ÿ4ÿð¤sQjY"B°™4ðâ5pâª7ðBpYeðó "¸› TaØ‹@óröÀœœ}^jÈ .§|A«¦©p_¼…<‰L¦(…îNÅÉ:ÎQßܶZñ<Ÿ¸oÛ/Ü3.¸ Ök8­ $ÔAª ˜ºU%¥%âU·*j\Q×ú;ã}à[¢Ç3s["I¾_¤ˆÀ¥XýCK(•«÷èñi-ƒxf¥7':6HÙbñÈP:ªD©‰Ï<tÑ(åðÝÒ¹¬-ì\Þ>Hå×IµuRSmC¨V®kòx³FÌjÿªPgWÇŠA*¯?¦ µoS_Cd\½"Øm¨­+k=>IÖ‹³‘Ï$î eñT7V{ˆÌ¬Å†•k/äÿV˜ sa6\®ÕSO%ÒjD¤*kÃJM4VûbšVÓN $jT¥7¬Ö¤ÔHMö Zµ¢­míMiäaóPK’KAYÖwKÝ rebar.app•VMoÛ0 ½çWr’ ÛzJÑ˰ýa·"0d‹Nµ1’¦¬…Ñÿ>)67¥M‡Ä&ê‰zÌrÉÖÖì lXäj?~­¥ üá¸ew÷Ó»ç­[x%1E/–KÏ[æÝÃsâGïÆ$ üb1pcPvÜK­VÌBËíjÁ®³ÒŒæ›ïɾe߯¸/A¢`?´Æ›×fÃÑ%ЧÍíæv²Ä‚[±Ç·œïÖÉØðVõ]Ó郑Ƙ`ék‚—H¸[î ’½Óª—{Êgð pE¦ôy»rN}¬Ô Bw„ÇbÂé(IwP’¨¹IK c_#8–÷"ÙfZ’®þ/° ®ØHËy²Íz¸Ã)¨cLrÆD%û =èYìvÒ¾³wˆ¶æd[E­´ÚÆ$ÙXÃ-Gd?uëfñéuÅ>_†qõÒÄca±“:pNFý›Äm;š³ìe¶vÉ}¡!rðœ~äpDå dSåÀ“è•»+Î#qÎ@'{Ù•¬0—Z+1\cö­Úòh!‚þA-ˆÈš|PU–”Ÿˆ) >SÒiúgŠÂM„5™ˆ!Dž@_ÏWj¹¹Fa©Iá3ó˜€&‰­ ßß›ÙÒÀù¯¶Ïþ["Àĸ"ÐÓˆ©n%˜YÓãîu³ø PK’KA\@‚¿.° rebar.beam…X \WÖŸaò"£@A4!<A ¢0<#" ¾ŠÆI2„@’‰“Ä‚´•VÛ¥ZÅÏZíC­¶Z»¾ªm?ÛÚµZ­Ö¶Z«öáëºû³ëj}õ×ÚvÏ Êv÷ëÇïwæžû¿çž×=÷̲I56ð¢ÒÂÊB¿àÆ0Åã†5)EÞʉ 7çô(yQDUçtñv/º8CÑȹü!BsˆSP5¢›óbÀÓóz]Nçw …KàìÊÎåãiÞÃY]¼Å+ N—Óã“”[l‚§ÁéÐ8x¿ÅᬜKá¼²É)‘ªVup ¯æ<œ«ÕÇ«Áˆ… ´¨lb«×/(}~Nô‡µ¹‡Âéqú§s}‹³5òï÷þ5ﳉN¯¿_p°x87O"åˆQsV5¾û΄ž#\Àå¢JÉŒÂÅùüHÀqt)-Í|뀙´4¸8‡Ö×(%Ã׃!©±v¥%D5¶Œ5W1¬&"Y×^³$±CMïc XkÇY^fÁ”éYól@µñ‚»Þ+Eòqj5‚^޲8íFÃôÿêú °lƒ£ÚC:NÖ#|š‰<PGÂeœ â–ÊJ„¡®õZT·TƒZv¥‘²!÷l(…³ÁC'gßO¡”pÁY\ú…5‹š…|´¡²ƒ­p‰WÁû'`ꀩ¦Ù8ÙÓF˜:a…“M0u‚·Í9”‹€oT©Á«ÄHÕ©@/ð¾¦\YT2å†M°Ñ£¢ðá4Ù/Ö¢©r·Æ*`áÿ>L ¤ÂH P  ~@a2>@þ é#ƒð FƯ•¿Õ)ËD ”ñA@12?(NÞ;h¨Œë€†õ±/Ë ½ÃP(#€eyä²,cJ‘÷"=©2Ÿ”ÞGgÜïxLæ2Žò’)ëÌ…¡¯Š ÿŒçîÃçÉ<Ò3VÖ‰ðÙç^¾7–bY¦¨T¶‹r>N–A1Nès.•2? {pF5@“eå¡V–A|Ì#ýSd¾FÎI¯þé2dîÃÏ죓÷Îâä9Âí}l!>¤´Õ•ä3ª'›¼>Sæ1ÙF™Ì'eË2¨>L2%ÛFxHYÀS+ëGùo’q,‹© êÃÐ(Oò:†½;}<2îubêö~ÈNƒŒór<˜²`¹c‚Ó¶”p¦ý>iY½dŠ[`Ìt¾.ô»ªŠ“‹Bjg»ÃKU¦5Ú+ߌgÃ#Ýy¦ñ±w9w¦õî;8GWÔ=.þƾòuÛ3•L½a÷‘sGÇäå™òŽ) ¯ÓŠw—¾=ûÒ¶E-/.c5Ø`-{ö½ÜŽwÂ;¿ÚJ®oQ.Ze‰]s¸~³Á,÷à+-kc_é\ðü´i«”¯$*³v×߸wx|[DZaߟZ¸³Æ°5Í(üNùñËçbv­Š|¥ãÇ}7ªÓzfoi~ÿÙ÷bVìW¼vG½ù þê¿Fäo»wç“ÏË„Zö«×¯ž}šv>x…q voëúÖ#Ýõ-_lžö ½ï¥¤ùKS~œk¼üzÁåÖ¤]»Ï^[6vé-ûþº [«–ŸL³}ÿö¹Í ¥î剥–/徎ëªü ¥kDÄ/çFLŸ¹ßyzÖðŒM/&Õm[|L¹ú›„7O_ìÚl>ÔcJ9å8Õvõ—³w¶×ïË=ëZÁÙW)§ÎÝÕ–÷í{Ôê=myÜ_÷gÿÖè±g*‡ü8íqjYºÁºù×ת¶÷|þþ,½«øÇþûN}©t±ç›¢’Ìÿ‰?§KŸr·3±%?ôµzïÁ•÷îŒKÚÚù^ÉÿNykwÉu×À²2ïÔØÜŒ$qëOG®ºvõí–®bvÏ”'l™òrWÒ:¡ykÿtÍ!UËgïäîÿíâ“êQ+Žr­¯Ø±d[÷ÎÙļy¶ˆ§_Ï›)¬®¸:zIÁg_ÛÛqirš/ùÕS}¬;Õõmº³¥jÿñkÇ&|Q÷™7zòİC—KF^èžÜ¨êSÏ”ÎY{ëÛUQmC«¯™Ÿ¾ÿ£äcDrTòror¤gÆvìS±k{ŠuÑ¥M•ççm<ñÐÒÒ´•!ß·mѹtÏé ¨KîĵëZÆv¿qmáª÷‰¸|÷W׫:S¾ÛÛ¼vƒؘïÚRõ=kª{k”§ Ö5›ŠÏÚŸ»|p?³çBé©Ïæì˜Õ“œPêýjI“¶½kÚŒI®Ÿ½ÙoçÑK¶ÎçÃyWœ|ì·ÍëóÜV¹ãü­;[Öæ·.?Ùýªz˱¿Ç­˜¿={ËÏÏóÛþÒèýek véÍ(Û†mNl}þÆ”äÄš'Þ·Þ]3?ñløçµ|›Lg­kœ·×96í²Þ;²¼dÃO‹Ï_¬YS¾øç–·¦ÝºùÒÝ› U1©íc~Ðjw>ººn¿óOc6VÅ>ùÏâ÷¨‹?ŸŸ¼1‰rϹ¼Bã©9ytÝíÎôM[¦ͱ{iz}ý‘ê'Z{ô{VZ3ž:2§!ju§1~ÖÚ«ç^P~TÙ~ólîÜÍŒx©3¦.êÑsîÞüi»ê‡õûV¹knØk‹W/Þvåõ‡§ÞÞPß^ô…š*|ôÞƒºÇÚ¿[{u¹gè!na”»N_óFœ1vQÇ®Žy#×]Ê~!ëDæÜ¶A8Z[=ïø²øËµ_òov=·áX†+!×1ôèñІSæ=4Qõý(}½³ªËàß|`ÄËkæãŸ+Û4Ðü[­Ü‚#ׯ{{sóïúußÝ·/ór϶Ye¾Vž÷¾ûêe½gÈúÑûsšÌ£wìTYg!Pµ,ÞÛe<¨BæÑûh¼üNÈy$Þ™å2Ÿ(ëêýƈ’yô­¤‘yu¡ß/Â8r !!v ý0*M<4F]v>U±n}ÓÔ±ÚÛËššŠË=;>H’W yuðwOÔvŒ’~·øn7'¶"•ðÛb3¦à­NBpg3¦vzl®€·c~¼n$`ÍnÇ4EuåJ,µå•¥ÍØ€LcF¦1'#Û’aÊÌÉÊí"§O¶”O,›ÔŒõs8ýº [nNC¶íþò¤Ú*yYU“‘Ud45IÞÊ?ÿ6cʬ´‡Ò²¦ð;Ý|£ ÎN}†#9š£¸Á\†äºOˆ6¾™Þ(¸ùt»—œ~º•ó5 éÒïàé>ÑäÒxÑ… ©Ðêó£CúPK’KAboÛSDrebar_abnfc_compiler.beammU}leïÞk{½­ÛµW؇ƒ´|.£×®Œñ1}÷ÑÕêØ–1ŒÑr½^Û[Û»zw &"FAcÑ £(ýÃD3 „˜Hâ’1êþ0$F31è€Æ|¯=ÈBhòë=÷{~ïó>Ïó¾yn`x4 €kco¬gS© $À ¿.§D=)¦ÔŒ””´bI)ȺË6è´&%uM3C+ë’œ”w˜.­l&ӊεt¹P¡œ²^Õ,ÙÖÆU£¥DC¾ êe•©Æ×J¦Q[•HššQ²0+›NÌ*šê.éZ© ¦áÆdrB,”eWZΈå‚ÉV—+F²¤Ë†¬šŽ AIZZvlÏ)Rv‡ºkUMÅéàŠšõØÛW+£L½,;2bÁé fU±(ÓV––q%„æP5-5NY^RË;d]×tw5ׂ–…3§kÛkìº5£Õ[™Î{÷¶Û»†"홲Ú.´ƒ>œ"d#î5 ª¿}Ín‚%}Kx‚¯aì§Ø‚Š@ÄE)^F0ˆ¢ê…ÛoÙ£U;`Ù)ˆYp. Heòw h µ‘‚ê‡t‰!Òw‚%"è7$ðÄ黯ÛjyqO±/#гbû!-`A‰ô1^–Ø-”áXnØ=:™ê}?uŠ8€â,䈣(ÎãÇ4"ñÿ ûq¹ÄpÐÅ¢Çd pÄØÙ(¿× ‚—B?.ŒW‡{¸Ä4yX¦Ùã#hoîõÛ}èÅ}ðWê¥^í8Ë ®rñÛ*éV[QUr•¸ì ;ÀâÌ¢8ŒÈÀßgÇ©XG cZN$]|©Íã…ÌÃ>#h/‹Ø$a,ˆ£ÆnŸ€kY]ÂnGf‚ö¡ø‡›ø ÷8$h?®u~Y€|pˆ=JÐ -‚%è+9ÌñÓ݈¹A79…›p³©Y—"Q,YÏI ÜEà 1Hëž`06gù<£Þ¾S–íÇX€Aغ…öÚ‡0Zl›Ãàm;€´×Zú¥óÖ.¿Ï&c;*¹­°õËlƒm{oò.Ê꘽/1o]“­®æÛƒŠiin`É›;Þ}ïÀ™áóBícfÑôIÉýÊ¡ïÿ :9ñÒ/jóÖ¹±¡UW–>qçÙÙ gëÞ>üÑíëÉÂëß5IêÁcŸ|øØž¹üÕ·OO^uzAç¬rüÛk¬©;VxQ×Y½øÆÑ¾Ö‹‹8y|ú¹ÿ;÷Nû«ýÇ3Û;Oî|jÿ¡¿Ï ¿°kýŸC3ý uêë•=­ŸÊëîñnüìùOï”–zÎ\Õy×\á¨/'#éÉŒ§Æq®ÿr¢eæ¯Ùá¯>¯¿üóÆú¶Ù5uéãûç¾Y“ÿ!IÙ²êlËr¢»uNÜ£Q²óןZmÿÇóÅÞ]Ï€AM²êÄpÞ×›Æyçê³[eµ×î£uêì[kklžê1MÝŠõRÁbrdÀ C­¼¨,Xçs¯níým sýVàµ%mãã} 5ƒ}U=eé]ÕlX„+ <•é—4ÊÅ¢¨ï´N<õñÐÏJN)ªÅJ¸U*”Ór¸Ë*žÕŠ*§sûÒiÀônI ö'Ç›byP¡+Ü™ wDº¢ëîŠè'û6'CÃyP“UL>,­ëÊtJ÷ÜÃc#¶Û9Žö ã•l'dÝÀéæ#ºzíê¨ÅQ¦R”sÎÎV¤EVôˆ-b¸’zõÛ•kC9­(‡Ò%QÏ(¦Âó?§…*#>dèRèA_ÂÕøÓ6Þ“2Lë0þPK’KAY«¾O°ü rebar_app_utils.beamuVolIŸõ¬í“M&^'iþ\ºí&½¤nâuì&NÒ\×N+U›¶I‹øSH{“lb{­Ýu¯\‘¨€¢~¹k®œŽÓÑUOœ® |tåJU*ÐQø€§¨t:N§W¾ðx³ž4&袼7ïÏï½yof[.ÏW£` Ûä «¾ªrÅþ%Ý™Ï=›‚^Êu~Å4J~:+ ³F!ŸËZyÞ±*ºw1[°u¯nY¦UWÅ(˜Kh ܶr‚ešòéV![Z‘‰F¦›wLj&,dm7–'¨ÊåÍUovÁ´B%@#—u ³d7ÔNüT{Þ.ùaÔ Sþ|Φ²FÈÂ^5Êe=Oê*¥¼¾h”ô¼Ïv,£´äsÌU½d‹3ëÌÓU [ †Jð”ñç N¥àÔ×ÄÅåŠC*%ýBYÏ9ïèVÑ®£µ;Ÿ-Tôº²e‚­íØM4½Pµ¯+õõâ‚n Ô„6O?>-T’×Ë–qÀc©`.d "•Ò•¸ÆuO8a‹«/šùJAŸ7J‹f5®™w üo"ÑB®ç QÕšŽÛØ*Ÿ`©Â˜4ó:BÞ ì%‚ªW€R@AŽx‚{'7 ä’Fœ ÂiM²L4J‡2û !tƧù ¡3?‘gpKJü²BTyJÆ™k)(KÜÉøeLd~2næ›C[¾IÝòÕ«¾•¾çâ¬ÝÄ”-»EËhÒiدªT‡$îÕñTwòÿtkžà#ÂÝh DËœ“ e¿¬Õ{Oò‰ÄÝöAÂÝm@®Ú/ŸÓ2eÊ–´Ì%,È—÷ŒZ·I10ÏqϨ،a±¹MSÿ)‹„û(…‘”ÂD ‹ÍR US\pÔŠ7ˆ¦¦Nóz  ×'4Åœ„»`"ÕFh¥Z!‚’ÅNUÁdkucH¯hvìUÅ>pnÙÖº#Ø ¬•kƒ`0ÙÕèv¡¬“ë¤ÁÚe±ƒÚ·ƒuÒ`!¬)¼ŸÜ€ Ç4^ÒB» k±ÐBxÈd‚|p;¶óèÜÎ#Dó¸Mó9¡“æÑytƒýS@þJ×ăaq7ìn$,vG»HKÙ­eîB_îBºí ½²¨‚ûîmÅÄE2àþö4É*™’¥L@Éà€÷¡¤ŒŠ{•1qŸëWS Š¥29¥âL 5ËLÒÍ&ì ƒ¢K°]7GÅ^<$o­L{¥qIìmÓ­¢²!öp‚’{•¤›ãÇÔT Í¥b$—ŠÉvXì <{'‰zI³yšN.cÓ²æB~ù#¢!–@(û ô¸ß^r®šzÓc±Q=¾£ '< ܯrB_ƒ¬Bw —~Y a±Ê€p XÙ²²÷»¾ûÁíÌ DvƒÐ¬Šƒx‹ƒmÚMñÀ5q€UÏ!ï–`«ƒ´uÚ:€Pk!b"Ö¦]£7Å!Nˆî€r¿1êÿ℃Z@…ü6a+EñŒ*9aT1Ph8Sdª¨†A5ªñ lŒJ Åã´ñ ”…'a„ ñ *‰!C"´T7‡&Ñã57Pš]Â3qñ†ñ08Ž£–“Ÿä¨Õ:&ãâa,a4çX§é%:],ÃÈÁÕ‰Z0ÏîW/ˆCÆS[‘ÙR›& »—›OåR•?Åä2ОœfÓ ´ñTÞÇlÂ@û?4XkˆÔ~¤Æw¤”ÊÓhMÜß—z af;ÎxÄìö29ͯ›ñ4ïÆïbıZ´0¾‘þfÕÔ²‘ñ–Çzàa±<Ç ‡æó¨^¹p]¿zqú$Sûf£ñ”[q³=¯[6¤»Š¼ñÁ‘Á8•ñŽQÔ—} ÿ;Y!K²b¶+uS·ÍŠ•ÓWÑPdÙ,ê‘|9k-ާñ²q×x1Gv¼âáQ½‚’ ¶Cñ_PK’KA‘i Å” ,rebar_appups.beam}X lõ¿óÿb_.¹öìs’6m’kÎ…¦©ãs|i´‹ǤM›Ð¦ˆ1„sñ7¶Ïº;·e[¥òQñ1uÆ“Æø i¬b°Qº‰v 4&cÀ>„ª1LULliïþ»1PQééÞÿ½ßûø¿s®“3{㌤Òc»Ç\«DQèMŠ¢ö¶Úæ‚ngõJ¥ZqV/šeÓÖ]3JÎ5¥m³U·PtZŠ–ndsV9_Xl[4ݬ«ÛøQÑm³ìf‚½Ö;ÚæÁ‚Uu°¡©;&èÝ%6_(še½d2¬By ÆÚµ¬âX¡œ·ÂDñ9¡ß´‹zyÆF[j)yépÛªdsKfn™qíªéåò…²‘Å¡ŸµÌbgp§µîš s¡ºØ\sT´P3vU,8®ãÙ,›×;MÞ‘q,Ûm6@{h ¼¶V+‹¶n˜öԔ׋ŽÉ—ÅX¸>ﯖL¨‰/mÅYd]+‹/Í.À]<ƶ,3"ÔÚ«rç–jiznÀD‡ù ¨€k†ë=©õ¨v·æjÙ0᪦ъ¡Ø›úúûÙS/ÁaÍ•*¸#Žì̲([‡²Žkû »àϲ ®É`wœÇzž}ËŸ·ì’î®Ä-”Á¬šs V9[‚>˜F –›Ñ¤P n©Z^vøš0[²Œ*8a».æ*«õrÎ48§Z1íƒ(´¿Z1Ö’³ 3[ U¹š¯‹ æ’ÓesºëÚ……ª ÕÀòƒz± e&ÚfÂTíU'Ûà/`®@GĤ„-5ïÞ¤­Æ®νы•?–ˆs‘ëcñè`ô+!q€Ä¿¢D‰†¢õYq¾Zmo¯ »¢_ØÔØ`ƒv®KQ§a¿ªöïÐe@"-øB½-­š•4JCAР$AÒÈ'¦U¬Q4$jHA¯ ¡‘!„)D‰iÑ'§Ut*Á©ÀGÒ,Á(œB£M`Õçä Ë-Mó ˜ûd-C‰Z‚ (•þ!ôQKÓ‘0S â1I!b-"jŒ¬…Q0Ì(ûk®A‚T¤pšÉH^²E HÇßóñ°Ò;ØÉƒŽ)£ðA ¡A¹Ñš/ĉ =»JS49‚ ÝN5N‡qš¨qm( œÄNTŒ/ Ô´Š³aŒ`¤‡=m$ÁÚù ZçS×2ik++ZHÿŒ– UHs",Rõ²B‰_©ñ8s ©;4jRA™H†É¨!M¤çán] ]Ù|“( óʤ”ȈyR3(“€¾‹ôë†ÇqöHôý«$‡0$âc ß:/âê B@:_ã5‘Áùz<+±‚@Ÿ½}¦•d6Dѯ€p£DŸKþ[l•¤1Qc·2¸eÁRô<²aàš¤wú¼ú'Q¤Y˜Mn“B³Á$/Êcrb|˜#@R*AíK%„r ÈI©å¤rÂÑ~>äp}Ú¸ì‡öÒl¨õøñ u„†Nhûpù´ñ9 ÚQWsn„èmPÀtsôF˜¶]˜‡ÏGéÌýheì#šVîE5$ž.˜z¶c˜£ o|<šPgGõBÙà¯Í&”žOJ‡Á##ÂÄŽ@Ü5¸Rs^Zæd-:YÌ0Fy9†»V8#¤]XEF–Ó.„d”žCbÐºÇ„Š–9ëÇvÖû8‡uý)$ ¦H ªZæŒYÍÐ"xÍš ”ó4+ª¼ k>QËœC{@O³aX¶ š´U¢Ùv…oCÛßÖ1Ïmã;¸$¿†æ×Ò¸mâS•)¤eÎã[t óP¥Nï5€«$÷ó"± bYJÉðÖ÷‡òô6n#N‘äÖCô5­”äøy  VÂó@«ˆ¾…ü½P— ua·uÙ µÄ'к~=Ác^jˆ»ðr'šðÂcÌ%„Çþ/m°ÝÜ€é'ò-@цXƒó‘š(@q‚J^jð3Bxw¢ŸjÈaWC»䳘OÆý¢6‘úì$Ø-„§È|uš¬–çH­0n†<·,å{;Rž.¸x.úèðJ³»w¡¸pGÏÕ¹wO̹LÇœ{ö'¿},Ì}£¯í‰—ß,ß·;uçã·º±ÏÞÞóó'?8;~ó½_÷Ö¯nŒ¿nÞþüm}§ŸÛyä{¾Ðm¡O¼ñû±³ŸU®í ½uâüã·¼º=šdß—±·v¼§-ÍþeÛ@µýξpWéÅ÷Í®ûî®ÿɧ¦žŽ'œ©ßÅ7Üò³'?ùõ[ÍÅ?¤7‹­¾Ó·;=óÁu›™[‡^ÛøèŸKÝß?ræ½—oßbí|pÿÓ¥—짦߸浩ÇJûNï{ä¡÷ïýñ#É›•çØ¶k>¼òÌ#¿ø‡ÿÏ«o˜x!zíþwŸÙûìݧnúÖ£wß»úª¾­ô¼tâäïúô;Ýol}ªTjÿÄùûÌ«ï>ñÎ_oyF ú_üÚÏö]}ß7­ßýCó뿱üé¡ç·ç8tjөξÿ)=›?¦¦­®õoÉŒï%µÞt%é×ðz°‡ðxNvÏÑ4áñ¬e¿(Eø^ Qâ÷v+µ²;õÙ,_El°-ÞË"ÇûÚEðxGDÂ7Á—öu´ˆ­–|…:eïP¨Ý30ðÃÐÜÈ×ó3]5ýŸãŒO•ó “<<ƒñ«‚¿Á,oÚ¶egj©¤Û×c€ßªºðñ¸L1æB¡Œ%ta™ ʹb¾ø¨•Ð%:à¸Ôþ©é‰ìÜÔîô2µzP‰*ÉøÖl<1˜T‡ë öªñ}Ù©=“3ËTËbÁ•â¹ád~kî‚zfn–¨ý{ãjJIð²=hÚ¤»L5©ÛT,cÜBÉ\ò/@þÓY]Ðy}½÷Rwà«/g.S±Ø’U2cFE·ó×Á'ø’ó>ûcŽ‹5þÏÇ€iŒ-8.Þ»ÿPK’KAª`h`rebar_asn1_compiler.beammU]ˆU¾3w’™f³íd&íjÇMDèv7“ÝeÝV¥wwMcdÛ®ýà :;™¹If“ÌÄùÙ¶öÁ¥¶² è"¬ˆÖŠød] Rð¯ e±¾ÕAhJ©Jú"X¼7½[‚4ð%çžs¾s¾ss¹w×Þ}yÄ—Ç c»ÇB¯ 7Ȫ>.›¾anÞ°¼fËi`_d†X!_ §,q¶eú6K.›~˜ ýÈY lºòƒ(%Qè4‚.7pˆ lZ5Þ«'¥Ý,Ý ò±a;¾D®ÙÄŒ縫ÚR¼V$Ô³<·âTa‡1×óÊ3qš`…1ìûž/Q-”Ç~Ãt«|__ W£†é ¡áXÅl˜oÎÆÂšïQ ݨbûfˆí¶Ú Öp‚0ˆU¼†ÝèjzvDD:nÅ[CšëMý ç†ú+‘Û¯÷K¾ç…TKªŸMšd!&<À«dÏeðà3OðÄɼҫqÚjMF0ŠŠ2@P¨T”‡PQ›@E=ƒŠh?T-”†RKÖ8W|CI@ò4§HŽýž(k}á9¨ÜÔ ›æ• :×Jj:-¯B”DYïûžCÅiʃ¢†V<«ˆÏ ¦QŸ’‘\H(0S(¶2*i+jÓÛOÁËP‡@í[Véç¾áæú–i)™f¤Ò¢ÖBÅ9UÔæ$Å5Zœôå}>—{PâñÓ‰õ_p ¤3¥Ìk@ÔÎÒæTðYt*šÊ-¢â”äE[zrWÉ7x%±Içî&e2‡€2°*Ëš\ŠgUºVÉ®-ÑãÉ’N éWeN"{›Ð'¥÷È78I¡P©<âÓîrRšøz'­M"”"¥Óh(‹ÔaQ–d‚‡´ #Ñ ¼ZH«tRy©ý-ª¤Û¼¬?"NõdÕT–†¨V]å¤u¤_V礞¸A°?ôÐQj¶èïu…AŒ N ÒóB°ŠùiN’ÙÝ« xvÆR,®2ÏrÖ2{A³!;‹«¿¡#gãÿêS{3ÁÆ£9O0ÿŠÝÙk…›¡váh{Æa6›Æâ*³Ó-²B‡v~Wä®pé:Ëú÷0à[´/ã­ôæÁ½Ä¶I'¤Üw.ýøà{c«Oèr¡x²wìóü'' ÝÅÞÉîÓüÏÓ=翾3¶îüŸ?ì|ó#å—3óç?ûò™Ÿþ9üÖ¶Êø»?~ßÖW˜¼8zaäæÒ“£­ÛÏn¸{eqËÛ_ß¹yó·'K»ï_>t߸¶þýß®¼{%[ûqýídæÒ)|üVé«O_NßQ^ýÔ¯mÝ&=«s/:çéœaó¯!èb¶8†>ùÝóVƒNXãmg—.8W¹×Æ?ȾñáKw¾7’·æ.34!nFaÍóÛ96Pü( 7&*›eóž WÖ y&Jn…ÄŸj×(M$w±ã¹uˆ6ènß»F5›¦¬]׋Br׀ˎK=œS¢ãZÈÆ6X¹6®8.¶kÄl$Æ–&Ÿ7”vê`Í žÔGó#F~hptxûJ’thb¿QÚ³kotUPË[ÛG+#ÖÃðÞS,ß—ׇÚCгØˆÜ:ˆ <=0L}Bè4q-^&ú¯›’)›ÝæF3ß–x‘oá:ÉÕ¼&ÎÙ-Ó¯8a˜#ÏJÍ˵ \à[¹G¼’äÅ™cå ¤gï?PK’KA1 …· rebar_base_compiler.beamuWklÛÖ&u)‰¦uZ”ŸIÚTì$ŠmÊbÙnšk˲ê4-ö6,ȦèAÙ´TH* ÅŒÁ\¬E; [f?Ò½€V`+0`+ÐÝß"ËöokQ Í2–+†u@±s¥ëL];‡<÷œsÏã»çSËgÏÅ9‡Ó §<»Æq¾ÇqsŠcòN®wÍ\Ñ®5¬ªé §Y÷Ù•€éTóõuÁ5«åPÛ¬h×ËÖº¸nz¹M»àúKf¡¹ÞÕÖUíuä¯Z®ç"×¼ä‹ÅºÛª¦gU]©lÕK¹2pw7Ìb%WÍ»^®f—ºŽÝhmky.ØvµÏµjêã”rWœ|£a:‚ç4M9_uÍ õTµ xÇ‹U¶ÌRЭX`XêöòõEDú¨çkf°d9ô-Òj)#lÚV=ì˜5ûr+TÍ®çyoÃïB:žòyE<È í$fæ‹‚U/Û>Ë”m§–÷ðŽîRÓlšBݼê å¼U™¼ä7k ïšßÛpì+ÂÒÙ¯ž ÔéÆj dVMÏÜõ¸hÛ©˜NÀµ›NÑô›Žc;ÝPhT4ânZ`ÇOÀ¹M%'ÊÍú„>ÑÃVÕbôúT$šY+€¿B¾à´õF‡»ü•:x¬[ží`¦o{ãRvÉä¸À· gd®ý· ´ÔÃ˾ð(áÕNˆ! («)dM JTÐñ q4B¦QXWx½‹C$ªAYçŠöAN–U™ !-ø4’áru ¶e•ô  ª“ˆÒTœ¡_ŪÊÙà³$#»­&–[|#´µEG”ɨ I â ¤!«Q’2Z"ÚZP%òE9Ýuié®Ã<&5…¬A,))âA47"É4û z‘ ²”¢¯­Bë240%(A<ä'¶ø-_XR²üKúÔ|êF?‘"?‘zÇßeI@Ã*ˆ$"D‹dåTJ–0ãoˆD4b($ 1ÐÓz8«ð¯iQæ­GH"E´Ii ãþ.DÌò„H<Ö©(I5…/(oÑÜ# ·Zd[ÖƒêK-äXÑȇÒRÒQ‰òmÞ†U^”C€³û_§§›;x@;,ób˜êb8‰´€´¼•%µÃJJ#«ì˜ò¢rF¾Í‹°Ñy±7ÄéO«:îGó÷4¸o÷ñb-Gì?‰xqlGÁv0‰÷¡Ñ2(FP^«wzu'NFyqàŸ‚˜ÚÕa:$ˆWZ Õx&áE½ü¢9<ƒÔ”cxF‘FzŸŒà8ÍECdIƒÖ¡MËñ´sŒVçLOã/N·Ò¿a&‹`Õ¡‰¶Í#±crèÿšò]yYÕ2’ž(òËj"#Å3(дÖÖƒDÑv–k=ÚëG!Y$î¥k¸ÝâÌGÇé3 L4³$ŒÎÈxqŽ Ëyz A¦Š°x„Æ/‘-Ú—t¦À|ƒë— . $CÈ> }ÄÞÝ=ãì÷àˆŸ„G¡¿O$ñ" é*Ü0¸[0š¢AUìÑqŠ‚”¢ƒ ©/ð"¡#0B[䤷Ð^m«20¬aŒ ° E,øIzURD:Ç+†Áz ¢%!Z:‰—QH…hô&£Ö„6^#íE¦;.x‰:Ì€“9pöŠFJGܪç¬Ñ>+µ}ÿ($ùÙÿ¥Pñ]@ê ù˜=fü. ÝŒï 3¾¨ˆÚÓÁïe6”ß×!ßÏø(ÐŽX1&§9LvÈL¾Ãû˜ÍL‡M¼Ãf–òé«­Ú «yšéçÏ1;º_dXøØÛßá׷ܬS?“Í1œžb>¿ö—癞ú9Îâ¸ïÄÞøl•"¾á+qè²[o-ê2wëU~þ•õ ßüÙÐè§ï~é‡ßÜL­ÔË oÙ Ô>h7<Ë®»T,q¸õí˜s›µZÞ¹F vÓƒ¯á '˜«N%¼Uá‚V½Xm–Ì×Õ¬—Lø`7Kt¥'-~yåÔRnmåtºÂížÖãÓz2>“‹'¦“ÆìŽ‘ø•ÔjnåÌòÙ ×½nyj¼8›,ϫϮe™:p.n,ê‰ÍV¶—MÇ…t+œß˜<6iP™àY5s#P€üÿœórç÷æã­ÔÛßÃnfjî™S¥FÞ)[ž7_õöTëǔ맾à—Í$ü¤Ùä ®Gü?PK’KA-й+,rebar_cleaner.beamURËnÚ@?0$„2‚mô±èl”’‚„”@”Ю*¹Æ›Áö ÓvѪj×ù„~Dû ]ô ºìGô:ã˜*±t|gÎ=sîÕÕ-¯l´gãéèbÄi ¸h4Z{ÌõäÄ*E¬7Ä ÊŽÊ<%!Ž´ñJ‚3žUCÊçoê) ò¹˜„Ô@,ñHÔ"÷Ýìvf¿æ¤kuá£twsŽ“¬ÂR—…¢™ ®w_$p  +Pm=é(G:êS§ß®ZÀÑô8z»ÖP±ÔÖ 8NK[ÀŽr)nPyëhmIt,e§¶~@åó:¸æl%ÍçéNFG "k”Q0ªjYÿP@¹w–ü‘œŸä§ï ŸçåÛZ©5Ê3(½Õ=f9‘úãRW/ã^ ”ë^ÿœú«r4#Ι¬õ5‘ÌF €v“‘âB øõwôó£ž|óûö[üîÞn's"F«<.ôºÔWéŽcJ2ITÐ@ŒQæfyšzìƒ4çf1ÐÑÉ(8ULü$Pr l4‘ p8~5?鮿Ó4û–Ý·†ö©kŸô‡ƒ³½¨özríγe êæÛ?†§þÿôruY¦+{0¶N¶E·7ˆe¢ÝT½½ätŽS´1Ö¢ÿ?^̓^Ã;öì¢õŒæÌG1°Ì M‘ì<bÎ͵—m¨Ylž™1ß|°õ=±¸[1Ñ:ãrþÿPK’KAþW| rebar_config.beammW]lÛÖ&u)‰’Å„2e;®Ý„5Õ´‰"›²\Ûr~LY‘§ŽíÆN°ía*%ѲbZ4H*M±(’èúP¤ëöÒX€¬Ãô¡C±‡P´èK†aÅŠ`Z¬EƒmOÃúÐb?ÀŠ}—ºvÕaxϹßùîù#).®^ÌqÜAa¡\¼PôŽ ½ÂqÜù„kÕL·ZwÚ›­f_Íô,¶Žt/ñ¦åW›¶S3mÒ¶žêëÂ;~Ëö¢t«þT#äl‡ÍšãúâfË¶ÚæŽ%\qZí°åºŽ±ÚŽÕööS7íˆåÚf»Êd|c»®³k·<ß‹Q¦«¦Ý±Dº¢¶À8ǘ¶}€]»@x–iX¶å[q,±ØÁ9tÉÂE5ï åªúNµÕö­¦å’óK¹‹ê3wCÝô[N;J­öÕàD\cvÃÚlµ­F¼åU¯ZnÍñ¬X×Ûvš6ÍŽ0­«–eûü™ zx%ô(€Ö%f]ó­¶G¡ªÝªQR×jvlÓ oš¶g ¾Û±Â «Öið eB£U÷Þï¸VxÓòë[ò¹ÙnT-Ô$²^º¸´¶)­®,.U"^ÝmíúI×Úq®ZÕ®VE á âQ1»žÕç»OWS¨æ‰hP@–@¯«µV»Ñj7½ð¦c7ìxЪ³ oº‹õí8Žm¡¸›ÎAšužÈÖ¼‰\v³ÓÎêÙ>³ÑØ£Kfá=1™µëéoç€Ð³½–\–ãJNÃâ¸èã˜Q™ëþž‡\†Œðr¨LæÕ™ Æá”¢j™e2!ëF…SŒIbhBTå ¢ «¯É¼ê¿ÈñÆ™‹r²A“*òš¼h(•ÉŠP Uˆ¡~Yá×”ù'g¾K¨¦Y:^è¹Q»GÉZ¦£Ü0´Ôÿ%Ju‰T…ß• ¹LB¤œB™ˆªªòÏ.‘¹K=Q_R&ƒ5Q_ãoáp•¿ÐÕ¤`()ƒ¤qåI…ÄRN)$Šq*ê™»÷UTú=å¤roÈxç—7ÞãßÈÜÓ~o¤IRH¦]•U¹ü)!§ÿÌ¿ «¡¥“”b½kV(0U l¿¿µ@êlTTEàŸ –¯¥šª¤»©ê ÿY¨?žÔyQ.HI2¡ùå‘_)#%ó“@%eE_ãŤQÑÉŠü$/öÃ'%¢K2/¦ @(Hƒ ì¥ÌO&Ô5ZT¡D{+¨R)h®f¤ˆ¨¯©¼8¸Ï<ªAX¤aP T¨òiX ¢É++ê./ïû<ŸC8~¤ Âg´÷øQ¯¯!ÿn8­ˆªÏÒR¨yB(ç‰f¤#‡XnetŸ÷AðŽ –ÃI%ñÑ鈒U4Р¼½7 Òa”àHVR÷v“(ú†€¦kFühß@5zÀ°¢¿Í‹…úÀ=F}íDÕ÷ ’†Ò=+¥éÄó-RÄ5œ¨éó„F˜iŽ÷Ç'Õ#è.-ôX_ø3ÂÀw ¸G£˜YiŒÁzñïÞ1QY”3R†T 4S6k¤¤8P3FÅP`Ŭ!K“º4NNi|ȈK'âR–OÈ*‡‰×ŒÊšò<Æ?®“¨.ö#bQ”¥•IF:N3˜@ ¡ôzAÊ!ùÜ^u40‡ÊkÝ¢FH]ŠU·H{ÎÜ~Ï&A5Þ|AšÕÔÞü蘟©¯æGàÅ©}§Çà4§i ·ypë ÝžTzâG6(ÈIù6&G©Äg1:JHYTµJ¼P!eM¡õ*v§BTÅAÄ5⓸Î&8š• ¤Ht± Ä|hZQË#ÉB>¶ ­T,­×¡­ÇZÐêźwšs¡Ý,Þ|ù´—cuhwŠwÞ|Ú›1Ú»Åw?¸íƒØ¸qŸÖym.œCeçÀp2!Ëݦ)i…™ïyöHóxøHóxúH§nHgxñTF:'P¨;7§eC/kݧŠQÙ¥ÏB0ž‘U½,„òôŽB«¼ÖSªÀož¶Ö@ó€»ãÕähœxˆ–)EçXÔÅa”~¸®¥Y©Œih×YíS´kÙðâYÜ%¨0Ž¡c[âÅò”´@ö·á}9WV8ñ^<µ uÉè§€^¥/,-¸ÏØ3Z ÝÄ×è 6^|bJZ!°\Áy¬ÏJ—ÁÆ× Ö{ 6ºë¼xiJºH­ûî}‘.íìâÊÛX†ð‚D Qö¾¥ë³Ç!} {½“©½¢@³'†Ú‡z0ÃlM1ôàìá<Ì0*ä!†¡ë1fr”ÅFñöÄ–a<' Y¶¦ø㙄ä™} ò³Óõ4㡘9¶>9Íð¤ÈÎ¥ö…ßpO<‹=¹,2ê{ŽâË×h͹÷!IH™agë -=¹æ{j CŽ3<½cxšš­i]özH9FØšÖôã¡¶Af§¶f§×[+,>º–Y~ôÜHO®{çP{h±Ó¦y2½Âö.0,Y~K_nùsòÙµWw^üõwôÄsÙÈ—Ñ£?»}n1a?Ã]þþÒtë{ÏÿîÒ𛟿÷‹ÐBíógžú+yö÷ú¿£'–~xã…»üÖÌëûƇ=7}¾¶»õê­Cÿ®dïgïQ=Õ|勼ôÜ7¥~÷¥è_¦&f Ç®—%]ÿËõÍ¡æ3ÍУ¯¿5}zNÿ¸úãwü±­Ó¿¹µúSåG/~üØO®ývõßùgßïÎå–:õ:׫ó,¯uÖº^ýŸ<ϲT©­Äìô:ÏðtvΰõI&t= ™aøiVß`ž‹¾ïÒþÞ¤w(¿jpäª×”¶Ìݾò§‘þËwþõ¨2?ßg*W®”–Ú›ØS¼@ñQüKÇ—†G Ñ'ŸbU¯³³cºOS@Äéø–»Í þ–S ßÚæ¢­vÝî4¬÷Õ§ÏÁ^£ÁÅ.--Ÿ­n,](os'õܤ>››®âÍ:;U؉—KëÕ¥•ÅÕm®¯ÙòÕ\½0»9]ßß^ÝXcÛ‘‹¹©=%ˆ–~Š Üm.<5>3>Em‚ßÚ±¶"5Äÿ‘)š²)™£f.Ýs:nÝÚæ&&¶œk¢±kº›-ߟÀÇë–3|žMxn}¢÷Ëv6WŠ5ϧú/PK’KAÃ9XÊÌÜ'rebar_core.beam|X{tՙ׸ެY7ŒzÅh»>„¶'ÂM·XhæKõ¦Ë[+|¹Òìu›ÕBm†Í¸íóµ²;]©¹e½Ýœwƒe·8?³Â»S­Ï0ùvOý`_¥•ï0Nª-wEgÙ2ÍzÉmµ fn®P+·‚ÕJ«Ý MCj¡4®7Üf¡]©×Z}ëùv¥Ú2Ü[ Æ¥²›oÚ³!(”/.ë-·Ýb5÷pO¥Þ s…öiÞ½C­Z¾Ž.EÙ­ºm7_¨VóõâÍn©Ý ¶g›õÃ}u [hºRu«•boE-õÃ…fÓ^­0ç† Åý²Z½­Óf¨åiš«—ç«n+¨Äöj¥¤,P:ºµC½ÅB¹Ðœ ºÍf½+)†e±½­ùééÊ­ý§8¾%`é¡°Òǵá–i3rm¡v„&y_žÁÁp£éú$z¥6]ï+”Ëyà0çÖÚ}z«íšMlÍÝ&™“oÍÉør¥ÔN׫åꀧXµ^(ã¿R¡ /Ô¦+3‘N¸ÐÂôyUj3ùb¡å’*¼3 3Õz±PíÙµkImåo˜ä«-ÍÖë¸à¼}ž#òí# 7Ôt«ÊI„~}lhWaCŒ|šúT}î­ni¾M°º‘¥9L7—Õù™J-Ñ#$C¾]ÏSDFè?ZÐfȧî¸JFÁ°kuµÕ;]@L”{+t»l4+µv°P¬7ÛaçÅ*µRSÙš_smИo” Pe)¸9X¨dYAÀ)ÌWÔêùÒ,2ÑÕ‰ŒÓ‘†É§4iœmº­62©‹W˧<ÍO¡oýæz¥ÆWªåR¡Y^Ù‚JíNô·ÖšozN‡UÞntz¾V"ó`ËÜ2œrÈm¶Ü¾æ|­sUeÀÏàðòì oþ‹¶$†«¥øm Úö‘[A±õ#)P8Ãë†?â0xx¶RšÔ”÷6´Œ /{kË6_ÕK{ª@âwÕpWDlIútk>°»,)ä׃õÈؓôÙ0|J¨c¿‹ Ð$ß®þ궤mP±X;üÁ¦´L€4m¹ÃKýk‹Ó%$HCx °º„þi¼ ÿ…±]3zú7šušá»-3»)ËÂÁ€i;ûìö¾¹÷‚â¸æ–%M}œõØ20e“…CM©3nY†&å Öo˜ÚÄ[›êéÙÐ'³cÎSl'{j@ïÜû°vÔÔî—‹ÌÔŽïaÚs=ýï´—"hð'hˆwÚë=ýÿciE&¬¨²LRšñ™€d1=ðŠd¦Œ±h,dIp÷ÇB‰AeÅP`J2=hÈŒ-ã¦d ¨Õu)bŠ þ/‹V`<ÓcFcÑŒÌ,dÕÞf,G†×²q¿Ô‰{ÐúoGãFòMæÝýLƒ¦Æ£—2÷ˬŮ4ŽkÜìéŸ)5‹4$)ËDRÚiNJVÏ9b¬ä¢XU«5¾Št(šŽ)ÙL–¦ UW@òÕ² U^’,މnÌ;b±XG,Šât¨±S㧇ƒ¯3dÅV$ÎñSf¥²Œ¯QœÞg²rÒŒNÒ=Kl—l׋€K†7C‰s@þ~ T;0¬10ǘaãšyB–MiÓ¥´,'d&-u[&sÄL&£™èd´¬O‰0Öëc;cb=-Ö.Š34¾Ö×GÁ’ðt::ô7`æ:?LƒY&MèÉ ¯ßÓø™„ñÄ·ïð”Æ7¦„å,¥\ ʵ’bSiPlj핉’42 5Ó2gK–“%Ö;%†5¾)Ò8 S¥™‘-€2ÅdN—é˜LÄ¥*‡,uÄÙîÙ®]qÛdr¶Á¼ÓÍtº™lŠ/г4—É„Œ§)ÆbƒÔK0(Øç64~–Ì$@i3ådNÆYšàäì3v3™xLÜŠs#S YÒe.&ÓËAÂþ”8¶v;fЄ¯q›¢è(å¤Ô'&(ˆô€˜êÒy d‹®@$ñC¿ ‹á”ÊíÀ°"÷OQ$åÇÆrFž¥`'Tœ,é¦fôÚÖ­×6Ì13z !øL™´e;!à !Qò–@ •¤E’Bëóÿ'º‡ë6#>Lï0𲟛†e ðÇcÂýÂäI„_ªDÍèb—d™N*lC*øiµ•|»•|{þ¢Ø¢ñó I™ÉÆ'X‡ÁÛ=žl—@=ØÓ0&¡ò§»U¶¡ršÄ¢xL2Š0; ©WÐúX7¤|$8Ìù[ToÒј·yØkÜ‘ŸQ@Ù™h÷c´£˜IûØ‚ÕP,ã¶œ¶#&áÒÅs,<Š$8ùXÄ‘²”° ‘²Ì°hf ¡ ¡*Lw¢g+…Ç6JÅb$ei<¹’ZAlÆPu–¯RöØÔ¾ç€î"ünÔ2¨B9"E §(½.,Š_Hô@ütD¥HÔܾ»;# {ÿ%„Þé}A¾FgéE ›Ðø®!Ydjb”Áµf’ò@$})[k1J¢GÉ¿/ŠK4~1Õ£I‚è%ª…K ÅH:’š ²áòzˆŽPbÑÉc‚Úˆ26¡zKž"Zh"“â"8šÃ(Ù1 3@!="ÆÙ(³)1fïÀ°"޳lÌ6âž²¤KS"ƒ@ÚÝû»‘ÝŽ³ÛbÙxÖîwÀ8ƒMd²ßœDÑ8žcLf_'¹»InrÇ!÷RG\N†_> ûÅeá¬Ø£ñËPt®48Šòo¶Nã—«>Ì?†{—ÃŽ+d:'ii'¤i“k³ïP½ZãW‚âc ¸êŠ÷}Š P\Ü®ŽLP†ˆî:†"¶žÈb†¤ØÅÆ™„:°êI3Hù ñ½à29¹HcÂo¦ö¤„¿Ì]/å¤LÀÝeÝsIq-óZJmOt¦ªiñ ޏ‘P¸‘"o²(öi|ÒkPÚ;¿‰Îo¢ðØ·(®Ñø>zÉPgº†úq`Ê^=l\§jÀ Õ¬¹c D¯EoVÏäZD‡~>ÎlÈçQjsª —mªChá G.ÖÅurRµ”ä8C:f°ßÖøu—è)qÂ`w\o†‡†Ä;<©ñëSb?‚h¿m!‚ƒb"PL3Nõ’J=i ‚{T½“È÷]#â³p+šiÕµEnm)·â=öâJ9¹u.tàjvWm?µIÞ…>›wúMrês| >¢¾.eøV“rÛâ[ ¤áÝÔìe7Bó‹ ünÜ'Þ-{Ì^KÜ«ñ{h'÷ŽˆXı.1…”gÛñ yìAªÿ÷Åý¿O}Žtzè½°ésO­HŠ{˜×ü8úbRÊÐöe¯½Q°X\=·cê4Nýe0ø1_NŠG~s?‘µÁí‘•^L'l8éñ”x ?¶ 0Ôé–éCâÑXY¡Þy|OM Ϙ]â+”Žtut:©ŽÆ¿âÄ~=|ŒðwPèv(ö8êLTe®I_Eª¬¢cÝaʽJv"Fé5(¾Êö‚í‚ Ê$5þU2>IóE¬5±{&g˜þÓ||Ŧ› ˆGé­sœÄ`gÑVáâ€óv’ó· lÁ°¼]S}¼/Hø ½þ ñõÎ뼞_ UNÈ®'`Ò§ÇéùÉèî…)ñ5Àùdw¼>Iñê½%¿†Cõ_¡O’ÇÿL>о>#±õVǰú½I³|éñI‰§Á÷iætøŽ1+ሧͦxï®!ñÍâ[ÿ¦!é+Þ”úëUÇ¿oQŠ!~tÑýl0ÏPÀIŸt»ÐŸïèÒ“îîôiwùûš?—]²F»ø¤ýù¥«OOr÷tɽ²k~U—žWûwÉÞ½þþ>Œk|¬ Ïk»äÞàÏIŸ›ü½<Æ”¯?Í >š—»ðœîÂy¦‹¦Ò¥ÛAÿ—t«úû¤C£K7åÇÿÿÿ]” LSWÆ/¥´L™Š²áDp N±”² Ý€¢R‹¼A Rû¸ØR¸•ÛDeøDTQ¨°©†Ól‚ø ‹²€ CyÄ¡8«t5L’YSÐ1Ýο ñ&¿œï~ç;Ûžó'‘…°AÌBè Ä*D.hœÙÚ±´'" tþçÙÙ•ˆ=àïGx– ÀºX„<æ+ðßê·ù£à㽕NÉ—AÆq2xÝÊ)™o°¶mkjEâd/‚ÆObÌçàÇÀy6ôcÍX£§âà7±C| ~Œ#X×¹ ¦öñúmˆ¡ÇÞ¨=ïí0'Á4%G£¦Þ[aÁJ?ošBð/á(Ë4¯ˆT:´Æ&dÅo«Ì‹íSÏ vnb™"2ƒ×/©ªz˜œñú—¸Ûìès³_ŸuŽö¢¨ÞerËî‚ñ’ü^͘µÛþQ»¥«k¯ïKÞ1ÒlZÖn]æmî2: %¾'·ï£5O;¾LmÉiÕŠ§g»þáq§µ!fú`›ÛÂò¬Á‚””³•3¦}àß’=Çt¢íAwàcAv^[¼‡Õ}¡åMâݺúrþßßÄ<©-ºÕœ¿µÅ¡m¼¶vèþ¢g5…ÊÒj¨h8µÛiဇï˜ç€x¤=?”o“4´gS™ØiÇG£—•¯þ5Zâ`•=ü;'¨bÕ¢â#†ä›l¹5ju£¡‡÷$±ŸÝ¨X:|µhîš»åžQ<3¼þj±Ð,/ÖWU‡ÖªÖ_<¢eÿ~%lDymןAz )žEÕ¤í@G…‹ã'Ùƒ>ÑG­žö\aîÙœÔ3—ïÖÿëðÛ-wÎÛ}RºÎ2®Ù¸·7uöË+Þæ±AaN¥óo4¾´¤•7Ù›º.• †ª*ãÍFãMι[ê‘ÁšK7s¨Fâ€K¢žÕäö«ƒßq¹¯³Ag¼¬à s‰uÀó!Ý]¶aìN]̲/à ©Â™5m†Ñy¯ªž&¸ô.5%íO½—g8šqÌmVíëê(uöÈýNþ42ºž*ý^vÇõç1ñõO\WòÂ^%»‰šÇ~ÐÿãÀÊ;¬>“û¾9:ùÌή€Ö[^Û×YN×'ä v®åíúÂ(ÎrOq}eǰÊsî¯OX%ÎôðáfÔÆ–üfz¾Zøy€ú‘Y8²2öv>ñÜ׈/ŽFŽÏ™I_Ä)8»ýïœû©gÝ~¢În7âd:ß¹SÏýð[‡Aÿ„0€¾†(‚ü•wîF̱òß"ö‚®Fì†üiDäñwäÀÝ*}\o¶Cþ0hX?|\«²¡€fÂúzÈàZ¨±¸¦RÁµ64®ÁJX{$èt„ÆâZ›Z†H"&ŸÍˆ(ØC,"‚˜¬u¸¦ˆÀD¬ûÃ`oëСˆÈàz»Öú >"´?ÂÖòApˆÉ:¹Þ±ï˜ß8;X§£Q»xožYÉP¶ÙZjâ…r&Ô¯õKòžJW¾µ7­„—žN¡o¶™?‘gâ<[³U§ÒPZl°„#IÓZ¢ÕgfJé\`iô:…ŠVLR¦¢°c£Rl%ÏÐ+HñžžRi*ŠT(mQŸBAL ‰ $qáajb†Ÿ/×Ï7€Ë—py~þoCö ¡±’ð k"ÕÄô-*Ý®<0 /ÿ¿;2. ºY1\ÿ_^úÄn³IZ‹¶«&ìü—¯Xî=¦N•I*Yèÿc÷Jí¥ÎRGé<)wbëZž–“j‡£Ôd’ÅV)¦Òé82©V©áФLJs´´|RIäš\NÒè„Ë´øüÿPK’KAô‡ÚS  rebar_ct.beam}X tÕžÙ»Ù,˜Íl<6†@Hv’l ‰$L›%B ªHØÌîÌ&K6;éÌ,ÄW‹ZÛ”Ö >êƒjS[íÃ=BÕÖ#jA[­â«ÔŠQ´G­RË©­ØÓþwæFìiÎùwÿûÏ÷ÿãþ÷NÎvnÚRCQügm¡Ö­¦6JQ¨“¢¨~FWc²›Ž¸éŠ›Q%©ç“–N$‡r‡T3šÒârŠ×3騩f4™ˆŽéª¡¦Mw"™RSɘ+i`Ïœ„œ2T§©gTçnYOçÚL)m8´f–ûT=¦ªKÕSrzÈQY‰Ôô®9¶KÆL¦ ‡1œO©6ƒGM]µÂ¨º®é9æ°®ív§µÝQÃÔ8Ïn=iªQ¬æÆ‡ÕøvtÁÓdzÁj4£æ¦fGRs%4}T6cü©ÊŠåÉŒÊ#j4>ª¸qéñÝ ƒ­iyTuîÔ’i·3¬E\STF×4«g ÆŽÉæpn&­¨‰dZUÜi0ÉÊh®Õ½aÍ0]I- ÍÊI% Óp'R²iªi{ªã¦.ƒ¿.óâg¯ó¬4̨1¦Æ × udX{ùÅRª’£¨±ÌPŽÓt3/®¥R*8¥´˜'¡¥ìò vÖn­Ü<.'ÇK%Mר:Sõ|Òañ†éêP&%ëóì>dˆ‘λ¬O#Çú*ÀfE…I‰Ë¦ªXiÈ)—©ÀN΃)¶“Õ6«q†xðÊÆÏÕ”LJ&Ó Í œµ.ªúäiåS<=<˜­ åˆ7ˆôØzDïqä,Ò×Î *s ¬Ðx5DB¢œmˆC‚“c97%Š/A”—Ф©O¤ïÀLa¹IB|óú€yɇ Ü.”+ Êm±?ü°ôO–œh‚0è®Sð‡ÃRØò;üB]ØÃ‡ý¡:ïõ¹…^æpl@ƒ$O¬Cô)G¾§£.ã$êEnn°‘õ¢&–·òå!_%ËóžbN1«ä'8Jò[M!†£hÆ (4ã¦öHá=¼]‚¾–c¥H¹…k+Ù|4ƒÛÆäC|†‡DdQYÌ9Ëë$ñeØ1|˜zÙbȧ8;Ÿb~F æ%ܨìŽ99 ù³ÛëÈF•l¡s 6¶ ú½@ Ÿà%(àÜÌ +Ù"tîÔÿÄá)ð9 A†CŒpL¤™b\Ä|È¿ ò_@ºh!¼Æ1¼Ãl)l1[ “Ä.œbÑÌBÒ îD#[…•dVÂÏØ}Æù8 ^„Gƒž•àp¥¸g‹!f¹@3ÂÜ=0ÛŠ„L7u \x˜ïˆ[` ‘XÂ@E^º9Æ+¡ ˜ fMdÎÙrœ_9Ì »d’]J3KTÈC;¼e³ÛÈá}lfý4³Tr@x?v¦˜|Ü}Š¦Ã€Á r "ä BÀ¯öñáÀ¦•lòTƒKxJæ©8%*¸Ã\9PÈ SÞâ) "Þëôú¼e^\Ã|ìU5IÈ/Exp–üŠ7)TCý’‰¹Öà°–ÖŠ‹0a¨LXtâ3I±=Ø–U£‰¼&Qƒ?Q#È!ª‚¼ŠÕ„óh¦Ì®»G·Šüæÿ¯Ã<«¨ÂkžS‡i×áx» <ÊøØf§G3çad˜YÀKhbŒÃQ9Ž=v†¡B{NÊñˆ,ƒ ÂXVX³\Ï÷ˆ0JËÁ¸ Œ+ò(hò«¾­D­ˆ÷Ù•p¼™E0v`+a$OµuÍ1+¡¬mvª|¨ Wà VçqÖ%; ±x¸aE¶V¬À$[K3p+ÁWS$1küœu?‡œøraJyÉÓh<'޳Ç„E"|m”`ßA6ÐagXƒ§Y'g x1ÅàV‹â–Ôá–!Ùó!ÙzòF@¾!Jš‚a®ÃÁíÐq¦—™ˆU€l†ïÕŸ#¡ô íò—â[$²M¸Æ&|¸¦ØFši°î'Ê f£D”&ü| l…”ÖÌåpëý<™ -Ùµ˜h-nVó$ÛB3Ívùe¤ü|˜ìJÖb2 ÈÚÁÞj“w6Y&ëÀdm“l;Í´Ùd儬ý ²L²°w’ ÌÂèe°“Ð_¦´’ éµ9*¼d˜å8êb°Ã^Àžöãþ‡™Y'vÀ²È» “]³oa¦ÒzϾ¼Î³RïÆ©wㆮŸb7ÐÌzûÒÅ{¾’Ÿ¾üÞÙ0Ûän\ÊFˆ¶¬=y@«a–6à*ÙM¸2)›ìM¬"3Ü Ná{³”z8f ÍlÁ¨²Á(0p1FÀ¸ *éo`·"¨¦ÁÆ;¡ò.|8ñ•ü¾ Ž›mœ~«Ë[ƒlÞÔÌW€¡.p ìjš¹–›!ʶö"Ä‚gˆ·&¸Úºìá pø²/ ²bÆí@±(ØçR¾D1M±#ÈnÇQ èƒ¤Ø8Ê¡,?”•ðxð‹˜ñ‹¬‚÷EÁ#%O²1š‘ízsàÒ‡÷`Ì^MÜì[`6J<ÈFqEòôÃŽ1e"¢úL=‚ÿQëƒoú0¨ç8Ar@ˆ„¡A`+)–ØYÿçyAòA >¢cß"â‹1ó‰Ž1 ˆïBE_ ²˜è/déKˆ¾ÄOô…$ßYÎe„³d9Á`}ÁT‚¬$¬W½4 ‰½&+V-H]V¬¦¬×~áX-ƒõµDǾR¾-‹'Lú‰sXG0¸·ÝYµ÷dõ°'+ŸH¦cBãx­Ø˜s#ñë#:þÛL|,é̤#¤ÿ×Kì,E�;iÆ¡@ZMã·ö Œð›¹×·ž¹áС-kïœßvïÒ×\ö·Öß­j{ôPlÆxàÞÉú[/½éÒí}(ðï·~0}ºüʶÒÄ3·ÝÜxé;å{§~T±w«vô¹gŸñí{ãìºþä}Úóž?Ú—œ¾÷¾} ßUo~_žóZÉØ¯ÿòÒ«COœþΚº#{©_Ñ;v–½¿në%ûÓþÀ^þô±‡ŸÎ}cßu·ûö¼ºç“žî~å½xßÇÝ'¾=7uφéON$îÿ~hCêž{/¼MïÅN§äEOô=ßp¼³»ù2nzý¾ç¦Þ«?õÖONÆ~‚6w,»éÝÛ[v]²ÿ*×§ÓO7ßvwÍ'wýèë‹×½õçk*¶_ûÒ=øêÿz:RÚäúÙØgìÁ'Šþûí»®ÿð‡/6Ýé¿åÛ—;Þ~îÌŠ@íëfúMÕÞOïºûÃ;ËãÉØÊÿ´¿â”ÿzúã©}÷ï\vxÕžk>|rûS å¯Ô8rüêö¾±ä_=8wè÷™m‘ùþ¶‡Žu¸zpÿÌ«žƒí¿{€ ¾zeÅŸŽ^ó@EEuÁ›÷ž(©¿ùg—/›¿õ'y|û塨øbmГ{dó{gôÅ7ÿíéSýÄ­—=µ® ¥âà{M®»ó“ëÒåüéë˜|á߇[+·Übl1Žì::óÏSWýÔìÜx…ëÀõソíƒW¤¯Þ0“\rÛ›½V{ëƒ(y9:¹ññÆÜQШQ{ŒºÓ§<[W=pêÐsû4?ù­7Ç_yÿLßÄcû6«Cõ«‹2W<ß9úä7 gÔ½Gþ:ö‹ÇYùSýYyø‘3'ñr× müþåOÕ¿}¹Bûã¥}'/HüRxõ\°²è3´7.ìïÖâ{­;¤Ìã È2£d†±¾íœ™ÝDô~õd„ñyé"vüÝA|ñï>íDo%B“³ÜLð«AÎ'z=Yc½dÁã»%˜uæË F)#v|ו×UHt|Î#g5ÄEtg«iê˜ïªFÃáC»Œ´µHƒSËXÍÃCÇ?nw~ƒ¡¾yãÎí]é<[dáïÖÆÌ¤–6°Á­P¬õcQÔÈŒŽÊúÅàÒ2¦’ÔG(§K¦±…NŽPîd:žÊ(ªB}ñÎ0‚gŠByÚú»º;¢‘®¡j^­XS+6Ô¬ŠÖÔÕ6gAÌÖö¾hWOç¦jÎPÒjâ ‰UñÏoŠô’Ç®-5Á6±n§•í.U7 Ý*'X½º:ˆmN39ª»bÿk2#s2+/’k¬Ô -£ÇÕª20¬ªeLÖIÓ ÄdcX X¿ =˜ýU¯ZÕS;[c†‰â¿PK’KAB}a0¹+rebar_deps.beam¼XktÕ×øÊö⛌vûäå––î£e[h¡-%-ÍÂ~Øs8{Î~Ûsº¿ÿ=“Д~XŸ3Ö̽ÿ÷ã÷¿3Ã7ìéóù.ûß¡ä¶ë·•ós>_û&ŸÏw8Pt'SÅñŒ[( E·P̧ÝR‰Óóx&[ìò¶ÓùÜTv:0í–ǧgó“©Y?,¢çÙ|SÙ\¦=ãNV¦y³ùi†«}*5[r•ög JGûl¶T.uNå‹n*=Ó–ß¿¸/•«Z;Üâl*7Í vQ%—q!ÔÍ´»ÅTÉíLçç ÙYHr˕¸››÷—‹·-_ò—ܰ`­- ¤gÜôþ^¥«C“×2m¤­;4µ‰%º/Ð.»Y¤Â!騬[7´‚d~¬uê#ºí61ûiã0¸–›Ú±StkÇñУk'—@O\:ÀeÂ.X¡Ò uú&"O3GJg„my^{R:L{–t8()DN³…ª"§à„¶üvŠBãgA§yØ‹nªŽ€„Ñ^× z’µæå8‡PÒ‚w¦¡qîñ Œ»ÐÔx÷]§O­!"cu#& Ctå:7¤áŸÖÆ#º‘”Î1Æõc>‡vBì2ˆ]±Ë»|çÛ±=J,¥çU\¯Ð6‚iW:ÞC®€¨µµòLQuJX_ÆõÛ³Ù/§ÎU]ðù½à¯†âÕÍÁ_­‚­–œŸÉ¨ÿ [,ÌóËÏÕµ¬&#/„ª0T]ôFa4!Ãl¨‰5Ðl°&onÚI =ágÜ<©kܤˆ®…†õа.&,ƒB᜴䦚šM }Á·H „„A½ÏË6Ö¡‹õ¿„V l}£é—y]‡ú:YmA}BGIfI¿A­Ñ©?[ëŒõÎà—BZ/¤m€%ú©ˆ¸Œ9¨×g½ÝËÎÁ‡ ŽËûÅF¶1Ê‹MÆ®‘!Ãdž =:d˜‰!ÈM,Ї–£†ŒZ2Á¤å÷Ûb*.úÈ>/¶è3 Ñ×#+DBã½Ò9Uëˆ×¥óºïpשs="lÐ !dpݨ¨uT+4~Ú¨`oŒ‰«†Ô¦<÷Q*6;ˆjçÝ ‰Â¯«ð³E” 2í‘w‰+ëÄU¿„ÝV‡-ú5~Ê»»š8l÷Ûb8‰#ŽÇcbЈ‹Ak—Ù¥ÛC"céd á5;ʆª!ö{¦Ž ^i±ÝØÕø`¿¸ÚØfD¶ØÕ'F†íQ'ê8Y %G†gËæ¸ØÝ[{¤)¶ØâoŠúF‡¢zÚ[Gõ‰Â°uF4±Ekl×91R£Šš%iÅ$ ËDhx(ØbÅS¢¶ÓÅP\H¤MÖë?*ý–Œ%‚±#ºM?"Þ‚FŒ ¿­]º¤Vôñ. ÀXÒÿªv¡3߆XÆñ hH°OƒDc' *!œÔxBå ¡éÖøvbBÊ’q­¡ãb'¸wÖ¸Mpï$n´†ÅÐ-ða½}tóõq±Ô;jE¸ƒŠpŠp@ …£ña5¹À´Ácjô9 v¯DÄÅup]³¾ëêúʈÎí ¢ÛÙ\t×Õ°½ îlÆ"ìÚ…vÚe˜h'‹ÚÉ»¬AKìê‘ b7zäïFÀÕ¤p¢0æ†%ºŒ‹Q3Ú0fˆÙ‰ˆ%ƒTPÔµöÛÒ=5Ï÷ç{Hú¤ß¨ñúðæ ¿±¶0X]ØC¾Œ6›?ó·Œhü-¶£v£vx+Úáf¿k¤kˆìÛá›4þ¶¸K àÂùad("Lè鏨‹žÙkPÃDÄ^ ;Ö29ê—i$ø2 ê$ód‘á„T:nzÓÒÒ~9z¦´c(i7/ÑGââ0ßRc¾¥…9áWœ&qzm»·9±·4Gæï™­ø}{\¤öT-C4µRÈàA•'áÁr[LPô&î[ãß×»e@ûmU´ƒtGøx}”OPNRM 2 ÅÛA’º£? c}Be¨ó\Ð$ѧSBJ;è'0Âh•d b¤ty ac8½ðqq+¼Øß<{÷«Ù[uaeDd1˜üD|~\‡¤h’E£É®°úµhr9¼§îM˜aÁºʆtÄ`?b°KL®3ŸÖ'|ɰ²‰„ìZic2°[¹îÕç NXM¬'4l[«Ž¡nt,"X@‚%|Ÿ©ô '¦²™’Å05Y2VWq Ÿ­"TUkU±§UÅ­ˆ zÈ]Lån•qC¾*l§XF…2¸Ÿ28‹ŒŒ!ks²@/¯ñ­ ªòQ0´¸¨ þ•fˆ¬ ŠêÇ ¾ší6Oj¼°dÂŒ‹ƒ =¨h-làB¸0 ¾tD´¬B2JÓH¦Ãr4&Û%ó*ñeááÂm(Æ¢ÆoÓ¥—„í ±ŽAÙ…8nðÕ2Lp—–ÛYp;á^\ÌCï|sÌS„±±`|» rÌ † h-%~Ùí:¿Ð4˜ù eŒHª?†Âíx€ì Ù0”ÀEZ‚¡e—tIÑ`É15k.¢Yeu¬cÁ±ú±b¬~¬˜Ç±ÂÛS‡ˆyj•ëž@^*MM5O]s€u°Þä}9º 9º=.› qˆ&ñ¶x§Æïhàø!ÂqlnïìwjüÃ6Jáf5Ö× ã·küÎ.SÒ‰†<ÛÞOGI(@ `à<Ý&…þ"¬Á)›ÜÄAñ5]t«ë; }ï ìï Œ‹÷&Äû4þ®¸¸ xyw¬¥-îwú”8˜ïÖøá.»àÙêh˜â5÷ÚÚ@‡EAêçµ ƒj°àJo,×aª<Õ» l¥¾·Q{9|]¯Aí'jr Øôîÿ+¬óXqW Ñ:g¶îî²GȾ:éí 3OO³}á7°/Ì‚áš}8Ç+¿Îgß{þ²5+ª‘R¶„ϰ利ŸË 2Fãï}Sž^ü7zzÉy<}ßßàéú7ééû©Í ©§ð𸸘soóÙJF#â^šÞRbl¢Ò者Éóðï(è6ãßQàßâvnÃŒŽ†øO¶¸‡0ö5í?¸ >¤ñÖ06F Ë/mAذz- ãÀ þc¸ï¶Pª1á š12ôñ j´ÜCˆu”œº· Ìî#ZÇââ>B­ûµ>l‹jüà ԺPä>…Z÷µ>¢ñûÏîƒcÿˆðI©bU°{.€úh+@UE@} õ)Ô§PŸÑøÇâⓨšê¨@}õ \˜#œ [’ˆYæpz)n-«Ìà%…ÌãŸxCþÈYüÖ9ø?ƒ…ç ÆA‹æŸÄ ãü>’E’¨ìl&ø)\5!á«êºæíF°nÃï¿ÈnšF—hü_i)ø7ïðn“¯×øÏ°XÂâÏûų¬K×·1õ–yiý+õ)åÂϼ}6&~Fiþw0VÀø‹]<©ñ_âq¹y®_üš-±ÍmÌŠÆÅ‹xÅÑ{ŲtÄùEzÍGé$ð¦ï§/—ŒŽ'lñë jP?¿ ~¥ñçk_‡Þî e¼´<PúUËÓ¯câ—dÌ 4~_¬¿0`ç7°ç Ìûm¿ø[¢W?¤¾d àªHˆ—ÔgúšMÇ›ýü]Lü†D¿Ôü­á÷z¿/÷‹?0Oä)ˆ<¥DîÿsDœÚÿç@z,z¹8 „8 õUVhéËͪNØcM㈉ߓÒ?BÏíÐóJ¿øSÃúÓPuºÙúÓÍÖ¿Ò,òO1ñGtºÙúÿ€Ô;ðûj¿øÏªõ¯Aäkuë_kXÿÚÖÏ5[ÿªþÿÿ]– Tׯ'L$ ޤ¨h$€ ²„D œÂƒYEA$ MvTĪ´îGT\*•`RSF£¶2ŠÎÀéÝTU ÁøÒƒ1úüÔÁvb 2'K…ô%8†aáje° ôL0šÐ:Q¦™ ¦Á¸9ÐTÄ@ÓQƈ DAl…Øhöñy.)Ã"ÍOòm‘ïäHêabØßR”wrEüɇw .)Ã#Õ_†ö¿1¼õ 3Þh°ŽÊ€ü V’8ÄAˆW­Fu"¢HëF¼‘äÃ~bIýđ֛DZ£˜´–RÍTÒÜ4RFùÊ«I¿Ãfäm~@6ü{ÀvbŸwÊÞE ?w€ìÑ<øü؈á3^€>sÄ3æ‘î? ÕœŠ®Aß hbS4NJ¨É€ý£ß³Í}‰zÁh—+¿C>òûЈM¹L‡s4èû¨F‹±ð–©AMü ø6’}¼ rµbî bÓ½|Á1]Ö&MÂtç¥ma»=}Âëgýf‰kšÖ„˜Îlu©¨¨ql³oÛ“ÿ{cQƒÍoq^Çkif×Gwp‡îÏ¥^•TWãͫھc¯ ‡ ÷8M¾oéù÷G-p¨1“Þ­<î[˜]ñô[»[lVm»h|GiqÇ©/LušÙçX‡Ìklz¹þIP¶²ÝûÖ¨Ù½½yzí™YZ]J—¨«Žf(]ìÉJ›¶]zj‚ò Ãåy£³ÿ£›nßsœ6:zàà]ïoü|]ÿ˲þ=â¢ä†>¥À…õkÖùù]eeLÖå[§=éU9 ÞüZÜj.k®Ï§GïØ9‹v&ð:gíöÆ“ŒìJÞ°í2[üRù±WÙ÷ê›vÞÍXkNر&t„çuxz0yëelKß¾ä˜À;{Œ#nW_rÛ·»æB³®¡ÓqAJÓZÙÛùg?(/$ðïkˆ/·/­ã¯ §>ª_ýòJb½÷Ni²²Ää¬Ù⇕ö¦CÛS•w ó,v%F{ü¹£qߎ~n=Å8^ßÝȰ?yøùºÙyû „Aý^úðõ6›S<Ûvx³#þjÿbw¿0lö퇤ÇoSÏQ*k×¾«_ °Ì{Õ<çA§œ?fø¹Ü¥¯Tíýµôè™û·(«MV'±£ÝX¼!©Ö&%<ö¦U«§^šÒjl.O½(ø¡p{_÷!¯EÀù±BÒÈSùÖêÓ_[Y­ÛVß‘®¹=/4×Î.ìô/ßoÚkˆu£æ”œ,7f Š›»Â^—´ˆœqšÀkßUûõFû/ñö?eŒ‹sËÜYîSà<“ø{ÛJ§n[oßyêçHk\Ÿ²JÜ·mød†a‰v~ÔÑ:-ÁÍúãÝ …k_K“à~ìÅÐòÙúÅñ¿ìÌQ\ÑÕ]Œoá1ª¿èÜâkö ìì7ÿ*ÜRõO«9‡žšë”ö©²w=K°ªˆ9²wÜúœ¾ômÛ†ëãxÑ´†ÝfJGt7;W²´c¡_á#ùŽ×•£ôMÛ£\´oŠ–¶T¹kËŸ„©»géJy%DJ³¿ ±¸ÔœöäÆWÃ6ŸW¸wvæÆƨ¼æ²^^ÀϽÒà:¡Ï)9Û6Îû³>5Ø0RaÚÓU2" äžÌ{S30b䉜 Ø¼àF¬Hÿÿ”£=“¼§ 6|¶§ä!îÊEü (qP6âÇ@Z´ß´~¶©ÿ(e®){JG~- ùç€äˆ«÷C¸÷IQþ[Ä0s(ùûCÐzäÃuD V ¦ û úpž?òáYôÄðŒòÂ>¾+À3îKTg âÄŸÎÐå¨&1ÌÀóÙ eàîŒx1ä…ˆ1ô¼¢¹v¾j5<×OžzR1†kU“_2,¿)íö®êg-ë˜Ë‹ënñºRSý‚2Àz(ó'óT˜§)2Õ2E† 41Æ(• e¼J“ž.RæÀ€©B£Ë”rŒ*I”e@‡"“c4YFRšF,cfš ±$Y–!KqpM,ÆÌ‘AÁþñAkäØtw7Ž»Ÿ³<žÃuçó<>…èQ~áñA!µrljŠLmËIòà'/Oúÿ嵡è²i‡'pã¦Nv«•(U ]96…ç²Â…=ªZ–.‘š&‚þÛEt!bˆX"Îdë*…F™$‘cήREºÄUœ)R&ËÔj×D‘JªpUJEJW•2é#Å‹%™*‰2 ¼Mø&ªà;ö?PK’KAÊ Å Prebar_edoc.beamMTÏoÜD~ö8ñ&»é:륩 «á€‘ÝÍ’T&’v¥´‰¶).ÞYÏì®w×Ë—‚8DBH=TjNœ8pèÀ N\Tnñ ñðÆq –>ù½ïû<ïÍèNúë^÷pÿþ¾’ü…x}9C–ú‚Ë€ ê—)K?Wá<[™KÆ‹tÎ…)gKÚéËDeµKk ãQ8&c¡,-UÑ;¦B[䢒 å'LM,•梎YžøZ(ÈʸT—çEÀ*bÆ>Óêe¢[û‚yE·³HXSÆÕHò|.ü0ÉE‘ÎY<®kã+ôVÂ}þpàòyŠXA,ŽÙ¸å^Íó¨kQÒ´à%.µ¦¶{;äÎiw ¸]⬭ï¸}º¶E‡.5×h“Э¦Ývè]p)Ñù*¦ÞúéãO=°6&¿Ð>i€k´ïƒš?Á8½æ€ ”Ë‚/lçt] É" Ç5hJÌÆò*ç5@×€ÞuÜŠ—€qôu0¾¦ òÀ97¾Ñ©c|¯ÛEÆ» ¸¡‡*=ÓìE‰~†XFhÉB —¨”ÜÒ+zQ+=:®—gU-ÏMó „[òMÄkqCÏQ鹊ÍÃ'Eï”ë_/õZCYÛ¼Âq¨´ÿâ'_ƒÁ`ˆˆ~ ^’ÍÝóÚ—/_üô>¼ùùàXÚ{³üvµ\OïëZ/ì+•êúŸÏuå‰É<Îâ"‰øöù¯Gÿl\¼ýûßÏ>ýèEóÇéô P{«ð[Úoããgš°9¬ˆ4•©ŸåQÄÒO´aQæ Çt–žXÍá ì0æ9–ò˜‹Q >!¨qËÝG½ãü³ÞýÃÔ7ÛÍönç¶ßÙÚÜÝÞ»2U>&¸U¶E—Ü#‚žBzBaô„?©»Á‘nsë>ÉSVõ½$…ùeUOhLäñÏ‹øõ„‘ˆ B¤ÌE©ªî¶ec^Ìü¦*j®öçý¢Þ¢Âµã^H¿ŠÎ`<ãQµMOœõzüºž8m•oŸÂ–ž¸ÊQˆQ‡iZb7ªKdà* Ò&µ ^qÀÕ®´ûÅA¸Û¨íË´Ôı–AM÷®Ða CñÂÑMm@—:õMPõç*)ùâ>l&ÞöêÊT:¨û0›Ãe»EwyÝ~¶\{ÛÂÿ˜ÞIËcºÐÃ{èÚñÈ)©_ò"§ýP,r*ÖK¦Ã§ÒºWÒC^=iËÂïN©­Óžvê‰Ox€g=êù®S’Òæ.ò0=êÛõ="ÎÓWxQ€‘A²Ö‰Bp]wo:4 zôOxTY­óòl_%‰g‘‚ªx¾EµÁ¢,ðz4¹­ÎZ2ãB˜7¼܎8ÇQÅ67wRY(é^,d¯ö¾´Lzº®,zC™÷âEÕ/Ä•n·Ô®zÅ·©Ê*Û§Šï­‘ÄO`Nó‹²Ú¬úmí }ª]1Ò©Ê>] d”^I‘©ª®ÆÝ’7žU¯­Ynƒ²0”µ7ûý0m¨ûåi\ØÇe§÷±©ÒR T¼QI hlªw™—M…ÏæUÚ˜O”½ª®Å.)îƒtBnó¶ùx­UMXé—î„«Ý»>ª½+¤á@ƒÎ¦Ã‡©Nž‡útQžÞ¬ëzÈ­|º· @<3úX\èpºÐA.tÀ…66CYÆ®m®¸z4 „¢5 ø“Ñ€–îb!ey»6©Ü¬±™iø–Fýå™HÚÍl¶(Ï\ÂfÕ©¨ÓøßŽ#Ϛ؞ÕÇüé¥þhZ4vÔæsŠ_³„ùA‚ìn§¬(ÏÖ½6¢Ü!=,Q°ˆïZxkÃGRÑá1ôvØz+Ñ´:òxÛBÖQñÑG§ê‹W ¾Àe×aÚÖÙF©¹†§×—p·ë°ØAŒWYô¯I‹òõHoTå9Í~ …&ä+³GÊ8¢qŸÛ+ûåkQŒãêDФB>=@e¤UÂXX¬½Ý€‚Ü0Y7éã¡_Gú:%:…*üIÈ^oý8Ò„ŒÒf;€r(ÓØ-À` PÌyl®²ˆÍå¹õclcçXö ‘uÿ˜: ®ôJ"ÑØÙ©ðËþ>6Nͯ;ÕÅæšöi¥¼àÜ®ªÏæCÛTIVåëäBÞ 8Êò{ òÓÕ¬idÒÎUžÓÅ4ò:!OC;‘Õz?™$+·ÚÜ-ápã ÒQKÈÓ¥>g&Ú‘ècÝð®Û‰ánÂp·}ŒÇAQ^ØÅºÊm7³E¢Dćü*,!ÿTª¹“~ÌœìÎcäe}²1É‹&D8Ý Fö À  ôNÀ­+½t]ÛoÊk,¡$îxŒ÷M!ø-.Bß ù°Cþö/ßâÿªCþ&Èß”/nÖt:ÜHN¹ÔYGÀRBÀRK€€ˆ(/Dì{W!rènóµu–Qã>d±o¢Æ}5ÖxÄ®1Íúœ)XJ)Xë[áÅò»YBËë—ê!$äYÈžâ¾Sy{¦Ë•-WEùæ0[†®J‡ù+P1¤[ÂL'°_CDBT?6îÄF” @¾”gSséÀ˜æ½]å8î†õa÷®Så¢ç}WòŒ!W¶ivá4®y%$Rx&p·@Ñ }l â^ãDÏBÏ»®‚V‹ò*@väøÈYÊœ2䕵ãаÓzË_C‰¸ŠÓpem„mÂ}õ±d`y€%§ë»Mg¢|ú'z§ŠÞéGïLÆ”L³VÖ“t»èiŸ¢sy£Æ6SÍ6Û5[‡š­åuê€`Îá„/pø‘ǵ(ÂzݹpZ@‡®p+ú·RA/îÔCáÏÚCEyƒ:(¬ÔlCÜTØV€mÔ«$îÊx¯%!©QÞf·REQ†.QÞL9¹9É"U[U6$Ê_Å2‡å͸×í“·Pcw‘wÑ5ͶÂ;Ey+ÝÔnµ„k%4Ï DîÔë·|齊ò(ÿ=z;™Ã™N|ƒ2ýr·( Aа´›À¦wÉ“W:CÔTÝR]y:Ì _‚%¤ÓìcY #+é@GèˆE%-ÙŲ!¥ŒÏ˜² I0$µhRHG“j%šôã²É¦í­ ¶*z´"œˆVÔsÑŠv['lÙsÊve/,»À²ˆÝbÃJ…ˆòp„eÇûÇ/½ éK¾¤G/ ?^R?^ÒšTþÜÿT©‚£I]JZ´IšÚð©6µãÓß„œmjSªôð*µ0˾K ¥©=°N;.Ê#ºR¡8³õ˜C¸;Ým}¬€p v¸„‹µX+Èf!¤ìC 1-’јšŽÆüÀX!ioáÊ-¤u\¹ã¸rODÓÚ9lÛ²'(ܹeçXáîb£Ên–åQH!I;I¤KHÒ»à¿`K]RîÅç»×C‚üÌÿ¿¸Ñ·î#îB=¸"‚۔꠻ü¯^·ïÇs{„UÑÀlÔ¯'Mc5gͧpVDÙª¿9nGº*õÎÛ ª†Y™ ש; }xwÒ«¥ý9»©Aî™àÝ…í`|w„Ý;Pþ4‰ÐÝNå÷†™Šû ø ÷DØý_&¸Ç)x˜ÙYÙ Áqî‹°ì×þ…lÌ«,lÆ·–—Ûç”§wŸ(?f{IÃÐð4ŒGØCÓ½NÓãö¥å¥6âŽ{¹ª‡ÂìAR°  ƒÐC1=ÒcFuŠòAÐ"W‡"ì ·ßáêÅ’x&û“éJ˜¬4ëezEÙ},†­„ÆŽP™ŽLÄzX¹c;,Ê«cB¼¯ÎnŸNxãaoýMåðĆDw8€6Vß8BîN).ñÍ ‰£pí\;aÇ¥fmò–“è $¤±ÇÈÇìFú°ò¨(?RÕÈŽ¡‘'Ùk9ÏuœîǸžëŸƒàÿ+!žN}.ŸOøéæôùœNë¸~šwqýäOÏIgç'zÈA¿‰Ïc,qÌ—r~Šå+|~‹ÃâéçtŠ%æÈÕ ÎCü+¶:8­uG®Vsz“#'kùþ„ì:}=ŸSù¼‹ÓI÷=|>ˆa8ô›?GþosðŒ:|+8òPpØÚë 9ø÷;ô?ì G8ýÆ#¼^DÔ¡ç¸#®Çù|¢Fb|aØŽŸ°wÄGsÇÜÎuË|îâüŠp¿yu­¬¡SlæqŸæ²/r}‚kï¿Âã N?Çm ”ƒÏSœþu®OúÒ[x<Æùžäû‚øÉ?‡ñ8Âé'¸BÃG/Rýryú?!K¡±å9ÂâÎw€Çàrí;OµßÇùw õ3!zŠî×ðÜÃõ—xü‚°õ5:£;8?ÕxŠíÏÁž5œü3y~DÏ[g­ÍU)'À­ëÖ]Ï6ü°ø}M­ž}=šÛüòAK¯Í}aÍKÊïö ·¼szÕ¿N;øzæ ò§ÿ¹°øÀì_½ûÑGo}téè+‰üøüO^ýÖàŸm|O,oùÖk›bwîÉþËÚ½ïmxù·¿²ãÍÅ-ѧ–-\¸øù þzݼŠú#öûßɯúøz¸öó/FÒÏgΜý åŸ~ç{ÿþ¿-7Îýo¶êgÇ;Ÿ}­÷èÿl>yê—µ;’©Ÿ}ûÃy»Öù>~õ£ÁMƒ?lì}ôïï^¨¾¥®Û2úÔá'·4œþî¢ø¦_oýëï¿èom¸GÐ\ôM/žþIuè—o1þî³5'÷ó¥ßÝûðÌÀ7VíyfÞôîøÆ±ïþæÛ¯|å¡¿úíËo¾ÿ7ÿõÆŸ~ñ³;ÖÍûÇ‹±¿|äü¿=ž¿ì³þváÞ9¯7ì_ÿÒs¢µÿö?]»-øésÓ¿×ÒsËñßÚùûýûV<¬-¥)Ÿ?ê=ˉ1'®œX:Éëx†c…æÏ\…«£|~ê*\âµ>v®œXzˆóó!rL=Èç„£ø|÷Ux»ŸÓ·_…7'Æœ¸*rž!ŒŸß‘åó-i.Kg;Åé Œ»9úéœŘ!\îÇ[9Ïr®—b¤Þ¼™û@çnŸ÷b¬ásº'✿“ë%:Ý-}œ>Ë“~ê%ŸÓ]¸€ûÐÔ_­Z´·;RÖ•¤•¢½(ªÂ´?|ðñÆ‹Ù3MRÿÙþê;nÛ[]ÆÞ|›ßMüžR™~¬Á“˜ý+gªR+ k71ðŸG·9”+EÌ þkjF˜R+òŸ\³ö2A‰n^½vEjÓêÛâ£Bk¯ÖÓ«Ez§zB½‘pß“|{,™Z½nåúQ¡i$Wõ÷¤û"ËӓÛë7 ðíÆ=á¨Úf{K¿ÜÁÝQ¡!¼hÉ¢0ÑÜÕ\ÁÌ6¢ÆžŸ²¡̘môØ®WJ5+mŽ ‹»³¥‚Ù)Öp®Zí2*ÙR·ý;wwÅJw[ÿ'ÿÿKMJ,ŠO-ÊIŽOÎÏ-ÈÌI-Òò²“ŠK€PK’KA¢*Ò(‡ drebar_erlydtl_compiler.beamuWl׿ó;û.NÎ>“ á‚ ‚ãsâ@ýó☰¦%´©­9|çÄľ³î΄2h£¶¬aÝÖ•þÙÄÐÚJkW1V:ZZ5¢[[ulCH« ë4ÖÁĶvCŒuÝоg¿ ¯]#}¹ï¾÷{ß÷ûþ¼KÞÀ-·ÅfÎ}ÉÞM½®U`ÏU†a†êmc«f§ ;·îæÓ«PÌå ›§ —±tC3ÜtQsÇk+à’›Ë;<1f&u! 0S+Ü6+g š®—¡œk— A·2iÛ²\¿c•쌑6v¸¼UrÓzÎö,½”/›|]3Ç>°æ,³¦h[Å|ÎqBr»–/¼ndµRÞ›)9~ÚÕÆB£–†IƒSž:÷NŽç2ãu¦e;p“3Ǽ†m[vM%`ÞC ^wܶ&½Y-ï¼3‘+ ݯ[³Ä=ÖD-Í‘”G IÅåsÇÙ¨ÏqmpísJ[AMÃÐÙÍ<©j>·UÌkŽ›7¹lÎнå¤fÞ=×6²†m˜C'Ì ä Ó˜¬% 0òFÁ0ÝZÝÈÏê¼k¥ÉnéãÛàm£˜×2†OƒL½&kCXj®­e\ÎÉí4¼%Š;›SÎÌZsIy«Þ›£ŸôëŒæ3‘»:bñhGÔŸsÒ¶1VÊkög"「G?sY…e5Êgóšë¦Ç÷¹Ö„a: Ñÿ) ³%ì 謭ƒÚ˜õ0Ó ãýÌ¿ÄT~¦AÖ‚XÉ\¢°Êœ-F£œt;Fý<Ã`”à §™W^RÛºÐ!Ü/ã#ˆSJEˆ~¢¢‡ˆ~º¢‡‰þ>Âá~òš’`7ƈcpÿzêÄÜf c”Á§¢@`tZUù©â•CÓŠÄK[Êá8”dVÝ€Xì úC;‚=aìÉÃj‘ݦ…-Ö) –9`ÁIû1' !$¨S ;ˆ…»O݃֡= =>U”³ÙµGɇw°P„';êRÂÑo²ÄGuø3ˆ‡bj@X¹ôNì ÅŒL1ó@ê©m>Ȫi¦˜%ÔF|†©}QULÂaEUÜ•UzÅ­‰R| D¥øß‹é ˜H͋諫ìkªônº—ü]ZGëBüÜ@ísc•~SÕÞ›«ì˜Ú Ͼ*Î}ÔNxöSûlg9§¨Nz±¡*ÇÁ*ŸŸ#zré#³œæÞK÷-¥:Ckꙕ’9Jù‘÷!º¯‡b>7Iléúêe;8”sÉÌÿa÷îxòÛ·ýpøuU*ÝúÐÁ`R©QöÔìÛpà›.¾õÖ}Ëû‡woZ´îH¬ïÎ#—ßìyfÓöc-;{>~õ•ã -?yLzüx}æäQc×ÉŸ_ÞvÏKï.¼çëo£¥ÙŸýóÉ·ð.<üÖþûÚGÿ~`Å›Ü^ˆh¯t$Ÿ~sðÁÔ}åâËGyï³ïœ8>1³d¥Â¿ë{ø fç´³g¾øò÷ßñi×þá¿îÓ?ÿÍ7º†;~Ðñq.²»ùÍâÛS‡ÿöü}}›Ïž?ynåÞ?=“¸sížÁßÝ¡©Ú^¾ºxè£Ç_Øvé»{[ž8sìÔæÓõ[Ü¿<õÛ©Ó×ÿþÅøƒÞû÷êä]{_ßžw5v|Ã?/žÊ|xCij¡• N¾òÁš.ŸZ=3|nÅ/μóá¾Ë÷µ-ÐïêÎ_ýڜѺËyä23ÿÉÎó>`š›víŠ>Ó__úøØßë“OošYµÏ¯¼ö•à3ë.œ<ûܧ¾sÍóì’—®‘&YÒ³ç@æ|¢gÕ} :™ý$ÕÉ™XO{ØJ÷½ H'ųØNít–žœ×eÔNÎqÕɹ_H1ä{Ð@ýÍÎm¯ëÚÄ×ýyb÷è Úî˜åSb½·Áû‡á§¾|¯pïÚ5ç„Ƕm[?hfameÏ<_¹T8ÄÀëŒX¾ ¤R¡ Ùw€n4p“˜`8ckÎ$67lfò%ÝÐ™š’ —œièãÖtñ÷Ý>8ÔŸÜ”œ`æv¨ñµ;¾:ïìèNôÌ‚„ϯߜ¸e‚©˹J<ÓÓ]¹¾|Ëè]öÝOô©ÛÊl·¶t'o¢}M{‚Ø87W0Æ}[ÿ{š Iš¨5iñ2õʽl‚é‰[#¦5;›sÝ\VÆ­XùºsìLìÿßÛÁ° 8Ü_È™ý/PK’KAgÇ”´Ô rebar_escripter.beam]V}hçOïÙw–}ñ+œ8v_sêÚT³u²n‰å-ìõ‡¢¹K5NÚ0†å³t’Ζtâ>â4c4c8¸ôc ÚAƒCËØKÛ¹tÌŒ–ý3Ö°uÐŽ’…±Q¶B×Ñu”AaÏ{:»NôÜóüžçù½¿÷µï=qêt¡žßMç§šòì&B‘8B(Óï˜K†S2ݲcµ=Ó‰†žuÑ SF»]ò=«áŠÌkM³/Ät:¨²ÝªZµžšé•vÙhU«a6¬¥¨Ùr}Ç,U,'b¯Ä¶+­V¹Á:»Ý¦Ó0ZµH*…/Zíî²cžÙe:ŽíôoƒÝ:ŒhÕ04߉•ífÓlydûÙlú%é¹Ä²–ë•<»´dµ çqž‰®:–g–˜ÛÓáÛ°k¬Ë«;öê˜Z ²@¬j÷ìxxÉvzËun–švÅì*7L£E:-T LoÅl˜Ðß4Êu‰IÀ”Z2¦Ë›À‚/C©b0z;ÅA]—ý=qÕjTʆS‰6ì†Û³ÃHd_Lh~Ù¶ZR0Äö`ñn/pòCªýlî®çÁÑÏ»¥ÇGåä‚–ÎŒj£Ã£w0¼#‡Ð PE¿gƒ ÎgL‹r$?¬pÊž¢Bñ,•±@=-S¬ÒYLU]ÐÅI(©5¼A_‘i„%X4"óÊ›'hÉ´@0¯H„&äXBP4Š!¤¨´ ”æ|<éce#yUóå/Ëþ>ºñ¥(9Ëi9_ôUeZEÙi•̤ülA£Ñ4 ‡™„ )æiT†X±3YM@`1eg!F.‘|""籌ó³XÎó2Žñ±DlV ‹ŒQ J;—¿ƒLÊ—£„P-¯Fp^‡UÚrL§QC.ÑÂ%Ðã GS>Þ8nrÅ;€W›½ ºÄ`¹–[Ók»&­É¹5urM½ÝYk{&µ–øvWñÆLeôÖ‹HP¶˜Òq$sí1wék˜»‰GGîZQ˜ »·ˆÇëÁf…äq‹ä&ânvtkâï¸*1~ ã$•4ªB‰.(·SÂ…kDAy=úÝÀ¢òån[F0•yA åUªÃúÖ‰ÆkÒ!ÊËëD 7–Ç]Ê› w[ß4–¹`à… #¸].w)Ò0áÄ$€dòöï\¯ããcŸ®\ýóÓÏD>{JúÙØÚëÂc[ÿùê¤.ùçÞèýï¿Zú‚zü[/m®šW®îÙüÎ_®ËÛÏ?÷Æ‹¹ë¯^þÛûGÞu‹ŸüãåñGÏ ßüÉù……<éO~ý÷ÿð±…[óYtÒ.³µ ÷:î#Û-\?ÛÃÑP¯D¨y$<GBŸ½/‡~ß”ç9lϾÛ`UõHáón+xhôÄætlð½U«ðSé­î¹É//Ï̵ªS<Ïð‚ ·»å²€PARp'(¹~³ ouè¶}^¨+(xɲg­ ]-üŠYA=~«bV­–Y©cÈU*(:}vîäléÌÜCùÔ?®eƵ‰ÌÑR&;>¡ç¶Aâ£3󥹇OœZA½5ËS2åÜDõhy'}êL1LwŸÎèÓZv9`{Þt\ »‚ºô±cc:‹ñžÕ4ëÝKÀÿ=C4ˆ!ŒL@ݵ}§l® ñtÝnšéJÛpª–祗 ·n§ƒ+BÚuÊé»ngcp[ZFSK®ÇëÿPK’KA\ 8ý#P6rebar_eunit.beamŒX[pÕ™îÖéѵtä–zlùn{Æ·<H6²Û’å ¶° 6 aÔšif†ž_DœÀbɹ@vÙ,† ! sI¸$a¶jý²oûÀ>míÓRµµ[µUÙï?§%°MÖU£îþÏþË÷_μÿÐáaM»ãîñɽ÷ïmÖæ5­û5MÓþ½; fü0´ªåfLþí Š_-u ÅgË• Rž1ƒj£ùb9ì¨0 µbÀKA3_÷›s]~±(_|£¶‚¥Ï…Hp«Y®4ÌÙrµ˜'iX¥Üh6b³µJ±b)¢+¾îbP šA>ð sF¡žíȺ°RÈjóup†½ÅZ„ÅïØLàÏ7ºê~Ø,7˵jG:Ý ˜çÏ‚OyÖUku©¹‹ ?éWZAlÖ¯4‚˜?S ›¼¹+T¿ çóál—ÜJ^ÇiSáT‘“©U>0«•«<˜)WiYÔƒp¶†=JW«Z àpPŒ5ZåfУ|(Ôª³å’I’J•ÚŒ_1HX¼¡$Í Ñìl4ÃrµÔÙ¬â½ÄªL¨Õ› ³ÜÈŸ ™Z#0—©2äX¢)-œð¡åþEª„J’4ö)òl9l4UXVÑŽ¶o<^PìxéjúöOúå ›|`¢›à¶ÄЩÞW'¢J¶Î©Ã‡¦&w)(òåY½HbM‘/W •V1ˆ8’‹aPjUüÕ[ÍX1˜i•º|•Z‰á·u¡0„ü›GHf*A1úò«~åÌBŸ­øÍfP5ˆo{(©:ʵNÚî7mÅ\àÍEÝŠV¨ãîjm‰“S­–©Päk¬ÑDÒÅ‚0¬…«ü Ïä%-(@¢ÚS k­zU·LJ£\­ÅšsaíTß sóóµb'~­JÀå‚_ âÑZìÔ\¹0'£@q+/Åο臥þ9?"æ)ò³­j·’'Ellû˜I,sÒ„ÞÈ?• EEP©a¡ØS­UóÁi¤Ò¯zY8­³0תžh9ê(¥ŠÁ¿R.Uó@J Š ¶ªM=¹v*DúÃbp:&ß×]EÏ7‚Umg¹FjíQY„A¿5‚ž2³ÇGóÊ7k2éMdC!¨6‰i(†þS-¬ÂΠæˆEPøõzžÊ¶Ñ·J¹à“J[ùžo#5l„¯ÙjägJ˜åÞQ Ë'ƒN¿oú3,@⹃Éš êóE£Ñ¬ÕÍ*ÔžÂjPé>Q®`å4pkÄZ”kÃu [e[P=‰ž6 J.eqXjÍóFœ8[•&O§ªîžv†Þù ,RŠ”P,š]³am^z“«ñ‹¨+1dp›Ïø ÙÖâ(Bz®[——’"~‚Õ)¹† —+ù"’*Ÿ¯ÁôZhì;tì Ý,ϵV3OÌȨ<À4^Íë~«DÛ—Êbõ ¨—c´…U ‚úš¯0äg}JÉUä}[ޝM¯D`ûŽ4ª í¦·¤¯óöaÉ2œ–ÝÔ¿Èê¦oú:–J!õ¨‹§›î!œ)÷(MW§ÛB¿$iÝW¨m›#0¥_«Ð !K–Ťs>˜Ÿ B“Œ˜ùá3åWÁÔæ"N­ºAÒ7¥¯:#MÃx§c²©vËD"[ª'¯¿cž;Ò8Õ"°®Ï©¼Øœ¾FmwÛ86¤W劵Ó×jx;¾~y8݉ã¹ÔœûZ.7L_·mÏDŠþ2Ïðÿƒ‡|½Šg)Cצ—{3ˆË táä Ë3­fÀpNúê.¿ñxpºŽ¶ÒøFöµéå3,R¨¢›X¹°hÞUÜ×%ðâ AÇÆ@zÅ·„ȪÅUB-eÃU|Ëv]{MYqí5eÈútû8´,Q­åå`!«lCzÅì¶Bˆ­„¬Ê¤.ÃÑ€V.+›ºåyy­u%’‡µZ“’~ÕÒ¢J%6¶sl%ÍMk8c5mãqÌé–¦þ½¢iú<ïÓ­Žþ-ŽîôN[;jhz9ÍŽ;Zܲ†Z,4´YIˆkŽÇö/n¹ø¾ †¸åÑ›—³l/ç°¸3屬úrÕWª¤yÙ¤×a{,w§ãVDÑw*é%X_;1 "vi^΃Ús’v”–¸D€Ø—»/â…Å­‹PT²°%î\m±-æŒ3ÍgVÂË2ÏÎVºßc¶Òá|N¯YÏhqQRàLá£ÇcIR”yɬáˆÝ+E&‡Zvè%†&j3¼qÎ{,Cï03Ù¾”áŠmR#ŒÞ bßQ¼ ¦ËIÏ\Çâî7`»X0à]¾ÝÜ8©»žÁú 0=®{ÛÌ0}F œ_èSÞ>vaøR²~ÍÖ§ïezýn¦Ÿëè779ºä Å-ý"›5ýR¦Å5ÞGˆq‡÷kúçXتéW–¦£…/°p“£Ùë!´) æ™ƒ¶gÞ åÜnˆ|HÈ­ð^âÏCŠb¦Ù—êËÂÿ~ʃ]p­e&ƒõ[¶Î-ÍûH¥«óþ!‘Hšƒ=–³Û¶g'I]’¯Ö¹½Ç;=Ž»;!VKµõh} ÖåJ1¯Þ“èwÀ¼’]Kç=Ú€¹®Ø´ÅÀ-ÖšÅ:¯õrçØ˜X¯óu^ìYOA4wØ^Gvz#î‚¶Œ;ÄmÜ|#dgñqC¯gQþhbÃc3€ñÌÛåö,S{ ϼcI(“)ÊEMÛ—Š^XÐåX“¹>“"YRfd¬#iæˆMn‘Ds4ZåXƒY7¼šÎ7!Â^î"xw¡/Á±»`$5æ‹9" .Ü»ñÜ,¹?÷p_··Ì½w‘{ ¸Ç']±ÅÞe‹-f `nÕyÊš²ö;vΜȱI»ƒ! [=ù¸ »öy:ìu=3Æ×³‰!që„9HpÙÌ3÷#˜†—|ø™å¾ð̈Ë-:¿y1¶ýÈ :¿E•±g'.XÈ7Xž6it°É È}i÷!÷Ò7R¢Q&ÜêM°~/C°â~$Û¶×Å~Rin„¿_ ;6y  HEóÄm`LÓ˜}›+Ò”9irv;œÅÚv2Êd4lÔÜn>Ièï'Xs€µÊݽ®å™EðQîŠðæ@;‚Á^(îˆ÷êü0ÁË‚0„3>¡Ÿ° Câ@&EÝéˆáÈ©ûeQØòp£ô@Kø†ÂB?ü^ÙÊ@v›5-ɨD6™¢jäkmìX‚!Úq€Ü¹žÌÁ“ûU{†¢Ã®˜¢T™¢”<ˆl9¤óƒ±ŽŠH÷!yLY®ê3åú!›ÆÚøž‡‘‘žy®kúoÝ1~Û¢©GÀ1¤<ÚãP)QêÁjW#µÇ¦ÍªxЬ‰‡ÌºxHçªvkñí£â8 =Þž(Çms92&Žéü!0êüL]o_°Ð»¹{Í!¨@ÿ8¡oeFÄñÌÞÌÄã2D Ö‚Ù¹rÃoXOeÅñ#ˆÁKóžÂ¤!þµÝ«ã”õjë®x8³+#&¿ Ñù7ÏÆ\>œìKZž»ßÍäXÎÎ%½ Uà#W“¾I§Ò£=®ÓgPߢž¢°j¯<Ì·;˜—e¶A–£ÒÙŽû+yh©4ÐtÖ¶1‰$~#EÂ÷h‚èK-n¤Åei‹-j«ü”ä €i˜}}×ÏŠ™¤jM3Ôw“f<§<ƒÌ߄ښQX¶^õr û¥vBΧ`¦–gTçUÓ(™Q`¡åhÄÕGL›¯Ç„µ-+¥iàPªS$J“-àHÊßÒ–˜¤Kr©—ž@BTìðàÍVK̃ÙkyÓK/«NŒgcϲuþ³<|r<¥Žƒ•.RPèÄÝbM“7l2Ç·¢r F|7aÞá):K¦”`ÊY˜2§ºýí`¤»€åÉcf2§Ê„2XŸDþ<6$N0lÜ7S@NôhÎÙ˜Ãï`¶mÝéàb9>Ô|{Ðz4ˆ jƒ>ºŠƒN‘>œA-›ÔØ·±çNFçÚDÝ‚i—^¢§ðœWsì(άÆgägð¬õ¢WibMàŸ¨Ej|§šZwÉ‘ìYw ,žKäŒ\JöyÚÕ!‚æ¨ÇGE(×™×ãZ: qæH)®h» ÑpPe¡ÎqpØC¢aãúÃo¥Å "`Ão7ÌyAç Ùü1¼À²¤Ö#eƒ¥óþC™ –NK‹eÑãÂB+øyæ½óZ½’ñp„ŽÔ!äó¬8I'Ð69p.ÎAjà> ¥KÑİ8…Ÿ‚°— ìôˆøë²ö²ì>hö(—£™õ ”\Üg¨(²„Û^‚P¾Q&¤e&D½?7ÍìIÃV3©ó3{RxÁ±¼$ÚûÅ‚Žˆ…äÞd§ÐB«w<ƒS(cÆ3úàÂóé¬XÀ1¿PÈz åÓOÈ¢1ñ„ÎäÄþµ(óe2r¾ -çÚµœ£«šQú<:2²9ä>BCCŠèI°?ÙÎþ$.=ÔÖÏêüÛØÌÌGPÀ:?Ù© Ž«Ò,Oü6{ l´»+mŽ£ ±ÀßÉŠSL5¦'©¤ÎÑ)ø] ÿSË÷FÅwíø9²ëŽÛÈ5Û¢ã÷iT)ò♥©~îûʇQú‚š[B*uù$¨û# •Õé§ ëg0äi:qs|»­ºtNM›>°ínOº³]R0.-^Iè~ˆ­aî3jZQ= Ï·cxž{^6+ÎOx™è6ÅÝ+q~1/@Øë <;,~ÀzKÞ3Þ ¯^ÏÁ°{`ß+â9?7 ¾ÏFÅóÐó<›ZÔƒ:ÌŒ3Éñ¼mþ3æø›4VÓ¸O3Õóki÷÷׋çÖ Zk,W£)Ñ|3—@§º^ü@Eã¯aÇ[h/x¯³NK¼¤ó‰Ë^Ú&~Ìt˜6—?TwÈ^W‘Rí¾³1}êºþRYÝ9ø®¸?BÒà¯m–¤»¢CeØ*I[¾üØ3ߦË:F³Ÿ@ç Xñ²×O”ûuþ Q`ÅO ~Pçâ;èÊ‹,…€Wñù.\ù»Qñ*àyuéXÍ,ÝNºƒÔÏÀx Œßéˆïéü5|¾ÙGÄl/³“£âuäßëÈ?ÇEö1dŸ¡¦º©öü˜ZÊ<ê ÑuÏÈ%&m¦\{vÄ‹:#+^#ÿªÞ‡ªŸƒü¬ÎßÄçøüňxŸáú¼—±,µg‹?0$Þb¸RQ¿%“á#™â?<$~I+òJø+ÿÀS;¢ó_Q+Â}Úü=l‡·‰_'íþ˜©­oƒ ó_«Ý¿ÑùÛrõ¦öÿÆïRW^PÞ¹,.éüpŒ‰ßêü]²Î;$Þ³/ëüâ7&ðò]9éÀTCîúOšå[§ùitè•­ã²ú¿&ÏÎâ^Oíš& ƒ©x?+Þ$>*Ÿ!<Žˆß!ÉÌ6ñQÒüCëÑ4…{A&¡@z¦ñÝPpEý‰ð¦6ÄôCÿ.+> Y¿‡¬?aüxDü²hÂü ægNÏÔ4†Lcòö›¢ÿ›9²ppÅiþ£á“ËâS¢<áOå)ä)§Ž ‰?a´aÿ'ÿÿV Xeža`GEÐrjµøÃ…•p_w]ïºHj&à‚rÐò’–I–R©4ñZ^È?3--+ïo¤(T”ò’âýÒ¾ÝC|ùüÿóüû) LÖŠ³Äh€£…½´ê>¢>–߯{8ð•} rÐ$ⴲ؋ã4*çï)òÃUNR5œ*i@å 8Dì#K1þ1«b2P)Â"QûAâ°I(ÅDŽ@"G$Ãß9L'rÄ•Èa–/U„¢rTÈ,,R8ÊE´²læ™fN¶¨’¿j‘T#§‘…t1Q´rnѳúCž1¼‘ãe¾¡ƒp=)¡ã $!R ”õêtw‘Áq/ '5®\NªÊ€YÌŸ#…2`–qX[kÁ•I2”c1K¢m†{"aÑqΫÍ(‰†Ä>².†‹‘ 0:R‡ ,:R8R§8g/8*- hSuÕ¦ƒjTÉeõ7¸º=GdydªÑ_å:AE#»ÕKŽ?7G¡ü*zGU»î¸ƒ:U…SÅòç¡’d2< »´Ö$Ôã.­ƒúëœõ¡~KˆPgô.ƒÎª½Äòu®]ZËòõŠp¨\•Ÿ¡ÎK&¡ë¼ u^ÖÉÍu†—m,|Y¼õZqyÀ äz‰Îõ²+;X¡A.B•¸ÊP?êWMÂo¨Þê-êà°Ã&›mŒÝl¡vïÑZy¦*éÔ’:ÙYFÿþò_ý¸ Š®¯²üoŠp…Tò;¬uî\UÙ*¹é¬œŽ£WÉíÄò×áv9´ë†IøÛuÚu“´K„¼ná‡Q6!/#©ú¦Å¡¡aª Œt½7]}¼Áò(Âu²ú-?ò·MBÓßÇÎ(zìÜþ/c§In‰; Qw#…;°ï#&:Ï9G¨©ªs,DèðTø×#…{x#Ó@ îI®#v±û vÔ˜„‡‘„@¥/ͺ¦‡ŠpŸ¤ñˆ¿B›„?9­A¢?Ù¶Î=k3è.šÓ3ªwáÉVá)Ë?ùëÁ<†ú”ÞÐéþT„G°@0?˜…U*E6ØÍ¤çšÓƒf ¡ÒÓ»Qì`Nѳ„­bÝMzOçsì¢÷¼«É Ñ!Ïæy8•Þ öTô¢ÀƒB (x™ôÞÿki/ZÂ[Ñó„èÄó@ÔšôEMµ4QPô>„è ÄZ ¶2éEú£’±öMnE“EEïKÈ­\d?“^¢V{¡›ä)3´€- )úÖDÀ.@-#"‰éãÎ'p,GöKp[hÙà_Y†?%OU2‡%k eø­Skv0èƒÈÓ P·êÛywвÁíD™±jü[98PEÔãl¹Ž8>±™áªY0 ŒÓ€¹¹ƒy€±`<˜ãúìMùµˆ0_ä¶Q¯5˜Æ,aŒ?XŒ!ܶC¸CîµCÖžŠý$‡ç)}™ÊçEÌYÖ ãÿö â°.O~ëñ FÅwE‚˜ÁݳR=‰¡zØý$&ýýÁP:VĤö!T†Rxr›k!~XUËô{s&þ1T?“˜DŒ!þ±wúH-ã©üGSx¥3 ý°j­7©Ü¦ žFåLb¦SømJ&å—òÏBüØl*ÿ(<ñ<°ù_ö!úP˜ôvÆ,+Dósd1ÿ¨˜%ˆ?[Fá"\Ÿàåè'Ïk%ÓòìVQµ|NÕ¸ý$·bÌá °Tü—Ï`7ìÃf¦en¥b¶!n>;Ígó»gÖmÖÙEõöC ï¡â¡Ÿœ‘LË8Ë´ìŸ_˜–szi9uT.Ry^¦ü¤W¬u ™KŒÂ¸æQÆ.EL>Ÿ€uDž^Ö'/ ¸ì¬µÁågǸ-——K.M¶ j3n¯–Í€Kþ¾‹z ÔƒÌ ÓøûæÌhÆ“3|ý¿b®,39€àRô“^¸;u:n —#È'ýòpúvr~£Ÿ¬ãI¸š’“+àZ‚:?3®=Éxt¯ {ñ úO`ýŒæ‡ ä|@ÿ1¦yNsADÿ¬k-˜‰wèKöÖ×Oú®uö!?ú\¾Bÿr|v,÷ãÚ¹pÝ„y’}ïëÌÇÿÖ;Òr¡çôÉ}ñ”å)q¯gŸ6øGØ+&TvcÃg¥ñkü•NeñïyMª>pzmiì ¢Eå¾Û£ãŸ¸µç‰†Âõí‡|qmÇ£ûÑç·ˆu+ıw¾ôŸ¿âÝ®‹ºÉ›…-°o=óÍÙ†#S‡, ‹.2È¡%ÊYëÄ ½Þº5²P‰_PÐùˆoà©åŠ?û¬ËÊÆíA­‹–È Ó¼jœ}¾ÿ§#"_(jÓsõ˜îGÂÛ·LÉ8Es4ªîµ+ヶ×ÍÖ;¡Ä:êzÃGŸlZ·}ýKÑókCwïq$®©®]Ü?yÓ–OG Œ;[‘Þûf•¥êÚ…š×{÷<÷ñé¨Y7ZOþΰ;ôDpnŸ “®Ç ¿Òº8ûZû¦ÐãÏhã»#tÙªïK|™Qÿhíp·.¦ÞO8³MùhNˆQkݼmi—'[goxçDìñâ>…ÓLÑ ÂèÍA¯åoo×¶wjú¬5ÉõóªVÆÍÝòüÜ㦬?gvú<Šhì¾sâºóågŸKÜw:*ј?^ZÓÍ{E|}AÔôïN®l?zèÜÛñëv­ZV}«mdtõÌ„ÍE…¥ÓÞH¸?oÚôÏ‚ÿ³ÃÂ>¥ƒ~Xq¨æÚĸòAMe™ýô+9jÞ›¾­2v@„—ד-"aˆ¹—ßÂÖ7WWÞ¿]ѽ୷µåÅÖï‹n4-(xmx»GGÿž>ênÒô+gëŠîõ/N ŸWó$ÞÞ(wY;¦Wcr"sÄÐyE¶­”ä¢oÞ‘?~n«Ï•Šœ` U;3ãëM%Víî8Ýþt[’¼d­­_Éʆ’o;¨„ÜiÉnŒZd-\ÒyäÀáƒTöhïg z)§ãE« ´]w±ÃuíÖâÅÖèø¼êšÚöëúØ·×—¯’fU(ïÛ‡h+ÏÔùîYé#¼Wfï1#RjìÉ.ÝüžÅÇ>ß1-°ÿB÷}Ù»_vÊwrÁcZ씲ÚWu\|òÃÛ¿¤%,/[ØvS«+OŠŽ8.W§ªó¯fm†¡GªN]xr·ü™S (^½o€Ñ×gcv»®ž ýªó‚n£ž‹÷iz°¦@öyÏía•²íä|$3®÷z&Ñs¨1y_ªELfØyÄä|Ö &g¾ 1™/•ˆ›g¹>;‡çþÁ3³í âÛ`åˆo<3çN!¾ŠóÇ ó=‰ñµ8gÜ0zÒóžyôœ£g=Ïè¶×"¼}ˆIì^Ä些qÍÞ`?!—ü÷}‹1럙[¯~fþÑ3žs0þ_ˆÉg!ØôÏE-Â}lÓòß¹ý³OüSOpX âIÈ'Ÿl°|Ä™`ï N:Ø ŒO{ q ØTÌ™¼ËOÆø1¸éÏ(Ô"þ8Ô"Üa¨Eð@0;b²WGb|°xôG Ƶ‘CôC?y¯îþ—ÁÌLË|¬ëÔ"ò_® >y·7 &gä%ÔôCÜüÓ¹j‘O¯Ü\òœOÞØT·d†{3'Ëù#KdÚN˵¼ÈfߣMÕ-=Ý1=Ý›5Žü;;ã5$Þ3{bnZvVqx&3BŠÃ‘íHÈÉËÌLrL%Ùy¹ÉiŽ F“26-‹xØ´ Æ3-Ë>!/9%™ñÊËJN—–•’œ gžMNf¼ÍÃcôNˆ‹hÍ`Z…º†L]#ºÃMJdso±%Äê38ƒñŸ–+wµGšÆEØÿº=8nÞöÖU1ŒéÎlßLqä@ºŒ»Ú-T!>MnZfJª¼Ó{V%ñIb’Ô!©«3õœì<‡=%ƒ KÍÎL Kž˜ä—–›66)'5;Ì‘26É–ã°»PBJ^VZnhŠcB:ÓklN.iðPK’KA–ØœQ¸Ä rebar_file_utils.beam}W lç¾ów¶'_|ο q|Ž “BÏ Ž @ ¬[÷ã8öپľ3wg~4ZQu?ÙZVÚuEl£?¬ÒT&”i mPÁ&4D;Ú©k)•¦ý FY'­­ö~çsp#1K¯üÞû½ßû<ïÏ÷=¼ykˆ¢¸SƒñØÃ1S+Rý{Š¢Va]OéɬR“eS)N½˜Ô³Í`Ì=%Ù¹KQýLYUv»‰OAgw)…L:¥g\²^H©9G àÐ&]Š–„EWVÓ‹)ÓYP Ópg )Ó”Õº †Þaä™t)©»ÁQN¥ó.ÃÔ5ÇLhŠê(îd ˆš*Ê5e*;-Õ)뺦×eä‚lÊI²‰!^®ŠÁ%«š¬šs*-‡@œf^×v5ÖlIf=i%S·;­•öTt€å̼‡0ªXS/ËÎlª`Èìxʰ°ÅÔ¤Lx#©Ë¹r!¥{dÕ(ë–•!ñ\°:'éTIN¥TZ6ºìÖåRôº¢–)C5«ÍËÉf²æÙ¸‡ì dËj@ ̵Œ3Þêc!Ýþe1°Zú=5¤edŠrýz‹©Êg dd.Þ¥˜ê1–㦨¨Œúe$ "Še~€—›¥­«Æã´(1¨q[n æbâÁ"ñŒ[๱k;šÃ¦àiyòR<-͘z±€ãÈÁK ¹Ñ%)y·°\‚4ˆû–Ï zl=¢K¯Ç+Ðûê$ä#ÄΡþs6±s@ìûîøQú@ä(ÉÇO ”[³#‘|¨Á¸k¥„0%,á8ãðÇ‘Ÿ8J i‹ŸßcqXœ—€E“@ߨ…Fâ}j'<8õƒT˜pNÑlø£išm†Æ9aršm‰p>€A+Ÿàm¾ [ˆ`4 8©fu„ŽÌÎaÉÁ ·¶-Œpóíp‹HB‹!ÜR€YRÛÉûwéøì.µA¾mµù¶ñÓ{â?êäU›%ÌnÖ™û7«ðZ ¼Ú—?ÊõDሰÈõøü\O³äYƵ{:¸.šm/¼xa§†y< ^CC¶×2ðê¤Ùeõâ$FÒh%ÍKä¤ú*'õ†ßêæ:PâR'’tH _X¬ir\n‰å`Qí¬‡S5ŠHµÂЋ\ .hÁ.Ø4»œäÎX¯œ¯÷Ï}…”¸E,>lC”[ Ékë„yªNcdñý#®„-äú©ä2‹×ÿ¯[7$ Ùn’%òY…c쪑bÂT;†Làü0dz ÊÂ÷Àz£×b%ØütõHõK ó¤‚/oGC ˜D”ÃÕöøÆ3M¸w—±Ar&D21!˜˜€÷B=à„±Þ0¹ß6I¬fð(‹H^´ ³4»ŠXÀ}5‰ Fm¢ÙÀØ S×g#Ça†•ßbe]¥’A¡Q»ŒQ‚ß{ðw ž*ËÚË’å5°¼µ}ÜCÕs[¹ì—¹É)fòbØõP„[CŽ©WÁÆX·îS· WlœL[šÕÁ BÆhv°rÖcÀd¨Ò%òJª ¼.ÂI$p|=B£¦¾¼ôFŠ%ø¦[@mA Œý>„{bAh9 H=gësAæÙ>ä=ÚPcçmÝÒhë£Åö_²ÐÖƒ,±ñ –Pƒë·u²·³F¯Æ$q–ÛvÂyE¾²«Ëö'önÛÞ´s&X¡\¢;â»I}¨ .Ñ^_mëä™oÛ §¦šxmµ¿‰c¸¬n³÷[Øþ°ãÑôÜwÂw¯mï³÷Ñα•…ŠIúµ–æì>ü¥çbP-]¾ÒôôÔbßc Åk^ØþìâSì'ÔÙ/¼T8ôú‰ßuL>¸¹ìà';’ÓøÉAñοN¿µá×-ò3åkÆÕÕ˸±ëƒ'“^?v±)÷ƒ·¿õ\ù‹×¾ý³WÏm<¼hÁû¯ ?¶ÿ«¡·ß’~qÖþ¶'ï=|rhù¦-fg#w½Ô{ôúñWðÅ §ñ Ç^¾Ú=ïâ«O>ûñÓ×ö®tv¾¶âùÒ+\í¢ÔÜ7ã8}½ëƒ=Y·âðÇšÿèü£‹¤\hÌ‹ŒÉu{ùË¥ o,ÿï7ws·õèå+ÿÜ÷äçéøëŽïDÆÿxvÿKâ/?:ôá{ù¶Gÿqä½3?|ãOë•Äå ¯}]}¼Ü|*ôD¾ÿvù/Ýï—?ÿÓKøû×uá·µé™ó;Þ½q÷ÊŸO¸Çv~ã7·ÜÊC-µÝí;Øöæwž:|sdÝ÷G7Ïîß ÍÕÒ¤»O«ìzÇì}í¬>Õö&`û[»m'3»ÔÖÉ\·Uç0fš:™×§ Ä’wd(´ÓP­Sá ÅôéG>¼ùÎæ—}·óÊ‹C#jÖÚ-†ø»µ’©hªA î ÅY¿ú“F¹XLé{ˆƒK+›ð{’bäqE%Z™¤ÜŠš.”3r†šSV3rVQåLÁZ&Cy·l\—Ü6òp|’š×+†zžÐêd(ÜÛ‰VØÏ&G6 ož¤êrŠ)„ÒѾìêôÌòæm[ìe×ÖPdP OXlwʺt')g¤çž±1¦R”ó®qàÿNŠMá—Z˜ YÔ ­¬§åI*ÌkE9˜)¥ô¬bšAø‹‘ׂÖ— ¡§ƒ³ÿõÀ¬‰Ø¸a’ô?PK’KAA]n[Œrebar_lfe_compiler.beameT}Le~-›,.zÒ„iféµ| p1ײRamVX¦ K¹{Ûmï.w×Áô-ˆ:ãÌMæ‚q™FF2·%Ä ÅÄ©Q£d‘…0£ÑŒ?¦q›Š‹ÑÍ÷Ê¡F/yî}Ïïyïs¿»{[#»¼˜†A‡_“r€ë•ö%”x6 㜔“…,T,ÆÄ®“IAQ5tÏBµdMÊIbRHYSP‹gUs®±} õŸ „’‹@/m]/OrMiK—ˆ’‡ƒ¨‚ ¦LPQ$¥Èð"¥3T² ”ÒÒŠ4`EA\’5Õ¬@YR4Rw„K™âœÄçÑ&‚˜”캥ÅånÂÇçNæE7ãFÜ‚  áw ¬]‡JL…;ªhŒ.£)w±>'KTXÀd °!Pˆ¨6D»ØcI”åØ Â*S4ÆàŽ!cKh-aG ÖEZ(zk1φX'*vˆìaa6%¬ °(ksè–$ÊI´ ÕKmN õºÐMv9Qñò m‚D3$èœ[¡Ó¶µm ´ë5jјŒ;lvu;©^lD)ìU–pê -co!¦’ÁÞ33A€˜¦têÎÉúÈ#XH½HÌ6„b ¡ Ánhôþ•|Bnðwüúöº×X»ÑÈÛŒ90<àëhÍ‹º~³¡«4Ö•Z€?sö£vAC¬ áéÁ—;FÞÌ3>kKoßô'1ûƒùž±G·ËµæÏQ×–#——ž;¿0*~@éY=ò󥡥 O|öÖ×G/TÎðÚØáž›ÍÏoq»`›=||¥¦zðÌO¡ÑS›®öl{XÚ3v}ðpðí½OI§^šûôÚ³7­+g#_´äzºûz®˜†Ÿ¬w4øO¶M}µ:¦=6  ¤o e.¿>±Ô:15?ÐÝÜöÆx׋ZÝü ”ûcU¶žß±8~gjîm§#ßj«¿œ.zçñÛ_¸V=×°úfÕÂkÍ¥øäIß n¦lyw“ÿ;ÓÅߎ_˜ýæ¾úìÌÄädìîEmqêsòêC+SÎìˆ|â}{úWËôýÃÊîw…_ùäRôØž£»Àôrö í·ÞOü?ý´sÒ¯iŠþŽžÈê]Oã< ö©b!)pî‘Xlðû•‹'ûù\SÏ­þþ–°˜D¹ê‚žÔõô‹ ’¨ê„…¥…ß:®æs¹„²_˜¥¼Æ J°Ou2À"ˆ\6ÏCåE&òiåxØ]áöñÎpG0ì>Æëc½ qo­¯±®i]dÝÝ‹‡w¶F2 8%h´—kjL6p§#Q#mÞå­ 0µý·û ¢"»`ª«ÙVS§s¤&ä`Ú܇ü/'¬ *QšØœð¬«R^á`Ô{ÒRzx9¡$Mó £/-y g—GU8ÏÿOÔtzõàïS5ýÛý PK’KAÿ¢Ä¦qtrebar_log.beamMUÍOGŸÙñÇÚxÂÚkbÂçš„Ô|¬ I!ÕB($í©öÚ»6‹×»îzM¨z±è±—)·ÚJ•*UŠªæR©—¨@ÕKÕK¹p¯8·Uߨ›„•~šß{óÞ⦅ììåŠØ«ë…‡ßm „§BjÌ3˺W´ÝZÈr,?zlze·e&zîŠëT­Z¼fúÅší–u;ôD÷ˆ¬ºaÓó\/l˜åv-Ö‚Û<6íõX¸«Ð§7›¶UÑ}Ëu¢<ÊtŽ·«½NˆÖzÎXÛ1̪å˜á½ø^Û Wu»eFLÏÖšË –©º^C÷)„êm;è;ÖmËèqÒ°ÒÐOúºÝûÝ{<Þ:tÛ¶ÁÏç­6=(zÒ×p¶mù¹úyC—l¸¤5×0j@%Ôû¶s€–„Ô$ÂJ¡¢CŒÈlD’èàl›Ü#íL'y{b?Ê›Xce–ž"̘×#»ì´GJì¬GšÜRßIøË’ØÏ2#*ûD5)÷=¹H!ó>Á? ©¸„ð (ËC`_Q–ÿ$wω²J¼J$5w._0•ðŒ?rç$ž‚RÜxþ†tYâ”Ð4F²LN÷T˜âB4MîÞJÑ4hee )tL£2ŒÊOÓd|€¦°˜dY’Ì©§XZN¦£ŠÆB²¨0(’b$¥ÉX”¡²˜†îŨ?„°x5w†Å ˜Ã¯(#éÞE†`á÷™&\o—Ó•’‚Åk0ùC sÌ–çæ(˜ DA£*oTÍt<:~J•28£“XŸ¡ª|¶Â©2C'åÓªbqBzO¦“æQõŒ»&á„\Qeñ¾fAyÒh–+g32½îѧtúŒÞÄâu¶xà ¶!ñušm(|½É64¾¾ð\ÄK‘m©‰ÅîÅY~<ð)‚ö}ï€?²ÍF“¯M@ ñ÷…P (à €<ø¯2\»ä¹ÄG/q€/qaý¤[÷#@0ìÏœ9ÀPÀyžô"]úÀÛDñ 7Ô㟰eù\ÿ6€|])•Jz©ôÊù½Zê’¸x¾·Ûùdåß—ÿ|õ˳Bá¿Âãæ³/~Üÿá×§zï³>.²åVx> îc"¨Áç™ÔŒõF=ñƒß÷`þÜæžCÁ@ä¸åt GBùÏ·Õ©¿Š÷#§Ÿî|ûáÑÑÚ¦S…½Ñn|ˆÇGÝ&Ÿl-ö¦N«ÝhèÞ§< â¶}Ãòê(d–-‡{°UGQË©ØmÃ4ÐÛ±wH`Ï0P|õÑæÖýâÁæÃõ:ê_Ðò ÚRþN1kaiqùuøxm¿¸¹ý`§Žúj–¯ä+ËKÕ;•7Û;»Ávd/¿¸ªÝ:êv ýíÖQxqîݹEî ùVÃ<Œ”¡ÿ—º¨K:ÕGô|·õ–Ûö*fÍ̺ sÞhê^Õòýù²Ct¾;Þç[^eþÍ?ÈŒê#¸‰B¹åóËþPK’KAeÕ3Ǻ$ rebar_neotoma_compiler.beamuW lw¿óÿâ»8¹öìs“¦ùè%ÎG“4ñùciÒ®í?I/£¡Cc€{±Ïö5Îuwn»ñ¡LÝ b¢”je¬UÖƒ­ÚªA›(*BŒR`TtŒR"( B[& ±Nl¼ÿù\LÇ"½øÝû¿÷{¿÷ñ·ÎÛ¶G(ŠoKŒnµYŠòœ£(*Ù`ªÓŠ™ÒUŒJ*m̵‚j²®ÂeŒtÊ4 ›5Jv*£™¾Y#S*¨)u¿íUÍ‚¢ç<ýýbdZ±ÔÛÈ,éõX£h[õe§´¡gµÊ©¶¬š¡×M£XÐ,Ûªcj¯R(©lFÍ*¥‚í³Œ’™v²Õ¹À„*ëâ2i#£ÖìËké|½nèà0šž«QMÓ0kË FÔØyÓØÇØfI­É*Ke­­XT3¾ŒQ!Íe៮̪)…(õ„XÊ6R äó–k÷B+Š%›!Îc†×U5cU Xb-hÓ|A@вšš©qêCŠþàRSͪ¦ª§ÕLª¨æ,ÆRá@W÷Õ)™LJ-¨³ªn×eÔBEg!9‰îŒxL•5ÕbAI«^ Ñ3µYÓ˜uœ9«4m›JÚf,í!µ¦¤CŸëÜÉizÖXJ:]õÜ6p'z86PHw~"Ž D|š•2Õ\© ˜èÏȳÇÐôô‘ÁG`³ŶU½®<Ÿ’­,•÷Z¶ ³óÚÆŒª[ÿÓVÈ–t¦ïöTlQ×6[@QÌeØg*ÿ̓ÜEžiÁèhi 0Š3B#G;IÅ(ˆ;E<†=Dô퇜£$%²…“£pç8N 1ÌìÀÁFiìqR²pqs¦eOà„@cì áâVY¢§<‹½»^’°È@Fx3"IDœ EOÀ'ôœ\BëP©qnìHôˆÏÿõí§éC8)#‘^€|ðq {àÿYðÈô…zYƨûD È`1È ¸ÿOÈ×€“X„äó2…}ˆ•§pr qÂnо‚ƒ"f .ÄÈ|ƒÌû!ïoľæ·|-¼@ß¼}^#ó¢Lsöµ¢€,Òœÿ^DsÈÜfq †ÔqBnǪ˜Dè+¡Wå:Œü ´æ„aB %}I”yBR,é %ƒ‰XA„?èïtZ]Æ9ÔÏ‘¯+€EPÀByP"ÍKîçñûjä–Én Ùýñ3¤C¤AЇ¥‡odT].­˜åg"œÃ¼ç%‘ø¦2iN:%ÐÜr@í—h®éöYê,qÅ ‚$$‚žXyªó‚€c¤ÃÍe€yb¥+œpÈ­˜k®Ç¹ C®ó¿«èóC+gáŠPâ\ '‰,†I8¹üA ÖÏ œŸÄ2"`D+ýuOW1ßh%+q"¡*pÁ~¾ÑPžÓÇB[¸éîx°\³ÞËHÀÊ h†z[ðoôUàhn%±@G$’Œ×Hsí`\ÆŽa¾ ÕKÂ(BL9ñr™ï&kÖ kÖ‡|Í|'Í9 €&$èt:$Ò¤‹ BvÅùvØu®›ì] ¯ßUÃ|/â%,"gãÉò$Ä”Â5¹ócȬ 4¢¯7Î÷¼>€ÚPýÃ| æª P"¹€PBD¡Dò”º'Ï’6ð2Z "!JCBHæeqÈËPT¿Ú×ÈÐÜjœ¼ €€–õü Í Àu¥¹Á÷3ë¯fŽó}„™L*½Ð‹Ö dÍ`Wëj¸ÖŠk N“°=q¯ükDQ;ls'ùr›œ-Â']µ Ä Â‚x@8Z÷³¤"©% K]=² „YÒäÚ Î ×¾Dr1‰½Ýµ‹ ®½d•kïésí«AÜïa¢VÙÃUºìÆFAb Œ‹wí«ÝïðŠ>T»¦Ê>\Ås­k¯èžwWÕµ¡Š3võQ1×dSæÑûIÏzI¯FÜ8ÉÕ)wžŠL”ôn-ä9éÆÅ]_Š>ÐEú’pÏ£.í¹2öâfÍ&ó}Ž6ïêØ‡×oû‘,”>´caüKBÝokÛÛ¾çh„žVÁŽžtã`ë±Ö§ïó'/í;?/xëú§nüî azð‘áë—:>{|Ùºäß6/®¨{µñØöísÚÙ>ýÊởYüW—lûì“w}d1¯)ïœù˳ùkolÑÚðmëÝOžìUòçú"‘ß|îÝ îàb+å}¶þjÂwÉå _n¼ñzË™æM¯ž9wòGo-|LÜûú}‹™çŸZûÕ%¿q:÷ûÅ5Ï5Q›4™ÏÇ|ªg²ÑÕûAÖ»:Ùuî¼:@"nl³ëG|Èêví în ÷þ\ä\Î}®ìœÏµ3£¶m’œÈm§óž …öZºó  Ô§ÑìÙ¦?Üuë+'ÎÝÚ³g|RÏÂYŸã϶üšm›¡xçÝ8e•fgóAâ@ÞgáÍ~†bÔiM'Z›¡XMOJ5CÕ–tx×t5“Gp–ÉP¾±]“›7¥vNnIÌPK£r$*G†R‘Xt8>Rqâîß‘šÜ:±m†ªËi¶I g‡Ò··íœr½Û#ñ19¶Ça»W5- ;CÕÄ× Æ‰±µY5ïþo(œ"(¼Ò¢Dêåß3ÔH8o̪áLQ1³šm‡áý=o„̰e¦ÃÿÿWÎ ü‚Ù—Ú²ÉüPK’KAD¶¦U° rebar_otp_app.beam…Wlw¿ó÷’»8¾ôß5i~´¹ÖI“6q|NÜ.irqp¼lm¥-ˆiÃ9Ûçæ’³ÏÜÛµCPÒ­êT@eDµAÆÆ(”‚öÇÆºŽ `B+‚ ƒR4`¬]hÒñ¾çKê­BDz¹wï}Þçû¾Ÿ÷µóÍØî©(Ežˆ'Fv8fž¢|§)ŠRxKK«VÊtŠ)µXd3f¾¨Úªr"©’£¶_·ÝÛÊ0ŽUÒªrªak¼aªY7žƒš*ͲL«¶\éVU©iÓr|æœx@5ô¬êh.8ofK†fÊÈŒYÈéûkökNÊ03ªÁz隢e Ývl7 °lÆÐÔB×IÊ1 C¯Îj†æhÕZÁÔ Ž¿hiPžÑl»Z³ µ°ß×ÝÍ’²vU¹ÄÜœvÈvLK«…”¡gTG7 Õº™2ôtuδòªã?héÐ6Y‚#¿ j^c³ºå>Õ´MžLÆÌjœšÍ¦Šª3sK”ªe×” Y-§´,¿rɽ3kÊ æ~Úì’áí‡VøíÈZ\ZµÝ&d®0Ì*gÆ2â¤'!kZY[s–™O‘Î.¥KÍ8lÎPG+´´^XÆW¥55o36 ­¶J‘6Wý+ޛÕE9ldÚ?*G¢a9\KHW\~?‘>h4ü?Óe¦QД¢ª†àŒbªüsl+Oc_pƒDKYªgÔ®HA"‹)ymG‹ÊÔ–t‚–Q¨•vÄH|ph­("¢'] \D;PÒä=G”G8Ô½(ÌcEN„|(!"AIRˆ“$™..âHêÐ9`VBHé‡ÅE`oS~ (S!Xª¾•å•.J>¢0Âq,)Kˆ•HT%ñÐýIå ʽp¢Ïú‚þ D_ì…!{á1Ððx~‘¾I¿…õŸdñôàU´í*’VÚ¾*Ì÷Ü ùè׃X ¯bxr˜¹z n”h.X§H йôíD¾$à@^y‘æ„>¾á–íDLtPhN|;§Ä@Q Å̯ÆŠï“xL %—’Ȇc™•Š D=jµ FÁâ#X`Òß’DJ=CD( b•“xÉ¡¤]R,ÓÀ$“h¸’»”´J"–t¶›_ÎA˜ÅXü ‹_')¸B¬¾„h j4‚˜æÖÔa¬ø»BŠ“ëæ›¿KIÊ‚âƒØfÄÊ×_¹¸ KI0I*Âr–´@±˜!›Ñ6°[ãà›A— RPÝL–nU{a­üZ4‚Býƒ|Kh˜ÄcY‰‡¨ÑxïãDÔMîQ„Ñc”±rdZ¡íµ1¾ÁxpF€³-“I`®Éɲ\=ôÜÄK†£ ¶@%D'ƒ`ÓÂq‰RæÝ}$‹ˆÃœ@ÑÜz`ìÆ Ý|Hðwñ”„ˆlúˆp6Tþè "&2rXP$ŠÐ辈^/«c|;â;h®ŽH r X!ÄähùÉ rHB¯dª"öz±\¿yn#PDo£XŽË·o§¶3Ï®ü•Kž%äPÞ é5ÞéíðܬÑæšh®›D@ä²J\3Í…!8ÁÞ>‚ qÙ$®¥<E`-œ·|d"1>Lf$Cñ0Gø>ø$KnuB€ÏDòBù(ß"ˆVôÅx™ô±~Ëÿ#ˆUl‰ñýH@ðe¹Ç±ö’/Ïñ|ž4ñ[ÁHŠ£=Ÿõü0?˜|Ï‚Õyyò\ïÅÉ»àáE°Õž¿¬©ÓìÅÉzk½õÚÀ$Cj×{þ°‡'~»çw€môün°›Ô†+ð²ÇCzˆVôÓçù1°-þVOz»£bïƒ=o«àÙñ>ßçá?@üÄýD[——ìq»‡íñ|ò³,èÕ¼§k;u‡Ìú¤¯Ýú¾“CwFÅcGg.ÎùÄüá /ܳøÖZ‹oÿµóó7þtoËË»â4|½çßWÎ?|8\ˆ î~ôïëüUcüô™á—þüÜ«ÇVw$4žøù³oÇ'6½»þl÷ôW‡{ä³­O–>õñé¶{_ŒÎ¾ûŸŸ^›ÿÝÏ>1µT³tñ©îK¯Ýulà©ÂÏ<ýÍÍ üázÓõ‰ËµcùâåÇ óþ%~éÆÅo}íâ7&f´ÿñÒÒÅ7Æ6þ­ç3çž_(4 ¥¾-'ž™øýì³Go¦ï~xmÝ UÕùûj¯’{þg¸ÒD˜O¾üÚš¦óg.¥í{úÂcG†¿ÿ‘u èÔ§?[sð/ú#]÷œúÉ“~½wóŽ_þãðŽ/}÷ÍÇ_lýʳGß:°çÃ'JKwþ«¦sñ¡Ï½ùÉSm»†ö}'´êsìW¬—"ÿüíwQÔN3Ct/z³P*æ;ìùä, y~/Ø€7.°þгñü6·|6:+æÞèŃ#ŽcŽ£ÉÎø²¹Sº/LuW&¾÷ÎÞW/-œ?#\þöµÙÙÑñBrë]¦\exZÊ¥z£©Ô¼|a[K¡ìåÇcu¯1Q%‚Y^­œ wtÌ-W¶æËCEo¤4îÕ£Áœ8û¨YõF­4>¹¼ROÔ¼j9_ð†¼] o¼^ªŒóèGÂÆ¦AµJ¥A ¹ú“ê¶Œ@‡2+Öv´Nb”p#ùrÝ‹4j^¸T™‘Çò )ÃõmÑš·Ã«Õ=1îyÅú¤a£´i¹´U”óõÆÐX¥X)yEmCÜ_U.oww³±ü®–¢·ub4¼±;F )cÆ&Æ}%‹ V®òå94švR¸R4vW½öixµ&Œ~4$Zªåk…mb‡½øÎR¹XÈ׊|,¿Ý™Ž”ó±|Õ‚ÊÖ˽B£ó'ÕFOŽæåwo…Ùv–…mÓ¶N€Fe¨X.Uj@y6šRn®ùjÕ*N#òŬRvÙª$»¹ST¾kÚi>C7>ŸàŠ3m„ðvUóãÅIPO% ŸLƒ9¢¼›B,?QnÔ#ÅR¡©UƆ(H[ƼڨmTÔlŽš©¸Ú‘¯E+µ"-ÀaE#Ø¡A¸R~kÙkñjµJ­¥Þ@ ë8A¥RmÉo…ÈášÇjã-ˆ*ÛD èxEÍ¢Û½Ý4×ÒÉ€–C¥qð(Oxs ìZ«TU^©ÈQK¢AFÉ_MRùž„œ±ÉAÝ ’éWÊÆ‹ϽZ£>T,Õ"…JÑS)D³(E?\?»¾»ÞðƆ(Ñg!ùÁcV¥®R|ñ×^÷ʈ¦É ÂbÈÕðBdÑQ8$àþh–Oá’Žòi 8»‘¯‘*”­Mã5 ÔÈ}F¨B@x1Eø´¥±­VÙ9;ˆR!Z/”'Šà ¾¯—®ð81¦°›üž€d¤ú\6Í“iß«ít¹ºlÍê5é5飀6€vº¥Ï5Yòu°ìÍKOzK¦—¶5ƒ‘µé̱ µÇ‚Ö ²ÓKÒGÇäj§i«ù险±zm@·<ý$ä I¥g$?¨§qí驺2¾0Ý\|f°[š>¦ÞÍÀ/NÏ,“3øÎOO߈风ՙ@Ið›qøÌpØÜ´:³¦,¢û•*¿_ÚAe„¾*‰É=‚åkÒœuõV|u(Š:zŽ£¬NÔT¨†B9¤](Ô~g¹òûðü«éá¶e¦f¶Úf""¤d–\kH7”‘½LZ©¨ ÉÔ¨ÆfίQó¤‘HÊ‹˜â¤NuyÌìe!£—éV§guy–Ùk…2½–ž³·ë-íò–uû5ÛÙ’q¶ää#¬Í64‰Y0mØÉLRæRQS—)ƒ¤JBœdÄóu€X¤?¶¤«òµÍQHeDM²È%nÚ¶6|Ӫᶸaj{æè¦ñ0ë:Ü$âa«ëp“ˆ‡ â!ˆxÛÁ‡´›œCçQ7´û1 †Ë\dÔ”ÚDמÄ&Ïb“¤®½,ÃÆ,SèÚš›×}ò¤4R‘ø4ðâZÉ RÈHFtqÍ,‚m¤kXÀJM.°}º5¥O–Hªa«o€ ûtë j"Œbçµèb{Hã ÒŽÿ¶ÖPˆøÆç³¨9€m_—® “ O×Pêú&Óp]é²~#ÌÚB†Æ /†ÉVÓ”)Õ«J$òH‹-æy-²5>¯U·¥‰š{”i¤®ñv L æ;bShhµ‰>lpû&¬Y Ã_fÌ’b‘Ƃ’_”KXkU&"‰dc›e&%-G}’ÜK•!hò'Øb)[ÏÄÒvO‰Åñåâx/ÖÍP‘¢f˜¢F¦Šûl‰ØQªÒÉÀæ-{ï/ÅUæ~es˜ìbÚ£ý&Y´d$##QŒHq¥2åÆW¸N¿†Y&‘TFö³%7+ÎU/qÄB„6;ORãKÏb7¡oŒxB«n"¤Á¢ú³¾Ó¡ Ƴ[^Ž0v|Ö®ÆZË)£5¤+ì¦ù¾JÍ(ÒdýmTç”'«:Är¦‘HIÒ±Ï ÉøZÊ_îS/×%Ö'±‚õGƒîMF°dv OD’¬ÍĪ! N â!¾N„…ÍÛ:Ä _ßcSì;¹º­bê  eü}VøAìãO ð·LãOƧa‡SšµY M¢!n(Z‹òä¶øU@ž&ïy‚jå,]¼ªñ4¦ë1]Õ)Òléöa)VÛbµ)•«Qà žÔ¸M†ýtµ¶S¬±6Xb dlá˜bÆ3­Ã6$J…Ók™¹^ËÞ,YŸÌ1Êo]œFi©‹N2¼C‚?@éìøéì$(¡%A6SIks¢õzUß4l¸ñ®ãnv“nÄWgâ8ú€=Y›°áà&i¹7çºáY¶X«ñuM _§ðöÔp[/´?­UW±?Ý KÆW­ü8•¤|ðY(Më:a´W4Þ…i.X/ ‹,n1Ô´—4¾ð>À»;ÅF£ Ùk„¬^CÏtˆV|EkHÊ =ð òaÊ11ÀßéàѲCô0÷~±gNã=>ºèM$çKŒDÏŠ>Öà «Cô±Ux[îÃÒ}Ò/Š!ª5î³TlPãúÑϤû2áüòÓ‘ÊœMàëb[wŽDܦ$süpJún:—¬s¡ÂÙa~,Ÿ¥b™ùîÄÙ7‰•Ç_p-H±D ©ÖŽS©ŸQÅ8‚ŠÁç´ E ~—ë”Ô|a·8SãgÀ¢‰”¢à©Œe¹ÌuÔQšp`pñ"Ÿ%ëgkü,•J8À¼¨ñ³ ¡"¡â9Pñè|. ØÃϽ ÎÇa°:KÎÅ’óaóç5>€éy˜^Ð).d]xÌé|¸0ȇA¬9k6ÿ?!´ë`à‹:ÅðÚÂLÔ3°³pÈRQ“†œõø2h†aR€|ô°¸¬.Ί|àò<\Ž™Õceri‘Ϭψ|»ŒåÄ;cq‰Æß™ïÊõä X:À»àò¶n1¬ñw9"ŸƒTX]&j˜ ®“=±ªx7˜\Û%.‹uˆ!¿;+.-ôê{ÁwWÐ錄“Âää2›¤ÚfÈŸ§ñáI|ƒy4Ø ….„M T,©´'GeSeç‹§Ú5Iª>GÕ6Øöx®ó%ðYLÞ&^VlƒU¬L§(Z]xÌV)‘ù ™ïwn)ŠL“/í#ð@iºÇé%ãj£",k³[Œj|`¿„àak ¥ñѠȦØ>[è_äôpÎ6GÐ)Kê•èøºâ] øöÉ„%­Tó@†¨¤¶L«p°ŽuˆñŒFX—·³óL¾LããYñ(–ìå\³ux¸7Úܛө¬¢íÃêùD²À’™ˆtPr!˜Õ)*P´Þ¬h݈ç)}tñ4DI‘}NЉ•¢Š:ík¶lûtd-WwU·¯?ç÷™tª+±áÜ ²xAãUecò=Ž(3GÔpS[ƒí–ÿJ?Ž«]Õ"ùI™D†¢?LÝ͘Æëd³¬1‚3f"+v±Vi£½qè0µ ¿Q„WtŠÐmw³n»áĤïD%<ܸSã;€ 7FÀx' ¢"…ÎlöÞåˆFà­Ý´óØyð+[Ñ'ZôØØëdê€\¾:IbëO©v’¦Ô2ðżŽ7¸ä§@·÷‚Ïvøõ*¿Ö,¡K©ÚX¶ØC×t^yñ¾xA\­ñ÷M5W£óG{Hœ¿›2Ø\3==5e0 åd|̈ðXct`jdÔï9Ùè?eŒ#T÷‚¾‚ÿk³âƒAnì¥C{o»´Åu¦Ø§ñ릳„NìÙ9Cù–´Åõ$éõt¹x?úÄhüýú@ˆj±ã¦ú­H°Óµ0ØdólŸ>@Lq"냴çq¿eèëpP^«ñ:b/™]uyד¦‚¤UîÃs`Ô_©Ji‚&­«2cÂdFÄ`HüU0Êß‚dHn@ç’ÕˆéÏ¢Ž? Ð@í‚Þ7ÙâFÒáFè°LÜß-nÑøÍþ™z«ÆoñGwh|?®Ï[³bPZ÷±fª´b–‰å0 jä~ª‘ûU¡½-v±¸]ã·9b?À(”nÇzÔ¼e˜[4?îW‚ûYq à~@q?p? ¸¸ î÷;Áý.ßéˆÄ=EÜîÂú€»:>îï÷»kÔQÙâ>Òù>è¼[ܽïÕø=X|¢X÷bx’?¼,?ȯùª_®Â‚…ú>@?šŸD>¨ÎšƒÁYsΚƒíÃ1O<«‹‡bEñ1?ˆe9=l|7‰ö?=¹[|\ãó'§hüãð¡?ሃ,XúwØðjløIU'ÑKìQ‡€Éí•âSÌåêü”^ m²q>îÁÁèò•›LæÆ/q „Äÿ=˜ì…ôŸžc£¿–ÊÜ'Q÷qü0´NÔPè{N._Eµš±~Ø”F†ß§¬¢c"~]@™D\­õ[ë ºþq›î._ÃüéZ7Òo0b—aÈq“ n‹©½N½OUïÓÔ;«ÞêÝ¥ÞëÕ{ƒzw«÷Fõ>]II€ 3üôÜ=ÿQ¶Q;âhüa‚ÀÿD¶k£“Ýø#^à£YqH9±S<†¾ô1Õ—fVŠÇ2á©+'~”ªÉ«ÔcÔÕ¦ñCŽx„<ôpû¸}6+>‡«ªŽªU{¨¶©NêTØï´©ó›Ò±™áçñbóy°¹¹ùxV|áàÔôÈÙº:\ ÿ;†g¼™þ Žø<Ñ?úq8üs§x‚n,OP-û¢)¾¤ñ/¶Ú6ŽƒŽƒ\/3“tí°ŽálžÓ)ЦntsûR«IÄ'Q¨þBýl}fWIb= qè’þ/°BŽLÑGA¿qž¤Hÿ2°7CÙÍŠ§TN‹§¬õ–xJe÷Wb爯iü+@fz2¹A sësò0Rÿ«?Ü!žtù¦nñuÕŸ¸jò5L2.?Cã_o A)•ÒOáù7lz DúwA±b™þØE¼.¤W_Æ ï†,¸,;Ùÿ4ûAótV|S…JV–ÏKÍ|^vĈÏÁçèùJVüd:·èJlΨWš‰âˆñOA|'ˆ_ÍŠ_Ì4Ò*[¼FFzMég0ÒÏ5þ3ßH¯BìŸOéÕfÆ¿pÄO‰ñkd¤_‚û]ðǯ²â× ^íaåÖŒåïBó¸–î‘ )–™Ô>SWšXþÚ¿$–¿·@ÖßfÅï&mþžC_fšé~çˆß}/¼Rüg§8‚¾ïr‰nö²ÜpŽdâ[í*‰UÀ²‚ÉAõ‰Ôæä¿=Mª/Màô{p¼’¼ž`QφÑK+A^oäŽø= òÈîÙuŠ7 ÈJ4 &.r÷ü7ŒøF¡£{ÌDú­050]ÓøÑ› ~{ÿ±S¼ â7'µ0¡… ´x“´¨ÊA¦ZÞ¤,Ðm\æúÀj}óíhýäý-Q‚ðtO}‚C§ùùþ-åû?Á÷ÖøŸèWŸjXÏ4ö „ü¯ÃôÕ–ŠÇŸ‰Rw“;ýl$#’?íI#ºfÌê˨ú0˜¢{L"…Â:óKéÛïȳ·(Þ†òÂÿÝ)Þ†òoO[®C¼ «M]6vˆ¿°G”D9ƒ±Ð`£¶™>ÊŸ9VÅøžŽ§Ï,<ÓÀÓÀÃ3/ÓúÁx!žEÁøx'üÿÿ]V <”Ùþ t1Ji‰P*%ãÒN›KnK”B%1fcÌÅ\Të’M«”KîÑÅJTúÛ¢b©h#­•Ö&­µº(¤Òu%û?Go»ßÏü~Ïœç{Îó½ç=çû¾÷‚ !,F  LA0®°AÁa9ðÙ¦àÁÜŒä7'y,AŸ†À€±¬¬‰Ï?<– ÉoÇîuEpÏ·¤<±Çt]I{6"lsˆ¹/è›¶æ¾aä¨íœeç‚*ÂIð‚Õ²­5…ïè§(œÈÆïÊq¸~ñâm£'ú? þWÐ*V ¨Í‚ëvxf„‚š¤5ç̇P¸|[é÷:¬Ÿ5sÇ9þ«8Eì§t†b- â×ý;ÏÐ}Ã\)š£ú¾Ô wÍö}áÕí<—±F-+ÃÁïcѺªæc†§¦Ÿ¡qÂ϶ÊMøù'UþMk®¹§Õ×x¯ó˜£eÊHñî¦ñîºïšÊò_N鱉ëé?ý¢nþ—}49Ï»]·„Ô¿°£õÝNk}õ‹ÆÔýM¿ÊÎÏx©¯ESò§Eœv>Ëj_Ê´Lýƒaû=±E]>ä>ÞuS•bºë¶üžbƒZÍn +%N½7Jñ-àC<÷»Äúx¥âŸõÔFmÕ¸øíuɱüX“û-Çè©~Te;ѳ,¿ù°t­;Gã€uÿ÷c7Øú¦v1ïóóuG ”ïVk6õ¾™´yQQgÇboÉÁÈ¥Õ¥=Ï\E† ¶Ö5¥ƒ´ý˜1=¯–ý”!sj‰³j¥r£slaÑߪÁ-qO$÷•Fê~ý}0øý­íÏyñ¥×TZ¥¼¾§kÒÕRúC‚È#©Lóü`~]dØ;Ýÿ-Qºsfp ½Ö\¼RÇ­?³2ù‚懿Xþ?ãºñû²âës, T»zå1ììÔ÷UR1§íýÍõ¦Î~?„éžÈ>µ7Ñ#36êÁ({ ¦‹ÑSÀç;ÎIË•èìYþª®#Ïh¿M‹=¢ÐÀ]Ð0_tyƒ°þÈdž·æïe¶k_;H7h·^½¡VãÛØðe<Ûˆ#zõ½v4X—Ç™WíÙvQwë»_ëÒ^L[î½'Q/ZÞ?Ssôô‹ 5ªR±•Š…qÉîûa½›e«Ž?NåÆÝH‘Ç'V\8ä›ëN‰>×icÞ}©3©=‘3æÿëÔ£Óòã¡O—˜w±Ê]Z ;u¢òöQÓM 77؆³^RSšoØÛ©²\#Þ[eóæ~¼Êô¨È—óÎŒ^))»ºµ)iÍ£¯½ýNÍ2^ûhËŽöäÀÖêîÖYÌ_æÖ<4¸îicsÇì’r˜xgГè36 'âî»ËÖü|++ï¡üõö’¡Æ[×oÜhksSæ]]žÙRvt“à{IZ•œÅ[þI=>5Èß)èNáÃ2í¶Ó×õ>}’÷8äé¡¿ìÎ뢨βÓt)£­ ÑùÊ*¿÷Y J†Âû]?Në7ŽHî¨I½{÷’oòÚ«¹þ,Åi.z-ZZ.÷R» ™ãçµ]DIú_ËR½–©6k¦?ùùr^Ñ'§!m­é#:~¿™T¿I?”Ü‘ð¸9nN…$tØuWÓÇ3S?>ª¼iôijÿŸ³­5c~FUžžFNµNF¹>qF‚ÅuÆ'sõuÇ·FG÷]½Vè°oMΔ†‡OŽ_)oò™$½ê{Ó52sÏt•Nyº ¸¶`ÛøkµŽ~ÂëÕŠ¨ÚpÖmÏFgæyG®êΈq¿ÝSÜÇ<\“Ö$1“<¦TZÆzSÒ®iŒ|{þ^ýÆê * BªŠóu˜TÉ5‘\=©}!ôA„<Ð#Þ‡ µïO„à¸Ngƒ§sR=Íýö¤zJ®¡äºI®•©à©A8ž*„À/ $À–P†°ôR„8àx¿ŠŽ×&8^ƒhàx~ßǹï„qq^Qç"Ž÷R!xö"DÀ½xæÇc†Ÿ÷ÌWŸß3ì·†Ü1_ > @¡tBýcâyíK䀈ôÄÏýžßóýžý[H#äçrùé'¦³ŽóB(5hi%Å*6,Ó1KÍJÅ.–ÍzC¯i–ÏUmFÓÑk¶¿¢j±¨í1WXÇjjÞŠR³5¯fY¦ÕݦÖÌ% Ò¥Y5ÅXò:UË<ë-×4ÅðÄ㽩tk¶f8áÿ-€-›ªæ=[ÕËU<•š ¦QÔÎé¶£KÝ%M©·êàè?C©k\I±ÛJÕªµLÁÊSÅm»lêF-+ohšºÌG¡š^âkŠí릪WtMe ºö¢¦”«Ý쪘V]qºí²b´Âø5ÃnZZQÕ-Òíiyê«U«iNÛ¥–®6Ð¥&´€LM ëFÅìYÒZ™·ž…Dkd©‰D­ûl:•N¤;1 0)Ñ›pkÜÎÀðÂ`ǵÿž3€zâ ‰Œ¸‹ ¹€¹@°OD™ay‡‰ÀH2fYtMÒðG°Ö/—òÖ)F–YüñŒ\˜8QBÌm0 æn§éLÛÄAçþAÂp¡~È$=B¾Ð pÃÀ®°3P'wm‹îˆÈp½A"B›²å®u†ô‘†\Ünô€÷2‹[ír}à-B¦þ,?Œ§±äû„‡A¤ ,å„s™É "+ϲ‘qLŽfX‘ï•øQØ? Kâ,~ˆá`ù˜F~F~EŽAæ8?ˆäÂe!“ Àßð‘Ûq~„‚ AŽàPÄ'Þm,¸®í¤¬m­¨M™¢yÛÍá| GåÂ!Ć"}û$øLcHÎ`zZd†Îð}t½ÐíÈÇ0ÃÂ!ávCßû¡ï=Y~ E214ÃáÈ$/â‡ù(s 9L¢q>*<7ÎïúYÊG!5KSo@êvÚ)~/ÉÀà ·º¢§ªËð»ÝÔQš5Yã°³‡ä0>A¸Ãí£Ô±Ÿî@‘ 3ÜÌò‡pÐâè‰v_"’üÖeø4I“à8žåŽ¡NÇñNÇD†SÇ$8¦À1•å%”Hˆm$Æ’Mz¨b˜%÷i”D‰ÐW‘œ!G%¡+°…H^€p„‘2| ¡“޵H_üÙzƒ~Þ@À‚XH7ˆßÅ ð®!ÆÕw¹œH¸\¼¤¿Cr9[8ÕGAvwøîqù{AÆ\~?E;|‡\œúÆ\ü!}.~ä`GÌñÿÒ=ùs­~3nŸq×¾ßÕ‘wãqîgKŽëõý¸DÏ]šZ¿~Œ&_¾þûMÖu¾Ï;Ýøñ[‹ÒûÌ.ué;·F/}kð™¥ó'¿×ÿÝ?íºùàµWÿ–{›üzóÝ/½úàéÏìÿÊäGsŸÊMî¹vãß_þǯTþúý®~ûÎúÌ//-íþÆ“·|úÝ·þðÁ~òæÍo?z5Ó¿ùò×ûž|¼Ó»ž8aÊ/]ÞüÄĵ*¨¸öÒ…gïoô6öý죿¸ð›¹Ók·6n>;òâ½äçî}~|îùóêÐGowß½[¾ìtv•»÷ʯ†ÿ~ò·?˜ù×ûïxj½vãñ¾Ÿ®êûøü)hð¸Y^tèÜRîŒègÒÕé,®~ÐãîPtuºçwv½ Ã.NÏÈ «Óó3àê=.qçßãî#0í8ÝíùµV=*«¶Ñz0úê7w£«7~~ö™ÇfSï¿ø—åå™Y£¶D‹ÏR¾Ïl8ºiØð©ˆoÝHŠv³^W¬§)¡Ël:ð3½‚X­¤aôäÓr­©j*ênªM­b°©*òçNͬ¸8ûD~õLHé )›>RLžÈf&·HÜ陓ÅÙGçVP`IwÄty2[9RÞ6Ï-λ殅t&'^nU»ªY6”»‚¼™ä‡“бŽ^ת]%¨ÿ…SˆÂ+#JºUºm6­²¶‚IUͺ–RŠUÑ'—žª™j]%®D’àŽ€;¢&"ÌX"‚³à–ƒ9 欜È2V"‹ÏFE_‡.¢Vú¬K,ï{’ï'³Ë,/y™“Åån,b†å`^îº*Rõ@ª¾šT½Cªž’ªRõ‹¤B@ªHEÅú¤ óe‘[·`ýÿ1h SƒÆG ê€A˜W‚y¹ZDâÔ´JûŸÂ) EðwI)NB> ˆ=øT¯¸ÂYÙ¨¸BqF•$Ò;¤Ë$Õ¥@+\€¸ÐÅJR<øšJÀ9¤*ÁW ¾ƒÊch~,¿è4­UÐÙê<ôÇZ@½W£y’_úÉü«ICðk º†Ê‹å»›¡|ÍÕåk&Q™ß%ü8R$†5W8 ÖôEZ¨µº®Š—ÁªO"¼4øý˜ØØ­ì Ø* >‡E è”Þ5J¯6¿€‚´¾ÂNÚ ŸöJ>A$´pNqL|€·Wo—„ö~q#Ëo&à ü•˜Ø¡mÕ¡mÀ…À‘íD°69XêcX~–ß;„ÇŸ§MÈô z¬\ÚÈ´ò@¾,P˜t½ó°ð¼Opó~„ˆCHMßFN B°†wFE`T×RŒ+Tû€I_5Õ¾EªQBõa]¢¤.1±›ëcœœà œ#á1IˆÅ)—‚œÍ#Bmð6X8Azd^ ‰½pp‰½ ê¼½)nfù¨š¾ëô£ÐCN(–ßL)Ò Ü|PìžáÀ¹§ ׉é%uˆá”¥4—FÃ`ë#ÚYÆ`Ïlí·A{+‘˜Ø¯ôÈp¦IR#¨ö!Ë÷ãQµÖÍ×ùD.ÍŠ2('Óp¢¥’UQÛ¢âHþv€ÞÐ*ÝŽûOUÎÊÆ¡žñêzÆI=9 öT6ö°C8’|i´Øa>Ä«p$°|v)9¤ùÌÓóÀ2ˆN¯ÀÁ‹#pø&(4Áï•©I¤Žqj¾âAUJ þtÒà€´7’ÈíЃªíÆ|#˧‰fÝA– Œ2ßÄòC`ŒÃÌýâS²„ã!™ó$I•# $ ù8ÉÈvgeÍžŠŠCHBc¶9N†Cs%¸²[A]‚@8úœtƒÔ€°Œó|dxÈÚ—‚,£ã$òL¥1u õ4†ø«Æ®¢öÕ k¨ŸàËÔ®€´Ðx¢¯£vÂg=Õ7‚l¢c‰½£*&T®âßEõÍ Ý¿$Jó%1}ÔNÆn¥µ sl£v£VaÝ•:JjÈü˜¾cl§þT'¿AµT'× ÕInªjÐJuR—fŠCj·’r!뵂êTgi훨]¢:K¹aª×R?KstQ|×μMúêɾ~ôêÑþöîj®_ÛÍ7¯ûʉóçØæºWjϰÏGëœøògýWŸf›‹­ùÉÛ®º¶÷Ž¿{òäá¯íA×ùóo_z}ì[löò[ß±ÿp`÷­—WÜÚóêG/†ÏµØûþÔ½ðÝèóퟔþù»Ï]Wîþàðè+ßï÷N7ãÏà ί÷Ì÷Ÿ8óæ™-W·ûoI),d~ûÌç/_ÒTsgã¿ÞØuõˆh¤ìS}™™R£w¦ý‰UBw}kOp×鹿<ç=ýÚø±,û¾krèÙ…—.ÞúúO¯üÑÌ´MMÄì7Íúmßzæø«ÿpý7úÆùßßÿäHþ³,¼yÅÛðâɯþ¬ÇõÚ/½s)øß¦Óoüõ“g÷ Úøî ïµþÊè _:øÂÞÿægØèWÏÿ^(ì8í%RÏ8­é0H?Õ“ [¨Nú&Fõ­qÛ6ÉÚŸ-™v导ÎM3—v·•.¸o?ÿÎÝ_úðßC'ff’CÅIð)NGH@Q¶áE}–átøF!6?ËxòÅl¡œÓsÌ£oƒi¾\Ž{‡vdƇv¥f™e]¡pW¨7Ü Gºz£±Å þ ɱÌÐîÁ‘Y¦v*oËál¬w²;ûÐ=2>JÝ5{ÂÑD(2ã°¥/곌;ÚÑÓ%6ÎÎÏéÓ5Àÿ7¯aMÔVja‡ºe”ͬ>ËtuNszg>O&ó¶Ý9¡YÓF§óáÔi™ÙÎ'¾F;às†‰OX6iìÿPK’KA)aû««Ìrebar_reltool.beamY tWvžÑHÖXöØ# Œ=X"†Û²%ÀÂü<[–„ÁØÛ$À‚,iƶ°¤ÑIŸ¦Ccv» ’͆ YØ&g“ÍÒæ@šMIÂÉÏI³Iv7-IÉ.IvósÒ&4iÚMÒÞ;›!»ÝÖç*ÇÇ"ãÙ´9®H²5™ˆáÊ’ÂÊ¢hLQs,zIGS2‹f5£<£*q9›èæá®z8ø)üH"=¬Xa<›PÒ%uNNi}&·Ûv (²€XYÍe50R"ž+V•T$™Èæ¬9EûÔy'™$ЬÚU9«$ÇåÈxTMDcI9kÁiYë˜<1œHKVôß#Y†£É¬lÆKu´¸$[ !d´Å8s<šÌËÅù´$ÃbY*-ìVH› 'Œ$•X4iIɼLË)zÑfÒò3V˜ŸÍ'svð–¥&ƒh&“e ~ÌYàÓ=y/î]6CZ!ûh5çÔ¼lSr:W¢æÓ3ä–²œÍÈñRxE)ä\†}£\jÌ ón%‘¶"NÈ´M¤ªŒýE²†Å2¬¨q™MEÇ´ÞRxLEsMŒÅR>•Ñ\%01KFM¤seÈ_K¤£ê„mš€˜q‡ry¯ÏÃN9(,3aIávª ,«V0QJIŽåGØ™¼ÚgŒÈžDRŠGU©(®Êð 8GßìÌ NJÉ"ÐæHnÔ¼'ª¦‹Y-Òx&‚ÂGq¹¨9“*Wæ!æL2 K%ƒÇ¤Y|'' 'UR6»‘öX~-¨ÂsNdK°;ØÞì/Ÿ‘ûh4-%eµ$¥Hù™¹È¼á¹ªá´4ù†óéOCmÃH¦©¥!wíò45Ãøœ£va¨°,ç–¢J÷@=â©ÂÖ¦84Í›*êDZ,#"\„ñ™©×ˆ‹±»¬âˆ“)f‘«Yk^N|q9‰ƒ±;ì.»ÏìáêiÏ:³?Ȭ4¬»?\#ÓÄ=Èì« Ý[““„)f¬ ó ËBÍZ™õ =iªøD¤•R€PQž³Sô S…éÓ³ÝV¾ÏÊÃJVf(ú)¯¤èWJ)ŠÄ`|Òý;&ì!&„ ʇ(ú²•?QÿÖÀÀPaà ÙÇTPÍ[¶jžfíe^£§¾¬üi?ç`VAƒy3±Õ@ßS„Æ*¾Â_áC¢¶- ;‚‚I‰Î°­.l:…‚í 3`3v³•¿L\p9‡0ðp…˜è!vÆK쵟0Äë²zX»Ÿ«€-«œ |²’œÄi¶RlaœàŒ8¼ÄÌX׿¡Ù ˜ÃØ–‘ð¤@€j[Ãz<Ð/hDÂxáÉ,³•l£H³sÊ<"Kl +˜ynFmkô.G¡Ëúh¶£tÂ$S M².âõg'F4u"|€´i=jªö°7ÞbáY7#ÜbY7ød@]Á‰›º´M« C¸#Í@±xÃ]šžç v× šN'вãÐÐ ÑlgàCʽxóCÑ ýdj@cÐ÷‡ öYÞ‚ÿ'o 7Ø)¨ñv¦j8g‚¦lF SŽY9\—ZMo˜qÇõ‡ò2lÚÆp=p–qaáÖÓlX«z84»1_Òi‘Àò†oÂwUÜðqƒ’mq~òD¨ÎUÎÕTøˆñlmøæŠŽ9YXUzè´AèȺ Ïý¤DŽäÈÔþÿ·ÜA/9_`&Ö±0»P mRÀKöÏ äNØF”»COÛÆ?‘6‡–¶LÛ!šÝXHÛÌÁØ~Ç1}µ‚=gß?-fþ—ÂI鿇ú´÷¤áp $2áÃaÊÚ&· /]0{°„öb™ëƒ277éæRnQ[“ŸÛ ·An€‚^DEÖ=zÑÜ‚NúÁÉn8¥GÀb,‚tøj‡tj°ár¯Wø¡BÙ‡xƒfx[sh@˜­ÓOa F'ÞÖ´k^‚Éf?7ж¡m5\”¬Sñ„~è€[1Ô›`n“›IÓó-4» {àþØŽÉN‘…{kt¦aù·0§! p‘Ÿ(Ô«i^Dd€>än·…Íð¶)8˜ ¶Ù KàqW+7Ä”zÄvƒ *€Á÷­tM‹<¾a 73… 'R±@7ì>äãvb’¢à2Ï18…CõçÔüÒÑ•ÊÀ§)¦Í Öm‹nA³êv ´R}œƒVf˜o×í h‚Ávèöhsu{´*h&hó¡-0øY¨Ûè¿Ö`‹ú|´Åz?Ú7èv=´%úœ¥ÐnÔýá^ný{V4>§š×às†´WèóWBkÕý£ÏÕº½Ú:}-bk×mä*`ˆ¥ÓÀaPïÃxÃúüõ˜}îÕm°7év/´>=7¸×fÜ-öúo2Ìÿ–nã¾; \í2ä4b˜5ä1¦Ï‡ï®ÚwU³îsÔà?¡Ïƒ¶Û€9eÈ#Ú¦à^ÔE¨‚Î’úøvÝÆ¿›©Â÷cô‡º+×íbýSk¡|z@Ï>gô8bºÊêùê>øHëý3ñÓ¦ØÑÖîDõ?0Ïï½7ß¿³×ÑìX8ÀWN…ÄõÓw~ïžeÏÜ^»ù/Ë/<\|ð êíï6Ÿjû·Æ»{ÚÎB¾xô«w~0>|1èy=™þøÜ{—²ënè:\ßuxuuÍâO¿Ü~¯£îÓ}GNÿÓņùŽÇì÷.¨ÙõÎ Òü»ôãOUT_=pÿù¯/ln‰øäÙE_u‡žµÿrá³å¾-u)Ç¿þÉ/^¸;}¸Þýí£¿°…¯öõ½|xÉ]ÿxìhèÈÊ_Ù]g>í¾ÿ?mÓM½Ÿ>þÄÏ~ðdÏÊ·.ÝöèW‘ñw»Šß]½sò\xðƒ÷¿œ{þÖN}ôêSÎ*·•6ì}ì;ÏÕ<áŽßV~øØûá{þzÝËŽmxiÑOmòž|âoýE9uî‰ýüÿrU6ÿnñ©û7…6¬ª-Þ.î}ò§ÛÂ=Œ<ï{>º|l[xç˜ú|jÅgs>ÿéÙïž·|Ñå1vùËÏGŠÞñÆï·gøÍ]ÊieòÍK¯>×ÝõíÊq×Å×¾³ÀE?¾zËëÂö›ßµ»øãÛ«Ú>w4½×qÇÈÙú[^ Ü[~ßщ_?¯¸óàgÏ^œü›²“‚ñãïUWoüùß?´ZšeË;^QìG;Šïê½m[U×ó¯¿Úê8úðÜ[ëê¹ß$³Þý`æ·å‡V|i—Ï[…ªº/ì—6žlÙõÛ¶ã¡«w¬~S9sß?ÿühæ‘å/Xo=õvÕ£«×›VÞùýÿê岃¬Í?½kùg¦ÓÜôÌ•fïKîÊÁïÉ®¦;NÉ›¿ý£ÚøöÎÜ#\D\´¥Ù×áñîÖÐê?Q_ãÊFö™s‰”ÊE«£Íô¬’WãòåiURr“”‰ªÃ‰\®)ÍŽ*MÚÏÕMY5ÞtÝÿJ4Êj“ÜËâÝLýPK’KA¤aE" ürebar_require_vsn.beameT_ˆEžÙI²¹¤½ÛüñDak´ÁËæçr0¹»4Mïš‹w±´¾$›ÝI²ù³›Îî=ñ¡*úàÓqT¤(T,'µˆÒ¾ôI‚/>HŸ¥Èi|ñEuf³)-|üf~ß7óýfvvNoneü¹R,œ+8ÖðÃ\Œ’¦Jë”\r Jê;¶)jÖ`hôI¸¦áLk¢õê;„Ú†eÚÒDH¨csõ±ñ|Í2[Fµ‰#úÒ¡}ÕlGí]Û!ƒºa¶,D]38P­#š–ƒ:iºí©ñ2}«¢ã‘ë};¨6-êÌL|-gÈm£ÍLNq‚ù…E†‡Ñž.UQXÆ2üú,‚ß ñÈ,€?â8ªHUø;J0,a”à)¹¶ZãV y¼À 2„üˆ¦" !ÊpÌÏKþó~œ!Á øú9_?é ÅËÞúüf}^òû¼Mûk ¾F˜`ÃpøÜk _þXk48ú¥:¹ü¢¼~kI<“m)Êá©S³W¯Î|¦þüà׃¹W~Ë¿™XßÏmm'ßߊ®çÞºù²pâ›ù¼8ºö×îùˆ;ŠÜÝÁûÑ›÷“7ïKŸ|ö£ý믱÷aýÓ½h6¬n¼Ú}£¬ÝX¨Þxù½â?' ®TºÍK/ÜZ>‰„Î|µvJpý6+lÃÒjþ~ _?¡‚ãPŸ§Ï3Aˆ]mo`J ôíwO_ý{ÖÎ\®Ý†Énwµl¶÷œ§p½h þ[ò„¨ƒã„R‹Ömw0Pé.„,×Ñ ÚÒ4LžFˆ†©õ]è`Ê5uÒ2L¢wãtDV^+o¬ÕkåsŘÉ*™¬²˜Y¨grÙÅüÒD>¿º]/WNoö@´m8rF[Zl-héÍZÕ§C[™üŠ’ëzÕúOCóó/Íçy.àÒ 5Yý?¨aUR«O©¯tÛr©Fz ŸîX’Ö‡*mŽ“nªvÇJ{ODÚ¦Zú/Ø<{zºìD MÛá—ç?PK’KA×G 0rebar_subdirs.beam]UMlEžõl²›u6™xÝ8 -ÝÔ†Vª¯Ó&­‚6N7UÚ˜$åVܵwmo¼Þ5»ë¤=Q! D…è-‡PN ¨Á¥Tê •ŸPÄ*U‚ ª8UHHÀ›Í¦ µôÙ3ïûæ›÷ÞŒ<³ ‹„¸#¹üôÙißi"Ę¡”èeÍ-yí²nºžÐr–ëT Ï‹nmß´<®fø¥ÊšÎƒ¬DuÝÛdű«f­‹²–SÑ,~Í´ôŠæê\Õ´ Ë,w®¥Ù5¾©5ŒRµmwX¦ç{\ÕÒü¦Öv\\#jz%¯a¶¨;ë»m££ªYžÁ®i®Ýµ-³œpUk•zÄi•ºQiá´xº¡­5 vÅ1í^×ðkÕ(y—›–i7XÊ‚¦—è4Útô¶e”L»êôÒä÷Ìã#»¦éÌä<¢ŒôØõ%0‡pÂɹ$Ï%å Ãð=#RSPûÍIPã”gx‰(hVÆ¡¯bøø¤˜ïÄ®·"&¤“’˜  ÷ }b?Ãï;*&’q¢¢<Áù††+’*$1¯!ß~JT8ª€OR¾¸‡«~S$†€ S2ÃNˆC¸[–§1Ô(a5¹ÓZXÊJôj$ã„Ç$“<‹1í7?”°„áb-ùî2½hsÍý}Ð  ÞÁNzÿ˜ˆ†cª@ À$@|f_¨ †cz§÷‡zêùìSãLãùKAnGBÏ¡–„cîÙÁlÛ^Þã0\ µæpÏ›>Õlî_Ú¼öv¦çŽBØwNËÃ/—®/=û`}}“¿8\Œü­å&~Ü:ýðùƒ¿Ÿš^øäó¡{‘ÛèÖ—Tœ»dNŽ2=Ç¿Ž½9µµö÷¸ô8öáûwÎüqí~þ‡cßúw¦.ÿòè³ sÑ¥Õ‰ùú…Õ «ÿª½ºùð-#W¾9üœ¥Ü{¨îW¢ßoýóâßÝújèÜ¿+Ñ×Ðè£S×ç Í1žE*¬o𩚆Â:é¹$Âq×´ï»´g¯[4Rè¯zv0± *¯_½•Ÿªýôëèæ[ú§Ó++3sv¸á@ÏR=ç´|Ó±=àt$_ð4›š{™ :¶Å ÄeÓ¦Æl δ+V[7tÔÕ¶u£jÚ†^ÇÀé:rççæO•–çÎæ¨wLÉŒ)™c¥ÌøØDvrGÄ¿<³Tš;7»Ð@ÑšéË™ÊäDõXå ½°\ éÎÅL6§Œ¯Ù®®é6PGvôøh–ÆXßlõÎ2äÿ³ÆkDµýZ&HÝsÚnÅh %]wšFZoinÕôýtYóêN:xLÒž[Iÿïå…—jº1]ö|z‘þPK’KAÇP@u_rebar_templater.beamY t×™žÑ[ƒì #0l/ì¿ è–ÈXšFlÅ—Fßá_ƒ Ù.Ø$ÐIa€„+Dz¸l pVi„8L³i@ì«vœ¿1…àHg`LôdÍLVé¼D$?2MÜýÌݰ KÀmº¤ýç¾1N§L<ˆ:<+{õ;p‚Y~aŒyD¶·0öÀqp‚“:8j‰S%¨™xdbi¸yx]/J«/ÚWÀW‘¥È6GáE¹OEMH­õb‡Ú¤øT®Ù§JíuØÑ^¨u’vj:ivZ§UzR–B1}¢‚-ɪ]ɺ(ì‘x8Q> yqªÁnˆ’X ú惾i…’bÖÀ¾–^•­ä \a¯×ÌWAQY·À¶…/N‡Âè1 À µË´ÒÂbu`ÕD»Ï€@ÏÈMÃò(Í\›¼"3ƒÚ>„VÃKI!Ç™òjÌÌÁ¥4uh‰ðwG)-,qð×À[™-O”AV¾„wò¢³˜-Ÿ¬ÐŠSiqD¨It@ùQ@,¢/SaV–­ŠXLáÓ1|A˜² _2‹[f¦(Rž„ y6hh€§:†Ó¶$ Ôi5«^tš"Á¼bàœ;–‚—çÖãù,ªs ªsT¥¬k†3 N•I­ƒ 'à˜Vç!AÒ¸å xÎ"rç5'<—ðâ|žƒ$Eñ˦ŠÑ:¥“+@Ý2P·@Ãh ÂPR.\i›…òbådIÉ:Ìl ´_´W`DÉ•%RQ‘ZrÔm·LÈ8J©Ù.È*ÐO@¿»W3s50W»‘ÄÖš ¥N"«¤]&ÍˆÔ ¹éê†Ó$M£†ÛŠ*®öà–³5’&-WdºÂfjAa(ôÔãE¨PSšrRwB+âôlíÓÌü+Õáu‹<¸–I[ ÒÊ`ª®×#ÊýÍ‚ò5ÜÀ‹õ‹ðbTÈIà‰ãKy°QöÒ}/6LV4h²„W!ýgzq3ZŠpó4¢à%^Ê‹Knx®Y¶-'¶€ î#•Ê+–Ž­ûRkò¬ðbŸºTÅ>*¤QÃËx±\‰*±Ù`(‰%°sÿÊ,@à}´—â[G1¤Ê­’¦0ÊE ˜IhøÁï’XêÅMӦܘ6É£’ýס҄ËÚšh|}«T^l¦=«L^&û ‰f¨Ñæi2gAZ-ÄËqZ%^'/.‡¶ +e•x5­ÄìZ@°µÑSÄca]^¼…ž£x/n^˜Nxqt`»“ SDÅ‹Wô5¹Ð×ä_z|‰3h߬„E4jÖÑ*˜ž‰ÌájjÓjÎZ0g=кz܉Nyq(¼4ŒCÔï­nçÅV_˜ò…¥Ã -¢K6;n³mÀëy±¤P>´t^\_ØÎmPR"“È´³VMTIuìåÔ^¼ðë¹øõü)ÅßÏ‹`g-ñ@7“HàvÒa#°Ü>†ÍVNŽã;nkǶ¼©o†°Õ¶oçÅ.Üw†‚<,““@$rPÎöâ"ìCˆüiå,Šr/n\ˆ;Ñh#ÖyqSáÈš ÝAš¤â"wT„œL“ÃÃà• Ó6\Þ+àÛ@J™œ½у—¤éŠ3*TâØí©%-*q6“(èv1íáÅÛvÔ_i@3l"Q(XØL 凅 õ›Ê™^âÄrZÍÙcÝ3~–ÂiF‚†ý^¼e"'À·jÛÚˆoçÅ- ñÌê­ÿ?µ7ëÛö×õñâí´0Òàðxü^Éú°ÍL^¼cbÇvù“%§!ˆF~Žÿo‘/g‘2ŧ(p„p§²´wæêÕI¯‰)Á¦wHqöØ%’_´4Ó‹]ÇØM *³Ëƒ×Bÿíôàp;»`‹a¸ OKàÖϹì”W©D¸«ÙŠ‘¨iП#}Pâ:­ón¨ó;`¦‡¡u’8{é ôü(L*â|^Ü“A˜ì«Ç1„Al’vÔΡݧbüJuS½Ê˜1ÞAÏ’8ˆˆD=N¢B $p¤ã„Ô–=Âf@ Û“ôà8Ý¿l]°gg=NC’U/NÉ @ðƒFóÉÜúÇ/,séýŽ™•Ø@¶HöÚ vŽ)på(0¨a zh ò3{_J{p?Õš­:ôÈB…Ðäo­c5Çää—È<8vg74ýÝÀ¯ƒðÚp÷Ôã;ܽw/ÀÕ(\Á'Ã导ÙÀUL5o6R'¸Ê¢úªêGª ç10Ìc¿Ÿâ·7 q/ÞéÁƒHF\{Úè ?ôVÆûáiaX $åY€èÜ$6¶°ñö;ÉlìšÊ~?Nº…ñS™¥l< ¨ ˆgüJθ1åã‡?ýðÙ]ïðkwŸ=v,ùî±Ë_Mº}ëÒüCG±ç·¦n©ºï=oIÝ•Ç.]uJx¥y÷GñOÎŽ<ïºÏky±ôòƒ çÆ•m~°þ£ë·žìÝW¡Um_X×PÞw ¡ë®ÄpëS§ÃéMsÔE^¼óªÒÃòÖ-G§¾ñý‡Žn˜r­fúk¥¸:¼äëO.~c$qmÙŸ¦?µ²ñ£—ª^}á\ëÿlkZ}ß{ÂÚæ¾þÇ·?üñÕ{^xéÂ÷ïo|¥òšç¿s}ý¢ÃwjãÛî‘ÖÉ5ßy¨ìÅTýcU—W}–wíÔ7ÿiÇåÀO>Ÿtç=çßi<ñ£¯ ºÀ¹ÔwíÕ¿Í_Ž_<²é‰¼Ô;kÞö[^Øðóìym¤òU'½§?Åwò“ž*¿û‘ç6\¼jàӯܱñw=øÐqÏ¿^på쟆>÷«§Olso=ˆŸ9»ÿéMÿíû¡ýœ£îöÿy×öâC«+6µml_~tàê.í3ôüðõÎí_qÆ3ü¤oæ}½/—¿vWÍPõ«·T ÿ‡ïýßG{¯øÝ}‘3e­k¦U¹Ûþ¹r á깞»ïùmäÅ_q–†ï)þ³¿íç§üGñõëÅeÇ>äÎEþ§k_Ø<<ïÛZ_ï{OŸ~Êzè“¿=¹â¹¯®kºøÝƒ£¿MëBñŸüËsÎS¿ø›oTµå?w×ÈÛúéäÚŠŽï½ýí­÷ÿøÒgåÁ\jßs¼ÊYñ³ÌüÝ¢¡ë³v|ŽV¼ÿÙ½oÎ}©ä¡Ofîýø»«´jË‹;_¾ÿBÆýÓ)óÿaïñ‘Äæ¿Çoñ±òoLÞòË'^YwàÃêo6(ÂàK¿<{èüò=wöñ÷öŸ~ö— ~fiâbÁcG¯•ìz°ÿÍG7ýºò­¦kkË>ø’}ä7ó“¯nzëì0y2Lsÿ}V7=,·÷|¡rs¿‹ñì ±q(ÈÆ}@ëY­­c}±^TÆÆ ÜþKûH«=Zƒ„Ý@ËØ˜öÕ¥l<—í§•í¡Ú·kؘʮfã …l<½)6hߊQí½–‡R ó%!qï½{ù »c3‰ÊÆ¿þû×WïØÑ¼2~àU“_ üÖd:šL¤è„5ÂaóßÁT&ƒ”!?™IG¢F'è]Ñá£}œ5šÇ2=ÂÝøÇB/‚µH„³ù6®\ÓìX¹ÖßÇM©Ñªk´úêÅÁêÚšzwŒIÜÔÜ\¹nykWÐM+Õao}÷âðørkG[ÎßPíñiµ;L´ôOÝ·ËóTÕUy蜎ÆõÞ|ˆ£õßBbH áPI¨Ú„žJfŒ°ÞÇÕ¸{“qÝéÝÑtÚÝJõ&Ýæ_¬Ý)#ìþÂwªt#¶ƒkêJ¥©“ÿPK’KA£ž’õ~ Ôrebar_upgrade.beamuX pÅ>iOÖY¶â“O¶c;qξKH¬8:[ DŽ/¶dŇ›>‰|–ζbY§9ò˜–óÎ I ÒLC(ZÒ”¶¤%0ÂÐBCÆ!ÊÐ’N å5¥ÿžÖö%4ókÿýÿ¿ý_»wRǪë)ªôD[d銥†6LQö÷)ŠºÆ­«}ŠËet%¡²jZÕCm ‚’¼ZWS±œ‘Le‹Rš’ˆÅµtr l@5b†¢ã!£èjÚˆ%’ú4‹¦•¦VW×'µ\ã¨JVscéO¦Ô´2¬Òë´dº@ÕSJzÀîóÑq-¡2yPcЮ 1YÂÓ†žS]z.‹ªñ¡¬#¤’}É,Þªˆ„‚ýtet-“7›Ž¡`cCÓR“$Óýš—(.Ú[ZP‹¿Å{æ24ÞüÉlb6$S‰¸¢'©dÖÈ(™ŒšN¸”DÂô,«c·²›²x—,3Á¸†•!ãç2U×5Ý¡ôiºáH¨}¹Â¼¿)m™¦Ù¸žÌŒÉC]}šfİÙ¼ ´kYÚØ”Q’é@Sq~Ù¦áT2=äÄÅ7$œY2BR1ŒSÝhèJÜ(H@¤†Jkà<ßñ”–UíI­ _ӇÇD¤s'LU%>ÕÖÖ›»Æ ]UY2WR©¼S…øÛÌÛ4XˆMN Ô´ ‘—b×L©£_IeÕ¢a-‘#v%Øc˼ªáÒ-üM ý¹tƒÔP^¨qCÓ71¸Ø)'ăGOqÜßHŒ©vh"Š*T ÇY*ÿ‚3@M³±öÒ:ÞÆOëåe9YJF=N–•QXî)/£ “’X™ ; sÈv²²ÜÃÍ_Zˆš"‰åÙ6DyÛ+´!> ² F cN“ï’í¤zeÔ-‹‚È^N¦Ûa¹»Ç㥻~æ[ˆÆe„ˆæ#‡9lDž -¹Ùü<às¾…Üx^ë=al-¹Ë`ébiÖ]i¢ÀŒ¥œl&.VG¥g“–!›l/uyx[—hØŒr ¸é± r”âœÒVŸŠW„!ê]!5«ù=!¦ a ¤ç! y@8U²ŒD"^¡¿ '8^œ6€ ô\¤Â[ÐEŽC=’1;‰ÂpO^ÈsøIñ˜—΋%n„í²˜‹D.sqBÌÊT‡„¢Þh8J—vq¶^ÈF²QÕeÛR,Cm‚2'ÊÑ.\+9@Ëí^¨ÄG¡H´q‘ƒÄJfÔ‚i ; 4¶$½ͤ`•4§C£¨y”Tn”gy*ânA/˜9Ùó8y#bt+²h€HD½np/x AiÈãE㸶[!š]M-oÛïfy#pvNŽî Èœà”™ÒÐÔ|IùLó‚ïçY^ŠØj?bx†cm‡äè!§Î59%Æ ëqNž) DÍ'-ëOZבõcrôôeÖã<0塳¨ù¬á¬áÕF ‡žÙbÖzRó½H§CÔ ”ï#7”‡¬˜‚¼°âûGXþ{é(3 B§™Mjbz§4VÌ–µÀR—…ÅýÉpРŒŠXE,+î’<´Ç+sAHl%9®Zó†ôB9ªBî À¨˜¼Ÿ»Ü“%¨%{#‰†–±+PÊj°0Ë_EúuF^@cåL“Ï×¹€Ë'œ+‡:ã ƒ¸Ðù 'EJ.BÉEËMDCO/⣊c·ømúlcʧÚ,£è Ž@ßñLÍåãÃæíÍwªÄÌ"AõšçADS"s?–á'‚‘ØÉ$à †ÆGŠ™‰ÏT-kc*pò§Còär<ÈÌTsñQíÂq\î*óN¤ârJœ§Y–<]ªÇ%âIkNÞ¥"‡G ào3ž©3+ Ï/(\UþNcª°ÛÕàv ¸=?aŽ+ƒ xw™ š%¼©)†4G°2ÍAÀu`< T­0òÅø!'Bnr.Lå\r ÜbÎ-TÈ.Ñ];1µ>· ¸–N<=1äa‘h-”h6"~”ŒG…¨‹5=­³ŠÚñ}Åæ·ˆC˜ Þ„)3G.E+Yf¶¹KÀ¿¹¸y@È3slÌ<v@<õ%¬ÌC¨B„H!/|Èݾ4L\ ùw Ÿ»¹ç Í@§Û µ <´Þ|äjõ¹}W;|s®hþ \1a‰ÖËBþÃ]Ã2sÁ3_ž ì|(M-žÌƒIhxz LüÅ›?_)¼c x¡ê6ôü‚Õ9œÑö-°õ@XEÙï°ðÞIÞÏ B"wÙŠÜÄó%Ħˆ#¼¨Œàa*·àWŒ9ÝÂW¾há1æL²¶háñ¾<áë€Þw6Y{Ð\²'¶™Gäu${Í'8 @ H\X.Yl-ò&b ZlZäW9æ¯">`~± 5×Õ™Ø`¾Í’ÿÈ%ü„ý2‹}§ÅFÄ|d#îÉ<„‰~.áñgÁ2©#—î±Äu ±÷[ªàµYïÂÐAôõDoslzݵYݸöW7?¶å˜ßùÔGcŠã‰þ£‡—•J­¨yëݧ׋_d7þÃ÷ÉGNìþíS·ÔÛ7ÿúèêëË^yñ³WŒ¾:»aslHÕ·?º÷¥Og—¯Ý¼cùÏ»Ÿ9ðæÿ®¾çì_w‰ËFÏün[ÓɺYwÝzàÖOn½ðä±Ñs׌QwžY¸Vl‘~áùzõãÛÏľ ÿ]ÿìg3P…Ïú¯Þ·ÿÄ…#ì£5‰¶ñÖô¾ðÌŽÏGk¶·V·J¸ —kqÜGø7^Ñ%}díV"Çgy‰å<´9¾¾’šºÇðÝâ#<þ=YKÖ⽪¨ü݆ï/‘;–†Žûþ¶F´'(´>›6'i–jÊ8åÇrieóý§ö„ÿW¿n]{gºtµ¦=íZÆHjé,8”Ûüÿ –Í +ú&lP å øñ;DÑj_2%¶äåL¦ã©\BMP…¹tBíO¦ÕÄ ]"A¹Ú®ï\Žõt®ˆ Q%MRc“´¨ñÊXc iQ04aÄü ½;Ö¹²cÕU44øÆxhQÿ•ñIõªž.¢.¸®1Ø&Ö™Þ®Wõ,¸;D9‚ ®ZÄ2ÚH«ƒ}àÿ £°Š[™¡4š®gµœW‡(É?¨ «þDFÑû“†áïS²ƒšßücÄŸÕãþ‹þZ ê©u¥}Yß ÿPK’KA+xVÌt!rebar_utils.beamŒX |Uš¯êê¤+T¨¤h C5 4‘&„%•4V.A;}T:ú¢»:  r‰f”[@Žêeº¬èᜠQj³"y› &t{2hÄúò(Å0îÑëe¨@|d+=fŠ ±eô>=ƒœgAa¬ˆ#"–‰‘bD¡Â=ð§ãÁ°në g}Ùä¨|ò€ÂAØt#[O¥VçÒNBOűdVÏ%L"0Ý–K®F\“B8)§’á aíMŒŨO õ̇¿XO¦  <K3kÏQ&í1ŠÈ§t5#¢§3:”è‘@4ž ã%¹dDGôHYÞ=éŽEíÄœçPÎ’#½fLL$\­þª³¹(÷f陘}d«8¡'B¨>ìYb©²ˆ®…@O0nXéÃŽ£…r±8*Òj¬MëET@™¢l\×ÓòYVñ˜!†0¨ÆÊ(^´Ä ²cD061“JÄPD²Ùj=‘Ccèo”¿M02hm›9@út+ñgS¹LX/®ÔˆíKZz¢Bh3ʇ·bɾÔj½ærqÝœH£(”ëñõÿ«áižzd·~zýÿ½ï®/?SŠƒ:Ïÿ£®¡~T½iÓ™úsë¿•œ3{£ë¿™t¶áù®éßµñªêÇÖŸ]iÓ˜ÌØú³GÆ47Û²CYJmUýÈè<1¹>Û%ñ°ó7ì¸ëq)y¡‚ãFý¨Ìåÿ¸ˆ—-•8ÞQÆq6Žkš!Ìž!8ÚNidÕ5CiÓT¡’Sx÷¥¯Y*—È|G™,k‚ÕÊÑüœªY• «Í-»· ÍÂÖm³¾'Çwi‡„JYáÓÚù½qžÀï²T>ÉñÊœ•û¹&Ti/ 6ÙEš]& ÿ|%õUJE•ÍáÎ/E³ ¢Ãíà[*핪\æz¬¯h~S"f½®HÖ6 ‚(wÈüé^«ëÁ^íú@±Ÿ£Ù+‰£pÿݸª/ŸBUƒårÍ¡)NMh´reMö5Z<>Á£j~‡¢ÙG 6w—ìà|N (nPÎ%Šæ×Í)T8á£MN[eé1 ^ÚÇ Pesl¤s9±væÂJ (°×Axq6 V‡Ô³Ø«pjö `= ù;:¶[nw¨~»ÓßHÌ*¶Ž“<ÅØê–ÒM’"ÌœI[R”fERj4{µTÑ&Uòb˜T0©MU´*&ç;*5…+ÍO¹«„ó„jíZì–jxñ¢¸y±¦ÌíÖT«¦Ti‚3ÊiVUìÍÆi.ÈŸ¦Ê%M†Lg'aY­ù7*Ã0AÈŸe2Dæ@É·4™,O®Ñ†$×!i*/º4î*‹â9¼8¼õàmÁ±.DËD©_mœX£YM@9 ƒ2‡Œ†¡1¢,Žß4ð{¡ÛMÇGòKP¹8¾€ªÏuIÓÑýN¡Ò ÍÓ5ÿ.ôÄd踺Ðþšx:F|UHf•€&Öü§(}ä¿ÕÚŒ¸ÿ]̰Ó{~dÄ3Js;¨è¿ÒÓ(5Rèa¥[‡@_оÂtkcfñ6ö6º¤ÔåÒ jó*êFôÓLtZªÝ¡ø­èÈÁíq(}Sjµ>!Áè9Òû²ts“4u4»°«fSWÍFW-”fÙIM¼8Kv /œ˜8û§JEãðDpæm4Q««B‘CºUãÅÙf8ªÀ­øü¢¬`‰ã)Nó@ÑB[j¡4¶P›Isx±Y>ÅùJ’VÁWB-QÒ‡!õ‹‚âs*lYœ@“µÀë–B¯[Èës\Ü&]‹»¤ÕÞyfމ•…Žc: û{‰¬±Ó >§@œ 8Žaf”ŒƒƒY§vi¹BA9ODÕÌQ]E²{X€êÞÔŽ\·PÑãò°/Ç¢US=šýJµX“¼¼ØFT8à-Ó4š‰fk6¨ó]Ò\Á~¥FòI”©y Æ’Ól.4ª§qÐ-cB.…Qòâ\3)>h_ ííšÇ ›žâéR^ôµƒ/-ëèЄ¹šÒˆ£kö«ó½½BмVÍS…ª»@sbôyµF´L§6W)ê’VAî2È_­óF´.àÅùDÅî‚oj ü­ZB¾ ZÍ”.WËÜëëÁIni Ëš6‹‡$H\θ̛‚BjÆÍ “]Òb„ˆ;h RÓ..œLK‘†%”“N²‰ÅRù€Û§ZTŸ ª>EÍ °î«Ì”)¼xX#WËò·¿f×Í}Ÿ&¡Ë-­$ßV’oˇ$^N7·,N…Ä•˜<õ.i…àÏÑJ"Ô Žì®ÈO,xñª1ÒU¼¸’<»æz»xqUYW—¦6j^US²šG¡¬g­Óª©UfÏÕÞNªg¸fF ù{(™,Ê+]ø¦àÅ55Ò€Ð$õ#Pý…†~¼úU<¼n©ßÓì‘ú1Ï )cÏI9^Ì€Ë .¯£ÍËu¶yå0¸:›;M®>)kï— ^̺¤~ÅYgJbÌ0ž@´Âd«¢Hã cò‹c0஥ú±*àÿ6sÎ%õyùaµÂ ›fá›ü)‹ZÛH.úÎpi^ç Cfì’ó·“Ðîüöj¿ùûGKkxq` }®E¸`l]Yþ]lÞÓfIë…VAÁãf=j“.\ÞæÓPtc9¯q:š©õ¸ž×B͵ÈÛuù‡…ÐÈö¯ÇÖõØÚoâèF<ÿ¨£üâ¹æÏJ<ìoß$n{ !q~ñ4.i·b_Æ[Ü á\»1¶JÛì7JÛí7I;ìƒÒN^Ü+µÔrÛŒ#dñ„ì4ŸØ4v™óÓ/:òöw­Ë£»‡[wápëî3ßC%Ý*qfÔìI¿âSý⪖™MÒ^¸¸·ðá¼?ôp­S†ªìrßKÕtTÝŒÅíZ¥°HgñâDÁI廊UR«ãytˆÛ@¼Ö÷ßüðÏæÅ{±Ü‰å~lÝ|ðù­ƒX‡d‡Ã'˜®ßÒäõp“t?æÌýŠƒ­*›(G°{+ŽŽüH{Aú~±CJòâXÞ†åƒf½ä; \|;ÈKòUôVµZhX™4…Þ1V6Ì÷ð>Ò$CœŽ™qR'Ïðó„~3ÁÇGÁx'SÃ*t‰5Ó{W`·Ë lßí¡gÒ>œÿ±YÒ4a«€Ò²>S€ô‹Ò|3 y?l”~QŽë42Ké‡ûe‰4¾-/½€ÎÂ~Ósæox“Và^ÁøW ð*Æ30–Éž¨etÂÇ3þa|˜G-Ð3‘á&ŠS.æÛT@=ã¹0é'~7ÃgÐÿGø<‹ÙjÌdx3`6ã¡ó_Âp‚¦ŸôhÌî…²„·Øjcø\€ÉR ÛV 5`“%|~ÿ—øÐQpöÅgÑy&¿¤à\K ì.cû+WÄsUÏAF'ž£‡ âIüÝÜHÞu¦ŸbeqèÄ |[[àðÿD_W s}ÿºü:†S^62þÆ‚8Ó^Mž[ Î~ £ߎwî Ú滸|ýÝÌöïd8ýݸžÑ7®e8ù4Àt“¯F§øv1{KN¹]¸†Ë×é†ò½’Ñ/e8Ñ©&–3=TC~fËð2:Õq ó“ò6‡Ñ©†kö&Cô:n¤fÇs#}@½5™é¡¾<Ÿñ×0œø« bLÿ§WÉøËПƒgßÃsÂÒžKRœ)îàn¶7Äö9~âGO³¸ý8ÓÁÙ^¸™âv£?2¬S8o=õù­l}”Ë÷'¬y»åŒè3?0-¼ÿ†ÏÛýAv>Î’Ûü|íeôï³Øs\ïÓTË{ßa.?çx˾Çèÿ0w3þCÑôs`š†¯]Ìï€R“ÿôß;}?‹oÛý_ã{;£ß(!\øñ_(/ÛýnSÞ²øË¹ bÍááâc÷\·tååJkÕ8yײ‰=¡÷'¾~êmã¡íT*·?U:zÛ_Ú–m~©ïÃÿ¥Á“8øþOÿ´ó«ç´ŠÐûs>¼ç’?4¿sòW ÿ´ltøùóÇüÆóÄŠŸ}|ôñOWѾ—Úyßé–{­O½ÿÏW¾÷òèÛ}kä•‹g=qÏŸÞȾ¦i>ºâØaõ…ÃCwÙ~v¿Ârøªé[û_°>×»ÍöâO=sûçO–=Þ5ÿñÄé1oïyuì¹mŸøß}¼ëËßÝõ™–iI×í;¹ öFwüŽ’e'',n?®ßóirmvaók^=±õâWŸýò£ö“÷:SGm«Æ=·Òvzgè•Ò“[Êf¼3æ¡ ‡-;î{ƒOÌþbÀ1MÛ¿ýÅÏtõ½×ž[°/Z÷aøÊñãïMþöõUǯù¯)o²pôÇÍ[>éã^=ºêdfÇ¿{ºÑ˜úúnìÝøñ¸sǾ´ð/G¿zs[ãuýóm?šÙô{ÍÝáfÁ‚_×Þºèèe5ˤºGµ£«÷_²_Oìÿâ™}ï8±ü¥•Â#}Û›÷\}J«½åÊMð¹†{{ï{âÇíן˜ò‡/. jï0°ç·m¸vÖì×[þü–³®ÔÕù1?¥ôÉC“î¿ÿòFMkyõ—¡{×½µxå¼ë„@ïË¿~ÏÛ±oÑ܉Gv¼»ûÙ†Ï<ûV™pbË‘—×´<ñ¹zäDéE}møN ½<ëHû¼ÓÎÓñ­m'ŸüsëÖW½V¹°¶âµÍǯþù©™?ûã„Ô‡™IZ‚sbó÷ÿ¢îË7BCÕ-O]±¾áí]G^þ]ÑVþª,>¶¦±û½×M:æ}eMÉWñ^›?þŃÙE¹¢„×G'|k¼‰³¶<ùIí¸Åá½=Wßù»ÉíoÜñæGñƒ»ž}{ÑöeW¼¾sû­|¶÷® _™ñÄ‘«žØÑ·nÃO·”|ðÖÌåëgÌ[tÑe£ß”.­[Õ[½nÅ£ŸÇŸ~¾ÖúüOÊÁ¯KNüuÔOj?~§G,Þ_³á¯­ÿðßöÏk÷Ÿ|}ÿÀsó¾´=wþrLò©0Í7›?ûXý?vÖ¬(œ…3¡°ß {¼°¯ gEa_öraÿölaŸöæ÷˜,é¾ÑéÞØÀôodžd°†ñÇNwìjÆÓESˆÍ5º›—ÿÿÿ=;OÃ0…oÛÐPEÙ‘èÈ”4ièclHQ EPX#'vˆó°+۩Ć„Ä/ágõ—0á„Çp|¯Ï9ç †–§µÒjjMæJ =/Þsý6’&†ÖN²úÃú°ïß .¯byúÙðÞ–iêù,ÖÙyÝ7ª~‡oåLVFCÁE Ë¢@âµ*´y©0$¤¬r4ƒeQ^b‚á°d˜Ä”œ´t†1-žüÕU°ño¯38q†¶3œÚãÀ9SwöWê>{w³Îàø…ªͦñ8ú×›û߸ý`»‹á(­iwDH›ÁkNL·ò E ’´CÍ¿G]ÔG=t†ì]òRD$ÓJxA,¼E"¦JY!’ · ‘°¤ˆ~¶ T4—&y óP*}øPK’KA5îÀ¶ „rebar_xref.beam…Xkp×ÞÕ][ëµ/¬½Â&`Ì 06¶V–É`¸’…ÁcÙ<Ò òJZÙÂz8»+ˆÓÌ”–é”6 C›fšNò#3´i'móhË$“™¦™6üèLäWš–L†6M“þÉcRÚI'=wµ–·LB5suïž{ÎwÎùιWÑ£SA†‘ˆ'c1«ZfîÃ0w †žÕŒÌ}†^àè[“ii†å©.ˆ¦neJŬ¡K™EÍšÇt;sN3*ÅÊœÙTÐJ¦ÞV·ÎU+…âšÓ-¡hfÎêF¶jê^gæ—MZ)b^/hµ’…µ|>“/zΪK\®š×y0·µÖAkV±dz©0w.ÏŠ%½¢•uîLµXá©5Uå,£¦·ÚåæõÜ‚)ê÷-V ËÌTªV¦fêù¦RÑ´Ìæ²^ÎêÆÚZü+z>S¨UrV±ZÉä´RÉl³!î­éFQ7HxÓ †3­ê¢—¾-êùfÝ(i•¹&kÞ¨žë´=fnwèÕ*Zié~ ôÔU¾È«·P5t-7ßZW£î—Ø{=Åj3l”5«…ÒbG!Aú–nd´sÚR¦8W»|SÍǨ¬-z %ͲôŠg¡à]ЗÀU¾-_4K \.h¦P‡£ëæb•µÅ‘´6S+轤—õŠåuf.yrlº9«å5c®¥ýj LA2fµfäôÕ´6Õì¨aÆ.`V×ʽ97_«,˜XËš–¡9»« í\¦!9lb¶fé­-¿LMGƒ#Êh¡ î[ËÕ|­¤gŠ•BÕvêzÞ0p[Tà@)ç?­Â¬løâÌ¡&Ý0ªÆô†`Øð-øɘ­õ=ûDµdõyílâòô÷ßÉGæà£­ç³ªh'ßBÛ(«Aßw 4z% º ¼”[Z8—pÜzîÜ‘`[OhÇÿWtE5@“ 9¶LBa˜–oÂý"2õ×Ez×ÀXËŠžŽÍ2+¯""Aa²yE&z _Cr1Rÿ5)Î1x-AÝ“Åþk(N²1F^U&ÈïeTñIqTVR?O¡¤âAtù›”?© ©Ýo›’bê“·{™Yb‘jxåó^ñ2¸:‰Ð%‘”Øð"a-"’Ï+?©^E{ÐÕ.bì:“¬J„N42ÃŽy‡$H!>Ð]ˆò?ººÐYcgmݯ³‹R;{ž º%â¡^H(l;âæÂIíœW~ŽzõƒS¿W|¥¥ç5º”ÅY&é÷ d¡¤òôµûÛÃÄ@.ŸBçGÙË$Ž:ˆÄ>IR2âÅ„}îb_9ˆØ×<‚°7V‰ $W§çÃèM4|³NO‰JÿM)NĉxI©„ÇÉXnmâE΃:D‰ý€x¨¡°•aùvjý2î@Ã0VÀpÇ2Ú MT„D½2ßî‚ã;(žx½"Ëû¢X Ém²è pn×ïˆâNØít;è”âMáP?^ƒ qVM2t‚ÍÒE™!)±ñÐ@¨ƒkhI:dXuRÏ]àyd²2Yi –ö '5Éx⺠´`^·J†®õÍѲÍ‹xEÞGëÆ¡‹¢ŽÖ€ ³.ãa0ZÆA™å»ÛD™H i§¬zU¾+Š7@:=îtz$ø²‰ÙOÈ M=PC~# …IŽàM(†”PoT†a¨m„Ä1Wd?Ø@ ù ºQ¼\lF2˜e/6A~To%J”D 4Sj²Î'An¼LX~SoDÐQÂfÊ—!„!)+€¬ 3³ è8’CɧKR³r-œÉ[Àxoâ-`¼…0ÁXVèI®-º¶ÑnHºèÛÇáíPlßÏEqàô¹ì“„(ˆ–>EŽ+LD!a˜{êDöÙïýº"‚ú¡©mêr>†#¢×„ȯ‹b4T¤®øP%?I—€iˆsý²‚ìVˆƒbPë1@m¬&b‰t6Ò°‘–ãiÆŒ§Å  n Ä@|AŽ_`‰_¯€ø!ÆjV!®Ä® )Šà-@k²Ây©‰~„8¼+íð ™Í„O0~»¨J;G® NÅ»"xHR¢xP†1— JILÄ%9ÝCÂ0„LÓ>Q•QÊŸJt¨@Ýl Qeê2!i i{^ay•vIè…Ú ‘tDä»Y>D%@x˜ Êü–ß Âƒ*ËC8ÔFÔ ùíÞ•H;½O‰†Û§·ïF–HÑçíð죱Æ#WÏnÏ‹ªHe1É¡zÉw76›`š:Æ;iGGÁÿ´Öp 6UŽ!ÀÿPx¸Uñ>¸Vñ>z¯â=ÞËò{Gc¢Þ[º(‹=è.‡#a¥øûˆ0 W0ßÚûÁ×a €DpÜ¡>ÔÇ$µMT}®~O7N dÍ cùx杻 @”ô"Fá&ñ-2ö‡Õå¢Û^¡@ýI¡1 GL[­ÜOõ kcýš£ÅIú1àc4‚:÷K š8¥Èm*Ü/ŒúØOBü¨8+ŽªRŠKùà³W‚˜i'¤`¿6Yþ`'iÌc€:è‡"ø0jEHž#BZ!Â4Zë¡PDˆÍüá0£æã`>AMDðämEyYÅÇh•ŽÁ'.>…:ÊòGUšÞº«4áv0ÆãH”å¤ä¡~ŽÑžg'!ÖtOÁ1›Z9õô˜J6%Éây%ƒÃ"¦×]F‚Þ^—iwà4`¬™>áTü8˜—€MZqæ>úA¢øéUí&b+}ðÑ=xð7¾ÐÏÑÏ%ýx½QfXþDOÓlN‚ó»Áù)û|ñJ[Æ4ý"6V^„™½ ËM0<0è6묛œ™‡Ñâìѵà|£{Ø™éXåÌ«]ßõÚat8k †Ï¥³ÆñuŒuŽœ®7¸tz\ñltÖ4ÖÍ.¹ß™©|‹ g›+¶íÎܣߥ3èŠ!à’«.ù“ûN—-õqÅ9âèߥ“rÅœrɹ䓎ü8 ú;œMÞGëÂô:~Gݰ³fœ˜–sóŒÖ*TÜÑ¿ÛÑ?åè2M·þv¦“Ž<íÌ wÏ¢cGŸ8x 7\xz¼hQÌ÷akì¾'f&Gs±¶‡ÿò»¥Þ“ü¶7¸Ö„5Üãÿé:þ'l>òÓÝ/.ýköê÷ Ÿ½øÇG¥g[–ÆÞúòÇÍL'£nÜwãâNÿò+ë†ö îÝO¯âà6eÓãßyŒ|P|áôcã_zUßøjäzíï÷lïúíè©Ð¥à¯½ýú¿/½{¢ïå´<øÐæ[?ùÖ Ï~ûú£Ï|`ýêþÁî_?ÿTßü–›ÝÏW®n;úã÷oq}\ÙòfïŸ_zê©â—ßè=ýÖº7GR;{Î<[{¨öô÷>þÈxbû¾c{¯õï~|þÆïŸI_z]ÛóÑc=öÁûŸl˜nÿÑn}ÒôÙH×þM1½ Ȩæ¦zÖÜÆå)g=s—3o0¦9­ï1G>zLJ51æè Ã8èÔoŒ½ŽÎ»^gÊ·:ý@×´ÿCŽŽ #謻a 8:ë,úZë`Q¹ÏÁ¢/zVg½*?b©Þ…Õœ÷ät֬ؑ¹7µçá‘wÒzM?}ñ½÷ªgÎ$Æ*Øë±õ9ªï­.Ò߈&xó ¶\gÌZ¹¬KT¡¹Z³àwèÃéÙb…JØâã-Vr¥Z^Ï3+ÿ6Ì#ØËç!>36~ 3=6‘\`V©Á!5Ü• ††"áè²<‘ÎŒ=ºÀ´Î-9˜‹F »rí£Ó“ÎvóT0WCgìhÏê† á.0MáÁ݃a*ã¬bYŸoÎBüoj¼&jXëÖ‚vèõÿ˜À|µ¬ò‹šQ(ZV «™óÕ€ý§UÀ4r•Ôu£t†abYÓ¢ÿPK’KA¿…jjD–priv/templates/basicnif.c½U]o›0}çW\1©J[Ú½Fy¨:"EË҉ѾT•ei­;2&Ëøï³ÁHP³uRy0²}?Î=÷pù@yÌŠ„€K$Cœ¦Ÿž]ÇÉV4†@² MC’‹BÆ$*·Äƒý>IÁHU¡0øq{Þ°€ÍÝz=w¥M’B®d+gïT}ûgÌF´ÙlߥP˜ç‡dámVKá·¾'?' €ï< |çå °|Š}Î?±à¹†×¾»‡Çéü\î¬L +*øÿAø $CΗ:-èn “?x„…&Ó„Ø»šׇKÿˆ£Ê·÷fmvå—S9U/åû3ßVs,š·–1åcÆDŒ¤UàdD|ÿÂ÷äôéä$ÿTwÂÜ0ëôS-¤ ¿QMŠõm\k#IÁyÏn`"‰*$ï…SÅ–‘ÏM°î+‘5g®xq§¾¢ƒTÎÙæ½›tm+Oj:B_ƒ¶˜w‚&}¬-K(Ö¬ñb{‚Ø8x&a›mæÁM±"€y IÉqFc-–jÅ`EÈH&d©g‘zGù©ÚÀ›µÑ^Sâ©L¼©Æ27î]Q†UÁ8ÇïÁVÒJ°ÂþIãƒ(OE[Þpð.~Ê!­×ÅÁ3ŒÐM\GüîŸE×_ƒÛû œj&¸<`=ÒÙì³jtéÐèáácŒ4š+#$Enx]*Ô@5V¼vMÁHwâ`­±t<9¿Ì3úÃ?ñYœD:°Jè§QI¯m8jã"H–êeã‹«³ûIΔOf! ÀÊWAïòÛ; .U#+,hšPêÒ5Œ·ý©UýZbå󃺪åÚâÛZrLJQ)„ÑÜû¸D¯&S­û´²6ÏH!$×b‹ó·åêÄR¡‚<òøáK#ãûËéŠ.c;`Nçóká¦Û`– ;SW Ï5]1ÒZûÙÑ–¬È´SQxýñäÌ6ç†ÉýdéwîeÇéä2wËïãz,ãnüÃz1)¿jkÌÞ9þ»˜üÞïqP»ú¿P¿ol¯5–<0¬õ¶æ…/nág‘:9u Öå¯P4„lô"´"ýÐi±¿PK’KAý+¡R‡ priv/templates/basicnif.template«.K,ÊLLÊI-ÖQˆ®ÎÍO)ÍIÕQPÊ­„0•jckõ¸ªKRs rK@2I‰Å™Éy™iz©E9J@~qQ²~5Tcm-X—Ždúäx4É õPK’KAȪ8’‚priv/templates/ctsuite.erlÝXmoÛ6þî_qÀä¼ìc¶nhÓvйC’~ ¶N1‰ÔH*‹çê¿ïŽ”l)vìd±S`úbŠâï幇GïïÃXç¹V±CëÀ–Ò!¤ÚÀlƹNªª×Ðo™a¿5_~;¿útpØH5ÎÊãLŽú{-eGõ‡£±;œ˜lÖöô½¤  m\,²Œ§÷÷[xH |.ÕØI­Nƒ+ýü ç*Õô‘¿óÞÁµ+ ²âà†ç¾Hò]§p‡Ó£{‘•…ÆÖBÑŽ,‚Þ t¥Q²ZÆk²à4Xt`*ÊÌAatÆI´a‡ÖÃÑu 6[ µÃS¸j¦Ž!­=iA«l 9 åxŸBi1á¡ñư‚fãD8ÞÒd Ú1¡¦ i_l™`ÕÞÁ­D¾ì뙓9:#ŠfÇZ%dÉOÇUu³£Lß]¶Þýw~¹©£ê_(Ý3?Š£?牉ü¤}¯’+Bë™°h«¹¯%AátÞ?)ää(žæ¤ÓØoË„…N†V! Á3øNˆø«D5F^NÊ4Íx4»À…»š «ÁÒjhá SÎ6ÍH*Lçæu¬æMƒ<)÷VEs*škú­š—5Î ð\0¦U~ÇÆôw`NÔÃè1©jn1ÈYÀ—ŽP*¡ƒ6 š ‘„8-R9¼EÓ?ˆVŒ¼ÖE¬h½ñ/´{Ä¥r2c‰õݪÙTHÊÂRvשé*išeéŽcÁ%.I Rð2Õ™’‰sëI#•Þ£YG"bA#MÈ®¸ž¥’Û­ÒN¡ìª)ða‡e ¶«r Á‘ûT]—aÛªÍ'ð¾Bh-ÛsÁ7© a$BM¡`— & ÖŒÝÔC³‹†Náôáîþæu|0rád ŒtS&{ð@UÓ v[ÉkòÕcƒ®a ÊnRj91ÜPûãëÇo_>†v –t˜RÅÖ’Ÿ}L¿7øQq¿ |Ôìi*3GeуõyýYK}WL©È,þ¼IœŸþŒ<ú/b\n1Ñoì³èäåP%¯S7BΔϗiûºI†Lleö`W$ÐeÿL«TÞ{˜=.Oü¡r'‹è…ÕªjÞ‰‹“ØŠ{¬?Dõúª.¤Z7¡³Q´ÔÞ½Ÿ—î£/‚‰Î©n}}/ècì5•¡K: çïMª ÅCÓ„ÜÔ±µE£¬ÓÝu(åœi]dò¯¸Ï‰§;BjÿÚ­`jÐSŠHßÒ=òˆ?±ª ÖsO$"FtR褢Ë,á×+¢òåÈ`®ïѫŠÛÊêA¶vî¬DÜsÂ뎀Ø)É6á^ËÄÓ3WRþCÀµ„³ŒZ}êDJê"c+ê%~”}·kRðhÑ“Ã.ùaSÛÐMNh¾|óMÅ&FºôW.SØ:7¶æR¸h\^Ä8Ü.´znMl9ªêÀ;ªŸÉH(Æ“U-ÕV€ñ á§ÂÛRÃËÐø,Úx æ¸í·“úJñvxÛ@B;C7? s8²‹ìa¿¹7ì–œ6ÜNº8Ù1+m½Z³zéüŸ{¡'‘ö¶ì÷RÀ¯ç?žçÿMš:x Ìw@„Û€8»÷<„¯cЭsç àÄKãÖ_ù­ëÿŒÿkà"ºž%zí±¶ÆÛ–„+ú^uãÿÕ]Òø¸§ ä¸Gu 2§¤åTV”Ù½ê°÷/PK’KA}Oê­P_priv/templates/ctsuite.template«.K,ÊLLÊI-ÖQˆ®.I-.ÉÍOÑQPÊ­Ò¥9©Jµ±µz\@‰Ü‚œÄ’T LrIqifIª^jQŽ Ò¢_ ÓY[êâ –jPK’KAôävÞ priv/templates/simpleapp.app.srcmŽÁ „0 DïýŠà9,ì÷Ȳ¸6HØn-Mñüwk[P\s 3/ÌD‡CâÙ#¨fÉv]Ñ@oÔ’Œ‘C¥]·û ‹ìâÙT¤‰%Q$‹Ð¿ªw ,I×ùRôäð†H²Ž?ÿ EÿæÜ£Ç§ï¼KqÅä—¢L¾˜ PK’KA¤yE†\Ï!priv/templates/simpleapp.template«.K,ÊLLÊI-ÖQˆ®N,(ÈLÑQPÊ­²”jckõ¸ªKRs rKRÂÅ™@f*PJ„‹‹’•@‚EÉúÕµµp \:ãA R‹r0tÂ%pê,.Å¡&Ô PK’KAÀ­À‰œk priv/templates/simpleapp_app.erlÓÍÍO)ÍIÕ¨®N,(ÈL©­Òšz\\ºI©‰e™ù¥E@‘œÌäÄ’Ìü<Œªª‚#BD!91'')19»˜K7µ¢ ¿¨D#º¸$±¨DßHG¡¸$¿@ß0ªË–r€Ûr*™Ïv»F|0ˆ ©,HÕQ€°‹Ò‹5tí¸€ZÅ¥V`-ñ9™yÙ Ÿ‚< 6 $®!?[ PK’KA‡O³Ì priv/templates/simpleapp_sup.erl­RQKÃ0~ϯ¸—A ©ë|TÄ +LÔ§QJ–¦.,MJš¥ä¿{uÝêÃÞìA¸»/Ü÷}GâÊ­–´ëx]«"„¼iëèŠx+wü lë(¾HwPu}a6ƒ‡×”Äò«¶ÎÓMã¹ó¹Vf?O²¡áíŒÁµÞr±oF„2ÊÏ§Þ•ÔØ ÎB‰ˆB Í2Ÿ vJN°%ŒC¸¥2’>®Òõ’¦ Þ¿k1èÒã'b°ÉDVÜHã\'Ir`-ÍÂ0ÄíÿcÊÖ¯¬i¦ú—Œ|hñŒQŽ›?åN[Ô›ÁýóËòcýη^ˆi©^´x*Æý†PœøÄ¶³he‡ÉÈW$ÇŒV2X$á×bÈíPK’KAÛ"'»ŒÏpriv/templates/simplefsm.erlµS]kÂ0}÷Wäe¡Õ}ø´‡ Á Â6‡2_DBÖ^5˜ÞHE‘þ÷%ÚÙV»½ØZšÜsOϽ9× U°‘@‡yŠ Iš­†û K¾jÑ 3{À\ б7šx#‡¼¾{_ož‰4îîˆ{ó²,ÝÏéoÐ×B!ñvké¸"ö† G>:54“WíûY¥òÓfÕ_‚@¡Û1¥h`ÈCh?vOYr $0Øj³oß•â=úi´sF œ+›¬! ºB¦¯`¾. Ý©¶u…›ïY§ ûYYë²K§Mâ¾kJ¯ë9;HåsiÌ}ryr¶¹C¦3ûÔë— ·|”u£E|®û V9þ‡K–™æâ,i»–)ó¬U2¶GÂNŸðyÿ¥°?(X?RáSk¹wˆÕVJ”÷sQÍG,v‰ÊÑeSP*¯”:§ôf;J” Ìû™çA¤l_\_Eðö5Ÿp¿ÿãôüä"8©môA&Œ@ªd©t-ìpÉÖ“ZH æçú\ÔÁG¥JÉϯX¡0x)²R¸!~7>WBh=±BÛ4—Æjy³¶RQð)Œ¼Û*#øfèž½t“%™¨ª`ÀŠ@·ñÒ• ¼BÁšŽv÷-ÊÖ3B5‚ã®(]ìc_ŠéµÄ|“<44`δcšv…š/#øÄ:ïÌøï G'[!'%‰+WU}r-‡?ˆÿw6;òè xÚZÿ»‚ªÜYáZ”˜6È=I<Ï?ÜqC\¸ÜøÌÚnNûf•$mb¬j‚7®×wi×ëÙ¯®Ç=ËvÜSâ«Þe,Rz)s' ¡MKÔÄÃíƒó'³RÚ»™M¥Ú±N »d>vàáyT+f˜Z• «ê ãÕ9=?OÍú›­Ô2W«»§•ÌyÝp8"Ì:Ÿ17óy4’бÍ=¨eovgõšsk÷›ÂmŽ*gƒ]ÊFb‹Ñ°”¦>'–”åV1Œ™K·õ8 fÿ»×y`²÷øXë¶¾”?­™ßw[jÖ«>g¢_”± ¿Ü4N¬*‘Là´pš8m:¡X©éûiGã‘fîÃ$\æŒ3›· À¦v·w·´UÏãy´tÝšgB§ «LÂù42BþPK’KAì,?¯ˆÓ"priv/templates/simplenode.nodetoolÍWÝoÛ6Ï_qTZ宊=(Ȱ.ëÚ>t’ìÉ3F¢bÎ2)t“ÀIÿöÝ‘”õa9Ú«üAÝýîwwäÝñøf?Ì`­Jž×5“×'þk&dÉ¥Õü#¯3xyþ[vef^^Šš´ŽßfPÙS¯ Öœ¾sƒÜÒÛÙ×?CH [¥Ð[^7\ÃE¡Ec¡R„´\³Â dp#ìjñ‘; ´¿£52~¥¯M³Ÿµ‚S0–i›óf]ÆIê–Ñàë[KŒÀ.90TqëÛsn,¤p‰‹Üþ¢ÑªàÆä${ù"… ¾’—ˆÛ_p¢r¸ä ÅFkLP}z#%ý%!aŸ”²)Üð'u WLÔ§`†ÃVr›¯¸–˜å¥(1Çy¡¤ä…Í 9î(&),+×Yƒðý7 *éü³zÃSh”¼~hCÔ>juÒÉå(Ä&„„Ê0ŸkfãˆÐáSCôAsƒ˜%yfóìoa:&‹ûöY²ÚÆ/·Æeèo³Ð§>6ZŒaÄßU>¸V”LŒvÅtÚ…ŸÕš³ò.P4¼$†ÌqLÁ(øgc,”›u3FeQœ¢CþÓKô19éQ4V5û{JŸÝYÁ꺗©O‰À@~wýôŸd1°€nÐnþZ#æ1;WJ}3„òˆ•¦@„÷ªÜÔ¨óûFb‰Pîá¼)hì™wÛcÒ`-ŒÍ­Ê™UëØ#&£Õ´‡Ï¼5Ý2îoÂöÁ²2"Ö½9Ù[ß^±9§¸¯™QrïPMÄöüÏ3Ú§x¼*, ¼Ì vßg7>XíØ>Ÿüþ‘l<š£Œa)_›‰´¥@q{e.¬ÆÃõ?¤‹£Ù }ÉciüÞó«–þ$Z“N~ñH¾&{@î}çBÀK‰ÿeØ5 ¡ÓÖªè=¬ûPPîý‰ ÂØUvúÑëe¤'ÏŽŽ]•jÄ«¢èwÞ]ßÒf0™ÆG£X2èÐ'#¨hf¸-”Z Ž~¹TUä#Vüˆ”¡jîuc×fÇ{ÑÃ%!LÃd`Ÿdk"dðψ\¾ãt‰ÍuÚS`MƒÑt­?7›ª·qB”Óøcó(ÛªÑð2=&)ž·¨èv1bcŸñ‡Ì’`Ïf2á™ù~\3K¥í·ó «ÊÈ•í&Í ì ‚²‹ Œ{þ¨?¶Êóú¢LVà"½Éf—øúéSˆ`V2¾V²u^­¥/0^kk~ò7¡«ÂÚDe¥ÐÎ3nÜ4žù¯Ü­µ[Øeé"Òn CB8Ü–9¿åÅ/5}>:Sƒ²Z±µ¦Êþ¤É¢<‰2QŒÎÔ¦.ÝôIÐ@äŸ}ÚEiü¬¹ojuÅêר}Èf'q¸ÐNéï4P’¿ÛeÞõ íâc\¯Ê¬ZqiB£_¢A|æ¹ßÖù[…[pllP¡œ^×vã÷XcŽ3¾‡:Ù' Â"ÌPÏ'=lÓWhlÁ&gî©¢J°‘$½HLœvïò…ûó¡ñæ>˜)’ÞhJ{Ï~#è’8`þ¹@~‰…a@Âø ^Š%Þ;¼Ë€÷æ+!™¾£»¶=¼-ÒEšn/dnKñŽÃ܉ÏÂôãsBlÇ!„¸Y"´0>§n¥ r¢ö‹ë4«£Çí*žòN׳qkÊþínß”CÿZ±3%m°B-|gl¾¹)˜l3Ý“oÛRI7b$}SowÕö*‰b“Ã5‘KgÌ5“§ß‹aœ©ÝI—‹Ì}æÿØc¨;ýí¨Ò´ˆš¡7L¥-W’róØAfû3ÑÖ CøNVêQ/{r‡ËÜv­4§JÚûñîeùE ÎbÕmôPK’KA‘®?WÚÛ(priv/templates/simplenode.reltool.config•T[n¤0üŸSXH‘’1ÊöË»‡µbld{FËwO7 ày¡,î®*÷£Lç[Ÿ²ß;6}Ve!•£ØaH—0¸@¡®¶²ÖÈ”Ipê rHYÇ›¦8* )óÁ©fˆ‰·¹5ã@§,é:c%(9 ž>’%¿ÖÄØ8ƒè5àƒÄBã÷q~U]b‡»«}à.B7t÷]ýP¶´6wmE€ÆÙiP— %MoÉ)#ôe´ðWè“„xü)¸pä4Î㆒ì=ÁØË ûe™±]0¬eìfod»]‡.« Уºñ%íœæm[/ª¿&¸¶Õž:L4æ…m“™ühy—Ï´8{“ù0n’r[\ª&Xû\`l©\?b¢=ôÿ1µ¼'Ñ-é c—1ÿ:¸EW±Z§¦r\B^àO*ÌBÏÒ›µ>C?UE*ø7î1LÃÅÃ2Û¶¥v®3´ß”š1C$CÖûPK’KA·Ì£rÀ priv/templates/simplenode.runneríX[oÛ¸~ׯ`]µiÓÊNŠ}JáÝ&±“_`9-Цk+móDuD*N6ÎßRw«iÚE‹c ¶B g¾ΕOŸ´.YÐKã)±v-"KkÍ<¹<øå- <H –„µâ=˜D@Joˆí_ˆXÕ†1> ºã©}<î&ÓNoÜ6_¸1ïöžµvïÉóç$\{/3º£C»«©î¶v↔®;9Öd•}-*Ý”ælxZOãó`pI‰\Â_ä0Ÿ "|G, ˆ9ê4©‘>µ[r¶¶X¥²Îíî¸m×¾sE‰ˆ#dÍnÄBIà)Šƒ…8B uÂ0âaÄ lN>“'Äú“4ÌÓù‚FúLfë%wVlFž´·(Þ"ËÀ ð¡7Ôù'VLŠdÄbÄÜ#æ;cÎÊ@?v  ’H®pÒˆ\:‚EVEëòv°&RWòèä3!…±º‚%b…ÙÞä0`g½‡Ío•ûΊú¤Û3 w†¢FNXx,ID}ЏœÀ#4’‚°`Î {r8žL»ã³öÌuäÚV²K´„t"9¥‘ßôéÌŒîxbO?Øp¶ŒÇ3Nv8Uןî’{sâ3†@Óº^5hPæ„ÉD}ÂA·hÍ„:[ˆ7%ÓÇlÑü·aš‰øtOù€?ôǧött8yßþ&õý:‡$ rrí%[êŠ[Ñty0g‹oi žP~—Ò¹€²ÞÇÃÁIïôñzøäª×2IUϧÚwo 7¸Rg 0 DH O¹+™G|¥þÕ;8ìw§`ØöŒ."’?,ñî³`ñYb ótK%‚Ý%'Ô­J=q¹t®Á® ÍL,€ÃƒPO¡Á¤Q³‘$8˜ý%µ¼ uåjà» ™ãq·o¿7Ô÷tòiÔ­V™lˆ³¾";wˆ¹ýûYBŽ$ß"ƒäÅ<ó0¾z&f¯Ñ<ÔØñ}¾&«Ø—,ôÑ Wa]å „®Î” ’Š[€ ÎÎ8SA3ȽK0æ[”ÖÉ»2ÒFÂV+¾–FSØÜøŠÃ¸œ_1j‡¿÷ÉüÂD½ýº‹äÛï$É9?쇞G0 ¨õ˜Ã‘#Ø$—:;ªHÙ.²{-3MŸØ) 7›Ê8}W+t.`Á$#îkσ³2ÃNw2žÁ¹dÜ[4©…%$–væT´D. N=H,©ï×IVRÕ•EF~ñè´€ÊoI<^R÷Jé2g‘,¯ÀëT¼°@È(v%ã0\¬Q s¿ËÊèªð¼Tø)w ¾¡üXúu¼[8AåÚIËíwíöÌLHBx7Ë^*ŸA·:„•š~´ë PˆME&²ž4Ê´Ú[ÒÁkÒG±ds šà €Ï™98 Xy|؇NOÑœ4.vž‰‹Ò€ï¹!Þw±ºûýÃA§&«c jê¶@ÛPwÍ=JoB¯J̲—y#’vrÙ«‚C€öØËs@ŸBXí_HC5X"çV+yóëóÜBo߉[ð°è¦½) íÊ+È~’ú·Š¾Ùlf;”ŸÍb•Æ-1K½-ýœ± ¾Ùt(ËÁæ$¢ôÈîl:‘³àÁ‰»P‰ Ãðû²´Uãõ:¤jÏôïÚ³üç†X\Ñkão‚íÍÅÖü¨Ä·}ÌÍÝÖçË/ÔY56ÛE¥ÊŒWü׎ƒ¡ý£à-:/¢Ç\úB?þtú±7Ø­àQ~M&Ÿˆ=éA}z„>7߉ôÍ7Rá¸yÈdÉ}1[†¼dþVÍD˜ˆ¬€’½ú,„™hêrËzÉ |fW ’ºµ‡ÁØjyôºľ?ËÁy¼ÄTøtß/¼èVÔE´šŽŸ’±^S÷¡OÖÐfá¼ qfÃe×\*D)†?Ë9îK΄]H/ ‰dIÕ[žB„~ýe­ÈùgãÇrUBoSŠÜðª±kZƒ/,ÁŸ„ΑÒq—õ5:)Ç=ûû*ò -Õfl ¨ËÊ¥¹P±^å¥NrUé¶ËaîgØSM“*ö¯µˆžpªÊÇá"r¼‚Öy+þæ¡vªÏ„ÀL‘ì‡Ú½r4k5{ÎP´mH·Þ¥{Õ ÷ûºÝƒá¤[GKúçö„À[h\?öô|Õ„ðo.þ„Ó›ÏÙÍ·š¼Ù#Ø)ZäQ³hÆ2ò`1ÕÃSº3êçØtsÝPS×(â°Ãí49ñfFœa&f ÚòÔ$>7ÉïÔõ©£µ‰IL⫉Ÿ¹ ñ–ü'†É%õ¸Œ¾N/#•ó·/ùš^ÓèµjH=z/p¯‰à0N²T}¦äjYpXPvæ±PnQ‹£Pö"I/éÿGÃáä¤wÖm§à*ÍRYÍ}ÅWÛ–t\¼„ö&÷ÿÆ,¢¹v¢¼œ_ÝeqFpÔè÷š°nNI»ýó6ŠÊFãáiñZdü/9v´e­V«à‚Ç}…´8œTUº²”qíe¦†!ênžÐÕ%õŒÇ`*0,dô jÛÊ6hÖ–¼Ù`„>¯ŠFr‹”X©Ðp§<ÂÖð ´`¥“3Ñf«||BNÑ5:ÂÖ¶i@Q *Ü‚ò;Ò2‡ªô¢>v!¦÷áúè!-U ¡ÐèâÔ´%œ“^„'-\x«käÈ6OG‹qÿ{1yŸÎgpÕ½»9’æ[T5< €-¸@ÐZ?‘þ‡£Ñì+Ï'‹þpžO¡×M~PK’KAš/Á”œÞ ,priv/templates/simplenode.windows.runner.cmd¥VßoÛ6~×_qÀ"A+­É£~q‡í2¤é^æY¥%Ê&,‘*I;Éâäoß‘¢dJqׇùÅ:ÞwÇûî—4×ÌÔ² uÍñ„,Y.hò§'ûÌËçgT)ÖÀ¯¨6[t­e½7 Zj¶`¤;l©bÂ@É+ŒTï:›û-/¶À5P­÷ +-|Íœ…õJJ“FóJ*øåÄ%«y£³ù\ÀEL^Êö}šÆ—PJ8Ehí2B^ª>nÅjF5Ó9F‘C–½Â“øƒ*Í`q{÷Li.PQöæÃY¥dÚPer¦ê´¤†ž¢4rDŽήÞ]Ÿ%ad96í‚¿ˆsÌu 3Œ97Š7À”Ñy-z; òÎÜoÑ¥gÄŒ¢…AG5(¤ÜqÖ84)UÝeèÐäVÈ&‘’‰o²¬ß â½fkZì¾CO< ˆ«¸(µAä– ^ä þ>òíTº.ļCd–DäÏ1k.F…³‡ ÓC–ˆñ&š©/|«’¡kIþŠp$A®â,C*tÃb˜o$6¢B-X·ºîõ^Ù‹ f8Q®ú= c­lOJÙ†:Åz[ߨ‡7o~äªgq äÅñ}ÏÔc¯wB¨¥ÆÐbÛ«;iD·Ý(Zž։ќ[ _ÅNÈ{·6 ÎÐÌEŅ̃µÃØçñþò™Z‡¤­ŽŽ’ý“íêèÙ¯ŽžÈêè"^»Èа à廓g¶¸ù€ }#Ù:¤ì÷UY û…@R@¼èæÅ­¡ lSmC¢íù’܇HšP´MÌÑ”ØA€Þ¾¹Äá&Ì޲pìEn\ù/.ÓxÌ7è¹óŒq-È›ƒÛ¦tÐdÇ­ŸÐ½ï²ó®ò•ç±¹méYc;ÿ—ñÐÁþž“—{›Lñ³?Ýb£z¡ÛŠo~n¤uê±®fyÅë`•é…qø~ÀΓ¯¹~9öÀ]dq{{sûiñçâÓÄg?•Óm¬à­ÔÆú Vm”ÙWÊÿNf×Ξ H°»ô6ÌÁœô· òu„ð…0Úþ’Ãfq»çÚîžü Ó-’Ï\kŽãêø½QìpµÖ¿+„  áÎéáO=~mßò6ÄçÀâ÷›»Å9|þúåÎj1ÍE½/»—“‘nþ½¯*þй9q¹—_Š·Æåzº#üç>ÆÔcG+b’4 דaó_ÝK‘\ecÀ¿PK’KA­Ò.´Z/priv/templates/simplenode.windows.start_erl.cmd•TMkã0½ëW ¦i]ÚÞ_ZØî¡Ë¶GƒQâq*jKF£ í¿ßñGd'4t×Fï½yoFvÆj·ÕµR™§~iÏÚïþ4d'@¾f¿O胠õÔ’-¹«M)ç!8¨Œç«U2H=‡7òŽå%lÇ&g¡ìU„*8éÞ#Ò^.TV‰ÐÍ#,JªMÃéj%²ïd9½½º»º_â0.°ãàJÙ…yz%ñUôj‚ª¬†µœÁ›¬+©°º!Qz:ðÎAüTK5XôT“fâ¢4>ňÁüp0N¯í§÷ðûõöä¹K«my ÇZå]´…XNJ¦èSàYÜy̘úh 'iÈ.]Ï eŸážbðn¢²ú£Ìè5Î¥1ß›w†;7-*S õØ<ž´“JÜ JWS}¹Gßòø““­³•ÙÁìè¶-†ê÷'µªeCg„æéÃ6—£Èû/Ëû&鿇Y›}3^Ùä~á4JœØŒ ñˆã&ðð• \oú‹w%•q 8¥—b‡î€c/ÙT¼@ÃÂñ6Å;•íœüÖÏê/PK’KA“Ù–”\”priv/templates/simplesrv.erlµR]kÂ0}ï¯È‹!]·ù¶‡ Á Âġ̑Ùk ÆÄ%©8Jÿûçú±½ ÖZrsï9Ü{Ï *Éà<7úÄ“¢èßáìØ‰«Lã$5 O ý{[./âù2žô4^Ÿc— z=þûx–áË3¹±\IŸJ[Ó{Â…¯ŒeÚRÁå>º]·Ú~µ¯î§à’Û莠“‰ºaBDƒZhlt_†\n• ô},è—Ì‚/Ú¨Ä!\i Ñ Ý4yqmm•–¸ÂÇË€• µt.”Û‘³í—‹ÒÀ­ÖþëÜ ŒïùðP§¦>W{‚üKáÆ©yÓ9¼g`,At¬Õ …uòW8 GñA‡_2 ¼±˜NMú $Õöâ ‡éÄýÿ€)Íè›dFI×c¤ö®¬fSLg"Yy%qõñÙjÖÜBÉßšªéZ•Ltªé'PK’KAZƒ`óJV!priv/templates/simplesrv.template«.K,ÊLLÊI-ÖQˆ®..*ËLÑQPÊ­,N-*K-Rª­Õãª.IÍ-ÈI,IÊg™©@uz©E9J ¢dýjˆÆÚZ° PPK’KAžxè[Ø getopt.beamPK’KAß±«F p „mustache.beamPK’KAYÖwKÝ Ïrebar.appPK’KA\@‚¿.° Arebar.beamPK’KAboÛSD—0rebar_abnfc_compiler.beamPK’KAY«¾O°ü !6rebar_app_utils.beamPK’KA‘i Å” ,>rebar_appups.beamPK’KAª`h`ÆHrebar_asn1_compiler.beamPK’KA1 …· Nrebar_base_compiler.beamPK’KA-й+,ûVrebar_cleaner.beamPK’KAþW| VYrebar_config.beamPK’KAÃ9XÊÌÜ'crebar_core.beamPK’KAô‡ÚS  úzrebar_ct.beamPK’KAB}a0¹+(ˆrebar_deps.beamPK’KAÊ Å P¡rebar_edoc.beamPK’KAOÒÒ« H¤rebar_erlc_compiler.beamPK’KA¢*Ò(‡ d)·rebar_erlydtl_compiler.beamPK’KAgÇ”´Ô éÀrebar_escripter.beamPK’KA\ 8ý#P6ÏÇrebar_eunit.beamPK’KA–ØœQ¸Ä  çrebar_file_utils.beamPK’KAA]n[Œ ðrebar_lfe_compiler.beamPK’KAÿ¢Ä¦qt›ôrebar_log.beamPK’KAeÕ3Ǻ$ 8ùrebar_neotoma_compiler.beamPK’KAD¶¦U° +rebar_otp_app.beamPK’KA¥º(t,° rebar_port_compiler.beamPK’KA @÷¤® &rebar_protobuffs_compiler.beamPK’KAþŸd“ Äø,rebar_rel_utils.beamPK’KA)aû««Ì½6rebar_reltool.beamPK’KA¤aE" ü˜Frebar_require_vsn.beamPK’KA×G 0lJrebar_subdirs.beamPK’KAÇP@u_ºOrebar_templater.beamPK’KA£ž’õ~ ÔK`rebar_upgrade.beamPK’KA+xVÌt!ùkrebar_utils.beamPK’KA5îÀ¶ „ó€rebar_xref.beamPK’KA¿…jjD–ÖŒpriv/templates/basicnif.cPK’KAéz›ïQpriv/templates/basicnif.erlPK’KAý+¡R‡ %‘priv/templates/basicnif.templatePK’KAȪ8’‚µ‘priv/templates/ctsuite.erlPK’KA}Oê­P_—priv/templates/ctsuite.templatePK’KAôävÞ ‘—priv/templates/simpleapp.app.srcPK’KA¤yE†\Ï!E˜priv/templates/simpleapp.templatePK’KAÀ­À‰œk à˜priv/templates/simpleapp_app.erlPK’KA‡O³Ì º™priv/templates/simpleapp_sup.erlPK’KAÛ"'»ŒÏ›priv/templates/simplefsm.erlPK’KA¥DŒrFS!Öœpriv/templates/simplefsm.templatePK’KA—¡49A[priv/templates/simplemod.erlPK’KAþ6ÛöV’!Îpriv/templates/simplemod.templatePK’KA+]çI;D"cžpriv/templates/simplemod_tests.erlPK’KADV^$Þžpriv/templates/simplenode.erl.scriptPK’KA?6X8’®1v¡priv/templates/simplenode.install_upgrade.escriptPK’KAì,?¯ˆÓ"W¤priv/templates/simplenode.nodetoolPK’KA‘®?WÚÛ(ªpriv/templates/simplenode.reltool.configPK’KA·Ì£rÀ ?¬priv/templates/simplenode.runnerPK’KA8&’¬M$=µpriv/templates/simplenode.sys.configPK’KAT_ë»Ô"+¶priv/templates/simplenode.templatePK’KAWš8±!?·priv/templates/simplenode.vm.argsPK’KAš/Á”œÞ ,¶¸priv/templates/simplenode.windows.runner.cmdPK’KA­Ò.´Z/œ¼priv/templates/simplenode.windows.start_erl.cmdPK’KA“Ù–”\”¾priv/templates/simplesrv.erlPK’KAZƒ`óJV!3Àpriv/templates/simplesrv.templatePK<<­¼Àrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/README.org0000644000177700017770000000407312633765070027037 0ustar michaelmichael* webmachine ** Overview [[http://travis-ci.org/basho/webmachine][Travis-CI]] :: [[https://secure.travis-ci.org/basho/webmachine.png]] Webmachine is an application layer that adds HTTP semantic awareness on top of the excellent bit-pushing and HTTP syntax-management provided by mochiweb, and provides a simple and clean way to connect that to your application's behavior. More information is available [[http://webmachine.basho.com/][here]]. ** Quick Start A shell script is provided in the =webmachine= repository to help users quickly and easily create a new =webmachine= application. #+BEGIN_SRC shell git clone git://github.com/basho/webmachine.git cd webmachine ./scripts/new_webmachine.sh mydemo #+END_SRC A destination path can also be passed to the =new_webmachine.sh= script. #+BEGIN_SRC shell ./scripts/new_webmachine.sh mydemo ~/webmachine_applications #+END_SRC Once a new application has been created it can be built and started. #+BEGIN_SRC shell cd mydemo make ./start.sh #+END_SRC The application will be available at [[http://localhost:8000]]. To learn more continue reading [[http://webmachine.basho.com/][here]]. ** Contributing We encourage contributions to =webmachine= from the community. 1) Fork the =webmachine= repository on [[https://github.com/basho/webmachine][Github]]. 2) Clone your fork or add the remote if you already have a clone of the repository. #+BEGIN_SRC shell git clone git@github.com:yourusername/webmachine.git # or git remote add mine git@github.com:yourusername/webmachine.git #+END_SRC 3) Create a topic branch for your change. #+BEGIN_SRC shell git checkout -b some-topic-branch #+END_SRC 4) Make your change and commit. Use a clear and descriptive commit message, spanning multiple lines if detailed explanation is needed. 5) Push to your fork of the repository and then send a pull-request through Github. #+BEGIN_SRC shell git push mine some-topic-branch #+END_SRC 6) A Basho engineer or community maintainer will review your patch and merge it into the main repository or send you feedback. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/demo/0000755000177700017770000000000012633765070026311 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/demo/priv/0000755000177700017770000000000012633765070027271 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/demo/priv/dispatch.conf0000644000177700017770000000020712633765070031736 0ustar michaelmichael%%-*- mode: erlang -*- {["demo", '*'], webmachine_demo_resource, []}. {["fs", '*'], webmachine_demo_fs_resource, [{root, "/tmp/fs"}]}. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/demo/src/0000755000177700017770000000000012633765070027100 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/demo/src/webmachine_demo.app.src0000644000177700017770000000055212633765070033500 0ustar michaelmichael%%-*- mode: erlang -*- {application, webmachine_demo, [ {description, "demo"}, {vsn, "1"}, {modules, []}, {registered, []}, {applications, [ kernel, stdlib, crypto, mochiweb, webmachine ]}, {mod, { webmachine_demo_app, []}}, {env, []} ]}. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/demo/src/webmachine_demo_app.erl0000644000177700017770000000077512633765070033563 0ustar michaelmichael%% @author Andy Gross %% @author Justin Sheehy %% @doc Callbacks for the webmachine_demo application. -module(webmachine_demo_app). -behaviour(application). -export([start/2,stop/1]). %% @spec start(_Type, _StartArgs) -> ServerRet %% @doc application start callback for webmachine_demo. start(_Type, _StartArgs) -> webmachine_demo_sup:start_link(). %% @spec stop(_State) -> ServerRet %% @doc application stop callback for webmachine_demo. stop(_State) -> ok. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/demo/src/webmachine_demo.erl0000644000177700017770000000231312633765070032711 0ustar michaelmichael-module(webmachine_demo). -author('Andy Gross '). -author('Justin Sheehy '). -export([start/0, start_link/0, stop/0]). ensure_started(App) -> case application:start(App) of ok -> ok; {error, {already_started, App}} -> ok end. %% @spec start_link() -> {ok,Pid::pid()} %% @doc Starts the app for inclusion in a supervisor tree start_link() -> ensure_started(crypto), ensure_started(mochiweb), application:set_env(webmachine, webmachine_logger_module, webmachine_logger), ensure_started(webmachine), webmachine_demo_sup:start_link(). %% @spec start() -> ok %% @doc Start the webmachine_demo server. start() -> ensure_started(inets), ensure_started(crypto), ensure_started(mochiweb), application:set_env(webmachine, webmachine_logger_module, webmachine_logger), ensure_started(webmachine), application:start(webmachine_demo). %% @spec stop() -> ok %% @doc Stop the webmachine_demo server. stop() -> Res = application:stop(webmachine_demo), application:stop(webmachine), application:stop(mochiweb), application:stop(crypto), Res. ././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/demo/src/webmachine_demo_resource.erlrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/demo/src/webmachine_demo_resourc0000644000177700017770000000357212633765070033702 0ustar michaelmichael%% @author Justin Sheehy %% @copyright 2007-2009 Basho Technologies, Inc. All Rights Reserved. %% @doc Example webmachine_resource. -module(webmachine_demo_resource). -author('Justin Sheehy '). -export([init/1, to_html/2, to_text/2, content_types_provided/2, is_authorized/2, generate_etag/2, expires/2, last_modified/2]). -include_lib("webmachine/include/webmachine.hrl"). init([]) -> {ok, undefined}. content_types_provided(ReqData, Context) -> {[{"text/html", to_html},{"text/plain",to_text}], ReqData, Context}. to_text(ReqData, Context) -> Path = wrq:disp_path(ReqData), Body = io_lib:format("Hello ~s from webmachine.~n", [Path]), {Body, ReqData, Context}. to_html(ReqData, Context) -> {Body, _RD, Ctx2} = to_text(ReqData, Context), HBody = io_lib:format("~s~n", [erlang:iolist_to_binary(Body)]), {HBody, ReqData, Ctx2}. is_authorized(ReqData, Context) -> case wrq:disp_path(ReqData) of "authdemo" -> case wrq:get_req_header("authorization", ReqData) of "Basic "++Base64 -> Str = base64:mime_decode_to_string(Base64), case string:tokens(Str, ":") of ["authdemo", "demo1"] -> {true, ReqData, Context}; _ -> {"Basic realm=webmachine", ReqData, Context} end; _ -> {"Basic realm=webmachine", ReqData, Context} end; _ -> {true, ReqData, Context} end. expires(ReqData, Context) -> {{{2021,1,1},{0,0,0}}, ReqData, Context}. last_modified(ReqData, Context) -> {calendar:now_to_universal_time(os:timestamp()), ReqData, Context}. generate_etag(ReqData, Context) -> {wrq:raw_path(ReqData), ReqData, Context}. ././@LongLink0000644000000000000000000000015500000000000011604 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/demo/src/webmachine_demo_fs_resource.erlrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/demo/src/webmachine_demo_fs_reso0000644000177700017770000001206312633765070033653 0ustar michaelmichael%% @author Bryan Fink %% @author Andy Gross %% @author Justin Sheehy %% @copyright 2008-2009 Basho Technologies, Inc. -module(webmachine_demo_fs_resource). -export([init/1]). -export([allowed_methods/2, resource_exists/2, last_modified/2, content_types_provided/2, content_types_accepted/2, delete_resource/2, post_is_create/2, create_path/2, provide_content/2, accept_content/2, generate_etag/2]). -record(context, {root,response_body=undefined,metadata=[]}). -include_lib("kernel/include/file.hrl"). -include_lib("webmachine/include/webmachine.hrl"). init(ConfigProps) -> {root, Root} = proplists:lookup(root, ConfigProps), {ok, #context{root=Root}}. allowed_methods(ReqData, Context) -> {['HEAD', 'GET', 'PUT', 'DELETE', 'POST'], ReqData, Context}. file_path(_Context, []) -> false; file_path(Context, Name) -> RelName = case hd(Name) of "/" -> tl(Name); _ -> Name end, filename:join([Context#context.root, RelName]). file_exists(Context, Name) -> NamePath = file_path(Context, Name), case filelib:is_regular(NamePath) of true -> {true, NamePath}; false -> false end. resource_exists(ReqData, Context) -> Path = wrq:disp_path(ReqData), case file_exists(Context, Path) of {true, _} -> {true, ReqData, Context}; _ -> case Path of "p" -> {true, ReqData, Context}; _ -> {false, ReqData, Context} end end. maybe_fetch_object(Context, Path) -> % if returns {true, NewContext} then NewContext has response_body case Context#context.response_body of undefined -> case file_exists(Context, Path) of {true, FullPath} -> {ok, Value} = file:read_file(FullPath), {true, Context#context{response_body=Value}}; false -> {false, Context} end; _Body -> {true, Context} end. content_types_provided(ReqData, Context) -> CT = webmachine_util:guess_mime(wrq:disp_path(ReqData)), {[{CT, provide_content}], ReqData, Context#context{metadata=[{'content-type', CT}|Context#context.metadata]}}. content_types_accepted(ReqData, Context) -> CT = case wrq:get_req_header("content-type", ReqData) of undefined -> "application/octet-stream"; X -> X end, {MT, _Params} = webmachine_util:media_type_to_detail(CT), {[{MT, accept_content}], ReqData, Context#context{metadata=[{'content-type', MT}|Context#context.metadata]}}. accept_content(ReqData, Context) -> Path = wrq:disp_path(ReqData), FP = file_path(Context, Path), ok = filelib:ensure_dir(FP), ReqData1 = case file_exists(Context, Path) of {true, _} -> ReqData; _ -> LOC = "http://" ++ wrq:get_req_header("host", ReqData) ++ "/fs/" ++ Path, wrq:set_resp_header("Location", LOC, ReqData) end, Value = wrq:req_body(ReqData1), case file:write_file(FP, Value) of ok -> {true, wrq:set_resp_body(Value, ReqData1), Context}; Err -> {{error, Err}, ReqData1, Context} end. post_is_create(ReqData, Context) -> {true, ReqData, Context}. create_path(ReqData, Context) -> case wrq:get_req_header("slug", ReqData) of undefined -> {undefined, ReqData, Context}; Slug -> case file_exists(Context, Slug) of {true, _} -> {undefined, ReqData, Context}; _ -> {Slug, ReqData, Context} end end. delete_resource(ReqData, Context) -> case file:delete(file_path( Context, wrq:disp_path(ReqData))) of ok -> {true, ReqData, Context}; _ -> {false, ReqData, Context} end. provide_content(ReqData, Context) -> case maybe_fetch_object(Context, wrq:disp_path(ReqData)) of {true, NewContext} -> Body = NewContext#context.response_body, {Body, ReqData, Context}; {false, NewContext} -> {error, ReqData, NewContext} end. last_modified(ReqData, Context) -> {true, FullPath} = file_exists(Context, wrq:disp_path(ReqData)), LMod = filelib:last_modified(FullPath), {LMod, ReqData, Context#context{metadata=[{'last-modified', httpd_util:rfc1123_date(LMod)}|Context#context.metadata]}}. hash_body(Body) -> mochihex:to_hex(binary_to_list(crypto:sha(Body))). generate_etag(ReqData, Context) -> case maybe_fetch_object(Context, wrq:disp_path(ReqData)) of {true, BodyContext} -> ETag = hash_body(BodyContext#context.response_body), {ETag, ReqData, BodyContext#context{metadata=[{etag,ETag}| BodyContext#context.metadata]}}; _ -> {undefined, ReqData, Context} end. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/demo/src/webmachine_demo_sup.erl0000644000177700017770000000326712633765070033611 0ustar michaelmichael%% @author author %% @copyright YYYY author. %% @doc Supervisor for the webmachine_demo application. -module(webmachine_demo_sup). -behaviour(supervisor). %% External exports -export([start_link/0, upgrade/0]). %% supervisor callbacks -export([init/1]). %% @spec start_link() -> ServerRet %% @doc API for starting the supervisor. start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). %% @spec upgrade() -> ok %% @doc Add processes if necessary. upgrade() -> {ok, {_, Specs}} = init([]), Old = sets:from_list( [Name || {Name, _, _, _} <- supervisor:which_children(?MODULE)]), New = sets:from_list([Name || {Name, _, _, _, _, _} <- Specs]), Kill = sets:subtract(Old, New), sets:fold(fun (Id, ok) -> supervisor:terminate_child(?MODULE, Id), supervisor:delete_child(?MODULE, Id), ok end, ok, Kill), [supervisor:start_child(?MODULE, Spec) || Spec <- Specs], ok. %% @spec init([]) -> SupervisorTree %% @doc supervisor callback. init([]) -> Ip = case os:getenv("WEBMACHINE_IP") of false -> "0.0.0.0"; Any -> Any end, {ok, Dispatch} = file:consult(filename:join( [filename:dirname(code:which(?MODULE)), "..", "priv", "dispatch.conf"])), WebConfig = [ {ip, Ip}, {port, 8000}, {log_dir, "priv/log"}, {dispatch, Dispatch}], Web = {webmachine_mochiweb, {webmachine_mochiweb, start, [WebConfig]}, permanent, 5000, worker, dynamic}, Processes = [Web], {ok, { {one_for_one, 10, 10}, Processes} }. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/demo/README0000644000177700017770000000233712633765070027176 0ustar michaelmichaelProject Skeleton for the webmachine_demo app. You should find in this directory: README : this file Makefile : simple make commands rebar : the Rebar build tool for Erlang applications rebar.config : configuration for Rebar start.sh : simple startup script for running webmachine_demo /ebin /webmachine_demo.app : the Erlang app specification /src /webmachine_demo_app.erl : base module for the Erlang application /webmachine_demo_sup.erl : OTP supervisor for the application /webmachine_demo_resource.erl : a simple example Webmachine resource /priv /dispatch.conf : the Webmachine URL-dispatching table /www : a convenient place to put your static web content You probably want to do one of a couple of things at this point: 0. Build the skeleton application: $ make - or - $ ./rebar compile 1. Start up the skeleton application: $ ./start.sh 2. Test the basic application: Visit http://localhost:8000/demo 3. Change the basic application: edit src/webmachine_demo_resource.erl 4. Test the filesystem resource: $ mkdir /tmp/fs $ echo "Hello World." > /tmp/fs/demo.txt Visit http://localhost:8000/fs/demo.txt 5. Add some new resources: edit src/YOUR_NEW_RESOURCE.erl edit priv/dispatch.conf rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/demo/Makefile0000644000177700017770000000035712633765070027756 0ustar michaelmichaelERL ?= erl APP := webmachine_demo .PHONY: deps all: deps @../rebar compile deps: @../rebar get-deps clean: @../rebar clean distclean: clean @../rebar delete-deps docs: @erl -noshell -run edoc_run application '$(APP)' '"."' '[]' rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/demo/rebar.config0000644000177700017770000000015612633765070030575 0ustar michaelmichael%%-*- mode: erlang -*- {deps, [{webmachine, "1.10.*", {git, "git://github.com/basho/webmachine", "HEAD"}}]}. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/demo/start.sh0000755000177700017770000000016212633765070030004 0ustar michaelmichael#!/bin/sh cd `dirname $0` exec erl -pa $PWD/ebin $PWD/deps/*/ebin -boot start_sasl -s reloader -s webmachine_demo rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/test/0000755000177700017770000000000012633765070026344 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/test/etag_test.erl0000644000177700017770000001064512633765070031035 0ustar michaelmichael%% @author Justin Sheehy %% @author Andy Gross %% @copyright 2007-2010 Basho Technologies %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. -module(etag_test). -ifdef(EQC). -include("wm_reqdata.hrl"). -include_lib("eqc/include/eqc.hrl"). -include_lib("eunit/include/eunit.hrl"). -compile(export_all). -define(QC_OUT(P), eqc:on_output(fun(Str, Args) -> io:format(user, Str, Args) end, P)). unique(L) -> lists:reverse(lists:foldl(fun(Elem, Acc) -> case lists:member(Elem, Acc) of true -> Acc; false -> [Elem | Acc] end end, [], L)). etag(Bin) -> integer_to_list(erlang:crc32(Bin)). etag_list([]) -> "*"; etag_list(Bins) -> string:join([[$", etag(B), $"] || B <- Bins], ","). http_request(_Match, _IfVals, _NewVal, 0) -> error; http_request(Match, IfVals, NewVal, Count) -> case httpc:request(put, {"http://localhost:12000/etagtest/foo", [{Match, etag_list(IfVals)}], "binary/octet-stream", NewVal}, [], []) of {ok, Result} -> {ok, Result}; {error, socket_closed_remotely} -> io:format(user, "Retry!\n", []), http_request(Match, IfVals, NewVal, Count-1) end. etag_prop() -> ?LET({AllVals, Match}, {non_empty(list(binary())), oneof(["If-Match", "If-None-Match"])}, ?FORALL({IfVals0, CurVal, NewVal}, {list(oneof(AllVals)), oneof(AllVals), oneof(AllVals)}, begin ets:insert(?MODULE, [{etag, etag(CurVal)}]), IfVals = unique(IfVals0), {ok, Result} = http_request(Match, IfVals, NewVal, 3), Code = element(2, element(1, Result)), ExpectedCode = expected_response_code(Match, IfVals, lists:member(CurVal, IfVals)), equals(ExpectedCode, Code) end)). expected_response_code("If-Match", _, true) -> 204; expected_response_code("If-Match", [], false) -> 204; expected_response_code("If-Match", _, false) -> 412; expected_response_code("If-None-Match", _, true) -> 412; expected_response_code("If-None-Match", [], false) -> 412; expected_response_code("If-None-Match", _, false) -> 204. etag_test_() -> {spawn, [{setup, fun setup/0, fun cleanup/1, [ {timeout, 12, ?_assert(eqc:quickcheck(eqc:testing_time(10, ?QC_OUT(etag_prop()))))} ]}]}. setup() -> %% Setup ETS table to hold current etag value ets:new(?MODULE, [named_table, public]), %% Spin up webmachine WebConfig = [{ip, "0.0.0.0"}, {port, 12000}, {dispatch, [{["etagtest", '*'], ?MODULE, []}]}], {ok, Pid0} = webmachine_sup:start_link(), {ok, Pid1} = webmachine_mochiweb:start(WebConfig), link(Pid1), {Pid0, Pid1}. cleanup({Pid0, Pid1}) -> %% clean up unlink(Pid0), exit(Pid0, kill), unlink(Pid1), exit(Pid1, kill). init([]) -> {ok, undefined}. allowed_methods(ReqData, Context) -> {['PUT'], ReqData, Context}. content_types_accepted(ReqData, Context) -> {[{"binary/octet-stream", on_put}], ReqData, Context}. on_put(ReqData, Context) -> {ok, ReqData, Context}. generate_etag(ReqData, Context) -> case ets:lookup(?MODULE, etag) of [] -> {undefined, ReqData, Context}; [{etag, ETag}] -> {ETag, ReqData, Context} end. ping(ReqData, State) -> {pong, ReqData, State}. -endif. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/Makefile0000644000177700017770000000052612633765070027030 0ustar michaelmichaelERL ?= erl APP := webmachine .PHONY: deps all: deps @(./rebar compile) deps: @(./rebar get-deps) clean: @(./rebar clean) distclean: clean @(./rebar delete-deps) edoc: @$(ERL) -noshell -run edoc_run application '$(APP)' '"."' '[{preprocess, true},{includes, ["."]}]' test: all @(./rebar skip_deps=true eunit) rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/.travis.yml0000644000177700017770000000032012633765070027471 0ustar michaelmichaellanguage: erlang notifications: webhooks: http://basho-engbot.herokuapp.com/travis?key=66724b424957d598311ba00bb2d137fcae4eae21 email: eng@basho.com otp_release: - R15B01 - R15B - R14B04 - R14B03 rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/0000755000177700017770000000000012633765070026211 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/index.html0000755000177700017770000000771712633765070030225 0ustar michaelmichael Webmachine - software shaped like the Web

    webmachine

    Webmachine is not much like the Web frameworks you're used to. You can call Webmachine a REST toolkit if you like, and we won't argue with you.

    Webmachine is an application layer that adds HTTP semantic awareness on top of the excellent bit-pushing and HTTP syntax-management provided by mochiweb, and provides a simple and clean way to connect that to your application's behavior.

    A Webmachine application is a set of resources, each of which is a set of functions over the state of the resource. We really mean functions here, not object-methods, infinite-server-loops, or any other such construction. This aspect of Webmachine is one of the reasons why Webmachine applications are relatively easy to understand and extend.

    These functions give you a place to define the representations and other Web-relevant properties of your application's resources -- with the emphasis that the first-class things on the Web are resources and that their essential properties of interaction are already quite well defined and usefully constrained.

    For most Webmachine applications, most of the functions are quite small and isolated. One of the nice effects of this is that a quick reading of a resource will give you an understanding of the application, its Web behavior, and the relationship between them. Since these functions are usually referentially transparent, Webmachine applications can be quite easy to test. There's no need for mock objects, fake database connections, or any other wastes of time when you can write tests against each component of your application in terms of the input and output to various functions.

    We believe that by giving Web developers a system with conventions that directly map to HTTP and REST, we help them to write and extend Web applications quickly while not dictating the shape of the rest of their application. The resulting applications are straightforward to examine and maintain, and have very easily understood HTTP semantics.

    rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/0000755000177700017770000000000012633765070027456 5ustar michaelmichael././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/basic-trace-decision-tab.pngrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/basic-trace-decision-0000644000177700017770000024713612633765070033443 0ustar michaelmichael‰PNG  IHDROÑÍÆasRGB®Îé pHYs  šœtIMEÙ;6°yîtEXtCommentCreated with GIMPW IDATxÚìÝw|ÕÚÀñß´mɦ’„@h¡#‚ÈéUA±+( bAQì‚`£¨¯½ "‚€`AiÒAº R¤BKÝd7;»3óþ±!J¦žï玗ìN9{fwçÙçœ9G²,Ëâoš2eJ‘Çš6mŠ ‚ ÿ]²¨AA.õØ?ŠËF‚ ‚ œ+‘ÉAá‚POõDÀŸ‹Ïo€¢æDu%‚ Âß 2ü™»™1ñ¦üì!¼rerþú ädx¦?-ë–ÁÆy²~ýz~¿ÿò+Û†}ÈrÉ“\î0*WN⚆uÅ A ™»–ñÀ3ïQªÁ=¼?¶#qN²gýžzíI~êðÃz5Æ)êíœY–ÅòåËq:T®\™°°°Ë®ŒvW)ÂÃJ~–3³j×¾’ÄÄÒ8—_Èv$ÓKdDx‰·‹ÌÎÁ´,~[»‘­î¢fdñ Aø+ȉï_¿ˆ_|&­nkE¼VtÅŠW·áJ›Ì÷ŸýJÎ9ý„×Y8úi’’’Š,õº=Îøi‹Ù{Ô{^^”éOáùö-¸yÈlgdßê/¸¦qCïʽà•mš&ëÖ­£|ùò”-[»ÝvY¾)ô@ aœrÙ±cG±kvå+”!!1ž9ó–c𦸄 ‚ ˆ Œ`èbî.þÂ'ÙÉÑ$ðïÇ“wG’l´é;‚ÙÝÀ±‹Ù³o7Û¶¬gü Ìyê^š\U‘ß®Ãø›/JRÜt|ô1ž¾ã*´3¤ìK%7åÙG‡Q%Ú~áó+†AZZ‚Á ¦i^vK  »d¤g²pþ|2Ò3‹<§äåéDFG°sO*†aˆO˜ ÂX‘¶›Z|×N+˜Çî<Ô¿wß«‚ €ääDIÅ厥v“nŒß؈îjÇðÇ:ãŽ[Ƀ-Ë{¡ÆÐ¥ï€³ZוP—‡žº8u]GQ,Ë*èðùwÆ[µ 6lEN™NFZ6’ÍM”»äÁ“߯ã÷ëÅÐbÁ‚y|üÑ{¸##éС’,z}¾†a¡ë:š¦‰O™ Â=“aºèéAãnrþº_  ž£¬Z8w¾žE~kG¶ü@ýÖ·ñ¿§1uêTæ¼wOõ¼Žc×bʾã'FÏü‰~7]·Î#Œ{gK¾~–Ñsþ*È"lõè¬^q¨H³eY¡ C’ÐuÓ01 £Ä‹ÐhÙ÷9*ãÄ’ ïã÷!sÐt>Ì_kÆóáÓ£Ùï –ìf`°è²pÁºNBB=Àüy³ ¯0ðùt$I¦©"ÀAAFH\Íf´s«¬ýá'öæ½8l^1€î·4¸ð·°Ê.¬Ã¿ÐÿÓ*†çñëÒ•¤æú?ò72®¡Ç ‹1ünâíjd ^xµ7]Z”GÓbiyóýôº%¡`wº7”¥Xº|;†G¯!=°™öØÊÜz{÷¢€,¦{‘òÞ¤sƒÒ\q]Þ¸#‘iÃ^f‹'šw?F«p…¾ï̧gǦ´îÒƒ¢4rõPfF¶'óñòßX:®;Žbúƒ¨ªŠD¨iÁ¯ûóû?]rnbÔ}5‰'¾ÂÝÌùm_ÁsZteÔ«Mùª.Œ`áíü†Å Û9ªð¦€ðZ¸äà)SÜâ÷ЋY:tì§_L,X®ïtc¡çý¯/Y–E3‰ ‚pBŸ ¹· }œyGñÔ€)üß;7Q&\‚ìXñ-¯}µ‘ú·Žî-ÆñÁ¬ßèZ'þ¤5½º@áJr…:«J'Ô–ï[TMC–e$YF–e¥hêGvñÑ‘Ìïú?ÂT‰°:x¹Ù«¬Øzˆúe*œ:Y–PU=V0“_Þõ%Ƶ·¸§ï^ý_½Ð•ˆ b³Ù°ÛJÞaÔ±, Y–°‰ Cá?¯È"ö¨Štb ¯èιsØ ›´º÷~ÚžçCS ߨbú÷ðÞí¡;BlK¥uÀ7—O~\ÂOe_?݃U©¡‘:&M_y¼s¥•Χ½ÈÎÜÂWÈÜ:‹Ù»KÑkèd–Oÿ„º6™ÏÚX¨c¦¦ªÈ6¥*Ûæl&ó„~©V04~G|„ë„@¤0ç ñ îCZ§|Ý’$!KŠ¢ iZ‘E’,ÐJápœðx´†nQh=§,¡œð·ØËë/Íࣗî¡åu=Ù¶ú”IƒX¹ÇWìqNµØT›M+²¬Z¾„wß^°,^0§Ð󊦠È2’$¡iªøt ‚ ˆ £xUšÜȧCcZ,þây™ËžÃYÿv_¾Ð{ËŸ)VÜÌÃü¾ä{î©Û‚S} þlªEâ.=ãíLxª3/|<“ ¬æƒ1!æÚ6jD¿D'³GÝÍ}CưtÅ^¨ß€­ïÌÏzø8¸'Ô‡C$%Às¯ÌÀkYT¨×ÛE&I°ç`Hqt5Ò?bô› ‚—Ÿ§~KíûÇqe‚Šž¶‹é™Âlj¡ìDZ̆éßÃÓ ® Ã³3ß sR–@’$$IBQTU-²D$]A¯ˆ¥ü°bªªâK]Ã3ÓÓ¦^¥üu$TÉÀ 0B«*šÃEE—ÂÆ]™¡¿]vd &,¬Øãœj±Ù5v[‘åšÆÙ¹c+kW¯`˦õ4iÚ¼Ðóª¢æ ÙD!‚ð_wÚ+AÅ«;1q\3voÿ“­[w0éÝ‘x¤JÜûؽT‹-a:ÜÒYøéãÜ3ìG€Pÿˆ‚4@{ž~î]_w-ÕÊ„æòíxê‡qìnc_y€±@‡'?gâ€f¨’Ä Ÿ~@é Œ¢1ððÈoyâæêXÁTÆ<7€áË2Gyùšx´ÔH[þíúìä¦ÄuŒ×ïáëj‘ºa&ƒnéÊžÜù Ñ“?¦[‹~ÌüÌ¢Sïü¼¢?µvÉöÚÙðbkTã ï=þ?ñõcû‘±ì-¦gà±k©W~5ÝÏ0䆚ŸÉ$ EV°Û‹k–¨ÀàŸ&Ò»e[ÊzB)•Q߬¤urÙ;gܰghÕ%W1 ê~ÖnNw5žøè%ZÝpåï©ïðïiQ%{ šK6{±åŠ‹‹ã®ž}xû×¹óžûH,“ˆ,ÏìAtY™ AÉÊ¿ÏpÊ”)çuÇM›6=/û±‚>²rü¨váΓG#5ðûtLEÃy¿œƒºŸßÂívqÝ€ÏCz¶Iuë.Q™ƒºSv`;a.˲ÈÈÈ`ÇŽT©R…ˆˆœN'Çéú”x½~T›³Ð¾ÎÄô{ÉòøQ]nÜ®’_ìß´WXñu”•‘Á§Ÿ¼Ï}}úWè¹<99¹¤gdñ׎]tëØŒèèh1Qš ‚Èd\¦Qê$*êT7Í*ØK0Á˜jsâ>ËéB4§›§ûÜ*ÕV´L’jÒÈÊÊB’$œN'aùͧc·»J^»gĹ׹ÓåÀå*¾^].'ô@BBœ;hZ(KãÍÍC•Í‚¬ ‚ ‚ á³ÙlèºNnnnAÐq¦ ãRp8NŸa©P±Bñ!Ÿ¬Ð˜f§-ôzAdüg ƒ@ ˆ×—G0¼ “z¦3ÜÍêßÖ‘‘CRÙ²¸\®Ë®Nr¼¹F ÄÛù¼>ö8Àî;(Ñô YŸ2á_AQBµ]Nš¦¢*â½-"È8C€‘ç÷“•å!Ë“K®7ï‚–eaI6Ò2rü¹“CG2°Ùì—]½øƒŠRòfžŸ¬ÌL¼Þ<,ÉFÊ#¢¹DøWa.‘î0"#Ý8ìvh‚2N`øòüdddq$=“£éYx½¾ü ¾.ËgxY9^ޤgþ«æ÷$ ›Í†+<‚ô¬2²sÄ'Lø÷²‚Ëåĉa˜DGGâtˆ@CDqÃ0ðë:YÙÒ3=äæúÈHOÃ0 ‚A㢔Á¦*ØT翲~ƒºŸ îŸ.á²tèpö9eØ118í6YAVddYB²ÙйW„ÿh¡ ²³s8’–AN®”ý)D„‡Q.©,áîpñ®„±½)‡O1>ÍéegyØ·o?Û¶ï¡zõŠX˜(²Œ‰S‚pùÇÆ­PT Íá@“$ü>»óÌw%|i¤ R¶\BhÌMKç`ÊA܉å;Ø]'Ç›GfV99TY¢f*”-Sæ”·n ‚ðï`X á%ïpíñxÑl›·lçÈ‘t‚ÁHÂÃÂs9qÚÅT‚pÙzæn¾ûrƒFM/ôxï‡îã³oãùcÍCÄœ"iSùø™Î¼úõ!b›¾Áʯobý×ùeÐhÐê³dã$ŸáUåùu<9¹dfyÈH?J•Jå©Z9™ð0ª*&ö„3MÓp8O}‹öî]»¨X©R‘ÇeE¥’*s õ{÷D’e"#‰t‡áõ*—E‘¾cuZõg{&-ZC“ª¥Q€Ìëy£óMà»L/Ä„¿½¤&òÀ«30RÚ11ʆŒFãÛžá{sÓ0•³Ó0 t=€’——GDD8²$aš&¦iŠw… ü‹`±ÏåxrX8>Ýn¾¥HÓiÐ4MÂÂÃÙµ;=D×ôŽ4AAF ˜Þ<c_Ðê3mé'\]úxÖ ªL]†-›ÎoõžãLYÙEé NÈ:yØp‡Gplòµ3¦‰eYƒAY.øâ‘e™K{³‡ÁÆÅ Pj¶¤f‚]¼;/1=sóVçѾ]mÎW~Ë ¦óóœu\Ù®5±6q{ï¥à÷ëøýz1'ÇbÁ‚y|üÑ{¸##éС’|ü麎?OGè˜&ƒA,ËÂ?Láò2þ\2‘é™: z’º¥‹~mË®Z¼ýåÓÄØC_Æ?}>‚ç:Ê[ç“ÚéEƾt/åÜg÷uoxv3zØ e”#,m:áÞgÔSí±éûÛ»¾ë¤F‚Šœd†i•,“‘µík’oñ²w]/ÂÎÇxV ö&~ì:ªÇ‰f›K-'õWîèeߺš(çi¼3ï Ý_÷%ZAÆ% ÁbƒÌŒL&Œ‹eÁįÆÒðšÆDEGÏd˜fèw $YúWÝ~.ÿŠ Ã“q€Š•9U_ìj°kÉXúßÊ’?PɾŸ¶däÕxïÎÚgu¬‹ßb¼ç^–~Ö™¼½]húä^B_+:)A#ÕKõx7²,#Iº®c³Ù0¤³O}ºÊ´å—ïØL“ó“05ÑÊk¨²%R°ÿR”'ò[³oޭʹÅ|Š ’†\ÌùÝ6ëiîœÚ„Ÿv-Q–Ã’dZÇ^‡i†2.à  m.Y¸`]'!!€`þ¼ÙÜxÓ-ǃŒ€ÏšeXV,D!g"_´#Y9lY²€úUâθº¢EBT "œ6ÊWwn?û˜H²Å³wÁ÷¬Û›MXùæ|xoåÐ ¶'óÄ;ïqç 5$P”Ð>u]ǯûóÛk‹.[—|E»¤ÒÄÇÇ3ä» <‡×òî„ÕxôÜݼÒgK–ÏàÖäDâËvdî1÷Ó¾ÄÇÇÓìÑ1È x˜þÚc|·xCo¬B||Ï_oóŒá¼öÝ[f¿Í“æ1á•úÔì6žì@€” s¹¿ZYâã㉯6ˆ¿²t/«¾=ôXÙŽÌýã0@=÷Oî«ÓŸ¿²t¶-ø?€14!¾ÆKìÎÑ äâ‡÷mÏÓÖà œººA©r>~™ÿyh›ÊýùeOY{æÑ¬çìù±eËvdþŸ™ùu6…¥?}Xp¾6ïÞÂÛ÷×">>žgF/Í?V(Å8ÝqÅrA¿?€^ÌÒ¡c>ýbbÁr}§ =ïèx}yHÈ(Š,®‚pYe2¤p®lÙ¦gíŽT:ÖŠ<íêåßÏÞå©Ìþôú¾<€¾ÝÏþpQeªïcº6©E»‡ßbÄã·àÊOy;##±çä…ŠuB›kž/^1ƒHYGûÐs\7z!“Å’Äãñ}8• ßæñTš/m‹ÞáÝe0kÎ îžý2w]Û˜žÃ'ñËŠûÑé&ÞÞ†ë«ÛHMYÀ ½r7yw9ðT—;ù°ü\ú7‹%/`âËõàñX,û¸+_1„Í[?cûü¡ô2o–eá£ØþpcÊfÿÂ3WPÙ¿’®õ:°mþgì­vfVúY–¥ø©Z=™iLúôqÒfÙÏwÜÍ«ín qÄL¶~Å/^Ï›Ó*0°u9–}ý8[~Èæ± ñfççñàM_ÏÕm{ñÆä…|P7†õÓ†Ó¦õ›¬ZörZ?ÎÌcØt íèvvø³ðxŸ¿Œf?|Öe)6‹¤PúyFömC¸ú‘•Œ9”GוÓ»ÕÉsÓÈ®•‡ªÚ(wEÖö¹‡·£ßçŽ.­‰RURv.‡Ä¡\W¿<6àï§ÅÐüu´?5í2›°É2’šxJ1|4zf2w· 5‰íYö+D÷á¶W).à—eSÀSãÇbdü Ù+ÑÍah®ê5ˆ9f’XÊÁ¡ø¢Ýá`âç yò‹.$ºíà®G¿ÁxrÖîk–TìAQ ˆ’o†÷ B‚¬*õ‰õÛQU'±¥*“\ŠøØ(ì@ ¿ÎÞ~ò:Â%hÖâJ¶5ŠÎõËcéЇª„êüø ¼"ȸl6ös˜3ÈÈïè)IRA‡qA.£ £JóÜõ9Ó?ïÇ¢[ÿ c­˜"ëìY·”@R]~}ëiÊw~—go® 䑱/Ý空i®›1‰øënã«-›Xôå+ÜýÂG¬Ûý0åkEbè~Œü %Ô'C–$EAÓŠka×èôô"æ·]Ìç#zñÂЇø}ETUIAÕ44KERKæÐÐ4 Íáɇ¦ihX€¢ihš†D„9 Ž%)²¢¢iŠ$¡hªšGв¸®C;:_ƒßhGÇ£ ³ÅÒúÑv ž5z¿ïã‰÷_gCjfÏ®ÎooÖUB ¤ŸuYŠ£©*±ÉQ¸lBo“n F„D»vípÅ”AÓ4j´’5‹Ûð×#iUÿa~\½ƒÈ€Š»ÚÞ²T$À’Ôо+ºòËÙ¯]R%¢¢ Ê¥ª (a¡ýœx=V Z×hß¹.–¿î°“nC+˜ÈJ~K~ÃÂé8^ïvUB–-äce)®ª$ž_’*!óÏ“•‹$«¯ãä:s¸¢‘óBÏ[– ,4 MU‘%U ᪊ÍVôŒ/Y´€_W­(ø»ÎUõhß±sÁߺd¡˜¦2¡.ê'EvUcðW#èӾ߭ø‹@~íDÓ;BË¿µoï‚,Y·Õs>äÅ%鬙3‹åì$`å°kqVþå?$8~Pô Lþy7Há´¼ý>êÚdÂ*¦õëË„…Û±,¥PH’„¢*ù¿0OZ$?©s©Ù¨#Cßú?HŸO®© ¢Ç· ]<ò·QòcÏÉR(C¡ª8c5-ÿ€ª"ö³p\* ª'ZOs$Ñ®WY~^}˜J5¨Q£eJE ©*5ZÜÈï>Ç4©ÕK'P¿S^{âEîyñâ´’•¥Ø…´}Ç·HªÉce]¬Û«S¥F jÔ¨J¬ÛªJMM%ªjCú ~“¢4d(_· ¤<Åï{½¨ªÊÞ53øY»‹ZåÂCûÞô;G}ppà nxz¥ùÇ•äÊU±Ns8ú6?­Ø¬ªè¹Y%'õÚÞͶYK!¢<5jÔ RÙ8쪊ª9’JPRQU;±‰vöz¨j¨>;Þ’À»_¯*¨÷i#æpCÇ« ;Ëz8±|î„ʤíöTŠ_W:鵜x>$$õ4õ/– ºØì»­ÈrMãÆìܱ•µ«W°eÓzš4m^èyUQQdIYôÉ„Ë/“xU6®¨Ì'¯ôb@– 8Ṟ/ŒaÃo툶KnëÓ^âÞæòðˆ1Œ|¤O½÷S¯©ÅæñÏóÎ~/ì”—¯‰§½c!· ÀÇóÒ+Q5oölΡ‡&kÂ'TêKWrÁI·ÇûÒý:QŠÓÀô§ò^§¦L8ê¯1ðƒyTv›®QªR»ÍކHUA³Û±Û%ì6•RUì6;vLœ²Œf³a·Ù°EªØ4*eoàŽ¡ßÑ«Y9ìø‹ÕBëÙ]´{ti/·§V…G¨Øõc–Ö¨Šõy¸Œ ¹o+¢ìvª5ì Œãæ–Õ°Ûí˜g[–SÌß`wž°¾ÄÀ¹ÓÖ¦3å„ú²ôú`)£zTä—o¦ÿ¸ý¡_~}ߥMíRD¨mXùí(7¯Ú¡«#Ó}@ù0;fÕ&åŒÝ4nÚ”{ŽPÍnçšîOѧ}'ʾq?kÿN§ç§²ë‘ŽT){_~½ͳ×WÉg®‡&”¯R½ŽÜèíH­¤ç˜ôË®)fÝ(ÅVp>d)ÿ|(6"5[þ¹.>‡Í^ì{?..Ž»zöáí7^çÎ{î#±L"²|<= ÑåÐÝ%’ÈdÂY‘¬ü›½§L™r^wÜ´iÓ3®“™FŽ7ˆ¢(DDÇâm¸\ê9Öñ‚éøt §] SX°” IDATœöOòû¦¸ÂŠŸ»$+#ƒO?yŸûúô#&¶ð]pyþ<<žöîÝϾ”DE†“\¡,’J“˜'*V.‡LƉ"¢b‰ˆ:Mál'NV¦`+ñD .wÑIlÎ0\ölšJnއ a (*aaa§ì œÓÌÅ\ö÷ñ› ް(agÞÂ~A.b>¼óÏþšGò±;l¬ßñÕÿœE£n:õ¯{»«Øòÿ2ì8\g¿ŸÓÔ@±û9õq ­„ó´õynõp¬\v‡øù§qº§œÑårò@ÿ$$$ÀIç^ÓT#tg‰e`ÓTì6 EUE¥ Âåd\*v› §ÃŽËé 33“¬¬rr½DGG#çßerá¸yhý^LÅ…zIg‡vs÷[ó¸û?ÿõð_ãp8O›±¬P±B‘Ç,Ó´¬üyüȲ„ËéÀé°c·‰XA…¾dl„‡‡å&-#ƒ½)p8lÈŠBtd$Šz1Ú[³Èï?A¸è, #X¢m à ''‡ÔHOK#,ÌIt”›ðð0d‚2N|ѲŒËiÇNd„›RÙ½' ‰èè¨"iRAþ=rý&Z Ç(±L‹Ì¬l:D à'..wx8.§UtdœHQœN'±Ñèz‘™ÅÚu0 CL|$B!Rþ8:aáá”-“HÙÄb£#p:§ÀO„ÿl © ááa”TE%Âí&#+ ^ÃS7 ‚pÂIÆîÐˆŽŒ$:2‚R¥¢CSE€!"È(î…+ N‡UQÐT w¸‹ØèH|~]Ì€*Bá CQpÚm„¹œ„‡‡æDÓòºA§ 4TEAÓTÂÜx}yƒAd‚P$ÈPU—Ó!‚ A¸,ƒ KgÑ—ƒ¹û…¯ ªpýK|÷Þý”¾Ä# 6œ1¨’ ‚ œ/¯[´d£uÏáüöÓ[Üþò,Ýû"ëçÎ&Õ+:t ‚ ¿/ÈÈç 26ü¢s÷ʱtzh ‘áA„‹¦ ¹¤G缓s™÷ÄÌŸ55çПü¼ôg¾™¼—ÞƒZ3µO&§é zgß|¾C±|ÙÆ]Eû[0÷Å!,Î1èùâxžîÛŠ´U_ñø¨Å¨qWóÑGýñþòF-¥ï}9yÓšÝ2€&•Ë1dì2îo®òZ³Öì¾k4=Ú Mc‚ ÂùvÉG‘±Œ<6Î}Ÿù+Çr[¯ÜôÅdž¿-QOa[†IÀ{„_ÿ‹ÓçòÖ7›ô5\ÃØ—ïæµï6Q±Ñ­Ü[u+—l'ÛåßͰ»X½qºñuoå›Qwƒ³=3Vlà®I€ÎVÎê‡]<Aá_d¸ËÔ¥c›–àlÏ•¯ÐôêÜñÀ`¬eÏÑ•qgï;ÁÝiã{ó¿zôöÜkã§)¿áA£z³k86ˆŸªQð·j '*\‚èVT.…Ó¦"Û“ùxùo,ׇÈb‚ ÂQÐ\r¾§z/ -,Ô£8ò£éX”ÏнùÿÈŒ\hwg"“?]ÌïÙLm•Clr8'î5<6Vœ}AA¸€.“A÷½%Þ""¾D\MäYÞu%N¶ ‚ ü'‚ Y;‡ŽÝbå°qÎzjw®EÄ wŒG–\…þ†pö®>P(” ê>ô ¸¥UA.À bæÇC·hk‘]×Í[P¿jÂy9`^NYi9…#`6yA °‚¡[O4õXšÂžqü¹s(åkF²{Õ· [šÁ—¯^ƒ&I€ç[–®éO£˜Ý´í÷1³–>H϶ÕBϧÏcã–¶ø¶¦Y§Š nØšßۿˬ‘D¿ AA¸P™ IM S¿¡ íÛ€G^ÿ„É_O`ô‡#(—ñ#_x”oÖü{G²t}†«;`Ò‹7Ò´ïg¬ûu*|¾¹ôô»÷¬á™nðÄ 7Ùt(¯`½Ú]A§äò4»eï}¿Š¶ÉaTnz37DiîîØ³Ž’k@éš !°–;Ú·ãHé 8ÅyA„ N²òç5Ÿ2e {VŒã©wfòÄ›ci˜ºçþ…{y‹2­0òÁ&œm+GÓ¦MÏ[!·LŽvÏÀŠ_‡où°lá8mR‘ Æ“Äåv¡`` pâØ[~ŸS9¾]P÷aÊlªÈb‚ Â…pƹK¹ÞK^HÅæó(Šªà°»O.Ùp»mǶàäÁ=íÎÂÛ©6‘ÏA„ ©ØŽŸ^¯€/“Ý[WòÎàÑÜ|Ý•h— €™62cÌ$ð|ËÊUá5A០ØLÆG/>ÈGùÿ.ÓªïÝÙ˜øÇ%)`úa |ÁÔ'%¼ÙGÈôèDÛÅl©‚ ‚ð 2žzû3"6á…Ñ+Pí*‘—(ÀH¾ª1Éâ< ‚ Â?N±Í%†a§jÛû¸³–“½sÞç½i›‚ ‚ üí #4~·›ÎO¼È•6™Õ†2kýQ[‚ ‚ œ[áóe„þ_†ž ¯ÌÃÃú0Y—â5&‚ ÂÙÇFü2z>Û›1³7cQ•Z3´o[^¢3×µ&‚ ÂŒë|:Ÿƒq ‚ ‚ðÏ#‹*AA‚ ‚ ˆ CAd‚ ‚ ˆ CAd‚ ‚ ‚ AAd‚ ‚ð Š*Ž3Ðu ›Mý[AøóÏ? DEE‘——G0D’$ìv;š¦¡ª*š¦ü[Q ÃÀï÷õÏ 2Lo*ˬ 7ö*Ú7©Œò/:‰ÞCëùòëE(‘•¸ñö.Äۥˢ\Ûf¿@›—ê°cåm8¤¢eòû|HŠvA3[A¸ðE¡L™2”-[Y– x½^òòòe¹ À8¶ÈŠŒi˜ø|>t]/²¿KÒ\²oõx:%—'))‰Ÿwæ]ÁÒ™1ªw<8€m©žßIT$Dè {õGr‚g¹‘•Å;«³tÞ+WBåkŠ}\÷üÅGOÖ§rÕª$'W¤^—dÚ šJže±eΛ$UêJ¯›º‘””T°Ü=x i…£Ÿ=V©+½{÷¦SryêuI¦×ˆ9ä…F´?í±A„‹dȲ\P¸Â\”*UЍ¨(TUEUUdYFQEAUBÙ E)>pI‚ŒÌ}¿²>rs–þÂÿÊ»ŠYà íO/ÎÝÊ€›¯*aÃÀë ES¦îç[ç\Π®£­böï+æñ³g­ÎM=ï •³˜ ºî+˜·PŒÌduF^ÿé_»ÿo•-f³ÐÓù¨ýõ¼úÓuÌüe3›ÖΤÍÈó„Ž‘X³5ØNêùrâD&NœÂWŸ¾Ê¢I³ÉÒƒ\7û†æ«;3{ölîø`<úÝÂo¿e>NqÇA.ªcA„$I ú²,4•Øívì6;6› U;Þ|rÙª&[½Õ*–!L->5®!!©FAfcλýéqo’ê¼Ê~è·-ÿWôõµzòÆÐ>4½¯7’+Q­j2ϼ>œjT§jõY¾'ûŒe2ý)¼pueêu{œ¥Ûö°hì3TLN&¹êüv0”=عzjþþ«’\±O[G ÿ׸Lgþ¤QtJ.OÓÞ¯±pù†õ¹’^#†Ö±rXþÝ{¡_ò7=ÏôÙKYì;~üô‹¸«F’“«R5¹"?ž‹'ß™û62ï§9,Î1X:w6Ë—,aþ‚ŸÙ—(.ÖMŸ¤¤ ¡lCÅrLý5¥ÄçE +ÇÓUãÄ·Ê¡õ³µ/—É? ¦nÙ"êòÜWÃØ».ÈE•¯ÏMw_KõºmhÛ¢µ«T¦I›æÔ5æàÏ Ò´Õµ´êБV1íiqm :Ýz/e7Ìå ÷ôÇA.>넘¦IŽ'ǃiš˜¦‰eY˜fè'¡Äé›·/iŸ н¨XÁÃ,ÿ#›ë= Ù¸¢y+VŒÈøy¿«dë>‰JÍïæ[¾fbLîêY«k|#§0<~#ïx‰O¦-Ĝߓ¯—í¥i…Ú§-‹l‹çá~$fЭÜÞæÚ=üóÝÉæiWHýý+Zt{†¾_F»«Ë½ïWvìÊ}&¯ß\‘q´åùÅ-ûõ Jÿâù»z±^7ùjÑUhä1mصôÿº_~7Ÿ$vóòí}@íÆ±Ëï³èŸÿ¼š8—„†„4°‚¡ $ ªƒ Ñõ‰rþØ‚ ÂE0, òàêºNZZ¹^/`³Ùƒ šT.Û £8»VñÙû2=·Ä¿ %]Õš~‰Np»Ø³ø!®(óˆ÷ ¦èÜÛ³¥œ$Vvß Õµp¶çWUų¿sdg, ¢ìÜw¯×î Kyï¥ÿcóÑFÀ®*$ÄE£g¤°`Ò'9zÂ9–ÎÜwºÑ¢Uk¾ÝšuÖç£jó;i¥¦çËS8ã QÛkipEep¶§^õh¬`G¦‘wô(YžLìQQø3²dþt2óïfòû|d=Bº?ì´4<o ówçVvA¡„_·–EZZsæýÌœ%ØyЋlsá¦T©(âJ'R®rMÜ1eÙ»ï‹-b×®]ÅÞ¾zɃŒSÝI Ûi{u$’ZøgoX¹: (ë¢qó+H®Uº6™;ÚÔB±t~þ ;£öåòbïO9(ÇsC”Æû“×`ÆÖaÅ+·°xûé;zöͧVíÆŒÚ—ËÓ75£VíÚ\Ñâ#ŽägBª¶ÈäW’èÚäJ’’’¨^»!C{¸¶M lZ"ƒfÏ «ô!m®©Oƒ6/SíÙBÍ!RMû†zó†Ð¢þ•Ô©-?ò‚o.ý^š‰uùxP nkQ‡ÊÕê2hÖaÜÖ˜75cüÊÔü@'’®ïãÕ;[Q­ZMšw¼½Â$ºU*7€[ƒoѰfe®¨ßŒm­èvårº^;˜½ÞPùMý0¿þxžážIg}ŽÔ¨+ýó4ZnJÚ•IJJ¢v“Ûh}Ç D(°eÚkÜ1ìgf¾r WÔ¬Í5«Q»aWÔiG”- ÌÙš:×Ü̹kètÍU\7höƒ¾Bï“s,» ‚Pr7nföòõìÏðàv; w;wâ sî""ÌA…äd¢ÊrðÐaÖ¯_Onnn±û’¬üÇ”)SÎk!›6mzÊç¶L”Û&´bͤnhÅ ¼dùøâÎk°=6‡;&z*àó`há8T ¯ÇƒÝí¾¨u™º\¿…Ýi枦µÉJᮺƒy}íç”+h20ðz¼Hv'Îb´òû<°î´6ã’g†:à~ÝÕŽÓV´NsvÍ£Fó^ °’û[–;§×îõd@Áiw^Ô‘9ÏGÙA„3Û±c'MgòÂ?¨‘\– I‰”Š$&*’˜èÜî0\.'6UòLÖ¯]‰Û¥ÑªU+’’’.L†€´eÒ£û@~Ù[Lô#Ù¨Þ¾OßÔ€Cæ4hN7Žü[2\9ÀeYœ¸Ý®S†çOÞ2˜Áƒ‡±8}.ÿ7fÙ åWp¹ÝÅv§û´€¤Úp 0Bûv»ÝÅG÷BÜãtirî™—;ŠH·û¢ý}>Ê.‚ œ™ßïg݆¿ˆ‹âæÎmhßæ*W*‡ÃeÇátâr¹ #":’è˜XÊ–¯ˆ×ë%33³Øý]’ŽŸÕ:¿ÌŠzâ7J7—B“{ǰªå^ W|ñÙŽÈÝ;êMzzwwV¬ý?Ê»þþpÖ’=šz-Z‡ÆµínEv–A¾ †É.×à~R~ÿg¾éÿÉeAø'±,‹Íî£ÿ€»©UMdY"×ëgóÖhšŒÝnÇå Ãår **å+&³sëz‚Áàåd¨¶HÊWŠ<ÃÕÚFR¥*çåxaåÛ‘’’rQ^›l‹§YÛkÅ;UAøG¹¹~jV©ˆÃnÇ0LvE“ÑT6MESì6;ª¦{ÊNŸ—,ÈAáò#Ë2²ÓAD¤M“A ;v› ›=4„¸ª©8ìl6–a`YVh|âö'ªT8Qæ¾õ|3é[¶-SQdU•±Û4ì6;š¦bÓlhš‚ÃiÇér†æ99UÐ"ªS8Æônãáv]x|Ø2²ýÇÛ×rvÍ¢RÕÚ´êx ã~O+á^ –¾‹Zurãíw°1ýäYduü¹Š~÷vâíÙ‰“ ‚p‰¹\6TEF4UÉ44TYFSTlZþÌ«’Œ¦jH’$2™yöoa±Ñ–ëþ†eà +ׂM[¶ðý¨Öç°W…ú·¿ÏÖmëy¹ELѧ¥Hn|t$sß½‰•¤bˆÓ ‚pIU,—€$ÉHr~†Â²Pò§—d I Mo¢ª¡LÇéˆ>Âñ뽪K>œôx8‘n·G½½Dî(°|h§™­OÒ`ïoûñ[®ËànA„ÿ29?Àd IVT $ EQÐì ²"!«¡ ãTM&"“!3‚¡Ð‹cð÷úLN³}0dUñ†A¸‚ EV%Y‘PPP$MQQdÉ’C}6Î0!•øNÀò±vö—ôëü(µ{t!Ñyñ‹P¡^Ò–?É ø+# Ή Â%%å÷µ™PSIh†V@’Pó¤”Y™èÜ»›Å9®ç)?S8]3†Áá}»Ø¹cG<ÅÊj.)>êµ¹Bƒ²M¿™LoÑžy™©ìܱ”CÙât ‚ \`²,#Iäª*#É *2š&!I¡K…%‚ áLk$úaÓ¢øõãÉì÷~ÓXAYžLŽM#A–'“_á@ÂôþÅÀv­hѪ9OÚ>Ï“IfæQ2MƒìÌ£dgz °}ù×”jòÛ6¾Jý²ŽÂå³° ‚ \ÜËB~çÎPa!É2ª¢ É– >4åôÍ%¢ã§püM¥jÌÆ8)‘úûDv’ÿ×ÏÌ|ú}8ŸºÔ(X'sÏfçÜ9rW–ÒN|Ìx¥MÈŸMvY3ž¦ü²ƒ&'ªæÆ’ŠŸ·EÌÂ*‚p‘3’ /¬Ð( fÐÀ´,Nü}h Ad%L#Ç×ñ@¡LƒûII¹ÿ´›íX7œíéÙ±ÎI‘‹“î#VÓ}Äé¶6ÈHÛKù«;b/¦©Æ{` cû:¡+1âÎA„ Î0-@Â0 °B›†…a˜ “`Ð ýŽ4Oÿ,šK„îruèWj3í¯ªÄôm%h–°|ܶ†.Ï=BÍè¾¥¬#¼Ò =^XL·æ•‹í±!faA¸ÈAF~†"BXX–…aX¦¡ÿaš¦iœ]&£Gç\˜)S¦ˆ3ò/ ©I<·d=ö¤—V‚ t²Š.çtÐú~ÿw(±$—‰.v1 « ÂÅeš&¦i`Z&†#ˆa–I ¨c¡@ä ÉeÑ\"";c©V#ö"Q!¾\âEÕ ‚ \6,3”©°L 3Ä2LÌ ‰eš˜¦‰aXX&Ó÷ÉÍ%ÂE¡ë¡7bP×O?t¸•Åæ; Ý}bAô`0 öSÇŽiA‚Æéo·:°c‡¼ÁóvlA„"˲š†e4ÍÐbXV(1,“€ažv?™Œo¾ùë<΂¹|ùrš6m*Δ@ö®©uý"–.y˜‘­Ûqý÷븡Zd±ëî]9†öý¼ü¾ö9âòûžn5ûg¶çûgíüïÚI,Y÷9ÉagÙÔòñuÏF¤ôú›å‰ÜûMM~Ô G1H Ï&¶êÈ—Kþ$!YýûÇAøÇ¦2B<±BM'FÐÈï—a4L #ˆ ž}Ÿ ˲DPðfú÷0âîŽ|°"›Ç?]Ì«œtñÿ&·¼FƒknáÙw_)4Ú™ØÝ¥Co6»›nÚ)ßÔéL~ü#ž|oqÚù½×«‡¹éõ›w-6ÀØ<ïcÊw~—¦•\â !Âûš`š IXf0ÔËS3h`Y&LJà:SrB4—Ç~dzé\ÆÍZÂÝËy6ñª;XE–ÀE‘‘8ëÁ¸TÚôÁìî`ÈØÅìÙ·›m[Ö3~P æ o…OIÂhô®¶0ÈåÌdø#4&Ž;bÌ›„Í!\p &+ʤLÖ¸2¶2lz*ÏÝq%rͪè¹Ñ³™ýÀK {í>ê…T,‹!bÁÅšÉ$|†„Ñh@2€Q6`2IH’Ž7ùëÿÁ®b»K a„ˆ})%&³Ÿ¸Ö$c-cþ­LÖ@ã¼jäµw~¢]íŠïÛ¨è¹âz…~½WøÜB!V \”y ‰YwÉ`ÀèÛq¢kÞàC–Á$WpºÄÿã›U¬þ¼È² Y¹Ëé?èV¾Z}¸DóÑís¸¹é5,°y(Q]»*¬¡±í¹çÖöÎbTJT¬|q IDATVŠäÆ{Vñà@(Ä ‚‹2“!IœU_ÕuMQÑtÂ+%TܪRu™ {Z³3Ý4¸¹µ, Õe©ÏG+~éèX¢KÊ•Å6ëŇ+~Ã¥š©Ql°®„ k¥Ãí¿ñÜ…X@p‘>wjÞ2Ÿª¦‚îý]S½¥ÆUCñ•3Ð5©bA†ÉX´Is¥òîǘðd¯2K3 þ¥Hâ]Vf³ÉCƒF1¢ŸàR2| ïH¯ûtKTtMïhšP»¤”ü²wEgòÞ£¨ºBž-ík¾çžÖݘqÂÉ„OWpCâV‚KÅíÆ­ˆ]G@ðoGÓ44MEÓ5T<ª‚ª«^åUŪx¼H€|C±ŠŸpϤŸxýÁ^¼~¶ÉÒ‡gƿÄ믣IÝj¢÷/bli;Y¶n?-{÷£Y’¥?Oìø•Ù«Ó¨wÅ5ÜzÝçÖRøÔNç´~›ùO÷Àt3]nûQV­Ú„ËÇ5×u ÊX¾sçdgß_ˆiÞ‘F¥|f]É%iË&öÏ¢ZVôéÒ$è5$§ÔÉœ1^F‡æ¥ûrffÓ–]œÎrѬkZ6ˆîKÀ™Îæõ›8jÓIhÕ™v‰5Ëéëݬ߾—¹WvìDýè*íW€C[ã„ܘNmé³ÊÚ.Î/ºæÍT蚎¦(誆¦hèšæUeUut Tl&ÃHÏïsôèÑ’?û?çÑá·ˆãb\ûÝ»?c&­#ÇUú…c dï'o0ù“]¸ŠÕJ‰hj¡i­ß‚¡àÙ·øyF³§b6»RyîênLüi;³ŸLßGæ`º†‹ÊïßÅå­;0`ÈPvŸÉ/ÀØ’×¾7 }‡ã§3p+rÐFnÊB%¶ û·óÕöÌR_sxËL[_Íóóv‘™cÇ¥ë«T&tíÌÈþ$?gý{´åýå‚î·ÓÉ?Ò¢ó ,=˜MÚò1tn7˜]ž*êWßcKÆtp£^ßPäZ©¬íàü£¢¡ë:Ц£ê:ЦyT]÷ ª®áQµ`3‚Kû±dV©½X¿ûm”Q7¢ÆeWóìôÿÐÿsѹ¶€ 0Uœn‹¹äYÝaG6WlÉÑMó™­ÜÉæ_¡VvâÛÜÊæ”›é•L@,Ó~È{ì¹Keî=J åü0Ÿ7Þ¹6ÈL€L‡A/³æÅ~¼ðáç¼ÿú0žÝÞƒá=ª¦_õlfÝõ,o~6˜:¡2S«Òv@pÁÆ #Ùà­&.ûÊ‹û”X ¯~‰?Ät‰t'Û–Ìáí'&ÐâŽÿ£N¡(ÿŠUÕž"iâ`"% Çñs^*Ã:7Ì‘4hInýv_ô}W¿ýÝ^YÀÈþm¨{Ãh–UƒÔèdkî~èqöÖ=ˆÃ5Œƒ+ýQÌaU7Ûûo~³šW†1ïå~Œxã –L½¾J¶êN ¬ƒX²rµÝÉ<Þg0 Zoah»ZA$q\œÌW0……b±zoã“™9@ ÎíÊ÷rÑ¡V¬a AÉÀfwCAv£âýz|ë<^u<ÀÎË#ÈÝoO陹4¨a­ÛÁ0|Õ=%]G–$d£ŒA–1ʲ7Ðe$ h—ˆ C¸9yä0«rU:T·@U† ý¶„—o€­R´r[³žwÒ¬ðÙ=:~…Qð*ÏÈÅl%.6¢Èvaô'Ö&ƹ„ô´#äºÀ[ŸšÖ’—½wº¤èªˆØ†MÀÒ‡k;'`1IÜ8tÏ´á"ýQºm…ó¥÷—딇#ïàŠÚÀ• º%–ùÉéE‚ ]É&-í4š1ŠúõkXx|Ïf›Ÿcß+&Itoj¤õý›xø†&E2¥Ú¦;YòÊKtyac‡·ý,{;3mÕfþ§EÐýZ–mÙ'Âé¯hÿvÁkû=RƒMßÝA¨$i{`Ÿ ‚ó‡,¼º%’Ž  FL>=Ù ²l@ °‡UL—@Šä¦/‘´ò}6ϘͱBJ¦õZô€ùlÁœ±ÛIùóWÆ=þ#’–IŽÛ;äØ2ɶÛÈÌ9ƒ''Ëûo›U²ÐñþÁüøü3,ý3‡ÃÎÑýÛ:×¥1aצd2NßÃü¦òÝú´Âí¥+JfÚ÷ùÏMå¯ g®æéŸÓ¹¥cÃ"ïíO¥5ßnÃfËÀ¦©äØ2ȱÙñø¦,"ê4£µºœuÛ¡(ÙlXú) Ú„ 0ü©°êŠ“l»ŒŒÌ‚~ÉuúÖ^H:Þu›?^Àž ÎŒ=¬]œAÏÄ¢ÏNlŸG—kº3ôÕh…¦R"¢êAÆ/ì?îÝÉ_Û~#&!¼è ]f¿YhÔ=šŒƒ‡Éré¸s³wKmc#ËÕ¯eÙ–xýËìÛ¿Ÿ¿vïdѬç úÃü4ã¶‚~ÁØ^e]@P™ ƒ÷~• ’AF2‚$K IȲŒ)DÆ KŒ"“!6Ö0š@É)¢KѨ7«¾}îCná S{º‡Hì\?‘·\ëý,L¼¶³3Ï.î[ů“KÖìøŒÄžOñã;3 oׂ÷¼ç©x g|ÁïM{ޤËäþ´ùöQºÝ1žñ7W?7àøQ:m3„Ï]NŸ6^‘³g?YÁUÅÄÖÊTiÕü2¹7OÌ:áý}ÝÕ<ÌÙt€.õB1Fµâ£ùÿ¥S¿N< `ÄOKŠÖñgÛ‰íßÐaàK¾ßVóëdùÁr^èïÍã4èü Ÿ?ö×µi@‹ûÞb|ëÚE20¶ÿÀ”bµG"/ëÎŒ1K¸©cS_z©ß-)Z‰×Ÿmmo™N—o¥¥¯Ï›Ü9…Y…ôW÷kÙ¶ÍfŒ@òòW¸ñá¯xìãÎõS‚±½Âʺ Š‚ ²AFÓÀ {‘‘%“lD6‘tïz Yò¿/NÒ}KCçÌ™C×®]EÏ^Âä¤,äòž±tË<./öÅ®¹ä¹tBÃ-Zà=^ÁŽÅ\Úñ*.§Šd2a.Vô)7eÍ®ÎÄY¸ÿÚú¥ÛnËD“ɲ–,¦µùÛÑÜ:ÁÁ²ÍŸ–_D ð8íd;TÂ## ­€mȳÙÈG&&ÊZ,r‚W;wã·îo³pêM¥–òÏ·ÛÈuCdõÈ~ l›JŽÍކ™¨¨°rõk0¶Ÿí•õ™@ ¨III<÷߯yýùÑÔ‰­®ëx<*ûSÒˆŽŠ$"ÂJddV, .W>oLz޾}ûrÅWˆL† l¬õ[1²Æ_ôiÓˆK¢_¡òñ³«¹QqÀãeB,¥GÄÁ(FD•¡«R Òúa…+“ÅJ2«B…µZT¥UŸÐU7Yn•çîQæ j"”ŠÚ&å×¶²ú5ÛQ¦íUà3@PùL†÷Ö–0$ŒF’Œ²“IB’t_»ÿéLd ŒqŒ_³‘Á©g¨÷Ï©îZ)¥Óó¬Òz>UX ! ykç¡‹Ò¶¿Óg ˆÛP¢@Ö]GG20úvœèH’„,ƒI–E!(Çàa‰¡I3¡¶*—ôX IÞðB÷ÜÒM×)\ÊGUÁ­­]"@ªæ-ó©jÞÒ⪦£©ÞR㊪¡(Þ*Ⱥ&¶° .t7{¶,áÛù«° ¹y@ ¨\áËPxCݧ[¢¢k:xÿCÓt¡]"¸48¾u&× ¼ŸÒð‹1Ò¶Ì䦄ÄÅűúP±’库ï_îH\\CÇÍ$³œŠæJeÊàˉ‹‹ã­E%•DløÀ«ërÛ6+§F‡îfÉ;£ˆ‹‹£ëˆOKئ¹RÛ:¸¸¸R5cá·_*i{ ~9¯¶ Ÿ Ÿ ŸVº_4MCÓT4]CÕÁ£*¨ºêU^UܨŠÇˆX÷-‚ ÁEAfÚÜ<ƒ/ß¼‹š¦¢W½-m3;#gÉÚM\Ù ØVMÉB¯Q?°`Öˬùi%Ùå–&QIú3¯®áîÎ%·‰Öi3”U ?g˦¹œÉSÊýÞ™{6Òâ¾wùæ•Ûˆ*¶}Ö`®ÃS‹V0ã©øš1Áà·_ªÀvýr^m>>>­t¿èš7S¡k:𢠫š¢¡kšW•UÕÑ5P=þÏ)~ . d$Úu»¬ÔF“DLÓF4‰¯[j{d­º4ɯë}mEvcš{qYÓFÔ*E Þd‰¢qó¦ô‹ªxA©+Û·¤al)J®’™Úu‘P\3&HõK¥m÷Ó/çÛváSáSáÓÊõ‹Š†®ë(šŽªë(šæýQUtÝ€¨º†GÕD&Cpñ“•ñ'’®ˆÙý´©•;¿?¥v]S±+Z…ß;Г‚JåÖ øû蕵=‚ýù´]øTøTø´ý¢{y¢{§NTEõ­ËÐQT UUPE¬É\ܸ퇙ÿÑËÜ1émâ"E‡A iHº®zWyJ )*º®¡s®—®‹b\‚‹Å‘MÒ¶]XJ))^RY­çWmô|Ú^– ë¥Þ/§§‹O è#YG$Ùà•y÷)± ^ý‘É\´„ŶfÂÇó™=á26$§Wý ü¨¬VÉÓÂùT=϶—¥Âz©÷‹ð©ðéÅàSƒ¯º§$,IÈFƒ,c”eo !ËH0Êd.~¢k´B—üGÔ™±ô§dZއ 29Ÿj£ÁÚ®UÈö²UX«‚`ûEøTøTøôüøT– H’„Oñ£ÁˆÉ§g"$ÐA– Hˆb\‚K?VïÄî'R÷÷Õ`’K¿QÇ“ù"ÝÅÄÿÝBu?7¨Éø›d’±K¿ÕìX–> »±•¿ÛÝïg7›*i;å·]WÒYóÉfš ™AÇFaê¶×/§§§ç˧_t!$$ƒŒdI–@’eSˆŒA–0E&Cp P¯åùu,Í/ÑbéLÝ™ëcð 'Ùt¤x‘7K?~†AÝ*õ}*™ª Y¹Ëé?èV¾Z}¸DóÑís¸¹é5,°yp_Á] 6úh™j£.›ÂÌ'z0ê¥9dëÅ‹üeÚÈAôzø{dsùm÷Û/l¨Â _üÚD¿Ÿ Ÿ Ÿž_Ÿ dƒŒA2b%dddIÆ$‘ F$Ý»C–üW’î[:gκví*F+Á¿–ìSiœ°ˆo\·È ¥¸³9~ì4.U&¶A<æ¢7[fZ gòL¡ÑÄׯQ¾“êNŽ>†SѱD×#®Fѧ3“'³p©fêÆ×§Z97øŸ9žFf^>’ÑJ£Fµ‹>+:·µfjG•oák ~©”íúå|Û.|*|*|Z±~IJJâ¹ÿ~ÍëϦNl t]ÇãQÙŸ’FtT$V"#£ˆˆ°b±Xp¹òycÒsôíÛ—+®¸B@ Jçl1õÅǨ]«:ºŠ¢r0õ(V¢##‰ŠŽ$,¬KùùNÞ˜4¾Ì CL—@ (‚$Q 뮣# };Nt $IB–Á$ûŸ.A†àâ «Pi‚ 1HgÕWu]GST4]§ð’U·ªˆ CpñãO…Õo»PŬ˜íBSøTøô¢ö©ªyË|ªš·´¸ªéhª·Ô¸¢j(¾2æº&¶° .ü©°úoª˜²]¨b Ÿ Ÿ^Ô>U} oOë>Ý]ÓÁûš¦Ô.eÅþTXƒiª˜å·]¨b Ÿ Ÿ^¼>Õ4 MSÑt Uª êªWyUq£*o à=E&CpQH…5P»PŬ˜íBSøTøôâô©®y3º¦£) ºª¡)º¦yUYU] ìdþÕRa*­@P‘ EC×uMGÕuMóþ¨*ºî @T]ãú¼Ät‰à_M Ö»J«Pżøl>>ýWô‹î]ä‰î:QÕ·.CGQ5TUAU”€k2D&Cð¯& ë¿]¥U¨b^|¶ Ÿ ŸþúEÓ4$t]õ®ò”@STt]C‡‚É=Àç-‰$Iâ÷߯RûEQÁ…"ºF+ô|c…Û+ü T1+Õ/T¨_„Ò©ð©ðé…ð©AÝ`Ä ëH€$¼2ï>%VƒÁ«_Tqûí·W¸æÌ™# ÁßJ ë¦XK¹Éµ¥ XÊÊïÅYÿpUÌRl¿ ª˜³þ᪘§§§¥ö‹ÁWÝSÒudIB6Êd£,{ YF€Q*¬‚K*¬Ú…*¦PÅ>>>-ÎI$I§øŽÑ`Äd0 ù²è ˤ{X Ò*ƒÈdþ ”¥Â¨]¨bVÌv¡Š)|*|zñùô¬@ÚkÏ=Ll­Ÿ «Æ¾Ã©DGFa :*’ðˆpªYªáÌwò¿×&VaA†@ —6IIIŒ›òÓ'¥fL´7ÈP>ND¤•èè("Âà ·V- W~>¯û‘zÓ%‚ ‚Û—cTÜnÊ[FWÜŠ¨ï#‚óƒ$Ð4õÜDˆ®{•X% ]Õ¼U>}ªØÂ*ø»ÉIù‰„ÖãH9}€GÛ5eá¾òm!Û³ðIº^ÌÉÔßH¸b‡ò‚O¾93ÓHNN.øÙsàžbÉ»S¶2oþéîsíé»æÐ¾ûVnßÀ]ýºò~aDÝÍŠwûÐoèý¬[4ކòç)O¹ÎÿoVw—胡ÝEž#EUQ4 Uñ—çÄåòàp8Éw¹q:Ýä9œäååc41 "Èøãü)(š¬5én8Œn¶R;!”òІ„Åß±!‘ÕLÕ™šaÁ+#1`êrŽ=êýIzzgEŠt'Ë?|./ÌåýÉo±ìÓ{™òÔ|Nû´à•ì=Ü;5…–&1í“M¼Ò9… w—Ëö³º£@ ¸ô0 H’ÎþCix<Ü.n7‹át8Éw¹ÈËË#בG^n'ŽÅb±`4–^/C”œã¼)(šé6|Ñ!FjvE½:aå::¶IwnÆŠ%¦&Gèå΄¤çda³¥ãp™ˆ.X•®¹O°vM÷i @“®Ci}#'³£f ެ¨þ0#@’èzO?¦ýß^ÃÚdÁ³º£@ ¸ô$‰øšáü´tQQÕˆ´†cÏu››‹ÑºAGÓ4ÜŠ»ÑDJÊ¢¢¢ A† 0Š”±ƒª¢*„†8FŒóîÃîùàCå>¾Zý® õ=¨ßÿ`ír>ë묟|;-&{oØ÷eæM»Ÿ:aÞAÙ®hÔ‹ñÉ„É;ã eHl'sysÎJÔnÚÌTg…Ò*eË©uÇÿ} Á Ë2W^ј/~ÝÄ—ßýJƒºuˆŽ¶R=ÒŠQ–Ñ1 yòóó1HÇÓRIhXððpd.=]=–u›_%¾nnûA&]Û‡o×_Ï“×ù¢¹-F¹XAÉû»âÈÎ5²èN@p‘c0¸æêvìØ{˜'Nc0šÐÑ0H !áVTò]!˜MFl™éD„‡'‚ Áù¦rJ¶ã‡9š­Ñ(±Q¹‹ôø;wx­xÎ^úfk c•vr$ËAóèpPŽ8Tb}Åpj$´ sï@(pêÐnb6.¡ ÔÁÅdÔ­[›¡zðí‚Õ>žŽ¤k(šŠGQq¹\„YBQ]¹Ôˆ áòæÍ©W¯aaa¸Ýî’ï'ºTPTF)PsbtÏk¹¡w7&ÿ¸·êέç²{ÃÏ­(œÚ¿Oæžäò¸HïÅo®C¿Ûkóþœßqèn6ΙÄΘ¹¬†w° mNwç;ü¸þ(šë(óÇI¿¡W]!ÔÁEdFÚ¶mÉ“ÝÁ€­©bÀ–MFFy9g0¨vš6ªM§«Ú“˜˜Htt4f³Yd2•~ð-;Q EI¶Ð©•Uël´mYn³Ê>·Ê¶¯Fðü‚Óy`ê<†ŸU”Ì\ÿ䬿¶/MÞs¥?­Z  fkÂëß¾I§~™4¹ó-~è߸è@} ¨; ‚K É`Àl2Ñ8!žø†õ½»L|51dY&¬ZáÕ‰ˆˆ 44ƒÁPfQ.dŠp~Ëx_cF·“n³¹ü—d™ç–"¹÷ÃíÜù?;N—Šd#2¬è”­MyeónÆf;0[«S­XÝÿ¸¶ƒIÙ߇lDÇD•˜®¸ÔÁ%dø2f³£ÑˆÉdòʺeLFF££ÉˆÑ'ó®ª*šVú£”˜.øšÏ¯‚b`ä Áœ;Äb%**ªD€q.ȱS"À(Ä-QÔ(%À€‹[ÝQ \âÁ†$yƒ ³ ‹ÅB˜% ‹Å‚ÅbÁlò ’$TXAÖçSAñRå߬î(.=RSS1›Í„„„`±X !$$³ÙŒÉäÍbȲŒ$IH’„ªª(Š‚¢(äää”x?1]"ð…›â]Vf³ÉCƒF1¢ŸÊ‰ÑIƒF‘ç§_ø,`»@ œgDžT ÁùyÐ] (Œ-m'ËÖí§eï~4«Rèï»Y¿}/.s ®ì؉úÑ"õ.ÿˆL† Í±Ñ½û3fÒ:r\çV!žNþ‘o`éÁlÒ–¡s»ÁìÊðˆ_D&CP€ýX2«Ô^¬ßý6 nÚ4OÍeÚãALè±Î|³ê S5&‚2™ A’ÑWÍ¡HMûi7¡gödÂ$²Iħ@ ð)ç"NÕÆâÚ2½Ì°kúñBþ$êØ–0e{VÏH&ÿãŠèº“m‹¿däÍÑbpêXŠ6»ò½E¤¢C­XÂ’ƒÍîý&¿ˆL†psòÈaVåªt¨n)ª‘¡;YòÊKtyac‡·ý,{;3mÕfþ§E¡÷Šž@ (ŠÈd@Šä¦/‘´ò}6ϘͱŠœ’…FÝ£É8x˜,—Ž;÷8{·äÐ6¶h)¡è)‚âˆÇMÁ¹xÂh%µ˜˜^Û[¦ÓåÆ[iùí£4¹s ³ŠiuEO@ ˆ Cà%“\‡aç…°ØÖLþcOÛìh˜‰Š*©*=@P1]"(ÀZ¿#küEŸ6X°/»X«LDTT©†PôAiˆL† ÉÇø5œz†šqÕÊq …þ/m¤¿èB@ ˆ CPK Mš µU@ TÁ˜"º@P(n7* « Šª Û@ ‚ A9ÐÝìÙ²„oç¯Â¦¬u'ß »Š7—¥p`Õt{äòuPÙ¹ä+¦Mÿœ=®¿Éæ²l2ÿŽoÉuïgÁ†4<¥ŒÓm×Dsœ¢ý5Mõô2…YY6ýeö¥çŸ§ "›é›²ö˜ÿ÷/Í6@ ˆ Cð!3m nžÁ—oÞEMSÑÚ•æA’%ðdc+ø«Ìå×ôgH§hBBC@wãt—žEÐ7nw٥ʷ·Û+?¯9ÎÆ–¬|~%¥Û&dþ1ÈH´ëvYѲ㒙Ëy˜è™¨„ô­^( pcˆ’™úîdâê'˜PŸO–ï-$œaáGÏP?>„„â®ÏÚý§ Úݶƒ|8®=ñ ‰$$Ä3pÀe<4}*`KÛͲEKX•«²véb~_³†å+V“fóg›@ Î+bw‰ h²2þDª¦”~t¾Ó[ ”ÚR<’ —ÉϪÃo›¶‘¿g}G¾Áõ;?£%Ùã¯gÜâ,X³•ËjøséWÜÑ£-_¬LâºÄH®ÎŒ´§H>|&ç1|p;ÍÄ£ë8méìÚº€Cû’Ù+E““uZtLAÙ&dþFÜöÃ,øæ ågE–ûx†±] IDATçQϾ|MêYÐkõ¦»e=Šjn*3ç⛕ciÛ0€®·>ÆÛ+¾å§Íi\—IhdS2ÇÛïeÑ VMÂ/Ë·v!T’¨Ó²'c[4áÀ÷ó4z ½B…³à„˜.Dqd“´mkH¹7!qv%…®yÿ/É «*;ݦ¹èë­ç~¯}Å Ì™3‡öõ#1“Ëžß'3ð¶9é[yª9ÝØ ¥ÂŸOW²9’r€Ãi¨ÂÝ@ ‚ Á…#,¶5>žÏì —±!9½\Çzœ62Sò9}: €|[«ì™äd:0FÆñ|C+Ïÿ÷;Ò²(Š“ä ³=ë8Ýš×`ÿÒ‰¼ðÃ):Ý<„¡C‡qïà<ˆÛ·ìÂ`‰áªèP¥Äá°“²k-ï¾ü6ex‚¶ñÄöyt¹¦;C_݈&¶· A•!¦KA]£z~9.ÝÉOûófZ<ð×oõG€ç7õy•õ¼ÊˆÅ‹0OºÎ-Ÿ+8lúœuÜÖÎdCâØ÷í£´ö)ÀLød õÂ|‹O¥HnygWìΫ¾ö1¯|Nk°vªØþSžîQrQ«@ *Œ¤ë•t›3gN‰¿uíÚUôîEÆ®ïå¡%W³dÆ`¬U<»œvÜ „XÂ1Ͻ·®¸ñ`„§Ó…±X{á×åk`6›‘Ëq^]9Á«»ñ[÷·Y8õ&QCC \Ò¤¦¦b6› Áb±BHHf³“É„ÑhD–e$IB’$TUEQE!''§Äû‰éAÐÔky#G~KóËÇpÄUµÓ !+V«µD!͘’ÑLX)í…_g)g€ «n²Ü*Ï?ÜC@PňéAÐTOìKÒ¶ œ°¨e¾8>“!¤!oí<$œ+"ÈüÝDÆÖ'2Vôƒ@ ‚x] ¸PœUC½˜lÓU·¢jAÙsÁ¿áS@‚ä·s*­€æ:Ľ-Yº/ûgvelÛ³ðIº^ÌÉÔßH¸b‡òÎ}î£;~eÚô̘1ƒ%ÛO\ÐÏäÊHâÓéÓ˜1c3lÃSh}wVÊ:¦M›vÁm*¶´Ý,üy>?,^MZVIa·ý(KÌgÁâM%®5€S¶2oþÛtåܹuµhT©;ìÈf¹B×Ñ¡MÓéðÔ\¦¹ÇÞ\ÄN‡øfÕÁs¢Mó™­ÜÉÜ_á‹us9òëX6§8 ²Ë?|./ÌåýÉo±ìÓ{™òÔ|Nû¢^%{÷NMქILûd¯tNaÆÂÝAû4¤F+&ÎÙÈSõ«q2Û%nz@‚ E™*­€ÁË}£Ýb*…ÓñêÎÄ´¿™ëÛÆf­C·k¯‚èkhoõ dþUZíZÊ]Íhœ˜Hø8nJhÀâý¹@*­eÙ$±Mºss+–˜fLqY,[aÜe¤uìÇwòƈVÄ'$Ïð×çpÜ~îµ7Ìæ¦„F$&$Ðvàž¾­ï-Nñ=Íåÿ^ºƒø„š$&Ðæ¶WÙsªä“µG-=€Ðgëâ¹¼t{sš$&ÐÿõÈ,´-Ù¯mº“ußN¢~¼÷ÜmoHýVÏsÄ¥£¹ÓÙ´fëwl`÷†Õ¬]¿†åË—³+%«X„âfך_øø‹ŸHÉp ªì§Ý„F„\Ua’Ùd,8n÷ʹ ?”º& cLK¦ö¯ÅÊ]iÞÏå>ÁÚ5YÜ׫%Mº¥uötNf{%GV T˜Î‰ …Óõž~ü¾x/ŽB™À>5Ó(É(‹›^ A†àB‘•ñ'’^ƹÉí§^ˆTl„Ì][ùmýfÖ¯ßÌÊ [ˆ©ïñf%ô\f¿žïG°`ÍV’“ÿ`ö¤ê éÑ–åû³A?ÍÿÝ÷]?ZÍÑ£©ü±v Âd<º7§QB¥5ù/vïN&Ç¥e[0T«ß•¡½âAªÍý_kC±ýÉW÷ãT»)lÚ•ÌŸ›—Ó!ã :tû§=:i[>ãÚÛÇÒoÚ\6oÛÌÇ5æ›M¹¤Éóµ ÑÍþâ5›Ø½kÏ6þ‘I “Ëe{êŠMt¿˜-kçQïë'Y¹÷LP¶å¥­ãΧ>fáÖ¤Þ×ö÷It—}É»ÙwÜÉ™”’÷$³?i7‡3Š®}ÐÜGycÄ#Lzáž_°¯H¨ÚaÐˬy±/|ø9ï¿>Œg·÷`x„‚ ÄvÊExÁÔ–LTlöBq£]ѨíÍÒHf ÂdŽñf:l'sys΄­Ý´C‰LO°>MJÍ7½@±…UPi*§ÒjG»ÿl€È;¶›jÑ-¼ÃI •ÖË⹬GãFNÃóxkjÖ°Òkâ´©ãÍoÿ“UZ÷oœÍÎè§ù桾DJD7ã¡I3ùåûؘrÙo¿C·W0²[êÞ0šå_Õ 5:ÆÛ7*¨9pc·QïÙàæÃÚD £{ré6a2×·m4dð½õø~× µŠ `ÛÜX+–Öfÿ}ïm®n܀굙1ãqê†,5æî‡go݃8\Ã1(±ô§s-F½9‰V‡TúöI(ÒæÊ÷$Ñ¡V¬a AÉÀfwCDéþ3‡{V’Ûb”‹e$ïïŠ# ¨](¤©’™Ý[ðìðÎDNûŽ»tÅj…ܑɜ*£Ò*ã!¦ã½<2r$#GŽäчsdÇÙyþ*­R8×Ü÷!³?êGˆT{&?>?’±³vž{b®•Ö|Û ØÏÑS9:^¦”Èc9¢h*^%Ú,q6T=ÄRäf=ïäú¶u@w2oü­Ìr\ÅÆÉ:¼Ÿ¹o(õ†ö7ˆV9wöÚÍÚ[7À6CX=&ÍúŽû»· ¾‡ùMå»õiç‚?×!FvíL÷k:2qþÞBÁ‡…FÝ£É8x˜,—Ž;÷8{·äÐ66² ‹Ð¾ÿƒÌn*e¸8sp5OÿœÎ-ú2$uèw{mÞŸó;ÝÍÆ9“Øó"—Õð!á±Íéî|‡×Eseþø/é7ôÊ ²?…¡óW3òƒåÌœt7µŠM³iŽƒ<Ù»;ݺ_ÃI—Põ\ÚˆéA•Q^•VÍuˆWï~lîšχC²è5ЫÆúö‚k˜2¨™_•VÍå$6Dfâ°^L<ÛhÄü%ל[|ZI•VÍÎæŸNCì³ÜÓ-®\ÑÏôäéŸÏ]«¸b2Pýa¶nOíØŽl]6“qoåQÞÀ F§1,ùí„IÐó)~|çcô='4xÏSñ@Ïx$z<úWß~33,}x幑̞0…ÿ¼Ô…So"eÉkô~ø«‚c;¶ôöЧ+÷ÐÊ6›Á/¬V±òƽ4=0!¾ßWÜ´‡ýÛ–k¬Î¥ÜÜåò‚÷ïqßÿèÔ8¢à÷¦=GÒerÚøÔs»Ý1žñ7W?KÈ:µ±²j¶ ŠN±µ½e:]n¼•–¾c›Ü9…Y]Îõ}l›!|öèrú´i À³Ÿ¬àªÚ¦‚ äú'¿`ýµ}iòž ,}øiÕÐA?CX^ÿöM:õëÌ ÉoñCÿÆå¾ÖMH´nVúõ`Ký‹U¹*ÿ™ú -k˜Äƒà’F¨° ªŒ¿C¥Uq»‘Ìft·§K'ÌVêAEUZsS–ÑìšáLœµû¯­zMÅaw "cµ†•ä8És)C±˜¥RÚÊþÌçÏ6·[Çl–p9ݨȄYÌ¥ïrªH&SÂvgßÇXj[ŽÍކ™¨¨Ò·çØ2Ñäp¢J™¢Ó'¶lfkuª™KžÛã´‘í€è˜¨r÷æ:ÁkWw£Õ—[éyÉ5H›¿Í­,Ûü)Í£E²XðUXE&CPeÔky#GAóË7°~ÇÛ4©º@#Äb¥´ÕF³op3[°úm“Œf,8oVƨ9†þ]âÎS¯É„Y­e¶ü|.C€Ï|þl“9Ûí!‹ßãC,²ßv³¹ì¶ˆ¨(¿ÖEDÅøñ·…蘲m3Y¢¨Q "ïÈ2šv–>,«Vjëä¾­ôÿ¡0‘ÉT5Ù§Ò8a7߸®N\thîlR¥^¯±å\ä,ˆL†@PI„J«àbÆ`ޤq³HÑA°÷ŒèÁ…àliê²kEŠ@ ‚ ÁqKWaÍIù‰„ÖãH9}€GÛ5eá?P‰µ¢øSìdUDY*¬!Vo…Ecˆ•fV3ÿ¦M}•QdUDY*¬&kMº£›­ÔN%¯”Y…²ÔD ·û›Žðn¥ÄO»‡³üÓÔDý)v 2‚*¢lV3݆#:ÄHÍî£hQhë_ 5ѳ*¬gÕ@‡Žy’¸+Æs0Ç[Úq*‰7F´¢qb ãâxyÊ8î~éò}›¦Îµ'Ò$1ž&Ìæ„CGWNðþÈÖ ~ð¾ÿy>OßÖŒ¸ÄûøbñNòõàÕDƒQad•¤,VCH#Æ À*™éùàC4>7ûUÕ,xµ/#¦¹˜µp [7¯¢oä1ÈþФ£vTû^F\Û—•±O±býVÖ-û–S³æóçž\4@µïel¯›Éëü»öä@òF†þÇU×~JŽ\“c§a^;“ÇžYKß¾çÇÏnfî¨~ }g#î ÕD+ªÂ*—b « ÒTF…ÕŸšh¨ós¾=Á‡?OæÚ&áÜõÒ‡DÔ[DëúVŽlÿŒUæì˜x5 P›·–ÎcÎj& óðNØ<Œt`ùóQÌáœÎõ@Æ/d: ¾WýsÑúÿÑ2Ú\ÎÌ_Zõÿ„ã|”š¨@ D!8TX…Õ§&:/ñ6îK­(#Ûæ>ÅØÕESlfc¡ËTªNÿÿÀ~L‘ZþAXÝö â `7˜ÚÓ¾eCb ЉÿùŒ_î §vàVAnKh¡²ÓæÐð¢T 5ÑÀaéiGÈu5¶>5­â–—bºDPi*£ÂêOMÔ`‰¡wêLzýköŸÊÂaÏäåŸÇúcù4jw#œz·¿ù3vÙ§3÷ÎÄuúŽ|]§zýËÁ³tg$­®êL‡+[Åi~™¹Œ,ßS«´“‡^úš}Ç28‘²•×o{”=¯/²€ÓŸšh „"§@ ™   (¯ +’% šèÝo-@{} =Ú¿ì=ÆÔž©_¬ c½PdÚ±cåL^x7­žñJ·7¼a¿Ìéë]Q£[—}θ}x>×—°ôaê‡c|F÷zÇèÙ± }—P ðHM4B‘S \ÊíA•QQÖ`ÔD½*¬r¯ñª…b )S Ônw` ±`)¤ø©{R¹»ýDÞÚñ±öR-¡È)þMTµv‰øÖTõZÞÈ‘_ÇÒüò1)ÇÔ€ÁlÁ@®<Äbõó¯Zh醷Ýjµ 0”tf½ú4«Î,e̸ L}çGÒË´Y&Äb.w€qN‘óQ`‚K1]"¨2ª'ö%iÛNØ Ô2ÿ³m•d+m®Á—=Áèq£˜ªSM®ê“XèÿÒFú‹KC ˆ C ¨<ÿVÉB‹Î½h!\&ç ‘ÃüC¸xULÅ¢VléÓ¿E½öø]œrÚàýú÷ùSq»q+çy§“žÍ_»áÑÅŽ*dÍq‚5 æ³hýÁ_°û¿@B·¹åÀ/t'ßÝ}%O~¿·Ü‡þ[ÔkU{ºßÈî“.t%_¼Ãç?o;oÌÑ¿2mú f̘Á’í'þQ}Œmšë÷µJü{ü©;ùnØU zkåy Žløœ>C¿ÅDÜ™•²ŽiÓ¦7_º2’øtú4f̘ÁÌÛ.hàówžûŸb›2èËÍÍ/odèóDslãŽe|Y}F\\<ðo‹#ŽV¬JkEtөמW…X=›é›²öX~À—þµl n~‡®Âä”Sß1}Ö~ú8‹/fˆ·Y°>µô¨<  «¿v‡ÓY¡r •V$ Íoh…£=H½6à¹ñnv8åNÍëŠ-Yù8\²S®T>˜ð Ï>ÖË[›DŠä†!/‚ä Šå!'&rÍC_ñ;œ-ù^>ü©þòyò’·ˆK¼Y‹–óÑKÇøisI³—ì—²lK^òqqq ¼m ›Žä ü+û³=ŸåYæ=÷À|²üp‰Az߆ÙܔЈ„ï½2ãç^EbŸ_}ý3fÏxšø¯O7É)%:Ìå×)SöÚ}Ôöe1]oál]<——noN“Äú¿þ™.oIÿC;6°hÅzÈÞÆÊ5kY½b9k7üE¾îfÉ;£èzß¾{8g§¼N¿fMIl:€ßS‹ÚçQý•f)’šÖÐ"ógû/+æÐ·é¸ÿr'&ÒçÉטô`š$&0uÞŽ"X s—Å™+¹«YCILˆçÉK±ûî×c •iªÀ6dþQèJ:¿ÿ™Sf{XÝN¼‡…ï^Æ­ØrÒƒ¥v&N¿Že›·p*_ÅhÌ`Ëæ%LŸõ&­cCpÚÒÙµuŸ7Û—ÌÞä¿Ø½;™—Z̧'øò©Ïy㽊_3AöW¤Gþ‡ÍÛÖ2¥ß:žÿl]÷k»!$Ž!SGñËøjáo¼ûÀÞû¶‹VÿBç/³1%¯òסÕß@>oÜq´ÝÈ3CoKÎ%ò¯WèÜu*GƒœÆkÔq(ë×.¦ý‘_HÏWŠ\çþ‡ÙŒÏ,µ;°~ýZîï~šéE§Tö¯˜NÏÛÇ2üÿ‘”œÌÚEŸ³à‰þ<õÍN¯_Þ|’Þ{‰¤þlÞ¶–·îØÀsï®)1Ÿsx /n¹’û®k\ä¼þ®·³¤®ØD—ñ‹Ù²võ¾~’•{Ï€®r:m{¥€û${’ÿ"y;ö%_5ÑéŽÇ´†ŽSç°è›—ùúý÷5o9>|šïÖ èÇ©½,\°ˆåË—³jǶ.YÀ’åËY¼x5Çíþï•î{1jTÉò“,^ú-M–~‚½ó;üüų¼3õOU°ÆÁåÔ¹yê7lܶ‹?ÖÎcïÔøý€÷>ðw=sûW™¾kCÄVÁy'+e#Ÿ¾÷0 òZñhõò­NP²÷óĬ<Ûý‡è´2ñþÏÐý‰k8²ýW¿*¬þÛóÙòó{`jíÄŸ|?g=¡Õ$¬F3§þÁ‹·]AÓV P÷F¾{övÂ$‰ÖÍßÀj_ϤÿÛÌuS¯ÿÛTZekc¿çÖÜ'X4÷4ƒ}›—ñG®ŽIwðåo¹jh3®ºa4[ÅqÕWñ"0kM×&xt«µìÉØM8ðý|C¯„ÐRí8±ý¾ÐGñçU5‹µx æÒ•HIbàˆyî®,ïÉe5,ŒúäWFÞØ€æï/àpÛîüqx4q—V ªCƒÈâ‹ÞZÅá@¶× Âgs$ D’[¿ä ä7}ö%]^XÀ k¯ ²e>žõ,˜ÃóƒZŸØª?ÌúR]’¸ùÞñŒ’‹ÇRžàømÆËtÿ Õ¤"çõw½èž\ºM˜Ìõm |o=¾ßu‚A­bèØï^Zµ®ÅìýN~h`Ñ‘Z Ôil¡ÖUWÑÔ” –>\Ù&û±«Xb<¼¹§I=”Šl•8u"ŸÔuGHí\ ‡ÝDü•]¨kõo{Bý\YïZZ\ž@×VÔêÕ•ÖÑ‘õ§wc­V¹ëU2™I[3N£6P³™Ón tï}`ެï÷z¼¹qÙ*Óit"¡Ú…ù¾A†à¼“g;ÉÎ_Ï@资‡•ï’;´égˆ¼yßZæì„˜Á·²ù£ù¤>x5jVÅ_»îÄíPix]š7¨ƒÛ錌˜ù=Xë"I¨;1ÌEÒ}5‘ù» Õ÷åúwª´:wï¾-‰«c%ߣc25fÁ‚눩ßà\°Rèµi'³ Ð—¾ætcW4ʘÖÏ0÷±éŒ›¶œêŲO2Ó´gŸQ%¹dÚԟ황 é:’9ŠÈ|@Wñ ³d$?™³lÒÒN££¨_¿†÷È Týû\ÅeSˆ‰8÷ô-Cˆ1—Lû³íÜç.¹Â ,Åá`lè³ö‹ (- 9p«€ê!æòæ%0þäù'Ö3zÖq–íj]zpìçz¨rn²´v³vè…‚·ËMæ¡bAM!ÛuUE•<炱R¦«J[ÏÝèj~üjöÖL"óúGJ}`ðg»êV ®Q—Ë+ìØÝ… ªó—o;ÁñŒ\ÌÖXâb½SJÖ\yÝüwöo$MŠ'”LÞéqí¹*àõXe:ÛÄt‰àO\Û|µs%ÝõØq8'øAÔ~˜9/|ÉÈ)÷ððãOðì³OðØ#ÐOþ‰o–'Ñ0€ «_•VBiÝg©ëö#Å\F—.]h}yö´­ü¸b?š®µÈü}ïÌßDzF»Ö|Gÿ§~c䨮ÞEŽ>þN•ÖÒÎm0GѶe8{Ó=ÔkÖŽ.]:Ò0ÖÄž5?ñÇ‘ltÅɾõ3iwãh>[³‡½ëÿg_ÍÔy; æk –®ŠåPÚI;)»ÖòîËoóW†÷‹üÌžå¼™s·w*¹¸ïtF™3Évz€39 ÚÉq¶ýLF†÷µ¾q8=' YÞ5'»l» [ÎÒsN{ÿmw˲̣Ë5ÝúêFŸ/}O®~T}Æeû­oæ•a/ðÛŸ‡î*¼ IDAT‡È8u˜ß™ÈY-hT+, mºâ$+Ó†=׆C×8}:ƒ›\§; âp0¶û÷™JŽ-“l»Ìœ3xr²¼ÿ¶ÙQ¥pZº‰5¯½Ëšä“¸…Ì#Û˜zï:Œ¼ƒzagJø4£˜OUÖÍzžOÍ¥I±ú¯7Ýíë¯,o_w’‘y†ãé§ ÒúÆ08>ž]GläÙÒÙ²â;þûñJòœ62Sò9žaãêà\Jf®&ﵓ¯ë(î\l6;§}6gÚrÉÊ´‘_l¡wþ™Ýœ)1%èÏv7™E¯Q›Ý;¸»W‘ã îܺ›¥ÓÒ­{æí9·­Yqz³qujФõ¿2ý˜ƒœ¬Œ‚~ t=úS™.Ë6‘Éü+1˜ëЫ]$’1ȸYw³pò`fœp¨ë0˜Ö2þ†p¦ô¼™6±ëî=Œî?²<ôy%–™£j3ªÿËåaÈ'µøíÉVÅæý?O2ö¶7 Såž×+3ªU –=~ ;¬¦rÓ2<Ðïܼz?׎gÿ:â?âBꎢfõšüƒ 5v­›À›Ï¶Í ¯—Âõ7xç :4z½i÷µçþL•òM`Ò¼7|ug¸ø#HÞl© ¨×jP^a-iÉË@>ãKtJÌ{H:ÓÝûyí¦¶LÌTy›6Ò·ŸÅ뿤^Ï—˜l|D¯×²wç‹_ñÕÀ¦Hî=Œò×iÏa•YøA½ÀßÇ&2ùٶ虫é÷~ ¿¯.Ï;/Ù…5Øö\XŸ ZžîÞ1ó¿ôû³Ë>¹µÄã_:—ÖàÇv»x …P›í¬Â¢†W%G‹Å’—ÞÈfÆ÷s¨×»16éœêílË-xžÓx£Ykæ·yÏ󕊬ï¢}ƒÖ¹¡òÃ=7Pá͵t¬~á‚ÌÁ‡KãX\d•ºì\œty 9—DNú~Y ÷ÜÞø‚†ß½ªŠŽŒÅrõ<ŸÜ;‡Z­úóÚËpSlÑ×0VÂOo»J8Kï2]óíª¼úꫯžk!mÙ²¥ÐgÕªU7VA>9+ãr,gðàÿ2;».wµID9o‹ɘ­VÌf嬶KŠ«ÕŒ"çÝäÝyúÎÿ°aóŸì:~œ ½×%D»“YA‘ÏÜ¥uÍoo¢tA¿fUÎú·;¶ÉlÅb6Ÿu¿¨$+˜¥`z)„¤u(c–ιÞΪÜJ*VÏ1þÿ5ÞC(K±õ}z™”Tçûþù†¾ïLgý¡,ö,^€½îT-sþMfk‘ù –÷ë¬ÔõmÆjµbVÎ,µ)¼ jW¹àýï²¢ (WW/ú®…|9¿!︅0E*æ.Üv;}.ÓÃøbéB¶Ìb÷ö$]W“°RˆùììlEÁd2DE®°PY–‘e9 2 Ã@×ut]Çív‹H†àRF3TR÷íG³U zÅ2—uVUG*ËWnC2[PU'QÕÓ(©¼¨Ã«˜’êEâ%Bd.§龿¥3\{X)ágëd*‚Ó††î‹Xhš†¢(¾¿%=ðU]×Ñ5_”£(Dw‰à‚âñ»$=êë ÉÉ:ÊBG&'2þí2³¤-Ú¥°4.†çêd*  Ðü]$¹/MÓÐt-ï½ÿ¥ºˆd.…V™ñvO¿Kâÿ¸eÝ(–½6<étiÿ2ËּǞ/sïèÅ$—Âù[¸µF;‹q Ìïbx.N¦@ ÈCÓ4dYö·ð‹ ¯æ-àW Kr?=ޢˊ ®xÎÝÉT »wïFQBBB0›ý†yfs!³´\±¡ëz`YqÉ\}.ïXM÷>C Α\gUMÓ$©ãªay>%|Q /Ša6™…È\mWD(Ý_ù‡î¢$àœQ…œœœ€àðu—hy‘ CGÑ”ÀôUÇËI‡ƒ +fš‘! °(0™ÈÉÉÁëõ"¾Y&y3LTCÅ0 TUÅétbµZ±‡Ûq8Bd.? ͋NjIBU ,qZŠ:—]×)_¡‡ÄãñJhhh`<†ax<<n·YQˆD:NGtb .ÞÉëLcñ”ÉÌX¶»ÀêÛ¦£Í£39œ2Ÿ„ºƒØsêß1 5uý4ƾ?žñãÇ3k]Ú¿ê\ø·Ö¹@pÙ?‘ÄÅÅát:9räGŽ!33“ôôtŽ9ÂáôÃp˜Š-7·KE ’7¯êB²„¢\€ZSUfBÏ¢;CW]äh` -œ·ÒÔ¹@ ¸øäú“˜U«TÁf ÅåtšÎj±X0›K^—HD2 3’I+ôyÅmèZÍNht-^t ùO[ÝÊׯÜE\B5’¸®×lKÏ lw¦oaô ú$&%P=&†Wß|†û^™ps-iûžU¿Ó%!žII$ÄÅ2þ¯õx ç¡¥Ü[«:C_þ˜_|›. Õ¸ã¡Q,K>ê¿aÅây,[¿œÍ˱dÙbæÎ˦½gnò¦zŒ"ÅÅú)SDÞ~_™ê/“^l”Èco}ÉÄñÏ—DõÚO²bÿ‰‘£ó¾ãÞZÕi1p~ü”þ=“è?z>;DLÒƒ,ÝŸÆaŸ nžL[w$üØ®Ü[«: I$%Ä1lülù–ÔÉØû#õ"&¾_ý9ƒoF!¦þìw`d3ç›ç©–D$_Þ–ìµsc²Ò6òÛ/Ë “°›d¾³–—zÕ¥fý¨Ò‰ŸŸ¿›$Ñ öhìŽeŒøz%íÇÜÂ}ƒŸ`{•Ý8ÝýÔ;©¨šòÕï6[Oé†êÆ(×ûoo‚¹Ä›ª ¨üùVOú­ô {o*”7+Ä%ÅCÔÃ<Ù¯Q’D×^àé>'ñfã$kÇþÁÛ.§SýÞþ} µîÓˆ­`ÇBµjù ÉB…Ø4hÉÚüŒÙÂÅci:t9åY8ªê`ø¢P)«¾æÚß1üžv(@íW?áàôIªYIMcƯéP v¬œÃÚ“fÃç®ûíüÝÜз–¸ ‚+"š‘/!ÉX­Vrrr X½ç !2—”SY‡Ù0í„ÜD¸í N9ÃŤngRÒëü³þi*DšXóëpž^ä Áy=.0G`ÎwŽÛª4¦_ßû Û ªS£zûŽÔ®VÕåL úþ7±WÆ*IhÑñ–á¾2åãÉ\š…˜ÉíêЊD¨ìݹ†ÔŠ„æ É×]36¥ˆ‹tǬ7éñÔ)¦L[Ę˜r8/¡ÁÍßcÊ->ÍCtÚœ.ÙdÿåX'§ŸÈP½n¢«ãÁÀqÒ „:¶÷øZ®o7ïLœÏ–q„ɸ¶7åYçJe8‘îÄc(’„¡99®jÞ¼rèй1•íäx ÌæD¦LiOtlµ3‘—ÂYW ¸†0HË]ÕÀb±°iÓ&5jøÞéVðE!ºKœ˜†·ñ݆´1~gý¾g”Öå¥QBU¢Ë˜Hß¹†IoMÇ™™Æq—F|£NþïMXÊ1‡“ìô}ü:º1M&Ç0‚o'„o#åïHÑ×мysÔ‰Áq`5ÌÛ‰n@2—>øÉ+8’‘Á¦Å?Ó}ø|† mQ ¼¿iE2N'Gmcò§cøyÙdk O¼ýo¿þ:#FŒð½^‡Qçu 8Yd;²È:qŒ#'ŽúÞ;Ü~ áÛ5T,_õx*ó~ú€£¾™9Ç22ÈÜI¶K üæà„ H¡´Ð×ïjÂ{?þÉ´IP¿Ãó„•µ¢ñM#øîÏåw:9¸m!ÎÏàXÆq<†×å‹<ÄT.G¶,›Æûœ8žÇ0Hjq/eg¥Ë3Ÿ0kÎo<Ó¸53U_ƒb‰¤a½p¶ñPµV#š7¿‘êÍl[ü'k÷g—ºÞ…³®@p9„4òÞ¦¤¤ðù石oß> ÃÈ[n<_׉‚K†l©ÌÍ"Lg0B ¥ícÃÿHW’’hÖý+®}bËßäžWfâlÈúß“þæ}Ô¯]ƒº[2vg7¦þÒ™IÂT¶QÐíIí†1qd =š×#&&†š×6áµ…Ú·«åïÎpprÃW4ºî::õ}†‘_Ìb`ë˜@k¶BóyÏp]4lÒžÉ;¹¶zT©¢4<׎ºµ¯åβldêÖ¾–k[¼ÃaAb«ÁÜå}—&µ©Û¸%;Ê´¡g½¥ôhÿ2ûŽïfTÿ‘ö=‡ÍDõ¤þ8vOÜ<Œe3¾Ã’º–äŒJ|õÑ NW±“úG |?”z5jpc‡YxRcÚÈ;˜·ë!•0~xkîn]ŸÄ >ýOÜÝŒa··äûåi„T¼‘_—Ïá¡–þÂ-ã>ã®è\ŀϦÐ)ãe×N$&¦:šßÊnëu4I*WêªκÁ¥fœÎO?ýÀ¤I“Ð4-ð’ÆdVÁE:k]|}ÏXžœÅ=M*ŸQR]uqÊm`³ÛŠŸ‚êp‚ÉZÌ×àÛs÷o µ`1å…åwÌü/ýþlŲOn-!‡n—†d6ŸñØ’öëp81Yà µœÛ~÷/ÿ˜æOE±cù]ØrlyU\ž`Ó‚x°^Ìö@.[èÞ Ãæ&ssBXÁô†B¨ÍvÆÓk…³®@piHMM%*:šªUª`2›X¹r%Ÿ~ú)999Ȳ̃>H«V­°X,ȲŒ¦i¸\.Nœ8!"‚K„d¡fÇú™¾›õ›÷¢›mT¯MblÙó¶o]Ífãš d8 ÊV‰¥n­x1 U ¸ 8pàÑåÊ"3¦Ïˆ ·Û,ËȲL§NèÛ·o‰‘ !2@ U«`2™;5MãøñãX,L&S`ÐÜm¢»Dp…£¡ª^Q ÿ"¼^¯vvÏ@¹çŠWU‹˜`,¸uze"D†à²!ëÀ~ýiÛ2Ü…¶í˜ù" ­ ,.¸Ê1\ü|ßõ ûmû'=±÷O<ÃÞ£»x¬QM¦ïÈåy‘êlÝâYLš<ƒég¶ò­+óÉÉÉ×¶] ŒÛ Z§†‹•³~cê¼ 8Eû D†@PºsvèÎS#þæ„»pÄ¢bâE4j*³Æõ%&¾Þ΋Ÿ.9£¥¾ÑÍæýf5Yr0çÌÊÂïMÒð¶ô¿½'111|¹hß¿ò¼8ß4«½&«Zv‹ðE¹(çºÊ¼:Ò­ïþžñ m›öecº§ÔÉw-C‡¯ö=>âˆZÚ:U9´ý†<Ð…±3w‹º"C (Œã`2 µ›Y¶þ=šT +âÐ=èù?’j·}Œg:îeæÌ•|óÖ;lË,ºKÅí bÕp©jñ7}Õ…Óå:ã­áÍbÕñœî3¼(-‘ôzÿ3¨¸Š´º]ùæ›oh_ôÚ^UÅéRƒîÏ«º.PxYÃír¡zÏNØ-W)”Ú·Ö÷¯Trf˜íåi#ïðة”Â)ïÙÕé…*7ÛWgÆYt•œw­Äsâ|ãÍÞÆcöòñì-Œý|¯7ÛËøé›K^Aâ¶1sIMMõ½¶Œ¢ªU*]JÜöøf»åÓDWŠA÷“9·},úÆËsÔ8í F¡Z½f\W7‚£¿â?·ìc‚O2%¹°î^>‘. ñ$%$аçS<Û«Î܈Dç&Z’KkÖÍÌ™1‹…'5–ÌžÉÒÅ‹™;o²Jñt'EаÕÍtêÚ†š ZÓ¾}{êT+sZ´£xwÚÒ¸´êÎ4&½ÿ,111<ùÞL0Ž. Õøuíö–èÒZ¼ClîSmq°£t.­eb;rgãØ³8›,´îß²VåÛ åÚʶÑ¥âŽ]*wÛ ”Xn†‹¿Alœ¯ÎöèIlýÿúœkK+.ï'öΡsÍÛ1ö+^¹ãZj$%pëËɃÛ3äÙ1T~üsÚ×-OÕ’\Zƒ8ÄBpX3¥siHjw?-ÂÎü\²Æ0è™Û°KÚ=4˜šeÍ›|°c—ÆÝ6%•Û©s÷ðϘ¾zömãÛÇnõ0ÞÒŒg.!ïöØ&<ñˆÏÞy™&ÿ™Êª%ÿÛóÌÚr´ÀnR7üÅá/2l`VïÏ ±íœ÷>­{¡n¿¯˜ýçóýc/~0•WÞíM%«NÖ‘Ã8p€#GŽ^©i)÷/ƒŸuø Ñuj“k1S©f2SJƒÑ0X6ò®½¶M×£õ /Hs%×iþhŠÿü7µs#::š˜ØXêÖ­Ã Mn E‹´nÝšV­ZѬY3š7oN³f͸þúë©_¿>5jÔ råÊDFF¹?á:$¸´.ÖÌú…÷ž|™kïúšÊ¡g–|ÿºYl0’¹o7W8Åòýé^'ªDÖEï£õëSÒ½!Un}”¹ß•#¥l4z)ÜDƒ¹´Îs O_[ƒ]¿M¦÷£OqsBÈi!ó3wi5¼Ù$oË$©n—)W#§`¹X"k2ðégðX¡ÖŒDT˜µ@÷Dˆ"£z5 ÍMÚž]¤\ºÝ'ˆªK= \µdnß…Ò÷l&ºzbÁ1T†‹”]»È1U¢f|Á…íÂ+ÄJÌbãúÑÌKÏJ/2,6_­ýþýVúݧÁi"#X¹ „È\­Htô [Ú^GÝî98¤i_Á8¼m/->Æoo?,šº®M» `퀭4nÔ Ò»óÞ„ëx¼{#çfÓ‡§~‚]ËïâÆwòüÀçè~í8Z^űƒ[x¯w_¢ßšÇ ·úÜD§úÝD+ÚMٟ̼ß'Új0ÕÊÙÈsi£_›kHß:—îÃçóßßð­~Í eCØsà0ÎJIß½ž©“Wsó£R§œÏ¥µ¸¨Óá ##~œlG^MA:å ~™Ž¾¾(wÚµ9îÒ¨l3ù]Zu²]!þ¿ÑtN¨P!¶cºW S“¼;®/Î _ðâ‡{ò1§ðø¦¼õçr:Õj‡3åoþœŸAX}ŸK«Ï!¶Æi±6Žf8¨Vµ -ô£í]MpŽþˆÖý ~r4ÕºŽóÝh-¥)×R<Ù;w3¬CžÔ˜±~/åí%§)ͱƒ–›5XùnÌÁÊÍ™2Ÿ÷Ï`ê¼±ÜÔ¾ º³)É_OâTN>j¨Ì~¿'C?Oå™—ó¤ÿfXbÞ£MdddrD?NŽaB™'Žq(Ûwì\ñ®;÷ðH“›™"dõš¨d–@²Ð±Ï?ü ~y‘±fþþqãÓ\|H¦ të78hÙ†W¬M×ãü±ìNú]/1ù…oéöÂôËØgïšM‹¶0aé.ZW <,lþ'[õkˆ©`çøÞøü×ÃtíqFMÉÎ¥?S®ù(–M¼¯Àqƒ•«@ˆ Á¿Ek˜Ìà=VÊ! º{¯Ýñ(··yŒ%›¾¤RÚ šv{€^=>gÝÊa¬_ð=/õ¼úÏùúû«ß:4Ÿ ëpþ÷·uÎ[öþáŸ2°]U¨[K IDATH>›‚öZ/×Îk`‡¼ø!ÜDó¹´>9€‘_Ìâž\—V)‚ãFвgÞð§xêõ¯¨\ÂS·îNáéf73%Ë,bÚÈ|+>Ýâs§myGWÆ„väõÿ aâËorÏ+Õ™6²ŽÏ•5ËCÏa•YøA½ÀßÇ&2ùÙ¶ô·€¸°pùbb¯‡Ã°BÍ v×ï<¥ãÔû2ß³èÈ;èyó6ÚµÌ]Þn4©ý–¯Lþû"=ë½Gö/³lÍ{~Øë˜2}É×òÕGƒ>Á¿s¿Kkðr-™³ri-áØº{O‰å<Ò¼ÜZšÂÀ5›®Íë6µ}ð]š&æÝðtõ+ÿ< Ÿçþ|n¿%åýľ9ô±XÄOVÑ&ç'ú¼¸XȼN[¸µ†ï†upS²< ù¸—O`øóÝüñü`}—{»µ ßGÐ-rf©ëC¶Õà­ŸÞ¦i·f¼ Ô¸ûüÞ=±ÀwÌ6¿hˆ¸Ÿªe-Dõšïñß)yãGŽ™Dÿü¿¿473³C*Úk§Ør\ø¶],+.¸8±w:uÚ}ÊìU“¨sÞ­½KãÂê-Öí´87ÑÒº´^•,Ë™›…#%ºÓ–ÃÅ„GZ°¢ÝÞï]«@¾‹wi-½ClQ°Áʵ4œ«Kë¹»Äâ,¶Ü4TÕÀb‘üSª•Bß9¹wµZõçµ—3à¦Øóž÷u“£Û‹ ‹W¿GBXðz›xO"__Á-§' †Ç•E¶ÊFG™7ëâ¡h·b·ËË­!YlDØ,g|/ûæÞLÌϵ*tìÒ”«ÀÇùö.‘ Áe=¶>CÊm¥ãuñ|2 ÝjDœÇ½û\X‹} ³„bÒ¦YCíXOos]ZO~ËÐrý¹ñ¦x ý5ÅDi,„^€2+)ß% ‹ß^kÃëë¯åèêY`nÌ_/ÇÊ·ÍT|™Úƒ”éÎyïÒvà":\·•9«\üç›……BØE•kióîsiýä¬]ZÏúØ¥ŠÊWn Kîñ‹>#Žgì‡òOѽyÌùÏ»á"eå î{ý»â†¡²ä»÷™³ÛÁW‹2)÷Ü—4øa(•JÙ…i¤\hð²±û]gs¡GÙ¤9ãÓ\ŒøeL‘â¦4å*È_¦y±‡víÚ±hÑ"ŽÍ‹4Ùívºté"\XWº+“])Ç(_-ž²¶Ë[ÿ^ù.­’×±ý`!¨Y«Î ž,‰ é+¸°çÅÎÕËHÉrc±XP=!\Ó Dš¤Ë:ÏGìå¤MBqž+©©©DEG"+W®äÓO?%''Y–yðÁiÕª‹E¸° @ (û÷ï÷­•’$1zôh6lØ@bb"ÇÇf³a6›‘d ]Ó… «àÊÅм¨^/‰õòC½@Ž˜¹N›†æ=k'V@pvÕ Ò§Oz÷î¢(ïHr ‘!¸l(Î…uÛôa´yt&‡Sæ“Pw{N‰›ÎÅ$mý4ƾ?ž_çn) (t÷¬Ÿtþ]N ?÷»·çìe×ÂÑ´~äwá¾+\’'¼¼·Õ«W硇"..I’ÐuÃ000Ö!"D†à² $Ö+ó=;ÖË sxÛ?ÍÈÏ7æ ¡g3QÆtaÆÏ4L,îL§q«¾uGÁEiäkÎ ƒºuëbFžÀ0 0*4„È\saµÚ*wcu"ÂÌÙŒòE¬×¤ª.\AºR®$ÖÓóæ,Áé4˜[¨WUƒv1•´ Ü5-yþý{@*¸º©l­Îȵ»¹)ˆ¿ÈÙ:™ºx <Ùd‰ËC ¸x|§ ˆÀµìõþ¿uß¿Bd._ÁÄ…µb6t­f'4º¯ º¦ÀÒÆÇv-àÞZÕIHH")!Žaãgãȧ¨¯HV?{VýN—„xjøNÇÿµa”Ê-Ôðcú§Ï—@BB}ŸFLÝØ}Â×8m`ô úíýßú…C޼rsel÷¹pÆÄðÂØ¯øyâ_„åó?Jžõ?bbbèÙë)Vì?•×@•ÆÉ´$—VÉBG¦¬U!2¡'cÃÅ"\$NHä §Óš¦¡éšWC×õÀKˆ ÁeK0Ö°Øô½9¤J x¨mйÛeÐuÌþY³‰µK&±}Ì@–îòÝô®dÖ´u?кçc ùy1»öíaí’ŸùûÙ¼7VÉláÀâ±4ºœò,Uu0|'û•ëÂZŸU}æÆd¥mä·_–&a7É|?f-/õªÔ-Tq¥ñËOi|ò×Hnªá‹ÜûÊ'”©:ƒ±vv.Ȇ²Ï2apg"$ ÊÖbðˆï™úÛ­ü³w 5÷|ǰályíNßö¤gøëT ýÿÌ{ ‰¬Lµˆhâ’Nï» îk6‚»´ ‚K/2RRRÈÎÎ&''¯×‹$IX­VÌf3&“ ³Ùx¯( š¦áv»‹´{"Cp‰9{Vïñµ\ßþnÞ™8Ÿ-#â!“qmoÉ·æß•ìª:5ª·ïHíj•Q]ÀÄ ïã{e¬’DN·Ð\,ùdJQtè’=PjèvB ¡¬EÂð‚æ1@¶Ø^T½haQðã`y+Kk)šÂ³vaÅS³fͳJZÌ*¶u1®íÛ·£( Š¢`ò7€†a Ër`0 €ÇãÁívúdYôê®LdYF’$E ¬ù/Îgàß)0 #Ð.˜L¦Àý/÷^˜Šü·hY–ƒNÍÌÌ$::ºØí¹SOó“{ìÜ.víÚõo;xðà¥dx<ªT©hh _ ‚$¡y½dff²yK2·§°u÷Av8FNŽ/*š 5㫈³TpYãÕu4†W×0+2•ËGR¯F,Í×¥J¥ ˜L&$YFLÊ®~Œ<µ€®ëe¸ à ''‡œœÊW¨@dD’$ùD„ä[â*¿(0 I–÷Ì¢p¹\D—+ÆÍØŸÎ(FÄèºNJJÊyÿýUdDFFRµjÕÀÓ].ªª’œœÌœù³lÃ.ŽfçiçázpM\,¡6+èà/uIF–%ÿ¡äßÈ’„¦hš×?­4ô@åÈŠ"Ò‹ô,½+Çí%¨ª—½)‡X°t sW$³s_]ÛÝÈuõjb1›EDC ø7ˆ ÿTÏ\Å‘;¨2w ¤×ëåÐÁƒXÌfââ1)ù»9)0´`X¢ðGYYYT­Z%ˆÒ):¹"#;;û¼ÿþ‹*2rÍUÌfs ðTU%55•%Ëþa麸<Õ«V SÛÔ«“DˆÕ·6:ø˜,Š"û–6•¤\Ó8#Pòº®¡ë¹Ómt$d ‘^¤¿ éUÕ Ïb«T¦|¹Hþœµ˜ô#™L_¸šÊ•Ê‘W ‹ÅR*C@p…‹ŒÜ©ŸºŽá¾¶Ã÷òx<ìØ±[X˜Ï˜ÌdÊFÑ‚¢(T·;0¡T!–|"Æãñ“sþ¼¨"Ãëõâñx0[ÌHHè†Nff&[·neÓ¶}¸51•ËU–ÈÈpYFÓC÷E2d I3%ÃgÊ¢ƒ,çÕ€a€¦kH€nøñêþÉt/†lB2Dz‘þÂ¥÷êºï/ $CBÓ5ÊØÃ©R¡fEáPúqþY³…ê±U1™L¥oÁ‰®ë¾1ý Vå¾rÇ_ȲLhh(‡ƒ=»wc³…R.º²$±ÈÉÉaþüùtîܹб<O‘^"Ó§O§]»v„„„Ž„H¾µ0<^ïù_mù¢¶p’$át:±Ùl’Á©S§8åôÍÁuœÒ¨\!Š å")c·ã8噓ã›&£È€¡ƒŒ„H²‚¬x5_è:°¬©ÿ‰R3@÷zÑrCÝÈŠ"‰ô"ý…Kïõz wæÉ¦M›øüóÏ í÷øñã…>s8E~îvç(mذ 6ðÐC Ïr§ÏšÍæ+[dä®–û¯®ëx½^BBBU ÂBC·Ù°‡…a³Ù°Z¬˜-&ßl$Û7ØÎ/6ßà“"#É’¯O]óõ¥k†o€WÓÐ4Ãð)H“"Ò‹ô.½¢˜ÁÐÑ ¯GÃb±à6ç`r)h^/n·‡H»EQ0›ÌBdÿ‚î’Ü1^¹ÇsE†nè(Š¡¡¡˜Íæ@tÓ0 5jÄsÏ=ǤI“Ø»wo`¿‹¥Èù¢>Ï߯ÄÇÇÓ»woâââ žI’tAƈ]ôHFn4Ãl6ûÂÒQQQÍ:„5ÄJHˆ•Ðl¶l¡á˜Ì¾F]òÙ—$ Eö-b¢È&_co–0üë‹x5_ÿ¹Ç«ú Ï÷™È’¯°Ez‘þB¥—dÅ?¨YC×t\®Ì& C7QUBCTä2!ØÂlŸ¢»D ¸ºE†lÈè’^@<膎¢)¨†ê[€Rõ-Ë;ûR"/ÚqÍ5×0|øpV¯^ÍäÉ“q8E ‚܇ø¢D†Ýn§W¯^\ýõ(ŠXƒ#w!.I’®üHF®ÈPL¾n]× #>>ž»öp"óÊ•Ål1a Åf Åb±`2›@ÝYñE5ÌVÉý´¨<¯×wCм4Í@÷¯{à‹‚HÈŠ"Ò‹ô,½â›‚†×ãñ}×gÙîr§z•hÂÃÂ1™M§@põ’_\È’(#oµMÇCŽ+‡š5k"¹ÑŽÜ® Ã0hÕª×_=Ó¦M+RØl¶"?ïÔ©]ºt!444Ðæä·lÏuT½jºKò/+.Ë2 4`×®]ìOM#í`å¢Êú"&³Ù„ÙbB–|ßWdE‘‘ Å¿h‰$¢@îx—ÀAÍÐÑüÓrdYFBéEú –>wÅ^M×ð(fdÜ9.I"óÈ!ì¡2‰ q”)S“"ºJ‚KwÉé‚#wꨪª¸Ýn¢££©Q³F¡}nWF.V«•¾}ûùpb·Û‹¼™ûýüK’ÖïÀ@öÊÈ’|åw—(Š‚¬È¾P,!á ÏDEEѪU+,X@úáý¬Ÿ»½›–óÝûÏ2êëÙÌøú9bbbˆ‰ïÁäeû0¼G˜0f8ýoïÉçs÷qŒ¯_ÌÀ·óäû È1 æ¾s Oþ˜Æÿ}Ž˜¤Yy0‡´õ¿Ãô­ÇÄÙ"Áå*24Õ÷oDThÑ™  ¢Uç."ÜÅI›X¾x''\P­Ù}Œ¸·"«6@5 Bƒ»øõíû ´#S—mâÞV•9ºo /¼=_zMáøcÂ;4ÖñÄ-Yv¨ w?ÚŸ9+W‘–Rý_C+ó^V&Gn¼ç]Xdú¼ü¶¬}Ÿ†U¬œÌÜ Àáã9âlàr¹„š‹žÔb¨'Ùæð`’,ÔlÙÞÿÞ·Ýäï]1I`²„.AÙ6$ÆFj I×~¼Üª,M†ÿʳw´áúÖwóõŸï0oÕ> „n‘æ|G´VÆ(ˆ°èJT³)DDGa·c–$’Ú gýÚõÜ×¼²8[@ ¸l#8py¼En—,áÔ²ûnúÞRå)WãFºEšq€ì†Ë(>‡§Ô™¢\…rbz­@ —³È(S.€}{úoçQ3S™˜©R­u3*ÙJ·Ï°È’¿cS „P¡@ ¸ºDFì R9”™~ÍŽãz¡í+§~ ÀÀZaË9PüY²øÂÙ¿ê?>R4º#‰™*IUÊä*òE2ò¦¥äŸ f)Øãv©âLàr’©2Cú\³éÐî=vwû6*ë§¼Cß‹hôè—ômæÿàõŽI,Y½“}ɳ¹yÈxpLbú’x ÷ýØ6'ocÖo‹pr¸ÂŒ‰ó8ì6À8É_>åŸ¢Û •‘,¢-2ß¿òëS²â·§yòÇ4œG“ÙrÀÈç߫װsç?ü1o7û—}AbRÍÝ'Î@ .W‘uMv¬™Å³7ÿÈMõiñà@bbèúøÞþq“ŸëHˆ?Š‘Ø¢Ý"ÍkÑ¢E‰éœŽ,œª0QôàJCÅqÒ‹ÍnCACC)еáv9ЕpB-.&<Ò‚­·üÂÈîÕò¥+ˆWu‘£)„‡Zðª^LºG4œ'ÝXÃóÒ¹]*ÖP‹8[@ 8.©AšÍI‰ã;% v{î ^)$¬¡öÁåeGÚQ®É—î´m %<ðþô"P°…ÛN;†@ œ)WÕ»¡²gõ4^Z|ŒeïOdYr*9ÂlM ‚K†éjù!†æâXNe~ýýwLxÉ>tORUBL¢’@ "ãL\ߪµ¨Q@ .dQ@ „È@ D†@ !2@ „È@ D†@ !2@ „È@ D†@ !2@ „È@ D†@ !2@ „È@pYsYZ½«ª‹Å„WU‘,QOÁeÍ¡]›PªÔ¦¢Ítuý0#›­[2IªY’.ûìæ¶™²æECÁ¤HâäœÛ·oÇãñINN^¯I’°Z­˜ÍfL&f³9ð^Q4MÃívy‰ CeÛê¬Ûo¥S›ˆ4ù.†{ÿ¤Nç,Yü(cÚv óoëéV#¢äÝy0õ‡Ÿ9Õ‚ûº5:ÿ ‚q’…?O`c¶ŽE²ÓáÎ;I,k>/»N[?›‰‹öÐî®~Ô¯rŽù<ÆŒï~e{–™¶½ûÒ jÈ¥=cK(7wƾÿq^kaUoàî®®ˆÆürçLÊ5mý4&.:@Õº­¸½}Ý3õšc MÚtâÛÅÛ‰,³ïœCĵ¸ýæšçü€p®y;Wö/ÿŠŽCœ¬[ó¦Ô¿ùöÏÕÔ¾é.niXù’ÖYÑך‹Ÿû5%µÿô’'ðÀ¯µ™ÿIOBÄõ$8E¡J•*T­ZY–ñx<8Nrrre9 0r_²"£k:.— UU íï’u—Zý=í{`ÊòxŒ¼Ï­öJ>õcµSËn!øm\ãÀ¶õìI?…¤Xñ¦ÿÌû?îÄä©äýf5Yr0ç¬òl‹ªL%k:#_Ž­GÏugë7í!Ç0ΤiäÝd•xç푤œpŸû=]Sˆˆ aÎû¯²ÿTÉû+)ïV}OL|º$Tãã9XðÍ#4ìÑ“ž·`iÊ©s*7$åcbQ²ðÎAêNpfœA¹šÃ#ØþùhF~¾ w1ç®f²q}2oáí[猧Z×q´ˆ·!™LìûöF~¶®Ø} ¥É[þ›ìöõ›HwxÏê:,J°O|êžùà~Ê›%LV;ß}ÀÔ­™A#gÝÆ©³3ic&–Gw¦Ó¸U !0g%2dY [˜råʉÉdÂd2!Ë2ŠIAQLŠ/š¡(E?\2‘‘y`=ÕºŽç۷良9ïB0ÛËÓFÞ‡a±S)!„SÅ´é»þaô †4kß•_6)‚[û¼’O˜x\.´BÑŽ,VÏÁéQq©¾ ÙR8MnéÆýÐ-Ò\@ü8Ó×ѵSk®©óóÖ¥à)¡!8=ïåkÝÄ[­£‘LÖËÍ«ª¨ª7H;AónÐïÖò¥ª‡’ò]­ ¤ulôíêU£Æ÷1¤A*{•F$”·|s¹pºNË[r°FפG¯^ÜÛ·™)ÅŸ†W-R%Ÿ·€‹WEU‹»Áºpq>]4TU-ù؆Š+ßyQÚr(wMKžÿ,…¾gxO²vÞÏt«ÕÎ];pô´kGw§ðñËSyþñ› ‘$,‘5¹ÔÝ„•-é¡tu,o…v&cïíNãÚq|2éoŽ»Ïì:<#›§óþÉÞÜÝ<{•Ü÷Zd«ï:uºÔ"~SÉmL^»¢ØG°:+mã>àAR$ðd“%î—‚³ WDH’H¾ÿ!Ër «ÄjµbµX±X,˜ÌyÝ'—•ÈPhÔúš"ÂZ÷ïGY«‰òm†rmå‚7²Ìý;¸>Ûôæ/ýn¾ù}O·À£©dnZÍ÷㇟”DõÚO²f¿ï %ëÀfæÌ˜Å“KfÏdéâÅÌ·ˆYtw /6JdȰ§‰K ©îÞzs0‰II´üÙù.h]Uqxõy ¿…s&1¼ËAèÖ‚økÿËâ­©…n Åç]CŽTغf>Ÿ¾2˜˜˜^xÿ8òže‡60zP}âHHˆ£ÿ[¿pÈ‘—¯ƒ›fól¯ZÄÄ÷à£'1ñ1ÌÀ‰½sè\ó6ú÷Lâ3ö‚‘ʨ»z1pàíô=k\Ç y·U¨G¿[ËÓ}ÀÔªT–ªµ›ró ͹鮎T¶Iþp £Õ'1)‰IqÜúòDÒœÆi7êÂå–¦s#:ÆôOŸ#6.„„bê¾À’GÏËÍ{ñgÐð¶Œ;Ú¿ÿX>›±%¯ÞŒlæ|ó<Õ’¨á?Ÿ–ì<†Ê¬qC¹sÀ@bê¿ÁAÿÍlǬÿ߃ÎudéþâŸdsÒ×ðpƒÛ8 Ã>]â;žáâ·×îæÎ·Óô4r /;–O¤KB< T‰aü_ë}O²†Ê¼†߃Q_/`ËÊ߉‰M )!Žæî+U¹º2Ó"§ IDAT¶óÍè!¾smìWü<ñ/Â" F’—ÿN×uèþÀ34x|³—m"!¬àõºûï˜b{¶µË䕬Ç`ÿ¼©üðÍ8º$T㎇FñO¾:+©NƒåmÉ·ÏÓâÁt®y‹÷«xÒ—ro]ßùýãJƒw-à“‘óÆ“wS/1–of¬)} Ö†äeò$ÓÞC¿QR)ßCN8«gþÊ+wÔ¦FRÝßúLýkcŽlúƒÎ5}už˜”DÇa£ñÐuÔHJ`̤õÚŠ¢ê¬TmŒd¡Î#SÖª™Ð“αáâŽ)8»‡®|ot]ç¤ã$‡]×ÑuÃ0Ðu_{.*R¡w =ÎÌOñTß&dØÅÁl™ Dzt ­ZÖçÀüq´»ãiú=ƒ-ÉÉ,™ñSžìÎð @²ÐðΙñm7>~é>n鿊ßf/à×/Þ¦v…’£ašc;µìÈϧÚ2kÁnM8ÆÓb÷‹;poíZtèû ý>ûƒuÉ»õä½Ô©Vö4˜Æ·Ã¿bô‡·b/ð°`×l~O¯Æ»sç1¸­—Þm2cë±ë´¤¼5¼µ?6-âPƒÛ©_ÅŒ¹BmZ×ßÍö /ÑáºB£ãèÖïYöïÙÂÌ_Ƴéù;¨ËO‹w—² ñqbßb^Zu=¶O,T~)óVÐü…™¬Z2‰ª? cÁöc>q¤)W³C‡ÚHV†1söOÔ˜ý9Žfãøë›ç7f#ί¥„ëÔ÷fw?Æ •B¨xÝmôi'î–‚3ov ü磪ª>|˜Ãééœü?{çEþñ÷ÌlÉ&ÙB'¡„ÞA¤ ¢D½OQQNÅ;EE°¡ž]QO–ņ"J¢ˆt= Y²!›ìNùý1k @Àçý"/Ý™g¿ÏìÌ3Ï÷™ç““C  77—£G …ÐuÝþ|I™‘3ý‚þÌšöc&¦0ajl™×Óƒ9ØeÏç{«$YÔý0T»—;nèN¬¢0dä¿yè¦,BA­Ö—r«&¤|6“¡£ï¥wrá‚Èú ‘Щ·iÂæ¸ä_×кacÚ·ôÔËž(wGÆ_ÍžªÈøm;Ù¹:zTé¶ý÷¿·„}0æµÙ¤uèÉ/;GÓx÷tÖÆÿ“i· VQ ¾·?þ!_v9?¥ÞÄ‘W^fÈ3s5¨Éæ’1· ¡ðôÉÅ7ü“ë^ø–ŸSÒéT»*¿};‡!“> sݘRm[f¯g]K3h±cƒ­Mø®pçZfùBŒÊßÏü/f¢»¢IÏ AÆ×dæÞFlT%r 9»øðÓƒL[p?íëÙþê~õ=¼ðýG|¹2>c+u,ÆVO¦ºæ`âÄ›i^'«z_zy–…3/ûùö“ƒÐ ¶®œÇ/9N+Àû?lçÕ.aT-x#Ùµð.úܧ²bÝ«è{‚Ü<¢ ‘%Í…+:÷¦ü†7"ÀûîàÛËÞæ‹ûâX¨ÝÈsª2ÿæ÷éöÈ,†^ÜÒ¶µu?Þšú o›ÁÃCÛR³Fm\¹µ¡Ú½¬YyŸ=娢q™¾÷ö¥°0ê6LfOÇòÕÑ]Üò¥}²ÈËIgaŽÞTIˆÃëq¹ýk>ç=ëN~ëxâÔ\.Ô~’ÿu‘ŠBÓäñLÏùÿß2.ùwƒ}Z7á£m‹®Ñ”;Þ}‚)ƒ¦²ßÑÊ_’ÅŒèylÌU§‡*Õªâ ?]q(Ýt–ábO=ý0å1zŽ{ó¤ÌÊ¡çøI\Ö¾Pa7×á³uûÚ&¡”sLÉIU¹°ÎÅ´j‘L÷61Tïݶñ±õ*é¹ÁUñsŒ œ*TUE! ²gÏ6nÜHFFGŽ!''‡ˆˆªT©Bƒ hÛ¶-UªTAÓ4,¬³#ÈÐs°áçux¼î2¯çŠkÉ„O6qOÚz¾úïDÚßµ”V·LàÙ¿ ¢uƒjá8š6à÷­*Zát°Sö:Eÿ(3wiY(®8bóË „Þò±; ¯CEq.rñíÛÌüOÞåÏN£^ÿûø|Áj.h\3¼fl©¶Dzއ¢¹‰w…÷òƒÖ´ð·A¼Ká÷dêvšrŠvhv«îzŒ~e4=F@›W’øç‚ž,{®eÙl·X~“›ŸÃÈAv´¥ÎF^ñ‡=Îth]UG· ñïðõÍÑÔŒ¤Ôq;¶´ˆs½a°6hât^êôj'M}JÛMN>xk$QÍ[Öúpðh™F¡ã ï€Ö$Öò’²p:2kV’ê‚É€û.çõO¾¡Õæ_ p˜¹s¾àÓWòvØR÷•ÔŽQŽ;™5»ß °þ“9Ìjì¦ý_ûSÍaÛqb‰ŽÃf.Á°Ù !š6 ÎQÒýoß:dê.t-Í6€„V˜Üÿiýx>Ãhuët?Ee2Y±èk®½íapvàÅ÷>cc×6ĸìm”åw˜·£§îcÞº¶EŽi÷1ëj6»ËÌ¥cŒ Qp^ÉÏ7P= ôò€C)Ùg¥ŸcÊ>MX±ßŠðgÁ4M ]gÓ¦M,ùq9?¯KÁávGí!ÚÏþŒÝlݶ””zôèAÆ ‹Íhœñé’ÈmÿÖL¦oÄòM‡Ê½~BR+n™0”õ«x¨].ý{´çÅEi¤gd¹=“#û,|8# ?Ùá)NÕ“@Çøv¤ 7×Oêº%¼òØ lÌq8#Ãþlø~(; ' YY`ñù|ø2°;× ý@Ù>GrurRgÓªS~u_Ì’_·²ôíûèXÄ¿8ÛÍ £¦ÉÄÛ&³xã.22Ò˜÷þóLÉhAãZ‘4èt#ìÇ;³~!;_'ψÙSa¡v#íêW§ñem˜ùÐdý¶¿ÿ?~üžØå'à;VúÕ Ç_x°ÅG\wã8îýÏê†ïúJ³Ý2üì[“ö}{8ª[èÁef_z!Ë¢JR ýÌ¡@,m:v¥Ó…mˆ#¯?œGVÇí÷ •Ïç'=<þ™¾²2}äéŽØD®çåáç>&-+]°iùtFOÝGÏæÕý(r·s_ß^ôìÕƒùeŸ¢ |d¦æ‘žže_\|é,ôg’éGuÅѾu4[…¨ÓìºuëL½N6/þ’_vÛS5M»_Üçï㫘'Y8ëyÆþ'#.§¦» ýJ5?t9ÝõO®ü¿y¼ûîý×ÛÜÖ¿%šMÛ¡W°øÉWX¼éA]'s÷ÏL¾yùì1 W{PÒ¸Öiu ìŸÀ;³~á°ßOêoß0vÌ(ffÁoEqxhÔ¾o¬Oå—%_¹ù:w¼ƒGí}Þ<Ÿg³¯áÚ.‰'eÒ÷=cyoÖ/¤ge²mÕç xàÆÜÓ…¨¸’}ZÛP¢üàXöÄßýì.žÝ °ô=<Ð¥#cgfòÙ¼¤îø‚¡·-0Êrƒ§>L§>¡I¼zÒwóeæP¶}ìcÈÈ<̾C酘şcŽ’‘‘Yø¼âóÛnð{2²óKôYYÏ1¥^@*ø[þ\Ó%™™™Ì™óŸÎ[Åo;c(.¼1^ªT©B•굨Y¯1î˜ê¤îÚË‚ HMM-¶ˆ[±¬Ê?g6cÆŒ“ÞëÞ½{‰ëlüì^Ï»“W‡7«Ü€èAL‡ %wuèÍ,_ˆ&7ü—9O6gLû^Ìò…è4ö#>ûGv®šÎECî/XÿÞ‰ïrËÐ&¥ù´L¶Y‡™Ô©3ïøˆi»°—«B¿C ÈÏXAÃv×ðùêT:Ö,\-¿oÕ;tò(ï.ÝBÓ”é~ó'}Qç˜k»…èÖûvžž>—¸Õ·3ê­ž,_2’÷/ëËÊ¡o2©Å|ë3O…Î1'R¡ßŠð§b×®]¬[·ž·ßûšíYy4nHb­ªT«G\¬—ؘ(<8÷’ë;DëV-èÙ³g‘O˜üaAƺÏîæö¹1wʰŠÆÎ@¤¦É3Áuvµô ¸=EÙfëÏÅ@Ãë=y>9?à'„›è¢æÐ­<Ò¡;ͧ,çÆNÕOƒå~.·ëÔ§`ó~‚:¸=Ѹ…—•æêñ¹Ì[ù_šÇ«§eß!KÃy’OB?†3š‡B®ßÛë-×1•íóçE³‚ør,âN˜B´ô9ý´Œ« p4ß""ÚSΦOGøöÃy´z ‰‘J)c@qFœä³Ò|ZšmGRfÓràw,^ýÂIu•!ïàÏÌX 7^Ý¡R熳õsº+¹OJJ Ó¦ÍäO¢~“º4®W‡êUãH¨OÕ„Xb¼Qx<‘¸öùhý¯+‰÷ºéÕ«‰‰‰'mӺ?»ïIóËݽ!‡ ÏYê`Åá¢øÎÌ‘^o±ëº=^N¬rÉÏØÀ«¯L'mïL>=”O§e[Ö±Úi誩á-Á¶ÊRÔw³Ïæl]Í qoœ¶“f±ûœoAý@d¾L\xÅEœ·¨ãÁÃéVÕåÁëªÈAKÿ¿-ãØy*4®ÅÙ¶sùt^›½žýŸ|9+×ÞOr·¤S6&5:ð׫ÏÓsÌø­ç>ùùù¬ùu;u’krÛ H¨O–ÏOn^o41^/ÑÑ‘x<‘¨ $&Õ'}ßv|>ßÙdTi<€ ?/g¿_¥ºK{ºpFV¡sÏž´söá꿆P=µQϧ.€Š‡AþÄ qõŸ‚èšÍ¸ìâ\}ûò÷P*µ¤„üV„S‹Z[÷gsרèra;šFÎÑ\6¥ì$**oL4±11x<‘85«qv¥¬C׋.vþCK‹ck$[Cœz:Q#kqQïZ2ÂyAÕm ?å-Âi 2òPhÕ4™(Ó4‰ôDአÒã&*ƒÇí&:ÒîZ£Äνòü’pÆ)).;÷ö-‚ €Ý'#ÒëÆ…Ãé@7L\(¸#\¸\\nN—ƒO.—Ë2°,Ëî¯QÔöÎÖ/jæîgñ¬™|»lû¤qúÈ=¸–7^z‘·Þû’CgÑcd[ç=¹âº›©³î;ä–¼oAáAUí)EUPT ÅЦ€¢ iN·†ª)¨;Œ(nÊ䬬²³ôC,ý-›¿¿¡¸lÕËÉ÷ñá¼5¶êešBƒá¹k?fZ•;¹iD=¬ÁƒLžÁÓÕ×Óøc¼ùÕ˜óGðñ»é^¯UÉêªÎè/¾¤Ê×qÃ¥ŸÐwô+Ì_p#—m!Ö­±Íÿè9äAÞøìGú^P›ì´•Ü×0»‚ßðÔ5õùàîÞ<¼ðbÞûøkªêÛyø¦[X4ùß‚v8Éã«ÇûpçÇ]xæ|ÙÉÄþŽ!šù‹+'OãéÎ-påná–ÞÃXÚ{#—7Ž>YÝQ‰';jµê 8Á20\µyï³ï¸ ymÒ–¾Ã·½ÏE?³…³ÊHdí.Ü}sá÷íXAB÷çèpœªhBë›ØóÓqѬž;›ùqµøÏ=_óâO¯ò΢UT‹Tp¢Ô ,ÝJBAÀA½øÄE–¼oAá 2T4UÃ4AÕBhØÓ#NÍ®ÕP,Ms )%Ï5œuAFVêOü÷Õ;˜u´ wW9vJlW²êeÍj5ôP½cGš:sÀÓ Û5Æ¿·#sýeøšŠ‹šIMHJˆ`ÔkÓyd°”4kÜÚ–ýþêUpvÀ·ÿ7>›±Œˆ(¯CåÃÉ¿p_Çý<<+ÏW?nE܆isuZZJrÝxŒœ¼ùþ>>Zò4=êDMxû»whÜ{¿Ïl(Ni‹_¤ËË©v‹ô  –É)MA‚@/Ÿˆ•aÙgïPüA¨VÉÔ€Ãé%35ˆþ¾ûr GN"]S¯+ÝšÛÂR1nÜ'UàÐ<ÔL²}wÓ´µáLÑq¯;™7–Þ%¿bA„³%\ka¡*ªª†ZEÁá°¯«ªVò„ÈY7]rÔw€µß†ˆDßúR©Æ€û.gê'ßðí׿@à;æÎù‚i¯¤KÃ~WÔ´ C·§ #¬êXf ò}:[7:iI0× ^Ÿ~4¯[‹úõëS³ZCF~øs¦õÃaØû‹>NYRsDž „r}¬ šÄºus¸í‚ ‡zÖ/\Øçz’†<Á†­;øé㥌©YH´$uÇ­sŸbð?~âoÏ-bÛŽ¬]ö!èÙ8Nˆ­ò|ûÙ‘²=³Ë甼4²u[66.¯3‹Ûn»“ômŸÊ¡U׋éÑ} ÿùfµ”Ý<}×;¤1öJ{,WØvA¡B™ E!h(8*ŠŠ]üéTP {†Ä:·‚ŒÄöWñÁÚô²>ç×…/(%©^þ®¨¹/ÃGȰ ð™9:8mEÕÒ´ô ÙG2ÈLÍ##〭ê (Úö»Š]?nCIhD·nÝhÛ"Új¾ø~QIíUËÃèIï²uïAö§®æékî‡-nQ½ cêDò§§²ã`‡næµñwàËÎEØÅ‰µªŸ ˾᥽¹dge”AÝ1„òCd#jT‹'˜µ‡ï?z€ôŒãžÌ±‚|÷Òzöº„O7)³?÷¸‘^Á·1qûr"èÒ»[6O?Ú7ÇÒsÈÈÈ$/#ƒ#~î¸8ò},ž? _¸?K~ €/#Ãù‡ÉÎÌÄïÏ-ßAQAÛA„ æ1øý²ia¡¨*MCQ,Ó>4 œšvnª«½/ˆEq6>*© cêDÒµGK’[´§­Keø¥-Ь ‹^ʳiGù÷mos@­ÎÀ8'¯N_™Ð†e“®eá¶’ï€ýióiѪ+Ϧå_W_D‹V­hÙó‚»ñÆ—ÞÇôI‰ îÖšÄÄDš¶êÄ„…~ú\Ú —³ÌùšÁÊë\Ú¹/H“‡þ `O‡(Õ¸ë«Oh?ïQzvhM›}Xt0ß1ê±¹P«-SèÉõ=ÛаI[˜}ˆ1×w徫/âÃåûÃeðËóĽhÒ¤9=úß@°^Kjy4ìq;×éÿ¡Só†´ìp[cz1¤õR÷Ïî\Û~3xˆ•_¦CùkÏÄ2ûÂ×’·}ÅÅ›'ЩyCiÕíz.> 6}õ$Ã_Ä7“®¥eóV´lÞ„V³¯M_â\v€0wò%´é| ¿]ÍÛqÙsÊÕ£¢¶ ‚ ¼+Š^XöŸ©˜–Åñ§nÀ Qr†?L…µä;×ÿwcg\ÿ˜Ë ·Ä®¬êeeù]Òíqár”PëaíᦶãyêçwH:NV=ן‹RŒ¢f‰*ªÇe\ŠVwü]5ëäbÏœÔy4ëq ¦.çÖ‹+&(•ë÷BÃãöœÑΜ§ÂvA¡t6lØÀCÏýÉÿ¾‡Õª ¦a²-uUâ㈉ñCtt4ÑÑQäæxvÒ8 @Ë–-O¾Q=;ó4.šökð«;òá­ï0ë±~ª¡•U½¬|–¥dåJÿ…ן›Jºy€…‡¿ã…w䙑…í/¿ŠêICS¬ºcÉ*¨Y»¡Ú½ êVñL@¤7î9N…í‚ BÙ1 ûÊkg3 ÃÀ2-°ÿaš¦YrŸŒ³T(B£ÛÍïòÓÅ»1"«WZ–üèîy4ívKñðeÙÏ/P7²òꤊ;žö={’‡“>}¯;kTO“:ÞÊž5çæÁ~.Û.‚p.bš&¦i`Z&†!Cǰ Ë$¤1ôˆ”ry;{Õ¨‰ ’MEÕíËž={Έ٪«:õî#G¨ ‚pÎb™v¦Â2-L]Ç2LLÝÄ2MLÓÄ0,,ŒPÉ5ª ¥ ‚ Çc`bYºiaXºiÚ†eÙˆa™„ S‚ ¡ìøÒÖòÉGŸ²9£°HJ(à#eÝrVnJ¯Ðv³3÷±zÉbROØ.V€•s?ãëï×’+ ¬‚ g–…a˜`ÙS'†n„ë2,tÃÄ0t ]/µ&C‚ ¡3w+£ûâÞÇ$;ÿX ,'u6 ·¢Wÿkù`Mf¹ãá¥oÝD‹¶¸ê†á¬?|¢Šl}[~bÔÍWðâœíâA„³áz`š (X–aWy*`ê–ebq¬Wi¨J!àß»‰…Fo–ýúêD¼•Ô“ ›6ñÙ³—T`«nx•Í[×2±g•“+±\uÏd¾{ùj–ÿ¶CÜ ‚pV * ªTMµ»‰káöâ hª-ï®i%—v:d…‚ë½Ãù{òá„÷£‰õB´;òÊ¿ÝoXœ%”!+NØýË^ò-‹È³àiA„?u€îî©Xš¢ 94TMáiv ¡i(¨8Î5íá<¨ŒPA+ô¢0¨\ÍD¨„õõpgU9 Aþx4EµuKÂ÷|Õ3¬g¢© X i*J)ϰÊ9]+ÀÏsÞgÔ•÷ÐjØ jyμ õÚ"séXxf*Û³BâA„?ò¦3](ª‚¢j(P4MÓpº5TMAuH&C(• vïdaŽAdO±ÍÏ´#VƒCi©ìHI% ™ü IDATÝ_ôsÓötIÑMà]‘¶4üçnÄ—{re†¨° ‚ œÉ CES5TŪ)hhhІSs ©Ë®ÇДsP M8Ã(±\1òQ6,x•S¦³7¿ð´†¥8â÷‘‘‘I(;‹#~9„™»ûúö¢g¯8aý<¿Ÿ/ŸiíË Ûç/P—ýmK?¦j·'Ùºþ :Ô‰(lŸ¨° ‚ œé CXæTŸªjwøTaí.µ”š )üŽR'èÙ'$ö¯™F§!†_-â›I0êõù<2¨YÁg|»6²0ÇàÆÉ_Óºªó¸!Àדúò©a5Ù/â_ÀŒ)t;.˜p8½XJÑ¢0¢Â*‚pæ3vR[AUE‡¦ât*(Š^nI!”=“œ\" µ;ÞÊž=·–¸ZʯóÁÓýÛœ¹xúÌ*†>SÒÚY™»©{AÜELÕäîÛÄ{‡ò™0u0UäÉA„ÓÓ©P ëna¡¨*Žð'– Š¢ iàÔdºD(#Þ¤6Œªº‘~í0kk9¦%¬¶®fи»i_ÎCÊJgRÇf {d!Cz4,²bCTXAÎp&CQø]}Õ²,LÝÀ´,ŽŸé6 ºd2„2F®ŽDÆ-þ‰a»S-1ª+zôèO ªÐN«0ò³o®%\;¾Èˆ « ™Å0í6Ÿ†iwü4L Ó°[놉®Ûš%–©H!”#zõ$ФYÂÜ£Fõ¤FT—¡A8{‚Œp†Â!¬°n‰eZ`ÿÃ4-Ñ.΂Aû€ÕƒÁ’[‡[Gظ~G¡§O,C'¨ë€Q°òðû>-CG7J.RÚ—²Žƒ¹ú)Û· ¹ˆiš˜¦i™„ Ã2låU=ˆ¡‡ì@¤”29 2„ÓNvê—$·Kjz w_ДÙ%Ô{ì^þ.ý†„ï¸ëùæÙ÷Ñkôìúä–#Ùq´G­èȳóRIYø =ïúœ¼b} ÿ:õêÏúù§fß‚ ç(–ig*,ÓÂÔu,ÃÄÔM,Ó´UY Ë#¤K!”!jÍßÅSÃZ˜˜ÈóߦqñÄÄD†\s/+÷-×¶ÝÞš8Ü^šy]8‹=ª3ýÞ7ûÊ_©æ<µO‘´oX 3÷ z4!¢˜'T6ΛBÝ+_¦{ƒH9 AøSc`bYºiaXºiÚ†eÙˆa™„ S‚ ¡l‡Ô†ßŽòÁìÅü¥kÒIKkµÎÂÙï²jÅ'>Z¾i§·½ÔX./5“#(nõCëgóRÎP®?á)wd êw®Gl”âºR­œ1@~ZÈn‡:‚¯„ ëõñ_óà=½ !•Ý· ¹™Ê°‹<±ì©C7Âuºab:†®—Z“!…ŸÂ1\½iÔ´ÕÝ'ßé;=q4lÞ”qΊl˜ž·Œ Þí Z¯;©S«ˆ+µ•Ã7OMfÄ“ŸQó„,F&½¸/ž„jLiQ. -[#.y²£‹üØöÿÇ¬È Lnsêö-‚pŽbš&( –©ÛUž ˜ºe™XkÁeYÒŒK(º¸‹ lM¿n–{›ª;‘‘cíìÄ¥¿½ÈÏdï\Ì¿W]Èâ·ž´,*©;ÃÃÉ•[ÿ^³œ{×èzýÝöÿÖ¼ŠŠú^ú~Þà]ž™²ï S)•Û· ¹‹ª€¥:P5Ëî&®…Û‹‡•XUÕÖ/‘ C8»±‚ü0å1zŽ{“ä¨3ßÑsÿšÏyϺ“ß:V_‚ j¸»§bYhŠ‚æÐP5 ‡¦Ù†¦¡ âíáÌ`p(m79ùà­‘D5oÙ­¼ýË=uóÖµ=ãûÆ:Ì'÷¼ÄØçW¸eyžo?û2rpykX#FAÎy4EµÒ p¨œa=MUÀMSQJy†U ?…SBI*¬¥?N}˜N|B“xõ ïožÏ³Ù×pm— ¶,…XAÎÇL†jŠª ¨Š»€^QÐ4 §[CÕT‡d2„S—¬(–bUXK!?c5#^ÚÅç«/D« YÝ7Ö¦ßö(#žœEwŲ¢+Âùd¨hª†i‚ª…ÐÐÐ §æ@S(–]¡)šBÙqºŠ_¦85¼ÅD­Åª°–v7<ùò—\P³âÏmTtßõoŸÈÀ¾ +¼oQˆáüD±§KT Õ|ªªÝáSQp8ìðA-¥&C¦K„p–B'+g>ƒ†^Í‹vž´xÏš\Ù´³|!Nê®] ÖˆøëÕ*œÅ¨”¬Kÿ¿%1²âÁ(Ä ‚p¾f2…p ¡àp¨(*84§SAQ,ìû*y„U(ËåIâÍï  [xâO–+«Ñ¬7o|ÿù†‹ÚõO(n¬Œ k¥ƒí?p߈B¬ çiC¡@ÖÝÂBQUá'N,Ó>4 œšL—e¼X'6hTìb§'º dœAþ 7žŠb‡–ÝpËÔ LËâøÞ[†AC´K„3„ ÔE@Lá\Ç0í6Ÿ†i·7L Ó°[놉nÌh™%O7K&C(„/m-ó~ÜFë¾iVõäÖŸûý†é‹Ò¨Ó²W÷iy¬– ðñˆ.Ìhû3ÿy Î3XôïaáÂä;éѧqŽòí;;s[7¦Ð¼3 ŠøÎ–žÃ†U+ؼ/‹¨Zmè×­I™kHB»R6qØÑˆNÍ‹nöÈÜÉŠUëHÏʧY÷~´®[¶^fà+—­`Ï"¹MW.h\­œ¾^ϲ5[ÈwUåÂÎ]HŠwŸÒqرúök éÒ¾^¡1«¬í‚ œæ #œ¡°õVX·ÄÀ2-°ÿašV©Ú%’ÉŽøs·2ºï î}üG²ó‹N9£cÙòö3Lz{ù'ô¬iê¡iõ˜pš­ìló0£§m®˜Íù»x袞Lør Óÿ1ŒwÍÀo•5›b°ô­›hѶWÝ0œõ‡óN`|Û¡ —™}éu­ÌFNêl4nE¯þ×òÁšÌ"?³sÕ‡4n{ºŽÌl?ùFY}µ‹ñÝ»2êõßÈËÞÌ KÚóÚü”2[ú¦/hÕõr¾Û~„´ù÷Òõ‚a¬Ë¢qµÑ3~¡çUåΧ—:V*k» gàz`š˜¦i™„ Ã2låU=ˆ¡‡ì@¤”Ó½d2„ü{7±ÐèͲõ/P·˜¾U]ă/ÝÈ ·]…#ÔR 0 Aëägd­\?š«bÏ—ìY1“éúõ¬|c"Õ ¢~»«Y™z%½“£Ê°¶F‡^eóMŸÜvÉÉ‹­_=5‚éÖ­¬Ø<®Ü½4¢’z²aÓ&¶|}'q}6ü¸ëº‡4ñS^¹¥K¹ž°É9¸÷Yùñ8j;:TõÑ÷‘ÕÜÒ»!‘eòv¬x‰N|‹cº‚5Œˆ½]™¶p;O mv ư‚Ì~íNêõÂr>V*k» §Ë´3–iaê:–abê&–iÚª¬†…e‚’š ¡Œ(çïñ@![xï™Q$&&2îÅwùxúWDÅ[~t÷<2doÏßyÒv·/ŸÎÉ hœœLû!÷òÏkšñêœTÌà!V,þže¿.gýòE,Y¶˜ùóç³.5«Ì²õ >aȸáÔv*8Z3yPu¬K+ówŽðÆí‰ÄYD8žwè7þ1u?ÿ›9š:n³ãM¬×K´;¾Èå»V~ÁÚØ1ŒÞK×˵m@ä÷ØLs-ÇÚþô 1ÁV¤¢¢9§l\³w~Ë_ßʇý‡£YÁSh» g˲ÐM òÐMÓþ3 ,Ë@ Ë$d˜de¼p!pÄœp·½…¿_Ô^ÂÜ ¸<ù0¯Ì>L„÷ØEÙS³Ë–-áÖ^é¬=TxÊ!mÕ;\|íý |ñVþ¼’·noÈ´9¤>Š•ïgë¦õlÝàpj*›6obÛ†õìÌ8ZæŸï`>ÑnGÁÅ2®†¨üß=TijÞÁ\{Šã¦KZ’˜XvCŸ'%#¿?V«È,ɆŸ¿ô¸°aõë×güÿ-(ó”Ddí6Œ‰þ”ëÆ¾Àÿþï%.½m&ϼ|q3†>Æâä‘7Þåµ§GðàšK¸å’äS3®Ö¦Þô Ͼ3ŒZ*™»N¥í‚ œ™T†]ä‰eOº®Ë°Ð ÃÐ1t½Ôš ™.À ðóܼðñ´ºîÿ¨å9. ±ôF=À† ÈUh<–¯Žîâ–/] UW,uëÆ’“täÞî¢^¦çÄYŒÔ€Ú—fþUÙŸ€æ­Å_nÖÚÛÉÍÁÈ¡+ýU\‘§.n޻垶ˆ«.ŒäÓÇ2ò™–Ì|Ù))lµ&x‡2wÁãÔ nbL¿aÌj»ŠáT/C'Ÿy:ÎÈJ·Gfqÿ-íÁŒgKW^\˜Â‡7¶*ó¸gÛ‘Û!ýÚÖ¡à³ïªÊН#BQÊh{%”uA8%¨ XªU³ìnâZ¸½xX‰UUmý’·!Ã( ÄrÅÈGÙ°à5VN™ÎÞã”Lë´ºöOàY¿pØï'õ·o;æ 3“ì }1ÈöerÄï#3û0¡ì,ûÿ}~ ÅCç[‡ñÅÃÿâ»ßv‘›ëg϶Ÿ¸¿m2O~›ZÈ„u+6‘‘›Kú¾ÍÌ|s2/K;þ¶½h¥SÅE‡AgæC“Ù˜‘Ïáí‹øçW‡ܹ^ሼ•Ö<¿Ÿ/ŸiíË Ûç'ŽÌcj5£­1Ÿ×ìE×°ü»ÿR·]t¡£$VKpÄï###³`\ráÚ ÅCç›nbå[³Øœ‘K c3Kædpiã Ïö¯ù”n=z1ü‰Ÿ0»cˆ‰«_³m_.X6þü ÉÑ…ÐÅŽ›‡½âÉØ¾“¬|‹`Î>¶¬Ê¦}Ørkq¶5¾ì1¶nÛÆÆõkùvêCP徜r á¢,¶WFYW„S`„»{* hŠ‚æÐP5 ‡¦Ù†¦¡ âÐD…U(k¬áp‚žq\R!¦A_~ô$½nÌ3Îôr+¬]6fõà‰&\| Ó3/î[È7“O?ÿú/}€/^~‹«t/Øæ_x“Û.­_ðºé¥£è6ií>º€ž×cÜ•UŽ]pJP:­ÑîÞ¹{>ýÚÙ"g¾ý=O[+V¥Õ ðõ¤¾ücê~ûõñ/`ÆŠºÕ‰À׆7g>G—]¸À;”/çîR’mû×L£ÓGïñÍ$õú|dçqêvý;ïÞs;}Ú5 Õßžg\Ûš…20)k~à©zÄ6êÅ”{çrEç¦áôR?>žÛ»àB^šmí¿D·þWÓ:<æM®Š©Ç鯔>®ÅÛæp¹p›æO¤ÿpÏ[] ú§”Åö +ë ‚pJÐÕÖ-Q, À¡:p†õL4U 4ME)åVŲ¬Jß&̘1ã¤÷ºwï.^:ÇÈNM‹Kßä»UŸÒâ„» p4ß""ÚS¡z{}‡;«¨õ òŠÓ‰ë„¦O9©óhÖã&L]έ'm»/S‹&Î{r3­•æêñ¹Ì[ùßò‹¨¡€Ÿ#¹ѱ±DTÀ¶Ò8êó‘‡FBœ÷„LÈ~žèÚ“z½ÀìÉWºŸ‰É Bl•Ø“üRºmÙ>?&.ââ"Ë5®e±­4J²½²>¡blذ‡žûO>t5ª'`Y¡ÉÖ»ˆ%ÆC|\,Ñ1ÑDy¢äøÏ“ã0`-[¶”L†P<Þ¤6Œªº‘~íðÆØ$öXêÌåÁëªDê­Ôõ5Üž¢;E”Eé4&®]••Ö7*|±rz¼TõPaÛJ#*.Ž¢ºOXF¬ ÁÃw\RìE<ÂGµM#&.®DÛŠײØVÅÚ~ |&BåPUMÕ0MPµš¢áÔhªŲë14EÒ„2¢8·ø'†í:LµÄ¨³Æ®J)žf•ÖөªºëñüÚç¥m¤ÏA(Ó1,ón¡á‚OUµ;|* ‡>¨R“!”ëâáI I3Q[AøS_ Âõ  ª ‡Š¢‚CSq:Å //¹âBr‘‚ ‚ BQ(u·°PTGø‰ËEQÐ4pjšŸ+ÈæUsùhæB|"7/‚P)l¡K[}Õ²,LÝÀ´,ŽTÄ0 hˆv‰ð'`ßêé3äVf-O#tBŒ‘¶êC®H®Kbb"‹vœÐ²Ü ðÙcILLdøØÉ,g€bæïâ©a-HLLäùoOVݽüu[×åš{Y¹·œV¹/ßIbb"ÝGþ÷$ÛÌü]Üß6™ÄÄÄ"5cJ£Äq©¤í¥Ëiµ]|*>ŸVz\ Ónói˜vkqô0 »Õ¸n˜èº­Yb™ŠÂùOfÚ¯Ô½r ï?{Õœ…z_ÚJÖÆŽaî’\X÷„G5½ïüœYScñ— 8Rniƒ ¿åƒÙ‹ùKד­Õn8 g¿ËªŸpø¨^îmgnþ‰V{…i¯!î„ÇgUW-øö{¦­ô¸á …ým¬°n‰eZ`ÿÃ4-Ñ.þh(\гQ‘=<N…„¦ hR¿v‘Ëc«×¦I^mû³yÓÕ›FMP½)x§'Ž†Í›20®â ¥.ìКz5ŠPrU\Ԭ݀ä5cÊHiãRiÛK—Óm»øT|*>­Ü¸˜¦‰i˜–‰aAÈÐ1,ÃV^ÕƒzÈDJñ…d2„󂬌ßP,½”˜½„eFåö_’R»eøu³ÂÛ6B¥}¯ÊÕ ”ôÕ+k{i ö§Óvñ©øT|Zñq±L;Sa™¦®c&¦nb™¦­ÊjXXféß[‚ áœ&èßÉÌ7ãºÇSh—+"‚p 00±, Ý´0, Ý4í?ÃÀ²ìİLBFÉÁL—ç4zî6ü¼O-ÅO¥©¬Vö§|:ÕFO§íÅ©°þÙÇE|*>=/|jÙEžXöÔ‰¡ẠÝ01 C×K­ÉL†pNY£-ãßšÉôñX¾éЩßA *«§‚Óª6zšm/N…õÏ>.âSñéùàSÓ4AQ°,îòTÀÔ ,ËÄâX ®ÒäÏ$ÈÎ â«¶ÁRJ¾»¨ÈŒeIJ¦å¸ *–Ó©6ZVÛÍ Ù^¼ ë© ¬ã">ŸŠOOŸOUTÕª©v7q-Ü^<¬Äªª¶~IIÈt‰p^``ñË¢µøohŠ·˜RI§§Vô:¹û6ñÞ¡|&LL•~ ÎÄß§†×Qt<Ÿòë|ðôcDÿ6%XWr‚ÓåTЬZ/³í”ßvK?Äâ·WÒä†)tnY¡q)Éö²‹øT|*>=]>òDát:Q E…èèh"=¢<‘DF¸ñDzˆˆˆ(=P‘Ë“p>P§uvs?Í[ÜËîÒ™V2¼‡aCïcÅî›üùî­1´×íEn·T%SC'+g>ƒ†^Í‹vž´xÏš\Ù´³|!‚'a¨Þ]¬Úh¾OçÃ\ÂÎàˆub“Ÿ=¼8j(½ïø ÍU~ÛK—Rl/U…µ”q)Ñö2Œ‹øT|*>=}>ÕM“²cµìzŒP(„iZC! Óž:1 ]–xnV,«òo3fÌ8é½îݻ˕O8£9˜Æ~¿Jý†µ ý ôàöíM'ßШQ·>1®Â?¶Ì´Tçé8#⩟Tµ|;µìÙ¹—€nቯCbÕÂw ¡@&ûd‘o¸¨]?‰¨r>àx_™GóP^4¨Yø^é¸}{«Õ¥f\ù _K—JÙ^ʸœnÛŧâSñiÅÆeÆ Ü÷Äÿñô#wP§V tÃ$ÒÙ´-•ø¸Xâbcˆ‰‰ÁëõâñxæçñêóOpÅWТE 2AA(š 6pÏÄÿòøØÛhP/ ÓÐ †L~Û¸…„*Uðz£‰‹%:*Šˆˆòƒù|ðöKôïߟfÍš´=©ÉA°%ޚʦm;©S»&¦a …ÈÍâÎÍCÓ44‡ Ð ƒôC‡ðx<8E‡dçVÍ«°f·›þƒ/>I? Ôå‚ Š¢P«Z}1¸X/ñ±^Žøâ÷Å¡ª€Ýj< ât8Ø™šB\\\±E Rø)œ”¤ÂZârQŬ˜í¢Š)>Ÿž—>Õ4ÖM’H٘ʔ>gú—óYµf#~þ£¹ääÅw$›¬,™™‡9°?š5k-A†pþR’ kÉËE³B¶‹*¦øT|z^úTUUºvhI×v 8î#ýp69¹¹ÍÍÃïÏ-hìLÝF¼7’ÄÄÄbƒ ™.Î JRa-ËrQÅ,¿í¢Š)>Ÿž>UU•Ú5«sÓuý™>g)û3’ã!ÂíÆír¢i–¡Ülâ½.Z¶hF:uˆŒŒ$ J!œŸdeü†¥Wxù™PP,îôtJÝŒí§DÓ}zÆE|*>Ÿ–ß§ªªâp8hß¾µk×bñŠ_IÝ{¼@¿ +D”#’ÆõjШaj×®×ëÅápH!œý;™5í=ÆLLaÂÔØr/ANH®¨*.§“ääºÔ«W‡P(D0Ä0 4M#2*’è¨hbbbˆˆˆ@UUŒb„Ò$ÈÎiJSa=×UZEóü³]|*>=ÛÇE g4\.‡Ãn/®ªh §Ã‰ÃáÀátàë–†a ª•‘Ë”p.Sš ë¹®Ò*ª˜çŸíâSñé¹2.Š¢ØA†Ë‰Çã!Ò‰ÇãÁãñàrÚˆRŠèšÂyAi*¬eQi­Ð @T1+5.Th\DéT|*>=“>UPP[uUUUE)5¸ C8¯(Pa-æ.¢´åeRP,‚Åÿœåª˜EpFT1ÿs–«bŠOŧâÓRÇ¥2H!œ”¤ÂZÚrQÅULñ©øT|zz4ἡ8ÖÒ–‹*fÅlULñ©øôüóé®]»p¹\¸Ýn<n··ÛËåÂé´‹>5M+˜2±åÞut]';;[‚ AAÎL!Ó%Â!Î1êÁ åíõc:A]Œ‚í‚ g?d§ìÔ/In;–Ôôî¾ )³·–ï²Í³ï£×è9ØõÉ-G²ãhÙ“oÌ46mÚTð·9e/¡’wSVóéÌOY¸fWN€5‹çòéÌoÙvð¨8SA‚ ¡¼œNE··&·—f^Î3ø½RM¦oß¾}¿Æ¡ã:ßZ7ƒ½®bÁšåÜ4°;¯¯‚hùþ•~ ~+?~;–Kº ç·ƒ¡ríÿ\VwA C8Eœ>E§·½ÔX./5“#(¯ˆ¡;²õ;×#6Ê q]©Yöu5®š<Ÿ={öØž¤Îï"EV€ùoáµIÏ3ï¿7óÔ3IkÁëG6sóäT^ÿn/¾½‚‰]S™2{}¹l?—ÕA$ÈN¿+QÝ\9B=oA¼ÛAµ^wÒªVd¹Ö®Ñ¤WÖõâIhÆ„‘Ê 9”…Ïwˆ}³ Õƒ˜Áý,YœÅßz· I÷á´=òŽØûܬT¨r]Ç€M÷¿déœ-ä–£Vúx…Ä¢*ÒO™ºcQéÇ«; ‚ üˆv‰PˆÓ¡ ¨º9Ö~ûÒ¿ß^îõ£’º3<|£~ëßk–ó^ßbÙ¤ki5É~]oÀc|úâ­ÔŠ´/ø~ݤN¼;|MöP7Rcïá\ZWÅw`/ -šó»T@ͦÈܨPd~.«; ‚ H&CŠ ÁE÷óãÊìÙ³‡›qÉê§øhÙžcÐÚãÐNè"¨Ø¯õܬBok2œ‚ d‡ÒRÙ‘’Jº¿ü™úöídý¦Õ­Sºïèêõ©_ÛVtyësaßR)¼ÊZvgå†7£³;× Fxê¡jr+2·¤^ÊÁëI¨w²F@žo?;R¶±ç`ö)UK?ÂîÔv¦e”ûÑßÓí3A 2„3Be”ÍüŒ¾ôb.ïÛ“I_l9uû¶rX¿|;öeÔun[ÎÛŸ Eb¬}ð»j1ðÚš¼6c)¹VŸf<ÎÚ„Ó¨ª=?]£9½/óŲ=˜ù{˜9î}¿Èã»‰Šº£ B±HM†Pžßâ3•PPT4]ÚyYø£öucËŸ)vß?0’‡g¥¼sÛäO¹åwµAÅÅe÷½Ç²‹ÐäÕ|ðôãË…Ãñ†ƒ5² Oô,]ve<Ðäúçù|PÃÂê?º£ ‚Â)áô*(³]G-F¼–‘A —«ü‡d±ûVb¹ù5\ÿ?|ÅIldá/¨y›2qåzî?’‹Ë[…¨úþ'¶Fê¶~É…ø„¸“ê~o%/ IDAT2 T §žåêŽy§Ög‚ eA¦K„ðMóéUP,­BFYöíöx‰‹‹;)À8äxˆOH8)À(¸ˆ{â¨ZD€ç·º£ Be4¡à¢s:ÿ¬œËꎂ üù8Õi2]"„ÃM‰ »ØéI nƒ§râpÅR·Aìé×R|VêrA„ÓŒäIAA8=7Z2ÂñøÒÖ2ïÇm´î;fUÝǽ¿žek¶ïªÊ…»/©wA¡d$“!`ænetßAÜûødç«BLßô­º^ÎwÛ6ÿ^º^0Œu!0A¡D$“!àß»‰…Fo–­ºîcˆ;V¼D§>áÅ1]ÁFÄÞ®L[¸§†6“AAŠE2BŠ#ÜÍ¡Ps(zˆ˜ˆðkHEEsJ|*‚ ”Œ\)„c§GÌ ïjtú#z 䑼ǩå›ËSk.aÑ”d0A¡äëŠ €àç9ï3êÊ{h5lµ<…ççÙM¤â#¼x#ëžÏ”qAJD2äÀî,Ì1èTÅSX#à 0wâ£t{d÷ßÒ¬Áx¶tåÅ…)|xc«ã¶ap(m79ùà­‘D5¯Z‚ v$“!€Ë#eÂ×X9e:{WäT<4èOÆödå[sö±eU6íkn0%Šž‚ ‰Èí¦p,žp8AÏÆ8A´ýà—èÖÿjZt7M®Š©'huˆ¢§ ‚ A†P2z&9¹:D "k´eÒ/[ù§Ï‰‹¸¸“AEÑSA8™. ð&µaTÕôk×€Y[œ°T#&.®ÈC=A„¢L†P€âHdÜ⟶ë0գʱ¢‡AþÄ BAA‚ ¡8TOMš‰Úª ‚p ®)2©@1ËÐÑ KlA$ÈÊdóª¹|4s!>ý¸‹µàãyv^*) Ÿ¡ç]Ÿ“gY€ÁÚ¹ðâKï²9#ÿ²¹8ÛA 2„³†}«?¤Ï[™µC®jÄí/-Ç|ië™÷í\æ,ùnK/fþ÷‹Hó…Êf› ‚pZ‘§K„2“•ñJ”^døÑõz»(5¯â†#Ùh¼¬Zü°âgò6ÏbÀ¨g¸lí;Ôõeú¸Ë;ç*f-^M£j*¿}÷×]Òž÷l OãX¶/y‰)i°içu8{™õúµ¼±'“eðbÝê­ìغ‰-J<ÙyP«UgÀY&ÛA 2„? '³¦½Ç˜‰)L˜[îõ{òyð±¿Ñ¤Ž«z_zy–¡[`äìâÃO2mÁý´¯@÷«ïá…ï?âË•iôiKDlS2—Žå…W³¨[½Ñî癫»¡(Ôj})÷·jBÊg3:ú^z'Gˆ³AÎ"dºD(=÷~^€Çë.÷úN~¯¤°Lû¿Š–a°6hâtk…?ï=öºfËË™1c’bq‘Ãæ¥“rÍWžš ~ÝDG¯ð÷³ô#ìNMagZ†¸[A‚ áÌY£-ãßšÉôñX¾éP¹Ö |d¦æ‘žž@ž/‹…þL²3sqÄ&òp=/?÷1iY¹èz€M˧3zê>z6¯À¶ï&ðÈçérå >‚›o íÃeª'ŽñìH;@n®ŸÔuKxå±ؘ*³û×|J·½þÄO˜òx« Â)C¦K„2_µ V^9+À—ñlÚQ¸íy.[ó$Ë&Œ„ÐA®è÷Ë~y‚‘s¾Åõø5tmýPÁj/Íø‘k.°ƒ ‡;‘­ÝMÛ°,Àø·çR'2\|ªÄ2øåǹhH/ž/¿wâ»Ôò–ÕNƒ”5?ðÔ?/9¹¨UøöÎ;<Šâ㟽šŽ„BK †ÞQ:HW:HQ°""ŠAQQô'` Q©¢ôBï%ô¤rÉ]®ìíï»\’\º:ž<ÜÝÞìÎÍÌî¾ûò Á #)ÊÍ?º-\¸0ßg­[·¥û/ãèÒ1<·¶ kç Âp‹oƳ«ôÞ¥Ñirö­Ø­ØÐ¢Å†ÙlAsÝöÜßËr€N§C]‚ã*öx>hÙŽMí?cÕôb @ðŸ&&&N‡^¯ÇÛÛ½^^¯G§Ó¡ÕjÑh4¨Õj$IB’$dYÆn·c·ÛIOOÏ·?Ñ]"(6Uêw#våkÔ®ó*±–[Û­ ÷6`0ò I£C§‘4:| Øžû{Þ%Šl%Å*óöó„À‚[Œè.ÿðîß¿“x£Š@Ý¿ã7©ô!|zø¼¨\@ "Cp·ñ­ŒoQ@ (ƃœ(Á"Û õß”7E¶cµÛÙ½ì¹àŸ¨S@ˆ Á=yu.Ä¥pXÎótýpÖN»ç²}3y;¹j,í_\Õ˜M„ÕÉùÌœß}ñÐJfΚÜ9sX{0þŽþ&KÒq¾Ÿ5“9sæ0où~l¹Æw§DogæÌ™w/YÌ–ƒ1´S3#Ö²xÉjÎ\Í,QZSϱì÷Å쉺"Îw@ˆ Á¤(—V€RzM®›{ ›TgÐðÚ ûx-g,#(´Ãú…3ãï³·HøÏ¥õú¼Ý 4^¾T¨RŽ´_±âDò­ ICù `Ô©›ùä×3ä^5D£7ôËç·5O§×¼Í‹¿¼¡´‰Q˨×òaÖK#në´l2ˆ£¹Ö=qXbx³M;&ÿu¯ ¢û 1æQ GÒ´}_6ÜɽZóå† y„ðÆÏ»ÒkÈ3l_=Ž-†päjñ×TQì™\út¹Ÿ=—²ÄI/‘!¸SxriE¶s†T«è“Óøtt7Èm-y¬k]*‡6ç§š²þd:Ô¼îâîÉ¥UÆb6ØÝQ—Ö‚òV\ô>¨Ö<ßRZðkIù\»¨X« ƒ  o¯ö(RáÆnµzˢ=ºÓZ1™óo×Ô¤Oÿþ<1d(É1yOtCå†<9¹*½sõÖ‚Ò'oŠ=çØŠœWU*&#jú†ÚÑùݳh6~3_ÎK3"x·Åy~Ûr.'B´{ ì±èë÷ùiû"bW¾Æžh“;J±áëh5q_Ný”õß?͇ã—èR½ö´“<==š¯Ögæw»y¿e4sV+vêË5`òÂ]Œ.Å•4‹8é!2wŠB]Z•w†¿Ø/ïS©4ÍÛ´$ iOj„¡í|ʶ¥a5ƒëFæÙ¥õÒÑuÙ€jaa„…UcØG ¹lÌùî¹ èJxXû½ÊëýkñÅšh×ÓüE~œô(Õ¨F£þpòjþ'k›\°€pPš}k1i`mj„‡Ñû£?IÎ5-ÙcÞ3ÛŸBp5ç±÷éGpƒ·‰µ(8¬ ìŽØHä¡Û¹•m‘lذ£Ñ)×)+G#VðíOdÉ#ªŒ‰V¼Êx¹[•¤B­Õ¸ÓÛ¼ˆ~o ¡²VBPŸé½Ù|4Îù»¬ñl‹Hax§úÔh=„†i³¸’æJ¦”hðž–áe@*Më§z±cÍ)L¹"!EשހP/$Zœô‚;EJÒ$¥'rÉ—c†QE/]w„ä£ûع‡ÈÈ=lÞ¹—€`›3*¡d°à­‡ùe–Gì#*ê ¦ø3¸Cc6œI%‘‡¿@ëo¶rñb ¶-¦ª›âŒiäsi:Á±cQ¤[äbå­8” nÍNÕ@ªÈ3Ï­ {êkÓ‹«M>d÷Ñ(ŽìÙ@³¤iÖî$ÚâöÎåÁ¯Ñkæ"öìß÷ÏUç·ÝÄ]ËtÝkí”­õ8«#vsìèN&T_Æ”UQ%Ê{ÌÆÝ´zk {·-¦Ê¯cÙ|êZ±ò–·ÇÆ˪}g‰»p’ŸÇtëìvP,FNGãôe3×¢£‰:Å™ãǸ”wìƒÃz‘G¾À”‰/ðöòÓy¤j³ïñN/&~ý_~4” ;0¬C˜[„¤^µPÚݵ¥Æ¯‚c.Ýh´;¨RÖ¥‘tÞTõQséš3Ò‘zåuj“½ lÅšÍòEzŠ[§ÇcRÄI/˜Â*¸inÎ¥U ¦ã;Ryé¥ÊÖsÞNŠri½¯÷uðcܨ™Ø^nHùr:MþŠF•œñí{Ù¥õÌ®.û:¿=×_I‚²µxnÊ£Mõªø—©Èœ9/SÙÔRuž|îeNU>‡É2”‘ ~ºÑ2zÆœ—éÞ5,Ï6K–S”õ2`ð {©F+”)¸þt>×=+©£Q_eœïí¦ b.IsH:ª¶¯Ç„a-ñùOômA#rD$Cp[¸—V56š?Í £F1jÔ(Æ<;ŒØCÙýüE¸´J¥i;ük|Ó‹JeôÈÆd–½=Š×æÎyb¾.­Y©ñœ?{†‹WÓo(½šn@6#¨Ëä Å«½(«“Èùë½ó$©Õñ1j\ 3‹ßz„ù¦Øu(ŠóΰhFßOhO7Q}ÎÑ+Öj’3n¤ˆ¼©|ª0eþ<Ó¾¥õ©q{õtvd‹ »‹Èä`©4 Zuá‘Þq_å\ƒ3kߟD«‰ËymØ@žzi*Ÿu9ÌÌ-góD.L¹v•mƠ͉l¤ÃĦ¸¾!Û‰5ÉTðs¶ËraõH>íNõü1BÀQÂ5øy$s¾Ÿ)“Íù³Ñ$ÅXÁMq3.­)©F’Ï\æªÑÈ\¾š²‘t+Eº´:,çy£oNXƒè;x0O ưÑUI:—äž²yÓ.­Š•u³úÑ®}Ÿ,ÙW“1•4c*©é×HHOt¾6:Ç„6{.¿ÅÜåH·ØÉ2&°jÎD¶¨§Qµ@š?3ˆeo¿Áº#1˜LF.žÙÅk ضÚ9&Ã’j§IXÊh¸zf?‹?Z…)9ž×ÏnÍ 5ÕHb’³<“S3HIN%Ë®€buå)ÅYNŠ™¤äk\NHĦ(Eä­ Æ˜Môyê{|k<È!C>rèÈÌÊ{C=º;Š$“‰ÄË'YòÍtþˆŒË–óŒjÝ’öm›3yÉ©\âÛÐöeI:w‹‚5ã2§ö¦Ó¸‚¯;ŠÐ´÷³,ys:'’,\;·•×ÿN OóW„¤½VäË…;0)Vv-œÂá€w¸¯œS„”®P›öæÙ,‹¼ˆÃr‘%oýL¯!÷+ú“[Z²•Q_m`Þ”' ¼®›Ía:ÇØ.íi×¾-W,ÂÕWðßFt—n%uiuXÎóÁ“ï@ª'¦TãëÁ)têçtcýly[>PË£K«Ãb¦‚^Í䡘œ½Ñ0€%kÛæ >½I—V‡5=%B… <Õ.¨D7¢eotäõ¿³E×êNüŸgßþ·¨X¡9ûÖÏc\¿Gøx´S”kñ*k7½@U :ŽgÙìoéÛ=Çhð©ñß0¢c5$:ŒO›=™àÝ•÷ßÅ‚w?äñI!¬šÞƒèµÓèòü/î´Íë;KèûÍ'iº€A·[ØÜí5ÏÎd°ëýÆ'y8ÜsÞ24¥À¼Žž­ê¸÷ßaøÿhQ½Œû}ÍŽ£h5µ7\î¹í}‹·zúçh µ7-ز=•ÆUóv±5î3‹VÝ¡¾+mÇ>d~«œ²¯Ðh0sÇl k£êLøn#TÔºEÈCc"òÁîÔøÂÞ]ùkË·¡ŸÊ§ý>ƒ½Zò.Pã±Où³wõ·u- kÜRcN°%Cæñé+¨_N+. ‚ÿ4Â…Up˸.­v«I§C±š1[| >vܨKkFôzjµÆäù;yæÁàÛPj2&£ 5ƒO"ÇL¦ÅŽF_oTÀ¶ÂóíË›ŒÕª ÓIXÌVdÔøxë Lo1ËHZm!ÆvÙûѸ-=Õˆ~~O-NOMÆ¡._]tŠÝLjš ÁŸRºüǶ™SI3AÙ¿—ÃÏ´6íhðó>z×É?iÏï/òÈ»&ÖïùžÚeE°XðÏâV»°ŠH†à–Q¥~7b_Ií:;‰<ôUõ·Nhè½ 4ÚC£sÝÜtÞ<˜¶IÞ7pÜ”¤X(ÿ*½[ݦRSãc0ºUåáw©ŠøÍ·/oj²‹]ïíí1½Þ[íq»NWø¶2~~sWÆ/ÀC}{S6 ð¼i½ý(w "3v=5[ ﮬ¯äS`ëÊé}ô~ëk!0ÉÜjÒ®ÆoTQ­zea.ø×á°¦}>ÒUªR¡„ƒœÉnáÒ*ø7£ÒùR½–¯( ¸çŒ(Á {iê{Ù‰õFŽ@ D†àŽÜq vaMþ‹°†ãˆN<˘&5Yu:±Þ(ž;@ˆ àQ˜ «Þà\aQ£7PË ãŸ4©ïfÜD@ˆ àQ˜ «ÖPžöª (:üÈ, W¡07ÑÜÛ=uG8§Râa»“¹äÝE¹‰zrì!2‚[Dá.¬:Ú JY½†òíGS/×Ô¿¢ÜD³]X³Ý@‡¼:– ºoq.ݹ´éêq>Ù€êáa„ñÞ‡ãxrÒ ²\“¦r¶‡S#¼¿»€x“‚bçËQ ôìD–þ½„×û×"(|8?­9L–R|7Ñ⸰ ÁMR˜ «JÄÈq}1H::>û5ËæÜŠ=º‰*f–Б3-Ì_Á¾=[èî{ Ò~áøE#²ñ#ìÎæ ãÙ¹íëçêü%9™§x­SO2[~ÅÑÓç8µ‹aªÿñÀƒß“®.O¿×f¢Û6—ÞØF÷‰KY6·'‹F÷bÈì]X‹é&z£.¬@ð_@LaÜ47ãÂêÉMÔËÏÂßãùúï©nIP‹?ÈRüƒë€m? f_<Ð’f÷7ÀDVÌ[OŠkŒ©A:Ìs“~åô¥$â£÷ñQÿ1TíøPžœžÜD‹B8r Én%uaEò.ÒMôÉO—ãø¨š¾çL£mÊôŸ6Ò¼Šjšphó<Þé÷$ ÞpZ·‡<<š »;ÇF”k¾õ?0®_WÞÎpE#¼»2ýë— Ð.¡Ñ¾Ê%:6o@¿1Ÿó瘾nƒ·¢ÜD‹B8r ‚ÿ2»Dp˸QÖ⸉:]XÕ…|ÇéŠF_¨¨ÑhB£÷Æ;—ã§b‹áɦ“ùôÐ\*¨<å·(7ÑÂŽœàŸÄ­ö.W=Á-£JýnÄ®|Úu^%¶]*7†"ìÊõÞßqº…,0œÛ C^aO`þ¯³åÚ:^÷.Óg/#¡Ð<«Ñ{ëJ,0r9Ç!þ“ˆîÁ-Ã?¼;Ç÷ï$Þ¨"PwoçURhôÐH~îø›»ÖŸRê[}ozOÚEoÑ4ÁÍóqa•¼©×²õD• ÁmCÄp÷ÿ^S»ÝŠ]¾±¡Oÿ÷ÚËgrÕ$\h‹_¯w¯>íV+Vûmžé¤¤qâØylŠ˜Q%D†@p‡p˜â‰X¾„Õ‘çò]`O¯™HX»EîåÀÿ5(fþxò~Æ.=Uâ¤ÿ÷ZÙxœfí»qìŠÅžÀòŸfóÃßûoÛ æâ¡•Ìœ5‡9sæ°ö`ü=UÅÉ›Ãržá ÂïN}*fþú>Ý|[@ìÎè:äwR‹¡;S¢·3sæÌÛV—–¤ã|?k&sæÌaÞòýwTøÜÍcß+y"Cp‡.nVVÌèÇç_æt¼1ßæ Õ›r±šKPP#FŒ ßÀO‰5Ý["¤¸.­7â›V”{ímuˆUÒ˜Õ²&Û.eùÕëçPµçlZ‡ú ©õدþÁ¬ùg°Ý‚r+—/ª”#íÀW¬8‘|Oµ‡âåMM5 e4š»RgejzS3° ªÛµ¾r¯~͸ϟÊc”Xh™é $ýò¹ÇºÌˆ^å^ÿ¦ÄHÊ£NÝÌ'¿Þ./ìü“-g®ÝÚ²(æ±ï w(oBdîÔó.ɧL|µî$/÷oTÀ,8l8®û´|ö|?ýeÖ¬YÃÞŸ±<2¦`U^¤ «§í2&³ù†BÈE¹´"ySûá˜n ÄŠr¯-òØ8§›Ìæ‡æ{*{S²0YŠˆNYbøêÝLx©“smÉ—‡¿’SÙ 9vQyWìVÌVÅUwy÷Q±V@ß^íQ¤»Qåú{£'o*}SœãÁ°R…æÍS×aay/V¹#Ïv!3µä"»rìVÏí)áØ*fe à±VAÅ*3Cå†<9¹*½sµà‚~›Zm•Öà 4ÙÎa5»Û€> &}ú÷ç‰!CIŽ)ü¦g¼¼Œo·_º±¨€»Êyò_Üc…ÕjÆ|‹»“oUÞ„ÈÜ3h‘4_ž´¥‚yã…ùžÖ½ªÓ¢q5ʵ|“¹3Gòá›ëIËõ4S|Ö‚·Ÿßû'=ÂB©NXµ`æü}›¢`º¼ƒ'j…0úݯX4=ª2ðÙiDF%º.dÅsi(Ü•AMƒo Ä v¯-Ö±•4Öÿ4ªaáÔ'¤ö+ls=¥eÆ®§{; {¤«Ž$»sýy† Ð>D^Ê"5îëW¯eK†Ì¶ukØÁ†[‰KÍÿ¬snû¯,÷™L‡Úerä¢l%ùè>æÍM¨ëØûc3‹Ì»ÃÃÄ&Õ5ö5‚«…^÷>úð9ª‡‡Óö¹_òÔ;d/ù^2<¹þUçQk?%(|8óWoà›IÏÄ[3gÌ_.…å-jí§ѯÿ«ìŽÍ¼N$xvö”÷âÔYfìzç±ûõã» òݤOï\@°PœçÊœ¿9‰]õ2棹,˜ó:Õœuº;6½u˜Áʧ3tÚp*º¢Eµ7¥Ù·f“Ö¦Fx½?ú“d‹sIÿó‡v²zc$¤ígsÄ6¶nÜÀ¶'ÈR¬¬=šÖÃG¸Îá0&|ø½jÕ$¼f_vÄäÍŸMö,*u’/å ^y>ó”÷Ò½f_FµAâj|1Ûc‰iY “QKµû[QÙà9ïaÁ帿ʃԫFëeìÔš†e}!å MOb(usíUÒꈋ˜I‹Ñ;)ßDG¢ÕŠó<Ðù{l=«î27¢E=÷d ‡ÜBAÁ¡8P)*$I¡8œŠÄ%J„ÈÜ2S¯pxå5ðzÒ>%krçwÿ ¾O¡>½…‡!`Ð#ìùf 1϶A.Â…Õîi»bÆj’ éÜ•ÚU+a5Û #ç-åC%ô’„l3ªËî+S>”ä©È®‹ëÝti-êØ]º×'¨’,›‚V[åË;\5G¬äúnÜ•ÈuÑw˜­íìÒ¬\cÑK³7sþ×EŸÔ@@ÍP²ŸQ%uþ°©§¼'Ç€CQt~øfŠŒ 広ÉCä,¸¸D?‚ƒË9SÃõ×sËXRí”Éyú–4ztùžò–ó»ó0(Ìq¸8y/²ÎŠÈæ:ewp˜°Ê€l# Ní|˜sÿò¬øH^œ™õG,Ž=´7}NgiÅZMPr‰«ÅJòùëDM®¼+²Œ,ÙrÄXÝUç(Ú†ç_nÀ©òÇI~è…<å]¶Êî6j±8Û{Cî‚‹Zç/+5žËIè ªàìz´§àþÎñÉ‚MŸR /’™ÝáÁœªÈöX´Ët¡yËŠ‚âpF,dYF­V;ßK9£çÙåÝ%‚»BPã¾ürx3í•?9t!½ø7QãNü™Q>Åó/¿Â„ ¯ðÒ #è¥þ‹ß6'¤V.­xѰk_b¶ŸA ¸V­ZѰNƸ},Ûx‡¢$ïÇì%»IHJâhÄô¿‰Q£[;9º¸›.­[¥ó£qýÒœJ°Q¥VZµjNH-'#þâ@lŠÝÌéÈy4éö"s#Nr*òG& jÃôŇÜýµ*ï(ëÅù¸+˜LF¢nãó÷>ãD’óB~íäf¤÷g`‹üƒû“’H>—LšÙy¸–”²‘tkÑy¿–”äü®ë>œž‚ŒŒ‰¤ç˜“1•4c*©é×HHOt¾6Z®‹²,¦UÛö ù`—«.]O®\]Æ…×9à¬ãý¡Ùtä±;,çùxØTHµ1xR0k¦ÕfÚ°w!ÕÆ¨¯k±ô•¶…æýÍ®Ììû$[yüýJLk[ƒÈ—²¥Ë>*µ(ÃÓC?¥Ó¾il£#¯ÿà:âêNüŸgßþ·\ƒ eÎÜÀ‡¯wÈ ¯Ãõ×sga5Ê ý+ŸìÌSÉVÊ7{šÅ?pÖbf™‡¼ù\ÜLý¶#s k[Þj žS¤ã0PdÞ½<Ô™ÃËä;° ÙêÎÛÊ©ÎýDšKý~ï°Dù’þ]îwgoÐÄøaD $Ëy¦¹ê´ßØJlù¼¾ûýˆ™ÕYòzÉû:+†?÷埵rrõûÛ[?ßu š¸ØÂæn§¨yv&ƒ]ï7ö8ÉÃá¥)Ü’¹¯÷¦k×¹jÀWsG±ý‹̈˄ßÑzùCôòÓòÅ‚}¼Ò ‘ÏdKÇㄜúØ}|€æõ'ðýfç¾³©ÞóWf{;ï*óTfNÙ lå÷úkñkn`Ô°™tÞ6’ZïýÉÔ:è^ıÖöü•&ðT®k‹W¥†ÌߎÇÚ5p]›Fóòc-ûH2îax˲ۣå» s™ŽZ;­Àr‰ˆˆ@¥R9Ç[¸Ä…]¶£R©Ü¦h*I•Ç Íf/x¬paÜ3?>ÞÝ+ky¼Y¥[¼ó¢]X=mÏvuš åèîÓkÞfè_m‰üúá"÷\Z=Ûb6bSÔxûøp#Ö,ŠÝJ–t:]Nz%ÕóÖS@‚|¤›ª·-7ÏyŽçƒ–íØÔþ3×ÍW*°¾ rôõX犕_€ÀÐ5D}ÛNOŽÃÅq,.°ÎŠ]vf2Ìö|ŽÅE‘uu? wÀã4E}/#v«*tºÏóqFôzjµÆäù;yæÁà‚Ïaô”¾þÚUD{,¾Ët^Î;‡Z­ÆËË ­V‹^¯G«ÕºXs»°fG=²]X ì&{ï½÷Þ»ÙB:~üx¾ÏªV­*n¬‚\rV…Ù¸“çž{›uiuy´}uÔ·l1 Z½­V}CÛ%µ½^‹Z•s“·$áµAorøØ_œMI!ÉQ•Faþ…î_£U£V•Ü¥uÿÒQ÷œÂЖ•oø·{:¶F«G§ÕÞp¿¨¤R£U«ó¦—¼oX‡2Zé¦ëí†Ê­¨bµ]ãï9?òÌ'Ó©á¯+´¾¯/“¢êü®ŸòÉ*]Nå|Äf u›S¥Ì­wÔhõæÏSÞ‹¬³b׷릢.YjMéÊ4¬]ù¶÷¿«ÔjÔêW/ÿÕ³[˜»©1ŸMyˆRj©s8ÿµËS{tºLåû[8y)•s§Ò oT“RÅó©©Î.•ëz˜½$)ÏÐ쮫͊ÅjÁáp V©E$Cp7£V.^ˆEö $¤B™{:«VãEvî9‰¤ÕaµšðiJ“ðò¢ÿÅUçIÑû8t>֎Ť¡V‹VûiEÁ î Û£bæØ®H®Ú´n—é­KdÄÄÄ••…N§C¯×£×ëÑhµh]Q I%¡V©ÝÓWm6;F#Ý3M„È@K—.‘””„F£¡T©Rxyyåé&Q«Õîu2¬V+&“ ½^OXXFc~Ë1ðSp cµÊèt:Q@p—p8” äò¥KØl6¼½½ñööv EQ°ÙlØl6, *µšÐÐP÷ !2÷$ñæAÛ‰847ÏB>–¤ãÌ›¿»Þ‹RU౞Mò¯ *‚[‚¢(øùú¢Ój9}ú4F£ooôºœõ8,V Yæ,¨S»6þþþ˜]Sn¯G¬“!¸'°Ûµà]ýõ²÷^v1‚ÙSUCÃBiÔ¸1eË–Åfµ‘””ÄÅ‹INNF£ÖP³fMZµnE`` Çý‰H†àÎ)d»›C‹N—?üÀ“\<’?Ó)°&æX&/KªX n#Ùþ$µ†*•+ãããÙdÎ7U§Ó¡Õ=ðY\³·™ˆo_ qßg˜>óc‚«…Ì·«»VVìñüïѺ4îÆ+³ÖæsÌæv; À9eW—´F£¡\@9P«Õ¹¶Bdn#jöÓú]ü¶£4ëwïgÝoï1å¥O‰ÉtŠ IÈ“Ÿ­áûÑ/°92E™@ Üm¡‘ë…J¥¢TéR”.]:×öœ•?Ù€êáa„ñÞ‡ãxrÒ ·›kQÛÏïý“a¡Ô'¬Z0sþ>„MQ0]ÞÁµBýîW,š?ƒaUøì4"£]7ÐvGl$òÐNŽíÜʶÈ6lØÀÑè’›¼YmJââÐò/ ¡º+oî¹è*“&6©Î˜æ²`ÎëT '¤ö+ìŽÍ5G]±rdã/”UÝùmXcdã)F>ؤSÙÙ}æ>øGêÞŠÜðWÚõ›À×K·Ó¥IeÒãö0¶[b¬+™Ö·oÅó³§qñ…ÿ1måJbwýÊ .ùnݺ9uŒÓ—Í\»MÔIÙhÆì[‹ú¡eoAÉȺÊü´tMjW&nÇ\zŒø™6ûߢ¼>ˆÁ3ÆòÐÓ“(ûþìÙÿ<Û¾~Œ7?`íôh%‰ƒKߣ׸ã|7ÿO*k™3|kcÑÐû ч0Ôð?®eÙž˜±€k}û°îÜ5z4tE~zNÿš×Ag:ŰNƒØÑ釗&=v Ú>Á‹ÿÀúWÙõLJLœ»ƒ ßm¤Š.‹¿§<Ä»G²aß î+§âÄ–ŸèÞ¡î‹æŠÚ"ë\ Ü=(WŽ*U*£Ñh܈4»D¯×»·¶—‚ÛNJô.¾ÿây–g6`ŒÉââ² rúºµíþ¬jÏhLCqõàJ¶èFrhò”SI@E>]·˜…[mhXÛ³Øû÷ mJjü–.ŒÄ«”„A£bÞô¼Ó¿.5„Aånü1a >’DÃÚc0F2åÇ=tžþO>÷2§*ŸÃdÊÈáùDÕòþäŠVç~JW¬”ryê‘fh‹œúe¬üõQ?†îq-¡n€Ñ åµjª…‡‚ÿó¼2´5þ’DϧßâµÁØ­’Á™Ë˜ñ×Nº5ð`ÆŸÓ©õ¤Lp ^Ôªåê²’t× a ?ä:º¤Õ1“£wR¾‰ŽD«g*fïÔ{æÆ?Þ5Pû½¯¹´ª9á5« YãY½è*Ô‚Ó{Ös CA«8ÝuÞtކÔ'„@ðBˆ Ám'3õ ‡W^¯)íS‚&§˜YüÖ#,Ÿ]‡^#ÐOÃþEãym«³ŸÏn3ƒÖm®ûµOå¦ ì|íq»bÆj’ éÜ•ÚU+a5Û #ç-åC%ô’„l3ªËÓ§X¦|(É;R‘-Ù]r+ÑgösÑ«ÞÙ‚B1a·Ôt§ÍF]€UòéµÒçÕL–¯ÜÊô r˜®l£a§yh²‹O¶P§6×K6•kª` éÆLÀ)2¬v !îÄØP0fX€ÒùŽmO9Àýã“›8>¥^$3»Ãƒ9Ö¹RÒ¯š°) jIB‘M¤Xe{N9té^Ÿ J²l Zmu–/ïL@pÕ’ÈKâbɰ€¡B0å âR%üc2· Æ}ùåðfÚ+rèBz‰ÒZRí4 «B@ WÏìgñG«0%Ç“b– mÒ ®~Äg¿íàšÑDÚÕ ,ú¸%A-þ KQŒñ¿ÙV¢¥·ÿMcVËšl»”U²²py“4îû ÃéGPPs·^øO¶‹ñMӜ˔kôjtÂ厴u+?ïJ¯!ϰ}õ8:´‘«¶b'?»u:]ºtqÿuîó% ÖâÖ©•˧v1êéÌ\sNÔÅ- iäªbE¡nݺ(Š’#0< !2÷ÆKQl‘;yè3šU)UÀ7là°‘§§PRS»ÃÆufÍš=üôÑ'œL.¸KÅböb•1[­…ßô­fLfs‰C´Š=•½)Y˜,%K§ÒùÑÖ·<]a/ñu{òÓO?Ñ2´àµ7ìV+&³ÕãþìVóm /ËXÌf¬övËUò¦öà \+•” ­¡<íUPt*†y‘i¿±:½]妨sêL¹î ¢ó.Ù&n5ö´“<==š¯Ögæw»y¿e4sV+vz5}§oàâŋοãÓ¨¢—ŠW§’/}_šÎºÙ°óH¼èJ¹Ù¾ë„»Žíö|CÁõÞáü_ˆ Á½+˜5ÚìëcÁ7ŽRÁ¼ñBëž`ÔT­ß’Fu}ññ¼ùÐ~Û’÷I¦(Ös;Ð#,”ð°0÷{•×û×â‹5ÑîHDan¢E¹´¦ÆcýêµlÉÙ¶n ;""ذq+q©Åxº“|iܶÝz¶§fÃvtîÜ™:UË\í(ܶ8.­S<‹g½NPP¯|ö++~›M°ª,:@t‘.­…;Äf?ÕækSŠçÒ P&¸+ƒšß@kÒÑnØPÊê5”o?šz•|òD— ;v±Üm=Pd¹)f¶ÿ>…àjÎ:kܧÁ Þv:×32VXÞÓ£×Ó½f_¦ÌüIëQ#<Œ‡ß]@òuûv˜.²â÷ŸX¸fÿu] 2ç÷®`Ì#5 íÃüÕrœu3SÙµq 6lÈó·~Íœu)Ñàÿ<-ÃË€TšÖOõbÇšS%ê¾HHO!55ËWS ¸ x¨ÓìÓF ±.a]&7'‚¯+¿l!a2™ÜâB–ed‡Œl—q8î?!2÷,*ٚ§µúTnÁ˜§[ä3“Ç™13†½:3à™ç˜÷ÁJ]ÖéÙ.¬›+Œgcä>¶¯ÿ«ó—päd nï\ø½f.bÏþ=|û\u~ÛAܵLPÌü=å!Ư(φ}'¸pá$«>¿Á°÷Š ï@§Këß?Lc^lÓV®ä©Vi êÒ˜Õ'®aNMàè¾Óœ?Å©¨;Eº¥øÏYV›‚l-øû9î´»9vt'ª/cʪ(gYº\ZÿübÇõ½Ù³Ÿ>º“7?pÝä¯ñy§ö|v,„e«VóHõF½>J/}Gçºå©Òàa†¶æqiíw„uç\B —C쑨c¬üþUÆŒøü÷p SIDATÙ]î—¾G÷Kxü‡?ùjdS¶}ø5¯ðÖÐûÑ’å±\sÞñ)Ú„•*y[Ò1r\_ ’ŽŽÏ>GͲZ÷MÞÓ±‹,·"(ªÜ2ã¶óØøoYµï,qNòó˜N`½‚½8㙋Ȼ!¸/¿à÷Ÿ¼K³7W°wÛ2B—N`íñÄ<»¹xøoFŸÈØ}Ø›b;³qíú¢îÐX÷×—eâç+˜ô¿TÔ;HM¸B\\ î¿‹ñ1¤¸–ÁO½r‰€:µÉ¶˜©X³É1Å¿ÁÈ(DNH½zMhÖ´>íF~O¼I)ºNsGS\íOÜÔn2>)ç›Í†)ÓDRR©©©Øívìv;‡Ù.#Ë2vÙîrÁ×*1…Up—e³™ýkòÙ+ïRïÑ©ä]²ä±×rXiLò…sØÌ¥!q;Ï £wÿ"]X·~6›vï/gTïÆT~øE6üRŽ˜²8Šá&êÉ¥uíô‡x­^ Î.]€_¥S˜×u!ó’»´*ö4¢N&^7Ń;­äÙ¥Õ·Ÿq™lÞ0šðR4¨Ï_×þä—Ò!”ÕK  .Â¥ÕƒC¬Æ³¬Ã}×\Z‹S§žÊMSDé|=—›¾LêT|òÅg´©^ÿ2™3çe*ûÜš¼W -G«‰ËéÑÄ9mùé—B˜•À&îýT¬Ý‰I/¥“Ø„ÆUô9–¹?1ôË-Œêíœb^gÎ:’š¶¦jXtj(W%-Ú<‘DÅfÅßÏÙ®í¦ b®cÉmóÛ÷|@µÊe°Ï1åÁ®üùc;?’Ò¸7É/ cüÇv^yîQª—£qnTdÄÄÄ––FVVv»I’ÐëõhµZ·Í{ökµZ,ËX,üüüòG˜îäb\§NB­V£V«Ñ¸VWT•Jåîç°ÙlX,whF¥ÚTðШTH’„Z­v/Ç+Ú³@ðß¾‰+Šâ¾.h4÷ý/û^˜{ iî[´J¥ò8“#99™€€€B·gÏ É#`]ÇÎŽFtìØñ†Û¥K—în$Ãf³Q¹re÷…Vq– H²ÝNrr2ÇŽGqäT 'Î]â\Ü5²²lر"[!µš¡•E+ÜÓØd›ŒÝ!£U«¨TÞú5‚iÙ´.•+¢ÑhT*Äú˜Á¿%G-àp8Ü+d*ŠBVVYYY” ÄÏ×I’œ"Br®>‘[(Š‚¤R¹ï™a6› (Wˆ¡+Rˆˆq8ÄÄÄÜòßGE†ŸŸUªTq?ÝecµZ‰ŠŠbý¦íD>KbZ~žº÷U ÆÛGp•:jI…J%¹ž%×þ@%IÈY¶»F¼‚ŒÃ]¹*µZ¤éo[zs–ÅÙ7))X­v¢c.³yÇ~6ìŽâÌ…xzvlN£ú5Ñiµ"¢!üD†kF¶âÈï=†Án·sùÒ%tZ-¡a¡hÔ¹n˺ f:#55•*U*{P:ç/[d¤¥Ýú5eî¨ÈÈ^÷\«Õº ÏjµrñâE¶EîbÇÁ3˜m !UéÖ¡5õë„ã¥×"©$À¥ÀT’[ ¨UÎUÇ$)ÛÏEq—¼Ã!ãpd„u€$¡’éEúÛšÞjµƒ„û³àÊ•(_οÖFp5!™U[öQ©b9ªUE§ÓË`H üÃEFö¬ גݲ,»®Î?›ÍÆéÓ§ñ)UÊé¢Ñ䈥`AQV‹Å=¡X!–\"Æf³‘••uËÿv»›Í†V§EB¡8HNNæÄ‰=y‹¬!¨RYüýËâçWµJ…ì‡3’¡’d•¤ ©$P©rj@Q@vÈH€CqÎݵ;\‹…8ì(* ’"Ò‹ô·/½Ýáp¾“@R$d‡LCi*–C«Vsùj »ö'$¸ ¦ø@ðÄáp8«r­%‘ý—=þB¥RáííÑhäü¹søøxS. *IU`Ä"++‹M›6ѽ{÷|DzÙl.ó½jÕ*:v숗—WþHˆäœ¦j³Ù°Ûo½uýÂI’„ÉdÂÇÇERÈÌÌ$ÓäœcÌ”©èO`9?Ê 3͘²²œ#XÕ*@Aq€ TjTj*Ùºv¯8æz¢”pØíÈÙ¡nTjµ$Ò‹ô·/½ÝnÏó„ Ë22Mø–1¸„ˆDÌÅD§ØÖjÝ‚[ ü»#ÙâÂ.ÛqÈÎqvר ooo¼}œBÃl2cò6Qªt©¡áb÷îÝ,Y²„¤¤$zôèQ  )(:ºdɶnÝJÿþýiÞ<ÿêÉŠCÁd2Ý–Èêz½ž¬¬,222P©Tdff"iiiè}JQÎß??_| ¥°X¬œ9Ñ’VKHŠŒ5*•‚F¥AÒ€çˆ}F…¤Rá°ËÈ®·M¶£Èç <»ì|²ÔµH/Òß¶ôé™fW[Ùæ@v(ØmV| ¥$vÙAZZ:V«•J…N+ºL‚{$rÖŸP©TȪœîÅá@£Ñ ×é1¦ÑjµÎ{£kÚ¨N§#&&†ßÿS§N¹ÇP´.Eî±× ÄÄD¾ùæ¶lÙÂàÁƒ q?™L&²²²Ðëõÿl‘¡u v3™Lîùµ:ŽŒŒ JûøàçkÀ×P __>zo4Z ­IÊÕ)%IhU*$µ„Zr^ä%hÔjŠ‚CvMÅQdvçMBQvI­B¥V‹ô"ýmK¯ÒhœÑÅŠ„ÅjÁj±¢·ê@%9÷ms.^£Ö8§¯‰ Á¿¿»${= ·¸È%²»Msßè³gž=z”ï¾û.ß~SRRò}f4 üÜbÉYxíðáÃ>|˜gŸ}ÖíE’=}V«½õk‹ÜQ‘‘½ˆGöÿ‡»ÝŽ——ÞV…RÞ^”öñÁPª>>>èuz´:s¶Ž+’ílçjçàZ…¤’œ}ê²³/]Vœl첌,+(ŠSAjÔ"½HûÒ«ÕZP8v›ŒN§Ã¢ÍBcV#ÛíX,6ü zÔj5ZVˆ à?Ð]’=Æ+{àx¶Èp(Ôjµ[px{{£ÕjÝÑMEQhÒ¤ o¼ñ‹/&::Ú½_NWàƒ|AŸç¾Æ„††2`ÀªU«–Ç‹D’¤Û2FìŽG2²£Z­Ö–¶Ùð÷÷'1õ2z/=^^z¼½¼ðññÂÇ»4­ó¢.¹†ìK’„Zå\ÄD­Ò8/öZ ŵ¾ˆ]vöŸÛìVWá9?S•ä,l‘þÿíMOW†Ÿ{ï öŒ=@ìˆV†¶1F¡tÃÆ[ÿÄ’ÿƒŸÅ’5ûˆ RÕMh•¢¤.TQ¥8êàß;]Ìv0R*ÅQól,YslK–î¼s>Þ#ñ‹ŠWÚMÍgq|ƒï)2—QO‚z‚^®6ªñSÊ%‚ð¸E†Î4N¹ñà2‡±†$KrÊ$wÌ,§/·ÙŽ­­-ŽŽŽ8;;ãøø˜Ñh4W”ñóDFEÐï÷1ÆÌ¬k/3,>“QŠ ãåeçFƒn·Ëë‹ßøðþšµçÏð—< –––ð|¸ ´É³~Í 2]ÒYõçM&ù ÁNR¬Íp…ïAžQhc$^âŸaòé,“4ͯ'#Xþ‰câÑßüÐiÓl4ñ|¯zªáñ2-.´*|¢²[·Í4M¹‰oØÞÞ®2e¶£,edYÆ`0 ßïsrr2W„a8÷ý½½=ö÷÷ ‚ :s¦·©–ËÎM¹dÚV\kÍîî.\¾2|WçyëYž±ð4¾ïá/yh•_o´Á6 S˜–(Æ@ÙïRÝØÌa‹±­5 -ñ¿°øÒ±×:Kj|PšñMŒQŠ÷×šÞæ –——ñŒ”Já©”K>åèh’$ŒÇcÚí6/·_޹ї¥Œ’Z­Æááá܇“(Šæ6o–×O[’O¯k×Vúá—KŒ1h£óTV(òôL«Õb0pzzÊÕŸ—¼úøï_lÒÝìÑn¯‘$ßóP…ÀP(´§óÆ»b¼Õ7†ÄNȜ¹|À¦Rëp.2ÆËëç/ñ Š¿'dÎŽ4±üu}Åïo~eøö’°æ±³ó#N§šW¿os¡ Dd …ÓNŸe?bšæ“Ú~ÚÙ!¨3q uçuF¨|B™©¸/“¢Ôìç•¿ CÕœú E†µyÚbgžàŒ1ôz=´ÖœŸŸ3yóúg~9E’$•’“´²ðð< X]]å»Î·lll°¾¾NEÕþAž€Èœ-‹uéišòq4¢V«ÑíviµZ÷ŽŸ~î½/ ÃÏ>WÊ,FefÝBΤ¯*2Æã1qcŒ™q+Œ:+++\]]U»ëá¶3¶|±!üßQJõzf³I³Ù$ ó†Oëìmˆ‚ HIEND®B`‚rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/site.gif0000755000177700017770000000153612633765070031121 0ustar michaelmichaelGIF89aPPæ{{{€€€ŠŠŠ“““•••˜˜˜›››£££¥¥¥¦¦¦§§§¨¨¨ªªª«««¬¬¬­­­®®®¯¯¯°°°±±±²²²´´´µµµ¶¶¶···¸¸¸¹¹¹ººº»»»¾¾¾¿¿¿ÁÁÁÂÂÂÃÃÃÅÅÅÆÆÆÇÇÇÊÊÊËËËÌÌÌÍÍÍÎÎÎÏÏÏÐÐÐÑÑÑÒÒÒÔÔÔÕÕÕÖÖÖ×××ØØØÛÛÛÜÜÜÝÝÝÞÞÞßßßáááãããäääåååæææèèèéééêêêëëëìììíííïïïñññòòòóóó÷÷÷øøøùùùúúúûûûþþþÿÿÿ,PPþ-H° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹3jÜȱ£Ç CŠI²¤É“(Sª\ɲ¥Ë—0cÊ\Éa‡™/À8Ò¤çpJÜ0¤§ÑžB4…Èã¨SKšpJµDT†6¨:­qua­GƒtUø¬ÑcÞ0ÛóF…´_°mòâ-Ü‚%æ’ p·à†¹øö%hÄl ‚ ÄaöbÅY˜E1Á.äf9P°¬ø‚­I&$†l¡,UI œ¡õEeÕóR ±¶…¿N™T­ºˆÓ!©m3>j#8lNW¼¶m„SÚœUspj7lž>Û6ݵuÕ5ŒÄÊXÎÜ‚ £&j—·Âh‡ïª10i„|ÕBÑμ 䭷›hÑõgŸzëY DÌÇD(”wÁZíl¬5l!Ì!¨Ã\1¨Ö[<¨–Ã\9¨†[-8˜VK˜µÄ6¦•‚Y%ðw,äxÔ&4 $\þe CFðÐB <à`»IàÀt¹€ˆõ˜V–4À@„iàˆ mìf_œ Öiçxæ©çž|öéçX;rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/bg.gif0000755000177700017770000001155112633765070030543 0ustar michaelmichaelGIF89aYÊÕ ¬¨™¸¸¸ÖÖÖåååæææçççèèèéééêêêëëëìììíííîîîïïïðððñññòòòóóóôôôõõõööö÷÷÷øøøùùùúúúûûûüüüýýýþþþÿÿÿ,YÊþ)H° Áƒ*\Èp!€‡#JœH±¢Å‹3jÜȱ£Ç CŠI²¤É“H,À@ в¦D+YB ðPEŸq AÏÎ4fO¦ 0€H„x&åiS@Ò¡-àIS@˜ (€ IqNÀÕ€´ ÐMð0M¡M$Ы`nøX0QåC>Dä ©Ñ4%õY€(LÅ?žLI§VÞ9tÆ‹š†(YëCTê¥ÚùöCo%î@ êCÌ\0ÖKS'E¡Œò,àóki瀃ýÛZ¥Yçªþ0 v§ËÙ¼§Ñùqˆ ü¢…I è˜B…>@@>¶Ú‡v-@³ÝP<µõeP, hoM€V}} ES`´6ToMUÀTBEä“Vl½%PØuS…Óa7M„Õx“÷›Dy=´ÀTVØÖml)UžQÒDÙÃåä€P<Áål `ÀLÙA¥uH‡Ö T7[lÔÇWƒÇuFZVåðD|u¨0§So§{k0€QÙ%åäSeUUD]þ†“PP"€hý–`n‚±4¥Ui­(@vÿUV)U—±'O|E(šƒt 5•Zÿéú¡4à”<1@qtV%«t5À挥ñ„ÕbnOD@UäÑçUhyQÆPzY'(˜ïQ…SS\Æë_»ª$”NL†Z©{%…€‚.-ºê‚„G¥—³­Ö²§Jd\«@2ÓK@6<ÑcMp€·ìá”K¹Áf«—ZJš©8ÁF“‹,JU»ûG—|…([’8Ô¹¦F$éD´ò¥l‰:±„Ss% Ú¼LµÚÀx - -c˜ÀÒž¡Õ ”“> ×R¦=`T”]M@ºC9 XFt@]!5œÅ7@—‡éSU$ ÚŽþ¾WL,·T•^¶äRcêôiË‚ìX¥ÎN‡o·&Ó)'X ¤—¯’9üÙn‹2.O ZK&ïÍ·dù”çM:¡Å„)›Pª-:ÜÞ*É zÒ=Ã-ÍY¢d2}eû§qÒåÓºÁd@¥>©´vPw5ê´W«}0·[þÇ^&¿&¯@:°£îÑhyÛ·p°ÛqÊNƒò½`îÉï ­Œ3Í[Tr?^%€20Ašsr¶‡%?JyOP©¯ŒjhAHSˆò(âèi8ê ñb"– ‘CØbT!YÇz¡™LæÆ»D`Zx‘]@”ˆD` þU1Ö¢ÊD ,¤Ls*÷©QÉf7¸±°`ó-Ü4J4üƒˆtà×’ÕÍK4˜^E¤6·˜üˆ+Ђóx¶€‘9…,ÀúJàTb”$ˆIr˜”x¾è±“ÂÏtHK°$EðÍLÌXŽùeô€±´DGä ~p2LrKCÌ‹G±(ƒ P€NØs±µ¤òo¿ñZÒ`å hue\Å  ˜S²J4ÎB“ù,*• øK`ÊîMf-gá×n2 ,óµŠ~^RŽ^*%"õÒ4~;ŽìV“›ù8, kΪ`DÎ …?¦A‹QÜ7›+"ãSÿœ©Äê¹”¬q¥©f€²*³TÎK:±Ý`ô"4Æ„jŒÊbh˜·Õ™N)÷¹Èê$¢’õ•(ïIŠŒÂ­½Ñ hÿÃØú¥_í€z™ŽKv"æòŸÀ£K¥9³H‡2Mù’HĽ¶iÆ}:Iá†j³kªF+ °dÅð²J}Ɇ-˜!¤RH®‡eN<@¶Ì(ê1iCðCJ a©A72ÊA%ä ¦Ád&­’ºÍÝ(‡íH7×d)³%…p«iÌCÈä—Äz𕙤f3ÔIL5bâ}†z϶ýí5§Ã _†XþõÒ¦aWÁ²åœ½î(Kdò%þJX"<¦|òòΪΓ²²‡m±˜*ï¼2}e7YÅ\{ÃwÝF%£­”ÈvR¨ÀÊ4Љs£±”¨P”L(K¤€µ+ôdŠYû¡‡˜­>ýŒhöÇà+š‹,]ÉÌ²Šµ¬’ŠoSóÈEUvË=@^Î ¬¥ˆñGÇŠb€Ú̉3" »fZ`h¢V=‰«6¡_ÍÜS¢ë¶mK&•WKÀéw"¼K0–°kN”ÉÒº¹·g®VÝœlÞª¸A¹ÇÈ•Bÿ¶Ðlíd×dÝy™²hµ%…ª fàhe<ÖOmä•lø"à72˜pb“#Òmò=ÛœH˜K”ÖÞçq¥YO½Æ•4˜”)sâ5ð•¦Í ufZXy±ù›P+Ť:yžô€c»˜Pf°PlÊš?œÀvk#M´ëÅ¯ì …jTµqËT»åT*‹t9@‡lcëÜ{“º¯ÚXr4¡Vf›î M§T޵ªe’A OVÿ• pÚ!E(ƒ1£8`¬\|â[ÿu½ªXÐ9?UÇ·äÄNˆ5=hܳu›s"6u­V]Ì7ŽnD$“€-FO×ð+vÃ[²–yì=YÄ Ö?†M‚Õs(`‚nb“Cå³"ziÀ×ätPÓE3¡dUkOMTŒNkëCá—¥¦àä¬{gy‰b ‰›N'ZBDÀ40‹€1•ÀŠ\I5jQjfÏEqâš0½¡6&VG¢bVÂ+BÓoº–a@ñbSÄCå&*í1_4dÁ`8RÅ Ø8Ä=Ôùó°†WO÷ØQV‹Åb+1a'’2<ƒu%&—·ed8–SÓ‚AÄab½VM±>uóV ƒtp˜ ̵XÔÖá’l~×BÓFNR0Dãÿ˜v!n¶[‚ÆQyèCt5XB#^¼±6¶seZ‚zBñ2´+<3#”Å0‘”B1µ€'ƒ"uD0{ÂE !"rhœ‚?uck X HlÇõ 75|Aß GDpƒ‚0‘s1Fa` g¿R “W–„P‹4nn˜SsÒµ§UÊ5|¿Q9?„zø2sídg†\Â×n€Æ„ŽÑgC=2N²'éc_¿qz_Gäx3‹Û8x¶EZ1N±Øw‡ À$lA²’,‘i€Wï²|D8æDM!z¼¢VD‹ö¶Lµ#•#ÿ@™Q%b, ÒX[U#H§v:„¶³=[Ö"°§?Å(ßâ@å…Dy R©äzm–W9æL d(:!ËÄŽû–ŽÓh>0\áhDø¹ADc'Nl÷Åvî¥S~t$§— íAÔä±'ë“zt(‘c‚‡Ë2=4‘sIÊX#Ä%=a2±‰÷yå5óögë ¡ Ú†‰5Šzê…‡yòHH>ÕœåSdr:ÿs‘(j“Hˆ‡ÅqXÌyß †÷‚Ù2PÍÉ<ÓÂóƒE)ª)8†’B ÐÅÖ‰€m¤&—¥ÁVüb¦£´“±²ÂãæD˜}ré‘ã"¿é‹ƒpENJuLCpñäÖ±…Æ€`!G Ä* b³>"/€ÑUôbHSTî!+Çšn\òô5wó$ñ49hA  ô›ÿU/c!#íùjû6CçŸ]k9†$5­†ª{-к®ûº°»²;»´[»¶{»¶[º»»¼Û»¾û»À¼Â;¼Ä;¼p¼È›¼Ê»¼ÌÛ¼Îû¼Ð½Ð{Ô[½Ö{½Ø›½Ú»½ÿÜÛ½Þû½à¾â;¾ä›½p¾è›¾ê»¾ìÛ¾îû¾ð¿ò;¿ô[¿ö{¿ø›¿ú»¿ó›þû¿À<À\À|ÀœÀ ¼À ÜÀüÀÁ¬ÀPÁ|ÁœÁ¼ÁÜÁüÁ Â"<Â$\Â&|Â(œÂ!¼,ÜÂ.üÂ0Ã2<Ã4\Ã6|Ã8œÃ:¼Ã<ÃðÃ@ÄB<ÄD\ÄF|ÄHœÄJ¼ÄLÜÄNüÄPÅR<ÅKÜV|ÅXœÅZ¼Å\ÜÅ^üÅ`Æb<Æd\Æf|ÆhœÆj,ÆÐÆnüÆpÇr<Çt\Çv|ÇxœÇz¼Ç|ÜÇrü€È‚<È„\Èÿ†|ȈœÈŠ¼ÈŒÜÈŽüÈÉ’<É”ÌÈ pɘœÉš¼ÉœÜÉžüɠʢ<ʤ\ʦ|Êœª¼Ê¬ÜÊ®üʰ˲<Ë´\˶|˸œËº¼Ë¼Ü˾üËÀÌÂÜÊ"PÌÆ|ÌÈœÌʼÌÌÜÌÎüÌÐÍÒ<ÍÔ\ÍÊ<ØœÍÚ¼ÍÜÜÍÞüÍàÎâ<Îä\Îæ|ÎèÜÍ$°ÎìÜÎîüÎðÏò<Ïô\Ïö|ÏøœÏú¼ÏüÜÏþüÏ÷\=Ð]Ð}ÐÐ ½Ð ÝÐýÐÑ=Ñ]ÑíÐ&ѽÑÝÑýÑ Ò"=Ò$]Ò&}Ò(Ò*½Ò,ÝÒ%}ÿ0Ó2=Ó4]Ó6}Ó8Ó:½Ó<ÝÓ>ýÓ@]Ó(0ÔD]ÔF}ÔHÔJ½ÔLÝÔNýÔPÕR=ÕT]ÕV}ÕOZ½Õ\ÝÕ^ýÕ`Öb=Öd]Öf}ÖhÖj½ÖlÝÖnmÖ*×r=×t]×v}×x×z½×|Ý×~ý×€Øv½„]؆}؈؊½ØŒÝØŽýØÙ’=Ù”]Ù–}Ù˜ Ù,°ÙœÝÙžýÙ Ú¢=Ú¤]Ú¦}Ú¨Úª½Ú »®ýÚ°Û²=Û´]Û¶}Û¸Ûº½Û¼ÍÛ.ðÛÀÜÂ=ÜÄ]ÜÆ}ÜÈÜʽÜÌÝÜÎýÜÄýÒ=ÝÔ]ÝÖ}ÝØÝ•Ú½ÝÜÝÝÞýÝàÞâ=Þä]ÞæíÝ0Þê½ÞìÝÞîýÞðßò=ßô]ßö}ßøßîüÝßþýßà>à^à~àžà ¾à Þàþàá>á^á~ážá¾áÞáþá â">â$^â&~â(žâ*¾â,Þâ.þâ0ã2>ã4^ã6~ã8žã:.ã;rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/splash250.gif0000644000177700017770000000326612633765070031675 0ustar michaelmichaelGIF87aù´€ÿÿÿ,ù´þ„©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçúÎsA â`4‡Ì¦l):§T‘”ˆ8®Õ®7šÐj‘Û1ÒüM«ÃlÅ­„¯ç̱øh7äôþNGÖfg”Äç‡8#DZ˜øôcqxyy‚Wèè`i‰ "ùõ6Џ§T6º•+ÊVH$õÆ*»ë#ØÉ‡ëËðÉ[ì¦KœeÌ¢¬ÜMùŒ<-z Ë ­ êÝÙjý]îìMk.›Þ6]«W«Þ\ÙJ=.Ç. ¼Lî[ ˾bh^Ák”„Ì© ïQ(•Ð᫆å&"<¦‹b,þƒÿÝ:“%œF/ŸD>49’ÊÁ ô® LI–HNa‚Ã.%›¨ViÐÇÓX0+^­Ã%`»šÉŽòWášQ§Blí, f*ÕH3¬dtëš;œÒ•t(WaÇUÒšÈZ|·úa›- ½axwiµŠ¶/¤¹ÛÜPƒ+x ±gˆ‰xõ®ã¹XN ™éÒ˼¾mÌYMeÍ¡¿]ÚÜ\Щ±n ;¶ìÙ´kÛ¾;·îÝ·ñfæò÷<‹_‘§ëñÁ¯—7Éçœ_׿Ño˜­~‰:öÚ·ÿñžXwð,Ø'Ü.ú±ê×§Ùë>æÛøïù¶¥ßå<þžþôï%ÌfÿÁp_¿ H`N’!XBAš˜Q„ ¢@T NhŸIʶLþåvšTžp†è‹‘7„òõ™„&zÔÁ†…xׇ²1V"Œ?ÍH\Š¥ãŽ7â™6‹¡fº½–ψüÈ¡Š‚9y#X6©  !9P]èeT/…T$@§å‘–M©¦›.v¶*`Êy¦…Y•CVç,sfi˜žX$¡õùøÂDF)ɧÅôg‘&J¦NçÜi‘’îá©BU>„)i0Ú“ÔTgqghy–Fõj ßw2"WÇ@”g«ŠÖ(£-̺ `žþÒ—=:3ª ¡N‰ç †EmŒËâú…ƒ)@VP55­Õb­'flULM·¦0ðxö ´Ò^Ûl=g4ö,KšŠæfùäJG ‘뮚Úç­~öú‘ï’ )¨^Õ ¼—’Êi< OŒ,ž[V¬éVÛ,µªl ²kg½´¢¯`IR'ÂxT§®)ã+S<ÁÁeHÇ–KóËÿÒ®ÅqÄ óÁ¢…Ì?Wa™Kû`Mç9=ç}âCl/Yý3p†„œ;(Ê÷VcH˦"´RÏ*t»ö¸TO-¡y]ÇíuÂR—üöÙµ·Lêg‚ß³´„Ìaoß:p¬PVjä^êþמÿb[y€ÉäÓò͈NèOƒˆ7N¡‹BIT!òˆ—Ç©+~U„– ´¡Ôå­zPÔßÂì¸ÂÈénˆ±cŸ@ÒèGÖhk€YÑG)DJKt¢¤'7”ñŽ5a£^óÓ;N&eŒh)¥ÊH´¶mÛÆš5kxñÅÿйs#FŒ ¨¨h·û±ù1×/„B!„B!Äþ¢4÷¤\»v-Ó§O§G >œN:ð¿yófæÍ›Çúõë7n={öl³Ü›½½~!„B!võßÿþ—]eýhÒ›R!„øíRtC7W¬XÁÓO=ÍþðŒÕjÅ4LPˆe6AA9® Ó Ã@QT‘ ¿XÈìÙ³¹ì²Ëèwp?TEâe¨ØüÀëB!„¢=3f̤¢B!:Œ¦Çtf¾1“¾}ûÒ·o_LÃ$¢ $æZ<棄øœŒŠ¢`&&F,@¯ƒz±qãFÞzë-z÷îj'é´Ø´uýº®“›—KNNO<ñ^x!š¦É;C$(Š‚ÕjÅív“ššŠÛíÆb±H`„B!„BÑa´Å‹‡tè¡èºN$ÆjµÅ“oÊѲÓ41MÃ0ˆ„#` CåÍ™3Y²d ‡~8¿¦ØÔ¿DÞ¨ •«ÇãRö|ýº®³mÛ6¶lÙB0¤sa!ëׯgõêÕôë×U•Þ”bG{‰D"ÔÔÔPSS@nn.ÙÙÙÒN„BÑB8XGc †b±“ìucU ŠB!öжxñbúôéC²ÇC$AUULÓDU-¨–xBå×›ˆ0c[¸¸ûÆ|¼•»;À=¦F‰„#Äb1’=z÷îÍÒ¥Kéß¿?ORþZb“Tp"ËÞ‰b5 Œöb¡˜`B(bõªÕD£Q¢‘(º®“ärQTTDqq1=zöÀaw0=hEÇ+//gÛ¶môéÓ»Ý.B!~ã«xzÊ8|u;™ƒ£rÉ×`Ä”ç䬣{J²R!„{¤Ö××Ó¹sgT‹ˆF£!B¡¡`ˆp(Lõ÷s8*ÓËñÃçÜ1çrî¹'0yæ Báõe˸ol<É<Ù£™ýõFBá¡pˆ’oÞ⌼<É3‰e[ë…CT?‡+o~‰y³Á“ì¡ëˆ¿òíúL9¿+žd7>>Ʀcìüô—ñúÃWÅÏ•ìáá™_6•«ãÕ[ÏgÖêêx¹†bn<ívÖÔÖ󿤓y£&ÊY³}×[ÔA‚Á ‘pÃ4PUÕb¡sçÎÔÕÕìMl‚ ÅÜ12Ÿã‡ÏIçžÃ¹cÎåâ»gP¿Ûú¶·`Ã:îº`óþ÷f,_¿…ï—½ÏâëNfÚ‚-ÄbQ¶¯ü”Æp(Qöû•k ÇTŽºð1ØT¦¼õ%]s V#>Ì@QTEÁb±`Õ4RRS°Ùlñ$d(ÄÞÄF·ärõÓŸ3ý¥WyüŽóy÷ÝwqäçÂîê»›¸EÃ~6,x˜3.Yƽ WòÚ½œ{ì¡,p^ÌêóøÁ|º¦f—ØÄ6Ôðâë•ÄvŠïõ35¾ùn%Ï\ü%w-‘H„âââ6¯_³Xð${°Z­D¢Lä¡KìÕ«W'Ú”B!~[ŒÀZîs=x/à•G/¥ÀcoPlô9z<ïý߬|æ ž|ý:O¤®„—'_A—®=èÝ»'={ô k—n}àïõ¿Š-(Yø"ùùùíõ½Íþ3ÿrÄîËåç3å5íÖEo\EŸ~ýØû/„Bt$5)) «ÕŠªª‰Dœ¦iX´øfUUÑln2²²°ÖÃqãþÉ=¯-âÌCrˆU¯ãáŠ>\=úp\šÎOåǦó¿•ålÿþÈŸÌɇbÓÜñ‡+œÊÚŠ(M‡¼IÁ¬º(c&ަ³½õîÞÃÎåX·…‡ï|Ÿš}ìyX»q>£9š›Ÿwðò‡‹ÙTZJii)ÅË>&§äeÐ’Ñè2x«< ÀI_dMI 6l`Æ ¬^ö1¹¾£:#´=Ê­O½ËÊïÖóý²8-ÅJÆ¿±|} «—/äï—æQi¿®Åÿ£ó©ÓÈsÉýB!:’Öœ”jN©UQQ%ñ«]Æ¥GŸÃ•/àšáÝš’1°fb³Z°X0,©¡˜‰ ‚êÀªªXCS7âÇÏìîÅn‰o³9RQBñD ¡6 ?VU,µE"$¤›8lÖÄÊÂVUA!ª‚ª€½)Ii¨&µ1â×cªøt3Ñc°ùXÍ ç(ª‚¡X,t]Çát&z…íml0«y|ÌpÞ=ìaÜyEÙm}u£ý¸©ªŠ¢eâ´Æ¯_µ9@ Ä㉉¤éÎ,ª ŠŠEmŠoÏ,\Mñ5L“ÊÊJ,KâúMÓŒ¯ò­Ç‡¼ëºŽÝŸ·©ƒÄ^*//'++KVýB!~côHü_oš³ÍíªÓK¶ÝuÔ -é‡ßlàöÓ.a¹e8s>}ˆþ;>¸3zqíc³Xs资›rŠJÓ£H—¢’4-QÖ–Ñ‹?=w†ÝDëz#ãNêWQ0lN\…´BI6 ŽôΚð Õ Û©aÑëÏsö˜·pÈ<›B!D‡RU‹J(ÚÑÃPÝ©wž¦¡ijd w =…†Ë¦sçy¿]ÇÀ‚·óÁ\ž<Ÿ×?݈¦iÊqý›œxh 96_Ë’M4M£dÑ›|¬]L¿B7T*KÔÄñ±¨‰šfAAAÓ¬‰íš¦autæÔssøç¾ l± F¶ðÆ}ï2ê´ÃpkVTUaé†JÐkøÏígñ™‚M³bMJ¦[’F0÷‚´´¼¾¯7cQU¬Vk¼å^ÄF³yûžáܵj³ÿ=šÕ@×Ùm}³ Û[ëë·Íç‹_g‹ó7}Y ÐÔÓs—øj=I$[[ôPUvôD£;’¹òÌ%~ ŸÏ'AB!~£œV­Í×ÍˆâÆø(mž/×}ú2³ê¢œrÓ•-”Ík!S>|œN{èÕ¸fö?YaïKA²—³o‹w7 FGÞ±\{æAmn3‚%¼þv#úçÈMB!:˜êrºðâªh­uòËb!Pö On ñõCç‘—’BzVÇÜ8›˜VÀ½óÞàëËãõz)è&Sßù†ãŠ<¸óç›YS9}Pg¼^/‡]Á î¥ÀiÅj·U´#‰fS’;Ω( m׺Ø9õžÙœUqy))¤æþŽÚ«^âúSº¢Y=œxýÍ<2î0Ò³zàr;‡XUMÃêèÄÙwŸÏ„cz0øÚYÄ,­¯Okú+k(Äétbwر;ììMlÔH%ï¾RUSé——NJZYÝNy̶›úvn7nš¦áÕvº~‹Ú"VEAÕZ×E³YÈ*²`Ñ´6ã ùw$fw*ÞÜû- a·Û±Z­(’¥<à 4ˆk¯½¶ÃŽW[[+AB!~ctâÏÊÁhÛÓ)67yâÏÚ1ó‡}Û¦r:e¸[m«,ÛBYY~ÓFCy)µuX¿êK.ú‚/¾ø‚Ï>šÉ¤›þÌȾÞÊ5Ÿ±bÀdŠRäYY!„èhZAA•••G¢ÇàÎCŠ3>pä¼¶Ð}8³«#h6';ÿµÏˆ+.!ѱ;¨M¿ËÓ{aˇ;ÊrÁ Òüµ7³·¾Ñö¹¼=¹ùÕ-\b`ÃéÚ1´ô ×h¼œ6œv /¾,±í¨ñÿ¢qÜàZ±i †a`˜¦a¢(J|á™`††òóóq9ãŠÝ›ØÒ‡—·µ×ƒ¬ýú¦µ7ko^Þ¼ãú[ÆÊÊåï•¶y¦Ë¹Ûˆï_W®"‰?˜5_?&ñ!øºN8Æï÷sÛm·íuãY²dÉñ&ƒ¼þúëÌ›77HII¡OŸ>Œ9’N8UU÷{=Þ{ï=6oÞÌ„ ~•q”ž”B!ÄoOrF>%+Ñ9ˆ]'~‰T—òZu„Œ!‡ùCçp4ƒlüæ ºx[nŠùX½ð=œxË#¿¿žW§]M^Óöµë7³¶s#z} |:çÿè«ÕYòÎSŒÿ² õB!ö-//7RYYÙ´’uÓï¦!Î{yß“Ÿûñ‹o7ýc/¬»<£6/Ü…=#Œ]†Ÿ|îúX±{<ìËÓ|íÚ/X<‰'34¹ñB!Ä~ ¹’\tëÖ ¿ßOqq1¦iÒë ^¿‰Uz Ã`ݺu“™™I·nÝp%¹ º=6†a°eËJJJHMM%??‡ÓÑf‚rãÆÜvÛm8NyäRRRZ>´ÕÖ2mÚ4>ùäjjjHKKã˜cŽáŠ+®øQe ÄСC?~<<òß}÷N§“Ñ£GsÅWP]]ÍÃ?̧Ÿ~J,cðàÁÜqǤ¦¦îñúß|óM6oÞ̽÷ÞÛ*AÙìÐCåÐCýQu¿üòËyøá‡Y½z5n·›Q£FqÅW´ˆó AƒÚüÿÎCê›7aÂüqV¬XÏçkQæ‡ÔoW¡Pˆgžy†¹sç²mÛ6²²²èÛ·/·Þzë÷B!ÄoSZ÷X»äž¼{ Çü0§_|1 ÿ΂ðïxðù}|ŸVÉŽÕëèó8'ýY^{æR>:g#û´öm±µ½ŸºËB>ªÍ ÕœqÔK<ûõ}äX›ë³·Ïõ:ß¼ÿo.ºã\2Ô[!„Ø/4UQIIMáA‡P²±„Õß­fåÊ•RØ¥¬Ì,¬VësÁÑh”í•ÛÙ¼i3›6mBUU:è ºuÁív£*;†¨ˆ±‰F£ÔÖÕ²­|ååå(ŠBQQ¹y¹¸\®×߬®®Žë®»Ž@ ÀÔ©SéÚµk‹í\|ñÅ”——sæ™gÒ«W/Š‹‹yã7øú믙>}:III?¸l³ÒÒR&NœÈ¨Q£8õÔS™3gO=õN§“Y³fѯ_?n¸áŠ‹‹™1cáp˜G}t±˜7o.—‹#FìUìöµî7ß|3gœq§œr ³gÏæé§ŸÆëõrÞy;æy4i/¾ø"k×®eÒ¤IíÖaóæÍ\y啌9’O<‘ŠŠŠU¿Mš4‰÷ߟN8 /¼MÓ(//çË/¿¤®®N’”B!„h—+»/×=ñ-ÇΚĩz€1÷ý…ó†÷ýQÇU]]¹õÕGyí„ \vb_¦Îø§îŠUQˆEªY[¼:þŒÛTÞÔãÿ~¶xµ#:“¤@,¦¾b=¯Ü:ÇEÓÈ´îH2êuÛ(nŒjˆ`ì¦F¸”7^(ã’ åf !„û‰b6Ñ4LƒP0DEE%›6±½¢‚H$‚iš¨ªÚfïº_ÓŒÏE©( 6»¬¬lº’Ãéh3Aw ÄfãÆñkiº~«ÕJjZy¹¹¤¥¥awØÛ¼þh4ÊUW]Å’%K¸á†;vl«2ÿú׿xöÙg¹çž{8ýôÓ¯¿ùæ›Üwß}\zé¥\yå•?¸,ìèUøì³Ï2`À >Lû¤“NÂçóµ*ÓM71þ|Þÿ}233w“ãŽ;ŽÂÂBžþù½Šá¾Ö}úôéôí@Œ9’ÜÜ\^}õÕÇ¿öÚkùì³ÏÚ]¨ùx“'OføðáR¿¡C‡2uêT† BÏž=÷:m9äC䧪Bñ1cÆ Ž<òÈV¯¯úøiF\øú]ü]6’îy騴}fŽÔ­çž`â”—[¼žyØhnšp£Fôgû—Ï2tô=»=Îä™K{x% _dèèÛZëéÇ`P§Öê×ÿ_úž[Áw‹¯úásk !„b¯$ÆA¨ŠŠË墠 €ôôtêëë‹©„ÃatÃøÕ_¬EU±Ûí$%%áõzñz½¸\®‹ê´å@ˆÏïÇ¢ªX­VœN'n··ÛÃáØíõOž<™%K–ðÇ?þ±Í%Ä{$¦§§sÚi§µxýŒ3ÎàñÇgþüù‰äØ)Û¬G‰%€Óé¤W¯^,Y²„3Ï<³EÙ0þ|6nܸÇ$¥ßïÿAó9îKÝ{öì™HP¸\.zõêÅÊ•+÷é>æææ¶™ Ü×úíÌëõ²yófV­ZÕ¢ÎB!„?Dßãdzqíé¬Zö ‹¿^Æ”ë.£NíÃSïj3¸7l)Ýs탌þÓÝ46†Ñ±àp¹p;wŒ÷î2øRJK÷~±Ã.ƒÇQZ:n¯Êz OdéÇVIP !„ûQ«ì”¦i$''ãv»ÉÉÉA×ut]? ÅP%±ðÅbAUÕ¬_ql¬š†¢(ñ•ÉUu¯®ÿ¥—^âÍ7ßdРAÜ|óÍí–+++cÀ€­z”ªªJ·nÝøöÛo÷©l³¬¬¬V¯5¯À¾ë¶æ×Ãáðc’””„ÏçÛëîKÝÛJ”:νª_[ ;´~;›8q"wß}7\pYYY 0€#Ž8‚#Fàr¹ä§¥B!öþÙÓ•ÅàwCF0þÚüðbs“šþÓ/¨Ú¼dÙä¾ !„ûS»]èš“YÒ|”öò+ŒÍM2}þùç<òÈ#äçç3eÊ”ŸõZw7œ¾½m{“8îÖ­kÖ¬!‹í±7íþ¨û>½aµý·šä°aÃ8ì°ÃøüóÏY¾|9K—.åÃ?dÚ´i<ñÄtéÒEÞüB!„B!„Ø/T ØÕ† ¸í¶Ûp¹\<òÈ#x½ÞÝ–ïÔ©7nl•4 ƒõë×Ó©S§}*»¿ 6Œ@ Àܹs÷ªüþ®ûMhvDý<'t·Ür ¯½ö=ôUUU¼øâ‹òÆB!„B!Ä~#IJÑBmm-×]wÁ`x€¢¢¢=îsÜqÇQUUÅ»ï¾ÛâõY³fQSSÃqÇ·Oe÷·Q£FQPPÀ”)SXµjU›e–.]ÊÛo¿ý“ÔÝáˆÏÑöiÿ[¿úúúV¯õïßÿGÕI!„B!„boh±³‰'²uëVŽ8âêêê˜3gN»eO>ùd.¸à>üðC&MšDqq1=zô`Íš5¼ñÆrá…&öù!e÷7§ÓÉÔ©S¹æšk¸è¢‹8öØc8p n·›ÊÊJ¾üòK–.]ÊÕW_ý“Ô½OŸ>|øá‡üãÿàðÃGQFŒ±×ûÿØú9’!C†Ð¿RSS©««cÖ¬Yœzê©òæB!„B!Ä~#IÊß›ÍF$Ùc¹o¾ù€¯¾úН¾új·e›“”‡çž{Žÿûß|øá‡Ì˜1ƒ´´4FÅ„ HJJJìóCÊþ yå•Wxýõ×™7oO<ñÁ`äädúôéÃ}úH D‡êÓ§ª*?J„B!„B±ï$³ðc·ÛéÛ·¯ô¨?š¢(ôíÛ»Ý.ÁB!„B!Ä¢µõ¢aD#Qìv;¡Pˆ@ €®ë‰Ä–a8t]'ššŠª¨¨ªJ4Åjµ&zV‚ª"ùÐ_ »Ý΀¨¨¨ ¼¼\"~°ÜÜ\²³³¥¥B!„B!:D›IÊ€?Àwß}ÇÀYºt)ùùù,_¾œƒûL,cíÚµ 8ââb (ÙX’X”åÛo¿eØñÃp9]TVVòùçŸsÚi§ÁNkjD"*«* ‚¤§¥ÑÐØ€ËéÂn·ãIö°yófœ'‘H„H$‚ÍfCQ”Äâ>ŸŠŠ ÒÒÒ¨o¨Çåt …ÐuÂ.…`‚ÏçCÓ4jëj‰F£äååQS]ƒ×ëeëÖ­x<²²²(++#‹ár¹ðx<444PSSCff&ééé‰óy½^‚Á ªª’””DeUéiilß¾Ô´T’=É8λ9†a‹Å@‹ nè`ít„´¨EA×uLÌVÛUT4«†ªªäææ’••…Ï磶¶ŸÏG4Å4MygˆEQ°Z­¸ÝnRSSq»Ý²HŽB!„B!:T›IJEQضm«V­¢¾¾ž!C†PVVF—Â.Äb1jëêÈÉÉaÑ׋¨ªªÂív éÒ¥ ˜F<ÉåõzÉËËC7ôIòòrÈÌÌdݺu†AQQÛ++IJJ¢lk]»vEÓ´xB³²’””5ž™Û¼y3iii”––â÷ûéÚµ+6›h4Šª¨D¢V®\‰Õj%“™™IÀ`ÅŠtêÔ —ËECC©©©X­VJKK±ÛíTTTPTT„Ïç#‰àr¹¨««£ªªŠÊÊJòòò(--%‰âõb‡òòrºvíÚ!7F7t–.]JCc†nRZºÕ¢P_€jQ›z·Æ0 Åxl*·o'‰™•…ÃaÃ0vÞn †øýáƒ),,â«~{½^¼^¯¼„B!„B!ÄϢͱš†a“›Ë€ðz½Äb1 ÃÀ0 t]ÇÐub±™™rÈ!tíÚEQ°Ûíhš†nèÔÔÔÄ{@¶1Ô0 ìv;555¤¤¤àr¹0 ƒh4JeS¢R7tœN'n—Ë…¢(4Ô7‹ÅHNN¦ºº]×IJJJ ?OJJ¢±±ÈËË#¯SMÓ¨©©¡{÷î„ÃáxÀï÷£ë:éééôéÛ‡ÜÜ\ÊËËINNÆëõbš&@|¸z—¢. 0€p8L Àëõ¢i†iÄÿoÑ0 £ÃnŒ‚‚ÓåÄðÎ;³ˆ„#|AÞyg¡P”T/6» ͪaÑ,hV•uë¾'Œàq'³îûï‰D¢‰íMÅ¢Y@_“B!„B!„¿ŠÙÆØ^]×ñü${’ihhÀãñÐØØˆÇãÁÄÄ×èÃíqãkô‘œœL$!û Ì¼ IDAT¦Çp9]¬V+>ŸÔÔTp»Ý-æ¤lN’iV ›5Þâ«O†¢(¦Íjv {Öu›Í†Åb!c·ÛûZ­VLÓ$ ârºç2LƒX4†ÅbÁb±`š&ÑXMÓ…B­æËl^nš&º®£ëz‹…Ab±X¼îM½<›Ë67w»Ýrc Ã`ÅÊ<÷ܳœ?v;wFÓ4–-[Æ{ïÏá¬ÑgÒèóŽ„1›æݺ¥ŒcŽ>–E‹Ñ·__¾^ü=zõ ÓwÄÞïg@¿ôêÕKZ¿B!„Øg3fÌàÈ#”@!„¢C´9ÜÛb±ìI 9¹å¿ J«×l66â Åæ!Ò©©©ñ2MÇÙYs™fV«µÅ¹w¥ª*6›­Åk͉Ã÷U¥E‚@UZî«(J"ù¹kÙæki.§išÖ2D;¿sÙŽœ‹À4M蔗ϧŸ~ŠišlÚ´‰³Î:‹üü}hV ‘(˜¦ à÷ùQT•ªíU‰Ä­B!„B!„¿dZ}}=.—«E²Oì_¦iÒèkÄ¢ZHJJj³Lób%ápˆ¢¢ÞÔÕÕQTT„aèÁxRT5±évLÃ@QävÊåã“äJ¢®¡†ƒî h;å}£Ñ¨¬ÈüŠÅbl6‡C"„B!„BÑmÕªUäuÊÛì•^w?‘X,FII IIIôíÛ·Í2¦iðûñù}ØívÆŽ‹®ëÌš5‹F_=‹}ÍöÊ ôX|ñ­)Y]]‰ÓåbîܹìXà[ÁÄÄÐu²ÓsÈÊÊB×u¹û™Ï磬¬Œüü|òóó% B!„B!„8 ¬Y³†h4JJJ ¡PˆX,–X³Æjµ¢iV«5ñ‹Å‚®ë„ÃaRRRZOËÍÍ%-- w’[¢û‰Åbdgg·¾k™ç~ÄwÅߋŸü‹Ï0M“H$Ê–-[øÛýoµONN.ŸÀŠå«X½z57nlU&))‰sFÁ“ìAUT ÓØ)‘Ió"à{MQâ_m­¤(ÐVÞ»½×DV«Ã0:l®R!„B!„Bˆ_‹ÅB^^:uBUU¢Ñ(@€P(„ªª‰eó—jQ1tƒ`0H$iu<­¨¨H¢ú³Ùlî¶ŒªªtïÞ/¿ü’p8BZZ†a°ukU•U 6¬Õ>)))CA¼^/ýúõcç{k¦i’™™Ivv6±hŒÍ›7“×)/17§iš„Ãal6[b#UU‰Æ 2±Y!§KAü“` ²2L@UâçÓu¨o0q»L¬ÚŽädM­IZêŽò‘(D"&6›B,j¢ªàp(fËíî$eÇõ˜;ÎõKæñxðx<Òè…B!:H,D±9±H(öJC]N¯KÔOm@%=ŵÿNfFØVº OnIÚOÿ°^¿½Œˆ3‹LO|Pãvjò²“;ü\ûëØf,H½Ï$e/î“ñð÷´Y4XMyUŒNÙ?Ë{¿eÛÒ©)+CIÉ%Õ¥m«#Þû­IÆ"4ú(šÛ¾Wm¸Ñ,x<{wí±ˆÌ·û Ö±¸I²5o×ñ×5bu{±ýDï“tê1-6ÜW‡½, ªªîHHÚ¬¸\.|>@MÓPU‹fI,h­£·¹ ´³º·øå0LC70šº*ªªÚîÍ41ÑcM7[‰/rÔ, …HIIÁ0 Š‹‹±Z­ÔÖÖRUU•HLF"’““ñûýQTÔŸßÂÂE:ÍSY&%)de(C&ÛMªkMr³ì6UU…FŸÉÖr“Âüx’ÒnWðL¢Qp8 {W•u ‚AG ;S!5©­‡,*8 ¹Ù ›J jëÀn»-ž(ÍÊPp°™^S!„âçñ³¬îmÖ3uÈát}a §õ”‘*{üHÚ¸ŠÂÞ#¸þ‚“yxúFM~ŸGÇöÛ÷%ÂÂWÿÎè‰O‚uŸ¬|‹®I?]B«|Ù[L<÷ZøtŸ»ŠÓûxÁ òß«†rý{ù_Ÿýxì­ æä©…,~eVEi'9±—î»›[Ÿž}ÀÞÓ×Zδ[OåþW+H?ò,|õ\ÊÏÛ¶Œð&®t,kF>ÊžÒî}ú5¶­{ÿí' ›¿âÊÏfãØ4÷}N¹óE¦N8G;×S»q>yêYPýò èçO奻ÿ@ún‰:oÝ2˜ù‡½ÄÔ³z´ùÞxíüè¸ò=®92/þRtã>šqsÖ0¢ëþ_‹â‡ÆaÛwó¹wô%ÔŸx>êœé,°]Îûï]G¿NI?º.[¶l!##ƒ¼¼<4«†Ò4Õ`ÀïMi³Ù°Z­Øl64MCQ•DOʆ††VÇk3Ňihlhÿ–é:Á`0>T‰$Z3¿ßO0Üë ‹F£-¾7Lƒp8ÜnyŸÏ×j{,Ãï÷PskªŠŠ¦iñÔ›oª¢´ù¥*ñ̵ªª¨ŠÚr[Sfâ‹òdddàóùp:äååaµZQT•ôŒ ¬6ÉÉÉddd 6ôê®’•©àq+&6¸“zvWéÓKÅë‰'(u=Þò¡zvSÉÌP ãÃÁl6ÈÊP1MèÒYÅáˆ'(ÝI`µ*¤zÁj'5;(X­àõ(dg*8ñc${rs$½.„BñÛÒP²ˆ)[üüë¥Ï‰þ‚k7~ɲÍþý¾O{Œp9 ojõzEñÿè|ê4.»á*Žu[Èth?ø{E±1øÜ[™9åà(â§îp—û»?0å¿SHtlRlô=w"·Üs=™®¾Ç|ì“_¿õ Wþù÷»M")Z£¯¾ò€¾§;®5— ÷ÏæÖ¡)$¥Úø©û¨´Õ¶‹‡‘×\Ç-çý®’}:Ëç¾OyÀüE´­{ÿízã*®<ñl:Ýý6Ÿ?û4›×~‚úØ%ÜóÊò6ˇ«–rðQã8ò‰ÿ1ý¾IÌZ¹€CgßÄØIïjã÷‡.åoçœÉœoË)<|8r­¬ùäi†L˜NulGy#X ‹‹8éàü›0jô?)©SùýÀɱU3óÞsù×G%¿˜8˜±R¦œ{)ýÿõ /?4‰ÿ|WÌãgÎâòIó;ì÷¨¹Ó ÃÀ×裱±Ã0£z›s†;w¦kK›M¨xM1±hŒ””TU¥°°uëÖa³ÛP•ÚÚZRSSغu+éééx<ÒÓÓÙ¶meeedffŽDHöxÉC»ÝN$Án·SßPË•DaçÎ,ÿö[ÒRSINN&ÉĆõÐ ›Õ†§i‡Ã¢(ƒABá˜àv» ‡ÃôìÙ“ââb|>iiièºN²7™NyäiŽøPîæä­¢(dee‘••µWû:-PÔ%Þ Âa§£ý†ePYe’/SØYÁaWhëgaaÁžÍäË-B!„è,zý/¬œþ8+þ4ŒCr¬?{­ÂUßòç‘çpÎ;Åün?îÓþƒ¾™wŸÎ‚/2øÐ–I‰E¯?ÏÙcÞÂí áÑT"šöÃŽñ“Zw2øYîC’{×ùþ-ô9ú\ú½?îqÇ»Åç¨` O¾•ÇCwä챬Õãþyï©aÉÜ™Ôçϰƒ3÷ë½Um)ä:¡ž_DÛR´4N¿üÚ9vÉÂç9åªÏùbåˆo·ûÚ¶:æý×ñ–ϞƂðïøpdÿx»puåò{Oå´[ÿKF>M¯Ô–¹… _ë †öïœ(É”«xþÂ+XtÉ:Ž.t´jgÃ/ÍÜéeÚ«s€éŒ¹äFî;‚ä³n[õuÇ]@g‚ªtaÜ)ßòЄἹÈÏßÚÎu·œÍðži¿˜8Dê¶SÜ£O¢;é~ðáøWûˆ?ö·¨iš‰EG"‘ÕÕÕøâSÆb1¢Ñ(III‰!á»}¿ïúBCc JbNBEU…BTTT°­|áHUUq8lß¾P(„ÝnG×õxòRÚºZl6>Ÿêª*¶mÛF]]]bŸòòrü~?v›ˆé1¬šF8!‰P_W®ëD"Qjjjhll¤ºº:Ñ{Òî°…QU•­[·Æ3´f|þÄÌÌLÂá0Û¶mkÕ;SìhDÕÕÕ,[¶Œ@ @$Á0 "Ñ¡PˆH4B4M¬þ›”o3¨©5©¬2QˆÆ ºÆdC‰Á÷ë "Ñx9Ãð&ÖRƒ†F]‡h´ynI(Ýj ë ™ÄbÐÐ`²½ÒÄç7©®1©o0‰ÆâÛMãçÅšŽoÛXbPQiRQiR[g ÅÏUZ?~4Öòœá°I$ ‰Ñô>òûMêêMÂáø¹ #^^>B!„øe‰Õ.ᢗÿÈ;3ÿ Ñ%<ýÞò6'‹g=F~~>ùùùœwãC,ßêßó6 äë79¥kgòóó¹òž)©b«YüÉ,þzù™L{û=™ÐŸüü|޼ì!Š«Â„«–òÇÃOeOçOÃzpñäw ™>þ¿óÈøO¶†Í6^míc¬ZÅäËãÇøÇ;˜÷my|Èí+SÙ Üqãåüý¥|òÎSÜxÃeœwÓÓl›|ô\÷R9oÝq ù=.aÑÖP")ñúÛŒè¿#)®ÞÀG/ÿ5ƒ—ðUSÏÀ]ñÅÚ-,þd·]ñ7­þ:Q¯»ŸûŒúÆrf<ø§D65ìýg®Æ²åLžpg_:žüü||}QÓÄW±žÞx’óû_Âôÿ>Ïù’ŸŸÏO̧q/¶·¥¾¢„Ï>z•óÝÁ¿¹Ç6Ð^ÝÚº_ÛÛûì3ªªª‡ÃñÞ•í¬ØÜêÏ.N‡“þýû'|ÍĘèi±XÐ4 Ó4«÷lݺ•üü|lVݺvÃf·¡ F©®®¦±±‘ž={¢ë:XmVš†"[Tz÷îM,Ãér&zH:t]GQ”D7ÑæåËóróˆÅbX­VLÓÄfµQTT”F±;ìò4×V»ÆÄçó±eË*++ã ÁjÅïó‘ššJcc#@€ãŽ;ŽÔÔTBaX¾2žˆÔ,ñ9%órTB¡xb¯²ÆdýF»=Þ‹Òb‰'ú*¶›äå45zêëA7L²3tÖ­7Ø^OzvÊUñLjêLlÖx¯Ë¬ ¶WšÔÔÆ°Õª€ Y™ >¿™HFz’@µÄ‡‚—o3Y5ˆDãDzXš’“$W|h¹Ã¡ Y ªÚÄá€úp: 9Y¡®Î¤Kg…~}d:v!„Bˆ_Šåï<Ê™wÜÍ!‡¥sE®“iþ‡›Î´Óœm:_¼p WÎ9†¥ë·\Á‡œÊŸü]˜÷ïÓYÚî¶QT.þ7C/òåÊMxë–ró‰g1tNˆeŸÄÚ…ïò䜯àÃO¿öOýþU.»ë!†/ó°ò‹ ù×k÷3tÔm<4ó3FöÎÂNEq1ø„c€}׌ýZícõ­æÂ¡'sáÌoØò8¼vû.8ùf|µŽ!cnÀŒ\ËÙwÌá¯gþ…îÖÕ¼öéá,ýìR²ì GŒ}ˆÿMŸ»nãγúâjZ@¡rÍg¬0™¢"à²(¼r÷%ð×™;ç÷üíì˸þo0ïߣZ#¸m9Sþ|-¯UGxñãu¼ôÆ«ôí÷WÜu.ÏÞ÷?÷³^ÌiçÝδ'óÀYíŇóŸšÀ£‹FóÝÒЋ_§ß §2è5¢TòÅ«³ ¦‘•ÿÌÓ¯¼ÊÁÿžÀ£“Æ¡§¿Ï̓|»ÝþÀYýZ%жo^ü×îgAàø¦¡Ê»k§¶[·aw½_l+þ¼Õ±?yò$Îû¿#ùߊtõÔ2ýÏ#øÃÑñô¼Ué±rîc|´°†.6xíÅ×èþòÜÓ=œ8ìMz§ª`Føæé\8~ÅÆà=Üw#üóßS{ŠF¾½eJÁ•w÷>PMÿã.§ß¥§ádáÌÿrÛG+8²0‰ªußðʯ¸m™ºï—/â™IÏP{â#M½¾ö­m3àþ;e£ï®`öÇÿ¤WŽ‹Òå öoÛ²ærñ¤»øÛÐã˜æ;…+ïéMåퟒôçL<«j¬†ÕŸ¼É½Ífsý“o3ëå.œvÞíûÞCrõ£|8÷¿¼tþù\>æ¾Zz?ì­]¦aÕJ?U)t@‹•ó·cŽcÑYO°nË¿±E¶ò·¡ÇñɠɨÀ÷?ͯ¬¦ÀÛúXzC=}FcÍçu¤˜ÑâGªÒô‘}ù÷Û9£ËÞ‹±(œËšòFz¥ÆçÉ´XâÇ/­ µ:.å¶Qg¸â9æ¼Ð“ ©Gc¼3Ž“ïÌá‹â·èlW0‚¥¼þv·ÜîÙ¸i.§ž}=½1‡¿¿?‡^cŽaêéçòÆ]ðâØƒ~qP´|®}ißœr)WŸþ{n{þ3®Þ¥C~7†‹ñÝwßñég Y²buÁ(v{Én'n{˜òªÍ¬ý~=ëÖ­ã¨£Ž¢[·níNÓØ*IÙÜõr×.˜n·›H4‚ÃáÀb±‰Fšnr|užnݺµ(ÛÐØ˜K1==‚‚‚ø 5 »½uòÐn·ïx]!±"òº\.LÓLôøs:;.LÓäI® ÉÉÉtéқ͆aD" ;wFÓ4êëë›Æ× û[hh4ñùLüHö@’K!'[¡ÑO^Ãñž¡l-74P%Ù­ðýƒ´T…ôTP- î$‡C¡? Û+ 4­y>K…Ü=Ÿ—27GEUÁé0é”=—K!Ù/¯iPWïmi±@Q¡Jn¶I}ÄbñÞ—6[ü‡Q,ORZmÇçÔô¸ P 3#~ IfºÊNMI!„BüÌŒð&žžjcâ§ÝAQ¸à¡ë˜6æÞüäjnÙ€PÅbξsÏ|ò4YvlqçýãùŸÙcû’v·iz%¯^ý=¿‹ÍË5̪‹Bݽl\Ĩ1gqó£³yüÝéœÔÇ ‡÷ç…Æ-\øà½,ÙrGd¤œš‘X9vô?ç1<`!«E/ÍFÆ.û,}e ôã[[ÌÂEsÆ÷{eÁ:†ŒíÇà±wpÅcp÷Ù‡s·óD>\Ôt@Rz]¼é)x›>CÎ’wžbÌø—q( ÐMNŸ4‹)tο$Ÿñ¯•á×!u—cx=C¹ûõɼvâøpÑÓôNU1º_DZ¿KÁ}pá ÙGÆ>Êã_­#tf¯vlh‘ uZ;ñx<ŠÂöXüs^4#µçï;~,Ϭ¬âÇÓÙ®pÈ#o±ý«á¼7c)·Ÿ9nÛûîr& =Á¹5_óägU{lÖÝÔMÑ’v¹_n<»;°õSΛ´ž;^úÝR­@cxœÊƒO}ÊžÂÈaÇðè|?óÞGÏd•~ž»¹ÿÕ«ØTÙHïT/F¤”—_)ã–k:%®aw÷Ÿážš±¾`|]ÍâÃW¥¾±8ˆ‰Ñ¼zrZ“yãþ?pæÐû¸÷¥… íOet߇zìÅψŸªm)ZÇœy)•‹žâ¡¦áçûÚ¶4›—·©ÇÒ­ §¢´j·û£m©ö|®™1•iG]Î1}^§ç˜iÌ>³o|µg-‘—\ÉiÎ ÷Þ÷¸ñäƒÀìç?Âcú-¼zËp) ãî=‡ço´ù‡˜ø9 ùû¼Ï ÛÒq( ›¿x…iuGñÉÕÇÅÛ•-ƒ†¥0§)†V—‡ƒò2q¹Zÿ1’’pÛ,8- ¡Æ¶[Á6^.8˜ÎÝ÷ü‡þOŽ'G«ägn`pŸÜ6êœÏ£Ÿ/%5=…9÷ÞÁ݇òâ=Ÿ2ôÏáÄû®rÍV ˜L·¦^ŒÉE#Y¶üt2Ò*ùÓ¥O9î:¦³”º˜÷€ÌƒçØL˷ƧnxãýO}Ta‹Ÿ'ûªy¤î‡}¼ū Fr²2ÈLO%-ÅMR’ ‡ÝFc]%›ËˆÍŸªªäååí]’2‹±qãF¢±N‡ƒh4ŠËå"‰ ‡q:Øl6ÊÊËIöx=Ãá0Ý»w§¶®¿ÏOUU={ödõªÕ†AVv~ŸŸ¼¼<E¡¼¼]×q{ÜD#Q¬Vk¢g¤aÄWúÙy.J¿ßÏADii)Á``0ˆÛíÆçó¡ZTòróðüD£1ºu늪ȲωÆl”o+'ààt:±Ùl¤¦¦&æÝã|dg)‰9& ƒ«jçdïÚH¡WwÓCYnŽJ; ’“™±çÞŠ©)»ãädÇçÊT•iؼܽ‹Mv–ô–B!„ø¥+]ú.³¶@§éO¡Àö%Óxøö·¹`ø dZ"mà<‘ÙÍl s7ƒ†o·»Íl`ƒ?Êﺧ1b±df̘ ÄÈÐ ¢Áxç ›Õ’Hzòùðà'Dc1Œæ>æŽÁ•Vg Y»ù£wbÉQS3Ȇe_Òëô ¸•øç±®#cæI1’r:5%Frùó+S™vìå¤:•î-žãçõGZ&u_~¥Œ¯ÌoqÞ¼tgâ û„§–R†T­õ1- ´t’š?ÄZ4<šŠSiyÞPccon¢b㤛?ç÷[âC_}÷ËøÒ¦ãé‘À·EurÂØ\^{j•q{ÜžÑÆ)ûÀnÛ°Ûºµ¸_mÛÔã£{ìèÁ¤y ùÉiÜûÁrªï;kR6hU8šªh-;ãT­ý‚)“yr§{»ûûþÓßÓ†oÓ÷¸ë[¾øéY¼s׎o?Y³…®I ‡7%X§ùNá¸CówIôýÊÛ–iñíi[à#½«»Å¼€?EÛJ.:™™SÆñlj/rþ¨Ã[ û5ÖsŸÙ<¨·&æ l¾/»[PÉ›•—ˆ×ê/ß÷qµ3ue—Áçð×Á»Ë„UòXO'OË6×§_çÖs@&ÌG/ü…áþ…¡?вnm.8e!5=þ‰žÃnæ|·Yé¶D»\>ë)ιèåD¼ÍMF:˜1'O¼Ÿî©Tg:i¿ 8`ÖóòUÇñÞÑ“ùö®CyãæÓ¸÷ÕÛøC£¦§†|¯\ù/úŽú té”IvF:i©^¼É.’ÝIØí6²3ÒÙ¶u Û*JY¾|9^¯·ÍN‰­îL ÀjµRQQArr2‘H„`(ˆÕj‹¯Ø ª*N‡ƒ`0ˆiƇ{SR0 ƒúºzÂá0©ii8N¬V+^¯—úúzjªkÈÍÍ% ¡( ÕÕÕ˜¦‰ßïÇ0 ’ÜIX5+Á`¯×‹ÏçÃç÷SSSƒªªèºNcc#ÁP§ÃAee%ªª’œœLii)6›H$"OqmˆEcDcÑV«°ï uù_E!‘ ÚMPv$U‘{,„Bq@2kxó†©ÜýÔkšaC”#ž¥ ÷Jîzöaæ~3ޱ‡g¡â‚à\6V„éÚu—v³¦gÕA‡ÆÃ[.,‹Å4¶NPY,¿`OПÃïÞeåÝçŒ}Àÿ³wæqQUïßY™aP7qßÒ´ÜJsÏ¥ÜKÓܲÔ2sksIÛµL+ÍÒJ-K-µÔÜ÷}ß W@@f˜õþþ@ÔoúKí¼}Í gνç>g¹÷ÎýÌsžRv`SdKÚW7z­ëƹ=lóŸïJäÜË+Xa7ƒÊÿ޳6æ©s{î!Nü:ž®cbñ޳¼úîª4€£ˆ0lþAÁ¿F-$Ý¢ü–Ï EÍÿÁ¶|{gÓ™¨k´ óÍ‘u(fTƒ33{ÍEö͉uß0lÒÏbÄÝjÜÿ?ÇT_îIÖ®] ¨P©2YÖïyt›ÊÔnU±g¹½NËêsN7lN0ýΧ?õâÛW‰¹åÅ6߀cn9ÉJßÀÄWæòôÁw(}“WE¾[W7×c,`KÁéEŽHŽ>Îßqi…®ˆu8ø•©HéPç6]Æ ïÚôä ¨ª-Õ‡,§½ËĦ­ÙÒà#T,:uz¥f]¨tÓg.k<+–^eÈÐà‚ˆª8^ì}_öƒ5å"ãV&1okkŠûûñÒ7Û ,݆‹Ö“`êÁÿŸ‰)v»£§£HH±P1¤4%‹aô÷Ãhô%À߃¯½^‡Z­¢xñbÞŸNBB‰‰‰ìË-÷óõÃÏÏR¥J¡R©°Ùl¨5jvZ­–¬¬,OFôŽéüt­3#ë¹§ÎóÐxåÜ~·çTi¤,G¶a±+ÐiŠAåÞG‰F¯$vÑ+ìw–'³…Gê ‹dö¢žøX¢y½ÇXæ-û…CúóRŸy=0Êc+€¯çXNŽ®û†þï.( xùæµG­/ nä-÷h¬g˜üî"^™½“¦a¾Xb¥ì>¸é¡:çxr§Ö§fÇø+óI^Ê-9¸’Ò‹Øã}~´˜Øë¶lS{ )–ã”q:.¨+I˜œ„4{”@ ¤ÕGÖx–-¸ÂÀMùØ]æ¨;÷{?¦j}µjyæx•þdU«EÕˆJ„±uŸ<‡vüB¾ŠžÅkô`SËÓ´Š0þc;\÷ÙÜrýã¹åGìÁ+ù§ÿ¹•xt½ç½Àïó¡{ÿÉLù¥-³<ú¯×yûÈa³àPøà£ÒZ·:¬\Èå䉔+çS`ð¯ìŸGï1+¼ÖÛåÓu kñ ,ú„ø”a/áîÇ´«‘`èî¾{ŽkC¥ÉuUTitøádË·˜Ÿdeþ˜vù®V‹•NwË阵“UúÉ|^âÎB þÛýu#Î=ç”9ùBŒ´yqÌBªÉþ>ÿhÌ­V+gc¯R¡|IºwhA@€¦L V«ƒ?ôzô:’$Q1¬1çO‘ššZ¨HY@ÍS(($…Ç Ò×× ­V‹R©Ä××­Vë‰M©R©<Él|||ÐétùêÉÙÆÇÇÇ#,*î2ZC@@¥J•Â%»Ðëõh4”J%µ½Þ-jæÄGÔëõøøøàãããÙV§Óy>׉`‚…_,T*4j ’$\@ ÿI’ؽ{÷]}@Î`ù¤ t{»U>Àþ8o5 yÏ;l¼…Gx¥ŒŽuÓú2pÒìܳ™ñõÕ¢uª×óZ^¬"Ï oDòÞiýütv=Á¦_¦ÐìåXuÌ»¿s_$NÀš|‚/FOçw^#Ü_ìp ‘g/pbóbö_Jaå”'ˆ¨1„È…g'ηϖåø4 @Ÿ–½ùmÓ~ïYÍ3õ:Òñ­Vè±³nZʰžv=ÁësÞ…k_0õçÃùêÜuè0çÏïcźÝ,[p…g Í+…ûAø@dl¶ç•“K'ÖŠrêøcóE®_Ë’³Xât`r¸ Q|ð,UuØó¹¬—Û 5q<ÁB1ÄÖí›9é‰ wêÈ>NG_ô`ú³QnÉ%fßïLÙyƒ±/>–í]Zty΃mjvÌěũ¢æG­«HÛ Œqlf¾º}Ë7bFŸ2¬œð,Û£ÜeY G·2‰W‡4Å'Ç>G:YÙ.t9uªUZR£ö³J÷UK庋÷kLó ‘vdœvGîN8º€!+ûðf÷&t:žNjú÷œÇU»û¸wnGÑÛÒòÙõïÎ- W/Y<öü“¹å°×7r*ò ë—oÏŸáùÍ-—ù£ŸŸÌ’e}y¼å |9¸+'<˦ói9£ŽÉáÊ#p!ß)ó K9}ä²^âÍ5¨Tm'“]TjØ€®m¦pð|Gw.fä¢ϲåZ=¾ **Êëëó^5¨òDO:¨™õû~œ€Ëżñ‹éûþ`ÂýÝdÆn¤BXÓ×^ÈwÙ:ýÞßÎG‹vyÄr€´ kˆ Ã¤Õ·Ì®}bã·ô·ñeľúÁ¯tUšû)Y¶ý¤Ç7ÿü‘]P|(ƒþy²iY–¹v#“öO5æ‘Ú• ¯B•° øêõè|}ðÕûbô7b4P, •"*c6›q8^+̇Íf“/^¼(_ºtI¾pá‚-;vL>uê”)»\.Ùn·Ë/^”###åÈÈHùÊ•+òéÓ§åsçÏËgÏž•£££å¬¬,9þr¼'Ÿ>}ZŽŽŽ–O:%Ÿ;wN¾xñ¢|õêUùêÕ«òéÓ§åÔÔT9!!A>xð |áÂùôßË111rdd¤|éÒ%yÿþýòéÓ§åóçϻ˳÷@ K–,)ðŠ/ðš7"TdÔõåÏ–îÍ-‹‹’Nìã.Ë~-Ù}V¾xl½<¼±¿ç³W§þ.GÇÅÉñññE–ÅÅ‘?î]:·>c?yýá r||¼ü÷ÎïòÛýI>—½ï¥Èírÿ ­ Èõ^ýVŽŒ=/Ï~)XF×FÞx2ºÐvØ'.F^ÿý[ùŽñÙÒ]Ùí|FäÁSWËñññòêoFz¶é9áw9:.F^úá³îÏ ÝåeË>•)õ–™§mŸ nâÙçÍYË䥳ßÌ×–›ëøù§érs?¥ È¡íß–ÿXó[nß©ëËß®Ü.ÿ6mˆ§Ža,–çyߨý0yýá rìÅÝr¯@ Ès7ì•?ϱC]_ž»äOÌÝpBÞøÍ+žýëh2 µ|Ÿ§ÏŠ*?¸ö[½¨ëË_-ß#/›™ÛO%*¯?|Áûˆ;]¤mùÇëkya!uÇ^<(2¨¬ ÈÏ ò¤ù›Ýö­þÚcsH‡ä]»ÿ;¨=ûOx¾”ÜmƦ›æwãþÎ\ùÃAÿΘæÚx^þ¢s)¹ÿ¬mùæöÞ»÷)ù†|,6NŽ>ügîØ”|C^½ü«;²cèäoå‰Ï—ò¼ø¾{Ìþ­¹õåoÉ“{7ÎcÏb9:.îž[G7~íÙç“%[ ·wsn]<¶ÆÝoº6òÊCÑr|ÜQùõrzÏ1§ÿø³üÚÓÅÝïumäÖì—Í|ÙSÞüòê¥_yŽÚn˜¼ø×Y7óϼ-§åø¸¨|ãZ¥GO+?ÿ•|!ûZu;¯sþt·O]_®£QÈ=Çç^‹Ý×ëoe@~iÆ&9êÔ.ùË÷GdϵQòª' Ôçéu}yËß±^{q·ÜÜO)ÿv(ú¶mÍÙïßî‡øøxùØÖŸ<Û·n “1ö“ÿÜsöŽÚâíµvíZ9ü±®òò¿6ËGO•Ÿ8#ï;|R^°d¼jÃnyÇþSòÑÓQòùØ$9:áºü÷ÅËòˆ#äÕ«WZŸ$ß”÷;Ý”NLtŒ;ë³,“a2¡×ëIOOG­VS£F dY&22—Ë…¿¿?‹«ÕŠR¥"ÀhD­QS®l9Ž=ŠÑh$11‘âÅ‹£Ñh°X,( ¬V«{ù¸ÕJhH‡‹ÅBbb"’$¡R©p8 &“ Žàr刋‹£bÅŠ”,YRü„-@ ü ,]ºô®ÖפI“»T“«Å†K©.d¹uQežšŠ %†ƒÇw(=z Õ› aÁŽÓ´Ö`v*ñÓinòŒ´iÏóùm,÷.°`·˜È´:ññ3z’`Ün›ÍV´~z$[Éf5Aú;î·œ:îjHy9ƒÚÍKïÌáÛ©c)SºN§ ‡ÃŹ‹—0 ðÇÏÏ€Ñh@£Ö’‘ibÖôiß¾=µk×.P_–øü G­Q»³ngǣ̉ý R»—o‡„„`4‘eÙEe¶Û¹R©¤î#u‘(_¾<{©±ÍfC©Rzêt8žeà’$Q>¤<Èàt:=ÉrTj.§ ¥R‰R©Ä`0 ×ë@ ‚ü(Ñz UTøÌ`‘›$G‹Bãƒ_!ûI*~yŸ¬$ ·Ð² î¨utÿ[›õ~ÙÏG#AšXÇ]Ãɶ¯Ú³§Îl¾ÎNT‘·ÿ%•†S•=¸’Qª”øh ­»EùݘÞló6^…áˆïZäxÏÎ…»?¦÷ ÏÜÒê ·=Ou d›¿êȱ6?2(Ô'_[µÙåäÿ¹Ÿ ï}–Ó×JCUoѵ²#Ú÷fÞÊìkz‰ d?ä»îÍpËîp  H¸]E‘$dYB’$$@©Vy´Aoz™õõuO}Z“ïo^êÖ­{KCsöË›V<'f¤§îìX“9Ép”ÞRAçÉ÷âçç'¾{ @ ‚{ŠË–ÆÑÝ›˜¹t-û5'¬l1Ñ1w@>«hXôƒqê•S¬þáW0¥±wßZ>^›by2 ߪ\ æ–˜[÷’’Gž[IË B®—²ø GØ».…Ø”l~¹!í þ—¼}xcËß^³ƒÿwúáŸawÚ—ìt “ÙÑ/e\ ¹@’qÉ2²ËÈH’äÑoF%Î@ @p§ü5g ·ž)ðùãm»óD³'¨Qêo£Ý”Œ3¨3+VtÃn·˜NhÙbçÒÙ{‚’b·öܹžd¢Áë?²bŒ„9ý©&Å´ÚÛ.ˆ¹%æÖý7>Ń ÿAGvZˆÍ û¼%<‡ƒ¬¬ëXårw”æn!©tˆ~ø§$_NÆf·c·;q:8.,–,4 >>>h²¬¨ÕZ”J;v›³Èº„H)@ L&>²Ã†Íqo#ƒ¨ 牻’HÖ-Žaµ˜HMM½åvw×>é©©˜2îã‘ÖAšùÿ÷Þk6¥zæ´@ð_D¡P`4øp1&—ËÝéÂérà”]Øvlv«‹5 ‹ÍJbR":•ªð蓊›šË—/##sãÆ Nœ8ÁáÇùáû8sæ *õ¿Â2++‹ ™^ýßÀÏÏråÊaô÷ÿïNHIAñâÅq:Øl¶¾=þþþ¸œNÊ”)óPŒ‘R¡$44ôÎB:Ü'h5Z<Ú€bÅü,š …‚%J R©Ðjîï`܆ P·n]¯7‡a<Š+†^¯¿û_ÂeÙã¡©ÓëîÉøÔ«W’%KÞמ” IR©Äb±––öŸ¸'*UJJ”(AÍš5 C­¾?¹ª”*‚‚‚¨W¿F£ñî_«µZp¹\÷¤þûõþT¥J}ôQÅ ðÍ„¡¼ÐÿeÞœ4ƒ”ÆCøj݃ïîr³ž¬ËšsèŠ9ƒƒëæ\>ŒjÕªÑçùZD„U ÷¨V·:ÎFñó{¯V•÷þŠz š–•xœI=»ìyMüqvYÆ–z–{Ö¢zÍ:Ô¬YЈô­Y•-1ùW4˜Oóå˜z„GÔ¤õÀ—¨S³Ë—ç—M§oK¬¼¹•¡5+ñÊ”ÏÞ ¡µ?äÔåÌÛ.8¹üý|m¨ÑâkLÙ‡¾½•ªE0üÓ©ÙBäÞÕô­Áºsé÷`^]cÖ 3~ÖT5¬ÏS¯þEV!ýå4Åðã¤^„×~Ϧ ¦R…òüºãâ=Ÿé±ûé[3‚ö£ÆP­j8/ÏÙZ¨}.k£ë„僜צóE÷NVOxЉk¢ÿNeG?OjHåÚ/òÆ€z„Öþ‹7ì^mÛüeïBÛ4eÙq<ØŠ$Rš;r*2Š«‰ÉDÇ\ÆnubͲbͲ‘e¶’™‘IÚTâb¢ ÀÇǧðï­yߨÕj,X@Û¶mYµjƒ¦k·n9rƒÁ€ìúw^¸٫ôt|U.Kë¾Ç¥vžÑ– Ý«ÃX·x-%}þý ]ÖöŸ´ÑèÑ[ßw|JÕaò’Eԙܜó.3wÃiÚW7‚œÆ‚·ŸcÖùAº8ŠÒZ‰Äó»Ýi3b¯Ae÷s^ÒÉ?¨×þUBŸ~½‘/RÞ ÙÆß;Ò¦w[šÃoïuÀàeÌeG<ÓžDíY;údyøüVNiÁ÷ë°ý›¨œ—‹,WK.ó9fO>̤Ogà+Ù°ZM”©ÙrZ kòj5ëË»‹v1ôÉ ¸ÞÀĦ­é#©ùã½øxµ+‰Å³f³gû¯lËpòÂ?V'Ç7l$¨i[ÊèÝÇ<·~ŸÄŒ'ú×^\îý[‚ 97œìü±/3Î çܹ^è%‰!=fÓ¸÷(ê_AeÅ=™CNÓi†µéI¹‰òsﺸÌQ oØ’Iþ+ø´wÝÛ_Øö KÏñåìfè5 "zÓ›|øW3*–Òz^}Òïuê¾;“І­¨SZÍÙó°HêY} T݃k„laÕ‡yku?ŽžNI•uÓZðd+#G÷ §¤:ÿ1ÉÇyqê&ϘE9?-v™'yyäLÂË7Á¯74¨U‰?·Ÿà·U[)W¦$ÅŒŒ~hmjÔ·÷´ÝaG¡¸z%ŽÐàÒ^5¾|W" ‰Ö­[óå—_z„A—ÓÉã?ΡC‡Z@ @ð„§–ˆ–éS]Gìú¯ùjåß÷ z½“¿¿À©…³9™x„T°&Ÿàµö½ˆË*Bä‘ml˜Ù‹W§ðÆÜmŒè\ßlñD¡ âé!3ø¢s)2 6øaP)°ýÛÏ^rË'vfѹ;i é¨V¿“û¿Ùæ»l)œØ“F‰|5îÏJE4åóŸÞdïwœn—ù“žŒýøõ«An@ÒPý‰Á¬ý²§¾…ïÖy÷ú³¥&qÆä@“Ç–Jµ’y#ûm”œ^÷«T­hÙª%½z÷fÀ€—i× €¨½¿ƒº>Mk‡¸ÇMÆÀiÃ9õý+ˆõ¾„YRñüëïññç_Ü•a‰Ù;Ÿ×bWæÎ­[7R×ݲ º0°s]”…ÌÁäËYøÓxD€â%Ëý0ɦ{·"îøê9l³Ö¥ûÚž~2¹#‹&}ÉÙ7­‘-ÄÞ¨ÊÑcÒµs{ÚµkG»v­hòhc*wlGˆ¡ à¨ÐÐj@Ž,œB§×2±WSæm21¾Ï£ø+ïM›2ãv1ln<“§?ã$% Í_œ ‰Ÿ°ê`BíãÏ_bñ޳ êþ íÚµ£Sûv´lôèÚШFIq<Ð( šï\€ ;—²*ÕÎóc{¢-(DU{ê9šû)ùbü:®{Y&¬ â‘5“ú4â#ñ¤Äîbì˜?è×ÿQô’tËr—õ³'®†ÄOx¢~-BƒƒY°é¦ØèªÀ\‘ «ÀÉóWoÙ· %fïOté:ˆ/Ï"Ù%›ý¾Kω7Ë\9ø=M{Lˇ—绵»ø¸W]F.J võzvíÊÈ™; _/i ¯Lìê¼óí6ÒL ¬øî}›|F­²îPDéÑ æûíqžÝ’£w1´fEºtéÂ#]Þ`Æc™z»K”e gvî¦DƒŽ” È×°:íÁ²3q7%“”t´z®{>ODÙ‘ÀÒ©kèÛ£^ážÓ’Ž2¡•ˆ¨”»Z °J‚ËÏÞÞÉÞ_ß&¸ÚHþN¶{®‡×¹¯ƒw¥÷èéL3„uçn/êùo|´ž-ßtAJ9NËçG3uåqz× dÿ‚¾t뽌Óxî_¿ú&Û2œl:•Áfþì¹nãâ¶éüdz‘ó:’Û™&cbqqgÚîÓóXŸéÔù¦Õ'¼Íøî5Ðûi‰9ãNdzõFÖíœTœn³ßgZ§Qœ]òM—¼Çóþâ¹¶µ)_ÖÝWÎlG>cñÂc9+tFJi•`¾@ªŠ²ª^Róú¢9í0ˆW;?ÀÛów1¼U…Û*WhÊ0eÆ_Ža몯øô‡=¼Û¿%ªåéÓ° ;`ÙÀÙUйãï*•nûãS³îʯðx/^ŒøŠWWH·@X£¾Ly!’öïÆa“!¤N/~›vY½ùsª”Ö£xr3%FµgÖõQ̙߃¤ñAIÓ>bÌáN|öA_–~M>cïb÷Òo€ŒäX.\s âéÑ©Ûl_¯<ȳõʽ•êÍú2dæ \Öx¾?… ®ÂcÏ^¿äbàC8¼;•âmJ7"»”íáxü|ÏÔ.z¹³)î(óMO²½j‰BË]ÖxÞîÒ ó+?²fAe¢Š=ke_ž_š=gþ Dcãò±M`J !ýCª—Ps`ñ º~PžíÇî/³gÁëô|w ó†L#3n7o½ñ#šÐÂc,gHáônT˜äìvèÊ2Ùn)HËŽV}Kß9õî›ÁÿŠB¡@¥RQ§FeÊ”*Á£‘\¾šð¨K IDATLzzN»›¯—Ÿ†²AÅ ¯X²eËb0P©T…æ5Q€{™wNÖn­¥B‰ÓéÄh4b4q:ù²{ @ ‚ÿ.͙Ĥïö0ûíÁü°îoœ@@ÅLÒ€Gà¯ãWÿñ±\ÖKÌ›©áõö•@*N¿é#Áô;+ò$ýÈJ`Ö{1Ë2¡4`⤟‰¹a%Ëϲïß Qõ»”pSÒP¥i«|íTe¯|WI Òøà'A±æ„—@§Ñ¢ÕP̨F_Ü£N‡^ç=L€BJ›6xÞ§ÙÀ‘èÜD>eí˾{ÿl3X=íMB:~I‡GJàW6Œ^,2HJ Æ’e(Y²d¡¯òÕƒP«@§”È2îýj¹˜‘Û§QùÙž….õPhƒùj÷–|’ø]ß³,ÒE×I;9règ·W®¤£ë{9pø$-Ã|±&ï§ëØ­L™û*áþ @IÏä9WU”©^Ök»Ê”ôG ݉(Wð|÷1HÜ*º§)î(óoÔ¤‰áU xÐ ´Z-CËÓ½SK†õïÊàçÚÒ³cS:¶jD»–ÍhüøcDDDˆ’¢ðsZåp8°;(î@x”eù¾Î(*@ î-^™L‡W /«ÚrKZ¹kÇŠ?ò«’ÖSná·” éð¾xçOúµEIµ„Í|tmˆ(•í³%ihôüDéÑz-s™£ˆÊ´S·RqÀÃáÏÒ¥Ë%T.ì·§‡FàNÉ£O¿Sw`w8p©s’ÜžT '7ðçî(´Z-²5’õ»ñD±Û0r(¨ó/´v{˜{„4+ÔàçÈóDî]Á -DZ-à Æ~QËi—AåJhTP¶2XæðLãê´~u:Ÿ¾Ñ=ºÈvçx†eæut‘4”úß„CÙ:¼½äOoX@‡A“9·øm”,Dzq-pbÀâe垤ñ£ªAÅq8dûW-æèZ d¥[iܽ?uÊZùex Ö>ñ)'&<ʲq˜¼ømž5iX?§'Ò‹.¿éy¸Bƒ¾,Ÿ¶Ÿ®SvpÕÜ…°ŠO³iÁ{´zñ=šÖú8ß¶FU¡ãÞ);žåÝ%ƒÀ0?ÔEláÍ–ó›§ÓfL*kÄuð{:Ás-û±öàïÔ*¡ICpEwÌM—9‰;nðôGÕóxû91;e4¸cmö7ùÂÁ5UÖás“À˜sÔ )Ú‹2Çãð…¯káq¨¤X û‡‚ÊOã?£{i{`®Ë²B@ÙìÓ)+5€ÐÒ¹ž’NgnVn}ÙÇxgÊcEÚ¹ê0ýÄùËrÓ2î¬ô[ÿ¹}•»ö*¼ nJFƒJ¥B­V£P(Pª”¨UjT**µ •R•}Î9½jŠªÐÐPl6ÛyGʲì>¨¤£!@ îòuVŒšÉĹKx´„' =öåË cÂ_°áh_ú4 B,ˆN´–?»xQe9Fê×k@ã†ù³¶;̦;rãó+•Þ%"kF"[¢|€gZ Õ+t@âQέÞNì„g¨ìëg¯|â Ý *T’;ãöŒ~­X(dãÉnlù§F&YWP­žÚX’1]ú³ñëQlüå<»¶?Wd»¹Ké®Enä¢Oc¯è ’†:m_âĶ Ôn>€#‹’2ªþ%Üq:c¢¯á¤j¤/¶”x–¤ØéЈÒzçcþæX´_ ®Ç¤R«S_¬)·2‰y[[SÜß—¾ÙN`é6ŒX´žS4¶¢Ë …Œ‰N+º$úlçĪ-Õ‡,§½ËĦ­ÙÒà#TÔ“´¯à¸ß+|Š./l"g°ëûù<1qµKƒNcØf  yï÷Øuú*µž,_èy—áå¼ÌàØ¾#˜d…å§q8T¬U›Ò¡:ÎmºŒÈ9óÒ“ÝBa`€¶Èväxn©Yú¶ú¥R³.Tº•˜¢Ì9 wã´¥ÆpðD,R¡‰«8¥´…î뮸îã•=Ëç í¶láµ×Wõ¼f„T$Ir‹”5µ[°ÌyI’„B¡Àé,úæ¢Òëõ^V @ Á¿IÚ…L³½Æév1æy¨0LfÂC˜öÙ::/é‹+Ûê×U{ybDs·ç•|¹¯~Aƒ—÷ZöÔ/¢WJL›öm~æIÚ½c:?]ëÌÈzîã©óˆWÎíw{f–6@Jþò ú²´Qß›”‰æeð—¿óù/½˜ýJ£ÂŽ5å,Ç®iPÙýÞW“G$Që!ÛÛ0fׯL߯ªcƒ(©–¸n3çÕH åØê_ jû?Gžfë‚è;þŽ_êPd»ÇwT´°ZlhušÛ?5©¼üözöÿÚÅ#Ê ­L¯@ KœYà‚ò žæ•2Ÿ0çë9ׯ ÕŠåw†9°z6ƒ_l†^ÒÑöµOi{ó<9ïNö¢Îމd¤Í‹“`ÞRM6J™‹.Çß§€ívk•Ûv S*?œlùvó“¬ÌÓ½$>îyPáûè²Y°âƒN“;¿•Ùã©Üc¯ôŒ¯±¯äýn¦0[dG—Ï[(ß1׎ðÆíèø1—Ó€òÙãkA¥Ó!eëû7%mH}Œ’„¤Pæ±9‰Ïôu{òzaö†ÓÔhñ ,ú„ø”a/án_ÚÕH÷réÒ¹ñ,6*Mþy¹}!m ÷8̱óöx;1[œèud‡û:±çD<­"ªæŸ€åÚqzõî½*]6n|ˉ¨$Z†UÀ–z•%)6>­Q:OŸÛp©4ùlô¯µJ‹‹»à¡%'¤¤B¡@¡PÜQØHá )@ îOä –Oš@··[å(ŒáóVÓ’÷¼ÃÖÈøWx„WÊèX7­/'ýÀÎ=›_¿Q-úP§z=¯eáÅ*òÌðF$ïý˜ÖÏOg÷Ñlúe Í^ŽePÇÜLÜ;÷Eâ¬É'øbô÷t~ç5ÂýÑ#òìNl^œ' wÞ'6 ­‡þ@ÿ -}Ѓ±s6lvd Î\Ax–\•5!è@dl¶3£“K'ÖºëQ‚Õî%7n;ÀÅÈ-¼?v8Ò9}è —S³—­:ÒÉîQi;É’í1 ùñäó©£Qàçv[íÞuè0çÏïã͉Ý3ðˆ0fmŠñ2^Nïú3»Íîv¨}K’²kæïœõ8ùÂ9–¤Øh8è)Jj%$U†ý:,hýÔ\¼aÍ®ÏÆ±UŸÑ{Êvê½ú=½yýèWº*Íý”,Û~ÒãzþÈ.(>”ŠAÚ[–Ÿß<àˆ¬?ÀÕÈ¿èZ´‹VÆÛšÊׯº“Ò¨Uù½]ÖKŒmPƒˆƒ8q5Ë Çô;;'&r-_™¦ßY³óvYv—_ßÈ©È3¬_¾3`3ÝÚíURQ¯c M[O¼Ù=æ„K,I±ÑâQ·@™pôgÂ#"è0i5Yº`žéW–ä=“ùé\Œ½ÀŸ³?aUª móO'**Êë«Cu#UžèI§5³~ßpY£˜7~1}ßœ2c7R!,Œék/ävsNr™çëð8L»°Æc§Y¾E`KÙÆº©OP9"Œï·Ça(W‹Nj¾{½ 6çÒù}|øì«¹×•ˆŽE¶)*ò;ª…6dÞˆP>»œ«Vp²mÁ((õ”ζ?ž «Ñìå…˜òعãWBÚ¾(–z ^"¥@ @ ¸/Y7­-v\gÙØ7Y¼'.Ÿð°eî§|²+€amj³ç²?c×þÁðÆþlýaÏ÷|¿1‹˜Ò­ ’ªŒ×2PÒlà|Ü»4Éû¾ W§§éÿaë·}B9m®0oܳ„^÷iì/ýÀgýëàWº&ýƒ´|òRÆ4P½|á«Ô”†*LÙ·—Ùú°ôƒÔ­\àà`ÊWˆ Ç§Q¬Û–ÎÕ,úp«Ríùª³ÿÜÏž•³üå%0ýΔ9Ûy´=Ô|9²;ý¾ˆbðãÁ²—†ocÿŠ/h=t!X6ðDÃw9qÕuZ¥Öóyÿf¼õñ' ¯ß–*ãШ¢¡Èv+´¡ôÛS?Œ¦EçÅT® ؼŽUVâqÆu„‘‹Ü¢*Ü…ºTÔ¸N §rùòt á‘Öè>æ[æÜãeV¼RkÎ^ϸ–‹x²V8M&¸|GìdÚ¢Í,{³M‘Ëc•†*ÌX5ùóç ­ø ºDÐi"ü¹z$%ÕÒ-˵z#X60¨ÓãÓmúYÖ:KÃrnE[j ËœJpùªŒßΪ'è÷d…[ObÙÆ®_§Ñ¸Ç$¾ýè~XyûÍâše—¯[ oÒNjÆôzЦ½OòãÜI`èŽ6-™L'”®Öì‡éݦ5I%õüú拌[™Dìêô}ù N'zË4®¤ÝØßx¿Ób¯\žÁƒ»R¥Q/&ÍßLëÊn¡UÎV¶O­8Î ›š6¯þ˜ÅÙøõk<Ù¸9'\¡ùjT©4h4Þ_J@¡¯Ìç~GñuoB+>C§jÍ‘‡~Ï„n5<õ8³Ó»›2sc’šâ0?ÉJóÚå ´Äfwojá\âM·Î¾cǽÍá¨dú0¦üöu4 Þíß&OGø«}óõSQmÒ¨T ih7v_=·ŒGÃË3 KUÞÚÿ4›Ö¿äù1Ev:±8eb¥“ñRv$°jæz>ß@,õ¼ ɲ,‹n@ wÂÒ¥Kïj}Mš4¹K59±Zl¸”jtÕ”Azj*.” ñ,=z Õ› aÁŽÓ´Ö`v*ñ»i¹³ì°i/ø¹7ì–TRn˜‘”J´ú Ú;k¢lÜúìã¶T¶°~1›Ì¸T:ünÊ]X»=ûdXÑúé=ŸßérodY üt*¬f³ IãWd›Í¦TÌ6 ÂXÜXDÒoí4aGƒŸA_Èr`ï囋դÒK›)‰¨Ä,Ê”-Q¯¹»'“œÁ‚aÍ»‹–a¾ Û0e8Ðô(qâD™ÏN«Å„Ké—oyø`µ˜°Xøø³,å’•¸›JOåô¡áÙ‚›{ÞHZ?|—Sÿ 4Öðq÷ªw|^šLf”ªÂ3ß¼|[vذØèuºBkËJÜO¥v»8qdÅoc~œ\ö"§¿Í/ªzÎÙ ‹½Á€-vû3oËiÚU6Þa_ZpB¡v:lì7-ã·Z,(||îpN ÷/—.]B£Ñ ÕjÑéthµZ´Z-µÚ4G©Tz–|;N‡ƒôôôõ©D— @ ‚‡%Z/ÂFÑeàP0#In’- ~…ì'©tøÝÁ“•Z@i]ÀÿÞDIƒ>O3n-PºÛ®7n»Ýž}üò{†Þ‘@™m«Ÿ.g_ZÝ­wÑÐÿƒñ×þ§r•F‡ÁKó4† ªîÅ|u²í«öì©3›¯+ê=}fð¢, ´juÿÌoã ;âù }?æ/>˜'¼Bíîeå¾Õÿ4.ƒ¡›t7SO¢‚v&ðAûÞÌ]tð¶Ê„£?ÓþƒÚÚW%ß9›cŽÍêÑ V©þ‡¾ô>¡U]Á¥¨íXî-@ …â²¥qt÷ff.]KÔ•¢Sw:}Vñí+îïº@ÞØò7­*/ô\8²yKRl¬]½¸œ¸¡ÿ ¼±åoÚW/~[[«Ôž³GQZ[°ÓcXõó‡ìÜw’L‡Xh*ü›OJ@ @ (»)gPgV¬è†Ýn!!1вÅn3£°@p;()p_X"©tx3ÅnJ&C]‹+V Û-\KN§|±’÷…ácôRâ$%!ŽÐ¶_³¢£„Íbáz†ßµ˜–Á ²,#Ë2.—Ëó7çÿ9Q&eYÆóÏKäI!R @ A!hÃy²e¸è8ÊsAIXÝf„‰áþ19Âc^RFÆ%»PÈ $IÂ%»ÈÎc%DJ@ @ @pÉë)ér{Q:N”J¥û½äòlêr¹p9Ý^–…!DJ@ @ @pǸ\nIgöÓéDR¸³zçxNº\.\²Ë«'¥Hœ#@ 6 NÑ wŒ”Dn˜È —ã®õ€$¹öºli$¥˜ïhŸ,S W“±Ød\¶ RMV1±Á§Ó™‹2[œt88NN‡Óó>G¸tØØöBë"¥@ @ x0Ó˜õd]ÖœËx ÌŽÙûÁÁÁÞ_5Þ!Öüÿ+ &œü‹ª†RµN}vÆdwðGkÔmÑ™D¿ÞM{eG?NêEHX Þ_uÛûÙ<‹JõÆ2îÉúD„•'$¬*ßïº"ÎU@ð߸-Ër>2g9·Óéô•»»ÝŽÍfÃn·c·ÛqØ…Ö'DJ@ @ð@s€iq™ÌZ´»|ÿxû݈ÞDZXïBY…F}9½í;Úý‰³11DEEÅßÇ6Ó_IJ¦ãÿÕæ2µ:0mñ44ÙAÀJ„5áíS¨TLû@̇»i¯¤ ¢÷kïÒÜOIIŸÛ‹ŠfMÞO«?fÕÞy,<¾c{P·JÐmíï²&°÷Ð%qb ‚–œ¥Ü9‚¤Ýnw “Ùÿ·ÛíØnÒf·‘eÍÂ’ež”@ àAÆÉßßàÔÂÙœLtÜVY“OðZû^Äeýh%)Ý+T,¯J…F£A£Ñà_¢ C|—>ÿÿ¶/žï½¾T†H¥êbFÜm{5Å)¥Ub¹Mý;%úºSÊ(¡Ð–¡ûˆQt PcwÜÆÜ”3X>±3‹ÎYÄ©-X”J¥[€´Ù<ž”Žœ¥ÞN'6» ›ÕFVV‹³ÙÂë7P« ¿n ‘R @ Ü÷8n¦ÿ/]Y¹üs°fÞÚã7’mZõµguïÑÓ9~9óÖe@ÌÁt !88˜a“~"憗%…C;V1eH7æü¹–/×&88˜&/MçL²kòº6ìȶ 'CŸŠ`À§‘u‡žgWÎIm ÊÔd$žå¯ß¿£ñì:°™ÑuÂfæ²c¹q8‹l£…ÃëæzÊš¼4CQ×óõÏþeŸ\ñtíB÷æ=E.[gîdÚ˜!l:Ÿ†Ë’ľͫ˜òòK¬>p‚¥Ÿ>ç>Þ˜ŸH²æ¶1ùÂ.†Ö¬H—g+ñH×wYºv;»wì!.ÕŽËÏ "öØÃž={صi9ïùd²3‹S¾fÓÞù<7`3]\»ϕbÚ˜Iœ»áºew|׎gFG³ýd4q1G¢ú‰gŸ¨ÍºsiX<ˆn“­ì>±‚—ͧo÷R»ì¦dömYÄÌÅkpÈ€®_XËw­å•®Oc®ý g¾ÎŽÅoóÝú‹î7æÅ6½©÷áOe åÙ6Å™¼þ8qýÝõ•.á›[îãO9;„¢Ýy“­TåÝdW~H‡Õí¡™|Í~h´îºµyôH¿À@ï+ið3V€Ô½$˜aô—(Y&Tþ¨%@ò#¢’È×øö¹á̘ØC¶ày³½9ï½U^\–$¶¯Iæé*¡Î®/oûd[F‘óÂ&GnYH£AÄîN`ÝÜ·òþ"†xtU÷±2³›tÉ-¸ûk(³bE$uY´·ð΂ …B$IT «ˆÞ×—¨‹1™L˜ÒMdee¡Óé J•*T®R§Óéµ>HY¹re|||D @ þF´Zí¿çÌ _gŨ™Lœ»„GKhpÒc?ðìÝw|uþÇñ×”í»)¤‘PBQš"HÇŠ"XÏÓ³sö†zÅvžwêé5Ïz‡õ΂gûÊ©§è‰‚ ŠØ•žlŸ™ïïÝ, $€Šåó|<ÉÎî”ïÌî̼÷[ÊŠ§pãwñêÒÉœ9¢?D_euUœòòö÷5ÛšF:Ï6t8cF´•Ù²,"Í­ë±ù¦Ê0:¨%ÞRż÷–P–“ݸ†=i7ÝI¶ËŸ6•./‘æf<¡éüfpÛÑzÏ÷ùªMŒ/o "Ýäf»À㤷s«A]\ÃèYÚæ.èl ™¬^£¹éØ|®;óŠŸý=Mÿ¹‘îÇü…ýÊv|´í~ŸÑÉœõ£LûÅ@øõÓüúîÿÝ&˜ûäÅ»¸çëÝó#ºíÀ=ëŽì«ty|°º{óŸ;|\숺¯þÃ~‡žËEw¿Èúu¿ç…ëÆñF'e®©ß&qåö¡¤e+0$¨BìzÇA)…i˜t+)Áï÷Dq¹\x<\..— ·ÛÝé`9íÏsiùùùR !„B!Úq»Ü„B!<Ïÿdù_Ígjâ N8†¡Ã‡3|øp<`84·4 IDAT?þéÍL½ãeš•¶S >=gáæAZTÓ/»¯šN[qðS§þ“MÉÍ Òê·îäOÿ·&ó·ËÌÔï`ËR5»†¶šÞsôdf?ò0ùË_¸ûág¹hbŸö7`.³ýßnFt9'tk»åwd[ÛX‘Hýý麚v¯I4Ût?è@òÜ©ëõ«¶º4¶Hè6o«ÑázøÒy™f2tô`u2®–M”ý4ó<5SÓÀJDIXoWnÏA\Rìcò1=ØT™àÊ×?á²#6—Y¬j¿úù“义˼ë?œÏúˆêpßl_ÙD¢ ÀÀoh,~üýL•šžz,àN½~GŽ‹ö B¦Žf ¢¼|ç¯è~ì½üú¤ý›úu±­^Ѻ¬’}CôUü¿6B©(3u ‹7ÆåƒH±KÒ4 ÒŸù¦i’Ÿ—O^^FúÄ’š¾ãó“s„B!„»&ÕÂs7ÝÀI¿>¢]Í:€ìÞ£¸n\5 ®çåõdõ<€KŠ}¼â®«áøë¯ w–޲RÁáò_ñÑë3YTîxSÒ•ûÞ^ò1õñÔȧ‘H3•«?äîs‚÷œ‰¸´Ô šÕD,ìµÎßez¶¹ƒúáî3‹ù× ?â¿«Rë«ü€kÿUÍå#¿{êµOÿö8ÿï š›+yé±›!ù>?õU•¹9\»1ÕŒ;Q»š9 ÉLÖZ¶Ö¬ Wü‡~ó“ö/#ÊÂmÕ±|ù*šÒ©_˯†dâ¯;õü³çÏ‘ŸÐ» ›ì,?-V²²"=ÐŽjdÖï.aYÂáž[Ï ‹¦¡¬jž¿ýy¢Š­Öw{û •àõ{¥_ßrþþ®Î)W U·rÕís©jnæ³·^dVm‚7þû*+jºìÐqAó3DÒû*Q»ž9 IV­k¢µ9wÅë/òÖ‡_òÞ+Ó¸á­:–¼2—w>ZEk]Ì·—¼Ï—_¾Ë¼•¹œSèaƵÇòÛ^âãÞão—ŽbF—+ÙM* !v]Z›_t]'  ÛL×2å(¶ýeœ¦”ôÂ+„B!„øffÏž½Sç7vìØ­{ùö±\pïZp ãŽå´1e© *Á¼é7ðÓ[fdž;ëXÃS~Âß4pùíÏpÕé#qiñšO;¦¬jž¼þh~ýÔÆÔ̲Ê+ónd`‘—¦ÕspÐEíÖkâ5OpïÏůiØÍ+¹é ü£:ÎÐËdƯŽnW“`ÍÂG÷“›¶¹ý·=÷‡»pÁƲ„C÷cþÄS×à¶c~œ†$ù#/eÆ´«èc¬ìt;œx%Oýé®{d§Ÿ{.OÿýïÜô×¹ðˆT ÄHÕûÜ0á'̪MÕ,xT/¿5Š›ÿ|:ÃÊ"ÜqöÏRù¸†qïS·°æî3¸óFðM`ú?.¡þí;¹ö¾·¸ó¹÷8©ÿ&Î~\»Á(ø%K_I¡SÁ5#cé„{™{û1žS±à.Æœò—­?þ÷/ðÇCª|pªì † §§ï½÷dÿ”þ1†»'_–Yßûf=Àø‚¥ÛÜW¨/O=Œ î]KÞØ;Xøô^¹ã7\qïœÔ2†ºÙôA‚‹®¾•ãN8ž!e±N‹Š…O0æ'¿ Ç¤+¹óŠÑ¼ù׋¹on¸†ñàsÓÙ§ù_zÆïRûé¶Gé¾þQ®½ïmNÿý ÜzÎ=þ NùÍ :™WçßFid S&œ‘)ωW?Â]?Ÿ°Õñ$„»ŠuëÖQPP@qI1¦ifÉd2IccãVͽu]Ƕm¢Ñ(MMM[ÍOBJ!„B!Ä7öC„”ߎM<šÀ1\øÜæ7˜M 8„rB™†Î­!åco}Êa¥n"¶AÐ×¾NeE '·~üû³íí7ÔÒ·ð†òÈöo]‘æº/ˆ×t°1:iÔ½}Ÿ¿þ~ñÖ>̾~“XñÞ•”ú¥ µBì 5Ð~úé§xæ™g°m;óœíõIiJq !„B!ÄÖ’Í5Ø…Çóüó'‘LF©¬j¢GIî·®}¸GÑ|wí|Fžö%k«ê/ÝÊ(+Éßáò1B™öáÇ\µü+ª›#¸C¹t/+§0Çó½í+o(OöBì$º®£éíë?.Z´ˆ+V°zõj–,YÂA”:ulg¨o )…B!„¢ž¼Þ2¾·D§ »ïKa÷o?Í ÒgðúȾBˆÝŽR ÚÔ¤ŒÅb<ûì³íjW>ûì³xàx<ÛÿJš{ !„B!„B!¾¹6}LΛ7šššv“›››y饗ؑq»¥&¥B!„B!„âÛIç”G}4Çs ¶mS__ÛíÆ4M\.×6Ìi%5)…B!„» +Å–b‚Hs ÍßêýàDkY·¡I Q±K‘R!„B±{Püí!Ìý¢e·Zí5 Ÿ ´´4ó3ö¿±1®dŠo÷6°ªyò¦ôÛïl~yîPzì÷GVÖ'·ùšÈ×o¶;»÷ÝŸE5I)L!Ä.Eš{ !„Bˆ½V,£¾¾žX,(º¶ã¯ß‘˜)Õ§¼hºFVv699ÙèšÔø¦šÖ,fêº0ƒf¼ÃÄßMÀ¥i»ÄzÕ¯~—µÆ`†tt8½çèÉ|úf½ˆîÇÞËë÷ŸˆwYw±›QQæüñx®{ñ§,ýâ2 Ì$/O=ŒCŽÈfé»—Qàêà¸R ^{øN¾êVÆéÄqœP?ŽÜEÊS±K‘R!„B쵪ªk¨¬Ú„Ûã§®®]7ÈËËÇQŠÖ+¥…rÀAá8©h²uZjdËÔïéI8ŽB¥Ÿ†ijhÄa]óšØ¯¿›@ ;à±YüÌïøäñi||éá íêúŸ¯U¼æ#®˜t*§þës†lãyš‘úâ‘$ ßZxÝÛL™¾ž›gœ$Ýzöípï©ÌyïÇœ7¦d«×ĪßcÊô·yhî²o7n9þ„»& )…B!Ä^Ë0t²³»›‡árahù…Eé`”“ U:¤T(@¥ÊÖÇÚ†šNúwJiD"͸Ü^Á,,'JS8‰Ç§0õÝ7,8å”S¾õkgÏžý_cÕ¿Ï9Oý˜=WÊñ?¾Š‡ÿ½ŒiçØþI*Á’âG—Þ ÀÁ§^ɯ®¼˜ý»¶= XóÞó\vêÏY–p8þü?sí/N£»·‰Þ[ÀÜ'ÿAá1›û+îx©Ž“®ä‘?_F/>åÇ#~IJ„Û‡÷å¹+äþkþN!dó†eL»ù÷¼oå°à•—ùÙÝ/òË“ö'^ýÿÿ_þ9«‚ ®9Œç/¼Yµ ®¹çE.?iFzû—½òÇ\ÚÆãÏ»ž“'Á´ƒtáCn¸ë¿˜C¹ÿþ)D=Éϧ¾ Æî{ìJJýZ§ËviÚ6ç}ÀèÁ„Œ&^þ'λe¸†ñ›;®çÜÀ«i8ñõüiÜa¬9ë!îÿÙ¡Ö€Ö|ʽןÎ}së(q6ùÝå¾_!/æÍyÏóòº~\4^qÖ…7ƒoOϽ‹ƒúfwX†k>Á/§¾¹ÍmݸüU®>yÁ£ ¨Z]ä‹§rÑÄ>ϯÃc£žÅ ñêì1ôü+ˆ¼ñ'®¼ïm>íÏÜýdz(ôh(«’¿u$¯p/Ï^{X¦ßå!N¸àV&NA${hŸ3ø¢©Lì—½Ýã£bÙ"z–m®éÎ)åÔ<7O>ÿgŒ.nü©ó¸€‹ŽÀ‰WÜÇï®úy¦„•Bˆï¦¶¶–h4JCC‰xœd2‰ã88ŽCss3.— —Ë…ßï' áóùðûýèúÖ-J$¤B!„{-$m‹DÒ&™´±u…eÙØŽ“žªgž·9¤tÒ¤Âth™®Ué¨Ôsl'U«RÛr°mǶQ lÇ!i9(G.!ÁŽZö¯û8é772tx—ûxàö'¹ú”a”ZËÐfÁcç1eî!|°r]¢sÂÐc¹4Ü“y÷ÏN;‘MKîgÜEQÞýd-Ù pí„“77Ƈ¯Oä‹…/ñÐÜEð‹‡g=ÆôQ3¹ð†;9âß,8›¿Íú#ãNü5w>÷6“ú~·Z’*ÁÓ/æ¾Å?aùWbþ ƒŽ<–aCW0Âã“WÿÊk ëxí\‡YOÌ¢ÏS—ðÇ«obÂáÏÓ?WgÃ’‡9æ‚[™ûaøsÆÈOµ¹êö'9÷'§qvß¿rù¿B4E¡|ôdn9k9“~³Ž„Úö²Ç—¶9ïýFÅø×-Gñr÷»Y½îVVΛÆgŸD…z™?Ÿ<Hðys‚Taÿ ¶¬ÿj7Ê…ãŽæìç–²n̺þ(~zôcÌ^ô]c™uÏL–%ZòdîœG¸ýô‹øÕ_^g^'Íæ{Ž:•³ûÞ·mmäù ~ΑO¼ÍÙCóøø¹+¸¿2Úá.Y÷Þ´ß>º¯þÍC/ý^ú7˜>‹ÇïÆOþk:x4¿=¾ÊNðé'ajr"ؤ¶{ñÌóùñÊøïgôÎR,xìçœò›¹<|ÑTÂëÞáº_þwŽÃÊ­7gŒv:˜’:'Öœ`«©š›q—?Ë[gTóé;¯réoïåùû®àˈŸ9»P— BˆÝS^^yùùtëV‚išhhhšÖáèÞ'3-ÒÔ´õà]:€ã8|úé§TWWK !„Bˆ½‡J…Œ–í`Ù¶£2ÿ;Ô74°råJ>_¾œ?YFÅÚ5TVV²ò«/ظq#á–Zš›X»fkW¯¤¾¾–ƆÉ$¨TÓp'Ól<dþÙ=ÔÕÕ±zõjÿgëàÄ×òð=n~>©h]øé¿€ægxþ­•™çĪ–pÊoßä¶['SèÑ0³÷å·¼€ãîŽSý~§ÓL{3/¿›~ã ©øp!¯©dNC*o¦"Ò•O?€i/=ÎÄ0éÜ?ñصCåͼ¿.I~~Y¹ù„Bþï¼­nŸÁ™×Œ'¤i$¬Tœ—´,B%û3éðCÀ7y ÿÀØ¡Ã9ãâ!ù>k75ƒJ°|áÓP|=ò4Ìü¡\tå8(ø%“O;„—›}Æ@k:3¶þÝÙ²·7oï¦EL™¾žžÁ‹ç/¤2œ üž¸ý"J¡{Êyà˜ÿøÉ†ŠË^|€7íñXõŸ³pñçX¾Ôsž~ó+ÊœÈÉ£rè~ì½ÌüÕÑìwÀœrzñ¶ QÛö¶:‰f¾Ž&xú…ר+w5?”»õǃUÝé±±º>—‰“Á¡Aƒ‹îys&å°ãOá¸á„•ºÙöôàÖyïð­GâÕ4â5‹øñ5opËôËé¥ûvÂæÕ6LŠ”PPPÐáOqA:QLßn[kÞÖáȸYy%”÷Âqç\ËÊ_áœBŸïmˆË9@±K1!õ-pcc#999R"B!„b¯¡Pض"i;ضèX¶ƒ¬d’µkV³¾b-^¿Ÿd"I} @(Â0]´´ldÓ§›@ƒD,NÒ²CäåR\ÒÝo¦›}§j^î®’É$‘H„P(ÔîñoÓdûÛZÿÁKÌ©~…n?H¾Õï?À]×ÿ?=âJ \‰ÈFðM o‘'õ"ÍÍèÓod4дúÿ:æDV±*œdHŸ.€…ee1{ös€E¾éŒ&p»ÒJbpàÑgÁío‘´,œÖj*U›­òãWù¿wVáñxPñ& †ÄqÃKwlC57¯}‡Që–qÛÅ'sßKï¦nÚÒA›+Pf Þôšéj÷Ú`vOhXHeóùdgi÷3 —ö—½yW¯M…ÅYn #g Ï??ÍU‚'Jóò:yFYõá»ìsüÅ5°,‹ò£þÊs-]»*ó@ck½fƒ¾C'<ƒo]Þº§˜ÃÎÉ?n¿Šý½Š§¿Äù“ößzÕ-Û<60LBææXP9öVóÈ.ÜÜGd¬¡€]7×”´íÍ#lûKFrý-#·¹îËçüšŸà˯ÿH÷òöýÚÆš:¨I¹Oþ@®™u'ÿ8ì2šÂqÀ+'!Ä.#Rz<BY!)!„B±÷P©Ápl;õ£´ÖZ” ¥”vïEvN–eaÛ6þ@M3hnnÂ0Ýôè•…ÇíEÑhÇqðz}h†m§Ú{ïÎ%ø|>|>ßÿhÕñü•÷pãôY˜ïÆ´‘RV<…½‹W—NæÌ…èø!ú*««â”—·^¶5tö8lèpÆŒ(l7ɲ,"Í­ë±9€2ŒÎ쉷T1ï½%”ådc7®a@Ïcvh3›jkñuÉféÌøñ5O0ó­\þ›ì3æ\¬Ì1Ùæ<ú|D'sþÕ2íyà×Oóë»ÿCö5éµYüôo;]ö¶æ½¡¦|˜pÄ!mšß§ËÐV`lùÑpWF½EócT¢ƒg·|Çò6Å#<Ûíoœôó»¹åÂcxùê§ùç/j=vèØH·²&ºƒïñÖÁ“”Ýñ  kxï£ 4³£^Ù,l-O‡¯MÍxȨ~øw`_‡ºõçРARÎBˆ]Œ `š&Æ “ÒB!„{EªÏHËv°…a§û‹L'‹Oa•~rj@‡Pv.J¥Gðv”ÒÈÕÒ£{+…m§æ¡íý½Aáÿnù_Ígjâ >8¦]ØÖ7t37ÈÀnƒ9.ÇÅC??‚Ù/qh(ÓO½|ó1Ý÷XV­šÔùûA×qÿ¬\ó§¿{%]=o>v%]DZÃS!¥²ÖsÈC˜7ü&ž¿q® ÃnœÁ§Œ%¨à®S®æ’{æÐ/K—s€b']O¥þ›;w.Ï>û,J)âñ8º®£ë:“&MâŒ3ÎØî—·ò©$„B!öZ¶Rıx‚X"IpÕŸø÷;‹™y÷¯˜Óä‰_ÁìÅ•›W&ú*_×EÐýåÜòχØß­ó›sŽaìÑÑûò¶µ@ Ünwç?¦™ê;ôš9ÜwڳػŒsOÜ—ëÍk¯\˜ ò•mµKšÐ}©/ þríiôïYF÷?£ÿ=ÿá·Çï+'!ÄÎÑæsøðÃ'??¿ÝäP(Ä1dzC­K4¥öÆï}…B!„€ªêj¾Z¹–ÚÆápM×ð¸Û7­ÝòbYCÇ¡¥,t-ȶ¾÷×4 ˲H&˜¦‰¡äççѯO9y9ܮݷÎÀìÙ³Y»àq®½ç%®½û1†·©5éÔñü-W2sy”3®ÿ+'ì_°Ýù;v'­™M<šÀ1\øÜæ7˜M 8„rB™p­iõ\t½õ)‡•º‰ØAŸ»ý1bE '·~üÛŠG£˜>©f»I\4“ÞâѪcÖõG9ៜ94H$"Z½ˆÑg×òŢɩþ U‚æ ÈÑ.HìhÙ.êwhÞÊŠÒØÇôø·*‹Î›{o–Œ6ŽÛxƒÙ™Á¾Ûó¶·UY Z¢q<¾àVëµ|ÎÏø}Í…NlÀßA±V"J/>·–ÙN访BlÃúõëé’—G·’L—‰†ÆâÅ‹yðÁ‰ÅbèºÎyçÇA„ÛíF×ulÛ&ÒÔÔ´Õü¤¹·B!„ØkRXXH$jŽY©>&•Bè0#ÑEMóKÄ’«ÉÏÝ …Ýé2´ôŒT:îT <.=§®@jdô6ô.}ÅÕÌœò{žúÛ"Æ?t,Álm <ò³­i•“³õ+2ƒäxÐÝÞ·C3}wâUÛuÔL7;}6¯{—«Ÿªäæâñ…ðølÖ¬ÚÈ I½2£l£¹ …Ü™ò0v`ÙM«wlÞšé#'§ãò5ÝÛxÉå ‘³3ÇgÚζjfÛé›U.}’#oìÁ»ï Úæ±±]*Áë÷ˇþÎù=¼íŽ—Pº;ÈD<œÚvÓüNÇIGåmng;…â»rå´¿9r$o¾ù&Ë–-£W¯^xà™Z”j;×>R !„Bˆ½šø½&>ïŽÕ/Š'k¨ ¯%n‚Ç3’üì~¤{ËÛ¾TW‚éØRÛ£ËÕUÀ!ƒÿÆÖЃ w÷Û'ÑÈÒw^àžÙÿ¦×O¥¼$w—\|;òN IDAT×@~ŽËqqÎa~ —÷–ÄtÞ_˜qãaß©öÜ÷9ï]QnŸI¬x¯ ïZ›S38à´1¾°ãc¦±j sžü#óßý˜QÝG~÷e !Ä}ÕA3îÓO?eË–qòÉ'cFæ9Úv®}$¤B!„r­mÿ¹•×Gi—ãèšs8!ooôΫ]v° ½°pu/®Ý4ÅJ6×`ÏóÏŸD2¥²ª‰%¹»d(g„2íùjùWT7Gp‡ré^VNaŽg—ž÷®ÈÊÛY{….……Ú6µ•ëèqÔ_yþXD4J]‹E Ç…Bì–Ôæëœ=zpá…Ò³gO4MKÕ¸T*3à`g$¤B!„âÐÐÑu]¹Ñ4“½3yüœ¶ÍW6Ý•xòzsÈøÞ»Ï±ié3x}v³yï ʇD¹„bϹ@ÊPJ1pà@”R›J¥@±Í RBJ!„B!¾!C÷‚R;4RåÞ*R½šÿ†mòFìG¯”‡B±§Ù2€l *-ËÚ* T¤ÿvRÿwDBJ!„B!vP$¦6\ƒ¡éøÝ¹4FÃxL¿'°ÃÍÅ÷D†Ñ~”r•¬âÙ›ÿ À9§ˆ4`B!ö<[ÖˆT(”£ˆD"™pÒ¶mlÇF·t0RÁ¦„”B!„B|G‘D˜_“°âÄ­q+F¿ÂôÊï!e€µ›Z\J<ÜÈú¯>bæ÷óqÂá¬+ï`D©_!„bdÛv&tL&“$“I"‘±X ]×Ñ4 MÓ°-]ÓSµ)mÛ¶;œŸ¦¶Õc¥B!„"#aÇI$ØÊÂvhšÏÀëòíueqÝä1Üöä­'¸†rêYc1ü@Jóv¼÷رc·û+%W¦†ËëÅ¥iÄ£ <>÷nUv±æjê"^Jв~°e*+Jm]ŒÜÂÜ]~4îd´–Ê‹neEÿ£òB±}+V¬ ™L’““C,ò,4MÃãñàr¹0M—Ë•ùÝ0 lÛ&“““³ÕüvZH©”bíÚµÄÉt›sÃ0¡ƒÙ£ªÎ^Óúˆ¶ý9v2Ùvlt]4BÁee¥ßh›,XÀ‚ 8ÿüóÉÍÍÝkÊÖr¸à‚ :<È„B!ö4M-H$Ãd‹q¹‚{eÌž={§ÎoGBJ!„Bì¹vZsïd2ÉŠ¯ÖPÞgêjj¨««¥OŸ~ض"=‚Okਊֿ­ýkªô?[ýÞúœ¶ÏOO£Ík3+Õþï6Ël}½¦|±üsJËzbº½D¿üŒÒÒ4Mß¡í]°`o¿ýy…ݘvÿL¹ô’NƒÊÖB5RÕ\å o±µ›v¼ž*‡·É+,Í”ÃÎ *•tH/„Bˆ]L8¡b]„ú†fz”ùéVìÃ0Œv×/À6¯aäG!„¢½R*¥‚ävÉǶŽ£ÈË/À²¬Ìô¶¡akhÙBÒ.€ÜL¶}mkø¸9¼¤ƒðróüTG¥ç¡9¹]ÈÍËÇãñ²®©šMõ1òs|èÛéO¨5 6êzöéÏ’wç· *Çá³Ï>#S__×ë%’››‹iš(¥¨««£{÷îTUUá÷û1M“¬¬,zöì¹Û<­åð±GPÚ³KÞ}‹iÓîç²)—’“ƒRŠªª*êêê())Á¶íT_¶mÛ$“I‚Á †aÇÑuæ–f¼/±X ¿ßÏÆÉÊ΢gžònB!Äÿ\8¡býFlÍC^×îTÕÖãØ•”•£ë:Õ›ª©­­#à÷ã÷ûq‡¯¿þšX,FII †aÐØØˆiš”””•%ÍW…B! MH¹3¾Íµl›dÒ&‘´HZ6‰„•é Sµoùݦ¶£ÚbzkMIMÓpš–ú;½ Ã0p8éyovª-Ê-CMP([kÓÁ§ÂQФÍvË PŽ>”žåû`[6û ƒm+þ–èáp—ËEEE‡r---hšFee%½zõbÅŠ455 …HZÝËÊðû»ÍÓPŽ{$Ýzöƶö6ÇVüuÚý\>åRBYYTTTPQQAUUh Å—_~INnY¡, IJ>¢©±Ã0ðx<ضÏç Ê;U!„ÿsáH„uë7’°MüÁ,¥pû²©¬­GQIiI±hŒD[—¡T©aÛÍ|]7Ÿ®9ã0­ÃÍå!”öèË'+kðz ’–MßAñU*¨üÑ ÇãóûIÄŒ3Ó4q{¼èºFI·n466²ÿ@9DãñL Ïh4ÂÚµkwÑ+S‡dÕ—h†ÁêÅ|Àð±ã)*ëÅêÊF M#KÒo¿‘Ø*TN™r  bà A4¦CH }û÷gãÆ”––á÷û;v,ñx—Ë…å©õ877·Û-ïT!„Büàì–MØõëуÄݹTl¨&fD’.Ö¬®E×!àsãw‡X¿© æåáõy±,‹ž=zàñx@+iaYJ)|>>Ÿ—˵[”CMM õ äçåíÕý° !„âû•úúV®ëÔÕÕ}ëÀQ´l[¥,»5 t¶C',¶ù[)0ЈÆb455„hniÆåò'C,[ºŸÏOirlG¡œ¶}P¶ &Ó+µeÿ—[Ó±VÖü’ˆµ†„u.3;µN™>…`þÛÓµ[?z” ‹‰'IX6¦©ÓIÐoÀT®_ÍsÏü“’\_›\vë@´ýÀ?›—³ëR8-5¨X5f1夬W?ššcX–ÛmOÚD" ú JåºÕ¼ðÔß9m\/@#7³­¹º‚Ê5(ÇÁ«ix5-µ“¶ø†ÞÞàÍtðÃÑ ÞÁÇ é¦|J±'R6ÉM«I¬yÍåýÁ?c„» œ†õ$–¿‚ãÎbc¯“ˆ #”“KmU …iÄI¼nº+@ņ\¦IY·®{TQèºN,%HH)„Bˆï ©&Î………ävùnŽ£°[kSÚ*X:éL®µQwë b›ÿTë°2 GrÀíñÒoßA©kDÝÄešøü~ª«62îÐ ¸\.‡LsíÍý]¶ïË`ûùŸƒ¡çѽËo°˜Oqî$^”RxLº®ã(ÅÅ̃>Ê‚·^áÀÑãéVD×4–ƒI’׿WoŠó¢iðeõçTÔ®¢ «˜H¢…X"ÊèÞ‡0åÒK™6í~ÙŠnjDz,ôh˜7æ>C~Q ã8Ÿ?†IíúU8Vå8©‚JÌ/¦¨ßÝî@Ñ߀I©r.½ôRîŸv?ŽŒ8˶ˆFÂÌ›û E%eŒŸ0Ÿ×G¤y#áŠO¨æ3 ·ǶÐt’AcðwÑŽâ Íôȧƒ{4 4Íô¦jR !DGÊùå˜ùå¸ 7«×U ;xüƒß »kOÜþ.…ø²ópûCxB9{Ä“•Å¥S.eÃÚ/xoá<"‘óæÎ¦¨¤Œ#&LÄëñò›té’MVQwÜ,y]qûƒx³ó1¥ŸI!„Bìfrs²éUV„N”ææfI›Æ6¥ßç!pãuï9µ(…B!~(;õ«ÞH,FcS3ÍÍ-´4·ÐÒƲ쭞׮¢c›jjËçt2mg0 ƒh$B$Á¶‰D¼Ýô’œ²N_ÛTN:••Ÿ/¥GßÁŒ~€ Ï$+ àrKËÉ--ßcžì¬,.½ôRîøË|õÙûôê·GL8 ÇCÈï"à5Á›‹7$} !„bÏ›“M`Ū Tm¨¡ /‡’âÂT@éwáuRHB!„ßÂN )].åeù44oÀŠÅ𹡾ª¢ÝÈÝ»MƒÜ,‰p ‰°FqQ!º¦ïp …8ÿüó™óÜl; Ÿ?DЧgʽEvvç{ÿzñY0>¯Ÿ O'èsÉ»K!„{¤Üœlö-i ÀÃÌÉÁï÷òx]P !„B|[;-¤Ô4¡CöÇr ±%¦i8J±+·tÑ4ms?–€cÛßh}•ÇÕ\AAÝ»˜=N#èÙ»Úõ(u-54Ç›ø³)È ‘HÆú²å%„Bˆ=ðâG®¯ÆN&q»Üäc™n#‰[—€R!„â»Øé={›:t í¾µ ¿IÿAvÃ×(ÇAßôA÷)ÀÞuqê8këV±¦z -±®~€;H^Öáèš.ï.!„BìY×>¶E´±ŽºŠ(ÇA3 œdoV}È-”BB!„ø–¾—á÷–ŽÂÍü^˜y½|&ì…¡œ®ëtïÒ wÔÏÆÏk\2—é–€R!„{$Í0tÃå  M7P¶ËçÃÌ‘B!„øL)‚ït©šþOßüû^µõùÁBÂÞ0¦fQœ‡®ä°Bì”Ú5;MBìº×>šŽ7˜…7˜…ÝRJÄ0BÅh.¯ŽB!Äw$UÞ¾%ÇJ¦.V ͽw_˜*¥°UËNÈ!„Ø=h yü{ýç·â;\ÿÄ£8‘”\ÿ!„BìR“ò[pl›uËæÓh¹HØ ÕUhz Þì.øB¹{ãe:j©Mª@7öÆÊ±Bìñìd‚Ú5Ëqù‚hš¦ÀÕP‡nêÒTSñ i ËÅ‚B!ö^k×®Åívãñxðù|x<<n·—Ë…iš†¦ihš†mÛX–…eY455m5?©Iùmnrí$Že§:M·-jVƆOm¨ÙëÊBaÓþŒ–ØZVU=ŠÂÙÍ7È&þÅ|Âÿ™Jø‡A9rÀ ±G}h9D›©úâ6._JÕKY½èej×®²B|3­ù¤t!„B±SHMÊoSh.e„[ƪÆù”<…޹6ÔÐ xËÐ4È @ÛÝsoMÇÕu4ÃÁÕµÿ^9 ’{2Ãå¦ë>CHFÆrl”¦az¤?]!Ä7½fÐ$ B!„؉vZHé(‡Ï>ûœD"‘ª¾™´ðú¼(€ÌõÛÖrÛº¶ëlšêôyj›Ïk7AƒX$‚ÛãA)ÈÍÑ¿ÿ>;xMª¡»Ü,xw1_­ZͺµkèµÏ ½òr”bá;˨­ o,‡ÜÝ{f¾8O×çRooÊä3Bˆ=,TÐñ²py|Ô®ÿ —×GNמ?È¢#‘_|ñ%L$@·Ë>‡©ížÿ:xZ'çÃíŸ Û&™Lâr¹q™%ÅE””H&ذ¡’ššZ44‰¯‡6ÕÆ¶¹®;m=(¶eá(p»\ø}úö)ÇëÝ{ûM$Tn¨bSͦ-öOÇûdË¢VÛØm§YÉ$Žãàr»ñy<ô.ïA0”Ï!„Bñ½Ùi!e2‘¤jS-ýö̦êjZjèÖ£;–m¥PUí.€[SªõZ¡Z'õx»ÇÒ¿Óæ'=MSí_—y^ÛÇ”Jõ™¨JSèºÁŠŠõ”uïËãaãW«ÙgŸ¾èúökÎ9ŽÃÌ™3I&“Œ{=ý,gœá¦_¿~힣”Â0ŒlgÚ¶ýƒ.¯µâñ$#ÆLà±<ÍYgIŸ>}¾—å)¥Ð4m§®Ûýݺ=áHŒMà‘'f0ù¬3éÝ»ÏÿôMúCïW!ötŽãPUSÇ—• LÓb€¯‘œììïw™Ê¡¥%LKÔ¢¬G/Ö¯«@× r »a[6J)µù³®õÜ×zÎsZÏiŽ‚ôy͡͹5ýz­ÍùÒi}½N*ñKÏWI„ÙXYOi÷žXá(ö†jŠ‹‹Ñ4ˆÇÔÕ7È.Àqê6|MAI º¦¥ÖƒÍ!Xf½Óç['zµ®kÛórêïÔóR=ƒ¤·#ýZ8­ÏIo¯m[Ô5Ôb;6yy¹Ômj ° ×»×vœˆ'©khÀ*MQ»~=yÅÅhš– m'µORû+} (g‹k/…ãlÞ‡ …²SÇŠã84„ë ‡£uͧ®¶ÜÜz štÁ(„B!¾';µ¹·ÛíÅëóãõðE£xý,ËÊLo{S“ºŒnƒ¥Ô–µ>+}cä´}]ëM–¾ùq6ߨ@ûy¦ÿo{ó§ë@@0€Ç㣡ڠº>JA®cAekFé¿ÿ(º–ô ”Ý…O=Å™gœN¿~©Ú˜ï¿ÿ>›6m¢ÿþx½^lÛÆï÷‡Ñ X4FAAÑhÛ¶‰ÇãD",Ë¢¤¤ŸÏGuu5>ŸMÓ0M“D"AKK Á`0„¶Y7ndè°¡¸]îä&æÌ™„Ãö6Žü®¥øCAž|rF&¨t”Cee%U«(++öm4M#™L¢i±X Ã4pl‡úúzü~?@€ÜÜ\"‘ÑXÛƒRŠp8L}}=eee‚6Uo¢K—.D£ÑÌ~-(, ¾®ÇCcc#‘H]×q¹\Ô××ãóùðûý(¥¨®®fèС¸\®Ìö´´„2âPºvÅçðÄ3˜<9T:ÊaÍê54·4ÓµkWP©rWJ-Í-ÐÔÔDqq1›6mÀ0 ,ËÂï÷£iÑXC7H&“†A^^ÕÕÕ¸=nñD¦#Yx=Ö­[ÇþûïO ÍQÅ®/³zõjº÷èŽßçÇQ¦i¢•é(Y¡¨«­#//…"‹c˜FªSeÝ@)E"™ fS Fêý¢ë:õõõCA‚`f~Žr0 ˲0M4plG9$â ¼^oêñÖ€²zk¿®¥¸´'±xœO>_Ë }z“óý•š®áñúðúx} SÇç ¤?GÚ„{´ý²-0¥¢¦ÍçEGmb:[›ªm0™šãl>kšF  3t¢‰&à ².4MÃešx}”ãàóðùýèšÞæüK›/U›p¬M­¼¶Ël}^&¨Ü➟Óöœ­À²“Äc1,GHÆ#Ô5'ÉîâàuíÝq¤®ÜésøýôùÅhp·ÅN¦§h;lgŽ—6åïlqœØéš¶(ƒX‰( -ù ¿G¾4B!„»xH©i`ÛɤƒeÙX¶CÒ²ÓÁ”Þ.LÓ5ÛqPÊÁår§/ªuœÌ %zë-¶£H&â i¸ÝÇÆNßì*¥‘ˆÇq”ƒ»µ?HMÃI×ÞÔu=ý¿–j¥¦ÀQ6NºÚGkÈ—©uâèèÚöÊH4Ê€ýGQеŒ¤eÑ­¬'c;ž3žæÌ3SAek ÷öÛoÐ¥K à R__ONN†i0jä(æÍ›‡iš‡q¹\TVVÒ¿*++ ‡Ã444P^^N(bñâŸ\.Šºv¥¶¦†M›61zôhŠŠŠ0ᅴѶåþŽ#·°„D"IYÏ>Œ<øhžx2U±¼¼œ _o`Æ Ô×7 :Ží°jÕJ²²²ÈÉÉA)ņÊJòòòˆÅ¢„[ÂŒ9’††b±UUUØ–MQ×"ZZ¬]»–þý€R,\±Ã0¨¯¯'Ž0qâQ¼ÿþû躎išÔÕÕc˜:w*°ÌÉÍ!ŽÐÜÔÌÈQ#),,L…¤íÊCÈÉ+¶lº÷ì‹uФLPÙ³g/ªªª¨¬¬¤¶¦6s<¯[¿žÂ‚T: ‰D¢„ÃaÞ{o ùùùøý>š[ZPŽƒË墦¶6LVUáóù>|óß~‹ÜœÜ̈Wš¦á(‡â®%áÙ‹›6ŠÝ‡£b±ëׯgõêÕ„ÃarssñûýTWW£ë:$óÉ'Ÿp¹\(¥hiiÁëõRPP@YYK–,!++‹d2‰Çãaà ,]ºMÓhnifðàýˆE£|ùÕ—¸]nrrsñ¸Ý466ÒÜÜL  ;;›8Ó4Û”yEÝPŽÂ4]ø³ ùpù†ôïANÎ÷7·†–97Z¶ƒ–:Of¾ÌÓÒå¨2ç3 -Pj€†ÂÉ„HŽí`ºÌÌ9NKŸèZcBMi(-õe^jÖv¦&£“®éh+'µi%ql…év¡éúæoÓçåT¿~¤ª¢P¶“^ Ûi­š ÛRµÿÔæuÝ[ßkŽ"i9 œô1å ë›k«¢i™2r…í8©PßrpÃe¶9.@)Ûv2!·£T*èÇÉ”wfºB!„ßgH©”âÃ?¤[·n~‡T…å¤.˜m»õ‚Wç‹/>GÓ4"‘0ºf“›Cå† Ô××QÞ»/@¤•ÄçõcÙ6±hÝ0‰E#dçtáƒ%‹èÞ³×K¸¥ÇQ„²²ÉÉíBUåÖ­[Kß~ýÑu#SÃp¹pl‡X,š¹ØVJ‘“‹Ïls·YÌZÏÊ (Ë?·™µÕô§gÎ"‰3`È(ò Kùð‹*²’¶MaQ)#9–3žæŒ3NgÈ!†ACC‡êêj\.@]×ÑuÛ¶ ƒLš4)UsÅå"¢i7n¤¸¤˜ÜÜ\¢±(.35t»×ëMœ†A<gËÅ¡‡Š?àÇírÿ?{odÇqßk~™µž}éèF7ö @‘ ’–)‰m]Ûãð"Ëc%Ù÷†gîDLLÄDLÄ<ÎÓ}šWOÜ+Y¤dÙ¤${lÉa[‹¯hY²$[ -‰ €Øˆ­÷³/µeÎC>èAб›È/ö9uêÔɪÌÊåWÿåM¹«¿]žyæ:Ý÷ÞÿÅê$ç/×ñ\‹v7dbÛ,÷?úËüÙçþœ#÷¢T*‘ËeèõÚòMm›¤Ýj¡TDœ(ÆÆF( ò9®]»2’¡ZM…Ì(ñ}›DY\½z™D%4› ,Ë"ŸÏR,æyùÔI¤ÇI­< Å–%AkªÕ4Xf¥R¢Xʳ°¸ÀÊÊ/^àôé3h÷ÿE¼Â(/_"Ÿué1“ÛçxÏ#Oògöçüþï}”c÷ÞÃÑ#÷Ðl5qÂÊÑ#‡YZZJ­_³Z­6ý^_úÐärYº./z‰½{öàº.Q¬xõÕ ìžÛÁÄÄD*Ø~ø—±'],À´Öx®G&›Á­¢[«0 BÚ=ÃF I&“aÇŽÄqLELNMôFGGQJ155E»ÝæàÁƒ$IB.—#Š…"NH­ …GŽ>ˆ(–Jd2öíÛ‡çy,,.22RE Èd2ÄqL·ÛÅuÝ ý¬”˲6 ”ãÛé‡1‹«=â8f¬’#Sãù/pìÐ,åòí‹»§tD½s’n8A)Mœ¤‡M£Ñàä‹?M-¾])%SSÛxù¥Éfs˲™,Ò¶éu:H)©7j¸®ÏÙWN1½c–b±BGD±Â²,„”(¥†îÝhèöº´[ ªc“”JåT@|£nCC<7“D% õÚ*çÏÅ’ –¤R©råÊe²¹<¥r™ŒŸEHI·ÛA+M¯ßÇó|.œ;ÃÜ®}™ZÓK!B"m‹D)TœZØFQB§Ó"Ÿ/R®Ž`Yöõ0[  ‡_ßî±@µ—/~Ÿ¨0‹Öñ@Ì]›s]·¤t{^½x˲ét:ØŽC¥2ÂêÊ HI±XI#l‹Œ—%›Ï§–”¬sÍW¦_3¤¬®®R«Õ¨V«T*sA ƒÁ`0Ü9‘2 CΞ=û¶'JA+’DbqsþÜY&§¶§V–¤Vk!Qó¯ßû®ëR.WPõU‚ $›Í‘Ée9tø(ý~Ÿf³A°¸@»ÓÁ÷}æ®1:2ÁôŽ9Í&¯¾zÕå%Šå*cã„AÈÒâõ[CX‚ˆô˜ÂÃßât”§4ѪHyd’F;‰ëí>­NL¥èáù”†3?ø&ÛTÒ¢´V¦Aû(úÒ+(¥ÈII~Í:eASŽ—A¬þp¸Ð.û¢¸|šP)²R^‡°^LÔšHëôdÉçó´Z-|ßÇ÷}Š…"ÅBÚîØ±càšªÈår)X\HåóyúAŸJ¹2,G·×ã•óW™ÜÖE +.Q¬¨3©KºSà[?øGŽ‚-7>ʺÕ;P«ˆÕî¸ZûëC$üz:F& E¢4ý ¢ßë26>BF ++Ë,//ã/-"…¤×ëÑj5ÈJŒŽ‘/JüÛ”r8¼Óguù*ß{îo¹ç¾<ôðÃTò²hm²^ÇrITŒ%¬ÛšçíÇ1O=õ4ÿð¥gxüÉß ”óÈfÒ8•«Ëó|ï¹/sï{Npøá„YÚóäG& {Üli9BlÎøhZÅ/ÿwtÔ7"¥áŽ¢”baa_|)%“““”J%NŸ>M±X$ Ó˜«õzL&ƒã¤î¿»vîäÊ•+äóy&&&8sæ {÷îåÔ©S,..R«Õ(•J |ß'„d³Y&''iµZ8ŽÃøCr¹###ŒŒŒGñðAŽï{Ø;Ë©³W)ŽNaÛ’]ÛË$‰ÄŠíÓïÔØ¿÷1´‚±rÏqPƒòïo­#ʽcLW~ ìåä+ DIœŽ‰„å°s÷lÛŶllÇFJ›‡}| ¦†8nzßFa4‘ŽÛwì$Šbú½.®ë£´&Ib‚~Ûq‡qŒ-ËFX’n»M¯×¥\yC¹5 º5‘2Q©—„ëeس÷–å`Ù×Ë€Ö<ò ïK-DãxPVMÅh­RâûYö8‚R J§‰ëº6­V‹‘ÑÑT°•’ q¥Z­&Åbå¶ |?ß!ußww?Š3±ïö¶³Š½ýv~š…¥$ M’¤ÿÔº:-WF¹ÿ¡ÇÒ¸ž«f?“¡X¬Ðxgia[6Qa»nêÞ¯u&Àtg†عk'333?ƒÁ`0 w/ƯgõòVX{šŸ¨Ô=,N4I’€°°ìÔ=¬\ñ‡îO(WÆÐhævíÛhµ2 讟€/–ÒÐìî}ÃàïŽëã¸þº…²fjÛÌ0[hšT%ÍZª_7–•Ʊ*LþBÀùå—¸¸zŽÑü8µî qó {?ÀÇ?þqž~úi¾ñ_äñýX\¼š ”‡ïç‘GÁq][¾k3Ú¶ÍÇ?þ1žzêiþñï¿ÈãOþ&JÃÒ¾÷ÜßrøØC<üðÃ8¶m jÝž¿ô¯”2’•îï™yˆ‰âÔ¦9ŸO|âã|úÓOñÜWþŠÇŸü-”Ö¬.-ð½ç¾Ì=Ç桇O`[:ê±zîE–^ù).¶•RTwìgdvßæ­4!ãîm¸Óí,1™Ïçé÷ûH)Ó$Xƒä`kV###A€ã8CñѶm´Öôû}úýþpß™™vïÞM†4 *• µzŒï3::Šã8ŒŒŒpíÚ5Ž=Šçûè[yi]Æn)$##ö)Í‹¯\¡42…,RkýÕöîžCº‚S ?b¡ëáÙ>+íEv`×èÞ[»$¡œ=ˆÒŠå¥ÕTPŠSQI£–C¥:¾.Ljqîg €&‹n÷3b]2¸48¤ãx¸®—&E ¬Ù|q8Öù™ÜpLÍfrÃñ¯Ûë¼± ¦5:¸{Çé¸n;åjæzÜÂA€Êµ²2(+Z£3b0þ¦1 ýLvè~®Ðø~–ÊèÄ0ÉrÃÑ Å46hœÄ[ôV·=ĆÌUñ÷=NÜî /Å !Öæ[*íá¯7lÛIÚ®ŸA)M6_$“+^Ϻ®5Ž—Æú4^·ý y[Ö ƒÁ`0 o¨ÏÜ΃i ‰‚D§ÿ”Jß_·„¸žûº"™ P×´þ©«ª^÷Å£.p†žÁëƯ½_;îõÄ$©¤)×Ò ¤±-!)e+öÑzØ–ƒ%,\ËCJ9*Ÿûê9xô‘ëå£â¸.åœK.c¿»Î@Ø{ê©§ùÆWþ’Cƒë ”à8ÅœKÆ·HȰwü¶eÓ Úä¼y¿°éÎçÿð|úÓO Îçß}îKÜsìa>‘ ”¥‚‹'-˜ÝG¿ÝÄÍHÂ>*IÈ”GLob0‹X!©V«<öØc¶ïß¿Ÿ~¿Ïónj‰süøñáëÙÙY¦¦ÞüƒŒ™3?ÓÚQ ÉèX•ÃÀON_"_š"NBš« ìÛ3G>—Çr"nß…k{4{ üÊ,•Lõ¶]#5HP‰&QÉúáoð?õšjZ¯¥½a㘨xÍ~býØ·îµi²)$rð7M~óÚ]éå↲¿´±¬ÃLåë£?«c·Þx6¦Ü!øH%È¡5«0[†íhmzµVGRÝpýõÆùÙš¨üšöBštIH1¬™  J‰"Mxd0 ƒÁ`0ÜimævHA«Õbqq‘F}…z}•¥åe’uVoÞh½p©×›ܩŴeÑhÔ©ÕVq]?MX³nñ3^˜|ýïJÉÇ?ñq>õÉ?埿úŽð®(‡g ìýéŸ~šþêçyàÄxðÁãØ2ç§×¡à)øÅ-q>ôGÈýoŸäŸ¿úy|ä xðÁ¡@™õlÀ¦2½×ôÃ[éo¥¼ãqÌÞ¬;öšPyøÑ çÑÚbßÞ9òùYORÌe#í¯¶•gnkµVÔj«Xn–•Õe,ËFZö {òÍö_?FÞ8.Šë·z˲‚^·K½V'WX! |;aM*ÔZÑë4K€¦¶ºB._†´¸Qüfé^_V½þ÷,´N6¿üËâïþþ¯yàÁc¸ŽK!gmÙó1 7ï¿GGŠ>$éô,òù2YOS̹wô7K¥"÷ìÛF³Ýc´’OŒE['äI·…rþ´NÞÚ—5ä}Mfz‹€lÖbtd|àVßgïÎí\]X¦Ù ñ&G°Tו_wà”$ºO¯w×ÁµË ìÿÞt9m ãåLz4P¯’Ïïj×äLÆgÏÜ6®^[¢ÙMëÇÖ}Ðo  qY?™’Ü$âÚ€jÁ¥R°‘LŒ(—«ƒ¸—–éD ƒÁ`0 w„ÛjI¹gÏn­î ¸¿Ò×݇6Z¿Æ-\©„·IRG=dý¥K_Åyäñí»Ë -z,œzžâÔ¹ÒX!I7[á6Gø95 Ååú«Ì7¯áºyÜLB×Éz¦§0Þmý—j²ØûSl1J1{˜¬ïÜñßô}ŸCFÐ "Ä AÜ[]¨TÈ¥•/±Ðø'î™ûŽ}k–…‚5rÖ ËJý ÇaÛ¶)&&'éô“aìÂÁ`ÿ–ÆÙf÷g¾Édé}L¾w“úÖËšöÕ–¼{ݾmÛfÛÔ$tú j#ô ëGƒZ:…~õ«Pz ë¾¾aò¤áu××­xµÖØÒ¸Û ƒÁ`0îà\÷vÐ’PÎ;[ôr¼µr«ö2X.u|ën³.ÐDý>Ýúõù dŠ#í*V8Ç£4¹cˑҚùÆU–š t‚6ß9û5¦JÓLUÆ6mænƒÁp+½—"JÚ-‘–Àq:@éçòÛððœ['㤇ßZ¤”·q%JÙ±;RVK ŠÙ[Ÿ&(©Å\HÆkPÌ$á˜øÔN"BÑ¡çùØvBÎ Žqß6 ƒÁ`0l.ŒëÛY Tf°*ÓdO|ÄÝæþ$ðry¦þIb»>Ià«[òŒ¤”ìŸ8L)áÚK‹¼wß“8Ò1¥Áð®ë½$9o;»'ÿW,áâX¥-U~ÛÊ1;ö{T{§)emÞ>Ux”s÷²[þÏä¼#P¾“mÞrp·F¾÷Gf«F 4 ƒÁ`0lÎµŽ¹o­!‰îÊS—¶C¦T^zwâÒËoÝE‚b¦DÍ^Ý£’Í#…YÈ ïÊ®@G¨-hŸz÷Æ$*ÜCdB¢z(ßeíëg'§ù¹—I)tÔ›À`0 ƒÁ°)1"å-‡}„í!üü]}-´Ö¨n â¼wÉùèˆD%Èw‹¬o9îÁðnF †À­zW¸Nœ·m“÷¥ KºdÝI|§|7 †(£XÙêæñ°ÐŠ$Ž‘–È”~ÑtƒÁ`0 †M‰)o8èñêóߤ»„QÂò«ç¶M¦_@Ý8^__¾Ö~åú‡ƒ¤¯Ù¼î;ú†÷ÃÃrãÖõEЃÿ !i5d²9„”” Ž?ðž79çh)ùö¿|‡WÎ]ä•Wΰïð1ÓšÞ(­øÎ·Ÿgéj†ÆÒ(£…­>Ïüõ?ðâ©ÝüÇGÇØeªØ`ØÒ!°¤Åj}‘« /säÀ†ŸI)©V«T«Õ7}<­5H)‰âˆ(Œn‹Ø'HËÙîÔ¹xåvÍÜG&sÝý<“ɰwÏž7ÝÅQŒã8DQDœÄd3ÙMY?Ò² À¥Kg±É7A£‘X¶¤×î1ñ4#“3G&ÌÍd0 ƒÁ`ØtÜ6‘2Š"zA¡{ޱ¸¸ÀÊÊ2»ö"Žã¡0¨u*®éˆz T¦Ûô ÛôP\|ͶÁ1^»mí7ôks°ßÚ>–esqþyfǧp½ W®œ&Žlûg[(¥xöÙgé÷N<þËüù¿Äï—C‡ ÷‰ãxè6·¶ÈZWëF’$º½½N‡ ^³ £•¨w4×VG)Å3Ïûçüîï~”ýû÷oX,k¥‡õú³ÖkuÇ1öÛ°´ãiÉáñÖŽÇ1aÞtÁ¾v>Ív—‡ÿ0ŸýÜ3|ô£¿Ã6J©7<Ÿ$Ièt;d3Ù7}7¶÷^¯‡e[¸ŽkšÁð6ÐZÓh49uv)g8uæû÷îÒ8Íf“ .†i Z)%JklËÆrTJ‘$ ŽãÇ1ív›jµŠmÛAÀ=Gî¹-÷j§Óåìùe:Á$§ÏÎs`‹7£:§OŸ& ÃÔ¢OkÇAJ‰‚$IRI’†!£cc$qŒRŠ{î¹çMõÃ?oÂ(äêRKuß³‹KŒ ë.”RØŽMF¸®;Üà8¾ï¿&>èÛ¥×ësîò«Ý,µ+uöºÙá|CkME$IB&“¹¥±3mgŠ~¿@ ¥$Q ¶eÏÏq›ŽU7Æ!½Õû"´ ÏóLGa0 ƒÁ°E¹­þÉRJ4!%BX $y=Šqá1µª×Ìuâbºïzáñú¶5+M­Ôà3‘nÓzèZ•$ê&b'XRâ9ŽmãØ6±‚ÅZ‰‘–o8öÙgi·;;þ‹ŒŽo£P(òùÏ|ä·9|ø0§N¢T*±¸¸˜NÖ“„|>?´q€v»Íìì,/^ºÞ%I2-³Ù,–eÑï÷©T*œŽ?úA*#cä29žyöóüî@¨TZqéÕKœ?ž]»v¡´¶IÛ¶QJ12:ÂÂü¶m³°°Àììlº˜U KJ,Ë¢Óí0RÁ¶mêõ:RJºÝ.¾ïÓívÉårÃkuÏ=÷˜ÆfØ4¤ÂÈÖé/µÖÔ N½ÌÈØ6„´X]^â¥Sg9¸7J)Ú6—/_&¼K¿×j±ººJ±XÄ÷} UKKKìÚµ‹ÉÉÉÛ&Pž»xáä+çi6š¼xú‡öÍ E¸(Џrå ù|žb±Èòò2–eaYžç±¼¼ÌÄĉR¬,/333C±XܼåµE–j]&§¦éç//£ÑLŒÓëõ8yò$×®]£T*‘Ëåh6› –”8ŽC6—eçÜÎ IÞ.½^Ÿ ¯^%H,¦¶MÓnµyé•KÜ3C¡P ÛíòÒK/Ñï÷©ŽŒ¤ Û¶‡ó|>O­VC)•>„•’$ŽI’„(Ž)—Ëd|ŸÓ§OÓét(—Ëø™ õZmh™;555c‹Å"ív›f«™NF­4Njœ$ÄQ”ºñKI¡P Ùlc©®Å"]›+õû}<Ï£×ë¥ó¤äСC·¢À`0 ƒÁ°‰DÊ~¿ã8·<ñ”Òĉ"ŽUêž•¤ÿ„€8Iâ(145HKbYv*TjÍZ†è4YôukJtjU¡Ôõ'þBJ´R¸žG’h‚°c»aÑn·‚>ÅRiYh¥•¤–$‘So8ç Ÿæ¯(/¹Òý ¤2¶G?ðë|á _ä#ÇcY/^$Œ"\Çayy™±±±ÔU-Ž™ŸŸÇvlf¦gèv».]ºD«ÕbjÛ6õ:'OždllŒÑÑQ–——Ù>½¹¹9Μ93Œ!V«×ù…ÇcÇŽ#P¾MòÁGžÀÍ• ‚ˆ‘É~ü? …ʽ{÷Òh4ét:œ9óÊ0vÚåË—)—Ë‹E’D1?•ÉÉ)úýõz˶éuû¼øÂÉAÆÝËËËh ®ëR¯×ÉåstÚ,KR,yá§/Ëçp—¥å%\ÇEè!ãc£,..Òh49~ü8³³s¯+P>øÈðreÚ½>#“;8ñøà™gŸåw?úQöíÛÇòÊ*½~ŸS§Oã:J+Ο?O>W`ll¥5ÝnR¹„ëyœ=wžÅÅE&&Ʊ,ɵkóضÃ{î˳¸ø*W®\Åq|?Cô(—*Ì/,pøÐ!Š¥²il†Í%R’>XÛ*ec P–F¦¢ĸÙ2Ë­U^9w‘Ý;wP)W8ñÈ#”J%€Á˜ I´F% –e!Eú@oíÌûA@·Û¥\*cÙo_üët:œ»xeeÉdò„‘Âr|ú‰â…—ÏqäÀ.2Ù,÷ß?ïyÏýH)H”¦×í äsÙá\@)…m[ôû!n›j¥‚؄Ԛ@¹¸Ú£X'N n‘W.¦âk¡'Ÿ/°{w–(ŽAk<Ï4•J…R©ŒmÛärùÛ*Pžõ ½Ø¢P¨† Hì/ž~•Ãûv ¨]¹z…‹/R­V©T*ÌÏφ!»víBÁÉ—NÒj¶ð<™™‚  ßïÇ1­f“J¥B¹\fjjŠn·‹ß÷±m›ññqŠÅ"—.]byy™ÉÉIúý~*T6›$I’¶W)Éf³8ŽCLÏÌP[]åÒ¥KX–E&“!“É ÅIß÷‰¢ˆÕÕU:Ää táö³öݶms ƒÁ`0ܹ5šÖZ'IÂW¿úUxàÆÇÇom‚|û»Ï³çÀ–——X]]aß¾( ç^9M«ÕDHA«Ñ`jÛôP ¬­®’ËçA ù"½ Gw!k°€ê \±m´N]_ã(&ûÔk5fwîŠCSK´Ö¼øÓçàá£t:m •9µ}†\®€‚—_ü ;ævãy.{£÷åxŽ]ãÿ®]æÆØ–Ÿöÿ£Ó 8vüqJÕ ~|z×µèõ#öLWXY¼ÊwŸû¿ó‘ßæÀ´Z­aÖÒÔŠScI‹ plg8!RÄ ½~ohÁâº.Q¡µÆ¶m„C+¼0 ™ŸŸÇ²,J¥ÒÐs-‘ÀÏ}ñ¬b‚3ÿ„;}?2WÙr7Áç>÷9ZíÇûÒ+ri¾ÖÐ Òz]¼z‘ûÖßsøÐ~ª£e’( Ó%ôÀ}²ÝiSÌB{Úr,ÛB+5ÉU’ -‹8ŽY^Y¦ZÁ’´¦ÑlbYÅBiÛ$Q”~_ƒJ„%ÑJc¹ZÖõc§u®iöNš…Ë6Z;²Â¿Ÿ^`¬’¥ÑØ3]fþÊEþí[ÇGû7Ø3·˲évÛˆ¡À­YXX`rj w`ñÛjµÈå (•Ežç¡T2´r¶,‰’8ްíÔÂE+•>HÐ Çqoñˆ@Hp¯‹Ãíý"š½³€¦”=¸É˪©Õëœ9•Ru’N?áÜÕ®m¡€ãyÚU¶¸ìšGˆu±˜õðVZwÀuïuêôþp“¸Î? Õ­¼ò-¤_ œz€‹Ë]´ð±Ü,«±ÒtûÛFrt»<ºÞ» ßu6”iC9àõ?»…2Þö:‰¢«/’,Bî}‚ùžËr£O¶Påµý ¡Û(æ<ÆËQ¿ÎÞeª#ylË¢„Aˆë¦Öƒ¾—ºÁ )B¢oñü¢¸ÅJûßH’ˆ’ÿ×®ô"‰t œ»ZCJŠÛÆ „è¨Å¡½Ód|–D¬ä׬&¥%é÷út»]ª#U´ÒƒùX:·I’¥¶mc[6ƒpè²/„H³Ã ˆÂhj`MèZ¿Ò!U -I§ÝáÚüQ³0|¡H£^Çó} À²m|ÏG#p=—W/ž§\®°cçn\/ÃÕÓWÂ>ÿþ£02:†”/¿ô"ãS9úÓ;æ¸xþ,­V ¬,-’ËÈçot£’$Ô¹Öüøåì\»B*ý¤“p)½`…NWR,Ç MƸ¶E·a[ 8{ñ‡¦\¾¹åØÍb2IG]À׸1®ÒšÈãº.;vì0wÃíYjÇ1A“+Thu¥[ÒíG8ދְ\»F¶Ô4‰BÃdr‚Pu âh X&Ë`- Ö  2*Ðz™X§ïó%BÕA‡éa¢h $¬}ëïãDƒ©p™Ê´û¯Ð çé‡G@P(ÐéE$J“(c[ôÃÛqÑZpþäOØé,“ q„Fë´Å Û¤€ù%Ö"Êf„DÕÓ×ÎÀ k­8k‚ˆ¤¥¯ogy!ÑšDßRõ z5Ü÷cš´?†Û>XØÌ$IÂÂâ ZxX¶Cœ¤Cz¿i¢X! gϼB±ušbλAÄÓéyG¨î áÉ/wê´îýO43‡£Õ htBl+}˜k°•¥eÎ=ÿ/ìϤ]æ!V®®Þ¤5"R‘ò⿾ôÂzÅÑÝZ ¥ D8Nê!¡$8üäô9|ÈÅq,$- ŠA¿§oK[Œâ&×_§Ù;˨ףݸ‘ñzA„kIZýœçÐc²žK³-¸xi{ï{ÍœCJ9ŒCì:î뺠ß8w^7>öÍâEÞì–[q‡!n^oŸ7ú}Ãí'ã§.økñn ƒÁ`0îÈL[§ÐétÈf³·ì†ÿô/?bvÏaV—©ÕVÙ³w?qœ cA˲±m›V«IvàÖEBHõU„ôƒ>ãã“Äq„ãxiì#ŠGBH¤e‘Äqj…˜¨ëOô•BJk ayq¥5åJÛv°íÔâв­–”ç_æÄCGq½ÓŒŽÒ #úQŸB¦ˆ#Â8À³]>ûÙÏRovyß/ýa²¶(HhÕùÎ7¾Ä=Ç⡇!—u¨|Ä]`üµÕ-)“$á3Ÿù ­NÀãOþý(Á¶$A”Ð\ç»Ï}™c>ÆñãÏxd³°ÜZ ”)ãÙÂ$À³=ä;X×E£û2ŽÌã;Û7œO˜(Ô@¨l®.ðÝç¾Ä±ãøC'Èx’dõ"¥‰íôÛ-ü| iÛHk“¸siE´p´Â™:hzlÃíkZ:¢Ù;ƒÖšrîð¦/o†¼tæ<½Ø%_,“Ä1ýP büiZµE¦·SÌy¸q“ÒÈqØÇÍÒ1Ïqï˜-²»ÄµËÈL‰$SáòÕE®.µ)VÆèéƒ)$Z'45ŠY‡ÙÙYò›¬Ð©/§et}`û9„Ø›X|Ò*F5QA{|µZ“Óç¯âå*X¶K'$*}Xö»$a›]s³”‹yrE£ß$cû¸NHã4ºÖÛ?ßDõéWÂÁw¶3¿°Ä…+«*ãh ŽÓ<hµx2fçÜ,ù¬K)çÞs–ÛÉÝdIEÑУçvÍŒ%¥Á`0 [Ÿ;bI)„ Ÿû1’µ˜”J“$š8ÑÄJ ,8R³*ÇK3G*­ÉÊ Ó¤7ŽëƒÖŒŒM§”µRoËv“­µä7ÒvŸ¥2Ö׃l¦.¨SÛg†ï×ÿ}- !ÆŠÇ®ÕÏr~å åìÞ*ÍãûžäþàøÌg?Ã7¾òEÞûÁßDZµå5ò8'y)-²žm&û[˲øØÇ>ÆÓŸù Ï}õ/ù…þ&BZµ…T |à1Ž?@á8Šf¯ÎO¯|Ÿ‚_BkÍrg‘v<¶òô;vI9{=»üÚù¤íô·°lI}! GpìþG9þÐ , ¬¸ÃÊ…—X:ý#l7ƒR1Zk&öÝGufÏfQŒ§·á®Çu]îÛÉ‹/£¶Z#_(b[‚PijËóÌÍLR)•V.Òºò"«€íe‰ú¼|‰©CÇÉïÌC$áfq&ö¥ý)0=5ŽJ4W(Vǰ5„Q4(-f¦§±…³!‰ê—ÏÒ­- “ÛóI¢€Ò¶Lî¿SÆŸÒÆ*oÃbåJ‘½(^zå*n®Šã8(-ˆ‚IØfçì|ßÅ’Š^ÔååùG‰@ÐìÕ™ÙÃÁ©#o<“>…Ìîáû‰ñQ4pöÕòå±ô7¥¢Õ¬ã‹„¹¹8Ž…ïXfÎbxCŒÅªÁ`0 †Ÿ·5»·V ”Hÿ‘j“Z‹uNgbè¦Yç#:Ø¢.^CO¯á'kßÕ<Øô 2Íú ö1‰ÖÞ¯ý•ÒBJ‰2a48¢Ò KHF‹ãTò#QŸÉâ6¤´p-!ûƒñ™Ï~†o~í¯8pï#üë7ÿv P>ДՂ‡ïY¦um!,Ëâãaï›_ûKÞ{‚ïýÓ—‡‡M¥è‘ñl„ÈrdûýØÒ¦¶ÙVž¡šÙÜçstãùX* qð¢~ËÍ “4îWndÒ4 û!l´Ž·Ly]Çåð]¼ðòYêµU¼lÚÒ<;¶R­VÈ8‚Êömô ´Ž‘¶ŠûXN7›ÿù•ÓuÙ1=Öš‹ dóUÚ­5r®#)çÇBÉ #³ûÈNÇf­5^¾´iÊ›!…¤R)s`œ<}™À«$!IÐfçÜ2¾GÎw(æÂD³wüŽthM¦+³”3Õ;R.Û¶™Ek8}qL¾J¯ÛÆ s;wà86¥œ‹ïš9‹Á`0 ƒá綉”Bš­W¯^¡^[¡Ù¨‘ÉHâä5û¾6&¾~Íw:•%%«+Ëd²9\/C·×E¬3תfG_1"%ûØÇxêÓOñí¯‘N<Áñ‡4åDz,>ññóé§žâ[_û"'Þû$ï¹ÿÁ %@ÆÍ’qÓ¸¢cLlúóùä§>Å·¾öE~ï“Üÿƒ©@Yôð x'¦MåîBDÚço1ë1×u9rp7?~á,—¯¾Êž¹mŒŒ’q- 9)|üByS”svÇ$J'œ:wñ±Qf¦§7”Ò²ÉU'ÈU'¶|‹’BR­”9¸~üÂY´°Ø½{çP ,äRK4×ò˜,¦˜#ù±;?ѳm¦&FQ*á§/Ÿ£X¬0·sÖ”ƒÁ`0 †MÇm)Çå±ã÷RkvÈÚ%¶•RÝüÖeݸáæoïGïÙŸº Øvð Þ´8*…ä‰'ž j.òÐÁíÛ¥š³@¹•ÑŠ°Ûâþð,Ÿ{‘¤4‡’•¼Mf‹.⤔<ù¡ò÷_ù|à(–eSÊ[xŽi§ƒF£U¼åÊm;6ñŠ'­Ü‡çhŠ9ççšÕøÍà:.{vî`|lŒ –XÖFò݈’Ñj…G¡ÑPÚ ”ïdíØ¶Í¶©2~nœ8®â¹…¬…gJƒÁ`0 ÃfZëÜ΃MOog›†n?Ù"§?H?Ao¹2'I+«ÅRðf܇(æ¦7mcÝ—CG]¤_Á)ŽãJEš2À°…W–8ùÝÚn¡šŠÐ:Ù²§£´¦ÕoÐì×ém~|å_©fG™™ÙtWƒá-uU8V™jî,+@ŠÍ_^Û’w]=I)6…+u¢cZA“•ΫݚýE¿ÄDi [Úæ†2 ƒÁ`0lÌìôm`'‘Åq2G„(·úª?[ª’=r­I{+Wi!ÄÖ\\[ÒâÀä=â —ýyÞ¿ÿ—H#P [}ì‘Y¶W…BïÔ†LÎÃÍð,]cû˜ÙM¢CÀ¾“1Ç`0 ƒÁ°©æ¼M´BÇ¡¹ï Djòƒ"ºô#tlYr ßÉ` ‰R‰Y” ëïxaoIÑ^£Q:DéÈT¢áM´s‰k¹Ø2!ޝàˆÈŒƒÁ`0 †M‰±¤¼Eúíúà úÈlÑ\w×’nË‹“7¢IÐZoÙúÀXîÌn.‚á®A£HT€ÚÂaL ƒÁ`0 ïnŒHy DýW~ò]j" ®žú)Z%'vPœ˜6Ȱ©HT­c¸†cç` 3:Q½U@¢“a9¦B ·¯}¡Q[0»·ÁpëaÞ`0 ƒÁ°y1îÞ·²°ÕŠLy” Õ! »-úÍš™û6_[%¡Õ;G» ËÏn¹Ò«nÎ×þoºßø/è°k*Ô`0 ƒÁ`0 †w)·Ý’Rk}=Æ×î¥ïˆˆ÷z?ªo¹@n&ǶCfÇ8µðæî{ a{Æ%Õ°éX³{ñì2Û+¿ÄÖRÒ2_Å=ô?€ÈLÉTè›$Iâ4d­ÞØÍÿÎu[)Ò,óB¼ûB( ƒÁ`0 ƒáörÛDJ¥ßùî÷Ò¦ýår¥5¤ÿ­cã¶Tˈ†ZoØ÷ºÎ©7hž÷Ñ·ëÔoýŽzÃOk„Ôk«ds9¤´Éú’÷½÷Þ¬ˆÓjµxú©§£ˆ¯}ýë<ùá_5­É°éhµZ|æégˆ"‹|wž'ž8²¥Êÿï}Ÿ¿ûÊe,Ëâÿ<Ú¢P(˜J}º½.ßÿÁóX¶C¯Û# Ê• Jéagª×õ«zCy½SÖëúP}ÃçëûdµþûzãþaاÛMÇ$‰¸ÿè¶MM™J2 ƒÁ`0 ÃM¹m"eE$Úâðác,..°²´ÌÞ‡‰ãx°ÖƒÅñú…ò@x,ˆõº¿këe­×/~õÍ·­ÿ©åŽ^·˜¾Ù÷¤´X¬ý„Ñò Ù|«çOÒí…d|ïgZµZ->õ©OqøÈQ&gòͯÿ ØO~èC¦E6 ­V‹O~ò“:|/Ûwæ›_ÿk„|àî“$ Qáûþ+ŽÓ¸}¶moØfYÖM³#+­7±œëöºd3Y”V Óßw‡v» @>Ÿîûï|‡oûÛ|ðW~‡«—Ïó'òÿòŸÿóÿ2*µÖôz=²ÙìMˬµ¦ßïÓl5©Žl(ûZŸ¥µÆuÝ›~?I,ËBi…@Ðn·‘R’Ëå6ik’Xá¸ö8ÌÒâ"­f“]{öëo­_Ôëúãáûuý¤Bƒº±ï¼ñ{×_+­Ñêz?¯44M5ÏØô~V—X­·Ÿ˜Ä–›ÄšWrKf÷6 ƒÁ`0 †w#·×Ý[’$]¬jJk½Î4‡ë£b°HÔCáP1øL-|„H5ø``ç˜Z]^w-× EjˆIhS \ A ´F ЃßB`ÛR ¤$–ê}¶»Ø–xCáçSŸúÓ3³ì=üÅR•ÿúïówý9К'Ÿ|€F£mÛCa$Q ¾ç#¥Ü à(¥R®oõk>»QøYM„t{]|ßG hµ[ø¾ë¸¦eßå¬ ”Û§ç8|ì™|žýêïòÕ/?ƒÖðÄ@iŹóç9}ê»wï&I„”¬®¬àù>*Ip]—F£AEØŽƒë8ìÚµ‹ 8á¾çáû>A`Û6–eÑívñ<Ý»wóÒK/Q­V‰¢ˆv»M«Õ¢\.ïÏó( ÄqÌ}÷ݤ巾õ-N¼÷—˜žÝŶéYT¢†Be>Ÿguu•oûÛìß¿­5qÓjµp\8ŽƒÖšk×®±}ûvâ8Æ÷}”RDQD½^GA¡PÀó<,Ë"“É0??ëº$Iš}í>ÌçóA0,ãfEQœ$ŠDk’D£”^g5™öÍ úB­Tj9xУÖ­õËkýv*]®™Y"¥$QIúA²Î¾]Bú¯t{³Ó …Œµi®•Œ#ƒÁ`0 ƒÁ`x犔ÍV“ŒŸÁqn-{®Ä>‹cEœ(¥ˆcE’¨áÊùº#· Ói#… V ž—ŠlabY6–e#é1¢×óФe…)‘ÒÚ賨5Zi´RHËB«„0Œ°,{ƒ5Ðõ…¸Z­!…û3…Ÿ5r÷¡°ÜÝ^€°}žø•ßåÿö/xòÉ'9wî…B3gÎ`Û6ý~Ÿr¹<׬²”RÜ{ï½4›M.]ºÄîÝ»BpéÒ¥ÔúIlË"—ËÑívQJ ÅÙ5ë¨ 2µz衇pKF¤¼›¹.PβÿÞ‡ µMØê#,ïÿðïð¿ÿ< yÿûßODT«£\»6O&“%Žcæ¯-"¤`rr‚N»N­V§R-õZƒíÛghµ:ø^Ë’\¸pÛvرc¯œyǵ™›ÛI»Ýeii9íâ„f«ïgX^Z!*#Uº.v™Ó”JU (ÿù[ßâ‘÷þÕ‰¬6{H‡ïû”ÖüÉŸü üÇL»Óerûv^}õÅr™0ŒX^YÂ…bžb¾€\?C¢AX«µ:I¢ˆâ(íc¢aÙ\½¶€ï{Š–W븎íØDaL&›! ºŒŽO°}zfÓ׿RÇš8Ѩ$íƒ Lûb­è®ëZkJå rM¸D¥‹­ú!q!¤…ã:!ÑBöõ:ùBÇõèõ:ø~6M$é!½ÎZ~“’Н‰é4 ƒágEQáØÎ-¯ ƒÁ`0~6@·Ûå¿þ<ôðClß¶ý––(M¬±Ò×_¯‰”ëW…Bó£~¥5™L•$ÌíÚÃK'_@ I©\! ¶mßÁüµ+(¥°, Ëqh·ZDaH¡X" £Ô 2QØŽŠaˆe;$IL6›cÏþÃ$q¼1^šÖh¹>¶š@“Pï=Çü…¯°{âøÎDj¥y]Wå¿}òÏØ»ï03»ï%“+ðãÓ‹¨«ã®me>ð«¿Ï·¾þWt»=~ø!._¾Ììì,–eQ«Õ(—Ë(¥èv»DQ„ëºüÿì½Y”×yçù»7¶Œ\kßU(,Á’HJ")J2¥–%ÛíEiÆj·ÝmÍ9ý0/3=óÐgæœyôé‡omµä¶Ô²¬–7¹Û¶ÚÖ.‘ÖBÑw€ÄŽÚ·Ü—ˆ{ïž?½J½ÅŠ©‘<Çî|7®ððûüo¿ùI&z&ˆ£ám^T*e¼ L…)hÔ{ð|×qˆ¢)J\ÇAkŲ!„`tlˆ£½8®‹Žu'ë"Ú\×Eš2ªX~ ½#Àñq2½pÕ Éˆî8¬Tò€(Ö†z£É“Oü¨íY ™\£ ËK Ôj zz{0ÚÎdp‡8ND\€r©DEO6×K·ŽK¡ÐÃsÏü”‰éýTÊ%ª•~"•ÊÐhÔ9xøöV‘&‹Åb±¼ÆNŸ>Íêê*sss ØF±X,‹ÅrMp! Û+ ÄQü–v¦Mâ½Ó5Uj—ºÑš|¡—¥ÅyÂ0M_ÿƆGƹpþ KK‹¸Ž‹KÂëŽã²xú4™l–ÍuŠÅýƒ”J–ça`p„µÕU67×Éå zúÑJ'E#x=4)Ö¿A9z‚Áü}(]Å‘A;ÇZ"®½u„ÿàŸ˜8pœ8ÖH)ÐíókEŠÅ³/Òj4( ŒÑ?0ˆ”’ááá7h3M«Ùbßô4gg8xð ÜQ)=Žc–––èïïßF0ÛÞÎb¸ýŽÛyì±dzî8 ñ]‰àHI+.ž=A³ÑàÈñifgò8ÒÝ&ÒÕ–´Ö;d¦vi«íº}÷=^e™7Xk=M¥qŽ‹›ORpâÇß+³0á±)2¡GOÖga½Jq•Ó'ŸelhÆò)|ß#2;…”ä˜F ]Oöî 5C l%Œ0‰÷`ûˆ†3IXr¼vv„.'GÝYW¿ÕÎQ1ª¼D0ûnœüÈ5é¥ ‘Ò(£QÊÅ1Òq ÓYŒµ•UFÇ'éídÿL?‹‹ó‰`Yo$aîZ×óÑÚà¸.Q¤ÙX_CÃÐð0ÉôþYšÍËË‹¤‚ÍÍ R©&Ù\!$šØÞŒ‹ÅrƒJ¥‚À¦È°X,‹ÅrMq;÷¼ç=¯(,ñfI u;äÛ bõ OÊÎÜfjß ûg¡â×óC&W`bú@ÒM’³r®Ð×®ne`h¨F(ÚžHq¬ŽÄ˜ÜwH<ÄDñåÊA–é¾ÿ‡lvžÌ4ÅFƒõê ™A\Ç£7xôý÷’ò¾ÅßüÅçy߇?ÎÌxOòýJsêŧ8ùÜO¸û]rä–ã<þç.°¾¾N£Ñ ŽcZ­BÇÁ´½Hh4lll µ¦Õj‘Ëå¨V«(¥ˆ•"ð}r¹¥R‰|>ÿ†EN,77=ø*Öü÷?û<|äãÝ×1‰wó©ÿ‰“Ïþ„ûüGŽ#x”ãy¤p)¤zÐ& ȧ²×õ˜cU¦”L0Á=ÇÖùýßÿb¥9~ç}(¥|z­Ê7¿öeÆ&öñþ~˜f:ÄD4‹«„=4+eÒ=ý€ •ÍíJ?>·ˆ.>:ºV߀ÑÉø›„|k\×çØñ;QZ£µfdl)]‡FRÒÓ×ÏÜ¡[0”NÆKGº“xÔJÇ香@ˆ$äÛ@ßÀ0*Ž™:0‡2y˜C§àK5®Ø›Ñb±Xn„LLN011aä-‹Åb±\SºªäÕÈ/£tb«¶ «W ÷&*×KŠÜ¸^â¹c:^U)Ýîz‰dRÆðÿíOxðÑ_&“Ío ”ï|Ç߆#%ƒ}9굕J…Z­F?Q±´´D6›ellŒR©D:f||œ—^z‰ .°²²B©Þ=84D©TÄu\¦§§ÚQýØby-câ‘GÞ‡Áð÷_ý"}èã¤3YN½øä–@yø(RjRá¹å—‰U„#=–Ëó eGy×Ì{º®Ë@ääp¤jw__ÿê_ý&¿ÿÿ¥5·Üö.šõ*ßi ”¼ÿQ|Ï!ãjjë«lœ{‘•“Oâ¦Ò,Ö«é<Ó÷<Œ—JïÂÞIDÄkiå)m’|¾moö(Ö(µõ°Æq É:¦=ö&…È@ˆdüìÚ‘Ž›x 'É;l É&I…!$NÇ‹UH„1HÏyEú€Ý{¯8X‹Ûb±XÞ)¤.-‹Åb±\{mચß´‘h“xÚhd§lÇ>ßzéü×)ýmÝ;¦]Ù»½z"XŠmæöå7w¬ŽLr;:ŽÓ wM¾_’Ñ£… šªÁþÁƒ€ ôBzè!¾õ·ÊôÜqΞ|¦-PÞŽ#¡'ã2tdŽF# ŸìäÔìV vd·ªl§ÎÌÌ 333;Œ{¥UâÝj¶ÎU;C´¼1BÞÿÈ#€à›ó'LÏÝÆÙ?Ý(èÏ8Žàèèm¸ŽK­Yåðè-¸Â»®å«ÑßßÏ¿n •q¬¹xæÅ-2ðÈgôÐC4 þñ?äïùŽßz+Ž„¾| ßKNXvGˆBt—;_ºì8ÎÖ1v–­.i¹¡ò} ?þÜÿУ=r!Òu’k±&i 2þîòÒí•ÿá?ü OðÈ>„ï»2a ]^ÞÔ‚ä«Q.­ñòIE¹¼I½^GÅQ×[}ûÈj^e€Ýþg’rƒ+Î?V¯U“ß ^+1»—VFßÃùÕ’‡j‹Åb±X,‹ÅrcpÕDJ×óyÿƒïd£Te³”T NŒÜ+5¯½279zoÛAÈšGJçMÙ«GåÜs?掩Æué˺]Òby»1ZQ]_áý<Ì=G&i…ã±S Üíô÷÷111Äí÷#„ä3‚”ïØÎ} ²Ù |ø>6K56+­nõô®«¹yãaV 0hê­çi¨—è Ã[È¡i Ò™$›Í¡”lÿ½UßÍ’ ÆlcX,‹Åb±X,–†«îÝÛÛK¡§—FK!„@kƒÜÍáÉb+¼Àh“äW»Lte³q–ðÅ/“yôßáJëòhÙ-êå" ÏÿÇõŽ‹Öç1Æ™;N¶d—½aµ¼Ìùõ3´”G²Ö8Io~Űö IDAT+r½Î&$ù|žL6Ï@”x±'EÆÞÜØ«2/ÌÿâÖ Œý<)ÿÊŰÎ÷cð;F¾Õû¢Ö¬òüÂÓÒ½äƒKÏ3¢7ÝoÈb±X,‹Åb±ìiÜ«½C) Ü,"‚@æGñ'ïÂ}ãDmËu½6×%?ßr¹Ìç>ûYZQÄ_ýõßñsÿü—öTÇk£y饗9w~0²0?ÏÀà®+·úê’~ê6iûóím.òFŸ®ÁéŸ$Ûw¶ÙÑß—öÿVŸ¬./‘+ôàºi>ðð¶bº…ÇÿΔX8_å–™Ò›vÕ=§5ŸÿÓ?çÅØ¿/à×gß³kÅøX)Ξ;ËÊú<÷ÜÞ‡ãÜxN÷J)Μ;ÇÊúwßö@7àž8vmXZ¨²°¤é¹­…ç%^ ‘«#tu„E!E7er½Vg³¸ÉÀÀ½½½c¹¬k±+T¾‰yÁÒò «k:x€T*uSŒ[õzÓg/ |ìŸâò !n¸¼¯‹Åb±X,Ë•pÕ¬2¥A*ÃÑcw²¼¼ÈÚÚ‡%Ž£®0˜ˆWáÊ´Å0^)zm[o»@ÖYÇlÛv«ºæ%Ûl_¿³ïmÛJG²Yn286ƒ—J±xö9êˆTཡa¹\æ3Ÿù ÇŽßÎÈô¾ý?þ ñW_åcýÙî:µzååe&'&q' £s¤´¢žëÇq×»¢^¯S*—º> D±bßÌ==}D±`öྠ·U,½´]»â¥­»²1Ѻ+ëK·7ìè³-¯Mƒ6‚ZÓ086I*L³tá$åj“l&µçŠYX®=ößýÎwùàG~™…‹çùßý]þ×Oº+Tj£)néí}uË(Š’‚:žëa0øÞk‡ôj£©”+¤ÂÔk®gŒ¡Ñh ”"“ÉÐh4p\Ïõˆâˆ _!øh­ùâ¿HµÖàcÿM~ð¯ñ¹ÏýŸúÔ¯%Ìfsc“f³ÉÐÐΛ(BeŒ!Š"|ßïžs¥R¡Õj]QQ ¥/.°²!ðÃYž~ö%ŽíŠxQQ.—ñ<¥¾ï#„è1ÆÐl5I‡i”R”Ëezz¶r=vÆ¿NØl­V£V«100pÝîw¥..vÏñ™çN¶Ï1ñl4¬®®†!©TŠÍÍMêõ:Ùl–\.÷¶z»i­™Ÿ_b~¹I*=ËÓϿı#³ø^â1¹¸¸ÈOõkDQÄÓO?Í… Ãu]Ç!“Í$9èµÕÕnAŽT*ÅàÐ 'Nœ$h‹„­V )%®ëÒÛÛK¥R¡§§çM žJ)Î_œgy½ÁàÈ*Ö‹š§ž=Áí·Ì!ÉÆÆßÿþ÷Ù¿?gÏÅ÷|¤”¤R)Â0DÁúú:ÇŽ£§§‡ååejµ/ž8A: ‰ã­u7Gb?Õj•BOáuEä«E"P.°´Vchd„Xi67O={’Ûn9ˆ”kkk|ÿûß'æææØØØèn[.—9xðàÛr_h­¹8¿Èür‘¡‘q”Ö”K†Ÿ>s‚ÛŽÂqüöïIÝ*ÕëÙu]²Ù,CCCär¹k& wÊùå2}C£hm¨TÏŸ8ѹ}~ÀÂü?þ8½½½LLL°¸¸ˆã8ô÷÷S«Õèíë£V«qàÀ=3nuÊÈx õÐlD¬×1§Ï2{`¬·¤Åb±X,‹Åòº¸±h~až|.O.—»¢‰vÊ8ÖÄJ£tû5Öm¡ëUB¸Ûb¥‚(jQ«Õˆ¢ H¥ˆ¢ˆj¥ÂðèBH*å^ µ!ŠZ8ÒÁäzŠc›úõÅÉŽç¥Þ¶Ü9~G¦ˆu_¾zî¨íå#w€›a½T£Áƒ?ó+|óo¿„~þc%ŸÏsÇw°²²B³Ùdbb‚õõu¢(ê‡a*¤Q¯ÓÛÓCOOCCC×U Ä@¬ Jib¼J¥0&1¤õf³-Ât†z½Žç%Þ8Éû‚z#)¶à©v& j”!Š[8Òmç¾Ô(mRiŒŠ·yŠDdêxÖJ‰pt­ÙüÛcØ9âF q•.HgOjG ¼ÿÁG) L²¸VƘ½å(cøßù]>ý[¿EÔÒ>t”Õµu²™4ÚhZME£Y%¦qd@¥V%fÂ!ŠFI´(eÈç{i64š1*V-è0?¿@>ßK¥\#Š4•JVSÏKS«VÉd³¸ŽKµ^#f!Ñ:BcHÊr•w¾÷QpCV6êh­¹ç½á‡ßþ*ŸýÜñ?òŒŽORè`}m…$nÅ´ŠG²Yª/ä1Ò¥ÖˆðS!ÚZ‘BHçùh#ðýJi‚t†ÑñÉ7(ÁÄM„—JÊ ó,¯×Éö RkDTk£O>ó"·;L*“eúÀ ùBãêõ­fƒfK‘Ê8!˜D3fgg¹¸¸D³¥ð|0BbhီŸbv|òÚ ”Æ`â:ÂKwÊŵ*½ýÃl–4"E6¡\VüÓ3'¸íØ™\ž»ï}ÙlŽ—Obtbß(äs×7,ÜLÜ@xaW ¼¸\¤w`”j£E­kA†ç^<ÅÑC฾7­Ñ˜¸…ðR;Êlï fL³¥ˆ´ "˳/œáèÜ4½½ýÜ{Ï;Éær,/-388Œ1ÐSècdxŒ|>ëíæ1Ø MòPOJ¿-P^¤¹øé åj“Z#F‘fa­Œ1g98³ïm>fË•P­V©Õjd²™=çál±X,‹eï L?þ8`ddäŠvÔj5ùîãO2sèVÖVWØX_ãàÜabw1³Óö¢#JGòä?baþ"IŽÈT‚r¹D._ R©P*Éær¨8¦ÑlàûõZt&‹ã¸Lw` ñø{ q²ãaé8/<÷S¦öÍ!çN=Áì-¨ÅßàÐè¿Ás{v0ð™ßÿ+feræz{{yêä±28R2Г"pà[_û cCüO¿úñî÷u¼U´ÑH‘„v ’»íŸ_O´Ö<ûü‹Ä"C¡§‡çŸ{†™™ƒx~¢8æ±ï~»]lÁP­–¹ëžwpâùhÅMúúQqÌÌÁC<ûÌO¢ÕlÒŠbêÕ a&K¹\"ÎR*màyz 9rìvÂ0nWzùå'LgY>ùCîrž%œÿéû~ ™îãqMíí˜èü“Iõe/Üûw¹VD~‚7y2ØÝEþþñ'9y~•»øcc“œ8·F³¥q$dÓ>ùLÀ‹Ï<Á‰gÀèhoûéÈÎkC)…â•¡©‚n^¾7ºœŒ14šMßßÚ¸ÜËPÓŠ‹DªB½’ãàÁ[™=zŽŸáìÂBbeèɤS?þÞ×Èx¿úè}É—èŽOxÇ—<ð;Å­’cIrØ%!Ó…Þ¶®scŠÁ ‹‹ÔøŸpˆå¾{X«¹ôôðÜ™u­)ß'ð$Ã}YÊ¥MB½É­!®Óö|ﲺû JkƒãÈ­"\íÿ’ÐÛR=œk˜{Ö`Л©ÿð³8‡?Ìjß½¬T]ú‡Ù,7YZ¯¢µar(ÒšJ¹LJ¯s|"ëH0†8ŽaÒ˜ë}ã¢Ê«4~ôYä¾÷²1üóeèe£Tçä…MFz3TSCYÊ•Y³É‘±OŠëz¼jógþ1|ÅÑw³Xó)ô R©µ¨6"ŒFS1ØR«Vñ:¤B'y¸©ŽtÐZá8Îõoê+9gÓd£òÖ«O0”ù(åõ}Ä"ëgyþì F'÷l&ôÈÔ* šLL¾}¹•®ÑTëôgî&ðúì ø*oœG×6pû¦‘aá†>×ååeVWWb``àªìóË_þò+Þ»ÿþûí…e±X,ËâìٳݴRaAàû>žçu£;i¦’‚Û1qS*•^±?7±wcccW,PvM*cˆµ!Ö[ž”±ÚYåæÕ„ÊX+rù­V„ëùH)pt&ËÀð(ÎE)ÅÈè8¥â&Q¬Èf“¼tQ¬h4 Œheº¹·ç«¼ô»w:ç ŠH-ÑRĪ‚^·â4m©àøíÓüèÏ04~”XéĈ†\è‘ }N<÷$­f¾¡iš‘"ðœ¤lãr›Qþvç\LúH£µ!V¡ÏWkú†h4ê“x«*Óf8{æ4õz Rk4èbc}R±" ¯m6êÔ rÙåJ ¥4aèáøŠV³µ#_å+Ú@LjÖ¦QB×7¹þž”wø&nAܺ† ƒ;r4…š•]rHm—[!Úž·É=qÏÜ$O½x–s§_fhxœtÊ£/ïPkÄdÓ>Õj…—_|Šá±qn¿g””'Ûƒ£»)#ôVõ¦+F:2Ñßä~´‰Ù¬=M±6O ä¿óSú†¦Û‡‚z+¦Ȧ=V–.²xñ ÷ÞvŒf¹„ç&¢ŸpœÎB"þiÝͻի)kç{â’÷^»4¦UÂ46QÕ5âL m\´lè’K{ÄJSÈIŠ!Y߬RÎ4)dÜߺ혥ôG'ĥǼ}Ö×ô:ÓèfSßD×Ö‰²-4ªA$ð\Ò©¤5‰—çúfRºNO.$¡LÔJ~C´¾®÷­i–Ñ•U(/Ñ*Ô0"×~È&é/¤PÆÐŸ’ß0#Ø(V)§ä3Žã¶‹æÈd_Ú\3árG·šhã·çšb¥I&ôèÉ&ïi#¨Ö¬kô»~·`L;è­.g„l«ÔNArýÔM­›ÄªB¤6‰â"±Š1Nrd…t@µ‘MùdB/‰Q‚•"½ƒ)R~’ŸÚ`:^q_ ¢¸D+^lQ:Ë›'¦¡P(ØÆ°X,‹ÅrÍèZšûöí» “vˆã$Ä;V‰è¥”¾Ä.ÚÊO¸Ýhœžabj¥â®Õ!„À 8t´—hYBŠv†dÝ 6IUÚWä½¼ cPŠS}ÿ;…Ü¿& P¬W¸°yŽáܾPmVxäá»È¤¾Ï7¿öîßǘFµ¿ïÄsOrò¹Ÿp÷;ßËñã·±Vl2ÜâÈ݃*R¥A©D`–*)jƒt˜;r ­4ÚlµµFƧPQŒiWýýCLï'é»¶ù˜äø«‘ËP±!Û^2nÛÓM¢_Õà7Äá úžÿ›œ[$è¶U¾o0ŒÑ¬œ>Ž[øa­cü0 ÒapjˆOOÝÎïþÞï¡´âŽ{ßK)ÜŒCµZáÛ÷eÆ'÷óþ~˜ÀÈg4/­ž$Ÿ*Oå©¶jdü …0÷6ž¡&V×ɰìEþäK_âïý0SSû‰ÚjÌÒâÿÆW¹÷¾¹ëžwÒp%ây¢zßÍ ÁOeŽK¶èÚHõFÌ>ŒÌôc^>}žåå%F†PqLâ”n(—+´jë9~: ‘y¯}[ª¨Åâɧ2=h­®‹ç‡øé,an³F“š{™é#Lj3çYZZ¤·ˆÁ‘ŒÚP­ThV×9tô‹‹gPé,žŽããú)Ü E:ß{ÝÝ?pNv€œRˆ³ç™_œ§o`„±þ J'â\µVCEº•J³B½¶JO?Q«…„8žOºÐÿ¦ò“¾¹Ã¼“Ôá÷#ÃÙ¨…¸¸ÄÅåE }CŒæºÅÔjÕê&³ûçè)ô’\‚+ˆò¯4ªœÛ8C_ºŸÀKÑŒšäRy2Áõô|7ôåîaÖü:®“¥ÖWãÄËç©VcÆ (£Ûs’Rq“Ð3ìß÷Šåʲ© ?GK·ðŸtÏ5?âf´Êzõ§ Ë›%ŸËÛF°X,‹År͹ª ŸT''¥6Ér[¤L¦ó;þÛš"wÂÀ;ë™­÷“„xûçj[%pÝ]x‹Ónƒ6-Rþ ¥Æ:Ë¥óT›lÖרµj¼ïð‡ºa(ßúú_òŽ÷þ,ýƒÃœxî']ò¶ã·¡1ôæ‚]/P Ji¢NQ¥‰¥îÕnÑöDí´»ÞÑæZ«¶çêVá#éxds…D¤& ›ì“‰ç¤yƒ‹qúGmªQ¦¸x!]¼TŠúæ¹á)ò}ƒ >ý[¿Åïþîï¡´áøï¡Z-wÊG>ð(®+É¥±n²VY ÚØäL\§Xßàðð­ÂÃoã J\'ÛýëÐáCüʯü _úÒ—¸ëGŸÜ¿C ¼ó®{p„&HŠå…3Dõa¡—zqÜÐ$™ž¾k“#UHd&G\×efÿ$úÔ9–éé@C¥\¡YÛàÐÁYüÀ#€»í¹Q1q­Lyþ4ÂóAkTÔdèàí»C¤™éëžã}“h}ŽùåmçØ(Îâ ƒoR:õn*ƒÖ1Q³ÁÐ̱ë/R ‰“MÂ*Çaßô$ÆœçüÒ<=}Chc¨ÕêÔJËž;ˆï9èFúÆ< K/“ÊäiT6 ²=ŒÝòœ\Ï5:LÑuõ=Ÿ‰ñ$¿ä¹ÅEò½Ch Þ(÷O‘ÏeIùßëøA^>Úhj­2k•* *Í2±Ž86v™`òzv®LuÿJ§Óœ™ä…—α¹©Éds´bEµ´IàjöMO⹠ݥâ2¥† 5¨EUô¤÷:ˆ”Éð«°X,‹Åb±Xv+WÕê5Æ ÛagIÉéPtÖcç{f§pÙ}æ—}±½þôÈŽ‹”)œm…ŒÑ $C¹a2ƒÄ:îFÙTâÕ*¿ýUF§pñÌ ‰@yÛmhmè/„Áî/º¢n{C ´i¿"’V½4¥™Ø™TÔ´ßÛQé’¾IÚù=w)$Žãâ¸îVø·Ñذ´!%ƒ³·Ò;5‡ìä.4ík¥Ý÷…BO:*£VÌÒÅS]Òó\z²>)ßAë wM¿Wz4£®ãâ9þ®;çÃm¡òO¾ô%w=È3O|kK t½YÏsèßw„ÂèþNõ)$ãÔu*âäº.LaÌ9.¬,á!ÍÚ&‡Î¤ò¡K&ôvlã)ÆŽ½ 7Ž‹Q‰ç´ë»òús]—ÙSÎqni‰ •©T@6%¾ã¾öùxƒ”¸ÞÛ>®ã°zcÎqza‰T:G½¼ÂÜÌ a* º„=ˆÇÇÛ]’“ÃàÔÅ%¼T–¸Ö(s¤S.ÙÐãJ²H!éËôs×ô»Rv‹³ùîÛß?™tšÃ³S<â뛣I¹šééI|Ï¥õñœ€Lp7B ¢8‘îT¤Íb±X,‹Åby+6ÏÕÚ‘#%õZ‰—O4÷š%$Åplï™ÚcÏrn~•ÇæH¥r;Î1Ü¥Çîp`"²ž:»ÈÜÜAÂLH&L„¿ä:zû…zßó™šFG N:ÅÌ‘[Éç²oI Üúíò’ß* åî®~ʤÓžçÙgž¡¥=¦÷Áw%…¬OоÏC?½+Ýb±X,‹ÅbyÛí«µ#ÇõøÙG¦X®³^j"¥@k³«£uo?6×-ªãù~RÌåMlpnާ~Äì‘"RøôäÙ3¥”’£G±oj’¥Ço™ãí,©*Žîö…Û®¨llÚ¬›žB¡À¿ý·ÿÕzL¥QÈl ”{ c4çfx÷wc”K>ë๻Ï[Øu]Žžeÿ¾˜R="›zurOÿø¹.GͰzzÏ£ë8ÌÍîgzr’b-&ôeW ÜMøžÇÌX¡xž¸'ïÉK+o IDAT·,Pîö{\G-ÂÀåÎ#û©¶@‡)2$ðìƒ7‹Åb±X,‹å m«jøý}¹\'—áÞH)Ø=NΛ°žbU£Ö¼Àrå§ì~žëï©Î—B’ÍeñRén%ôÝÒÆ\Çu–„Lè’ $ŽÜ›áÿÚh‹óœZ=ÀJu‘J³Ä‘ô1<2»ò˜¦\|ßÙõùußú9î½kK©ÀÅóvqÿ´S9„)/ç#7¬@ ЪUX>ù:Šž—TbwÏ z ÆÜØ'o±X,‹Åb±\®ºÛŸìYO§7m$ Aè25ðŽÔ{ö<Ïæ}´ì~öª@ ts$dƒ$¯íÅͳ„~ˆØ9W› õÂ^¾¶öDÿnŠÒqñÃ,ÕÆ2‚f£J˜ï³¥Åb±X,‹ÅrØlíoÉ8 q}™»2eÄb±¼*RJF ãŒÆø2Á»gßã„;òàZ,7â’×/•føÐíè8†¨†A SY{X,‹Åb±X,—k;Û&x‹ƒ1‘m‹Åòº$Uë“Tè¢(-74Q£Neu-Tn­5Æhnüdá#ÔÆ9ti!$ÂÞë‹Åb±X,Ëea=)¯Z«J#ªã8iB ¥ŽtlÃX,;ôZnjŒVÔ6WXxî8n€ôS˜~ŠfLw_—Ž!pþÜiGŽƒ/|äÑ÷q¹ i¹\泟ý,Qñ•¯|_þÅ_J¬ ‹Åby´Ö|áó À_~é,¿ù-<Ï· c¹±ÄÞÜêõ:/:ÍêZ×õX[]¡·¿Ïó1Ú ·Ï[´AoMuÀÌ¡ëóä‰î\Å´'&íŒ1c¨×j”Ëeú‘Ä››bæÀ~{íX,‹Åb±Xn:®šH©µ&“-0wä–—–Y[[aöÐ-Äq̱;9ßw ‹¦;Éßú×~Τ~û~^)VvÖ1—“Û¿S:¥JÑÉü Åüég)W[dÓ~» ïkS.—ùÌg>ÃÑ[nezîv¾þ·Η¿òüÒ?ÿ¹®P©fiq‰ÑÑQ”R¬¬¬P(‚T+U‚ Àu]¤”T*V×Vñ=Ÿ±±1{eZ,7Zk¾øÅ/R«7ø¹ÿ?üÞ×ùÌúÿò×?…çùh£ÙÜØ¤V«‘N§‰ãƒ¡¿¯Ÿ8ޑޤR®Éd‚m4A½^Çõ\T¬p]—r¹LµZe|bÜV·XÞ"ƒçLï?HxAÈøø$~*À¨D”ìÌ-tÛÅÒhP:™|hÀ(´I¼0uòô­“¹‰Ò†riom•‰É}TJTê1­Hã{ö¶X,‹Åb±Ü\\Õpo¥FD«EŠV«Õ)·yF^âõˆ ®µAwTËöä¿3‘ïxD !¶Ö3„ÀèÄA‘|‡ÖÛÄPvxqšî¾5JÅh¥hÅšb5"x=ŸŽ@96>ÉÑ;î#“Éñ‘Ÿÿ$ýg¼C¨\[]ãë_ÿ:sss!8þ<étš|>O±X$ C\×euu)%A02:`EJ‹å¢#P–+5ÞõÞŸ!_èãáþ<ÿðw_á?ó9~ã_~ œsæ ÃÃäÓW–'MˆÄS VšXëäUTÛ‹ ªÝ™ÔwÊV£I±T¤Q¯“Íæp\Ý¥”¤Â0Ém)”R¬¯­Íåñü€jµŠëz¸®‡t$åRé:¤Ré®Ù‘=·{en ã×G•–qòð*^HÛÊ#·½‹j˥ܨÅš‡>ô+|ão¾ÄŸþ×?ç—ñçQJñÀpþüyr¹³³³„aÈææ&ccc„aÈúú:ccch­ ‚€±Ñ12ÙŒ½*-–„-²Ê;ÞýAŒ“a~¥„”‚;ø0?þÎã?ó9~ý×?ÅÄô>FÆ'‘Bfó•J™0Æu†FÉdÒ)%›É¢´"Žb\ÏA)M®ÐËÀà ŽcJË.b¥B1*´ª`|ŒtQZ!•AÒ†(Ž)—ËÔku´Ñd2Y”64êuüÀÇõ0G›Å"žçS(ô"$(e’û6V4MÒ™ì¶6í9‰°Ùc,»r¹L­^#ŸË†¡m‹Åb±X,×’|’?þ8÷Ü{/gg¯xgJ'"e2 ßZN¦ßíÉÿ–.ˆtO?ýS.œ?ËÄÔ>æçé¢ÕlaŒæìÙÓôõöS©”ñƒÒqXYZ$ÌdÈdrT«<×Ãq]ªÕ*z Ï8rËq‚Tmô%aà[ËŽÜi@‰Vñíÿ—òùoùÀ¿C¦û¶›,üÇ?ùûÌràøýd²^~i…j#¢ÖˆÙ?šç?û ¾õµ?ãþø¿ðkÿË'Ø·oŸ½Ê,–›”Ï}îszú8zÇ» ³N]Ü@)ÃòFžù?úþ?ðïû·ȧ.S™h» ¿ÖgæêûF©Ê¿øÕ_ úˆíHË•!¯ží™ÃVåZÏÿw"¤5ö!½ ©U2·Q†Í"O>ñ ‰‚¨V«ŒON±²¼L¹T$“Íãù>ýƒ¬,/㺱Òh¥RÒj¶Èz™™;Ú~hj/ËîÅÃÂÂ.\àСCŒÛF±X,‹ÅrMp!ñ"œ¥Ï¿åIL¬:âdâM©ôVrÈž”„6ŒŽO¤B¢(ftz)]Òi͹³§™šžÁõÆñä'ÑuŒc®K;‰nÛ\_5òxáäË<ñØ7ù€)-WŒ@fIÍ=„nÕöÎa;.2?ŽãåÀÏ¢”B)‰RŠXk\Ïgßþ9ªµ Kæ1éLžõµ5¢¨I:%É35EXZ¼H,"¹?Ù~›·ÁD;ד13µ-_¥Ñmˆ»ß{ƒñBÌŸ"ÿîOâ!žù!~:KÜlà¥BÏç¶;îBfúøö7¾Ê=ï~”ññ)´J¼+N<ÿ$'žy‚ûÞóGŽÞB©ÖJ³e±Ü´˜™áŸü_øüˆ•afî(…¥K‹çyì_åîw¾—»ï}®ãÐßã#âˆÕó'‰êu\ÏC'p¼€ž‘ÉëvìçÖ*D+5Û‰–·„p<œž±½•"uðþÔ=x‘Fž¾@3VHé·ç8© dtb:™¯$ɰÑíb9CCcÝâ8Jo¥•éíL ætæíùŽVÚ^$–Ý Áðð0ÃÃö1,‹Åb±\S®jáÝ•Ùî½%Rný¿µ·?ßáéøž—w»U»/×KòrQM„—Å”‚õ3Ïãx>R:4+Eú¦ç¸ï¾ûøö·ÿ–Ûïû 㓜xîIN>»%PJýùÒ ”ËMÏÌÛ„Jž™#,-žçñ¶@y×Ý÷âHèÉ88$šqLuõ&ŽñÒê¥ #ӆǻ…Æ®96þÔr³"$Âõ1Q £±rp´AÅš86ÄnŒ6[ó³-ŸMgQ·ÿ3¬;&@‹Åb±X,‹åÕ¸ª"eÜ…Šã¶@©“<•¯eóšWüÏ/Ëíú­mÅÎõÝôloFÈö>BˆmEt4ÁÈ¡;Á¾ð&/þô±®@麂ެï%¾fÒõØ„ÞɃ)Ú)'yýJ‹Å&yø)ƒÓ)¨ ±jg_`[ŒˆÙ9Çé>LEtg'¯öÜÒ A$•¾Eg]û€Àb±X,‹År“rÕDJÇqqL‹3'Ÿ¡T®Ò¨WAGh½Ó“òUl€ ‚ëâm ¥¤¼¹ÂÅ3é:¸B#;€HÉŽ(éx¯Üþ¾ûî£Ñ¨óÝï~ûßóŽÜr+Í@O ×±B‚ÅbÙÉÌÌ>ñÉ_åóŸÿ·ÝswßóNÇì(»ã“ë!]Ï6šÅò6"×1¬ÎŸBiA©T¤Q/áº;°š·0w1†f«E½VCÇ5†¾}Ó¶ñ-‹Åb±X,7%WQ¤tøÐ¢\m²^j"…ĘÝkIÈ;JcpÚ*ÞŒ133ËËO~;óÄþ;èKcJ‹ÅòªÄ:b|jœÿóÿú74#M£))dœW”‹ew n=z˜ƒ³3¬›Äªã.yŸ¤ Úù· H<×E)ÅUv±X,‹Åb±Xv=Wu,„$— SÁmƒó&Â)u£„*-ÀÓ?fà®"Ð^Q‹å(­X(ÎóÒÒ ôgQFQùÿÙ»Ó I®òà÷ÿ“[eíU]½NÏtOÏ®Y¤£ É2’0ƒñµ±Á`cƒ±qùÀýâ-°ÃöñÚdŒ Þàcd¿ À$ Òh›]³ô¾U/µårÎýPÕ5ݳH³ôH£™çuUVVvÖɬìsž|Î9õvû{ðܼ—+¥Hx=%wÙ°0—ž%÷;…B!ÄUhÕoÓ+ÅU3£r|œŽõ¤ïx7Ê’Œ!ÄÙ®‹ ßñY[³ÕR^×ö¤p„¸ì¿¿àØ'Ç–B!„B\Y»˜†‹ã¡\»¸eËøqBˆ3³”EW¶‡®la¼ÈúŽ>\G2(…B!„BˆvÛYŠàâƒ%cÊ !ÎízQig±~T C!„B!„XF2)/€Ž#&=M;hO:ƶ¥ç¥çJ‚”Rh^‚Þm{¨y‡ð§ôl{ &ŽH—z¥p„g«²€ÒL.|K¹ uÿ¢‰B!Ä«”ÖšÉÉI&&&¤0D›1†0 )—Ë”Ëeº»»éêê²d´=!^ʪ)Ëå2 ÑúvrÙL„©PÌÊŸÆ4÷Ï@2™$—Ëóöl×#]êEO`éˆD:C2×)g“âEyvM=¿E8vZ D!„âU¨ÑhpàÀɘçdbb‚ÉÉI6oÞL"!Ãà ñbV-H„ÿóØãt÷ö37;ËÜ\™õCè(ÆÐŒYbÌʟ͇˜öòÓ—-_Ló§ÓzlšOXúû`8¹^{Ko­gÙ6G ³»—D"IT›ågúM(uîw6Ž;ÆW¿úU|?Éçþå_ùàK&ÐB¼h…Vsô`ËRtf<Ï“BB!„xUÕçìß¿_ Bœc û÷ïgË–-¨âE¬ZÒhC6[`ÃÆ-LNŒ“œžbhhssLŽe_ÌæÏ“AÆ¥å+ŽKë, L¶ƒ’Ë—„l/;%hyêö•m³°X¡wÍ:ÒéGîeª\¥#ŸÆ¶^:ýóèÑ£üã?þ#»ox-›¶]Ï·þÏ¿qïßü-ú௵•û÷ï'NF!kúÖpðÐ!RÉ$}}}cÐFc) ˶°”ʼn'¨V«ôôôP*•äÌâ S«ÕxvßaÙFÃSÏìçÚ[ð<c sssŒŒŽÒÓÝÍää$étšt:Ý~= CÂ(¤£ØA£Ñ`ff†µëÖE‹ ‹øIŸz­N"‘`vv– B)%@!„â"i­9pà€„¸``ûöíÒõ[ˆ³XÕîÞqSo„4‚ Œh!QÜl@/e?+‚“Í/§j/‹uÌR?q­us¹R­AY£ÑzYF¦9ˆ…´ŽW;Y–•iŒÁ2Çš8މuD¬5ÕZLGþ<”{naëÎ=X–Å›ÞúsÜßW*‡‡‡Ãó<‹£V«Q(Ø·oZkÂ0dvv–R©„çyôõõœ•B\ajµÏî?ŒŸ)‘L¥#ÍBó£½û¸~×VÇavv–çŸ{Žj¥Â¾}ûpÛ¶q=—t*ã8ÔëuvíÚÕ¾fì}j/ûöí#•Jáyõz×uÑZ³qãF)x!„BˆU499)]¼ÅE1Æ099IOO†gà@3¸¸oß>Ö®]{^c3.§hmˆbMâX·k–_ÇͲÿ+e3:6F­Z¥40ÚÐÕÝËÄø(–eÑ¿v¥l&&ÆH$|޾pˆþµƒ:JÄQŒÁ`Ûqa AHäòt+òdpòdF¥R¦ùÇ¥½c–å0_=@>=ˆ¥ÎÜs)@yÝž[ظízŽŒ.â9Š ÔÜzç;xø[ÿΧîý[~ãC¿ÆÎ;éïïG)Å™LÏó¨V«ä Í}ã(fvv–t:zº»Éd3rV qY Pº~‘J`1VžC)…ëX8vžÇŸÚÇžk·ÒÝÕÇM7&Éæ²tu­!4žë , Û²H¥Ò$.¾ïÓÝÓcûx^’DÂÓ¼þ6¯Åšî®N2Ù¬dQ !„¸h333T*ŠÅ"™ŒÔUÅÕ)Žc™$G¬Š‰‰ :;;eÖo!ÎÀˆ¢ˆƒÇ1»víºð w«‘¼¨\ú ¬s²µ¾Ñ!?züضƒ—HE1–í295ÅüÜ ŠB2™}ýkyáÈFGF€B±„1†T*͉ãGñ lÛ¡Ý ¹BÚD§t_öxÙ>+,ŒZä…™ßgqüûì\ûÿp»Zsê˜eëÁçþá›ì¸v[wÜ@i&g+èVàÓ²?ùæwòûÿ/|ñ_ùÅ_øyººº^²Ìä,â Ïã1_ H—\®Cl J…\¦EIÇÆ`p-·5ê…jqqÝŠŒ Yl¦ KR!ÄQJÑÑÑçy )qÕš››“B«z>IRˆÓ9K•­[·^ôÆbM3“2ÒíŸí å)Y”K Å.Š'{^k£Igò,KÙŒ3jbÝ\!_ìlŽ;kÖ nÄmM*qrRCéóiÆ6ùämlíº×nŽmùÃÅ`èÎõQ®ÎIdÙºù5¼ÿý|ö³Ÿ#ˆb6nÞNED±æ‘þ‹F½Ê›ï~]ÝÔ~ÂA:Z qõ²m›Áuk0f˜ãã#”º×O{D±"Ö1Óãtä¬DÇЈž}œœ_ —È3W›¥¿8@g¦û‚~¿1!a¼€1Z†Bˆ –ÏçÉçóRâª&™”BÎ'!.½UMõÓ±! ãf¥6í.ß+[Í+•1+Ǭ\G²µêÒ¢ÖÏ•ï ,‚ \•}7&@á³uÇr›;Î\m+¿€ÁÁõ¼ÿýïãï?û9¢È00´…ÿùβew7 WQÌ&$@)„À¶mÖôƒ9Á‘Ña ¥â8fvª \;0€Ršb6A-ª“t’XÀ‰òÂ8¤7¿æâ®mH€R!„âbEQ$… ä|â[Õ e…‘&Œ4AFš(6gl6ŸÚ{ј—zÍ,{÷IlÍî­[cUžì’nÚ[¼¶ÿ5(e¡µFY+Ëààz~åýïãïÿþs|î ,ËæÍ÷43(®¢#›É*„m¶m³~p-š8> (:[JK:² <ׯs ¼fà¦æLd¦y=’k‰B!Ä+Ofõr> qé­ZÒq\2 ‹Gžaq±JÔ9¼ïÉìÇËèC+a­ÌäHÄŒãà»–³²(”²°,ëŒÛäïø¾÷ðw¸ù¶7ÐÙÙCÂE”Bˆ3²m›¡u}¨Ú Óåk÷`SÊ&p]û´krB!„BqYµ ¥eY¼ñ ·S­‡”,Kk:Ï\Ç—£YnhÎÆ½4–¥eÛœ6í÷Kí§R 9b3LGÏ ¤ü-äÓ–(…§ÑQÈÂä0ébý=%Öôù,ª˜|Ú] B!„B!®V«>ýt2áâ{ÍÍžì<}ùZ¾§vë~)•ú0A4Ï|ý¿ÙÐ{×yd…WCP«2öü(Ka»>ZkÐÎÐvë6K !„B!„¸ê­zR)®šlÂd¢—´?ĦžwÉ™$„8ÛUÛõèܰ ZÁMfˆÃMªÐ%Å#„B!„Bp ‚”WK¹(eãÚY–ˆâŒ\?IipM\™bìL·ŒB!„BÑ"‘µ‹.@Ë’X¯â¥£çG‰çƤ0„B!Ä«Ê=÷ÜÃüÁ¼ä²+ùó !.-‰®] ã³G™\DzÓÔC‹zX&—,HÁ!ÎNêUroHY`É},!„BˆKåž{îYñÜu]ŠÅ"ƒƒƒÜrË-¼á oÀ÷ý‹ú<ðÃÃüç=ï¹ì>¯mÛtttpÝu×ñîw¿›5kÖÈI!ÄUN‚”èøÌÆg'X¬/ðg8À-~R&ÏBœŒ¾üw3¬Ží#šö16lØpÁÛàøÁ~°*AÊÿøÿÀºÈ›ØË?oEËÖ;¹®eYìß÷,ýkq=ŸÆÂA~ömo<çñâŽ;Æ|õ«øÉ4ÿø_惿þ\ד3Jñª÷?ÿó(Oî}ŽXk’÷ƒŸzË=R(B!„/³×½îuüÅ_ü=öX;H†!¿ó;¿ÃÁƒ¹ûî»Ù°a333|õ«_å#ùŸüä'éííà£ý(_þò—9|ø0ýèGOÛþñãÇyôÑG¹ùæ›yË[Þ‚eYìÛ·û￟'Ÿ|’¿ø‹¿¸è11Ïʼn'Èçó´O£££ü‘)>. IDATÉŸü wÝuo|ãùÖ·¾Åç?ÿyr¹?ó3?Ó^ï|ÊNñÊXµ ¥1†L6GwÏ,å`;.½}kˆ¢•AÊÖ£æãvòdri[íàbkáò äŠ&§<Í)ÁËåË[+–m1=5Igw/‰D’ãÕ&Ë JyËzñnÛGåþáؽçV¶íÜÃ7þë_¹÷o>Ç>x2P9<2Œã8t;¨V«Ôu’É$A#`xx˜R©D.—Ã'†Y¿~=Õj•‘‘2™ ù|?éc´¡Ñh`Û6ããã ±°°€1†d*ÉôÔ4år™îžæØK¿/ŽclÛFY k\·Ù½´^¯£”²,*Õ ãcãìÚµ«ýºâêöÐCñÐCóº7ý4™\ÿúò?a´æ­oý)Œ1”ËeŽ9BÿÚ~¢0B)…ïûxžGEÍëŽRDQÄñãÇ©7ôõöR(¨Õj„aˆÁ0|b˜µk×’N§q=k”R$SIª•*J)êõ:Zëö5KkÍðÈ0[6o!™LÊÁB!ÄͶmÛA<€¯~õ«<óÌ3|üãgçÎíå¯{ÝëøÐ‡>Ä?ýÓ?µ’wÞy'>ø ‡>c—òmÛ¶ñ™Ï|fE¶áÝwßÍÎ;ùÄ'>Á·¿ýmÞò–·¬êgŠã˜¹¹¹öãƒòéO¥o|ãÙ´iÓyïÓ‰'ø³?û3¶nÝÚ.‹÷¼ç=|ãßX¤<Ÿ²B¼2Vµ»wÇADF„aD#ˆˆã¨Pl¥0¢PÍ@£¢Ý0mÅÑFCklG­u3بFkPÆèvPR·–Ñ @jmNfd²”©ZÛ9°\ ˜Æ:FkÝúghDs®Êoeû®0î¼çgùæÿY¨,Ï–Ù»w/7ÝtcccÌÏÏ366@¡P`dd¥µZd2I¡Pà»ßý.Qáû>¹\Žññqâ8&Š" …ýýýضÍ3ÏNÖßÂÛÇC=ÌžÛîB{%F¦æ CC¬á5·ÿ O|÷+(o|Ó›¸õöŸ$›Î0=3M†;:ˆ£P4êuAÇifg»®K„Äqˆëz¤ÓÀÎæI¥S¤Si*‹‹A€²-z:»¸õ'nÇó(¥ZÛ˶Iø òÙ, O2¿…âåR¯×™žnöÜI§Óô÷÷K!^FÕj•TêäD†Ç'‚Ó}'ÛÜç>™«Öš/ùË|ó›ßäĉÍ$ eVýólݺ•÷½ï}Í`„ãP*•èëëkï÷…ìS©T:m™ïûA°bÙj–âÒp F)Åâââw£‹ D±!Ž QÜ XÆúd0в ûö=ÏÈð ú×®£<;ÛÌ~4†Ã‡Òh4xòÇOP,–p=çž}/áQ«ÕÙ¹k7ÓSS<ÿìÓK„aÄžnæÈáCT©×kŒR«V©V+ ^«S,•Øuí ¤sy´>9¾å –…S›Âþ¯ß¢:¶ó¦be»QX€jÎÆ‹á¾øÛv\Ï5×ÝÌÓ'ˆ|:Á|5ÀÃMw¼Gø _øßÿÆ{ßón2™ÌŠ_“ÏçWŸÇqœÝC…—Öƒ>H­VkÏ~ °fÍæçç_4з¢:ø"Ùßüæ7Ù¸q#ûØÇV,_¦ì•p)÷é|ËNñòs<×ÃË{§eú¯“AJC¬[ÁÊVwï¥f«ã%èèìn¿§ÙýZ“LeN3M3»2Wèh¿WÇ1$ÉL®½ŽÖÍh:“£Ù©Ñ´ÆºT­†òò±-ÍK6æé»ŽÌΛP:fü™oàx‡0Zc9.qPX3Äûß÷>>ûÙÏq݆MÛ®%Œ"®Íã} Qå­oÿ9²¹qÔÜ7IB¼’ ÇÎâ¹ÅÓžÙÖÿÐ÷°-‡¾ùenÓÏR(–plë<òàWè_7Ä›îºËqi„‹LzÇó1Ja)(:¶íZóª(‡(eK·!„8‡ÇÒ8ÁBˆ—ÏÞ½{ù«¿ú+ŠÅ"o{ÛÛÚË_ÿú×óÙÏ~–¯ýëÜ}÷ݧ½o~~¾9AkËÒwwi.„åÂ0ëI€Rq™8·ëãwܾ÷ãæ×¿ßO𯱠tl›BÚÅÖ>õÒêó3$3yµ J)lO°B!„çczzšÿþïÿšº©©)žzê)öîÝKgg'ûØÇV #öÎw¾“Çœ?ÿó?ç‰'žàºë®Ãu]ÆÆÆxüñÇâ#ùH{ýÍ›7óÝï~—{ï½—Ý»w·ë|·ß~;ßúÖ·øýßÿ}n¹å´Ö<üðÃÔjµW¬<.å>oÙ !^~«¤¬7TªuªÕ:µjj­NÇ+ÊgJh\¹Ì`ŒZÙ¨6«‚\ÁÖ6AÐhNÖ š³Ò.ý2ËqéÚ¸“®;ÏøÞÁÁÁV ò³Ú÷Žmó¶·¿‹L+@YÈJ7!Ä«Óëï¸|÷¿ÿcƒ¶ðÆ7ßcÛä3~Â2ôn“n2B!„ëðáÃ|âŸh6·B¡ÀÐпýÛ¿ÍwÞyZ³ëºüéŸþ)_ùÊWxàøþ÷¿ÖšÎÎN®¹æîºë®ë¿õ­oå…^àá‡æþûïN)û·›L&Ã>ÈOoÙ !^~ʘÕ@LÍc=Á\%`~±F†¤Ó´Ñ—çWŠÅ…y’ÉJ)Ré$×îÜEW‡cY/ù~c O=õ~ïn»ãn:úÖ“ò, P !Î~݈CÂñçQ–‹Û»íÒÿ>4`’¹Úóôä_wÎï‹ã˜½Oÿ˜CÇžaÏžŸÆ÷äÓ.É„sE‹¿»÷¯¸ã–ëÙøšŸ”“S\ñáÓ•Ñ™¾áŒÃ?ˆóÍGWgq:±’y)óôÅ/~ñ´e·Ýv›Œ¸líÝ»W A¬ª]»vI!ˆW½£Gây‰D‚d2I"‘ ‘Hày®ëâ8¶ÝfK)EÇDQDEÌÏÏŸ¶½UkqZÊâ–›o Œ å…¥æ2Ÿ@áÔ}4ZŸsm¥…lfпð#ìM[Èù–œ¡BˆW5m4åú [¶oeÛŽÍTj6žÍ B!„BqùYõV§c+:óÍlÂWËÄ1Ë÷ó|&QˆÊ#˜(Äžü1¹Äÿ%g“âU¯ÕÙ{âG8¶ƒg'˜\ecç6¶¥vJá!„B!„¸dV=H© 9»6¯ž™­/t?ÒNçÒ¯{Osvp!„x•s-—ÍÝÛpm…ÆÙn:RR0B!„B!.)é¿wQZü(2—·âJø£`»ô0& aO‘OK¥B!„BˆKOÒÿ.ÑÍYË•í <_ DqE‰tƒJcX B!„‚æÌÐBÈù$Ä¥%™” Fžù>‹Ú#Ôó³³Xö‰TŽD&'$„83J9`Ù—ý®ZÊÁ²¤ò$Ä•t²•Ê–¢X­UÊvÚà !®létšr¹,!Ví|Bœ¡*Epþâ°A4˜<´—°Qgüù'8þă,NJá!ÎÌhâéãT¾ýÿQ}è¯Ð•™Ë÷§«™øŽŽÑò·åØ ñ*Å&ææÀØg81ýohJ¡\$]-SækT¾ý¿£#)!®pù|^ AÈù$Ä%&™”ÀõÓôïz-Q¶—Cs0tã0(Ü¤Ü Bœ…²°Ry”—B9>VªpùîªrHûëˆfgH'äØ ñ*g[>I¯e…¸N‡dI¯ÆuÒÏ¢ü4*‘@%s(KªÔB\é$óMÈù$Ä¥·j5*c ¤ÑÐ&&Šb‰Ƙ³¬ÿR<}9×UO}Í,_ëäd7zÏu1@>—eÓÆ çk°ð’iŽŒ3:2Âü|™Î5ëålB¼¸DŽøú`9.¨Ë7‘ÝR©[èñ䒛三«RÇLMM1>>J!®ç ZßÝÓê1æì5ó"uÇÄZã8.žë0°®Ÿ\nu‡ŽQÊ&él¦×ÿ ©kåà®F™Z6zík‰ × º¥(ÄÕÀ¶mº»»™˜˜Â¥»»Û–áW„8“U RAÀÑ£lÚ²©É ffçØ¼e-Q-«ÌŒiVÞ—*÷Æ´þÑ t²ìñR%¾½~kÙÒ6–¿¶bÙòm.ï²m[¶ÍóÏdíàF\Ïㅇذa=Ö9yäüqú×oåÞÏ~žßøÐ)•Jg\׃:ñŠÎw}!ÄåOÍtyžç§]\ÇaGižlve "Š"ǹèkÄÅ^C‚ à¹}£,T†8¤Ž²qÃગǥ¸ÎɵS¬¦FÐ`bršX%ñ<—ÑɬYÓ—H µÆÐР—ê"Úœ|lLóucˆ17ë0zÙkFkæçç)ÏÎÐ×?@ØXÀvÆÉfs«:ÌaŒŒ,26ÙM½2Ï–y\×;ïïŽ|ÇNZ\¬ptV3;oÓïVXë¥W})o!.?]]]LNNž5Gˆ—¢”¢««K Bˆ³XÕ¾)~2E6—§^oÙlž(Ž–i§´ƒŠœÀ\L¤Ì4++ƒ•¬ B.½¶<`¹lÛKûaY6¹\ž|.‡ç'Y˜ab¦Fw1‰e½x ò‘Gᡇâ†×¾ÁÛxüûñןº—ÿÆ)•:8tèÙl–Ç{ ß÷éë룷·—z½Žïûh­Éår?~œ\.‡Á`)‹ ˜™žÁq®¹æ9C…¸h£™žžåÐÑQºû‚€½Ïeç¶ArÙQqàÀÆÇÇéïï'—Ïá:.a’L&)Ï–I§ÓAÀÁƒâرcär92Ù –²°›ZµÖ žŒ1lݶ傂Ï8NŠÞµ9ÆÇlja˦!êõ:{Ÿ~šB¡€|ß§ÑhÏç Ã˲°m›XÇŒ P«ÕÈd2ôõõµÊa†ÎR‰çž{Žþþ~’É$¾ï7ƒ6Z“Éf˜™ž!•J‘Éf¨×ëT+Uæçç›;Ë¢X(P©TÂL:M½^ÇKxÌÍÍãØ6[¶l‘“N¬F3×óð9<Ï#;?O&›'á'0ºhädýCkÓ®o4ƒnÕ;´YÄl¾GƒŽ5ʲˆãˆ\¾À¼a¡Q­Ç¤“«“aLJG™«Fô¬YÇü|™g÷aû–!\×cnnŽ'Ÿ|’d*ÅÀÀ:â(fvvß÷I§Óض֚r¹L½Q§£ØÁºuë®ê3cq±Âñ‘q"‹‹‹ìÙ³G®b•¿¿FX–Ci¢(ÆŽb´n/ˤѺU¿±¬öÍR­ FkŒQ(KaZCΚu’¸¨lÖE4ÆhbmaVi^à 8~b”r%¦£ÔEk’©,‹‹†gž?ÂŽmCh­©V«LOOóì3ÏL&I¥RÔêuÐh4XÓßO:•¢««‹T*uUŸKÊ@»¤3Y´6$ÓƦgÑfŒÁµ½LNNòôÓO·³!;::èïï§\.322Š1š|>RŠ0Œ°m‹d2IE4 z{{Y¿~½tâ2”H$زe ŒJqΔRlÞ¼Yn< ñ€޾€mÙÌÍͱcÇŽ êZ¢T³‚Åš¸õ/ŠcâX7+ÊaƒCöã¸.ÙlŽÙÙººzxìчY¿a]Ý=ÍJ~¬ñ“IjÕ*ÃËrÂÇvxþ¹½8ŽG¾PdíÀz}ø»lÛ¾“T:CŤÒ&'Æéîíc~®Œ6Çv‚€bGg³ñpJ—ó%a4É Ñ_z3žszC÷‘Gþ‡‡zˆ›n½“†ÓÅóG§I¸6®m‘_³!­ùëOý ¿ñ¡²ió&&'&yûÛßN"‘ R©Ë娽{7¶c£cMGGÅb‘ÅÊ"ÙL–……ž{î9Èd2rv ñªp4”^ÅxEŽ/’ð,¨¼HúE~ôôavobóæMÌ–Ë$}Ÿuë¨T*Ì•çXÛ¿†RGét­cº»»ñ}Ÿ6`Œ¡^¯¯hÄ.e>ù¾,]ëâ—Ü×F£Á¾CGYh¸4 ÌTç£DZQvš‘©Eà‡¸ùæ›ðÍ›*333Í¿–jf‡iM­VòmL¬ñZ± ÑÀõ<´ŽÉd²tuvâ'}<¯9vqµZaçÎ y:ŠE¢8¢³£ÄÍ7ßL€Ás]¢¸™…žÏ壃Áu\Œ1är¹VÅï\ Ò¨çp–èfWm+މµ!6†j­Áñ£/07?¥Žë͈¹ò½ýý­®Úʲ>~¬}C5•ÊNgÑFãz üdºÕýûdï­)W§†tænáB;û6'F&›mP7IæFç1¦¹Qhá;O?w„k¶ rûí·Ç1ÕÊ"¶ãG®ëb;6A¢Ë¶H¦R$}ÿ,ߟ+³[r[ãDLRY$[¯µÇ2Ö¤[•¼S—×Ï5øGèê,FÇr¢Š³jö²ÐD±iÝ|5Ø–"Ò†ñ±ò…ÜÈæ±]‘‘<óô“ ,rù<[¯ÙI¬5µjù¹2(Åèð0¥î.v^»?µ¼Nb¡Méê}TǾK&1@5~ÑýS­úÉòz¡\/[ÌÎ RêÞÈôð,•zH!“À²š½S/ÅÔÌÏ?ø¶t9¸¶"¯l01( £›7™½=C­Ùaý´’2aS/£WV6³ž#Ø÷ÆöÛð.êknÃöÒĵžcc DqŒm;XN†CÃG˜kŸo'!Îз¦£ ½½½5@·6ÍLʨU‘µ&ÒÍçݽÜòwà:.½}ý¬ß°ÇqxÛÞB£Þ  †‰ñQ:»zضýºæØ=a€ŸH’ð}ìÉ nûÉ!\/ÁâÂ< ‹ ›·¡µ¡»gMsœÇBËñ0Z“+–H¥ÒÌ•g9~ô^Â?KóUc[%Ö—þ_Œõ}Ö–î"Œ¢8 ™HãZ¡ŽøðoÜɧ>õ7<üà×Ùrííhã{ZÐ ¾uß?ÓÕ»–׿ñnÊ‹ùŒ‡ w.ÄÕ+á{lÞ°Ž}GÆ(æ{p«uÓÌ<¨Ìϰqým䲇ZPÁw“8– ¨U˜8᥇±°m›žž.ÊójµE¶ vb´&ÒÍ+fkfËSt”:ñ‡®'Nht}žt¡‹°^ÅOg[ ïWÏÝa5P}ª5ˆg@)ÝM5¨Æ nÝô>üáó×ý×èØ°çÖ;‰¢˜°Qå‘oý]½ý¼ù®»ñ<ËR â*g)‹Î®Úž?öÐ7Ùví-|çk_l(ïÁó|ri—lJjrBˆf ²»»€½ûOíè#ŽBÊÓ£l\K¡PÀ÷lòiP7èË÷ãÚsµ2ÅT‰ŒŸ}Ùö5‘H°cÛfö>³ŸòlL*“evzš”gµŬGì0õ~‚Z…D:KP™Çr8‰¤pqÅiÞx5Äqë±­#Z÷RWTT º]»YJÒ5§¬h–ÕCPÍÔF¥NÖKšïˆ_²Š¦”EÎϳ¹kÚja×öð]ÙwÚcýº~´>Áèô$™\‘ÅŬ¸Ò P&\²Iß±¡«ÛmÎ@Ýìîâ¥rX¶ô—Ëf3 ­ëåàÑQææð)æçfȵ”)ß#›r°mC1UÂw“„QH%\$Ÿ,Xv|„B!ÄJ«Zó\¬.2=3Ë\yŽò\™ÙÙò)]™VVЗ´C’æ,ë]¶m³¸°Àüü<¾Ш7XžûØ“ë{‘ j–øÃ|üãçð¾'Y¿ioºë. P !Îh)P¹ÓžxöF6 P(äñv{hÏN°±kë+º¯~ÂãÚ[øñÓû>>Mg!ÃÐÐŽ£(f<\ÇÆÍñ³E9°âÊf ÌÎVI$”çÊ$’) ¿¹|\Õ ©·c¨,.°°°ÀüÂ<µÊ"ɹ͞m[6ÅT‰bªô¢ë%×¢õ Žœ&“öÚÊ\Ê%å7«‚¹îµäº×Êq?Ùl†Mƒ}ì?r‚áÑctwv°¦¯‡¤ï‘K»$ÜæØc]Ù),!„Bˆó°jAJ×õعe€™¹Y\Pʧ©-LžVá_AñŠM°+èïëÀÑ¢j…õý͉rι‚šåøÿqßÿæö×ßL"‘"›²%@)„8#KYôtupãÐó5C¦£“¤§É¥/¿±k ë¯Ý„ðaº»vaÛÅŒƒëÊ ßâêáy Ö­é"ŽFY¬-БKaÂQeÕê.HX1]ù$ºQ&ã;”J%tlVý;=´¾ˆrOàûI$dSv;@)Î_6›aK_š.§ ¹<©”O6i·”B!„âü­ZíT)Åök¶iX¨„(¥ÐÆ\Öã2.ŸÓ:Ž8Ÿ‘$c]'4Ç0ÎwÈg~…´/£P !N5&=K¶k ~Â'™M„e’Éôew ‑òq²~–Í›ndnq‘„—Äur ÅÕUArlúz{éîî¥RˆãfGìUÿÎ*À,uóc4«= ¨ASŽ0oþޤûó2w“ð¤Îra…i¨ÎM‡!ŽãQêêF» 7Æ“Ù[…B!.®¾ê´ ˜}µfžß~ׂQŒ±ÐŒò5 •S!Äé Ú(Xœ¦|⎟B‡õæ ’M×RÜzYín#¬sxr?¾—DÇšéêÛûv“Oo“c)®J¶¹Ô«;ãPë:µ`­5˜)zzz°¬Ë$ëGYØÙ.T"…+b§;ä  !.óë²GÆ #»ƒLrP”B!„¸"­ZRÍüq¬ ‚€( I¦Ó­L-³ôß)­Ù•OÌ)ËÌißÓ—š3<1gx÷™ƪ• ~2@wgí×l;çÏëÙ‡ftd„‰ñaÖ®Ù$g“¸ì4 ž}öYɘçE)—¤»‰tüv|·ë¢·7::ÊØØÛ·o'‘H\Ÿq¾a˜ S°7±]ºL !.‘8Ž91<Âøø8q¬ £×v±}êßf³¢F|Z8ÒuÂx7“–æ õƒåkž¡þlVÔ•‚8ÒDq„eÙØ¶ÅšÞn×⹞(!„B\V-H!åù*Ûw^ÇÄÄ8ÓSS¬ÜBEíà£iW˜ ¦´4­ÿµŸ·^_ZߘÖúK/³l™Y¶lYEìä:+·œ¬*‹ãG~ÌÆ-ë1(;ʶ­[±¬sˆ|ä‘ÿŸ½;³¤¬ýÿ©§¶³ŸîÓ{ÏLOÏÎÌÀ ›È"›È"æ ×är£Ä¸€F}%Æ›`òŠæz5¹AM®1‚5øâ^•%ÈffŸžÞûôröªzžßçô™nf€˜fø¾_¯™î®SuªÎÓÕUO}Ÿïó<ðȯÍÒ'ñÍoü€÷½÷Ýtuu7÷?[1uœÃ/bc Öœq´ÑÔª5|ߟ·\ˆÃQ­VÙ¼y³„8b•J…»‡¨†ìص—eK7³ µÖ‡Ìˆ ÃÛ¶1T#èEZëæupóæÍ¬]·–x,Þ¼ÆEat ;¸EsÛC=èG:š÷0mŒ©ßcŒÁ󼃮§µZíAÑ©©)n¼ék,^¾–'¶í ~÷Ý\rÉ%ó®½Q¡”j~Ög_ƒë÷™úµþH3DŸï؄ǗZ­F¥Z#ÙÒ‰£òùq²-9R©4ZGÍú«Á`ôzð¼ú¯™­¿Zõï1­_iÖoçÕ}õº±il[-ÉOLJ¥±,ÅØd‰ÎÎ ®ã!ÕL!„B,Gµ»·ãº(ÛÅv<×Çv<Ìœ.Ðóƒ•Výë!Žs¦ÀdN0²¹N3Àiæ­7ûE›9YœÆ Ë- b±¾ïe1Âøt•¶Œÿ‚Êx€_üâœ}þe,î[ÁÆG2ÜxÓ×yï{þîîn¢(âþûï'—Ë‘J¥ˆÇãA€çyÔj5ªÕ*Ë–-c÷îÝÍÜjµÊþýûY¶l®ëÃÃÃ(¥Xµjmmmr¶ŠÃ¦µfË–-RâˆU*UvîÀ‰gIú1¦¦'Ù¾s+–õECCCttt0‘ŸÀhƒÖšx<ÎÞ½{q]—(Šèèì X(211AµZeÉ’%8ŽC¥Raxx˜O<‘D"ÁD>ÏÎ;X·når™jµÚl”1Æàû>Zk&''' Cúúúð}ŸééiÚÛÛ¤\.ÓÑÑëºø¾1†J¥ÂÔô4Ë—-›wýœššâ«_ý*‹úVpÆ9ob*?É¿Ýþ] pé%—[¶l¡X,ÒÒÒÂÈȤR)‚ À¶m”R¸®ËOðu^o–Æ÷AXk¶î:®‹1i°,”RX–Ei"á8n3²†!–¥•>«™u9/ªi)ŒÑDQTFÎ7™ß¢<Ûê\_Å -3@yú9—нhA²ö¤Ó©šoú:ïß{èèè òù<¥R‰™™”R ÇY¾|9SSSìÛ·(ŠØºu+}}}$“Ižyæ´ÖÌḬ̀råJÚÛÛI§Ór¦Š#2<<,]¼Å«T*ìܳ'–ÅÅCï'™)ؾcýKQ(êëíÜ @"™¤£½ƒ(ŠÈON¢”E±X$”í ”bÛ¶mT*Uº»»Èd²ìÙ³‡¾¥K1Æàº.Ì ”J%â±ÅbÇq™)Ìà:nó~àû.?ü0¾£³³cY8ŽÃôÌ ¥R‰t:M©\¡T,àû>ëÖ¯Ÿwýœ Pöö-猳߄Ö?‘â‚Ë®æ¾;ÿ€ /¼8ŽK±T"žxâ :::QÊb|b‚0X¹rår™r¥ÂÐP½A)“ÉÇPJ±oßÿñðÃd³ÙF–¼Âvll¥È¶´²xñbbñ¸œtB¼ Š Êh¢F=9l4òÔ«®ÆDÒ¢0¤Ÿ´š3xGQXï¡ãúìm]O¬Ô`©F6ŠšÙ—³Áɹ½‘´>аo«Þ˜Ïá×Â0ê -ÒÃG!„Ç‚ðÌ3φ!ù|žõ'®'“ÎñYV½òFõ Øl€1ŒfÃsâˆÚðà¿ÄÅñ\m ýËVðäæMx±8-ÙVªÕ -¹6ÆF†ñc±úÁ:S“y”m“J¥©T«ØJaŒAÙµ †Ž"\ϧR.c;ËV¬!jt9?±Ùè2sà豌Á n¢ðدHùN,ÛÅh=o½~„_>ôœ}þåL›,[wá{6ʲˆw®¦_k¾zã×xß{ÿ7_òf*• ŽãÔ‚fPU)ÕÌÄ9ûì³QJqÖYg¡ŸÃq*Õ ¶ªgÜÄãñ…3Ù„xUˆ¢H&ÉG¬\.³{ßU“d4_ñB"£±-EdFvìÚÇâÞnÂZî3O¯_××õ°¬E„a½a( ÃÆõ®Ñ˜­ݲ}Û¦§3‡Ž"–öváz.S““¸®‡ç{ͬ  ëñ†z€ÏR„‘Ë€6Ä Êå2Ëûáû>ʶ©VÊ€Âvžc£‡Ÿ ¸oÕ¾7rÓwÿ/‹ú–sÊë/b`t†r-ĵm‚HqþeWóó»þ•J¹Ìº5+IÅ<,eÑšN²¸§ £#\ß§·«Æw=Ò‰õ€BPo<3F×3¦\K‡œzòIضš3D‰ifTV+öî|æ5qnuõôO¤äL¼fmÆÆÎiÐ×Í4Gš½~ªÕ*ûöíftx×óˆÅâd³­a@±XÀ÷|P¶í†aXo̯VË(åÐÙÝC,–À4úëÙÿ¬]ª¿€b±Èàà 333$“I–.]*ÃU!„â˜pÒé4CÃCÌÌ̼¤Á³µ†0ÔD‘!Ô†04õ å³2º¢($žH1>6J{G'¾#BR™vl߯øØ(Æ@*ÓÂÔôÁØAP)—±,ÅÄø©tšööN¦¦&¤wQ¹¶†÷11>N{GýËWb´&ÒOÞ3¯زQ3¨ûþ7µ©}TsKA)ÐѾáüÕ&zûVѽdãÛG©ÖB’q—J5¤Z XyÂ÷>Ãï¼›÷¾û]$“òØ–E%q?ždhhÉÒ^:²>”¬Æõ‘ÆØg†Ùæ”g7«Ì½Üjc¨c Ð’NeQ3Ww­‘ï"Sgî%18–±Ls[·¹E ½¿¡úëåþ–g°UŽNz=Ú´×V”*Ž£H&S¬Xw7þ‚‘ÝO¿<ã³½²'fèÉ¥yÏuÂò¤k»xm2"m½| ‘6D‘9Ð{ε2BÊ¥2µ Àó},¥ˆL}Ý0Œ˜šelt˜ZµŠçûAà{>‹úúѦ޳I3§¸¦™‘ùbxžG<gbb‚0 ¥ñ\!„ÇŒÐÑÙA:¦§»ç%È´©%g³)g[Š™­‚5ŸÇK–.§Åjt‹%À‚þe+Y²t9µZ ˲p—õ'@ ì£wQ_½åÙ:ЦV«â6Kú—Vc²— Œ^¸Û« ÑÙ¥˜ ¿Ibò7ÄÖœODÌŒ ’é\Dµ8M,ÝÊ{—œÏ7ÝÄ÷ÝɺÓ/¨?DÛŠr5ÄU÷þø_èéíãâK¯`bºJkÚ—ÈÅË.ŸÏK!ˆ#bÛ6íí9Ê•S¥i–ödÑQ½§R«wï›ÊOÐÖ–#Ö½žÈ3„ӣijm„µ2n.¹ü­ØÊÆwm PŠW„dRŠûºdqÑÞf¦¦H¦3X€ïÙLMLIºtuu¡,®–™x†ñ]Ob»:а”"·ôÒíÝ ç<µlœÜœÜÞtá…m¸÷Çßç‚Ë®&‘J÷]¶lz˜ÝOoâÊß~8JSÞËè3O`ûŽŸ VœÂOfYrÊy¸±„œ0Gü»¢x-«7â+cÔ•ÃúìÜs#‰ÆPŠD" –iŒ+©‰48®‡íxÍõ\·>Ò옒ÍY¾Ck‹{ij{þ!„BmGuvo£!Ò M½åØÌM ÄšÓb<§éxöµ9?ÎÎÖmÑJg~‹só¿ï=û dÍùï¹ö¶”ÂR³“ô¨Æzº~ÐÊ"–n¡cʼn„•2^*CP.b)E¦µë®»–¯|å+<úÀ½¬>éLîÿ·[æ([Ò‰˜#g—xEA … ^äC¨Cÿ’EìÚ½‰É<Ét¶ ìîêÆQNzAëâUÔ*E/†k lb©ì‚>O-Ëââ7]À}w~ŸsÞü; ì~š]Íe _‘N8TÚº±” 8®OP-áx /&'ŠâˆÔ»`×ë¶Zƒ1³ÅõTS8ÐsêÃêØfnÕ÷92%Ÿ«+öì¸è–²°”B)…–Æ!„B,0G-’fY3…i÷099ÎÔdžD2CÔ˜ p®gשæV²^®º, ?>ÆXv,‹jµŠ5§¢è'3øÉCO ”N§¹îºëøÛ¿ý[v<½‰kNæ’Ë.—¥XdVoñR¸®CÿÒÅD»ö²o`ÝítuvâØJx8¶;FºsÑ«ò<=¨4üô‡ß@)›«ÿ½Íe&YÏTŠ·´oi—Bñ¯9P­T-`ŒEazŠR¹L"™jLÐ8¿îûìKãѺRZ@¥Rfzj’J¹Œ²mžŒ-)„Bˆ…å¨EÓ\×ãìÓOdbªHÌÎÐÕ–Á¶#XÀÃÖœ|âÛFC_ϴч½m:æ=ïy?úñ÷¹ðâÓ±•GKÚ‘¥âUÏuV.ï%žœ"•ìFYJ8¸Îññ@kYoºèN9})ÓM*¹˜¸Õ³D…â(ò<ŸåK{HÄ'˜*T2~½Ò/_Ë|ýÊG:£-Ó…²êÙ”étš˜«OX&„B±ÕˆÚ’%‹é] ÅrˆeY >£kî1ÖÇÅÔG4lV¨F»(뱨åñ]é6#„xu«†öç÷’ŠgiË­`ºò†‡‡¹ñÆ9åä“'våà¶/@kÍ=÷ÜC:ýÂc> R©”œ G1!.a[cB,Kn‡G¿5& ê_k%ˆe$X)„B!„xNòTö¸¶K5¨°or©n PŠãÞ©§žÊ'>ñ ®¿þzn¹åÞûÞ÷6_«V«|ë[ßâ®»îb``€D"ÁgœÁýÑÑ××7ï}Â0ä–[náŽ;î`ç΄aÈ¢E‹8óÌ3ùÄ'>Ñ\ïÙãJV*¾öµ¯q÷Ýw344ÔªëׯçÏþìÏhiiyÎmòù<_ùÊW¸ÿþû™˜˜ —ËqþùçsÝu×ÍÛvîöïÿû¹á†زe ©TŠ«®ºŠë®»î°þÞo»í6¶oßÎ_ýÕ_qê©§b¢à u”R\zé¥-ŸÝÿµ×^Ë—¿üeüq …>ú(ããã|ó›ßdãÆìÞ½› hooçœsÎáø­­­‡|¿k®¹†/}éK<ýôÓ¤Ói®¸â >ðງž4fóæÍ/úó/\šrm˜­ŸÇuZ9­ÿïq“òh3A…`pÑØNÊ¿¹•Ô?È}R!„BqhG=HYŸ„À:ðýs­øŠ>§XÔ;ûÍ„9â:±÷öEûØÛÁÅk/E!³ÂŠ×†K/½”Ï~ö³üò—¿l)ƒ àCúO>ù$W]u«W¯ftt”[n¹…k®¹†ï|ç;,Z´¨¹îÿñóÐCqÎ9çð[¿õ[Äb1vîÜÉ}÷Ý÷¼ûþô§?Í]wÝÅ›ßüf®¹æÇapp‡zˆÉÉɃsÍÌÌðîw¿›ÁÁAÞþö·³fͶnÝÊ­·ÞÊ#<ÂÍ7ßL2™œ·Í¾}ûøÓ?ýSÞö¶·qÅWðãÿ˜›nº‰l6ËïýÞï½`YÝsÏ=$ .¿üòUÖ{öìáƒü —_~9—\r ÃÃÃÍ×vîÜÉý÷ßÏyçÇÛßþv”R<ñÄüð‡?ä‘Gá»ßýîAc‡îÝ»—üã\uÕU\yå•üêW¿â[ßúƒƒƒ|ö³Ÿ=hÿûÆ^Òç_¸1·®– °UB”ÇêNëÅqÚ–aÅŸÄí{=X2³±B!„â¹µ ¥Öšz,›jµJ¥R¦¥¥mL}SÎýÁÌÿqÎ÷sÖœóÂ6Ö1ó—b_s×ǰ“c$ÓY,Ë"›ŽqîY‡?q…­l¦ûiCoaÑê%r6‰×Û¶Y±b»wïn.ûþ÷¿Ïc=ÆM7ÝÄ)~O~h IDAT§œÒ\~饗ò;¿ó;üó?ÿ3ý×Ý\÷¡‡âÚk¯åýïÿ¼÷þÈG>ò¼û¾ï¾û8餓ø_ÿëÍ[~íµ×¾àqß|óÍìÝ»—¿üË¿ä¿ü—ÿÀÛÞö6V¯^Íg>ó¾õ­oñÁ~pÞ6»víâæ›ofýúõÍÏsùå—ó£ýè°‚tÛ·ogÅŠ8ÎüK­1†|>?o™ëºuåÞ³gŸûÜç¸øâ‹zï“N:‰Ûn»m^Fã•W^É)§œÂ§>õ)î¸ãÞþö·ÏÛf÷îÝ|þóŸçMozSsý¿ø‹¿àÎ;ïäꫯæu¯{ݼõ÷í~IŸA31ìòE(ûÕס@ÍääããyV­X¶€»P[<=8ÍH-ƸÓM¯\>…B!„Ïã¨=A@¨ë7¼Ž‘áaÆÆFYu‰„a€iÄ gƒ‰õ@¢i,o,ß××£±ìÀÏÍõÁJ3»ýœí˜·lö}LsßsCÙ6CãE:s}x~Œ‘½OQ "\Ç>¬ç½ßfüÿY|ÆZžú“ ì¿Ñ½¢£ùz-¨á8jNæHµZÅ÷}¢(B)Õ .LOO“J¥Ä$BŽT*E±Xlþ|×]w±jÕ*úûûçß’É$kÖ¬áá‡n.ûÉO~BKK ï~÷»i¼À_6›eÏž=lÞ¼¹8;\ÿþïÿN[[¿õ[¿5oùÛÞö6¾üå/sß}÷¤\½zõ¼ý$ Ö¬YÃOçßíÏ~ö3ûÍã,]u"ßüöwùƒ?¸†Þžžæ±„aØ<&¥Æ\×EMP 0Æày^³¼Â0lþK$Ï{Ï|v¯Ž jÁAÙÒB!„Bˆ…㨦X–EA½“·Bƒž—ÕõÇ c™ÆO¦4TDQÔxŸz`Ѳ¬zÒ#Ìé‘=·«¶Á²À«U mtýýIÝxZ€±fƒ”ʲplØJjÃèd™î¶$ö Jv~o˜Ý?&ù')Úú;N²ùcð÷4•üêR©]]]LLL¥R‰lK–Áýƒd2™ærSSS¬\¹’ÎÎN9#Å«B¡P˜÷°¿sçNªÕêsÔæ1öìÙÆ žs Äçó'ò'|êSŸâ]ïzœ|òÉœyæ™\zé¥$‰çÝvÿþýœ|òÉT”R¬X±‚M›6´MGGÇAËâñ8Õjõ°Ž7•JQ(^žLðå/¹ù󳃣³–.]úœï­µæ;ßù·ß~;»víBk=ïõ©©©ƒ¶Y¶lÙAË–/_ÀÀÀÀA¯µµg_Òç_ˆ¢(bϾÆ&«tööR«…ìÜ?„–,^D-¨±é7›˜™™¡µµ•¡¡!ÚÚÛI%“T«Õæù“Édxâ‰'ð}ŸÖ\Ž( ‰ÇãÔj5Œ1¬\¹’Z­F¡PÀ÷}FFFæ•]†8ŽC,£Ô8yÃÉ/xìÚh&ó“<³sŽ®%h ?1Áæ­Ï°þ„•„aľ}ûغu+‹/ t¤‰Çã¤3iFGFI$Äb1ž|òI:;;'™L’J¥ÐZ×ïÇJO$l~æ––Œ1ø¾ßlX Ã5kÖ2ÿ³ŸýŒzˆ /ù¯´wv³1–àßøïþƒkèíí!ŸÏóØc‘H$‚ ¬ìèè P(022BEôôô`Û6–U”Öj5¦gfȤÓ8®ƒïÕþÇ¡µµ•}ûö‹Å¨T*DZãØ6J)Ç! CN8á„1©–B!„â`ÎìÃn…Ôªµ=s¬eÖ†0ŒÈHkÂPFçF\1jõìS_`Y®ç1“Ï“Éd±­   q(… #*•2–mãØ–RXÔ÷iY@##Åócõ`§HGxž_ÏÖhƒ™“©™@µ]^hlÊßf÷-ÃØÿ_œÔ¢•jÄåiª5Ý T¶÷µL&)•JlÛ¶r¹L¹\&•J1::Šã8ÌÌÌ0<<Œã8ô÷÷ÓÖÖ&g£xÕyf»1Ï ˜­]»–øÃÇtß]tgœq¿úÕ¯øÍo~ÃÆ¹çž{øÊW¾Â?ÿó?ÓßßT÷÷R'‡Y±bO>ù$AÌ Ê:ŽÃ™gžùÂhç¹Û‘¾ð…/ð/ÿò/œwÞy¼ãï ­­ Ïó0Æð¡}hÞ0/þóçîž}Œä+´æº¨Vj&™i白# §«“x"í¸(¥Hg2ìÝ»¶¶6|ßg||­5K—öáy>Ú÷¢l›d2N,–Àu]‚0 »»›Z­Æ£7284„ë¸Äb1ªµ€Lº~X¿þDR‡1³ûlåÓ;öÓÚÞK-Òhmpc)&f&yzûnV,]‚ã8¸®Od û÷ 05=CG[;Kú3S,O&ÁRd²Y\Ï'•Î05=E¡XÄC:•fhx˜žž×£X,iؽw/éTšd2I,Çó|ºº»I&ucš'Ìl€òü7_E[g•ZȪõ§ßøæ7y÷»ÿ€T2I*“%æ{ŠEÊ3Çahx„0¨áz>.084„1†ÖÖ6Òé®ç†ãã´´¶0™Ÿ¦Z«ày>(ÅŽ]»IÄãDQ„mÛxž‡m+:;;Y²¤O”B±Ùìéj­Š­êW2Y¤B!Ž`Û¶mDZ36:Ê)§œBú0˜ù¨ ¡Ö„ÚEï£Ù=Ží°cÇvöìÚE"™Ä¶mÇeqßR~óØ£´wtB£+v*ab|ŒT:ËÌô‹–ô1°wél ãc£d³-K%ZZZ ÃééiÊ¥ñxŠr¥„mÛT+UâÉ$«V¯Ãõüf—oŒÁ¨g=Àë¶ÿŒ™½w“<÷¨DëAŸoç¦Ø÷£©?I3¨-FvŽá»6qßaüu𓿉°îï4gœqÚh0õŒ¨gl5¿·U³ûàl–ˆ¯ÿöoÿF©TâÜsÏm.ëëë#ŸÏVàméÒ¥lÛ¶í ÀÝáJ§Ó\vÙe\vÙeüüç?çcûßþö·¹þúëŸs»E‹±sçÎyÝ@¡`ݾ}{sbŸ£éâ‹/fãÆÜu×]u3©~ô£±fÍn¸á†y˕ټ†íÜyв;v4ËçxE!»÷íg,_%™é`×à$Õ Âs´Ñt¶vðôîLPeÕ¢¶æuÙÃåDQÔ÷׃ƒžË }‘±¨w£¶”…ë8h­‰ ãØÀéë—®^Šã¨ú=±ÑHgŒÆõ=QaüÙata”òþwÅ…2«Ø¾o;ÑΦãtd㔪`Û1†óL¸ƒeÝZO^m+V/j§X,ÏOÐ×™feOTýÜïÎ.ÃVЉ6†0PÊFÙzí2lÇÆÂ"Š"ŒÑDQ„eYõÏî:X–ÂR ‹ã˜òÕ@¤yh*ÇüçfÞø¦+±ã­LªŒM–Á²Èô®§øú7¾É%žC{&Rö˜LhbYõ:ˆe5#nÜ7Áè€%åÔ3Ec Œ‰×»Œ‡E6¬êCYõ^Æh@aŒÆÑU&‡w39¼çe8Û,âÉ=Kúe² q\(‹ 199I*•bÙ²e’‘,„BˆcÂÈårLMMaÛv3ˆöbhc#Ci"Óø‡R›ˆD2¥‘68®M¤5ÆXø±8;¶?ƒR6}ýËØ·w/Õj…j-dßždZZqýCƒûñ<Ÿññ1FGG˜žšÆql†÷“JgÇRŠl¦…üdž±±Qú–®ÄqýF†æ¡ž',¬Z{Ë M¸òüAÊ9]̇oOR;§Jzqû÷L`qßiN??Éô£žúú=Ÿíª!-ð¼ã‘=_f” ÝÆùÜç>G{{;W_}usùå—_Î?þã?rÛm·qå•W´ÝÜ™·¯¸â n¸án¾ùfÞóž÷ÌË<+€ølSSSd³ó» oذ€R©ô¼Ç~á…òõ¯Ÿüä'¼õ­om.¿ýöÛ™˜˜àª«®:êåuå•Wrë­·òw÷w,Z´ˆSN>é u^lÆãlÙg»é¦›žs›ÑÑQî½÷ÞyãR~÷»ßà¼óÎ;®ÏÝ0ˆ ‘é®­Ý€£(¢>Òˆ…ã%Øöä“t¬HbfÇhlœ¶‘³À4Ç Ánœ²jν,Â9¹úʲЦ#œwßÔ‡8^c º0B°å‚ü>FV¼b‹qlßµë÷ǦÖƒˆ–í³{×3äjMùÍckZZ-˜Ø^þdö˜,‹ÐÌ?¾æ±[Qó5 ,˜±R1gœèÙÏPž$Øþ ‰]ü:6+ÖN6×ÁH¾ bžM¹†%ËÖ1¸gwßóïtåRX÷?D¼zO6cØ1˜çþðwé]y’Ü8Ä«^,#NS©TšãÒ !„B @{{;¹\ŽE‹Ç_ô›iM½‹wh_çgRF‘&ÍqÚëÏiNhà¸.ëN|žçéÛvš“ã„AµëOFÙ6Æhzzkø~Œ( £Ûq1Zs‰!¶rÃ, £ Žë†!®ëòa~î…Žåˆ.øZj»ð»W1¼ãIÒK*%¼DÛñyÝ?Ác´ƒ=åôþÎ"”e¡,¨…šdÍ¡ð™8]³êºÕägªä2ÒÊ,^FFF¸ãŽ;€úD###<úè£<úè£tuuqà 7Ì˸þýßÿ}|ðA>ýéOóàƒrÆgày<øàƒ¬Zµª™åxõÕWóË_þ’/ùË<þøãœuÖYÄb1vïÞͽ÷ÞËøÃç<®Ë/¿œ³Ï>› 6ÐÚÚÊää$·ß~;À¼À㡼ë]ïâž{îáÓŸþ4[·neÕªU<õÔSÜzë­,]º”k®¹æ¨—£ïû|ñ‹_ä£ý(ï{ßû8óõ¯çÔuËÉårX‰üìg? ·÷Èæ>~ó›ßÌí·ß·?üaÎ?ÿ|¢(â¾ûî{Þ`m__ŸùÌgزe K–,áàÞ{ïåâ‹/ž7+ûñÈ÷=NËqmäñÕo¤R­pâ©olô·ˆÇ\ 3Óüâî[Y¶r ½ùr¾ƒSËS+ˆ¥ZküT JãÇyµö/ÐÕßøÚ×(—Šr3ÇÇÂãÐÑÙAkk+–eIƒ»B!Ž]½ÌîùR”Ðèî"­ßÏRÖ÷¥°l›ÙlÓØÎ‹Å1¦Þ Z›Ù™¼-l·è«·Ú*\?VÏQŽrê™WÊÆm|ïzf(5<Ï>¬_ ÜEë0QHqt€‰[ð’i¢Z•jqš®5§púWÖòëë¶1®÷Ñ~õ"4 ¦¡ôù1ôéë¯[ƒRŒKN¼z=ýôÓÍ ¢ã8´µµ±råJ>ùÉOrÅWt­p]—ÿóþßûÞ÷¸óÎ;ùÅ/~AEtuu±aÃÞö¶·Í[÷þáøÞ÷¾ÇwÜÁ¾ð´Ö,^¼˜7¾ñÏ{\¿÷{¿Ç#<Â×¾ö5ŠÅ"Éd’õë×óñü»š§Ói¾ñoðOÿôOÜsÏ=ÜrË-är9®ºê*®½öÚc6ëoOOßþö·ùÉO~Â=wÿßÿw0=SÀõÀ\pÈmúúú¸þúëùÒ—¾Äw¿û]Òé4ï|ç;ŸsâžãŠe‘L&8ñ„eüfóvÂD;®ç¡”E±P Z̳zÕ |×ÅS!åüãÛgl»Á‹§©¦ðâ)úN¿/þòÌm9nÏÚúß‚V.cóÖLŒ‘δb´&Ò!SC¬\¶„dÌ£´ÿ)Æ #è°‚íúè°F¼¥“Å'…=g–ñ£{œ>N®¨gn¾ÿ}ïã«_½c 'žúF@Q.øÕOoeÙÊÕ\xÑ%¸ |«ÆÌØ ùgÐAˆíûè †—jañ†³ðâ©Wñ '™fâø¢,5¯gB!Ä1y¶0G©ÏF­Vå§÷?Jߊe2?ÆŠUk‰ætŸ»#cžµÄÌù2'ËòÀÑ™ƒ«ü/áÈ•m³uó&úúW‹ÇÙ½íqÎzÃt·%Q–¡<5AP)âÆ’„µ FGijíxñ$•ñ¿¾n…õÒwSþÛñyʶŒçÚrv‰WÄÆ¥jØ" 'våà¶/{Y÷}Úi§qî¹çòÅ/~ñ°Ö¢“ÅMtdÞpÌŽéÔSO}ùÆP(yìñg°üÆh*…ñz€Ò÷É$’1‡ R¢<“ÇR ¥l¢0@Ù.É\Ö+8Î`lÞº±¢E<‘brle}½är­Ä\ Ÿ a¥H½›¶Æàx>ñLîe irr’¯~õF:z—Ñ·rÜûY¾r5\t)ž£È¦<\Ç¢V.R+Í€K)ŒÖØ®K<ÛöŠ–óKQϤ¼‰ Î}+6¼aÁW-Ì3UzŠlbž“9ÊXšhz„p|þò³_3×ô0¿]Êãä–¢âY¹É¡[n¹å eçœsŽŒBñ*²{÷n<ÏÃ÷}âñ8¾ïãû>žçáº.Žã4Çû·¬ú˜÷a6ç–y¶£–î§,‹™éIvîØÆÔä$…™)”í ÃèÐõÙƒ~6‡~áQÊfldDZq\r¹Ôx 2X–"ÑÒ´rÛX›Çé_YÅÃïÜJðð8úl P !Ä«eY¤SIN9q%=ö‚P±î„uø¾WPÆë“9¹ñ$îË”1y$\×eý +Ø´å)v<ÅÚÕëhiÍ’ðmÒ ËŠAºå?Ζ–Þÿþ÷ñ÷ÿ÷lÛ²‘uNã‚‹.Ãs,²)¯yŸôiüDZNL!„B!ÄÑ R:®Ç%žE~ºH~º¥1ߌµ Ç”ZÒýúÆì­†ØÊ%õÁÀsÛX›Gÿ?e¹åÿþ„+®ü]Ç¢u΃—Bˆ…Ê"•Šñ†Ó3]2xNŠD̼j†ép]‡“O\Jg·&æuà:é„÷r&J–––®ÿÔ'ÈÏìAë\Ç%PrŸB!„BÒQ}"kmm%ÛÒJW%¬O^ó3õ.sz» öït1`d²Âã;&ùí û±•%g”B,`Úh†§Èï¦-Õ‰ëøŒ–ŸbEzùѾ%ƒÛ•aªœç©á-t¤»ˆù9FŠOÒ×¶ËZXcÅUÂ2{t@K[Ù8Ê¢ZÛC-|U(›7mKáÚZÏP¨lÆwüÙHfY ÏöPÔ¨†;±­žíˉÿZ¨ !„BñbŸw¤„8¾¤R))!çé ¨‡RBô«4¨bL„6áÂ?N£1Hoƒã’Ñ•2•â4øIÈ,’2B!„/šô»: ” H)ÖÖV&&&¤ Ä‚?OÅñÍQ §(Õ†ñœ®Â’ñ(+a­J~ß6¦‡öbû1,e£öìÂKei_¶Ç‹I! !„BˆÃ&O G„(ÅB"™”BÎS±h]#_|Œ§¿ÀþüÝR ÇcýGÙø© ±t ×OE–UM!„Bˆ#!™”BglÛ¦§§‡ÁÁA) ± õôô`ÛÀ8î¯E*N.õ:–äÞBwËù’Ey<þŽ]lw?Ùî~LXE—'±Ó]ÇlQ=kÉK®Áâàá\­æûZ–%ç¬B!ÄËL‚”/’цᬰ|ÓZ¦/(‘<)#…"Œ®®.†††02‰X`,Ë¢««K â5"¨f)]@Í”Çñ* CFöïglÿ.N8-‡ëºG÷< ö °cç\×cjj’D2‰çú ÆÌŽJýgݨ«ƘF(³¾Þl\Sc@7¾6V.f0€‹“IÄX»f=Ýr½B!„x¹HòEСaÓŸïÂs<º?¼šm¾ïÓý´,ÝÅ ”bݺulÞ¼Y C,(ëÖ­C)ÉN:îÃôL»†ˆ¬»÷N`¡hok«ßG¦\*éÇ©WE,,âñ8ZkÊå2QaÛ6Édm4a¢µ¦X,’H$ˆÇãÏÚ¥!мßì² 0Æ ”jfðj­q§¹M±XÄ÷}b1CñHEQÄÈØ8»G+8él}z'kVõãyµZ™™R©¾ïcŒ¡\)S)Whii T*¡µ&Nr¶z­5ÚÀ¢%ËÉd[Ø»g7mí¤Ò"­ëÁIcÐÔ‘ë‹tãøL3©ë]? Ô×5¦Þø<<„²­9ªÅIŠå‘6Ø2ö¸B!ÄËB‚”Gh6@‰‚Uÿ£“Ÿüü?Yýþ.¶\¿‹u¨ ˆïû¬_¿ž-[¶HF¥xÅY–źuëð}_ ãx×Pnßµ/Ñ‚OP*–xf×ímm EüqfffÈår áy½½½‹EÆÇlj¢ß÷I¥R8ŽƒeY¤ÒivïÚE&“Áó}<×Ų,Â0¤««‹ááaÒ™ -Ù,£££LMMQ©VQV=ÚÛÛËÞ½{ ‚Ïó0¦Þ­7“N§Y¾|¹üþŽ@EŒŒŽ10œ'×ÙƒÖ03cxòé¬]½ c û÷ïgffß÷) T*¦¦¦(‹ô÷÷ãû>Zk”R¬]»öy²0-Â("#"c£ˆ0Òh­ifIb5²)ëJ­9”ÚÔ”Àª%ÿêÎÙ× V£ËwFÊ•ZDÂwÑ5\!„Bm@¥RAÙŠj¥J2™”,—ç07@Ùù¡W½ý*îùéOÉårÜø?¾Å–ë‘@¥XP|ßçä“OfxxXƨ¯˜žžºººäÞòšPP>³kåep½8•J K9à¥yjÇ Æ@*™ ¥µD*…RÉtÛV䧦 ‚€T¶Çv( Lä§É¶fȦ³(åH¥©…†dÚ§X*EAÒÞÑE-ˆ˜šž!•Î0<2F¥ZÁ²žçb{>(›PC©R£R P¶Âõ\–õ.&›IÅr8þ#Z³ÊÝx©6j5A㸠¦ !OlÝÁ «úˆùqòùiŠÅI‚ ‘HÐÑ™ 6=M©TÁ±=ÚÚÚIgÒ‡P´ ëåi¡Ž£ˆ(ÒDQý´®‡Ã0¤Z©„!J)×ÃhM¥Z%•Ê`)E­Z¥Z©`».ŽíéAKÝè2n¨gfZ¶= NÖ3Yƒ h“]ÏEÉxB!„8€]»vQ­Uyú©§yë[ßzP*Q·éÏw°áÓý|þï>Ç=÷ÜÀÄø8ùÂù÷o=(•bÁQJÑÓÓCgg'…B|>O¡Phvâh², ×uI¥R´¶¶’J¥d’œ×c Ó33lßµËËP lÂR…Ñ|‰HCiº[[yrÛ>Vwû¬jw°H² kQ½ëµŽP–BkíØ`ÚÐÆ`a0(,ÛbiªÇuûŒ¡Æ²ʪÐÕŸÀ¶ ´¯ë­gÙYõÜ8m4¶]¢}Eh«‡ÿÙLÂô$áQ(”0Qí¸þ]‡aÈÈè8»óX^ ãSjaD™úÌÞX(åóÄÖ§Y¹"ŲU1”J`ŒÆ¶Æø‘ézwë(B©2–ª2S›{5¡å™úµ Ä”Þ@ÄRÂÈéú¹iƒÖ†jµÂ¶§¶266J,§P,ÐÙÙM,ž@Gû¢}„AéÉ)J•2Ùl ñDŠ\[­­9t£û·ž3f¥8 T*188ȾZ²YÖ¯_ßìÎ/„Bq49ÝÝÝLNNÒ¿l™”È F|ê_¦§§ç-žšœ$?]’ò –mÛd³Y²Ù¬Æ+ĉ‚á–rq»OXÐÇDƦËô´ž*¿8qxç7† ©ÖBq—J±J©bHø.ÅjˆƒBcQ®j÷î&ÓÞMS³U={ͲêrµFÏiD1sö¡, =çv;›è¦]y¢9ßÏno5Ö±‘åÍÛËK£k%LX­€xœÒ¦ž¡hŒ…ãØDº†ïÚàB5Œ°-…60:5M&?N®ÕCE ,EèæïY›ÆlÝÏ®†y µ]”Ë“¸Ár»0Ò„¡!ŒêÿŒ®-]?N<žÂqm2v ®ëá8.ãSS”K%”cã'’`;ÔjJUëÁNSI|¯C IDATϬN%By(‰D‚\.GEÄb±CŽ*„Bq48---´´´Ðßß/%ò<6üM?›þ|›®ßÅï¿ã÷¹ùæ›à/Þñ9*7UXö‹$‹R!Äk޲¹–V,5lÛ5D6݆R6Æ@:éS ¦óäriº—¬'ðAi”r~Œxª°VÁO¤QŽC<Óúªí0­+Ó(ÿIhŒ‹x<ò\ŽÝDÑÃù<ÝmmÐè21KeÊ…<«úO 5›#åÃTuœJ­L&ÞÚÌlíL¶>ï~Œ èÌž‹ö L32UÆodRÖƒ”£5¶òè_± ݆Q=ˆfÕǧÌut žÚt¤ëãUZEZþx_èo[)ÚÚÚhkL|%„Bq¬ÈÄ9GRIs¬f ²ö/qîÿÙ/¸ó§÷ÑU^JÇ¿wÒõñn:OÍHA !„xmÞ'•¢½­ŒaëÎAb©6Ç¥Z ˜™œ —±hQ/ž­‰)ÍÌLž©g˜Ø¹7ž V,êè¡÷Ä7àú¯Ö¡gÌkb( Ïóè[Ò6ûÙ?6F¶µÈÊ¥2ÕBžþ%=d²i|Wƒ263ÈDi eYÌT¦É%ÛÉô½×vŸs–åâ;9ªQ­¢F`2Œ""­›AJ£g·QÍnÛõ‰‘ìÆ¬ß³¿ÀRXJ²&…B! RéØœ@åô×à¿_ýߨü©],úÓºÏÈÖ»; !„¯Õû¤R´·çXƒÅægpü,•òÌ¥£È&=ªw©¶žú¸’J1(Û}(_[|Ï£¿¯Ì~vãÇÓT‹³Ê ß&ð08,ïXÅ2³’ P–…­œç P>[}b ƒÂ Ð(@a,kN/íg`šKfçyy® ]ƒAÙ6`¡l»~> !„Bˆ—•)_̘cqògûùÏOìâñOîà”/­$»*!#„BPTv´·²V<¶y íí‹X´hžc‘My8v=äúq H¾ÊùžÇ²¥½Dz/{†Y¾¬ŸL6Ý PÖ'ÒQ$¼ä‹Þ‡eYè(`ßÞ]x^œ‰ñ1&óy‰8Æ4‘ÿ¯Êµ"™îú„2ð9îØ*FkêuxN+¾—=fA=Ëß•L\!„Bˆã•)…BqTŽk»7 M@qí$–å`+é6{Ã,ÇÃ0Ó¨óòµ5ŽÏYK€!³ŽÜ­çñ¼½¥ÀãñÍÖ·CyÂàyÅñJánÄ!ƒ—€ëà\€³0¿`˜_˜ÀZ‡ç%8Ö^¦3Fîµíñý*ÅxN‹þÈm0pãÆ nܼIc·7rE*Œˆˆˆ¸àðÜa’$! CUDDDD^³›-æÖ’å–Ñ(£RŠ)™uäyNšæìtrê†Ð7€Ù % Æ8rçpöU‚D žafº;o‡qn‰oãn»mü½Áàí¿¾×"Í[t׈ƒ ¿¨ƒ+O¬B¡Àôô4¾ï« """rßÕJ•j¥ÊñãÇU¹kÆêµ*';^ºtƒr¡AÉ3K) SÚ­ MOrèÐa|cHm›ëÍ«L—gCfSf«sÄÁƒÿÐt”mc]Ή¨È“Çó<FCÅ‘ûJ 爈ˆÈ0ÆP¯×8s^øêiÖ Šc†ÃíÖ&‡¦êÌÌÎú–bâ±ÖnÓî0Êúlv×H‚"b8¨=${¤€RDDDDä¢RDDDŒ1†F½ÆS§Ï¿tn¿@>êí”q`¨—#<ÏãPí³Õ9n<¥ñ}M=#""""ò$ÒLð"""r ÆAe§OͶ¯2[/23;Kj»%@à„~HäGÄA¬€RDDDDä ¦ž”"""r lš2tiT+¼óM'ÄÓøÔŠÁm+w‹ˆˆˆˆˆÜ¢RDDDŒ³9íÍe6/?.àlŽçßÀ‹"â#'(Ö§T$y ÷‘Ä q¹Ž³–¨PÆÙòãû*Îc0ÆÇ3ºô‘‡ô}„J """Åx>¥Æ ¥Æ .O±ý¼B £ù&–#¤ˆˆˆˆÈCI§‹ˆˆÈ}ᆲµ—qƒŽŠñÀÌ} ( c @EDDDä^¨'¥ˆˆˆÜÆÞî×'f§1Æïáڞۜިƒs9Åä4’å)ÁõlÍò”ö°E©Ï“å)Æxøž†ö‹ˆˆˆÈÝQH)"""r\ž’­_&oo^ÿöì3xqù¾¦a6àâÆËìôš£íA“Z2Á[Ž>{ÏA¥ÃÑìðÜõχ ž hõ·89}ŽÓ§Õ DDDDä®(¤9ÆópiÛÛ"ßÌ0ÞƒŸ‡3ô#Wç™­Ì1Hû4Š£òôt4 a‘S3çðM@gÔf²4ÉDI+¸‹ˆˆˆÈÝSH)"""rŒO0s¿qŒðä›1aüÀ_Rè‡ÌV“å=úÔJqá@/ÿ Q‘ùè8YÞ¡4P-T;‘×E!¥ˆˆˆÈpÎñ{Ÿþ"—×Ú\û­Oówžþ6jµú]£tÄÿþKÿ'—/_faq‘ŸøØÇð¼ƒ[;qss“ŸýÙŸ%Ë2>øÁò|@ADDDDîšBJ‘{äœãS¿û»|öOÿŒøÈǸòò |üãÿ˜¿õ·~’Z­Î(±º²ÊÎÎQ‘e“S“øžÏõë× ÃN§CEÔëã`szzšrùÞæ´¥#~å—…ajùÈý'üþïü?|ò‰þøáyý~Ÿ¥¥%¢(b4áy£ÑˆÁ`@¡P \.säÈ‘W 6777ùÄ'~óoz;‹gßħþå¯á|çwŽƒÊV»ÅÕ+WI *å2Íf“v»M½Ñ Z­0;3«Æ#""""x*ˆˆˆÈëçœãw÷÷øìgÿ”ïùþ059Í›ÞþŽ<ÏÏ}üçÙÙi’ŽR677ÙÜÜäóŸÿ<ëë묮¬²¶¶Æêê*qÓn·¹¶tþ`Àh4¢ßïßÓëÚ (ûƒ”ïú÷þ*…B÷}ðèR>ù‹¿„µ–~¿Ï‹/¾ÈÅ‹¹yó&­V‹_|‘­­- …N‡<Ï_ñü{å©§xç·}zƒïøÐ_áÓŸù,¿ó©Oa¥ÛéòòË/såòe–––h·ÛcHâ˜V«­Æ#""""û€íím²,£ÙlrâÄ |ßWeDDDäÉf<Œyå çRé6¸œ$:ħ~÷÷øÌg>ÃÛßÿ—±~‘Õ­ÎÁìâ[I³œŸûøÏó?ñPŸœ"ÃãM3‡¥C¬ñåŽÙ¹yªIÎJl7·)–«LMNR*&wõr]6Âö¶1q‰Ì‹ø•_þº½oûöï¥ÝÏ¥Crç8÷öïæËŸýÿøä'‘þë?Ì;Þõnj+Ë« ‡CÎÔ'1ÅRgsÂ0Ä¥lw ¿vˆÍ­m>ñ‰_`îøiŽœz;Í.y#Sä[Þû}|æÿÃ{ÞónÞû¾÷RH \»vz½N’$KÅY¼Gî¿Q:¢ÓîÐétˆã˜©©)½W‘û"h6›\¸pN§ÃÌÌ µZM•‘'–s–aºÂjóßø…;îKóëí?`³óyn|é/°±œð¾ý7¶s¶–¶(ÄÃQ ξƒ(Šùøÿò82³w}ewÇs~îU_ƒ»»gäí5\ž±eê,œy3o{ïû¸´Üb4êÇ!Ý~Jø<ûÞïåËú;ü¯?û?2Q-¼†z¸qH¹s•YO œ{ë»9râÍôú#šíŒAj¦õr‘÷|çò¹?úWôz]¾ïû¾€gžyF ë”e+++\¾|™ÉÉIêõºBJ¹/€ÙÙY¢8bccƒ(ŠTy¢ãxB¿JܹøMw(Å |Ž}ë»ù_ý4×¾úeŽž};Y–“D>ƒQÄ0ÍôÛ|õÅ/pâäž}ú¡ïÀZü0ƺÏ ·û?wO¯Ùõ[Œ®ýxå³|ê?ÇÄìQ榎Ѧ„¾¡’„¤¹esý7o\áÝïx–“G¦ñÌøßö‚ñë1ÆÜA©m¯2ºÔÆ›}Šv |åùÏ3{ä$Q«ÄTô9žç¸zñúý>ϼåíäÖâ{šaèQ•$ óóó$I‚ïûºè’ˆˆˆÈ×ÙÅb‘b±È‘¹#ªˆˆˆˆ¡_¡R8õŠÒ›0Æ ûØy~á> ÆðÖ·i–Sˆa§ÕãÿõoræÜ3|û>Dìå¸ÖMÚkKDA6À#¨@õÐ1‚ð^?(v¸gßÙ >'ŽœäŸþú¯ó­ïÿKÌ?Išæ” pýÚe>ÿG¿Í¿çû9ûÔ3D&e¸ü2é¨Oà{8 LŠqúጹíùßõ1žÏé<'ù7¿Ãïÿö¯óÁïýÅR…Ü:бåù/|šë—¾Â‡?ò£+uÒÌáë3ðG÷L0Õj•jµªbˆˆˆÈ}¾‘Wp8œ³¯rÙíi8Nïf¦§ùØG?ÊÒůð¹Ïü>ÖA³¹Íþë6(ÿÂIG¥àãû.ÑY]bØi²³tÎÆ26Ïà›Ý€rüýÓçÏñáú0ŸþwÿŠK¿Šu°tõö‡¿Å¿çû8sö) ‘¡œxx¾Ï¨³Cwk…ak“æõ ô›ë8—}Íó‡ùú¾Ïw×yÛ³oãwþß_e»Ù"Ë-Ïÿù8 ü«ùQ ªÅ$ÒÐ`ùæ•@DDDäÞÌÌLó±}”OüÂ'G¬Þ¸x+ Œú®‚ƒßÿí_ãð±3¬,½|G@Yˆu©)""""¯zRŠˆˆˆ€™™i>úÑacù§ÎœâýßñÝw”Ïð‚püÕîS@¹Çðôùóüµ¿öa.<ÿjåøuãáù!žï¿z¯mîAß÷ùÐwgΟæú¥çøÁü (EDDDä®éêQDDDä€ÌÎLðŸþÔ¦|QL Ã:#çŸ:ÏOÿôOÓä8çî(_/ç,£^—l4à-Ïœgcu•Ã3ħ€RDDDDîš® EDDDîQf3¶:¬wVh§ñLJj¯F³Ä^òP¼FÏ3TŠwé—†ìܼÌö‹¬ït zl~ñßP¨My+Aœ¨aˆˆˆˆÈk¦RDDDäYgé¥]vú;t†mZýqS/4ˆƒÇ3¬óü€Bc ›¥´Ý*~¸E¡>ER™À C5 ¹+ )EDDDîQè‡Ì×1W;Bf‡€‡ï…DAüØî³„T¦æ¨LÍ1ˆ.]¸Ê‘g¾UADDDD^ßõ¥J """ro †ÀñLÎ(½ ®E$Ìã¿óÎâmlÚSC‘×M!¥ˆˆˆÜÆ`‚¼'ià†Ãºçò'ñ€«Í‹ˆˆˆÈë¦RDDDœK¤7žgðÅÎðâà¬}BöÜ`0X—©ˆˆˆˆˆÜ…”"""r®0|\ž’-ý ¶»…ñžŒ^vÆŒ q[íÏÑ^;ðsŽœ<ëâû%Œñø¹-y>$ëUM­³l7w¸r}Úä<ë;=â £?ÌñŒ¡GD…ˆëËô² ?~ëzÃ9‡sŽ‘ƒ¨fÀ9bcp»ÇʹñÚ»mhƒîxŽKc D†žS€¨À+†i»Ûžçè;ˆj»Ï繃òÔø1Ö:¶ûŽ,ëƒZñœNy¢Yk äyN­^#4KDDDîàÈ‘# ‡CŒgð<­¥#""7cBꥧ(' Ü1½YÞgeçß2YG¥RÅ9ÃFgK/3Už!Ës27âÔÔ9ÊIEÍSäaùMi< …‚F[‰ˆˆÈðMDDD˜ãI]u¥X(púäQoÄÖæ6ÖWàt¶wÊ ÅħXð ¼€j¡F–§4ûØÜâ{¾šˆˆˆˆÈH“ʈˆˆÈ* œ=uŒ^¾ÊòÊ2±ïn (*…c`¦zˆ™ê!LDDDDDRŠˆˆÈÁ+ œ[œ%ê?G<µHµZ£˜x”“q@)"""""r;…”"""r ÒA~k‹B©ÊÉ dq|G)öPŠˆˆˆˆÈ«RH)"""Æ9Ë Ýdí¥?ÇZ‹8›ãœ|†ê̼Š$"""""¯ RDDDTT¬Ð8v–lØ#ˆKäi/I* GDDDDD^•BJ90ÆxÄ¥ q©‚Kûäí5üÊQL˜¨8"""""òuy*ˆˆˆÜ.7oàF}CDDDDD¾!…”""òÊ?&Àu¶ý Æ„xOz =$à«-=îí?ÀhU$¹—·*ˆˆÜ.·=®®ÿ—×~µÖ© wɺ!«Í?àòú?áÚæ?ÇaŸÈ:¸´ÏðÒgéýáÏ3xþ_âl®Æñ¸þÎè¬3øòo‘7WIo~Y‘×E!¥ˆˆÜÁ˜€ba’‘»N99¬‚Ümýˆ£)Ù5"¿†yBÿÔš Æ/×q£ML\Âx¾Çãz¬½Ä8;Â+O© """"òºhü•ˆÈcÂZËòò2;­,K £¸×ò·m”æ3˜þ÷sõb ¼„û&Ïðµ÷:çȳ ?ñ ÌÎÎ091ñDc|ªÉYæ ÿ!3Õ÷?û4JG¬¯­³Ój›í7n;;÷ƒxé æ…—øz-Ñí¶›[ŒÏ÷)$ Gç†á{NÛ)þS GûçÕ}RíÆg¸1††Ãnpú¯Ì¿ö6_¨áüp¸uëM¢8ZDDDD^…”""‰4M¹tå:©Cdéˆ+×–yêÜyrkqnpÀnä€ÝèÑYÆ’cwœ› ˜|;Ãt÷¶ñ}v›ñW‡ÃZvƒÐ½Û`4J¹våÇO‘ކì´.ñîw=!ežç\¿±ÅÚòYì`§ÎVð¾¦á^ØdÅ0nŸ¬³xæáé9踺t“J}ša¿ÏÚúÇpvïõ:œÛk#ìï‚)Ü᜵ØÅ9»{ÿ^{qØ0¦9[[Ô“ØÁ2ÕJ™©©'·gÞÖWZ Û#üß#Š"6ÖשOLEñîù¼{.»[çÞþù¼[ßñ1r·êîÜøÌß;V8ú½íS‡ÈÛÜonÝUHyã3[¬~ÜPnœàsÿÕWyç?8‹<¸ù)¶óGDDDD^…”"" c q’И˜"M‡Ôwv¨OLᬽ#@äŽh|ƒµ·…pGØ´×ËÊÝjp{µ÷ÜÎaÇé'£QJkg‡‰É)ƒ½î;Ý”j1äq^[#Ïs–®ßd}«ÏܱšÛÛ<ÿ• µZz£Á ß§Õj‘œu ò<'â8æØ±cDQ¤? """"˜`ii‰~¿Ï7x÷»ßM’$ªŒˆÈ} ,ÔÙA›ÑÕ?ÃÍžÇaÈ2K–ž,ËØnn±¶ºNúth f¹ÍÁ¢0ÂzÝ.¹Í ‚qLëQ,$ØÜ’[G©T$ŽR”^¯ÇÆÆ«kk”K%N:õDÏ+"""÷Oàùëë묭¯Ñï÷RŠˆÜÆ`üˆÑ¥? ½ù¥{ZÛ]gðÇÿ˜lòùüß$;´H–»Ý¡‘)^¾@·Ûebb p„aÄhÔÃ:¸ðòK4›[Xk9<7O¿? ÓiQ­ÔŽŒ†#<ßÇp$ÅÇŸ`ÐÐ ;|鋟Çôx¾Ïôô 'Ï>M¡XºõÃ_ú4ö¹F×€íüÇð(®xíkpkÌü­»¶ûŽËùqæO>Åf³ËNgDztú)QèÓ˜­°¼z“΃œÅ)ã G+Û”1³¸ÔV="cèÙ€Ú!Ÿžý2ÝöíAÒÁÑ\ãzóÿ&t'q£¢båŽÜ{Ônnm†,ËH EŽ;ÎÕ«Wxñů0==Kœ‰£˜ ^À÷J•k ûCr›3 Éq û“Ì=N-Šõ{âUd¹%ËóÝÞŽ–<¿Õå9ý~Ÿv»çŒFÃñ¹ã±|ã*¥r…C‡’ï’ÖÞ6/è~»ò0Ùí-þ‡ÿíS»·ýæ×}]ßóã?Náé:ÛíiîHSKw˜RˆCâÿ¨Në^幟ûSr¼ðOXñÉmNÀd,7ÀA7—;Œo(NBp <0·eC.¯`Ìmç ƒN>µãxŠ8þ5šƒ|³äyNs{›t4zÅ0|‘»î˜žž¦Z©²¸¸HµZUUDDîㄇž"˜>9{ ýĶ·… ¸ùwâ–zdiJž;²Üâð9{îM †}<ã±¹¹N©\¥X,F1ƒ~Ÿ^¯‡Ís¬Ï]é{>Q”Ðív0ž³·zmËUÂ0à©gÞ @¡P"Œãý!¾Æ*åÊîcövìÜÛ0o'Iç2…gþ˜Gë ®³–~{?ˆðv‡\Qa–#‡¿“jœ„ŽQ6¢&~°;7ßÃ6?\¦˜%tg¹rÅ’fÙnHf ¢„§ÏøI¡‚(æíï¬Òív1ÆE žïSŸ˜ÄYšâŸ4σÜ:²4Å b”Žô‹âUä¹%Ý (³Ü‘ç»”r I±ÌâɳøAˆçyxÆ#Œ"šÛÛ:rlÜëЃKwÛBGw.¸nqAD­ÞàïüðwSð†Ä§¿Q·‹s9ARÂå)~\äÚ¯såg¶|̧|º€ï{àÃ4'åôþÑ6Qœ°ðãç¨c<ÏÒõHÂìN1aðÌAµVŒÖè .íþ¤~¸eo>ÑjµŠçyJ/"""÷M…Ñþ$æ""r?‚Ì£üÚ¥oý1†Ãöêsd¹%Í-YæÈ­ÃCÊQ ÖQ¬ÔvWüu8,I±D¡XÙ›kñK¹Zß_-xw¶;òÝ8ü`¼ºðü îœ4Ð[K:Þ  Þñg)–ÞýHF6²yíé »¿˜ñ}Ji{–(Œ9¹xŒ—/\f«Û¤Ö˜"ÏsªEN·C¿»ÍÙÓ'I’ÏltnðÒÊ—i”&ÉóŒa6ämÇÞE).?Tû].,R.,²ÓjcíEòÝ©¬ƒR©J©R¶û³š†¥Êx!”ñ°b(«ûmÈî¯ ¿S`<5ÁæÆº²¥W‘çnÿƒ‡ñÿÝnH9®©ñ<¦¦gÇsrkø¶uŽéÙ¹ÝE‹Æ·ï“oü;Ê'8ý~ ±!íwÙºy™Þæ*xƒ‡†$35þó9®üÌ&ÞÇ É›«ä™Åe9íŸß&Œ<ÎüÝ‘gºÃ¾xýsÄAL!*Òìp¤~œÅ©Só{‡g"ŒÑtëþ7Ëâ8&ŽÕÓYDDDî/]ɉˆ<&ör‡,w8;’r»·âöxè°/µ<þ~µ»¿PÎÞ-ÎݹÍ×elsûŠWavßÔcƃºw—ó66=’!”ñ}ª³ót·×ñƒd透ܨß& ΜZ䥯^fumZc’N»Í°×Ü(+…€BâSÈŠ,NÂ:GgТ—ˆ‚‡;°ÒýV/œ“»¯i+{ß°»ÿÙ 0_­9ÜxÚR7á±^þ®ÏkÇxá©Ü‘çãs:wîÖ"Xûçq¾ßYw{GÝ w.`娫»Á0>oq`lxAH©11ãE’<Ïæ)Q±Ê¡÷Æx>—ÿûU¶ÔŸMhÿOûeRð©•#ß#´!ócø^@«ß¤š4ºP^DDDD,…”"" çƒÁl§sív›V«}k¾9w+”¸-¡¸ ݶͽJÓ”^·K·×c8B–=Òµõ¼€ú‘Ôœø†Û…aÀÙS‹¸ —¸´t…BÜP– ãaîS•¦*3Ìþ[kŒZm²Ñ€V»M«ÝyE›Úµï¶-CžÛ ’¤Èp8|ƒçà|ÏiÀ Í?o1ˆGô7ú4oìЋ‡»uv_ss׫¡;ÃAQsD{«Åp{H0¼5g¬FÔ/P;¼ðª?þÞYø/àò·J»Ú"¬œù»‹w”¥¨ÌÉé³úE-""""_—BJ‘ÇDøŸŸaym“n?¥ZŠimÞàAä<ÎYÕ„Ak0ÌÎÎðŠN—ëqž:s’Ré&^X&Žï (E…$fþÐË뛤ý”bìÑÞ¼yÀmÆyéxnÁÖ•$¦X*>ÑAåĹ Q% ø{9¹íS³EŒ’™œ»ÓA„cÒÁtI€â_,‘篭îÆŽ}Û4ü×n.ÝàÈ;ßúŠ€RDDDDäµPH)"ò¸üBÎ=Í™3Ðì¤û½(ÄèYc Ö‡[ëð=÷ ŸÅãGŽrrë(%öŸÛ$IxêÜNŸv´zÙýk[Æì·—ñT•vwÎÊ'SR‹xÏ'Γ[è 2²|wxöŸ¬€Ï :ž‡Öâßż¹¹ëÂé?&œù4µ©s”’†J¹û÷Q*ˆÈãÅ30Q UˆÌIä?Vûøæ i[Z›ùN¾•âÃ{É–å}zƒ›ããæ­“:h""""r÷ï7Ty˜( |´$Ñ4‹3ƒÎà µâyDDDDD^Å‘{ä8°•·DDDD䉤RDDDDDDDDD(…”""""òÈsXÀ=Ñ+‹ˆˆˆ<Ê4'¥ˆˆˆˆ<ÒéWוÍÎqÎ2S{¯Š""""òˆQOJy¤EA…zå …¤L½|Zy©'¥ˆˆˆˆ<ƒÁ€¥¥%Z­¹µäYFÇã;{Õ¥x¾v4÷x+C–éßÃÖoâ¸ñªëø¼ÚPð½[²,¾P.9ztŽF½®ƒ$"""òQH)""""Äh4b{§ËÄôúýkk«>v k-ÖƒÅq¶8Ž#÷~vn|ÿxJpî0ΓÛ‡ÃYƳTÚñÊãÖìþó?ÎÁÚÖ ÖBc¢F{«M¹Ò¦^«cŒŽ“ˆˆˆÈA!¥ˆˆˆˆ<Æ‚0$J¬µ$I8IpöVɽ޷ÇñW{[WI›ï˜.Ü/­g÷¾ßÝf÷¹Ý =Ç÷ E,P,é¦Z½œÁ(#‰•""""o€;BJk-ž§i*EDDDäþs€µg–Ì:òÜ‘åç,Î:rgñðv{?:Œça­Å즆v?™ ¸Ü1X7:nA€sãíÇÏaÆÁ¤g ÏÙÍ0wCÐqô¹÷½ÕBá·Ž•s8žÑ{¹?€Ë—/ÓjµØÞÞæmϾj¥ªÊˆˆˆˆÈý寒g¹%ËrrëH³pôº].^ü*ÃÁ€<ÏI’‰InÞX")IâQ³±¾NµV'ð}º½µzƒ$)póÆi–Q((–ª¤éãùøÆ#·9AR,UÇ=7§¥ò ½^7o²¹±A¥RáôéÓDQ¤ÂˆˆˆÈ ’$agg‡ÖÃÁ**ŒˆˆˆˆÜÖ¹qH™Cfsò|Üc/ËÃшõõu¢(&Ë-…b‰~ÀêêAàÅ–õuŽ&qsö©7“å9ÎÂõ¥kXë°yŽ„ŒFCvvš4“œ:ó3‡çÁ½ê:;a@ÇäyN¯×#Ë3"RŠˆˆÈ}¸î˜™™¡Ñh°°°@­VSUDDDDä¾Û›2Íyž“çåã!מ2t‘……Sä»SÅq©™Ã»Ûæ8žgØÙi†Z½µ–(Šé÷û8GN’e)`°Öá°ãEî¶áãòJarøða&&&0Æ$‰Š""""÷Eàû>¾ïë¢CDDDDÞP¹µäùÞœ”ãž”–ñü“ÕÚÄx½žŽÎù·¦Tß[í»Pªì¯ø½·HN±\Ù}ÌÒUÒÞz|Æ‚ ´Þ¦ˆˆˆÜ_ºÚ‘Æ9ÈíxœÜB¾{Îù­aØûa£½ã±·ÖÎqß0|5ž1` Æ€ñ›ä×nþ³Fƒ¡¹µ9ÞÞFý“µE•""""o…”""""ò@”Šž:u”µ&mߣMáÛþk{°y·½F³“epàù#êS5ªÕºF‚‹ˆˆˆ¼RŠˆˆˆÈEÇeþè<ÝÝŸòA0Æì÷ÜtÎáœÃ÷Õ—RDDDä¢RDDDD(ß3T‹¾ !"""òóT¹'Îá°ªƒˆˆˆˆ¼nêI)""""¯‹Ã‘Ûœ(¬Q1 *ˆˆˆˆˆ¼n )EDDDÜ“1—áN¯É +ÏQŒÊ”â*ÝáŸ1[9Ì¡Ú5¹+î-"""r@œ³@Î>ößc ¥¨Œï¬¶nÐêï`†}‹ˆˆˆÈÝSOJ‘à°t—yáÆß§ãÜÜO‡õÇv †Z¡Î›Ž| ÖH³.I4©† """"¯‹zRŠˆˆˆƒGNP+ž£”Ì…µ'c¿ ¤ù6ÑKj""""òº©'¥ˆˆˆÈ]XMPñ~Ÿó„ÌKi-t;9[–©²ãI™SDDDD–zRŠˆˆˆ€4MY]oråšãƲc}csÿ>ç£ÑˆápxOÿ†u–ÑhDžçÅ>[gi6[¼|±ÉvsŠKW–À¹;jr·û|PsZºÝבç9išîÿ,""""'õ¤¹Giš²²¶ÎÊF‡CGæ \¼º†s03=I»Óæù/=O†Dq„Í-Aàû>Î9jµ•J…••‚ Àó<œ/LÓív‰¢ç­vg-µZ³gÏ>Ð}”;\º¶J}âøëÛ›X{•S‹Çé¼ð \¿~…… Å"ž1xž‡1kÇë^<Ï#ŽcƒÃá0 é÷ûA@±Xdccß÷) ‹EªÕ*«««”Ëe¢(buu¤££4e¢Ñ Ïs†Ã!GŽabbBUDDDä! <ßÃæ–$IT‘×(MS–W×YÙhSŸYÞ{÷ÔÑ­°Þú#&Êï LséÚ:™Wa{{Dž÷É2Kf-I³¼5ÄÚÎ*±˜µH >Àh8¤ÓiQ«5ðŸ( ±²gÎáû¾ìþkgyžáy>Ö:ŒÇn]-`‚€¹é:a†>öÈ,çÏ,yž1¥t»=Êå"år‚G†eW‘QòìŽáí£~¿Ï¥K—X[[czzš³gÏDZN~9pÀúÆqï9‘o®×pseƒbeŠæÖ€íÖ€0ðÈ\Nà{x^@FÄs/ÿ9OŸCQæ1Žán[d&µØ< ý||-f‡’äàp ½¾Å±ûð7Pgp…«[ÿ„›[¿O2úëX³HEØ~Á('Í,o0ÆÃ ‹\¹t¤÷'”/ý ‚Sï#,&„J°yÜî>1û?ïñ ø˜;ë´÷½s` €³dÆ8ƒÃáH0$}Gºî¼^ÎføyLXx¬Ûø`0`0àû>¾ï뤑û&8sú4A0þäºT*©*""""¯A¥\âÄñ9.\Yanr’#SeFYNž[0†tÐ't9µð­”“Å‚£;l“„%¢ Þí÷ð¯e8Êš4Êo¦ZxŠÑ0à«——¦†Éz ›çd¹ÅCš¦ôÚ[>~šdòYâwüeâÐ'œ=«ó(¶ñj…sçÎaŒ!Š"Â0TQDDDä¾ ïy<Ïcr¢sðÒ¥e Õ)âÐ'÷=zÝé ÅâñyJåïè [A?¾‘aDcþ•é9¬µøÆ`Á"”""""r×4›¹ˆˆˆÈ=2Æ#LJDq„ißÀ¶ˆKü0zŒwÚ#L ª ’¼Ö5еIâRE BDDDDîšBJ‘âlŽËFOÞtŒy†Ë35yÝRŠˆˆˆgq£ùÎMlg—§OÆng#òelg;計ˆˆˆÈë¢9)EDDD„#ß¾Fÿßþ}ü¹o!<|üð±ßkÛݤÿ¹ÿ‹|íÁäÞÜÓj """"r×RŠˆˆˆ¼ ç,iš=±î›<À@^œÁ{úñjódø¸ÑóM†~{Æ`Ã3?xcCÍ<ÏÉó ŒÁνŽ:…e¼3–¦q‹ŒF£q9îrÈûƒ¬ƒˆˆˆˆÏfóÔ½^šy›ù|ždÑIY¥: ìNǶIUUišrb.²½’Òæ;Ï-»’ö$Ô+¥É¼ir8œg2iÓ_ëû:–’”¶Ít:ϼmÒ´M¦³&ͼ9Y¦Å2¦$©ëE8Ù–4¥=­PÚ¶œ–§÷w7M{Ömzn–¯»GÛæåîʶmSÒžt™6™7mŽFÉxÒdcÍ©*ÀeÑO’/^¤®ë,--euuUU€Km˜%󦤗6ó¶Í|ž”4G éõzg•W663O²²¶š¤NIu’ãUiK“¦iÒëõÒ´mÆãQ––VNº Û—n¯^sãà¼-iš6óy›¦)™ÏÛ´Ms¶ÿ÷ßg0¦îÕiÛ6wû×Éú•\½¶“ÍÍ­¾8È•<úãd2ž¤”’Ùlv21O/«««y÷ÝΛßKÓ–³±)Û¶ü÷fìᵘN¦ùãç`?·nÝÊ{ï½—^¯§0À+×O’§_~™[·n¥®…“Éb6ïÒ´)©”'å`8L[JÖ×73™ŒSÕãÔu?×¶wr<fii–¦ir<8Îl2ËêÚzúKKYY]Íêú•$‹™¬Û.³¹“q4gÍ¢S´™—Å׿ë…jš&£Ñ8ÓÙ<[×¶Ó¶M–—W³²ºžÛwÞÏîóç™NÆi76Ó_^ÎþÁA¦“IêºÎÆÆVö÷÷3Mrug;W6¶ÎÆî,¥M{ÚEiW»ÐÆãqf³ivvv²½½­‹87ý$ùèãRWuú}ãþääVìfÞ¦¤^t6mªºŸ›·ÞÍ›ßKUUg݆u]åÚõ›)¥I3oO_"Óé8MS²²ºvr;sIÛ”TURšŽWqqKö|þu@9oÚ4M{Vƒ¤ÊÖµüå_}”TUªªN]WiÚ6×¶¯çÞž¶i’*iÛÅø’õ7B¬;§¯S’6mJSNƼäM±s}'W¯^M¯×KUUBJàÜô“dyiY%¾¡-ɬ-é7Íb¼Æ¦MÕkÏÆQ<²=¹[µ*Uþßóȶ-©êE—^}Ò­WÜpé)¾¥®’¦™æÑ>K[Õ9ØÛÍx2J¿×{iŽ—ÿI¨XJ2g8f6'í4;›w_Û:–Òfpt½ƒã GƒŒ†ƒÌ¦ÓE·äúó圖#‡9>>N3›¤mæyÿλvB€KFH ð-ëëëù«¿üA>¸?ÊW/Æ/M&óÊt]Ö½:ëëëiÚ&ÉùÏž¼½}5÷·çàx”ãÙÙrtâ´ë²”Ô½^ÖÖÖÒ4SU€KÄ™Àbyi9Û×–secóµÜ†]²Èêz¯iø¿ºZ„¢+«ëÙ¹vq&³9«ƒá+ÕSA¦ IDAT.!%À¡ª’•·|Ò^ô–{662UÐ)!%Ð)!%Ð)!%Ð)!%Ð)!%Ð)!%Ð)!%Ð)!%Щ~’ìîîf>Ÿ§išÜºu+ý~_eà’›L&9<<Ìt6ÍÚêZ®]»–ºÖç¼zý$9::ÊÓ§O“$›››ÙÚÚR¸äš¦Éîîn²½½+W®deeEa€W®N’gÏž¥ªªŒF£¬®­ª Á`áp˜Éd’RJz½ž¢ç¢Ÿ$}ôQJJªT*$IÞyçܸqC!€s×O’ªª”ÀwT•ëàüõè”è”è”è”è”è”è”è”è”è”è”è”è”èT?IžŸ+ p.úI2™LòÁ÷¿Ÿ?ûÓ?ÍÒÒ’ªiæMÖÖÖòÃþ0›››î¸ÎM?I>üðC•^²½½íím…Ήs€N )€N )€N )€N )€N )€N )€N )€N )€N )€N )€N )€N )€N )€N )€Nõ“äÁƒÙÝÝÍd2ÉÇœ¥¥%•€Kîøø8Ož<Éîînnܸ‘{÷î¥×ë) ðÊÕI232 rtt¤*@š¦Ép´¸V8<<Ìt:Uà\ô“duu5÷îÝKÛ¶ÙÜÜT U]åÚÕk¹zõj676³²²¢(À¹è'Éýû÷UxÉÖæV¶6·8w}%þܽ{÷;ÏÍf³Ìf³ÿÖë™Ýè”è”è”è”è”è”è”è”è”è”è”è”èT$mi“$¥θF^‡~’<øüAžûì³L&“K½ÍçóËh4z+Ö§-mÙÛÛKÛ¶ºÎÓÙ4ÃáðÒO·û³gϲ¿¿aÞ?§Ëµ··—áèÕo¦iòüùó<~üøÂòøôôéÓ<þâñ¥?xU: )õ«_å—¿üå]¼ýýýüã¯ÿ1ÿñèÑ¥ÝÚÒæË/¿ÌáÑaf³Ù[±>ÏŸ?Ïþþ~>ÿüó·æBê׿þuŽŽß¸eކù—þç4MóÆo‡¦iòÅ_äé—OóàÁƒ ½¬£Ñ(Ÿ|òI~ñ‹_œ[ˆw¶Ç—_~™/^œËëϦ³<|ø0£á«ÿeÇx<Î'Ÿ|’‡¦ªª ýy: óôéÓKsLlæ‹÷ù'Ÿ|’ÿýOÿtaŽ‹óù<?ÎßÿÃßçáÃ?œËgÆ£Grtt”gÏž]Šm=òé§Ÿæ·ÿúÛ€ÿ¹~W'Ë7oÞL)%óù<ý~ÿ,ÞÚÚZv¶wre}ýÒî@uUgkk+ÏŸ?+:®ªTY__Ï“'Or÷½»oÍ6ºyófš7°»eyi9?úÑrýúõ7ߪ«\½z5OŸ>M]]ì‘6–––òƒü oìçóÿõ}Q×ÙÜÜÌêêê+íRJ†ÃaFãqÖÖ×Îeû|ø‘^]§iš »N÷óÃÃÃìïïg{{û­?&öz½looçÞýûÙÚܼ0Û¦W÷òÎ;浪ª,--½ú“É~?›[[™ÍfÙÜܼ'Ðý~îÝ¿—µÕµK±o¼–ëæRJQ^ÅEùEîèaÑÕtÑÃ1À1Û™Ëá§?ýéwžûÉO~¢0p‰I,x%\”¼ov%àí À%µ:%¤:%¤:%¤:%¤:%¤:%¤:%¤:%¤:%¤:%¤:%¤:Uýìg?+½^/ý~?IRJI]×iÛ6¥”$Él6Ëd2I)åìï¸êºNUUéõz©ëúìoަiRJ9»¾ë÷ûgùßiXUÕÙÏŸæ‚§×…ßüþÛ¾úê«\¿~ý¿üûªªÒ¶íKÏþßMÓ¤išüÎÔŒau_µIEND®B`‚rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/gossip4.gif0000644000177700017770000001146512633765070031544 0ustar michaelmichaelGIF89aóáç·  !!!"""###$$$%%%&&&'''((()))+++,,,---...///111222333444666888999:::;;;<<<===???CCCDDDGGGHHHIIIJJJKKKMMMOOOPPPRRRSSSTTTUUUYYYZZZ\\\]]]^^^___```aaabbbcccdddeeefffhhhlllmmmpppqqquuuvvvxxxyyyzzz}}}‚‚‚ƒƒƒ„„„………‡‡‡ˆˆˆ‰‰‰‹‹‹ŒŒŒŽŽŽ“““”””•••–––———™™™ššš›››œœœžžžŸŸŸ   ¡¡¡¢¢¢£££¤¤¤¥¥¥§§§¨¨¨©©©ªªª«««¬¬¬­­­®®®¯¯¯°°°±±±²²²³³³´´´µµµ¶¶¶···¹¹¹ººº»»»¼¼¼½½½¿¿¿ÀÀÀÁÁÁÂÂÂÃÃÃÄÄÄÆÆÆÇÇÇÈÈÈÉÉÉÊÊÊËËËÌÌÌÍÍÍÎÎÎÏÏÏÐÐÐÑÑÑÒÒÒÓÓÓÔÔÔÕÕÕÖÖÖ×××ÙÙÙÚÚÚÛÛÛÜÜÜßßßáááãããäääåååæææçççéééëëëìììíííïïïóóóôôôõõõöööùùùúúúûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,óáþo H° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹3jÜȱ£GŒBŠI²¤É“(Sª\ɲ¥Ë—0cÊœI“äÇ›8sêÜɳ§ÏŸ@ƒ J´¨Ñ£H“*]Ê´©Ó§P£:…§*PR³jm ¦ ®YlK–§W AÅ€¶¬Û·©bè CQ!-”Ë‘ïF¿p42‹®‘[Ú:„„€£[„ cŒ,ÐÕá‹”oYÌyV£ƒ` Oô º"iƒ`LFÍ9°W„—%¾>;âìÁo¬Ýzë …s!þVüáð„ÅG˜¼·T'·•á"wDèÒ©[‡ˆ}zõÝ»þk/hÃùX»­rÜ ðû-Ý Ñ«gÿi½ÀÔåÛOdÿ~á·¤×_ÿ™'•]²ÔGI}õ „…D*Ø BxK‚·,x‹üÝò`~JxËìyh V¼ Ô d¥xK\äâB)–Ñߌ ¥˜H”Ââ‰R­–b ‰‘y’ )i“@6…cyMI‘•A‡•QJUà@86ô¥ŒP69æf—K9qÉ@œyÝ›ÅyKpˆp…¹ §œÜщ l>ÕFŠ,`B 7Ü"AH¥x¨ENDRè¥éR£š †“á*GNLŠé©5€)6Ì2EþF4wI¬9¹bC™¨æjÐa±Ü- kêFxªë±CÚ0êGƒ+²Ð.ä ¡}ä ÕF«­E `á§E8†)Û–ËQ]Ná— l°àá„ ¾>kî½øæ«ï¾üöë¯N6þ+°G3$ÅŠ}B!AÌoÁ !\P‰Iì°¹ä#…êI¡|"‹}ì•ø‰È¶÷IŒçºÈeÌ1G(IÁžñ—Èe”ј@%÷÷ =ûx!Î¥ŒÌÅ-³Ùsϵ2rÇÑE'ËR22{šüÇÈ­ Ä5Ö6Ýå=K2ÓfG uÛp7D)q×­P&vç­÷þÞ|÷í÷߀.øà„nøQm8!¤gFgïá—ÎÒªB–¹Â6ä¹:!C›bÞ%(±‚2k[kt‡úè,ë¹.º³žÓF›±™b„‹¥çh{E¼×N޶˜PñåñÂk¦Ðæ= ýCÒOôì㯉¼CÚ¯Ðö ­‰;àv--ô@ZBT~Ð/R"Pú­ßŸîß¿CòS\âý‡Ûu ÎRðÑŠü§>°î+‹dÀ %íIÈ“ÔÀÞ¢ ^jŒöõ® lŠÂ†¦‡„pCb“‘DNX°•èƒ~; Ôs‹_‰É C+‘ 2¦OÀH þ;\È™(Ñ£6ÏTALKB&øS1Ñ!Nlb¦'Sk" â-¬H‘,„‹XÔ"ø+<˜‚-ÖW@QFSl +dcAÚpEŠÈ‘ t”"AÂå„o­'${jˆ)„.#è`mI 2H8õÑiDvI=&DUàžQ€Ü“šÌÉ,2cɆ$Xš;’ êxGÉ 0§E*—´ÊZ‘²”áã#+™8ÈHº|¤ nR,\*Ew¬ä ìŒÉ”Y-K#ƒ¨%3¥2‹6a˜‘´Á§©P€A›jÈ,.aÍ6„“›oyUÜ…Îvºóˆ¸è‡&Šˆ|/ØŸ/dÅ;*¢‹ '=-JëyÖñDª×<¹ÖÄ ùñ‹ƒL‘OXŠF6‚lL£$/¹JI¶H”-y ,`Åuš 4)TùÊ´2…–¹Ì½:YYuçïþ™±üN …-ñHnáf87d3Öˆ+„<ÍYF&ˆälìgðÊ϶ZÈ s"Ë«Ö gÞ¬\Nù§Ž´@dIibu:²Q (n%V™ÔÆ¡ÝNXu^T7dVMâNíêŒtKqL~Þ Ä•æZÿE^pµJUvy_ûØÈN6Orªì£0›Ÿ¹œ>› ‘t e™ªPmȡԮ6B$:ÕŠ^¦½…S/äÑO€T $ ÷@ц2´¡ 4+ÈJs—-Ý 3HMGV5yäihøiŒ!T¢ªç¨ßV*S U©ª§ 8ã´› ‰ž¡b(34øÁþÓ ò¤Œ"%O¹ÊWÎò–»üå0ïs°r‘YÌ<æ›5‚“a„+Š" ÛyÏòieÇ‹‡gÍëk0$]å,4€|çLýØ`Ò ìrš;7áQhÉú@¶~‹®3d_gË¥Çkj½í„;ìÐ'r ¹Óšºr·H‰a8,yï ¦:à—·¥#Þ8"Ø¥‹D_™ÅÞsW¡Ši$‘ÈÛïïásàòçí È|%ÊAýòŒÎg-Äñ3*ûú£yòUP€)úAüwÀÝBÿsàÈ2:¾‚ ç€,Qïýv¾„)¾ÕMB¾cØøÿF~C”BJÞsO ù-þ_z¦Žû³Ç!ŠÁªƒÑG½öÛt[þÌSdýï'róÌ>vÓT×»Òº¿ý‚õWrñåÁ ÇÅEx(N–‡9ñB~EÒ+pØòGj×m=Èd€xVª@K·g:a'ÈöÐvñDm0|¹wxµ0 =— /ë’~Ö£j)7ƒ?gý'oÍrw1+E8 sM8…×ÂKXdÈQ(p“…³q³qFA}t¸b b¸.Hx)s_(03US £5¥PAà ²°†nΡõÁ1‰ ‚2(T‡…‡þzHPÛb3¹×RÑÁ3>c2‡¸E#²€4`C ñ&­ð3,Õ!‰@4eP ’x‡”8Š!P#o|x*R‡U#ˆXC?ƒxaö5’B(@6¸Øì15Š¸Ø t2“8Œ),Ã…}“”P? ¡x‡ K!z¥¤­æz`)§EÑÜôl8ŽF!Ž! à |@ eð|ÐRò@ ýv °†áaŽGŽ•°ìH ¢ÀŽòh–ðªpªöè/°°œ`#ê·Àª`62®Ð‘·@1‘,V ƒ QiàHÑh@r ‘·Àþ êX‘Qy –PChÁ#,v ´À\'" I‘)tP )¢ ŽA > ´  °à” Ñ3gÐO£DÉ”·@“¤”8é•9Y9É‘·P ¹-‰0´Ð¥@¿1Ãñnymi’Á @™2 ™ð4.™hð4t“mI r)—5t—vé#ø•ƒ°–ÎcD¿A™}3I©fPlÐ MQ i€’@qoÂc ¯«€s¬ÙšA!:öK`€ƒàƒºÂFŲK“&*¶™+ua…>HvÕ›­ mNqqœf´-œ&” MÛ ´#²?Êʆ×Ç@õ­2IKAúÆ#>R:#{Ú*(Æ­QËb%µÒc>¶@¬á]Ή¶¡¶Š–¬5ç¶a¬Â*r˧õª‹·q¡·@Ç·ß5«¶ ¸÷U«ƒ{¸:—©¨Š¸Š UP%‰Ë¨>Û\É©ó5=¦°„_¹ƒðq06P¥[Ô¹Ÿ[y¢›¹ëbM *DN ¬ 4!Q]v«{Kiâ]»A-x@-A-v¼e'‡P»2›Ä[h ÈK-FƒDQšu!þJdë¬ÒûF p #ðføNákg QlŸu¸D:  0 xðiu§U‘!qî»v 1×Êú‹d7)Zþ;Jü©ºï9ÞBœüº²D1 þ;j›c U›bˆJÁ¾,ò‚ÁtAjΡÀB!‚AaÂQÒL¿i*x–½q[¨k­Û$s)`š‹?:·-¦`Mèû«ÕY ,ÞÔƒqaæô/¸©›cx5|›±©›UQÄ®yÅEŽþ¢ÅfÃÅ8^¼/aOu3ÆcÆø‚Æý’UO£¾ÐÒ '…rzã[Ù6…YkÐ7=šmƒ =“R*|3eìS~c4p#ÇXœÈŠ¼ÈŒÜÈ QÉ’<É”\É–|É&êÈ;rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/vclock.gif0000644000177700017770000001317712633765070031437 0ustar michaelmichaelGIF89aæ‚çþ $$$&'+*+-(&*-.2555<<<76<3-2!";=CE;ACCCJJJFDKKMTQQQ\\\YR[TNV\^ghYccccllleckfisrrr~~~tu|ueqcT^A;B´33ÙÚ ÖÛÛÔÚ"Ý#%Ü),Ú%)Ù-2Ü5;Ú4:Á""à..á44â<<ÛW$îížþ3æo;÷óiŸ—/ÿÏ<ú÷g¡û·ïÙ3ø™êǯRûs îá§Ø@áhà&¨à‚ 6è ƒóXÝnfEÎ…fxa9vˆáAìÀA–hâ‰(.ˆ”3ë±s]Æ(£†PHY)æ¨ãŽõÜÇ@•ÖŒDiPUò¨¤ŽŒ”‚d8;Е÷bFd]D$YEz˜[^jRd–Yff¦©æškÞÁ¦™hâgšŒ4Ešd•9H!wˆéçŸ~ö)¦ ƒ (¡ÆSˆ¢Ž(Ê矄¨¡b’)¥˜bǦvÜÁé§vµ©§œYY8.©j‚à,ؤHþO¥”,µWžze)‘5çtÉe—4ÔÁˆ7’äªÈ6ø*±8+­*5óLkZ¤ëCÀnøk¶T›ì¸B2È$ˆÀº(r Jêµ¥‹9¶ÜŠÒ üöëo—‘+p8 "2Û œÌ ³p2‰ˆ0ÂÃÉÙÑ1‘³Ï1Wr$_þ01 74@A½rKNb#“„†8\¨‹©þ8cß3ÎØ|3έœìÞˆPƒ‘ P`èB8rˆ°D$+„ƒLGí4oJ‰à (4„É©œ!.:¹ †œ°p!/4¿ø­!þ<ãó¸ m4NþÃ2S`"$c42@]´[ÍñÚŠ’!û³O×AîÏÉ)‹}¡€°]ÎËäT# kÓÌâ äÌKá:3w² ˆ€„ÞQ ß(ôŽ*ˆ#u8M(ŸRÎÀµä[›ly†¹ˆ@/Ã_ØüòmûÃÆ#•˜ê«¯J€ š¼p`7³#Ž&š„’wb»ó~ÑäU‰’#€A P%þHƒIï\8ÀñŠ9¾p‡443#ÅMŽpyüñ`oITˆB&Ü"šÇÂÁµð--9@8¸&7¤+…£H•~ä‹yD\‘_A2Tþ‘CʃžŒØfÀgØ„þ/éÀL·ª NðãR„Р$MAàÁ  5‘¶8ã:+y„bd(í"¨Cèv(:…m«ŽhYD¡”Èj„ôºÔpÐ àÓ ÞfÉGpô î<_±R¹³îó âþ©a»d סÕÀdךͅºu‚RëªÂ¹TØ"oG,Ôª¶ áˆÇUèÚp šm‘›XcjèŸj[}Ë£‡F²Ãí( ;aiÍ…’s TU¨ï(éèP;TïfèŸÚQmÓz] © §¼ý)A‚Z" Z! Â]’gÖË^¥roÃPÄrWa Ìw¯"@¢Qb´ ×¾¶šÇ,C„!Snq7±–H'É‚tR¡a°ƒ¸…:T•jP]4KAèS‡Lf$‚6x(¬2l—LŒÖ…×K5“¬‰zŽš2©Dnߌ¼ ôÁ„H%Žþ”c$e"½8±3ºr‡L§å( W@ê’Jà!+¯)ƒ£d•LY 1B•¢àb-ãÑæÅ2$-i€Å혦¦/ iN£ˆ²07² Ê gÉ" ÇG*G$FPÙ†ú¬±ÉɂԢÒ{ê‰#Œ©‡‹E1ëí›·µF‘p#Ì£6(µ×e+4‚n™c¯>69îàdmϹ!)’ ‡ ]hG;B9žáíe»ØKQ,Þª*âš[A”H~-'Šw»þ†u¼ï b‚7(ßµÑn‰ ¦ ÏÐÀ îlƒ;è2ø\Ⱦq ½¹ã¿w“þ-~q„äÇÁ2:ž!XcFúœõ‘D&XÜÞ$6B6^ì€+Üç'ˆ2  ÅàQ̹ƒ‘˜¿v±Ý¸WY.qoe\¼X Àõ) ¨UÆu®/I˜î:Õ/ô 7…æѺ4€‘ŒC`ÏÚѶf$ˆ‘¶íêþêÚ»å-Â&µIüc.0 |&#©OҦò£œ:ùÄhÞò´½è§0…Ï”Þó–¡™@QóTKsgçH–wí]F} °DÀ†ÁÞíþ(€A”Ò‰ Yj„ü°Ü-ù{¾ú ¤ÛÇ(÷ 6‘¨þñ{±Eê!?{ˆ•ŽÒ¿Á¯t€ý‚`·Ã»oÖÁKg;³OÎü±*Dçy>Ó Š†*)² ‘hú•m¶v¼@ü~¶—KÏ&+t0€ƒV%â‘añ5"‚Â} #ßu–ó :à¦* DŠ 80¯ppu°P€ þ@ ‘ã<7‚ä%!_‚"s,7 þæ„¢-x<˜# K bƒ>cK 8 "¡Ã36_ <$l§_ ·vg9a :Ð:0VÀr…)’… ¢G>“ƒ ⇠bhþÚ0„þ ¤€ ‘†p!  ²¶2gÙ‚>'…äP…T(6|x""R[xƒ#ˆ'ñT èvª±B‚1R[½w!¥á{žpá2t„7ÈAº€\JÒŽáKòAòä&7†%S2]“øØE0@ÓTþ(P`˜(ræmýÆ‹T( ,¶Ps ü·#áŽíUŽ{\c;Q³$¶· ’Ì;Ñ'9d(9"³I° 9…!4i“ç{q˜-Áà‹ThUˆBâÑú‹D©^ Å º;.Rtà7 {©*9>핈!Ðú`Å3ŽX#(` 6P—p eIäðräP1R÷{:`\@…åЖ¢ø‚)Âtà, RŒáhJò c€)ð Ç•”Í0 ±Œ ñÍè!„X€Ãr"0 *cŸØ‚¡è‚Ɇ"ÿ'+­‰Šä¢Š%¹Wé› þa @怜-×?‰‚bÓ‚;М≖öœ&ÒÙ^á %€!5Qá€ZK’ƒS°"`,B‰'©lªÁЕþpþœä -·R)H$¬¦_79#£Ùä:ð 6Œ €`>òYyDÍw `j:rŒÔCg¼) 1Ê_ax‘qGB, ÚbrVÎö*¨2Ì©Á°™ìÉ- ŠdÄPƒ&z åPƒªâ Ct*  M6†pI[Z#ðˆGHž ¸Ú6¡2R…Ý ; s¨ù Qt~Ò©ã$ á 2>\qH €Ÿ9¦c þ\ÁÁ ó˜oú`#?áÆpS#þ0 äÁ†—s¤€`¦Ù’fBZ¤Uˆz¸ AŠ(HK"¨dðCÚ©e1öp!9#¥q³VœBêwH\°¦À§&€¬™ª«Âª v« 1«´º2n&ܧ“›™‡lÊi›¦­™6”K')š uW€#áä:{29À4Ôq®"Xº]šÈ©3B…£ omº ðip…Ö;æ¡WI"`SFÕjCê9¬ ñ ÆzjÿŠ(åð©Á€Ñ%·`¯ó7k¾¨2G Œ›=1-?«‰áBñŸOGþ$› x 8xGúmzj)´ñ‚RQ"°@‘¼™vÛDZýs–ö§z¥:hpš=9{Br5)e‰ñ´!†JEè!ýæs·€hI»‡ûªZ7ë3V»>Yö¾ÄËŒs[Û!•t‹na+¶5[p§&]qHÇ`¨Øá¼G°N§µô:ew‹·K‹ Lç ÙsˆA%Ðg›"p 3ºZ¤qëqMö 2Òv¶3K³‹k ý:0ûm!¹óqµm{˜›‘ûjåqG²@Êj³s³?ÂÕ¢´™‘¹Q¡ HeF›¸§¢¬$B¶>Ã+t ³;±þK"P¹Q$(g·;kžXá,è:.0ѺV„c¯Ï:ø"#·g}‰+VqUZ•í° üKüû¿ÀÀÉÀ¿ë ô s¹Àsù ¬À'¥ÃÁÀ l5A » Á¬ÁÜÀí ÌÀd±ÁÜÀ< *¼Â+L dÁÂÓðÂ0< Ë0Ã6|Ã8L &x´æ¿qRç»$ªÖÐÁ³² ¿!¿~—†O\¿=|x‘Bæ{UJòŠ+‘1mÄ¡Äïë¾M‚Q<‚e,6¥Ë?âK@ÄÄ6W ßǦ›@Ò ^œýðÿ€£AÆþºÅ,Åȶà Ÿ "&2[Åεá qa‘˜œÉšR›¼É@È„ Pʦ|ÊùÙ ˆÌ 31- …{’œ” ZÒäP–°’òÙE_ÊÇ6ªíYª«œ AÆÊv,òÑ®QËQËЊï Ù ˆ‘ ð0Pƒ˼ |° ø0Ï!¹âÒlÔÜøÈ•‘ lP PtãœÌ² â¼v\%üàWÁ+³Œñ¼ûp § Ú,,àˆêù+΂‘Ê B-ì`Á¸¢²‘<ÉMÁ* C€ýÀþ5Ñ÷A=l îkÑÑ ²ÌH1-ÿÀ"~¥ï\  š2M4­ r`¬j²VÓ Í’<™9ð×Ï þP7‘¡½ Á5B9Ä“ S5 A9ÔsqȬ4/À{E,qÙÜ5Žø˜ñÌ"EQ½Ñ5C?+íÔ©EÖsÁÖaØê܉D¼J1 (PÒñ8AÍ7Rs`\6€ g ŒYÏÏ€á6AØrØÚ11±™íÔ, P080ÙM.&Y=áЙ@-,g]Ïú<ªMê#ì¸0Á\£’þû oðvþÀ6"í¦@ ¹)„Q½ÒúÆàwP¥¦q)ðÙþpÍþ0ÜÍ,=M? Aå¨Í±íÅnP ×ÌÞûð5þÏB`)÷sàÖþ°”0 Á_]ßVQÀ²SQwp†9ý l Þ¦ ˆÔŒïðÚQâØìM›Â"9]ƒ£÷=/:Ôs2qM` ÎÁ,>§0'n%ã­].)` á9nN1q±6Ò[óã@ÞO>ÒÀÞÞ“à-é=N§_½ÍûMa^ãHñ:êÞâï¡£wÓ<Ò!O9/°ÒŽm ½îUŽ”úäÁ ³ã ¡çèßFîç@­‹ä’áÓ NsE1Ÿ.êŸÓÕ,¼!0ÛltÆÁ²>ë³Îé¶~븞뺾ë¼Þë¾þëÀìÂ>ìÄ^ìÆ~ìÈŽì;././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/basic-trace-response-tab.pngrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/basic-trace-response-0000644000177700017770000002745512633765070033504 0ustar michaelmichael‰PNG  IHDRž›ÅÈÿsRGB®Îé pHYs  šœtIMEÙ8ð&ãûtEXtCommentCreated with GIMPW IDATxÚíÝwtUãÆñïf7»é„„ª!š ½)¤È‹ô^¤KñETQ¤Š"Š¢"H‘&-Té Hšté!”Ð ¤'»Ùß  ¯èïùœÃ9dgwfîrŸ¹sg×`·Ûíd‘€€€T¯ùûû#"""ÿ9¨ DDDäi2=üBZ½""""OJ="""òT™2zC|l$ѱ60:âêêŒQu&"""Y6bÂY9÷S¶„ãV¨g΀CAzîK2ù:DDDäÉÃFعíôü=9*uæ‡õÉéìX9pƒFdM½wÙµ Ϊ?É@ª1öØ‹üüÉp®Ãðþ “‚Fb.É_¦!Ÿ¿õBÖ~ËòÝ—²`ñ6q'<*Í©vkwÈ}¢é"""ò †K7±;:šmk’Ë1õ ”•Rf–L "â/,øÆ©Mt,VK–¤Dñ¢tÀÍØû_ùq7d7J¡þ{)^¬½'m"Æžùé"""òŒ† ›5±Ávs7§ùƒÅ /GÄ^"<æÉj ?DÙZ¨öå\Ö¯^ÈÀ†^lúù=zNÜŽ °…¥ïkmx~دìøy*!'·âðC7†Ï;˜ôùô§‹ˆˆÈ36î1›Òj·Æ“þ‡3ptÕ†ì§O^,]…þVÓ'¯3WŽ_&ÖnçàÊIlŽ-K—ú¥—ãR^Ÿ4bÎðï8q;!Ãé"""ò ‡Ç?ÄYmi÷l˜œ(àäôÞ'S¨ÞºUÉyžÆ\”|5;q †?·í G¥F<çiH~OÁ2õ!z=^¸’Áô0mU‘g9l¸eK ¡¡a¤5Âz÷:["m¸úÁÓéÉêêé£á~P°Ûnrä÷ÛÔøÏ‹˜ã®±oG^ùs`y0ä$u´üqìxºÓžº¦­*""ò,‡œÅ«QÇÝľek‰H7Ž. UëJYöèë©Ó˜Û…·¼€³Ñ@LxÚƒ=£íO‘g8làƒ¶Ÿ¼ ñûÔ?€ËñI¬œœÏè_ŽP¡õ`ê”ôÊ’ˆ ùWûìaÍïƒðq1à`v!OQgœÜ i®h©‚yÓ^Ò×K[UDDä’æ—z¹=_‘Y?aÅ´‘¼Û} •_«Käæß8l-@¯Ac¨Y¡@–|ƒ¨-ü½_ëÁŒõ‡(•ãÞs¶näÉïÌÉ —ˆîÝ©¹{ã&ÞÙ½±¤7ÝÓ¢­*""ò yä%Ï´ð3ŸõoÈ®õë8—@Í7ºS;‹‚†Ýʸÿ4¦uÀ!þS$[òk ì£H­¦põ .Þ¼OäΕãàÞŠ"yrR"ÝéîÚª"""ÿ„°qOáªóAg6OÂû?¯çüµ;XÿÊØû|Ô„ñ—¢¸vx “&MbÒ¤Iô-[•yóSªz{:2aÑnl@BìY¦~<ŸN£zPÈÃ2˜."""σݞòk7Ò|£-öÁ§Nð矧9üÇQ ~¼ñÎõvLwþþþ©^;¾öSêô˜D¥ŠNìÙûÀ7ƒeëLàžÏðu1uy^kÅŠÈÒ”1à…A3ù´wM\’žbÉhºˆˆˆüÃÂÆ“J+ldžðð(Œ&g\œMO0]DDDþnÏx mÄÝÝý/L‘¿›8ˆˆˆˆÂ†ˆˆˆ(lˆˆˆˆ(lˆˆˆˆÂ†ˆˆˆ(lˆˆˆˆ(lˆˆˆˆÂ†ˆˆˆ(lˆˆˆˆ(lˆˆˆˆÂ†ˆˆˆ(lˆˆˆˆ(lˆˆˆˆÂ†ˆˆˆˆÂ†ˆˆˆ(lˆˆˆˆÂ†ˆˆˆˆÂ†ˆˆˆ(lˆˆˆÈ¿˜IU """:þ>>éþ»üÄ¿ï²Ç±¤G ¾œõ#>>ù)[¹—£žÎ¢BÿXFÇbù)Qþ%v^ˆÔ‘-"¢°·NÿFÁ’Õxÿ‡XæmÚËù‹¹xñ"G‚Va]8¢N–E Óís»ø#$k „ØPvî=Ÿî{b®Å3xÊ*Ž?é?ÖÑØÓ‘UGsðL0Çîä‹îÏq+îï R™)Ç_­ã„è`fîõ£C›Ìû´)8ùa2Eº1wÃQâív¢¯±kã FöîÉÊ CŒi‹íÎæZ¬ØûiñR#6GØxóÕ"t³Š»èGÓ«4>>>”k1„ß…6BïdÖøA´8•Ík¦$Þò(Òm§î°á«º¼3'”eC>À§H7‚.Ť.œÁ6;Íðè4qåüv¬™Ì°¡1&€[v;1—wóa¯žô~g.œfÝâÉt,ÝY gбX~|||øø§M„ß»µd¿ÃúÉ$®£_S&.Þ<"!ö"ŸV*Bñ›’ÇÀ<(Ír(¼žÎ *x)kÌŒŸÏÖù#wð9V¯˜FMãF>øz#1v;/wG³í†}ÈÑýã)÷œå‰Ê_ r+ºÝÍÏÓçS§]¼ œò–¦DD•[7ÆËzƒÀùß°ùÖzÆ-Œçyóé×À‹£:1zñQ°G³|d]–96çÜ… l˜úŸõoÉ'‹&-!Ž?ÃãØx5ÍÞ¡Ôå°?r~S^ºŽJö­óY°:œ¢¥Šã¸{®õFò~ûŠ8{–JUÇN ÑYôëUj—~þþ‚ã÷1`D(ƒ–¯ä“v¹ù¢ïG¾O®2¯³pl'p~•‡éX=/!Ç7óÝ ±,Ÿö!ƒ—ÄóÕÊt¯x’Þ+S¦î<š_Êï7æç¡mÙ|Zc4DD6r|ë*ΙþíwX:r(¾ ¿¦Q¥<”¨Û—¯ÚçeùÈQÏN½NïPÓÍH¯ñèRߟZMÚÐØÓ‘È8+“™9¼ðÈžww®œÄf[m¬·ÿdgПX{ æm>MÁŠõhUÙßFß1ÿƒ”.÷Ú´Ë›¼:®Þyðu1’ÍÛ“lîî8žð^ˆÁ™êèéK`lg™{¬õËå$»_e:ôèî­X>»ËUáýo—ñº·™5û¹qy7}§\¤€[ AÛv™x;dö—û‰²Ûq°dÒŽýl›Õ*©W!¥‡Ëa Íh~>¼0ÂQãÅâÌxéK>oY#¤YÇ×Olæp™1ò¼·ü(poEà®÷(]´-» †ø}\º…É솧›²×¤P>OœÍJ×îJ×Ö¹ñmø5¿ŽmCñ«Ð¶ssp~ »Çá_º8:÷LÚOl:’ED6R*U£ûN‡¦û¾„¸›œ8‰“‡ëý58S敦¿‹×¢ÀhÂÝt¿ö„” OBòØ£9ûÇ.^hR7X­V Öý% èS5ñ Ü=ŸåŠ1R¤ü«D†Ý›Iâ¼#ï=•kc÷Š™Lúi:Ó§OgâøILëÖJ\ž{™o;äeíS8i'ôÀ2Üú´"cbãl‹‹zp‘8¸ä§N‡¼Ü8°™ã'N%6îf+FϪ,]ºe“k`I nÞÞxX5R2e9®?“áü<ü°dl':6 —BLŠ:NšÿÁSx½ËË)Þ÷`y ¦‡ÇWDà]Ðä›jö¤•38&¿æìí&\’F™:¸xÓØÓQG±ˆÈ3îo·ï–Ý€íûNÓø…4¯¾Ijìŧ\i—¤ëþkÑqÛ>:2•«Ty¨gÂv¿{¨|4aÁÇøãœWÜ £TãN™îÝxµË˜ó_ÖnÂsÇAþûÖ€t?â‘Ë<Êc¼sœ_ãµÿÔ  kʺ³Úì`|¼—È¡™˜Ÿ˜» ë3…{>"%íå$Ä^diÀz½éóèâ§1RÔÕ3ýõÌéS¬{SÔ¸5AG±ˆÈ?-l´iÓæ‰g©÷~¥ =§±bZ6½~ˆú/z¥zÏù?¶ÿ|aò8™8¹îa£›qo,©ÝšxÕŸËÃKsεƒŽ&`Äìb$dN FÁÄÐc ;D¾ÇùqN“ÔWëip½÷l¥Á™ºýÆP7ÝÒ>úñ ¯bÕ\Í“/Þj ÏæøË£?nàȺƒ”lÔ¢%Ã!ú'~úõ cÚ—MšÍüÁoàûö,ª>ï„5.š'Ì~Ö4¹Ï+Ñ“ÒßÕ3i?µ#‹f@«.Ÿ0rn]~ìZ1:†°³ÛXáò _çxœ,ëFÈžËDNxGld˜NÚŲg2,«-ì †[‰¹—:À¼hÒÿ]>]÷=-.¾ˆg¿c>x×"Fn»Íûo¼Œ—oYºä²0gP#>ž´ŠÃ‡ö0áÍÊÌñêÇËÏ;‘{ž*• Þ‡«Ò}Rã^9~?“=ýùEd@»OX°¸•kwä»ϳ|h36$=¥“¢Ž7ÎgÞ‚ñtR5Å-”ðˆ»)“CrGâ ÖxàÖo9þ'ë–l!*võôsŽÈؤ§n¢ïeãò¨ó ‹ŽÕ‘-"òÿ=lä-Û†#¿Ò¯ýÛÔÀ/_>|||(\¼[bšrxÿgäwwÀ¯zVMÌäwêQû½ÑôkY…ʆ3gh-L¶+üøî[L0š5;‚˜ÿí¬‹gö;ÿ! (·<%é’ËÂ=òñwªÔjźi‰ƒßíÒ’¦múÐé—­´*åζYŸ0hù5BV¾Í‹w¸â'úN¹׿aô”íØÌ¾tz¿!G~@­&ó)ZÆ'Ý2ïœ_…–ŒK dÕü[¼Ç¾‡Ætø”¯EM7#¯VðMs]ë” aA_ªµÎ÷KvQ» +–ü Z6‹šnFf|Ú›ú šs Ø—ÌTÌ\Ó;Xò§(Ç _~äü¬7ñ~•zl¶ÕÆÙl"8³æ6]j•`éCuüÑÎh¶Î½F×ó?PÓhñþ2_D—!ŸßËû·[÷Æ£9t%†<Å_‚ø}´­×s?Çþù_ðΜPBV¾Íè¿ñGàRöÿâ÷Ñ®ç7ì>´“±½Úr0.¡¯÷äç€Ùô©ÿ&ï4íÆÒ PÝ""σݞòÒwá…سø{ üýýÓ~7ì&QVŒF#Ù½q6§îúçÖÝ( &ry»?ÖòíÖh"ã¸9›SÌ/2Ö†“[6œL3ÆÁFTD,7²¢³>ìøBŒwfËĆ)Æ_ñuC`ÐHrÙ£±›ÝRÕ‹Ý͈XL—e2q%u9Ò›_¦ëØ n\¿K¶œÞý´Nlt8 F·4·¿ˆˆüïdõ¯¾¦º©n·Û3 YÍÃÓ ::»“ÛÙý‰æo09ãfJ=?Oç'™›7—¿T^[øE6n>ŒWþ¬íþƒgîMÕ0Í.p£Éˆ“Åý‘åò|D!LfçÇ.Gzó{œ:Α+ÇÍÃò„ÛWDDžmú‰¿AÄ•t{3q¬FÉîÓXÜ#eoÇå#¬üy„ßaç®®Ô®\šì]틈ˆÂ†d’‡_}6®ôáV|6ÊT,žêÑß[שÔ:Kˆº{°ð8²[,ª8ù—„„;LÔ†ásSMjÒu-[´ v¹üª¹¿À`rã…²U9½`Ù*T5‰ˆÈ¿Dê§Q²ÑýË–ŒmÀ„Õû¹|–»×RôÚtÞhìÏ7ΩæDDDä ÃFw·Äß"±8»`0™Éù|Izù€ëŽê—6EDD䯅´Ä܉P‰ˆˆÈcÉp€hxx81áQœù3ˆÏ;½@ÿNUÓù=‘Çï6©Ä»Iÿ/Úök7Æ7‡‹jNDDD2%ÃÛ(3·bùØæ˜]ÌäðvV­‰ˆˆHÖ…x›3åÛ~°W²säç~¼ûÓ.lª7ɪ°60xÑmâjºYõikfl¹ š‘¿6Â#®‘ôsÝ&ÏÒŒ[8€áª°9éçÅEDDD/l$}ƒh‹÷—ðNƒ2 ›¾‹x»\¥Ú°dl':Ö*Á´-ÁªAIWªŸ˜øŸÿ꫈ˆˆ<;²ú'æT¥"""ò4)lˆˆˆˆÂ†ˆˆˆ(lˆˆˆˆ(lˆˆˆˆÂ†ˆˆˆ(lˆˆˆˆ(lˆˆˆˆÂ†ˆˆˆ(lˆˆˆˆ(lˆˆˆˆÂ†ˆˆˆ(lˆˆˆˆ(lˆˆˆˆÂ†ˆˆˆˆÂ†ˆˆˆüïÂF\\œjADDDž^؈‰‰Q-ˆˆˆÈÓ ‹Eµ """ """ò ªQØ… … QØ… … QØ… … QØ… … QØy€éá ;vìÈÒ…øûû«¦EDDþ¿†;wî-[¶äZ·nýÄ3 PБ”a#>>>ÃÀ """ò¤œU """òô†«««jADDDžš‡ˆÆ±åOŒ™ý{ª7º~…¶ ªQ¦T1ry8©æDDDäI†™òzó…—ƒÇo Ó ohX!/qÑá\>s9cÆ05.f}GÓ¶F! ª?É€CÚ/ZÈûœ Xœ=ð+ù Ïœ@ÛâÎ,ûñ#–¼®Ú‘' ÷Øl ½Û‹ý0wÂn"T"""òWÂFZÌ9©áj„˜`ÂcT"""’Åaãþ'p4ªEDDäi…„l6U ˆˆˆdq؈ºvŽ-‘6¼Ë”ÆKOÀŠˆˆÈ_ FcÊÉöø«,þ亼^GÕŸˆˆˆdÀ”ö˱œ¹Nù¼>ÄFÞáâéCÌÿj"‡ãèøÞW¼äã¢Ú‘Ç qì_ñ-c~Ù À‚qYpo’cy^ïø]*UÄÇ[÷ODDD$s v»Ýþà Yý«¯ú‰y‘ÿßT"""¢°!""" """"i†Û·o«DDDäé…¨è(Õ‚ˆˆˆ<½°‘Ã;‡jADDDž^ذX,ªyzaCU """ """¢°!"""¢°!""" """¢°!"""¢°!""" """òÿ€IU """:þù R±z?®ÆBèËèX,?%Ê¿ÄÎ ‘:Ê2Ú¾Ô—ÝzéÃ_Ç·` F­}üãÁ~”K–dÕ¼g¿|\—÷L¢Zç ¼[º /”,óÔÖãiž/D6þ&S.Zÿ·/5ÝŒätzô°’„ØPvî=ÿ„ËÈKïÏV2¸š'®ÙÍYZ›t¦Š·o_K–Ì7o©†Œ?s²ÉW©'À·á×ô%Å€Á”—7¿œÅw=ž`Êú£t®Q Š4S¥í`–ŒmN~˜ ·l3Æ.Ÿ¥ëûo–Q}L¹hßoH†Çã\ýs ¾&Q¯õÏü~ùx Ž=ËæÑïƒ ˜ùE†ëqûÜ.þ‰|æÎ" ƒ«§w±aÏEÝÝp79gzÄÙÃÁ’aM˜s2úÉ oö$O~ç促÷®gÇá‹OÜE~‘uKÖpÝæFÁJîÄ„Û1fQ½xzyeú½™-‡sn_{:âäñÐÉÓàLñ “N²™9›qwóHñ’«›YG×cȨ¾Ìž^䶉Îè‚ÚÍá­+9x)2¹AZ4ƒ6íÊãdrÿGì—_×b+!!:˜ÉËž£F©ì3š c{Ó«4>>> ›¾;á¡|ù&>>>ø÷Çù»ñi®Ctèf^¯_™Š-†°6è$1ÖÌu•Æ„]`ÍŒO(X¼2݇¬#Æfw#†„[nœ•¸î~M™´üÄûæI¾µS’oUø÷ÇÞ³·R\µí^ü>~MéÚ¢9­jv»ÒÞ9›6=ÞcØÐŒÀ-»˜Ë»ù°WOz¿?óç7eº.Fà˜ªñq0¤ÑXìYJ¾øøøÐwøl‚oÇ?Þ6>µA-‹Ñ¼ys|Štc÷ë# Ñרµq#{÷deÐ!Æ´ÅÇLJög'7<\?{¿O~‹rͺӼÕöž=Ë‚¯Ó¦{º¶hÎüÀP°_gúˆÞøéFÐ¥˜˾°g6 ^hF×Íù%ðÁ{fãã×”=ZðñO›ˆ·Û9·m*>>>LÙ €-<˜¹cúP®YwôåãI«¸el„ž;ÂâŸFðý¯»Ù‹Wʥ߿p8ä†Z‘ôÂÆíÛ·ÿÆÅÛ¸t|cz•¦BÍf|¹¦sVï`\«bÉ á¼aÝXó ëWÿLMãFÞ½Ž»—;Œ£ŒÙvÃ>äèþñ4œg^¿þÌ^ù#-šN¤òç3iP~Ú–Å+]®'+æŽæüšqLZ&͵)Þxû·-£O©Sôhñ*…‹4cΚÝÜxÄ ³ˆ›Á,ÿi…KV¡çÇSùãbÿñ ¾–Ä“ßùÕ#øhA3çL¤±ë!>íÛˆ©[/6¶N®GÓçØrø‚÷ÓË4›fÕK³ö䂿w§å'±ì8´”é‹gЩUîäå¨ÜŠnEwóóôùÔi×/ƒ§¼¥)DåÖ©ÑòÓÇ*ÇÉ 'øó\0gOŸâÔ©S‡œãÌ¥Ë5º?R­×Y~:ržãA¿b_<Œj¯ÍàN&ï]_?¾Œ µÚRñƒM,]º”uß—`P—ºôŸ±/ã+]#Ü:½†É«ÖЧE¢J÷cÖøþlÿ!“×Iýp¤F»·©|úw¢KT§ŒŸ­}N¾½¿s"g[šUɆœÔmX†r=ºRáy§‹ÎWñuú´¿ÂoÇóSµŒ*¾ÎÌw]Y»Å“Îíjàh0¿BUJgoEƒWò“{žá5j3Ÿ6ì\:•y›çqàË7©à?Ž+1áÙò ýGMeÌ[- 8æH³nƤ*òÝs«)W§+­ö0m*ãg K µ{ qwØ¿q>оHýöoãØe,›ö nÁÄ+ýë'¶s¸Ìü<ï7Èÿ”ý2ÝãËÇå³x£G%œ ÷Ëöq¯.î>Ÿ€?àäüL\}³gI&,ø €qK¶ó]ßZÄ\=ù—γ/_í;Äo 'aýe(õ«–Å¿Çh¶:Ÿ©-òÿ.lÄÄÄüï—j#äðïŒìY–—ë´âûm¯2sÅÎùŒ¥ó'_eGÙì4µ‚±ÝjñbéÚtìæCÈžËDÚÀÕ;¾.F²y{’ÍÝMLš'#¹ü*Òû“ŽîÛÀ·ï¼À=[R¶h¾ž¾šÔVÑŽIDAT¤.Óˆ«g˜7~ÅÊT£ï¨© ùv>œ¼@·&/“Ýò@—@îÁ¬˜Ü—Ú5óÍú_(cv`ö¼=ܺ´ö£Î0äÇ7)”݃)>ŸI³_NÙFô}´xc¦ö$¿»²ñZ×!)nsTïxòœ¾ô6Àq–¹ÇQ¿\ÎL—ã~ø†Îï¾Ç€÷1hÐ ÞíÿƬ|àªùóÿû-Ekç"äeEX<„~™«™ýo¿ÃÒ‘Cñmø5*%^a—¨Û—¯ÚçeùÈQ»ŸA÷u.êuJÜ–½Æo K}j5iCcOG"㬮ŸÑý:¾íÏ‘¹ 8nÇÁ¥ -ßk@Èïë8f{4뾙Ļm+¥¾½`0S­Í`_Äæƒ¡`0S²J%ˆ^ÏÆ—’®è—âùÞ€ëß0gÓmê¼1œ/›ä·á׌9˜žf@}¿‡ê+‚Õ‡ãÛh Jå P•:4ötL¾’w“ µ3é\º4MÞˆWÇÏøm÷1¦nC‘Ü®Éa~ßò)´ëñrŠùYß/3s|%Ä]dî¼ËÔ©ð|Šª›²þ(^z‘*õ›$ï“™9¼ðÈžwwrþëç ƒÉâU1ñð ¶­™E]Ã<:4ðç¥ïñë–ƒÜSèI>çÌ™ó¾ÐÃKzRµ~g&¯¹M“Q‹8ü[j—Ë£!ußýsÞÎÉA éúpw?wbO¤‘qü®`òÆõ^ƒo4ánrÀÙp¿' &<Ž„ Ö1[îb´êÿ%gl¤±§#ß íEÕ²EY´qÅ*Ôàý±sÁëMv¼À›­ª‘Ã%õºûVz—¤ÿ;å-O§V¹‰ºu“È¸ÄÆµh¾û÷»MÙòÓì5/N®;È…«WÈ“Ãõþt'sRßtûã¹—ù¶C^Öþ0…³‘vB,íO+ò82U޵§îߪòmôAË–°téÒäßLìõ@6Œàldýi5—ÂR†×ŸestI5¯§;<ܶ¥wµýˆ¿ïuO7*ú"õÚôc¿×,X³ƒ %ã¨_µ(Î7JUoÁì#GY3÷;ü¶ÿD›:ñï9Ž=§®§»Ì¸py<¹÷ôâÑ 7RM÷}¥"ÞæÄÔÆÀ³©Êf4>xÅ]ÁÕ<óVK>Ü܈r\™gT'“!EEe´#¸ Œ»ëñ÷ÏÄç¶Žcô¯Á4dFÌ.äq2qrÝ1¬68‰=¹<\’‘¨è¸ KJ÷®B3\?C6ê¼Ù‡“óмËôïÝŠûp~õúC«ª>é–£È+M¨iùƒ Û‘ï“Þ4nܔƮ‡è×kÿíU-ñ6…ÁŒoÑ!z=^ ¿¿]î$ î|`_¶Ç§yµl2#.FA³ö%‰18$¾vo¹ü*òöWûÙ¿mƒZ^àƒ )^¤‹¶%Êž8õÀÚ‰tR5uƒü ï—™9¾b/²xæeê”óÉð8x@­£)kÏWϰø§(\² =§ËÇ?°iß1fìN)¿œjaDþΰ‘|Eí™Æ]CÇ”O{2iT/^.Yˆ_/`pH<Iºº³qþКT'‡í{÷qêÔ.–m<í+Á½ž·“›•pkBš Vb'vç6ßIþûÂžÙø,C‹Cðê8œ[°cêGø—J}‹Ç`z褸m<Ík•ãÕ³¹iMGXRÛyaï"-¿ÆÈ^5ðÌW…o;äeùÐfl9›øtMLè~-¿Æ{U#‡o9úäufÞÇ™µåáᡬšù ÄïcÖÜ IO6/šô€GWO¾2Ïl9¢¯ždÁÍ8bî>ÔMlæà¶_S\I7}« 7v~NvãØqàæŽä•Þ!toTk|Ê*¾·c…EÇ‚!'­Æö‡[™üëѤeÜbËÒE”ì>‹R¹M`cãw5)Z¤ Ó¶\HÝ Þ<ÇŠ°ølcòUhfÖ ÅÄqåûÍ¢„§œ¥kñº·™†zâë’~ƒlÊVŒ6íò‚{+ÚVχƒ¥­zù€×›Ô(q¿Q)R¹ eÌ Àͤž†àÿók´¯]ˆãöxBößMó@ ‹ŽÅÁ’Ÿ6ï5€«_0àËÕ\ çØÖ•,¸Ǧ-ë9~éþgït¨KÑ¢ÝÙr†Å3/Óôåü©‚ó¾_ft|=¹›ÎQ,wÁÁ29\¾lwÐã'Nshã|v‡Dþ¥ó…Éz#^§X…ô5‡_Ng÷‘3|Ú§Er{¨eyørqĈ#|áèÑ£Yº__ߌo/8e£HÙšôíÖšbÞ×Ùáõ_Góc`0¡AK±òÇvr†­‚¸c\²”§AÕÒäp;Ë„¯¿cæ’Ú721¶çp‚ãì^p¢L³ÞkÏÂ31Úx”ª¿ÄÍ-éþõîœ\Cœg1þœ×/øsr á^þøÆlçFá.Lýáz6©BÞì®®»ÁÁLîüÅiÞ§'¯½T€ïÆí¡}÷F)œSs‡ñÑW_³m댜ê΢ ‹x9¿+̫ޘܑ«èûöç„Þ¾M¯·†0|ÆFºøçÇààNŦþ\[¼„ï~™Î„ SpÈiàôå4oRŠB}q·$žÝsyràçY¼1t89“.óCv/àZ¡7Ò-GÈÎÙ”«×€;§Ö3o—ÍšV•+üøVM†-¾Àò™?’£B+7mL®k¿²bÍ͛ò ¬Û4ŠBvvÎÿŒ¦ïý qÇ8v*–\7Ù®ÁqvÖìÁ¯jMªT­Aíз«.ưwr?¶û}Êœaõq3'·Î`ùî;¾Zœ7Z•¸?^ÁÊ÷½Ú²óB,{¿Lñ yÙ0Š [ƒ9´v>Õ:P¿Aý´×/›ãýmåè‰ùÆn*µ{“¢^ ¦ì˜#wS¤~ {gð½ #9¼¸ð|:WypÀËóžè袃Sn4©ÄÉïÞãÝ ÁÂ§óæ§‘üºñ{^Ì~“Ÿ×eÄ’ë±…‹Ö‚T­\ŒÛGWÓ¿ißõõŸuð³]ä‡ï¿fò„ ¬ "*ÔFËú )TäòfO9¾Ä5ûs¼üZo:6¯N첯p(Y [+2â½ÊXî5äGrøú<ÓûefޝB¶ùxµz‡¦I!/êê>ÖëÂɘ–/¹BõEÙ>áC¾ æÄ¦yäªÜš …¼ [8æÏâ¸OKš=w’a†>ñùân¶9òótÞøa!ã¾þ’Úå‹àá¤o°“;wî`41™LÉ?¼vïÇ׌F#888$ÿ›Ýn'!!„„bcS‹0Øí)‡Ydé ûûû?Åê°‹ÅÍ%˾¤(«ÅFGgµãâžö:F†Ý$"ÖŠ“»7Ù\L©Ë…ƒ³N¦lSÍ#ìøBŒwfËĆi°ÍjwÃÂHÀˆ»§ûÕy|t8·îFa0¹ËÛ=Õôã+ÞfÔžÌíZꩬŸÝG‚Éœ<íῳŒ=ŽÛ·ng5â•Ëû‰·Mlt8ñXps6c³bÊäWu&ÄÝáF”#¹<]þuûedØMl.^x˜o¾vk4‘ñFÜœõ…s"Éê_}ý‡Gq#.n.ÏôZœ±¤3ÝÕÓ×ôÊçîžüÿ{'t[øE6n>ŒWþ¬íþƒgîýŸ OÏ¿ôyGgwr;»§9-ôÀ/Ô–Ÿ];J>µõ3<, O#hÌd÷Îû{òþczŒïw0g#—ùß¹_ºzz?Ù&19ã¦Î‘¿…½ ˆ+;éöfâ=ñ’ݧ1°ø¿ãqöÂõ9±Ç W“Fðk¿… ù[yøÕgãJnÅg£LÅâ)¿°éÌÉÝ[Wû¥ˆ(lȳÀ`rã…²UT¢ýRDþ™a£M›6O<³¬\*"""ÿ|ªQØ‘¬ÿìN$Ž$šIEND®B`‚././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/http-headers-status-v3.pngrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/http-headers-status-v0000644000177700017770000144573212633765070033575 0ustar michaelmichael‰PNG  IHDR Bˆå°vÍsRGB®ÎégAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<ÿŽIDATx^ìÝ œdey/~LâÕÄ«ÉÿÞĘ\·˜`î½IÔh”qÉ¢‰&¨j£(*Š‚ƒˆÄ]@EqAed†e€a‡a؆Fd“YØ5^ù?UO÷Û§OUWï]Këó~šÓ§Îò¾ßsªºéúÍó>áñÇßȃ @€ @€ @€ @€]ˆ“ @€ @€ @€ @€º(°QÏíÔ @€ @€ @€ @€1&· @€ @€ @€ @€]cêòpz @€ @€ @€ @€æQŒé¶Ûnk½Þk×®ÔM0Ùí'up @€ @€ @€ @€˜Ÿ3cЍÐöÛo¿xñâVÍêS{î¹glÖáGè¼Af’ÆÚ¦µ×_}l\ëUv©m¼©íÝpÀìºë®óóF1j @€ @€ @€ @€³'0ó1¦Í6Ûl¬SyêôÓOmòqØa‡Åú6•5±©£ê·Wª®yì±Ç¥u}lI£8`¶ªßÖH™aŠ-'cŠ Sl,Æ4{÷¢# @€ @€ @€ @€Ì[îĘªÜ‘"+ùT6‹¼QÛüÐXëcãxꡇª¡®ŠUF &cŠãDÊ*¶œ~Œ)椋„Vô*bàåQ»ÿªOårƶâÑ6tÕº}N~W;Kn–OµË¸¯„L˜`m~½±úܺ¾:œÖÓÅaË`óÙêš2eãZÇâhÕ½ªwE‡ÁÖNT¶Œ£µ?×ÔN4ÖÅ­ÝünƒØrùòå¡_[»É8`ÞQåöhK}‹Ç½¸6 @€ @€ @€ @€tK`0cL‘í¨æ“"ð‰¥’>ÉLR|üǸ1¦Ø+O%‰tÔ4«1Åî£É U°Ô”Ê› s]ùTyd%+HµÞ+åPeû¨›å,x幜OµK‡1ÏGˆÒV9-`ªsŸcËëeHeÊwRt£LuW ëD¾$zXzÕ6«”+ÆÔy­Ù 8Nç]Z‡»TãGa‡ÍlÍX«d‚gìcK&OT¢fÕÄO-x1²Lbu¸Ž­Ã‰{ IbL倭۴=W‡³dð®:мCJ©Ü-yäè[mD­Ú9ð)ß½v$@€ @€ @€ @€̪À¬Ä˜"TIŽÚ#£EµB;1¶Ìµ®¯; Ï´B´]ŸéjÞ%úSêU2‘SuûiƘb÷Rª5¬S‚2"A]Œ1e©¡Ú%ˆTM™¢®sÀ(vœƒS\èˆþDW«5ZCEYʨÃëªÕ¹dVcLåàåf¨v2‹`åšZŒ©\ˆ²}[í¸‚ó­ Ó%—\òOÿôOo}Û[·Ür‹-ãË[·|kõñ¶·ÆSok¶üOs¡ÙF=;Æc‹-·j[lñ–-ÞÒã-úüú׿þ‹_üâÃ?<«?Eœ @€ @€ @€̈À¬Ä˜2EÔú˜S™Z«:kXœ¨Z7¨VئÀÍeŒ)'§+§n1•lMfhâkõ‘;vˆ1ÅîÕí³|T‡Ó¥I‡]j·Wk‡«tèsÙlâ1¦Z .vÌ”[ç³d£<],”ÄXkð¨6É`ë ©Õ¹$áf5ÆTÎÒV»Ú«ˆ4Åcû¸ÏËH«i«o›ç›‘·’Þ<ÈvÛm·ù–o>ë‚3NYvÒ©g.]vÎégžæ9ËÏ>Åù+.½ð²•—®¼æÊ«¯]uõuW_s}£ÅªÕ+/¿ê²‹.[qþEçŸ{á9gæç.;í¬SOYvòI§-9aéâãO>Ž=æ„ï½xQ´EÇuÔqG6Ú±mG{DlÿÝŽŽãTÛ1K¾Gk<;áCuØòÄÓ–ìðÑžö´§}àèÍ«£W @€ @€ @€ @ *0+1¦¶¥•ƪº4ÍjL‘Xªå¥"Û‘³³å£sq£q'•«bM§S­šQkN¥ô3AJ*+:=jÍrUS\1„¶“ÊÕNQÛ¥ö:©!:SöÍXL‡>—ãÌHŒi,™8KµXQµþVÛ)Þ:w&‡S½¯J%ª™1u–qcL1Þ¸ 1äØ2¯~mŠÀ¶ÌI÷æÕ;à—¿òåsWœ}úÙ§yÞôÒEç­¸tù¥W^rõu«®¾~ÕE—\xÖ9gž¶ìÔÓÎ8íô3-Î8{ÙòD¼iõ«›y¦ /¸øüsW4òLËÎ9íÔ3O9yÙI'ž¾dñ©Çgžé¸9æÄïF)bIjKŽŽ£}ç¨oïÐ~{}ï¯î÷•½÷ÿê~ ÷=äðCŽ=ñ˜Å§?‰£}Ò8ÈÒ3OÙúý[o»í¶óê¢, @€ @€ @€ô©@ßǘÆedÔ£íå™ËjLµøKkN%RDYL¨7'•‹‡daÌ2NŶCŸË.1ÕbpŪóY2u”ùª\ÎS·²2VÔdëE[+ûTÝrfcLÕ²[Õ³´1Å|pÕ‚^ÕÎG˜¬v“·ÕŽqûzéÓ7²±ºý•½¿rá¥dŒé¼ ÏY~ñòKW^ºêš•—\vÑ·¾shÌ÷ìç<{£'lT}üÏßÿŸ¯}Ýk¿¼÷—/¸¨fºòê+¢nSäŸÎ>ÿ¬eç,kĘN?qÉ©'J#Ãtì’c¢,S¤—²,ÓDZlõ–>¿çç_ýšW?éIOzâŸø”§<%~ã7~ã…/zá.»íñ¦H Mü€N1¦÷m÷¾±n›»Ö†C€ @€ @€ @€ý.0ø1¦Zþ¦zÁz*ÆT õfŒ)缫ÍUW2=]1eħ:G^|}ŽË=‘àQíeÜa8eKkN®mý§ÖwŠg©ÕîÊ}ËÒZT©õPmcL¡4cL+.[ÉE†é‹/¸|Õe«®½êØãyã›Þø›¿ù›™^ú­ßú­§>õ©OúÓï÷~ï¿ý·ÿV"M/}ÙKúæW¬¼|åê•9æVœÖg~öéKÏ8å¤ÓOÌÙå¢xRVN*ÌuN2EòéÛG~k‹·mñ¤'?9Nú‚¼ ¦½ûò—¿¼óÎ;ÿÝßýÝÿøÿã Ox¦¯Þtÿ÷#O$Õy›SÎ8ù½Û¾WŒ©ßNë? @€ @€ @€æ‰À€Ç˜¢ÂM‡"@scªMjs´E5R¨ë1¦(VT‹+å‹¡:½]|›™˜ÈÖÄòÔbLµyÐÊY¦P©:‹\§¤‹ª¡¢¸"!S¹•ic¤9a_õÑa8yG• ø2>•y©òh1Mö,©öå£z‡Ä·qÒÚ³y!Ê£ím«mVøà}ûÕ½¿zÉ•;”aºüº›®Ýï€ýžýìggVéþÏÿùÿðŸøÄ'ân‰[⤓NúÌg>ó–·¼%6ˆlSlð»¿û»øàöË/¾àªÕ+W\ºâ¼‹Î;óü3¢¶SăNãÜe§uêÉËNjL-7º SçÚH'œºxÇ?üã?ú£cŽ9&Ïû­o}+Öl½õÖùíºuëÞµÕ»bÍæ[l1©idcê—U?  @€ @€ @€ @ <ÆAågÚÆ˜"êÕzÆ*49¹¢3µ,QoÞ‚Ó)Õ†Úö0Bš~ç#ÔZ iú‡Ô"¯6µE!0ñÎOù,1–¶·bcçg«™ëšÎl1¦•«¯¼øò‹¢Ó7=83LOyÊS¢êÒÏ~ö³ÎŒÚHÿëý¯Ø>fÛå»\wãµ—\yñÖùgŽd:åøãN<¶Qfé„Eç•‹éä¾ñÍ^ü’?íiOÛwŸ}~òãçÙ—.]úÿïÿýÜç>W:sÙe—=ç9Ïy泞¹ÇW÷ˆ½¦“dc€{Ø @€ @€ @€ 0f8ÆqHêÄL[­‚c=Õa—r8fÛ`ÍXëËŽ‘P©–Þ©õ*O]+¼Ô¡S<Õ9ßÓù¾‰M'5g7eky¡Ù8uhÌ͉:w>.èÄÓHSv˜›³tîÞ¸/–)®—wüÚ>_[uÝÕW_·êÌsÎxíë^™¤'=éIŸÿüç'Øç“O>ùÿøc¯?ÿ߾軋®½ñÚ—^xÞ…çžqÞ²SÏ\zÒé'F¥FA¦%Ç|wñÑcL'ž¾äc >‡zÛÛÞö_ÿõ_ÙŸÿüçwß}÷š5kn¿ýö˜`®ôj¯½öŠ-cú¹ØKŒi‚Ëf @€ @€ @€ Ðï3cêwŽÙîLéÕ!V5Ûgwüy+¡±(6‡ÿµ}¿u˜®¿åº/~ñ  úßøw¼ã?üðÄ)?üðßþíßnÄÞþ¶ëo¾î’+/.Ètú)ËNnÌ+wÊqÇžxLdúî $ÓX©£(Œôž÷½û OxÂ>ûìSÎoo¼ñûoÿíéOúATÖŸ}öÙO~òo¿âU¯ˆ½Ä˜&~±lI€ @€ @€ @€}- ÆÔ×—Oç è$°Ï¾_[sÇ­K—ú÷ÿ÷¢Jþççw^îÕÖ­[µ¸6lØðË_þ²¶ò¾ûîûÕ¯~+ï½÷Þw¿ûݱïŸþÙŸvÄw®¹nÕ…—,?wùÙËÎ9}é§œxÚ’ÅÍyå¾»äèqcLïÚz«ß}ÚïVg–<ôÐCãÈùØzë­ËHV­ZõüŸÿò¿ÛDŒÉýM€ @€ @€ @€óG@Œiþ\k#%0ïöÙwŸ»ÖÝuÐ!ýþü~”bÚn»í’à®»îŠÿê¯þêyÏ{Þ&›lrà>ðÀ1¿Û'>ñ‰¿üË¿ü“?ù“W½êUGydÖm:öØcë·~ëIO~òÇvþØM·ÞxÑ¥+FÍ+·tñq'{Ì ãWcŠÓSÿûS9æ˜r¢ÔS‰1•¾Å³+W®ü“çþÉߊ1ͻր  @€ @€ @€ 0¯Ęæõå7xƒ-°ï¾û¬»oí—öüb¤…~ÿ÷?bC1ÞH,Eé£X³Å=ëYÏzò“Ÿüßÿûßyçßÿþ÷Çʧ<å)Ï|æ3c¢·ßû½ß‹$SlAF¶)žÚâ­[¬¹ýÖ‹/¿èüçyþ§uÚÉËN:áÔÅÇ|ìD&•{ïû'ýâ¿XÌ£êR„¨båsžóœj•¦SO=õ7~ã7_õšWªÆ4Ø÷§Ñ @€ @€ @€ @€@U@ŒÉý@€ÀÀ ì»ß¾Xÿù/~>¢BñqÑEÅPO9唨®ô›¿ù›ýèGcò¸ÈmµÕVÿùŸÿù;¿ó;±r·ÝvûÁ~ðÉO~òMozÓÕW_ÛÇÜsïxÇ;âo|Ó¿wÇ÷.¹ââ .:ÿ¬óÏ<í¬S#Æ´äÔŽ?ù¸qcLKN;a×ÝwtÔk_ûÚÿøÇEüÛßþvy›m¶)kþë¿þ+2UQ;ê?Þó®ØkÑñGM¹E ê½Û¾wûí·Ø l` @€ @€ @€ 0@bLt1 …ÑÓƒë¿ð¥FŒé5¯yMä“âùÃ;,¾éä–-[V6?ꨣbåŸþéŸVWæ³<òÈŽ;îϾéÍo¼íΈ1]2…Säœ=âWÿëã8Ÿÿüç{ì±<ø¡‡kÞýîw—žœp O{ÚÓžÿçÏßÿÀýc¯)g˜bG1&/ @€ @€ @€è#1¦>ºXºJ€Àäª1¦W¾ò•·ß~{ìÄGDr(¦“;ñÄãÛŸþô§ëׯ?è ƒb峟ýì¨Õ”+×®]û³Ÿý,–£xÒ;ì0ÍS„Š¢´ÒîŸýTL`eŸ¾úÕ¯F:*óÇýßÿû?÷¹ÏÅò/~ñ‹ÓO?ýÏŸÿçQjëm¶žf)&1¦ÉÝ+¶&@€ @€ @€ @€n ˆ1uû 8?³&04©Ü>!¤ç?ÿùçœsNœêì³Ï~êSŸkb.¹[n¹åÃþð_þå_Æ´nÏxÆ3båvÛm+?ô¡EÎiñâűýÝwßý–·¼%žÚìM›MyR¹½xÑñ'÷Áà)Où'?éÉQáé†nˆëxà˜Û."V‘mzú<ý‰O|âë^ÿχ}ØwO8z:¥˜Ä˜fí¶r` @€ @€ @€˜1¦YauPzA`ß}÷Y{ï={}u¯¨oô»¿û»Qr)zõÐCí²Ë.ñm$“žÐ|üŸÿó>øàÏ~ö³OyÊSÊʘ`îøãí¯ºêª¿ø‹¿ˆõoÇÛoýþ-_~Ñù+Î;óü3N;ë´“—t©‹;ùؘý-RGTê<ŠmŽ=ñ˜wÙé™Ïz擞ô¤'?ùÉ/|á ·ÜbËø‡ˆdU˜~ÿ~ÿmïxë·úö4§“Ën˜T®nB} @€ @€ @€ @€ lôðÃßÙî1ÁýmF€ DÙ¡Ö7›{î¹g‚»Oa³}öÝçöÜ~äÑGn¼ñÆ‘CzÏ{Þ·Åq~ô£zè¡Qcé oxûÞõ®³Î:+VF÷¾ò•¯ÄšýוQ´é×ÍÇ‘GûþÎS~g·Ýw»áæëW\ºâ¼çžqÞ²SÏ\zÒé'ž°tñq'{Ì Š1eM¦ØþÀoøŽ­ÞñÜ?yîDý¥?|z´?þ_üú}ýÞûï9§qãP¬Ò$Æ4…{Æ.´ˆy0ýºèÞ @€ @€ @€˜mâC© Û=fûÄŽO€À|¸õÖ[[ßl®¸âŠÙsØg߯Ý|ÛMË/^þ¶·¿-¢HÏ{Þó–.]:©ÓÝqǯýëcß¿ü«¿<áÄÅ«V¯\~Éò³—Ÿ½ììÓO9ã”O[²ø”ã#x4ÁjL?Š”R–n:ê¸#<öˆl±OM¤¤Ó3Lª1MêBÛ˜Î6lð뢛„ @€ @€ @`¶Ęf[Øñ ˜ûÓ¾ûí{Óm7G’é€oìÿ;¿ó;‘FŠbK÷Ýwß/ÉÏþó/~ñ‹±×oþÖon·ýv·~ÿæ+®¾âÒ•—,¿ä‚s/<÷ÌóÎ8íìSO9óä¨Éy¦%§ž•™"Õ4ÁÇ.Õ6©Ý'r–3/8cÛn»ýöÛOp¼6#@€ÀXbLî  @€ @€ @€93ÆÔvê+  0eU«VÍq5¦=÷ÜsÙÙg\~ÕeW^uùû¶yïžð„È$½ï}ï{ðÁÇ}{ýÙÏ~¶ï¾û>éIOŠ]^ö²—ž~ÆiW_¿jé²¥G}Ä·ŽøÖ7¿}ð‡.<àà¯ïà~û}cß}¾þµ¯}}ïh{ïÿÕÞi}ëÀ-Þ¶Å;ßùÎ)_2; @ n¸áÕ˜ÆýÁa @€ @€ @€i Œcjûa••˜YYTnë­·~îsŸ»×Þ{]óu§œvòËÿîå‘IŠÇ[ßúÖk¯½ö¿øÅXo ëׯÿüç?ÿä'?96þ£?ú£}öûÚ-·Ý|Ô±G½bÓWDjšìC>2Y• µåižeè€OØèo|ãÌ^2G#@€@˜æ¯¡v'@€ @€ @€ P0©œû9˜ûIå"Æ ¡?þã?þŸ¿é{7->qñ‹_ò⌠ýÙŸýÙþûï%F¢2Ó£>úë_ÿ:¦{衇֮]»xñâW¼â¹Ùÿøÿã3Ÿýô÷ï¾í»‹Þäo7©&¦¼ü”§<åùÏþ ^ð‚§?ýéqßÿýßæÑžúÔ§>ç9Ï™ò‘ÛîhR¹9º¿†À@ ˜Tn /¯Á @€ @€ @€zE@Œ©W®„~xnŘ"Üóìç<û«û~õÆïÝtÒÒ“^ý÷¯~òo7Ê,Å#2C[n±åî»ï~Ì1Çì½÷Þ[mµÕ _øÂRiã7Þ{ß½¿wÇšS–òºyÝL¥‹¶Ûn»‡~øšk®Y¸páŸüÉŸl»í¶K–,yÆ3žñ¦˜ïÀœ©åqĘþ•e€æ@@Œi‚ @€ @€ @@ŒÉ=@€À t1Æ”I¦¯|í+×Þ¸úò«.Ûy—Ÿù¬gþöoÿvÛÀПøÄ§ÿáÓß²Å[N=ýÔ›Öܸdé’×½~Æ2LqÆ \|ñÅ/}éK?÷¹Ïí»ï¾¿ñ¿ñ|à ƒÚqÇ¿ùÍoþæoþ¦ÓÝ‘NC€À„Ę&LeC @€ @€ @€© l4õ]íI€ÞÈIåÊãþø>ý¹ÿ¼èÒ7ÝzÃ]°ë§>ùŠM_ñìç>;"Mdzžù¬g=ëEý¢í?¸ý)§|Ó­7^¹êŠC¾sèLÍ%Wºå‘¢ÓÊ•+£SÌm—ëwÛm·¥K—F¤if3Lª1õöªw @€ @€ @€ 0" Æän @``j1¦Èô<ñ‰¿µÙÿíèc>oŹW\}Åu7^wÃÍÑ®¿ñ–¢ÝpËõ×ßtݪÕW­¸dùIKOüðŽþý?øƒÏ}ò“Ÿ¼âŠ+¢Ó—¾ô¥o|ãyü˜Øî¬³Îšñs‰1 ìÍm` @€ @€ @€81¦»¤D€À°@kŒ)sBO}êS_ûº×~qÏ/~÷øïžxÊ’%'Ÿ°ä”F‹åã—·ßû½õío}Æ3ž1¡¢8æ[ßúÖ˜_鍊nŠS™Bn»í¶‹yåfãŒï}ï{Ý @€ @€ @€ @ ÷Ęzÿé!SØa‡:ƒžÐî1Y¢Ú1cò¸'>ñ‰qò²>;2ã§þíßþíOúÓSä³ @€ @€ @€˜C1¦9Äv*æV ænÛx~<ž÷¼ç=ó™ÏüÓ?ýÓÚp#Ãôë_ÿº­úÂ… 7m>baj—eýúõSÛ±ìµùæõ”CNðØÛl3t„\Ƚb@SÓ¨þÄ1׬™æ§ÞŸª@fµ7Ñ·¶ë'ÞãVÿ‰ïkK @€ @€ @€̸€ÓŒ“: æZ`Æ ^xáÃ?<ÁGziÁ‚«šm¶Ù&–'¸cu³Í§‚ÙxãúiË!'xìÚöùí{4Úô›núøªU£‡­­™ÈY¦ÖŸª@[èIôp:Vÿé; @€ @€ @€˜¦€Ó4íN€î L*Æ´hÑ¢Z)¿õ‘jÚ£™ŠJK±5Ãõˆ–/_žk–.]D §¨ü”•œjÇ–±WîËñ (b4ñdœ0‹'År¬Éoc!¾>òHce,ÄÊr˜QZ´hhÇ\({Å‘ËʽJ9¥ L*Æ¡¥Ì*ÕQ¢)ŸŠXRD”"® ¤Xi¤xÄB„œbM<߯r>ÇBl|*Žk2Æ9§“ÖEŒ&¦E‹8NăJr(¾Í€N$b!óL™pÊàQ)MûæÌk¹PöŠÁÅÆÖ‰ðM&ub9K+Å¡²‚Q5oTÛ&RGm4t´Ü+ÖäIc!ŽXkªOåªkb›X§ÎlVõQžÛäs÷8Nf¤R Œ.–³3I‘89–laÌ5 [Ž_ÎÏãĵçS)Ü:–oì5ÁBYóéõg¬ @€ @€ @€ÌŒ€ÓÌ8: º(0©SfŒZ{›A¥XÏÆLsÕ)çy䑈+ÅS%ÏËYÃ)K4åÑ¢žSìX]ÓÙ¤Z (絫MW7-B6µ¹ïÊ”je¡uR¹|ª:=\qâP­1¦Ší£cyê2…\ ?åšÖ§Ê–%'Tz••ª2ðìI9W,T³D¹K'j;ef«ä™ N¦âÙRö©vüê©«=ÏÍJ‚*1©ÚXªã³Ls&»Î·„g  @€ @€ @€˜ÏbLóùê;"0©Ó‚ j1¦ˆD5Æu•âÛ|D2)2LZÊåx*ÓNcН9Í\<²DÓbL%‘Óc*Ñ¥j¤)ÎÙ|ª,4;ÓXS(ej§Äzʳ­1¦ê6¹Wkâ'#GåD9êÜ,žÊM“*»³Œcʳ‡±W¶E~-£‹üP¬‰g³ŠRìR@òŒñl´ÌK•±äñ³·‰ºG­Õ˜2TbLYµ(ùT|›bCóÁM¤SÆŒ²ÀR>"®”ÓÌåXÊ0c³’èÊ(R ZµÕbLC‡nþ§ ³ô¼º&§ö«%¶l ?Ui™ @€ @€ @€3" Æ4#ŒB€n L*ưQ–MŠ…È0Õª1Åñl’b!&’‹ rû¨Æ ‘sŠmbÇØ&æ›ËóPQ·©cŠ-sã¶jÚ&³8YÍ(“4‘ÚÉ2E±&–cƒÌ U‹•oóø¹Wk5¦ˆe-¢,\²&Ž–ÝÈ,Qìžkrö´2½Z‰1e€) ÅK¤Ü7×äÆq®hÕmâÛœ®5fT6Žã4kc ¥”>ÊÉæÊ5cLÑÏZö<·ïcÊaæqªÏ#$NëXĘºùòvn @€ @€ @€óF`†cLW^yåâÅ‹gOʃ_ýõQ d¬~úé±Á”»ûÆÆ=Ë”?g;Ƶxì±ÇfötE¾ó%˜ÈI£o³z·L¤¶!0“1Ũ#oá¤x#…Dˆ¸RU#ª4UßfãÙXGn)y„œ].±P–˱¾ºÜJ]BBͳ=Ÿ+£S¥àPÒ¥Z^¨o*je^³œ¹¬Túi <åle¹c­@QíDÕøN9QìGhÛ‡RL(7.ñ r–ìX~›sÏÅfÙáêñ3UÍNµ]m›¶Y«ê]UMU#GÕüSn_ªCå·U̬¨”jÔ)ëBeZ«æ©¦Çªò­Óùå|‚µGµÃÕ^ÅrõZ”³”ÉûÊqjQ­ªŒeŠ€“› @€ @€ @€ú]`bL¥|QZä´k9›X†‡r}©WT%«Vú)¹–Zž&B6qÌêüqµèO5áT1mÃIÕþ”n”’N¹&ž}γä³"T<Ê wÕþä69äj«íèªÁ jE¢¶Õªª£¨v¾Š\RÝ`,Ì(”£‹þW§É‹oÛ²Wm‹I^Ù0*çªæ¨b˜­ ¤ê)ª÷C9KUµÚÉ~™é?Ù˜lŒiýúõ .Üc=-Z4Û}ëpü=ö˜îÉK÷«ãˆLiKѽ©œháÂÇyd*;Öö™~Ú^¥è[ôp:iú¯_ßpž¦Ò4q¦0@û @€ @€ @€ 0³Ó1e(§Vtg¬zH­³¹•yÇr6±Ro©3bCY+(žŠàK&oªQ¡,UŽ\ ÄÄS%~”“Á•I⪈9„œ7-NWž ùlNuÙl³Í2“޽òŒ¹q-ôÓvtÕmª‰ÚVŠÊˆXŽ¢Ì—uªE•r8Å*ûVŠEŸDÈ£•#d"ª”’ÊKYU›º®Š“+±Wémö°5ÆTN-â–Ã)“ÊUû0³w¼£HIŘ"ôñÆ/X° bLÛl³Í¦›nÚ-“7®Ÿyó͇֔…Î}+}Ï…Ü+Ò9Ó èäI㘫V:Dvjk&B7µþTÚ^¢èÉ4/]«ÿD†S¶‰qE©UiRqj8¥ÓG¨ ¹Ã7Á{rR†6&@€ @€ @€ @ *0ÝS­|N:")‹‰òBÕØP,Gº¥¦Ÿ•2¢!›͉xPfƒÊšLùÄ6qØj‚'–«ßÆ™ž‰ÍªYŸ¬ÔÚìO™ý-²ÏÕ³ä©óìq®øš{e'³>S°ÊÙsƒ¶£‹mJÀ¨º}mß:Ÿ¦èU³J72ÅUb!7®­•=ŽS2jÅ$ K9Qœ«ô°(U¯xu8ÕÎT{[[³¯vÛø–šÀ¤bL‘^Š S9BĘ֬Y“ß®j>ÊSe}.<Ò¬MT6ˆ8T,ÇײýX»u½"F‡Œæùc931™M)+c¡*Ë‘¡É¸R.”½2SÛ«Ùó‘ãĹJ¥¥rÀJ,Ç×ÄÁ«kâ©ÒóZu¨ÚÀc÷Ø2wÏTPK]Œ=;S(J!¢X+ cUa«7OAÎaÖpš—®ÍXÊxó\ùHÉšR9~Y¨ö'6Ž ]}t¾Xcõ'¡òk^∗•‹•Q³]v;£Nyõ+ù½Æ6¹2S½[µk÷d!/V‡ãªo @€ @€ @€O`ðcL0Ê FãQLîùÈEe£\˜Üζ&@€ÀŒ L*ÆgŽ$SdŒ"ÌÈÅš… –MY®©mŒ©l;f *¾F¤)Ž_sL™yšÈø²SnÊ W¬)å»r\e›Ì*å£R*gÌQ”ê\ÙùVíX™OUïɼŽ_•·L€ @€ @€ @€À¸ƒcŠ9Ñ"l4ÖtrãuØ i€éľ˜¾ÀdcLåŒñ©£Ì!EQ¥\Ÿ¦¶1¦Ì<Å#bLÕnÇöŠªF£ÆW9F‰†´Æ˜JÆ¥‰#Gh&³)e!–[+-eФÚÙÌú´Æ˜ªÛä^ùux¼ÿ–SµÎT)É+³8PÙ}سMŒ©úTœe£,­Œ¥:º,õÏ”U‰ÐOYŸ×§ k"©“½Ê…2¨RN©zêØ>~¬UÇlÝ+ð³8V«RkŒ©$º²oÕþT/Dq·?Õ‹•§«î’>µm²8SÜãÕ³§a¯Ê„Sé|M»<ÕcʧÊñǽím@€ @€ @€ @€ÀXƒcrí  0ð“Š1U+'…L$“Ê#¡"ÕÃM<Æ•œ"ÆT2,Å'šHŒ©ÄJ"}R,²;Y³§,ÄòX1¦jÔ&ò7Yü©THÊnÔâ8cL±q©ëSjÿd¨µìX²;¥ÖT¹k1£ZB+cF9–2º~))T­Æ”•œ2QT­Æ”çÊZAQj(cO±Pfö0¾–8nž:XK ';V®ËDbLe¼Y̩ڟ¶1¦qûSXJ@UCKe‰P®Td˜²DSÑ(‰®Ì6•qµj—§ZcLµã—«l @€ @€ @€É ˆ1MVÌöè9IŘ"o”sÉEÞ(H11Üš5kbedÊgãk¬Ì5‘jŠ…Ø8ÓN9ø˜].£Nñ5–c³,à 9ßÜ#<ï,ÕcÊŠAñˆ§"t’5u"Ê““‘e^¤L?—ÙÈÓäBÙ«5SªÅ¡ò¤±ù›ˆFåšœž,Ni¡X“›ÖjLñl†â¼¹{¦‹J‡s÷xäXb›Ø2ûßæ$zµSuãØ=ÓZyÀ2º ÖÄÑrñ5ó4cŠå$*IŒ1U9ÌX¬<ÖdÊ'0ÛŽ¥ZÃ)NZËTÿ2–êB0•µ›¢õb•vèO²§ÆÊšH*ÈY­*X­ {¥vjäˆòªµj—+R|òBäëø£è}C€ @€ @€ @€ÀxbLã yž=/0©SŒ&bFHвLñ5–s|‘dÊ R©«™¤ø6ÒH±&bIñµ:f¬Ïgs÷Ø8òL倉1•„M„{ò0‘ÅÉêAYÁ(“:ñTÎt–Ü«ÄhÊB¬Ì½b˲qIE„%3%ó”‡õYÕ©œ=ó@ñ(û–“ƾyüØ ÏUB9Ùó<~W®ÉŒQõ€ÕWÇ‘šÒ™<~utÙá uE+h¥'‘.Êþ´=þÐ ›­ñ-'r´ê6Ñ]wÝu¬nÌÞy'ÛÏ®lÿÐCu>ï¸t¥ÛNJ`€&cêŠÚlk³Úí •(U­fOëy«…šfµWƒqðêŒoƒ1"£ @€ @€ @€ @`6z1Ætúé§G„¨ÃhãÙ Ê\ýõpÀŒ»¬]»vûí·¿òÊ+ãøÕƒWÏÛ¹‡3Þ¥Þ9`\ÎæãnÐ;cÑ#0¨1¦êäesp±"ɳƒEËÙë:qäHÅ#V–ÅcMl•“ÊÁ3`ÈBÅrìOeu¥ÖkSíUž4ÖTO‘»´ž·Œ±Úɶ/'ãGgòø±¥žZûœa©ìpHìU’Âùhí|¢e9«µŒòÔf+aRÂ'6.õ“ª§(y¦’Œ‰sU£6Õ Oѯ–kÊ•cu ª!—«É8Q-ʨc¡š¬Ê«}¨n™ËeyüR䩊ƒdÈi¬Î…Vº]Û¡Õ[6+H•™ìâÚU§ºËaÆ6±ë«TÇ[íXlV;l¿Ht@Ï ˆ1õì¥Ñ1 @€ @€ @€˜¬À ĘªóµÕ2@Á‰tNLLVI¹A)ATº›ÅâÛR§šì)uŒªÇ/ɘê–e.¶8o)æ‡-á§rÆZ¨t Êí«ç­&uÊYÚ¼v1ª}¨–\Š,Tú$WîUê•…XYŠ0Õù*EégÛöí@µÃÑ¥œQ.I³‡e¯ZY¦2Õ]õ°e¼y„ZÛÃNö®µ=) ÆäN @€ @€ @€ @€˜S)ð“(XÉ9Ñ"=S&›++3îqœLäd´%·ŒÉÚr÷ئzœ¬á”ÇÌÂ?¯)ç¼N–>Šc–2Hµ°QkŒi¬Ôêå jç-a£rê±^n”Z¬ª0ûœ!¡œú-GWfÊ‹5iëKÑ£zåŒ%QÔö°m;P½­‹d†Ò?'΋…œ.°tu³Í6+W-7È©÷òBG -—óªåŪv`^NB`ŽĘæÜé @€ @€ @€ @`öf ÆTfË^f¡ œ‰,“+ñÈO®Ì˜Kmef˜"ÚRŽ–A™,/T›•Lõ¼™Ô)y 8Tdeʉ"&U¦B«RV{•ˆG¶,—kç-㪞¥íÀË¢¥$U®,}ާÊfee™“.“CµÑµÕ‹NVMªþ­‡«¥'%~TUÍã¤O,çÍ TV޵A¹ía«Å2xä‘G®m÷øÅ/~1ñƒØ’ @€ @€ @€ô‚À ĘzaƒÚ‡Ú\uƒ:Lã"@€ @€ @€ @€˜çbL=}D§Z±«žî®Î @€ @€ @€ @€˜’€Ó”Øæj§˜e/su6ç!@€ @€ @€ @€ Ð1¦î¸;+ @€ @€ @€ @€E@ŒÉÍ@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€.ǘ/^üØcÍÈe¸þúë—/_>#‡šþAfp\¥3§Ÿ~zŒqú}Ë#{tr¦Žæ8 @€ @€ @€ @€¦#ÐåÓöÛo?ÞW÷PN}fêhÓ9N$„öÜsÏé¡í¾»îºëm·Ý6S‡DTp¦Žæ8 @€ @€ @€ @€¦#0“1¦‡z¨µ+k×®m]™[F(§–¤i{„¶Ã›ø–ÑiÛÉÎ;Nj—‰÷¶ÃaKä«õhc¿íú\©¯Ã;l\œj­¬I yÜ#Û€ @€ @€ @€ @€@˜™S’âQ›މ LYY¦{»òÊ+seylذÁÅ#@€ @€ @€ @€ @`0FbLwÞyç7¾ñ‹ûáqÔQG-_¾|0.€Q @€ @€ @€ @€ 0*ÆtÈ!‡¬é‡Ç’%KĘܻ @€ @€ @€ @€F@Œi`.¥ @€ @€ @€ @€èW1¦~½rúM€ @€ @€ @€ @``ĘæRN} ëׯßxãÍÓ7uÁnï—/›o¾ù6ÛlÓíî8?^Xºt馛nš¯Ž ôJ·ôcªïÃñV3ôâ(©·Ê]W~è­þéM ì±ÇÕ{&Þ©z¬ƒº3Pñ¿–q•w'?êêvL\÷x·)›ÄrõÛùã`¤ý"wìªU«ú¥·sÜω·ñ9>i/Ÿ®ö†jðG†^¾^³Ñ7¯ˆÙPuÌ® ä/íÕnÄÿ·Øõë2ÙÄE\¸paÙËo8UÀÉâ«ÿ7™ì­eû(x‰Û;‹-êñëÉ ˆ1MVl·Þ~=íëëZýŸˆ1Ugíëqé<éÄçgñÒ(›ÅKÃÿ¨LÇÓ¾âf+Ä›°¿oºaæ@ z×ÍÁ霢ß„ úý öQÿã·¯ê?’‰¿£ù±ØG—oš]­}6àgšžvŸm¸cŘÆBcªÉTßÐ|:Û¯ÍÞ<¾ßgzóºèÕ4Z?ùδÇ4k÷9È@Õ ò¼~Ã)þñã;4Ræ‘G‰A¥çøætºY¨þRZû8lVÏëàæL@ŒiΨ{÷Dùƒ¼ü8ïÝŽêÙÕÿ‘ö—b· ˆÿ-©ÆÏã].Š3Á!0Kµ@IÜ~¥³Dí°E@ŒÉÍ0)¿"NŠËÆÓhýgþEàt<ûk_1¦þº^zëC¾÷€S §ü*å_ºÏÛ·1¦y{é{àùË[)¿¿·Ç/óbL}wѳS¹Ž~éþ鬤»be$™¼™÷Ýí­Ãjÿîµïn<1¦Á»¦“Qü}"†¬TÉäìzfëøÝ+ÿžQ­g.‹ŽtYÀü]¾óìôµûM\`ž]ÿî 7îºüå-fîÎe蟳æß¦Ë ¼ëŸ¾ëiŸ ø¬Ï.ØŒv·Ì×ÿ²?ÿGuFÏà`fRÀú;hŠ1ÕpÊßÜ|º?“/¾:–O¾ûêréìDòGa¹½ãÿã_z£›(_Ïl—W°ü£J¿áä•iûË œž¹mudâ~Ž?Ç­x÷®Ve›£;˜ÓÓg>ó™×¾öµ/yÉKâëÞ{ïÕæ§öX²d‰jfêæÉ‰–â=Nµÿ™"ûãäGyÆœ{gìM¡õæuÔ^‰1 ê•íåq‰1õòÕéÁ¾‰1õàEÔ.U&æì²,ƒz­[ÇUý+jüÿ©+5.}ŸŽÔçX.œS '~•Šgùg7Í>}ÉO³ÛbLÓ´{o äÂø„(ë§Æ[\|+ÆÔ›«C¯ò *ÊeˆÁo8i%ÆÔww²OV úïˆ2‡:Ù#Øž@ ÌQŒé¤“NzÎsž³ÑèGä™bý’LbL3xW•B>åÈgðà57µÿ‘öÿÕsÃî,=.¿ÃU¯ñ¿pñÿä=ÞgÝë_ZŒÉ¤rý{)û¨çš}t±z¡«ªÄõÂU˜'}¨M죮Õ9Ÿ'ós˜&•›Ÿ×½GíC¾Ökõ³d£S '«1ÅÊüØ?¯íßþ”{îÏ­S¦³c/ 䜯#’Lñcêåë5VßÊTN-ç7œ2µZÔÊÕôã®Ïc øc‹{càæ"ÆtÉ%—” S,TóL‘dcêâM¿ÖT?×ÏTÔÅþ8õÔªÿ#×Ô?˜˜£½L k —ÿQ‰÷:1¦»Ä=5œj $þúãï›=uuµ3bLƒzegi\bL³ë°­ùs°|¾›÷*\1On1¦yr¡f˜>äk½”ñ‡Áüg“ Õpª¿J…’¿¼ ÌûÀÄâó'neË>(? sFàè¹S]¾ÒÕêT|ÀÕ$â:öã@f¼ÏA®~"à‚vÀî ˆ1u×ßÙç@`.bL;í´S–aŠÐRDš"·3Ê•ÂLS˜]N5¦™º3jÕJâ°ÂÈ3e;—Ç)“5Ä‚?ÃÍ¥¼sõ¸@ü1ÿ'<2L=~±ú½{Õ÷áø{AüªÓï#ÒÿÞ¨Þu¹Üû}ÖÃ. ˆ1už:?ü· Ó¼ºjs-yç™WW¿›SçôcÏgµÏåÝÛ´UçÚšÏAgõ&ì̓×þÿ«7;©W&+P~FÚ#ÿ}{üdôÝ'ËØõí«ÊFâ7œrQâÞÎOÍ|@ÐõUf\ÀdÇ3Nꀽ&01¦-·Ü2‹0UKiÊ$S„œ&[IŒ©×n#ý!@€@Ï ”ôì¥Ñ1 @`°âoèƒ=@£#@€À@ øŸè¼¬E€æ­€ßmæí¥7púZ`ê1¦L&Å£5‡ôÚ×¾6ŸŠS‰(e¦ò(SË}æ3Ÿcêë{Hç  @€ @€ @€ @€LS`ê1¦(Ÿ›å”"TÍ!E\©D”b²ð¶¥±ö`žI5¦i^u» @€ @€ @€ @€è)©Ç˜ÆŠ+Eq¦Œ7Å´q­±¤x¶„œbᤓNš`t©º™SOÝC:C€ @€ @€ @€ @`šS1E®(&ËÄRuò¸Î³ÅE¶)w‰Gì~öÙg‹1MóÚ @€ @€ @€ @€@¿ L+Æ´÷Þ{׿•‹YäÚÎ4W²J1\dŠØSÙìàƒžl’I5¦~¿íôŸ @€ @€ @€ @€@U`Z1¦ˆ•ÚKiŠoK>©ZŸ©mJ©Ì=GcrS @€ @€ @€ @€˜ÏÓ1•4RÌWM5EY¦Îá¤K.¹¤D N:é¤I%™TcšÏ·¬± @€ @€ @€ @€ žÀtcL%™¤˜.§Š{ÉK^R%Å6TÊrMÕ‡ÓàÝOFD€ @€ @€ @€ @` Ó1E,)ê0•ôR.|æ3ŸiWª&™¢\Sn³Ï>[5¦)\<» @€ @€ @€ @€ ˆ1UI‘IŠKµLRÉ9ÅS9\ÔgŠŠMmK7M$ÏdR¹Á¸ùŒ‚ @€ @€ @€ @€@ Ì@Œ)‚Gez¸H&m¹å–µ(R[*ÄB>J)¦˜Šn"Ñ¥ê6bLn_ @€ @€ @€ @€ƒ$031¦vÚ©Ä’¢8Sk,)²JÕèRnkªÓÌM<Ì$Æ4H· ± @€ @€ @€ @€˜™ÓêÕ«#É”i¤Ï|æ31—\>b9¦–›xtI5&7+ @€ @€ @€ @€A˜™ÓÔÒHSÞK5¦A½‹ @€ @€ @€ @`~ ˆ1ÍÏënÔ @€ @€ @€ @€zH@Œ©‡.†® @€ @€ @€ @€˜ŸbLóóº5 @€ @€ @€ @€cê¡‹¡+ @€ @€ @€ @€æ§€Óü¼îFM€ @€ @€ @€ @ ‡Ęzèbè  @€ @€ @€ @€ù) Æ4?¯»Q @€ @€ @€ @€è!1¦ººB€ @€ @€ @€ @`~ ˆ1ÍÏënÔ @€ @€ @€ @€zH@Œ©‡.†® @€ @€ @€ @€˜Ÿ#1¦ 6ìµ×^‡ôÃãk_ûÚå—_>?/˜Q @€ @€ @€ @€<‘SŒ-’LwöÉc𮄠@€ @€ @€ @€˜·£bLóVÁÀ  @€ @€ @€ @€袀Sñš @€ @€ @€ @€†€“û€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º,0ÑÓ‚ V­ZÕåÎ:= @€ @€ @€ @€}.°ùæ›·Ž`B1¦È0m´ÑFbL}~è> @€ @€ @€ @€n ¬_¿>2Lo¼qk'Æ1-\¸p=öØtÓMŘºy › @€ @€ @€ @€@Ÿ l³Í6‹-šbŒ)Ç.ÆÔç÷€î @€ @€ @€ @€è 1¦ž¸ :A€ @€ @€ @€ @`> ˆ1Íç«oì @€ @€ @€ @€zB@Œ©'.ƒN @€ @€ @€ @€˜ÏÓŠ1m¾ùæ«V­šÏ|ÆN€ @€ @€ @€ @€Àô¦cšþé @€ @€ @€ @€m6âB€ @€ @€ @€ @€î ˆ1u×ßÙ  @€ @€ @€ @€x\ŒÉM@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ @€]cêòpz @€ @€ @€ @€ĘÜ @€ @€ @€ @€tY@Œ©ËÀé  @€ @€ @€ @€cr @€ @€ @€ @€ Ðe1¦._§'@€ @€ @€ @€ @@ŒÉ=@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ @€]cêòpz @€ @€ @€ @€ĘÜ @€ @€ @€ @€tY@Œ©ËÀé  @€ @€ @€ @€cr @€ @€ @€ @€ Ðe1¦._§'@€ @€ @€ @€ @@ŒÉ=@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ @€]cêòpz @€ @€ @€ @€ĘÜ @€ @€ @€ @€tY@Œ©ËÀé  @€ @€ @€ @€cr @€ @€ @€ @€ Ðe1¦._§'@€ @€ @€ @€ @@ŒÉ=@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ @€]cêòpz @€ @€ @€ @€ĘÜ @€ @€ @€ @€tY@Œ©ËÀé  @€ @€ @€ @€cr @€ @€ @€ @€ Ðe1¦._§'@€ @€ @€ @€ @@ŒÉ=@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ @€]cêòpz @€ @€ @€ @€ĘÜ @€ @€ @€ @€tY@Œ©ËÀé  @€ @€ @€ @€cr @€ @€ @€ @€ Ðe1¦._§'@€ @€ @€ @€ @@ŒÉ=@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ @€]cêòpz @€ @€ @€ @€ĘÜ @€ @€ @€ @€tY@Œ©ËÀé  @€ @€ @€ @€cr @€ @€ @€ @€ Ðe1¦._§'@€ @€ @€ @€ @@ŒÉ=@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ 0ß?üð×t|üMóÑy›yõì_þå_nºé¦‡|æ™gÎ÷Ëø'# Æ4-Û @€ @€ @€ @€ƒ(qœÏé«K–žUÚ §œ•mñÉöÖ·¿kË·¿ëø“Ïj'y\³{âюɶ$۲﷣OXmQ´ÅÃíøeG5ÚéG·#Ž?ýˆã¢íðc‡ÚaÇœí;ÕöÝS¿Ýlß:z¨ºhii‡,ZÚhGòÍf;8Ú‘ÙN>øˆ“j¶›ma´Ã‡Ûa'ã°“¢ð¡öõïœôõmÿoµý¾µ$Ú¾Ñiúçñ¡þk‡,i¶öþæp;ø„¯6Úâ·¿g‡­·Þzocš-1¦Ù’u\ @€ @€ @€ @ _"Ɖ¥µülí–vÏýfûÁýî´àSÑî¾ï§Ñîºw¨Ý¹á‘lwD[ÿÈíö“Û×ýäûÍvÛÚFûÞÚïžF[Ól·þ Ú¢Ýrw£Ýí®hßí·ol¶îˆöP´ëoo´ëšíÚïÿ0ÛêÛíšhß{0ÚÕÑÖ<¸ªÑ¸êÖ¡¶ò–¢]yËývóýW4Ûå7E»ï²h76Ú¥Ñn¸ï’îvñõvQ´ë¢mXíÚ f[½aùêõÑ.¸¦ÑÎo´uç_½î…/yù>‡.9wÕºhç¬Z{ÎUvv´•kÏj´{>þé}Řúåþï‘~Š1õÈ…Ð  @€ @€ @€ @ kcŠ’K%·TÒK`úA3ºô±ŸŠvw 0ÝûÓ‘S%Ô¦Q¦fŒ)3Lk¦FŒit†éG Ó]C¦fŒ©™aªÆ˜Fg˜1¦’aj‰1­¼µ‘aŠ1 g˜®hd˜š1¦Q¦ÖÓ†ZŒ)3LµÓyˆ1í,ÆÔµÛ¹_O,ÆÔ¯WN¿  @€ @€ @€ @€™ˆÓñ'ŸÕ -5rK]i÷Ř¢Ó¨ L#¦GJ¦IÖaÊ0ÕJ1Ê0M¶S3Æ4ÙRLÃÕ˜š¥˜*Õ˜†2LÕjLW¯ËSL'׬Æ4ªS³Ó=ÑĘfêæœ?Çcš?×ÚH  @€ @€ @€ @€öÍÓ™C¹¥á’Keò¸XøèÇw‹64\3½Ô:‹\ 0•¹äjE˜&P‡©QŠiò¦‘åÚ–bjÖa]ŠéƨÃ4ÅRL1£\5ÆÔvF¹³®còZ›´€Ó¤Éì@€ @€ @€ @€ ˜@ĘŽ;éÌÌ-ÝY)¹TfŽËS%½ôÈíë‡æ«Î"WLe"¹æ,r#ÉÅtr7G»+Zc"¹R„©9—ܬd˜®¸y8ÃTŸQîÞKn¸7Š0e»èºh-ÅT‰1UJ1]µ¶”b:³czËÛ¶ jû¯_ýzÀîÙA1¦Ät( @€ @€ @€ @ /"Æt̉gÜe–ª­Yr)«.íøñÝ¢Et©:y\kù¥’^Š:L#¦ü(ÒK•Sû‰äêu˜¾ÿеßÿa¶Õ·5Ú5Ѿ÷`´«£­‰ LÙ¸êÖFk[‡©s†©Ä˜.jĘÚg˜bR¹ ®i´óm]–b*1¦±J1cúÙÏÕ—÷‡Nω€Óœ0;  @€ @€ @€ ÐÃÓ’3"®4Ü~ÒH,UBK;î¼[´Zá¥ÖÚKYä†Ë/•)ä:˜Æ*ÂtÝèÓd˜†bL×n¸0Ûê `+Ãtîªu/|ÉË¿vÈ ç\Õ¨Ætv³Sµ“Sßì½Û51¦Þ½6zF€ @€ @€ @€Ì@ƾ»dY¦”ªí¶uCs¢}dçÝ¢ å–Öþ8ª.ekä–²UÓKÃå—êSȵ›E®aºîö‡­¥S3Ã4\„©Z‡©Y„iFê0™aª–b®ÃtÞªucÚû›S#Ã44ÜÚ³VÞ¦lm'•Sinîç>=‹SŸ^8Ý&@€ @€ @€ @€fL bLGŸ°,RJ¥}/²J¥ÝóãìôÉhµÜR5ºT­½Ô¹üR³ÓCÙ®¿}¨e†©6‹\k¦á¹ä†L%Ãtå-\yËýWÞ|Ì"×h7Ýy£ÝwY´íÒh7ܳÈe»øúF˹ä¦aªÇ˜VF€©‘a:k8Ã$Æ4c·æ|:Ó|ºÚÆJ€ @€ @€ @€´ˆÓ¢ÅËFJ+UË,5—?¼Ó'£ÝZ)¹ÔÈ-Uª.U£K7GÕ¥lw>¡¥Òn¸c(Àtýp€©c¦^ó½Ö"L¬j[„©’aj˜š¦`ªd˜2À4Í Ó9«Öf5¦j¦j†IŒÉël bLS@³  @€ @€ @€ 0Pc:êøeÃ)¥GD©Ö"ôÃÇ>Y¥j»ùî5Ú]Ù†£KH/E¦áÓÇ©ÀÔn¹F¦[­^„éæ±Š0 ÕaÉ0]רô"Ûµ.̶zÃòÕë£]0ö\rQ‡)2L1—ÜPŒ©]&“Ê Ôkc#Æ4‡ØNE€ @€ @€ @€ô¤@ĘŽ<þôZJ©|Y¥È0EN,5rKCõ–ÚU]jNW™9®eò¸ë¾ß&½ÔœB®Q~)ÚÕÙÖ<¸ªÑF*0•Y䚦Ê,ræR„©ãDrækG2L`jd˜®i´ómÝùW¯;/Ûªu`*¦ˆ1½ ª1|Bë\r™aR©'oó^ïÔ„bLË—/_¸páš5kz}4úG€ @€ @€ @€˜¼@ĘŽ8îôjJ©V`éCÛ5ZÎW›*.çŒkæ–:E—¾~Èw/¿þY{é¼Ënþäg¿ú­£OèR3½ôÃs.½é“ŸýÊIç\YI/5L‘[ŠöÍ£NùàN»ïòé/ŸqÑcT`jÎ"WHî†û–^pýv;îöé½îô©½&=‘\%Ô¦s›E˜¢5&’kƘ¾Úˆ1 …–JzIŒiòwß¼ÛcQó±~ýúÚÈÇ1m¾ùæÛl³Í{ì±é¦›.]ºtÞÉ0 @€ @€ @€ 0èÓ±§eD©mJéCÝ5ZÛÄÒ w<íúJÉ¥‘9ãbò¸fnié¹+ŸýÜçsÊZ:÷²›ÿúoþöÃ;ÿç›ßú®wo³CÔ^:tÑÒxv‡vó–ïzÓ–ïÊ L`Šö¢—lòÆ-¶úàÇvßê};<ë9Ï;áŒË¯¸ùþl—ßÔ~¹KohÌ"÷ª|Ã;¶þÐß9éßÞò΋®oT`šH®Y„iÑÒKßÿáOŽaj;‘ÜÕõ"L ÓÊFkƘ·¦—Ęýµ2Ýñm¼ñÆ ,È$R-É4NŒ)*0Å>yþU«V•åéöÈþ @€ @€ @€ @€žˆÓaÇœ6\QiT]¥L)}ð£»FŠ+N, - ç–²êR¶ˆ.ýÃëþµc:ù‚(¼Ñ¥(¼”3ǽè%{ö%7ýýkÿõ {œé¥-xÖeò¸H/E†©1\s ¹Ï}å ø6LÇ/»ìðÅ眶üú˜?.Úq§_é¥ïα§_¦cN»ô½É§÷\¦ïžzi˜N:ÿÚC9ûÄó®½ðÚ »iáÛßýÁ3.½í‚1&’.´îœj¦•ks"¹ˆ1}EŒ©gnà~éHL¦ìm$™âQíùøÕ˜ÊÖq (ËÔ/ÃÖO @€ @€ @€ @€À"ÆôcN@ÒXíƒ;îúw½.RJÕöý¡bKÕÐRæ–ªíÝQõè³_‰ÄÒwO:?£KGÇB#´ÔX^tÒy]:êÄóJí¥ƒçyQ~)f‘{泟·×GÆDr±ðïïùзŽ=û¯þúe‘aÚ}…±}‰¯{ìDd˜^ù¯ß÷Ð%\³þüF[wþÕëÎnm'’‹"L™a:ëÊ{^ðb1¦ Þ\6k/1¤˜Z®úÜDcLQŠ)j:µNJGš @€ @€ @€ Ðïcj(Å”p9+ÜvüD´Z\©5±饨·tÍmF±¥l1a\LWÒKÃÑ¥ósÚ¸ 0}h§Ý߸åV‘[ŠSÄ’>ø±Oeí¥H/Å·GDŒixò¸Ëoºï²›…—^øâM.½ñ¾h ;ù/Þ$Ê/EŒéœ+n¿øú{#À´íŽ»]tݽ/øë—zìÙÑ"·å—"Õu˜b¹%ç®þÔ—¾ñÍïže¡†2Lc˜Î‰YäšÉ ˜VÞ“ÓÆ‰1õû=ßÝþG€©uR¸ ŘbÏÈ0E’©»pv @€ @€ @€ @€ÀlDŒéÛß=µCQ¥í?ò‰hµ2KµÄRæ–"±4ÔÖ<%—¢ÞÒ!‹–.:éüH,}á«•èRN׈1-9/L[½ïC¯ù§7lõÞEkä–š¦˜9.bL1s\¦—rò¸S—_¿óî{½së]rÃ}‘^ÊS¤—"¥_c ¹(¿´íG>å—"½SÈEkĘVGŒéO"Ã-¢KÑ2ƘJ¦±f‘kf˜î‰–&1¦Ù¸çÕ1c^¹Ö SŒcÊô“:Lóêv1X @€ @€ @€ 0¯"Ætèѧ6cIÕ6RT)cL¥ÆÒ¨¸Rä–š‰¥œ'n¸=õ–¢ÒR¶$½ë};\xÍ]oÜb«Ïå æœq¼ð%›,»è†e+nX¾êÎŒ.E™¥Ó.¼!L]Š“ÇÅÌq‘^ÊÚK_9ਨ½ôãÏÉ L‘[:åüë^ð×›Dz)bL]·!ÒKQ~iÛ2Ê/UcL‘^ŠS˜b ¹?¹ÇÁGŸù¾vÍYä:˜†f‘«f˜TcšW¯Ž™lÌ%¶Ç'Æ饨è=š… ÎlÏ @€ @€ @€ ÐuFŒiÑÒ‘BJÕ¢JÍ”ÒvþD´–¬R†–‰¥U·6BKµõ–í–F‹ÂKG.9/f‹;øÈ“#«tä ç.øÏ/G¦ˆ.}î+m¶ÅV‡/>÷ãÿ¹×«ÿé ¥ðR¤—Î[yG䟶ßñS]úô^ £ðÒ—82ÒK]ŠÉã¾uÜ9¯ú‡7Dí¥0EŒ)2L+®Ýå—Þ?c:䘳¢Ež)ÒKo{÷_ÿæwüÝ3ãëÛþã}æ_¾èe‡Ÿtqf˜ÎYµ6æšB®Ý,rbL]¿K 9#\Æâ±|ùòê Æ‰1ÅÖeO1¦¸  @€ @€ @€hˆSLýV©¥4NʈҚ¶ûð.ÑZƒJeM5±”¹¥(¶¡¥¡vóý»üç—KÉ¥ƒŽ89j2}ࣟ*U—>ûå7{Ë;?¾û^¥ðÒ¥7Ü-§ÛùS{½êß°ÝŽ»sÚ¥9sÜÙ—ßé¥h»ï¹0ÓK]ŠvÆ¥·í÷­%Q~食ÜcÙ%·E‹ÚKQéükÖí¸ëQé#»î‘˜>ò‰=>ò‰/ 0­\ÛœB®}&“ÊyíLS bLÕ$ÒäbLÓ<·Ý  @€ @€ @€ @€½/1¦ouJÛ”Ræ“¶ýð.ÑJi¥ *•6WŠÜÒÍC-'‰+­™XÊÖ˜-®Zr©mt)LZ*-ÒK]­1sÜPkæ–²En©´ V7&Ëùã"½t~sæ¸Úüqç—_ªÀ4áS†™^ðâ—åàŵMÕowþô¾oyÛV·­ýIµýìç¿êý›A»%0N5¦nuËy  @€ @€ @€ @€s&1¦ƒ @€ @€ @€ @€³)1¦¯礋®‹(R¶‘@R.¿÷6fJixJ¸¨®T/°4\l)RJµV -Ô['·´n"Ñ¥³VÞÓ!„4ý§Ä˜fó~œ§Çcš§Þ°  @€ @€ @€ @€"Ј1}ûÄ !µm[àãÑFMW›®]u¥’[jM,u-5ª.­Š¸Ri£f‹;'ê-e]ui¶£KÕð““—ÏŒ ˆ1Í8© @€ @€ @€ @€}&1¦ý¿}bÌòVmÕâIïÙþãÑZ+*u*åôpÃsÃLW›!®%´T¯·TË-U'Œ›Ëè’SŸÝÖýÖ]1¦~»búK€ @€ @€ @€Ì´@ĘöýÖ’¡šI«×7š ¤Ò2ÆT[Y¾Tž.²JmâJõ2KYo©^l©sKµyèTcšé{Ðñcr @€ @€ @€ @€ó] c:tÉpiÝùEÝÞ½ÝÎÑ2™TZ£ŠÒXmÔ”p¦‡‹ÄÒ¡¥µQi)[-BÔ ßŠ1Í÷×Ì,Œ_ŒiP’ @€ @€ @€è+ˆ1ísè’±¤Œ17f8iTPi¨ºRÔXjF”ªíì«Öµ•kcn¸lg µÞ -µ§Ä˜úêïΊ1õÇuÒK @€ @€ @€ @`ö"ÆôµC–Düh¬öÛííœvɤ1ƒJ™X;®Ô¨´te/VZšHµ'1¦Ù»çí‘Řæí¥7p @€ @€ @€ @`H bL{ó„‘RI¥fÒð»¶Ý9Zk!¥v)¥‘ÉàʬpýW+Ò$ÆäÅ3ãbL3Nê€ @€ @€ @€ @€@Ÿ üË¿üË‹^ô¢3åãÕ¯~Í&/eµ=ç¹Ï{Ö³Ÿ[[Ù•oÿèÊyk'ý½ßûÿþê/îГçýÙó·~ÿ‡n[û“jûÙÏÕgw†îΡ€Ób; @€ @€ @€ Г6lX^yœwþGŸ°¬Ö?æäÖ•s½fÉÉß¾ø%s}ÒŠèÀD4n¼ý~1¦ž¼ß{´SbL=zat‹ @€ @€ @€è–Àýê×µüM|{Áš/²j£Ë¾Lôg²ÝP©[·t_œWŒ©/.“N @€ @€ @€ @€s'Л1¦5÷ÜÄ51¦ï^÷‚Éæ‡zd{1¦¹»‰ûðLbL}xÑt™ @€ @€ @€˜MÞŒ1e)¦l}ZIŒi6oÛ¾?¶Sß_B @€ @€ @€ @€fV cL¥SƘú´ “ÓÌÞ¨v41¦» †C€ @€ @€ @€LWàÿýú×ëxtí?ëÐnºóGwß;Î60©g/¾ý«¥S.¬ºûøIaV7þÁý^ÇÃãž"òaÓ½6ö\1¦Á½¶FF€ @€ @€ @€ „À¯þßc‹®{F-Æ´äæ Äà ‚À€“[ @€ @€ @€ ÐÓ×ß»_-ÔßÞùðÉ=Ýo#01¦ÉhÙ– @€ @€ @€ 0·mK1eŒIA¦¹½Î6»bL³ëëè @€ @€ @€ @€é<üØ-«Ö}6ÛÙßS¤—–ßùž²æÑ_n˜ÎÁíK wĘzçZè  @€ @€ @€ @ “À­1¦u?YމÀà ˆ1 Þ55" @€ @€ @€ @`0ĘóºUS@ŒÉ@€ @€ @€ @€è1¦þ¸Nz9%1¦)±Ù‰ @€ @€ @€ 0çbLsNî„s' Æ4wÖÎD€ @€ @€ @€˜Ž€ÓtôìÛãbL=~t @€ @€ @€ 0$ ÆäV`1¦¾¸†F€ @€ @€ @€ ”€Ó@]Nƒ- ÆäŽ @€ @€ @€ @€ô‡€S\'½œ’€Ó”ØìD€ @€ @€ @€˜s1¦9'w¹cš;kg"@€ @€ @€ @€LGà?:óU­Þ°×tb_½) ÆÔ›×E¯ @€ @€ @€ @€uŸüâΈ1­Z÷Y4O@Œi𮩠@€ @€ @€ @€ƒ)ð‹_=¼jýçÖÿdù`Ϩ淀Óü¾þFO€ @€ @€ @€ @ Ęzà"è @€ @€ @€ @ E`óã6§B`þˆ1ÍŸkm¤ @€ @€ @€ @€@߬Z¿JŒ©o®–ŽÎ„€ÓL(: @€ @€ @€ @`æÖ<¸fÓÃ6¶èºEfÚfé6±+7>`ã<É• ÷¸hXˆg£å–3w~G"Ð1¦. ;% @€ @€ @€ @ ³@„“¢ SlÑ¥Œ(Å·Wʽ"Ø´üÎåñ5òLñí#¿x¤<–@Ÿ ˆ1õé…Óm @€ @€ @€ @`²ðR5ºT*0Åú-­d}l5™²‰1 òÝ0?Æ&Æ4?®³Q @€ @€ @€ @€ý#¥Œ%U£KQŸ)*0ÅÊ 0eÂ)¾F‹õKo]Ú?ãÓSmĘÜ @€ @€ @€ @€Þ(E˜rò¸ì\†–baÁ9 "Ò fŠ…Ø, 2õÖô†À$Ę& fs @€ @€ @€ @€À, d5¦E×-Š|R9U|é¥hQx)ª4ÅúXÈ52L³|A~.ĘæBÙ9 @€ @€ @€ @€è Æäö @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ Ðþ׆ÓÖ¼f̓‡÷Gwõ’ÀdĘ&£e[ @€ @€ @€ @€@÷~ò‹;YµÑªuŸí^œ™Àl ˆ1Í–¬ã @€ @€ @€ @€fV@Œif=­§æWŒécûØF&/°zõêžzݶíÌÃ?ü‚ýÍ™gžÙû]ÕCs&pçwþùÿù«¾x Ï™‰ @€ @€ @€ôµÀ}ÞõW/ú›ƒÙ¾¯G¡óÚ Ì¯ÓÖ[o½ß7Y÷àÏFµ~¶v¨=ºï7yÛ¿¿kíÞsÿHûÁý6Ú}Ñ~íîÒîýé]•vç½?½sÃ#Ùîȶ¾Ñnj?¹}ÝO¾_i·­ûÉmk‡Ú÷Öþ¸Ñîi´5¥ýàÇ·µÝúƒÝr÷H»ùî5Ú]vÓ]µ;¾±Òn¸ãáîx(ÛõÑnj×ÝþÐPûþ¯­´Õ·ý°´kn{ðšï µ«¿÷`£­i´UCí«ni+o}`å-CíÊ[¸ò–ûíæû¯¨´Ëoº¿Ùî‹vY´‡Ú¥7Þ×h74Ú%7Ü;Ô®¿÷âJ»èº{/ºnC´¥]»áÂJ[¾z}i¬^Á5CíükÖ7ÚÕë¢WÚªu玴µ‹N½üÿèYç\µ6ÚÙÙV®=k¨ÝsÖÊ{μòž¼øåË—/ïñwÈ0ýÍ&›uÂÙÿÚ7H2õøÅÒ½9ˆ ÓßlòŠãN½0¾J2Í» @€ @€ @€ÌžÀÈGÃÿä£áÙcvä® Ì»S•"¥Tk÷ ç–ö=à·þû»2Ã4fz)bLõÓPzi$ÃÔ 0uÊ0 ˜"É4¦áÓÄ2L?ìœaZµ¦CŒ©C†©cjd˜†cLC¦fŒi$ÃtÃè Óõ‘acºvÊjŒiõ†Ž1¦F†©cªd˜Ö³j$ÆT2LÃ1¦F†©_bLñƒê¥›lºø´ #ˆvÅ ë^ãÇU×ÞQ¸‡"ï‹3.\¯‹«nÉË$™zèêè  @€ @€ @€À|4<4»ô—Àü‹1pHµÒÒH\©™[ÚçëS½êR–_]Š:LwÞÛ’^®À4Á"L·UŠ0µ«ÃÔ(ÂÔ¦S³ÓÍ¥S,t®Ã4Í S³Óp¦X?Ã4“¥˜1¦Ù*Å4~ŒéÊ>¨ÆÔøAõ·‘aZµµ"®´Ë¯—dê¯÷a½yF†éo7=sŵåu±ü*I¦™wvD @€ @€ @€9ðÑðœQ;Qæ]ŒiŸ¯³}J©™UúÚ׿1¦¶¡¥œ?®L7jò¸úüq1‘\} ¹˜N®L!W«À4͉äÆÉ0Mn.¹–:Lsœašt)¦‘éä¢&S™N.š3ÊSŠ)&’ËIå:”bêñIå†~P¾"êl•¸FdÎ.½ní«ÿQ Á.¾µ:u72ÃtÖE×–×EÌŒ¯‹ V~_M¦n^ç&@€ @€ @€˜ª@ëGÃù˜†§*j¿˜w1¦*e ©m‹g·|û»š•–êÅ–Úæ–*U—ÚG—¦–^jSéî¬Àô£›J¦;§[„)S/¥]sÛƒÓŸKnZu˜&ašÖtr‘aj1µrm³ M'¦Œ1ºìœþøç¥ýìç¿ê…tþ :áô×ßþÐuߊ1åϪ«n}à’k#ÉôúÓ—Ñ ]Õs&¦³/º¶ùºh–(»í‡åuqþÊï¿øe¯Xuõ5sÖ'"@€ @€ @€ 0M OÐî}$0ïbL{ïÿÍZE¥ê·ñì–oßꎨ®TÚúG"«TÚíë#®”í'Yr)Zd•ªí¶Ñ…—†fŽ‹ùãîjkîùñPûÁojmæ»%¢KÃé¥Z€éÆIÏ"×ø8?rK¥0_„iÕ­#sÉ­¼õF»¥Ñ®l´ûíæF»¢´›î¿|¨ÝwùM÷]íÆ¡vé÷5Ú vÉ ÷–vñõ÷–vQc.¹ÑÓÉ]»aŵ.,mõä2Lç­ZwîHk˜ê1¦•kÏ®d˜Îj˜JŒéè–U‹iÅ=Óõyþ Z²ì¢š“–RL͸FãbÅE¹hõ=¯úÇןrê²Iõvýúõ›o¾ùÆÍG,¬Y³&v_µjU®É•ñˆ•e³òÔÃ<ãòåË7ÝtÓ|v›m¶É•±I¬,]Š#çѪ,çÍ•±}ŽO—ª O|DñYU~œŸÅAâcßÖÝ—.]š+ãS¶üÌ7¶ŒÏ£'~"[ÎCycúê~߬ƒjËñìoߪ’UWjM,ez©pÉåïEh©’[ªM·¦cz©]#½TŸ?î·o¸#ÚCÙâcûˆ³d‹7¯¡öýñLÃE˜"þ2ÔÖ<ØüÈ?Û™‰)­˜š¦v¦›[Læ¡S3Ã4V€)’LÈ0žK®2\Û¹äÆÊ0E’騜Tnì SVcêµS-ÃTûY+ã‘*[qÍ&›dŠŸ4 .ÌwÃø¹߯’Œ1•·ÈøT²Gµ§JÀ"2L±K|ͽ,Xé¥ü‘ßæúØ=×Ç1ËÊü1–+3®9Ø+3UÚ ” SfûZK”å»V¼.νâ{=¥$SføÊ dF.DÜám«ëpðx9´M>u(¯£¹RB€ @€ @€˜{ ç,=Óüh¸$â#°òð¸ÃŒsó®üy¬qó€ñqsl–oMê,ãvÃ)0cLg ¥j+µ”¾²ßÁ[¼m«Zu¥òmk\©¹¦™X+´”…—ZsK?øQ[ª¶Ñ饇;Mך^j`U~©e ¹ö˜&`É0T`ŠRL3^„éºÑE˜®³Ó׬o›aªaZwΪ‘:Lg_µ6Z‰1•¹äªu˜z³Sü zÙßnzⲋ¢(Wf×ZgÎjÄ5šy²¨ƒµüê¼ò&Z“)~l”²Iù–Ñ¢xÔ²J%{ŒcŠŸI‘Fª¾oƳH5EÒ"#M™p*‡ª¥C2)RýW~ä{±AMS 2Lñº8ûâë"ÜY/Å4\¢läuqã}g_>é$Sü‚7a~-½_ì2Û”¿áeb=¥ZR,äšüM.^_ùËY–‹GüÒ¬ýn—IÁüÅ®Z±,ÖÇ·q„|”Íj‡*'-½*ö:šæfw @€ @€ @€Àœ Ô>UÞ¢ñX3Æ4s —hóƒªR„"ÿÍ|ùô*‹0å'\cŠ5ùiWõ³³œç$?ð*Ÿ…å|>sèDý(0ïbLTj™ôm¤œÒWö=ø-oÛª]\i8«4:®4ªÌÒpb©ZŠ9ã†g‹'·ô£›ïê]ŠÀJ³ðÒèÚKSK/ —_º¦”_Š…‘òKÍ L•òK™ßÌ)äj³ÈM.À4E˜:O$·þü«×E;¯Ò:g˜¢ÓQKÕ˜J†©L$W]è©jLC?¨Îhd˜†JÎTg”«ÌœW§cj²_pÕÝL2ÅÏŒZ¥™ŒeV)¾æ#~•´ÓX1¦ÖâIeʹX(?ŸJŒ)~te!ÁøqXj8•wÕÚTtýøn«Ï³'¦s.¾näuñý¡™›Ó,ŽÊ¡7¦¹l¾.μtÍ_ÿÍ$f—‹;3_%„—·qÖFÊ„S¾LòwµøÍ,îÛ|¥T#P¹&~‡+õÉjÕ˜J¤¯l“¿–£årt&wŒnä1³S¾”âÛèU-2ïu4{7¡# @€ @€ @€fV ÍGÃÃ5>량†Ë¿Ì¯ö¼ü«ø2N|–,Ê µjLùmëggµÏªòc¬Rÿif¹m`æ]ŒéËû4T<©]¥xö-oÝ*ÂIÕÖ(§ÔÚ~P­±q¥‘ÄRD—j•–òÛÚlq£rK‘aº³Ñâ3øj›ht©Y'ê-UÛêÛ~XÚ5·ýðš1ÒKµS}þ¸Q¦ærÑ¢êR¥EVf¸Ý×È O!× ”6z¹K®¿7&+müYä&_„©>‘\K¦œHîÈFŒé™g­¼§µSI2õNŒ©þƒêŽÆÔYg+CiÕ¼m3ÆÔ¸1_PŸ·ò®Wþý¿œrê²Îo^ñc£VB©Ä˜6Úh£ŒeÒ¨§CŒ©6­i5Æ»—:OÕ¼m-“Õ•e޹yç5h“ajÉöÕrèåuqÆ%k^4á$SþRUñ•)s8Õ*e¹&v) ¤üõ.Ö”°y&ŸZg‚‹-Ë‹%guŒCÅB™Ø1ŸÍ9³XZž.•iª8o-èu4ƒwC @€ @€ @€fU`œò3ôÑpkŒ)>`ªfòó©ò)UνkÚÆ˜jŸÅfµSë‡Ñ³jèà}*0ïbL{í{PûXRsê·½öiĘbatE¥zJ)k,Ý2F\©]bit±¥1BK:"£'Œk”ÛÉvûP‹ØÊHë]jD[¦”^êP~iú¦jz)–'`Z¾z}LWZÛYäF˜ÚL$טNnåÚf¦¡SÛ"L½cj›aÊé䢵+93TŠ)cL]·áœ+ïÚt¼$Süh©F”â}-¾Íy¬Ê§Ú›ÝX1¦Ö mþXªþôŠ5QQ¦Ô¤©¹üäËoµr5}ú†«Û3.¦—Öê0• Sç×EóýgÅuN¿xBI¦ ×ÒE‰1Å+¨ìUûµ/#McLñlÎÜcŠ•¹{‰ý•CE’)§®+)(¯£¿÷ @€ @€ 0KÕ¹ä230RÞb6?ÎùFÊ´<ùUù Y“"¦cŠ}k©¦YÒsØ~˜1¦}*½µ.ì¹ÏA›¿õmk)ÕV•VÊKwU[en¸œ'®Yf©µÒRV]ªÕ[jÍ-E€©’[§êR&Zª…—:Í·æjí¥O/ÅœM )m ¦ W¯ÜRiT2LÍÓ$f‘;'¢KÙšE˜Ê,rGžÒ¨ÆÔû1¦øAY%ˆç’kþ Ê\C¥˜š5KÉ™Z)¦‹®kÄ5.¼vÃÙWÞÙ9É”u\J—Œ(ÅÊ)Ęr>¬R©T‚©&?âD9mj¼“–‰´b¹LÑÕïï°ú?«™a:»:—Üp†)³}YKs¬RL‘í[qmãuqÚE·¾p¼šLqV •e¥ê¯q±Au*ßLÆfe–Æœ¸dÌóµ>YW© U~í+³ÂµT®ºcõPÑF¬ÆgõZ88 @€ @€ @€ÀŒLû£á¡À&øÑp)'Qæ)å-bMÊšÎ1¦ÖÏÎb÷üû&.0ïbL{|í Q ¤2×[s!žSK2©cJ)³JcXŠ+µK,ZjäTÚä–2¹ÒaθZt©6mܪ[G¥—VÆ´q£fŽ{ ÌW«½tEëäq™?®Y ¨íüq A¶k‡ÞI#O­š^jWiL1‘\¤—Žè‡SùAÕ ½5êrÕ3LÕš·4¦ü‹iþ“ú5“dYŠ)U# væw¾â5f—ˉ±Ê#Sˆ1Å^ñƒ*SJñˆQ9—V­€Mä-ò‡_< ¹q™]5ßËTcšø{úüÙ²d˜ª¯‹òöXæÊ0 ½.î+¯‹,Å4ôº¸fýÒ·¼ð%/¿òª«Ç¬U#+‰¥åM›±ôüõ.ïä½'ç¾ÛãǘÊ[›jjîû:ý3n½õÖ{|íÀ¡ÔQ‰UâÙ7oùΑ † )u(§”)¥ÎY¥‘¸Rez¸œ'nô$qíCKcä–~ŸÓ—Ö¨;RÚš߼廞ýœç½è%û…½Žb$]zÍkÿõYÏy^|Í L]zÍ?5×üÓ¿®¼e8ºtËý]:舓_øâMâÙh›m±Udb¢}ࣟŠvYD—šé¥Øà[èÒÈÊd]{)Ó3c˜†ÒK­¦Õ£LÕòK1‘\û)ä®^wvΪµQx©´¶˜2À”mš1¦_üêáu?Y>ý;³Ã*?¨†¦Ì‚ÑþcÏó^ó±S¢½i÷3·Úã¼S/»;"hqù¶ÝgÅ«?zÊ;¿xîwÏ»­™a×8ÿêuË.»ãï:&™²?¥Ò48Ùãä1ù(ð௙Рj(ÃtÑuCï®Í÷ÒòVù™ÃWÆ‹â5—Æûpý¯‹¡ôd%Ï»zÝÉËÇI2ÍÈ™xy$Éôw @€ @€ @€@—}øñÕ'O¤c}4%Nª 7>[2öG`•É?Á†'ûyîDÆb¢jCæçªSâä.ãǘ"=—eÄrľ¶ŽÓ—ö>°<ª-dzcª­¼a¤RÎ÷PÛRŽ´fD©´QY¥áR:9#Xk«UZž'nì©âš'UK.}h§Ýß´åV‘UZqÍ]/zÉ&g^|c|»Ë§¿Ñ¥øúÆ-¶ŠÜR|åøt?×T /E†)ÒKqr¦—¶zï‡"±Ñ¥í?ú©hZ&7Þ÷‚oË3–^j-¿4Æüqñ>iƒ¡VI/E’©`J/µL!W 0M3ƦUë>{øêß»ð®­gïE‘?¨N8}EãÖºsF²ÔX²âŽ Ûîyô5[}鼏޻çÊm÷¹0.Ó1çݶÙngÔJ1E,ô‚ëôKoÿ»WwªÉ4{ƒrdc D†i»ßç5ÃLæk+¯‹¡ ã 32LïÚã¼Kn¸/^ñ¶ðÆÝÏ8â¬5»»ñºˆ·¬ÈöÅë¢VŠéükï*ñº8é‚›_б&Óô¯ÝÄcLÓ?—# @€ @€ @€t_ þ%|öÅu3ûÑp| – yÎ÷¢ªÅÒKî*åGã>[ݨâ£áî_}=h'SßDY‡xÄB-H7~Œ©TF‰jL1aM_#7bL_]8V)ÖdzoÚò¹Á¨XR~;:œ4NP©1%ܳµ+µÖXª$–&ZŠ·ªF½¥5#SÅ}âÓ_ŽS–\ŠÓQK΋XR³äR£êR,}m^Škr!sK¯þ§7|öË^žU—† /-<üäŒ1e†é3{õ–FZká¥f ˜Ëld渉LWI/M°üÒ¹Q~©RiÌÓpù¥R‡iÊ1¦[î¹ç¼5»E€éUE›½Sþ Z|ÚŠj€)o›k¢}ïÁˆ1°âŽ¼Ð‹—ßþÆOñä‹ïÌi³"òõªOiøÏÓ× m†ÀB, N½äû/õ?Ÿrê²¾~Qëü@ dŒ)Ûa¦Ì0µâÚÖ`_ΧE˜â&Ï×E¼×yÖšS.¹«ýë¢Yþ­üUÜâu±äü›^ðâN³ËM\±±iÚ @€ @€ ÐgcÊ6F˜©óGÃñX|4üéÃVæG`ª%Ÿ:㸠¾?îGÃY ÄGÃ}vÃ̃îFz©D—Ê´ƒeÜãǘbÓ8DÎYØï\cúâW¶M#eÁ¤/DŒi‹w¶)žTýíû#ù¤¥]j[]i¬Kù1|m†¸j¥¥ZŠyârz¸ÒoXÍ÷¬Ò>ò”¾d“ZÊ’KZŠ.5sK±Ü 0Ý—Ñ¥øö¸Ó/‹(L^ŠÖ0íØhïØúC‘aŠ–¦ÓÆÍFzé¼±Ë/eþ ÑV6ÚYvO¶Zni:1¦0sënß¹úw3À4«1¦øAõ7›42L×5ï·¼†n›¼CÖ4~Ví|à¥ÿyØÊÿüÎÊøAuð©7ÅuÌ«öÅ#¯Ž¼íW»6æï»°Yìª *9Óàj-½X’©ßßÕ«ÿÕS»0Sd˜âuqæŠkÇz]D°/bL%Ôozw¶Úë¢%Û×ø._WÞ³ä¼ÙM2 Ö53 @€ @€ @€ŽÕS»0ÓÄ>>#>^|áíQÞâ›§Þ՘μò“øhøJ »K{N j2m¾ùæFªõlB1¦Ø'æ•‹£ SÏl2ŠÓ¾²p¬ÚH±>ž}ãïè°ÁDÂI%·Ô(™ÓhF8©µµ+µO,U*-uÎ-e½¥lqrLwÄ çVë-]1ZjF—FrKZÊOºüúœ0.ZÄ•¶Ûq·lÏ|Îó>½çÂWýãb93LQ˜®Ñ&PxéÂfá“j»`bµ—&™^0Q~iŠ1¦·˜2ÆtâÍ/ŠÙåf¶-¿e׿ÙäÇŸva5½Ô(Â4`Ê4[NzzüòïG½™íöYI¦üA—,&›‹ Ó¿í¶lé¥w¥ùHÉ™fÞ¶¼†’L{/xüÔÏjº,pø{F¢è%“>\™©™azÅ®•êýº8aÅíñK[³øÜýµ Sëë"Þ‚j¥˜Êëb(Étð.]ñªìG ~ü—MæwÛ @€ Ð ¬ö| @€˜#ã?Úþ#°fe¦f†iB ǧ`oÜýŒøPx«/{ÐÒ›&ôÑp³Hý£aÓõtãC³U *åìrK—.­>;~Œ©Ì€I¦~/È1¦Ïea‡òHñìßòŽñê' ‡“ÆÈ'eb©žRj–Ï)­C©¶Æ¬pÕ‰áÚÄ•FWZúœ~8´ØçgöÙ>÷•ƒ2ÔóÄUë-År–\ªæ–²êRF—¢ØÒ—8²:gÜ þz“H/Et)ª1Etéäó¯{泟÷õïœÔvθœÂ¬´ D—U‚b²³œïl¤M®öÒDË/M!ÆôÒM_úí‹^^­ÀT]>ôê‘ÊLcm3Ùõÿ¶ÝF[¾ã½#%»Ê5tÏ •àŠSd˜†³÷ÇO¬cοmÙåw_2”-Û1¦£ÎþÞP)¦¦mµäL¡8ôøåÿç÷ŸôÃ÷?¥ýÏjšÄ2n ,xÆÖoù—òžó*Ö‚}Y„)~‹ ÓðD™÷xÊMŸúö•ñºÈØeÔ'«½.âEј›²ñ ÜÚêûÃ'¿tà¿müÔŸoÿ$¯ “ˆºb @€ô¸Àgþ÷¤ÕïÖÿ;/ @€,ð±ßûì¶[lÿ‘Otþh8>‹†ÿó;WÖþù,>¸o÷Ñpã#°œ¤| ¶ßw–¾èÅ/}ôç¿êñÿiÓ½ˆ SŽqæc1¦˜Ž®D—.\ú+bLŸûò7ÚÖFÊ•ñlĘj´ $µ›÷mìˆRÆ•†‚J­“ÁÕg…kW©±”%Fj¡¥’^ÊÐÒW¦ ®º£Ô[zõ?½á+ß8*rK ?ùÕÿø†ˆ+Å×X¡¥…‡5ÖTCK‘aŠÜÒ)ç_—õ–"À߯ÇÿÛ~d·h]Ú}Ï…õ×/‹@@„–j¹¥F€itÕ¥FŒ¦Má¥õ]ª¥—š‘‚ÒÖÆTñÞZZËÌq“«½Ô:Áܧ\þ‡ôÌÎϽàÅ/?ú„e+ïX¶øúW¶’θí_ÖýdùŒ·Ï~ö³ñãjäÞ`šñt÷ÆŒ§9!`˜"½?¨Þÿµ ¿päÕIý®ÝðªO9þ‚ÛëÓÉUò¶1ðØä导ðœóo»lù£7^øx|ú®è–Àùûµù#ò‚g<~Þ~QÞ&o~ó›~ûø¡×E3šï®ù.šáÎ^ÅÉòu±üšõ›}ꌽ¿¶ý뢖í«ÌAùÅý½ö_þíÆË/‹×ÅÏoò¢ 0a“>Ù¸‡Å˜úú—E'@€˜'»=÷ñøwÏÝúÿ_ç%@€ @`^ \ul›À>ö{ZP>ÿ–1†q?Þý;WæG`¥Óø G†©ò؋Ί†¯¾ùžÛÖþD’ižüïoosÑ¢Ee.¹Xˆ0Ò$bL±iL$I¦|”ÊL½9Ôq{ÕxýïõjU¤Úr<»Ù[ÞÑR*©V9©|;œLʈRósôέ‘>ÉvK½U烚nì¸Rä–2±4ÜÓÃ5Þ°š-2LQl©´ÃŸsÜé—E¥l±¡¥cO¿´¬‰åL,•Ñ¥¨·é¥h¯ú‡×÷ÔK#³íG>­D—þuówF«êÒ¤¢Kµiã²2J=ºÔ Š6²¢CížxíæF;G‘Æzvâ1¦x+Öfºð®­Ç½ñ¦¶A$™¶ûð'Jn(¨1œÕˆ([T ŒèR¶ÌjD¦Ó/»{³Ý–EØ6ÚG¾~q3ô~¨ÓèéäF2L—ߘ£óãjjWÊ^3&¿°VÓôærüL2ðíãG¥—†ßQK¦m›s,F‹—Ænߺ"ÞÙNkóº¨Ô'íÊ0Ý~y]üü—é3v‘ü@—.Æ4à—Øð @€F bLû¼f`Fc  @€ô´ÀƒwŽú¬`*ÝŽ$Ãg÷úFç†wÿvĘF2Lc|6üÑðèéäâ£áj†ÉGÃ=}ÃÌÎE¥Œ!µVSR¹$вL`•/þI£xöß6ÿ÷qÓHíg|#Ÿ”‰¥fJitQ¥Žu•j–jq¥’X*ÃåÂÈÜpÃ3ÄE½¥Riié×år‰+•’K9ÝÒE×ekÔ[ŠvÒù×6BKc–\ÚÐy¸ Ð4Z»ªKm¢Kã§—šÑ¥™H/•TÓdcLù†~õ]gœ¶æ5Y™iöbLñŠ‹$Ó¶Þ%§Ê¾‘†f¬&mó*_ÄF¦¥—Þ•I²’aÊpXµfàP¦J†É«x—ëï!”SK€©Œk(Éô­ãK$´ä>‡óCo†']tgû×E›lßÈtr­¦|]H2õ÷­5g½cš3j'"@€ 0M1¦iÚ @€‰ ”S»S9L 3äGÃc}6æGã?‹†õA†§“kÍ0ùhxâЖs,0ÑÓwk–N¯üÏìùÖJHeM<1¦”§ÚÇ’"™”m¸ÒX³¿•”RK]¥F¸Ò²ºR£5SJ¥µ+UKÕIâj•–òÛÖÐÒPbi8´Ônª¸zniÌ’K× ÍW›0®G¢KÕÊLS‹1ݹ¡1McL$a¦Y1ÅY"ÉôþvÉ›*o›Ì´å]wB‰¦e-/\É0Å%hNÒ7œa®8V†©õÇÕ÷–-ºæ;{üòÑ¡™)ËkóÑÖßµbé,½Tvž DŒiìS1É$Óþ‡×òºz·¬½.2‹9ôºhù®ší+ÃTM2­[µ<^ñµv¼"æéM[¶“û€ @€@¿ˆ1õË•ÒO @€ 1¦Ž¦2ÄÈ3|zÏ&øXëGÃ9EOëGÃce˜$™àæÈ!Ì»ÓÐ˾äFGŽ>½Çcª…Ê·ÕìÑ„–GÍûVŸ®: \kP©Mi¥È¬Ü0Ôª)¥‘åÑÕôR#±4Tii¨ÌRã­´kð· -5£0mê-EŸkFÚP½¥‰æ–Ö3ºäR£>Pi³0gܸ3ÍM'Æ”ïþrCÛ·†MÛtý#3SÃ,“L#•f†LCÁµÌ¥5/hÎñ×È0 ×ÁšN.ë0M,ÃTýqõÀÍ«–n³i$™ZÇIŽhù¶hP]ˆÙùØDÎ^’LÕ LCo›ÃÅÉF½.V¼.Æú®s†©$™ŽÛ|ãxEüèî5µ~zELä þ6bLƒ @`PĘåJ @€>ˆÏ¿âS°‰=I¦=ë£á¡’%>®—·èœa’dšØe±Õœ Ì¿Só5?V‹w„Ýü߯¸éþhÃó¸»0R<©M¥vµ”ÚOW™n¬ºJµ)áje–*q¥‘‰áF%–:TZjZj-¶42OÜ„sK°gÇÙâšñšFÂfÆ'Œ7ÃL?ÆÔöõºjýªØx̓ C|/y¦òЍ­÷Š˜½{ ,ÆÔ‹WEŸ @€´cr_ @€ ЫïØê?vßãëí?«–·hóÏø×5ʈTÊ[L$Ô ÷*†~ÍGycúÏxÁ—™ÚZâíà_ßüïõ FOèV›ß­Ó\o™L*m¸–Rç”R‰§´ nh>¸¡êJS‰+5 ö´”YʪKŒ®´4~héêu-óÄ5‹Ô•[j¾iç–º]š©Iå:¼a,8gATcZ¸ráò;—o~ÜæÑö¸hRŸ)rK±»o³t›hÕ§:3’Lïûà‚¡â[£Le¬öY)e˜¢'1mVž‰S,¬øÂ6Ñ¢ÞLd5r.¹x*¾Æš\߯féˆ reì8ßSy2É´ÏÁǶ}]”âdï‹uÓÌ0=ò£½`óh7¿0 2Õnõ|EÄ« ×ç×X Œ…9´qª. ˆ1u Þi  @€LZ@ŒiÒdv @€ @`îI¦/}}b þ¬òѰ ÓÜ]0gšQycŠWû¨hÑè¤Q<û†7ÿ{û *!¤2¹[.´Ÿâ-Šå´¶1æ}«&–†Š*µ *ÕK+u¬®ÔŒ+µ™n¬ÄÒTCKç‰ë½ÜR­DÓ,UcŠdR´x©Fž)‚JùšúL¹ñ¦x6N¹fÑu‹rûÎH2½÷ƒ †¢l9-`s¹¼Ð™B;?²ecLz:ñ:L¥™ÌˆjL‘ÛÈ•9sVÔ›ÉLF|ͧ"½-ñ5·Úïzz~2ÉôµƒéðºhÌ}9üºÈe5„>‘¹ä¢ÓÏÙ¡—;¼¼"râÅòŠÈ _lkb›êLs±^•²¸ä=~1¦¿@ºG€ @ ˆ1¹ @€èmH2}ê‹_ŸòGÃ2L½}yõ®“À¼‹1}ª„ÛÅŒâÙ7¼éíãÄ’®šÌk¬jIãTQÉ'ª¥¥6)¥JPi(°’±•j[=fu¥¶–*q¥õçWæ†ËùGµUQZ©Þ!€ÑÅ–™€ÒšÅ–zªÞRç©åf)ÆÅ–¢äR¼òb!ç+˜b9ÒK‘aŠxS<›µšba"1¦Ø·‘dúÀÇGLó]Ö±³SÈ0•dFœ7‹ÐD˪KYŸ)ÖGù¥X™%šbûx¶º¥w_s I¦½:¦ì+ÅÉF2LWM+ÃcÉÄR,Du¥¼Õ³ØRyEÄSñÒˆB–bŠ…Ø l)Æ4÷C—O!ÆÔå àô @€&, Æ4a* @€ Ð-H2íö…ýÇÿ¬åŸñË0uë’9ïŒÌ¿S3±8V‹<ãëßôöÖgG*$E©´ë"‡TmRkk¼­´m×6Jé”V'Õ³JI߯j­“ÁE¨eq¥ösõ™.K}Zj4ÍRŒ©^* ¥>S¼ncåúGÖG hé­ÙÙâõ™&þzŽ$ÓÖøx)µU 0e¦¡ËT™ôt ¦èOIfä,ZÙÃŒqDD#Ödž)·Œ¸FÎ(—›Å69÷œ9È$ÓW<¦íë"ã˜Cï]•׍ê0•û?âæÏ_¸HºH€ @ ) ÆäF @€ @ O"É´ëç÷ç£ááÀd˜úäªêf'ycjd[çe^ÏþËß>Na¤±vï8¹[§BJcG”FWTªÏ×f¸œ®ÝdpÃÓõ™nT¥J\©MbiåH`"!¡Þßf–bLQ])Ú#¿x$&+¯¿,Èu˜Jí¥H2ÅšI•b*G‹$Ó»·ß9“j¥ØLãR6L%«1µ:Ly–H)•B2iŠ–u˜â©üšÛ”§âÛÜ ZViò 0—™dúò7Ž®¼.† ÈU‚}SË0Å@Jù±XŽSÞçY„©¼"bMí%[Æ+e.)œ«kbL]£wb @€“cš$˜Í  @€è¢@$™>ñ¹ýÆúh¸|(/ÃÔÅkäÔ3(0ïbLTì0;[<1¦´>5T*) &u $Uk)UJ(e-¥u6n-¥L)M$¨Ô¬>ÒÚÎŽ˜Ki+‘—lÍâ=ÍøKiÃÍÞ"M§‡³cšÁ—h‡CE’é?¶Ûyd¹«†.b™N†in†à,fV “L{ptV& ö­*Â4å ÓÌöÓÑV@Œi`/­ @€ œ€ÓÀ]R"@€ 0Ø‘dÚå³ûuøhX†i°o€y5ºycŠ”âX³³Åúx6bL6h)T&t«ÌìÖH*ù¤6³¼•dÒp>©c-¥¬»Ó¬¨4‘ RûÒJó1®4VÔ©¯cLñVÕH2m»s#š6ºØLΗ·ÉË_yáå7Þ¶ö'Ú£?ÿÕ¼zË3ØÈ$Ó¯‹êìŠSžKnàÅ p&ĘfRÓ± @€̦€Ólê:6 @€³!I¦ŸÝ·íGÃ2L³î˜Ý˜1¦ZÑ£ê·cúçÍÞ6‰ÔQ-„4•LÒÐŒ`ãæ“†*‹TË)år›¢J£ƒJ7ÜtÊ/Õöí÷S¼qD’é]ÛîTf‘ËÊ0uë-Õy{A “L_úú¢Úëý‹û/zí¿üÛ·ßß!Ø·öŸýü—²}½pû³bLýyÝôš @`> ˆ1ÍÇ«nÌ @€ú^ ’Lÿ̾µÀd˜úþºÀhycÊJkcµxöu›½­ÃxjmTK)˜4Fͤq¦{k7ï[eê·–”’ ÒT§À€S&™¶zÿNæ’óöN d’)rKåu!Ãäö˜ 1¦¹Pv @€3! Æ4ŠŽA€ @€ÀÜ D’içO$™d˜æþ8ãl Ì»S”Yk•5ñìëþím6èðT£0RçV)›TJ(5ç<ª¶{ΊLR­M5£3ƒU‹õPƒcŠ·‰’dR‡i¶ß4¿_ªI&¦~¹j}ßO1¦¾¿„@€ 0oĘæÍ¥6P @€ƒ'P’L2Lƒwq(æ]Œéí[ï°÷7Oh´ƒÛ´·¿{‡¿yùkÚ>U[ùÕƒO£-þêÁã·¯¼XëO~éÀÿïþAçž<ïùqô ˪³Pݹá‘|ûˆ$Ó›ÿýý›¼ü•^~c‡9³â©Gnά¼€º4ó‘dú—7ükÔ*ûÇþsÉͼ¯#¶ ˆ1¹+ @€ô‹€S¿\)ý$@€ @ @$™â#°M^ú²«o¾ÇGÃ_1¦c=ö5£‘ù¨¶¼è%¶ñÿ®­ôí ¼t“W<ëÙÏí<ÀW½æŸ.[}[ïǘâ½i¶—a°÷hÙ¦À÷ŸýÏ[ÿ÷3®9¢Ã/pkøÙÏ)Û7Mi»7ĘÜ @€úE@Œ©_®”~ @€ ÐVàÁ;?ñ7¿}õ·¿(Ãä<ùcj½~_Õž%ÐV 7«1=þËÇ_ðŒ^vJ‡«¦ÓཉQgu?Y~Ȫ.»}ÑX¯ &·ÐL ˆ1ͤ¦c @€˜M1¦ÙÔul @€f]àÁ;ßn£.ÙÃGóNís. ÆôI“èÑÓyûÅϪǿø¢þøçmG$Ã4ço°NØ}Œ1Ýúàá÷>ôXëëB†©ûWhÀz Æ4`Ôp @€X@Œi€/®¡ @€˜ÍÓã§~ÖGÃóájÏ·1Š1‰1˜´@/Ƙš¥˜?«¢­>¹õÇ• Ó|{s7Þøù¯Ž$Ó£¿Ü˵$“ “›dæĘfÞÔ  @€ÌŽ€Óì¸:* @€s$Ÿ¯Yþx„™ÜGÃsdî4s% Æ4éËd+÷Ø~ðz1Æ”¥˜²}ñEµW2LsõŽê<]xätîAI2É0uùR êéŘõÊ @€Àà ˆ1 Þ55" @€ƒ(ð½e‹®ùο|´þØ£¬¿kÅÒ2âj’ÉGÃx#̯1‰1‰1˜´@ÏŘª¥˜† 2Å;Yþ¸òƒj~½©ÏãÑ.½ué6K· ’L?¸ÿÑŸÿòWãni“cš4™ @€tI@Œ©KðNK€ @€ÀĸyÕÒm6$Së.‘mŠV]ï£á‰ÃÚ²Çæ{Œé§ýW¼ž;´{ø³~ôXçm<;Hq¹ï{hœ+·Mo½°«¥˜*™¢“²½u¥ôfÖ¢Ó‚sìqQã×µ5®‰¯«Ö¯*˱°þ‘õyòÿ÷ë__qϪ|ÖƒÀ ˆ1Í0¨Ã @€˜51¦Y£u` @€fD *0]¾ÿ‚hYŠéGw¯‰TSaʃG¼)¾­­Ï†c}>åA Oæ{Œ©O/›nh-ÅT)ÈŠÀ<X~çòØ8’L‘gÚô°M7?nó¨Ì+K}¦XÑ¥H8ÅB¤b}lîë˧óÄ˜Ü EÀϪA¹’Æ1ƒbL3ˆéPã ˆ1od  @€½! ÆÔ×A/ @€˜¢€†§g·>cꃋ¤‹&$àgÕ„˜l4¿Ęæ×õîúhŘº~ t€ @€ÀĘ&e3 @€zSÀGýy]ôj&ĘfBÑ1ô‚À/{|ÍòÇã'–ÃbLî…9cšSn'#@€ 0 oýûã‹?6ýíJ€ @€® ˆ1u•ßÉgU@ŒiVyœÀÌ \ó=Î^°ù÷–-ªzݪåñÔÌŸÏ ô³€S?_½>ì»S^4]&@€ @€ @€ý' ÆÔ×L'* Æ4Q)Ûè¥Ûlúèë[;sùþ n<~atR7ôˆ€S\ˆùÒ 1¦ùr¥“ @ ?îZ±ô¸Í7Ž?¤´v·íÊþ•^ @€ @ Ę܃+ Æ4¸×ÖÈNà—>Y¥ø\Æ•âk”_*e™âpܼ*ÖÇšX_"M‘yŠo£ýèî5Gb@Æcr‹Ì©€Óœr; @€qV|a›H2µn*cr÷ @€ ÐßbLý}ýô¾“€“ûƒ@? Äà"ɤøs[•"·k2±ñ¦ø¦X“ë£åæâovÑü…®Ÿ®´¾Î€Ó A:ÌÄĘ&æd+ @€s ÉRLñW”ø«ÈÙ 6ÿÊ+N½nÕòXŽ…ÚúX{å–sÐC§ @€ @€ÀÔʦngÏ^cêõ+¤ª¥äR^Н‘jÊJK™RŠHSþ….–ãküõ­”kŠ-s/óG@Œiþ\ëž©SO\ @€ ЈšÖù/¾â!ñ§’ø6–óï*Yµ:¾ b}´ü[J¤—ò¯(ñוø‹ G @€ô®€Sï^=›®€ÓtíO`.ª€ËDkâpñW¶H)eOb9þú–ÿp0žÍD­Ä›æ²ÃÎE`î|tõ!«6«ÝùðÉsß%gdÕ'?¾ÝFc¶Ïä± @€ÈôRv0–£Sþ%ÿ%XþC¯Xˆ¸R<Ëe}<MA¦¾¶ºF€ @€ÀãÿxC㳉ã?Æ‚Àà ˆ1 Þ55¢Èâò¯lQö<Ê¿,Œ S¤—²üRŽ?ÿ$_c¯ÜÒ¿#Ø;ÃÀZÎþþ›ÛƘ–Üü"Zf^à‹/jcŠõ @€tI ”\Š¿‡d±êø;Iþó°üšüÇ`Yë:ÿÁX¶(ÈÔ¥Ž;- @€&&1¦#¶žØ¦¶"ÐObLýtµôuž Ä¿Ì(Rüq-âojñ5ÿôV*-Å·ù§· 0åB~-³ËÍsFßcdRŠi>\ý.Œq¬‚L±Þƒ @€. D&)K.•ÐR$“ò¯%ùÄbƒüGbùÏÀâ¯.¥Sü½%Ÿò @€ @€@ï ˆ1õîµÑ³i ˆ1M‹ÏÎæR **EË3f…ó\(_kOå·Q¢)¶ÉšLæ@kA&¥˜æÏÕïÂH[ 2)ÅÔ…Ëà” @€FÊŒr‘IŠåˆ(Å¿ûНñ¯¼ò‰EP)N±¦üÓ¯\ÎâL(  @€ ÐëbL½~…ôoŠbLS„³ô²@kA&¥˜zùzõ}ßZ 2)ÅÔ÷Õ @€ @€ @€@ ˆ1õðÅѵéˆ1MGϾ лÕ‚LJ1õîu˜žU 2)Å40—Õ@ @€ @€ @€@o ˆ1õæuÑ«i ˆ1M›Ð @ 'ª™”bêÉK4XªdRŠi°®­Ñ @€ @€ @€žcê¹K¢C3# Æ43ŽŽB ûÞùxü¬:õ³Ýï‰è,ȤSÏ\AïHdRŠiЯ³ñ @€ ‚Àyû?~Ùƒ0c @€ @`Þ ˆ1ÍÛK?ècô+l|óG@Œiþ\k#°@dRŠiÂ`6œž@dRŠizŠö&@€ 0»=÷ñ}^3'r @€Ì’€Ó,Á:l·æWŒiõêÕŸíøØ}÷ÝwØa‡ÎÛxvÀ¶ß~ûÎ#Úk¯½{ì±n¿T'pþï¼üÍ=¶d÷ ljóHà˜s¶ŸG£5Ôn ¬þ»Ýç'@€ @`|;?ô̇¿´éøÛÙbÂþîÚ/2¿…>üðÃãÜóŽ{L_ >ûˆO@:çÎ;ïœðëÞ†æ…À~ûí×ùUãý­æ3.H΋[Ç Ì€ÓÜ8;Ëœ ̯ÓÖ[oý/oØìãŸØ½´?±ûHÛe÷~ýfñ—/Øy—OEÛ©m[ð©|êcc´.Øí£oÓvüønCmçÝv¬´ì¼[¥}ò#; µïôɶm‡}²µ}èc»µîú¡JûàGw­·wýàŽ»~`¤}â;Ž´í?ò‰¶m»|¢Ñ>\m»l÷á]¶­µvÙv‡]Þ?FÛæC»4Û‚Z{߇4Úëí½\0ª}`Á{?ðñh[·kïÙþãmÛ»·ÿx£m·s­ýÇv;—¶ù;Þÿߟú´ÿØvçh覆޵íNïzÿNøGÏ\¾|ùœ¿6'}Â3Ï<óo6yÅ›ÿñåýºšôøì@`*‡~øŸÿŸ¿ŠÿšÊÎö!0I¸Óâ~‹»n’ûÙœ @€9ˆéãO(Ñ"{1§'è“UÿîZû‹ëλìkýç×ÿ[üÝuÔ_\ÇþCkëŸXÛþ}µõ/«ü›jë_S;þµÓ_PÛþítÔNÇø«iÛ¿—¶þ±´õo¤üióO££þ.šÝh£ Í?‡¶üE´ñ·Ðç=ÿ/&û?¶±}\Ü6ro\úÆÕÿv;<íw·þ÷ö±þÆÞáìíÿ´Þéêüsú¨`Ô_ÑÇùûyË 0úÏæcÿͼõ¯å¹úmÿBÞú·ñÖ«!ëþ‡ü¬×ýÛ[ǼúÛîôòWÿs¼–ú½ÊàLN ~gˆ·¯|«|˜Øø ±|Œl³í­V–Õ>"¬ýüªýðýÆÕüpø³¿‘7«vïTµÏø*íUÞšÚ½/Uß‘jïE#?†šŸÓUÕÞ|òç-ÍÝò=g¨ÕÜìô”§>Mbrr7¢­ tcr{ ¨À¼‹1í÷CÖ=ð³lk‡Ú£kjû~ã·þû»î¹ÿÑÒ~pÿ£v_´ŸF»»´{zW¥ÝyïOïÜðHiwlxäŽõCíöõ4ÛOn_÷“ïWÚmkRÚ÷Öþ¸Ñîi´5¥ýàÇ·µÝúƒÝr÷H»ùîÝ|W¶‡oÊvg£ÝXi7Üñÿ³÷'Psgž/ÌÌ9÷Nß™3sû;÷»§Ým Ý=—¹ýMO»ñбeÛm›Õ Œ1›mÚòÂb±ãÆľ#‹Ù$!B }G í•’Ú­ ±·ÀÆØúþ™ÿ¬§¢r«¬zkÉÌú׉óž|³r‰üGTdÄ¿xž·Vn|“iÒ† =¿áM/­Gzã¹JZ¾î KËÖ½±lÝ®e/yi©¥µ»úªiç’5Õ´xÍÎÅ/iÑ‹¯{iµ—:iÁ ¯ûé5¤g‘Vé™U¯yi¥—æ¯ÜÁôôŠjš·bǼ瑶#͵ôÜö9Nš½|›¥YË·ÍZ¤™Ë¶Í\¶uæR/ͰԷuz5m1qÁ_ýõ>Ó–l™jiñ–)AÚzÔQG‰d*i‹­ÇjLÑŽüîñhÜ0~ÉÔ˜v:ºqPÇ£¾}çèã5ø6~7!¤€R@ H) ¤@“ ø Ó€Is–?2qÎgD25©bÌi@Ìî5ºÂÖzã­ÝÕl­‰†ÖŠ•ÕL¬±öÕËj¼YµÆ¦jÕÀšêTÍšj¦T³£FÔ oš5T×|šd8XMÍdjöÒ°±4ÁRê›Ii’uÔ5ÖÚEiÆ4­o Ì¡U‹èâ-Sͺhó7ÿ^££Zìñ?غ+ÞäŽÒ_°tõÞûü-6\c{l¨1°WlìQëzš]=΢î•~`Q¯šÓSJ¶ôŠ=Æ„îÙÏãK&ô³¹ÙÌûWú^,äÏmŸk Î6n†q³Š³ôÿù3^w×–~PjKÿì_ß(Œ©uí¢®TÐmØgß¿­Ì'3‰›wÖÌ!¢}{¦ï¶i6oÈÖ¬öEV"d#V3-Xi»^¬Ì²Õ²@6Y|[Õ¼ªÖï)ç åÌ i²é“1LAŸ)‚19 ÓVôŸÂ“;l[¼yÊ¢b`Ld˜¿°Í+¾—vÝö»Ñ"™ZÝTêzÅSÀg˜N`û†ß\ʉd*^)'Ç>Ãt¾Õ·#D2§ì”S) ¤€R@ HžRsfŸ;`Àä9Ï¡÷aÔ„9Ÿù¼|2µ¦ }H±»ÂÜzí®é+E]€©añÖˆÆ.M^a˜ÚI±¸¶S[ÿéÌûVÓ˜eŸ5k>mÁgüjÏÐRÏ8ŒÉVxú‹7ì.﬇1yK:amcòÖ'XÝQúÏúSÆÒLü‡W·‰a “ÞJà4†É5žWÇ2LAé» ±Å,÷ ¯õmÄæbLFø[Pú˜ZÓ ê*%R=ÂŒL)V¦=t‰S`jŽa²ÙÀò²݆ˆÛmIŒ©†³´y½Ê¤_LÁ\^å­TõAPƒ1Õ8HÁ˜j^=Œ©2…&½ÖFS‰~"z”( Œ)… ,´CžÃ˜0`ºU7KUgK7Ür'F\Õ… ô½ƒ.E|/…©êL LpÅ0Uü0Å.rqìŒ~˜f˜B J²2Lž+&oiQÅS00ë'ÃäàÞÃÔ +&0àQŒ)äŠ)ÿÞ˜<†é[‡-^½Ý¦Ïa7¹U$S;ÚK]³8 x Ó1'` g¿ ˜“àÑ]$SqʰH9E½‚?g«opdˆúvøÀã]½Z¤gV^¥€R@ H) ¤@ð¦/ ˜2÷9  \ñʨñ³E2µ¤01ÕØ]=ßö5îí¯7»kÔÖZÏÉ}"ÀqoëÛ¾Q?L=ñd¤Xü ã°÷ú¦\1ÅxÂðüa4âŒ'ðÆ”äŒÇ÷Lß4ÆTµº;¥Ïø˜àÇ4?-í!c{8ÄA_sC¬s¬ë­%Ø22Lîà ŽA½ ¸bª5•[È‚p¼‚ÚU¾Ñ0QWLæÅÃ˜î ¼1…œ£0.0¦–´‡ºH™ Æäø>ð^m5sˆ;<ŒiþcŠú“ 9“³F,ÖS:Ãä»bª‰¾Â¸+t˜Å([FV‰wÅäNÞŸbª¼ƒª®àoLt.`-½1ÅbLþì›ÇË c*ÓoDÏÒ}„1u¿ ”ƒ¶(ÐsÌaJ©Â*a…oùþIn´8n‡\.µƒ.…|/…ãÇÕÐK¾£ÈÊ»(rÑ@rµ®ÍŸdµ+S‰%g>Ý$!€©~˜ZÄ0ÁeeáäÂëàA× 'GW–Ęj—žTWŸ`ä–sŒ‰ Ó’·‡¦ÏѽånùdjK£©‹æ_2L´9²¡#V‚ßÅOOÉ”ÿ,XÉ0yõÍ·`Á“Õ7‘L+KeW H) ¤€R Ô  Ó¼çÜ/¾#Ÿýiùdêwécб»:ÌŠkwÝäÌõV ­ÛÞƒ‰5Íý‚'ˆÂ˜ÖÆ…{±J¬—çåj 9ךjzÚÂ0ÕºbJd˜ZI±Ä»br1¦Xg<ýÁ˜¢kƒXÂ?¦ù£®JBA—²”~8 ÓæwÖ"¹¥_‰Ç[ú±‘»Â0‹~Í÷IBé{±œqÄeq¢Ž¸‚ r>Æc÷-á˜úÝêeS€Sˆ[ Í!î½Ï¾O/~!ô:KІióƒ^Ûå4_¡Xr«1ý~šÈ0Ùd_œ+¦°—¸ì®˜,vJöˆr˜†s1¦š¦•ˆrhj„1•íw¢ç鮘º«¿îÞ6zcŠRJ>¨ä±J×Ý ŒéDw Hu(U -9cªÀ«m]Â"!so`§ÐK1!äâ<0¹#®€Éx×xÁ8a âyWWù+Ò*îpk¢z{Èv…Ú®úŸŒwŒÌˆr­ðÃÔJ†É 'ÇøßUŒ)NÎ_}bÓ˜ñS¶ì|ßÒëoý¾m?É. †éß:¬ïÅí±Óç(š›ï~äÃŽØýþû \Ô?´¯òiôÄοvíÚ¶Þ´…ׇ¨-¼Z[ŸºÐÃtÔ1'xæ'ßõw°¾ÖؼšüäôsϿ𒦟åØô¹ž­0í»;ïÕ¾ë7úìÑãÓsÕ*ýçÖªß#¦ÓÎ<ŸõÍu‰‡ú†%êÛa:ìžæÿ½÷Þë@£»àÓ\»{VÕz6qVwSw—R@ H) ¤€h‰d˜¦Î{>vÅ L(#ÆÍÉ´s×›-¹]o^„SÌêЊ§%×†ÖŠßx%db]ë©_K‹¢‰/¦ÖR,ž£zßF:Å£è^{íE»¨²¸ÑŠ-Þ˜е…n{£ŽuÖ˜„µÁoLðcš?ꧤ\ ‹)ýt|-3ÀK°Å®vœ`åÒ.ÏÓ½p¹–ó?Lé¥??[8¹G\né/‹ &è¯ïÝbޘ¥_1†c:ö¸¸¥í?~ôçÞlÖôÔR crßn!-Ú·y‹_‘¸æG0êF.0¹s‚tc©Ä’K÷ÔÊ0íê« 'rÅTÅjãJú„3‡psÝIºåñ®˜ˆ1ýUà©&¢\àŠÉom€1-Xö¢ÛÔìz'“nªóR  c*d±)Óõè9Œ æGµ•‘óµ>ÆÄÞ†%š¶ô.±ƒXŠBKQni½.%8^ª¬ ‚Ç¥ÐKv¯ãCÈU<050…`>Àätçô4¬»; îîLîìY¬)±TqJÉXïæ#×íÍC¯ÈRËü0U& ׇÓS2ÃDoL#Ç<åBi¨Bõ[m>‚ ÓÒ5;°V,ºŽÓç W¿~Ó]|hc$¦xaÎà¸ß~û <¸}O³mÛ¶#F4zý &pv9äœtÝL2¤Ñ»àʡѳ¢Ç#«¸rˆÜâÓÿ ê I T¦·¢¿ Z‘ø»tÚàó.h†d:t(~¨´-,«ÌÑk¢Ú„ ܽ…·¶KYU¯{ý”ܶ#cnùÛIÊaT«è^­…¿Ç Ãô–;k&]Y};ì¨ã†ÞÑ ÉĸµÂF›J´M4­ÍUsWK'éu0hÐ HŠoqâìÙ³›»©Î’R@ H) ¤€(¢Ãôôóq+^üÞ;¢«¬~}øc³>ý¹/Šdjºˆ1¹v×*¨TÁ•®½©jwÚZݰq)ðJÇöÞpÜ¢PšRCÕŒN˜|7öÁ*P %æšOÓ §°E0eôÔ‘b±hba†)™b9”Sl@1.éÆtÍÃB tÓ+†1U×GKÞ"cŠ–|K{J黾—²”~]|-» ®Ú Mµ¥_³¸ŽÙöÄPé¿ÿûšnt¢(º>ÆäQ˜Ñ–ÍÚ40wÑ œ:LŒ‚ºùj#ç>°òæò09~˜Vn¬‰%—•Xrýa˜z>*n cª 'gá‚©ºÊ<_@³ÜÆgéV0LÆ41À˜èM Ôà°©Æ4gÁª¼Mº½®*ÿ½«€0¦Þ-û’?yÏaL0×bI.¢ôÞµ7 ûî÷O4P)–Uª2Ô?Æö®  ¥XnÉw™Ž.£¬„àqqî—‚î‹ëö¶J/ùˆR¢Èycï Àä."É 0ùtS0Å3L+_{¦!†©6Ú7"¾× ÑC+‚wiÍr“ÚXr5 úO†1 Î(ànÊ!Æd SÅŽœEÂÌ7޼vÃ7D2hpç†á¥£åóèn³ŠÛ51ƒŽSBxG]<¨îÑÆ¾Unm¨VZQòWMG צT]19¾h˜ÆØìÙ^ûqS$q´ºÌ\C­Ìvzç1¦º9OÉmÝs[r@ÿ1¦Vý=†é¬ó3Ö·C'™@Ë‘%m-pm ‹‹1%Õ¨ØÖžøO×Dµ%UZ‘R@ H) º¨zÛÑéŠ}(Þ.Ëóâ°þx夯M¬ÁÀ'Ëíbégš¾oÒ‰ýq f˜©’/ypìÌO‰dj¶ü€1¥Ú]ßõì®Çž˜dnm™Wû—=?î¢Ð½T3 Bl¹X„¥7<¾átµ—e˜jV{fˆ&žHNe˜ˆ1¥P,McL¾Q½ÆÒîÂjs­Â4K¿})X sº%cתŽLjã1Õ˜<ûª¥'L¾¦¸Ò¯‰``á ,`S¥Ÿ‘`«ñÔ™aBéW1¦`YïfÃaÆÔlû§óʬ1¦HûVãïÌY¸ŠS‡îëÌ|î—B0+-X½MwÂäø tZª¸6*ÕSV†É‹kYq7PË0A(‰1ņ“³ÖFS™3z¶Î+ Œ©óšëŽQ ç0¦knZÞáþ‹o1œN•Rˆ%Ô5+B’¸%Ç·-GYî ¡ÇK‘V(x\"½Të÷8?Î]< !×O€©ÒïiÒ S¼¦ÃTñTb½oÉQ†És–kÉ[qBŸÉÆ€ŸàycJa˜rèÉa˜".gÌ ˆá¾û«†ÊN2ÅbLt?CgB0òʱYvîÄw:œ´I `n“¸‡3Ít7rȺ.KWF8‘¶Tœ‚mlÐvbþâc—2GM¸ vâÞÛ–%>.NïS!›²aL<€Y¥5™Çó©íjø–ÏʿۘÛ:ÒÂ÷ÐM SªaÚó ·òµŸÚ˜O&Ð$Q‡@VyÈ6Yí2"Tð/]ÂðwäVf;×~¬cîoÄ ž¤:º>oļEŒx"«½¬Ì¼>ûÅY5rsËãy°ý -Ãü*)“Ñë»p·í\Þ™wÅ^!ª•µ9íø=†¦ õíÐ#¿ßO&6§VëB%Ȇ(©úYéXcËÓšJ·iˆbLѪhõÊ*§U'ÖO«<î‹ ÚròÊ–«Pƒj°B-3Îe9#“Äêê>£½¡ø[s/n—ê¡&R*¤€R@ Ä)À¾ zèQtÀ_cöu2Àš¦vl¥PZ=ºJÁöXw:u§¹åOÌ9¦?ÿ…Óž~&5:Ý ‚GV¼p%L(÷™!’©¹rÆT×îõòB[kÝ¥¡nظæ\Ú›7 × D,3À°¤’‹8½ð î‚Oc˜,ˆOtþ8¼È3[41³‹SÅÒ<ÆäÕ£æwLðcš?«e,ýÐÂàk­ë ÑKñæt‡^ Ò£Qä]pù~ÝbK?Í WBé›û“ØÒoša‚Iü“ôÆ”\úòÆÔ\¨³J¬1¦¤YE¶cÆäûJ Ïâ¿ÈÞö^a1á/Øj°Ëܶ \’aŠz „Ÿx7¾ŠCX:dmF?L3L˜ 0¦pôRš4÷˜Jü“Ñ£uAaL]]·ì„½‡1E<âºÃ'øËÅpº:r® GP)Ì*W KÕ8q¡qu·T³<.—B^—¼þŠç\¤ÖñR4rœgˆñl1ȸ+ÎýR \¯c±ré Ùz9þ0,ÞS“»²$À”ì„©Â0yN˜è¸ÒK!†©0¹~,+SxÝIn½1Ã三¸bªDÎò¼ÎøÖ¨}ÝYI&7¨ç›É@`þÛÜ&‘ÅÁ.î4ò)Š1átºÁŒ²MuÛÚPlDÍ‘Ñ᲌Ì5TÔ´Êém›òç¶Ûˆòw?20[½dOÄieÆM I±4bÉNá’© e٠Љ¦½Çîá0Lµl_È0]qQÃ4cYþë)çd.g« 4va|Ë:Àê:€¹he@â¯Æ~V™y«xذƒí'ÆQJ³SpYþìWý1Ú̲äbLÌ<+QÈû‘ûÓãO›²¸ø#)™Œ^ eÁ¥°+›Ë+f2D®D¯ÕŠ'¶ã÷è0LuXR›a};¤’ ùg}@pÃJú¤T?ûÊZ*Ûc­™5Ñù­”ªh~Œ¬òu« /m9Ýæ·àÚO&„…žŽÕ™gÅ&0Êûâ_VWÈÂ:Ég$ÿÊߚ뇀î{ƒk_õ¸R@ H) J«@*B‡ÁúÀض'z5ècð[ëT`§õêÙùaïÂ=ØŽ$ÒÍýî-Ø“áuØñ#ƺNÇ–ÉSBÎ;¹ˆd7Û²Çþ¶e˜6cÈ”»‡½¬P_1”m{F\Öô±g±oyüå0ʺmì³ñ°ô§³‡j´:º Sàµ7à ôÞï{tÆþŸUt¹FõÞãaLÉvW˜[¯¾ñŽÀîZ1±¦Z+ÜR̤odQèÛAüz+BãâÇÕXSÍ­Eü*PobØRm±æZíVîÒ oäÈd “ñ™[ñá2LÍÇµŽši´fm§³°ÓØo©®ê¬uKß4ƔĨÑö>{ÁJLó‡&øã+@k E_µ±»^—ܰq5Ž—’}/¥„2Èî)`rçõ0½ðLµžµ–)#ÁV»Ê7c$AÇ0^]Ù /\Æ4ÌØ<'Lµ~˜T®áVO'ô†èN ùŠR˜.€ûñ½÷E+ |F0ã¼Ç…âÇÅ:KŠ"翪_q±o¨8¼2Þ”-_Fµo¢Æü0ñ½3r¢ç; )œœ‚ÊõÆïFOÙY„1uVoÝ­c ôÆ„³ÑHî:^…áô÷N¬:x$¢ä€JNÏ£f(`ÔNG¤ÆŸm5NœçÖ¸:´®q›äâ8hÅ¢KÇKñ¾—¢Áã|z©Žû¥ÊÜ]GâúÂu–’4à©>À•Îȃsw‰‰ë'9À$çºM~ÐóÆ´w4\>1¦†)b€óÏNä,Ã5°vçºÛ3‘LÄŒpaRMøàrœKƇÖX×ÄiÛv¬$®« Z0£“o7r/kóÓ¼µåÁææ95NëªÛ’òZ¿ôádŽ:B†lû—b:2áeí03´e&šfƒWèXãÞ;72†ÉY\°}žÃ9õ pÌJ˜EŸí«`Lø]œœ™dB¡ãç€r¤wŸP…gevë«DôWÙ ~‹_.h¿#Ô[ó@ÃB·º¬·ý"²ü]DÉõuÄ_ Ÿ4 c²Ÿ™À³mºÆIÊdôúð‹šàN~0QŒ)z…¨V”¢å¿ÇÃÄÅÜ|óf©o'“O&<>[|¢ÍŽ5)n+ǦÛÕœUÈê‹’ÍÌT…¦¦x|´*Z-ÅBœh’7¦PËIFÍ* (šg{:û Ì6™<»ïK, Ø”6çax@ûa¿¡]¦Œ6¤€R@ HžUö"\Ä;±‡}ZãõÑqãÒ²7E&ûéåa÷†›ªtl]SvÒÜ[°s…芰lWÃ5ynðÏ˺ùg§‹Ý¼þÅïÑftLæ9z…¨Víø=Æ1L!fn—±¤Ñ‰Ö·,$'X^6Éä–[Nk<­ú…ŠØ*¤GY0¦Øªh xˆx³ŠdÙcÆ¢-§ÛÀrªÅÊ3ë ®€ÆÙ¾bãɉ={(W\¢1o®Ç)\×±#‰Ò¶¼!Ò¥€R@ Hâ*À¾+ûä¬büu?l ;çè±Ø콸#ÊâvEB] Þ‚øµ‹YÜž:<ìDµy;vÙ¡²î"¯cR»ˆÛ½·n˜ O¬›m·Ðíq¤õc٥繮±C•ô§³‡Ê^Ó0ãø¹/ ˜êÇ’ ûar½ö&¯xA×ýžG¦Ë'SvÍq$0¦ v×\sk’­5€–+kÝE¡¾'ûºèRØ“}]÷KuðÔ "Ö„Å[ä™HÎõOo “M'Ã(êcL5Á}B¶Ðoþ½¨c­ôÊûŒoTÛmÏÌgW`š¿¹Ò_Í•À–6½U\‹ePÇ ¡ÒÐT5ž¯vB5y*™|P j3¯ç‚+`˜Rœ0U*ÀÌeÛf. (H$Øü@rðÆtí°GSÖô*¨\Cížîˆ1ŵoUôÌxvEüŒa0]˜ØˆÙË+Îe`µÕ²&+ì’Qä,ÊJM¹³’3?LQw€ž£'X _@ÖþÐ`¥åÙ‚i¸*ÆTñü€ÆÔ ¿=cçÆÔ9­u§Ž*ÐsÓ•×ßêL¸ÿâÛß;!z@uð*Õ.rT±¸GY¡¡uZJt¹T'`\(nÍ’‘°ã¥„Èq5¾—ªÁãšs¿TãÙqDrŒœ´²$ƒ¦: ot˜,¹cõêz£Å›_ ŒÉ&vj¹z,ðÿQ1À™Ë™Nî…—3\¸3ÇÕCëLfÐdSÄic.åäì/&2F0ÐjÉÅv6,ü–]–_|E~È¥Ìl½‘™_Í Ù#3‰bƒžð9w œÄ#ù-­¨\ñÉÕ¢<×rËœ˜ ÛlÇt¹¯Ü {æFg˜h] åŸWÃÔò—›Ã0½Éa^<Ôl˜ö~Ë·Ãûë‘L4ÁÛ#°òÐ(ÏpüQX…$†­ 8€UÈs¼c¥b=¤C&VïÐÁ¶|9¶Ž¹¿ˆèÜ@ôÇh{HþYÅÆ6áE[nn¹Å²J”…?pþ´qY†HÉdôú†6â DXìçÌ)ôFµbY´ð÷è1LgžÌ‚4Uߨ£¾}»žO&Ða±B·¼°RýP QjèII­¹sËԆȮE«bc2ïG¶ªÞšV|Åù°hËÉ Ãß‹Ur^ÙòÌŒÙÓ±¦á[¶ÞøkÏB•XßX]ÍOßY|䧦¸åM±.(¤€R   °o™go„ÝZöUðáëÕËFw†¥îÁDšì`»rhñ@ôÖ“±‘,»²îÕÜá[ä|6óéöp’0&ìg‹£ZYX76°‰yàNöôBʸåîbL¦6B^œM7à’åž}ºF1¦†Éõ¢Zwzïw?<ýŸ?sàÎ]o´žw8ÛÀ˜²Û]kl­5+B#nìãÜíÄ»\Š'WÒÐ¥¤àquØþ-ªæS¬c±T¬'»&µUÕ OV„%Ñ “k­µ‹nö0¦H 9w޹YŒ)ƨnföÏxS8|Ax=p“¥Ÿ3®^ƒe¾gåï%§ô=+º9ßrÝ/5„¯¹QäÒcº¦rr!#y8Œ`ЦŠm嬋H/áxŒÀŸ˜³âÒ«oç,9Ž#±Ã>ᓟ> ƒáO~ê¤_]t•C/¥ööW–lß{ß¿‹™»>*èÝzH†‹öœúƒ1}ô§Vì¸iÑ– ZQ7¯A†©ïÅí³‡Õ8ò’ÉG^쥓†Ìøê™ãåè³^8¹#.šôÐŒu4À™+&(IцܚF25ñD!ß!M\¡U§ÐÏG«®V÷:0ÓM4üVÝsu@Ó €a:ò˜\«4¹OZ¥ñ‹ð“~vÃ\c˜b~þ0 †iþ.~ðÓD’©é¬†Nt×4·êšÝºŽëð)vÝy·2Öòû‚a:õÌó£õ Ó?üpÛaÖ·GgoHªoæŠÉêÛ·O$™Zõík™1Å>¥ù@ª›gLåFó¬{¢R@ H) ¤@›0fšnl… az. utas»X\¥`kfb{Ť½IŠs¬Šë»·À÷:ü7„1ÙEx.Ž1軎cé6‰Ô¸ÑB¼ ÝçâºXn{Ü‘ 9šm+Ó„´ýbòamNça\AA¸§îÓÙCÕ­ Ã4ï9ócmË]ŒaŠtݹ&”ï\4iÔÌuI+^0Z6j*ü—È'ô÷›žX{ÐÖwgÇ–EŠÝ•ÆÕ+’í®ßøöá°©"}ì¸"ôècOªì9Ɉ¥{GM„55´"†V˜"¯¼a˜Tô“_ìû‰¿wç€ã½.Å9°w]ïÀ"jü –HzÖEØóÏŸ>À'‰cÝ/Å;à©õXï#,Û}Õ§L~1HýÁ)@X~|ÚùH°l¤#,tÂÔ&Œ FõX{;KA1ÍŸbfwêÀI´®‡êÀ7|+º¥ sm®­÷Œíx¨!Nøamp½.¥ KQßK^pVÿô/‡¢ô±ÓjÂ觤ÇËŠ¯¹Ð@(~S\ AÐK¾v*ÀÇ÷ý»Ä(rà †ÉÃ×Xú˜ê¾Jt@*0ú¬=/ݳû­èãcжonƒ†Ê6-K…¼¬qjà8^¢qû¨ïô‹³/ñ_[p9ÿ¹WðF[Zyaíÿ™/øé€Ë®½ƒ/,{O]ûpLöÙêÄ=-Ú:=pÛÞtžE‘«LáUÞGæ ®^ 9(k˜.Þò ‡1í¼RÞ˜zôW¦ÇnŸ˜ڧ­®Ü)h$ Ý-Æ£}Gw*«íº†Ó0¯DL77¡Ó½@oW\{»?5^¤ÎQSlÂP '8U"_rFNâXzà±'a…ÑÔ‚•›q=7ÐÇÒ/ιCnZß|×Cø74´®‰«…–²pKîxÛ§þêb,ላ -Ù±è’3ö~ý«ÿrh°~Èw€|ߣÓ~~æE^G‡ie°R-ä ÷wLÛ{ß¿O¤—¢‹ŠœÎ1¦$÷K5“³Ä$fˆîCß•q–›øCµÅÞP-”šÃ˜6lÛ €iÄó»«o¯9/ŸÜ®úºg¦¯ë°%`˜*ëÉÌ•(j&Î኉l0Lß¹xRÀ0½ðÚO®Ÿó•3Çœ¾=Øù`úÜwÅD\\ü[ZI2µo²¼!yaýDN¢®˜ºHCÓ&K{t'ïÛP&Kv0¦(ØG«ô)7Í;çŽgÌ?Ù‰WL¿qÌ ²}ÎïÂ[SRý]¼½0”'µ™dBU Em(héÐyežn¨ ú,éÙ&Ã[ßà‡é ³ÆÛ2͛Ƭ¨¶Ã¡úV1AzTn¥¾á=…®I>™Z"fûZfó½d~Y2ÌÙ,¶™YŽ×1R@ H) ¤€h·Сcãb@¸#:·`µ1ŸWÝп ÖfùŒuÁ‹Ø·¡[ð¦6R°ÃÜ«Ñi“»‡§X>Ý<à07jž{ßhNBKqö„nÄ‹G³mûíîÈS¹{¨§K;1ç?ŽŒÕÖ­!d˜¦Ì{Ηª Å-ráߣs6âH#­ÿôIDATc2/ª?½a†š±ŽÞ¬C®˜Ì„rÇH‘LžØÀ˜` CŠ…™hw­ÁõÌ­–*v×°¡õªïÂBV 6Ò'f,A2\ K@A/Á²jëBCìah…õ ÉŒ«8“¾ñäJ=tɆu1=lþ-Žøî‰§œ‰% ~ŒžJð¸¦ð¸˜l‘§ëýÂ]äé®ðüÒס Ó¿žv>ÌL¡(r†°Ð.Ú>Œ)2…_-ý©óžÿ›½÷M2³_iu`C¸ è­0‚5·»$8Zög¨ãsËóº”6ŽVô¨ 5!;½„æ¥Æÿ–=°!ÿ[¾fNP*SPô‘Ò÷ ãŽI\S»»º~Qxàä=àÎúË(ÌDŒÉ}9ÛÁ íÛTŸ¢vÆGbñã $ù ¼àÒkÑv~öÅœ¼qØH@KûþíßÓýÒyÿvõI?>啕Ë^Édó}h¦à~ 핹ˆC…fêö¯ñJà9#H˜ž2ên+31»d“tUÿµïø~#Æ”îöOÞ˜ŠúKQ¾ó©€0¦|–‹r•Y.kc¢ èr`L—_;4XÁc·/ÄøöÈïžàzNŠns,ýè§¿À¨Ø<Öb,}ïCÞ’ ÐXl]h #jÀÔ.·tóÆ„¡õ×C§äkß< 9ÊB…xõ~ú¯.†Áź,§ýêb$ ´ðý*ỷèÁL~z¶ò.rÀo¯¹ã¼Õ!Ÿ9`Ìä6êv;4¶lÐ†ßø‹oáu _ýÆ¡èè`ܶ±ñoWÝKpÓKz Ûî0 Û÷ø×!ÝýðÔúÔç¿üõCð÷–ß=n‘ãlÏM÷ŒuûCÀ˜œØº^¯+Šþ×þŸÇâ Éð=åâ_&ô“ð÷KŒ¿ßçïn>ièðI¶ç¶á“ÌYnJ¸÷F1¦µ›_Ÿµöê–ÿ­6mŘ<†é›‡-Y½Ý¢™löb1™»ŽÐïœøp ŽŸ¯ôù³n›Ä…“|ŒÉwÅTër†Z b/¿yDJt¹ÌÍ‹”SÀc˜¾{‚­· [¥_ÚuЙÀJ*1_|õßc˜üßÅ™þïbÄôuU†ÉqÅäý.<'Û›Oüɯ’¢Ëuî9u§|(à1LgœŸTß’†êæ?ž¹¾¡úÖn’)B*R@ H) ¤€R`Oû {ˆë1L ˜2÷¹Jï=ð×8aª0L0¡cÂòzQ½ö“oÖ˜¨ó§èÊí#¦`ú¿Ç}2Æ 3cб»:Î'’ì® kAa#¹àEXY½Õ¡•å €T0üÇßßù¦×P8Zéz‡Ž+Ÿ¶®,è»b丙fk½kÄâÁ¿\‹rçðñ0Ÿ¢Jà¯ÙQaa›4o쨞ÓÏxNw\×õ¼âÙß°Ú †S˜L‘`#ý·«oDzϟŸqÑñ'Ÿ¶÷ßþý¯¯ _õ_ùÆ¡HtZ XM¯ºåØ%ŽûÑ©4bψ ÏÀ^zØÀhAE"ÀtìOý'ß zÈQÇ£B90“šiô#‡Éôà#Ätþe·b›k;O?÷Š“O=/„°´c –œ…Lî• €Ÿ'¦ù“,íá:ðlPhöAѳ0¡Lvµ»$øt«¾E½^8€k€­  u! P40¨¾ã¥Hظׯ0v Vt”>ë}/a#¦Üo}𞇧¡”?é1ÊšìÚ÷ýš€tèQÇ£Üï50’ãï…W܆ @Ãø…—ßêÆï1™¾‚E Uâ‘Éˈ¯aÛ"" „1é},â ÆÄT 3¡á5_nãæ¼ÚØ¬á€j'¤&È©ç× …[r¢íÂä æ9ˆ·fÇM]ˆ9A¶Zh¦Ìa¶ÍUš©Á—\Ìõ8sñF2L'œ|ƒ¨ š (¸!À_LHôÈWÚ(Î%…£È¹eÅÅ@È MëHY&Ý„1é—(Z©€0¦Vª©kuZ,X‰äú“¶Ô÷Æ„¥óQ7Ú~‚ÝÃéË®Z+ÝíRlxßzäžÛ¤ÀsÌ¡®ÆŒgWsÍFMn˜mKî ŠÃfðIŽw¥7ÐÁΊûGoiÈMÃFN}æl<ýÜ+c_~Ý0ôW¦Î¡2´Þuä1'Z². 1&¸ŽÄHÛó¹f'º)çþúêSϺC/,ˆ ÿ]‚ÇcÄêvƒµ‡ ŸsÉU{cô… tk®¹m8¶É-ÑëŽGÿæÞÑÓ~vÆ…ØÀP –~}åPôxÇKÞ’5oÕÚ=OÅðÛè¢ëƒq8é%ìG{0ã¨Ìã–÷KwÓÁ9ºÓ;.’ùFÆ1wŒ˜„†å¿8ï ŒÓž¼ ¦ë†½4jÒRìI÷ZÉ!\–Fw#Ç<L˪S[1&2L‹_ØŠ0¸ãò{±Œatâ30aîüþ)kQŽ“¾zÂåÓQL®1í%7œœ¹ p _‘L-j]t™N(0L•±_5Ú¦öat‡èø-í«ÆX|áµIÑß…?£kóè†Öƒ-ƒH¦Ngîï†é0Lõê]7³¾1EPßV8íp¤¾‘%e}É”ûº  J) ¤€R@ ´@èÚÊ\Ô¿æ?{À€Ésž‹šPhE1ªè½ž½ývôÞ'/òì'0|c –%x³æ´ºî"™BSfªow½†v×[+ÊÁ`E<8ÃV8ê¥Äð:H£÷L¯ž›%ßÖ­…­6XTQÜXð ÷\ Ëêˆq3±1bÜ ˜79üØ”…ØøÎ1'>ÖT˜Rý1çw«@=ûê%W£†À§…!,œ¼‚=¤—°=ôþÇaõ¼×ûNë.=üä3°šÒ^Š[(&Œáè SŘ$†áôÊ[€itʳëA±À^Šô“_\€D3)§A®ÜùÐ ,°‹Òõè¥_ž?qÄ,‚¬ Y` Å OúÀ0|ÚùiÂ"ÊûûnÔSKca´ÉSuÕY­½¦xüB1Ío¥××§ÜÝ:b ÉJ?¦¬Ö(qÌý»u€¶ôaŽÇ2àƒþå0®þeéã/€«†˜Û-”¸‡1ùñ &Î^ËÎX´ÆX€k °ÁrGðÊýäÓ`3»z Ë}=³ùsÞ¢S°g^xåÅC†æÓKHà–θ`Š5á©ùë`$G¹?:u9*Š%Îr(w²ð{Pô(qü=æ¤S¼ °xËy¿½õÛß9>).‚ʵ꽣ë”Pcª…™ˆ1ÅÏ*V¦qÀ¤9ËC¸’­¿M rꆹĜ p[ó_`AW,©‡1Áö ­ù^Zø‚Y…Ñ4=ò䳈¬‚„ x% ½„„ µŒ¦BÞäÝÃSѯ¤åÛÑyÁ ™òÀD/•„¼CÎÿ̧@ÆI7aL%ü鑺¨€0¦.Н[÷[0L yß°7&8‚fàx{.‡7¦Ë®Û™àN|ûï²zDýa°û=ŒÉß`zèñYðXË¥?–¦ù|Hjo–ÝOô±„õ@TcŒí§gbÛBÛb{Äc3Ð/±Õ!è¾`;è² TÜY3ÑÙWa©Ð˜I H)a…ГsWbÄ… th*#.oÔMKìÊ ‘ËÆ)ØfÀ8`ZùÇ]ÞÐËǘп!½4~æóƒaÜrï8s¼Dt‰¸é™Çf<‡ž7&÷c˜ð×Ð%ËýÎç{ÉØ*‘ÝI/ž²—aƒsŽÍ¸ÊÄ<$cî—ð†è^úçÏa@þ»1sÓWfìQ}úóÜ?õgD&kî^¸e2ÿLýß8kèÿþµoºè…mnݳ­YßÀ0=:{çÎoxtè ®¿|úC3Ö¡t€1 Ÿö’Nn›ùBw§ÏE2õ»Õ:¤&´Ï5? ƨ,«èùij¯à‡b˜Ð¦9¿‹§†OuÕ0‹f˜6’鈟üûÿsÖ ªÀá?Ûë”3ÎK¯oXÆÔ7%7^¯Ä˜²Ö7Ç©»G2ü7ÕU_¶üKR ]ÁÛóêòµÂºR@ H) r©€Ï0} s‡!Š;Z¤mCÅѳ<Œ ó|è·£÷^Y–൷âŠÉìK$™nœù¿t¤Ó¾l#ÌÜœÅî5´†V„"¤°UñGýž_ ?¼ÒC¾w%3±Ò ¯°šÂÙ&€a4óÿzTz¬·i`:±ÀšO¬ÿ´`a´©Â(Š„S¯pb˜vT?pX5fÑ%Ø0= ó)]\0Á"Šb˜OiA½š*†½”^êi5½D¿;Ę`&¥—úA§_0ì¡)ƒN?æP:^Â&’+œ?·Ïô0c‚¡ïäSÏGÂ,ò·¿sÜy¿½åÞ1s¿xÐÁIvÑ6aL®Q=j~ÇÓüé¥ÏoA¤¡ø¸RPîVPâ0³c1pPÖz‰³þ•:°u€Vt«\L€u­Æa°­ø¥uå~ÿ£ÏûÀëRmÐ@Ôs¼„u¿°œ{À÷k‚'¾æ©Æôy¬øõ æ~¼úÜ"¾†mp¨]qñ5Éi*G)[ä&àk VÀ¢÷9¶-°£ô cBxxÒ2ü z å~í°GSLâòÆ”ËWY2µkÓž ?!ÃTŒgýå[ÃÏü‡Oì4«È†ëo>¾ïSµ]ǯAÍtaõæ7_ŒGÇKçýúj´]lÐb#œ¢E2‡nK…WÕßõ˜Zâ•À•¼W’ß4aÎHÖb‚Í%4MÞ\ÞsÛú‹ Ðá„V‹Þ˜ðJÂë¦ÆÔ[laLCSÂÒg'LÖòdñ Œ)?{e¡D c*QaöÚ£]BD9uÉCÏ2ÖÖ3bÅÇ`©imºeüg¿0àÍ]º±&‚{¥GXßÖìÆëçÎQ¾ÞôùŒuÇ_>ÝK—MÿÊã¿ð©Ñ³6@yPbÃäcòær†ýë>öÄmo¼ÿ§?ÿ¹Ð?pe¾Ü ÀEð¾…«¶ñwa+ûh•V2uñfþ.àßûòáK# ò»˜f¿ ˜‡ª¿‹J˜E·ÑVò“KŒ^~xkݺZQ8ëªúÉõ )êC °¾áßI ^©o>­›Ä’Nxzý_ýö½?ùæ×¾ç†ƒ”¤@V.ßß³¯=s¹=R@ H) Òxë­·:è ‡'Ω1¡8Ë]l"ËÀö.c×ãÄ#`?™½‘QTèµ×ï½{&oÅ‹³>­¿ðµÿuý“?›ðâ7Š2ºia>ǯùB5çå“~Æ1Q»kÅÊêùOªØ]öVXVï1Áu«sþ¥×À©’-=ÿß®¡‰«@Íu=­H6ã ;ê wŒ¡b A½å /z¶$àJp¶D¿¹æNQ¸M³*È•YK6ùÕw˜01ìÂ+´ záÃ>ufˆa5ešºpÃOyáOyÃôëŸó=^TÜÕc{ìôå0‚_1~þ _\n‰ ×y`‚÷Ÿ~>øl€^BºÜÓæ€‡î—à™6RcZLŒÉ !„ ËwOüù¹¿¹¥ÓÓÑ5kÏ‚HItµî'1}|ß$c»Õ.FªÖŸTCà2àhpgý­Zbéó/¼myEÏ:P)wÖ,ÆJŸiôSÏr­/Ëݼ.1d05ÒYˆ°ôïAzxŠžø*ËÝð5bL´“£ôÁ0!n <0_»ñî± :Ž—BËzY>ñ€Ê Žœ£|’3”ò†Ðèyx ’ï± ’õHð•-˜ £k/0Ü‹ÁŠl`QÙbpÅ·¾‹ã‹0ÊÂ¥è+]Œ²ÐkÁh clô]Žøî‰ç\r5 % ½µÌ\²£ƒ1ö9{Ñâèi ûáLò¾ÑÓÀ-11h76È-`⬲rh0m ´èréâ+‡¢¯X›èR5UBŹè| c$vÅMp4Ž!Ö…WÜ “Ðå7Þo£2ÒKô‹ËtûˆI¶¬„K‹à×ñìϱÀƒ´ó~s V^ÂhCtlc×BŒ AåÖmy÷Ùõ£¢0Ì4ýýÆ¿|ùr˜áæômpz·AÖÁîvã˜0Àaùà×búåè-öz~Ê ¼ÎÔමJ$#c˜ðtH"™ÚQ”ºf É„¦oÁŠ­)¿‹!#–᧺Fï¾Ékñ»¸wÒÿwáµ]ø]<8u-Ù>†“‹5LƒaºæÆaü]¼ñÎï[øºT€0¯KP³4ªÒûFpD£@{dÖú‡g®C;ü“ë瀙«´ÃÕúVÃÌEXÒ€a9Nõ­@u#/Y];[S^ÊBùR@ H*3½·ïÃÕ„Yn]w8a„–d ψ Xp#®Q´~Þ¾ßß{ï=÷"¸£ë ÞFI|°NãŠÃ%”öUC#É4j§÷6¡ØòôÞ1f„q,èº{Þ¬“½ö:Á éÍú›¾jÃëè½?³jç?ê¹Å`±Aå`Ã~–6fw­ØWÁ0M™·ü$l\vݰ)ó_pö0eþ*˜XÌu°D[ë©¿º c4˜XñíØÉ ]gK ”Pú×ß>TNÃÊ Ó(Ö‚rñ' ª°£ÎZ²ÀÁì¨G}‚gRxt3x%˜&¼â›O™0O|ØÑ'À7uÁz,ø|hâ3`˜¸à8 ­¦tQsÕc¶Ø|/\Ë2ì!S!B€ ôÒ wÅž‰ó^‚íâà#ÿÅyWÐRÊå°‹dáÚÎÇç¬Ãô£SÏ£- K:ËÒ&oLiFõ—v=1{¦ùCnHÌÆž\^ž·üe+M놬™™n–²ÀêÀ˜É ÍÙI5”ûu‘:0ú)¯Üî[×aHÇÚ$=¬è¬(ú T˜c×Xð½›xôÒ¯.¼ˆ@€¯Uʽ‚¯yåÎЀØ`(@¹ÃZŽ„2}rþK(zì¹àò[ƒøqþ*_˜Êý °å{¾C&w}/1&TcòÊVq”»Uƒ$ø0¦†Þ/=t01&Øzö *÷TþÊ1/¨œÛ|ÕN)²YÃOÌZfmšùXªlxЭ5\¡Ìp[rKt^À~ ½ !Ä ¼.¡±Bë‚,A/Ñ÷b›¢uºõÞqhšðzºê–ñn M(Ä3§€x%Ñà÷ŒÅ+ÉbYžqþLn¹Å>äM'Lê-Œ©g=zðî+ Œ©ûe ôWf¼1Ù=a˜(º+&§/½ê¶H¢ê¹ßbÄåö-¸¬§&Õ"ÒŒ§Î„m Kö/‚¬c”Déú;FX_„”̶]LÌ{ðqKô[‹o§Jc‚=„–ãöÒ«ïÀˆt‹s.¹ Ãlô]ð/vÒi$Z ¯‘®¹m8F\ÓŽ ¸%ŸÅœ-îŽ}o·„–ÐÅõ„×Å·\ Ão ¹ÑÅ9ñÀ¦,𢶛ç[ŒÃáý˜1ËÜ„UD¾î¹d3m9Æ`Lt¼„Þ¶çqOÊ/}í`úÈEbdwŒÒ±„ÀÞ{½·€U²ðÞ˜á_þe' °áo–ˆrÙ½1cbÌ4ÊñÌÔ&Œ Õ•$Óì%ëkúµdðýþëOo˜ ÓÒMÂôùcó6Ärtí¸brú S­Ž~˜ìÑD2õ·•ÕùíW€$Ó³+¶˜[2¶®ö»Àˆî†GŸÇ²Zð%øi¸ ~?¾vvÌïÂtÙ@Ëe˜D–´¿Hs}Ÿd:Î ¤H­¾Ÿÿ2a¶Ã×~Îe˜âê[e1w¥¾…&Õ·\׆fNS EY’R@ Hâ(ÐÕzf†ƒI-]˜¨Á®Uˆ¨ <)îÎ<Ø¿¶ÑÏ#§å^$Ä!¹“¹mÛ6ðLÈ’•É*\P¿j4cÉ4~v’ Å\¨Ž›· &c˜@ ºn\1ËÀ–9‘Ç“&vÝ{d aL0±¼2Û]öVâ)0¢"1’ü*qÏe×ÞAT ˆmªî¤/ ­H0 Œ™´Ͱ¿OÎ]‰ $ØNɬ[á4°—à—ëäÓ<[kÅŽê¦?ù4ü K)’‘+°¹Á¡ö^¡g Ô¤ã~t*XM¯¼ù Kg^x%é%ì¤Õ~w`2¼Gõ؆½î£Ž§ôÂËoÅ6l¤øK§¿håúœ©Ã´¼Èœ÷W``ôý-áÍeÜ›"a*ï,4Yh¾øÂ¢Ï4Vh²à¤Àæûøª"YËè–ø{É•C¹¬÷,Ÿ°D´„v‰ÍcYÂÞJx%ÁZ!Ï¢Lž1“ɃhëLlTN­Šè´˜:­¸î×z ŽÑåÜOVoL­ÏN7®Èát”z¶=øöðÇÅ÷0*æØ‡;~®Ìq.éø1H~wÄí”R]ݨvPª=¬ B ØN4nsklž–ÜEB6Ò6jG\ÕQ·3ðfϦš*¡âB.—nºg¬ÃÙã1n‰¾dÏÙ‰Œ3‚ÛbÆUƒéVPîj(Ü+ Âëºp7Æä×ø¡¾ÇÍY“Ñ÷Rt—¥G…E*.ÆCÕ¦íïmzëñ±«÷‡'íöaLø‰dš¹x}µS[‰^ÄFt²eýTúaò Ë¡'ࢠ“|2u£YÒ=V$oóŸÛ÷»¨:{·õ‘lÖŒ¹Lgû¢ “È’†K¨\'€dBÇ J/U@RÚO‡¤„iËN¯o3Ë0©¾•«ú´ùi„1µY`]^ H) Ê­z/7ïAðÄ=!Oæ‚®Îq ¿‚} <˜ž“¢{Hð¸ËÍ_:µ={6¯`÷ãÊ@yH2át3xðàP‰àâI_!3üЏó€!Ùö‡®yYÞÎnA 'ò©í²¼ KeÁ˜p)†LƺBÊXI2||vh­ ¦PïËÀ¼Þ»T¦J$èŠU3C¹~˜ÜÅ`½F2ƘXF Ù]Lªkh5T%£qµ2ï[5«z¥_–,þŽë·žäJÈŽj¾vlÃE—Òl§µ >CVS†‹ÚKÝužµ'˜6ŽN'8À°Ež4™v8¨\Ô¨îÚØ'Î\ö×ß§º&-›¥Ý/ýZ{=Ózmð ¥&Jßu¸תöó8Ëyhů[†=4…>·èv+âï¤â5Ü1•ÓùV :Pú(ti’7¦Œï( Œ‰S-ÀDq€1Yó•4·ˆ&Ì\–ôF«iÇ’1‡[BÃÅ~‹Ø4vâÏ}UÙKÊ}CÙ¼žÛ4Ù\ž½’⚣X€i³»8©É2éöW½÷œ«Ü>&Ýô{”R I„15)œNË»=‡1ýÛ•·E‘#Ûƒo1⊠¹(R–TN2'1”’gL±Ë*²ö–ƒ8áÜ€Üa\©_Ç·ëAKá8qSão °6üßÓ®íñTÇá¡ÁX¿Ð%ÇKŠÛ1‚¿%:^Âß”pïé P²ô¨b1¦  ûÖã+vÜû+ßöÞ¶÷þЂŽI¦‹ÖtãPÜ&Y‚áteî<†a꣦-f€Kb˜D2å½ÍVþ|<’é‡<½|³ó»–Q²mtWÖšU:&ÆbíâÚ$†)…,Y»«áUÂ*ÃÂ)@’ÉES µ Se1nu$½¾¥0L¡ú¶ìÞ!S|驚ÀÔpîeƒ '¦2ÜJ„1µRM]K H) zN€2@pðî'*ÂC¤œD]Àôu¢!là_Ì=ø»‡ÎŠp$¯ÉÅ…Àž¸ÇÍ€ˆóÖæ6 ‘K2 ÃíAì-QoLÌŸž‚ò‰è—Û8‘¹ÂGhÈeÄ”1ê‹26]I27Ë5¡¤/?ˆ2LÕÈã{TÄ®û#‹g÷É´ûÃí±‹ SŠÝæÖ_vWgÁgÈâê¬ÿtãéDWFX¥À¸Z ¨O,E¡%3¯ÅN ÓéNÿÐ¥`µ§ ¯ÔÚK·ÄÐK¾ß‹jìžTz &PxâÁRÏtWL8¬MÞ˜l Pìrßñ3<Œ©f¹o³¥oR§¦õ:Ä’o2Š-ý¬Ü’Ï>†çQpÍYñ¬õõÙµa#'ÃßI,½ÔOv …Ž¢Ï@Aåš~Å”üDaL“¯b¹è‡S쬢ñI8`üŒ¥YÝÔL:ÍW”[ Ý5 mÒ{*xIÕ¶QÉôRí[ÉdI?pÖFÄK˜§kÎw€0¦’7)z¼+ Œ©Ã‚ëvR ç0¦_¹5ÆR…1·‡ <.倸¯âɤšE?@më?"•âý*UWñã«d\)˜O­%–b=-Õ…–ØÑIô·TY?T[ÚêÆê{]ÊÜ%J§”ê~ÛOŒ)åwºß­žI®%’LÓ® Ö‘fsÐÿGeaغ¿‚Ç3yT–a¥3LœAýíZ’y]D ´II“&}å‡Ì]¶ÙÖ¦„µ+k˜’êï"aâïâÝݺ3ð‘³7ÍnÓê²¹Rà¾ûî;ì¨ãl wœ&Ï^u%·o²ä›&€PLϺ ëÛ¿ðGˆ0aЀÝ;·EÕØÚ7xS®TRf:­€0¦N+®ûI) ¤@©@c&úC¢g&n×± œ‚¯ c2‡ç€rp|ÝãbL8‘çE\‚‡§×Œ5|DÉe•ð/om@T¸nj(¿â-¸§À1I¡%-rsEhÉ2ŒLº¡è¨^`1{!Œ‰·èg=Éô¥_þجŠ¿ Ì÷U¸ìu–~˜b˜†LûÝ/»]÷W_ßÝÏl—ãt`L-±»Æ!JK­°}Õ™ñ±¬&KQfʼnD y܉ZPSœîTÕÇy©÷‰–BöÒx×;­6“¶ cJ7ª?>})¦ùëZÝ[^ú kIKt¹”¦À-}¨zÞª²kž×/%;ÖªkúŽ Œ©ímëŸBS²¦Ä˜Ò›/€V®æ˜¸ +Õ·Xíû«ê¿ @-¹¥PTÓXt‰ÝKQßKî\^ô}û&j¨µÉ2é&Œ©õ¿b]±—ÆÔË¥_êgï9Œé’!·&‡^Ç·•yÊšá±ë-)ÞsRœkb×ëc§bשReD*Å®ªqhŒ²"Ãl['ä·bˆ¥ˆ§¥zÐRBœ8ÌÔ:#ðŒÑâjÖµzH–±_•¥G•â)©q2o0¦¡‹‡Â!Ó„5FÃT1yda˜¶ì|ÿOþs©›>=\?ñ)L³—¾ö1À"£Ä3%1LÛÞ¨ù]àÇ‹Ÿùài^¨þÀñ[Žý™£ÀWö«/ƒô=ù wÝs/zY! ’ÖÖ7†U­e˜‚ú–‘aÚñæî~oÁ̓¸ßªÑÞ+™à™‰Ûø`)º{p ¾zyn7KOc¹ZS¹ÊSO#¤€VJ¤…\ŒÉe’1ºÂ_¸)2Œ g1ÏÀ˜ÀáÛèž$ŒÉÝ+r èC¾Êö»î…IP¹tskWã²`L<+„1™ÿ$>]ŒÉ¸Ë-á©› 'ªA2zä÷«¡<+˸³×·ì sˆ°q ™Þ~e-þb{çê> JtÂ/Møl÷ã/cÌa?ŽÁlÀcSsOª³Š¡€0¦b”“r)¤€9U€Žˆ˜9 B j\fð þµ¬¾ã•3À×Y»v-N‰îqÁ »¼(×aŒ6Þ"„þ`Àa¸¬eù1'F8W¶s!oLîƒð¦I“›PJtÝd¹¢,&2‹1írËØÍ'ö‘îr3I‹®úï~)¶†‘dºÌ Ç„Rõc»Ü¥!† ˜žß´ã«w;|ñ“¿ÿð#Œ á¬—ËØ¸Öì„];9r„ýÇäô÷ТlcjÎîšhn­µ¯¦-M Ub•hx¸Ø•ŸQ#jÈW}·6œ&˜LŒ×*‹hû0¦£úcSû0Í= í¥Ÿ!X-çnj´ô›×¢èRGVù cjQƒWºËcJ.RbL)í¾Âhåb´šYÂ0®”Ï4Ö9\LDËZ¯KÑp–Kk饸ÈqÁ,^#L뾌²Lº c*]#¢êª˜º*¿nÞ>zc 1Fî¿lzäqÙñ£4>)yüœ¼&•J)TŠw­-U‘a»v™ýI†FÝáq—ïO"‹³¥,ÜRk½àÖí0Õ= Kª Œ F+.¿sÁØ­€;`'éضð-Û°jeáH2MzfmP1*ìGcQÖúÿðѱÍÔA~˜Ú×’êÊ]T€$ӌůÔü.|ß¹¦eS'¶W¿ü0ñaÒß²£C?sü䱇ÇcnémÖ]¬»5H¦CŽü>_ÖEÎ@Rÿ•šXße˜¼·ƒÏ*aƒÁ3[ÂNlÃKþ‚X¿ØoßfÂÞ˜è®IŸÒ* Œ©´E«“R@ HN(@oL`hÜgÜZȆzcâ~¢<ÜÃq¢Ø=Ęx5";ü‘¢#%° ycbNHGñþkÒb–’Nç·Ä˜˜swdÌ?‘ÝšÏèzKâÒÎE¾°c'Î¥¿(^*ÄZa?¯æJÝ*oL¼#I¦{¬sü§1ÇS—]~óˆo|øª ¯3âslúŸ7ÃÄ•-t¼sFˆÁ#W°f ô¬ ;QÅ»qbLYì®u|ÖPÏÄê¸VJ5«¶ÌW}ýPqþ‚Ït)ˆÑSC®TÖy¶4dX][(hÆäÕ£Õ`,0¦¿Ù'=ALŨWú©‰T6ª§”¾ïÆ;&D`Œ³%oÈÓkŒñ<¦ _àš[+„1u£u,Â=…1%—’‡1ùÍW4ùŽ”<8 Œ™º$éí–äÅ ‹kÀtÈÒÆ…ÂYz3z•äIJŒ¼˜ZJ/YS“eÒMSÚå±8 c*NY)§ )ÐsÓE—ßþœ= |‹éÉtßHu¿ :UïÄ„“ÂéDÉq§”Îq½ëZ)˜¹OÕª#®ÌÄRxì b©ZŠ„û.—² ž»xL–UWÚy&¿ ºäÙì|>ô% Ëõ˜2œ"ÉôÔÓk][A'µ0Ųb˜jup±ðI¦ƒ§/zÙ<“E­ÒÁÊÚ%¾•°b"lΓûC޵SÛÏœçìgnäb±äUnC d `âJ°ùH;¼%í=ØÄû’U¬œ0KâßÝ;·f‡`]4á/·™, ±œ c*g¹ê©¤€R  ¸Û‚‚Ê-åà (‡OØŽ\µ$<\?µ H¦Ñ3jL(Œ9î/?°0ОËY–…ašºzÉ—ïýrH÷ÛÌ*=0aƒ ذí K¿²í®I¦×&ì®U+kFãj…VIZÿ™è¨>bJ­»ìÓ™Îä¥~Š_Ç‚Ôqtɵ¾¶ cú~J陲äc³O]»zL€‚„M¬þM³¥ûk}-5Zú!j-ºÖ×/ý®k˜úù6é‰Ó…1%30¦ºÍ@+—ôYÔ2Ý3\ŠSÀ4t)â ®åÓsY&Ý„1õDâ‡ì˜˜:&µnÔYzcºðò["`ÃŒv\x™‡1U¨£Düˆ ¹BÉóÊ”œ!t>©B)͉¬ÉâWÉq­DKÁ‘Fp¥xb)#´”7gKu{`YzTM`LF,Ù XfÕ¢‘Ë–èa›ëö²|H2=1o Aõ-–ÕÔEXSh@2 øÚÁSmªL®U:`±éXr¦’K+ºvj÷gî:]cpÉB‹¬Ì› ™þÎ÷k<á¥Ö·æ&c•À-!¨ï8 ¡âàu N˜Ì÷ý6á_PM<ÛîÎúfQáRaL…,6eZ H) J¢@ÓSIž¿8A’éžG¦;þz«~¬JÕ•u†iËÎ÷/Ÿ}ýj㯭L3+ì<ðÌä:èÅx0‹îâH“S`LÝ5@ŽªWÚZ»kŒeÕ5´Æ›Xkí«Ñ@`¶§Ù•ŸivÔ´ÅVª¶Óh¨¸Ž «kµÚ„1yFõ˜e½A5xt²‡1Å.ôÍdcÏn]O6ª‡ÂÖ†)Hö´èQkrKù±™ËS¡›Ù6f^S²¸Ä˜¼ö-þíæ½ÑpÀ£“×iÍÒAÛÊRÉð<`2aéº\ª¦ç0äx©²Lº cjãÏY—îA„1õ`¡÷Æ#÷ÆtÁe7§ðFøöïx.²¤”ÑrüWË·§ÃIÖAñÆTqî”"ƒ«P)žUJ —ˆ+ÅKþ¢4gÕuuåPöÁyÊ‘YzTÍaL°a]²•v\‹ÌXä™`ÀâÓ¨’Lç®!©ÆåƒtÂZA¨Xr½Ñ’ë)=H2M^¸É]VkViwemÿ&Ü?düœ±avêèÏœßâ0üÆ dTi•C’L$†mwl}kŽa‚Jd•°ðp¨A€™ð/ü3WÕDOKøÛø {Â)ØC§MF8•Cp=EŒ˜T-¤€R@ tO¸/ y0Šîé^îtçH2Ýýðt¯÷ž`B1WF† ±ähÏÁš4óÀÄ -?øŠëXhó¡-Ȣ˕µ„€1ÅØ]+kºÝ5«¡5uågŠ—zgñgWʼò3#,ên§b;Í…¿¥t«iû0¦«{¥Œž´ÓüI&÷–~½u¿1Ð’_úþ9K¡(*}aLemûû\˜’$ÆnßjçqZ¹$G€Õ&.ŽU ÖI6ê°6–e|ÕAtÉ}ïd™tÆÔß߬Η®˜TJª@/bL)ã" §1+éö*æøìQFü(i­Ou 'Å#JŽ;¥øÀÛã6;àZª«CjÇZIQá\Éqt\ b)vŸ¥GÕÆËS®%ìa¤9þÅËò°Ýœ‹$Óø9/Íx³ª+Å0•´ÝÖc%*’éK”n]„1¦¨”Q) ¤€R û d6jªkBq—»4Ê0uÿ‘ò—`LQ»«ke Û]@9)ÆUÇ‹Ršq5–Sñv&ÚTc\ì$¹¨úÚ)´‹úöaL!«»[ú£žZ„iþº Z´&D¬ëÕi~ZÔÓÄǃK³¥WÝ,•Y‹ÚÉ…1å¯íÌGŽ„1ÕØª’M:³‡hßF=¹(óDa§€ñaLS}ÂÑ&¤nQÉ2é&Œ)¿|å¢, c*KIê9B ôÆtÞonŠC‹‚a0¾ýv#&=JÀlÈ”eì X[Oªƒ(¥ƒJ‰®• µB¨!,©Ñƒ³ô¨r‹1áÇL’é±™«£1þÎþõG{âº-捻-;ßÿÓŸÿ¬fQ ”LL_<èà‰ó7àwjZ⇩dréqú©€G2~l`BÅÃÔOauz}„1Õ×HGH) ¤€R ªI¦;FNå$Ÿ;ZÃÔ’ŠŒ)³ÝÕ·²f°µ&ÂIÙüÓ{¿#áÀR\Ô;¦ÔÊdp¨m˜âŒêUûCOz#³·¬ôë,ýM,ýXK=Rú˜ZÒÜ•ð"˜êaL)³ŠhÓо=ôäÂèDagOÙÖCl«qârÄ-…,ðY&Ý„1•°Ñ#uQaL]_·n§=‡1û››RÀø–bê¤>o)SœûÙº;·TGÑq±Þâ#mû!üTñ É ê4âT©ŒcìF¥,ÇgéQåc2’iìŒÜçÃÔÎfS×.€ ™üê·Á‘¸¿ 1L(¹bf$j—[ÙÄ0³$‹–kaLE+1åW H) ¤€èº$™n1E S;ÊS¿ì®ZëWkÜê$TËŒ+%™FÛ…1¥ÕG>±Óü)N³1³×/ýÇZ=‚+%•¾0¦v´~e¸¦0¦zSúŒ!Ú7´rÁ1õ' FlÉ–ÄÙÀšqù…–¢­M–I7aLeh7ô ùQ@S~ÊB9i©½‡1]zS xtî¥7!:Ll`l€G5ìQÂR·Ï»Bœ”Æ'9}”Üx†Ì åÿ˜,=ªœcLQ’I SKI]¬¨ „H&1LE-È‚äÛ%™Ä0¤ÐŠŸMaLÅ/C=R@ H)ÐyB$“ü0µ°<Œ)«ÝÕ³²6mk7®Ö.ûLBU  ®U†Ö6aL Fõ`¹ïȉ ÿêoö©XÝ»Qúþ¢_UaL-lôJu)aL©“Ó|…\­9qAàÿ¯QÏI¸RÄyd«Þí¾N–I7aL¥j@ô0]W@S׋@h=‡1 ¾ôÆÒß"4LiäRGÑíÈ€Ù<'9>“â<'œ$/J Ü›¥G•ŒÉ%™Ä0µ§©ÔU ©€‘Lb˜ Y~EË4I&1LE+·"çWS‘KOy—R@ H) º¨€‘Lb˜Z[ À˜’ì®´µž“ÝîšÉÄê8R¢eÕ‡TĩԟnÆtø±IVw”þð‰ þê¯÷Éduo®ôE)e3ª cjm»Wž« cJǘþzŸhûæ6hhßÐÊÕ4qqMYbd•ÚX·u›ñœeÒMSyZ=IÆ”‡RPÚ @ÏaLû|âÿùägLJûþÝ~ÿŸÿëÿN9 ÓWŸ>ã¥B(ð?ÿé³ÿûÿþŸÒ³ú_þë9æ©u[Þµ´iû{mø1ö÷’}K—í¿ÿþG{¢›Õèö–ïÿéÏîïÍt¾(ˆãGÄ èšß\šþ»Øö†~)Ñ|góÆÛ‹ú6ôþaéõmÇ›äû9”»‚( Œ© ¥lJ) ¤€9T€$Ó7>|Õ†×Szï0¡üþÃr˜ÿ|f S+í®2®¶Mÿðÿcº-æñ›n¿/ôÓH¯u÷ߺQý~Ò·Á&›åÃ_µíñ a²n_&ÿëûË¿ßïS®_ññ?*ý÷¯–0Ÿínër%Œ)cªÛ|ý§¿ø?þáŸ>ßÄõ^köÿëÓ$½ƒ¤s¬Êÿ¤[ë~cº’h§˜ک®®ÝEz cÚ¾}ûìÚð”Pºýž‘ÑÚSb²”xhä–OŒ íÈúa§ïyg{ºN S\ݺ ¬½ñÿyݤ‡R~b˜ºP.%½åš]÷_õÔ~ö¥Ù)õM SI ¿%Œ©ªëžR@ H) ¤@iX¾iäÓ«ÇŠajaö‚ÝuÄè ¿¹ëÄ¢›I›°…â—’^U>øàƒÕ}Ìø)峺£ôQ ]²”þÒÕ›…1µ°m,Æ¥„1¥–Ó‚ Ü&nâSÓòپͽý¤<´Qu›š1geÒ­?aå²ÇÆÔã ¼ß[S´Óý%è[)«@N1¦w¶ï9ý/þøÈÙ¨ç±Ù–¦ò¶äz²düiþÝsLjÍÄ0©ö´P`Lwõíµ~ל¤ú&†©…jëR{„1©H) ¤€R  Œ]½ÿ˜>SI’ E~˜ú¡npjù슓WÜyÍôÿÑ·¾¯|V÷‰­I?®º7Êí(w”>ê@nsؾŒÉS£õ¿xÇ cj¤ÌÞxç÷íû¹õçÊ¿ÿ·O"õç ]<7§“nT +º¦€0¦®I¯·WaLÕHa]|CëÖÅR §=ªÑg×ðH¦7·GI&1LímJuõÜ*°yùžëÚ³jòîßmgÄ0å¶Ü š±Wß™üÄÚƒví^[ßÄ0´Xó›maLù-åL H) ¤€È»›Þz+6¼ùx¶P,¹V•_±Ì}us»öÕ]·Ì> ˈ…?«{pùh´V”cB¹£ôQPÊW¾éO$Œ©Ñú_¼ã…15RfùʶÍåMýl/l±Êé¤[#CÇJ®) Œ©kÒëÆíU@“0&)аyìQù®˜ØOÝ3ú¬?~ôg—dÃÔÞvTW/ˆ!²D SAÊ­¨Ù Õ71LE-È<ç[SžKGy“R@ H) ò­\1cÂÆŸþüg—·ÃÔ¢+â4jJžéЉ©25Z1J†1ÑS:dÆÔhý/Þñ˜)³|bLðÃÄé¡‚:dÊã¤[#µBÇJn* Œ©›êëÞmT@SÃKÉFàzœ&ÈcŠ®˜˜À3½³ÝH&1LmlAué|(°{ç¶ ƒ ½ýÊÚPŽæ^6hkßlÛid‰¦|]±s1dÞô°ú&†©Ø%ÛÜ cÊmÑ(cR@ H) ¤@¾0WL$™Ö¿ñ°‘Lb˜Z[tMØÜr{йb"ÈÒƒ™­%Ø芉©2 cj´þïxaL”Y1&sÅT\‡Lyœtk¤VèX)ÐM„1uS}Ý» ô:Æ„WcúðxéÚ]«6¾Û!´2ÖrPÜ(ôôËbÞÆe—v]1U2á2 ™Ä05!§N)œ/=5bÁ̓c³ ¶ “ûÈ1L…+âf S]Œ Ùþ÷þ(†)‡ÅW’, c*IAê1¤€R@ HN+`®˜ˆ1xþcýé’L¿ÿð£Nç¦Ô÷+“ÝÕuÅT2‡L«_y{ñ‹o¤ÛB›˜]ÆX8ýšYl°-7ü6wA×SÉ2­Ýü΂Õ;ÓeÙ°õ½?üñO¥n«ôp{öcj¤¼»ûÃô_M–_VsÍQÒYæŠ)Ÿ™ž_ÿ&RÁ&Ý©:V tYaL].ݾ] ô:ÆÔ.]u])ÐI\WLŽC¦NfA÷’ÝR Ó#÷®„—çN˜:x Ò²{79ø ƒ—&î‡s&æpÏÎÕ}Ýʹî[\FR@ ôˆ˜z¤ {ï1…1õ^™ë‰K¦@Ô“2•¬ˆõ8õ Ë%|€%mí› J {à tË„st×ÄÃð-3ò©Þåõ½+D  öº|@¥Ù›fóP°M œpLß¶>&9dR5j½˜Z¯©®(¤€R@ ”\XWLrÈTòRï÷ãźbbµ‘C¦~«[€ D]1 ,@±)‹* Œ©QÅòs|¬+&ÎÉ!S~ŠI9‘mU@S[åÕÅ»§€0¦îi¯;Kþ+ðá{n9xÏ yéê/ìùù^{.úDð/ö`ø¡(»æQ –À*aÁ&7f¸%üK/Mø–„“qNeIÏ×b€+KrÑ%z`ÂN|‹mFšÃ_&O-΄.'„1©H) ¤€R AžÝ|Ökbz`ù_Þ»ì/ìßkðb:¼WxõíÉVOF­ø–ñ/~Áöìþp{¯ѓωòµ²¦/·Ñ«þÁö nô¤*zè2* Œ©¸¥ŠUîœB:ë/½dÿâ+}¤€è„1õB)÷ä3 cêÉb×C—R]›<Ä~⥥|8=”HR€Aâð­ùd†Šã_| oL<Çà/cÏáHûJ Kì LÂñ†.a˜xÒK†:ah§ k¼°†úHV* Œ©•jêZR@ H) ¤@Ï)aÔÊOôÜcëû§@ßÖK²¼û‡Mý»ŒÎ.¤[ßÒ_³ëþBæ^™–é c*G !À¤½¦€0¦^+ñžy^aL=SÔzÐÒ+ Œ©ôE¬ŒS˜ài ß`Ü\.LÂßÝ;·câ]1ZbŒ9R  àZ ÃÆÙéØÀ„4xÚ`D‘Ã~lc'ö4q"ê( ŒIUD H) ¤€ýP@S?ÄëÝS…1õnÙïÙ#Œ©—K¿üÏ.Œ©e,Œ©娧* Œ©QÅt|AÆT‚R6¥@]„1Õ•HH) ¤€(˜JS”z) ¤€R  cê†ê…¿§0¦Âa?@S?ÄÓ©¹W@Sî‹(S…1e’IIÒ) Œ©tEª¢˜T¤@YÆT–’ÔsH) ¤€¨¯€0¦úé) ¤€R@ $* ŒI•£ „15!ZiNÆTš¢ÔƒÄ( Œ©ÕBS9ÊQO!U@S£Šéø‚( Œ© ¥lJº cª+‘R@ H)P„1•¦(õ R@ H) ¤@7ÆÔ Õ OaL…/Â~<€0¦~ˆ§Ss¯€0¦ÜQ¦ cÊ$“’¥S@SéŠTD„1©&H²( Œ©,%©çh¥»ßÚƒ™þ···òšº–HP`÷‡ÛaÖüýGoI!)Ð „1uBeÝC H) ¤€(­˜J[´í|0aLíT7ïׯ”÷Rþú£€0¦þ¨—Ÿs…1å§,”)ÐI„1uRmÝ«ƒ cê Øº•h«˜Ú*¯.^P4Í_Ђ+f¶×ìºÿ®¾½`Ù,fö•ë¢) ö­h%¦üJ) ¤€¹R@S®Š£(™ÆT”’jG>…1µCU]3/ cÊKIô/˜ú§ŸÎ–EU@SQKNù®£€0&U)P„1•¥$õ­T@Óü­TSת£€0&U‘Ž* ö­£rëfR@ H) ¤@ÙÆT¶íÈócêˆÌ9½‰0¦œŒ²Õ„1µDÆ®_DS׋@]Q@SWd×MÛ¯€0¦ök¬;HÎ( Œ©3:ë.ÅR@ÓüÅ*¯‚çVSÁ °hÙWûV´S~¥€R@ H\) Œ)WÅQ”Ìc*JIµ#Ÿëßx˜1ðoÇÅuM)Ðe„1u¹ZtûË÷ß’I) zMaL½Vâ=ó¼Â˜z¦¨õ ¥W@Sé‹XØ„šæoB4Ò¬˜šUNç5¥€Ú·¦dÓIR@ H) ¤€ ˜TšP@S¢•æ”Ñ«þ`¦Ò<‘D TÆT‚ÚðÎö=@n9¸¢GR 1„15¦—Ž.Œ˜ STʨ¨£€0&U)U@ÓüªT@SÅÖ­öìQû¦Z ¤€R@ H~(0uýQ£V~¢Щ½¨€0¦^,õÊ3£ÅÿâzY={™ÆT‚ÒåôŠR) zMaL½Vâ=ó¼Â˜z¦¨õ ¥W¸ýõ©ŸZúrÖ6¦€¦ùÓKG÷KaLý’O'7ª€Ú·FÓñR@ H) ¤€p˜óòɘT#U`í®ûáÇk÷·7z¢Ž/+_»yí®Jð z)£ÀªÉÞÌÂæå§À pzE©½¦€0¦^+ñžy^aL=SÔzP) ¤@* iþ,ôî=²0¦îiß“wVûÖ“Å®‡–R@ H) Z¥€0¦V)©ëH) ¤€R@ H)Ð5„1uMzݸ½ cj¯¾ººh­»wn›0hÒÛ¯¬ ]ù¥§F,¸ypko§«IÂ+ iþÂa‘@S‘J«yUûV‚BÔ#H) ¤€ÝS@S÷´/Æ×îZ;aÍ„bäU¹lµØêKêzR  L<3 «F 冓¹È¢2QOÌ¡°P”*ÄzRé{)Ð3 cꙢîµÆÔk%®ç-¶)¬ÒÜËáÛb?žr/Z®€¦ù[.©.˜¬€0&ÕŽŽ* ö­£rëfR@ H) ¤@ÙÆT¶mõó ¸o@ß¶¾V_U×+€(waL('e±qRX%L+`r¡ñKêŒ.(†éÃÝïEo¬BìBaè–R ' cÊIA(­V@S«Õõ¤@Û@Oô‘û¡ŸŠ xcqd ºhŠîyî)È©m%£ çXMóç¸pÊ—5aLå+Ó\?‘Ú·\2'¤€R@ ä]aLy/¡®æoЄAûݺYl™7ÛCñ|°€Ð0|‹mQ/]-®VÞ^¸@°!¡¬Q Æ6ŠEŒ¯p'üeqó+$ÔVæ@×’íQ³˜>Àägð—SŒù?tÑÚ¯™…ö”FóWE‘Ýõ™½èŠ)©—Ý;„…‹âÃa6a¤PÍë®3¥@ÎÆ”óRöšU@S³Êé<)Ð 0ØØ¹Ú[ fè}¢cŠ=„à¯uOÑ‹ÅØckßlâùHØÀ’‹näZ÷”ÝS@ÓüÝÓ¾ï,Œ© ½›¬ö­›êëÞR@ H) ¤@áÆTø"lçl{oðÜÌ x&P,ïýá=À+柉ßbÁ&ÐË2dÈý*ŸþgíZ$(ßOŠO±žË ¥ V‰™G5àJ;ñ×JܧŒiE?ÀÿNŸŒéý@ìë“K³ì‚µýHc•lÁ30Æ’ã\fHº`Çhf¡íEÒø –ἤB$¯†P œ0²‰$Eóh\o! ¢€0¦‚”²Ù¨˜ULÇKn*À®'»¡H$ë1®À6»§ lŽ—ì[€~*(}¤@) iþ*ìî<êî·o}w6ÓÂ-çßշ׊7Ù|Ûlé®eU`÷[{Ь1ͼiƨãίîÙµ©¬Ï­ç’R@ H) ¤@ËÆÔrIËtAƒT\>‰è>³7Í&¹ÂÀsL 9d¹~Å:t(€2 hÏRDŒÉˆ%Û`Yó¡@/¡zÐ Ü5ÑSWCñ1ܳmÛ6ü[Vˆ •\S®~׆³`©³AKdb8éDtË„frU|Ì æƒ¸¦=©±…ˆI".hGirV sF+»¶Hè¼ÆFM.Ìó+£R  „15!šNiD€J¿[ö —¢ û…15¢¥ŽÍ À‡ìü1^ŠM¯.Ïp "¤€R@ H)à) ŒIõ E¸ÛÀ„€ªZ†ùgÂ6¾5~…H<>ã'„1õËÂs DÿLüGòß ¼Ø@îžÙ³½ŒáxB0ø‹m Î º¾eûy¯Áƒ#?ØÀìʼ¾rïèn‡.‹¼ñ^6£,y8ÌuÄeè ×uËD]F°Y¨ÁŒùw1&œQ^ذÂ1ÂsññMC^Ùö° ¬Ä­ °Ç ÑêkEôú–[Üwä½Pô¸¸•u´¾¹¼·CÙÆby¬B˜2ÖŠÎFV‰Þz0YÀeÏØ0ÿ=øì vâHÒ0šYèLÑd¿ Y´ôBÄÕPp(>zÛb4Naæ(û½t¤…Q@SaŠJmLaL饣¥@0VÉVN˜kPŒ.Ðeg”94—¡ì›ÕÅüëÖR  cê‚è=wËg7Ÿ‹1aÏi¡î€3|'LÑtÇQ¸¹n!¤€R@ HÒ( Œ©4EÙŽ¡›%\àZ° µ ºúdâÝA;MX`FYòàrôTD¤‰¬È#ZHÑiÓ{ï½Gd‡‘J!ùPÉHìáÁø‹cð/X"lã\|H5…®ïfW#=ÃÓ±a>¢ìØÆ‡Ã;F/KR‡÷-ÆdÍàq”ˆ¤š§Éâ¡tÑ„¢'¸†¿ 9âÂ)2²è±A‚Í ‹z’ "»†Ã¬hH± ¬ÄYjø—µg¹erÄñÑë[é³¢°p¢}DEë.ÅÌà‚±—µ13˜²49ÆX%w³ X29wú€ûñW3 )ìwá¤OR!â+À¥ì¤—øÿb' T«Ü³K­#¥@‘ÆT¤ÒR^P@SbéP)Ð]È*!ôÆ—K膮„HÜOÊGÒ,÷(¢\w‹Owº£{oÝ5Ö!“\1õV%èäÓ&9d’+¦N–‚î%¤€R@ _aLÅ/Ã6>À²)æ0øìÚbØ 6p’ñ.ód)ó´ä²M¤”ð—°¯l’°séu‰¤ˆ‹1qO4 [ôú–as… òv¼ ý*…ãÁ¸;Ý….ëâ5@^Š…1Ñ&ðItÄ…Ü/±J`5wÿmècä5méE‰EF/VÐ–Žšè+Z±“+´eÞ¢×·<[=‰^0Zß,È$¶£—ukqº†ÄÑÁíS€¬®Ož ó˜kà”6ð-¾â$þ2ÒœfÚWÍ]™³?é…ˆR¶"”µ;aÄRÖG H* Œ©„…ªGòƤz ¤€åU@SyË6WOuÈ$WL¹* ²e&êI®˜ÊVÆz) ¤€R í c‚SÕ¶ßF7q Ðÿ ¿èã¢'æ¢ p’‰^‘Ì÷öðDóäÔÆÄë[î\ŒÉ½ ë{ ó0sÃÃ̸.ëÒ0Ø.ÆÔ ëú(²ˆr.„m:å'DÐ-䋚71ÙõÝŠ„íXŒ)Tßp={±ÒF³íbL¬ T·R@ H)ÐÓ cêéâ/óÃk¸^æÒÕ³I) z]aL½^:ôü!‡LrÅÔ!Ý{ö6Q‡LrÅÔ³•A.¤€R@ 4«€0¦f•Óy-PÀŘp9PJtkd®•EŽ ïǯ,|÷0ê9eq $^-t}÷I’0&ܾÂé=ˆ.yŒ¾ ]ÖÉèi-¬D—p1&(I@Í-,F‘+F„ˆtQ´ \êˆ×ŒrH,,œ½¾)šâ)ZßpÑ%ÖÌèeC1…1•¨æêQ¤€R ¯ cÊkÉ(_ýT@S?ÔéR@ H)c„1å¸pJ–5×!“\1•¬póø8®C&¹bÊc )OR@ H) ¤@ÞÆ”÷*uþ‚Ø#2xœa(€NÈàÒBøËãIq'90L8—aÈx þ;‚¼6ð1÷ú–c•ìtRS8€ÐoÊgøXc/K¦Š¹ÆªË.Æ„¯PŽÔ™…ee’5ÙIªE ÂJ“á۬ȬPXj¬¡ë[®\ŒÉª%«A´¾±½â¢—u÷c*uK¦‡“R@ H|( Œ)å \´\aL-—T”]Ràý·ö<ñ›=€6ô‘RÀƤÊÐ)Ì!“\1uJòÞ¾ëI®˜z».è饀R@ HæÆÔœn=~Ö¶wg÷mûÍ>z«­:¸±ÞÚq£6]¿M—m‡Í]sÆÆã´f©9étV€a3 »6 «Êb’œ’H5D ô ˜z°Ð{ã‘…1õF9ë){A 3ð®šxi/<«žQ dU@SV¥t\  C&™5[ ¥.‘E:d’+¦,Zé) ¤€R@ DƤJÑ„}[/Å ïÝ?ljâ\RtF­üÄk*úS(ÿR ^gî÷, Z ]èúÁé!¥>R@ ôš˜z­Ä{æy…1õLQëAK¯€0¦Ò±° „15!šNiV8dºù_âo³ÐyR èIËìÑLÇJ) ¤€RÀƤÊЄ˜š­4§c*MQêAbÆT‚j!Œ©…¨GÍ) Œ©9ÝtVîè-Œé¦›nÚK)Рÿå¿þ·M›6åþ·¼gÏ;ÛÏú§½–ß~F²ª,JŽ) Œ©cRëF{ö¼õÖ[ÇŸôü•R  |ðÁÇÿ¯Åè¢t@ÝB H) ¤€ * Œ©AÁt¸§ÀS‹ÏûÊw÷zý5’£8þ¬ÿûò{?Ûƒ®GîÞšyïÉÿc¯·–<Ñ [Ögüൗ=3ÑØëÊú€z.) ƤÊQRz c:ùä“oºí®­»Þ§ïoñÒîo»ëØãNÂÆf¤×«éÕ×w{é5¤ÅI/ïøw7mÚþž¥ÛßÛ¸-H¶½ç§w7l}w½“Ömy·’ÞyiË;/mÒÚÍïxéÕwÖéí5¯¾ý"Ò+AZýÊÛ^zÙK/¼üV6½µÊI+7¾µrã›L+6éù oiýÏ9iùº7,-[·kÙKAZúÒ./­õR_vö­Ù¹¤’¯Ù¹øÅ -zqç¢_÷Òê×:iÁ ¯ûé5¤g‘Vé™U¯yi¥—æ¯Ü¤;žvÒ¼;æ=´i.ÓsÛç8iöòm–f-ß6kYf.Ûæ¥¥[‘fXêÛ:½š¶Œ˜¸à¯þzŸiK¶ MeZì¥)^ÚŒ4yÑæO~úÀÙ³gç¿@õ|ñÏð¥åË—ç?·Ê¡è˜:$´nã1Lh{ÍЃ:H$“*D»Ãôõozñe×£Ö‰dj·Úº¾R@ H)PJ„1•²XÛúPèx£ûNøQG…y[ïÕ­‹¿çbï¾víÚ¾¾¾ne¬ë÷½ôÒK|ÊY_ûæ¡“'Oîzfú™%®Ršøª—ËºŸòñôªEë«_‘E«ˆ%ˆ<ûf¢Ãd&*hñ)ÛR ¿ cꯂ:?§ ôÆP ”Rlºtã­w}︓ `r饀©–^ɘ* S"À´Õ&l´aÚ†)À˜<†©‚1ec˜Þ3L>ÆTa˜°Qe˜3ÕbLÃTƒ1 “‡1y Sc &cª2L+ë3L`LÃäbLôuZ_cŠe˜ „1aºìš¡ÑæömøÌçE2å´ÁU¶º €0¦.ˆÞ‹·ô->F?1íðÃæˆdêÅJÐÁg¦qêŽûE}{rö2¼÷E2uP~ÝJ H) ¤€(‰˜JRz Ÿa0iÎrt‡þntÉH¦mÛ¶1Zñ?QQ 4pàÀÁƒï·ß~…XíÙÚz†é”3ÎÇzà…«¶ô/ý%™bnm†S®> E‰P”±‡ 0Å6’˜¶ŽåV7ꀰh}N­ÝÎ[ÈLÔNuum)P„1¡””Ç&è=ŒéÖ»\7K!béc¢×¥ã%Ï S*½’)‹&xcrœ0½ã„)ꇩ℠ޘ2ùaê'ÃTqÅøaê'ôš~˜ZéŠÉŘsÅ´´ÆS}ŒiQ1¼1aºüÚ¡KÃ’mΑLM4†:¥¤ c*iÁæê±<‹Ï<úÄ\k‡GÉ”«"*Uf<ãÔ·»ãþ1Vßž˜%’©TE¬‡‘R@ H) :£€0¦Îè\Ž»€a oòÜçØ ‡ÉôÖr‘L@[ÈÖÄbLpÞ¢…E9aÂÛ.GáÖ} 0L§žqþó»ë‚•[ûI2‘"êú'c:t(&æ ÔZw‰«®KÔ E«¥,3Q Q ú«€0¦þ*¨ósª@ÏaL7Ür'%7Yœ¸ëo¹SðoZbü8×ñR€.ÅÆ‹†«ë)5\À0ùäV[ 9l¤Ç’kÔSó S+ÂÉ5êŠiùöTŒ©Ž+&’cP¹WLù*G† ~¶l:~³f-^/ŸL9mt•­+ Œ©Ã‚÷Þí‹Ï“s­†EíðCÏ–O¦Þ«mb§¾ñ­Ã†Ý?&Tß&ÎÉÔvñu) ¤€R d c*Y¶ïqÈ0M™ûÜóë=ãÛ2c ïÖ{š÷É:Œx |°Ì$Â6üeoA'ôbcÕî ã9í®óŸÛòÕo2iÒ¤&Í´…˜ŒÚF8,¥ Ý¯Há«BÜãV*ì!œD<äáB{¬"1vAîQMM<©Nɳµ­7eÑÊsa%å-j&¢¿@6S2±L•g)Ф˜šN§å]žÃ˜®»ùÎ;%÷_|{Ì÷Oä/Bœ¥mïm¬¤ Û€+1½Kn ¸’›Ü°qièR„^ Ln¹4LÀ´î—*˜ª“?½š0Uœ0a0Ä’[» ‹KÐãñÓNÎ--^³sñ‹AZôâë^Zí¥…Nj,–\£~˜žK÷ômæRÏÓ K!†©Ïc˜j0¦Å[¦.Þ2ÅK›½Ta˜ˆ1ó”[¦`àòðËö¦ën÷JܦÏKŠ×OEM_´îÓŸûÒ¢%KÊ-Œ¡eUI«¬0BîÌ¢ ¼9xFNh¬Éø±åDYŽ…{Ç£ÙB%n¸ƒù,´cg®{³¥l ®ƒû¥€0¦~ɧ“Ó ÅgìSóB6Mÿí¹/J¼‡›uà—¾ÒÉd†ãÎC´©¯»Ä­b¡í×Ì?>IÍ{Cšpy´‹[^j4NÝùÀX¼÷CKÙIC}{|úR¼÷ׯo’dBþ;S ´ÑãÅj3.ëQ¤”KR}NéK´»Ð[^‹tA) ¤€RÀU@“êC]* Óó)ƒ>LzD£$ˆ³aýaP&f†Úk¯½6…¸dØx&‹þ†‘#¶éN‰“Ñ'ØÏíƒcÈ»ØÄQO4¨ôð`ÊP˜ºÒ•à0L§y~Åî†<`w}zùæ¯|ãqãŸhôaMs·Ð©­•]¨ ‰£ñFt§äzÌ≡€€(;s×äÖlÂ~#ÕpM‚tø`C S£ÅZ¬ãÛgÑ2çp¡ IÛ ìVÓ ÍæÜoæB6yšnh]W C«i®™ÓC©ƒfÉ~š‰lf$ÿ‚§˜õB¿J{(Ò½î4“}åÎvY¥µæ±î„Qh‚©¡f!£•5ãa ݺ­kj¬­òV/.Œ©CBë6V ç0¦ko¾3N"¥tíMÆ„ ‡UªC,‘^ qK £Kµî—2ÒK«¢ôRƒ“OÙï ;aª˜‚NOÀ”î„éõ/¼†ô,Òª =L¾&¤ù+wiÅŽ§4oÅŽyÏ#mGšËôœ—æXꧦ ÃŒi8ƒÊ%3L±(·NÿR#÷«0Lo¥XR@•M_øÒ§?÷ņH&w}o+ûC£‘6iÂUhè#"cEg'™êÎÁ[žÍ^c{Ðé´El0-a»¹É]æOA»@öÌ·IÏž»¬0¦ž+ò=°Y|̦r‰›&°´ÃÛÙÉDûNkñGZ±c5Š6õI¿nVõ‰ÞêÛàͦ>É>›]¼nhé E£Õ9Ý2NE]0›C}7­ïSŸûb$ƒ4 ìÆ>rl}cô ¾aqåjy"¥ª'•ëCôÛ¤¾D» ½åµH”R@ H) B <»ù¬»úzË.ª:ÐÃôôóî Ïõ¿ë úüõœ7Þõp£$“‹1‘G1‰]ed5 ÆÄn0¶’‰6×X`ّ͋Ù&[#ÃØL™´Ù4Y¸š;²¡5¸œ»­™½ ¸º7:7«ºÀñô}ÖTÚûÂmYà¡,Ù^ŸÇ„žÑjЉÃÇwÛ^Ûæ¹ö aL¡+à")š„²áŠSÿj´vÓ8u×cclèWáÕúöÂkc§6C2qòõ\×­o¡Š‘^ßøÔ ÃDà‚KH+¼•Ž•µí±ë³|Y”ö[pK$TÕí^¼>k)».Vñ¬'ªc4ª²|C7mk¡7ZIt¼R@ H)Є}[/ÆÔ„n=rŠÃ0Ń,tt†‰ƒ¾†5F2¡3ɱ{Èø‹¹ˆÅìrY0&v¤í:貤‚ø–CB.W@?×dP9ëÍRÃcì+f,4{ÝÜ¿ÂÕa:Ëc˜ê.[ÂòÝÙK_ýò×óÉd%k›HÁ˜XO &ŽÄ ÌÑ=+[¬8˜_Yl¸Œ‰0œ;ÀÁ¹ýñ)R¸ï© ›E+“…¡q‹–kH‡°¬x48˜ÎhI¸ßZ0~åú·ÆWöspçÜŸIOœû°!3QR¤ŽÀ,Ù¸™Ê»+±íEbu´Ã&}\ 2Ï9³Ã`‡!ÛN’¡‰Wà·Ì›µx¬®!ÈÌY¡¹·RÙè/Ü•õ Õ4ìq5 ÕsžîN0Ùƒ„ÚR›£®,$­k ÉnfÕÐT®2½ÚC™Ô|‰G‹ʸE“dótí«Vš|R÷t÷ú®yÖ}Iõì·.Œ©âêÒÝT ç0¦kn¥”ÖNòù¤knvô±'F]+qÏK[Þ©¦Íï€U²T-Õ„Š{ÄSˆ[zñ•·k½.…Ñ¥Ré%]Š÷½”?ŽAŽÃî—‰¬rý˜úå„)[ 9—ašîÄ’›æ8aÀÄ4|‚ç)…aÊ¡7&aºÞa˜".Cµ§%šOyvmv’) cb?iÐ ‚®ú@<‘]:l`ù²=6f6ÀˆŽdqeןÅmc;…ÿX‡’¡»³¯Él®çb³ŠÎ™M퇚d7†:™Ëe|KZŸËž¢÷²«ñ”Pï¹›ÍÜ[St“ŸÇžš—fÓ¬Z´=g„h‡ï{tFC>™Ð¬Ñm‹_­y¡±2Ô ¢mÁñlޏÁØ´r Í5‡Át$ã~e­™™/Ùbóv\¨ä2.¼>ö[°´A„ÞvdñhI7#)oÍ’=¾â1Ñg´’g;ÏÖ†ÌØÛ„M7vR®¸²ü›a"t¤IJ6h}na} ŒSz SȆîv"Ú êÛ˜)KòÉÄBD¶-0AÝú­)õÍ>¡ZįP¨¿•NlyÙ«–u½‹ØŠaUÝnmÝ›b-uP¬¬',JÎôà_[Ýn7uªµ…ÞÂú£KI) ¤€) cRõHR }Óž~>´€fÕ¥îB‚còÏÃßüõÃFe÷ÉD´ÝH")Ì ¶Ù©æD£ŽqÝ YÏýU|È?áÃE€ØãÌÙaæ•y/žË›áÄ‹¸_á›FÅ‘=⩆aJˆèí.[BéÏê{¥!’‰CfÚ'Yè,…”‚渕emCiŽYl[v8†_Ù ½Õ»‹;Š1FŠµÂ½”Š2)МEëþF,Z®!æzƒ–\%m Mà Ù÷€qb_…<—©t2>KŒ™(ÃôPCf"Ú=ðâp'2’¬Ž´ïY»²Xš†íÂ.f<4CP’¡‰76pYN$рÛš!ˆÖ›2aC•ŠùqUiküØêÚ›Ô- Ø+›`²‰ÁÌtF_eœk3ÑøP4Ør#d¤BøÛÉbz =8N¡õ×gÑD¯oMy©)ß)QãÏÕÔXÆxó‡ cj^;™kzcºúÆ;jh$—LÚò¾=ú{'º|R"¨DK5n–ªÄR,´å–V».—°á–Baã¼é«DzéßK½”!~\ß/nnÝrô™l ¸ŒŸBÈE£È­¬EÎ$W"‡mǼ1ÍBªøaÊà„ik Ãä’{ÐØöž²x3}/EÓ'?}`~¼1Õ0L¡±t²%1û&Í_»ÿg3ùdâ#Ô-s»)ìŽpû[<غŒØfÒí²K„l;Ñí¥Y‡¦n§Ð½—Í,ZNxw\„'æ{ØÿCW,šUæ6¶µv{¥6ø7×ͦ³½—]GºÖŸ\¿Ê”9aLe*ÍŽ„JlÏ‘=ükÔ©e ¤)½B’&IÙH²²5]së§j]1ùS0ƒ‚úöèäÅxïgŒ.g¢ÓS·¾™aÂ*FJ}3’$ŠÖ™¤òbM ½R£%‚ Z². «±Õy^ÇìõÌ?íGn=g_"zS>TË ½éÚ¢¥€R@ HFÆÔ¨b=r| Ù!®ôÁìYô]wGV’ÉíçSXýùÌ[ûrå0L.ØÛiW¯l‘eKóW옱$ÓÁãÆ?Ѧ¼¹€–ßÂ]Ôò‹ë‚ùQ ŽE+ÎÙs-޲ùA‚xlíu DIȦ¤[H[æGÒÎç$l&J™ò'ïš6Ñ¡Š åBkdŠÕÑ,oÆÄ°|] Lh¾‰æ›ŽáœQº¡É®Àzåšzl®Š† ‰+‡À8ÞK+­~vãºY²Ë²pùD¬Ìf§â-\£¦µnõ&¥gUžâ,÷›W`%·{ET†1™z6¿2½º¿&Ì£[4Ñë»%E˪íq1&^Ü5 ™é8TôöŒško‹!Œ©½úêê]S ç0¦«n¼#ì9É ‡o1Ÿ¡”*Õ°JI¸R•X‚Ë¥—-9qâ|h)™[ŠÄŒËæxé9då&×÷’·jß’·|ßÒξµz©?ޱSãǵ`ªa˜–o¯‰"˜¶…£È-ݚ䄉ä¼ä3LpÂ`L SÞ‚Ê9 SÍXš«Áâ]2T,)Ò÷äÓ™H¦hÀöTÜž¥áAè©ØZ.wLÂéCûÊ:I˜Èò³·gýEëù¹#–P·Ïºè`Ùt¾uͼb“—–Oö5ùq!}>»VìÌYGÖZåP¯ÿº¦œÐÒ%\$t/^'”á®5ù=xcaL=Xèm{ä˜UkfÎŽ·i.ñ`Óœ·bÇÜç·ÿnt&ŸL&¸t’&ƒP#lªû¬nãÃѵÛ@Ù(—-Ûp×m÷زv?îÂ)^“ËÙº²ÁŒ¾/BcàÐ1ö€n–Œ¦²á.³äfƵ ðA(ÛsüåRþkžÿðúp öòŠ^Á^+¦OLÊ_­ª€iÆ©ôúæcsxï?2)+Édõ¦ÃïØú­Iõ óÝŠlM›©k‘¹ûæNÖ«¤òâ18˵rFK$Š1¹ÇXVùî}ùÊæïŽ= ;8tS«™-,ôVU]G H) ¤€È¢€0¦,*õÚ1Œ%Wã‡Ée˜âÒÿ® ú®½=É”sŒ‰¾1zmÆ1Ä0ùqšÞ¤±Ý\á&-[Âøkú¢—|­]$“YP[þ“ä@Þ\·üº`[´\ü¥ž…¡!‹VÈnç¬u¡ŠG÷3<2ºd(d&ʃªÎC¬™ˆ¨e³ÀÚ˜§ŒŽÒ™Èt8UDCeÈ"Gë E€å„vH.°ŒZ`\à±ÎwbÔÐäÞ®`; Ê¡aÇ Aô9Ç«¹u,Z©p–­ë³Ò$WŠ­ÉvLl=w'˜ìÈÐëÞ2ïîw­”Ì­R| ‡ŒTfà5Œ‰‹š^£yˆ-÷ú¡_ïeWŽÅ˜ÜÚ{}>‚;—×áN¯ÜNS¯”tÏ=gïaL7ÜaQÞ¢WÝpÇÀïpR(QájX%BKµÄR2´Tñ·”[ò†Oa¯KñèRÔñR8r¦1¾—¢ô¦ZßKŒZRã~é/h ý ù=¤jZ‘ÉSSR¹éN¹(ÀDLĘ’ü0å cò¦ë*±ä|¬þ·bÇÒ!Ö~ÞóÞô9¼[=1oMŸLèš®NÞˆÁP߈{ˆÛ£cŘð­uPlÛ¦ Ñ›D‹½±P¯×m‰q¢»Ì‚]F÷^œéŒÞèP?‰¾ ¢[/3úõJéź­Ö³öȼ/¨ ò]{» cêšôe»1,>0gucÉUÌÙ.KšbÓä îžG¦×.çnØ”¡©t‡|„A ¿]A†Òp 6×8ÀZ!kÉ9¼´ƒí:¡ÖÌÀ¸»-KB\bÃFÎÖî%¥í"ô‹1Åf‰·³7QôYÏÜVÝ |=áÃ76ìA\AÈê#í Iš¤d£Uõ>0N=P‰%ç[yï^-~jQ]ŸLæh™çk·n}‹VŒ”úæÊz«âß5eïôØòÂ¥`U±¯Ì¤ªü!ŒÉ5Ä >Ð0Š¿ôÉy)\™F.ÖUëKDoju¯U…®ëH) ¤€V@S‡ÏÿíÈ0MucÉE®ÀšºØ!vü¡dñ}Ë·_sûCÙ£Ëå_–É¡Ç0y> õ^0„Ô`Ãxê¢Mí#™z¤ ô˜íP lѪXˆ¿d¡ô²[´bñ[oƧ3"ãq›nÀ~‹~@Ó„Y½L“^æíúm&ÚÁBÌb&rÍ;´–cŠZ a¡×"Y¬&c ™c Mv‹Œ2i0\QŠ­T49†¬Ø²•qa›UÅtŒÉµ@í²ëbL–yºK©²›^í¦6¯-šèõ]5¨¹)µ—ºEF”Í~¶f|Ã45ÖŽ†=|MaLPY÷è‚=‡1]yýQ‰{À$ ¹Þتp’¿Óq§Tõ«*UX¥XKÅKÑ8qÞ0ÉMëƒY++nŠñº”]ªu¼äM¸:èRÕ÷R½Ô¼û%ûö<xN¼á=Ós† <0¹ÓŒ>× Ó–¤(rðÀD€‰Qä_ Œ ÓÞ˴±tˆµw\1Adã›0wÍ?æÀEK–¦´7\t…~ Wä4J˜øU¬‹#z-"÷chvà, {ÌÞ° ï‡òfÞ5Øæˆ;9Ôa.câSðúìfñôXŒ »^F’z¥ìµ»dGbÖ¿݈g±ïB«ßk·ÆÔk%Þžç5‹ šÞ‹ÛMó¥cñy1ðÛ¬Ê]¸b‚±Àk‡—m»ëáié$“5˜|‹e-*[QÖ²ñ06Ȥ? ñ`ë ˆ•µTtiÃAi¨5ã~A‰¢†LHlºÝûb½…°W^„ (ŸŽfæÍ "6Ô¶‡WæYöâ=#%ââ0f’¯ îw·M.^ŸYBþùFˆ½B’&Q©ív-©€4NÝi »…n}‹±¡W\UÖØõmù¶‡ž\„÷~Jt9CŠ]1íÕiåªoÑŠ‘Rß\YðÊæÛ™U—¯i·Î°\’Ê‹—r_µöq+¿û^æ)nþQ‚fƒ#®dõ¿«K¬E8׺4!³—kÆjIéë"R@ H) ¤@ÇÆÔ1© q#c˜Bƒ¾¤i~. ¹b²AßÕ·ÉTˆrg&†éÍ4†)Õî ‚ CþÉ 7}é vùd*¤Êj~ˆµhEVIí VåE,Z˜Íáêèì-×;‹é€6N®yŸËϸß,?<%JœÐÅN~„ídN:l&¢ÝÆLŽ”=Öêè–5ír±ìŒÅ˜lЦ•XCSCmžî´‘‹ÅbL|´¨Šæ 3BrRÉ = câ“Ù< ír|"×fvQ.û´_ ¶£F*Ͳ˜^í¦îÁ!ãXôúT‰Ù ÉŽzÒâÊ"¶Ò´"3[tèúÌåwò'Ó‹÷ÆÔ‹¥ÞÏ\c²Òl4 ­ cr½u•TÙƒo:æ„øüpÑHpßøöáD”˜žœµäª›îòG¼oÝ7jâƒ/a¶7 bÚðæ7¾uø3–`ƒS¡=iâŒ%þU&h‰1¹—9ÜR(`œ_¬&lz¢nòÐ¥ÇK‰‘ã0,?ç’«‘\÷K_ýÆ¡G}‚ë{ {ξè*×ýú¸n½tØÀšø 6’&tˆÏ¼`È?}êóAÚÿóÿ´ÿç=êxÌûÎdZºµ†^ª !WÏSÀ0™û¥þcL»v/o÷‚ S@¼9s™§Ü4ïÈ‹'#sÇ3W\ÆÕ`puñï]ä§ ïYèû ­l@½ñs^¬K2a>æ–É…¦ÍQêì~YgÎØ9Il*á+»¦ïöc×U`'ú:¡Q¯½šÝ_Ù)Øp[°hV±'öÖÑ¡—Ûíæ|¼› ´hÁÂШEË’GÍûVG÷»ƒt»B¬é>‹9<¦%f¢\9cäôuK+KÝ~vãÜ Ï¼Œé¼+F,³7ÿG§‡ÒÍDfA¹„fm\ÃK¨8Bÿº˜Xã Ùšù%dh Ù3™±èD’kGrmžföቱ•Š_ñ¾î\˜Ý ;£ÓâI¶ ›`ŠZ–B™wm§f˜µc\[nèR|ØŒ¦W{ðuÔŒc|ö¨…-jLf&M^ûMÅÚÐÜë‡r›ÃcI²$Œ©$Ù£a ãñ^pÛ+ÈQc""Í—J 0&º´IJøSÊ+}ײ•ôæÉ?ýÅß~â¿sœƒôäÌ%Ÿúì-W:ãœKŽ>ö$üEºwÔD×ÇÒ¾ŸøïŸeâpÖ¨ñ³Rœ-eá–jÑ¥_ÕE—N=ë¢ÇNOç--:åÌ‹~~æEÏ:‘ãöùÛ¿Gò‚Ç­ôÒÃO>³×^{ýìŒ g7D/™ï¥O~êów?¹­íŠÇ0];4X ä84F•ÀHã–ÇVŽ™»ñÑ9ÐIýÙ sYŽ_=s¼×O½Ç0¦ÊH£bI™Þ·uܬ՟¬ç“©­ÏUЋÓ?ª-,ÀSDWôÑJ›maL¥-Ú=->cžœm‡ÇÍÛtÐYãÇÎ݈v °’_Ý>í0¨_¶Ã´ø€â­aJ–m…Eí𰇦Ö.×χä~^¤%§³3‰Ìp5OÆkâHZ²B oÆÓsuØÖwgßÕ·ú é0¦¯ë°a÷Izï\æ{iôìõ¨o˜A‘ï}`L5õÍyïýŸLý—+?õ­ÿÏ¢+H) ¤€½ €0¦^(å,Ï0Lóžs:áÏ»~¸¥ƒÎ0Ls6`¬wã˜ô¡þ“ëçpÐwÏSkB üAß–!"™²@›Ž¹ð{.ßÏòÇÓ/†éTŸa²ÅÆ®ße˜^1þ2† ËHÀ0ýô†¹Ý;iM°ŒÄ&hÆûO>³á‹òÉÔ¦’Õe¡À3÷ï9ý/öŒ>+fJ±hafá±¹Ѹ¡’“aBõ¾rIJøá¨‡g®Ã¤Ú:aò1&—Òë˜E«ôåÜ3Ì’(AÑ`™=k=¦‡`&:ë¶ùœB‹ÐÖí|¤{›7uñ¤P9`âvsÓü w`Â|$§$ÛWQc/ÃT 2hiÆ0âXš# o5ØE“PˆÏ\ÂåÓQRDÊ‚Õ`΂ ZR ר™/|òÓu¢ËµïÑ ze œ!˜.ÒTЇ*y¶…1•¼€Ûûx´ø<úÄÜ ^ï’[÷&3g£F{ +"–ÂâãµÃ+kÛáŠMo4 ÐO]²åö‘SÚJ2¡½ ÑëíÕ+õêÀ@Ñ`6êC˜$>c›úCû”õba¦*Ãx^¬©o|ïÃï—…&»ŒuÀW _®oÎ{ß«o}^}{p¼÷ÛG2媾º¶(óR@ H) ¤@g Æô‡ÞêÌít—|*@†iÊÜçb}¾%6XŒûò\­ €µ÷,)ãµyì ‘LýhPtj!ÆTˆbÊe&añùìÃä·ÃÁ[žïqr%Æd«ÖhñÔÖûo´cB;¼hóí#ÚK2åRÚ^Ì”kŸŠ…™<†é›‡Ýqÿ˜¤úÆ÷>ŒS|ïcúdüü—ñÞ3‡„÷þN1m]¬ë¯à½ïÓÛm%™z±hõÌR@ H) ¤@a Æ”1òoaŸROS }“ç>—Ô § óÁè„ãï_ÀBÌÃjŠ1ÍãÛñ—M E\²„X] ƒäå7‹dêF=4Œ)fÃtÊç§Ø]Qú NH°Áî:áéõ"™ºQö=pOØ`¦º-X°:5F†+G.ƒE 5ö„+¦c‚§gXо!]óðsA8¹Šsq³0È¢ÕŸªÖ ™(~zfIÌÍ¡œúRÅ,¹¨%Z*o†èŒñgÜ:_f¢þ“Ε…Q@SaŠJ +€X™`àS úº>Ædœ°Æºè$“Ç…\3”î‘,¹N’ðíw¾{¼»'i{à÷NúÝCÉ*¹|)!q6à` dô—^ûµo†YOK8 Ð,!c«„„ Ɔ;ò˜“FŒ›ùµo†qSZ„8EŒgÓþŸ9£)¤ß^sÇI?>ýÁ±3-yý‹¯ÿæš;'rÖEHk!aÏß=ñþG§Qââ!¸_ºïÑi‡+½ÿql#a?ùéˆ.}ÑU Ç„¾È$ûûÐÏ6ðø[bÂ6"Ç!aã¸JKX“„\ Ð1¦áãç]3mù±?d:ä°ÝÏOU¼s þXஆœG-Ìä3Lç™Ù?X°TY³Ä!?ŠÞØfo0† ös„“›µtÌã—=¸´.Á†¢H¦îê܃÷ì§§ü±ócªwÅ3S‹7 z¨ážy™®±ì†GŸûòÐŒu¿{jÍmãVÁB诜ñø#³6X$2Y´Zehj‰™È3K®Ù †‰…H³$¦¢yδVìtÝœß<Ðvè{웉ÖolË»V•R 3 cêŒÎºK@8‹à1hРP4ú“›¥·NmÈyë/ Œé·× 9FrÿÅ·ß9úø”øÕøi‹Á!~ö%HþÆÅÆ'aÛý×@%l¯õ¦?áT ”’£x ôþ1n˜¤¾ ¥¿J/LÂNpE¿½ötJ°Ah‰Aâ;ýÄŸFhéÁ1œOK@—-a{¾ú/‡^;t¸-½gKØD 1êF‚›%ü‹á7® nÉÒ½£=Œ‰ÜÒ½LcÀ8KÀ˜0P¨tÉ•CÁ*ÁëR€1ýâ|J‰ cbW `˜îÆ´ÿçÑ:ô¨ã±7KHˆgôR<®ÏǘFLŽã§-øwÂܵ¤—†Ÿt ý-t¦± ÷K'Ÿz¼1ýãþŸûÇöH¦bL¿›ÿO±³Øy÷Ò FLÒMì?üg{¹õ>B­þp ͱôèÙë9wÎõ@ž;kYÅ£õ·>}þ] Œa ¹qY®ï³ïï?ü¨õ?9]Q t]aL]/‚bf Ôa0Š”ÖLÚ²¹×&:m†½ ˆéé¯ËüeL;ì…õäª\KgÿúÆÏü_îìûM¼2tJ 8ûÂýü—çYÿÓ}ï³£hïýKî]dï}NŸð½ÏuÀ‡_øÔð©/Õ¾÷½úæ¹`têÛ5Ã=àãÿù?ÿßbìž®‰_Û%Và¡SŠÙ6+×R@ H) Z©€0¦VªYÀktÐA÷ŒœXí„W–ºƒ>†éÁ@ÏÓó:\•œuÛüh@1Ló3œœqÉfˆ9î;ñ'¿:ç³ÿõO?ûê„w]Ù—‚-vü*}†¤Ý ŠÞÓdËH¼µ£!G5‚+Hÿê¯÷Þü¯ÿµë® ô„gýåÉßûŽ;±h z¨átá3yÑ«p3†Œiäôuæi «£yËÓçݹ€kÎ1A#‹VglPÍDf–hKÖ–fI›ºõ±•°e2øå?~ôç¾Ì•e) |„1©"”B &À-“û(u0&¸r2LÑ“ § f%sõm®W¤Ð6¾>’r€aItž„>  19ýW#aÌ3nê"øRâä‚ÄTâÄ'ÓAß<ì²kïà¤ÔÜe/!šüô*pKžk%Œ×x”Òð±3ŽÐÒõ· %ÉS°J§žuA%BKt¼äxZò÷œyâÄ´tÂɧž–üÙ¯ŸŸqÑ}£§1NÜôEÈ-ZõÄ3GnéW¾7&¿ÿêM’!Uz –€+Áy2q%DŽûþN¥'€›î‹tæC¾ÿÃSá…#:àJw>4 (Ò0ÿ/Ñ¥cpÊO?ßè¥ ·äaL·˜„Î1Ó÷N:èÒ—:ôÐ%œŽi`àx Óéç^ñÝL˜ŸCj!Æ4rÌS÷ÆÄºêÒK6‘D;¾Ø‹vLwÖ³—mC·þ~rýœÛ_…2B¡ “z׫Ãci‡µçXú€¿NÌÓ½w ÃøëÝyðžrJÔ³[ÏS]‹j8VGûæà‡iéO¯Ÿ[, ^´úéëàÂø §x¿à©;'®®iÜdÑjEhŽ–˜‰h–äôJÿ™Öu<œÂêJ€héÓC™hÁ*L‰dêñ®‘¿À c*páõzÖGŒ¸pTAåBqåê{c÷'N¸6úúú -'1&†ƒ‰M¿¹ê¶#Ž>>ô•ùLŠÝ€_%ƒ“°ÁXoœã“tä1'â_lе’Í}޲@Òw¾{"œ-q}GpKˆ<-áïAÿr(þâ†Ã¿ØŸ„ ðI€–p:âÄax¦YK62$ÜGŸ\ {f.Þˆ¿Jø _MœµÜ’yZŸ„íÛî÷ë+‡‚[¿‡}†d‡}‚-î¯|ý8[·¤ç|ŒÉ‡ rKæu T¸%ü‹á{aãàr aã|ziò°‘“±ñèÔå ”@/aÞÄ€qæxišöû‚ÇÑU)Ò½ÍÞ놽„Èq؆Ë% Kð½4nÎŒ ±têyØøÝ˜¹­Å˜ÐCŠÂLs^n×<ªë¥WÝV©uÕÊcfÆ”aÂܹ7ØX± f1/¸kÆ?¾vvM£`,]uâ2L|@‘L…nâ”ù„1©Z4«I¦Qãç…l/q¶ÃX”ù?å¶Ã0àín‡Cë2k™2LKWof#¼eçûú³?5[f9>ThÅúïþa“eqå@2Ýú»Ñéï}/¨\å½Wÿcs7žyÛü#.| ï}Ì\=j¹oœÚVµ0Æ2L¾qŠI&ªך¶eíÂOcj›¸º°R@ IaLE*­öä•$ÓÄY˃>M)C‰!¡ŠÅs†ºò5‡Ù LtÂayƒtôز¶ÆOm'Üc˜>|Õ†×Ùßö†}í)ÎÐUÑéu½«V&; $ÓÏ~q^Êø‹šjÆ_ó6ò@¹_p·WîN]ëzᢣ×.#ÊÝ;rœ¿ÞÝýaG^7)»ÏÜ_S½+áäì±k-ZOqÑÃ"y z ”i€&,ZÆ4í%0Lhèоará_¯daE«?õ¬%f"£lñ†ÂêJX)š¾îÉg_Añ!L¦€²•™¨?E¥s¥@!ÆTˆbR&ãضmbÁ` ¹bÂáõ1&z 0.Tt…+\HàÉÅÊ ÔÈá3Þ(ˆñIô¢4¾–½ÌE$“~{Í“æ­â¿‹‚äÅ€Cöàãð·4fÒt"äÑI 8BžÝ·‰ØóÀ£ÓG?µ€Qá ]Ì™>´Vé‘'ŸÅý-ÑÓ÷ÐÕ-½Ý"H-!ÁÙ’EˆûÝ#Ó¦-ÜgK=ñÌU·<øÐÄgèr ÐÒÝOEÂÆ”gד[bº{ÔTocù¶ãç3`ܤgÖ!Ñëü-Ýx÷XN¤ùi+Ð¥Ç=ýÄÓ/ÑåÒãžÆßÑS–#fÜýãžÆà‰.Y¢Ë%†óF€~º÷KŒr냓È*aÃÅ•ðoF?L< °9üú¦OŸüôðÆdNlÌßp稕Ÿà|dû0&üÜXcmŒaëÆãO¿ 7¡^š±î©¯˜³Ð‰Ï¼|ÍÃÏa,M†Éuúꎥ£ “H¦¢7qÊŒ˜T-ú¡í>=>;¶Æùa6Â~;ìÆ’«¶Ã.SaIC‘Lý(«¼ŸêÚ§B“e= ™îTßz“Õ70sæéýÑÙñÞ=kCˆ]¦³w 'ç.°s{5"™ò^{Zž?aL-—T”R@ Hb* Œ©˜åÖâ\$ÓÌe5ü¾#|ó¼‹N¸MlÄ´uÓ—l™±½ôì “H¦—_Êå cŠLvH¦ŸþâÜ èÿ[ï&¯« Á0þ@?L罄ñ×øù›jã4m ¦Š£š(ÃÄÒÉÔ¹:Pâ;Ƙì¡ëZ´0»clܸ*ÓCcæläjøU£–ß?emÀ0É¢ÕêêÔ3Ì’n¼Kx d@@âÝO¾è…épÜÅEQK™‰Z]ªºžèž˜º§½îÜfûŸè¥2aL-ÉA.(äß®º¼Ql·À˜ˆeL!2‰|R|8ɇ@ñ©‚(«„~¤%oÅ¿è'”Ðˬ†‡óq%$°JæiÉ %#–ÜJ¸ N¹%ó·„¾ŽË-“O,¹‰Ü’› ]bÀ¸ T\eÃq¹äù^Š¢Kt¼ä¢K·´xóy¿½¾—ài‰È1¦,þ–ÒicÚ´ý=Ôç5»îÌÔVŒ wñ*í•·Y²´”©e¯tRéñµ–a ¥“&‘Lyh©”‡V* Œ©•jöâµh÷ñø,FtuaÏ«¼·w•Ç  “z•oÏJl¯À/NÔXË0‰d*k%£}* `²§&ÉtËÝ£Ý÷>;‡Vßê¾÷ý¾VepņždœŠúdÚ¹ºïÃÝ^?'ôÁþ²–NÏ=—0¦ž+r=°R@ Ä+ ŒI5ƒ d?cidÐØcCƒ>ØNi& úhät„ü0¹k à“é½×·Æö±Ñí«¼SÞd€É.å‘L§Ÿ›ÅîJ†‰¥OÛx8’ ã…+‰aÊB2¡V¼ýÊZÈ+î^;S2ÀdbТ5òñÙÍX´bñ—Š…A­þ׸™‰úÿ°º‚mW@SÛ%Ö º£@ÏaL¿¾òÖÒÈ¥Ž^|ßcJâ²2I!V)Qò¢ÕÆ€J ¬’Å[ªàJœ4¾hÃÙ]e¸üñÀ¯Ò¯.º*Ä-yÄ’7ÖªK™ ¥Ê¨¬!n)Œ.UCÅ1fÜ–tt©âxÉC—èx‰|,vîÆ$!ŠœûoÓ·”är);~Ôª#Û„1 Ä óÖýà6£o[þ¸oþb'ý3á/¶±1âùø Ûø[÷÷’éâ+n±j;6wÖIs™Yü0‰aª[: H c*Riå:¯´û<0ff€×LfЬkÎÎÂ0-X½L‰+Þx­àeÁ7ß,xÅðm‚6ð/7øZÁ)¹T™KU€&ªî|8ã{¿fúÄa—³3Lô·DoLä™°_zÊ«H؉ ¬ç~FMØiGªH £€0¦Â•2*¤€íU@S{õ-àÕI2Ú;è3?%u}u¦™£¹ûûûÉ×ÐÆjö¨‘ »ÜØ@ÛzÚôØÄc¬‹^@seL?>mpdüU ?'m ÉÆè'ÃÄ¡k‚7דpDݯY®kUn2X´ÆÎ¬‰íPYÝ‹¬[¶|èâ¡\¶'‹VJ•iÖLÔäR71L¹ùù*#R ›˜²é¤£ §@ÏaLõ~TÙƒo=긔¢ÁÝè6©Žó¤«äÏ}¦§Z¿Jɬ’ã])W Âu»á’ˆ%o)I¶‚ƒaÂÄXMÊ-1„Yo´Tá–ª.—ZÅ!õó:m˜¬ó.8æ’ßûÃ{h¬kŽ©e„œÛöÞ6£—pN©Û|€dºèò[ `òœ0ùQäj‚²/³¥`ÍÄ’ÃT·t@ÁÆT°Ëuvi÷¹ïÑ®'¼ ¦AÓG $õâ¨âmè8mnŽa¢(öÁ%×?_(À›ø6Á{' ›k¹{>s4Q]?lTúV}ï‡ë[v†‰b›eœ$ö˜&L–€sZvïÚзöÍÆ16Å‚=ø ëƒ{¾Ð "€0¦‚”²)¤€íV@S».âõI2™²$¥îÙN}c)ü0M‹ úê2L°¼mÙù>&t§Ñ¯6§§èr£û=¤Xð/W § TÝoö·?ÜýžÂ=·©jy$Ó©ƒ+v×°ó{[;J;¹Wú¾õÛ‹0Ð † Å‚¶BçcÒ?Gd6@C5@=ш¬M5¡”—Í›E +ñÌl[ÖìM³eѪ[ñ¢f¢êôo–Œ§l_ê&†©nYè);„1å®H”¡Ö(ÐsÓEWܦÍ'ðí¡G~?倘¯êI!\)à“<ÚÝÒvt8Ü4xŠ›*aàâA%‚,•žJƒ¸¸¥*±” Z †èª¹)[Úl¡âúɵéô6aLX:€Î7~£èŽs+ Ü®9I&ÆIhlg ’éÂËnöªG À™;W,¹Ö´“ºJ‘ÆTäÒËaÞi÷¹÷ÑuÛá¨9»? “½D\Cy`2.„_+„hs( ²Ô4Q]wǨ&ê[£ “YƱùL–p©7Íè4ÓcöcrÿbÆÛ8’xþ6ôt:¸k cêšôº±R@ äKaLù*Üä†$Ó£“W;á5ÓÃÃä›FÝ…+¦ßø‘Åc_šnx@¥Øò-t•JWLØfÇISû* H¦=å x>¼pÔ_ý[Fз»¶Šaâ‹°× ôY1lD† ×#—Fdí« ¥¼r®,Z¶RÃ~»–,ZYj]ÌDb˜²„Ž‘¹S@SîŠDj½‡1UœÙÄ:C‚«›CŽü~VWIŒìVßdRKâž0œÄ=¢”F)¥‚JˆH<8Ç»R=\)>6\Lx8¢Ku-q—ÿÔ&Œ‰oüF]ç¨`•ø«ÅNNHf„46è±)Ë$Ó—Ý\õÀDçþ@:i)˜bÉeVÇ”SaLå,×n>í>¿=Ãâàm[i„mQf«ü0áiñšÀº4l¸†×É‘&FšCA;a·rWŸ¢+@Õµ·r=/†ßû‘é“&&Eû8£WÐÍè¶äÆtìä„ ‘&lã[$l`ApÑÕî•ü cê•’ÖsJ) ¤@„1©Š$)@’é‘I‹ëúh¢ºzèȘ÷¾_ß (oŽaB6±Ì—ñ ðÁz_F‹ƒMôæTEŽ‘æød˜$:jÒ§ c*F9)—R@ H)ÐvVì¸é®¾½Þýæ¶ßI7(¦$™zb¡3è‹Y=Ø(Ã1ÐÁ6G§ìNù)ãÇ‘Jq{Úô½D¯“jÝ&Kª'ùŽ”’})ÑõÎoüÌñ«”Â*ù˜K°jÄ[»oiQǽ 4RÓÙ.4Æ„¶$ÓàKo¤÷,׃¦|7¼Ê]ÆÔA±{ðV´û {hªµÃîûH SV‰¶>2MTCn[ßÄ0µUüR]\S©ŠS#¤€Í+ Œ©yízéL’L#&.¹ááЯ¡Xr½$[IžÕ#™~zv¬ÝU SIʸ‡C­~KÌDb˜JPôR`0&U‚’*Ћ“‹…¶1}ûˆcSHó”ê6©–äFKã“,p˜7‚rS%œ*ù\‹X¥TB«èI¦sþíF‹&C3ŠbÉ•´ÅÖc5®€0¦Æ5Ó )@»Ïí#§„Úa1L ɨƒ3*@Õ·ŒÕ71LÔaž˜T¤€R@ ø cREȨI¦',­¢ÔQÀB’餟þ v·ôÅ0ºL•yS@­T†~š‰Ä0• è¤€§€0&Õƒ’*Ðs‚pÑ×Q(ù.޶âÛoq,·[‘ŸI n“B¾”ÂpRmÜ·ZD)B)XêU§J=ë‰íH¦³}£‰ †©¤Íµ«)„15%›NjHÀî3bеÃb˜P7¤MT˜2±ú&†©!u°0&Õ) ¤€T@“jBvH2¡ãmp1LÙÕ+ú‘ ™Nüɯ¬èÅ0½@•WY´JPš6‰a*Aéë¤@ €0&U…’*Ðs"p±Øâ"²áÛo~ll˜¶†vÆÓHæ<Éñœ2‰©ë-.â›Ï' QjšUJ9±Þ˜Ø4É$†©¤mµ«Y„15«œÎkH×î#†©!étp ¸&*1LMØë§ÈS¯×=¿R@  cRUhH—dÃÔt%8ØH&1L%(M=BHY´JP%š0‰a*A¹ë¤@UaLª %U ç0¦s.½1…1·À˜ªÄñF¹µ’Ë$Õ†u« ñ&2©dRC×, Æ„ $ÓÏué~yâÔùë¶¼›’ÔI-i{®ÇŠS@“êE§ðì>_ßx|áKKWoNi„¬Þ¹û÷u*_ºO9 ‰êç_ùùœ³`Uú{_õ­œ• é§ÆÔ´t:Q H) Ê¥€0¦r•g'ž†$:áß<øðU^Oé„oÙùþï?Ô ¯…Ò±{€d:öG§øÕoß;r\úøkÇ›t,Wº‘h‰$™<‹Ö_–E«%’vþ" ™‰4=ÔùÒ¥@{ÆÔ^}uõ®)Ð[Ó¥—^º—>R AþÓú‹©súÜê¦íïuí'›zãŸýð1Lù,åªk cêšô½xã7fÞ{ì?ü—¥ÓžÃÔ‹ÅßñgÞ´sÎü/#§Ý,†©ãÚü†Â˜ ^€Ê¾R@ ´JaL­R²§®’験ŽÃÔS…nûëß\.†©7‹¾ž$Ó±Çý@ S¡Ëzç;›²˜‰Ä0º”•y)¯€0&ÕŒ’*Ð[S´Ó'~ô­ˆU ·ÓžË÷ß1‚ü0•´¹Öc5¥€0¦¦dÓIM*ðÌýúùܲdNR;,?LM «ÓâØúîì;—ü‡ùF¤¼÷å‡Iu'FaLªR@ H) |ˆ1¡O%=¤@vví^þàò½_yí­¤N¸ü0e³ˆG¾ñÎïSÆ_òÃTÄ2UžM?ýùÏhÁdÑ*n•x÷›êš‰Ä0·|•s)¦€0&Õ’* Œ)-ö– )P$Œiùã{ð®Éôæ±ÙV'µ¤Í¸+UaLª Tàíí{ÖÎþÓ¿¿k÷ÃÔÉ¢è…{aÊ o«wÞ¿íx;£¦^¨Í<£0¦fTÓ9R@ H)PB„1•°PÛÿHS×…Nøòm·ÄúÄ0µ¿º‡$’I S÷ËF9è·I$“,Zý–¶Æ”n&ÒôP'ŠA÷]Q@SWd×MÛ¯€0&aLR arêéòý=Œ iùãQ’IÔö7§ºC.Æ”Ëb)z¦VºìÞ!ѧØÚ7ûíWÖbÔî#‹OÑ =‡ù‡}ªoÛov½¿õ-J2‰aÊa‘å%K˜òRʇR@ tYaL].€Þ®˜0CŒ4âùýþÃ÷C$“¦i“YŽ’Lb˜š”R§åOY´òW&Ysô‡ÞJ1iz(«Ž:N QaLE,5å9ƒ˜FXä H äc¢+&&ðL{ö¸$“:©CRR„1•´`»øX˜æ^6襧FDó0aЀ«û¸ßµûˆaêby•æÖïýá½”g ‘Lb˜JSîmyaLm‘U•R@ Hâ) Œ©xeÖíÓÓŠ7ýñ£j&1LÝ.œNßß%™Ä0uZ}Ý¯Í È¢Õf;qù™HÓC]÷]T@SÅ×­Û©€0&aLR aòˆ1™+¦ŠC&´$™ÔImgªkç^aL¹/¢beΖÀ*Ãhɸ%<È#÷ããp?í>Ï®zLIèÈb=µrÛu&¬™0h ôl˜‰J S×Ë+ïÆ”÷Rþ¤€R C cêÐe¹¹b2‡Lýé’Lb˜ÊRÈ=I&1L©¦£ ¢€kÑ*H–{.›î°í½m)mf"Mõ\åÐ÷ ˜z°Ð{ã‘{cÂ+CŽ”´uçîo~Œ¾-“¯½ùÁö7v§?Qîz~®+&Ç!ºªšËì–\O™¬€0&ÕŽ–*€pr`•àéÃÝïgZpó`lcc÷Îm$œp·©ƒb?ŽD;¼c=”ôá„-ÍŽ.Ö ÀÓàiƒ‡Ìóâ®ÝåE-ìÛæ9ýâ6>f·B}{öå>~«HT@“*‡R@ H_aLª )àºb2‡L¸H¦ßøQC—ÒÁ¥Qàß?øcižE"B ÀÂðþïÕ¸å´^Àò³ß­ûÑ.„¿° ᯙ‰Ìd„B|~Ûœ<åô!•-) ²+ Œ)»V:²P ô:ÆT¨ÂRf¥@‚!WLŽC&I&z]aL½^ZüüÆ*aãå¹xuÆ’ƒ‹&€Jøô]4yíªikßl;²ÅÒåz@Ù›fÃ8’ <Û |d <3a§ùgÂNؤ`®Âh'ìÇÁ= Œ±Y„15«œÎ“R@ H’) Œ©dÚÖÇ ¹br2µõ¾º¸R@ H¨0ûÀ4tñPX‡`&B‚9Èü3ÁF„mœ’û•Ä”R œ c*g¹ê©öcR%W êŠÉqÈTðgSö¥@¿ÆÔo uWc•*Obb,9xZb°9àM›°¨¼4áÛБ’T 4ª0&ž‚ :[‚ æ*Û‰ TDX¯¸‡æ*}¤@¼˜T3¤€R@ ø cREÈ®@Ô“ë)ûut¤R@ Hþ+£vƒg²Enf;‚½ß’pâ½F8Ò8IN)][E‡ ³@Ñ.B'LpsWày`]{Ê~ÙC cê¡ÂÖ£J) ¤@š˜T?2*ëŠI™2ª§Ã¤€R å ˜QŒ%g¶#lsð&ºôF¢÷î–gC”R / cÊKI(-V@Þ˜Z,¨.':ªÀ‡ì¥Á´äá=xWÝÿ£êží/v43º™È¡˜rX(EÎÉ$<@0IôÉDP‰>™W û1á+ìÁ·ØF\9lc*ráw-ïXEÇ q¶ØÛ*1Ša&fHÓ„5AÄîeZ7γ˜ò\:Ê›R@ tPaL»Ø·z÷›¶¾;›iö¦`Z÷æÃ¶ç½UìÇSR h ¸N»™÷ɦ!ÐKf2ÞE{PåW Hl cʦ“Ž*œ˜ WdʰHP`×&cšx©’R ª€0&Õ†–*°ìÞ`é`&lƒO2LØæ­°Á¯ø/œ0á_$L-Í‹.Ö+ ÀEŒ (z`‡Ñåà;ñ{€1Á,…õvØÆÔ+•£¹çÆÔœn:K H) J§€0¦Òi'¨oë¥À˜6uâfº‡R@ H8hr—´Ñv„Øà:7‹è´ÉöHK) J«€0¦Òm¯?˜0¦^¯zþò( Œ©‹F¹’mW@SÛ%Ö º£€0¦îè®»JÖ+ Œ©õšêŠÅW@Sñ˰HO Œ©H¥Uø¼n}wö]}{aú­ðO¢è°˜:,¸n'¤€yU`Ó[£7…>U^3¨|åQaLy,åI H) öìy÷›d&RE=ª€0¦-øò?¶0¦ò—±ž°WÆÔ+%­çlDaL¨¥cû«€0¦þ*¨óP@SbéPWaLªR@ H) |Ø›ƤêИ’KK) ¤@ÇÆÔ1©u#);„1å®H”¡Ö( Œ©5:ê*R û cê~(ùS@SþʤÌ9ÆTæÒÍݳ cÊ]‘%C˜ŠRRʧR@ ´YaLm¸œ—ÆTÎrÕSI) Н€0¦â—¡ž@ 4«€0¦f•Óy9W@SÎ HÙ“™Æ”Y*ØC cê¡ÂÎÁ£ cÊA!ôN„1õNY·øI…1µXP]N H) Šª€0¦¢–\Wó-Œ©«òëæR@ H)¨€0&U)л cêݲ/ù“ c*yëñzHaL=TØzÔÌ cÊ,•l˜Z ¢.‘UaLY•Òq!„1©JH) ¤€ðƤŠÐ„˜šM§H) ¤@ÆÔ‘u )S„1å´`”­þ* Œ©¿ ê|)>ü`ˆ ÀLúH)` cRe褘:©vÏßKSÏWfÆÔ¬r:O H) J¦€0¦’hgGSgtÖ]¤€R Q„15ª˜Ž—åQ@SyÊROR£€0&U)P0^zjIJ{‡|¸û½P¾wïÜöòÜ {eW ´[aLíVX×wƤúÐA„1uPìrÝJS¹ÊSO#¤€M+ÀÞÔ«oOnú :±ÆÔƒ…®G–R@ BaL…(&eR ´EaLm‘Uí¾˜º_ÊÈ®ÀÎÕ} É=lRöKéH)Ð cê‰bÎÍC cÊMQôBF„1õB)·å…1µEV]T H) Ч€zSÅ+³äXS AYR@ H„1©ZHÞU@Sï–}ÉŸ\SÉ XW&àiÁ̓‘èŠéíWÖ‚j‚&>#ð&üÝ=ØÏ¯ô‘=§€0¦ž+ò®>°0¦®Êßk7×Ä[¯•xËžWSˤԅ¤€R Ø ¨7UìòëRî…1uIxÝV H) ê( ŒIUD ô®˜z·ìKþä˜J^Àz¼2)°µoö#÷Æ„¹— B‚û%ÐKŒ%‡¯ð{¸ÿâ0ìÁ„Ÿ°Q&5ô,R “˜2ɤƒZ¤€0¦ ©ËdQ@oYTÒ11 cRµR@ H)à+ Þ”*B cjB4"¤€P@SDÖ-¤@NƔӂQ¶ú«€0¦þ*¨ó¥@' «oL«Få}K>™H)á/¿ÄäFšÞ$ŸL,,Ý+ cÊE1ôL&„1õLQçáA5ñ–‡R(d„1²Ø”i) ¤€h½êMµ^Ó¸¢0¦(d=¢R  c*d±)ÓR % cj‰ŒºHþÆ”¿2Qޤ@‚Æ*áû©ƒ2Ñëý3a?"Ía§ë¢ Û<Ò¢ÎI`)ÐC cê¡ÂÎÁ£ cÊA!”; »?ÜþÄÚƒ˜Æ®Þÿ®¾½F¯úÛóêÛ“Ëýøzºæ¸ç¸=7¤ÓÿbϹ«þ;ú¬æ/«3¥€R@ YaLE.½®å]Sפץ€R UaLª R wÆÔ»e_ò'ÆTòÖã•Ic•À$™7&ÀIÀ›àu {È3á‘~ø ×MÁN)“&z)PGaLª"T@S'ÕîÕ{M]è¥hñüÇ>úÓ½ªŠž»ž3nÚ‹FlZþx½“õ½R@ Hr* Œ©œåÚæ§ÆÔfuy) ¤€hRaLM §Ó¤@ ÆT‚BÔ#Ä) ŒIõB F²JÈ.1&Dˆ[pó`âJô´ôÒS#¸ñòÜ ÜMŒ%‡¿8¸0ªŒJV) Œ©UJê:YÆ”E%Ó?ví^‹1­ØqSÿ.¬³K­À‡ìü±ŒéòýKýØz8) ¤€i cRýhBaLMˆ¦S¤€R  cê€Èº…È©˜rZ0ÊVÆÔ_u¾è˜ ”̵&$úaBøc_q€'ìÁþŽåS7’9R@SŽ £²"Œ© 9uÈ$WLy(—¼ç!Ö!“\1彨”?) ¤€h£˜Ú(ny/-Œ©¼e«'“R@ [aLÅ.?å^ ôGaLýQOçæXaL9.eM H) ú©€0¦~ ¨ÓR@SCréàfˆ:d’+¦fµì¥ó¢™äŠ©—Ê_Ï*¤€Q„1©V4¡€0¦&DÓ)R@ H)Є1u@dÝB äTaL9-e«¿ cꯂ:_ H) ò«€0¦ü–Ms&Œ©Œ¥šÏgr2ÉS>Ë(¹ 9d’+¦<’ò$¤€S@Sç´.Ñ„1•¨0õ(R@ HR) Œ©TÅ©‡‘ ) Œ©!¹tpqÆTœ²RN¥€R Q„15ª˜Žï˜ú£žÎmD×!“\15¢\oë:d’+¦Þ® zz) ¤€€˜T šP@S¢é) ¤€è€˜: ²n!rª€0¦œŒ²Õ_„1õWA/ò¢À®M{ð®šxi^ò£|H<( Œ)¥Ð;yÆÔ;eƒ'¥C&¹bÊAQ* æI®˜ UnʬR@ ´CaLíPµôׯTú"ÖJ)  ª€0¦‚œ²-Z €0¦ˆ¨KäQaLy,åI 4£€0¦fTÓ9eW@SÙK8_Ï'Œ)_åQòÜÐ!“\1•¼˜[þxtÈ$WL-V”R@ H* Œ©€…Öý, cê~(R@ H)§€0&Õ )л cêݲ/ù“÷ÆôÖ[oÍ®÷yâ‰'ê¢ïK¥@–ÿàƒ ÐìÚ´ý$yc*@A)‹U@SGåîù› cêù*Ða&ôýð£?¡‹Òa]t»TÞå‹•HR@ tWûï¿ÿÒÔÏ™gž™~€¾m«_|ñ9眓~‹Ç¼»µHw￘ú¯a^ASºY H)P„1¢˜”I)Є1µEV]´û ôÆtÊ)§ü?ûý¿_üÒWÜtà—¾bi¿ÿ÷ÿ÷Wûë¿ôåÄôÅ/øÅ/¡ÁtÀ¿¤¿|@bpÀAúüâÓ|>.}î 2¥|­¦/}ö€úé3|ÉKŸÏš>ýù/ŤÏ}éÓAúâ§?WMŸúÜ3¥Ï~ñS~Ú¿‘ôÏŸý¢ŸüçϤ¥ÿôÿÇ?~ò³8擱éÓþÕ_ï}ÕUWuÿÇZ/Ë—,ú»ÿ¾ß¥?ÿ~½õ½è%„1õRiwÿY…1u¿ z(“'Oþ›ï‹‰ðzf=j¿À¢ôÿ:ê¨b0úý~^]@ äSM›6ý·ÿóÿ<缋™ÎvÓ¹Ÿ}îEH8`ÐÏNÿÕ¹UÓà‹~5ø¢³"éÌÁžyNM:㜠ƒtö…gTÒ/Ͼ°’.øå¯¼ô‹¸túYÔ¦óO;ËOgVÓ©gž_MgœêçŸRMçrF~þËóBég¿<ÏK¿°tîOá¤ÓÏýééçþ$. :í\? ¶ôãÓ{éÔjú×SWÓ)ƒÿõ”sNަŸŸó£HúáÏÏùáÏÏþáϪé?;û‹}û¿ÿÄÆ~꥓ÂéW'ýäW{íÕ[ö´|þšú™+aLý°7OÆÔ›å®§–R@ ä_aLù/#åP ´KaLíRV×í²½ev9ùä“oºí®­»ÞÒÎ÷·î|‹—v3ÝxÛ]ÇwÒæ×w»éÕ×w{é5¤ÅM;þýe'mÚþž¥ÛßóÒ6/mÒ»¶¾»ÞIë¶¼ké¥-ïxi³—ÖZzõ5Az{Í«o¿øJ5­~åm/½ì¥^~+H›ÞZ夕ßZ¹ñM¦H‚ôü†7½´é眴|Ý––­{cÙK»˜–2­ÝÕWM;—¬©¦ÅkvzéE/-òÒë^ZýúB'-xáu?½†ô,Òª =³ê5/­ôÒü•;‚´bÇÓ•4oÅŽyÏ#mGšké¹ísœ4{ù6K³–o›µ,H3—móÒÒ­H3,õm^M[¦õmù«¿ÞgÄÄÓ–l™Ê´ØKS¼´ÙK‹6Ÿø“_af—©õn¿|ùrjó–n„¥8ÿ¹­÷4ú^ ´NaL­ÓRWª¯€0¦úéˆÖ(†éëßð8ùdêÕ‘é¹=†é Ä• Ö]¼U$S&ñth½À˜@)ÕØ%<ßÏžûgã–pÀ3}/Dm›BôRªè°ñÁ]:õê;®ÙÁ|?§{}6—Ïa†©ÖÈuÅd Se}Ôξƒç¶¹bª.‚JrÅ´¬fá7“ïŠ)ðÆäºm^ä­wÆÔúßFǯ¸ãßÜշך]÷wüκaÆTàÂSÖ¥€¥V@S©‹W'RƤ RRzcºþ–;c(¥J¨8|û½ïŸä®q´í·L®Ûv]B¹°ï¥½´Î !—â©™@r›H.ˆ%ç[K®_~˜úÁ0erÅä"W.Q®ÖS ôÕüÃcNŒ)N¦ÉœcLd˜žyn–Àr:b„ÿCÔ¿Ÿž.’©¤Í¶«!„15$—ú) N¯§¦%/n¾÷E2Õ¯w¿¦'çZµ!õŽîâ-÷È'SïV =y Æ»zÊPá€ùK^ 9ÂE—B†ˆ¬!ìã}?ǯw#×',—ê7Äkl89ß»sBxz‹(uÅdáä<‚늩֑s4}’+&cºÑ *—QކaL]üµêÖšík•’=uaL=UÜzX) ¤@PǦ@…¥¬J+ Œ©Å‚êryQ 1¦XJ‰;1óýÝ q¶@K•ÅŽà–ê¢KÙé¥Ê:Èw€.…è%,‹´‘pÂô‚9a ™€ie,ÀT× Óº]˜Ò`Ь•ô쌮©Ó‹‘ÒcÉå€aJ'G£dÆDÓ$1¦³Ï½xËÎ÷-íxóƒ?ýùÏ]ÿ“azö¹M+¼Âõ0&xì7Œ ¥ó“ÓϽð¢_w=ŸÊ€è¦˜º©~ïÝ[Sï•y'Ÿ Ó7¾uXß‹Ûý÷¾ïS§ö½ØÀã†Ýõ»¦³Ô×××ô¹ž¸víÚÐ)MÜ=z‘F³Ñòãßó?¸lRÞ}pÈÒÏÇ$Ã4æÉ¹^µ‰Pïè.Þ|÷#‡ñÝï¿ßœÈ¹­èà~ú© ³Ê*×’KEŸ½‰ËòÛ*£.žˆ1EíÞÒ©Š³¥½÷Ù÷éÅ/Б}UßÏk<ßÏõ¦Z—϶VÊ55TbÉÅG«Æ’sÖGµ’aš¿¢•ÞI¿i.S\89oùÓ² ySm zºbB ŒépcŠqÛ\1cr­Ø~w÷‡ù©fÊI4Û—E%îµn½N¼Py¤ŒR@ H\) ŽM®ŠC™‘U@SGåÖÍ:§@ÏaL×Ý|g,¥Dãàµ7{SÈJ!–K¶¾ P)”\»¡¿ýÎKɾ—êÓK`˜ê†ëÀÄ9°T€©f­d0U¦E/ú+&ýE“5ë&ƒ@rÍÄ’k•¦, ScJpÅDŒé—g_*Ù?~ÔeŒ‰ Ó‚ç_ÆZØÐÚzg€ÌP( W¿>è´sÏ»à’ε(º“È›˜òV"åÎ0¦r—oWŸŽ ÓÒ5;Òßû‡Õ$Éêb¿ýö1bD Ÿr„ I0Ç€BÄîÞЭq:.ÒÐ)éoÛ¶­ÿ?Äÿ¤ä-ûƒC:ÅSF†iN#áäÀ0Áss ÆTk+°õNÀ˜BV¬wj®Jè¬n) Ù¾n)_èûÊS¡‹O™—R@ ”XulJ\¸z4)PGaLª"%U ç0¦koº“XRœô¾ýî÷Oô³¿¤­1â ]Š@K©ÜÒæwÀ-…Ð¥xßKè¥UQz)B.ÕS<Àäǘ¨ÃSkœ0­z확¯Í_¹ÃRøøÈ2Ê9XR™!–\F† k+=oL ¢Ü/möRey¥ycÊÆd S0)·¶žÓ‚^ûñiƒE2•´×ceP@S‘tHËÆÔ2)u¡ŒaªÀ(áH²€QH“ã½hS$ø 3­ƒôÄ–evš'©*´c‘á–Ô¼–`Là` «ŠÊ•%Ÿa†©Ò]dD9—zGµ¹ñ·› ™CÔœF´ôÌÇnÑrبµÙÎR"IulèСfágتz˜%K:¦[ cªÄƒƒñ!šÞÅs®Š_:UË-Á(á.Z ³ƒ¥]J£—V›¿ç—ß‚‘ÁRš¦Z; –2:a"FÉdË¢ðc2€ ­Sç¦é}žÏfbLæŠÉlÆ01¨œ0¦nýˆZu_ÍöµJÉžºŽ0¦ž*n=¬R @ ¨cS ÂRV¥@‹ÆÔbAu¹¼(ÐsÓ57 ‹ºP²=øö»Çžv°±VlUaOK/m~)d7ŒrK  Kµ¾ÜiR Ûãé%o~ËMaÛbrÙ&ß “YƒcÛœ0=·Nà-Í 9„‡Oøe[k¦¥Oxz†ÇªJ’c¢Q’SÔCoL`˜>ïûaBM»dpÖÖ£h`ÿ…Ù÷™U¯ýøT‘Lyis•N+ Œ©ÓŠ÷öý„1õvù·éé†)òÞ÷aó©ã½÷}XüÐ#¿ßht9Løkþ“H5Ñ!¾°‚m×3·±“´ ¶bغwâí\søÄ+ã`ÛcLIè²®ªîW Bp ogô•À=ÀAyÞ‚“žÿ?ªP¶é‰ù™={6.Å=Ì1”7¦V=82Öh20Lè.>öÔ<Œè@%6!{òì.Þ0lT£$žR@[€8T¦n=±zEÅPŽtAD%Y‘¢ŽÁb1&«rv<2–³*A6þì׳ªN–1œB‹BµGòIæ)TëìÑà¨,”O«ç8ÝÄlS“¢ËæAbL)v |…æ,\·nªZ › ê­›rÖ¿•°~càÉk=*Ö† „\€É R_Ï “Ï0ÕúuŽ:aò^mLÎj¨š¥PÏ'Æ’kÔ¦ŒÉYïä2L˜òðSê8Û·|ûUý¿”®Ð; cê²Ö“J) Š¥€0¦b•—r+Z©€0¦Vª©kåHÞØnk äÎknvô±'ÚÁ¢ÆÚ¨p4†q¥Š§¥,ÐÒ‹p¶ÄŒÃ†cCLD—jݹ'ÐK˜¢H¢—RÜ/¥x`Bx2/EÖJö`Z¹£íN˜j¦-.Ãd«*á„ ÓƒÆäùa Ù%sè‰ ÓÂç_ö6NJE\2T"ÊÙt&œíÿkf’‰ó‚n+•´Zsu9jϺLJÕÍ‚D«+Q‹ÆÔbAu¹T„1©‚´Zc˜êÀ(Œ˜ë…·Kt±i„d¢OäݼÂ`EÅÂW€?Ð`¬+¼Èð¾3n{ÙË ~Áƒy$=èð Ø07Ev°õ:xJô²¦¨}…l0˜K>á_ò4<×§çsrcùG&q…袞rb³M8_áv”‚w´GvƒÊµäÁ ë4T³\†)ä¹3ÎS@¿¡æ\×ÉD$3À+¥ž°ÔBõ eá–# ž$oLDøaM³ RA܃rÁ+ƒ‹l²=v_V7Üc? ^ÖíñF+žŽ(³aõÉ áŒ‹_4U±€iCÈ!ÕÚaˆlÔ ÓŒª-²ÆiN˜`‘¤Qò¯þzocª $çòL'þäW9 *Ã0…ãƒì¢K×§3¡íɧœ“%ºœ0¦¦[n›ñM¹‚0¦¦åmòDaLM §ÓšR@SS²é¤$\†)Ä.Œ’òÞ?ä;Y}2”1ßEÈOèm’æ2%`5€•`Y%|ˆŒ¸Aåp€¹áᡃ‰E/kâ.±Ý,áFäZˆÑç ‘£Oû é;*z£Xz&”mþ‹Ó ÂÕ쎦››·~>¸Kbeü¥Ôa˜j=w2!|œXwñºÛ³údBÞÈ÷àA ~l=qKGR|:Ó·ia›{Xj¼2· ‘7‡D[%Ø ‘÷n5ã¥ÜSŒ|â5ù/ïË\`ú9ÄÖR`I/E8É®ªuöhx>¾ëx ·³Ö2>¤¡KQgϼ¥2.½”´PÊ‹Wññ¼Ñ*™ªêwö%Ú^§¦8¿Î‘(r)N˜üAn¼ ayÕ€`.œ=€)™a ­z:çß<Œ)6–œÙ T®¸¿A˹0¦bçASç5×¥€R ‹˜²¨¤c¤@9ÆTÎrÕSíé9Œéªî ù/”¸~ßüÞ‰•µŒaD‰ R «TÅ•j<-Å8[zÁJþòÇ*·äÍW9^Ü«–Ä`5d×¥xt †Å—v1¹†Åï¥z)ê~)bg\ø‚³ÌO¯!!X2¯ïî¢INXr—Nö`ª $˜œ%•®&³Hcz`ü‚X?L¹òƆés~,¹ª&c˜Ö½ò…Ç~o.3êŠÉ—ph°ý¼>É”„1a¢…kè1ÅÂ)@›Ôá‚uNX2$‡¹CÀtãn˜ó¶»<8€§ÛÅÝé.;˜á”'Æõ]fˆËëÝ+Gs‹cx=…ùç1œ3‹îáSóNnñFÔ„3R<‘ǘŒ>û۔ª^AP@S'TÖ=* cR]h1 “Ë.»0ŠãŠÉëwaZ·òÞ?8ÉDŸ:ˆð•ír8 „§ÐûN+ ‘I8‹8$!ìâÂ"䜨O4Œ)J«ØaÖCÀ¹!î×çë/\{¢}‚ý<†ÐUèFQŒ)šmæ–!êØ!Á‡TM¬7¦þ?¸õ—2Ö,0Lè.2–\ØS†î":äè.^sûCY¢ËáéЋc±²c[OÜRC‰àH«l,Gë±Ch˜¢ýÃtŒ‰™qƒ$²Üí:é“)Ûnç-ZyP:¤ôX1\ÜZªc¨«ì6³p‘=…“ËXÏKp1¦¸õQ4Ax Ì|v…™ Z¸bjerœz'rœ‰²)÷Káðô¶8jÛÀª`Š"‡·[¬%!º*Ñ S(½c70†É,À˜¾éaL‰>›å©¿D<‚0¦r”c‡ŸBS‡×í¤€R £˜2 ¥Ã¤@ ÆTÂBÕ#y ôÆtåõw˜‡¤è¾ø½RÖ5ÆxWаJŒ·ÉKQb)êl© -ÅF‹ó½¸‡,‰uÑ¥tzÉu¼Dü%&xœodlØý’¿b²`rlŽžg ï÷=0®à}+d“ëN˜ 1¥0Lð¶UYöêyÒJrÅDïú0éÖ%™’0&.aÇDÀé% ºÁý6™‡ .+Ç)øp®‹S•œ­äL&o8ÊI,Î0¹Í3 5e¡:èõÁæ¥BÓEœ Šæ×áyæÙa²é[柹â1¡=ä´xG|Å9Z›³‰(; Ïhn¨ g4õþ霘:§µî´g0&Õ‚)` w²ììøÁûE<»\ëSÇ{ïû¾(¾]d²WóÎwwè Î75_‘ Ëe/D¾Úx_yá Ç˰ÐZ3+z°a@|ÏÚeMÑÐ+8Š1‘ÁñìfÐ3“½sÙÁ·ÄS¢ùwyÞ4šm>>ö³¾ 9cêÿƒ»½º•‹ ÓØ8†É«9—”jw1âŠ) ÞQm®Z‡dŠºb¿(©ž°ãdõÊ*’u¨Øû"e`“=rÈ«bc²N#Š˜49/Å*Án›Û‘³‹„ª“ubÉðá\·ó­‚1Rn­³G³N)q>&;ÌuKY”CbL)f|…f<³"ìÝ9}¹T\xzÏòÌ-Õ¬•Šêûx^›Ñý’0Õ*k¢¼eQîš([…EPAJ˜|GÎEnÎòmÆ0etÂä’3† Kž|Œé{)>›…1•ãÇ(Œ©åØá§ÆÔaÁu;) ¤€Ȩ€0¦ŒBé0)PB„1•°PõHžY1¦èú×"êwòÉ'¹þŽ0Šä˜ñíÀcNXý2˜$7½µšLRlòA¥$VÉ1Ö¸YŠzZªñÜø[Šá–Ð¥ÀåR£Ž—zéE}a ÖGF}/y!'Ý/¦Æ(½Të~)`ŠÄs°Bšý±B/Á|ãÓ/„\`¢³¥ücLÆ0ÕÆ™ËŒ™” ¹d¨D”#Ãäk¸õ‡?;;%º\ Æä΢ Ácñ;Ü .µw²Óö¢›à‰ˆr'®l›¥¡ˆ!ø6Ê$…f.q ïhüS,Æd3I\cB{¢ËúÝñ`›îâ|*‘&c³}¦ˆígQó,Œ©¨%WÌ| c*f¹å-×Ãä;欼÷'-ÜüؼMcçnD3wãs6]ŒòøÓ›<ßµ®˜‚÷þÒ­ß>âØawý.é1É»ßb]ÈÐ ab¾]Gƒ|±A2‰Çð‚dV,ì/Åw%Y(÷`{á†.ëf̸̮^éÆyæéø;ͽ¹‡4D&t#$<×˜¡þ1W‹äZ%ÞÑò½B£žÝ“1Lè.†Ð·qó6=T›Aµñ»‹?ýrPmBÝÅå^Ü¥«n™â“É5“ Y%Á­'ÜÃá¤yßdwˆ}$À=Ñ‚ÀN|‹ÃìcµÈª®/åV'þKàŒB4O¡Â¡êdCy$»µ¡ªèV~ÆSèÓ®ªuöhæ¶ÓNĹòÆ”·¦¸­ù!Æ1;ÔX!pÀôùϧ[!žœµ$ÆÇ³-=9sIÔòðÈ„YO˜5qÆÏ÷Rè’ÏD&s- t¿ôàØéxUÍîÛ„Ä(r4,Œ~êY`rM IÓCŸ¹çá©Hwûiʳë€)ˆ"7é™uO=³ÃÞáÏ ‰kŸ¶Ü7n‚ÎGãÎà 1¦ŸÍ˜ÚúéØÅ…1uLê2ÝHS™JSÏ"¤€(“˜ÊTšz)И˜ÓKGçQØÕ¼õ1&Î@ðÓЂàjàcL·'š_~kÈu·uÌ Ä’RȤäxpaV)ÖÇÒ7¾uø§>û¤¯ëpºmÿÑO±ï'þ{FŸežÛg<»úëß:,´{ŽúÞIXˆObéô³/FŠ wã°‘ˆ2†€q3î o6ü±qèRÕ»{ÈñÒNÿê¿j‘ãâJÆÑK®Ë÷XzéÊ[ÀºÉš¥“>g㦽÷ý;X™0›â§VLýǘÐ5\´å‚¶Vu2LÏ>·Éf¤`k&Íöƒ+gtÖøƒÎäÅ“O2câÿŸ½?º¢:÷}aîýƽgŸ{î9ãܱ¿s’½wº}ÌÞ÷ËÞÆ£QQ‰‰‰½ ‰ ˜Ä„hì[T@ FÁ^x;}餕¾WîDD@Pà[DQùþUOÕ³æªnÕê«ù¯1ǵjÕªšó?çš5k>¿ù³÷ô3zO¿ÌË–øîU5gÎiÛõ›‹£H&'d:ŠqHŒvhÿߊí/ùVÌ6b1bCò¯§—_ɲ~UX+c2M‰9JÏ,§îJ®%†Iÿ)«ê¥øú2e11&9À¼¶‰1Õõ/ã=91¦†Êû‹cÊ}¨^a˜Ú6îV€IïûgÝ:÷}ÜôϺe:R·¾sq߇©7ý€û¾íŠ c§¹«vá¾ÿ‹Ó£H¦ê³í¹•×ä„< xiǵû¬))…0Lãž!yw›Ór&/ÙÜlìˆræp±ßÀ(’©d®â`Ž‘âß°c0F5ñý´?7L7^(¦‚1æ%Üùs"Ìzqm _gÙÙû/÷~ÄǪô?ûåéc¦Ì—Àô]|¥Ì9 9Ä’=óðì¤ù:tЯ0 )ˆÒ^—¼è’7rœxvWFûæ·¿‹GÔK¯í}é5½1±Ðí÷—cVᩱ³OøÙ©’>0}`0úCxäéš^wY“}¿ÓÔýŠžHŽœùï‡)³¸j Q¢È=òÌtc2LwN˜®¿SÌæœîÈ1¥»þš”{bLMž—¥T€ P cb¡ùU€S~ë> %Ÿ)òò”§4Æ$øñ3Læª?¥ªcê{ÿ#Søö¬_uµ§=ÉZÖ˜d–ÐI[­ófJ©(myOp%IàQú=8¤Ë¯/Ä>â+™C|bÄ™[´ˆ%Z·tØ~‚©F J‚.]qÝ-H6®¤Éá–-™aã0î°õÌø¹þ¹Eº¤ë#1É8lìì~”éã½0ÏX¦ï% ¦1‚Çwâ)¾ßM÷K‚1ÓK¶MÎH;1)+)=‹)=0™«*+óÆôþ'o,Ü~ÑcmF­ûNýþÂ0-yy[ÁY×–w5¦ ™ðÇ€ªGEß5bu·¾sPwƒ'¿ÚµïÌcÆöø«'M}éMÈnºbs&Tº0œdÀHÊ¥QÞün‡tðI~Œ ¿ÕÅñâ~'D—"=‘¬†0„í0ŒIŽ—ðDöx47/-Çûs‹ HW&ûbR’[ÿdXý:H©=Â:{½¯N楾ê×lxæ"ˆ1±A4RbLT;‹×Ã`}%&wô(t»8_Ä}ÿÏO­<] $™¶O5K‰I|;ù1&ìÔÜJ08n%“ré=?hÉÌ­I¦M˼}.òéQOöˆ'*zcjèM„SCåÎýň1å¾ T#€Å0Aß°[¢ü(ÀdÞ÷o{j…É0á¾Â5“0v5w3¢†É}_`Ó“ pßG|œˆèrÕdž¿­“‚1I „™,†é¨Žc§. .âñ“É0*@³Y Íæ§Ùˆ‡TÓ“ï|¸5"º\ ÎÓRl+Œ ”R輄M&မ‹^ö¬’RÈ~Á'¹¬Ò{Ø:ÒZ¥Þ'ÏY!÷‘‡µ0&å–FM´0&](5rÂ<™sÀ»$t˜‹@Âö÷vV¦°, ó xöÄœ¶‘0« aãdzSHèdž_´˜UÀ;æ%0±€é¤3ÎIoLxb:fö¡‡%“ ‡NÀ Û§Ýó ˜1ù+ÙŽœcRßK­“c'fþã°#Oí|V@u¿âf¤Á#ŒI6Žýé)x¤u:nˆ÷?:ÎÚÓéd¼[“2LÅÓƲýÔÒcÊIE×¶˜Ä˜j«'ÏF¨ µR€S­”äy¨@ú Æ”¾:cŽÄÈ.®Rü¢”Ƙ`ׇé§À†‡JÆÀ˜î¸¯%ÀC’»äßžuNW¿ÿ$“€%I „“ü;=ŽÙõã•×ߊyCàJHVx8{Ƴ‡ØÙÃæ º„ |,ö´„Žj0èÒY¿ê†ùDÁ˜°ayZzÎò´„ DÌ*b£ÓÏO³Ö[KÚ`%Ì!7 S‡x_°r6n¸õØÀÎ8§ë ·ÞÉDìÁ;¸%Ì*þùžG°YE01ØFÌ3ZBÂfo»«óŒ˜pÄD$J^×ënÌ6úœ½Ï\º³€“îzx8VLâ`¼Ïxi‹½1ÓŽø ïýŸiÇi‹7ÇÉǾý‡Ã<&8èuç@`L (m'L•»_òÀLñ1&ÀTWŒ ÓGu\¼z›69iB2ãŒæ†€2×?²äÖ¡+nº Ó)¯Â??6þøÀBD”;£×ô«¾è1J©+&kºÖž¨ #™ðﲓx1~7åkRe xfŠuY/ˆ1ÕKYž7HbLl•* ÓŠWw{ïûöMFe¹ïƒ>Áû™H½§_üà"Ü÷±§ësz=±,ü¾oßð3!ã’L•VQs~gbL~˜ †‹Ãä>¡ø‡‹@ÌfsI`³ ñÜi[÷­fC’©9ÕÏ«fWÁ˜"æ%ð˜±ðåÀYˆßýñJxt_Î:¿¿…1MôFˆÃ´Ãã#&KHz$Ì<`:BbÓ#aÂA¼;c¡Të„yè10Ï 3 H˜Àr)ì¹ìº[0ðpÕvL2`”ÐK˜aÀF[ï‘qêŒ9‡acçÈô‚,‹²0¦õÆß&½„YL&`Mfð޹øÄdÂu½îÂdÂÐc®À CoF”Ã|æ0{€9 @/‹ þpÅÍHB/aÞï<6\æè«ÿé›ÿŒ"ö´<3ýÛ7öýþaGʪ'ÿz'bLÙýÿ•ŒSN*º¶Å$ÆT[=y6*@¨¨•Ęj¥$ÏCÒ§1¦ôÕsì( <€À“ˆSubaLr´ø2Iµ®ÆtoK‡„oÏ<ç‚À°$ÿ~' œ N' ±ñâËoÎZòª€J˜4|¼u²ƒ.Ù*lÛ³‡Ö6p%ÀI¦Ïö®dsK<ÒzÙµ· yz’ -a¢SŠX ©ŽÜeC¦‘°»’¬ŒÔYEY‰¹E¤–§&N’Å‘xÿÆ·¿ ßKH`˜0½ˆyFk’‹þmŒ èVÿ?þì,L,Âñ¦/¾²ç¯´6àx öËŠÉó~{Ùc6ÆÔÑv½„ÉG$ñÀ„YÅ!#f½$~àK³ýÀ¹‚šˆ¬ÆÓõ¾ÜôÀ¤Ëâ±ñäê¿›º©SmÓ€IGqÔ±/®~CâÈ8){ÞYm™h 0dö÷ ü0 Ÿ¹ F)X4Q•˜`Ë´ý1ìAP¹1 Þû˜Ø-0L¶K$‚dJõÿ½ÜÌ×c*7<¾. cª‹¬r0 Í$a—qßâe—Ý0²æ(øòYÝÿ}ü+§T9\áÏ @Æ4~ÃaÓ^x¨S§NÓ®‰.â!“<&`¸h5›õn³±£Z“}Øì…2\TÏÒxiyÔ!ÿôÚ§IŒ‰ ÄWàÏÿvSiŒñU¬€…1ýÓ·Âæ%dþÉ3WˆéBAO:tÚM·Ýc:iÇG+ Ük{®ÞnqK.±\  ál·í˜C|ÚC¼ôÚÞ˜mÄ;&±!3‰}D+ÈÈÏO·ò q¶$I1&kA¤mú²0&{nQfÅëf‘àŠéºÞwËôâDY%¹v7/ÁÁ&1]BÒyFÁ˜né;èÔÎÈl#0&Y.‰ G˜FÄëû‘3AÕ`VÓŽˆ‡iGñ½Œ©çO9ë‚«nê‡ùÇ)/lÂD$f5aQ¸“|¾—* —Ôž?¨Ü ›‡øa&û¨Gc‡c D[·«¸9†L44 pKXU/ &ñÇWLWZŒšÂ´¯åiþVÃ(µË1J¯­ô~ë;›w~ôգ,<'h¦Ęš©~þ®MŒ)u^«ƒdr† …¥3tœ]îû×µ,†&Üô­4w3†pˆ${ÇðU˜ xnðå’0 ¦«®ï…›>ÒG>¯Uþyž:)à*€iÛûår !@2M]°Z½uš¼»4<>`ˆ(ÃEa˜œfóô* šÍfµ0LÃE‹a:ú¸Uv Ù´¿ûÉ—_}U§òò´YS€·ÅŒ)zÚ8ÿî õQxH„gO zYeM>ØXæ-!!0œrK‚1霃ÝQX}…åÑÙî1°JJ–H-°&L5`ÂáŒsº¡×%v_Ë3ØoM5Øâúh$z{†‹£0«€¹Ì'ˆ×%ñå,âËyÖÒ-O<; ¾—]º¥_ fú=l…Ã3,ÞųD¢½$3 H–çæ‘30 Ì¥øo¾ã¡aè¸ðncL;ùÍHˆ2LR:“dÂ_Æ¿¤·2_UºDŠYŠf•·ÁòæîrĘrWåM-0íµM•?í’IoúâyQIÜ÷/¶È"á¦/iü¢7àÊ¢ûý .ŸÇì’ì²É0‘dJEƒ11&`ÒÌ É4eþê€áâFk¸ˆÔµï,lÇŒÿe¸èm6áÃE“a’fC’)'™äm1¤cŠœv؇ä¯íMöâ($ÀIgýª›9B,=0¸ÕŒ ,Iq%8uÆ3¦Î9Ès¥ørVïÎð·$s –$}×ß_ŽÉk>aìlL5\ËÝòÐ:–gŸ_"ÐÒõ½ï5u ú£Ç´öŸvvWܪ®ëuf°& “𺄠L&<7÷e|”Ô:i±L&`C¸%lKä8õ½4|‹0 vùÀcã홄“.|ÖO=÷•7õ½â¦¾wò™È츥ïöc¼?9n‘Ì`éw—ÝôË3Ï'Æ”ˆ¾¢y™ ÆÔ<íS|ebL)®QlEɆ–< – +­Ý#k"%Tœ“lKHB,Íxi‹l,´GšÉ\%)sŽöl£3á¨Ë%9G;fœ‘ŠbÆÐ¥…‹FÊŘÄ~³á§Ä°T?Œ Í$¦¯Ýé6§B›1WÕŒRvLTÐä%Û j”rÂÊìT5$–œøa2H&‰ )/ Œ­­­1ûô5ñ‘#ÿÁø-vÂëÛ‚ ôŠÕ‡³DJæ˜&xM\›W/ùCtˆ1%½†²•?Úk³UŸ/ H& Dul)ffÊðO¼é80Š{ß/ ‡Qü I¦ÆWq¹W”Ñf À¤§’iò¼Õq‡‹v,9Þ»ÃÅvÇ“}Xú&’LåVb®çm1¤úñ·ý‡úfô´˜2oµyLaÂõß2ÿ`L>Øsž™sÚÁ†>p¶Á?Ïà™džaXku5þ¹g>!hVÁœRLŸFöÜ\é§ëo{è¤Ó=“СCÏ£ôž÷>Íõ_>……'Æ”ÂJk~–‰15¿˜*@¨R€ÛȯĘò[÷/yî0¦?ß5È?Ù§{ð­e=òM º4R“¤|’1E1QX˜4´cÀùç £Y%1_’Í*àJB/EBK2«hN,>þ¬N¡¥ˆFËæ!Éuð^‚[ÂrÉ$¡KætdeÓß¾°¢i¼¶oØÔMÂ:‰Mû6UßX$ÓÏNyqÍÓ©aAœª·+ZªÒ†Ì‚RÖjTw7Œa’yX¸àR¿mð²^Ý┤dL×G8›ÿ`ðCÀ‰ÀNµ´´èå€1ŸÂEåŠB}Æ),I‡ĘÒQOYÉ%íµY©É&–CH¦â›~!˜‚Ë!÷}×ÿ¢Ë.ë}?Œa $™j2€i¢†Yºô¬-5„\D¹„dš4gUŒá¢…¼2LÆä‰>Æ0’L‹îè>¹{ÇÞôŽ~wµ-X=´(¨y–*ˆe)¡o‹! Æ1/¯pÀ¤¹«ÖD…Ì?xÖD…³J%ÖG•„–„£5“.‹òÏ0˜k¢dz!b5TÄ:(ï"(èyOÜùJé%( Æ”“þSN*º¶Å$ÆT[=y6*@¨¨•Ęj¥$ÏCÒ§1¦ôÕsKÜaL·õ¨ëýø¦£ˆÀÒ_ÀIÂ*9¾”Š(¥ §J^PÉ¡Éë])W’€âfÉN^hIlž‰ÅÖÉK-9Ü’-ù¹¥R.—à~©™^—ÂVRVƒ1EüɺŒî²`Û‚XÿÂR É´hõgu¬Ë±œ13LŽ-Óo”Šf˜FO^pÂÉç~ðñçš/u°Ex©c7pHp_${€á0OØ–èlدl¶x<÷NæÁz! SâÉã ?‘S)`„c䣻ԼÉ1MS~¥Þ˜ôñ/%ù÷¸›ÂW8¬Tðûô(@Œ)=u•…œÒ^›…Zl~@2Öù|Çí¢ëI™ug€g(~ÿ‹€QF'&Ã$HÊÇŸþMJ^ÃLó¥ÌS@EÛñø ³W9ì4|wE#ïå2LÒlÔïX%`LöPïKî±~LOÏS°¬ò¶Ò cŠž[Àç¬*9ÿà[å|p|9ûfŠp%cÎ!®;çÀIßô‚®± säÛ…sÑL‚ãxÉï¼¹jz‰SÞz.bLy«ñš”—SMdäI¨ T æ cª¹¤k¾ߺv#¿«$ÝS$yc½…D|ÓÐo”RP)ĵ’,‚ Ä•Šü·KgK¾q‘ΖBâÄø[*Í-Yþ¬´ÃIµ›vŒvÿ^+oLaÿ¶–-‡ <¤Çìûÿºòk“[×¶b¨&›ðQ~‹~/ôÃ1ÑÜIS¦ÿ³S®zËšnvc:µ/µ­6aV!ËT¯;>þ¤ÎânÊ|R'IÂ*ŠH<6aC,áA‘€ÉWêcIÝÅtÝ ÊäðÑ$$W¸€$É­€Sš[ý9öhXMœÐÌ¿g–¯ÊëGyt’ Æ”äÚÉ^Þh¯Í^6©DC{#RgÐç¾aØ*+\ïlŸCh?L£ìÜûÉ—_Y÷}ÀÈ6Æ-¥`0¶ÁW:ži’N¼l‘›6oùá}nV[Ðp±(œ'–\e šÍgŸ€ašÕ£ 6ðÐÜ/½>Í I M{7XD»g¿xi¢£¦Œ7bÞC*X0¦ˆy |…\0Ñ»&Ê»2*dqTÙ룂|9»ìlaYTD z7}”Ë¥Âj¨U»°ʳ*Vèyã¥;â?ûÇ?’Þ˜2Þ;¹Å#Æ”“Š®m1‰1ÕVOž P*@j¥1¦Z)ÉóPô)@Œ)}uÆÇR wÓ-}˜D‘gߊÑ(~ò®b ŠøV—’xTŠ•"X¥2p%+ÜX»Ç‹»|ô„‡3<- %¯³¥ª¸¥&£KõƘÚÚÛ:>Õï0òaCL€ˆ´¡ 'üAñìrpI×MÉtâ)óÛÞT7þâdKƒj=JMÚ2£ý0‰-óÞ‡Ÿ8îø€HyÀƒ4´x }IO#Œ”L·LòêСƒDmÓxsæÁ äT¦&³÷2ƒÊá0@Kx×ó‹£&/çoOò½œøgÒüˆ&9‚MrEùm¬¾“¥EbLi©©lä“öÚlÔc2J’éÔ³Î3LJN,`\vÈ®Á8­=â¾_Ärë¦};Æ*º€´ö`jc'Æ;9ÉŒ¹°’iܬ•Þá¢ÄvÃ9E#ïѱä}† ¯Ïì«nI6€+[‚s&qÂ4º‹5è•Ø/Gn_4Yð&ìÿÄÊˬ¼-†T­`LÑs8T¢ÿ˜ÐùÃ…shÐy{ÚÁN?úcÃN5…žŠçŸ^ˆr¹d?·©¤×%w&¡Î+ ˆ1e¶_*.1¦œTtm‹IŒ©¶zòlT€ P*P+ˆ1ÕJIž‡ ¤ObLé«3æ8–yĘŠ&þŠ'û€1zÖùf7ÿvpX7E‘ü¯ìY²®Ñœ@t& }1à“•xÜÑäzkW„Å;™+Z*Ž Wnµ³&²2h AL<Þ]K â–56f*æ–l?‚¶+AI¡ãà¹Îè’9Q@Œ)›’¯T>ßýX[P)9)/‹Yˆ1ÕDFž„ P*@j®1¦šKÊRÔ(@Œ)5UÅŒ–§@î0¦Þ}DÌâ[ká» I [ªgL*ÀIEÎØƒ%#æ CA¥p×Ja–Â|,Kñ<-M2Ú–3Iž8qœmŒï%^¬Æ&I°$µüa[<0á%ßÂì‡oñ.)fX›d:yÎòíE“¦I 9Ǔϖ“a’Xr yè®$TÈ!Ù)qâðnb@Š1Ià9|3„ éˆ1i”ºˆ~ËãIü6álà$«TIP9É›xf’ÜjÌxÏã‰áäÊ»¤âhbL©¨¦Ìd’öÚÌTeb "$S4Àdù_´ïûÖÌ5ñVÀ0éźéÏî’Idð `$ðœ`”ÉNŒf̈C2™¾¢äpÑj9úV䬒8[±€ `>Âñx&©Ù‰8‡Në,³ ð¶Rµ‚1‰¿½°É‡¯ÿã7ÇÍ\gÚÁëN)deT˜çÐ9‡xŽœ]OKQ^œ£¹¥Â¬BÐ|Bø5ù 1¦ÌöK¾‚cÊO]ת¤Ä˜j¥$ÏC¨ µU€SmõäÙ¨@š Æ”¦Úb^ËP wS¯;ÑE˜ã3¾uV½ËN+h—?Y â#R‘Û¤p/JQ|’„ ‰*¹VªW‚S÷HæšHïÊÈ0h©±K$k2AYŒI"Ê™–?ñÀ$M !³Ÿ± 1ÿ¸ ™:þôäYË·¢Èe¬ŠóÙ2Ëb˜$à{$ €$%TÅ9Ž?¤’0C À„ÃäçÂá…„üG”Ýt’¤WÄ%äüÂ!!‡’1œYÏa§äÖD²°G²äÏ?ާ7¦˜-0e‡cJY…¥<»´×¦¼“™}L'Ÿyž ©›äŒû~ÁMEe “ QdƒMû¬Û·cº“”°¹ÉÔ-ç¹’èrÏN[2\4Ð7×}We tVV ¢Åaü-‰&@Kø‘ã$Àœì‡O&õÀ´«mð¦œWV–‹ÏÛbHíc¥0/aL>à€±3Ä­ZÀR(s:"xþÁðß¹2*À»RŒeQá.œ½A⬹ÏÄBˆÿæð&h¥º\Š˜O Ɣ宩¸lĘòS×µ*)1¦Z)ÉóP*@¨@m ÆT[=y6*&ˆ1¥©¶˜×2ÈÆÔóއ#0#|k-y÷°G>÷H²`Ñ“¼aÝE ÜYÚ(3†…yCPJq@%#\°k¥`ïJ¡¸R¤›%#<\b&«á™ê„1Á,i¶@¸.€µû…g‚ÙOöà˜r=É4sÙ¶bC¦e‘ò¬ª‡20Let!<” $\bL ¯ ŒeöÚŒUhbŠ#$“x^Ô(râ„É߯˜aBq1DÁ@êÉ?€‘oqF/Šh'F*f¤ €L£ž_®ÃEÇggy/à3L¸ž°J²ÈqÀ’ð.“«„ØÌsòQ£Ë±ò2¨o‹!•*SÔò§µ»q|ªÎ<”ðÙlÎ?¬Ù½0ræ!ÖlÃ*Zòó>¶aJÁ“"WC…øo®æq¾N¿%Æ”Á)¤HÀ˜–ï왟ò²¤Õ+@Œ©z y*@¨¨‡Ęê¡*ÏIÒ¡1¦tÔsY¶yĘ"x#`L°•’Ö´GOš(’Ûš(Ô´ÚŠæO†cvÛ^%É= •BY¥²q%70\Öˆ¥À)Îz`LíûÛÅ™éc †@Ù)ïxÉaâí ÜH¦c;<}é2q,+\­…­Fd2LåªÊã3¨1¦ Vj‚‹D{m‚+'íYÉôË3Î żïK$_áTÃ0éÈæàÄ?€TñßKÿôIDAT‘ÁŒŽgÒ®m†ó/$Óˆ©ËÜ–<\¬†a‚z&‡„@rHØi¾ã#<0éW"¸çc†k!×Eãm1¤úcŠžvÀ£%4¤…"• ‘§ œi‡Òs±f|¸’ëfÉ~5Sˆ³%cn!þ–¢ù'bLù黀1-Ü~Q~ÊË’V¯1¦ê5䨠T  cª‡ª<'H‡ĘÒQOÌeÙ äcºù/ý#0#|«a;‚#Å€bI€“‚ù¤(Dɦ”‚Ö;ŠAË ç›FŒˆ†+%Ä‘{VzN[Œ©ì?bE?’éù—¶š“YwôÃT‘®üQ¶ Æ”­úLzih¯Mz ¥; ™~qƹaà2†7U2LéV‡¹Q@H¦Ö)KMß]æp±J†‰ÂS(x[ QG0¦èåO8q!K®€*µ&Êv0ÖD•¿,Êv°4ÏP –Ü ó6\[´ª1õ5¿ 1¦ütnĘòS×µ*)1¦Z)ÉóP*@¨@m ÆT[=y6*&ˆ1¥©¶˜×2ÈÆtÓíý#fúðí/Ï<¯Ø’ GžäzHòùI2}&•`’€%iŠâ“bQJÞ0pî4"@¥`VÉŽ—+\)lf3½þè ™ŽétòÔÅ[á‰ÁtÆ@?Leô‚<4Û cÊvý&­t´×&­F2—‹d:ý\ñ¼èÅ‘aÊ\m׬@B2=3y©¸H†©f*óD ð¶‰1EO;c)A!ÃW@•=ùNCÂ…²J¹Š8¯“ĘòÓ«cÊO]ת¤Ä˜j¥$ÏC¨ µU€SmõäÙ¨@š Æ”¦Úb^ËP wÓ·÷/ÀC&Hdoã[ ØQI²Q¤H‡I:EX˜+,éE)À—’;L¥(PÉgâªù"Å œ0Õ“C2ðËÉ/n1ë‚~˜Êèyh¶ Æ”íúMZéh¯MZd1? ™N:ýמ¦,Vu-Ë$$ÓðIKÍ–C†©–ó\ĘÊiâ)zÎHDÈÐTz)TÑ´ƒãQ)Žóæ’k¢Ò®Ê™ bLå´ètKŒ)Ýõ׌Ücj†ê¼& T€ ”V€SixȪƲZ³¹/Wþ0¦>ýílÁéÆ>ý­#â÷++‚›¦Â„`ˆ¯uA‘ü©È»ÀIÅ3†ÅˆR‘ovYNMJUÎNâçiǘ„d:Ú ™È0å¾c§†ĘØ©1¦FªãkyH&2L9n eÝC2‘a*C;Z±¼-†HŒékÿøÍèi0bÊ2ãgþ¡‚ɇ€icA”á¼¹xÂ!ßΛ‰1Uü¿O݉1¥®ÊšžabLM¯f€ P*@ ÆÄ†Aò«1¦üÖ}ÆKž;Œ©GŸ‡Â "ìÇ·Õq@@ì6ÅüÅ“ƒ>ÏI˜% "“È'5vqg0&“d"Ôñ>›Å+WbLå*Æã«Q€öÚjÔãoËQ@I&2LåÈ–÷c•d"Ô÷¦Ð°òó¶1ýÃ7£§¾ößl²4îüCÐ̃=Û É^åI}î®~R#Ï@Œ©aýDÓ/DŒ©éUº cJ]•1ÃT€ Pœ(@Œ)'ÍbRˆ1±YdTÜaLÇœpò…_–àÒæ_¾÷ýˆܯ®»ðâØé×]h'Ø™˜¨Àù¯ÿ­óyÝ#2vèáG_u}¯Í;?2Óß¾ø*i}|2!«'|úú­ïxrk~ܹ÷“f>ib2?ÙQ€Svê2 %¡½6 µ”™<üèw¿÷ý«.¹$⦯pßÿò«Ä Z2S ©+H¦;ì_ýñ÷VmØ=\üìó/RW:f8q ð¶Ž1ýŸÿç:ôGGG$ðoÿqxô1Þo?σL5Qà›ßþ_ÿÏßÿèSuèÐÁÓ‘îyïÓÄý ™¡R c*¥¿÷*@Œ‰m‚ P*@’©1¦dÖ sE¡1¦F¨Ìk4A|aLkÖ¬éSüžb¦K®¸îüßüÁ³“³­ÀÙ¿îV²€ —®O>Æ„þcÁW®ß´‹ SºR^2± cJlÕd2c´×f²Z[¨M ÿê¿lž>2ú¾O†)±جŒ=4ýŸL½™ S³ôÏ×uy[ ¯ï¥K—.0^S¦Í1nš™ú~ʳ']‡Íºä™ÉƒÒ•g3·ÃFM|ä‰ÑùŸ2k11¦ ôiĘ2P‰ .1¦ ÎËQ*@¨@Lˆ1ÅЇQ *@Œ)ƒ•Ê"Y ä cò×yôúu~KÂH¢C£w¼âïÌ–gúab¯ŸGˆ1å±Ö›WfÚk›§}¯¼cÍÁ:}´jFÄ}Ÿ SF©2Z÷9[º/Y¿7°å`¸H?L¥$ä÷±àm1¶Tï~øY–½7íxgøê¯MXz– §,ôÆ»É'è@bL ªŒ”d…SJ*ŠÙ¤T€ äNbL¹«r˜ ¨ĘØ2ª1¦¢Haqf¦x €IĘÆ\{÷ª_?°ÿc‘aÊhÎb•R€S)…ø}- ½¶–jò\qøèÀç÷}2LqÌÙqÀ˜n¿¬’Ÿd"Ô³¶Pÿâò¶[ãŒaLó7Ý4iÍ6¯¿¢lO&cŠÝät 1¦UFJ²BŒ)%ÅlR*@r§1¦ÜU9 Lˆ1± d]bLʨ@% $c²]1YÒÜþ>ûœ &Ôõžœå W€[G# ½¶‘jçãZö¶OîÞéƒ77yJ¼èŽî»ÚÈNÉ„û>¦|4ªJé!™È0U¥&¨o‹±F–0&qÅ$SÞ2cŠÝät 1¦U³B¨ T€ T¡1¦*ÄãO©@Ê 7¦”W ³¦1¦J–l¯ déâ(8ŒI\1IêñõƒŸª$&Þr­1¦\Wà O{mÃ%Ïü_ŸÖºôáÅÛÈI¿R’‰ Sæ[Eü¶µ·E¬$¦øªòÈ2àm1¶XY˜ÔS2cŠÝät 1¦UF"³²iŸw-A"³ÉLQ*@¨8HŒ‰€ äWbLù­ûŒ—<ïÓÖöý˜µH¯lý`óÎÇDŸß¦K7÷X¹éÝèNVV3Þ£²xÉS€Sòê$Ë9¢½6˵ۄ²aÝåàJØ€7¦Y=º Á “d_áÝÜ’é­w¬ÚOŽÜ»¡ÂÒ„"ñ’ TV·ŽOu,yALÛvïÇ{É#y([ÞcKöÁÇáAÍÕ5¯½õáKë߉³Þ¦¹Ç˜®˜2æiù†}¯nÇìPÔB8àh±ëœ&EbLI©‰Dæ£Ëè. ¶-HdÖ˜)*@¨ ^ˆ1±MPü*@Œ)¿uŸñ’çcáñÉg_D¤?ý[ôü6{ ”¬ôÄYzLWL†C¦Œ÷^,ˆ£1¦8*ñ˜Z)@{m­”äy\À0 ¤pδzh?ìÄì®´}ÑdloZ?¦_ ç¤PË|*°ÿ¯û{ÌîŒ ¶7$¸ejYÑ‚~/ôA9‰Y®};v"ÑÙ@>›J}KÍÛb}õMâÙ_ÙÓ_è%3í;°&‰yež¨€­1&6„00v:dà!PáGÉÈJ~‚²Ñº¶C)ýHI© T€ 4EbLM‘¥‰P€S"ª™¨½yǘj¯(ÏH¬€ß“á©Áyáå¨@â Æ”¸*Ét†h¯Ítõ6¥pâr /`IH ”À- ®„„ý šÄ]“†ãwµ-ƒ…sâ+· tŸÜæ4ðLØ€/ØLÿLblÃÔiòk“‘â¸nÊ­˜,x… ð¶X¡piýÙ_~Úºöë~ŒiÖ–Îi-óˆ1å ’+,"(pŒŽðŽñx& ¨0^»bL؉SƒsÂN†wåÅ+¼$F¨ T  ˆ1U!JR®1¦”W ³¦1&¶ *rü®˜è)åUÊì×RbLµT“ç*¥íµ¥â÷e) ((%0I —dÞ͘qà–ðQöcÂI9§²®Èƒ³¤ oâ` 66±·á6)£˜åðx“ì{²¤ËÒ|x[l~44®˜„j¢C¦†Ö/VŽĘÊQ+_ÇbàeÆ`I6dª 9 ._×Ãò¥KK¨ ÉP€S2ê¹ ÍP€S3Tç5 1¦ˆÌKPº)ðù§œ|ðÁNVºç'ÿÔá`ïï8±gýŒº]˜'¦)Q€SJ**#Ù¤½6#™”bˆ×%äF#Ê ¨${ðŽoáI²+ûñþùýØÀoõ«¤”‡ùh¬â!/µ®TÒp'ò-Þao“¤ØSc³É«eZÞ3]½þÂÍ}ãü©›:IºúùïúqÍî»s&‹›ˆ1¥¦ªžQ‰º‹Ëb¥Ø·Ž¯ä[ <§£)åÅžY^ P*@¨ÀAbLlT ¿ cÊoÝg¼äĘ2^Á,^ŽØ·í îUSúä¨È,*(©1¦’ñ€*@{m Åä©\tGwxZ‚â .—@&T:°·]0&ÙWL-IŒ9ÙI ó¬€x€Ø0ýˆ¿%˜âä[õ( ±çò¬Ë^x[¬‹¬é8é¨ußÃ”Ž¼2—ùV€S¾ë?ªôâºRÆKâáRÇW²îš0¦Ò¨&7GU© T€ 4^bLלW¤IQ€SRj‚ù¨±Ęj,(OGš¦1¦¦IÏ 'XbL ®œ föÚ V*‹DR©ÌlKNüHÀ3Á€&ìÁ·0ÂÉ»ºHe™éd*ÀÛb2ë¥!¹"ÆÔ™y‘(@Œ©"fôaԄ©&ÀLØÆÀ ûÕÛ%öà#`&Ý“Q=X,*@¨HºĘ’^C̨ŸĘê§-ÏÜTˆ15U~^œ ÔPbL5“§ÊŒĘ2S•©(íµ©¨&f’ äCLð±„d;a3÷ã#v¶ïoχ*,ecàm±±z'êjĘUÌL„ĘØ<ÂÀèH¼1‰+&yÉÀ ò./l›)) T€ P¦(@Œ©)²ó¢T  cJD50µW€Sí5å©@s ÆÔÝyÕd+@Œ)Ùõ“µÜÑ^›µey¨ T  x[¬B¼´ÿ”SÚk0?ùrõß-Ü~Q~ÊË’R*@¨ YU€SVk–墥 ÆTZ#‘Jˆ1¥²Ú˜i* €`Lv:øù§Ô‡ PGbLl T€öÚFªÍká¾?õöƒo­¡T€ P„*ÀÛbB+¦Ù"ÆÔ•yZ(€¶JŒ©BòT€ P*@¨@“ ÆÔä àå©@ ÆÔDñyéz*@Œ©žêòÜT ‘ €^úó¿Y$ìš|Q* cbKh¤´×6Rm^‹ýÛ@E ¼ýñÒ÷?ÝXÑOù#*P¦¼-–)X–'Æ”¥ÚÌvYÐV§o>9Ûedéj«ÀGŸmÛõÑ‚/¾äÂÚêʳQ*@¨@µ cªVAþž ¤WbLé­;æã%'Æ”ñ fñò¥1¦|Õ7KCšùcˆÄCj¦íµ5“’'Š¡û·"ñ¿T† 4BÞ¡rB¯A4$¡Ãlù`[e£(WbLå*Æã© T 1 cjŒÎ¼ H¢Ę’X+ÌS àv Dä)¨@R Æ””š`>£Íü‰©Š\d„öÚ\Tsb Éþ-1U‘®Œ,Ü~1¦tUYŠsËÛbŠ+¯Ú¬ ©VAþ¾Q °­6Jéì\‡Svê’%¡T€ dKbLÙªO–† ”£1¦rÔâ±)R€SŠ*‹Y¥¥ ÆTJ!~Ÿ;hæÏ]•7µÀ´×6UþÜ]œý[6&ÆTy–8 ð¶G¥ŒC4$£›Áb±­f°Rë\$bLu˜§§T€ P  ÆT¡püÈ€Ę2P‰,BĘØ.¨@†€©àN?Ü¡"±(T :hæ¯N?þº<h¯-O/]ìߪÓ/·¿&Ɣ۪oBÁy[l‚èI¹äÜ7ÎiǵIÉ óAÂ`[eë(WbLå*Æã©@SX°`A?ûÕÞÞÞ” Ä¿èþýû[ZZâäP(][[›ù“M›6ÉWØ0÷·¶¶b§ž_Ï Ë©â\:Î18[ ‹sªÆƒ&”–¶DŒ©1M‚W¡IT€Sk…yªĘj "OA¨  U€fþ„VLF³E{mF+6¡Åbÿ–ЊIz¶ˆ1%½†²”?Þ³T›,  T€ Ø cbC ÉW G]ºtôäC™™ð•)‘žÇà‡òÑS=FÔÓÌ›ê…Iç9•ªóxÄ—#¥RÌz׋ªtšëiµîô`ˆ,µæ©M³.—¦½6—ÕÞ´B³kšôé¾01¦t×_ºrÏÛbºê«üܽ ÐCÒº¶µeE R—Ñ]°Ý}rw|…óµïoÇ66à_É·å_‡¿ Õ*€vˆ†Šˆa.İ« R¾’o¥­V{Iþ>» cÊnݲd™R@(Ð*@O„ãш`Àt„¤Á»øæ›"!lð+lãxuVGX"=XeÒH>â*Âɵôø­„´3}#éaBÕèWÂåÈy«òXR"ez$cz ͘ž'ƒŸà¥‘æôþú–̘…Õ‚èÁz9Âd¿ê)ù·OâúH&9L+B¤Võäç8›†ÿócLòάgÃÏE@óü‚%ÉåÔO•Ö¦‰1IÕ›d’Ô¾çüfÁM ýê%a1¦$Ôó@š£1¦æèΫÖ]bLu—˜ 5Tàóû…UÚ»¡ 0>bø({ð`?’ÐN —^ŸfM¯Óž©†™á©¨@  ™?•”¡,Ò^›¡ÊLAQØ¿¥ ’’˜EbLI¬•¬æ‰·Å¬Ö¬Q.0¨KÈpKØ/"‡,ضà´Óþ¿îG†Ãh¤huâ6 €Ú'&´F´XõÏ$ß*i‡„Àã‹ ø¨Æc¹²b;OµÚ@*6ðã‡~o1©Vƒ™O”Â3Yã“â—é‘H0áH‰kÖ¡Cópù¹§\8³8ûÁKøÿ%Äð`Læ¯<¾ #¸’¸Ò—8 Âñf´@oL7NÂ3éŸ4,¨œ`L& „Kk$úQ‘ G$’â˜P!)Ž HêIKg:sò\ÅQSdù¡y~%Òä‡&_¥ÕdÖ¦§tžJTN î©*îâ<ͦ®‰1ÕU^žœ $ZbL‰®f®rˆ1U®I¯€²J¸4¶wµ-€+&pKÀ•°!n™@/WÂWØÆ~…œp<25¾ÊxÅ&(ðán+–œ¤yýb 7áæÂž}Ûš%^2' Ð^›“ŠNH1‰1%¤"Ò}Öìúh¤é›O~¬­ƒ~ÄÆ_~š†B0)Q-†a†acºƒ4¾²¥€bI@C„OR^Û=f÷Mx/‚4„½²ÕÒQq†¼š|’ÆCi‡V*ÞŤ¡"Ñ!S:ª¶¹¬Æ$h…àx™„A3ŠUí5áפb˃T›þ>÷ x(èáaY°G}©Zâ•Gý!™ÿ`ù• â‡NO(¿ªc¿I\1‰S(Ol5Ø„Ã$œYíRÓ±Y‹Æ˜T19§ ]zþ8“,°¦BŠ`˜ÌŠ0)(‘Ýì üLNÈ^žó›ÅT:-Г–NF†ýç—ÃP¹Š¬%ùFŒ)ɵüQú*@Œ©¾úòìMS€SӤ煩@ («P n–'‰& JØ–sb?襥÷ÀñuN2UpQþ„ ¤LXÈ®ø;Ël˜ÞZ“²â0»)R€SŠ*+Y%Æ”JlT^ÙÓèR`¿á°Få‚×ɇh…Á°ŸÃ°Ìµq¼d¢KÊ‹`¿@!81¼$l‚œÌÉÀ%]!êKqæi´øVÚ'Ð%m«r<_TÀ¯@m1&=¿I€?0ñØÎÅÞ¯$îÑxX²¡,΀ î€_y~î9¿æûÁà`lÈNÙ#|’^T¾2Y l›“çüz¤rž »€_iqQúg⿯€ÅW„A ^†wl£± ^ƒ=&u$’6~‰Œ&ˆ¡ü<ÐÃ$ò_¢,ŒI.*ð N+DŽ!òcLÖÝ­{w)¯dXq%‰%'ÿ/u†„ã#0&¿³€•8 %RDR#%1&QLtƶÀaøh†ç“>ÄãI*CÎÍN@/*âàHþókÝáºr Ù#1ædÖ¦\T[…ÿüRjbLÕüù[*@¡1¦F¨Ìk4AbLM—¤+ ¬’ KxL’Xrò޶/²´Šß&ødRLÀžä+¾¨@ösm° mpçì—%l¢Ęš(~/MŒ)‡•^i‘áo©uí×1¦mïO¬ô¬üQí@’‰Ã°Ì5 JâÏF‚ÇIù„‘9áGôøÌ)Á%]!ê¤5ŠÛ0màêÐPñQ|2II4ZbÒ Æü5CÚbL~oLŠAȆØÔ…»»Çèn5l_Ô*ìû=~Ž_á' xÎoJ¨ÄƒÚþeÌÿzQÅ5„™ÀÏ£ 䄞_ýKyü øK¤ À"R¢fÔ-¯™)ÐV¥5*™„âIÄ1õæA‚üq°þÜωç&è¹>z(Ck°ä†Š8F)@!üðQQ? aqë)°¼RdáŠÌâ8”Pr¤¸&ò{YÓ™dœMÏéù­ ÊbÊaæÏUd)¸ðFf1õ¢ÒçˆòZ"Ïù¥txéiå'xaC~e_ðMÝã?¿'·IþŸÐS’k‡y£õU€S}õåÙ›¦1¦¦IÏ S V /0IØ¢—Kx?°·]¾¨ {ð>™°G¶Å9SWäO¨@*sÈD©¬ÎôdšSzê* 9%Æ”…Zl\2ÑSã* WW sÈÄaXæš‚pÿ€û%pKx—òM~m2H $'Pöà0l+J’9%X ¤+€æ'­QÉf’f WLJ/I+EÂΤ‰ùkž5ĘÀ÷ÀT6Ô‚Žmq©"îR$ª”Éa(´ ÑĘü˜Äµ‰çü¦Êù#1©wÁ•Äý ®®yPŒÉôX#Žd<SX‰ôHœÜãý¥yµÍ+S(Lö…JU¯€@“8cªþä991¦œT4‹I ÆÄf‘Qˆ1e´bY,*@¨@Îð;d¢€œ7‰ŸSDæ%TbLl å(艮˜Ê‘Ç–£€ß!‡aåèÇc© T ± ÔcRw#JЬl“N€~à)ßb¿crBBQDcLŸ+þó«Ô&<$WÑkIfô%¨ä_ÞcBnM*’1Æ„ƒ=%Òü‹‡'¨æo&±­‚˧ø#øåSŠZ•Z:C¼V²2I‰1U¦E² 1¦,Ô"Ë 1&6 *@¨È¢~‡LôÅzNV™ˆ1%«>²žbLY¯áš—Ï㉮˜j®0OXPÀï‰Ã0¶*@¨È„õÀ˜ Œ¸;  A…—„@ô#÷Á»îîG1 ua¢{$¾•ü\b0yÎoÖ‰òFz݃ éE5º“DªŸL¦7&Í¿‡…’ð[%ßQÂ0™ T&š A¨hĘ$4/C¨1¦V ³T ˆ1ÕBEžƒ P*@¨€é‰>XAÙË1¦ìÕi’KDŒ)ɵ“ȼy2ÑS"k)C™22q–¡ŠeQ¨ 9W N“F¬&Aâ€ûèB¾GŽ”d|…wÀFê!IÀ ý9Î _ùϯ*ŸälâI1&q³„¯ô<ø;;tè G*ÆdfF*œS€'9¹¿D ]É•»ÊyKcñ© å*@Œ©\Åx<ÈŽƲS—,I‘Ä˜Ø ¨@†€Esêí?y?CEbQ¨@ ˜™è  !ùÓ¸ cŠ««…Ęj¡bÞΡ™èŠ)oUß„òš™8 kB4ù’o¼tß5MÎ/Ob(À¶C$R¤@­0&¸,òDMÂGñc$þŠÌo )–„@;yöèGù•çÌžƒýç— G…ƒñ.{<±dîñ Å Ì¿:j2³d)‘騿¨ T ˆ1U B2¢1¦ŒT$‹áU€ÛÈSúÄíjß¶ ‰E¡Õ) ™è :ùë¸ cŠ««…Ęj¡bÞΡ™èŠ)oUßœòŠC&Ú£~“¯:jÝw¦nêÔäLðòT †l«1Dâ!E Ô cJ ¬ê{©)y#%›šru^” P*ˆ1e Y*P¡Ę*Ž?KºĘ’^CÌ(CbLeˆÅCó¡€8d¢€|ÔvóKIŒ©ùu§cÊSm×°¬pÈDWL5Ô“§ŠR@2q–ËVB4$—ÕžÊB³­¦²Úššé cLñ­Y/¸€jnšUp^— P*P+ˆ1ÕJIž‡ ¤ObLé«3æ8–ù˜ž}öÙN‘¯Ÿüä'ÿþïÿ} ¿Í’Çü÷¾÷½è|òÉ»wïŽõjöAïï3¤#½15»Ru},w‹nÿÇsLÉÿHÂû„›N;4á9ŒÎôG-Dƒ»[ªÚ]v3KŒ)»u›Ä’cJb­¤ O[¶¾vû=W¤ £ÌbúøôÓOû_}AúËÁT¢À¥}ÿ¿&QÉ/ù*ÐXz=úÍÛŸ<´±×äÕÒ­À ›útëÕ¦âtƒ¹/_aÆ͘1£üßñT  `èÞ§O¼§#»ÌeĘØ.¨@~ ƔߺÏxÉó…1]tÑEW^Ócüä™iÒÌq“f^qõ N< Hc'Ò˜‰3Ý4cÌD#M˜1ÚHÏ>7]Ó¨ç¦[i¼™¦?m¤‘FŒ›¦©uÜ´Ö±ÅiÌ´gœôü3cžÚHÃÇq°‘>QSËð‰-ÊÓS[žš8è© N:a ‘ `§ç éÉç6Rÿ'Ækzè‰ñ=||¼“ÿ@!ëÝoðÿó÷ÿãþGÇÒq÷wŸ•ÆJúî÷¾Ô#ù=Áûï¿ÄQÇþê‚ßã‘#ù¹e¢ZËyüÆÛ%Ú} ¤ÛûÞ÷ý?TûCO¨}à³fu€Å½Ÿv}#Æ;ýžÕéyú½ Ïß×iG÷Ô³á½\Pçسi·Ô§y{³Ð~¬¸Ó,¢ï*ê¸|½–Ù_ýË÷¾Ù ·ßÿ˜ÑM¡Ë2º©swîn iQyÏ1¦¼·€Æ–ŸScõÎÆÕ¶mÛ†áb·‹.åp1šäRÀÒ¹sg46ŽR’\MuÊ ½gžsz›5kÖÔé<-¨‰ ~zÒ©HDj¢gN™·<Ôr`åÖÆî"· óÇÐýÄ“NýÓU7aO’)½ÕMŒ)½uÇœSj ÆT­‚ü}BÈÆôРÇvîýÄNüé¡ýúü w¼s@Ò[’ÞFúéM3íùx»‘¶íÞ¯éÝû­Ôn¥­NúhkûG[w}´ÅH›w~ä¦_ßùáë;œ´iLJNzëÃ׬ô¤oÒ†7?ذ]Òû¯JÚöþz#­Ûöþº7ÞCzEÒV+­Õ´åÝ—´fó»šVo~wõëû$­Ò´i_[!í]ùZ!­xmïŠNZ¾ñ+m°Ò2M¯¾³ÔIo/}õí—Ö;iÉú·­´îíÅëöhzñ•=š^xeÏ k‘v#-’ô²•iÁšvMó×´Ï_í¤y«Ûç­Þ5o••æjjÛ5ÇM³Ûv¶NYúµøæì•;giZ±s¦•vHš±|Ç¡‡|ŒÉžIé8fêBÔ#9hšJh›¼l¡©\ã-þÎpÇ^§Àtô±Ç™¡ö„}`@hö{»´ßûHû=ÔÝôuE½\xçïÜœž-¬O³;´åVòöfÚ•i?æïÄŠz0³û*î»ü½–vYÚ_IgõƒýÀcãÐMI²:«VÒžêúÛ¢0)ÿ-bLI©‰|äƒS>깆¥´¦ŽÓ®Áñk¨,OåS@¦Gž‹Ævû=ƒ8PÉU¡÷¬sºb¶aѪ7~D’)WuŸ¶Â]:ñ¤Ó–¿Ú¾|}{§Ÿ“dJ[ý5#¿ žykkkëÒ¥K`AKÎRêo±Ñ±cGœï%Õ QÓqM½µ-cw‘Žc.ËSÀf˜N“¡{Ë“cH2•'_’Ž&Æ”¤Ú`^¨@c ÆÔX½yµ†)?ŒiàcJ)y6`§ÐƘb¢K0áoC*0dŠ˜lC¾Ë0ù&‡aÚh0LÀä2LÀ›a*`L[Þ[Á0m®˜a²­þ¶á¿À0m(Í0U…1 °€b†©ÝË0­*0L€0¦b8`æòt`L˜IùñO:Žº“ÅxÞ¢qÉ•$™Ö‹¦ûBÀ˜®»±·¿Wt¸¥wÀýÒÑÇâ &8ƒØÍ€~Ï 6+a˜<¤fPÿ¦€¦2L«‚0&å2ý½™Ÿa‘1)…€`šð¥I^c—Š1ÁSaò`LËwcJПS‚*#Y!Æ”ƒJ®aÁ0a¸8cÑË.ÖPUž*Pa˜' kcúÜM’)/E ½k·¼'U¿°m뎤O¦¼Ô~ºÊ) ÓŠWw[muó»K×í"É”®l|n›2ó¶iÓ&IA&õë×/Z¡—pŒÒKØsÈ!‡4^· \±èÖÆî"5Ê"+`1L¿8ͺ"É”ÚFBŒ)µUÇŒSª ÆTµ„7“Ãn=aQ7hD޳z?¿ç¹¢ß+t}Žû%7næ›h ¹˜N˜LR³ÏV²Ÿ·5¡[“T~,9ÇSÕ ÓžàIÒˆ+&ÇÜ|7æ¼ÕíóVï2]1®ãvaLÅ=•xŒÆtö¹ÝÌ> Û$™šóß'ÆÔÝózUbLy­ù²Êí2LkÙ.ÞÔóÖ²N«c„Ö°áÆ–žkù÷TVŠø¿ÒAoÉ`.ñÏ=Æ#ŠéÏFDÆ`×Ä·bݬÇK¦G‡x6¹­ßÀsÏ¿ð˯¾*+ò /Øn#ì”uÂì>*yÑT?×¢™Á0i0wùæÃ|ìò•«Jêà9@Ÿ+aà÷4`QÌ|êDÛ(÷¿³¦äŸXVæ+è ¤Œx‰;¾ê¡€0Lmwk[Å3£x(Ä|Úê‹kvÿ³S&M™VîÕÍnJýß ›S%ÒÞ°Ó3ß"ÇÔ»—.·D<^¨ßÌ0# EÒLïJØ–;†C‡€=8RÛ’bLدm Ûr¤d[Ð(­Dü\)¾â+࿵դ»ÐQ þò¨J³Ã—»^ž¡Žt: 6ÇEr¼|•êDüzᑵR@¦è¡ûÃ>ùÔ3|òI­.ÊóÔ[bLõV˜ç§ÉU€Srë†9«JÜaL÷=ühÁ¯~•\Ûü}ý-ŒI‰%ÃN_ –¶ìZòsK›w~Š.‚(9V|ï%XôÕ–¿a{‘û¥W‹&ÛýÒ{’0e,î—"<0ÉÊH¿¿0Ùþ´1‰ã&ÀH®ˆazõõ\²ôÕ·5ÓK@—$­³Òâu{4© l¼€´Ö"‚!;0Sd,¹X~˜À0!=#Aå¦@Œ „GU»ZüXgRÌÉbϵTJ÷Ë{”K2áAÚœ )9,Íf±0?âyêÆŠéËû÷„ # Ëäܳž¬ZæúÆtC¯¢^Ñ@6ÑŽ?ý¨cŽó@Kþn0]Bè£—Ìøqf¿gõx.²ÈkvtÀd»"óL& ‰‰i+ÝZ[—éÇ´ÿ8š*òÃTÃ4·à:Îò'“ºb2ÃÉE`LðÌ”ë–ݬÂcj–òù¼.1¦|Ö{9¥v¦׺ÃEð5íµ.âN‡ábe$f5P¢QŒµþ¶j¼bˆy-Sa˜V½¶'°­¢§’njÑêJH&Ôš¨´(ÁSdÒÃì¯8ÀÖž »Þ½tL‰x˜GºÎ¼¡yh›A“þMú1cÂNuÔ$¬R Æ„3€ž4û@óŽSóÑZæ›Jô­­šîÂÕ˜Õ-q=}ˆt#r’N @1&ívpKõ@"óÍ)T†©äнÿcÏ’dJ` †e‰SŠ*‹Y¥5V€Såé’¢@þ0¦þz})‰G%;Ý×È9çv •‰¥üÐR‘Ë%›[rí÷‘èRˆï%/½ä`2é¥`L>€Ékéw¦:aZüÊžò&× `&ug2ßrgb§UENM `—Æ’† X€bLJÌ´½›˜Éï©éfRŽ´ý0훀Cav)Ðc¸¬<’)ÌX‚™s©¦H°G׌â+6&Y3mBK{ô·²ÎU®%=¥¹ì,>ü””^6ÙùÆtõ ½´,l¸ñ1GŽŸvÔÑÇiïÖ VLmFÓKa®æbLïÍ s/Wä[n£eW3û4À„ÿQÇT3ÄT ³b?L† =UcZ±3°§ ôÆDŒ©9ÿÊËs†Àæöç5ôF­®±ÑŒ¨g-}ý‡e’LÒ!HoãéjÐ0Ðÿ˜t£ Vzþn°þêÏÍ>GþÔžz÷Ô8> DåwÈd¶.ó/o¶.O#D6ôTfï$Î6¤=Ä«bÞ x˜*  S¨ÉÖŘÐV®zë¸ËóÉ„~Éì½¥› Ę´ "q’ðöYï™7ô` bÊR@ôþ rB¹‰VÒ%â%{tȤñæt†™K¸ÈÉÌž÷Öæ‡³îbA™Ý…gT#(jÙëË]ÏB+l»f·Ã‰Ód¶¥dæJ¦øC÷%ɔ̚ È1¦ÔT3Jj®1¦šKÊ&CÜaL÷öâ·Çë|ëÍS©Çõ±d8) –bIR!j’Á-½Uˆ$A”L$Eaã?.8r\±ï¥ôR€û¥!ä¬dÞreL®É†ÿõNªÐ “Œ ¾— iM{‘¦Õí —$iT&30“—a²é%e˜,Œi²å)‚aJ 7&™IynÚ 6áQðÛ_äŠÉx¢F-€·ø}9$“ç9YçÖež“ñ€-Çèê1Y¤óÈ:u"È#™Ôóì‘)i™ƒ–‹òHožM{KY[Fû5¼}XÓõ½(%70"*cò,s %¿¿%·÷‹¦6Kú^²Ú¶Ý¼ ~æÜ¾®l€©'LÑäLrážäŠÜÈ}WÁ‡\D,9?ÄþêPñÆÂ0…•#ÆTÿI§"ÆT†X<´jˆ1U-a†O† ÃÅÙ/®5†‹A®˜\¶cu.–E2 À$c9Óש ²¾ÈxO{22ÄÐ;Ù“™âB‚¡˜KÏ^ÁÏu1ºYý§Õʸ"Î&¾Udä©™D¡äÒj~FõºÂˆíÙ?j5ëñ| ƒ[üDx3Ú ~…¯Äâh’‚2h1=g0ÕÓ²ÈEýlÄo'«òà0LO[ “çÙÄÊ%NSáÙÄÂ˜à—·÷eLƒ xBe©Úø(„Šh+ÇCaSù‰I‡(d 58Þl-øè?¿jåùJRp9¹¢Fèµ¥NÅ“4oiuÒ¼=fËt=ï†^.é'Ø^µ3Ï|iSY$“ô¨tyÞ4A"©M©;H*–~©VÏŸE üòsóOŠ?<ޚϞ¸œÇiÎŒ#=W|Œ•çYù§ë?×Ó,qÁ¤ahïgþµIWù÷äÏUƒaŠÛVç·½YÉT%ÆT¿^šÍ 20ó&÷üße"éÐdX¢Ý‘ƒwéÐÿȈHçåð­ÜeŒ[êJ0W¦j*~UÁ­­¬îÂ3ª‘q‹ÜL}„i“Á¾ $ªÍnG›®D*šDÆ2é0LeÝ2Š>™Rш1¥¢š˜I*Pˆ1ÕEVž´ù äczhˆaÿ°àEÉŽwÏCƒ1Yz7’gÃA””UòºY*KV¼$´äã–Œ€q6·€.Åt¼TVIâ+Åt¿Th©ÙSh ¹r0­‚ï¥BB`&ÀdEhZ±óicÚ1s…× “:dJ”7&g&eºÁ0¹«‚ÄN šåZF–;ۓŰKÁåÕï/½!ft9L|tèÐÏÃò’fa—éxu’)xéÏô+™nöì÷ï1§hå·æÙLóºÙo~Ç™¡cºêú^è d’Ä´7ZÇcêhö„Þn0ÈÕ\Ü@™>^Ó<.’^ ‘é„‹0m|'` tÂdÄTOr¡0•a „/•¼œ»j—$£Ë²bÉ)piaLCÆEЖôÆ” $1¦UF²BŒ)•\Y¦ á¢„Îï8æp1>ɤã48[s\‡~bÔÇ Ûbu“ê${„KP¼FMt¿I†ˆæàSL>²'ð´r•è+"KþLŠíG²¤lŠƒåºøJ1&ëʳ8ŒIWÏ›pƒDA‘‘U”WmTz~†ðŸA/gêé©QOe´xUÖÒð«†ÉllÅ ‹øãÑÆÖ뎇cF—ƒ泉È%jˆ†ÑÁ‘T¤¶"GÔL("C9Æl-8‰ Gžó«Pþ¯¤ ð’ a#†ImR5x&OlÕZ;ØN×óŽzÅ —×Þ…(D®ôlpÆ<}ɦΈ]N°Ù’ERQÿAùkˆE_ªÕÿg‘¿’4Q^H5Ï“lüÿ‚ÿ1Vš“¢úO÷4Kyà•ƒ%Ÿê»K®.'‰ŸYRe˜L´Wž%£ÛêÜ• ™Nž4eZÉKHÓ’N@^rwÀ†‰&H£•³is5OŽž¤¶½tœœó¿™y«•ò~Gqµ:sÏSñ­-~wNÀì.䮤£Õ\o"‚YËô¬çîàï.Ò5Èakz‘¦ØC÷û“djz–Î1¦Òñ*Uˆ1eµfs_®ÜaLw?48Er±$|{ö¯»°ÍóÅñà*±Ja¸RX*ĉûÀïoÉÏ-¹A”bx]²' e®P“]zwµß÷’mÝ7è%¯û%Y2+–ìXKHïXiƒeí0,vzÛ±÷Wàé•=/¬E*raâqÂT \‘&øa²¢È•å„ “¸6±1¦oD0L‰òÆäIyã=x¦‘Ù·Õ¥&à€Y ÊÕEñH&ÓJ$¤‰É cR LÌ)¤“t2qlNÛ©UFžÆå¥3þr]sõ×Mçɹï½k#0¦+¯ëÑ+c:òèŽA=áèý4‰{93Åw5g;^*Ã÷R½+„œÛ³vkn‡EÎöÓ S¡3øKoÌâ^«ˆa*vŒé> c ¥-‰1ÕæÏP“³cª‰Œäão„/×s§9\,I2aȧ»¬ü†¼¦ýU!‘{F˜2ðSÐÄÃ"˜žœä´æÏ…°—=§Õ±¥iò\Q‡¦:ŽH&ûâ9¿ønÑlûG­ú[ÕD[¾’A¯™a¡XÄàIÕòdbRz¼ÿ ~õ´"<lɆiM¯òïà0LÃÝXr³ÄÂ÷lâqÅä4¶—wßü—þ%}2)Æ„<‹ã%)YÃaAÄΧfB))öHõÅÁ˜Ä9–ÿüfmê¶´+yÒG%l´ýËÙµA)„rö¦VÌ´<ï˜w†©.éÄ@ZV×ÀkéÔ^‹ã“Ƀ1A:é 4rd4ÿG¢³ÿψ1yº©²ÿc¬Ô¯ß“§YJÏ#]4a³d[ÖŒGjšNæJÑK^ßrÅ[€W9¯K¹õo{pLõÀ0 &¨iM»2LÊ_ÚQäÚ=®ã"œ0‰Ç8ôT‚1EЖĘù—)q-bL ªŒd…S*¹¬"*Ã$Ïò@¡O þèÊ•X \WL¸—9ÃÅK® ™üŒŽ 8:®«¼gà'e< S®Xv1ü I!9FÌ6Ø/ŽLÄÅ…l/2@‡£þÓªtW”o&ðgוK#cx†Á’m¼ûG­ø‰üV|ð˜5ˆÂrIdùJ\òÑ" ÈuÍQ±‰1yÎàWOÎì`Ëåje †éÑCˆNÎ _hû¶T8@ÛM·— ™<?e>Tm݃š’¦"Ð’ì×VäiEE–ÊUšD+ÐÐ~­PÏWP°$%lp9T«<éˆÝQ.!­-Y*W·¤ÂúhzíõWFW#¾QÛ6Ù¥&bT‚ µ?yÑk?øÑÑËW®Šèë<“y¤þ¡›þcòüYp0ZªFëNz!¿7&Ç•Eàc¬8RŠÎì Ìf)ûÑT$øhZ©‰1•uã‹>X&gÎÍl«®7kA{-äe5¤­Î\¶íØN%|2bLr»”ö`vør"ÆTÃê®É©<óV“<ó$5Q êÖVÜ]H¤‚jº‹@ŒIî².T†1Š+¡£Ð!±ŒO´ÈĘjRûy8‰0L…¡»¬–wcß숅ÈãAC÷{ZFdJl³!Ɣتaƨ@Ý ÆTw‰yæ(PcÂèÙ|5'›5ºêE]ÔïÁ®Ï¤÷Á!ic|¿éü«®†y%–lD)TŠÀ•‰%´äŒ#ÍPqbèûÀ5ç?1bJÏ>÷Í~éUE—o|çýCf-yUó(ºtùu·˜iÑêí˜Uô8^²#ÇYþ…«¶Ýxë=&½´ mÛ ·ÞcZú[†OD‚¥_Ò’õo· ›ˆäñ½à~)Fü¸…†ùßãÉJ„ ˜” €I˜€ê1¦¿~ñ~šgèit&Å?ûÖgØÊ?[4nÑsÚvÊdñèù[ž·eÔ¼ÍH#çn;02ÂûËo.‰"™§nÍéxäÕ<Ù˜‡•)`™…×)xÙ/f-ñ¥äß#Fý­9u‹ _Õ%Óúõn 5?¿1Ýìé Í>pøè©@èbú–sz¿â q½ÿrŸv}CGMé}û}ó–nTsS殼ê†[§ÌYá Žyåõ·Îyiƒôx@—zö¹wñËoJw縗‹ŒŒ9ýÅõ—]{‹Ó¡—B¼Ê½Ùj+™“Ç™\„&ûÏõÇ+{: “‹`bOt¹¹m»\†i§b—³Vî´RÁiœ\Â!ܽÕ`L›æÕ¼Ùð„¡ cbãh¤Ę©vâ¯e0L^°`äÜ-Öpñ©·Ù鮫124‡‹Ï½ðFa¸hßÈt¸F2a8ç1ó Î0®3±"jÈ$qM¡cŒ[ûbè5Yɵ[,\òÞQ/˜»E&p!ÏÌ~ýéY¯cìmw5Öc騹›GÎÙ¬®˜„`CtøI 7F“Lª‰_ÙÓþYäÿ%j›pó_,—ˆ‰1á<ž™ùÿÒN ‡é_[›%.$ÖßÕ˜ù‰ù—Ì×aû¶Å,¯0Lm÷HOeÛk´O—÷ŒZƒù+´Õ± ·Ž]°uÌü-ÒV%ʪ,_WLÚV§/}#šd’J÷gO€,ÓŽ‡É‹çøˆ^:fÁy˜WØý[ÄÌ&%pk31Í[‡.Ÿ´x»yw.®Ì™7VV}ˆ]õE·¶âî·6Ô¬éü^» ¹µÉÂѲº ÿ¨FuÀmBX[s.TnB¾šcì÷w;MHÔ·.yö0tÿâËOãH£ “è³Â½£Ö˜‡ÏÜ3šðhýºšdè~×@’Lq´oÂ1Ęš :/I¢1¦„T³Q¾êu[`$›•3•À˜Ä·¿¼0ŬKÊÏF"~Œ©ïýxb™ñ-få"(6ÒøUˆ00*\@l8{¾~OKΖ:ÿúÂÃŽøÉêÍ–ÿ·Ý¯ÀÇ+®¿å°ýD¸¥ŸžtZç_]\ {f.~UfÛl\é›ßþ®bL—]wËÂUÛÅ´o£K½„F1ð7燅 áî‘ÆL[zÆ9]ÍÈqº¦7è%'­{û’«{!©Ï3x\\÷KÅñãdªHS °8  €ÌÀ<˜L§&Õ`Lû¬™µ¥óÂíÕµqËLʸçéRW}ÃLJ§k'‰àúG–œpͤ§gmš¼xû™½§#Ñ{úñ×L:£×tÿd±±úÍÅ%|2Õµ\^¦!ÃÆ‰Ç/Ó¯ƒ—œuË il—<´è¬[¦c$VÔÞ®žtõ Å…Ææ2sx6éÑç¡’Ñåb–…‡•­@¯ï~ÑÁR€ ½gY S•T| õnÙøíñ9Æä·]!6~ï“©aã3ª~Âü p>í“©ìñYUmupçƒo­‰.&ÿÒÖcJùdʪð).×”>ï<ìàš‰ÑEˆžyü&ßÔÕÚÌ%.šø¢ÕÅaæÍš|»Úš|+J­–¡gÞš×vª¾µ¡Þe%€ÜÚdp·¾sÌ[Ûó/½é‡³­îb »‹æU}>®ŒA{ëÚ¯¿²§4Ì$ †îaf³sƒ=wÃ[†.Ÿøâ6§ëeõo§÷šæ<'C÷~$™ÙÒˆ1%²Z˜)*Ј15Df^¤ `Õ$‘̰ì¸\\ë&`(ÓÛy=2Ú€sZÓ}øcº {„Ô÷¾™˜ LN$™¶s'ïdöÖLêe¤°a³J¸R ±¤HZBê?d¬øHâ†~1çßqÿ³~u!¸%Øû-niÓ^!–L£>lùÊ-©×¥i/¬{zÜœqÓ—Š]¬½†iØX cº4lìlÇÆÿêÛ£ŸIü”<5v6’…1]Ý[|/ 3I0&¡—FM]òäèÙ“æ­•àq#§,ÁÝãÏÎ1e é½Áãüô’0…º_²ç4™ñã SÁI!„œ?*SeÓ+o-ÀôX[¤ºbL2“2 “¸{µ#ƒèì›5“rMa&E&‹%>*kþªvL¦ž¨µõN„ºðâ뢣Ë5à_ÉK4W`L—]ssX§‡ýOš‚F¨x»ÁÈÞ^—À'¡¿’v«ýöHw7iö x›3Ãb ÆtsŸ{¥¯Cï×:až K­ÏÍ}æ¹¹ÒËÝqß`KJg*š‰~ŽåÎ<§›I/¡3í%¥—г¡CSsÊüWЛ=ûü‹a²»2thèÍFNE'¶gÖÒ-‡þðHteÒ=>jRëä%Æ´¦ÐÒø9k5sÜœ5B/aLcg­>Jׇmø–9ÑêÊÀh±\ßû‡h'ÜÒ·¾ýÝ ³–ã}æâõèëг]znæ2l€Ô<óWÝ:ýü44{0Lذ¼.¹]æ•ÐÅ À„NÌõ*÷ú7 ˜gœmunx Gß…"ýÛäùko»»èÇЭÝvW z³Cx¶/¾ªçñ'žrþï.0ô9tbèÊðoúyÞï.CØ8°JèÖà¸O<¥ûÖž;ûÀôOÀ˜VíêyçÀ?ìÈ?\qsÇŸžÒóŽÂ0™äe€Ó87äee¦/®ý€‰SƒÿƒÄ˜,xÎ/GŒ)ç @¦£:ÎXô²=\´ aÿpQ 0ÞKܯ*Vä=0—¸bÂp>Mq?Âp±®$k2 ¨-$ f†ið°qaÏ&æn¼D½cºí‰BއG€,㾲ȳÉõ·‘djFsP[oÌd1LçtužÌ~S6Œ µïÄçZ°åº–Å– Ì6ôÂÆ¯O¦ö€BäJ]]ƒ0Êãç¾J’©uŸ¶kzÚªf²¦“N[±a·Þ «í¶* c,ŒiÁVa˜ðÀxñƒ ï|f•N.€G±M¶h«“_Ür4I¦5ŘB`¦83oh6ðP‚µšh90ó†RöÝÍê↷qæ-q¢ê[êÝE»È£â¹ŒY‹z ÊlÞÚØ]$®Ud(Cž¡»f²¦“N‹º  ‰0Ðp¡jq½ÞÄ!\ï'—«oÂî÷/üËð63άÏT³Â“dJV«"Æ”¬ú`n¨@# ÆÔHµy­ú(†ÉQ׉…1!|{ÚÃɉ¤À˜î¸·E©#ÿ¾=ëœ <Š¿†(é~‡Ur½+âJ²,Ì5É ×:a.’K°å+º$Û-Ÿaø‘ÆÍXjrK0äkêôóSÅ´?å6<}Í_ù†mæþ{=#þ–°-îI`ì‡ÿ©1Æ%x—@K ™`쇫˜ù%fÜù]t Ž—`æ·\•¬Ý}×€á°ôcê{f¼´ãÝkzÝ«¿]’ùÁã¬èKz©8x\P®û%Ìß“`’)þé›OÞõÑ‚š§o¯=â¨cÇN]èÁà¤åèìfRºõ›+>± §Öb'˜¶ôM{­³±ˆÐ³¶Þž€5H2Õ§ËMÇY1]zõM½¢´½'GNAS,ÙúûÀ+¯¿µgŸûÐõcB£ió—Ò€N‚ÄuèÐáŠën‘€“ì9e; æ&+&º»›n»§ÓI§aC0&K<Ò*1Ñ›^‚W¹Ë®í­.—dㄟŸúÈð‰èÙ@dÞpëÝøS€ÂìsÏ#Ò³f‚&œ_:´AOM4tz*q¿4{ÙVlã¿óîÃ¥C³z¶—wƒÈDW†íšžý¤CŸÖýÊžâ{iÚâÍ —îì? Üz0`Lx¶Çû° /â Ê ¯c;`òz`2{ª˜Þ˜‚&™«}Sƒèÿ3Gðyý2Qz+ðìV{›p³å–‰)— l[ý"îÑÓ®1é%Ü‘•w—»* 0%jzvÞf.Þ?æe`"‘Û  ÃEL5ñò„ÉQ`ÙΛͥ˜Éa˜žñlã®s²˜Îx²ô`[yïýr÷ª•ã( œ †ãÙÄ!™Ú7°gkœ=¾î…à ÏL6ÃT˜$ñ@!v 9Ë· :3>j_&÷ÉÔrhê\©f0Œ~’iáìÆ<—÷ŽtËØV]˜Éf˜N]þj{Ô[|[”E€h«cl†iÆò·¬pr¶»ñ”à²Z0Ù¢­:hÂø±é3'íØïú7×3¦83oh3VØÁ[¦cò -–Å%tá½(œ\É™7„D̉òM/fÕ·6Ô»‘yè EÍ•áät%€ÀÙÚ]ŒŸ469C>æ$ Ýf²¦S‰ºã9QM¼ƒaÂs_×¾sÀ0!É ~45œ\ÄÐ]H¦û–eCØ´—bó{Ïâ9®d ðt-˜K*@ÊR€SYrñàä)ÐÚÚèØ>Æ„@tžXtÉ+`¬ Æä™è7­ï¹·å̳/(É$ù|)ÁR°G%…N ŽF VI¦üŠ“e¿o³'V4dÒY¿êû=b'Á?~æ²gÆÐ%lÿàGG9Ð’½ÀúGž‡dõÕ‰Ä@L%€•‘VZoL‚.Ip%¼ƒ^Ò€q@—e $Ð’DYÆô„½Î~àx >Kn Pìýš0M‰mD\Â`á–c’ K’""ÇÅ¢—l¯BEî—|¾Lý0ÉÎ8ÓáG5tÑñþi}Ùóøª‚g¦°c*Øÿ‡ñ̸YEœø?·ÛÚŒ4ëIÃ]X?xò«Öì›m'¸fÐâ«-FÕè‚WKjÇUam½*sÚÙ¿¹÷Á±þE<([ cúÓU7EtzOŒ°0¦ˆìÞÏÛζ}ÈOBÆ$VXL›Ô—r¦c9“Δ¶mEôÍ`@—n¼íttOŸcù–³]Ê¡‹ƒ'9$„—rnz{êÂWp¸%$q2‡?:1™Ò³I4Lì‘M’Ùqa½ % ‚ (!ä°Gè¥Þ}aû?;ô<0¡tIøK˜@/a»¾ùÏ<3]Ý/Åïµâ`L›ÿ÷“³TŽT€ P*9Þ¿¨Ãßÿÿ9qÖ²€á¢‹‹_#î°ë‡ÉuóĴׂ±×ç„9Š>éô_wíýW0¬åOR¡À£†»YO†fî—§Ÿ}Oÿ'<ÍæÐØ®d‰˜ú0TëŒéÉå]ïœ_®VÞ'¦mT'òlâ·öI“ûýå=¯üáÿýå%ÿ‡7MW`A¿ßyž SFW(Ä4ôŠ LÆÞÖ“éÀ‹½p›K ÉôµøÆžßÿ§¦œHï?ÿ_ÿßÿX¾¾½ÐS¹kÀÜ™7ë1Sž1Á£Œž¿E¦È®´©À0™Þ¬ChKA¾û½ï¯9ï?§N(f¸ À‡ÅœyC›Áä›Ä’ôۃcת«̼¡‹+cæíøÿÆ*hº1omÁ£h3Hn9ÝÅŸÇüçT ™É´(1tÌtÞ…§ÁÈÓ¬@søÌM}[W?5cÆo½žX†¡;ð&tnVÿfûÑô Ýá²W@=IX„ðãSþ¯GWþoiQ/óù|å퇳e¾`i¨ˆ¡1¦"ñ$+oJ*çÏa,Œ)ÐS’K–7`L·ß;ÈŠà˜^ßwû=ƒ€1™®’¶‹°$åK\Ê$Щ’éhÄÃ*)´$ÖÄŠ=·‚4äéI—]{ R·?\Û<ÌùÓ^Xg¡K¶-Èð‰ˆôü¢uA F}˜íM£>~¥Ð¸%$ì¯$bÝŸ2ÿÁ•Ôº/sÍ×õ¾Ž—`’w a±bûÖ»Z-]²ü-ÁUÉË»oéׂXK0óc6nÍnpKkI ÿŽš {¿—^² ÿñ#ÇEù^Š F2ÅÁ˜À´N1}ãåO¬ú;ÿ0÷¹ ‡µíêSó4dÔŸ~ ×Yëv9æ—^R€IZfRd!fßf,{ ÕN`…lXðê."4äz¤uæQG·jÃŽ=ï}šÆÿ5ó\‚1Ƶ”Þá,aºð÷„¡}  *½¸æMxW’„ÀpxGl8€˜Âh>úÌ$Йˆ'.—ÔÉ\`4Ìi‹Ö‰?9éÜð.}ÝçtësÏàacç\z 0&‡ËDÿgK‹)]Ü:«‹ƒ¿%íâ¤gS.}ÜÈÁë’z’CŸ†® ÿôf­“—ØÓ‘N?&Ó3£[7{ è%ôiݯ¸Y}/Á7|‹@š`B8ËÓJ Dj†©»Œ€,Ë *·ÿ¡3þéžìõíƒL SàÖCÞÜÁN`¢P`À/>wóAË`Ê¥ï¿!d¸è,‡ë­pŠ3t¹ ÕyÞ㯞äGÞ=aôf„U¶'þâçã—ß³àõ~5÷ò„IP`æ–³'ô§nê„EÉkÖ¬Á€pQÛVÿ³ låöéY¯ƒ qš46B,ŒÉFÆÑÞŠžMV Ãðl‚´£Ž:zá#··»çË\þµ›Ð¥_ó߯ǃh¹¶OkÌ“-Ð*f% AW#O¦˜|°0¦'œ¥ügôš6váŽ&ÓO‰ƒKZ‘+5—¼·× ›G=ðÙ¤¿4A¶·ä+ØVásenÿƒŸê<Û*½T˜E)ܵ‰òì¼-²´ÝÔs/¼aûa ñfmDYÕ¶ ŸÖWuÿÚê‰w²­&Z<—²ì¶/xðŠ3ó†fƒÙ6JÁÌmø™3¿ÕÅ-p»¸¡2óväOV=yçžqw'Z±ä÷1sXÅ­ÍØØät­aRϽcøªž[êÖ†î¢ûU¿›²æ%ÛîLÂyȆaC÷Y[:ï;°fÛ¶m:uz~Áꈡ»šÀ0!¸ª,Ä$¾ áŠiÌ‚7†)rè~äÑÇŸÙoöÆ{V쬽‰$õÕ°RŒzå;x¦ÛùÑÜjŒü- ©T€S*«™.(pÈ!‡Ê c ûqê– ¸ ßžqö !ù7|Γ‚|)Ù‘·›ü…ƒa¦Ä¶?fŒ P*@ªS@†‹/E%¶—<hМÖ9›ax ÅJЇ‹`˜N:ùôõ[ß‘{Í»~V]®ùë$*€ÐŒI&Í+H&Œ ®Üñl‚P;0ôm]5jÞfx79þšIbiýºÆ¤w¼áäÄW.ÖW,\º^[û»Ÿ|ùÕWIÔ+cy±dšù]€IKiM¤Ü=(´ê7ZPˆà’2ó†ÉµYO¦Â0ù—ò›‘+QûÃôЩz¤Ï>ÿ"c2³85PÀÓV]€IÏl=Þ^y“¹†Ð™E±¹^‰ %uÐMɺôT†©d[µ¦ë{i[=ðÛj ê¶^§òâÁ˜Ü(„rÅ83oVäz crppôop1(f~íâì»›Aèræ­^5û¼eÞÚË–)zé.pkÓ0[¸µ þêµÿÌì×cÞÚØ]Ä®0Xžþ¡»Lz!™¦Î_mV@]¢cU0&tnxNDÿæ2Lº—W;Mü- ú—Ì\ºô’W½\ –þ‡Ÿ|N¼.á#,ýýŸ/S“ݯìyîo/ëÕwÐKŠ.=ÿâë°úcºڬ¸F*B— Ž—üa㪦—”g* c’Y*ÀL3_»âÉÕŽg¦úaL:Ÿ²díNu~.ÏÒÂyXOÔ6À$«]åqÚö˜µû/ÃÛœ¯¦À·àÕÃ0‘djvÕ„ëÛó¼7FôŠ=3 &«²;@{ÞGœÉ¹Ó@{Á*Áub_*  D ö×Ûïlv}èèlKާ1xs“_ÏÀÿW’eOJÞ`ë ˜4“˜Nùó]ƒJV½„T.Äç‡Éf˜Šý”2LU’Lh ý*IRZ]eù@C ˜ô”ÖCî7–ÛV ¼]¸O@(muå‹ËwoyReµZß_ Æ0饛5ó†{Y=F†õ•4-g¯ç­-Ï-¾µ…uÓÒ‚žOº‡Lšy!™&Ï]]òž¨K£=f Ýí)Ъ†î 3KÙ#Æ”¥ÚdY¨@y c*O/r‡1Ýv×À"7H¦K¤ïà[`L¡I%±¤"Ë}œä¥”ŠX%Ãr+•M,•-ɃY\n)0Zœ3Ø-×ë’‹.Uä¼$>1P1Æ$qÀLo}0#ìïÞï…~5é ìù”S^X³Ã];h-tÀ{U½9S\Ä‚É6"&’L5©µ´œ3¼ÔÞâþPzÂ!OO<üÈcõq×Ãeªc°0PÉh´á€fq§WDg†¡™®³%¥—?ýøŸ²hõ[‹TÑL±Ç ºm”*8B7<—d˜ð\½dÝ;Ÿ}þEûž.y ˜Ó»]ßàáÆäÿ*¼tú½hOr–⣙gK¥=ÉE☊.•t çéÊ|˜6Nç­âtAqŽ©cJ^«cލ ùT`ý˜?x!RÀâ^½&“¦Ls†‹.UàÜX€©Èg§,ð¯¯-É0a¸øæžÿöÅWšóÚŽ~«„g¨Ÿ«V¯>üÇÇÎYözégÃéWÃdx,(É0yb6…ý_"þbõ“"‡g¾ Ûoní7 PõF”%›• êjô±Ôµ¤æ’ jÏ{±°­ P¡a@I®ZìM=oí~y[u—•h«žÐ9ŽU¹àçÒMíx瀩0Û[êÚ[ƒgÞ@¿½4gAàÌ[MF†©Ó¿‰»µÅì.lƒ… ¹Ý…bLíï~ÒÄòVpiŽó+-9?ÙúÆ?9æ¸ ³ÛJÝ5°gùAECw6›Æ·bLלW¤IQ€SRj‚ù¨±¹Ã˜0ã¦t‘ßžÖù|ÿ~k˜‚<'™ˆ’NŸ$ÛÅH4¥¤^vãÁãJAQá"cÃiï œ-yãÄaRÒ*®4·äñYRsÃ8ÇÔ cj]ÛzÈÀC:>ÕQ–´¬hé2º‹¹¡Çìøˆ3ôø ©­= ˆùwÓÔ‚Uo)êa®ª×…Îžà ŽQÊx؈Ã0-Ý°×³Ž°ÆO—€1an7¢W|Óñâ˜Ú†÷½_©N/ª¯+3üåÂRnä"Ð%3`œõ²½Sh å/ÝEº1;Ÿø‡cJÌß…¡T€ T®ÀëÓZa‘‚e€™°!epF8g‹;‡È~¼‹Ç&9F~çÚ&M-. Àä:aò Þ½2†içÞOLÛ9úÅÈ`Œ„1¾Å¶ä\‡»2ôÅ·øIœBñ˜d*°|åªþø˜YK_÷=›sÅë+Ê7„|tàsÑÿü•ä¿£áÐBþ)žýØ©ÿ¬dŠ™º\×õ7·ôà­zÓß›àk>\N$Aw؇a‚¡÷˯ ¸dI­ÄÿxcžÉìE¥‘H¯+mI<6I·Œè¥äEy@bÉô‡Ë{VËß%Ô¸´U+ĪÁÛy¢^F@ Q€1á}ݲ•“þxœ¿½±SJlóÌXÃfÞÆÜ~ã½?ýÞÔÏG¯U¿‘aºÄonn=·6`*ÿÖ“a*ëÖÖ\epuŽó›^Õg`Ë–7Ž>öøñ³ÚÊ4+xcÇ\~€¡;›MõµVÁˆ1U B2¢1¦ŒT$‹áU w¦Û<žÌøS({¤’gÃ`’J“I&ÉÉoÂ7<Ž@¥ïJ‘–Â|,éd ækÌä±îÇ–ü–~¿¿%/·Tçhq1:aLøŸÁ6³ÿ¯û±ž ж3©&|Û¾¿%ôl<ØS²Â|Êq'ž2å› 0YNhì©7'.»Ì¾­5J‘a*)rÞŒ)Â?\˰‰°QEõŠÅ Ó¿iGçÙˆì÷<áÊð$烖üý›Ó³­ÚàrÉû2(`\ ë¸º¡KfFŒ)oÿJ–— P¬* pÒ®¶ê“ {`eÇa2ðQ ꫇öƒ¡Öt8rÀÇÏì* $†‹óìá¢`ÒábQl¯òcÉa¹‡a’*àW7Q2àÊXWø~l`lgô›ÕÆr É4sÉ&÷ÙĈZh“ÁN¿ª`˜ ›ü5ôo"JŠ× üM` VO<øãàŸ¥˜ üDþS|U¯Ì½½ûðT½iÏ—å€Yºõ`˜¤\ ´ É„=Ú*¤‘ %H?ŒîWVz mT¯Ï,’é²N[ åz‹C^Ú~ÚV£¡„ycFƒGÁmqá loì”’Óbæ¤13oëÖ¿1îâŸKGTבaÌRó0(Pý­-“ “´ Žó3ð’iÜÌ•f…ú ÝÙlßlˆ15^s^‘ $EbLI© æ£Æ äcÂ\[„•ßžzÖy%Ìð™ç=ˆ’Ã'9N××ëb³×´HÜ)izÙV$É¢±€dËwÌù6àR’XŠ-E:[ ‰§s@1£ÆV'Œ ˆ’fàrI‡ì0Û,ضÀ|üÃW؆)&Æ„ßÊ|ÊÜÛ SÑ“FÔ B2L5î>3q:`L˜Õèô=5ªÒ½b .3̇\¸’Kì•øÒß³År¹TÔ›Ùãê3®d_GŒ)5‚ P*Pˆ'tqÆBÑ ñØkº¸bÂ6¾’cÂ…dÂpÑzŽp ¦$j¸'–\ ÄA¯Œ~Ía­z`Ò±1F¿Â6!cÊÀ¿BH¦é‹7•|6ñ;ýŠ¿˜Û ÿA‘FÁÿEþJò—‘#Mo(ò_“ÿ¶ñžÙR˜{{Ýñ°Ü9ji®ã/Ü©Ãq„UÂÀPÔ¸´•¤‘ˆÇ&ì= Çã[i$Ø)$ _YR$Óï/íÝVçÚ+[d=^YÁ¡&Üç‚gž€c•°öÆN)m©Þ3o ·,[(;^õ¦± š•çjnmf˜8ÎoVƒ¬ùu…d;cEÉ¡»x¦7¡Þr‡îl65¯¾8'$ÆG%C²©1¦lÖ+Ku0ÓÎ’ÁÀèE½ïpÊYç…6*ÜÍYñ,LR0™ìHÉð¥T‚R²LøÖªÖ°$®°Ãq%ËOx" À•‚bÃÙ–~oL% ®äDVrÍü®³%kÉZ³Œý%iÿu˜'I ¬D‡+&éiÄ6ð­DÙ0 9ꨩd·dͧüôäÙË·«Ÿ-Ǻí„Igß<d˜J ›Ï€1ýÞ]œØÅ jaL½bʬ-—i‡cLþŽ®|r!¡â¼šÓ›UзÔð'Ęòùßd©©Ș°‹«Ë%@•à*F]Èà[|DSö‹ó¼‹»&ñÒÿe‘L2\tï§¶ÃÎÀ¤ÆZsnºb†I½âdÔô?ª4?¾¤IÆÀHO~­¼BÅ/>l¤ ™;â˜ç_ÜõlRµ!DK$„ þA ÿAO„öÿ|ÄMb2Ê_ ò/ã«V ÀÜÛóŽ‡Í€õ¾®Æ™:0¹º2L(št­¦SÚƒÐoÚHrrÛÒåj#©•8ûB)v¹[Õ{d¿à<²²[[œî¢Ü0©É© Žó“SÕçDH¦ÑÓW”eV(—aâãaõ5UÙˆ1U¦E² 1¦,Ô"Ë @î0&Y/–ð-0¦ˆœõ[?Iþ†ç¤Ò.”Ô¯R¸Ù^mù–ý¾V)WòFP²–Å"–R-5 cÒ`˜$¦^jÈG %ì‘Às°÷(í§£Â|JÇŸžkyk¸Ó¸ NÏÛ㉩՛p¥Ð^.!/µË"Æ”ÞÿsN¨hºɤÃE70´8 ÔMõ SÓ‹É $AL?øÑÑl4ŸM<Kņ$yˆPæÞoﯓ²’º´¦~˜XAT ŽÉtÉõÑm5”†é˯¾ŠsE“vj5óf2Li×$'ùsk‹Ó]¤aÊIuç°˜B2˜²ŒC÷,Õ>1¦,Õ&ËBÊS€SyzñèÔ(;Œé¦¿ôW;º‹1EPò«b ɉààÇ’N ‹øæØïÛvÍ ¶ÜÇ€+v: *¹K!1œO\)ÌJª1&t3˜O9¦ÓÉÏ/ÙªK]Í™b2L©é‰›—QÁ˜"z¶‡·0¦v}Á”’pK¡=žÎ××ù},wqIŒW[&bLÍûðÊT€ P,(’É3\4oFd˜²Plj)ƒLæo|6!Ô˜ŠªKF`îíÑç!`*b%É0ÕEqž´R@2ýæâë ÁU ®m5”@†©RíÓú»êgÞÈ0¥´î£omqº 2L)­úœd[H¦Ö)K9tÏLcÊLU² T lˆ1•-ò‡1ÁÛ¹¸;2“ cúåç*cTr#ÊâP¤™ Qr‚Aœd&›R 6äïRÖ]+UÀ¤crH¦Nž²x‹ 01–\::àäV£FôuÀ˜`ŽòP^ïW‚ȬÄ{œAdº¸RF»8bL ø£0 T€ Pt+`‘LAÃE2Lé®×Dæ$Ó¡?:zü¼WM_x6!ÔÈêªq¦`î½áÏyªž SUæéj¡H¦ /¾ÞßVã@ d˜jQé;‡E2U:óF†)}õmä8ìÖ§» ÔêªÏIæ…dzzòRYC÷”6bL)­8f› Ô@bL5‘§H¢¹Ã˜àê<ÂúŽo1‰SO²NWœvÎW"AEÔR”#%°J¢êQɶâ{ÆÀ=ùùI0&!™Ž>á—“_Ü¢G?LIìn™'Á˜B{Ŷ]>faL±ùKO'·ë‹Adæ(Ø¥§&Ɣȿ3E¨H™ ™<ÃE2L)«Âôd×"™?züÜWuHCCHzj¯ÚœÂÜ{ým™£Ù“Nÿõ½ ?"ÑÐ[­îü}ù €d…`¶Õ8P¦ò•ÎÎ/*›y#Ô࿵Åé.xkË@Õç¤B2a¸Î¡{jœS*‘E *@Œ©Báø³¤+?Œ©ÏC ŠÌT ‹Úv ú/Î8×Ü<ò£H%˜¤â(o&¢4s¬õ’ #º½|G~£”4“‡d"Ôô~7IùÆô›K®èô\ìòþÇÆcª¬'ôÂI>“Dfœ^ŽS’þ1Ì  T Å ˜$¦Wd²n’Ld˜ÒPcµÌ£iî%ÃTKey®Z+`’Lq 2Lµ®ôÏ$™â̼‘aJ_‡äؼµÅé.È0e¦êsR“dâÐ=Õ•NŒ)ÕÕÇÌSª ÆT•|üqrÈÆtCŸ‡,ën\6|û‹ÓÏ8@B—LŠÉ$¹Þè?)Ž-¿ÇdcR’©ÿÐÉG}ܪ ;"V».ݰ÷Àg_$·[bΨ0&¸Óèôît"ƒ„¯ôw†¾Þ/Çd§¿C#ÆÔÀ?/E¨ȸB2ýù¾'O:ùôõ[߉.ÂXûÙç.f¼=ÔµxB2‰•wáÒõÑÎx>:ðy]3Ó7X1÷’aj°ì¼\ ÉJ ÃT¼™ü‰LqfÞÈ0e¬È­-NwA†)cUŸ“âÉtﱺ§ºÆ‰1¥ºú˜y*P•Ęª’?N®ù˜®½öÚ|Qò˜2k±9ó¾m÷þdþ§1ŸòƒÃ'ÔÌÚIf®† Vþ‚¿HœW]ßËcü„¨b2ÿrÌ T Ù €d"ÃÔìJÈËõg¼ðô?þË7ïi2Ly©r£œ0÷2–\ë=EÉä˜òôZd˜ÒX³õË3fÞ;üÇÑ3od˜ê§Ï|Þÿáª_Æ0©M¬^º® l™ùôÑÿøŸNÏ¡{]u®ëɉ1ÕU^žœ $ZbL‰®f®rò…1ùuŠ–ñ[*¨@b1¦ŸïûJ'úaª¼Gä/Dóæ? câ¿™ P*@€çúabóh€»>Z0xùšûêȈöF?L ¨ˆf]bÏ{ŸFT=U4«^x]¿ï~øYômñ˯¾¢nTÀTΣ' è=› ¦×wöÜ×™·¶lV.K– ûÛŸþ+rèžÞæ@Œ)½uÇœSj ÆT­‚ü}B ÆôQÌÕ,BƒH,ÆôÒŽkkë°ñíI‚0–\B»á„e‹Sƒû“:]ŽSÂþXÌ T Y „‘LŒ%—¬zJyn€1áÙdÝžáa£2L)¯áÒÙ#™È0•ÖŽG4V0’‰~˜[iºZÉD†)MYV^{}çàƒxk+K3œ&– ;xI‡¿m\ˆ{_àèC÷ä×&1¦ä×sHê¥1¦z)Ëó6YbLʨ@Ù $c‚+¦'WÿLã7æŸO!ÃÔä¾6=—'ÆT'®¨Á§%Æ”žÿsJ¨hŽ~’‰ Ssj"»Wýè¯ÛÚÚoß÷ÉšÏ>ðZACHvk¾¨d~s/¦œT}êŠé'™È0¥®œá@’‰ Sƒk¡¡—³1&\‘·¶†Ê΋5L·ÖœzûÁ}ÛþöÅW~’‰C÷†ÕC5"ÆTzü-H·ĘÒ]Ì}¨ĘÊFXlŠæå¨@21&qÅ$iÛûÍù2L¼ ÄW€Sûœ ²DŒ)~›ç‘T€ PÜ*`’Ld˜rÛ SpÉDCHcdOÈULs/¦„T ³¨€I2‘ab#‰£€‡d"ÃG´ãbL’‰·¶×i^³¾wCÛçöûKý²ÓC2qèž––BŒ)-5Å|RÚ+@Œ©öšòŒ‰P€1&*P¶ ĘÔ“`LpÈ„FæSÈ0%¢¯MO&ˆ1UÀ %ð'ĘÒóŸcN© ÍT@H&2Lͬƒ¬\»Çì›ömŠ(’L4„d¥ÎË(‡L4ô–!m’B2‘aj’ü©¼¬’Ld˜RYeeÚÀ˜ð;ÞÚÊ'GÑ]YtG÷í‹&{²ôÁ››&wï¨;•dâÐ=9uW2'ĘJJĨ@f Ɣ٪Í{ÁòŽ1á‘ÓiÓ[mÛóqô1ü6K  ºQéÑ%Ú÷ágIë9LWLê ™Ä4 gR’VY ÏÏ{ý5ºýoÙµÿÝû³ô¯OWYÞzçÀÆ·>ŒÎó®½0Ýð–ÆìQ*@¨@BÀÄ4ø’„d†ÙH¯‡ <¤dæÑÒh)©RVøàãÏ¿üŠÔ¬Vo¦ÊõÁÇe[ÍTÖ¿0œy«¿ÆÉ¸B1Æ„<ñÖ–ŒŠa.ÊPþ–LVÉüåú1-KîaîÁÔ"‡îeˆ›€C‰1% ˜*Ð$ˆ15Ix^¶Þ äcª·¾Œ)}E`Žó­€ø[oLÂ3ÍêÑï¯Ok…0؉{Ûe?M`›° ä[¿”žS *‰Y¤uR€S„åi›­1¦fׯOªVÀïŠÉtÈTõéy*@¨ T€ P*@¨@¨À•-ák¼QÚÿ×ýØÆ¨&l´ïoǶ¼Ë)L‰²R*@¨ T  cJA%1‹%V  É„ õÏP œÓê¡ýÄ'Ó®¶r°ÒK`›p%N²Ę’\;̨¯Ęê«/ÏÞ4ˆ15Mz^˜ ÔD@WLtÈTmy*@¨ T€ P*@J*€õÚ ¶-Àa•d/ 3'LpÎÔc¶µ¬¶{â‹ P*@¨ éP€S:ꉹŒR@X%OK –Ä“€Jp¿„wñØ„ýÀ˜ðQ¾Å‘r°O|%VbL‰­fŒ Ô]bLu—˜hŽĘš£;¯Jj¥Àž—¶íê#I†ª/½uîäT« ñxs“¿ØŸâR1ëT ZbLéo!ĘÒ_‡,¨TbL•*Çß%\bL ¯ f ”¡1¦2Äâ¡T€ P*@¨ T€ ÔSQë¾Ã rõ˜ç¦T€ P*@j¬À¬]–>ÜÃs^€M“»w¬ñÅx:*ˆ1%§.*Í 1¦J•ãï¨@ú Æ”þ:d  ÆÄ†A²£1¦ìÔ%KB¨ T€ P*@R®1¦”W ³O¨ T w ŒîrH`™×iñ³M¹S‡ΰĘÒ_¹Ä˜Ò_‡,¨TbL•*Çß%\bL ¯ f ”¡@ûG ÚÚoÿëï—ñJ¨ T€ P*@¨¨ƒÀ˜fmé\‡ó”T€ P*@¨¨½ðÃŒ ïˆßKØÀûëÓZq¥Ewt— qׄýB5a§Yû ñŒT a cj˜Ôu»1¦ºIËSÄ+@Œ)ñUÄ V¦1¦Êt㯨 T€ P*@¨ T€ PP€1MÝÔ‰Q*@¨ T  €I®„¬â$6„gÂÞWN?~~`?`¦{Û5ÒÜê¡ýà±)Åd&©@€ĘÒß,ˆ1¥¿Y*P©Ę*UŽ¿K¸Ę^AÌV‹ƒ(  T€ P*@¨ T ± cJlÕ0cT€ P*@¨€_8Xiû¢ÉÀ’Äë’€MlÎtÑ„ãñG"aïT• ¤UbLi­¹B¾‰1¥¿Y*P©Ę*UŽ¿K¸Ę^AÌP ­½[ T€ P*@¨ IV€S’k‡y£T€ P*@< ˆË%0LØoL6©&Ù¹«mÀ~ 9‡HØ€‹&JJÒª1¦´Ö\!ßĘÒ_‡,¨TbL•*Çß%\bL ¯ f xØ´oSǧ:"µ®mí÷B¿³{`»eEË!‘C±ýدºO¶– ñE¨ T€ P*@¨h˜ã7Æ r S›¢T€ P*@ªT@\.‰k%lN¼ƒXOKòâ{ ûÅW“€MU^?§ÍT€S3կ͵‰1ÕFGž… ¤QbLi¬5æ9†ĘbˆÄC¨@€+&8dB¦€(UÂ>b[² hiÁ¶€œ”^Âñ€ŸVf‡ P*@¨ T€ P,+†‰S–+˜e£T€ P*!ìm& /„Š“hqØÿL€–*a?5ÉWz$6dË,Jþ Æ”þ:'Æ”þ:d ¨@¥ cªT9þ.á cJx1{T @u¼ä÷À„£Á3µïo'LpË„¤ØÕ¤T€ P*@¨ T€ ÔOWßÒ¶«¤Q¯|I?â«ú]—g¦T€ P*@¨ T  ÖÏ8ø`''ýùßþ©ÃÁ;+ìÁ·|¥JbL©ª.f– ÔTbL5•“'KŽĘ’SÌ ˆ¥€ J8T¢ËÉo*Á6ð­°Mx‡‹&IðÌëÔ<ˆ P*@¨ T€ P*P…¯ìéÿX[‡À„¯ª81J¨ T€ P*@¨@íøüÓƒ=¾~ÆoÂ~|ËWª Æ”ªêbf©@M ÆTS9y²ä(@Œ)9uÁœPX hü8ÀIQ/ðLf{€4aï-+Z°wÙàT€ P*@¨ T ® |ñå§­k¿îǘ°_ÕõÒ<9 T€ P*@¨ e(0·0Æ„ý|¥MbLi«1æ— ÔNbLµÓ’gJ”ĘUÌ (­€xcÃ>I<0á…`•&¿6Yè%øj’=-Wú¤<‚ P*@¨ T€ P*P <Î1ÑS-¤å9¨ T€ P&)ðÄùÇ^Û¤kó²T n :d¢+¦ºé]×cª«¼<9H´Ę]=Ì\å cª\;þ’ P*@¨ T€ P*@¨ð(0~Ãa&ÉDWLl!T€ P*@¨@ºèõƒvJw˜{*¨€ß!]1¥³©cJg½1×T  cª…Š¿øåϰš(ó%e© T€ PŒ+@Œ)ã\¯âuîÜùûÿq¨X£ ;TÁüô¯ÿöÿûÚ×ÿ¡¤É)ĺbN2LH¡f£"S‘e$úé1G™Ö¢h«P‘ ¨Øîjî)eÙSÎßÿ¯}ç_þÕcÐ1 7ßüÎÿºôÒKëUai>/1¦4×óNªS€Suúñ׉U _ÓE]ÔÐc»ö}RH{?Ùµ÷“V:€ôРÇÎ=ÿÂ{ìx§Þz瀕ÞFúéMM{>Þn¤m{öoÛí¤7vï·R»•¶:飭»>Úb¤Í»>Ú¼ÓI¯ïüÐJ;¬´IÓ[¾æ¤^{ëƒoÒ†7?°Òv¤÷_Õ´íýõFZ÷ÆûëÞxOÒ+H[´vë{VÚ‚ôîËFZ³ù]M«7ï[ýº“V½¾ÏJ›¬Ô椽+_+¤¯í]±ÑIË7î]¾ñ嬴ÌHK_}ÇNo#½„´ÞIKÖ¿m¥uVZ¼n“^Ùó¢›^xeÏ k‘v#-Òôòî…FZ°¦]Óü5íóW;iÞêv+­Ú…4WSÛ®9…´³uÊÒ¯ýÃ7g¯Ü‰4KÒŠ3´cæŠ3–ï8ôð£±J ±ÿaÍØŒ3~zÒ©g-ÃóƶmÛ’Ÿaæ P*@¨ T€ P¬*†éÒ«ozdèXoH2eµ–Y.*@¨ yQ€S^jºÆåìÔ©ÓøÉ3Å¥F(Ø¡ÔüôàÀÇ~}þ…ŽÉÉ56mÛó±XšÄÆä˜\ӒڕĢ䘓\C’X‘\ãÑ–ñ¨ÈfT°¹v"ÇH$¶¡ÕH¶aHLBŽ=È5‰%Hm@b»}ÄÜ#†ž‚•Ç6ñXöŸYG :óV[vœ_žqî·÷w-8–ÕÆ1ܸ&›n{f¾×S&NGŒ)ÕÈBPŠ ÆT‘lüQòÈÆPIˆ%M&´ô=jÄ ÒA—bÐK ™”^rF–.ÀÅ0¹H¦*&{*)šar1&gljaL “3TuF«>†©mS0ÆäŒ_mŒ)ˆar‡³.Æä0LƸÖ3ºÅ07cz¹h°»pÍîHŒÉûš“Á0íšÝVÀ˜”ar1&‹aJƆéÄ“N[þj;6ž_°Þ³H2%¿ÿe© T€ P*@¨@&°¦›±l'ƒžC’)“µÌBQ*@¨È‘ĘrTÙµ,*0¦q“fŠ)Ê´C¹+ç?~`À£‚1é‚ù¢¥òå2LîbxÁ˜<–#Y÷®+ÞÅT¤ ÝMŒIW¶Û“± Ý^Í.ëØÕTcROÆäšudQº½"Ý‹1Á|CŒ)~s$Æ_+I²¦1¦¬Õ(Ëã(?ŒiàcŠºX%×ßÒƒ,Œ©Èå’ø^*v¼$cJ“^òLLí>'L!“œ‡+&Ë S€&Ë S9~˜ªd˜Lî¾xØ ŸLÅ®˜Þ pÅäøaJ¢+¦ÒÓòtxc²¦_œ¶bÃn±à1cÊ|’Lìå© T€ P*@¨h‚`˜.»úf8Æã Ösãñd I¦&Ô/I¨ T€ ÔNbLµÓ2WgÆ4vâÌ";”ôC#~cúÕyzìMëÃ63 L%ü0Å`˜c tÅdyc*åŠÉƒ1i‰¿áºb*òÆdcLn¨ ×S!¼†bLv< ËSÇ“`LÅ14v\OoL!!bL¹ê[XX*P¤1&6ˆŒ*;Œ ãÂBT83Bœ½íÀïAÐ’Å-aã ^=}/ùé%#„\LLáäB0!¨\‰XrUùa*Bïc1LŽOÑJ¦x®˜ áä0ðÕpr&¿አƒ` *áŠ)ùAå„aZ¹a·i'À:‰)óH2e´Ûf±¨ T€ P*@¨@R°¦knFLs8C0&¬áø}2%µÎ˜/*@¨ T ¤ĘJJÄ‚Æ4fâ ¯AÊ0? ÆäñÀäFù(Z!£’iWòÆ’« ô٠'WXÙ^­+&ËÊ+¢\»Øq Œ)À¢gc û«cb'Dò«1¦üÖ}ÆKžGŒIýsú7œQ£ÏÓR´À-ÙP¼]ÚRŒ.y襂û%0vB;˜6ºƒNO$ã‚#P_¹€©'LvØckZÀícÇ’s|Û•hQ8¹rý0Á’ã1LÅáällßãƒ4šaòcL3ÝËNNÒ¡‡=eÚìw?üLÓÇŸþ-!¦Ÿýâ´¶»a'WL–ÀvšGY“æ®:üÈc·ly#!¹e6¨ T€ P*@¨Ȱ`˜.Ãô†ŸÂóxòðã£Ï<ó¬Ÿ|’aX4*@¨ T › cÊf½Ö½TÀ˜FO˜á±Cm3ÌO÷? Œ©›å~©ÝJå¦%M09Ö%Ø’$9¥¢h±äJûaŠf˜—à 'WQNÂÉ!»bÚ³x•`âq­z)ÂýÒpKš¶½hÉL^L¥&á]4ÁÏ¿`*HζF®ÅáÙõ&Ú(?L†+&£l2LsÛvÍ)$äÆôŒzcr¦˜L†I0¦㦙Պ6ÓÜÿ­\Ýe˜öxìpÅ$¾²ãoâœU‡ÿø˜ÊH¦ÖÖÖC9$º¤ ,ÀýìWLMÚÚÚºtéó`=Ls‚ßv´_ñ¯Xîµx< T€ P*@¨ å* “e +&w•…íŠÉ~<ÍcÃ; ™N>õŒ²H&óAÛxHÑŒáÑÀóÀ‚=aÏ›6mÚ¿?à9®¬g&a¿ »~ÎÇ™rÛ§T€ P*ˆ1%¢Ò— `LÏ>7Ý´@9ã\ÛÓ}ý=ç¼nžàq3Óë;-»RÁ´0©IGj9Â]FéVÚò.,D¦‘H–¸cèn%ktQ\B&ËúS`˜Ö#–œ?œœQÎ '·p³:}¾mÓQk&¤_8AåŠ\1Ͳl7ŽÕÓÙçvóØà>:ðyúG­sLŒ©ÖŠò|T = cJO]1§e);Œ ãBa’Ʋ1¦`€éåâ@r^'LVå"'L«L'L»Ô©‚c Œ%g•KÆäe˜‚"ÊÁ“Ø Pãg•M2µ··Ã ïÒGgR¤I–8Ëêg˜ 0õyYX¬VÙƒN‚ƒñ?Ç`°-?—vÊ™qÙ£“þ=zôÀG/F “[¯mMíQyq*@¨ T€ P*;,†éZ‹a uÅd{еO¬ÇÇ”A2Ƀ :tèàñ´$.Zu'žDðà Ï/xpÐg <5à£NØÐ¯tI†ÿYF«Pj°Ä’>Ýà·ò|äy™™¢½1ÉÓ„ä´°!}ú§}QoL8^–CàéC–dxže´¼ê›VO‹G$ìÄ™å*âÉ Ï2òQ8'Ù/—ÀµÄ]®e2L|œáߊ P*@¨@Ê Æ”² KJv1yH›Ö(@K÷<4©€åñNä8ÇÆ´1€^òº_’@rûQQ¹÷œ09F"'\!–œ’3íAb rÍ@޵랰/¬ucÉÙ¡6$ÎF ä‹ÒÁ0™“é‡É4Üc kÜĘ’ò·g>¨@ã ÆÔxÍyņ(;Œ ãBú7¬Q㯃F‚(izëÃM…qdibÉïo©(ZœÍ-x]*F—"é¥w5žqˆï¥xî—loÿšt¨Zˆ|\€Ér.ŠdkC£ÈÅsÂdúa’Q¯›œPÊŠßvFŠô´…1}Ãb˜ŠÉ)ÄC?:9Þ˜”a*¬uÞb=„X¶Z{Qq¦+&Á˜ óØ+‹M2a"“õ˜|Ç„»ÐEf´?Æ$Ë‹ñNfÄYô¬Î“<“bRÂ9ÉUÄÉ“éoÉ„–ÔÑN’¡T€ P*@¨ T Xƒa²–XXklìg¤Ãäy<±#ŒãðþÁ±H&Æ„' Y!òÀ"+(Ä««>8àHðFXž¡È‘M…ç1Gže´¨¸´<žÈŠz™ÕðÖò•<þ NÉ95‡È²gž–3ü;Q*@¨HŸĘÒWg‰È10¦Ö±Ó RblºÛ6HYÛÅÜ’µ0Þƒ.ÁýÒv+9ÁãŠÇ…ú÷ €É2%(Àä.q0 É‚öâ¥ì…°;ØN˜¬á½ ü±äÊb˜æ´íüÅé–7&a˜lWLÞÅçĘÂZ61¦Düç™ *Ј15Ev^´þ äc¸ÐC#a€¨éîwùu7Û‘’'}€£™ÌA¤ºñ,8ótÇ”2²ôBK!Ü’ ¦\.ù¹¥²/Ù‘ãœñh‘ï%ð8?½äw¿T<`õ ÷•…«`r'¯¶¢È’óLve?Àd’Û!“ -ù·“ƒ10Lf89s­³²A&€bˆÓ7zz,’I–{¦ìãcL~PIöÈT¾ù-vj:lÃÆ •}¥ÛާXëIÐ^–}ß#¥I&Æ$aãÌ•xpT/}ÖÐPnoLžGAŽÌ%fÜjcÂ1êWɃ1á$ ”ÄQ“ÐNŠ1á+ u‡ýX%""òq†'*@¨ éS€Súê,9¶0¦1ÓL ”Çðd¤ºŠá)Â̈.yÌI?®`BÚòn L;ÑÞ6wq{i'Lvh$—a²&e˜t½:,í—Ë0ÁˆŒé`L! l7ĘÂZ61¦Düç™ *Ј15Ev^´þ äczp°—F2ˆw=`=ãÅàác!ö°CÁGàJ~OK®‡Ïr¸%{a«=ýcPYój¡Kþ°qöÔ9NǦâ~É¡ÑKUij1| ‡ìñ=ôRLL/ÙŒš 0E‘+PüÈÿô¤Ô`Lf,9 qC{P†)b­³ëŠ :‹ãÖQÓ–ÿ ”O&1hÿ£N’€É½zc’=þ©Ô û1&œV~./|”0v²ÅÓºÓ½Sý;F^ P*@¨ T€ P(,†éš›±Ž&ƒa XbñŽeí°×j Æ$'÷´ŒŒŽ.W2¨r)`6”RÒ_™@" `-ÃSŒ®£=æ: ó£F‹ÃÙüAåÄç“yœ×Ò_á+¹› T€ P*Vˆ1¥µæšœo`LOyÞZÄꤩ ^{Óû‘è’7xœA/¸_²ÍF–û%¿&ÓHäF‘³ C>'LÖRv˜Ü}‘&{ï˜{Ü@rKnþšö‚eÇX—aaL¶0&¿&YNŒ)¬Mcjò¿—§MT€SÅç¥ë©@î0¦~ vF„2.,Nø¶Ë¯ºº.”L>Éò¨àT ~•\×Ja¬’5±ë¸Y*ò´TÂÙ’ ©Äá–¢½.yÑ¥bÇK½d9. uå{ ñßvÜ/ÙÃV½wüz)ØýR1˜ï “lÑKî·¶“D‘žŒÉ`˜Þs‚5ø¦6»rCÖ:[®˜ä™2Žœºì?:zË–7Âú3$Ž‘H’eÍ2õÒH¢'˜“¬-–ŸÈ‘fˆ1-È1z6|”¸uúÓ `^Q2ÌåËõ¼)ðÜT€ P*@¨ T „q&;œL K_}ç¥W½®˜ôñäžA#"H¦ŒIŸ ðø Þ[åYCäá_ɰdBBW ؤ5þg-¼@Qò’ÀpòX„pZÒËÉÕõZÒN¾Õ¸r|œáŒ P*@¨@ú Æ”¾:KDŽ1 ó|‘Ê ßáØžÄ U –Bâxñ0/ù I²âÝ´!ⳕ6íksR`¹S˜&{•‚íoU’Ë0Á!ÉÃ0Í]µK’0L³Ýxˆ%'SÃDŒ)¢YcJÄž™ MQ€SSdçEë¯@iŒIfî0ßgúM©Æêr…‹.º¨ß …Cr¾í,£ÆmEIœ'E§0V©€+ÙKTÍdJš¶XÐÒK¯¼õ­ï|W-ø‹Óðï:ôÄFÿGG^qý-‚Ï+DÃFL˜§^—~zÒi­æmºÅLq/ >‘ã.½¶÷¥×ôƤ³JÓKßøöwÅ÷Òb7²ÙÈx|—^úÆ·¾+è’•Üq­gtëÆkŸW"„\,L0IªcÚ·íàŠgëÒX“ ÃÔ¶q·:a’˜Öh ®d¥k&]ØoîŸZd1Lß=Ë™½§Ÿpͤk-ÖµÎÖÃÚÝx`˜·ºO#¦” ™ê](žŸ P*@¨ T€ P4* “óœk,¿ÁãɈ9›ñ`‚ǤnýæNYò¦,ã¾®e1OÎè=}äœÍv¤‰Â <âáñä®Q$SsU’Xr|Q*@¨ ¹V€S®«?²ðî>8·ÿÁÏ? <ȘFOõ¤ ÛSßû-ƒ”ÇðdCKEKâ—­ßñ­ïü‹ÆŒ;ñ§ã#ÞÍeðKÖZv%½„=7÷¹·Øf4WMEf¹yÆãé›ßþ®™ž;Û^ÁnyWï„IƒlÀ*ÑýŠ›‘L€ÉÃ0Á ÓI.ƤϽ1…5GbL쥨@~ ƔߺÏBÉeµ¡zE1‹TcR·êfȧ”ªŒ ãÂÉ3j4È$ïÀ“¶f²ähŠ`•ÜIÞ@7K‚. ·$ÃÍο¾°gŸû'®gŸ{±-Ķq0&%è¢ÿÖ·¿ksKض‚ö££žy®xH/ff™‡#ôÞ‘°pÖJ1|/ =[¸¥bzÉð&ZÌã]²0¦5–— 3‰ã%ÃýR»7~œ‹êœŽºÌ>"(Ûw’DÙñAjLÕbL˜†_t°þ÷0Lh+7îÖ§i'ÖZŠ×÷a²kßÂÔ.ypÑ]#V£úÀ0š·Ñ©ÿøÀÂ;ž^%Ë t­3”´:ìl²ôÐHŸL)ý›3ÛT€ P*@¨ T€ ÔI0L—]s³:ˆÕ8×x<™¶ì-<ž´ÎÙ,'ýǽt 'Ž}åââñdäÜÍÇ_=Éz<±±ˆI'b½è—`’©Nbò´T€ P*@¨@j Æ”šªjxFa&€ Ç×a&`LÞhV©ï}œõ«®–&ÃÆ„!·pK¾£Ë¯/ìuû}0àÛºú]ìJ…Èq¶ï%ØŒf.~U†èb3RzIE‹ÿÔN??Cw$]І©‹#ÀTÒ Ó®¸I0ÁBSNÁšc’Æôën{(Œa¢7¦ˆöMŒ©á~^ $Fú›ªSTf$k ˆãs, Ä >•Ê,aiŒ ¿‘Õ‡â2=ÕòXÓ}-I?b*öÎûZ0j,b’N*&“B=*ù\+©S%ÿ†é]I·-ýöWêpS6WÂ6Þáo©ó¯.üM÷+.¿îõÿ)܆•&·$CÒñ3–]ví-gžÓ­ÓÏOëö‡ËeTzÙµ½1*EêöûË10;})—KgœÓmÌ´—Nøù©8[Ÿ{ùÓ5½Ï8»ë ?;õÐÃúó=`êéOW÷>þg§" zj¸ûë{ß}Û]-‡þð¨»>˜¬oOD:åÐy]¯»ÀÐÜ5`øq'ž‚tK¿q¼tÞï.ÃÇS;_ðoý³ß¹heî—Ì!¯>YÒ+˜ÌApÞ˜¶¯_¿H7ëáD`¦º½,†é¤ÓVnØíxír&a˜Ð°ÊYcÉÝ:tù-C—£a-€€¨šk-îùIJÃäºb²ì ½Vì|zòÒCŠ.W·’ñÄT€ P*@¨ T€ ¤L‹aºúf<Ë㉮¯Ç“Kû¿p÷È5…P×ßyhÜ+x<éûÌ*q;·m0¦¢%¶+&}<éûpkDt¹”‰ÅìR*@¨ YR€S–j³¶eŒI’fÆôÔ¨)¦ʳÞ2HÓUíMEá;,hÉâ–€+ýζÉð[×ÀcnÙ6;KßÛý 1!©ï%Yú~Óm÷t‚‰ÁŽ×aÙŒÆÏ½ßKb!êqë=ÖºèsºÁÛ‘Ã^ÐŽ=–=¨`:ýì®bš8o-Ö'ÀÄ#Qä®éuÖ«ÃâóÇ+{v<ñ”Ž?=E¬<=>ÛH§t¾à—ßì$;…mͱì8À˜ào‰S”S¢ñ'T # ÔÙT•XŒD*n “dM=+iNKcLêÊ f mÛ°q_Ë3°)`e»FäÕìø-L?’®ë}·,_¿õ®€ð‹&+Ô†½j$ òaîéÕw =€–B¾Wÿé[ÿ0ÉcɇœÒ§æiÆ¿ÿéI§.µ]âÇy&ÛÐàxiì‚­clÁBç®}ç\ײ•#Áýc^1gs÷ûö|li!^CñZg±dÊõÍ…§T€ P*@¨ 1°¦›<ËuÔs°K¬g“…[…a¶¤ÞO.`ÌÚ îœƒÇ“AÖÞkš?ÚµxŠUºÉÔ©ãñ·Öü!‹'l´o­‰Ñ¸x T€ P4(ŒéÚÿ~ðÁNLTÀ«À=?)xcR·L®g¦N'ÿäÈ)% Ra&'ؘ~ú‹Óf/yUˆ%~›.—„[²íJë%^‡šÄxdaL÷N{a6¦-Z'6#؉à„I¢s<2|¢0­9ðnº_úF1Ƥ‹ØÅOëä%Æd/Që =Öªu× BÈ`½$˜zÞ1ð÷—ß\$gÓP« 1¦Š;DbLKÇRÔ+@Œ)õU˜ßˆ7¦ €D’ S‹“üF~ ÑéR-$¼1ýåÞ– ßžyö‘þ“lJÅ^”NÒ$1à¼iS‘3Oׯ’£X!á6ím0CI¸÷DêСƒøùX^’Œ8%!N’C,Ù¡‹‘d *Ä’õ±ài CÒ·/½¦7襖áqª®]Ž˜qê{ ˆ’ŒP±1tÌl$¡—„µhI\.áÝöºÐè%M‚.)}Q¬?ÎÂ*ÆÔýÊžW÷ìtéёƄ¸ð& $_ãj’¡­›vÎv!}O¼ä˜ÁãÂÜÆÄ˜¶Þþóà§óɤ¦Û¿ûÿyhp«—^²W9K›±V9Ûª^CVã㨹›1¡¾PAS^Ú;ž"àï*p­³ÊÒùü?Þrû=ûâ«TÿÁ™y*@¨ T€ P*@j®Àûï¿Øa‡M[¸Æ gÇ+˜¬õHÝúÎÅâ }<Ábn<˜ô~b9ÞÁ0áñŒXhqϨ5ö“ NÎuÅ$'“_ܱSÎþÚ—úßüÆËÕXzF`¯y;ç © T€ D)ðÄù5¾KÖt&™yK¨wÖéÈÞ1% u»m ´7ÁÀ4bÂ<@K ”`3»¹^¸%è(²+ýü41!‰ñ_ÉøÜbtHtŽ3Îé Ûø^’%î° c²ãÇY Ú‘`_€­Ç²2X†ËÖ0aÞË–¦—­Q=V&`û±Q3-‰õ¡û=‘`ƒ€ï%1ô`²0¦Vc‚}ç‘g¦cše¯aÐ(rà 1¦Š»bbLKÇRÔ+@Œ)õU˜ßÀƒ’:Q‚[%øT2µ(1ÒXr“'Oö{sJ—®À˜n¿g‡:2?â[kÔÈ!EÂIf¼ábDÉ¡”„UÂÈÒ ®ˆŽbÉeä±oŸ<ÒŠáæ§­HpÖÐÓ&–.»¶÷¥×öVbI6º½@ôÀ•0BºdzZB„8‰†Iý‚>eCK —dx ÄÑâ€+ÁÓ©‚1YCUczâÙYÇŸxÊu½îRâ1ã.¶A{ñ*ô=ü-÷ÛË0~•'¢Ø#¾—0–ÅG8Ì„áìó/¾Žqm^*B—À09þE‹Ð¥Â0× ‹V–ï%?Ìc1nZpD¹ºÝ>ýôÓÎ;zrŒÃÃ9ôR`ÒUάáÎgVÁBðÜ oرäö Ž<·îü;fK¼¨m3a–¤æZghÒí×]u}¯Í;?B"É”®>¹¥T€ P*@¨  P`Û¶mˆˆ1uÁêâÇçñVcŸžµ Ë*†ÏÜdÅ’[ÿöôeoác¯'–ÁbÉáñŒXe1zþÖ‹¶0cH´ke˜Ž>á—CGLÀ³ÉνŸ|ùZ4 zës‰º=,×'»<+ T€ P*@*RÀTN8¬™ˆÓaýxëäˆeð0Hqö:Æ3“»’YÖ3;&8^[À?8¸Cž™„m]ú¾Ü¶+© IlFسÌ6!ÁëX(Xˆn¸åî3Îî*¢ÓÏîz}ï»%‡ÐK’Ô÷’µÁ¿ëÏã£faT?~Θð>mñfO91÷`B¹13WÓØw~uá¥]v³».}‡zc5­6Ę*j…Öˆ1U,HR¯Ÿ¾S_…ù-@KK‹¢K=zôÀGS‹ÒAåð‰H‡¨¦T iaLw  Z#Â>w[£F‡¤ãÅ¢£C&EÂI”’=ÃëIb\+¹ŒÂ`$ô¸%$‰„^‚mÛê{ &!Xˆ$‡¬`GêÿÄxµ a±:ìçþö2ØwÎýÍ¥ð½„A>V­‹¡gp«å{ öˆ›ïˆŽítòÉg^ŒÉZ—î®aðÛeˆ1Uܦ‰1U,HR¯Ÿ¾S_…¹.œ( †ä÷¦TcåÒ0I)€1a\æ ûñíé]Î8ÀüJý9>8ÉáMJÉÙ¶ý* Œœ\L~êÂu~bI†žfV iôó/I„8Ó ¨º]ìõJÖ®A-ï ’ÄÞ§ª§P°bC-é|‡ŠË%IÖô´,À0N3ÇŒ t¼d 8ÑøQœoËŘd2}ÇÆW‚^ß¿uØÐb’é‰1B/™“:a’ÕêëUê4fþ–CWÃT¯ÁôÃ$E#É”ë{ O¨ T€ P*@ÂpH¦y«K>žL[ú¦3)¦Aª`o XoEˆ3íJÏ/ZWdTrmIºâ=ÀrdÅŒ+ gú^’Èq¦ï¥‚1hMÁ¤6 5ý…Ú(Ùð„‹˜ä¡€SÅÿbLKÇRÔ+À§ïÔW! p°½½Ý¯B\Œ)úcúó]ƒüÎt¾Æq€í6I’1p4·]8©¢$èRapé8öT×J#ï’ò¸’Ã-Ù¸R0±dx -¹Ü’I,ÉvIn©€.­ B—¼ãv5 ]2ñ¦Ê0¦m»÷[ÿ<¢€a ˜^ŸÖºzh¿Ï؇¯]m >x³<—fB2=üøhõÀ$“ÕB\³Ÿ=_¯.ÄÐ~Ž‘`µá‡©8^CÃD’)ÝKA¨ T€ P*@j®€L“æ®Ò9ºäÆóxb¯ävVo˳dÄ ¿¦rI&©(\¥äó«äÌÿºÞ•âàJ>–7KÖ`T’ÏÓR8´´Ðžhö$¿¥Ü’Ïå’5À ÉΆx]*ÉæÇñ·}LU“ü§>ÿÔóßÚ»¡mr÷Ž ™üÿ9ìÇ·åöF ™Î:Ë"™-Â0 ”aj³¬g×_k4ÃD’©Ü:âñT€ P*@¨ T ' €d:þ„&ÎYå,®(^_á:aªÃ3ºÜè.‡àÌ¿hlRNª&YÅäDj²êƒ¹¡T€ P*@š €…1 Ÿf‚í ©Óºœ¬£d¤ Óá.w/pKºþÙYíÚBÑ¥âÕìž—¬ØÐAôRÑzuÃýRy½1UÙ@‰1U) NR¬Ÿ¾S\yÌz”yÄ˜Ä ’&]çVŒ;Ÿoî‰Ü~ÛtžTp×).”‚))_Yš¬R¤_%fúU*rûéÕŠ£ááá,¾¾,hÉgŽYôÞërÉË-`ŠF—ª'“Ê:C 0¦âÿ<0-}¸’¸bÂ4:¸%¬–£0·.žý؃Ã"§Ÿ|rò©g<ôè³æg& S°ÐÙFǬ¥å0LŒÝÀ[ T€ P*@¨  lÙòÆÑÇÿܬ6ÿ㉳¾ÂŽs-'0~X!'ìåÚX¨-„ºÄ"Ú“údÚóžwõˆ™1LX1" ¾ð`¥<“®$ñì/ùƪ¯VN¤V« O¨ T€ ¤^`Lƒ‡O ÊáDç0 R^c“e`ZïMEv%'FG´äá–ÜõÏ^—ÄšàÄa.e·#Ç…ÒKÖªuwÉzÅî—<Özcª¸ÑcªX:þ ¤^>}§¾ Y€`r‡1ÝÒo@12y#{ßcòKî Æ’Qrù¤°Ðo‚(EƒJ×JÕàJ!Ä’L.û’™œAª;Nõ°ö·ä‹ç÷·T’[j€Ë¥°©æ¢€UÆ„EwtGÂÚ_L#fÒ±?"öÈ~)aæ°_vâ‡a}•LyÖl'âdËyä@r>#Ã0¹Ž[ãøa"ÃÄ; T€ P*@¨  É4~V[ñ㉓BÌ!…8×õe˜°€dV.HëÇ´Ïd>[ÉJ}§¾ Y€`ò‡1õaÔxjçó=N8eŒèO&{kû+øWt2F™Eaà¼~• ×JžÑg`èâ’±á áá OK~gK:T56Êö·Ô\nÉ3z®9Æ„ÿ™L”c2Óèò·“@˜R¨$3æò&Ó‘0áŽw92z]H¦†Œ²˜6˜ŒUÎÃä.ð.t&ÃÄ[ T€ P*@¨ 5U@H¦q3WЦÀdúˆµã\×Ï“H©ôL"}Ó¹’GbŽ1#Íá­‚Àß52£'ãDjF+–Å¢T€ P*@â+`aLÃ&FØ›,ƒÔYçÛ«ß½N•<&'¿]©Ø–T -¹ö£‚µÈ]fPà–Š—µÛô’….† £—,«+vX©:z‰SüFv$1¦ê5ä¨@ZàÓwZkŽù.¡@î0¦Þ}D GøöԳΠ8 ~ N*€ðÎ$¯Lõ:¾6’R”^¶–±J*nší®aÉï`ÉÀ• £Ò7KÁž–ÀÚ—†–\îÞ¿Ön[¿ý«šcL:Q.“é’ÄëVú‚dÂ~¸_ÂNqÑ„ãñ­ydô_VH¦ûÒVáD‘s&ÇBàÖ臉7*@¨ T€ P*@j¨€Lcf¬ð>ž¯¯xv,9ÇÂQ“XrZ!–ðÏ\òl%ΖÄE®† }§µæ˜ï äcêyÇÃ?0·5Fà|UÌ!©Ï¤ž“C @”Ì®ÈÁ’+KªÖåoÆJI×õiB¤9Þu0þˆ²,X¾ÂG9I¼4Å|9$Ó xðZž]ˆÔPXèL†)¦ž<Œ P*@¨ T€ PŠ’iäÔe…ÇY_a’Û©’5÷Ä «¿[l`’+qÂ$!ääÏ3—)Q¿ùª‹œH­‹¬<) T€ P*&€1=üäs± R–¥iwXPŽèEïq9Š %¿¿¥Ü’»ŽÝö¥ÚÈDŒ©âöMŒ©béøC*zøôú*d‚ÈÆtó_úGŒñ-0¦¸ƒE@H’l·ù1“1¦Ô¸oÖrUOòŒ2ÃIù P©x *îyrŽ+… µkî©‘=Lw ¡“¹ÊYŠÜí×]u}¯Í;?ŠH;÷~òåW_52ç¼ T€ P*@¨ S@H¦S–…=žÔƒaʘ†™*'R3U,  T€ P*P‰À˜ú?1¾¤AÊ13•µèݵ(’ŠV¶»±8¹%3Zœ†n$ºd^‹S%íÌþ 1¦Š¥ã©@êàÓwê«V wÓM·÷àð-0&ÿAì‘BH®«$Ÿ·$“LŠÂ’‚=yzø$ùh»S ¡”¼ R°k¥¢xpÙó®Tîð:ÕþÓB2õ8B&O…’abÇO¨ T€ P*@¨@Ã’é™)Ký'd˜V I¹'R“RÌ T€ P*Ð4€1=ôøx½É46Á õË3Ïs÷Ø9|q9BMK^\É0!¹+Û½ëÛWH¸gI;$•kR©ëñĘ*n¬Ä˜*–Ž?¤©W€Oß©¯B€ÓÁƒ]tÆ…JùÇ7bÔxƹ±#3Ž›»m×ÜàAd œdñI%¥J)¨äC[ê:ÊLÝÉÓŽ1)ÉÔ÷áVød˜ØëS*@¨ T€ P*Ð`„dzzÒRóñ„ Sƒk!—ãDj"ª™ T€ P*@š©0¦aoŠ2HE˜\sR1®TdB²‰%?´”ð•íĘ*n¯Ä˜*–Ž?¤©W€Oß©¯B€“1ÝØ§¿íÖ(8áÛ_œqnÄ!_Y£Æ‡TÊg’Fy ˆõ2I’;Ê,kaòÊË'|è™d¶)“’Lw$&vùT€ P*@¨ T€ 4E!™ð¨%O‚d˜šR Í¿('R›_Ì T€ P*Ðd€1=ðØøØ)Ÿ™ÉG)X” C’ÇÍ’?zC’-5’7bL7YbLKÇRÔ+À§ïÔW! @ŒÉƘzôyÈC™ñí/N?7â€X’¢H!LR™TëÍõçI>©Þël`L’‰ û{*@¨ T€ P*@š¨€’Ld˜šX M¾4'R›\¼< T€ P*Ð|€1Ýÿ踘)g}{¤uÉ•|æ$›Ê@"ÆTq«%ÆT±tü!H½|úN}²Ä˜lŒé˜N¾ðâëÃÒÑ'üò_¾÷ýˆB¾ºî‹c¤?^wá¯b”:Ÿ×ý¿ü×ÿŸ¯ýÃ7FŒ›¶yçGš¶íÞŸÀåÀ'Ÿœ|ê'œtæU×÷2sëßÞ¹÷“/¿ú*E`–¨ T€ P*@¨Ȇ ™Ž8úð#Žî4tÄ„èÇ“=ï}š"³E p"• ‚ P*@¨ȽÀ˜°l¾ƒT¨™)9&•ºæä»ßûþÑÇÿ"â0á}n7ÏóÅG>Ï}[;HŒ‰m€ äW>}ç·î3^ò/_qñ,XЧøàÃL¿ûãågÿº›g'?fX˯¾ñ—§U²€«6ìH>ƄƒiHï+È0åª[ca© T€ P*@¨@2ùÂy—?ü?É0%³vêž+N¤Ö]b^€ P*@¨Hº% R—\q R¦uj@“h{gÍ97ˆ1áŸ@Œ)éÝóGê§Ÿ¾ë§-ÏÜTò…1ù¥ŽžQå·T Pdzc²š÷š‰_^ñŸÛß|3¬â臩©ý-/N¨ T€ P*@r¤ÀÂí Yñà$ìñ„~˜²Ü8‘šåÚeÙ¨ T€ P  Á¥ cBs$ÆTá’?£P€OߨD!HbL…Haõ?ñœ™T ¹Ó‡¼¤Ã—c®m7ÀT@†‰w*@¨ T€ P*@¦0¦ÇÚ:ü틯I&2L «ˆæ\ˆ©ÍÑW¥T€ P*@­@&Í%M/1&bL‰þÛ3sT Þ ðé»Þ óüMR€1&*P¶ ŘÖLÃd¥+þîËÚ=$¦&õ±¼, T€ P*@¨È©ïºq×G Px?ÉD†)ûm‚©Ù¯c– P*@¨([¦?™Ì1&bLeÿù*%øô¥ÚdY ˆ1•°drœÇB•¥@B1&Û““Æ\ûåW_)ÉD†‰Ý> T€ P*@¨ õS }ûþ¿î8¿I2‘aª_E$èÌœHMPe0+T€ P*@¨@R(Ë Áƒc*@Œ‰SRþáÌhŠ|únŠì¼hý ÆDŒ‰ ”­@1&uÅä:d:øán!™È0Õ¿#娠T€ P*@¨@®8dà!%Ë’iÇ;È0•*#p"5#ÉbP*@¨ µT &—ÃÃÊR€1¦ZþKy.*:øôº*c†ã)wŒé¯ûò“ϾˆHø[ôü6c |üéߢ …fïÿÕÀ£LWLB2¹—É„ÔÀ|ðRT€ P*@¨ T€ äK~/ôÆÔ²¢™&¿6¹um+¶l[€$Bà£l \öÆ1ù(Ÿ¥åDj>륦T€ P*@"(i*i›È˜9¦dqâÂF¦¾vÂcmvü"Õ T w ðé;wUž—çcÊK=³œÙVÀãŠÉpÈ”ír³tT€ P*@¨ T€ 4]PJÝ'wß´o¦ŽOu¨€ {c_Mø G¶µ·aC¿jzæ™z)À‰Ôz)ËóR*@¨ T€ P¯ĘØ&¨@~àÓw~ë>ã%'Æ”ñ fñr¡€ß“á) °T€ P*@¨ T€ 4I³{ˆ¿% K`˜$`•Ú÷·cC¸%NøV¾‚7&=¬IYæeë¯'Rë¯1¯@¨ T€ P*@DbLl T ¿ ðé;¿uŸñ’cÊx³xÙW Ð2e¿âYB*@¨ T€ P*@)UBV]¶x` ÄR—Ñ]ð-Þ%i˜¹D€™¨‡œH­‡ª<' T€ P*@¨R€Ûȯ|úÎoÝg¼äĘ2^Á,^¾˜Òç nWû¶å«Ô,- T€ P*@¨ ÍS@‰%ÝL’# !WLpÈ${°½ÿ¯û›—_^¹! p"µ!2ó"T€ P*@¨ T cb3 ùU€Oßù­ûŒ—œSÆ+˜ÅË—ĘòUß,- T€ P*@¨h¾ —à] èÜ,In6íÛ„p„xsÂ3d’=8F£Ë5?ëÌAýàDjý´å™© T€ P*@¨@±ĘØ"¨@~àÓw~ë>ã%'Æ”ñ fñò¥1¦|Õ7KK¨ T€ P*@š¯ %$äÃô±„=iNÞñjßߎm9’¯ì+À‰Ôì×1KH¨ T€ P*ˆ1%¥&˜*ÐxøôÝxÍyņ(@Œ©!2ó"T 1 cjŒÎ¼  T€ P*@¨ T€ D(À‰T6*@¨ T€ P*Ð(ˆ15Ji^‡ $O>}'¯N˜£š(@Œ©&2ò$T  cJF=0T€ P*@¨ T€ P\+À‰Ô\W? O¨ T€ P*ÐPˆ15Tn^Œ $J>}'ª:˜™Ú)@Œ©vZòLT é cjz0T€ P*@¨ T€ P*À‰T¶*@¨ T€ P*Ð(ˆ15Ji^‡ $O>}'¯N˜£š(@Œ©&2ò$T  cJF=0T€ P*@¨ T€ ,Ü~ÑcmœsÈkCàDj^kžå¦T€ P*@¨h¼Ę¯9¯H’¢Ÿ¾“RÌGà”båé¨@3 ÆÔLõym*@¨ T€ P*@ cÊukàDj®«Ÿ…§T€ P*@¨h¨Ę*7/F¥Ÿ¾UÌLí ÆT;-y&*Ðtˆ15½ ˜*@¨ T€ P*@lˆ1åº!p"5×ÕÏÂS*@¨ T€ 4TbL •›£‰R€O߉ªf¦v cª–<h®ŸzðÏÿv·«}Ûš›^ P*@¨ T€ P*@Œ)×m€©¹®~ž P*@¨ T ¡ cj¨Ü¼H”|úNTu03µS€Sí´ä™¨@s½„{Õ€“›› ^ P*@¨ T€ P*ˆ1åºp"5×ÕÏÂS*@¨ T€ 4TbL •›£‰R€O߉ªf¦v cª–<h®‚1!®_T€ P*@¨ T€ Pf+@Œ©Ù5ÐÔës"µ©òóâT€ P*@¨ ¹R€S®ª›…¥E ðé› "£ cÊhŲXT€ P*@¨ T€ P*@š§1¦æiŸ€+s"5•À,P*@¨ T€ äDbL9©h“ (ðÿgïO å¨ÎtM˜î¿‡ªÕ]·ïß÷ïUU]¶Ëö-nßÕUEácd—'fmflcËÌ3¶0 FƒBLˆQbš%40‰£Yh@H$el¶þ7â‹Ü¹3"r:'2OfÆsÖ^gʼnŒŒáÙ‘ybïýìï£õÍmÑ¡И:´b¹¬%°{{÷ÄýT>xs]ì_›“"-É^2WÉÐØzm©õZp TÁqÍ€ @€@SìþÓ¶{—üUªÆ´âíáM9ÒèHmzà, @€ò@)µÌ5B ­oîŒ%€ÆÔ¡Ëeu"s•teI!—$-9]i÷ön[¯ßæ3½1o¢6°5d”ëÄ›‚k‚ @€@kH ÈD(¦Öª¤&œ ©M€Ì! @€ @câF€@~ ÐúÎoÝwø•£1uxsy€ @€ ¦H ÈD(¦¦ño•Ñ‘Ú*5Áy@€ t>4¦Î¯c®åÐúæÞèPhLZ±\ @€ @ /Ä2Š©/*¡¯IGj_×LJ @È4¦üÔ5W 8ZßÜJ©C+–Ë‚ @€ ôX@&B1õE%ôõ1éHíëàø€ @ù!€Æ”ŸºæJ!'@ë›{¢C  1uhÅrY9$ð§÷¬›³gǦ^:— @€ ´‰PL-U/Í;:R›Çš#A€ äSÞï®?Ïh}ç¹ö;úÚј:ºz¹¸\À¤ÿU“†æê¢¹X@€ @  ¸€L„bjÁÚiÆ)Ñ‘Ú Ê€ @4&îä—­ïüÖ}‡_9S‡W0——#hL9ªl.€ @­N@™ÅÔê•Ô¸ó£#µqlÙ3 @€J  1qG@ ¿h}ç·î;üÊó¥1Í™3ghÅŸK/½ôg?ûYåmxµœxâ‰C† ©|!›6mj³OÿŽMSÞëã'†´Ùisº€ @€@'è~wݘ§/èÄ+ãšj @Gj Ø€ @™@cÊ#;@[ õÝ–ÕÆIW'/éä“O>èÃ/ºdˆ• ýrñ /òƒƒûçÙç‹/S¹ Y^vÁÀËÎ/SÎxÙy N–s/• Ÿë•s.ì•Aç\•³/”,g?(µœyþ¥Q9ïÒ3½rÆy—–”s/=ãÜKO/–KN?·XN;ç’Ôrê9—ål¿\|Ê٥嬋O Ë/Ë”g^–~ùÅ™£rÆÀ_xåçg ,)§üù驜œV~vÚE©å§§]ôÓÓ.üé©ñò“S/tåÿ›ÿÔÿ¸_þä” OŠ— N:å‚“~yÁ>_Ü_’SõP+m1zôè¾ù£~ðí?þ¸•΋s @€rG`çÎ_Þó;S§NÍÝÅsÁ"@G*· @€šE©Y¤9Z­ïÖ«Î(¹Ó˜†ß>jëößo‰Êî-ÛKÊÍ·:ú¸“6¿»ÛÊ[®¼ó»·ÞùÝ›®¼ý»7J˦m»\Ù¸mWPºƒ²!*mØúÑë^Y¿å#W^Ûòák›£²nó‡QyëõAù@eÊ›QYýæAy#(¯¾±3*›v®òÊÊ;Wn|ßÊ • QY¾áý ¼®òÞ²BYºþ=W–¬oÉúK^ ÊbWÖíè*–í¯¬-–Ek·/Z•…kÞ Êêw_öÊ‚Wß Ë;*/©¬ŠÊ‹«Þ ÊÊ ¼°òí¨¬xûy¯Ì_þöüåÛTæYY”¹^™³´Û•ç–t»2{I÷ì%[g/Þ:Ë+3»¶Ê–][þöï?=vÒ‚¯l™neQP¦e³ÊÔ…›Oüåí¥1Éa:òG'¨*GÜûøQG…É”É÷#; @€z@ t˜ú=þÌÜ…«ºüî!˜L=`Øöo¡#µí« € @hhLmSUœ(2'@ë;s¤ì°5äNc’¨ä,¥äÂM·S`/½£Rª.ÉaJÚKoÿ..0…öRSÁaJL‡© 0ÉdÊÀa 4¦¢Ã$™)®1…SQcªÓa*§1¥8L¡ÆTt˜V–:L+ä0UÒ˜J¦¥1‡©[S‰ÆTt˜$35¦T‡©5&s˜T³ªMÕÝí˜L­ñõÊY@€ @ ‡ä0}åkýÆ=3ÏÚ› VnÅdÊám@4¦ö¤x¸ÒK ¿¥+dŽ«{I‰äÖ«ÄRÈ¥E`ª"0Õ”H.Ê%$’+ä’‹É…ScrÉõÐaª#\˜Q®l:¹x(¦ S¥PL¯l1éAÓ˜JÓÉM ¦6J*g“ªÛiL$P@åþ»õnL¦†|i²S@€ @ •€9LãŸ§Ìæþ,‹®uÛ_X¾å[ß9˜ìr9ºsèHÍQes©€ @}L©+€ÃC  ÐúîCøº‘ò¨1ù–Ò&)Jž¥tã-Ò˜NŒç‰sÞRR»ÉdÝåê=wZ’þÔ)G69X=ø‰,‘œ~4KXÚ€…JÒJ­‘d{Ó^ÕJ[ÐÐoÛ¾0u,Û³ÖÛqmcûm“ûqbSû|Ór¦€ @èLr˜¾úµ~ONžη)›ðÚͲPóä¹®7¿QÉdµÔXжBãEñ“¬A¡v‡ ïjo·iö’š$Ú‰Z%®ybRlâ„iLjªÄÐZÇ '½Ë5U´¥­±ý¸HNÚ^'f (ý¶íÝ™ø·ˆ­l㛆ŽÔ6®Ý™tèw2—@€ ö ‡Éw˜^ šœQ¤ØBÂk›e¡É-ŠÈ;sÑý¾]“ÉÓ˜,–’~L9²æF²ñ¢ JÖ/ÚÆiL±6Ej›¥–:°´îÇeÁ¶Pµ®Md‡¶ÓpiéÜÆ–ÂÛ¢4Ù[,n-'ÐÒÛБÚÒÕÃÉA€ t4¦ŽªN.u õ].6n¹Ó˜®½éε%éÞ$$Y ¢(éÕþGŸ`Ë~Y“È秇‹,Y¤¥ 7œ•¯ÆJš´Tˆ·”ð–ÊG]Š©K–PÌ/å2ÇÅb/¥ØKa22+Šù•Õïjâ¬+šA[(ï,xõ—TVE% ¿”H!×ËLJ'—šE®$S,‹\™ L˜,‹œ4¦1øá—bË'þò‚s. ÜõŸü¥?Ú~¦(YCíƒ+ÞVª¾¹Ë¶]ÇÃU³Ë¹N|›OìkLþlãÔhLþ€u¾×®19¶æK¹pM±N|›âÌ @€ Їä0}åkýžp¹ä¼l×jœé˃¸¿Ûâ·N®ŠÉfY(“øŒ…5™LÉhLj2X°Ø 5d,’k\¤jLÚ¦7“Ó•Ôl±ltnâ‡ÉEx²H·ÚÌÚY.“µ³ÕÝ™÷a÷öÐt¤ö– ï‡ @€@­Иj%Åvè<´¾;¯N¹¢@î4¦k~{§o Å–õª4¦²ŠR‰¥TÆU2u©Œ±”*-Eñ–ÊzKïWõ–,§˜²Å¹ô[)Iô#WÈWÁ^²a‰ÛK5†_ ºªÃI·ê°ú¬­TL!×I“Œ¥¶Ó˜<‡)J,¸<Õaª8H0wé6!½nD“Éuâ«K]=éJ*§o ’LcÒ‚VÚK±hL¶¥¨_>– ¡B4&õþÛž]·¾[˧€ÆÄ?/@€ ô-¸Ã´á}×< §‡) ÅΊ æÀ¸PL…YjžL{yÓV‰ÉT5©œh$/¦1©‰¡…/rŒ¬¥c™²]§ÜÔ‹ZÚ6ãB{³=kÁ2kë|th•LNRcG§ášT¶^Û«I¥Í´ÞO¥ÆÔ··7G‡ @€@Û@cj»*ã„!4¦ÌP²£Ö"P“Ƥž8SÚýçä“OöÛ;½€I~ð¤`yØoïèÿãR)¥ÅUJæƒKË Wf)i,)I\Iž¸ ï¾âç-Mœ¹èì‹.×oriÂŒEg_x¹~Þ’§.uá+=5{ú ¯V¼¤Þä¹KÞ¸øW×/dÏ8ÿ2+W\ç˜ñ3á— öR-á—ªæ«&0=—]¦éA¦(“ ¹Ô^SÌaÒÁò׃\r×?²ì×£_ùõèEcg®vÁ›n@ªÖÕc?5S”¯Á$óñm½öö‡*Ädò;Í]ß½zám2±´R_úZp?¶Þ6Ðof°/ o¶}l¥¿gõìûÓŽíX±ïŸZ†Úý›Šó‡ @€@Ëp“K€î;LÍ\ÿëûýêþEÎxÍæÉ¨i©†ØÕ-—ðZZl–…Ò…OY°±²ÉäÚnÁÁ©Ðx‘cd ½ËotX‹CÚ³£RÛ,5¶;$EiK5d¬¥£F °dõ›TZví›bo±3±`N±æRËÞÕOŒŽÔêŒØ€ @Ù@cʆ#{@; õÝŽµÆ9{Ì:H"©®1ij &ªOͦ-¶5Õ@cºñ •äŠï]}ãGýøM¹å•å'¹ò¾:pý²B¡•¬„–’+€â—׃HK~°¥a7üÌg?oÒÒ-w=ü…/MÒ’~kYÒÒð»Þ÷K_“«¤ßÃG>ä‡\úÌ?~þÌ †¨üdÀYZ5vB,g\à¸x9ã|bÖ¿}i?—6náêw?ýŸ?ñçgž~þe*‡ÿèDýY%öR2y\©½f (~éÿ~°rœei·:¯]ñ&õh‡ekIþ¸Å[gÕ‘B..0™ÉÔcé“?¼âíáÖ|­i9LGþø„ÀnÝ!G™zÑ/Ú Á‘C¦\~ß"Uè˜ië¾uÞ„Ëî]øËßÎUqùÜ Á¬Å[gvmv[%“©iWÇ @€ 6"`Óøgç¹<×6ŲœŸ4l–Šš'ÖB9õ¦yr˜F—¶PÔH´„×|×Úz“_Úðõj1™Úˆ§ #•û€ @Í"€ÆÔ,Ò­G€ÖwëÕ gT; HšKÍdo¯¢1Y`vÛT³-(zûþHcºú†;J $ßFÚyõ #L©\ÊYJÉÐJ‘´”ЕÔÏëŠuøªÌ|iµŒ%iL–$nß/íé Æ‹¯Ê[’´¤ßOÍX¨Å[Òr——0Nê’Kg>“%{bÚË2–T —Þ?uÁOÌ9æéûâ~.ä’ä-7Ó©Kzuèuw(ì¿Êýãf¨¼(o)T—Tî{|ƣϾ8sáͦÕï/o.£rïc3œ½tÏ£ÓU¢äqË·=4ñÅ»™þä¬eê°Ö¿~á«c'¼j/…ƒÂ²8.0É¿ñÊ–][f¼•é¯l Ê¢ ¸ðK–B.Yz 1­Ûüî²î›Ç.ÿ»Q]{=²ò³Íù˜Ãd>œ Âdw‹n iLãçm´z7gÃC¦¨O¸zæMã–«¦T5‡ž2~îÆ’A‚%Á ÁÌÛÕ·b25§9  @€:€9Lãžç" [«Ö°×?²ôô›ç«•jSh4ÅâˆË¦(êRÔBYYl¡˜Ãd¡˜l–…š'ϼ°áëßúÁ„I“;× t¤r@€ @ YИšEšã@ õÐún½:áŒj$ ˜åЦdÇR6iM©««K”½Ù_®ñØ­¶™4¦«n‹äÿ©WüÑ ©Ä)¥Uòã*ù¢’ëÛuÆ’¿àÒÃÉLzø©ÙÒ˜d¨ÈUÒBoiÝŽÐRŠ~›½¬ E%+’lAýÅGüèÄß\§¼¥“~q––•'îÀï¢HK ¹¤eùIŠ·¤ß¦1…Þ’Ê;¡Æ4ã¥0gÜìEõçˆÑOˆÙç‹ûpò™*ßúÎ!2cT´æø“Ï<ì‡'ìó…ýä-zî`•ùaì¥O}æóó—o{xÒ‹²”N9gСýOPQÏõ/Ï–õ[ë‡Ý2æ¼AÃ>õ™Ïé·MÀu¥œ½T~i«o/©¿».©ј$0=·îº1KþV“•æhLÃô£ &\ä½ÙÝ!¡Æ´ÁrÉ]óÐÍuVUj¨à‘Ù냚ZhL÷L^Mt.$49^WÝ2¶Bv¹Vûür>€ @€@_¦ýú{fž›_á‚0¹æ‰²];‡IÍϰ½ùNÐB™´P4ãåðÁ“ïy¶ÐB)„b²Yš‹2ñù×÷Çdê« Îü¸t¤fŽ”B€ @  4&n ä—­ïüÖ}Û_¹ÒÁéÇ.C 2™üKªžTNј,Þé"3µ)iLWÞ0"EH ¢%ùÝ®¼^Óñ–è-–î-©%ÅÖ¤*Jneä*­ß¡ÞX1WI©â.zýâÐOÒïTiɹJÎ[ òÄ…‹^:𻇪(Uœ–rI“_/¾ü:ë;3~¦IKzé¹W6Iv¹aăZ£>åÀ[ Õ%½äŠD¥ÓλLQ—.¼ìZéJf/I]’®tÁe×jÁb/Icºç±§œ3XÆ’ì%Eý‘ƤßJ7dØË'oÉb/™´4åÅõ*Zè÷íƒãöR˜<.–?®žðKQþ¸iiá—b™jŒÆ”˜š¦1ES!jWñF ï»C”¦AåÄ«g)“ÉÝ4n…*ÔÒÉ©¾î¼ö›çN4jA,_ƒ$0&˜LmúmÆiC€ @ iä0}9p˜æÆ‚ [ÛV-5O9˰䖥™´dÞ’~/ Ê»*úSÆ’IK7Þ(JZ¸sÌÓŠÃd—LZÒf‘º´êEW²œq–-N/Ýÿø ©K¿ºöŽOýãç'>·\*Œ¼%™I®|ó;‡hÍ)н´\±—¶É^RÚ8ýV ’Ç- 4&S— oùœ¢.)Ó¨G¦…+?'{éÁ§_À¤?öRÝöR2\ ö’“™jј†Ž<ÈÀäB1 ‹£°L%+ ±šz¿ò—×ìuÐa?Œ‡ìò&K$'‡I¹äTûªk]šL¦©/¿¥<ïöŽ¿jæ¹·=¯òàô×,äÕì(\¯!Ì»W̵'“éÛßùÞŸÿò—¶ÿ¶ã @€ ¬ |üñÇûìûåÇ&Í-i¡&kÕúÍ5KÍaR E“Ú•®…rÎmÏ?0}¥“S0H'ׄ×õ›'2™¾¼ÿçßùW½oXuÞ_õß³®Þ†íŽÔ†¡eÇ€ @ˆ@câ–€@~ ÐúÎoÝw•;ÖL$-¸ÈLvaÕ5& Ť-¸ìtmJEј®¸~„g…ù¹¼¢W¥1•³‘ÊRªj)™«ä•íÒPü”pó–¼qæC¬H':ã‚!Ò•öýÒ~Sæ¯2iIË2–iiòü•æ-IK2iÉŠÞe Š´ôÌÜ•¡®¬¼cÌÓò–î7CÛ[È%S—&ÍY¡KÀ´2(êY–ºtßã3,ð’\%Kš/«‹½¤œqOÏ^þôìeEiiù6å‰S¤¥SÎ$QÉb/ÓÒnKÃïyB}Ó*˜4Ñö®‡§Yì¥s û—}¿*¥&Иoå—® Û+[üäqQ渤½äé8±Kþ¬Ecºà²s§¬9óžÅ)½çc–ýç®­CW&½|Þ׿ñÅgç,q“›]&˜,‘œ‚0=þÜëVé ©¥A%k˜¼àMåà³àX‡ ž<á…M%ƒ¢ô½Ã޾þæ‘Ýïý“©M¿Ù8m@€ 4”ÀСCO;ç×"öš'jçFÉÍ/¿o‘ò\—­ÎÃ/›2øž—Ÿ}éMµò‚ʲB ¥˜N®0Ë›”rÇØi_øê>οêÅMW5®ÍÕŽ{~bõ¾³ZÑYÔ,i²/@€ T"€ÆÄýü õߺï„+W@%» å…“Éä_Rõ.0 PŠÃd1™œÒÔ¦TéºÛS¬£B´$½zø/Ù 6É‚'¹øI 3©’¥dÞI¬¸|p&*¹ÄU E¥3οìˆøÀø™ú­euŸ®Q†8ýÖr¡ƒ8°Xô®Óϻ̊Œ¥N>Ó¤¥ëoP“ÃiYÒ’ÖkYQ—$'Ic2i)(+Þ–tïc3,[œ%Œ»`ðµR—öùÂW¯½uÌ݉᮹uÌS³– ·Œv˽E“òÇit¥cz†â-I]ÒKZ#uéêáÚæsãg,=ø¨ãùé#šzî¥Ã´,{é>ó¹+ohL¥ö’¯.qƒ¬,ŠÊ´0Œ•Ú¥¥ä–µhLç\8xý–V½µ>)3=²ò³þlÚ´éÀ|æ¹%Þ-W˜Â@\ïqÙ” F¼ YΖ¦AƒªÊ[6àÆ¹ÎxíŠ1]Ç]9# Åêb–N.Åä ˜Ã¤+UÁdjtµ²@€ ´)™L§ž}IJó$œb´aW-”®žyÓ¸åÊ%§Ê7Ï› T×7X ezÔB‰GŠ- Å$‡i¿ý¿±xõfk¡ìþÃ'mŠ«§=÷“ј–}B€ @ Ý  1µ{ rþè94¦ž³ã}L@¹ä$ IC’ŒË(§3«®1éý²ŸôÓî“®VÓÐko¯` éÕÃx\*É/kK"'¥:Iµ[J¦+¹dpf,Y>8+æ'Y¹âú;e, ¼ü:‰JV†^wçá?:ñ¢Ë¯UŒ¥(=Ü«Á<×Óλ̕£Ÿ¶ù‹>˜»ÿ´mé¶k+B‡Í–ÕÐ/ÿôIDATGØL¦ 3Û LÎar#æ0F ƒ–K.ŒÃ8LʼnÎå&L¦¬*Žý@€ @ # ÈdúåY{ÍoŠ…Mªñ¦XTq˜ ¹Â+8L©&Óĵ×íXבx+\SÞjœë… @€@ИjÅfè@hLX©\R@ wÓ¯†Ý–ŒäÖèÕCûWaƒØKiZR”ýÍ÷“Šá”ÊXJ.¬NZh¥”èJUt¥(ÌR¥HKµHK Sê-ã-Õê-É¡iuÉ÷™zÉ4¦ª?]Ý]ýîïWu³Ú7É´ÿß|jÆb‹ÀÝ-%#i“4²R‡É™a•&'xïÃ?Ô~†l @€ ä‡ÀàË~5àÌ‹£v®Åˆ-Dv‰äâab“q˜jv˜Ô<™·üí?ÿ¥ØÛû¶½óCÛ])S+K† @€@-Иj¡Ä6èLhLY¯\Uþ4¦Ë‡ÝVÆ= ¢"]>ìÖC:.f •’ÊOª”ú­ÐÉk àÂÞÞ2¢RakjJ¸BïpIb¸ÔÜp)ÆRt,ž!.UZÊÒ[R@ EQQX i‹6GeáæÌƒ-UÝaã4&Í –ä^õ±ËÇŽX4B¥ÿcýµ¬ßö}£yÃZi Zi¯Vý*zýõ2™ž˜ÞU!°)Î~"9ËÔšg–ÑÏâ0©À œkq˜ºßû½?HPõôØ€ @ÈK]þ‹3Æ&—ç:&¶Ûš'Å\rõ8L Voßý‡O^µ¡Ôà0q€_g Ô‚‹ÏÔ½«[ËZПÖàÒ6Q5hLQ\ @€2'€Æ”9Rv¶!€ÆÔ6UʼnÖG wј†\}kjÖ6[©W¥1U—LEŠ•‚–T]N’Ÿd%4Q*”@RI„VŠ»Ja*±ô¬p^Š1 .±’Œ´T]ZJÉW>ÞR+yK1±©q“>ê4—¢¤ë4W7º¹MöÑTº¼¥9›æhÍ®?îRÑ‚¶©úÁ5“iüôWì†qSr„Àw˜,—œŒ1#€ÃT•3@€ @µL¦3ºV­ª.Ïõ\ŠÅ’hŠE&“NLí)3“4?D)µ­Ôªrñ™ô§iLzIr­VËÔ‘Z.¹o·Acê[þ€ @-K©e«†ƒ@à  151èyÔ˜\$Ï7²Hï\võ­‡ylä9Ù¨®…jf’“–J¥b8ëü­à*¥GW*`) Ï“È —4–Ì}‰—`¾l¬Ä“Ä)Ø\™¨¤Æ[*84Uƒ$5mƒ†jLNKROºùI®ŸÝ:ÓmZ°úÜÕ«®¢^uë^¯úc&Ó¸©¯D·G¨©Í]êa Gz“KŽ8LUk @€ # “éçg L LA;T1bý0±Ê6NtqS,î;m¿ý¿±xõfËjZbq˜ì NKr¡mÕìòçXX\kg©¨96lþ°¨24¦¨D.€ @ €ÆÔªìíA©=ꉳ¬›@î4¦Ë®ºµBô#½zð‘ÇVŽT)Å[Ið¤xº·²~’Â)y•ÊZJC+Õ +©y«\%+)ÆRä¿ÇÒR牫Kj¨Ædó€ýžtú¯½ªßêI·¢™Äš=\ãg×L¦Ç§,rSr„ šåL.¹™² @€ ÐS2™N>ý¢ yF`*æ¹.b‘•äӴ™!¶`g-QÉ"0ÙJ©Kú­v–kp)DSO¯¯…Þ‡ÆÔB•Á©@€ @ • 1µRmp.h.4¦æòæhM#;ið•·Î_n‚Q¬_y‹4&çU^ܣʥë­rÒ7ëðõ»}“ àÜšÔLpšçêEWª®+ÍJ‰±TÈ ΑõK™HKž´ÔzÁ–ª*MÓ˜¬Ç\`—ËÀõ¤kAÝèöªå>Ђ۾öϼ™LN^X˜ü‚Ä,grÉÕΖ-!@€ z ÈdúÙiyS·Ës]2Å¢Ðrìq&;1—?ÎiL¦+Y+Ì^5‡I –Å»öy#õ^{3·Gcj&mŽ@€ 6"€ÆÔF•Å©B chLew­B wÓ +oqRQrA¯|ıå6ð}£:–à ©µ”@QJËþf–R9Q©\h¥ ÞR])èJNèJ%¹áÂhÿV¦Ee³‚ÿeáæª’PëoÐ8IÓ‚Õoni ôÛ>èêCW×¹%’³Îô‰k'j3­±¹Âõ~˜Éôð³ aËe‘s#~¦¦zÙ²= @€ P/3™ü,rÊNnÓc¬yâ’½t˜tbjIYÂ8IÍ+×àR#KÛXp\kp¹vY½ÕjÛ£1µZp>€ @hhL-Rœú€S@çÍ G)n -íž[(ƒ~3ü #Ž­E9ªe›HKªh&%ü$ÅR* §T!\yQÉÃ…®RͺRÁX*èJ$-%µªÆiLÍøÔ†Ç0“é¡g^Žê:m„‡©iÕÁ @€ s2™~zê…aód«µCÙ7œSœ Ó{‡)Ïјò\û\; @€*@câö€@~  1å·î;üÊs§1]ò›áE»È¢yå’+ÉE?êñB¨"ÅÊV’bÅBé”-éá”ÌR D¥rq•â¡•¼èJ)–:%ÆRíQ :@cr&ÓØI RGp˜:ü˛˃ @€@‹Éô“S/ŒZ£¥A˜Ô<Áaêeu¡1õ o‡ @€@§@cêÔšåº PSuFlÑ–ò§1]1<Í1Šb IcúÁÇ(QW±¤¹Gõ©HIK©«\º7ç'yŠRZ8¥(88½µX iàhLõñbë¶!/éôÓOÿôgÿiŸ/í_®|ö¿þ?ÿåÿúÛ ¤¿ôÅý÷¡´¿þëÿíÿý×/W¨5yNC®¸ný–üòŸü¥•?Ù2™þë?ýÓõ7ŒvìÏî÷~ÿç¿´ô…´2dÎ € @¨‘À%?þÖ¾ÿ÷ß,^½¹B eÁêí»ÿðI;ÌùfhL9¿¸|@€ ”#€ÆÄ½ü@cÊoÝwø•çKcÚ¹sçœÒŸ‡ÆOŽ•Ñ<\Éš#PK-'»Ú[\cÒwÕÄ•G­zkq…A¦ÿFçò @€ Ð:ÆœÜ}Êÿ‰Ã”U… 1eE’ý@€ @ Ã 1uX…r9¨ƒS°Ø´äKcJÖLå¸5¼ 6ŠÆ´c÷ÒQ]{M}íG[¶ÿ>µâp˜Úé»™s… @€@»sòžS÷zïÃ?¤6OˆÃToõ¢1ÕKŒí!@€ hL9©h.)И¸-:”SIÖ0¬T Ðâј¦¿~”4&•·?Zš4™p˜:ô;œË‚ @€@«˜vݞߨ“KšL8L=¨34¦@ã-€ @È4¦<Ô2×thLÜJ µheÉB1Y‘ϤSõM&¦ýç² @€ ÐÇ>xsÝöÕ]É“Ðz¥o2á0õ¬ÎИzÆwA€ @ ã  1u|s(K‰›£C  1Õª°¦­¬1¹PLf2Éjr&S‡~{sY€ @èc«1q@¿yWHžÇcý÷Ž­4“ ‡©Çu†ÆÔct¼€ @M©³ë—«ƒ@%hLÜJ ï“ ­©PÖ¼õá†î]•·áÕv'ðÖ»»WlÜYù*¶nßýç¿ü¥5¿üPL. “NU&Ó»;ÿв§Ýš09+@€ @ FÓößÚ5'¹±B1IoJ®ÿ£?îþÃ'5îœÍbИ¸% @€ ThLÜÈ/4¦üÖ}‡_yÞ5¦¯^./b¡˜\@¦|\=W @€ ôaõ¥½d2IZÒo©K n¨SymòX Ѥ?µRE¯êO¥Ÿ³eýŽeëƒ h·C¢1µ[q¾€ @h4¦&æ0hAhL-X)œRИ² È> Ðw’¡˜ü€L}w^€ @èd»·w[È¥%÷ “·d—j¹äd/)ßœýù§Ý»´ «ÉB4ÉdÒŸŠádb?µ@cª[B€ @ WИrUÝ\,J 1qCt(4¦­X.+7RC1)7õÏ…B€ @ o8I~’L&‰J2“LcrÁ–,“^ÕJm¯Wµl%5ë\ß\I›©M*ŠÓ„ @€@³  15›8ǃ@ë@cjºàL2%€Æ”)NvæøäÏwmj奷Γ½¤§U·æ­¦6÷t8 @€ R‘rI1™$'½1o¢.[¿-Æ’ÉL–6N˜ádª“¢1©hK ËÄOíИjgÅ–€ @È4¦\U7 hLÜJ©C+–ËÊþ¸I“¦ü]:W @€ 4›€eˆS±¸JJg—,yœÖH]²Ôr’–,>“~k3ËF‡ÆTo…¡1ÕKŒí!@€ hL9©h.)И¸-:”S‡V,—•?hLù«s®€ @}FÀ/éG™ã´¬HKŸIÒ’e‘“·¤õV,2“ÖÛŸ½‰Ÿº 1Õ…‹!@€ hLù©k®qhLÜJ©C+–ËÊ4¦üÕ9W @€ ä…S^jšë„ @€@ИêÆæè hLT™\ŠO‰ûB©C*’Ë€ @€ €ÆÄM@€ ¤@câÆ€@~  1å·î;üÊј:¼‚¹¼ü@cÊO]s¥€ @€@Þ 1å­Æ¹^@€ ÔH©FPl$€ÆÔ•Ê%И¸ Ð!И:¤"¹ @€ teöV$€ @€Z—S¦uƒÆ”)Nv@€ Î!€ÆÔ9uÉ•@ ^hLõcû6!€ÆÔ&ÅiBÀ#Ðïþ~]Ý]  @€ кИ2­4¦Lq²3@€ t4¦Î©K®õ@cª—Û· 4¦6©(N&Øëнú?Ö_&“–¥4é÷°ùÃF,a›ì}ÛÞú­pMzI›é7ð @€ 4›S¦Äј2ÅÉÎ @€ Ð9И:§.¹ÔK©^blß&Иڤ¢8M¬Û±ÎÌ$©KZØõÇ]Zvñ™ºwukÙ~Û;|à Š€ @€šD)SÐhL™âdg€ @èhLS—\ ê%€ÆT/1¶ohLmRQœ& uiàŒúK¢ÒœMslµE`Ò‚0)8“6P& L*ZÖoøA€ @h*{ŽÛ£Þ4~2"ÐÓÔk÷LUýUûÿ\ôhFØ  @€ '€ÆÄ=ü@cÊoÝwø•Ó¥ØáÌåuYJr•t]N]rñ™´R¯Ês’á¤m”uNE ±‰@€ @Í#0ø³{~ýß›w¸N?RhLŸˆk©eéÓ^?\ @€úŒSŸ¡çÀèshL}^œ@c 15†+{…@ÃXþ8?mœþ´r Î$·IV“L&ùL¶Æe—kرc@€ @ Ò˜n:.YhéÃm{Îú«Ia™ø @€F©ahÙ1ZžSËW'Ø3hL=ãÆ» Ðg,aœ\%?UœÖ¨8{I''ÉVjË>;W @€ ä–S¦Uß“®75 ¡˜2½Ø @€bИ¸% _hLù­û¿r4¦¯`.€ @€ ÐИ2…ÞS2 ¡˜2½ Ø @€’И¸+ _hLù­û¿r4¦¯`.€ @€ ÐИ2…Þ“.9‰PL™Þì € @IhLÜÈ/4¦üÖ}‡_9S‡W0—@€ @èhL™BoÉÈD(¦Lïv@€ ThLÜÈ/4¦üÖ}‡_9S‡W0——»ÿcÛ3ë\·ct~.™+… @€Z—S¦uÓ6“®Úd"S¦÷;ƒ @€@*4&n ä—S~ë¾Ã¯©Ã+˜ËËþ¸iT×^][‡æç’¹R@€ @ u  1eZ7í¤1Y@&B1ez°3@€ ”#€ÆÄ½ü@cÊoÝwø•£1uxsyù!€Æ”ŸºæJ!@€ ÐИ2­¤vÒ˜tá ÈD(¦Lov@€ rИ¸7 _hLù­û¿ò|iLC‡Ý‹ÔIàù_þ×5kÖ´þ7Á;;ÞØgß/|ä´Ö?U΀ @è|hL™Öq{iL'ŸtÂèÑ£3ÀÎ @€ thLÜÈ/4¦üÖ}‡_y¾4¦“O>yøí£¶îø}IÙþû-QÙ}óí£Ž9î¤-Ûwo~·XÞzwwPÞQùÊ›®¼ý»7¼²éíßmÚ¶ËÊF+ÝAÙ•6lýèu¯¬ßúÑú-QymˇAÙ”u®¼õáÚ¨|°ö­Ö¼Y,«ßü (oåÕ7vFeÓÎU^Y¹qçÊï[Y¡²!*Ë7¼•×ß[æ•¥ëßseÉúK^‹Êâ×ve]Pº¢²ý•µÅ²híöEk¢²pÍö…kÞ Êêw_öÊ‚Wß Ë;*/©¬ŠÊ‹«Þ ÊÊ ¼°òí¨¬xûy¯Ì_ñöüåÛTæ¹²lÛ\¯ÌYÚíÊsK»Ÿ[•ÙKºƒ²x«Ê,Wº¶Î,–-c'-øÛ¿ÿôŒW¶¨L·²((Ó‚²YeêÂÍû|qÿ9sæ´ø7ÁÎ;¿¼_¿ÇOÿö÷™:uj‹Ÿ-§@€ t>4¦Lë¸4&õ½\yýˆ#~x<&S¦·;ƒ @€@:4&î ä—S~ë¾Ã¯ö¤0ÒR<ØRª·äE]JW—zf/¥D`zÓ"0}𪠴©·A˜ÌzqEñÞ{ŸK®Wq˜êv˜êK'7«k«Ë(§8Lr˜’Ó´E[²ÙÒÉYÙç‹ûOš<ã½ÿàÊïÿðI+|1˜Ã4þÙy+6¼¿üõHcZüZ:K=Å/,“Étð¤g&·Â©r€ @€@î 1eZå-®1Éaºú†;‚ÆiAcrÓEk“é¾ûîÏ”;ƒ @€"hLÜ È/4¦üÖ}‡_yî4¦o¹+QÉÿS¯þøØ7*º’+Ý»ä*¹²¡[º’•,ä’Š\%¿¬/ ¼eŽSþ¸ÍQY·ùè¼õáÚ¨¤ä[#u©`/ŦUug‘“æòž¼%WªL‰ L]k‹¹ä­Ý”5AY”wƒ²:(/»òê» ¢ò΂WßyIeUT^\õNPVå…•o»òüŠ·]™¿B‰ä‚\rÅtr˶Í[¶m®+K{î0Í,8L%Ó¢-Ó=‡iZÁa2é¡ñ“ý`Zºgúü‹Á¦'&Ï_& t¡˜Â €Ae©Ræ/ÝüÍï5mÑf•T‡©¥’Ê¥8L~7qi(&7ÛUÝIJÄf-zãß>h¤ɵ|WX¥ueZ?oì]®CÓúUõªõçZ±›„j›9ÉY2fähÏþ,Xmæzrõ.ëfõ«>VS…R5&¿Õú¸M2wÇâ0Ù!Ü,FQ…ƒV>ØôãkL®ÛÚÎÁQ#OwJæŠé¬Ûzí“§”ª1¹s‹u=k}lÿFØj¹7Ø€ @µ@cª•TMÛµšÆTâ0ùéäÖ¿W'8Lwô¬ ’ËS˜–×d2¹–Žßäq¤ÊiL®]c-Jÿ½z‹YDÖ@³¬íÐ#ßêÔö§köº $î]î¸H)Y£¦i?. ¯Ó˜\£Lkü¶9?6-Ç®%Ö¾K¾¤f£VÆ®Ô<-ÛÉ5Òmc¥Ø³9LÉ~€šnS6‚ @è hL}AcB 5 1µF=p™ÈÆtíÍw¦kIaê·ko 4&-”FTŠ[JciM])ÍX* ¶TFZ âë”&Œ ÂíXÙ• ƒ˜+ÕÕ¥÷z`/U¿Ô{©îLõg‘+˜¶¦a’ÀF`*hLiA˜œÕÔ"јü\rvcèN°\KünâµA¾¿°›ø] ÅTè)Þ6cáýj3™\ߨÅRgÌqñ5&ëÜLjLNJÕ˜,,ë0µ·ûF‘uຯ<; '¹®g{£‹½dÛ[Ÿ²¥rs¯J²xûNcÒ²u1»^æØA+Ÿ¡ËUg-§1Ùz;D-<-î”ýXG³MÀ5¥,yJõjLÉýëº:©3ÿÿÊ!@€@Þ  1ez´”Æ”t˜lnUÐ> Ök–T<SQc rÇtD•ìrIÉkVÕ˜¬qÓ˜¬B¬µå+A¶Æ×˜Re#¿ÙkÍdýXcÊ5™]ÐNU»M¦h÷Û¡î4ìþ®ìlµ;–ü½¥¾ä·ß]SÔšÆÖ¨´ íÜR–;¹ÊVºÀ™Þ¿ì € @ И—]C Å  1µxqz=%?é¦;]¢·äÂ57ÝÙÿèRc)ÅVF¡•,ÆÒ~ñrÃYž¸0ÌR2Ò’E]ŠÅ[JzK˜ÖSï0Z6ºäþ{ú¿ƒ÷A€ @ 4¦j„êz½u4¦Àaº±K.½qº#Ö8æØ„¡˜¬qªÆ~e“)©1ù¸\67­´E¾×éDU5&méhÚ›ZL¾¾ãÅ6#Åþ´ý[KÓNFµÐ¹nM2“Äu'ov]³1¦1ù»Òé™n¥ ´·ûû±³Š½d F×î³£h?&?(-XcV+¿ó®êºKÙ€ @ O 1õ v – €ÆÔÕÀIdO wÓ°ßÞYb ¹\oá‚^•Æ”0“*ZJæ*•°éJiÆRi)ðTR¼%›àXš0®’ºK×µ¶ræ¸ –eŽ‹Å^z9™<. _%\4Þ•ùa¯åüåÛ¬¨û2(Ë‚¢~LW|{IËÏ-)–¬&Ë"7¦4&ç0…Ò[—+Ía*t— ÅdÝÄRÁ¦¾¼é€«d—³žMs’Ô¿©ß&è¸×Óê¢ø¨?×zB-¨¾ýX€Û‰ÛÀú^­ûU½«¶¥S‚lþŒÅ²©±¶ÞwƒÜnMÓ±W]'ó~t ê!ìŠÊ4y†4& ÈËRgWa徭§Ã嘫[Ù]—u1'¡9à.o‚»XëgwÐ’û7DcÊþ¿+{„ @@cÊôhIÓÕÎaJ6N]®óXœàÒPLs—íSµîpø1#Gݛʩ²ÆäÚ_¹ÖæÃÔ¥1Yê4µÔ¬…¥·›Bdk*hLÖ(³¦Ÿk~º5j[Åd#×Ôzkšùâ˜ÆÛ¹NÉšØvVnÚ‹½dL\*: ¬k,kÁµ‹uÚ•¶´†§]ˆ«½„É”ég—A€ †@cj8b–%€ÆÔ²UÉõŽ@IÝ.Óõ¹Ô½;nß¼ÛžGÖ‘Ó¼½zÔO(nP¤T!œ’YJ•]¥ïüà°(7ÜÆ÷/»â†ï|ÿ0ý¶ç¢Ë­ ¾â‹¯cåß¿hÿ£O²e“–´fÐÐ,‰XP¼KÓ_|ÕB.}û{‡Ê[ª¬.¹ÀKGüèÄ'¦¾Äï Õ¥ñSøÝCætmR,+úS¹É åøyÉJ{éÔsöÃ,“Ô%-?òÌ‹*Zð¦È^J LaW¦+~ø%™L¡À´µß·îe&˜¬ôVcÚ½sϺ9 ½›ÍaÿìüHzÛðþO®™}àùTŽº|êIÃf=ûò[ ²eu:ý•Í'^=3H'†b:ïö¾yî„ÃO~pÆk‘Ɔ°šüÒÆ¯W3™zyQnJh/÷ÃÛ!@€ v%€Æ”iÍ5NcšûF·êùšÃä§gÜ2ÿ†G—¹\r×=²ôÚ‡—ZãT= 7_ñôóoXœà'çoüåoç¸qýÆ©"+¿¼ÉädšrV †äÎÜ-»6©[ãz·LôÑ[,€“[ïÖh½ _d[ºmü½iž‰…ε·«Ôæ°^Õ©&ÏÁ?º{£íÊíÜÂ&¥Bð_ÒÛÝ[´`—YîJý¾>ÿt!8LU?l@€ZS«Õçæ@cjkŽ”1?ñ‘‹“â‚•TÒ˜ä0íµ×^®;ÃÅVÑÄ,÷þŒO¶Á»s³}÷È_Vœ4¦Ø«+‹”,Üû©Å‰JÁB¨(Y9ù”³?óÙÿj‰áä*õ?æ¤G'>'?IËêì{dÂs_øò×ξèriL~¤¥Ï|öó*&0IZzzÆBUÇY1{©˜*NËë{ÉÆ}æ?¯lqé ãÂŒc®¨Wñß¾´ßOÌt—ÆŒŸ©CÈmr—>ýŸWŸcd/yêÒiç]vÿ¸ꋌeŽÛç‹û}ê3ŸŸ0{¹…_Úç ûÝóØŒ{±Ï¾ZŒ½TKø%/“~I Î?|æsQ ¹®­åRÈM/“BΘz«1I`š4tÏùÿyϘ“wÛ¦yvS…A˜Þ—½ôÔüMÁ]ñÚuËd²n⦯;â²)*ÖMüÛÇ—«›XöØØ¯6x²…bLÑ·g_ÜðõoU‰ÉÔ¸ëbÏ€ @€@ç@cÊ´Ž§1êÚëžÅÿSU™)èQ¹aD¬q:tô+Ö8Uůî_¤¢Æ©ºîšôê·Î›ðèìõ–Nîð˦ÜþôªÛŸZ©Æ© ÅdS¥€ÿþaec2eŠA€ @ 3  1uf½rU¨…S-”ئÅhò•& ÚâXÛ\,-Ø­²“f‰YXiÓ˜,¶¶] ¦»Å.¹ÊéX§[9Iëõê‘?>Á6(Ñ’ìOONŠ-›¥/¯¿wßÓBI6’U’±4ë¥Õ¶lŠÒÙ^n–\‰"-­ß¡ Ž:ú¤«oi‚?p–\%iLlé’__æCnùÔ¥Qc'È^ÒŸÒY$Ýõà-_ò«ë¬÷pÊüUgœ?DeüÔ—]Ô¥3οìâ˯û·/î'uÉÅ^=n¦Ö¨Ü0âAS—´7 ¼4ôº;¤.]8äZù1³nüÖw9þä3g.Ü`—^¥¥Ûî{ê›ß9D™N9w°Å^’½tÏ£Óï~tú¿~á«–<îüÁ×üòìAÃn£ù—úýäÌ¥Òkž˜¹ô¼AÃ̳9wÐ0^?c逳©<ðôóR—T®¼yô/κtÐU·Icòí¥™][f¨¼•²S!ü’‹ÃÔciÃë›w>28˜ô¡‘ÿÌa÷Ì<'0Ù#éÉù›mÝŽñó69dŠU´â0i¶«4&ë&>þª™÷N^Øc˶©§X’SÑʺ‰»¶Ô¤^ßÿ[?˜0ir{}Š9[@€ @ = 1eZO Õ˜d2U–™Ôr•¦Âì×8ýõèW¬ËB]r˜.—Æ´fû5c—¨}ªÆé#³×«áÆÇ—slÂÆé9·=ÅèW¬qjLA[~Ú¢-ß;ìèrÙå2¥ÈÎ @€ ÐИ:°R¹$ÔH ‘CÕ5ž›A ^5ÉiL“_Év"CI?Z¨’TÎiL¾ºÔÖ“õ»%‹HWJcúÑ éN’³”^WDœ÷\q9à’ /­xKÞÒ‹ËßrA•Ü‚¤%-ËXúö÷•œ¤å}¿ôµ‡Ÿší‡YÒJYJ–$N‚Ú@&“ü$EZÚ÷KûÉRzðÉY~ïÐ+o¸sÞ’7´FJg‘x¤pJ>1ëÀïzñ¯®›<¥B.ýöŽUôÒ¸) ž·R 7ÞñàÀ˯Sì%©K.gÜèq3ä0=öìKÚ`ö¢²a´ >ÇN>SYáî|†~[Î89L¿ºv„…\rEÓ­÷=õôìe.ö’ì%9Lw?hLò–ôû¼ÁרŸò–TŽýé²—ŽùéŸúÌçÌ^ú×}¿:nÆR¹JWÝ<ú滟ø—}¿:æ©çe/iáαS>òx§1ùö’ú=#iÑ–é‹‚>P^²ó–z£1I`zïáÁ>÷ÿˆ¦FjLr˜¾¼_à0)ü’K5h®Û‘C¦^tç‹¿ç¹Êaºë™Õ&ÔTWõ«ÊTG‡ž2vÆzÙc"/iÌ´uJÉçf»†”6O|“©ÞïU¶‡ @€j#€ÆT§·j‚ÆTNf’äޒ0Q“Št%“–T~sÃZÖdGIKú½pM 1YÈ¥‘cž>ñçgž~þe*oéŠëï”átúy—©„êÒ;ßúî!Ê §¨KrIËÒ˜$Á(ð’t%EôÑÞÔçø©ð·å‰SÎ8…\º÷±˜‚¨Kaà%M¬T:¹ äÒò@WºõÞ'ÕqhLD“ÙK’–,ü’–Çë÷¾_•½¤ßý¾}ðȇ§ ¾ú¶g]ªrðQÇßùÐT-ó“ÓÍa² LÒ˜\ì¥4{© 0• ¿Ô3iÜ#ãR&Ó˜®Ú7È.—iÙùè¥_Þï€ÇŸ™ëwaºÂI®ê)¾åÉ•ãçmxpÆk§Þ4ïˆ!SÌaRªX±úUMªiLÚ@ÝÄ.iô´uE‡)˜í ^˜LmÿÏ@€ @ 5  1eZ/¦1i|"óböR¬¸4sÃTèH)†‘.4N¥1™Ã¤8L'^-i¡5NÕàÆéóÖ+xó @cZ Æ©ÒÉÓ] ü8Áš†äÚéÉô«s³m_³7T"°nN¦Sv@€ú†Sßpç¨hhL­P œC 1±©÷í7ר` éÕ#~x|… ßÞ“œ”PNJ-’“$*)œŠ-HQ2QÉ\¥ÐOrÒÒv‹±$3I‰á¬H!ÒoÙKr•NúÅYOL{ÙrÃ)Ò’^ÒÆ ³¤ràw‘´ü]½dÒ’²ÅÉI’¨fˆ º-Ø’%ó–´ uIÞ’-ï#ieËG Š·$éÑg_”ºäB.iùžÇf(mÜ=κ„…‹²ÅIcúÆ¿¬"EI¿-üÒ¨G¦©Xø%Å^RÚ8yK*~I~ÒO¿ ‡éÜK‡É^Ò‚b/)yœ\%½dE˜ôûޱSÌ^:àÀƒŠöR8q³®ðK=ИøÊWÞº|ÿ’L&05¬Œì·×ÿ¹Ý‡f/EaºÂF˜ÆÍÝ`‰äTõšáúØs¯IW½c“ée‡žüàô×ÔMhLƒ&žºÖEìˆyš×ðû&îûůìþÃ'=ú†áM€ @€Ò 1ez_,Ü2(Õ7jèÊkü7ͱñí%C:lœN•À¤Ž kœÊarßBs˜ÔÃhL3׫}*‡iШ@cRãTÓ%w½‹ìÚéOÌzõþÓÿ²ùçÓ¸æ6{†@ }Mñ@€ÚŸSû×!Wž@cê)9Þ×ç²Ñ˜tÚÑ®]»´ PNJP×çÖƒÆtÅu·Wpôª4¦ØŠS¥„f’+NNûÔl+2–Æ>5ËD¥§¦½¬>¾©Ï¯Ò²”N)á´ ß27%ìT þ\³ý‰©/+Ò’t%õ žqþe*ã§,dÒ’2Ä)7œ¤1Ù”G½Ë—–x鄟Ÿiñ–$-)=ÜEC®Õoó–¾õC”*μ%•û4&‹åóÈ3/JKRѲ~OyCr)X–ºtÊ9ƒ”-.˜–ÅŒ¥±_ ¦W3,KÉB.9鮇§Yì%˧ù—xIÞÒ¸éKMZR¼¥s.vôONc/m¹qÔøï/ué77ÝoöÒ?|úsžºTkò¸r©åÆLXð·ÿ©Ê‰çöùâþŸ¼åÅÉ¿¿æ)ý}·´G³÷üòá¶Üœ±· :ôÔs.‰n¼‚ú¦[(0Û¤1ÍÙ`1·$0}ë¼ S¾eÝÄšêª LÆ´|ÛoÆtsÛóê&žúòæCMN Ť ¿cì´ýöÿÆâÕ›×où“©÷Ç @€ ˆSÖ·ÂÔו´´âíáÙ–Tê±Uÿ´íwÏë F­~’b¯H4+jœ*“9Lê‘Ã4äÞ…Ö8µDçÍ\¯Æé=Ï®9îÊjœª7àç7Ì9iµÚûÖÀ÷ÁËaRãtÒ„Éë_šóÑŠÒVv¬ÑÍŸÈ„€¢k£1eý5Åþ @èhL}‚ƒB % 1µD5p=!à4¦uëÖõë×ÏvÑ¿ý©…½*ïRÛuuuÙ6cÇŽÕûí§''Òï 4¦ko÷•£Ø²^=ü‡Ç{A’Š)ÞÒV!”Š¥EÉ…SŠÅUÒŸ¿½s¬ì¥3.¢ß¿½c¬:ûf)Xsþ‰JJúfnŠ• =ÜêwU´ ôpêtâ”îð0=œ|¦¡×ÝiéáÿÑ ³_Ù¨ý q³m”™$oIE/Mzn…¤%­9þä3U´ uɼ%å‰s—Îç”s;iiŸ/|Uê’b,÷³3ä-rö )J·Üû¤yK˜ä-YÂ8+‡(ÜOÏ·${ɦÙKºlIÒ’Ô%éJWÞéôŸŸlyß“óU´pò—tÄñÒ˜s^}A©-s\K©vI–JŠÌ4æäÝÚÉtö%áè2ÅMú¥.YQ(¦›Æ-wÝÄê#>þª™Aˆ¬°^ÔS¬8Lr˜®yxIj7±ï0Ùb25¨6Ù- @€rG)ë*·¼rYïuOLcr“;L¦BWIÐb}jŸjŽ"0¹,çr˜.»w¡9LÊ%'iìŒ×¬qªDçgßú¼ŠÚ§Aã´+ˆµì§“‹¦é/XËTå£ÝÊüJÙ!JÜt · @A©3ê‘«€@O 1õ„ïi NcÒÙ 8Ð4¤ØÉÕÝÿÕÝÝÝ—Õ£“Æ4ôÚÛ“š‘[£Wë\… ’/Eñ“,ŠR!’…SrEiàÓƒŠ“ç¯”®4~ê‚ÀU -%EWÒšqSX28W”Î,=>yXzî•*’–T”îú>3g…IK*–ÎO÷س/Y¤%¹J¦+Y1cIñ–f¼¼Áe‹“·¤`KOzÑRÅY¶8r顉/ÞýÈôb¼¥eÛôç”×›´¤…±^p ã4Ãrò ë|ú%Œ“½¤¨K<õ¼~Ë[ºó¡©*н4+¶s˜xéþ§æ[Ú8+#œ¢8Lši±—™²äö§<2eñ}OÌë½½äĦz5&ëNݶ`ÊõvYR¹†iLºÇe2röÅîÖŠ·ð& o‰ ÞƒÀZa-[.9ç0ÙT×§žßÅa*t;zI‡ “©Gß+¼ € @H#€Æ”õ}Ñh))0¹+Éd½%®ßCíÓ‰/¼!KÉú+zŽ¢//îv¥ÆÏÝhSÐ8]Ú}פÕ*%¹Îm¶¶yÒaÂdÊúÞaiИ¸/ @èhLR“\ê'Ðà¡êúOˆw@ ukLÙ¶ö"é××ÜsŒü?õª:æ*là^rZ’?©¸úI®Äü¤ØŸÖåç•ÀR²$ƒ³Rp•lÁRÂËÊ@dq¹áœ®ä¤%ç*Ť¥0O\QZ ’ÄòÄYocIYt>ÆŠ¯.I𠤥 l•´dE}”ÅRP—L`’ºdS0] ¤%+¡ºTŒº”Eà¥Ô˜L=Ó˜6m ²+‰äÔç•Иvoï^rß°U§$^L]YùÓ “é—g]lÒ›Ý9‘ÀTp˜\-[múÝĪ s˜Ô!U±¿œÃ„ÉÔG_N€ @G)ë*mœÆTA`ra&S¢qLU&Ø, ; ÂÎ(N°×8-ç0%M¦lÛÚYWûkChLmXiœ2 @©И¸1 _hLù­û¿òÜiL¿ºæ¶¸xäùF¿v[Ð+W*!Õh#¥¸Jq?)Pœ¥TATJq• ;t%ÅlOêJQ„ž0Ò’3–,ÒRi)œ1™"-…1~\©Ó[ŠBÇWS—2ËW!œ½Ô+ɾ>Üû’˜8 Ÿt¥7æMŒ­ß¾ºK/õàÅL¦‚èim~¦ –à 5íÌâ0yÝÄõ9L˜L=¨#Þ@€ Ä  1e}O4HcÚö»çk“ú[„É¢.9QÉÉi¥â6ÙW‘f—Öò$“éäÓ/²LIIq˜¢:"S-4Ù€ @h4¦¬Á¶”Ƥ‹“ÉtÐÇú)ÎÃŽˆh~”5NcA‚Ÿ˜õê~ûcÒô\NóÔ…÷>üC ^ÚÚYWûkyhL-_Eœ  @5@cª›A   1u`¥rIÜiLƒ¯¼ÅwŒb²Ñ +o‰fšiTK sº%Kz–·dê·òyß\2¸ \˜/,µÌz ­”„V²äbµXŠU6– éáÚ(ÒRå8Löjæ“å3Iê’%u¶JW²¢—ô§t%½$I ’œ´FêU®©ê—“L¦ŸvQÁTóúˆ-S0ÏuË´ðUÈ%W•'@€ @Ù@cÊši«iLº>3™ 3©‚N‰’,祉Î{ì0é@Íikg]c쯵  1µvýpv€ ÔN©vVl N#€ÆÔi5ÊõDr§1ITª éU›JØ“²t[…änÎIŠ-TV”J#*Õ&*• ­´µ^])ÅXZ´ÙÉ1µHB­¿M¶ÓŸvïr•$0ÉL’¥´µkŽŠ¥I;ý6¥ÉrÏéG ú³ÆPLî«K&ÓOO½Ð4µ¨fó\q˜ø¦‡ @€úŒSÖè[PcÒ%ÊdúÁÇxSI&ׇЇ©™mí¬+ýµ04¦®N € º 1Õ…‹!ÐQИ:ª:¹˜"ÜiL—þfx9£Hëõª4¦ $_Š<$ ˜T>fR,’B©H©–XJ.ºR—™+©%Ì—Z©$œ])ºR9¡*[©É_-2™~rê…Aî?˜,Ó¢(S“«ƒÃA€ @%И²¾!ZScÒUÊdúþáÇYäüÁ^ã´7SÖÙ И¸ @èhLR“\ê'€ÆT?3ÞÑr§1]rÅðrÙÙ´^¯ºpè5$qsÙÜü…­Éänš•h%%Ë[le×ÖY•%/¢R-¢Rº«˜.ÅRH=Öú‘“q†m­1é+&0™N¹0)0á0µÅ÷/' @€ N&€Æ”uí¶¬Æ¤ L¦ÃŽQã4œ(Uȇ)ëýeD)#ì€ >'€ÆÔçUÀ @ Ï 1õzÜXyÔ˜œT”\ÆôƒÃƒXèµZG•ͤšœ$?¢R¥@J.âNÐ-è—EA/¡•0O’W©í©Ý5&}=Èd:é” b{ÇØiûíÿÅ«7¯ßòQ…²ûŸ4ö †½C€ @¹%€Æ”uÕ·²Æ¤k•Éô½ÃŽŽe¢ÇaÊú.`Ù@cÊŽ%{‚ @ o  1õ-޾$€ÆÔ—ô9v äNcºxèðò騶êU „Þ‹²EI¾‚<_®„ ¿ª–¸œd¢’§(U²”Jg:Ö¢ï°èI_2™NüeÑdÂajàW&»† @€j$€ÆT#¨š7kqI×a&“ëpÀaª¹nÙ°/ 1õuŽ @€@# 15‚*û„@{@cjzâ,ë&;iàЛ+EzUQЫ*G©¤{HeÂ&¥ÅOJ‹¢dÙßò÷­¡ÆUghLúÜ;“ ‡©îoAÞ@€ 4‚SÖT[_cÒ;“ ‡)ëúgY@cÊš(ûƒ @ ¯ 1õyŽ ¾'€ÆÔ÷uÀ4„@î4¦cO>ëÆ»ÆedJ9ö§g}yÿS_Š­¼aäø2eÜ #«—ëGŽ£´AWßñÿý/ÿWå3ùüûç‡ÆOöS³mÚ¶«!ÇÞíT&Ó¡?ü ¹äzG‘wC€ @@cʤÛM[hL:[3™¾´ß—&M¡r¢ó÷>üCÖØj&€ÆT3*6„ @ Å  1µxqzh 4¦Âe×}I _Ó£>z`霿ì³ï—þiïÿ[ÉŸLà+ûðéÏ|¶ò~óÀï¾´t}ëkLú"ùí…¿\¼bCånâÝø¤/¿r86 @€ hLYWt»hLºîŸþêo®ø'8LYßì/ShL™âdg€ ô!4¦>„Ï¡!ÐÇИú¸8|£äKcJR¬Ü§Æ«H%Кјöüéã=ÿî½É·W¨5¦F}•²_@€ @ F)ë[¢4¦Q]{M[{Z…Æ)q˜²¾;Ø_ýИêgÆ; @hMhL­Y/œšA©”9F@cúSõhQiÖð=ú_%“é½S¯‡©¾b9$ @€rK)ëªo/IgûÑî?¥6Nq˜²¾5Ø_ 1õo‚ @   1µ`¥pJh4¦&æ0Í&€Æ„ƺ ´¢Æ†b 4&•YÃÕ)ë,Æajö—+ǃ @€@Î  1e}´‘Æ´õ£9;?^#I“ ‡)ëû‚ýõ”SOÉñ>@€ZS«Õçæ@cjkŽÔThLu+,õFîaûÎ#Њ“…b²"ŸéOû&SS¿V9 @€ hLYßm¤1ù—î›L8LYßì¯Иz·B€ ÐRИZª:84•SSqs°æ@cBc‚@ÝZNcòC12é[ÄL&¦æ}¡r$@€ @À@cÊúfhA©{Ww¿ûûU½P3™p˜ª‚bƒ¦@cj*n@€@  15.»†@‹@cjñ âôzJ ïÓï>þõ£U(o¿÷ûím(9! ê~çý*5®Û¦§Ÿ¸Æ¼ÏÅädÒÁþã“¿4æì€ @€@EhLYß -¨1]>¶ÿcýwýq—•u;ÖéwWw—»týiË ÞzÅ_Ÿ5öú  1ÕÏŒw@€ КИZ³^8+4ƒS3(sŒ> w©sHdK ŠÉ È”í¡Ø @€ Z  1ÕJªÖíZMc’¢$‡iÀÄs6Í8c -O\;ÑÅg6˜Š.Ok´J-¡›jÅÁvè%4¦^äí€ ´ 4¦–© NM'€ÆÔtä°9ИšÃ™£@ a’¡˜J25ìÀì€ @€@yhLYß­¦1éú¤%YŒ%-ŒX4B úS>“]ºô§“™´Fž1™²¾/Ø_O  1õ”ïƒ @ Õ 1µZp>h4¦æ±æHM%€ÆÔTÜ (Љ€Lƒfw€ @€@ИêVuóÔ˜ö¾mo;m·àKK¶R¿%9IiRqÚSÕ‹e4œSÃs@€šD©I 9 ZS V §”4¦,(²´›öèÕ¤¡­p.œ @€ whLYß­¦1­Û±Î’Ä)À’ËçD%ešs“ÒÏ ‹ØÄZ‚SKT'@€@И2€È. ЦИڴâ8íjИªâu´ 4¦v©)΀ @y €Æ”u-·šÆdö’%ÉI Âd—«5c—•äüq*Zc ÚX¿Î˜5öž@cê)9Þ@€@«@cjµá| Ð<hLÍcÍ‘šJ©©¸9H©pÙ5 @€ P'4¦:UݼÕ4&°ì%K*Ý»ºíü¢I+%6iAëm¥yNÒ›ª^#@ yИšÇš#A€ ÐXhLåËÞ!ÐÊИZ¹v8·^@cê<Þ –"€ÆÔRÕÁÉ@€ @ çИ²¾ZPcÊúÙšH©‰°9 @ %€ÆÔP¼ì-M©¥«‡“ë94¦ž³ãh-hL­Uœ  @€òM)ëúGcÊš(ûË74¦|×?W@è$hLT›\ ê#€ÆT/¶nhLmSUœ(ª@câ @€Z‡SÖuÆ”5Qö—ohLù®®€ ÐIИ:©6¹ÔG©>^lÝ6Иڦª8QT!€ÆÄ-@€ ´4¦¬ë¢4¦Q]{él³Àþ )4¦Lq²3@€úSÂçÐèchL}\¾QИE–ýB ÙИšMœãA€ @å  1e}w 1eM”ýå›S¾ëŸ«‡ t4¦NªM®õ@cª[· 4¦¶©*NU 1q‹@€ @­C)ëº@cÊš(ûË74¦|×?W@è$hLT›\ ê#€ÆT/¶nhLmSUœ(ª@câ @€Z‡SÖuÆ”5Qö—ohLù®®€ ÐIИ:©6¹ÔG©>^lÝ6Иڦª8QT!€ÆÄ-@€ ´4¦¬ë)k¢ì/ßИò]ÿ\= @ “ 1uRmr-¨S}¼Øºm 1µMUq¢¨B‰[€ @hhLY×SÖDÙ_¾  1å»þ¹z@€@'@cê¤ÚäZ P4¦úx±uÛ@cj›ªâD!@€ @mC)ëªBcÊš(ûË74¦|×?W@è$hLT›\ ê#€ÆT/¶nhLmSUœ(ŒÀ¼+LÐïƒ7×Å€líš³ä¾aP‚ @€ ÐИ²®4¦¬‰²¿|@cÊwýsõ€ N"€ÆÔIµÉµ@ >hLõñbë¶!€ÆÔ6UʼnB@ä*IcÚ½½;IcÁ-W=>J€ @€Z‚SÖՀƔ5Qö—ohLù®®€ ÐIИ:©6¹ÔG©>^lÝ6Иڦª8QÈaš>°¿ŠDCÒ’Â/½6y¬‘Qˆ¦í«»’ë哤%½ªtr–`έזŠÌdk™©m/‡ @€ÚÀÒ§Ëv¥é%~zG •5&]ÙŠ·‡—GÙ±{iï.wC И•]B€ ÐL÷.ùëÔ'ð±Ëÿ¾™§Á± f˜5<½ï嬿Úóá¶fŸ ǃ@c 15†+{…@˜«¤kAN’¢.é·iLiik×ý©õÚÀrÌiY öÛe—kÀ©±K@€ @!Ô€LZÉO¯ ´¸ÆT. Óô×êõ¥³4€S ²K@€šI \@&B15³8ú€@¹€L„bêƒÊà"€ÆÔ(²ì™ðSÂ)‘œŠáÿÖŸŠ½ä^²л´Æb2ñ@€ @ ±R2Š) è-®1éS2Š)‹Êg €ÆÔ¨ì€ &Hd"S“«€ÃA o$2Š©oj‚£6ŠS£È²_@€ @€@ Ä2Š)£› õ5¦d@&B1eTùì¦И•]B€ ÐdÉ€L„bjrp8ô d@&B1õMMpÔF@cjYö @€ @È#X@&B1et´¾Æ¤ d"SF•Ïn@©PÙ% @Í'àd"SóùsDô? ¡˜ú¬8p£ 15Š,û… @€ 䔀 ÈD(¦ìИü€L„bÊ®òÙS 15*»„ @ ùü€L„bj>Ž>#àd"SŸUn4¦F‘e¿h6›öœº×žIC›}\Ž@€ @ FÀd"Sv÷F[hLº\‰PLÙU>{j4¦@e—€ ô  ÈD(¦>ÏA!З, ¡˜ú²8v£ 15Š,û…@³  15›8ǃ @€ÊP&B1ezƒ´‹Æd™Å”iå³³@cjTv @€@Ÿ°€L„bêø}IÀ2Š©/ë€c7Š@¾4¦¥K—­øs饗žvÚi•·áÕ#ð³Ÿý¬ò]{íµüq£>‚îwǦGíõñC2Ü%»‚ @€ Ð3›&Ú9ÿ¡ž½—w¥hI'?ñ…Á[ß[H=B ¥  1µtõpr€:Àœ9sªk8IÃs¤«ü óuÂÍÑ€k¸æÁkÀ^Ù% ÐêÜyÉÇï¼ÑêgÉùA ~ùÒ˜N>ùäƒ9ü¢K†X¹0V.òƒƒÿçÙç‹/S¹ Y^vAXÎ/Sλhpj9÷¢ÁQ¹pð¹^9çÂÁ^tÎQ9û‚AÉrÖƒÎ:?¥œyþ¥Q9ïÒ3½rÆy—ÆË¹—žqË%§Ÿ[,§sIj9õœK‚r¶_.>õì‹O‰•³.>嬋Y¦ 8óâ° Œ•_œ90(gÄËÏÏXRNøóÓ/R99­üì´‹RËOO»((§^+?9õBWúÿËÿýoþÓON¹På¤x¹à¤S.8é—üíßJíú?\Í~ÇÔ©S¿¼ßG}·_{HWÍÆÃñ @€ æØ´i“š'xàÎ;›wÔN?R»hL[Úgß/uÔQ4N;ý–lóëCcjó äô!´>= {üOJ†¢.â?}ÿàÃ4 •rŠ 3ÅF— ƒJ)ÃI±Q¤ØÈQqÀ¨8TÅÆ†J‡„¼Á ÄPlÜÇî)â‰îÄÆtl(ç¿þ·>àÀGpâ7|ý[?Ð0_ëW}óÏPXÔþ=ztóÍ!>$ ÓúîÃ:àÐ #;iøí£¶nÿ½Ê–¨ìÞ²½Xn¾}ÔÑÇ´ùÝÝ®¼õîî ¼£ò;•7]yûwoxeÓÛ¿Û´m—+·íÚØ• Ý»Âòц­½î•õ[>råµ-¾¶9*ë6•·>\”¬¬y³XV¿ùÁê7¬ì|Õʦ ¬òÊÊ;Wn|ßÊ • QY¾áý ¼þþ²×ßseéú÷\Y²þ½%ëw,y-(‹]Y·£«X¶¿²¶X­Ý¾hMT®y7(«ƒò²+¯¾» *ï,xõ—TVEåÅUïeeP^Xù¶•çWËüoÏ_®²Mež•eA™ë•9K»]yni÷sK¢2{I÷ì%[g/Ê,Wº¶Î,”][ÆNZð·ÿé¯l™îÊ¢-Ó¢²yÚ¢ÍSnÞç‹û·¾Æ¤Tÿþ½C®êqïãt7ì “C€ @Õ „S¿)s—>6i.&Su^5oÑ“&ÕþóK6ޏoÓšë– û‚S_P瘀rE@OÂOL˜E¡ü±§›n ¤¢Q§ÂxSl˜)6ºT²±$7d£H…ñ£häȆ܀‘Ɖ¢A" ƆÜÀPa<È ÙH² pè§8ècÃ=±â±Áhdgé6Ó±7”óƒÃ¹øŠá…œ-¸‰Æn C6ýêf4¦ä‡HL®¼~„jðˆÉ”«/.6çŠCô¾s~+tèåçNc’¨´y{ÑRò%-ß|[ðÔXV]’ÃTj/ÉdŠÛKµL[K¦¤Ã L t˜–{“d¦R)r˜ŠÓº‹=‡©+æ04¦…‰GXïA6x–­Åaª[cò¦à©·à0ùϾ¾Æä&-¤hL‹¶L÷¦i ÛCc²T‹^íZ¯í¸“©C¿¯¹,@€ ´>9L_Ù¯ßÔ¹ËÔÒÔ@È#1™2«´Öטä0©ö_X²‰ÆifµÎŽG©qlÙ3 „¤1›0-6å?ýöֻɟ0ΖæÉ‡#Mµ8Lë óáÝLxÓ˜l¼›ún“›ñîÏu÷¦¸{“Û£!¡hB»›ÍnóØ£Iì…éë6qÝÍZ÷5&7SÝטŠóÒÃTIÃ7IéB4¦Ä‡+p˜naÃ| Lp8&ß?Ȇ†óQϹ¾ÊÜiL7Ý6*zLŒb,#-)ØRôÔX>ê’E`J‰½”j/UÀT)Sä0Ń0â0EA˜Â8L%A˜<­¾\¦¾p˜ J~!SôDë¹ùMÅ43|¶hLB1µ~4¦àÕ÷]´z›=§òÙº·ÝCL¦\³sñ€ @èÃôµ~Óæ-S«Ó5O™0‡˜L™TG‹kLÃôµ~/.ÝTÒ8ešM&uÏNA©TÙ' xô üøÓÓ é>R2~h@êÇÇžä9• LA–—âÃâ0¹Ì±œ©“<*†b ³vX(¦X²ŽÔPLnN{!S© 1Y(¦`úºÓ˜i7B©˜jâ1ù¡˜")̧DcEc*:LʤL>²g 1Å>ar˜®ºa„Õ¦iLJ«rXÿãˆÉÄW:›@úÐ0­ïήõü]]î4&=ÃyâLxwO~¸XÈ% ¿äž&-y\!s\Jò8=e®÷Â/EšÉO!W°æë˜ª$’+ä’‹„¹äЉäA˜Š¹ä²ŽÃ”‘Ãäõvc¼y¿»B:¹ÀaJjLi¡˜Z\c²T¯¬Ù{NU ×[ïÆdÊß7:W @€ ¾#9L󗹿‰Í²èZ·ý¡§1™2¨˜VÖ˜"‡iÙ&¿ö5ˆBã4ƒŠg "€ÆÔ °ì€ BiªË—Ìõqã-Ò˜N,9• 6Ŧ¸ÃT´ö­ ‘œŸN.š_˜Ÿê0¹¡¢b(¦D:9=Æ[F¹*¡˜B©öPLs]F¹ÒPL¥SJ(&4¦¤Ãtõ #/íõ÷-' iLª2L&¾‡ ÐÁîàÊåÒ|yÔ˜bŠR¤º¿ÈIþScIâÊÞR"ê’ ò.Kq¸ð¡Óä_ ÓûS˜º¸`/yQã´Lõ LÕ¦ð!µ(0EÝÍÁCOX¢ÖØck˜ 9ž¹4—\k8L‹·ÆÒÉ™Ë_ŒÆTÆa2é¡ñ“ýÚ|wçZá{Dÿ¨¾óýC»Öl ŸS£ÜÕî9UUsËÝ|è»ÿûz϶««Ë‹ý¹k×.-ØÿªÖë§ÞC$·í¶Þ®[·®—{¨÷ˆl@€ 8æ0MŸ¿Ü¦wû³ƒ‘5ÛÇ>õÜý¾ùÞûï× Í5Cl¡7­µ*Ýß@Çòÿ´Qìíõ¶AʵžbÇ*w’-«1™ÃôÒ²M6ˆ’¬}5N9¬WÓîîîmÕŽ3dÕ2uð]CØÅn¿ªw‘öº5Zu!îµìªö;¶ÞO–moç¤WgO»Æû¼gÒ“w¡1õ„ï :Hczì©©©)>løé†Pc**ÿцpt)6ÆT6Sa8ÉÉ­É%sɉ;¼8L•¦âÀPqHHóáH—NnµÆ} C?‰PLϯxÛJ]¡˜|Éf¡Gi4‚PLA4& Ö(Ó9±tèí£?þǟ먕NÙTq˜®¾ñe LÎ!‘v¦Ê:´ÿq#GÝ[ï妎UÞIò±¹ÞƒÚö-÷¬Ø³Ëà]h0Ò¡á õí+Œ…¡áÃëntûºÁTŠ»g°¸i¨›p ÜiL•б”œœTXðŸíÙ±4ÒRl©Œ´”ð–Âðžå쥷>ŒÇ^*o/¹GÏà´4…œÒÉ9•>J!—©'S8e6˜\àÐ4‡é]{x-¦CІ°…€¢…˜¢E%¿Þ\r½ŒÃTÆaÒsðƒ–T.æ0…Ä®$5&ÝBMøpV>„ý£Z¼öí Ï©ªˆá£;èúþ]éaqï½÷ön6L ýŸþýûkyâĉ¶^?þö±?kd;hï²Í  S8p v2gΜºÞËÆ€ @€@/ DÓóËm€¤˜Q®08öXýîƒO>·ÿõ™Ljžìµ×^Ö ±Ÿ#Fèlõð_ï9kWj5T~—öo½ðjbhÙoÚhYg2vìX·k€¤îPm¥TÕ#ÙzÒf:v¥s«zz­©1™Ã´`ù©Su#¨Ó gS±5ÂR´㓬 ž5EËÝ®!l»µÛOíͪդ[H[ÆvëßÃv÷ÖrCV½Éu2õºtÉÓRÛõåxºIòôÊ}0ëºÏ«^uf 1e†’A€@:iL<9%Êì‘6Uþ†áwýèØ“CNNÓñ˜bYä\¦@` ¦X¦pðèýhب|.9Ëí'èˆMk/:L=J'e” Ók¸trʰ¡¬…Ä[•XC“Ê÷£¤r願ÊiLíþSÞnAs˜¢ÆWÚ{?ô¨úL&¿ñec@µ4»b͵ׅò­yբϊµ_ [B Y74l-VwÉb³.±WÇa°¸WøZï͹Әô\è%€ó“ÁŠÒ ÃGº§Fßywò{Ñ‚[*¤%.d‹SÈ¥òQ—¢ÀK~´ÏbÌÏBì¥Úí%ÿIÔ%6É•¦KÉ"—©D`Ê.“VôE/Aò +#1ßÓóƒdÉ~¾äy…gÜØ“nð°[xÞ-›K®¼Ã$—ßiL¦ó[ñ¦ÔhL}®1¹T…A‚”Ù®öœª¼Ô7Ýõh]&SÉÿ¦~yû3ùϬj¯nê7a5&{Ƶ}º³j½/[΀ @I î0ºÑ]F9› lÍ“ž˜]—É”lžÄž5:ªV€ó3’¢†>1ÓHÛ”kÅhãT¹$µõäÔ¨ vˆy jLÎaŠ ¢¨ö-Ÿ…_û7×Ù8Õ%árbPÌ3k„Æäî™Ú[¬É³•{§îTW=hTõ®wƒrw]…në 7j¹¦Ö×~Ÿ×{ =ß©çìx' ÔD Иž˜R: Í“·á§ë5 ủÉäUì%?SY©Äa F‹ Q35N䆊ãè0­³|Ð%©9êq˜ÞÑXî ã0=óü9ê.œ¯1&åÓ5¦›-“†Š©8j“)o“¦a7Þ!M->‹ t‰ hTîzL¦XãKá9ky®e›ÔŒÉôÖ¸kÅgÅš>ålæhèаiL®MÝŽƒÅÍ»›u¤ÜiLz.L:InM¹§ÆXŒÊ(C\i¤¥¸´¤´qQª¸b¸¤·KS—*Ç^*o/U ¿d)ríÙ4–B®—ÓËQ¦ ‚0•u˜ ¹˜Ò¦@Ûwæ~àïwù¹ä¶X$Rÿ!øÁ‰A4¦ S jLÞ?ªÄsj¡así9UI©oùHí&S/5&=nºi²ZÖ¿==ƒê·EÎO®‰u [‡¯½Åâ*iÙüYíÖžem'¶Y¬“T/5h<£YßÉ€ @íD@ÓW¿ÖoÆóË­½\Âk ßûÒ«AódôøYµ›L©“j˜bâ RŠõÁiKüÆ5%´“˜Mb~†í_Ëþ«êÅóÃ/é%ÛÌoæX›E/¹·û ­×N\{Ç÷Z¬Ê“ç»ZMcò¦QÂÚ¯«qꘘ1#æ÷±jKëfµêóo ^²ÀWÚ›5Qõ§Ý*¶s­täO+×[‹ËBY“Ó¯YSÖÔ€uïÕ‚_wÖ†uéä쾪pCº†s¹c¹Û)Ù|»jÿ¦•>å&ÐkAº=»öµÝó®“ÚnÑäÇGGtŸ,½×.9öéó?˜1°>ª÷yó¾јšÇš#AÈ)iL?19u@ʆœ®¿y¤K‘æÒÆ•Œ4EcLhhÉ]*¤KÀTs¦õÞ ‘Ëα6Ê%'=c‡iٶذÎì%ÝÅÑœp(GÓ@_còÒÉÙäs4¦Àaúmà0•âîÍ! †‡V¾sð‘ÇÖ˜].Uc²‡X÷àgc4å›]cJO†ÉæXãÈôqß-ô¬˜Óï-.»E TÆà«»7CÃ6&ë>€®…èêZ Ú¨5X~û×õœh³ä—€û&q U·ÆIÖØtíe#¶&¼kfºÇ®!›HÆ`q‹ÞÇužVþ4¦›G&œ¤ày±ðÔx§ž‹ÉàJC+Y€¥])n,yÁ–JSÅ¥…\*AÉOŸû`ú]Æ©s-÷yåOA–¯¢1eI“}A€@ iLŸ*?mþðº›ïüáÑ'–OëªKÞSÜ^ G”ô0feåÆtÉeíÐ ‚•’ L¯¥aò¦pB‚MœV€UMNЃ}”#x¼¯!Se‡©RÃiLA(¦‚ÃäÜä\c*q˜6¶,°–÷EÁPÝ÷pÅǪÑdJ6¾¬µ¥':÷dhC0å›í)ÚeS˜ýÆ‘=…úŸœÖzVä[ -CÀ.(ŒQ\½´¡a¯õ]óа5 cyxüÆ©µò\šu7;Hïò»2üNØ—€k[S×¾[¬nßNÉ[ÖÇš™ÖzMm)3XÜ2wnoO$w“ž ”t’® Ÿ£Ã’“\y+­T]©è*E"|š±”¶¤Å¡®äJš·ä?q³‡[­D!@£@ ÁW•_ÜÃhì‘4~) … 5UÓçÚÇŒ{›D[úØ=¼úϯÅr…~j (”½Ê"ç²&Çr'ׄIOÀöü@éSÉDr­©1¥ý£òžS“¡˜¼çT¸ºñŽšL¦ “û7æ&nÚ?›ä³¦Öû½œúÓÞâÿ3‹õÚ›Kë÷öºYgÑêÿ¢vâ*üÿyv·eo¿y? @€ P‘@‡©´Ý2ʹnt%˜¸ïñšL&kž˜Œb?vR.«:­Ô±4ë>sG¬©â[#¶“d¿yLcR‡šíDñ¶à÷ÙYÄveaoôvkÑ8)ÖêñOÉ:éìí~O_ê­£1Y¦‡©ü J¢ökmœ:Â®î  µ@cšš­uŒÚ=ãš™®:lc'¥ÙÍ`Õçî1W•v¸˜ÆäOò‘ig!¸\ÝY÷®»gÜz‹È¥-õj¹2ÖεCÛ¹éÇŽåvh'ì‚"».àØ™¸û6y¯Ú’ôìüÝ~ü[W·ºQŠ}úÜÓ®ÑNX îÓZã}^á#ñKhLew€ ' iì¸ÉeçÆoþðÚ›‚©µÅ´ñ¨K±&\©‚½TB*ŒU˜vtÕ„)ÕaŠÆ}äÊæ«o‹ç’«ÍaR2ïDc*q˜A˜\ɳÆä9LQ$T jV³•<†•o+ÁŸRûtDõ˜L~ãKrþŒ÷8ª§;³öS›cÏÞ±‡ØXã(Ök¹gE¾Ò ÐR††ýÖwFCÃîCmÚ¢k!ú­Qû[KÙ¾"lÄÖ%…´Î ×L¶d­…¨·X¿þtA‹íî4Ü—‰[ãïÙj¦\K™ÁâÖ¸s38‹ÜiLz.ô -Ý[±èÕþGŸ`ZR¬øÎ»UòK`Á»ò†\%+¥ÆR™`K´ä™ò©ÞROÔ¥BDÐò™ã‚©±)öRA´¢ÏYì¥dø¥È»÷òÇü¢À´2šhë&{uÅeG.›BnÙ¶¹aò8Wž+¤L–ÃD ƒŽ–Lmßâ0%³ÈÙ°ùMcòŸƒ“Ëû|qÿØœ‰MÛ—¼É?UþQùƒklbD8B3!”…:|N»lÛõw<\Kv¹¤`dÿ{\ç¯=ÎÚ—ä71ÚuVÚ¿¿çÔÖø íO¥ç»·zÕW}õ§í·Ø €&W ‡ƒ @€@> Èa’Å2=Ì%ÃT¡½0Xm@5OîylfÕìrÖôHB¶¶†…7W»ÀfDhcËœeÛÇ‚-e¢1i·:f(ZŸ¾ëÅ3Æ·m¬[ß?y'‹Øéù]ÿjËÔV¶E4&—K®¾Ú§éƒ[õ7N}°®kŠZuû'±Jñ«ÃÞëß-Ö\-7ãÞëßEVãö«ë˜ÆäÛuÚ2æ ¹›Äîÿ¬©›jò%ï"]‚%Ôó?/¶Ò€.0†¥ÇSòÓ§ãÚÑ­ƒãîíïóæ}©¢155G‚ SÒ˜||rb@ª8ödRéƒM…a¦Tu)6Þ’;'í% ÕS1SI‚›Ü¾Ð†A˜lÄÁ²¡ŸÒŸm‰Šw¬,­˜K®0 cC9Ò˜.’Æäâ0•:LyN*8L7rÉryC1•z ÉYVUM¦XãË>Ör±üPö£95jL˜í%§;è(-÷¬˜Óï-.»µÔ?4\ ÅT×аûP뮨ÉLÖ8}m:µ1õÛÒ¸˜Æ{¯µpÕi£CØø¯k-Zó¼FI]@vž©ûg°¸µnâ^œMî4¦k~{gRBrkôjÙ§ÆK©Œ«T>=\Û3!-%SÅ%½%ùÓ^J‰ºä©KUì%/ð’Ez÷Ã/Õ`/ySøä ¿d™R¦À^ :.ëH!D`ê…Àäg‘󟀄iÌ„öИbIOíöˆRË ”†b žSÃÃu#ª›Lêy´Nyý'pÝ ¾Æ¤—´ë ôŸ5]w¼´þ\ml±ëcküï.7`Þ® ]è?Ûm Âž•ýµôû÷âÛ’·B€ @ S”Ñ J7z4ËBÍ“»­b2YOºß3eýjX„$×r±‰6ÕAM{£ßTqvHÌñ+Õµ>üfH¬3΢.Ùi¸É–7Á^²ž;³©, ¬,Ѷߣç¢Æ¶L+hLÎa²¬%ÉÆ©% úÒòY³˜ÂA”§F8föX¨®­Ò­ýhÝ þ–U5&kuZÝYMé-Öãé†p\•ÅÎÄÕ¬ÛÒ¯ëXO®3~´gë«­ÉnokJ[Œýä±ÜMk[jaÒï˜Æd{s÷¼b÷ª¯1Åí|ì“¥÷ºQ«ä§Ï}0ÝÆîì„k¼Ïýdc—јË—½C€ÀiL<þl…©aနKŸŸHåáÒÆE#J±ô¯CÉñ£%…a#Åì Š—£#™#M`ª3‘œç0'¨/é.¦×X¼u–•p.º?=И~}³Òhhì&5‡F>£1ÉaºÚs˜‚l-aE§¤“‹¦¸Óy»Y–çäG3rÔ½å>œ1Éž±­ÙeÉö(hFS›ý§ñÊÌzUû¶AË=+ò¾&à —›?¦Ö·Æ÷í«[y?•ôÓ ƒ]GëÛï Ðg_a€­=èÖ[ËTk,°uth!Öõ;=b_Öt5¨öMbcÇúÓ†õ[X_Šë]q'k“êíåZÊ|™ôõ›Ùñs§1é¹°*ÉÅL*.O?>AQ”R)¥%ƒó›¢4gáÚb0ÏPWzîåµ`É•Ù/¯ ìx/IÜ3³^ytâs*“f½>‚DO!•³ÅE9ŒS£.…£Þóhx©¼ºôà³"Å>ü¦?e¥3~¦•0çq1yÜc“_2uÉì¥ûÇÍÊãA¹/,1 ß (Zj/…O´*c'¾¹ù…ø¢ÉÜB¦ üR˜*Lu©-4&ïUpÛÈÄzúùMO=¿Én€BÃ#ê&ž¾hs,Ó3/½i¡˜ì9uö’­×ÞþPÕ˜L¦ÐêÇ=Gê?GÌ`µ ¦Z \o“þOØ|Vý¸7&׸/3ûïeÿ¥ìÇþÓø¾íÇþ9Ù?3ׯJ4¦Ìþ-°#@€ ”'à&7v¢6¬Âè>5“J0&‰,–5調t¥²«m8ó•-QódiawÔ#3*Äd2çÃÿ±FM·pÍ›)h 39´Æ¥¾²«qM×qf³ýku­äT`×ð±öˆ½Ëthk¡¨#ÏÖXÿšõ빎–ýÖS¬¥SKG[ŸkLžÃ5NÕ“àfù[-¦Xœà•o?ûÒ›ŠÉ¦*ÕÒ85žåš{æ!©»S¿Íãñ·mýé¯qç*ºbõãš–6c' `ÜinËä™hŽëš®®®Ý Žk™É”zªÉÒºwõãy$e;·»Èµ‘ý“qG÷û‘“÷ªíÁ]¦;t²¥o··±Ò[R?}n”m¬KnéöhLü³ƒ Æ4æ±gÓ¤¢<Ã~{ÇQ?>!Š·”–¢Yñ¡;þÜËkb“ᣱ¤‚Ñ2ë¥Õ6œ” ¿4ýÅWzjöSÓŒJ†ŠÜüvwA˜ÜxÅõ˜÷س/i (œ¾Í`wA˜îyl†žñÊ%’³Q pÇ&˜|‡I™4 Óæi^"¹œ'•3‡ÉM!ã¥:rSè+¼c¡ TƒáØPY!¨…Å[¿xY“Éo騇ø5¥@xöÔm/%›cÏíå˜íXR”íÁ²mð‡’ÝC mƆ5Mèé‚¡a}©6bh8ÖâB[ Ñ,¶–¯¥ëÑ»Üw‚‘5$c_®Ak€»ïëÒŸnHÚ?1×&uiì’_2 ·Í-ž¨Ë*èNÛ_SEcRõÛ 0÷“\ÓF8,î¢Ü£Ô¢‡B= è©ÑyH• ™àWÉ)J_üòןôœ{ ¼ï‘I_øò×,ž§+Z#c)Е¬¼þžÖ|泟×oWì¡3o)é-U ¹”¢.ÙÓÌçÑ÷ ¼ôéüüãgº'Ôûâ~½4n¦tK-«|뻇h›~~¦Xõ´ª5z<²¢ç×}¾¸ŸÊ§þñó*Zøæw)—<.5ÜÝLÿ×/|µzþ¸% ©ð¤›L!WU`ê½ÆôÇOvvmúÒæóúÐ?ªÿþ¡]k¶™÷¦æ¨Ë§Z9éšYž?áîg׸n⦯;â²)Ñ A˜¯áÞÉk<Ù…bÒ µ†ÝVÝdjèuõxç Ê=(ÇFz¼[Þ@€ T%9L󗹉€š„sÆðùÖB9rHPÆÏÛèºÑ‡Ü·pȽ ý逃î~yÐÝ Š³,Â1Œ‘L¯š]®ê¹ÙêAsÝa6¹¢Æ7¶Åf}«1™ÃôÒ²M~ãtè˜W¢žŠ×vüúþE¿º‘3ØN¼z棳_·¹Ojœj¶ý7ÏàB1Ù J[7NÛâžá$+@câþ€ 4¦GŸñG£bCN±©p¤©8ØdÃL'Ÿr¶6²¥knºË­1uI#¶æ¨£OÒð¶†ÜÈ‘Öìû¥¯Yùö÷M ¿”šB®É Ù0Ðñ'Ÿi£?§ž;ØÒn|ê3ŸïY"¹™a"9(ç{a4&ß[Š-WˆÆ´õ£9Ϭ;ð£?njp­6u÷Ãtƒ¦(,‚rq˜ôø­e\ýnø¾>šCæE9îÊNÍÍ"°á!ébb25õ 9òFàì¿ÞóÔ ª¾bÌ+:^ }/5 »´¾«Bgƒ¦°Ì€þackÊjL滹 PÚErMÓ/§·,üË·gÁ”¢‚#|B,xRêŸQ8¥Ò J?<æ¤Ï|ö¿>6ñ9ÓMιèrý©gG§+ÉXê´¶ùü#žó#-i›³/¼ÜIK?ýåÙ*U¤¥”xK¡·o÷K,aœÔ¥¿{H”6® ×KQ’·d˜$ÁÈR=næèq3´Þ\{•Ù‹6êO‹½¤§Uy÷±Ìqû|a?=¹–&BŽb/¥ÚK.5ò¨G¦Ic²ðK~ò¸‚¡tnÆÂ/¹p£¡À´Å'—<ò¾²EQ‹JRÈ¥ùû=‹Æ´¾{‹¦ÑKÿ󨮽ÔÜÛû²üûíÕ+r˜"ã-ˆ «ÿRÑ,ç×vÈa:rÈë&¾ü¾…ß:o‚4&7H0øž—ÕM|ØàÉ~(&{N««omW“ÉÄrŸ=C€ @>s˜¦Í_fSt,ÏõÅ#_:}ø|,Ñôî[ž\©ŠM>õ¦yj¡Hc &ÀhÒöŠ·üv®Z(—ŽZPèFfY¨yrçC™™L0Fíɦcê±5&s˜^”ÃT˜‘eÓ¡£_q3AÝ ÊÄßPËTµÿÈìõæ0xzÕყ¨ö½Æi±ö‡µmã´cn­œ^SN+žË† Ð<Ò˜îä™ÄPT1qÇÕ7ŒpR± öÐ5{Á1-X¹Y“~ö˳_qƒžÁ4ÀôÒŠ·4~¤A%•«;òÛß?Ô2ÇÉUzjÆBKà ¢LŸùÇÏ»1£#|â%¿º®$üRɆll(,ï¸Q!=Ëi0è××Þaù7T4‰Ý¦oþû!6îhLaÖ`+±<šY­œÅñ´ Lnç{‡-Q©^iýö™˜4X£ÒI“4¯ºa„k|Y"9›@òëÑ‹TË ‚«'ðË¥1­Ù>ñï <Œ˜õļšâ®'ðHc*Ì"Ðhš_ 5&Só¾ 8S÷Ú£RQfJÖ "}ö#EuÝŽÓnž(Œõ Óúæfl.º¶;Ÿäš²“6µ(è.SrM‹\gí§ý×7÷È/…PIz&8òG'Ä‚'ùC(¹XJ…)ðzޔ䥳/ºüÞ‡ƒhLÎXvÓHùIÁ6O?çGZÚ÷Ë_;ëÂË]ŠâŸ8+°æ_ÛqÕ#Í‘×o{î<ó‚!&ÎÿdÀYZûÔ,gÐø½C|r–Œ–“~qÖ¾_ÚO刨¯°)óWýÛ—ö“º¤ßW\§Šl$ýéžM_~5ˆÆ$oÉžPU¤1Yž¸@c*D]šjL“ž[¡œqzru­Î[2É|=¿÷³3öùÂWå'ÚÿËwìÏÎП¶fîÒâã¬iL¾À¤GÛ~ß>Xå_öýꀳ.•yó‹³.=æ'§Ûšƒ<ÞÂ/iù€ÒïøôçîxpŠž½‚R´—¢ Êåö ©ÜšÍ›g¬|ßâÿÞ‰ª1ÿ¨¾wè¢ÕÛ,Ï  «TOÎÛh©w?»úÄa³,ª–&:žDcrƒҘF“µ\(&›ß ÜÒWÝ2¶jv¹Ú?_l @€ t*ÀaگߴyËbÍM|nÉÖBªë —ܤ—ÞTóDÝè7_!‡é2iL…nô[6hÔ‚Hc*t£k^Š5Oî;-«˜LZ }¥1Ó~ý^\º)Ù8µ”0AÉvDQíß5éUkœSXûjœŽŸ»1И®ŠÉQhœvêÛê×…ÆÔê5ÄùAh{Ò˜”¯£Âx“ H¥Œ:½þž9+~ј‘Œ% -i€ÉæÀ?üÔl ¹ÀKÏ/{SN{áU „eûÔçWiLç®'X´Ô¹‹ß°¡„q¦eáÐR0Nôê»'þ;oåÀ˯ӂ¦‚VyKz–•´d§*NcRR9‹êâ…ê(И¾°_2mœVžrÎ ð‡\3ÂÙKZ8oð5C†k,sÜ!GÞ aQø¥%Ýw=_cJÈL±¡aç/곯Djw[d•ptx}ök6…‘Ö7·dëˆ%•Ó‰ùkò§1]?¢‚“äžýgÄZ–å0=üôszŒÐ£¤¯(¹gJ}ÅÈCÒc¥zxõd,„Ñ•¬Xt¥±O;ä××ëYó©é/K¥”¢¤‡K‹«dšEiiÍö‘L8ãü!ò–ôÒÂРW°¥ž˜)iI[šJoϦã¦,°5§ŸwÙ3sWª+Y¤Q\ÐBÂ8Ó˜¿>,’–î|†t¥OýãçõÛÂ/¹œÇ÷>hLÁ3k!ð’©KЍ$É/ÉX’·dO±w?2]/I]ºìêÛM]ºKá—BoÉÊȇ§ÉU²Ìq¦ÚèÏqÓ—Zú3 L®Ø3®"0é·¶qá—´|ûƒSaßJZþ¸T¥©–¤r_é÷•Ñ3Oð#0ùvÿÝ‹£°LþÊ^.ÿlè^ßþÞ! Wu»{/ÊÑNrÕsêøylþÄðñ+ô¿ªîõMuÕsª?H`“)b.\£µèxa2µÎ÷5g@€ V#:LL™»ÔoÛ„ÍèU?šFMÔ¹^4¦"v)Ìz.,šËæ/{åŠð©1x@´â=&VXÖ¤­XP¥ ýpè'ùÏ”ÅmB9É\¥®°¿O*´’õý)9±X2iI¢’_ä*ÙsçÈž–±ôÀø™zô´ôpZ3~¦C{Iâ¬<>yå‰=nÆ ??Ó’ÄéÁÔ¥Šó½%—'NO«½ôØ =ú9㮽íõ>ßó¨4¦¯šº•P]’«ô˳™º¤üq.ÞÒð{žÐí±?=ãÜAÃÌ[ºùî'"?LŠ<ò¡à)Öb/%Ì7ú©ç-sÜÑ?9]Q—~~æ¥*– M“~k›ûž˜oáFÿy߯SÍö’ûš®EcÚç‹û?ðÌu垌Ǯø;å]ζÜ:áËê)~vîR»ë‚ýQ”þ T Æ4ÅÙ¢¿jò„f¸>:ûuKV­©®zNõ dãê9µÂ PœøË ιpp÷{¿ÿó_þÒ'_R€ @hY;wîÔÌ£“æúƒ(®…¢æÉƒ3^ "‡-µL5ÑBs­É)‡I%öÚ‰êF4¦»TèF—ÈòµoÿËý/5ií·³mguÆÞnÔÌ[E›jß5N£öi”¦DÓõ¢ºÚ—ä4‚f°Ù Š^8ƒMµ/Éæå‡ý’8ÁÖH¿ðW7ÿð€}ºoìÿg…É¡@ ÑÎøŸöœþ?5óű @ oôuÏC“¢8:%CQÑðÓ×Ý H•êJÑp@aPàªGZ’¸PZúšÆ•\Ê !ø½CŸœöòÈ'èi\ESßUlÉ/iÀÈÆäškÀȦ»k¨HÓÚ­<öìK§{Ù 'ŸiÚUyæE~éáIA ¹h0(Òôõ@`ZhL6k]“?_}ÀY—ó“ÓIö’Šzî;%ИÂÁ c:¡À”ȧQ‹ÆtìOž±vp¹içÖ~­Ýû/¾a?ÿ®(7<¤JQËëÔ›æé Ü¿5Àwø`{¦P2;lÐäÑÓÖ–›âþĬW÷ûÒ—&]xÄG7ÜÉßgýÕ=øÿŸ)è{å¦d\õ…M ¦ú­ïØg_Mï [ahØ9L5 ûYz¬õ­¡á£Oí÷PWÿIk3ãn÷/á k¾&jíŽÑy{hé“ëEc*јô\Xòè‘pA¯þÃãS6ð"'¹J…Ö‡2*zŽÔÓdà'…el¨"ùaÁ!S„I™4ÅyØØ%zTU][¦jÅ Õsªë&VEÓ É ÌaÒÕ©`25¢*Ù' @€Ú€™LLœkÍa¿yr×3«Õ$¹yü 5WÕ:Sºþ|jþ&ëF—Ã4H“×.‡é’»^*v£'¦~ï ÃVmxWÍ“-Û™hÑ7Ž™LÏÌIoœj¨ ’©›Bµ¯ø[Á JØÛ ÆéØpÅ 6µO)Êu¾5Ç*8LÇœHã´%j=''¡¡,4¦œÔ5— @ è!êî±+ H]HŸ±K›lŒÉÒtX¤%7À¤$ ýæú;•¸CIsošÛµIcCR—Ì[Ry66RÎ8‰æÏÌ]qøOÐhшÑOk»F‹ô̤»ìÚÛïJkf¼¼A£BZ£"›‡`ö’2o¨<9k™ên¹÷IIKš¸®G; )ü’&­1UÝznºû ý¶råÑõ; 4¦ÊS½IåÖlÞœ*3}ôÇM}TÛYvôèщ# €ªÛ`È—ÅûΉ¯*®žÀ­ñõŠð |ÆkÎaÒðÜ¡ƒ&ß?u­¥óSøêXà0íÿIÓ_°'ðvÿ)Ëkh©} þl iñV Ô˜®úž-ËíÔ¢ÖwÚа‚0éãïZßAÉ2CÃj}§ {æ(CÃîýAcjÚg¥WÓ€Ö­[çŸkrMÓ®¤÷R4¦¡×ÞžªÙJ½ª‡'!¥,„“*=GJ~wŠÒÓ^>âÇ':?ÉôpùÄÔ—-œ­Q¨OuüY‘œ$iiN×&KZУ§6p¾¼RÂi~Ëš×Ó§b/iYE çÕcd2þÎ!zîÔ ¶¤GO­‘¨tÝm˜´¤W}6rêͬV~a?‰JÚLнžPõû›ÿ~°r鸟qÊÙƒÆN|Q­‘½öEZQÚ8‹À¤g#=¼*ö’t% "jO±ç^­ùÅY—ºÀKz~’·d!F­˜ÀtôI§KWR¹â¦ûÕ¹yÖÅW«˜¤oö’žkvÆ%_?ð û݇Io©Kc²‡9ÉLãW~ÃE¥kÆdÿ®¾ôÕ&=·$ ÑÎoV‘_¯LVN¹i®X7±’"¸q®å<¶nâÇfoøù sʹöþ?*:‹{ÿ à @€ Щ"“iÂ×v1x˜¶îÄ«gºÊ”—߲扚™W>°øÊ1]Ånô%ÝCG¿òëû_ ºÑéرæÎa²æ &S‹ÜNÖ—ê§QGØ8½fì7 ôê_õàbWûjœŽŸ»Ñ¯ýc3£œÁæ;L4N[¤Þ;ÿ4И:¿Ž¹B@}L@OP£ÆNL HEsà5ü Hõ?ÎRv¤=rÿöα~÷PM}× ‘ ŒŸŒI]ÒØÙäšñ®1#ËføU rt¨HZÒØ½ ­ †~uí iH£B6<ô«kÂ5_Øï”sqf°kúº¤%éJŠÀ$‡Éb/iÜG£9<ý¼Æ€l¸gÌSÏ|äñzÔtåm|û ½ª zæ¿ïÉùq|¹LþÈN-јœø®‡F“™î_òŸÝxMghLºqC“é¸dãKOà^(&“:ÿöôn“êQOàãæl´8L–ÍYÃCÏzÝ"¡úéäbS‡›LhL}ü]Èá=¾Æä Ln‹XëÛ:^T®yh‰>þ~¦:††Kû^®|G¢15óÛ¿ÿØáü5{5óTúüX¦1UôêaýKŸ ¼˜I.xRLKJþé+JÎUr–’=Y–+…§L{Ö,>nÙ­¬ Šž8Ub¹áì;ËŠ‹´ä\z8¡l)’ë“©âb!—ì(VÌ[r%–‚$Œ³RL挳lq…²Å%EÖƒT1²høPåÇ ¢Œziã~tâi×§gܧæ®UĦ¦iLzžÛ´m—’b*,žŽ§19“iâ¬%QœÀÂ$W»7ìfp¢}”ðØs˜T#ª…rÝÄÉTt÷ùw'@€ –%`&ÓCOϱ&°›˜Úf©®ý8Laó¤;jžй&žrÉÅ&L¦–º¬/5Ù8µÚ/iœ†[1—œ ¢øÓh"ø׊O:L4N[ªö;ödИ:¶j¹0@­B@Ow=8¡‚¢ôëp@*x*$ëpãM%ÃL…9ðñq¥h©8ä†J‚£â˜QÚQ{)˜Öîgáðæ±»a hÈúIî±ðKRÈ%ÇtêÕ˜ì¡ñ½]ïvm:zi 3uŒÆd&Sp{ÔØø hùq˜,¸@ê÷T‡©“M&4¦VùRä<öì1)M`Š™L ÷Õí‚ÆÔWä“ÇÍÆôëknYGá³`T~uMðÔX Ñ’ÒןTANr/%,¥4Q©à*™±dÅâ*¹¢tÅ*©º’3¯cÞR`,E]ÉuHKÔ§²·dýѾºTâ--ŽyKú³u)ÊŽì«Kþsí½ãçýó¿}Eq˜ôûâ+nm²ÆdŸ%ÉL¯¾;2õó”:4l£ù©3ˆÜ8{††ú×;”z7S£ÈÖ¿ßÜiL¿v[ÙH¯ê=Ô¢%½\òìèB(¥ÄR*†SJ³”Râ*U ­ÅX ;ˆ“¥Š±JÙV¢ÜpÞBRZryâ*„\ŠyKUC.Õu©g~RïêAR9‹ÆTõ³¶÷m{WÝ¦Æ “é+<5c± ¤”ˆöÉT¢„l-´*ÿ£²GÕw?ø¸ÆÓc3@€ @ ?d2Ðï›>ù\r~EÔ‡î;L ‹¥^‡É™L>aÍéw¿ü0o+Uãôëý¾5Ncúš x³ÀS{Q£dƒ­²ÃdµÿöûAãTc$«¡q”$ÇúgÖúnÔœI3 15ƒ2Ç€ kÒ˜îót}R)ãMQz8?ÌR|ê{” £$GGÊ,÷0Zj,#‡?Bä UнT2q=ȰQ̳Qgø¥Ø8No4¦>¹Õ4¹¢Ñ “ûî»ÿÐ£Ž³Ì-nÑ L)Hzç0Ùøþô‰ñ¬à*i.^íìu©nd¼¡ï ­ï ­ïž û3ˆz04,‡ ©ïo…ŸAî4¦Ë‡Ý–)²Žôª{ pɃË-D)ÞJs½ùñ“*ÄRŠ‚*À• ªT©S]¥¨‹0`©ä1´¢±”i©i)ž'.%UÜÖXª¸2ÞR!äRi¸%¤ÞoÖ ©¿ºQoÛ{ÀÄê^8c ¬X|¦î]ÝZÖ‚þÔ–*Ú¦ò·Ðºõ¯ñ+_bz—‹ÀMqNÎr6ÙÖ Mä<®åÕ–í¿ÿó_þ’ã/F.€ @(Kà½÷ßßÿ€o>ðÄìbó$TX\ºËe›bÑc‡Éu£ëœvýq—P-˜³iŽŠFF,¡×¹¦v–þ´–—uºe(—¼þúFÕþ“~ã´¶Ú·.‚0«ÈfkË×â0©qúŸüE“Ù2™uI&Ó’û†©lí jyûê.Í×Bl½ÖhXE›é½ÔÒ  1qg@€@ƒ HcºcÌÓt\>ìÖp@Ê•ªÎ/ *ùIâ|©Å%æºÞRqÌ(1¹=U]*æßð3ÇU°—¢Ç¼*6ªè´—Æd“+44vùX5IT4Ö£eý¶;K);´Òl$H¯öà¦9ê^Ý'i¯âüvo AÏã0EIú>üƒ¤§õ®‡m-¸Ø¨²—¢« C4%׿1o¢EQm!É ©·oiÖú®04ìç‘L.´¾{04¬ï+}¿é[NßuÔ¶¯8[66꙱έ±¯¸`–Á))ˆí"wÓ«o-gi½^ÕÓ@걜neÿôÌ$ÉI•ý¤Ê•›z")&ƒ‹[ó•u%[JË —j,%3ÄÕ"-%óÄ%½%? ²:.]ßeՇׯmÐ I_îf&ékݺ×ÕÕîâ3éOû–×K– AV}~•Éô…¯|}üôWbSRË›åì u÷àUF_5ì€ @èf2?Ëš'±DQzé‹L&#h=hjdYg™S~|&yKzU“\0Piô éΩ×Ú®ÄúR]ãÔôµ`lÌÂ<[ã46 ¼“NJ®’FPôÛ²ZhhÄÖhÔÄ”&mcëU´^›ÉyÒ‹6ÓoÛ€Ä  1qO@€@ƒ Hc1úéªR)ƒM%àKb,¥K¥3ÞK½%÷V&#‡‹ºòóo$3ÇGz~©Ý£1©=¢æ†î#ÂWÄo˜hHM©=¢Æ‹Š´Mî;™L‡y¬…¿-6¾¼,ÞþÕªÌêÈ ÃUÍ%s˜ì$õŒ­'jAÙötm!Q¥+é \ zêÖüÍ4Ð[4÷@E ©±T{pù½} So òþ>#k}Gñc­oŶH oÑ ‡É.ؾ»´ n}¡iY-n ™}¡9AS/9éÏxeq`4¦,(f³µú®77_›IcRѳl-qùÌd7õ•hòD¡áaÕmµiuç=¤ŸSq˜²ùÖd/€ @€Àž=f2Ý7nV‰Â²,PX\ó$%Ll¡íª[Æ~ï ÃVmx׺ËS‹"ñøq˜u›h]ixÉͱŽ65²ü¹"j‚Ù~²"`}©ã¦Ó¢ÀTsíׇÉNØ…\²hLnÖkàÄÂ2iÅ/Ém2ÛÉÞ«·h›¬.œýt4¦ŽªN.€@+4¦ûŸö‡¢ÂJV‚ѥ˂©ÀMI-5ä舌¥Xž¸äàQlÀ¨.u)6ƒ= Blö6öRrúz{Ec²¦‡iIj˜Ø‚›ân¯ZF ÙH õìf•Étð‘ÇZ°ƒy‰)~ –hI¯&{Æväzö–À¤Gk=u»çsYM®É6s¯ÚtS úþ©ïë€3è9¨õ]Ïа¹ÇCÃn\[ßc.N‡¾Ä¬ƾ÷LÜ´ï7•ÎÈ„ÆÔó›5ëwæNcºìª[Ë=üi½^Õs@… ª¾ê”–T4“R¢(Åó¾;ô|銟“8¾ö —+þ3¨ž]¬&fTŠºRб”–.zN­UZê㫤yM±ˆ¦ÇØ‹X˜ØÞ8LÖYfcsE\WšmcS¢U\­C¸·ÆeX_j²qö?D³kÜ›žå’sª‘ èO h˜Ä,Ù˜ŠÓ•¤.i½VjKBgÉ,T\æ‹Ö ÇY´ 4¦–© N€@§ÆtÛ}Oõ`@ª8Ì8+%9:Å•ÂpRlü(9r3 ‡ŠRæ´»¨KÑ<öÂ$v§.•L\/ =Ô5"Syã¶Ó˜¬aâOb÷gSØ«úmÃ@6d¡Mzö˜LGUw!K4üçæ·' ö,“ÎйJöîì%­×²‹xªIzä¶Çr=„[´TK ݳ+Íø]hLewÍ&P®õíaÊ|hXÃÖ¦%ÅìLS6-Μ¾Ö´ûг4šíþƒÆÔ:5˜;ið•·†}éE¯tæt÷È&ÆJɃ£ÿ™&'™¥TQQR öJ–R¹LpYèJ5„YŠGZj'i)ùˆÜ )Ù«n_âöÍn¯šÃ¤ %Zûë™LN^XœâöGA˜¼‡T¦ÖùªåL @€ БÌdºç±™®¡Z¶-‹8LbhsBlÁMõs »Õ¿f¯º‰Ñ–{®#á÷ùEY_jÔ8-Dv!¸R{QëÃd×(É…\²±KW¡û­ „I JiaÓÁº¤{/?ˆ@c➀ Ætë}O¥FEcLƒ¯¼%J ª”p•ÒÇ• .‹¯.¥IKQÊ¡øÌö®`H¨¶œqÑHP†ÒR»Gcr “dhXÝYýq ›Äî¶ïÍ}'“é #Ž-ÓøŠÉùSzì0é$«äRËYfg÷|n®’]Ž›c`ÏÞNêÍÅfö^4¦ÌP²£>#PÒúŽÂ—$††ÃlY »qmËiWÍ^rª“^rI6ûŒQFFcÊd»ÉÆ4èÊ[Ruu³‹ôª\f?$Rêr% ©œ¢´´ºœEÖQß_ØýW®”‹«”Z)=º’=˜¦d…+¦4óæêqÇJ Ô3–¼ïÁ†>¶6zçÓ˜,:¨ë.W‚d=³ZøPëj7Cßf»5~¦ÍdzøÙ…6ÉÕ&×Gì?¤‡©F¤l@€ ôŒ€™Lw?:³T`J ¤æI/ã0é Õβ\rê2sSýÔ°RÏš+Ú̆ ìw½ ®žqÈ绬/õ‘°qê Léµß3‡I`5pb¹ä´ ‘Kf¡e›ù­õZ£?õ[ö’ ¥hE úÓ…kÊgqÕ• 1q@€@ƒ „Ó“–ÿ+µØ€Tõñ¦4W©8œT:–TLÊ‘o©0”àÔ¥’A¢DÔ¥f¨KþP{Ec²DKjk¨ÑáZj’¸‘ ›Ç®±!‹ë¦^ôò¾3“É5¾Jæ·CPkFµ7“NÒÍ%°hLzðÖ¶Ó•ô|n©œíÉÜÂ5©À¢¢:ó©—›ÍÛј²áÈ^ú˜€µ¾mh86}(;“¡aõ·¸Ì˜I?öýf=0–"Ó¾Ü,QÊèðhLÌ`7yÔ˜*<ê©QÿþçÊ‘•*$ws/ZR59©4ï›%€+Éþ¦¯¤úE¥‚«”ÈWNWê`c)ÕˆjÆ”ÁG³Ú.d2ýÛ—öè™—mª„Ÿ¦Á=¤fòªÚ‰ð: @€ wf2zdFÔ<±±¥}è™8LZeб‹h«•Hð×ëO­tÝmy¯¤†]¿õ¥§ej¿Ç“N\“¹ÝékÙ/é·"3¹DúÓ½dëOÿ ÀŽÛ–SÛV'@ ]HcºåÞ'K¤ŠcOÛ4~téo†[d ¥ÂÐRUc)!-Å'·GÞRaB{ÉTö䌫:k½½4¦>¼e2ýàðc*Ïoï¥ÃÔ‡W—ý¡Ñ˜²gÊû†@¼õ¦þLö½œøË ιpðú-U([¶ÿþÏùKß\Fk©uê'w“ž S좂ftIøÔX´Ž*FEª0)‘ßÍ´¤ÐLJ““ÊúIa Y¥=ý ŸÅ Ji¢RÜUò¢+åMW*÷|ܾ“¾DÌd;iATÑžeo×Ë?ªÖùªåL @€ ÐÙÌdùÈt¿yâ‚™gè0u6Æ6½:ëK­Ð8íÃÔ¦L8í6 €ÆÔ•Ä)BhoÒ˜n¾ç‰’ñ¦Òï—\H•IÍáååHZ², ~IŽ%3r¤yK…,}á-ÅnИj¿ãe2}ÿðcJæ·{5ˆÃTB©ö‹-[ž@ÕÖ7Cý¬C4¦^Ìðí¹Ó˜ô\Xúðç£`A¯þÀ‚1:åÈÄ£2î‘EHòKòÙ1}MWU9)J=h–±”j•J“ÁuJ>¸ªæ~-´µÆd&Ó>_ÚÿÁ‰ üt§8L~E²+@€ @ Ff2ÝùÐôdó¤÷¹äj<6ë+Ö—šÚ8Åaê«Já¸U 1q‹@€@ƒ ÓÝO¤ HE£Ná€Ô1õ 3¥OzsÃ%F‘*IK-9N„ÆT×-˜L‡ãg‘Ë$—\]çУ1µG=q–µ¨ÐúÆaªbùíИzÏ0«=äNcºøŠáL#½j‘Ë–P?²’pÛk\Sx ,o&™@¢(•†Sò"*!*E¹~kQ—ümÚ]cÒA`2}q]ˆ]ü£Êê+’ý@€ @µ0“鎱Óüæ SíÛzKëK5Nq˜ÚºN;üäј:¼‚¹<@}O@ÓMw?QÓ€Tõ!§-f¼u%o)´[¼‘£¶Tuø©Þ»V&“ ù`‰Ã”©ދí[ž@j뛡áLê )Œ™ì$ÓÐáô£‹‡WFËÔ+‘ÌnJ{ ’S‘ü…’§É0]eTm‘“ä—Â#f郦y+íðÄYõ‘´6è)i2ñ*“/Gv@€ ô€@ÌdÂaêÃö}K¬/‡©}«2gŽÆ”‹jæ"!ô%iL¿õ„7 uºxèÍA^°Ú†œR]%o®{að¨ÇИzp¿ú&S:@4¦ÜX¼¥å ÄZß gUchLY‘ìý~r§1 zsL0òþ.ÒSãaÇ”•|ñ¨¢„TŸ“äÉIøIMv›:CcòM&þQõþk‘=@€ @½!àL&¦Þ`lÓ÷º¾T¦6­Á6SŽ*›K… Ð7¤1Ýx×ø²™7^Ù’2 •˜ñž«¤hL=»SÍdÂa*K©g7ïjy®õÍÐp†u…Æ”!Ì^î*_Óé§ŸþéÏþÓ>_Ú¿\ùÌçöþ/ÿ×ßVØ ÊK_Ü_é½(mDàÿý×/ÿ¯õוOøû›ÿ4~Òìõ[>reÓ¶]½üà5âíÊ.÷ùÿöÏç\8Ø?Õäò–í¿ÿó_þÒˆ`Ÿ€ @€Œ@`2ý?ŸúÞ—þßUÞ­ÐBQóäúhF@}©ÿô¯ÿç÷ŽÜ¿jãô?>¡qÚa•ßV—ƒÆÔVÕÅÉBhGtÐýoÿÜé\Ž4ý—ÿßßj®ÂxøŽÿÉ€ØCæG»ÿÔŽ·G¶ç,“é>õ™IÓ_¨üþÞ‡Èö¸í±74¦ö¨'β'Ôúþç¿ýßÎ9úભo††k䋯T#¨&l–/içÎsJ?9Vî3.¹’5L jÇ&ý'hMIßOt3gùúʃü£jÂ+‡€ @€Þ»ð³®9 ‡)ŸwÂõSÿç§–ŸW¹öq˜òyo´ÐU£1µPep*€:“À¶mÛªkh©ê`ö¶xõf4¦äæ“?¸êñö~Ú€¦] úRå3IZÒ²d&ŸI¯vïêÖŸ&6ÉaÒšv¿dοs 1uN]r%€ œH†bò2åJò²Ñ˜¸Ú™€æ‰©kE“Ô‘¢¢þõ±Ø,2¿[Fëõ§6Ózm`òS2Tv;Ãhƹ£15ƒrmÇ@cª[A U $C1©UëŠó‚ @€@ç°¨æºYJZ–Ÿd]fÖ_fsþ´ .6ëD“Ædë­©n)J¦%)ä’4&»"Ks65®[©ßZ#‡ ©*½£.©£ª“‹ äŽ@j(&2¥ÜhL¹ûptÚ[O‹ú^4%Ì®ÍrÉ)&“uËè·½¤î?ÓœúdˆÉT× ÆT®†nŒÆÔP¼ì%°ûOÛžYw • k¾¦'ÔGV|Ö­Y»ctcÏÞ!@€ ¼pýb6ÉO=e2™¬ͺØìÇVjK“.ÑÒÏiA¿ºÉ.š)dõV>S½Ä·=SãØ²g4•SSqs0@€ 䛀³—Ü$?Ó˜~ɦJTRß™MþÓJ­±e ΔoxrõÒ’oIåd,Y&ýhþT‘±¤PLZ£­´õrå\Fg@cêŒzä* @؃ÆTñ&@câ3ÒÎ\4kÓ˜4OL=*¦+Y¤%‹­ë„ÑzõÉX.9ý¦û¥ÞÊGcª—Xã¶Gcj[ö ¦@cj*n@€ @€@û@cjߺãÌ!@(%@4¦JwŸ—v& KÉ…V’Òd1°õ[×d¿õ£mÜK¶F“M3kçKï›sGcêîiGEcjºàL Ð+hL½ÂÇ›!@€ @È4¦üÔ5W @èthL•j©Óï®@cÊf/w…ÆÔK€¼­B©Uj‚ó€ @€ @ Å  1µxqz€ ÔL©*4¦šo$6„ИZç@cjºàL Ð+hL½ÂÇ›!@€ l ̺eÏKc²Ý%{k[?š³óã5ír¶œgN  1å´â¹l@€@@cªT©hLxËsIh4¦F‘­¿hLõ3ãhIhL-Y-œ @€òJ€Îâ¼Ö¼®{T×^sß89Ǹôv €ÆÔµÄ9B€ P 4¦J”h™Ör±Mû8u¯=ch}gVhL™¡ìõŽÐ˜z@ 5 1µF=p€ @€@H€ÎâßhL9®üö¹t4¦ö©+΀ ÊИ*ñ¡eÊç§³  1eZ¿hL™âìÕÎИz…7C u 1µN]p&€ @€Sžï4¦<×~Û\;SÛT' @€@hL•¡1ñêlhL™Ö/S¦8{µ34¦^áãÍhhL­Sœ  @€ €Æ”ç{)ϵß6׎ÆÔ6UʼnB€ P…S%@hL|€:›S¦õ‹Æ”)Î^í ©Wøx3Z‡SëÔg@€  1åù@cÊsí·Íµ£1µMUq¢€ T!€ÆT  Î&€Æ”iý¢1eгW;Ccê>Þ Ö!°û?¶=³îÀu;F·Î)q&€ @€@~ ÐYœßºßƒÆ”ãÊoŸKGcjŸºâL!@¨L©Z¦|~:›S¦õ‹Æ”)Î^í ©Wøx3 @€ @)è,ÎñmÆ”ãÊoŸKGcjŸºâL!@¨L©Z¦|~:›S¦õ‹Æ”)Î^í ©Wøx3ú„ÀØåcUúäЀ @€@Mè,® Sgn„ÆÔ™õÚaW…ÆÔaÊå@€rL©RåÓ2ÍñG#—ŽÆ”i5£1eгW;Ccê>Þ >!Ðïþ~]Ý]}rh @€ @ &tׄ©37BcêÌzí°«Bcê° år @9&€ÆT©òi™æø£‘‹KGcÊ´šÑ˜2ÅÙ«¡1õ o†@ó ˜8`¯+öêÿX™LZ–Ò¤ßÃæ±h„ÌÞ·í­ß פ—´™~7ÿ$9" @€ wtçø@cÊqå·Ï¥£1µO]q¦€ T&€ÆT‰-S>?M)ÓúEcÊg¯v†ÆÔ+|¼Í'°nÇ:3“¤.ia×wiÙÅgêÞÕ­eûmçæNÍ?[Ž@€ ä”Å9­øà²Ñ˜r\ùíséhLíSWœ) @•  1UâCË”ÏOg@cÊ´~ј2ÅÙ«¡1õ o†@ó (êÒÀu\‰Js6ͱ°LúQ&gÒŠÃ$IEËúÝüó䈀 @€@® ÐYœ³êßúÑW¤1MYûsÇî¥9ƒÁå¶*Eí™=<*gÿõžÓÿÇâŸZÏ @hOhL•ê–i{ÞÕœu­Иj%Uv;©KúµòÒ[ç©CcúëGº5o}0µ×G`=!€ÆÔj¼}H@–’\%€S—\|&­Ô«òœd8ieSÑ‚El†@€@óÐYÜ<Ö-q¤é¯¥Î¾Ô²âíá-qŠœî|/~ P'£Ž:ª'Ÿ­¦¿çÃß½ýÕü›unÓÌ!@€ $ÐYœã›bèUNž21Ǹô6 0uÂמrœ(§@€ª@cªDˆ–iµû‡×Û›@s5¦9sæÔ9ÌÞ~›ÿ—ÿ»ýιÞ3>ÿüó[ÿ¶Ï—ÆtòÉ'¿}ÔÖ¿—í¿ß”Ý7ß>ê˜ãNÒÂf•w‹å­wwå•ß½éÊÛ¿{Ã+›Þþݦm»\Ù¸mׯî l(–^ßZ,ë·~´~KT^ÛòaP6e+o}¸6*¬}ëƒ5oËê7?ÊAyõQÙ´s•WVnܹrãûVV¨lˆÊò ïåu•÷–yeéú÷¬, ÊŽ%¯e±+ëvtËöWÖË¢µÛ­‰ÊÂ5Û®ywáê ¼ìÊ«ï.ˆÊ; ^}ç%•UQyqÕ;AYùÎ +ßvåùo»2ÅÛó—«lS™geYPæzeÎÒnWž[ÚýÜ’¨Ì^Ò={ÉÖÙ‹ƒ2«PfvmueF×–Ÿœr¡ÊŒW¶L·²((Ó‚²9( 7™°à³Ÿýlë’?þøcéV× ¿çËû°téÒÖ?a΀ @èptwx—½¼¡C‡þâôó¿ý½C¦NšW\w«ÐÍ©[ô积۵ÕÏ•óƒ @Õ 1U"DË´ÚýÃëíM ¹ÓèÑ£9þ'%¢EÁ²_¡²`ÉêO}úͲ(øérŦ·Ëk¾PQÁ¦Hó(’…Ó'VnJq' âDÑš(Q&|_bÝŽÅi²„3%G"Ô$œ#á gG85·#J½ˆ)Â%:DèB„"DwR„øþáÇ\<ôfYò|Âù×wà¶þmŸ;I¢’}Šbż¥›ouôq'•|´’ö’4¦RI2SªÀä9Lmð>o’™êv˜<©f‡)ú(¦8LÆ”î0ESø™,jL¥Ë.Ïa’ÏTª1Å?Ÿú Vq˜z©1Ur˜"É9LZð4¦-£1™ÃtçýãT}óº6|高L­ÿÝËB€ @ Ó ÐYÜé5œz}’BN?÷R5N_^Õ}àw1™ry´üEËaú÷ïºðÕnݨ§žs &SË×'@€@hLhL|HòK ùSÆ/~t˜‹©zt˜Bh˜ .LIh˜§ÂE„ÑB<"LmÓ«i!`œ;á‚¿”üRêKb¾”| £½¤†z© 1¥‡wIÄvIjL.¤‹‹çR!Â`.‘Æ:LhLmóÍ hL•ü0KnÙ|À›BÉ¢.•^ Õ¥êöRácV£Àä䲎Ãä9L…PLÑG±W“b2UÅ9L ÅFcêq(¦Y^(¦™¡„X9ÓÔvˆÆdÓÈÑãõ Xh¯í˜û &SÛ|)q¢€ @èXhL[µe/L:Èç^ªySÖ8]°b+&Sþî‚V¿bs˜­Þf½( C~êÙ˜L­^kœ @•  1¡1ñÉ/¦kL."L̲ýŠÝ/u½*©–ÜV iW<(Œ‡)LiU´)Ê9LQ2«”LV.Uà0Å܉rÙ«²ŤtUÉDUÉU)ù©ü¨.‰´T±œTÒ˜*S©ÃTÌFµp3јZñëBÓM·ÞeŠ’+ÅÒ;¿ûí­w鳬I“–‚¨K¥—„ÉÿŒU°—‚L…[d/²ÈU˜ÊaZí%’ó-BEE«’K®SZ:¹ª¡˜V–f”óÒÉéCf” "§•Í(W9Si:¹d(&§1•Ë(×ú“s˜ä¨9I*ès‹^'&S+~qN€ @È4¦üÔux¥ÃtÞ¥~ãTáÖ_Z±å[ÄdÊÙÐÊ—8Lß?ô•ÕÛœl'IöN9ûbb2µrÅqn€  1õü eÚsv¼³ô…Æ”FrEX^ 5&9~‰gµ* ¿´kCw"«UõDr®}ë•5oF%™K®r¦R&¬Tt˜üÔUÉPL^:¹H“péäütUÉŒr…b 2ÊÅB1Y4¦¤Æä2ÊI~@cjŶ4&‰JÉ JW|ìIîOÿCå–ËxKág,ñ1‹ÙK1iÝæ‹%ÒãŸ:}üü,rEI&“-E`J ˜.©QÑjÈ%×8L~ÞG}bo˜Ã´dkÉG·$ÜV—RјN:åÂ@cZ÷ž¶p³>Ʀ1ýã?~ö÷øÄ/þË_Záþv“}Õºy„úU²¿Ù‹^ÿâWX¼dI+œ*ç@€ äŽÅyªrs˜4£1Ù8}aÙ–o}çà)S¦ä‰×ÚŠä0}GÓšm1ÙN“zŸyÖÅ¿:´Ï›s‚ @Õ©!Z¦Õî^ooMט|•"¦+éÏ^ 4¦˜bQcP˜ra"›¢²JñÆ~‰®”ÄaÚð~Q`ÊÚaòÓUÕ’Nî/¼‹‹íâB1“S• ÅTÏE“§1¥„q åiLßüæ·bòC ~ öjÁsjÜ)Icºñ–»Rå$[©W|쉶}¢¼™ºn*6† ô€S%h´L{pKñ–6"ÐS¤R¤óIcúL¥ 0[?’Já—*öRÒ¦ð#0EYä>pEY©|"9_œpÖ„ó%gº–8L5:L¾‘y:¹PcÚòýâhLÉ0.ÃEÓ~û#&?|´ûO­v×çNcºaø]f#¥½*iC·%¿„a–Ò"-Ùgl}i¸bÈ¥Ô´q‰›ñÌBŸÕ~©ÆL=˜ü¤&¥©ÛÑ•R©¶DrÒ˜V%J÷¨…•ï¸hi)A˜z™K®¶8Lr˜ôéuS1“ç0•Ó˜Þûð}ûIö¦þl×@D³nâµAÕH,›ùòk_üÊ×k7™ÔµäzÙ’]c}xÕÖI×ÕÕ¥ŽÑÚOcï½÷¶ÎDëŠUï³Öø]õïŠ-!@€ úÐY\¯vݺà0¥4N-È5Nç-©ÃdR»O­¿ºˆhû¤õ¢ µ íG~Ì^{íUUޱ£KŠ2áIŽ;VV}c²ÅZ¡ùé6¶…Øõê´ý5=Rž;´.ÐÜ/;œ»ä ïõ; l3khë·ö pýÙãID¶7íD y :uÝå66‡iñÚ·Óf‚E²:5oÀ™ë2™Ü «2»s´ÒéhIt=»4Û­W–ë*ÑAS?J½9™r•[áXôÉô¬®y @ vhL•XÑ2­ýNbËv$ÐS9ÑB~ż…ÆŠ‘\±!é-•š¯I¨Hu*ª‡_ª-S\`*É^U)ì‹'0u¥É -ÚËê ÓÕ q˜êw˜¶Í)„bzni·‚¹¤Çs)Äa’Ã$ÿÁ4&ŠÉO'‡ÆÔºqEcºaøÈècóÿgï?Àæ¨Î}O”û²oéZYïè#­ ÕlF‡eí#­£‘5-˜;¥/½cCcú–Æììë¶ ggµÛ²ÞÑÊV7½ì8¶­ùÏݪJö­ôž¡¨ @€òD€Áâk;îú7tµî>Rs¢—íÑzgÛ¬k²Gè¬íVÛoHÖ1t¦‹93É);¡1ÇÙª§-›‘c‘ Miš”­µãÉs˜ª†Ež“l§'ÁÔK•5üM›L6Èàú•tCFÌ1 õ=ëZþÈItT$´YpÃÈÌèa"ª~­×™~dG‡{Ìí"½£— ¿øš5Ðz……ÒíË?6Ý–“i­ó-@€@3Иâ(qeÚLbìè¾ÆTÊS/ùËŒ¹+>½û5äŠoË©°²Æ/UZEÅ©¨L×3UÙ^z«¡½T–(B…g/µ&0ù¾D©‰$L=Uy“›HN ³–†s»ô$v©$a ŒˆR¦Æy˜*"„²1S‡‰IåRz¬Kcºê†!U6’9I•¢O¿ÿ£ãÝQTûpr‡V鸪i,Õ”–¢ÞÒ*eZreC¬KÍ&^ZW%FÂ{)&ýR“Sã Li¶§Gi­µI˜¦…¦ŠÀä;L:€KÓ9õ¦´ec ;Lëß\ê¿8¡n˜Øžvµ8Až0{Í>_j<»œdÙ«{‚ÓdІÆü1e23iÉÏÚ:nœW ö0ŸjpF‘¶5ó¨lU öXgtR9½zÖªá×Í—–l¼LÛLéé‰jA€ @ g,ÎY@«›ã9L±vH%“=c£‹Óióe24fÜøõ5&[ÙÆôr©›ÌÜÒWtµîl*·em'd5µp<9‡)š0¬V*¦ò“`6Šrâ)ç53»œ£}hÊ0*M‘=sU¯ï¹ŽêSŠŽŠ¸æÛf]–/n­=L¬·û}Ì2jGÇyü¾ˆöbÚ“ ®Z¤w\ª3{ß*:6mˌɴÐù  @ yhLq¬¸2m¾'±f t]cRF˜°ká)JÓç.ÿôgö¨¡+™_QKZj4‡U]u©†G¶—ÂEür530U LåYäü‰äšMÂäMQV#^Øê{n"¹°ÃTÏejõ\r.“K 1ýy˜ÈÆ”ÞC\Ó•7 ©Rüª?}*É¡ˆ¢¤¼J=©•zr,Uû€föK^r³*i©4U\t¶¸ÊñÖDÖ¥@]j`/‰—T^ªNƒVJš²—bÒ/Yx“ ëLîX ¹Ø L}˜|ë°·I˜œ(‡IÅå^Š.¤'SM‡I¹ïì„»¨ä0UçB/ ÀU4&ÍÓ÷Ô³M&SˆÜ“‡Æsý!6÷© L¦Ùx«]º¼è˜rhŒÕFÜløXiÁ^VŸ¨ÆdµÒûN·²¯ûcµî¡[Û‚[3½')j@€ Ü`°87¡Œ4$ä0)¢_OÔU•ŠÉ{ÆF§Sç½²ÿ7ãL¦¨Æ¤«?½ij‹)5¦%Ù5 åî5½F—“ör¤öì.WJ"çÆŸͬ gç„Ìëã®UmÁ%-6HþE¨þ´Ô5vaëŒ+[3ª1…jî;OV_F±Jú“aÑËVö­[ÍÇêjšÓ˜üKr“ºÜÆm§f,Ùµ(”ZêOÿð9[mý}Y(-¸n-F5¦¦ŸÓC±DnÆd iL>‡×ROYÛ£}ÏuTë.X®§ it³îq2—TL_&¡Îì`ún5#bSÚätî»–êLï;wÍ:mèØt‡c2-wf¾@hH)W¦ ;+dš@÷5&©¡ŒJž¢ôÌsÆTr*\)çX*Ï^Uˬf‹ëq*f°8§ p˜ÎºÐ†m²û*‡ÉÏ\ŠI‰™õÄ¡]œNž·!ÆdŠjLN¡°ÉÇ¥S¸9Úlž¸è“3Âo—„ºÔu¢]®Úå­ïåØýëÐølLþ%§¾e¹vLïˆÊ7¶åš!ª1ù«¹kj½i»Õ+I»]¶GëYScò[¡ªþþ;ÑlL¡©ßŽÉç잃2z¡—ðÍ:L/OPªR1I¶S/ÕHÔÏÝ 'SHcòƒèwcQ2[.Ú÷\Gu#'5GEÜ–Ýfµ ~âwŒÐabHM5sZ˜z…ŽvTc EÄ=rf™ÙwµM×Ál ¶¯è±i5ïc@sz6¥Y€ ¶@cŠCÉ•iÛ:J%®kL¦RÔ+Óæ,“Æu*šÍSÓ[*?H¢° D”Æ"¬wÌ­TÏ™<.’ù¥JœØéç|ñ•‰ø)ä|S¢¦#Q%0óSmUÑÀHPšL´xs|.›œ 1yÁ¦ ÌÊwËÙ˜j;LL*—ÊÃøã¥1]qݘ#gÐuÆT6þª¼¿@NòJµXí*Õ̱dž`é«%-y[Ô[Š?êÌô³.Å«K&»´Ç^ò¦ò‘?.$zóÇÕ;Jm¨È•g¼Iëf`ê½À4i^pôÊaJ¿ÆdÓíÎaòÎÅe‡©Æ0qí8Á;óÅÏ}q¿y Õ ec qöéÙ.Œ›¥óiÈ°Þ Îa*p—FQÊUg³¶'Á‡©*aXY¶³þ?;ùܘÙåšÔ˜ÌE3tѾW’?*âë¢ædü¾:LÜâÇÔ¥%³m†4&×O\D쳚ûŽš?tc—­:6m/ŒÉ´ÜŸù" @ hLq”¸2m¦±Nv $¡1…\ ߬˜ZÒ˜ªµŠ:)`jK5…Š·Ô;uimyÒª}¢¾½T#ýRiº*=úâJüru30U‰š“ŸØE¡VžJ 0ùSÝ$L%‡ÉÒ¸|÷°÷Ûb¦¢ÊI6&]»ºÿ˜°L'õž$Kÿ.iÐu·­tÖQdAŸõÃãj¬PšÎ•Pî²Z©Ìº’sŸ_±ñÌó.±rñï¯1=pÀï¯ùÖ÷Ó¿þfö!G[}¬Ö8\§µ*0ÙÑÛWéí­«tòå&7úvêM³Žºd¢Jÿ¡Ï]ýð›NÎN¬BÏ<Û À]ûØ Çþqê™·Ì~|Æz“³ޢͣ§¯®g2idÍ=u§fiÙž¥soú'Øu­×:.I¾[-´‚Ê}äÛEþm˜Ì^ö|¡Ü ~­B5±•Mir[Àaêd?eÛ€ @ˆ`°8w¦òãëÞÔÅé5¼à’_õð’+Zbs˹aIJ1³_у‰zêéž /þêºý®›q˨åþÅ鄹ëkšL6Iœ{HwÝç®%íÿ:4tݽêŒ^Hús½i}m!tý½¼ÕWLœò¯7CW¬Íßm¹ÞåªöbÉ¢¶VÉšWë1—íÖ]YG›æ¿#»+Ǿ븊é#›ÝÌÞq«9&º„·¼>!a&k¦7ƒTë˜Ã´põ¶‡©4ãáO¯˜¦'ƒ„奲so›ã²Yß7iÍI×ÍP¼’ŠIO‚iàXãN?­o2ù½1TÃPÓ¡ uÝz”üQ‘š} æ Œmͯ˜í×ßiÍžãïÂH¨ÆŒÆhÑ}Ùf“i²³ @ 5hLqܸ2m­Wñ­¬èºÆT[¥¨HSf/•ÆTv-*rEŒYÑL ˜ž|K¥”K~þ©r'~ö«ßŒ™2ß2¿ÜxûCßÔ;ýN—>á ŠQSæýñÚ¡q¢äN”r¾L|vÅ ¿<}Ÿ/î{àw½î¶áÁEbPv¥¶½ÌUåOTÕL¦‡ÆÍ9ôèã L•Ä.%©î,rSÖNÂ䦢’ÆtnF4&7á’Ž6]ÿÚ³4.ïoܤrZÉæ¹·ãTÔØD(_tVŽbÕSÓå×Þs¨èS{õV¨H5’*U%1«NeJhöÈØg>ÿ¥¯œqÞ%*ò–4’ò›ó.9úG'<<æý«eÔÁ¦Õ~sî%=É–Js‡íñÙ=÷ùâWÜQ§åG=­!˜Ò(Œ_v~ó»‡ú)—xbšÂê9ãj«K¦šºtÊY«Ô9®Qî¥Ú“Ç-ÝzçÓOúÍE»tÅO¿dóÇÝþФÝçËÙ°,0ið¨§xóÇùG¬æ«7…œe`òKë“ì¥ÇÎþøôO|ÜôPZ GŠ9LCïQNÔ_ÊÕ/I#¿£fmxbæúSnœõëf™Ã¤™ãN¾~æOâµbûu-=üâ N]{ë¨å‡ oTmNªæ¨gVí]?'S Uå+€ @€ª0Xœ¯!‡éÔ’ÃäF9tqzé°.Iðoï¯bsß>nå7ÎóÈÓkuq:aîkœ5æÖÑ+†OyI§w>¹Z×§îâô©9ë¾Z''S¾øÑš¾¸þÀ`žÊ9÷ÅoE“†°®Þꢔ<ðì1ÎaRGUÿ´éä4F¤åÛÆ¬|hÚÚÃL¸küê a˜÷$˜†P”¨ÿ„“âr2õ­m|€ ô•SA®LûÚ¿ø~º $¡1Ÿ“Ÿ 4&·Âòž¹ªª¦« ›•â"“VÕ˜*Îå¹üº¡²)ýŒÔ¥}¾èwkîÄ…—^-S ŠQ“çéÍÓΚ±j³+vÿÇ=ÏÿíUŒœ6ôþ1Ÿûâ¾×Ýö@ïì¥Û}æÅ÷<6eöòmVª¦[ZžBîÎG&ÿë翚B®*S›&S ²¢1)¡¯ËL¬Gt´,7I&’Ë\Wc’±d¹ ÝsZ.Ÿ³}?݇líÚÓ5ƒÝÔ‰Ñ}zäóß/§)só,VÏþæ¦] T=³0†­@‰Jf/¹4K:À¦>·Êt%YJúwô”ù:Ø”iéôsš*è¼%­ ÷Úïtó–tÔ õ´&Í^¡ÃOEY—4hxÁo¯²Ïe]Ò(I áÐûG˜8÷üK®:õì‹5^símœröÅúWË· ýØø¹¦.=9c™\Â_Ÿu±Š†Ÿœ¾Ì–}ê9e]š6oý­÷Žú핃O>sÀ#OÍQÑÂ9_iç-÷Œ:éÌ'1Àæw¼ùž'7çìWH]zpì ýäç§~ý[ßt÷:Do¼kä¯~s‘Šy6ò–μhP¿Ó/pù­ÿ²Ï—£ÙÒBé—B“?õ£Kž¦üiQ©ålLë׬}oøÀ¤•ŽiL=Sy¹àñA?1kCÐ%Ö¼>bæú#N°(K`R*&ý«x)FzŽpäÌõÁÌ}/lÕHñý“×X*¦À`‚Ì‘O¯Üû ug—ËâN!@€ `°8EÁèkUÌaêú¨\œ^z߯и„iLº8½âÁÅÇ_>U§?½V&*Oðe÷/Òƒ7zôðÂ;æªø§z iÜìuû}ã߯Œß×ZòýÆdƒ0õe&s˜¬ÚZî¨^vsõÒ@c*åa:~Ð4=&uÉá»þñ¥|`‘ 7_t×óÝ9·ì0y²]ð°ÜüM'üꜘÙårÌž¦A€ ~hLq1âÊ4ý=˜ö…@×5¦JÒ-&ÏzáSŸÙ#ìWx–R(ÿKO¦¥—kKþ¤UfSÔœ´Ê쥣~x‚˺¤wFM~^E‚„f¬’Daù_œ;qÄŽ—,a‰—T† }ü/NÓuâï¯rÍàÎ+MW%wÂÉÁý÷ÛwÕmÁ;g^,;bê¼u|ûcOoÒ’\ê³ûGLýÜöÕ±'iI ò–4[œVÖA¨CQ ò–d/飫?péU·évdŽ›¾L^}ËR—öþ¾:,å~æ÷Ôqxå-÷f=u|Þý蔽?¿ï%W ¾òæa{þËw=2yàÁ1©aJÙKZtÓ°³\¡•u”¼üÖŸüìÔ sÖêM}tûÓ$-Yî%M$wðQÇ}h¢&•¾¦_ª/0µ 1I`zëžÓ>:­"0uRc2‡iÈ}#‚ÞèIoêBGœxóË¥(Éaúõ 3/) ›úÈÓ/k¤XçP€³aâ±s^9àLuµ £•I`6§“ÚÈi˜LIØ/ @€òN€Áâ¼DXÓ)g^Xº8-?]c£º8=aдߕì%Ù!—Ü3_#€z–Fƒ}¦1•/N—§ Ð36·?¹Ê¥b²Ñ7]œŽ}öeL¦¼ô—δÃiLud¦Àaúî¡óWmµÁ:7Ò­a7g;ð¬1öè­†JÔK¥1•ÒÃÐzÌ:êáÆßõÔêK¶Ú•ž³TLÖK5ޤ”Þ˜L 0[… @ OИâðqeÚ§ÎÅ—SO ûÓŽ«éZ˜_1qf 1Õv-š0+|§"$-9›Â©–pWeÒì•2(Jù_ö>jšMg…yK§ž=PÅ&­*Ï·z‡ä‡a#¦Ú,Uþ\UzÿðwÞ%W^}ë'î}|ŠÔ% ºx<÷â+ûþqÒ$”êE¦„®"åHÈ^ÒÂ1'ž¦™ã$HóóSm 9ý«¢)ªäBSéJÓ³—*Óf]~Z.+º­”ž)äüÙ¨ÜrÑL.™Ð˜ÌDr“˜5ÎÆdkG5&ÉPMŤæHcºìêÁõd#½¯OøÁ±1+ÄøI5«Š šX¹èÒ«GO™§…‡F=-iI˜ýkGšcV,»Ri¹îRv•ÝÒR?ÑHñyCæhŒøÜÛæhÜMÿZ 5§1bM$¤­“ÃhL[ÅDÃÄW=¼Ä&Ñ À‰&SêÿB!@€ M g3n¡Z—¦ ¢§Ö0É&=`süåÒ˜æÙÅ©ÆtqªYºtqZzÆ&ÈÜïš¿¼fº³C‚äʲɮÓË&Óýw†/±CWÜüYLܧœÉ†bªe&9Lßüî!óVnñ;ª˜ìÉ@ŸØŒ‡6—\IcÚnÙ¬Íaêwí •žéäBO‚•ziÙd:÷z) PP¯-ÉÅo;€rH )‡Ýš&5I ëS¼J1aÆiLÍd~‰šÁEÜÚ²Pš®Ê©.óKE¨Ø9kÉ+ò%.»fHH]2‰¢t (éâ ñR)ë’“–Lc*=ßb%P&T,Õ‹ŠÔ¥s^yïcST´¬l/Jõb×Jï"AB šŸê®G¦hÐCj~*Í'A²ºØ¿*ÃÇÌ6AÂÍL˜ü¬.5&6ª)[“ÊÕÔ˜”¢ÉMW7SMI_Ë®ÃdÓ®\Ï7Òûúôˆï³‚—©L’•ðáTû¸ªˆJ~v%›ÎS—vjÙš©˜Æäþ Rœ•4&SOøåé*š¦ñþ‘Se,Ùd*NWÒ›ÁqX9öî{<Иt*åR0OÜÊíò–ôŽ%@Ó±g“ŽCÁ1{ÉiJ¶dE&Ó]¥ÜK–MÉ( ².Ic*%^òËY rsÆéàÜÿ[Ë^’´¤iãtˆZÊ%Wθp4¦ò±ºpó×¾y°;VÛk/9™IÒ©„Ü&ÿÏacæ~ïŸ?ùá™ÿ{ñ2쬭Ë7î·Ûñ'žÒ#™z³ ꤬‘âÇg¬s£oz3û•`˜xÅö²ÆT&~`òKœ9F“—±¿’Š©2§ÆÞ6|Òûç½ßÿÛMþ ² @€ ÆИ3JûÓ§OÿÒ¾_«z²’@Zƒº8•Àd6J ‘Ã4ðžyæ0iœÁ4&ç0雲ÃÉì®Áõ˜ÍßÿÃg¶üâÿÓÍ pö• ¿öì¥ê˜·.ßÿSŸÞcÖ¢õ=Cvn¥ü `0ȦÁç0©—êOßaR¦‡)4\%“ë¨{a¿qGüÇlpkëhM†ooMû7õƒ I ©ŸF—t_cŠU)ÆKcúôu¥ºfEÙRr•4K.ù‹“–,É®+Ê·$wâ× ±©âL]²¹ªL¢0}BsU©„².I“PÎS—Ì[ÒtUÍÐ-k¯ô ¿h–ª[î%ABÉ)÷’ Kò"uIš„þô‰ácç|fÿâr/‚Dlú¥¸ùãJ“,ùÉ\bÄ}”‰lLvô†²1ICr“>í…ÆäÛO=1HcúýU·ú9ÇBËúTS½jB‘ÃÉŸ.rhy•¾ùÝCg-~EG×ÌůXj%QOLz^ 67œéJ:Òªó›•Sœé+nŽF]æ êÀ³É%-ÉRÒr0"óC$-9sÐIK.å’Þ  -/‡Ê´$iI™–,—B‰„¦1é°ÔÑXÊî³M"¡ŠR¢Ù„qvXê©J¹„¦+}ý[kª8;,å0iæ8½ÙO¹—Jçþß ŽÒ¡Æt¡’éÏ?ÞpŸyKr˜ž|ö%iLãf½${é¾R6¦ÙK½Ò˜>½û½ËÆÔŽ'#OüÙOÕ{ºœ7ôväÀ Ò˜lôMä5ô6úÙ ¦£iŒøðl˜øñéë5L|ÿä5áéäªàäií»ß×gÌ]±vÓ;˜L=³Qm@€ ¤‘S£Òë:)ӯϸ 'g{%´Æ7tqZžå|u0,(‡iàÝóìâTC Ò˜œºÖò0Y’`=ÔNÎ]ž[6¦{† ]ûÜôwWÌ(hžvŒ'ä]ÃlLz–oùæÈºåÑm ¡hðÄ¥²Ö µþôæ’›põ£/X&—Í:”0Ìec:ã7g©—¾±¤:37±ƒrO`؉ÁmÂ×7ôú§”/@è<4¦8Æ\™v¾²‡$ $¡1ŸOM_,©öp½Ð*vúsUùÞ’=Ie9_FN|^fÅý·´ÃЉó/¹Êt%›¥ÊŠô K¹Tv'Vl—2qø÷+bh¸W~ãÛ‡H“Ðlq,±|›t¥+o¹ß&§’,1åùuÒ'®¼ù~?Ï‹2¼(ý’å^šøÜËv])5BÿJc?g­nÓ?0z¶æ§ ®4‡'óí¥à Ô›“Êe`j˜~)d5eTc’äIáüC©YIOàí¶Ûnú¾½|*É#³—û4¦+ouù¢ úôðïë'Lª¥"•'}ó>*KV<0tPÙŸJ¡¤#êÔsêß?\=DÇØu· Þ9;xGËîHsùÍüIå-¹?o6ZAQš¥glС¨#SE+<9c™9-wâiîØsÒ’æ‰Sѱ'oI“‡NZÒ1&“Iù–tdÊ[:録u4îýù/k*G›3îÁ±slÂ8Ë„VN‰V:&U,1š~ü³SuLêàTâ%•ÒÁhL²—†>8Qº’¼%›9î—§]ø£Ÿž¢ÙK]v‹~qÚ…_;ð @cZ$™¤JSÚùAñR Å‹‡õ>m&“4&)>*µe&]¢wæ¥îzé•·–g¬¸¥:5k¤ø•‹Ëå¤ëgX”LJ¦“ sÙ”Î}ØEã-•‡¦½¬sŸHºŒýbâ;LÖFL¦Î“­B€ @ x,ÎKÌe2ü› ܳ6¸a§ÊÀäÔ9Lß=Ï.NUtq:|ÊKzöéÂ;æ§Ê§¿»g³CÜE}Ùazp”]™ª¼û> ƒóÒÚÒŽë¬J£ÓËœûü k^9e%nÙfEq½ÔžS‘·Tžñ°4„¢?m.€‹î|^y¬Õ?­\zß [éY;PãQóƒ(ÿY¸3Îàzéo¿ß–Ʊ@ Æ]ŠÆ”HQK’S\ع2-äAQ Fw]còUЍkñä3ÆëW4«U¸Ì/&-Y±LKVt (BŽ„•Ç'Ì}jær-ÈX:üÇ[Úó–,É‹¥\rîDpaøíCT”ÒEj„¬‰`θeÛl¶8•‡Ÿœ#ƒBÓÆóóÓdJèþû¡G§"_BY]´šR.ɈqÓ]O\|ù­&HrÔ±*$è}¾,GBv„œ»Òt¥æäqµ¤ˆ^YÔ˜ ¤ÌLÎD¦¦~ÔðÍò±ä9€þAåZ;GLœûû«‡è_—WiüÌåzGG—o,M_¸AÅY\Qr3;ÞL|tüs¤<õX*ã¦/³âìñ2›¯qê¼u*îðs ´t¦¤%Íà8Y%Pa–n4÷e91*R—nºû S—‚yÇαÇÔîxx’-È(4©pÄ”%7Ü9R3Ç™ºôÔì—žzö%;8å-Ùñ©å[Ò!úؤ%×Ý1rÈð N0¼÷‰Y·=0AÂÍ=O̲$i~ž´¶ØK½ÍÆä†¨LfzoøŸþ‰òZÇ4&\Öc}±T}fììW}æåGžVY;qÞköœ«¾©Œ˜±Þ’c)Ó°Ékî›´æÞ‰/Þ;áE&HVܯ¨Ã„É”­µ… @€@ª 0Xœêðô®r2™NúÍùÑ‹S]~–Õ•Û§—r0[‚çòÅéÒàâô±gÖéúT§÷éâtâ‹O=÷Zȉ:L˜L½ OÖvSD`r­7“iÎÒMn°Û†¶m¨M£(ÁHš{ ¬<ãá¶Çg¬`òK*Á(ʤ5æ¾Öã0Ug³Öƒp¾Ãd½“©½6B L‰®¤˜S\p¸2Mq×¥jm Ð}éècL®¨éNŒ{zñ?|z÷†ZEyx¡ŽVá»JΦ°g¨ü¢«T”ðÅŠ“–47œ” gPhaÚüõ*vK݉NŸP¦%MQe÷ÙUîztŠæ§²”K£Ÿ~A³TÓÆ•d ó%,ý’oJhr*™ʺtùÃôoi¢¤ ÷Òý£žUn_蜽ää‡ iL’ìzä›H“ôf© Oš6!)äwWÞZåÙáQ)úTST?Šy§t õxNôªèq:Ì|Q©²Üã*ù“2F=Á²·T:êBž~6€*Á q¥Iâì ´"yP%˜*®r(:iÉÜ ŽnA9áÝTŽ•c²'%ZÈ+¬NŒ¦'Ûªr£õ†‘)Û«.ù™™z•©êy;̓þØÙÌT_czw疫ʇŸüíÝ]*Mê´¿½â–r¿*­‡Ø<¾ÃT h;‹”¥ë¯5{oáC d‡SvbEM!P@hLqAçÊ´€‡D¡šÜu)P)œ\áåI2›bì´@cªgVÔÕ*VWpVB…û³Ú¦¨ö(*i–Bɖ̈ê ­‰@–¨øU²DéâÑ/54‰EÁÌq~â¥ffŽ«JéÒ·Ù¨2¤1Å©…Ó˜zŒJÂ1_<Ò§:öB’;lü…z‡PôýZŠR9ƒ™ŸWɬ”hqÙ•ëJ•|<µ¥¥ÀXª’–ÊG '-)Ù’ŸoiFõqhÇdï¼¥RîêÒŒºÔ¶9ãÎ4׺Æd–d&•Z/ N=zô^3/ë'™)ôùäþG÷jŒ50™ÝÒ3ôV{ôm›Ok9LáDèñ&S¡þ{Cc!@€ Ð) wŠlbÛ•Éô«ÓÏ÷’FW«!¥A yð/N[v˜B&“.¥UæÞÔ?Ô~]}í·bPØqw4 »d2¦êÓ•;ž÷æt«ã$…µ$7é[9‘REÉŸ|±GWªˆµS+ÕO°Tˆ‰äX²ÇË¢ÒR(ÓR]i©Wù–d6ò–Bgç&Œkè0i…¾jLõû›Æ§¢£«¶º†´z{üü丟^2èæ‡´2Q`Ïè[ø B—‡)ü¨k3“ãÞy÷o½­$ëC€ @è!À`q{Ãù ìwZÿPz`7ËyOz›I‚{—‡É9";Þz?þR:æê; M Œ7þ€o=øÈŸÄ¬Ð“ŽÌ²%¹²ÔÒ&ÕÐ’êÊIì«V”â,¥:GZYa±L<‘ìJÞ×3+\m]©Nš¥&3-…“-%:O\3°[§C“ŸÒh©¤l ˳ô¯>Õ“y*zSUrµÇFõ¯Šȳ,Mõ^2™.ºì&Ën“KÂäžs †‰½'q˜2y¢Ò€ @È4‹3¾&*/“éÄSÎë¹8õ2—/N#Ø´æ0¹ j=ä¦âÒ…³iö ùº ÖŸ2Hlºv»Ê¶ì8M4ˆUrH@&Óþß×?£cA¦Ü™·dR=̦÷-͘þµtM¼ ô@cJol¨ ð1S\'àÊ”C$ß’Иb\‹Ç'ΗÆÔدˆ8á©ßBBEå¹'B¥/©^J·×«JÝdKiõ–BþS&xiLJc#éÓƒŽøIƒã¤¦‡ä¿¹dKÍe5«˜yß"ó/ÚDŒ›ƒRšˆ±®¨T;µRYs©™`©JWòÂì¦Yj2'S‡4& ›Úv6&¥"IÿêÉQ³—ô²ø*–{É$µ¤÷Í]2™.øýžÀŒ»Ñ·I•ù5q˜šÉ:€ @€@û 0XÜ~¦iÜ¢L¦Ÿýú¼ª‹ÓZØôÅaò/¥m¶8{þGæ‡þ”¨ä_SG/ºíòœW‘ ÈdúÚ7š8w½ž =æ§²î‹ÃdМ¤ÐXÞqŠ’MçÔ9íO×o‹&Ú´@cJ{„¨ M).ü\™úà(@ã»®1Å«N4¦f]‹%µç}kRTªž–ªñÌTQc©lMÔœ!.&ÃKå.|“6B—WCcÊäa/I9lêéDz_ŸêØ‹Y!æ£ò´nõçwsZR%‰ŽiI®TùI ,¥’¨ÉiæTÁMõ\¥FºRNr,5:èÆÔÃC&Óù—Þ<äZkŒXp˜ºö@€ Ô À`qaº…L¦Ÿž|®qRCúâ0†" í,Àd:ð ñÏ­·<ÖÑÇÀúè0u¶ölH4¦4D:@u 1¡1qp—@SŒ/ñÈøyÒ˜šq-ÊfEdÒ7_¨ˆW)ì1•%’`©<£QkÓR¥[ZŠJhL™<HcR›Näÿ©O¥1ŬP'CRHHªäLòÒ&¹üIq)”Ü‘VûèòšÅ‰J1®R%»Rát¥zbS¦5&„2™ú_zC0ñŸ—¨ß‹Ã”É“•† @€@n 1å&”M4$0™N:×]œº Áº8Åaj‚«tƒ€L¦¯xÐSsÖ¹Ôãþ`QËsÉu£êìH4¦4D:@hL-ô®L[€ÆW2D )F¥xø©@cŠ®P-$5ÈóÒØ¦¨«RÔ5(‚ñ Wæ7ÖójM 1eèðí©ªiL¾QZÖ§ÿvøk®PWè«'úùïÇeN M¸X9ºjù€ö¸XØRªž®ö!7£ÆýaÄæóå{ͬkLêÜ2™ÎûÝ ¡àâ0eò E¥!@€ ' ç)šM´E&Ó '3i~ð\+8LMc•îL¦o4nöË¡Á.¦îÅ€=A »И²;j S\¹2-À!Pè&v]cª§R˜_ñГÏKcjì!õ.‘RUª—`’¢:E•«3+\IœÈ«Æ”É‚4&MÂeÓ±ùÅM…¨O¿wøkÍŒ’šù3’z¦TŒÕ’êúIu¥êtJ:Ø•Z:Ýä@c2“éÜßÞàζ8L™<=Qi@€ 䌃Å9 h͑ɤ«l¦&P±Jbd2í÷“`ç:*SbÁ`ÇÈ4¦lÅ‹ÚB `ИИ Öåi®G )F¥xpÜóÿ©Ý{éZôB¨¨'*yy^ÂsRåØXªib¡1eò!I3p•½Z^‘>ýÞa?vRQË áC¨Vš2KVæÊ¤`R0+%')TÈ¥Ô’¥ÔУ̇Æä›L8L™<7Qi@€ äSþbÚD‹œÉD¦&h±J2|“ ‡)™°Wd‘S£F!PhLhL…éì44B ë“2ÂÄÃÇÍýûؽyÅ¢®SQíQÔµ”Èó1(И2yšÆô“O¿ööõÊO~~ú—ö;ðÚ¡#z[®:"R¿fhãrõÐÇ) øÎ¡?R‰©ÀE—ßöéÝ÷X»é¿¼ñöû)<”“é§]´ï~_Ÿ1wE¨Â¡?ßy÷o)¬?U‚ @€rE)WáìEcd2ýøç§+áÍ=ŽŠ¿8Ýöæ{½Ø.«B }ÌdRG=ãÜñ½tÓο|øÑGíÛ3[‚2K)³¡£â(4¦¸(seZ„c ÈmìºÆ¨!×Â3+.¾|ÈÿñŸþsŒhQË©eQשHÐ"Èè® ýì´˜ÊÿúœK¥¤_Ø­PÇõСC¬~)H~ùçÙç¿ìù‡ÞäÏø§ÿç¿«Ä7ðØŸö˄Ƥcù¤ßœˆÃT¨s… @€@z 0XœÞØt¼fGœòÜò¦Žƒf} ð»;÷;âä=q˜ú€¯B `И pš l@cBcÊV¥¶í$Ð]iîܹ!×b¿¯àßgÿû~íSŸÞ=ÇjAú›&×eï}¾_Ï¿¿ ©‡a'¶?ZÁ§¨I Ù˜t€Œ\µÏÂWÆÆDuƒ @€Ú@€Áâ6@ÌÀ&výuW|-}“ ‡)-d}“ ‡©]€FC  hLM@b@ )hLhLIõ=ö›<4¦vH<½Uò·~ ]4&4&ôš@ 5&—ŠÉ%dr&S Ï;Éÿ¨S@€ @ ÓИ:M8Ûï?¥ÿð¥ÃVÄL&¦† X¡Cö¿wÿ-»¶ÄoÜL&¦…€ÍB ИòEÚÜ@cŠ -W¦¹íø4¬D ©R¨]cRH4šS6ï|wçŸÞ‹_‡OóD`Sÿo¤ê·ÑOÅä'dR%ÿò~ºªš*nT€ @è ‹;7›^óúÙ!c_«Ú,ܲÐþUr&—ŸI+XEeÌ~eû3µ§…! n¹×-{Y÷Ó¿êú×ïnyÙ–l^ØPx* 9 T@c¢G@)&€Æ®LSÜu©Z$­1éNt¼' ÑbëïæÉ%È\[¤»4¬ó‡}Ô†ÞØÖM]cj+L6d„R1ù ™’©{… @€ À`qÞûÀàùƒe‡ š5H •Ϥ¢äL~~&}ª”®Ii5ç<å íKõIõ=u×é¦ýèÑ*ÖMW’ä¤e-ôÛOÅÿ(]Í 6€@âИ€ê@cŠë\™rìä›@ÒS¾éÒº  1%Ÿ]C  ¢©˜B ™Ú°6@€ @ ·,î-±¬­ïüÙ!&‚襗öÆÞÔ¿–ŸIÖˆ ’¬µ’úfž€Ì$“íä3IT²ö˜c§—ô&}j†“½#ñÎÖç@ ŠH14¦¸àpešâ®KÕÚ@© ÙD  1¥1*Ô Í¨™Š‰„LÍdM@€ @ #,îÖmÔÙ!Z b5óíË̤w,Ž•5€ªƒ€D:›ôÐ9vÎÀÓ›ê“r˜¤7éS뢖<¬lh% ÐhL½¡Åº€@—  1ÅçÊ´ËÝ‘Ýu™S—³»n@cêiöøàÃ÷6¿3ÝÊÚ7‘½4}ÃÏÝ;o½·ºûd“€ @€š À`q2½Šùj‚ÓDBvˆ&éM’™¬™c_k‰šxA ›œZ眧jèM˦þiµrN^7+ɾ @cÊ@¨"ŠK).ö\™÷È(FËјŠç¶©€A§Éù$ðÎ_7HcÒÿVóÙí’/C¹$€Æ”˰Ò(ä…S\$¹2ÍK?§µ  1Ñ3rJ)§¥YÅ#€ÆT¼˜Ób@€ ¤˜ƒÅ)N[ª&9ÉæÞ2™É^˜ô¦™LöŽ26Yò¦¶`g#½% ®¨²ë¯»,y˜½\ŸtUÝØŸ±·{a}@ ÿИòcZ @cŠ W¦îÚT½ hLM@b•,@cÊbÔ¨3j@c¢[@€ @)"À`qŠ‚AU @è4¦¾ñãÛ€@G  1ÅáåÊ´£'N)ñPÎ@cê W¶ ®@cê:rv@€ Ô'À`1½€ Ü@cÊM(iòH).ª\™æ±ÏÓ¦hLô†œ@cÊi`iVñ 1/æ´€ @)&À`qŠƒCÕ @è4¦Þñbm@ «ИâpseÚÕÎÈκN©ëÈÙaw 1u‡3{@Ç  1u1;€ @€š'À`qó¬r·æ“k|aÛU¹k Êç6ž=mý1¹j:J©£xÙ8 Ð7hLqü¸2í[ïâÛi'€Æ”öQ¿  1µޝA mИÒê@€ B`°¸Àá¿cán3^9±ÀhzH¶{xùg3PQª¤„SJA5 ZИâúW¦5ù&€Æ”ïø¸uhL>MÏ4¦|Å“Ö@€ @ ã,ÎxûR}4¦¾Ðã»Ý!€ÆÔÎìù!€Æ”ŸXÒäS\P¹2Ía—§I4&ºCN  1å4°4«xИŠsZ @€ `°8ÅÁétÕИ:M˜í÷Sß²‹S±âMk!1hLqãÊ4cÝ™êö’S/±zV 1e%RÔ l~gºFŠWî )@€ @É`°8ù$V4¦Äг㦠 15Š!4&: bhLqÁáÊ4Å]—ªµS ²‰4@cJcT¨Z `Ó‹¯ß×Âwù  @€ 6`°¸Í@³´94¦,E«¨uEc*jäi7Z%€ÆÔ*9¾tSd®L»ÐÙE‚И„Ï®;I©“tÙ6ºHàýÞ’Éôîß¶vqŸì € @€@ ¸k 18ø™i:SfBEE!hL) Õ€j@cŠë\™rÔä›S¾ã[àÖ¡18ø4€ @€ Ð! wl6‹Æ”…(½ŽhLEï´½%€ÆÔ[b¬t‘Sl®L»ØÙUИ€Î.»A©”ÙÚK`ÿ{÷ß²kK{·ÉÖ @€ ´“ƒÅí¤™±m¡1e,`…¬.S!ÃN£!ÐhL}€ÇW!N@cŠ#Ì•i§ûÛO–S²üÙ{Ç 1u -†@g,ܲp¯[öZóúm^ÿÊgÒ¿ö§½Ü²´2ÂSgâÀV!@€ X ¸ƒ 18ø™i:SfBEE!hL) Õ€j@cŠë\™rÔä›S¾ã[àÖ¡18ø4=›úOé¯lLƒçž¾aúÑ­2hÖ —ŸIÞ’–Õ²~cû©øe³¹Ô€ @È&‹³·¶Ô©-ÙHG  1u/‡@  1å0¨4 ù!€ÆK®LóÓÓiI-hLô‹œ@cÊi`iV~ ÈLRQûä3IT²†*?“-HoÒ§f8Ù;×·õyA€ @è‹»Ç:u{BcJ]H¨P„è4¦Þñbm@ «ИâpseÚÕÎÈκN©ëÈÙaw 1u‡3{@Û(Ù’R.isZ°ùã\&-Ë^’Ã$½IŸZ®&- 1µ>‚ @€š$À`q“ ò¸S£š‡6-Ùz¥ì%+ÖüÝ=‹?áþœ¶þ˜<´6@í%0羯?°\.þìÇ¿Þí㫾ÒóÎÛ[Û»7¶@ ehLqè¸2m¹cñÅL@cÊD˜¨dï  1õž߀@¢\â%·àò3©^zsË®-²—ƾ8Öª©üL‰Ö—C€ @…$À`q!ÃnFc*pðSÝô×ß]¢ÎY³,Ûvcª«Nå DHT:ýëî`´ 9*‘±S@5  1Åu ®L9lòM)ßñ-pëИ |šžM•”~Iy˜”fÉZ IÌéM-Ø›šHÎ’6¹w²ÙVj @€ d–ƒÅ™ ]ß+ŽÆÔw†l¡C&¿|TTc¾ô“|ø^‡öÈf!lxììÚÓkK²Ý.jä‹S\<¹2ÍWo§5ahLô‰œ@cÊi`iV~ (»’Ê®¿îÒäq®•–Iy˜\î%™Lz‡TLùí´ € @é&À`qºãÓÑÚ¡1u/ï š ™HÅÔ¤|9'P3!©˜rušì@cŠ‹W¦ÙëÑÔ¸7ИzC‹u3D)CÁ¢ª€ @€ Œ`°8#êD5ј:A•m¶‹@(!©˜Ú–í@ ·¢ ™HÅ”Û`Ó0d•S\ä¸2Íj¿¦ÞÍ@cjŽkeŽSæBF…!@€ @©'À`qêCÔ¹ ¢1uŽ-[î;PB&R1õ)[€@Î „2‘Š)çñ¦yÈ$4¦¸°qešÉNM¥›&€ÆÔ4*VÌ4¦lÅ‹ÚB€ @€²@€Áâ,D©CuDcêX6Û..!©˜Ú…”í@ çü„L¤bÊy°i2I).l\™f²SSé¦  15гE)[ñ¢¶¨K`ó;Ó5Rüâë÷Á€ @€@ò,N>‰Õ)1ôì¸9.!©˜šÆZ(<—‰TL…ï €@:  1ÅÅ…+ÓtöZjÕ.hLí"ÉvRF)e¡:h•S«äø @€ Ð wjV6‰Æ”•H¹žJÈD*¦"wÚ^°„L¤bê58¾tƒSe®L»ÑÙGrИ’cÏž;J XÓ† .} 8ð¼ó΋_‡OsFଳΊoÑ7ÞØÑƒ°]—ÆtÅ8²1µ 'Û @€úF€Áâ¾ñËô·Ñ˜2¾‚T~óóžYvYAK3ÛH`ëÖ­mܛʷ·n½î¨,U˜ºBE"€Æm®L‹t,±­hLEŒz!Ú\,éÄO<èÃÏ»` +ç^0°§œ?ðß>üŸÿeïsÏ¿ØÊ9ÑÒÿâsú_|vrVÿgW£œyÞ€r9wÀ™^9ãÜ^¹èŒsÊå7ç\T³œ~öEÑrÚÙ–ËYžæ•SϺ0\μðÔ3/<¥§\pÊ™=å×g\P³œ|ÆAù_Î?ù7çŸ*§ŸÒéçÿªNéwÚù¥Ò?T~yZÿ œ.¿8µU9¥ÿ/N9OåÄZåç¿>¯fùÙ¯Ï ÊÉç†ÊOO>ו£ýÕÿ÷û?=é\•ÂåœN:ç„_ó÷ÿð™éÓ§§ÿ|0æÉ‡?»ç^ý/î—þªRC@€ @ ÿ,Ό붩ÀÁÏFÓß{ï½£Ž:ê_÷ù’žxÌF©e:èIH ¾-Y²$Õ¡]%@ô»Š›A½$€ÆŒ+Ó^v'VÏ4¦ŒŒê6K pÓ·Þ±ùõ¿egP6å]Wn¸õŽsÂÆïºòÚŽwƒ²]åÏ*¯zå•möˆ­»\Y¿uWP¶e]¹¼³nó;/{eí¦w\yiÓÛAÙ”5®¼öö‹åò§_ûÓêW{ʪWÿ´ê+o­teÃ[+¼²|ý[Ë׿ie™ÊºrYºîÍ ¼¬òÆ ^Y²ö +‹ƒòúâ—‚²È•5¯/ì);¼ØS濸sþêr™·zGPVåy¯Ì]¹£T¶«<§²¢\æ¬Ø”åA™½|›•g—õ”Y˶ÍZª²Ue¦+/lá•éK¶¸òÌ’-Ï,.—§oyzñæ§eš+ 7Oí)›†›û÷ÿ°û”›&»2Ó¤rÙ8iþƉó6îý…ýÒ¯1Mœ8ñ[ß=dÞŠ-rÑtQÝì €õ @€ tˆƒÅ›…Í¢1e!JÅ­£9L·ÝûøøK¾¸ï×0™ŠÛzÙr ¸é‰ÐY‹Öi߯a2õ^æW'ú™! €@Þ  1ÅE˜+Ó¼÷ÿ¢·©è= ·í/œÆ$Qɤ¥*ž®dË7ÜhL1êR 1…ì¥mî­À$™És˜z¦ZS 0µßa 4¦ÚSIc*;L=Óš×yÓÂÃTјæ­Þé4¦^8L%É9L5¦¶Îô5¦%[«4¦ŠÃ$™©¦Æä9L›§,ŒhLó7Mö¦Ió²¡1•¦Cç­Ü„ï¥×•: “)·çl@€ ¬`°8+‘ê@=ј:•M¶‡€9LCî¡Gû4ŠòäôÅ_ü2&S{Øæ{+%‹åBë63®S·ÁdÊwÄýÖýâÄš–B »ИИ²Û{©y_  1õ• ßO)ÂiL×ßrGÙR²4KåLKådK×ß|»4&?åRÔ[² L¾º¤åZé—”‡)’©J`zÇe`êE¦J&? ÓÊ^åajà0LU*¦Ã´¦q*¦ZSŠ)ÈÃTIÅTÎÃÔG‡é…j‡)œŠiK|*&%a gcªÖ˜”Š)ýÙ˜‡é{‡Î_µÕFR;åÍÒ”˜L)=éR-@€ „SA]«™hL~ª›nÓÐûF(I¹FQ”\iÈÇ=ƒÉ”ꨥ¡rd;õÌ •ÞÞßÔm¦/ÀdJCdºQ‡ úgýn f€@_ 1¡1õ¥ÿðÝl@cÊvü¨}]…Ó˜®»ùö°¥äæ‰Ûög}úßœš-.–"ÞRH]ªš<.b/U§_*ÙK•)䚘4£\+ÉUæ’+O$˜ìÚÛ›N®y˜4¯\ãéäÊsÉ5;ÜìvN'q˜ùÓÉ©˜œÆTžQ®V*¦”kLæ0-XµÕI‘Ƥèœt:&§~@€ @ 9hLɱO|ÏhL‰‡€ D 8‡iYi|Ìž+eß9öéÅ_ '¦³XªºMð áÎg濬nCN¦|w/úo–&1$6 ½*údäÊwèi2G )s– ·SÛP²¡t(¢Æµ”Ê –¶ýùÚ@c:>”i©ÇXRÖ¥-=eÝå[²d]R‘®äoæ¸`¹&í¥SÈU20­zå-? Ó / Óò o-_¯ò¦Ê2+ëÊ¥žÃT-0E’0•‡r‚ ³R‰$ajv.¹fó0ùӳ˶ÍRYª²Ue¦•ðtr[jN'WšK®)‡©Jc 9Lóƒ¸ÒÄp×ÜhL¾«dËž±T’–jå[ R.Uϧ.m|{Íko¿X.’ºk/ý©Sȵ 0­m”„©áDr«wÌ[µ£Ö\rÛËsÉ­Øþ\©´8—\Éašá•*):—ÜâÍ¡éä¦.ìIÅdy˜¬<0nîßÿÃîA6¦ù›&•ËÆIžÃdÙ˜1Þ—ÒÔ…?!T¦mõFRæ­"Òï´þ-˜LG}ô^{íÕ|uŨ¯hýzßÚÿýCWÝÑwÜh—>êß¿¿6hÛä@€ d’ƒÅ™ [{*ÆÔŽl¥MœÃ<û¤bê™QÎZëI0kš²è ÿ㫽2™Ü0ˆ†2ôš>}º«²½ãþTzõ½AÚ¦vêß¶íÈßÅØ±ckšÍTFmѰLTF‰o‚ ­¦ >¼æwUÿ~¥—Z}Ø«-˜ÅRî6ÞŒr=ÝfõŽ©óÖªÛôÖdR-pöRóU±zñНsÃ<n…@+Û¾ì¥xí¶ÛnÚ¯{§áÖšh›õw¤î¤wj91}#Z™nö–E߈ZŸ÷O Z%ÿHÑiȈªjì€O}EËÍæÑutÆpS V™f6ÕLLj_Çê]§Þ™Su³1äƾׄ-@ £ИâÇ•iF»5Õn’S“ X-k §1]sãíÕNR•¢¤Oð“ã¨T3Ç’Ë·•–ÖÚlqÞ„qUsÆ5R—Ê3ÇÕɽ´Ò˽¤–§•[È'Ì9€ @H‹S†d*Æ” wö!`Ó÷, ©õ¤bÒ™FÃüœ:%)H">bò‚æM&7H¢*¡{í÷ÐЊÙð3â¸1KªdÚ˜‰ ƒX~7¨â7KoZ{Sb‡­¬e{ß½¸¬*ZpY%U™Ð¸M4‹’ÖÑ·¢AhÇš©mÊSÑún;n5UÏÆ‘lDÈjr5¬-Ú‚Ó³ïËÅrvà0…R1i(µÜmzì· ýüäçzg2EžšñrÃhÁšè\'@äÍ1´¾g©˜ÜíSS^ô©“ÉÜ ‹ ¹eú3´}û®þ…”,÷‘{BÒ*o«…ý:‡z—*:4\£:Ú[b¢_<ætîco£oÌëÒ²?ò)Ô~ú%}d«Y«C[ÇßÎZÁ dúbÍsŽmÊÎö ¹ƒ–Íq¶êÙ¦¬Úþ€°>r'+;ÒݩƣܦBY‡7Î8Xý•̵ËÎ]Ö |¶/÷2›3ñ“€@âИâBÀ•iâ” t”SGñ²ñäOcºa¨?;Xhùê†~ÿÇÇW)J‘ìJJ°α¤4KU™–l¶¸Š´ôÚŸä*ùe•ò-YyÅÊ[=sÆÕR—*öÒ›ºr¶¢§Çô ˆ•žÜKAZìªÜK5ì¥hú%iL=öRp%Ö9I>ÍìåÛÊÅËÀÔ”ÀT„I ™žYÜSž^¼åéÈDrÓª¦ž‰ä4—œ9LšH®¢1•¦y%-EKª&•s“{LAžª?'à"ü‹Sš5™t­hãhî¡]Ú@’7é:Ù].Úµ·{ÐÇ.ueëòQÛ;ZͶàžãqíîj9$-ÙøHrçFö @€ ôƒÅ}ã—éo£1e:|¹©| ‡ÉϪRÒüœ:Jh-I£(#&-øü—šš]ÎÝ;ÞD·q»%oC%zYl#¬q»7ïŒKGäËCQWÃ6ë†n´`6ƒ¶£•m<ÇÒ˜y`÷øM°›šÚJ3’™aõ·aÛ»Û íÚÏcëë[p5Qóý=úGÇÕ\¡GQªÊ«Tž.<1\EWªi,Õ”–ÊSÅyù–Nš3®¬.Õ™6®ñÌqmµ—bÒ/ÕžB®Õ LO/Ú<­Rz%0˜æo6&“s˜–¯[ß(£Ô~ˆp‡ùdþHÊŒ’ö³X“É¿¶Ëf{¢Å`Òµ«]HÛÕ¦?dæ.­môÊ¥>Övì+~êi» ¶Çí9E7D‚ÔÓ_š@€ P$ )Ú¡¶¢18øÉ7ݦۇ Æß4„RÊÃq˜^/O'WÿI0 ¡<üÔ¼Ï}q¿uë××kUHcòWóµ †(]Æ@l ÅnÕkœÄ†D|WÃÌ$}×ÒóÔ›TÎFlÌEð-³o¹)·,㎭l;µ ÖÔ˜šЉãh_6ó”¹NVð¨˜ÆdµgÛ¬’N]Rµý æ’êCÅrÖ…®Û”2ñx“?¡X¹Û”ß*©˜d¿éBu›q3_üÜ—ö‹ÏÉ$\¾fÑqñÒ§¡PšÌd£gÎA1P½Õ˜|¼¾vfѱ­¹Îé"Õ˜b3ÔFBÉn³Ö™ýNXsPÑú†ë]nƒ55¦õ–f£_'WOôg5ˆ~HcòÃáL;„}—+Ç?~R9ÿðwYú'sÈÜËfy³ƒ44'¦ß[L³s'+7®ë¶ìöå¶ýÈl­ÐX±ÚåF•CzVè¬b[Žê€I@Ø/'€Æ®Lï T £И:Š—'G ×“Ë(›\[ßó‰'ž8èº!«^1÷¨FѧGÿð¸ÊGoÕ“ä'¹RÊ«T/»’.z=])7ñË“O/d”Š´ôôÜÕi©<Â2í¹UyfìÔùrV¢ÞRìK£&Ï[Ì5¦²SÅŸ6.”xIóÇ)ëÒˆ‰sg,Úàr/M_¸A¥ôt‘+•ÜK½O¿t×£Sf-Ý6yîË*Á“mV¼ôKÃÇα ~W†™ýÌ’-Ï,.—§o ʢ;½$),0-ìIÂ䦫d` ’0©X²¥LhLžÃô5dô³F=»Á¢¿¨4ŒbÁUg½°Õ쉙ë]*&QI¡ûÙÉçÖœ]Ξtñ0Kamï¸kE´¬—=J¨ut]m_´uì)1½lÂ>µËW½ì"Üå[²+swjû"Së§9¾ @€ ”`°8%H¢hLIPgŸç0é1°Àa*=&‡IC@å„:¥Q”© 7)¹ÆÁlÈkÔ¬ 5ŸÓÔƒO>c2¹¡’hFÐȆ³vܘ‰qßµD#j…콩ђaà˜¸7&cÙtLnpã3ö|šîôÛG6Èãç³±zº4ìFþ0Ž ÙWlâ³he¬ ²lÉróزÛWçòë4lŽ[!d±Œž½Áw˜FÎ\?{ùvJµ¤õê6ÊLoÝæ©ç^µ ^6ª©Á·±3V«ÛĘL_÷ Å+J5nf¡ùí²ïúý-:¸gý*Ê9wÛ‹m\Ñ´=šSRsûÖ ýràüÍêS»›`[ˆ*º¾áïÔÜWƒè-¡èë¤1iÞ¦ž,\Î`{qçäýèŸûj)Û¶æ£ïHF?]Óü@Ô‹ˆñÑËé_¡cÙmÍEÊu wB¨ S4¡ÍEÖV EÁ‚ng½œÓÚ—ë«¡j¸tSwýéêot{·úX9×d·Yǧùƒ5!WhLq‘åÊ4¯ýžv4&zBf „¼£ÐŸ 4&ýGÐ)ív™}æ#CdJÓmÎ=Š. ºö¶£~x\½Jf&…Je28 Ž„]% —œÙÿ’=>ûÿ³ræy—hôäŠëoÿü—¾b%IY÷æ·¾w˜ýyôN0WÉ•£~t‚[ù[ß;´’o©Îlq/½®”K~֥ᣦ}ó»‡ÖP—ê'^úÜö=åì‹5ˆc唳.V)9Lá™ãâ&+Íï™4º¢ûÌ{êªþ¤3.R LºÎ¿óáÉÿúù/;IöÒíMú×}¾lSI` ì¥Ó‚)°—œÀÔiÎ}»´£‡€9L WouI˜Žºd¢•®˜vàÙcî|jµs˜.¹gÞÀ{æ#)+¶ß6zåg9|À„ÃŒ|úzKÅ$Œf}ýô¤Ú&SGÛÂÆ!@€ `°¸@Á7©ÀÁO²éæ0 ½od9åy%•µžÓ(J0)XIGx`ÊKGœ`2ŠF‡Ž¸xÂá¥rí£/„Ÿ[¤pÜÜøœLI¶™}ÇШJ/Y,§žu¡ßm4àæ,–SnœuäÀ‰nðíøË§>úÌË)ÕàÛÙ·Î.¼ƒoe‡©2ø6zz“©‰z•WÑh¾Pü,VÍo¡ˆkö&úÊÂåG_êŒá‹} nã¬1öø¨¢Ü§Zôû];£sÑ/bìh3 Ð4¦8l\™¶Ô©øRf 1e&TT´Š€M¿îÞ2Þ—ïëjL2ÜÍ»7ÉRȺ|¶)™°¼·Ñ–Ætùµ·ÕV‘‚DÓo]~ÍmGþð¸’T[Kò3*•Ó)YR¥êÉà¤+Ùó^Gÿø„›ïxÈt%{ükÏîùܲ×t%ü›ó.QtýPùIæ-ÉX3e¾®‘¬hY++ÝÎâÒëb=]¤k3+z̨\–—Ó&ë©#WjÚKR—zr/IcúÍE*ººsÅÔ¥;žd“K¿$é_öùrmiaU¦)^ú¥) 6E20Õ˜úª1ébXÿõéðoƒ&ur˜*]HýDÒzLÐz‚& ½Y¦“¯Ÿ©kéwϳ0iîîñ/êû–Q˹lŠKÅTÒ˜ÙëL¦ÞžAX€ @hžƒÅͳÊÝšhL¹ iTq˜F¸ÇÀ\6¢HC1‡é·÷Î×àI 1•ÄNº~ÆÅwÏÓ¼`zjî€3Ç”sêT? ¦!”ÆÍÝ;vv¹ *`õä¡îôc+3™Ãê6Ò˜Ìb‘Ãôëf™Å2nΫ’ÞÔyúe ¾Mxþ5=@8máfu›3oyö÷úÁ7=@¨±Ê'žY¥n?»\“aqO“{¦IbÁs§­F_g _|´èß>nÕƒèÛã£×=¾ôØ?N-¥bÚzØ€ñM_ß¹è7ÛdÖƒŠM).þ\™ûèÈë;|«:ÿialfa§1¹ŒÂª‹›^¹®Æ¤/ÛôÆÑ †õü‡¥ ÍÜKÓ¯Öœ‡´þM}zäŽ3 )¦ôhIÎO*[J¨dÅ™I7Ýñt¥»§w4=œ\%³”ݳ¬?g/}mŸ/}eÊs+u…leÊœ•Ò˜î>Ö¤¥g_xÕ’-ý´ßéû|ñ+*Gþð]G)åÒ‘?<~÷ÜSÿîóÅ}-÷ÒÐÆøÝC9íÀï*ÁåWùÜ÷=ð;‡¨h˜æþS¥+iYÿ1ÕŸ3Î4¦À[*©Kr˜iÅö½¿°ï7¾}ˆŠvôÈSsä-ðíCTôþÞŸßW×lZ¾åžQÁÅÛ²mzç¡qs.¹bðÞŸÿò׿u°’0 ¼b°’ëjAêÒ¯~s‘Šô‘ŠÔ%³—nxÒgöø/J¿¤²ÿ7–½4ô¡‰Æ´hóE¼E zSÿ6ž?NÓü L JI`*ÍW³´0©Üö§†þû{WÂV†Ø¡!p˜”LkÕÖ’÷¦›UPÒš*ÎFßî|jÕñƒ¦)Äcç¼rÈer˜‚Ñ·RFëÙ¥XèZZÃ(¿¼fºä0—ŠÉL/‘9þWçÔœ]®C-b³€ @€@0X\ `‡›ŠÆTàà'Ótç0U#ìEÑóE)eÓy]#f—Ü;ÿþÉ/IF±Ñ0{L£(N]«„:Êîæ³tà ¡lÒÒÞ_ØoÝúõÉ´½¶@ÀD+ud¦Àa:óÂÊäƒ=ÝFSÈaÒàÛíãV›´Fçá§×z³nS·Q>ž«^RJ'ßÓm489rÚJu›¶˜L-(ôWúý'<ñÑO?fö+Ò˜ÜIæ“ÓùAÓ˜Ùˆ~¡û‡@  1Å+ÓtQªÐA¼UÝÁj³ébÐ|ÁÊ©ägc2Ê©$=Éf—k0©\Hc²Mze¬4¦Ë®\WBZ÷¦>•Æä†<äŽ8-É™I¡yߢºtJZ‡ô³_ýæ7ç^"{éòë†J]’«d –õ´T$3–.¿v¨Ö”ŸJ³tÃеÎÿ¸§æ†»ìÚ¡ºpºìÚ!ò“ÌU’·tÁo¯zà‰iR‹f,~E—ÓÒ˜FN|^ Güàø¡÷¾äTÙKãg.× Ón&‰;ûâko{@®Òa£5XóäŒà£ž ãVn×Gæ-YÊ%Ó˜ôPšV»ç±)Ö9öÄÓN>sÀ­÷ŒÒ‚å^’´t÷£Sn¾gÔß:DÒÌè§_½¤ øC>nÔ´d/Ùlqò5¦ïù“Ÿj¹—ä-)ñ’Š4&˽tðQÇžyá !Óã“—|zÿò䬗4rtÑe·|í›Û#MºJt%’~©±ÀÔB6& Ló¦NjLæ0Í_¹Õu0ëWê-zS9aÐ4 LºxÖè›kÙè[YcZ ÀÙó@Êä§ {f]p-]€ ¸iÎ`2eôlFµ!@€ v §=B¬Sá²és˜†Ü;Âݹ¡9Ke=²¤1©¬KÙ¬{æe™(¾Ãô«ëfhðäêG_Í e“= ¦!L¦Œõ>_d©%3Éa:åÌ Ý£ƒ6‹œ ¾Ic:å†Yž5æÊ[·qƒo¦1¹GÌX/‹EEƒœ=.ìé6˜LÉt›>DßÎ&>†¢¯‘XÿñÑk}A§Ž3n~–è'eö xИâºW¦,ù&€Æ”ïøæºu!Iy”ôŽ2ÑZ£{§1Ùw4£\FØÓÕƒc<$}zÄŽ ­àkI —KŠRy8—WI £§Ì“¨ô`I]2W©¼\J°¤¢K#eWºàwWk¡<7\)c­ÊÄgW\vÍ)J§3PEF‘–U´ dKJ¹¤e›$îüß^uü/NS¾%}$¯E™–,ß’þ}~e ¹XѧzÇÊn»íöèSϹ ã”]ɼ%]ËXRÑÂgþqOe÷‘#cIïhA¹—N:s€Ô%ÉIw=2YÆŒd/óóSÏp…ì% ýœ5àŠŸüüT—oI–’.ê,“¬šîÙïô‹”cI–ÒЇ&)÷’ì%Sm®¿s¤Þ7iÈð‰ZA V>½û黽ä235™é¹›Ï©!0ÙÈùŸüøúÛ[9á¿ó»‡Ì[¹¥gÜ­4†b=GÒ#f®³ éG,«LÊL¨TLß5Ï9L…;ž\uÀ™£COƒÙ&S®Oþ4€ @‰`°8QüÉî)Yþ…Ú»9L·Ýû¸sP Å¢”Ü4Š¢Yä4ŠŒž­ÚñhIcr)Ul¼ëÉç^)=V53ÔÔÒCtîI°“ià~íbk! Ÿ!—É_(ef*9LÔë6˜~}ÃLu »=>}MA¨o+·.iÚZë6åY_ØúûûüäSüƒ<ñ•‘·²Étî¾if»‡%sRÉ>DD 1Mˆ:LŠ~ 1yÚЫ²à_zß?ÑÏI/*ÚÁ%ùW–  1ÅE+Ó,÷mêÞ˜ScF¬‘RÑlLª¨æ…“Œ¤…^hLn"9M3—Ñ„LÒ˜þpõàIŸñýc+*REHZûº’'ùNRÍåžDJÝDïS•,¥É³W*©Ò¨Éó¤1•D¥×‡zZ9–FM~þŽƘ®d–’-«üáš!§ž3ОùP1]éÔ³ÿËÓ•fÉʈ sm†8]K[Ñòï¯"™I—Ö÷=|dÿÊq±©â$-Icº÷ñ)®Xâ%S—œ·:n†©KV¼Q”`„M£(K±Q iEc)–ReðèÓn6E u&:3”ÿ$˜|”}ÿy¯%ç~éÃë¿É}ú´¨'²œþ‰;ûÄã¢qàò p¤ÛÈV ,–Õ;¯xpqÏ„+ƒTiLM[kƒoW?RÎà¥Éæ½h¼›…Ðeð²Á·±Ï¾¼ß7þíž_øþußI;´Üx}ˆ¾1ÜЫ3Ø}u {|TY¸îzjµ ½^pûÜ nŽèÓ·³Màì¿ &ßä•ehLhLYî¿Ô½oИúÆo'HÀiLšnúôéVÍ7§—z¡1iC˜ô9Pz%ؤ–w-é÷WÝZÓ7²7õéáß?6fs’übfI­²sÒìR—†šfÀðËÓµ IÓÀÙ;ʱ4ô1zGSÂÍXôŠþpõ“–TÆÏZ!ßHN’ÆYÆÏZ®yâN=ûâ¡ÃFËI²âôNÿK®²dK.ÓÒá?8^ßzlüsòZ$*é#Ù-úWËZ8ìûÇ;ðÊo|ûß]y›¤¥{›¤Y*KV”cIÆ’þÕõØ•·Ü¯å‡žœ£y¾µ ‹s%^:錋T$-iˆGӯ飛î~B—mO”–¿þ­ƒuýfÒÒ„9k5gÜvª¦Ó0ÍWÒ˜.TùñOOўͧôK–ué±IK”²[3Ç]vý·•&=÷¦?0AC§_pù×<(x¢¥\6j,É=ÛÔ¤ºä¯Ö¤Æôàˆñk7½ÓåIåüÎ!s—ovö’ÍÅôœ”„é±é/+ ú á‹ƒIÙKÃ( ¨&Å+H‹uÙ”«^¢@\ù𤈪=Dè?d“ÊÉaRëT0™Z>·ðE@€ @ L©À}©ÀÁO éf2=h¾¬Ù:>Dß4&7”¹ME§ýÎcÛ]ãWK|´Ai»^ñÐb¢ßz°øfHaDcJC úP4¦8x\™ö¡kñÕ @cÊ@¨bmNc’ä$J»J/-Xr¥“t%ÙO¶á±cÇj.9}3£“]^zå­õÅ£×õ©4¦êvº)Þz* “\æ¤z × ~àw•Ÿ$‡É䤑Ÿ×Lpîy«wJNúÜ÷UÑ‚ sEÃ+C†–Ëb³¿röÅ6àréUC¾Qzó”³.Öà‹Œ¥ÃpœeZÒ5ÕàûFþýãl’8%^’·¤kl9LR—TŽ=ñ4Ó•øö!š?Nÿ>üäK³äŠì¥½?¿¯„$å[ºòæavY.9IÿjXçÁ±s4UœŒ%½£rèÑÇ)åÒY 2u风½ñ®‘ºz·¬KÊ®¤¢ÄKúW“šÿ.Ú|Æ…ƒTd/٧ʺôËÓ.<ã‚A÷zV _ûæA•~qÚ…nî}bÖAG+{I“Þ”ÌôoGxKV*™™[°—z;©œiLV$3ýû{ôd¥vb‡Î='NTôŸ[¶Éõ.KÍ¥Ñ=fEÃ(£fm°a…õ²û]6l‘"%«L‰Ðe2vÑx%µ~xÚËÁµ´9LÕÓÉ9‡ “©Cqd³€ @((‹ ø ÙhL~2M/›Lc¦÷ØK•ìæz8pììW4–b“†Ë4ò«ëf¸IÁ¤1IGÐÊMO,ïq˜*ÓÉùó‚9‡É†PÔTL¦dâÝä^}‘¥Z`r¨Œ—í%—ÿøË§º‰äf,ÙrܧÊ~3õMG™xlðíæ'–ÿä²)²Xä0•’ñ„ 9L˜LM†® «õ!úcç¼â†^ƒÑ×ëfXò6EÿØ?Nµ¡rEÿÂ;æêÔ¡èWR1ý6ÄM$F)1ômÛ1SJ®LÛÖÑØP*  1¥2,TªRÜjÊÀ$ I/KŤW©™dh»4qôéaGSs…à:6T*i“\þ$A~R©ì¨*ž¥dõK0°*Û5Ôâ&†3KÉ•ò¬pöTPez8óZB%d,XYfsÉÙ´P× ²Ê£(¡2 åçar£C˜LiïŒ&²Ô˜\å5\ü»+oõ»˜Ì{«ÑmJƒo64|ó ¬é0a2u©Û´;úN|´¡W¢ß¥8²›®@cêêŽí)-W¦ëxl8:|«:m¤…$P8éwW”¯KkºGúTSi°Ã•j)¤%•´’P©+'9i©†¥<æŠK­Ô²®dˆÄJKµ¼¥’´Ôo)¬.U{K–e7F]ªØKåÄK}É·Ô)ÉÎ’™tU\ýzeæØÉýžyY‰k¾æ L¦oüì’ÞÐ[Àd²ZÏè[èBzqÈaêÉhíÏ%çÀa2ò‡€FC€ @ ,îÔ¬l)+‘ÊY=Íd>ú÷è ˜z+¢Øã|u¦p6ëzSÍœL‹ï¤A¡—Æ9ðý׿…ÓõQ΀§½9¯ô§‹©­L¦ß^qK¸ÛD¦Òƒ =Ý&þ‡iÉÂÃÏÿõøþ?ŠVID]%í`3Q¿´F¿¦ÇVï¼!Ò- &g">T2uИR’^W)W¦½îP|!SИ2.*Û<ÂiL¿tKŒf¤O=ú˜ÆR4‹Rm3©ü¼W E©2\HT*?âãò*y©•jfWª§+U§YŠË´Ôš´ ÕHýçO¯®!P]&ÐLôCâcL üøè»§Iýè×;oÈikm0¹ËÙ] 1e?ŠhLq1äÊ4û=œÄ@c¢ä”@á4¦ÊitÖ¶à}zèQÇÔ›ÐÍ·‘™“LK*=¦S³¿UÏWWTª“Z©œƒ§gV¸]©æÜp5Œ¥Êìc5fˆ«ž$®-Þ’•Kç'Œkè0i…¶kLzzæÑ£÷²ìôìÜ(•–í}{OÅ liý©4NõÎ3£Æ<)“iú¢×\"kKÂT~¬z¥êBº¤ŽMRFëy H3Ó–7þòáGá‘”œži @€ Ð w†k&¶ŠÆ”‰0åµ’o¼ùæ~_;àþ‘O—GáJy¬«+¥²ž±¤4—œ=¤WžK®‡IRÂ;ïþM0ÿöî.¹J² êqi™ì™·è`‘††lŒy%ñù“ã~:ðò›ktKÂäw›ª)]·)'A·X$0Ývìwd2mÚü†‹¾ËÀ¤þ#Ñ÷ÝXbâ”òZ¦¢_cÊÞEß9LÛÞ|ÏH†Îõ“Cï»3LÌ`r^#E»:E©Sd»·]4¦8Ö\™v¯'²§$ 1%A}v@á4&]ŽÆhFúTS¼ŠT#a’Ÿ<)b&INŠó“4’k)Å»J½Ð•‚š`Êöhy&b,5#-M‹ÌÍ·ÔÐ[êNÊ¥Ÿ©í“®*mdJCWÊú«[Ùs3.K“-è}-ØûZÖ;ZˆI-“éëß:ø™…¯–‡ÞJc(îI ˜Ñ·Ò }8L]8² @€ @À#À`q»SƒŸŠ¦›Ét߈iö XÍÇÀœÃ4mÑæ©¥1®ò09‡Éš­ IHrC=zǬ&ÓS4jdƒEúWE¶ŠÖ”ˆ bcD¼’% —åâËoîñÞ*“KÂT_}+?@Ø0Ï‚gçIcZ=¾‹¾úƒº‡º ÚP¡õ ½¯Õ¬{øcŒÉRÊëÞ»}Ó˜œÃ:oÔL7šLÎk¤hWG 1ukW7ŠÆ‡›+Ó®vFvÖuhL]GλC ˆ“yE5‹4¦CŽ<&ôQpíÚZ) ”4,ABªŒJUI•¢R)ïŽ+ÁÓcÑRzž¬÷ÆRðð™+Ä©*½•–”u©V¾¥Ä½¥ÒÔvÉ¥\²gì4ab“±Ò;ƒ°ge´Ž]ˆÚÑ®7-]S½—™LÓ¼Zî•Ð[¬M>³¨y£oäaêι”½@€ @Õ,.p@c*pðÓÒt3™î}|Ú¬¥åT:å$å–„ÉFQ*C(Áƒy½ŸK.ä0©å.å’ ÙCn–iɆ†ì‘6K¼¤5"äÒ5iMû¯d .ËoŽë6‹Ë#o¾úfž &õiLž|˜Ú¨4<–¦Ýì%³”Ô ôŽËée]ÅŸiÝ­£Ý£ýj}­üìhyè5ýf ¶šSô¼L7z5˜ÜQ\l¸ÆºR­‰áJ‰|4‚“Gi)ªIµ]c2WIn|ÊÄ&˺ä†ì<ÿÁ;-ëI¬†§™Lûó Éó6ØÐ[)âe­»Êè›Ë}uü¯Î9ãÜñ£o[ÞøË‡}Ôpï¬@€ @ ) 7…)Ÿ+¡1å3®l•™Lw?:­Îc`ÁDrír˜Ül6#˜hiÇ ™âr[öýkùx´¦û(ƒ˜sXåÀeùÃMUݦÎà› 66é0Ébq®’ú† jÌÐÍ%g“%a²¹äBFÆçqÏa$’hRç¢m‹o½Áäèy£…Áä$(²Ï¬@cÊZÄ¢õEcŠ‹!W¦Ùïá´ Žý#§ §1ÓD UÞѧҘzVˆ¸Gþ„n¶\{Z·zï/iEÉÍd·®c)…E¥F©•‚LK5²+Y²¥º’¥Ñî)¥¹áj¤YR¾¥tgZj&·S‡4&h0Kɼӈ•eZ’ÆdZÙ¨–†*´‚%mj~ÄÊL¦IÏo°ÄZ6‹œ{Ì‚Pp˜rzö¦Y€ @H7‹ÓŸŽÖ©£xÙx¯˜Étç#SŸ®Ì"g£(öüž†¿,§¸ "µœ‡IUr°iÈF~lPH¹LKúÓžj3=Åì_7»\¯ZÇÊ# —å‚ßßtO`ª9øÖ¼ÃdÁÜ5-Xg°ä:zÇz‹ëê?ö¤j™”] whËŠ~´þî¼3˜:o´6˜Ü5tì(«И²¹žz£1ÅÅ+Óì÷pZG‰þ‘SEÔ˜bÄ#iLñ“+”ô£øyÜœTo¡l&Õ—“*™utyìÊæÐp5ç€3Q©«É®TOWÊ«±TÓjj»ÆdÏKé¥ÙK¶àþµô¾ŠYè¥ý龨ä©F&Ó×:L©Ì:.ǶüØû×ràmøÈ# ™i¥\–óc¥ÛTåîrÏvöÊaŠvØ04¨èº•vÙ¯h'¢¥âŸ7&»¯·6˜œý˜Ð‚N@cê$Ýîl)Ž3W¦Ýé…ì%)hLI‘g¿&P8éÂ?ÜãéSiLá”H–©‘~dR´xNRœœT×O*åÚ‰µ”‚4<õò*9»¥8 –šIÂäÖi»ÆÔá¶jóf2=5g]ÙHó´’‡©›á`_€ @€@‹ Ü!И ü”6ÝL¦Ûž\ï1°¾äaJi›©V;.Ë¥7Ôë6½u˜ÚQ#¶Ñ=¥èßHô»Gœ=%H)AømÚ5SH®LÛÔÍØLJ  1¥40T«¯ §1U²ûz–õé¿ñ“ZâQ@¸§, fòŠ/{ÔL‰Ë¢d3…U¦~«•NÉ®£Ây•”»2\íÔJ¹˜®WºR½•3­1éè—ÉôÕzrö:å?Íñ‡ÃÔ׳#߇ @€úB€Áâ¾ÐËøwј2À|VßL¦!Mög‘ëû\rù„E«<rYλô†h·Áa*B7±è—ØËSOÚIƒè!úÅj#SöãÆ„Æ”ý^L Z%€ÆÔ*9¾—r…Ó˜,p½¢Oÿíð7¥yI’êÏææ<¤èB%’ä¤^ùIR”ª-¥º¢®Réª2¾d]c*›Lßø7]<û-ÅaJù™—êA€ @ ÿИòãº-Dc*pðSÝt3™n>ÉB!Sªc–ŽÊÉe9÷·7øÝ‹%‘éF-ˆ~7(³Ä  1%‚>W)!W¦}î`l ÕИR*×:âiL—ÞXIqTÃ1RžØïþãú+îQyú6ÓIH.[’¿P5¿›iI®xY”ü裮ՊA€ @%€ÆTÐÀÍFc*pð³Ñt™Lû|ùÿùç/}vÜäÙñ£(ï¼û·l4‰Zv…À?ú®Æï~à±øn³íÍ÷ºRvÒUGþè ¢ßUâ쬛ИºI»3ûBcŠãÊ•igz[M 4¦´D‚z´™@±4¦­[·N¯~IOñË}¾í®Coòg¾ Ü8äÞ† M¤ScÒ¹aài«^ýSÌH S›Ï l€ @¨G€Áâ÷ 4¦?3Mdþ×Þÿ¯8L™ X:*ª›ÄýïùOK7¼Ósp˜Ò«öׂ跟)[L4¦ôÄ¢Õš 1Å‘ãÊ´Õ~Å÷²A)q¢–½&P,)Š'~´‚O!P“@:5¦—7ïúÞ…Óyú•zQÃaêõ ’/@€ @-`°¸etÙÿ"Söc˜ÿ<¹æÀ‡–ï¹iç_ꢇ)ÿ ÷-´›Ä붯­×mp˜z53ß ú™ mS ÐRö4¦¸€peš²îJuÚL©Í@Ù\Z 1õ̆²& ¤ScúýË¥1ýäò9¯¿ý>sÉ¥åK= @€ PX 6ôL*WàÐg¨éÒ˜^þÙ?ú¨¦É„Ô¡Pv³ªî&±t¥èàS7cÑý}ýî3gÝ#€ÆÔ=ÖÚS§úÛM?4¦ôLj¶D ½&BÉR1YõìF ·ùƒ)äajéôÈ— @€ >@c꼬•lLY`¡ê5™p˜ ÕZnlÈdÂaj™d¿Hô³5êG)ûý )û½˜´J©Ur|/åИz­°4™°‡ÕrL …“¥b²¢„Lý÷ɄÔò³0Õƒ @€@>  1å3®Mµ ©)L¬Ô-c_»æõ51{óM&¦n…%íû4kPÃ*:—‡©!«Ì­ÒPsˆ~æbJ…ã 1e¿ 1ÅÅ+Óì÷pZG‰þ‘SEטä£ÄÛ6ó_ܹbýŸrläдeëßZ´æõx,¯íx7U'?“KȤjèmóÎw5—ªÚR@€ @ ,.D˜k7©ÀÁOcÓ÷ºe¯†ÕÒà‰F{p˜‚*È ·,ÜÿÞý›i¬\¦f@ek£=zú†é ëLô"b…Ì@cÊL¨êV).†\™f¿‡Ó‚8hLôœ(ºÆ”Ó°Ò¬bðS1ù ™ŠEÖB€ @©"À`qªÂÑÝÊ 1u—7{‹# AS¿±ý”[¥ÿ”þZ°b©V¶ìÚ¢e-èO­©¢uZpê r˜Ôm†/>xþ`u -ë_#£ü^zÓ¬ÛèÓ‚CËSó\EßNZ–ϤÔ\ú׉M}½w}äþÌÚR8hLÙ9S\ ¹2Í~§qИè9%€Æ”ÓÀҬˆ¦bò2 … @€RF€Á┤›ÕAcê&möO@žÓä¦HDØõ×].?“þ4I)ô'J JÝ@Š’8˜¥$ÝÍÜ&#£¥N¢Î£wÔT´ uà––‹Kÿ*¦&Aª3è_§1Ù Ä´H­¦›™‚0phEn  1e?´hLq1äÊ4û=œÄ@c¢ä”SNK³ C šŠ‰„L… > … @€@Š 0XœâàtºjhL&Ìö›'à´$—2Gj‚ï£XºÓT,½JóÛgÍ\pZ’„󓜧e}jé»Ôs¬ÛXÿÉ%Š6Jº’eÞòSp¹.a’“‘Çæ2uMÎ 4¦ì).†\™f¿‡Ó‚8hLôœ@cÊi`iV1¼ùÎ_Ï¿c‰•SoZðoNïwÝ<÷΂ß(Z @€ ¤ƒÅé‹I×j„ÆÔ5Ôì¨!3N´šS—¤&X&{Ó¤%V‘½¤¢—s¥áÆY!¯,ÝŽ¯ªøiºìSýk}ƺ\–¼Ò(Z»,¦jµ¥Ý²æ»nö©M¶ž44¦¤#Àþ;D©C`Ù,ºM©ÛÄÙ @€ C€Áâw4¦Ÿ¦C€ 5hLY‹X´¾hLq1äÊ4û=œÄ@c¢ä”SNK³ŠG©x1§Å€ @H1‹SœNW ©Ó„Ù> @h4¦¶¡LlChLqè¹2M¬c²ã®@cê fvÒ}hLÝgÎ!ÐhLÁÊF!@€ Ö0XÜ·\| )aÌy#^wÉö?ÏÍy#i^» ¼óþ†ÍïLÿàÃ÷Ú½a¶—D?A¢Š-@cj]j¾ˆÆ ®LSÓQ©HG 1u+MžSò1 h 4¦¶`d#€ @€@{0XÜŽ™Ü S&ÃV°J?¹æÀ‡—¶`¦¹}%ÀMâ¾Ìò÷‰~–£GÝ@cjD(ýŸsŽŠ‹W¦éïÁÔ°/ИúB輦SŠƒCÕ ÐhL½¡Åº€ @€@‡ 0XÜaÀiÞ<Sš£CÝŒ=¡Ü$nZn¾BôsJRƒSö»稸rešýN â 1Ñ?rJ)§¥YÅ#€ÆT¼˜Ób@€ ¤˜ƒÅ)N§«†ÆÔiÂl¿ïИúΰ€[à&qƒîšLô‹ýü·)û1æC®L³ßÃiA4&úGN  1å4°4«xИŠsZ @€ `°8ÅÁétÕИ:M˜í÷Sßp Ü$.`Ð]“‰~‘£Ÿÿ¶£1e?Æœ£âbÈ•iö{8-ˆ#€ÆDÿÈ)4¦œ–fSñbN‹!@€ b §88®S§ ³ý¾@cê;Ãn›Ä ºk2Ñ/rôóßv4¦ìǘsT\ ¹2Í~§qИè9%€Æ”ÓÀÒ¬â@c*^Ìi1 @€RL€Áâ§ÓUCcê4a¶ßwhL}gXÀ-p“¸€AwM&úEŽ~þÛŽÆ”ýsŽŠ‹á]Ç|üøÙÙ2-€@hLtœ@cÊi`iVñ 1/æ´€ @)&€Æ”âàtºjhL&ÌöûN©ï ¸n0è®ÉD¿ÈÑÏÛј²cÎQÙ!-€@«ИZ%Ç÷RN)å¢zh–S³¤X€ @è4¦.@Në.ИÒêÕC‰ÞÐn·-7_!ú¹ % ©A)ûÝ‚sÔÜ›úí·ÿäþG‡‚ùîÎ-z?û¦¨O‰Þ‘ShL9 ,Í*9+v~ïÂéú·xM§Å€ @€@ú 1¥/&]«S×P³£–  1µŒ®È_ä&1Ñ篊 ¶ç–SöCË/”\¥¿½»+É—ÆŸyY¿ìG˜@ >4&zGN  1å4°4«x&/Ü*I9™Š×tZ @€ ¤SúbÒµ¡1u 5;j™SËèŠüEn}4¦"÷<·)ûÑ-ø/”’0ÝñÅÝ,Óâ{iAå•™cõ§²4­xlpôý?½ºÆVÓ Ù?-(64¦bÇ?Ç­GcÊqpiZ± 1+Þ´€ @)'€Æ”òu²zhL¤Ë¶ÛC©= ¶•‚ß$.X´ÃÍ%úï9o>Sö\ðs”Œ%ç0Yî%efzôè½´ ,M;W-”´dSËiÙ_ïh}elÊ~ &€ÆTààç»éhLùŽ/­+4¦›¦B€ @ ýИÒ£ŽÕ©chÙpÛ 1µ e‘6Tð›ÄE u¹­o½·zó;Ó­Lßðsýº­}ó÷Î_?x«€Lhr>  1e?®ÿ…R&…Qö’D%iIúÓt%û÷Ý[´ ÄKZПÊÏ${Ikº•³ßhA  18øùn:S¾ãKë D©@Á¦©€ @H?4¦ôǨc5DcêZ6Ü6hLmCY¤ ü&q‘B]n놷Fë­f¾ô“|ø^™Ðä|@cÊ~\ þ e)—F-ÈUÚ¼pºL&-»$Las›”ºÉV3ùÉÖÏ~ &€ÆTààç»éhLùŽ/­+4¦›¦B€ @ ýИÒ£ŽÕ©chÙpÛ 1µ e‘6Tð›ÄE uO[G®Ú§¦Æ´lÛÅB«óI)ûq-ø/”¥\’Éd3Çé¥dKR”$3ÉRÒŸZA‰š´`ö’ý«?õ¦¾bñ‚@V  1e5rÔ»4&ºrB)'¤€ @È4¦|ı¥V 1µ„/u•SWqçeg¿Iœ—0ö®52‘Š©wY;ýИÒ£F5,ò/”æ‰sö’&÷?ZÅ4&ý+“Iðä-ÙG–¢É¾bÚ ¼ ahLU#€ÆDÿ€@N 1å$4€ @ù €Æ”8¶Ô 4¦–°ñ¥®@cê*î¼ì¬È7‰óÃVÚMÈD*¦V8ò4@cJstš«¿PÍqb-ä‘S£J›D‰nœ@cÊI i @€òA)ql©hL-aãK]%€ÆÔUÜyÙ7‰óÉÞµ#”‰TL½ÃÇÚ™ €Æ”‰0ÅV’_¨ìÇ@ UhL­’ã{)'€Æ”òQ=4K©YR¬@€ tS §uhLi õê!€ÆDoh7‰[€–¯ø ™HÅ”˜ÒŠ*hLÙïüBe?†´­@cj•ßK94¦”ˆêA YhLÍ’b=@€ @  Иº9­»@cJkd¨W4&zC ¸IÜ´||Å%d"S>J+ÂИ²ß'ø…Š‹á´›>~nXöƒL P‡]#§ИrXšU<hLÅ‹9-† @€@Š  1¥88®S§ ³ý¾@cê;Ãn›Ä ºk²%d"S‘û@žÛŽÆ”ýèò C®L³ßÃiA4&úGN  1å4°4«xИŠsZ @€ `°8ÅÁétÕИ:M˜í÷Sßp Ü$.`Ð]“•‰TLEî9o;SöÌ/T\ ¹2Í~§qИè9%€Æ”ÓÀÒ¬â@c*^Ìi1 @€RL€Áâ§ÓUCcê4a¶ßwhL}gXÀ-p“¸€AwMÞ°aÃiçü¸Èh{ž  1e?ºüBÅÄpâq»O½«!Fcê*nvÖ=hLÝcÍž ÐQhLÅËÆ!@€ Þ@cê¯\­Æ”«pæ´1hL9 lg›ÅMâÎòMëÖKÓþf,Y²öß_u+&SZE½ú@©ðRòU~¡jBêÒ·¾{輕[æ­Øràw0™Âô·ûîÿ¸iç»~Ù¸ã]+¯•Ê~_ýºì¥W·ÿùÕm~¥T6¨lÝ¥²^eKPÖå—7—ËÚM屮´éí—6¾½ÆÊko¿”?­~µ\V½ú§U¯üiå+o©¬ØP.Ë׿µ|ý›ËTÖe©ÊËo¾ðò*ú ¶²xíë‹_z}‘•5¯/ ÊÎ/e¾Êê Ì[½cުϗÊÜ•V¶?·"(sT–oŸ”m*Ï. Ê,•¥[gZyaëŒR™¾d‹•gåi•E›|òùO~j÷i 7O-•) 7MY°i²•ù›&eãÞ_Ø)%'Fª‘uhLY õ‡@™]€ @H4¦£ÛUAcê6qö×{hL½gÆ7>æ&q;nñþ¯ì?qæ vU7M/½“©€!ïMFcÊ~„ù…ŠÆÐ¦ù+·–Ü—7æ.ߌÉ¢¤ß¸ÏìþÎ[òí¥×¶ÿYEöÒW¤1šhSà0•&ç0•¦]ëœÀ´9˜œÃTÖ˜*“Ó˜|‡ieµÃhLÎa 4¦Àar“â(‡©¬1•¦×–&§1Í«¡1mhL=S¼ÆôL-ɦ©%‡©¬1Í7i#SöϦ´ EИR ª¾@cê =¾ @€ ´™S›fishLYŠVQëŠÆTÔÈ÷©ÝÜ$î¾ ~Ù¦I3_PB§1)ñ&SƒI•c  1e¿ƒð Šaà0}ïЫ¶Êƒ 4¦Ræžç–mú9™x̸ñM‘õVr§G;7ÿ²“ª‘š9£ê§!ôÑü¾zµ¦iL~¦%7g\Ù[ÚºKÓÃ#'¬·Éã‚òŽ›Bî劽žEΘBÉ­zåO+_y+(ѹ䪦ª¹äJÓF¦f¦“Û™Nnûìå¡TL[g-Ý:S¥’Šiú’-VB©˜LcúûOíQÎ¥b2éÁãmr=+¯íx·WqéõÊ'ïöñ°{ý-¾Ô@cJ}ˆ¨ š#€ÆÔ'Ö‚ @€ºB©+˜Ó¹4¦tÆ…ZùИè-à&q вøç0³ÛÔ¹ >oÕŽçWí8èæÞšLº3m:ÎÑGÝ¿ÿ^¸Þßk¯½|{¦_¿~z§!C[G+K{Ò‚þÔ¦´¬wâ¿ë*ãVÓMz}]ÓGúúþûï¯T¥¾;=joÆį`ÍŒVF•\¸paÍïÖû(Æ;v¬¾e&“5¿/4¦ì‡™_(‹¡9L‹^ÜVSB5Ig{m2I-²³«^:¡5<Áº>¥³–Ö׿vFªwFÕûv*ÓXײþm~/­uá’Æ´Çú­»zÊ–]2–¬˜·´o 1÷Õ¥°½´éí—6e•×Þ~1(rÓêWÿT"¹`.9K¿¶^¦f¦Š¦¹Å ë¼ ì°_ç 41ܳË4—\d:¹*ÓÉùÓ¢Ír˜iœiL›4—\y:¹›&ÓÉ3ÊÉaª©1É k-@Í~ ©YR¬—1hL Õ…@=hLô @€ @ EИRŒnW©ÛÄÙ_ï  1õžßø˜›ÄE躧ûeÍ%÷ìÒåëߪw\7Ju‹tîÊÏ­Ø>ðòÞ™Lv \îgû©˜ÄÖ7‡ µÖñ5&ÝÕö})GúÓÄ#­l“ÞÑŸ¶š½c ¶¦‹ m*ª1éÝAw«©ú®Ò‡Xž'· ·eÛc´Vþ ¶5·N´2~UýeÛ²Û”5ÓUƶi$£Sè#cåVy5Ó%¾ò?’4àܲA*oÇSö#Ê/”b覲„ZÉ¥·(˜4˜QÎré•NàÛg,zíëßêEN&‚ü³¨ÎîOÿâΓvÂÑyFg;áØ)Å?‰ÙùÐzŸÖ±_úlÆdíKç5)H°ä—ÍUù–öÝïë¿ÖK¼äç^ªm/½ö'©Ke{IS$ÓŠ ²—)ê0)ý¡e`²¢TˆA6D+ANÄòì®1“~ Ke»~¦UæXY^•‡©ÊaŠOÅTq˜œÆ4Åט*Ó¤’ÄÆÔ—Éw!"€ÆD—€@N 1å$4€ @ù €Æ”8¶Ô 4¦–°ñ¥®@cê*î¼ìŒ›Äy‰dÝv˜Ã4åÙ¥¥;¬õS1Uî‚붨榹ø½0™ÌRÖ KzäO!g¹[ã’i´‚S”ô¾yNv‡[ŸZ^ýiëØ rK餵lÉ„,Ÿ‡mÙî—[Û¸Þ÷qØfu+Ý¿[ïl'}¤ïÚ.”µÈvjwèm_ú¢ÕS«…$-«¤5Á*c[°—ÞtëÛ²¿/·«³­` «BSè#K°ä[bú¢j¨Æše…²ž(4!k!Ïý)ûÑåÊs˜"ªÓ˜”°Ç$Ô•×òÌÂW›4™ìäí&þ9ÄNÎZÍΓv"ÒyFÚ Ç¥í$柜uÒ³}þ‚}¥£}Ó4&eWòKÈX’Ƥ)Ò^RÊ¥JÖ¥u)”{©b/¹ôK½˜–F&ßa* LÕÓêy˜Úì0-ÞütEcÒ\r–©'“s˜*©˜Ð˜:ÚcÙxÑ 1-â´7oÞzë­ûî»ï˜cŽùæ!Ç|÷ÌßüîaZ~ä‘GÞ{ï½¼5•ö@€ @"€Æ”¡`µ»ªhLí&ÊöÚO©ýL °Enç;Èe‡i¶ç0U2yy *é‚™k¼»àÒ˜”ÑaÀe759»œS‚¢™~ì#ÝÆ¶ÜlR!swt{ÛI?v;ܽc¶Ý;7›Çþ4I·Ø]2³y즻…Ò<¡PXmãú–“œ|Én±«†&c9õGËVËDâjå6î*i­óó‘èOW+Û»>uÓØù{ךö§>uY£B$£©á¡”Næ{X_Ÿr:”å¸ ™XyîÿhLÙnÁ¡œÃ'¡ö¤b ré¹y–m›¶@&ÓAcÆï¦%E׉žœ£éNk¡Ó¾ý韜uÞ³‰,}#S'®¨£Ùö~ª¾Oヌ²+•,™«Tm,í»ßþÃ_ž0®ä-ùÓÆù3ÇÕ°—^yk冷+õ209É%aZ\; Óë «'’+Í%çM$WúuV¦¶åaªv˜JÓÜ¿ÿ‡@cš\šK®4ÜF7Ù˜ÚÞEÙ`Á  1¼ÐülÐÎ>ùÉOîVëõ_ÿë;wn¶›Gí!@€ ì@cÊnìú\s4¦>#d'€ÆÔqÄyÜAÁoç1¤=mª‘‡É9Lkß虨tÇÔ&$rwÁg-Û6séÖ‹š3™B÷³åÜèž·^&Ù½m»Yn‰=Ìþñç²Õ|wÇ¥‰jLzG#Çæ$ÙËeiÒfÍæñëàGÙHå ‰Dî‹î}÷-G¡ð¾\¥eÕ94ñœ%ari™´_­£7Mågcòwº÷ýÈ6ë¶æê¯Û¾{9©Kë;*ß=¿Ü:4¦ì‡¹È¿P5¦úªÀ-—^iZ±­Sç½²ÿ7˜LÑlL–²®™“sMÉ?[ï Ê¢ªk':i 1}fEI–’_JÆÒ—÷ÛÿÇÆ¿øÚÛ2–¬¬ö².ù3Çõä^jd/-[÷æR+• Lf‘k<‘Üón"9.¹`"¹Vç’‹8LSn^Ò˜b&²1u¢£²ÍÂ@c*lèix¶ ( Ó‰'žXS`ò߼袋HË”íHS{@€ d”SF׎j£1µƒ"Ûè,4¦ÎòÍéÖ‹|“8§!-7K÷qÿÇWöŸìæ’[Ü[u·Tå0Y*¦ù/–&¯‰¤bÒ]ð™/l±dë…¸±aN¦Ðýl¥ÒÍl½´àdv‘êç’¹,&úøw¸M{ª™)t§ÜöårŠ˜¢ä×!4œU©É2ùwôC½9É ›;å÷+¹ìMÛ”Y¡½‡ª¤,m•Û”¯1ÙGj”s’\5ÌXÒîdkÙwýXr©|wûªÖ¡1e?Ø…ý…jà0¹é䢩˜*ÓŒ¶Nž·!Þd² mþiÁ,OÿT=9›cÚPcÒO§Ð¨‘Ù…^i“ó“¢ 2–4×êý=%]É•U¯þ)(¯Xyk¥+^⥚¹—ØKõ20­Ù¹ ©$LeÃX’qà[­åÛ¬HY ¬µ’¸üjÛw¥L_²ÅÊ3‹ƒòtPªæ’S&9LJÂTÖ˜êäa"S:-»(4¦B…›Ææ‡€fŽkè0Ù §œrJ~šMK @€ ¬@cÊJ¤:PO4¦@e“m&€ÆÔf ÅØ\aoç;¼a‡É˱¤tKµj:¹:©˜t+Ôn^ðû&Sè~¶ÏÖ}$‡ÆI<¦Ý˜ô#ÏFwÍí›!NïØÊz§¦Ædïk­©[ì6›{G·Ø]þ!«‰œË~d[¶ Iõ4&}dÓ'ÙäGúSÛ7s(j)Y%­¶‚›ÎAÐ:ö¦iLZÍ2BÙ›~6¦Ð®})ú‘iLZG»¶zšËeê€qsM°Ê 1åû¨ÏeëŠù å&ÍV¶lý›fɘ„ªYÉ,‘^c µtŸôü†¯—“Ée“S”ªR+Ur,)[á°GŸ\¹á-s•ü"¬TÞ´RC]Z÷æ€ß_ãÔ¥±SçÿæÜKÆL™oª™Ô¥;‡ýãµC-^içÂJú¥Ë®rê9ÿpõ ˆ%{IE¿ÅA©)0•’0ýöÊÁ'Ÿ9à–{F©T’0Õp˜â“0M+ L›§”ò0©h.¹ÆÓ¤ùUœ·ZØû û=8büÚM︲ak‡Óû¼ÛÇÃNléÌÁ— 03ìý—N‰î§1™Jþ)-4”í3áö±{ŒÀÖ­[?ùÉOöJcúìg?ËÔrë&4€ @I@cJ: î)AøìºIhLM‚b5Ÿ@oç»”¦Y/¸º>êÙ G]2ÑËÃôzp üÅ÷O^ó³ÆÓʲä;£‡˜pÑsý»àÒ˜4ïLÿKoh8»\¾ÙÒºŒ@cÊXÀjT·h¿Pr˜¾8L[Ý |Ò¼:{Ÿrã¬ßÝ·à¼!s»§ÉÁ7ÝþÐç¿ô•ÓϽdŸ/~寡J]úæw=ê‡'œ~Î@½3jò<¥Îré—FNz~÷Üó„_ž~êÙøÁñŸû¾e{©ä×ÈÀT™Eî‘§æ|æ÷”ÆtÎÅWªÌZ˜ÎpÅO®‘„©ÎDrÎaR¦ûé3êlõ&²1eñ¡ÎI¯éÏG¬jØ žÎ㬫1It’qï§¿Ó—-©SRád¿o¼±W“­|ë»>üè#B€ @è4¦.NãnИÒêTM‰Ñ¢Ý$nQ†¾bÓ$9L•Én,WĨY޼dbe.¹²ÃtÎm³¸xBIcÚÜ_¤b:ëÖÙ‡ÑsýTLº n Îû&S†ºC᫊Ɣý.P¨_(s˜¬ÚZ>¿LUöÓ+¦]ýð å‰ÉÖ¼~çS«Ž8A)|&/ب¸ÊÅwϳDzr˜ž|îÕÃŒ—Ædó*SIB NàOÎ^÷ÕoüÛ˜qã³ß)Ê-°¾¡•™ôSø©Ïìár)Õ\Ðoå= t1ÏXªš*®Ú[ò猛úÜ*yKÒ˜,ñ’\¥ÑSæÉ^š>y7 RMàÔÿ)5‡)i…@~¡V¯^­ø¼[zNàcF'áÏã T;ë¤ýÈÓÒ˜ýEÓ€»ž/M'÷Ц“Ó üþÉk¤1Ý7i›NΗPÍdÚóŸþùwý/Q(7ï ™úߥ19ž5¤1ÝõสÍjcÉý†Ú/©¼%•I³ƒiã†zZ)—d/)Ù’IKnÎ8-+L÷œö¹/î{àw¹î¶ôo9ýÒÊOβ19{ÉÍ÷orõ-è·XŦ» þµlÛ¬¥Û”{éÎG&«Hc’¦&‡I厇'éÏ obe9iLCšØ3‹\MÉœ6KÂäý¦£1µrzâ;¨OÀiLn:9-è¥9âô¥f³1Y&½†®´LR¢`$Bà“Ÿüd &“ËÆ$iÝæ]ÿþÁG‰TžB€ @E!€ÆT”H×h'SƒŸ™¦£1e&Tiªhn§‰w§ê¢dßÔ½Òå›{î¼–¦³Y䟱N“Ý/%a*%Pâ‡Û8kŒnë^©&›Nî˜Ë¦üäSn·ªç.xé–§s˜n>iß/eÑ}W¿1rÐÇã.¥@ ¥NÿÄǧü¿;uȱݮ(È/Ô¥—^úë3.pù~Lš±Yätê¾ãÉUÎ@6iÍO°>ÊÜ#‡IE¦‹R.Y"=•¯Ÿ9ú‚ÛŸs xl>P_BíwÆÏÇ-¹nΆ? ovË“/~£¦w5ã•W¼ôì§>½GEÉJ%—’¿ éÎácî’g,Ùh¥ì4™læâWN;g  I§ž3P¡Ñ´qf­áÕ;d/)Ùáa£M]ÒÂá?8Þ~sÍ^Òäqƒï$^*EPI˜4sÜÉgP±ÜK¿½bð¡ß?Né—ö.å^²ôKw>-hLø—I ›w¾›ÊÆQ)@€ @ /ИòÉÚÆÔ4¾ÒehL]žÝä&q>‚ß ™LÊú0wÙfwÛU÷\-EÄãÓ×)Ç%÷̨r÷¼Ë‡/2‡I‰8sL)ßÃÖ™/lUš¥v¸àö¹º^/“Gà0í÷õE«6Ú¨ìo¿_¶´1“Îþ;4¦LΫtq~¡d2ü› |oÆNàîì­‰än±LgòÛÆ¬4F'p9LÝù¼L½g, Nà’Z¤1Õ“P•HïŒs¸{jï¾ÿAv{ˆõ ¿H`zç¯Ô¢`R¹OïQ΢TILhé”\ùâ—©ÚU ¼1+?Tôc*iÉ•òlq«wœzöÅGüàxM§O9ûbÙKr•®üÀ}O ¤¥a£-ë’ýìÊaÒ{åmʺ$ué3ÿ¸ç˜§—>üd0CÜ•·Üó=£´pó=OXî%û]Vî%9L.ýR¿ß\¤ÄK ô¿îóå3/4ôÁ‰ÿ²Ï—/»á¾_ž~áÁG;nÖKá)äb&ó™Ð˜²{ Pótp“«^/&•«™u‰TLéŒ4µ*ý/­é²+oô5&-“© †fB€ @ hLÉpOÅ^јR*K‰ÒâÜ$nNæ¾b&Óœ¥›Ü7–ÃcÖ [M`R¹øîy|`‘ÝW⇋‚L=“îŒ*ÓÐq«jN'r˜0™2×CŠUa4¦ìÇ»P¿PºGvÒoÎwú©é2:Ož¿Q'ðã.ŸªøÄç_s“Nàwñ®ñ«}‡IsŠo©˜J xüDz!‡ÉNàÙ5™|É LÖåKÓîÎIªZ¨ÈIÒ˜n`L]]©ÚX*¢4%«Êª ÈU2cÉÊ¥W QÖ¥ó.¹Ê².=9c™Ò,©ø‰—ìgWeì3K%0ðíCôï”ç×ÙÌq›£ÉãTä0É^šøÜËg ¸Â"{ã]#'ÌY«"iI¿Ñ7Ü9RåéÅ›k©K*r˜ñÇ&-ùåi^{Lj&30ù ™Ð˜²²¤é" ôI¡ )“¥bÒ«A6¦t5…Ú@¼uëÖO|â½2™þóþûç–¬ iLï¼û7pB€ @è4¦N‘ÍÀvј2¤ÂW©ð] …ºIÜ  ¬}G&Ó7¾}Èì6¹®•Yäv”ç!ª¤ñæ’[Z•‡I÷GŸ^¼ÅÒxL]Xš‰FsÐTf#ªé0ŘL;W-üÓ«k¢üj¾™5ÌÔ7 И²¥ø:í*0™N?ßM!gŠŒ? ¨eÑ›]š},0P«ó0Im©—H¯¦Ã”i“ÉúFH`²î$é>½»¯(‰”ª‹4¦¡÷ñ³+U¼±Š®T1–LZª*Á$q®”g‹s)—,ë’ÙfN]2ɦ³bö’‚hq J)÷R¹”rkYy¦”dË~ ƒ¢iã\ñç+ýj—§›7…\hF9²1eÿLI 2F)c£º¡C‡öJcºñ¶{CyŒéH€ @€@g  1u–oª·ŽÆ”êðP¹4&:B Šv“¸D™ûJÉd:xÖ’õ¦ð-ðÒ\rµ¦ùÁt3*1SM“irÿ£UæÞÔ?JïÑ£÷ÊR*œIhL™ [U¥ ø %“éW§Ÿ˜ÊfL%‹^y&Ð’ÃT6]Á%ä0õH¨1S=“éèGNy÷ÙüÎt›B.ú2©ìòZ ¥Hù‚4¦a£-µ’K°Ö•d/EŒ%%[2'¸¾·TκԤºäÛKN]ªi/ùSÉ6Êß^*ÉÇ”ÎBŽzK¡wÈÆ”òÞNõrF)g¥9E!pà6i2vä£SQ: í„ @€@RИ’"Ÿ‚ý¢1¥ T¡4&ºH  x“¸J™ûʸ'Çðíƒg.~ÍIˆ,„ \ÖôÝaÒ¨ì«Ûþüï|ä@Õs•”Šil¿ý3Ç“ g’S&ÃVUébþB]pÑ%ýNëè2¡x9 SU½Ê ¼â0•¤–Àb©$Òkè0é¾qÇ»>÷…[¦_cŠéݦ1Õp’¼¤JÒ˜† -K©ZT*ç¾²¹ájK¡dK¡|K5R.ÕʺT/ñ’E3”{©¦½d[N¿„Æ”ý³#-È04¦ ª™€þ{ñ•¯|¥¡ÉtÀßY´jcMéOfR¹"÷ Ú@€ @cê0à4o)ÍÑ¡nF‰žÐbÞ$nTæ¾2f\`2M_ôš»ÉZžÈÆ›¼&šÆ£g.¹¦ó0ivÓο¼ÿ·"åa’ƤõŽ¥e’ºd™™^?|æeýj¾¯ulÍÌ¡¦Â)%€Æ”ÒÀô¢Z…ý…’ÉôËÓú÷(2=ÓU&’³,z–H¯4ŘKÌSJÆSN¤×ŒÃ¤ø‡õH¨k^_³ÿ½û« _:|ЬAý§ô×òàùƒ÷º¥œHOËz_Q´Tú Îêéy™ÆäT¤š _ø_{G©w¼X»D °7‰‹™L_ÿÖÁÏ,xÕ L³J7S5Q9 Sõ-ð¶8Lë\¥Å÷ Ò²¡¶üL’™V<6x窅¦+ýíÝ]R—ÞݹÅÙKúŠV(BthcÇ  1uqÇwPä_¨Àd:µùì˜1Àd'pÏ@õ¦Rnž>:LQ‰¨JȤ)Jr•‚ÿ*lY¨eûTÒÒô Ó%99{IëK~êxohz¦1…æ}ëImUÊPøyiL÷ŽŠJ5]¥èôp=qñ¤¥rŒ*‘Šñ–ü9ã*êRJ_]šV™6Ο9.±•vØKNfbR¹¦;+B  ИڑM@ AúÆ€K.Ûw¿¯ÿ‡ÿøL²—´<ð÷W=·dmŒÃ´nË._O°þì€ @È'4¦|Ƶ©V¡15…‰•%€Æ”(þ¬î¼È7‰³³ÞÔÛL¦ió_q÷¿ëÞ/ÍPãß¿mø$ ÉÖKŠoƒ´¡’Ætã]#k®XJQÉIK=ºR­4KžgVwª¸ZÞ’æÜh¥µtJ}üS>z>­È 4¦¬DŠzB )ï¾ÿÁ†­»¢2“’0½ùÎ_›Ú+A€ @è;4¦¾3ÌìИ2ºU©@Án_S¹IÜ>–Ø’L¦¯xÐSsÖYâ‡ÐÓ>æaÊ@û©b¡ 1e?ÜüBù1”Éôӓέi â0ù Lc %L ý)é†;GÖOªTš}µ"*)–K…e¢’+%±,Tª&‰ë‘–*ù–J?¾ {K!í )û'KZ%hLYŠu…@“$3½ñöûJδå¿háwÿ¦\MM~—Õ @€ ´S fuhLY\‘êÆT¤h·­­Ü$nÊŒl(0™¾qиÙ/û9<ÈÔ‘èQÍÞ@cê ­t®Ë/T(.2™N8éÜhΞãuÎ爟ÕdÓο䆚iLe©ZE2!Iås_ÜOS=9©ÊUª!*™·TÒ•J© ýRž!®Ž´”T¾¥øtMhLé<R«¼@cÊkdi @€ @ 9hLɱO|ÏhL‰‡€ 4$€ÆÔ+D p“¸€½B&Ó~ßø·±Ï¾ìîk’‡©€Ý ÿMFcÊ~Œù…ŠÆP&“¤%ßJÁa Q2)”6)øsaO‘ÆtÝ#kåRr©•6Õ•LZêÑ•ÂÆRO¦¥tJKQ¥ )û'KZ%hLYŠu… @€ dƒS6âÔ‘Z¢1u+m+4¦¶â,ÊÆ¸I\”HW·Ó7™p˜ŠÙòßj4¦ìǘ_¨š1ôM&¦("iLÿ©Ý{$$—6ÉËŸ$éÚÛG„)ÕÍ«ä‰Jš®2+\•®JpŸý(mŸ¢1eÿdI ²D)KÑ¢®€ @€ l@cÊFœ:RK4¦Ž`e£m%€ÆÔVœEÙ7‰‹éH;Ídºñž±ûî÷õE«6ÆÌF¤©ˆÞÿÛ…EóJ)«‘ë©7¿Põbh&SM>Æô»WeK %OZ°ioiLCG˜“*“æËOre£2*õ”yÓf µ¥>hLÙ?YÒ‚,@cÊR´¨+ @€ @ И²§ŽÔ©#XÙh[  1µgQ6ÆMâ¢DºV;o}ð¬=þÛ'æ­XÃTänÛ¶£1e?´üBÅÄð×§žö›s.ˆ9{ë#I¨~ôQö;BïZðÖ[oýÝßýÝn¼ÚJà?ü‡OLž±Ðïo¶îê]`z»öÉ»}<ìÄÞ~‰õ!~hLé5„ @€ dSÖ"ÖÆú¢1µ&›ê4¦Í÷f¹IœïøÆ·NÑ¿íùÿué†ëÝ'S‘»GæÛŽÆ”ù~Ì/TL —m»qÎË·ÆK¨t˜j{çÝ¿Åû^|Ú4¦ìŸbiA2И’áÎ^!@€ @y&€Æ”çè6hSƒŸ™¦£1e&Tiª(7‰Ón×Å¢¿ýõ5ï_â0u;쯽ИÚË3‰­ñ Uú¾7|é'Uv¼õv½8“£‡ÆÔ‚¥Ôð+hLIœÙg 1å!Š´€ @€ .hLéŠGWkƒÆÔUÜì¬%hL-a+ú—¸I\ä°åé ·üþ¯¼õîû„nXâ0¹cä¤íhLÙ$¿Põb¨TLº6QÑÂo¿=ã0ùèИ:I-¬€Æ”ýS,-H†S2ÜÙ+ @€ @ ÏИòÝmCc*pð3Ót4¦Ì„*Må&qš¢‘d]|“ ‡)ÉH°ïv@cjÉä¶Ã/TMö–ŠÉ4&-èOßdÒ ‡)Ä ©K©áWИ’;5²çl@cÊvü¨= @€ @ ИÒ•.Õ ©K ÙM 1õ^q¿ÊMâ‚Ä~øÒá*ñ5“ ‡© ]"ÿÍDcÊ~Œù…ªC—ŠÉ%dÒjf2á0Õ$†ÆÔÐIja4¦ìŸbiA2И’áÎ^!@€ @y&€Æ”çè6hSƒŸ™¦£1e&Tiª(7‰ÓÖeÿ{÷_¸eaÃÈdzÿo4\ hLRƒ*ò ä§bò2iÍ?ýù¯äaªÙ¥þúïJðŠ)¯íxwõkoǯS¨O7lûóÚÍ»â›üúÛïwösòn;±³»`ëH‚SÔÙ' @€ @ ßИòߨ֡18ø™i:SfB•¦Šr“8MÑèT]úí·Ûïw;úÑ£µùLZпƒf <°ír¯[öÒ¿òœÜ§k^_Ó©Ú°]t‡Sw8wr/üBEé†R1ù ™: ¶ ®@cê:rvØhLÝáÌ^ @€ @E"€ÆT¤h‡ÚŠÆTààg¦éhL™ Uš*ÊMâ4E£Su‘“$?I[—¨$cÉÒ2¹üL[vm±OÝ;Ó7L7ç‰2L)ÃÁ+W_¨P £©˜B ™²sZ 4&úBN  1å4°4 € @€ 4¦á'½k4¦¤#Àþ@cj̈5"¸I\„N¡¬Ký§ôWK•Éô² Lz _:\隤.é­`ÅÄ&^È04¦ ¯\u~¡B1¬™Š‰„LÙïé´ 4&úEN  1å4°4 € @€ 4¦á'½k4¦¤#Àþ@cj̈5"¸I\„N!KI®’ZªK–ŠÉågÒ²>•ç$uI úTeì‹cm5^È04¦ ¯\u~¡B1\¹c¨˜X¶äï^öY÷§>Ê~Ài<hLt‡œ@cÊi`i @€ @ AhL ÂOz×hLIG€ý7&€ÆÔ˜kDp“¸ÂÍçr,ÉR²eKÂ$«ÉĦ]ÝesÌ¡1¡cä¼hLÙ0¿P11|xùgõ¿ì™@ 4&ºFN  1å4°4 € @€ 4¦á'½k4¦¤#Àþ@cj̈5"¸I\„N¡‰ä”‡I-U¾%×^½£¢»ç^6l(2Úž[hLÙ-¿P11DcÊ~§±Иè 9%€Æ”ÓÀÒ,@€ @€@‚И„Ÿô®Ñ˜’ŽûoL©1#Öˆà&qa;…¦#~pìøK¾´ï×0™ Û òÜp4¦ìG—_¨˜¢1e¿ƒÓ‚XhLtœ@cÊi`i @€ @ AhL ÂOz×hLIG€ý7&€ÆÔ˜kDp“¸˜BÓ‘?8î…—ßX²ö§¦/þâ—1™ŠÙrÝj4¦ì‡—_¨˜¢1e¿ƒÓ‚XhLtœ@cÊi`i @€ @ AhL ÂOz×hLIG€ý7&€ÆÔ˜kDp“¸€"p˜~xÜÒuošÆ´è¥×Ç=ƒÉTÀŽ÷&£1e?ÂüBÅÄ)ûœÄ@c¢ƒä”SNK³ @€ @ @cJ~Ò»FcJ:ì¿14¦ÆŒX#B€›ÄEëæ0-[÷æÒ—ߔô¸¤1-\óú¸§1™ŠÖòÞ^4¦ìG˜_¨˜¢1e¿ƒÓ‚XhLtœ@cÊi`i @€ @ AhL ÂOz×hLIG€ý7&€ÆÔ˜kDp“¸PBÓQ?¨ôÒ:öÝéÓ§kaÿý÷×.\ÿÝÐî´²¾¢ïê}½úõëçªÚpS}éÚ×àÁƒ}½ÚÕYíÕ¿j~_jRôï¢1e¿ð C4¦ìwpZK‰’ShL9 ,Í‚ @€ $H)AøIï)é°ÿÆИ3bn¤S˜Ã´bÃ[JÅTšQî F¹@cZ½sÞªsWîxbÊÂÏ7m29s(ªÉÂÑË›LHŠî4&SÜŸkÖ¬i©šu;v¬}Q“™LÍl*~_²‹¶lÙRo³¦Ü jr¯4&g/é[Ñ5„À =И²ßø…Љ!Sö;8-ˆ%€ÆDÉ)4¦œ–fA€ @€$€Æ” ü¤wÆ”tØchL±F„7‰‹Ð)ÂS%“?£œR1=_Ò˜ž[±}ääfM&ól”:h·Ýv eZ’Ž# ɽ)ŸI‘Ó˜´lÉ™L÷‘dê}ËÆ¤e}Å” û®éGÒ’lM'Hõïßß¾•~ôŽSˆvíÚeJ“mJ “´Kzä6eÖ«Þ¾¬·¸Úú’–ëH–É5ÜiLnãúº*ã²CùMÓ}ç ©O‡'SŸð¥âËüBÅ„)}”JtŽSçØ²åD  1%ŠŸC€ @€rI)—am®QhLÍqb­$  1%I?³ûæ&qfC×lÅ=‡é­eë{¦“[¼öE/½^žQ®”Š©¤1mŸ³bûìåÛFLZðù/5ž].>“ŸOHZ,"Ó˜œ„$kÇÞ1ßHrÉOöŽþuÙ˜L’¤­fѵ‚ù@æ<… Ø›¶M—„É6¥wlS®’nS6­[t_¡kƒ&fY…ÝË©]6µœÛÕÓv'yKïë_½ô§L,k‘Ÿ)JëÛû¼Z$€ÆÔ"¸}_¨˜` 1¥¨§R•N@cêU¶™hL)U€ @€ äŒSÎÚ›æ 1õ†ë&C)îß+7‰3ÀÕw“7Ü›/ØŒr/½¾h4¦ó_Üé§bš³<Иž]¶íñ‰ó÷id2…4&Y8Òt,Ÿé;rq,e‘Óƒ´ìûF¶šËÒ¤•c4&Khdn“e`ò§l³XüœF’ä9[ÈyEN?²/†f‹î+ÊÚ4,—WÉV°Ö™Ÿdº’5Ð)JªŒ 'ý«¯ë¥W· 7^¾ûgg[‡ÆÔY¾ÝØ:¿P1”јºÑÙG‚И„Ï®;I©“tÙ6 @€ @ ˜ИŠ÷R«Ñ˜ üÌ4)3¡JSE¹Iœ¦h´¹.5&:¹ú©˜ä0ÍZºmæÒ­Nh`2…4&óŠLÙqù“,÷’M—f)ˆœ´¤‡4&Ë“¤÷kfcòÕ"-KòÝ#›ÇÍæ‰Ó¿Ê´dùì¥?m›Qɾ£1پܦÔsô¯MŠç¿›ZÎ5Эi–™‰e¬”YÊס˜N® S &¼ ~¡b€Æ”pïd÷&€ÆÔiÂl?!hL g·€ @€ @cÊqp5 ©!>OžSò1È` ¸IœÁ 5Ue.¹åëß\¶Î›NNy˜œÃJÅTšQ®¤1mñÂÖéK¶<<~Þçêçdj8©œêjb“ülL–-ÉOYd­’£1É…r®V³?M0r–’OGÕS*&{Çí½žÆÚTt_nËfeÕ ƒo ITÚm·Ý´k-8Êef² ï¬ÕZÁUµ©³RChL ¥~~¡bB„Æ”úþKûF©oüøvj  1¥64T € @€ YhL™ ]ß+ŽÆÔw†l¡ÓИ:M8—Ûç&q.Ãê9Lo.3‡éåÊ\rkß0‡É¦“›¿zç¼U;æ®TÙ>§Ça R1™ÆôÌâ-=ùü羸ßË/¯²ŠÑ˜l9}Å-˜Í£ù:–0Iÿšd³³Yv¢š“Ûš%|ÒŸ¶)½ÜŸ~’'ûH)ŽL¢²—ÕÇ6e)‘lµÐ¦\­¢ûj¦·ø“yZÚå ²& ˆmGÛw@Bé—ÈÆÔ êë 1µb›à*&hL ÷NvßihL&Ìö"Ð@cÒÝÔÈ–wÔ^~^ЄjÎn!@€ @H+4¦´F¦ õBcêdvÑGhL}X̯s“8q7‡I˜\¦ÑÏnøéÓ–¬}cqÉaZTr˜”¦ã/Ÿú| 1mnÅö_]7ãð‹'>@eücÓ×Ó’-O/Þ2mÑæÇÕ5™20:õ[&ªM%ûD©OøRñe~¡b€ƔŠ>J%:G©slÙr‡ 8?^ûq.»dœq“&Kãi5ÔŸ²—ô§^Ê;Úáj³y@€ @€2K)³¡ë{ÅјúÎ-tšS§ çrûÜ$ÎYXå0ùÃã,“›HnÔ³ŽºdââÒ\rÎaš²`“¦oœ5F©˜ä0)“¦[G¯>å¥&¿äR1=½hóÔ…›§,ÜôÀ¸¹{×ÉÉ”3†4''И²H~¡bbˆÆ”ýN b  1ÑA2H@Þ¼&?§¦ì%%5ÉTWc’±¤L¡.}¨V5õÉ}3ƒ@¨2 @€ @]!€ÆÔÌéÜ S:ãB­|hLô‡p“¸h©ýJà0ýà8³—T^xù %a5kÑ'º¹ä,ÓÉ×ϼaÄ2iLÏU¦“S¦'Ÿ{õ)‡©’Š)Иlš<Óýcçîý…ڳ˥– +.4¦ìÇž_¨˜¢1e¿ƒÓ‚XhLt Pî%M”Ò˜ä6ù&RƒIå|I² ‰ý73ˆ…*C€ @€ ÐahLœæÍ£1¥9:ÔÍ 1ÑZ ÀMâ ¥ó+æ0SÉ^2)˜Hî¥×GÎ\/i¡7—ܼÕ;JsÉíÆ¤{ù¶g—m1cý̶j:¹3n~ö77?ûôâÍÓlF¹R*¦IóÉ™Lc枣ÎC) —ßx$…‡@*¡1e#Nqµä*†Sö;8-ˆ%€ÆDÉ,?“&…³vô/½´Ð i×®]‚¿ÑÌ’¡â€ @€ t†Sg¸fb«hL™SÁ+‰ÆTðÐZó¹IÜ·´}ë ƒºížÇuɳ—$0- 20IcZwäÀ e‡iU9“æ’{nE 1™Ã4kéVéJr˜”‡é¦‘˽h|ÃTIÅd“Ê7¾{ÄqÿÃÐùÿ“~)E# y"mý¿v}И²§¸Zò C)ûœÄ@c¢ƒd–€o9É%TjVc’å20 J! ªÔ9Yú¡Acê\?èÖ–ù…Š!ÆÔ­nÈ~"€Æ”xvÛwNc’}Ô¯_?Û ô§hLÒ•Ü\rJßš‘®ï•c € @€ äSƒÚl“Иš%ÅzÉÈÒÝåä(±çnç¦K˜ÉtËÝ-\³SÅ&ËÀôØô—•uÉ•ãþ8Õ&åa:àÌ1ÊÃ4si0—Ü1—M9lÀøÃ./©j:¹ùå$L!‡ “)7§ù†d釩ù¸¦uM~¡b"ƒÆ”ÖnK½ÚD©M ÙL÷ øÙ˜d%™‰ä|¦S´º[¶lé~Ø# @€ @Y"€Æ”¥hµ¹®hLmÊæ:@ Kw—;Ð|6Ùn·Æ-ß*›Lw=fö’ŠËÀôüªsWî°‰ää0I`š½¬<—œ9L3–ÓÉ=³xËÓ‹6×›NÎÏÃd&S:{Bçj•¥4¦Îõƒnm™_¨ÒhLÝê†ì'!hL g·&Ðk©Óbû€ @€ džSæCØzИZgÇ7»E Kw—»Å„ý4$ÀMↈ²µ‚™L7Ýù¨æ³)äL`š[˜, “&’+Í%WÎÃdsɵæ0Õ3™nY˜-tÔ¶Yú¡Acj&¢é^‡_¨˜ø 1¥»óR»>@cê3B6NhLéŒ µ‚ @€ d™S–£×Ǻ£1õ _ï,Ý]îvÑn7Ç)KkÉd:òÈÀd*ÛKÕ“9L³ÌaR¦‚$Lu¦M“æ•§“«—‡©^N¦5¯¯ÙÿÞý³Dº6G K?4hLÍÅ4Íkñ 4¦4w]êÖhLm€È&ÒH)Q¡N€ @€ l@cÊvüúT{4¦>áãË]!¥»Ë]ÂNš!ÀMâf(enwÿò—ƒ9ü†Û±)ä,S( “s˜ž åaZ¸iò‚M“æ÷ÎaÚòÆ_>üè#µë¯»úOé/iú†éƒçVZ¦A³éMýk+HrÒGZпzÓ½Ÿ9άp–~hИ²ßAù…Љ!Sö;8-ˆ%€ÆDÉ)4¦œ–fA€ @€$€Æ” ü¤wÆ”tØcYº»Ü¸5¬Ñ%Ü$îè®ïÆL¦ë‡>˜\¦K‚8LÖÐ~cûI`’º$™éèGûâØ-»¶¸üLò–ô©ÞÔ;’œ´¬uºNˆ¶B K?4hL­D8]ßá*&hLéê¬Ô¦íИڎ” ¦ƒS:â@- @€ @y"€Æ”§hö²-hL½Æê ÈÒÝåð°ËÚ¸Iœãža&ÓuC¶)äz&"¹Å[$0ùS_ò09˜ò“”rIêÒ^·ì%™Iï+ñ’Ü&[Áì%[ǽ“ã@ä©iYú¡AcÊ~Ïã*&†hLÙïà´ –$§ИrXš@€ @HS‚ð“Þ5SÒ`ÿ déîrãÖ°F—p“¸K Ú™L×yئSQ¦h¦© 7Y¦¶8Lj«ì%ýë«KšfNY— ƒ>•À¤•„É•„±ÛÞÈÒ Sïb›Æµù…Љ S»,uj#4¦6ÂdSi"€Æ”¦hP@€ @€@> 1å#Ž-µ©%l|©«²tw¹«`ØYn羘ÉtÍm—¦òDrA¦r&s˜4‘Üü“æmœX*ß=ìGWß0tí¦wbÊ–7þòáGEZ¦%½o“ÇÙ –I ×ײ?Çœl'­™û@ä£Yú¡AcÊ~Ÿã*&†hLÙïà´ –$§ИrXš@€ @HS‚ð“Þ5SÒ`ÿ déîrãÖ°F—p“¸K Ý™LW ~è™Å[žV©LSn–Àä&˜úè0©¡Ò•”iIr’?mœ².)!“+ZMïhš9½ã¯–('vÞ˜@–~hИÇ3íkð !4¦´w_ê×GhL}È×ÓJ)­‘¡^€ @€ ì@cÊnìú\s4¦>#d'¥»Ë‡Áš%ÀMâfIe|½²Ét냖)˜ü‰äæ—¦¾;LÆI&Ó®¿îÒÌq>6½©wô¾Š[ÍR4ñÊ ,ýР1e¥WÕ¯'¿P11DcÊ~§±Иè 9%€Æ”ÓÀÒ,@€ @€@‚И„Ÿô®Ñ˜’ŽûoL Kw—·†5ºD€›Ä]‚ݘÉtÅ-:É&’sI˜Úå0¥ ­T¡S²ôCƒÆÔ©^нíò é{‘=%B)ìì´óИ:Ϙ=@€ @€ŠF©h÷Ú‹ÆTààg¦éYº»œ¨ù¯(7‰óc¯…f2 ºåA˜&Uf‘kË\r…"YØÆfé‡)ûÝ”_¨˜¢1e¿ƒÓ‚XhLtœ@cÊi`i @€ @ AhL ÂOz×hLIG€ý7&¥»Ë[Ã]"ÀMâ.NÍnÌdºü¦á~&ò0¥&>i¯H–~hИÒÞ›×_¨FhL;kdšS¦ÃGåë@c¢w@€ @€ ÐnhLí&š¡í¡1e(X…­j–î.6Hék87‰Ó“Ž×ÈL¦?z&ÓwûÑÕ7 ]»é˜²å¿|øÑG¯;H7,ýР1¥»/5S;~¡b(¡15Ó…X'ÃИ2<ªG‰þ@€ @€@»  1µ›h†¶‡Æ”¡`¶ªYº»\Ø ¥¯áÜ$N_LºQ#ßdÂaêñ¼ì#K?4hLÙïuüBÅÄ)ûœÄ@c¢ƒä”SNK³ @€ @ @cJ~Ò»FcJ:ì¿1,Ý]nÜÖènw túv˜LßùÖ—ö;#d€ @€ „ 1¸K 18ø™iz–î.gjþ+ÊMâÜÇxñ=ƒ&÷?ú¥ñã-yY?÷¦o2á0å¾W´ÜÀ,ýР1µæÔ|‘_¨˜P 1¥¦ŸR‘Î@cê W¶š84¦ÄC@ @€ @¹#€Æ”»6ß 4¦æY±fR²tw9)Fì7B€›Ä¹ïcûíÿîÎ-Ñfn^8]z“ÿ¾™L8L¹ï}i`–~hИúét|—_¨˜8 1¥£“R‹Ž@cêZ6œ,4¦dù³w@ÿöþÚ®ªÎ÷ÅwüÇ{õÆxï¾úûƨÆÒ²¼—ûêë^ %jÔÒRA!TÙ ¨h”^ÚУ ,A1ôBГ„.}K’œä¤O šä¤%A"RRHþßµ{ϳöÚÍÙ{Ÿ½ÚùÙcŽÃ:{¯µæœŸßÜk-2?ç7!@€ "@c*bT[ìS‹ Ø-Eyš]NUW`’¸À#â­7.þŨGF¾öÑ1ê¦2)3“më¥m•Èû2™T´>zeÞäákÈÓ©³gé(îPM¢Æ”¥¡J[b €ÆTN™hLYˆm€ @€ ‹S±âÙVoИÚÂÅΩÈÓìr*€¨´&‰‹=.´lœL¦×~Ó§ŸÚÞ»¾GŠ’%aR–&ý*·ÉÞ×O[cNïk½£ el*6z×.<ÝhИÚnööçÕ$&hLÙ°´¨«ИºŠ““e‡SvbAK @€ @E!€ÆT”HvÐ4¦ qHÂò4»œ0ªkL€Iâbs•ÔGû)ŸIÞ’ÞÔ¶²4é§Œ%ýª÷ݧ&3é¥lL–®‰<ÝhИò?p¹C5‰!Sþ8=hJ‰RPhL ,Ý‚ @€ ¤H)EøiWÆ”v¨pyš]¼7ì‘&‰R5æ*é%WII˜¤%ÙÏ7öö›Ì¤—‰M–¢I?mÛŠ[.¥æSmæäéFƒÆ”¹áÓvƒìõÆ[;Û>ÒƒИ<²ß]Dcò;þî=SƒK× @€ @)@cJ |ªEcÊBhCsyš]&–™!€Æ”™Pt¿!ÎU’·¤Eå¬ÉIZ*NEY—”„Éå^²¼MúUV“í©í·Þ8ØýfqÆ<ÈÓ)Ï#ÍÚnw¨ü÷#– 1Å‚•“f‡SvbAKºJ€»ZWqr2@€ @€DÉãa€ÆäqðsÓõ<Í.çjñŠÆTà›«¤jy8YJ’™ô«ò3IW’Õd™–ô«¶õ‘vö¤CôŽ%mr†Sѵv äéFƒÆÔnt³·?S“˜ 1eoÀÒ¢®@cê*NN–hLÙ‰- @€ …SQ"ÙA?И:€Æ! ÈÓìrÂh¨®14¦åRré””xIö’:« ÷Óú®÷í#{IfÒ¯¶/DäéFƒÆ”ÿá‹ÆÔ$†hLùàô )4&HA  14°t € @€ "4¦á§]5SÚ þÁ äivyðÞ°GBИM5(<ÝhИò?äИšÄ)ÿœ4%€ÆÄ)(4¦‚–nA€ @€R$€Æ”"ü´«FcJ;Ô?8<Í.ÞöHˆSB ©… § Sþ‡S“¢1å€Óƒ¦И %€ÆTÐÀÒ-@€ @€@ŠИR„ŸvÕhLiG€ú'§ÙåÁ{à @cJt6«Ù·õPßœCo½™ÍÖѪ ÈÓ)ƒ¨Í&¡15†ÆÔæhb÷¼@cÊ[Äho‹ИZÅn€ @€ ´L©eTÅÛ©x1-^ò4»\<ú¹íSnC׆?}õ!MJfâÖäéFƒÆÔZL³¼S“è 1eyèÒ¶.@cêDN‘EhLYŒ m‚ @€ ä›S¾ã7¤Ö£1 'B O³Ë‰¡’V 1µB©°û 16´qu,O74¦¸FArçEcjÂ)¹HM©@cJ;•ÆO)~ÆÔ@€ @ð“oõÉãàç¦ëyš]Î Ôâ7©ø1nÒC4&¯ÃßIçót£Acê$ÂÙ:©I<И²5XiM×  1u)'Ì4¦lÄV@€ @€ŠD©HÑl³/hLmc÷äiv9O74¦N"œ­cИšÄ)[ƒ•ÖtSבrÂl@cÊFh @€ @ HИŠÍ6û‚ÆÔ&0vO@žf—SÀC•õ  1y=2И¼'ÏÓ©“gë4¦&ñ@cÊÖ`¥5]'€ÆÔu¤œ0И²Z@€ @(4¦"E³Í¾ 1µ ŒÝS §ÙåðPe}hL^ 4&¯ÃßIçót£Acê$Â@ И²ZÑuhL]GÊ !@€ @Þ@còx 1yüÜt=O³Ë¹Zü†¢1?ÆMzˆÆäuø;é|žn4hLD8Ícæl“fõ®»ÿ`ÿÁ?Ìpib €ÆTN™hLYˆm€ @€ ‹S±âÙVoИÚÂÅΩÈÓìr*€¨´4&¯Ç“×áï¤óyºÑ 1uáÔŽ³t̨é£R«>Û~ëáÙn ­ƒ@ Иb€Ê)³@) Q  € @€ b@c*V<Ûê S[¸Ø9yš]N•Ö#€Æäõ¸@cò:üt>O74¦N"œÎ1ÊÃ4â‘#'TÎ!ùL=ý=£ç¶mkÐä“-‘öÔG*é44ZÕYiLB!â0~ÕxmÛ¯Ö½czS;kŸ4šIè64¦nå|!€Æ”‘@Ð @€ @€@ 1(˜ív©]bìŸ<<Í.'O‡@còzh 1yþN:Ÿ§ S'Nç9Ãîfþ6¤4™¯ãò3é;}}zS’œäëhŸtÚšx­ê¬/u_@Ô}‰Jr¹´a  C¡wÌÓËó%%*ŒS P9e 1e! ´€ @€ P,hLÅŠg[½Acj ;§B O³Ë©¢ÒzИ¼hL^‡¿“ÎgýF3ÿžC³n)—sþCgü§_õþ:é3Ç$BÀÖMë?د Ë3$‡Éå²OMf²æ8'‘Ö¥Y‰8XV*ÉL. •ë¾å¦(}j­”ìåU¶ª4cCݱ@cŠ/'OSzì©€ @€ PThLEl ýBcj»¤L ë³Ë)ã¡úúИ¼hL^‡¿“ÎgýFó“ÒÌwÝ"«‰WV X!µNi„œŽã¤%ûT“d&er%«½ér»,•Nª i^FÉ%£²Oõ«e±²âãërS8’$€Æ”$mêJS‚°© € @€ à 4&O]¯›hL?7]Ïúìrn@úÕP4&¿âé-“×áï¤óY¿Ñl_ÕPczê²N:Ì1‰°”BªJ?‚c˜ô’ؤŒD2x\ "y<þ$r܆ÃeÉ« ‘Ë\¥mKgÅ ù&€Æ”ïøÑú†И€ @€ t›S·‰æè|hL9 –·MÍúì²·ÉvÇј²Ÿ˜[‡Æ3àâ>7šº ™HÅ”í±(/G9„$ß„—“ £÷%0é#yKê6Li ï–ížu¡uâ µËR.Ùéô«¶MfrY¬ —!êB­œ©@cJ=4 hLñp嬀 @€ Ÿ  1y}4&ƒŸ›®ç`v97,=j(“GÁ®í*“×áï¤ó9¸ÑÔMÈD*¦N¢è1¶nšVŽsµ*ÕÞÔÏð›zÇöôç¥îpŽ%ÇÁÁ1\aVþ ¢§Å$€ÆT̸ҫChL @€ @€ºM©ÛDst>4¦ËÛ¦æ`vÙÛØd¸ãhLNüMCcŠŸqÁjÈÇ&’‰TL…tð“Qö²hL^†NC€ @€b%€Æ+ÞlŸ)Ûñ¡u|Ì.«Œ@cÊX@’mS²¼ P[>n4‘„L¤b*ÀÈ£ €€oИ|‹¸7ýEcò&Ôt€ @€ 4¦ÄPg¯"4¦ìÅ„E äcv™¸eŒSÆ’lsИ’å]€Úrs£q ™HÅ”ça÷ú¿oÝñúœ<÷ ƶïþýâ}oôÆX§†@ºИÒåOí±@cŠ -'† @€ xKÉÛÐ:„ÆäqðsÓõÜÌ.熨 Ecò"Ì:‰Æäuø;é|nn4.!©˜:‰sVޱ;TVZ“±vLXó^}3Ö(šî@cêKΔ)ÜÕ2@€ @(4¦B„±³N 1uÆ£’$›Ùå$¡P×`И#TèÏј Þ8:—§2‘Š)ŽAà9јšÀFcJp$RUИҠN @cJ2U@€ @€<#€ÆäYÀÃÝEcò8ø¹ézžf—sµø Ec*~Œ›ôÉëðwÒùÝhz§=6ö‚;é$Çd†ÀÓ/ž÷Õ ™ð­Ëï|÷/'™™XÑt›S·‰r¾Œà®–‘@Ð @€ @€@ 1(˜ív©]bìŸ<Í.'‡@còzl 1yþN:Ÿ—Mooï‘GóåO;vl'ýä˜ غu«‚xò©g\}õÕhN¶š0eÊ”O}ö‹â£¡ž­–Ñt‹S·HržŒ@cÊX@h @€ @ И ÄN»€ÆÔ)9ŽKŽ@^f—“#BM-@cjRqwAc*nlcêY.n4%‡iØ +¶ônzõK˜L1 …˜O[r˜†=?·WA<ý—`2…yËaúôg]²®þò-ÂdŠy(rúÔ 1¥†žŠã%€Æ/_Î@€ @ð‘“Q/÷Éãàç¦ë¹˜]Î MoŠÆäM¨ëuÉëðwÒùìßhä0}ø¨a z·®Üüª ˜å/íÃdê$Ò©#‡éÃG›2o¥ âiç`2•CbÓÒu;5¼WlzunÏËú9™R¯T4¦˜ÀrÚ´  1¥ê‡ @€ SñbÚrИZFÅŽ©Èþìrjh¨¸14&¯G“×áï¤ó¿ÑÓÑÃön]µy¿IÒ˜zúö7âë¬.×I¼Ó8Ʀ©óV*ˆÒ˜\¿ÎÅäd ¦Ï»lýÎU%KoÅKû–÷훳l3&SC•:c&€Æ3`NŸ4¦´ÈS/ @€ @ ¸ИŠÛA{†Æ4("vH@Æg—SçCê@còz` 1yþN:Ÿå9L‹Vn]õr ¿8É£§oïÒ{1™:‰wâǘÃ4mþÊÕ/ï›:ÄïíµÉ$‡é3r˜6쌌ðe÷ÎZºùƒädJ|¸Ra¼ИâåËÙS#€Æ”z*† @€ –SaC;xÇИgÄiÈòìrÚl¨¿!4&¯“×áï¤ó™½ÑT¦WVoÙï$KÅ$Éc醽K6ì9vÄ×ïºçÞv»=f̘ѥWOéå·7ÝK»é#ý9ínsæÌiå̓êTýýý¶³6Úmyîö/;L/¬ ÑAÜQ&ÓåWü°Ý®¹ ~8ˆ:O__ŸÖFø´ãÇ×›V½Ü\ìt*½o»ég»Mjws˜z6ì ¯Š¨á3—lúà‡Y²ly»gv= põ×:h/më•:„v»Æþù&€Æ”ïøÑú†И€ @€ t›S·‰æè|hL9 –·MÍìì²·ÉEÇјr¦¸‰ÆÙž7›7s˜¯zeÍ–ýY|*+Ê•5¦õ{¯Ûsì m›LÆ 1b„©ÚÖË¢{øá‡5*¢1éÍHìkws“ûÈìýÖ›¤1I]Ò›RdôÒFij)Ø sS%ˆU+ʹ ¾¸~ÏȳFµk2…ƒ¨hº *‚ÚvÁ9r¤QÕ›ÚÖûÚAä‹‘ýjû+ŽúU»ÉþÑOwlq1‡iùÆ]‚S•Š)õö‘™ñ¢L¦µk2…‡¨uÜ„<ërºâË93M)Óá¡q@cêœGB€ @€ PŸ“Ç#Éãàç¦ëÙœ]Î >_ŠÆäkäKýFcò:üt>ƒ7šÃt 6‹-F¦,>’<¤1-Z»û‹Ç·g2E|³[ÄNòG$¯½ÁZw7Û'ü‘9R‘c-Ó½iI'1ËÃ1r˜>¢µä^XµfKý ÊÔ ñ»g¶g2E‚¨_;yHæúUÌõQø}¹J.'“> ‡XF”£[ún;LáTL‘Цɇ’ç¬#u5&ëQ*º“óä‰Sž¢E[Û €ÆÔ,v… @€ @ %hL-a*æNhLÅŒk±z•ÁÙåb.foИŠ×{…ÆÔ"(v«ÈÚF“ô—W½²vëf©˜ÊÓî…kw/X³ë Ç­õÕå">‡s_ИÂãNÆL+—¥2ÒÍašþªPƒTL½‘|ZÕAüN;&S]Éi®×"lf’¥\ªM1xܵFT·H†¦Á+¼f¢Yzë‚>uQ_[&Ó5¦ t &çÉ4¦œŒæ¶J©URì@€ @€@«ИZ%UÀýИ ÔÂu)k³Ë…\Ì¡13®-ö ©EPìV!©M‡éå²þb‰jjS1™ÆôÂê6L¦ˆãRõHþ¿\ЦÈ`©»›íÉÆtØa‡…wŸÇ-õU¼‘Xv˜„¦š †—T>-ÄïœqQ‹«Ë  ØÚš€ne@mLž<9ŒÔW«ÈIr²p„W‹««1é$Mrn %dÎaª+xÕákv/X½ëù…}GÙêêr2Ê>¥6·žÉ:„¡äØ|@cÊwüh}ChL @€ @€ºM©ÛDst>4¦ËÛ¦fjvÙÛ(ä®ãhL¹ Y7ŒÆÔMš^œ+;7šA¦p¢šê,>r˜æ¯Ú5oÕÎϹ¥œL©gcRŠ °IS¤qV'“s˜¤b 4¦’©3uÄS[3™DÙ9’ôr9–êfcŠ,3g>“ã_Wc²%꺗:STðÚç/[QÎ ^óWí|î…VM&iL¶”ž^ê¯uDY©Â‹†×4LBשrÂ<@cÊS´hkИڀŮ€ @€ ´D©%LÅÜ ©˜q-V¯²3»\,®ï SÁܼ{hL^‡¿“ÎgäF#‡éÃG[^K®®þ²qô'œÅG’ÇÜ•;çôö·b2E4&ç¾$¶¨œ,Ó«“heû9L â4·–Ü–ý«*A´åäÂÙ†–„M³|Z ⼕;çöîüöéƒçdŠÑÀÈ݉HK¶rߘ1c"˜Ünu ž°îÓ-äƒ8LÎÒ‹Œp ^8áÏÌߨJN¦º#Y²´Löa±íÄ t &çÉ+4¦¼FŽvB‰!@€ @€@·  1u›hŽÎ‡Æ”£`yÛÔŒÌ.{Ë?§GcÊiàºÓl4¦îpôè,Y¸Ñ8‡iÍ–k¶ì_ýr•þâ–“kœ¨&ÈâcÓìýÿü¥¯ÞuϽMB(…Å2Óè%™Ã-’?äyØû.WÞ¬}§v7«.²¨\äX§.RcŠ:L¥ ®ÚüêÊͯÊajÄH*&ÄovaóÕåêjL ªàŠ°ÔœHpõ«Þ4ÕÉ­=—ŒÁã¦Ú¾¢’¤ÊL\ºaoCÁ«4Ÿž·ñ?ôÑ%Ë–7áu5&¥e²©.kkÛ%jJ‚GWUºÚˆc£ ј”3ðàÁƒ®ïúU×b—H° Lè @€ @C#€Æ44~¹>)×áó¤ñY˜]öu‘º‰ÆT¤h¶Ý4¦¶‘ù~@L7š}o¬j‘lÈaÚÿðìÍ?·lɆ½æ¾¨<÷âotßÒž¾Êb[öŒ›Ú·x])ÓšÝÏ-þ͵÷/¿ç¹ –Ågvoÿ¬ý3—ïø\S“IIhœ™$©Åµ3¬+9)ò¦v®»›D¹™J™4‘=ó§1ýng‹AtS`¡•D´kÆ-›ÛÛoA”ÃôÓ‡z¬Ù]Ñ6ì¹ãéuå ® ² ýì‘•7=²Ò‚(SÇ‚øÍ¦&“‚Ø(£•b*MGÒR8¸êˆådÒGá¯ÚÜK-ecjNÈa*ÃQOozxåÕc—=8s³KRep&/xEŸj99áOÎßrù=/>>wKYð*Á™4wCs“)<Ô·¤Ìás“vèB‹ãƒÝ `И ¹%àäWëî#º§¸ i3I;…W*uWá°Q›[,4€ @€ Ø 1ņ6û'FcÊ~ŒhaL³Ë€-64¦bÇwÞ¡1yþN:Óf\ïŸ_õW/¿úHó6™Ã´håVç¾ ?² §¿œqóüáçM Òb[§ý|Þ•¿^²hÝî…kwßûüÆ/]þüew¿8ògspë –ŠiÖò2`fôlÿÜqƒädê–oÇŒ;õÐχê›Ó¼ße‡iþJ b) ÓþáçOúæõ3]¦ã¯œòØÜ—-ˆ£Ç¯øòÏ[/ñÜ[œ{ë Ç]þ\$ˆßüþ 9™Ò ˆþ/R|ömmÞ9LŸþܱ=v:8c&®œQw,úÑØegÜ2_d”‡É¦i˶‰Ìó6Û‚‰˜NúÉŒËî^,2¿|rƒ3£gÇSsÖ¿°œLi¡nÔ%€ÆÄÀÈ'IKÊ`çÚ.Ô–£uiíjL²Ÿ¤+…Sä¹)SD¶Í'Z @€ @€@<Иâáš‹³¢1å"Lž72¦ÙeÏ©¾ûhL…q³¢1yþN:ÓF“´TšÈLæ0-”ÃTq_®·ìÌ[æŸpÕ[ikyß>IŸ:gËO'ô–^Γ³Ö¿ÿƒƒ¬.—*†@]hL ŒP?3‘¬íRš¤1Ù¶$%Kï×Pc²•ã\6&-áiI˜ä@á0åp0Ðd@€ @€@‚И„µªÐ˜²ÚSK ¦ÙeP›S±ã;HïИ¼'éFã4¦F2Sà05lAïVKÞcî‹–ÙR‘º4kÅãg¼tám %vH™¿rçÔ¥Ûä0]!iMYò?ý¥ËîZ|͸žHiLS—nŸ²d&S'cÂã4¦2Sà05lʼ•á Z&-É:Ͼø[eÒ’“¤TCÒ˜³yÉú=ÌÞüð¬Mòu,ˆrÑ´& ‚(mÒ‚­á|Z.ˆ'/“&“Ó˜ÈLÃôÙc—®ßY‚ o•[ŸZXz%‡Iv—ò0)s˜ðI ^ÑB{"hLkv?4s“àüê©5‚sã„•¶Öž’W‚WÏöiÁßöÄÌu˜LCáœ04¦„S]7˜¨ä4&[.ÖV§uK”6[TN‡5¦Ã;LGšÏÔÒ ¦Ýèç€ @€ @ Иò³®µ©k(9Qlbš]Ž­½œ8И2†´Æ”ùÜÖÓ&¢1Ed&9LGuÌ‚[Ìí0ñEåGc—ª(?Í õÊðP–šÇæ¼Hë÷¼¸~Ïâu»å0©Hyau«FËÉ=0í¥ïÞ4çk?ž.ói ‹ÏÒ@òÆ„É4¤јªe&9LGÊašÛkAtq”££"IšÎ ­8yôL%Óú²4¦Ù›-ˆÒt¾tÅóD™:Z1íîg7\3vÙ'ÎX•Š)Ä,šL©Zf*9L_\²®¿v„kx[†*·–œFx‰L'ИfnœglúûoMä.D—ܹ8:ÂKÓiH#œƒ&€Æ”0pªë°Æ¤m¥RRN%m ’ÉÉÆdošÉÔ½r&@€ @€ŠE©Xñl«7hLmábçTÄ4»œJ_¨41hL‰¡ÎbEhLYŒJ¦Û4qãÑæ%Vn›ó®÷¾ïðùË·8{IKÈY~9L?¼o鳋£ä=Jásòu3•¥¦"yìÖ2dr˜´™ô—ù«I+‘y˜zû?~îIJÃTITc“•#?:|Òÿ¬¼˜é&”¡xóÆO(ˆÏÍí­ ¢­•¦-WŽ=ñ›·|<Aì½ñäÿuÄ‘KÖö×Âùå“k”l¬,0mÜ«µä´Z¢F¸9L‚#2ÊÃ$8ã§o’½d#|Ü´>Á ¯µç,=3™Þ÷ßÿ¡oÓæL_hhD‰a[aIËÌY?,3“6ZÍÆ¤5æÜ‰Ð˜r;h8 @€ @ hL‰`Îf%hLÙŒ ­ @cb!ýå'¿ÿÙáÃ×ÞÿÓ7&þä¾ ”Ö üäˆú¾—²4íÛ:vìØ/ŸxRmGEPQS&§éèW­%gA´åÒÄù«v~ýÚé7>¬˜¦ ÊÔ¹Ï4& b%Ÿ–LÛÆO=êÃYþ럼þÔuY‰ày^Îù4ï§žzê5?ýU-œ™Ëƒ%ä´œÈHÑSš±+ï]òýŸÏ+ð5ƤÒrr#GŽ´µ­1é˜#Fèr˜l#]£ € @€ d’S&Ã’L£Ð˜’áL-C!€Æ4zÞ‹Æäm胎£1yþN:¿qßX=íx}N'7>¦vQ9˜Ü2™N;ç’ÊêZå¶ä0]ußR˜d{HdQ–múËšÝZiKÓeÒ˜V휷rç¥w-Örrã¦öóËùß¹iN]ý%p˜>ÜÚ—÷HòPyãßñ<Ú‰sí¢r%ÉB&Ó—N<)D9L˜‚¥KšŽD´ëƯÐúhJÂ$‡É–K 4¦R•ŠI9‡Ä&¬0S'p˜–Õ8LýøòõÛ,ˆ¯¿ñV;}ˆmßÈ¢rÉÕ˜L7üªÎ-O¬–¥wóã«•žJ“@MYò[‘±.2ÊÃ$KOy˜äxi­=ÁÑš‰?ºoYÝî&ƒƒÉ[¼9q7 1uƒ"çH…€Ó˜T»Ö‚ÓŠrZNNʯ¤wÉÆ$]éàÁƒ®ÝúU“Ö¥K¥'T @€ @€@> 1å#N±´)¬œ´«ИºŠÓ—“¡1ùéºýDcò:üt>)"0¹VÊdúþ9ÛÒc–¹çþi/Ý?­O/–¢F əᡕ¶îynã=ÏmЧ¶ØÖ z« jý%â0a2µ=>ÂSµÀäN%“é¸_Ñò ]uï Ln­´Ÿ<°|öò~ ¢tœkÇõ¸ ÞùôzYhçübþ“ó¶N/¯ 8°œ\‡)ä0eÈdrSÀäàÈdºú†_Õ¹jŸ¦o\7ãºñË-C•á׎[.‘KÃ{no0¯»L#üú‡VÔ¼"&SÛ#œ&€Æ”0pªë[<Î^ýýýZWN9™d2Ù;ƒhLÝkg‚ @€ @ÀhLÞ„º¶£hL?7]GcÊM¨²ÔP4¦,E#ñ¶ 1%Ž<ïƪ15˜´Àd:ûâò[•ä=%÷eÏ¢ÊBrr_LÑJ[–¥Æ&-C6kEÿÌåZik‡ô[lË-'W×aÂdjo¸šÆÔ@`r§2“)İÃÖtDËÃÔ(ˆá5ë:LY1™ô‘&G&Ó®ÿU½¾»j„¯¶¾³<ÂKSi„ï(ðš$Uu&L¦öF8{'L)aàT—4¦¤HS @€ @ÀhLþ妧hL?7]GcÊM¨²ÔP4¦,E#ñ¶ 1%Ž<ïƤ1Í}edx ¹&”d2}ïì‹e½TÄ—É¥¨i`xT9Lþ²tÛ”%Aiâ0ÕšL¯Ì›üȈÃ'VÛȺoæ=âm´éÃá%äšh&S“ .ˆh:5"ÚŒ’ˆb‡©ÖdjÄy׎ÜÑ3§^·¸ëÜ;½q •}e2ýpô­!8Ó`#¼â0ÕXzM&L¦V‚Â>é@cJ‡;µÆN)vÄT@€ @ðŽ“w!è0“ÇÁÏM×јrª,5)KÑH¼-hL‰#Ï{…1iLma¹üŠŽ<ëb[B.¼ÆV9 “e©©äï‰d©©Õ_u˜äyüvÏzçk¤4I0µ ~co¿ïS;Q¼ëž{=áëA+i´ÌÑ© ¢%ÓH5TÑ:p˜Ä­;Dõ@AT(ÛéJ÷÷=éäo^5úÖ:#¼lw5á–i,,x ê0 Îö½è~78#†Hiˆ9<«И²Ú@€ @È/4¦üÆnÈ-Gc2BN;4¦Ø±4¦"Fµå>¡1µŒŠ@4&5ã’Ë®úîY£Üêc–¼Ç%aê®Ã$Ãã?Þp˜,Ók¿é“Ì4mÔ•÷ŽV“”ÂGÛÚˆ¼¯wd>ÙžŒ¢0;îúõOøú@KKvÄAó0™¦óïo½mµ+‚¨OõQÝ *ÊĽë{ˆã×¾ñÍ+¯ûed„Ï/$gªl-¹åUy˜:p˜œà•@ר­@cj•ûåŒSÎFs!@€ @9 €Æ”ƒ ÅÕD4¦¸ÈrÞî@cêK΄ÆäQ°k»ŠÆäuø;é|F4&5=0™ÎU^}¬¢w˜ÀTÎßÓÛ?«©áÑJ¦°Ã¤Jßzã i.rY$3éWmkC¿Js1ŸI;è}³$¾¼ôÜx½¿öÑ1h:^Üc“éø¯…-4—IË1¬ét–‡)ì05¢…µ6ˆŠ¬ÅÎí@Ld2]qÝ/ËjWÝ®áÔ@$¨"-hLi‘§Þ˜  1Å ˜ÓC€ @€<$€ÆäaÐ+]Fcò8ø¹é:SnB•¥†¢1e)‰·)qäy¯0;“HÊdúΣñ¥²Šœ&¥¨©,$×,KM“j [,ÚV& .ò–¤+™Ì¤}´!åEiÛ½¯THÈT;þe2}áø¯)ˆSËAl7“ÕÞ$ˆÎE Q‡(Ä ¨1É¥e2]~í/«Fxi‰=7ÂgºNŠÆ”8ùÝJ4&¿ãßaïј:WŒÃИŠÇ{‘)Iý–Ét꘸/3zvL¯1<:s˜TÓ\$*©(Í’¼ËÏd?í¥÷%»,þÅ([‰ÌŽRQB¦c•›ª“éË_« ¢­•¶"X+M¥n;s˜š1¼fœ ¢…ØÑrn%ö’ÉtÙµ¿p9Æj½r†ªeÛ§.Ý>uɶ)¥ráo>ñ«'k5½&EIªp˜‹#uB©j“hL9M„ @€ äŒSÎÖÍæ¢1u“&犇S<\ ~V4¦‚¸y÷И¼'ϚƤ>Èdúöé™Þq_ê;LªËi.NZ’™$cé½ý–¤G;¼2o²6,mRø¸ LÒžì#^µd2}þË_ qVE`ª âÒ²¦Ó±ÃÔ$ˆú¨nõ¾-¨ …[vZ”Étéo˜ÂvWÏöÀÒ“À´tSÂq¡ºØ  1ÅŽ˜ Ò!€Æ”wj… @€ ™S‘£;HßИ<~nºŽÆ”›Pe©¡hLYŠFâmAcJyÞ+Ì Æ$¤2™¾uúEJÞr_‚$LÎð°5*Cq˜T‘[PLN’¶¥(IjÑOeîÑ;ÚA¢’”½£Oõ¦Þ±mKΔ÷èÇÚ~3™Z âP¦&At.Zm; bZËÊdºäš[Â驜Ýe“áäaŠu”ròD  1%Š›Ê’#€Æ”kj‚ @€ øBÉ—H×é'“ÇÁÏM×јrª,5)KÑH¼-hL‰#Ï{…ÙÔ˜D50™N»P«Ùd¶\°ÌVÈð¢Ã”÷Øe¿ý2™þùK_-Ñò ÕqˆSö!4j¡L¦‹¯¹¥j„W'ab-¹ü—–×'€ÆÄÈ((4¦‚–nA€ @€R$€Æ”"ü´«FcJ;Ô?84¦Á±G 4&¯“×áï¤ó™Õ˜Ô™Lßüþ…æ¾DRÔ =S'°8¦}2™>÷¥¯6 ¢·“”É4êê›ëÚ]8Lí5ŽÈ<4¦Ì‡ˆvF©3n@€ @€@chL4&ƒŸ›®£1å&TYj(S–¢‘x[ИGž÷ ³¬1‰­L¦S¾¡20M­¬"וµäòµ|µ?0™Žûjm=w˜,ˆ2™.úÑÍác6ÂYK._ƒœÖ¶D©%Lì”?hLù‹-† @€ dSÖ#cûИb„Ë©»D©K ý: “_ñŽôÉëðwÒùŒkLê’L¦“¿w¹8LÄ8ÇÈdúìq_ ‡É…E&“¤¥0¦ ŒYš4¦ rÊ,@cÊBh @€ @ XИŠ϶zƒÆÔ.vN…S*Øó^)SÞ#8¤ö£1 Ÿg_cRTÂ&ÓO~1þ³Ÿ?níË{6m½QÙ¾÷ÿñö;>†3Ã}›L8L‘@…M&¦ bš64hLCãÇÑ™%€Æ”ÙÐÐ0@€ @€@n  1å6tCo8ÓÐr†¸  1ÅM¸çGc*dX[íS«¤Ø¯L “Új&S®®™L8Luƒh&S®G8„C¤ И Xº@€ @H‘SŠðÓ®)íPÿàИgÄ5И¼hL^‡¿“ÎçEcRß¾~æþÇQÿy˜: sfŽ‘Éôÿû‡÷/_¿­y2­ëíÌ49¹†|íƒï:ñÃÿ­ }¤Lcz‡LcÉ…šºI©›49W† 1e(4€ @€ PhL d'Ý@cê„Ç$K)YÞ© © ì¬hLqóø¨iLº'Þ»äÖ’Ëûh}ý·p˜êñò÷îºé„æpp˜ò>þ½n?“×á/rçјŠ]ú@€ @H‡S:Ü3Q+S&Â@#š@cb€t@©hÅ9©8±L¨'ùÒ˜&¬yï«¿û÷ºž‡²ÔüÇÛd©IhØ ±šF&“‚èg¦2ÏÒÿ™îÚÿf£ŽÃ4ÄÇá)@cJ9T4¦¸Èr^@€ @€€¿Иüý!4&ƒŸ›®£1å&TYj(S–¢‘x[ИGž÷ s§1 x­É„Ô»qXk2ùî0)„3qhÑ8ý·Ödb-¹Üp\‡â И Xº@€ @H‘SŠðÓ®)íPÿàИgÄ5И¼hL^‡¿“ÎçQcR?Ã&S'ÏÀ1a“É+‡iïúž×~ÓW½ïÞ ›L8L­4¡ИºA‘sdSƒB“ @€ @9'€Æ”ó¥ùhLC¡Ç±É@cJ†sÁjAc*X@ÛëS{¼ØûPŽ4¦}oôîþýb33™p˜r=ˆÍdòÊaš6j„Êâ_ŒŠNbÓä‘ÃÂošÉ„ÔëNã« 11 J© ¥[€ @€   1¥?íªÑ˜ÒŽõNipFìQCÉëAÆäuø;é|f5¦ƒ<8h^ûý[ÿñö;ƒîÆY& “éßßz;Ë-ìnÛqxÝ®}tL­Û$WïOï0»Ζ4¦ôØSs¬ИbÅËÉ!@€ @^@cò2ìÖi4&ƒŸ›®£1å&TYj(S–¢‘x[ИGž÷ ³©1MÞ8yää‘ygKû!! “ÞTцR4姯´5И%€ÆTÐÀÒ-@€ @€@ŠИR„ŸvÕhLiG€ú'€Æ48#ö¨!€Æäõ @cò:üt>ƒ“¼%Ó’´!WÉze˜´aI˜´®œd&}jÅiO à$EÀR.…WŽ“¨d«ÅY¦%í`&“å^Òû¶‰MI5“z 4¦x¸rÖÔ  1¥@€ @(4¦Â…´õ¡1µÎŠ=Ó"€Æ”ù\׋Ɣëð µñhLC%èÝñÔ˜”uɉS& ‰•l9“™ì#)M“7‰mxA Ë”„Éœ$½lµ8ýj®’~•¨¤÷-9“}d{ÚÂs*Jã”åÞÑ6 NipFì‘KhL¹ † @€ dšS¦ÃoãИâåËÙ»A©½;“w!wÉëðwÒù jL•LcRš%ËÀ¤—­.7~Õx½©ŸzG“„'­+§ 4¦NbÏ1€’$€Æ”$mêJS‚°© € @€ à 4&O]¯›hL?7]GcÊM¨²ÔP4¦,E#ñ¶ 1%Ž<ïfPcR¦%™LÿxÐt%{ITÒ›ú©¢ôŽ’0Yº&™Lyí‡ P|hLű§=Dcò4ðt€ @€ #4¦áfýÔhLYí;t‰QÐ4¦ ç4¦âÄ2¡ždPcJ¨çT@I@cJ’6u%H)AØT@€ @ð„“'®×M4&ƒŸ›®£1å&TYj(S–¢‘x[ИGž÷ јòAÚ_3qhѸât‡ž@ B‰!QPhL ,Ý‚ @€ ¤H)EøiWÆ”v¨phLƒ3bhL^ 4&¯ÃßIçј:¡Æ1ˆƒÿgUΙhLÙ‰-é*4¦®âäd€ @€ ˆÿXìñ0@cò8ø¹é:SnB•¥†¢1e)‰·)qäy¯0G÷ļ6Ú?þÏ”!RlhLÅŽ¯Ç½Ccò8øt€ @€ þ±8&°y8-S¢ä{™²õ}tÔ4¦Ž°å 4¦¢D2±~ 1%†šŠ 0þÏ”!RlhLÅŽ¯Ç½Ccò8øt€ @€ þ±8&°y8-S¢ä{ј|õ©#lE9©(‘L¬hL‰¡¦" B€ÿ3eˆ›S±ãëqïИ<>]‡ @€ ÄD€,Ž lN‹Æ”‡(ùÞF4&ßG@GýGcê[QBc*J$ëSb¨©ƒàÿL"Å&€ÆTìøzÜ;4&ƒO×!@€ @1à‹c›‡Ó¢1å!J¾·É÷ÐQÿј:ÂV”ƒÐ˜ŠÉÄúÆ”j*‚À ø?S†H±  1;¾÷ÉãàÓu@€ @€@LøÇâ˜Àæá´hLyˆ’ïmDcò}tÔ4¦Ž°å 4¦¢D2±~ 1%†šŠ 0þÏ”!RlhLÅŽ¯Ç½Ccò8øt€ @€ þ±8&°y8-S¢ä{ј|õ©#lE9©(‘L¬hL‰8l–ÿôIDAT¡¦" B€ÿ3eˆ›S±ãëqïИ<>]‡ @€ ÄD€,Ž lN‹Æ”‡(ùÞF4&ßG@GýGcê[QBc*J$ëSb¨©ƒàÿL"Å&€ÆTìøzÜ;4&ƒO×!@€ @1à‹c›‡Ó¢1å!J¾·É÷ÐQÿј:ÂV”ƒÐ˜ŠÉÄúÆ”j*‚À ø?S†H±  1;¾÷ÉãàÓu@€ @€@LøÇâ˜Àæá´hLyˆ’ïmDcò}tÔ4¦Ž°å 4¦¢D2±~ 1%†šŠ 0þÏ”!RlhLÅŽ¯Ç½Ccò8øt€ @€ þ±8&°y8-S¢ä{ј|õ©#ly>hí”C²—¬üÛ'išðÑóÞùÝÎ<÷¶ÇN _Ó¯WüÙo1¤cTþÏ4îÔš4¦¤HSOÂИNu€ @€ ðŹQј<~nºŽÆ”›Pe©¡hLYŠF"mùmo .Õ-?9"‘PIŽ äHcêÝyƒÞv¼>'Ǹi:šÐeüž¯C…%€ÆTØÐúÞ14&ßGý‡ @€ tŸS÷™ææŒhL¹ •Ç Ecò8øw©svù=òöêkL½óÛ'Zž iL9jj2±£–¢@ò(ZDéO5F8#¢ И Xº@€ @H‘SŠðÓ®)íPÿàИgÄ5И|u2‘ŠÉÇ¡ÐvŸsä娩m‡ H ƒb`„;¾÷ÉãàÓu@€ @€@LИb›‡Ó¢1å!J¾·É÷ÐQÿј:–ÿƒj2‘Š)ÿQM 9rƒrÔÔG$€äQÀ Ò¥F8á И Xº@€ @H‘SŠðÓ®)íPÿàИgÄ5И<‘„L¤bòt´Ýí¹A9jjÛaàˆ’àØáÅŽ¯Ç½Ccò8øt€ @€ 4¦˜Àæá´hLyˆ’ïmDcò}tÔ4¦Ž°â pB&R1"¤ t"GnPŽšš@ਢ€< Tº"Àg8”SAK· @€ @)@cJ~ÚU£1¥êœÓàŒØ£†“¿ƒÂ%d"“¿ƒ ížçÈ ÊQSÛ@@<Å&À/v|=î“ÇÁ§ë€ @€ ˜ 1Å6§EcÊC”|o#“ï# £þ£1u„­(YB&R1%ž ô#GnPŽšš@ਢ€< Tº"Àg8”SAK· @€ @)@cJ~ÚU£1¥êœÓàŒØ£†“׃B ™HÅäõh»ó9rƒrÔÔ¶ÃÀ$†A± 0‹_{‡Æäqðé: @€ @ &hL1ÍÃiјò%ßÛˆÆäûè¨ÿhLa+ÈAS¦L9úÈ8p  ý¡ñÈ‘”£¦Æ7j("$"F•> `„3 J© ¥[€ @€   1¥?íªÑ˜ÒŽõNipFìQCÉÛA!‡éSŸýâO>|8&“·Ã ÝŽçÈ ÊQSÛûC €äÁ8(6Fx±ãëqïИ<>]‡ @€ ÄD)&°y8-S¢ä{ј|õ©#l¹?HÓ§?{ì’uý½›^}xò\L¦ÜG4©äÈ ÊQS“Šõ‹’G±âIo¢ጉ‚@c*h`é @€ @ EhL)ÂO»j4¦´#@ýƒ@cœ{Ô@còpPÓçŽ]º~çÊͯJcZþÒ¾ “0™<t9GnPŽšÚI$8HŒb`„;¾÷ÉãàÓu@€ @€@LИb›‡Ó¢1å!J¾·É÷ÐQÿј:–ãƒÌaZ¶~çªÍû¥1­(iL=}ûš8‡œL9ŽkRMÏ‘”£¦&=ê)$bÅ“ÞD 0Â%€ÆTÐÀÒ-@€ @€@ŠИR„ŸvÕhLiG€ú'€Æ48#ö¨!€ÆäÕ Ãô™ÏÛ³açê—‡I©˜V¼´oyŸ4¦½K7î?qö'‡uÿ~¯˜ÐÙ¶äÈ ÊQSÛ ;C LɃ¡PlŒðbÇ×ãÞ¡1y|º@€ @ˆ‰SL`ópZ4¦:ê?SGØryPÅaÚµzËþU!I©˜–m 4¦%ö<ðÔìó‰M¦žžž#F´ËbòäÉ‘CF}øá‡Ï™3ǽ?f̽ÓüÌ®vµAÛÚyذa:JgÓ«ù±îVïv¶vŽ9Ò•‘–«…j˜^ÚèëëSóÚê`ÂøñãER/¤¿¿?òiŽÜ 5µ•qÈ>ˆ@ò`L›#¼Øñõ¸whLŸ®C€ @€b"€ÆØ<œ)Qò½hL¾€ŽúÆÔ¶üdÓò»ÖlÙ¯TL«,SeE¹@cÚ°wÉú=‹×í¹ÿÉY-šL’‡$»´Ë¢Ö|’ ¤ó„õ ’šŸÙÕnâŽûõ`éÕüXßÌ'{É ªõuܧnçÈQÚ!õ–« â6jÔ(k­HÚ0&¼ÄAä  d²Ú`åÈ ÊQS;ˆ‡@à’ƒ ØáÅŽ¯Ç½Ccò8øt€ @€ 4¦˜Àæá´hLyˆ’ïmDcò}tÔ4¦Ž°åì ¨ÃToE9¥bz±¤1-Z»{Üã-™Lu5&™=r_ôrn<{Gn<K&¨C´³ó–dÒXz!ÛÇn¦‘}jç7eG;èÌf>i[ò^z_oFZb^Ž^µ“½¯æÕ†ÖvÖ™u~m‡ ¡˜Z®„U‘ö4j¹Z«=­¿ö²mc¢—Zh]8ÜÉ--V-%×AÙ]µšZŽÜ 55gš›H ͈‰#<&°œ6mhLiG€ú!@€ @Å#€ÆT¼˜¶Ü#4¦–Q±cjИRCŸçŠÑ˜ò½–Ú[h9¹†©˜ÊÓî…kw/X³ë¾Çfš“©Vc’øâ%³dÕ˜@£,ßRÝlL&?Ùºr:Äl'ÛÙÔ"—gȽ£³™dc¹Æ¸EåtK¹¤èeRŽò éM÷Q˜ ô;gdMºæÙ˜ºÞr×Në¾d£æ-7…K/ë£õÈ1±žª×¶áN¥w´å^ Sr@ì´µ+æÈ ÊQS[ú&³"<Å&À/v|=î“ÇÁ§ë€ @€ ˜ 1Å6§EcÊC”|o#“ï# £þ£1u„-7…¦ÊrrûWÚŠr/í[Þ·¯§oïÒ{é˜Lczaõ®{3™êfc2OH*’ù1ò`´!ÃÆ-âf“íf†‰G•œçdÚv /-g™ÂI›šhLæ*Ù™-Õ“Ó›tZU^TÎ…Ód©ðòvú(¢1© Ör}GËÍ‹²3kC©my¸ ÖxµÇV¸«ËD;X§²£"” §nnª¹A9jjn.(44S<2ÓuŒð®#å„Ù €Æ”8Ð @€ @€@‘ 1)šmö©M`ìž4¦ ç¿J4¦üǰaê8Láåä^’ôoÙÆ½K78©œŠIÓüU»æ­ÚùëG›ådª›É¤%óÌõ±¥Íœac“<'{Gέ1QÉ,"G¹‚‹šÙ Ãb“ªn6¦° cç<ÚkLªÈ–¨ÓO[º.üŠhL–±ÉšGËÓ¶Ã|Ô*ky¤ µ­0q6јÂ©ŠÚ¤YVKŽÜ 5µÀW!º#$árê `„g 4!hLqP圀 @€ ¿  1y4&ƒŸ›®£1å&TYj(S–¢ÑͶ4s˜6½ºÜ9L R1Í_µsîÊszûï~dF£Õåj5&K}dݰlLzÇ-LæÖ‰S²¥pW@#;Ç--ç²1™odËŸiÃIE:m“lLaÊÖ³sÙžÂ'±f裺™‡ìÓˆÆwËÃík›Kåãš!bRìW·T\#)|*CíD1·ê_óQ˜#7(GMíæ7ŸsùCÉßXûÙSF¸Ÿq÷ ×hL™.B€ @€&€Æ”0ð,U‡Æ”¥hЖúИ@cêZöqS°œÊËûW¹z šQŠ01,aÚÙÔ¨ZJ™lLÙÿšÓBß yø>ŠÞFxÑ#ìmÿјÜJÌzÂs²öüê-2:@€ @€À И<"hL?7]GcÊM¨²ÔP4¦,E£;m1‡©gîÀa* L_ØúÍëgönzuEÃtòu3JÓžëXþ¥+žÊå*ÏüÙܹ½;g÷öÏZÑ?sùŽ;˜LÝiqœg‰d~гª”Ï6ÃÚmJë”r”â(GMm7^ì€’ã ØáÅŽo¡{çŒ#·†²ùHf7Ó˜ä0vØaε7Oß~—{³Ðèè @€ @@cê[1Bc*F‹Ý 4¦bÇ7¦Þ¡1Å6­ÓÊaútà0ítI˜Vm~õ©¶žpÕ”ˆÃ4}Ùv9LŸ'ûß4¦ìLj‰’Çðqpæ 0Â3"؈@DcRŠ&­çvnOc’Ã$“ Ö€ @€ @ 4&Ç“ÇÁÏM×_øÍ¨´Kà×+þìoÈÍ@§¡õ}ôÑ<>Í¥_’½dÓò Ó¾Çç½|ü•Ï/­ÎÃ$‡Iy˜¤1Y¦ù«vÍ[µóçNš´`kt9¹ SÙa2“éØ¿ù/þïìùOí6ö/onÈþ)û1¢…C"€ä1$|œyŒð̇ˆ6"јôkxQ¸ö4¦Úêà@€ @€¢И<hLŸ®€¾Â¬ýoEè }€@=>|ø„Ésu©b/¹Uä›hLZHnÉúòZr‹J“ò0}â¼IÎaztέ(^NnFi9¹iK·O-ÙKVNþÞ?¸ðòMÛ_ß¾÷zçl@cÊf\hU× yt %'Ê$Fx&ÃB£Z!VúúúÂ+ÊéðA4&¥_êééqÕ 1µBœ} @€ @¾@còx 1y|º^hLEˆ"}hJ l2Mšëì¥` ¹R¦GçlVÖ%W¾ñ“ K“ò0)ý’åaš»rçÓ^úúµÓg¯èŸµ¼þrra‡I&C2ËИ²ÚÖH]€È)2L€žáàдæÂê‘”$‰Iáýј€ @€ @€Ú&€ÆÔ6²â€ÆTœXÒ/  1yvï:m&ÓCçöRe 9ËÀ¤²xJ) ÓÚ@` ¯%'‡inïÎr¦!‡©z99—‡É&L&ïFX®:ŒÆ”«pÑØö y´ÏŒ#òD€ž§hÑÖ6 1µ‹]!@€ @h‰SK˜Š¹S1ãJ¯¼!€ÆäM¨}神Lã'ÎvKÈE&K´`õ®ÒZr;-Sc‡i{íZra‡ “É÷—áþ£1e884­<ºA‘sd—#<»±¡eC"€Æ4$| @€ @€@hL 4&ƒO׋@©Q¤­ÉôÉáÃxjv)ýÒ@¦ª$Læ0I`Z$aŠæaêÙ>-Èô}ê’m¦1ÕÍÃÔ$'SÿÁþa÷ k­½ìX 1Å‚•“f‡’GvbAKâ Àƒ*çÌ4¦ &@€ @€ F©`m§;hLíÐb_dŽSæBBƒâ$ðêþý=æ÷?9Ë– L. S‡iú²íÓÚq˜ä3mßû‡?½óŽëÓøUãG<2âàöíëÓ›=ý=î§í£lCÙ§¼ Ð]hLÝåÉÙ2GÉ#s!¡A]%Àï*NN–hLÙ‰- @€ …SQ"ÙA?И:€Æ!È4¦ìÄ‚–$CÀL¦qÏ –[,!W˜’0Y¦Ù½ý³VôÏZ¾cæò3zvLïÙ^v˜–¶š‡©Öa’¢$‡iää‘s¶ÎQN&Ûçg=´Š '}ª }:jú¨d°P‹?Иü‰µ§=Eòð4ðÞt›îM¨}ë(“o§¿€ @€ ø  1ÅÏ8³5 1e644 ­@cj…ûŒ€™L÷=6s@`ª³\ÈaR&ËÃ4‡ÉÊO²K‡ßz¸KÅ$ŸÉ>Õ†ÞÔOyNnÿ‚Á§;©@cJ=4 ^Hñòåìi`„§ê‰SL`9- @€ @ÀchLÉãàÓõ"@c*BéCûÌdº÷±™óVíTú%ËÀdI˜f+ ÓŠr¦ SÉaš:´µä\e/iÛ\%{Ó20Ù¶>Ur&ýÔ§Vl^è"4¦.ÂäTY$€ä‘ŨЦî`„w%gÊ4¦L…ƒÆ@€ @€ A©aì¬hLqã(d„SFA3’'`&Ó¯Y-0 $aša ÉuÏa²ÕâÔÓ°ºäò3)“¤%·v“Ò4yãääÉPc±  1;¾ôî’ƒ ØáÅŽ¯Ç½Ccò8øt€ @€ 4¦˜Àæá´hLyˆm„@ChL Ÿ ˜Ét÷#3J˜ÂS„)p˜B ÉMY²íäï]ðƒ /ß´ýõ&eûÞ?üéwêRU&IKÿxг}ôÎøUãå0œ¥V’®¤ã$*ÉI²bY—,'“6¤7i[ïKuÒþúÔí‰ÆÔ>rŽÈ 4¦¬D‚vÄDÉ#&°œ6#á Íè64¦nå|€ @€  1y<И<>]/4¦"D‘>´O@KÅÉLÒq.å’Ô%ËÏd2“e`² ½ïVšÓ;Ò›$6µ_'G@ И2$øØræ,`„g! ´!hL1@唀 @€ Ï  1y<И<>]/4¦"D‘>´O@f’©H’–¤%YN&[TÎd&åjRѯ˜ô‘$'ÛSò“K×Ô~µô  1¥Z+$XñròÔ 0ÂS ˆ‡S<\9+ @€ @ÀghLGÉãàÓõ"@c*BéCûVÜ;Ú’̤m¹JÚÐÏ=sTì#ýjÙ¯z_¿ªØ’s¼ ShL9 Ín•’G«¤Ø/ŸáùŒ­”Ó ˆØ€ @€ 6  1µ ¬H»£1)šôÅChL.C>@cò9ú^ôÉË0{ÜIF¸ÇÁ/v×јŠ_z@€ @HƒSÔ3R'SFA3 Ð4¦Î¸q œ@cÊiàhv«FÝ‹>£1yf: @€ @H”S¢¸³US¶âAk Ð&4¦6±»Иüˆ³Ÿ½Dcò3îõÉã`{ÙUF¸—a÷¡ÓhL>D™>B€ @€’%€Æ”,ïLՆƔ©pдK©]bìï4&/Âìi'ј< ¼?ÝFòð'Ö~ö”îgÜ=è5“A¦‹€ @€ „  1% ÷Éçè{Ñw$/Âìq'á¿Ø]Gc*v|é @€ @ hLiPÏHhL Í€@gИ:ãÆQ'€ÆTð{Ý=4&¯ÃïCç‘<|ˆ²Ï}d„ûýB÷©Ðá¥s€ @€ T 1¥‚=•¢1e#´@cꇛS±ãëwïИüŽ¿½Gòð È^w‘îuø‹Üy4¦"G—¾A€ @€Ò!€Æ”÷LÔŠÆ”‰0ÐtJ©SrWhhL…¯çCcò|¿ûHűß=d„ûÿ÷©ÀÁ¥k€ @€ ” 1¥> Õ¢1e! ´@cê™S‘£ë{ßИ|…ï?’GáCìyកâv©¸±¥g€ @€ ´ 1¥E>zßþÓ›ãWý¥Ô‡ºeѶóÓhuB­øã¸{ùjô~rÃZ=ûA `fÞrHSƒuËÙvèw; Ö]ºã-4&oC_ØŽ¿õæ¡QÙðþ(ÿoRØÈ{Ú14&O_ün£1?Æô€ @€ 44¦¤‰§\ßê]·Ôu ~½âÏÞx‹‰Þ”£Cõ”À´M'4Ò˜ö½±jÐÃÙÅ$Ðd"œYðb†ÜÓ^¡1yøbw»‘‡Š„Zì¸ûÙ;4&?ãîA¯Ñ˜<2]„ @€ $L)aàiW×(!©˜ÒŽ õC %2‘Š©%|ìT`u'™/pĽì“—a/z§y¨H¨E¼ýCcò1ê^ôÉ‹0ÓI@€ @€@¢ИʼnÊj2‘Š)¡h@Ý„L¤bj {—@݉pfÁ‹p?{†ÆägÜ‹ßëZ µøQ÷²‡hL^†Ý‡N£1ùeú@€ @H–S²¼³P[mB&R1e!.´-¨MÈD*¦ѱ[Á D&™/x¼}ì“Q÷¡Ïµ*ªq÷°hLÝ.£1ùgz @€ @H’S’´3SW8!©˜2V D2‘Š©UpìWl‘‰pfÁ‹n/{‡ÆäeØýètïÄC2<¬ ¡ús{‰ÆäcÔ½è3“a¦“€ @€ D  1%Š;+•…2‘Š)+Q¡h™@8!©˜ZÆÆŽp ™˜÷ ÚvÉà{ÔåŸQÖ˜P=Šºg]Ecò,àþtÉŸXÓS@€ @€@RИ’"µz,!©˜²Ú ¸„L¤bj‘»yAÀ%dbÜ‹x{×I4&ïBîU‡-!ªWA÷­³hL¾EÜ›þ¢1yj: @€ @HŒSb¨3V‘%d"SÆÂBs Ð*KÈD*¦Vy±Ÿ?”‰YpÂíYOј< ¸ÝUB&$TÿÂîQј< ¶_]Ecò+Þô€ @€ 4¦”ß|óÍn¸áꦯoûÛÍwÈø§7Þw쯿(ãlÒ¼K/½ôôÓOoÞþ‰'&ñ=¢¤Aà®g?ÿrÿ‚4j¦N èrÚüz{^é•ú=å'?ºrÆEŸI½j@+ [·nõq0ÑçN ø 1éK1è÷÷k_ûÚ ûø³ƒ.¼ƒ>;¶ÓA—èqsÆÞxà·}‰VIeH’S’´©+AhL ¦*@€ @€€'ИzΜ9ï~Ïß^tÉ•V.tåâ+/ Ê*ÿùÿþ¿Gžvö_1PF]q~½rÞE—Gʹ]^.^~n¥üàÂË+å²\”sjÊÙç_VS.=ëüR9o œyÞ¥åÜKÏ<÷Ò3Ê%gœ[.§ÿà’H9í—åW.þþ9¡röÅß?ûâïÕ”‘g]\*£Âå»g Ê™å;gŽ(gŒúÎZ[N¿èÛ5å[§_ô­Ó. —ožvádžÿóýïÿ o~?(§T• Nùþ#¾þ½÷¾÷½ž|•é¦oz{{<ê˜áÇ8pÀ·¾ÓßTèrúý3Ω¹!wC» ý±«\Ps¬û‹ÞøêÜò"7»È.|«ÜàêßÚÞÔêßËndá[Xó›Wø¶ܰNnXÿçÿõŸO<é{ÁMÊJôVuÁû?øQ™©D“JsJÀI_Šó‰&—={ë ¼Î¥fÔá«Mä1»ùvøjÓäRzœ®sµ©~„nöðylnø´\óyB¶ÇãcJÏÃÚht©qR>ž‡§L™rÌ'>ÃMN¯N4»%hL-ab§ü@cÊ_Ìh1 @€ @ ëИDHÓGùÄŽ½°²=(o¸²mÏ*óî¿]¼|ýo÷¼”Ý*¿ÿM¥¼²ë÷®lÝyÐÊ+ý_.—×_ÞñúæJÙ´ýu+/mÿÝKÛ‚ÒçÊo·1(¯©løM¹¬ÿÍkë_ ʺWe뵕²fë5[ö[Y­òrPVYÙüêÊJéÝôª•*/íSYn¥/(=å²wÙÆrYºqïÒ AY²aOPÖïy±R¯ÛS*»©¬-—…kw/\”kvYyau¹Ì_½kþª*ó¬¬Ü9·Ræôö»2{E¿•Y*Ëw¨Ì¬”=;.¾ú–Ï}é«Ó{¶O_”iV–nŸ”m*ã&-FcÊú%ˆöuD ä0 {aÅ–‡ŸžË„_G9¨mºœ¾¸bCén8pC´»¡Šîƒ² Tì>XÿXsï«{׋Üïìf¹Ó­ÙR¾Í…op‘»[Õ­­öŽºUßËndv ß¿J7¯àþUuçêÝi·­ÖŠà†õ—ýîŸyQw+•ª[Uå>uò÷.@cj{ ú}€'“þ` z©Ù;p©Y´|½žÀËÜ•çí­»~?ð°íž´Ý3öŽªgìòvåéÚ­#ÏÕÕ¡ÇéȳôÀƒ´{ŠvÏÏÕÏKìá¹ê±ywðØ\zf®½ÔèÙ•#ÏÉåKMøj³|ÇÅ×ÜòÏ_úª]jf„ŸŠ+—šû'çàyXÓ§?{ì’uý<Øø}‘+zïјŠaoû‡Æämèé8 @€ @ 6hLÍ4¦oÓ¬IeâÄMÖÚ|­Š&Qõ¬ ÛK¿ ÙKšÄ­˜Â“˜´1T‡é•‡Ió.ó»Q‡i¿›åÕFHc ¦°ÆÔÔa*ÏÄ4ט‚)™ÐpØa æfJÓÀn&¸®Æ4»fJØ9L3KS5e©ä0¡1ÅvàÄ™# ‡éÃG [°bkà ¾´oÂdL¦ÌŨ ’Æ´xÅúÈ=1,òZ2Bw¬² Þ†ònH,pv[ Êžn­¡[ç¾VÏÊ­õq«Ä‚ZiàæenD½5ïV7,4¦B~Òí”'“²»…ŸºÝƒ·ýÍÀžuÆÔèÚu˜*!ÐĘŒüI@Ƥ{T®oL–žƒKMɘ\cʼÖoÓÒuý<ؤ{…¡öØ  1ÅŽ˜ Ò!€Æ”wj… @€ ™SS©X¦¡:LÑTLÎaê©ü)¹2u;S?1æƒ[NÅј\*¦lLKÈÆTäK—·} ¦£‡-ìÝj&b`öí›0i9™¼‰u\“’ „½¥ˆÅkSp §E ç ¬I@É>Ø(ï`ÝTLC JÉ#™#9ëçGq©˜ByëæG)kLO[6¦n»Ô²)ÉÆ”Øè-LEþhLM.5 –Sä‘ÛÒV¶[Ñ%ƒ§ë -8L.³i©˜ú5&ÃSÝÄoÏN8LŸ;vÙú<ØæJEG@cbp”SAK· @€ @)@cj¬1ý±»Eâ6Bü­IM¥„§l#‹Ç…&T´\ÕrÑ L­-$Zó¢´\kÉ5ÊÃÔ5‡)¼¢\“TLnEž!¦b*iL76JÅ4)Å UÇC ì0­ÜªÉT7Û'ïP¢áƒ1™âÎY+¤1™¹YËÉ­wÞE—«„×uðw]AµfíÔÆy˜‚åä­—Zg¥Ôš5R«¬Ü8R1•ò£„5¦ºbÁÔ%hL|»Ú&à‰Æäuk|©y!ИÞÓh½æÅš«’s‹5—tÉ’ÃT½LsÕ+K™M:L›j³™†–cv‹WFbn¶xeýTL•ÄoUÉJK—iLZd¹‰1™eIÓgä0mØÉƒMÛ—È#4¦i[GéÍpíWÍ{…Ï£=¤I5}äfÅt†Ã;¬¶%Vï¨Q£T«±S–×!iL2wîƒvC,Ý í>xîE—«´—z°¡ÀT¹ß5° \r”fÓ`y˜–T¥bªŸ¥±Ày·ñ×ï~ðé¥bj¤1ýÇÛhLQóDc „ÈðSwõ¥fÞ’@cjr© ?i÷é»ú»y&÷\Ý<å[°¨kó$«ÛæºZט4§¥kf»“±ünv°î" ÈÖ7D“ì&æ®ÖGsK¤Õñ š' g ßï*é#wºÚ•RëeFÙ×SJ+d ßÔ*Sw¦ð*¨nýÓÒʧҘƗ4¦ºbSZ#9×õú¢1U„ÈÈǹõìí– nz©©o/ $7máRãþ$À¦AuI—Ç4òülºdÕZrͦæËÉU/µ\Ö˜JÏÆ&÷—ŸŠ³ªõ‡¦î?ؘg£Spô¤!Çå†t ޽cb´%†´¬Eæ?éW=ŸØy&OžìTÌ®Öûa»Ú.).‘¤êuж=äØi%WYKLZ²ýÍ1ŠœSGé}× KHiz–Içö‘9èÚÕd‡hÃÞ´Ú;nÃ:>›5/r6{ÇNâºï.›µÏõ5…Æ£1¥*“ €Æ”eê€ @€ øE©A¼McªU”Ü;š8Ñ$ÊœÅkÂi–”i©*ÙRU¾¥o©‰ºÔhå¸ Es{©:ý’û“ñʤKu¦&«È Ìõ–ÿˆÜ­…ÑúBr Vï’½dÅ9Ló4%Sš•Q)§²XY^#C+eÌÏk±ŒÆkəär‘ecr³5¡O4¦j!2ú·zöÖø/5å¿ ( LåGëR²ÃV]É©tµ©½Ô è’åõ—«“0E˜Ût˜ìÙ¸¼Èr泓â0 ö`£«q+6Nñ±{>qO#î©fÐlLvÍp:TXf²Â“~ kLNZÒŒ-!çòPª=&ˆ‡5&w}²sÚ£Žt+»¹‡4Û¡‰Æä29¹*"SØ·¤˜µgs]Sk];ՆȳbQ.«Éö)YÞÔ–4¦ÄPS @€ @ÀhL BhLG««%¹75‰2sájûµì*U’L˜®TµB\½•,LZФ\Šd]ЍK«šÛK¥?ø{ñªÅãªþjca 15¼ÔÔ·$ƒ›iý´¦›µZk§®äÀBÌ{ÂÓ@¾·JÊ·Ê¥¦j!9—µ´=]²’¦Ôùý¶ÈrƳ“:‡©Ñƒe·Ò:¹C|°qRŽ=̘ m’žsLâÑ£EDcÒ¯zrêe‹4ý(,B¹g•°ßcW§©Fm»³Ù†=eÙu&m;=¨öœúH;kÓŒt;¹=­ÙsZm6&ílKÝYúÕÉ[ö‘ÄZîr>©åµg³§/ÛÙe`BcêÎå©;9Kæ ¢1éÂgKuÚËþÆý©JæzCƒ @€ @È4¦Q0ÉÙHu74‰2}ÁªÜNT åXzvö2ç*ÕJK³_Ü Rë-=õBiñÓª•O¥1ÝhL S¢1µ9Ùý?S“Kž½õ^{© ?o·°"sQòº»CeúÂuîO~ò³;TÂKÈ]{Óí*fÛDþ à±çŸqÞ*åççµ»g-Ýrá•78]òágžvîåÓ_|¹’„©áBrÎõf*­·Îò@vÒ¥Áj•µ%u­?ä0 <Øüjâš«Ç.»õ©5µrö¸©}ö`£ÿãxrÞ–Ëïyññ¹[Z|°q¶fÌÝƒŠ“~ô޶%ú؆~µ‰uKJä1ëHï¸çð¤ø¸3»«’;•ÞÑÃŒö×n–¾È¤%«ÚÞ ·Íš>§•\íj°-Âkga£(ì Ûû¦%ÙI´³m˜3`ÕÙÜ>uÏfMr¹¬¬hLݹ¡1u‡#gI€.áZuñ ÿŸZ3ÉìN÷1&oêþË:D•€ @€ dœ€çÓ£çzúêCo¨’þ­öÃG³ß"ÅM“heÚ «j-¥r‚¥­®øñÏ>xäÑö÷ßV>óÏÇ=òôì@MÐöçŽûÀ‘G[X*îåýOš}Øa‡¹ÞóÞ÷M˜80•Y3.¢.•ü+{­^dÇfyßý·ïÓÏ3Φ^4×{òwÎÒäÁ}Mÿäg¾¨)„r¾ŠHú¥ÒÂU®hÞwþª`2æ}à#árÞå×Soÿ@‹Þþ‘g_¦rçCSÿç‰L3+Ó3¶ŠÜwκTeÚ²íA LšÖ$Í…Cјöm=4îÔC Çfü Jó|#`Ó¢•[À´ª´Ì}ñ¿rÊî[jËÉé÷Éó&™Ÿ¡/é÷þmî—®xþK—??ògs]*¦@c*¥m¸c´AM&ßPÓßZ;^Ÿ3mó ûÞè­ GÓôV5º!êÆwÖy—ª„…Ý[ïžð·ïý¯ºªH]Ò¨¾þæ;ëÜø6ï¿üš›ô~d9'Ýþ¾õ½sœOpćŽ~ð©YáÛœ¾*S^XûcY¡%äÎ<ÿ ÝF¯¹ñvgå꾦;ÝÀ-äãºÙ=LÿŽÒìãŸþ‚4\9Lóž÷iû{ç\¦X•UP;5IE_1ÝÎnÿü€t[ºa™ÆÔ$e _Ãv x¢1éJ¾ÔDž´õì­'ðê¿ ('[ªM¹TÓ´~Ž7»Ãœ‘gŸ}ᕺÔL[¸N—m|säÙ*G|è(»Úhã”ïž­¢ K¿ätI]dþñƒGéAúôó®ÐÆ—Nü†ì%=K¿ÿƒG-X³KåÞG§ë’òÃëǸgæ–’0…V[.¹’Q]²²ÈòW­°<È"Ë¿í=tû ±>ËaúôçŽíÙ°Ó=ØL]²ý„«¦œqËü]vÑí ‡Ÿ7éñy/—LnØsÚÏç]ùë%öc&®ÕƒÍew/>îòçn|xeÙÏŽÿÁÆòuëνԭsrž¼@cÊkä|o·þq,|a´”½z¹Är 5&K(g –Ew¢p.8ßÓ@€ @€j x®1IdÑ?&žÿçµ2“iLk¶(— D¤ìÿkiLóW†-%·­©fÖ²÷¼÷¿j^V3(*ÏÌ\¦m½£4K’–®ÿù#¾zŠ%[úö÷ÎÑ ®Mߪ(ÿ„¦R\ ŠË®&w5¿bS¹Í׌‹¨KVŽ ç¨0©´þÅnËTQk/…Ó/5[?®¤1)wEm¦ðp)CLÿNѼ¯› L;Ü2r˜N5©´Š\Ó"”Ö¢3iïËIqWAc⪘%æ0-”ÃTJNc É•&-$÷Ò>iL?¼o©¾×w>½þËW>/)p˜Öí~jþV9LúnjrTS}L{©’Š©ß Ù·?ˆÉ”¥`g²-Ò˜îê9L¥®Ì$iÚüU5·Â{àÌó.U kºyÝ;áiç[ïzèÓŸ;NCZ7ÁÅk¶éÞ÷ƒ‹®:碫l„Ož±Tw=íI1¨7Uî?Y>)㟚Ukè>ðÄÌ3Ï¿2P *K£ÊÊþO_üä?}ÑnmúŽÈ*ÐÎr¢Ô&4«@yu ĂҚŒº—é׿I˜*VAIcz ИÂ7¬¿ø«¿Q4¦Lö¼6Ê©t%‰>u»gl={ë ¼®±dÜP½`\$¡iðh½©ü\}éÕ7JW²´@g]p¥Ê]ã' ÿì±f/ÿ¯'Ë•¼ãþIÃÿéX»Ô|ù_N6QÒ\ÉÛÆMÔE&œìMöÒn¸Mê’iL¿.Y’úiÒT`*%P,_mÖ¬Œê’ÁÝ<œò­ì÷oël‘å}k—SÌÏÃæ0-“Ãdq)™Ùß¼~æV–ÿ£oßÝÏ®?þÊ祢N[¶íËW<¯rů—èr-nr˜ÆÏØ$\z°Ñãå˜LàÁ&’0rˆ× %grK³ ñTž{hL¹¡0]ÉÙGa5ÓeYj¨1Y.ßp6&[­ÓÎIñä#]ú @€ @€@#hLöÏ÷52“iL–6©ª”&H¬he꼕îת‰“—÷kÊö—w=dZ*M¢hû×=­_e)é_ð­þ­ŠÍà*Û„\%ç-)÷’&nÝÌÊCOͲ'|彿ž¢)–O}öX½íÏnלîOÎÔß…kºE?Ÿœú¢–º°¿WÑD‹¦[”šB&®i]ͲèMº<;o¶5Ëk“»šzÑŸ«èÏÇõëq'~ã¾GƒlLöç㚃ùÄg¾¨ ˜[ï}J‰+´¡_?ñé/êÏʵøNx2ÆiLn>fü¤ÿëˆ ûÔôó 'œ$iäÙ—ªÜ^јnøLÇ|ê .›…ì%m[9õÌKk&›nWczeíÚßÝ~r9Ü1OÛpÉ@»‡é¨a {·ºy>7áê¦ú4Ï'IS}WÝ»dÒ‚WJSy99iL ¸lû'Îôèì-úZ›õ”Z!ð¶ñSÉÉÔn\¼ÚßiLue&iLSç¯,ßC·Bw<óÜKUÂÉËÛ›_•ª;â+§èöçR.éNç¼%MrßrçCº£E<Ý÷üíûî?Yï[ŠAÝÑt³“R ›ÝïÌ^Ò­M·­°R „(áôK<»H75í³`ÍîÈMÓ/ï}êýøˆ².Y*A LA6¦’Ãô7ïù»/žp’eÔêòë~¥»’ngæàêËõ…ãO²[Õ»Þýwcx¾Jº]² É«¯O2õEc:÷ÒðÓud[ÏÞz¯{©ii!抺To‘ÊàR#iIËÆ™Ìd‹ÇéRS*W¨Ø_¸ ¦ö7_ú—oè:œ¾ô‡7ŒÑ£rpÁ)ÙKz`¾ça9L;ËSÉ•´˜Ìõä{+'aªv˜Üãq»ÏÿíYðû›Kày8p˜>{ìÒõ;Ã6êïðó'|»¶ëª®ç™É _‘BªÇ{¥b 4¦5Ƥåä”cRÓÈ›æþà—/ˆLÙaâÁ&™+µtSבrÂø Øj˜‘lLôÒ›¶Øe³EåôqXc’äÃ" –Çß j€ @€ @ oИœÆT-3ékŽóûç\f‰+¬„W”öé/h2F³¿×Ý2.˜’Y±ã]ïù;MÌ|÷ìKULc²µxþí®ÇeZ<2e…f‚õSïØdð?ù¤Sϼ$œ)œÖ¢õi›:SÞ®UÅn¯&]p¬Øâ²²•ÓÒ”æù*«hí•ÆtÕ½KõÕ¶ šö &MKS}çýj&Mø¹UW\Æ‚ ŸYIþÃd*ö@bï"SDf’Æ4eÞÊèm1ðtUWåŒs/QqcØmÈRÒMmÒô¥auI÷>ó–´ŠÓu?»Cª®~ ö`z[w=Ýæl '[ÎI‰—t/»ø‡?µ„(Òp{~ñ¸ÇgèWY?.P œ•û£ŸÞ¦”ß8õ¬ŸÞzÿßÓÀMKÈ•îh¥$‚º£­Ü©UPMcÒÏ»&LU‘}kw1•ǦõêöÌ /ékuÙµ·J½ÕÏÏ’-$g“³ ìV…Æ4ÄÉáµ<јΨ"+×]jžŸÛ«'ðÚKM$ÙR$»Û ÙLKÕ*˜t©‘½dê’]jL` ԥʥF®¤ŠK¿$ÝÿÆ_=Pºwäpú%]gô -WòÊëǸdoQ)¼`eUäê&a ìävµþ:SlÏÃe‡i]äÁæÉy[”ZÒ=ØØZrJ0ùÈìÍ–?OÓ÷,Cý¯Çøé/éÁFy˜T~ñij»,Ç$6\!sI)—a£Ñ°Æ¤ s¦!¹Üu­jLJÎäN$ ª»¹ï @€ @…" )âñðk)3ÓÖ[¿ý©UwŽÄ½ù×ïzÏss{]%·qσOkÖV¿º)ÛÒºÁªp𦕥䤥›ïxÐ2-s·%YAÅŒ%û+p[ÕBÿÄoù–lŠÅÒ,Y‘¤ ]ýtë阺äòRh~W½6ÝR^3(õAoJ` VØY»[³/šz9íÜËU4m ?×êT¶þŤY«ôÓÜÑt¯¦a4Ý«)Íøª(_…2I“1½å¿&×ìï×ýê·¦Z)ÙKý—ÿäV¥_R Íkú!ИκԒ0Íè f]î¥Ã;L3ÁúÕ&ƒoºã1iLVäiEcúäßÿU4##Ðû/‡yÔ1/¬Ø¾˜¸,¥\ûlÈ’Æ´ÄéÒ˜ÌaúÕĵ'];Có£ú2~÷¦97LèÈXPZåÊMvšÉô÷ü/7ÏùO&©P Ð -3wÔð¿–=ÐD8ý—¨ÔÞuû»ûÁÉ2™,¹ mó–´`œ2 Ú¯”uioxÍ8ÝÚ‚T(¥»ž$ÝüÐQ÷?1C?Ÿ›·ÆL>Kˆ2ö±î§»›³rÇÜ71¸ÙMmM à†îhAN˜ô¾3q•‡I Þ·[˜4¦pAÝÂÜÝJÛJ¨bÒí¿žrƯ©l 1êQ9KñFcª#Dºk‹ž½õ^÷RãR™ÖJKöŒm·Ôȥƞ®]*SY5N]¸Ô”®6îRc®d9ýÒšÝÊ÷fÐ&ߨüðú1z~V&]atyðé…Ú?ya‹“[j¹j¹ð"Ë%W²uIÏÃÑ Lq> Í9î°c>ñ™%kû]˜ìÿƒtñ×_5 ?o’]ê-Ù•hëyæáYÒ˜‚ ¸&%aCý¯‡&eiÒeY=ýø¹¦š›ÿ÷ƒ΃M+wó¶ö™°æ½oÿéÍ,]óß4¦üÇÐÛ8ûHÙ”ÜB™ZoN¿ŠI«SxE:åq’ å-P:@€ @€À æÞqèçÃý-ÿe}‹ë'G¬ÿ‰UV©H¡¢I”gç®'R²íË®¾QÓ±¶è[° ÜWN)[J%)–JS)×þìýúÔ´%á9•ž’±¤¹[›Sq3+JAüuø†àŸûµ!KI³¹Ay|ÆÜž Á’M´¨È[Òb:]õSû›æÛÆMÔÊqnºEÓJ¶dê’–3BÛúi“¦ 4㫟ÊTL«vZ¾ [9N“»NfblÆ4¦ðršôÕÔoyEŒÒ”k!9å^R ÍûêO¨å0©Ü6>Е\ ÙKV4üG|Ø&ƒo¼ã±oMczßß¾{ï“?}û‚¿¨èý½¿ƒßç/~Æú~àºaÃ?ô?~z®»˜„sÒè",$WIW0zü ûjßåó&ÙŒéew¿xÙÝ‹mmšŸNèýÎMsl99i‚úŠI Œ¤1þ¥÷_ö/OoüÔ3}Ã)pžXDÝ Î±½Þ³ãê¿ÿ‡*s·ú†ÜûLc ßu7t·?Ý u¿«¬xKºK^ò£ŸºQu#S®A7±­›]ÉÐ f¸ï¸¢Ô[s•©ô-ØSºÙÝ %×|§œ~î¦èîví÷ŸtêYúš¸l‚n!TÝÑdw´Š‰+I÷/»‘ÝñÐT[<®œA°¤ÞJÀÕÍë¶‚rêY—ªAéô_Ýÿ|Dº%á]'à‰Æ\Ijžº¢ôìœz_jÜu&üW•§ëŠ·z®vO×ö\mE¤2]¤2Õã´e6u—š«z›ŠV^¶Kr¼ýè†Ûì)ZEKÈé™Ù&Sÿ?ñé/\uý LºÎXÖR=0k»þr¡ LN`²;xvÈJéR$(­Ö%[_dy÷³w¼uÉ{ê?ßvü¡§¯îb9ðð¥ÃüŸîÁÆÅÅ‚"'û®gÖ›À$Úã¦ö}ùŠçíÁFHå0©ˆ¡®ÕÒ˜Œ˜ŒÒc/{îÉy[=ØüÓñGM[wã²í×ènEé =è‘àõ?níúuÌë¢1yþ|wÞiL£K/ëÌøñãMijUcÒ®R—¤>ÉgÒ‘îDùfCë!@€ @€@× Œ;5ú¯ù?9âPïDÕ£Eå>tÔ1ÑyË™T)šDyfΊð”‰ùIî¾+é%þø[óµãŸš)WéÎ&i‚V?%-©Ì[ñJØX RPT¦Ul×RPØäŠ[!nNÏV›Ð•¨tõOo×\‹&tµ}ã˜ôþ¬¥[LZÒ¼KyÁ¸Òô€å¥Ð¯þvÜ–½Ð$®æ]LcÒì‹fb¦-Þ¬eã‚©—’ºtåè1š€ý‹q¶àÎß¼çïlRAkîhVF“¾®h–÷އ¦Ø¢Vôε7•Q¡ŸÒ˜ôgå–ÁBsÀ¶xÜ1Ã?ÉoÕÜŒ&efÒÒWÿð¾µ4üÏ_Ö²uCÊÆô®w¿gÓö×7¿²§¾Ì´pl×Ç'„@80|øð “ç†sE¸k‚&üî|zÝü•;å-M|á[Å&ø.Ÿ7ÉfLo}jÖ[™¶d»¾•A6¦‡VT­ºšòT³¿z²¾*Û÷þáOï¼ÓAk9¤¨j•3éoP—µ¨ÜÀ-¯únh÷ÁÓ~pÉiç\¾ JT’°«Ië’¶{”Òo Ã=9Sc[Æ’o*KKòwCª®K.6te,)]Ÿ/iC‹¢ê[ðÌœÕÚA?¥1év^ÎÉY¹˜tG{è™…¦äÖÞÑô•‘º¤$‚³{ûϽl´¥_ ndN±•O©¤ÞÚ¨ºsÉ*8û’ëtçúÙÿÙ8w£Š»m…M&4¦¢~SRì—'“.&MžÀŸ™hLÕÙ•Ü“výLKîRö–ÂyL%-ézbËÆ)å’þ@Õz–¾iÌZ-NfI‹ÇÝú€Šý€Ë½¤{±®BzÀþå½OêùùØß0{Iº¿=9Ûc³®6_ûÖ™î™9HYº<0þËÏÌ|\Z1­e©õlLö<¬R_fŠáy¸ü`3©ÎƒÍcs_ÖóŒ²K>:{óͯÖöm“× bKZ˜&ÉÙ–`räMsõT#Ïéêû–}íÇÓ–“ãÁ&þËîþhLÝÇŒÆÔ}¦œ1!Nc²uá´"œeVÒ¿›©ƒhLò–üI÷=9_À*÷>9ÿó_>©ô—åÛ?6üóÊÀ¤Ÿ¿~|ž¦dä0i[嬋¯SÊ¢rnÚÆÉLº0”™)†i›Ü} hpFT&üæ„Ó°Y®Íó)QÊ•¿^âòÍè»|ÒOfXºÍ•^z×b™LÇ]öÜ%w.j´êJØaÂdÊHÜ3ÕŒ°Æ˜¬‘Ò˜J·¼è­ÐÝO;çbyºn ë~7_ôDcÒ•¤ÑuFW˜É³Vè <Ÿ—šêôKã?X(­Í L‘µb;xÞµÿÍà1øò÷Æú<ÜèÁÆþï¦êÁÆœ°&6¥Åõx°Iì’…Æ j4¦X°rÒô  1¥Z@€ @€@¡Hg)-!Wû2©VHªäL 2'ieÒÌåUZ’S”B~R#EÉM܆D¥´uu¥r"–jcÉ–`¨*-zK¥$.UÞ’ì¥ÞòÊÎ^ªQ—¢s0ÁÔoåïÈKöÒÀdÌ€½40û;T{ÉÍÜt¦1Ó6z½õf 3­R¨ñLgb&ðÆÞþÉ#‡©¼ö›¾HU/=7~ñ/F ½~›ðÿÔì°ÈèæùÊ_öòT_`¦Úaê/ça*͆NSª³ŠiÑÈajd2õí뛼qòлÃòE`ß½n ¹Ú–Kcš…Æ”¯ñŸ‹Öú¢1}qõÚÊå|¥vyѳ·žÀ»x©¸Ú´{©)=H7%뺒µé—:s%;ÎÆ¤»ùyXã^2Sƒçá®<ö´ò`SÎkUÊœ×TÎîüÁÆ}ÁyÂiñZ‡ÆÔ"¨övCcj{ç†SnBEC!@€ @È;iLüÈ1áÕmj·5‰2qÆòæûÔ(JU¢Ò€«T])ª+É[*ͬÔ1–*kèDçtKÐÍ·T×[ZYã-ÕɺTO]ø#òª…04SÏ^*Íþ.­Zp§õÄKu÷’Æ”÷JûÓ ÐÄUšwíH}Ú•FiÂïcÇ|â'g—¯¦-VlE·~M–—ª©ÎÃTv˜*_·æ“™Lý¯þ!Üøa÷ ëéïéJw8IaHcj~Ë3©êžXå*Õxº¡œ‚õ¤¥*C7|«Ÿu)âTßÚœ[^uyý ·t «£´ÿBc*ÌàÏNG<ј¢W’êå&u!ÒxÓKM° ¥•HúRËcZNíV~®îê¥&"J6X<.z©ÈTÚÉ£r|ÏÃÝzì l†Ul\ìÁ¦’„)È;èƒMkr¶=Ø xZÕ_`žpZ¼ ¡1µª½ÝИÚãÅÞ¹!€Æ”›PÑP@€ @€òN И>|L Éæb÷hå©é=n¦$²Q^ú­ÆOj¸\ÈUª«+Õ® WþÛå²±ÔPZŠæ[ªñ–ê­¬N¥Õâ" ÆUg]*嫈Lú–fb¬Lm?wE[bS|Ó6y½´?šÌ{dÄáJŤ ecš6j„Šì%«ËR4Õ¾¿âÞѶçÞõmXA{÷íÿè1Ÿ÷ĬˆÀTZo%ÈU0øT_;Óö½ø·ßqÐFNyø­‡xd„ÞÑöèù£µ=fé˜ñ«Êž–}¤|ÚP5½ i¨âçì.iLOM_ÞÄÍyÖ(•*{ Á0² jé–M+ØÄ[Ь…: %¢.…”ܺ« º„(ÝU Ü ©»#³‰€'Óȳ.n”©TW={ë <ÆKMéV[»ìrË—š†iÞê^j:ÈôyZŽéy¸³ÇžWæM¶ÇžˆÛýêþš˜=Ø(Õkéï%ì4Œ’Ë>uâWO6W©Qу͟Þx°i÷ Çžì!ÇÛ+S,¡GcŠ+'MŸSú1 € @€ xB ¤1},¬ÕnkåÉi=îýyY÷wÞáJ:¥FI•ܪp‘¹[÷kðýMŒ¥J¦¥ZiinoxI@Zª›o©â- ®.U’UD².% .…gnbš¶ñd„ÓÍÈU2Émh!9‰JzG†“~jÞNxÚÞ´öÑ1úÈ<'¥CÚªÑL¦±ÏtþbyJÕÖ¯)-þ¨/r g yª/ì0©‘ýû•«@•ä3I`:øÇƒšÉsù™ìS—Ï@S}Îpj«ìœ/Ҙ·¼Ú{¢iLun…¡Û_­®¤{_í]/t¿«– jR.EB ßÝʉ—ª³¡Ø¼¸•ºn\4¦|ð\´ÖiT“'p]ˆôžÀ¥&òD]wyÊÊšqeû?Xg¹Rš‹’ágæ¶$þÚã{n÷±gGÏòÖU´¡5éÂ_+3™ÜƒMD`*?ØÙ%»ð`S×ajý GÏ<ö`£G =ääââÐõF¢1uipB4¦X°rÒô  1¥Z@€ @€€'¤1}àÃsK¹ÕÝø«¿~÷ãÓ–9ýhðÒŸ7/u]¥Ì•D,šY±þÓpÛŽKµÒRdÆ%*-iö¥2Å[™€©J¹ToÁ¸à/¤ƒRYëaˆó1-ß´'ƒœn¶KÀ\%½¤%©X¦%éJÎR’Õdéšl7í¯)=Û¹])¨¥d2ÝûØÌ*©j!¹.LõE&Õ«©;›´ ÏÞ™º¤×œ­s,9“ö‘ؤ¢ý•±©]˜ìŸ;Ò˜ž˜ÖS{7,™IA.¥ïž9J¥Ñ­°C·l,UÝòêÝ隈¹ƒªKA6”¦+ÇuñF†Æ”»Ažý{¢1éJZLÙ®09Ûôì­'ðü]jªWŽëâ:Ëñ=·ûØãŠôØ#»6¥™Lö`ãRKV¯ÛoX`šŠX÷ò0Ù·»•'9Ü&j[ñ6!S,w4¦X°rÒô  1¥Z@€ @€€'Lcj®ý¥4¦©Ë5“–~«J§4°bEtéŠW©®®T›cÉfv#™–j¥¥Zo)ô÷â–£¢·TY0®”¬"u‰lLž|3ØM§"ÉR’“äì%½o‰—¬Íò–4g 4ÿ§÷]é Se“éÑ™aI±ü¥®Ìó¹©>ûV¶µäJ­Ã¤Fj‘8YJÚ¨$iI.?“}*iI3|¶¡¢ ÛW± Hcj~ËûΙ£T¦VªÉ&ØÈÐè¹ÍÝܰ·¹»U¥Bi°þi¬÷24¦b#Ré'SÝ+‰»¶èB¤'ð„/5•Çé: .‡Ÿ¢-µë¥&&©ÝÇ}#Â=»•“©ökR6™Z°©ü„ºÙñZr®­<áØZºö„£bOD¾Ð˜b :S,X9iúИÒ-€ @€ @ÀÆtäÇæ¯’lÔ°hå±)K„Ôh#økãÚRI§Ô(©Ry·´tTÝR«+…Œ¥òÚu2-ÕI¶Ô¦·Tñ$ZÌ™ßn1MÛx2Âéf»œ«äÖX1QIçQÊÙKÒ•4ig§µ÷õÓæðt¬û¨ÝzÍdºç‘¤¸"(³*‹d•¥ÃRº‚p:´§úê:Ljž[-N˜ô޲X6&­.§eæô«9LöŽ>ÒÏvûÅþ¹# é±)Ë܃DJß9ã"•ð­°ù½¯6›`d…¸ºnno©:•`MÖ¥*·”A0æÛSîyöì‹ÆtƨšKÍ@¶6={ë ¼þ߸çíÐcöP/55 SF²–6U—ÊÒ|Ã:sLÏÃ<öèICú5OBi&SäÁf SÉ:íìÁ¦ÑZrî«ÝÊŽe´CäsOÞ,ìá )– £1Å‚•“¦O)ýÐ@€ @€9S^ÆvŽÚ鉯dW’FEÏÞz¯ÿhØ¥¦6Á[(™Ø¥&¦çá{^™7YÏE.'e“o–™Lw•lœÀ¤ƒƒ͠S‹O8¶›o,ñdŽ®Ým*Swy–φÆ VNš>4¦ôc@ @€ @ð„€iLÍæHzé‘ç–JEÔFj˜N©’^Å’¬„Keî¶”y¥2}[w7ô¯ÿQc©vy¸*iii @D¥%%¨¨,ߨLgÅ4mãɧ›ù"`&Ó]¦›•h&b)WÁÀBr]q˜ò……Ö&I@Ó#Ï/Þ7(ºÍ}ûô‹TeH­ÔàÆWk, *-Eîqeo)ñ¬KnahLIŽOOêòGcrIIí NÕöðsKôÞÅK=H‡KäZ¿Ô¤òÓçá²ÉälL`êôÁ¦‡É“«D·º‰ÆÔ-’UçAcŠ+'MŸSú1 € @€ xBÀ4¦ÈI)T4‰2á¹%µR“wBr’ü¤:ŠRQ)˜_‰¦V2oi{]]©nš¥üJKµóÄ9¶ñäD7»NÀL¦;&L+µ«&¦®ç„Ò˜‚[^õ}pà×e©µ;ààznm*ÁÚ;]o)™ rŸBcâKÔužhL"£—šë?áÙ@cjt©©~ÒŽïR“¡”¥ù}6“鎇†ú`ƒÃÔõKNˆÆÕChL±`å¤é@cJ?´€ @€ OHcúÇ#?Vc™{T.šDyèÙk³%™Š)µê]çú–RÙUª] .ºtNh:ºR~Ò,µ˜œ)¿Ó6ž|‰èf× ˜ÉtûƒÓ¦Ö|‡¾–\×[Ë F@ÓCÏ.ip[ \o~¡J{·¿nnÝû]=i©bdò‡ÆT°¯@ºã‰Æô­Ó/ªc#YvÒ;ôì­'p.5îi9×ÏÃf2 åÁ‡)¦KS,`јbÁÊIÓ'€Æ”~ h @€ @ž4¦}´¹{¤I”Ÿy±®Ô mRdÑ·ê\JZ%ª´PTÝ20}[í*ù +5²šr=mãÉ÷ˆnv€™L·Ÿþ^à0u3'¬% ©þ-¯²Ó·N»PŶp,ÝòêÝõªîwy^ü‰ïQ× ø¢1Ù•¤AÑ…HOà-^gÊYÜ }©Éûó°™L=Øà0uý"ãNˆÆ [4¦X°rÒô  1¥Z@€ @€€'LcªYÔ¦ÊCú iLO/¶5ݦIl^¶±±”¢~R¥T_T*ežÈ¢9-fNŠc·¼OÛxòU¢›]'1™p˜ºN˜Ö%hLO¿X}[,ßþì&øÍÓ.T)ß» Öu• &æ¢1ñUê:O4&]I*—šª‹Œ]jÆ?½XOà­Øà0uý >!S,xјbÁÊIÓ'€Æ”~ h @€ @ž0©61RxFä/þêÝ<½¸¾‡d6’J%“DíÆÔ¥Z Çʶ:Å{KiPó©Ó6ž|›èf× 8“©Å©¾ÿxû®·úF@“ìú‹™–îw§|ÿB•F~’» 6¼÷-Ù6èe?_; 1ùöI ¿¾hL‘+‰{¨.mèÙ[Oà‘U&?f׿ï¿ý÷ì?Ëd:úcÃZy°ÁaJàò…Æ d4¦X°rÒô  1¥Z@€ @€€?d2)'“{=õô´.\n»çÁÈ;üš$±&Þ=î±æ5N›Û“ýi¾Sô´»¶mï—¥ÔDcÂaê.pÏ϶uëÖð=qêôY‘˯.Ⱥ,'yÈx]­<$¬}y“ç߬¶ºïƒÆôæ›o†/5Ú~|ÒÔÚ«MÆ¿þ 7oÐçá¹‹×æâyxÚÚ³Öþvyó¦¶.ïŒÆÔ1ºf¢1Å‚•“¦O)ýÐ@€ @€¼% ,>ͳžði.ÉÛ¯p!;®Ä-L&¦BF<;úÿ¿‹k~îI6¦ì ò ¶Ä©{sa7wßñŒ48ƒÏÃo¼µó×+þlê¦Mlp˜».¡1Å‚)¬œ4}hLéÇ€@€ @€ à-4¦ŒÌ» ±œ¶ñö;EÇ»B ®É„ÃÔ¶œ¤ 4¦!ÞŒŽÆÄ÷® 4¦˜¾wž6ƒÏ˶WÏa*{~ß[k2é¦$/hL±ÐFcŠ+'MŸSú1 € @€ xK©s<œ¶ñö;EÇ»E b2á0u ,çAcJþƇÆÄ÷)B€lLq\ˆ²öÔ!€ÆÄ°€ @€ @€ @€€wИ¼ ¹gFcJ7àûÞèUê–'Ö‘nÛ R;SAI7¢И€ @€ @€ @ðŽ“w!÷¬ÃhL©|ÚæêjL[LL½mEhS¢Hê@cbX@€ @€ @€ @À;hLޅܳ£1¥𺠙HÅÔµ¸ 1u %'Ê4¦lŃÖ@€ @€ @€ @ hL @¦Š  1¥ßU]›‰TL]‹ S×Pr¢l@cÊVmiP¦e›ÊgûÊØ±ccÌõO‹Æ”(n*KŽSr¬© € @€ @€ @!€Æ”‘@ÐŒ˜äKcz|ÒT'-ÙÆ6•’·¤ró­Æ4ˆÀ´ë÷USlÓ+“d¦*éåÆTÏa 4¦’ÃÔ\cZºÑ9Le©ÖajQcš¿ZS 1SDcêÝ9 1•¦æÓôŠÆ8Li SLßcNë#4&£NŸ!@€ @€ @€<'€Æäù(|÷ó¥1=6qª“–².•/½ñó_Þ)©nú%åaröR9 SiG9 Sçy˜Zu˜ö»_Ó#OM [J‘í’Ætr8ëR9ñRT]:ørÿë/ïx}s¨(ñ’+/mÿÔ¥{iÛïúBÓÆß¾&uÉJT`zåÀº­kɹ…äÖlÙ¿Z¥ÁZr-æaj×ajq9¹*ËÉ•W”[Ùj*¦™Ëw”KÏ L¥²ÝiLnE¹p*&Ó˜îºçÞ?üûÛ®üû[oÇû5;í°CãN· Î4 1¥A:!@€ @€ @€ *4¦TñSyìò¥1=üäóK)üëM¿4¦-i)šu©V] å^ ¯N¿˜œ½4¨ÀÔ, ÓËûWm~Õ­%ç’ÓÆŠMûV¼”åVúöõ”ËÞ„¦ËÉÍé퟽¢\f­¨¿œœ4&-'g“s˜¦-Ý^Ö˜J©˜Lcºñæ;ÂÒ˜¶ãåhLñòåì©@cJ =C€ @€ @€ @ -hLi‘§ÞdäKcšðÄó&'Õ–—ûÞtËÿòµ“µ$[ª‘–,÷RD  /Ur/5²—Âé—:˜”‡i••ÀÔ, SµÃ´,¼–܆½KK%XH®ÁZræa²Ã$i@cZº}ÀaZZv˜Ð˜’ùRS‹'И< 4Ý„ @€ @€ @€À4&FC± äMczN‹Á…Kxa¸o¹ã_¾zr£¥âL`ªï-iÙ¸•ã~'oÉJgé—ÂKȵ.0µ“„©ä0­Ê‹•²xÝžRÙ½Hem¹,\»;(kv/X³ËŠ–seþª]ZH®¼–\7&Ó˜‚TL &4¦b_Lè]ÂИNu€ @€ @€ @HŸSú1 qÈ—ÆôàÏmRF%+%-)\´ZÙ‰_=Ù½S6–BÉ–ò-µà-•/ýæµõ¯eÝ+Êeë­çÊš­ÖlQÙ_¶—¶ì—º4`/µ©žÀ¤åäöº$LK7–30u„©®Ã4µ¦Ã´r缕;çVŠ–s¥Åµä$0Y 4¦ÆSœ_eÎí4&ïBN‡!@€ @€ @€ €ÆÄ(6|iLãn@Nª^NŠÒOo¾ýįœ¬¨®TÊ´¤²q ”ó-ER.…׌«R—ä0uÉ^êÝôê •—öYYn¥OÞ’+­ LJÅÔI¦ÀaªJÂ4à0õî˜zûÍašeeù•™•2£g‡•é=eI“ò0™Æ45(ÛTä-EÊgûŠl³ˆïWì´Ã;5Þ*8;Ò €Æ”uê„ @€ @€ @€@ªИRÅOå±È™ÆôØsÁêoµ¥d)Ýðó@c ¹JËÃÕ.g Æ­·RÊ·õ–šªKíæ^jd/…¦½=»/0…’ë0 ÓŠ*ifE`š!©â0 ɕ֒“ÆTv˜j&ó™Ð˜bÿJS7И¼ 5… @€ @€ @€@…c¡Øò¥1=ðè³&$Õ9I×ÿÛí#¾ò ó“jKÄX*yK•uâlck4å’VŽs Æ5[6®ñÊqe{iSuî¥Æé—´œ[BnɆ½K6ì Êú=J¼äJ‹˜š L«ªV‘›Û~¦Àaª,$ç& L%iÛÔS±/&ô.ahL §:@€ @€ @€ ¤O)ýЂ8 äKcºÿÑgÃ~RÙLª$U-é_¿áR+U6ª]¥ÆÆR -5õ–VKWreóþU›_]Y]$-¹Rgå¸Ö쥥!{),0Uì%-$·{‘ÊÚrY¸vwPÖì–·äÊ «w¹2UãUäV¬"§åäl¹ÊBr’0 ,$ç&·œ4¦Ú…äÂï)Îo3çö‹À Óøñãûúú ÉÁƒG5räÈ9sæø‰ÞB€ @€ @€ @ XИŠOz%/iÜ#Ïi“”ÑÿvÛ ÿúò§õR+ITrEÆÒì7žúýsNüê)·ÞýK¶¤w>ó¹ãn½ë!IK*OÏ\6â«§¨h#ì-Mž±ôG}ÙÕ79oiÆ¢õGyôÄéKV¼T{©oߥ?ºñ’ÝØÓ·oê‚u=}ÁÊqÃ?{¬~†s/•쥽_þ—“~q£ôKN`ºèÊÞÿÁ£T.¼ò˜Ž;ñ?»°y¦ú óVîœ[)ò–\i&0-ß1£²œ[EN©˜ÂI˜‚ L¥$LhL\b ÐERÜÙ¤$ICÒ;ýýýöf3iòäɇ~xOOí:lذ1cÆèWmè£.6‘SA€ @€ @€ @I@cJ’6u%O _ÓØ‡Ÿ «H‘íë~hLöf%¯RtU¸ðÚpò®¸æ¦G&ÏÖÆ½ž–´ôéÏwù57=lï<ô´¼%mü⮇T´¡ÜKNZš0qö{Þû>½é².]võ’x|jÖòRÖ%yKVκàJ•°½tæWÊ[²âVŽ“½ôÓû_øÈy—_÷„iÁÆe£e/ýÍ{þN?¿ú­3¿xÂIw>4U?Gž}™¦w½ç﮽yìÏï~âñ™L—]{ëŽ?éöñS~pÉuÇ ÿ|‹“ÉLhLÉ…©±ÌDj¤1ÉpÒ§Í•ÓÇNc²m©OsæÌ‘…ÆTÈC§ @€ @€ @€Þ–À„Æäí5„ŽÇG ²¨ÜøÒK&’^ª´ I{['•‹/Zœ€ @€ @€ @ @cJ2U¤H _Ó=>]×F²7,éÄ“";”— ƒ ü¤ÚâR+Y‚¥å}ûTlÛò*•Ô¥òÂp2–¬HW2I?ŸŸ¿vø?+iIÛ÷?!©,-¹¬Kgœ…Šì%K¹¤RÒ˜vëW·fœt%˜L] — ®¸Á¼%•“N=ëûç^>Õ.­g‹Ç]yý§.Ùâqóž÷)ýÒ×¾u¦-!gê’~*ë’ì¥àgiå8+Ò˜ô޼%+Ÿ?þ$ÙKç\r¶ßõî¿û×SΘ¶tûÔ l J)åR“B6¦¿ËT]<áÄI}}}ÒÆŒ#“iEå D8“ —v«Ó=‚ @€ @€ @€@á  1>Äžw0_ÓÝã'×U‘ìÍk~ú+iLn·\t£$*M[°N¢’eWºùŽmû=û>K*J­tÊwϾóIÃ?{¬yKÇÿëÉw<0iéÆ Ç’ÊOÓ’ {/þáO¿ü/'«HZR.%­ç¤%—uéŒó®P){KëvK]’ƤŸr•ÆŒhkÆé¥\Ò;÷>:]+ÇýôÖûÍ[’Ã4ýÅ—µlœ©K¿¼÷I¥V’½”•;•uIÒ’Ô¥R¦©æ-IZºkÂÔÿuÄG¤.©Ü\Z-nÖŠÒ•ä-éç3/¼¤G§ö*ý’r/)Óôží²—”I嚟ßwï“óe/MšÛ'“©E‰lLž_Iè~œÆ¤5æ$0YZQN«Ãi£lLJß${I2“ܦþþþ8ÚÊ9!@€ @€ @€  1%™*R$;ɲ%Õ-Wßð«/x’[÷­f#ð“Ê¥d&IQ’œ¤|KRˆ~~ûx½#uIïœyÁ•–cÉ,éM• ¤¥=å²~ÏýÏ´$QéÙyktøíã&j[ïŒ}lÆmã&êyKJ¶èJëvŸ~Þ*ò–>ù™/wâ7f.Ý¢÷¥.YÊ%-'oÉ–ŠÓšq¿~dú„gjCY—¾þí³Þÿ¸ÄK¦.}ýÛgJZúÞ9—}íÛgÊaºâº_I]Ò;R—¹—†}ê Z-näÙ—Êaºöæ±&0éçe×Þªw¾{Vðþ¥×Þ*{I_9åŒSKïÜûÄüŸÝñø?ñ‘Sϼä_O9ýcÃ?ß<ýRäS²1¥ø]¦êâgc’€$ I2’6¬§ƒhLJß&"õÉì'^€ @€ @€ @€@~  1å7v´¼ùÒ˜îz`’[Ö­vCÓq#¾Þdû(Ȩd¥”TéÇ7ÞnÆ’Š²+=>åÅkn¼ý¹ùkci}Pî7Ñ,¥Hyô¹Å¶BœÔ%eZRyä¹E’–¤+=òì"­÷ÌœÕÚP²%yK*ò–T”lIY—ì§\¥[ï}ʼ%˽ôÐ3 -ëÒÄY+•xé™º¤b ÆYyrF¯ì¥[îy≽ºÔÛÿÀÄ–{IËÆÝñÐT-§rûƒST›Ö+{iFÏŽÛÇOÑO•ûžšÛÏß÷ä|9LÓJeÌÏË^*-¬7áùå·Þÿ¼J[“vFcjåKÇ>h‘@OOOxO­~g©Å:Ø € @€ @€ @È4¦‹¦v@ _SxY7ÂåG×SíûNQ’¥4QÉR+•D%+µ¢’½c®R¨Æ’J`,•¤%W‚åá\)IKr•ªJÉUrEÓ=L7o©*åR=uiniÁ8W¤.™·dêR©ê’Ф%WÌ[²b+ÇY1{)(eu)°—TÚõ–ÈÆÔÁ—ŽC ÐhL]ÁÈI @€ @€ @€ 'hLyŠmmŸ@Î4¦û'6ñ~8úViL­˜IµÆR#W©®®$o©ÖXTZ2{i¾JÅ[ºàòë§.Þä[ªë-­Üö–,ëR»êÒ ©KµöÒRg/êÒÐí%'3‘©ý¯ G@ ChL‚ã0@€ @€ @€ ä—S~cGË[!/©îânÎI’Æt숯×I Ó)U%UªÎ«d –ª\%ýZJ°TGW*¥\ §YrÛaiið|K5ÞR .UR.µžu©¾ºTJ¼TɽT²—– 5÷Rmê&4¦V¾tì®@cê FN@€ @€ @€ <@cÊS´hkûò¥1Ý6nbÔ=r‹»­Û}åè_{Â×k×z ¯ûV¸ê•àš¸Jt¥Pš¥z+Ä5H¶4··Y¾¥æÞ’– /תº4äe㚯:‡ÆÔþW# Ð!4¦Áq @€ @€ @€òK)¿±£å­È—Æ4fìÄh†¤PΤ+¯ûåOøzÝåÞ\"¥F¹”ä' ”ÒêoJ%ÁÒ€®¤4Kå…áBËÃÍ[¹sn¤ÔHK‘uâõ–föt¨.Å‘x©®Ï„ÆÔÊ—Ž} ÐhL]ÁÈI @€ @€ @€ 'hLyŠmmŸ@¾4¦_Ý÷T•ovÖìºBÓñ_«³CS-)¢+–’Ê*+;Ã¥ÊUª$Xª£+É^ªg,5––úg­Ø1kyP”c©ª4õ–¦k8W" ÆÅœu©QN&4¦ö¿‚  1uŽÃ @€ @€ @€ _hLù-o…@¾4¦[ï}ªIž¤+~òË/ÿ5·CYH2-iÀLªã'™«µ”B¢R}W©±®Tk,ÕfZª#-E׉Sî¥íÓU– ”zÞÒö©K·eɶæ+¾%ð)S+_:ö@W 1u#' @€ @€ @€@ž 1å)Z´µ}ùÒ˜~yï“‘ IîWIH—]û iLul¤°¢´r§œ¤p‰.ýV³ÜÜÞ~iIÊìÞ~)Já2k…²+Y)çXj-ÓRi©A¾¥ yK5 ©ý¯ G@ ChL‚ã0@€ @€ @€ ä—S~cGË[!/é¿~²‰u$éó_þÚ Z’YJ½*Íä$'-–R¨dÒR«º’Ö‰‹® 'c©%iiÚRKi)ù–š§tBcjåKÇ>è 4¦®`ä$€ @€ @€ @È4¦‚¯4?¿‚ïPGcŠ—/gOSjè©€ @€ @€ @i@cJ‹<õ&C ×S2ˆ¨%ßИò?Z߃€ @€ @€ @Þ@cò.äžuɳ€û×]4&ÿbîIј< 4Ý„ @€ @€ @€À4&FC±  1;¾ô И Xº@€ @€ @€ ÆИÅ&€ÆTìøÒ;4&Æ@Q  15²ô € @€ @€ @  118ŠM©Øñ¥whLŒ¢@c*jdé @€ @€ @€@cbp›S±ãKïИE%€ÆTÔÈÒ/@€ @€ @€ 4$€ÆÄà(64¦bÇ—Þ¡11ŠJ©¨‘¥_€ @€ @€ @hH‰ÁQlhLÅŽ/½Ccb •SQ#K¿ @€ @€ @€ Ѓ£ØИŠ_z‡ÆÄ(*4¦¢F–~A€ @€ @€ @ !4&G±  1;¾ô‰1PThLE,ý‚ @€ @€ @€@ChL Žbx¦oøÊ]?-vé×N;ìиS½&@ç J© ¥[€ @€ @€ @hL‰Ñ@ ÇИr<šÞŒã€ @€ @€ @Þ@cò.äÅíðä“ûöõ·ô õ 11. J© ¥[€ @€ @€ @hL‰ÑQ‡ßzxaúBG Ð*4¦VI±_Π1å,`4€ @€ @€ @C'€Æ4t†œ! F<2BÓÈÉ#•iÔôQÚ°bù™úök[úU{ªhŸ,4›6@`¨И†Jã3J)£¡Y€ @€ @€ @ˆS|l9s’ƯofÒ˜¥c†Ý7lÎÖ9ÿxÐågÒ¯¦1飞þmèW’d © ±@cŠ+'MŸSú1 € @€ @€ @H˜SÂÀ©.&NKR¦%ó“”IÒ’U'ÃIz“Šv“Ƥ¢}FÏSc8-’#€Æ”kjJ”S¢¸© € @€ @€ @Y €Æ”…(І¡±dëÇ9uI¢’e`²7¥.é§|&ÙK*ÚPЦ¡×Ë 24¦”@õq@cŠ‹,ç… @€ @€ @€@f  1e644¬-ný8§1™®¤“HW²OÍaÒ†Ö›ÓnúÙVì ,@cÊbThS 1u"§€ @€ @€ @€@¾ 1å+^´¶‰J¶`œËÀ4yãd¹JZcNkÉé§´eæ´­Ÿ¶ð/äžSîCHê@cbd@€ @€ @€ @À;hLÞ…œCE"€ÆT¤hÒ—4&† @€ @€ @€¼ pàÍ =;®¶2móñwõ6gë·Ý;úÔ t€@ 1 ˆt¡4&Æ @€ @€ @€¼ ðöŸÞ¿ê/e/Õ½¯O½ @'!€S‚Hê@cb\@€ @€ @€ @À«wÝRWcÒû¾  Ÿ~èé¿æ•×&ùÑWzé%4&/ÃîC§Ñ˜|ˆ2}„ @€ @€ @€@@ nB&R118ŠG@ºÞÜWN-^¿èÊИ %€ÆTÐÀÒ-@€ @€ @€ Ô#P›‰TLŒ”â@c*^LéQ4&DA  14°t € @€ @€ @õD2‘ЉaRHhL… + €ÆÄh((4¦‚–nA€ @€ @€ @ pB&R11L I©a¥SИ %€ÆTÐÀÒ-@€ @€ @€ 4 à2‘Љ1RThLE,ý*@cb(”SAK· @€ @€ @€ И€%d"c¤¨ИŠYúU&€ÆÄP((4¦‚–nA€ @€ @€ @ 1%dzbýú $’S!ÃJ§ 11 J© ¥[€ @€ @€ @hL ··÷¯ßõýŠGàÍ7ß<æŸùÎùG¯kôehL …‚@c*h`é @€ @€ @€½täQÇ<77ø‰ÉÄ0)9LŸþì±·Ý÷Øé?¸äꫯ.XïèÊИ %€ÆTÐÀÒ-@€ @€ @€ Ô# oéÃG {aÅ–ÞM¯ÎëyùCÁdb ‡€9L·ß÷¸†÷ŠM¯ž†ÉTœØÒ“jhLŒˆ‚@c*h`é @€ @€ @€jÓÑÃôn]¹ùÕÀóxißœe˜L ”‚¦Ï{ÇØÇWU†÷ò¾}§s19™ `º&€ÆÄx((4¦‚–nA€ @€ @€ @ š€9L Wn]õò~Ó˜–¿´¯§oß쥛ÉÉÄ`É;9LŸ1‡©2¼eéIcZ¶qï÷1™ò]Ú_K‰QQPhL ,Ý‚ @€ @€ @€@ˆ€9L‹Vn]ýòþr®šŠÆ$ÏcÖÒÍüÈ1K{–à y$Pq˜ž†wµ¥§á½tÃÞï}ñ•Wý(]£Í¨O‰‘QPhL ,Ý‚ @€ @€ @€@…€9L‹W½²zË€äa¹jzúö.ݸwɆ=3–lúà‡?¶dY&Óˆ#/½´1lذɓ'×EÞÓÓ£ê~Ô××wðàÁÕ¨máªG—^zgüøñêŽ^jvÍ£Š¡0‡éÎqO¬Ù²ÀÒÓð.%3iÉú=#Ϻø’Ë®j½" Þ6ÂõÒpmýðøötuÐ*Ôf}ûšï¦Þ zžXwp×Ú9sæÔ­‘/f4¦XÇ%'OSzì©€ @€ @€ @ñpSEò¨ZQÎI/®ß3ãÅ—>ÐŽÉ$ÑǼ½ä ɇ¨ëH¤Ðžu;ªÃÕ,ºB¨‘G>¹Ù!ò–Ô“«ÆŒÓÊ]i!'éŒ@Èa:ÐÄÒÓð^¼N&Ó¨ÖM& †ð¸ÍÎ`ÐàlQþSûý~¥®1¹‹€Ybj°»ª„‡_Ì詳KGežSæCD!@€ @€ @€ Ð)ÃT_ò0É$EkwO[Ô†ÉÖ˜Ô@çyHG°ì5£FÒûaiäÈ‘ö‘Þ×nR(tmD w·ö#D¢ƒ;vv¿ZzI«²´¡$.–PÇ* ·MïH½²wì´¶D5°: Çu“€9Lw{bíÖU©˜B &Z*¦Òß½píîïžÙªÉј4ŒñÆáÁfãG_ 97ü¬Ãnˆšê§3Ø>Î4r#6¬ÚI´g˜šÎ¯—$òE{í`'wûë§åé›bcÞuÊȨ̂Úö¸6X÷urk˜ë¯{'ÜÚÈi#_ô‘}=Õ$ƒãΣm™[|1«¾ê€b“Š:8‡ ‘Àê]·¼ý§7=‰s˜lx›¢wÓÃ+O¸jÊðó'å”]ÚÓ·/Þ‹¢Ã{Áš]'ýd††÷ׯî,½YËwh„³±ÉmÒïvZ;ÅÞl2„œf4hØ¡9ÈŠràª"€ÆÄ€È!S'íeÍ8Çz§¾Æ¾Hš6eRž£]‹¹ìæp0Ðd@€ @€ @€ ‚¨8L[á!½CåÖ§Ö¬¨,¶5ü<ÙÏ/ݸWÓͯ^¼n¦/]ñ¼$9Lã§oÒz[#6÷§z•ŠiÖŠ@ò˜Ñ³ý©Ùëßß8'SÁ±Ò½ø ÜÕsØøUÙ\f’ÃôéÏ{ÇØÇÝð^µyÿÕã–i„K¹“¢'OŠÞ…·-, ï™ÞZNîáY›¾|ÅóÊ4ö½›{íý˵`â5ãz¾{ÓKÅTÞ;¦/Û~Ê÷æd*÷^Ó£ç:ûÏ;uP̧Ѝ•”xEŠ‚ËñÖÊ!~íƒÆäW¼‹ÐÛð—ú‚+›­°i}“˜¤Å^µÑ0“ËÌf“[°VÇ„·‹€Š>@€ @€ @€ @ çÌaZØ»ÕRÔØ2[2<®»LnÇò—ö-ïÛ÷‹'WŸ~ó @€ @€ @€he˜žþµ­ßËÓK‘ðH»Èzâ%Ÿÿê÷^}ÚUч)B±ÓÖóß=¶ò Ó)Ÿ¼!v”‹Gl'˜RÈãÜ Û>þËù~[—vBy’é¼ ¯ßr÷I²zbLÅ0ÓÏúñs8è̶˜ÏË*ü;DmÇ&‰)¢—2LÑf,Êû3W~7õaJå}õÍ÷\ÕŠ1EyoÚ–Uø3"Æ”¶“Û²#:¥ Sí$ÓÀSŠ1ò„ß\|’A z1¦Fü|';ÂE)2H{cJ¹¥|§ÉâŽtñ[±ÍÜ jš2 @€ @€ @€º uÔQ§žþÏ©ýRJ/e{lµZÔDŒés_½ã“—}'ú0þ¹›OûÜÍ‘ðˆœGêÃ]j^vÊå‘aºê¦{â=cŠ„GŒsZ1¦!ÈyÿŽ3ÿœwÖµÿóÀè‰ ”(ðÑ­ÿË™çÿÅþÏüÓ妈1Eg¦Û² S´‹-ä¢JóòŽ S«Âc#¹,ÆåÛÉEŒ©+¥×É0Åç~qóÿûÿýçïvl–X2Ô\àÂãëöß#÷C`´@ôQŠ$R¾_dì+»Ë¥C¢3S|O†n*œâ‘XŠG:Ež‡Z½zujÑäA€ @€ @€ @€@µ±åÖa‡ö¡^E—:l¥5±ÁÖg7Ý ØH.5aúôÆ,Æ!7|èê´ÙV4ªI›mEÎcõwEÈãï?üõ·üú,ÆtýެS!äqÊÖpà!·Þqßí;ü寮vâ®ÞþäS˜¾~×úÕ®˜ã9çœó¢¿,/ï´…\êÀôÆ3¯yÕi_M¦(ïW¾ÿ«¯|ÿ¦¼¼ó Sì–xÔÉ—}ð ·DyǾŠGþãeíòînŦ}÷{ƦͷFyÿè¶~sÖa’Lç¾¼1ì&B€I ÌÏÏG)~MI¤Ý»wïܹ3’Hñ$ñ$¾ŒûcJMœòGä–â­fŠ&Lñb†šä|\‹ @€ @€ @€)ÉtÆG/Èãi­´‹\$<Ž›»ú˜w\;m¿ñö£O¹ü+›øÌ×1rKùˆÍ¶N=Û!Ç9ú0µ[1E†©;äQÌ0EÎC’I5–%PŒ1Lùù#Éô¿¬XÞ©Â#ÀtÜ™WG¦çÅH¦¯|£¯¼oÜuÁ•wD¿±TÞŸºâ»íäväÛÉ3L©¼ôÓ_þæ‡ÛzÃLbLe­ºó 0c‘5*&‘Rï¥<ž”wSÚiƸL— @€ @€ @€À ´“Lÿ|AÊv´÷Øjµ¨‰¦´‘Ü51n¹÷ê[ÒN[Y¦hT“o¶µqëÝ^uçÀF5ý&I¦).—šÝzŠ1 0åwI¦CV••w¾…\k¹TÞ}íΞòN{É-”÷¶·îLå}ù–=Æú3L I¦¸ƒb˜IŒ©fÅãvh˜€SÃÔt @€ @€ @€fT %™>ð‘ÏDû¥ï`ZØi«µ—\ôašß¶36ÛŠÇ7DÂãîhT! …íä†e˜F$™vÿ÷Ý3º ¦½ç£LùùR’©¯¼ïûz'¢ù¼vDoP†iã w·+<í–xÝ]©Ó° SW’)n"…™Ä˜ö|}A€¥ ˆ1-ÝÊ;  @€ @€ @€ÔZ ’L‡¶’L­öKíLƒ»ÔŒÌ0C£3L“Lk.[³î¦uµ–rsuxèW»–x;‘d:xÕQ ù¼îcň^O¦ñ2L½I¦¸Ë‡~¼Ä[õ6C@Œi 4‡ @€ @€ @€¨©@$™^pð Oû§O·ÓK·f[ÈeãæöFrŶ:}˜Ú]j6Ûê4ªYJ†iÇý?ÿõÃäÛؾòã+×{}¼²eç–ôk4gÊû3ÅÒ›wîÞ¿•YSP·U3³ÿé£vT^Þi“Ävy§&L}½® SÖilI}˜R†)ƃýªfn‡cjìÒš @€ @€ @€Àl ¤$ÓûÏþt¾ÇÖײxG!áqck#¹ö^r¶Z{Éíi¦ž S€Ï]7·âŒk¯ZÏ#Ï#š3û3ÅïÆoE»¦ø­x[žyšÍÅ2ë1"ÉtСGuåó:¦¼ SÏV‰Ùn‰QÞ2Lcp;„cš ¶K @€ @€ @€˜ˆ@J2½ïìó‹¦þ„ÇB—š’2L1¹h°ɤx2ç|zx’º.¥^Mé•ÔŸ)z2­ú̪‰¨¸Hs"Éô‚CÌÊ»;À´iÛ€ˆ^»Í˜ SsÖßLh¬€Sc—ÖÄ @€ @€ @€fY %™Þ{Öù±ÇV 0õ'<®¸áîÔ¥¦”>LI;,¥VLñktfJ/¦LñˆWRg¦x%ÒKù˜å•2÷ñR’i¡¼[=Æò&L#"zç~qó¾û=cÓæ[ómã>±—Üxëâ(ì€ÓÞè9– @€ @€ @€@}R’é=gžŸLý B—š®»ë’k³qÊÖpà!·Þq߈Gÿ^r¹B$“¢S|ý–¢3S<Éû3ÅóøÝÈ0¥0S:dý·×§FMöT ’L¾èÈÞòÞší“8,¢'ô§ÈÞO€I ˆ1MRÛµ @€ @€ @€LT %™N=óSWnݹ1F+ÞÑNx6’ÛÐ 0í}†)æé¥*Å“¼SŠ1ů‘^Šc¹ñ$LñÎø­ør¢(.Ö ”dj—w!À40¢'ÃÔ •7š) ÆÔÌu5+ @€ @€ @€I dúÐyy€)Ox\zÝB¦R2Lq¹'¥MåR˜)="À/¦$Sz%:6¥íçd˜ê^ D’éù/:¢PÞ]û$æ=¦½tv8& Æ4d— @€ @€ @€ P¥@J2½óŒóR€)F 0å ²2LUNÒµgX ’LÏ{á—o阮òîŠèÉ0Ípu˜:Ó$ Æ4M«å^  @€ @€ @€Œ'’LkÏ8¯`êJxÈ0Gê¨Z dI¦Cޏ´ÑK›$¦!ÃT«•r3! Ƥ< @€ @€ @€Ì„@J2½ãƒëŠ ¦™XûÙ˜d$™8äðb1¦ÙXy³$@ 9bLÍYK3!@€ @€ @€ 0Z %™NùÀB’)žpà!·Þqßí;6vÜÿó_?ü[õHI&}˜ê¿RîĘ @€ @€ @€(&™d˜fhágfªy’É^r3³æ&J€@sĘš³–fB€ @€ @€ @`)Y’éÀóŠãxÞAú0-EÌ{¦K ’LÏ:àEû>鉛6ß:¢ÍXüÖƒýjº¦æn  Ðl1¦f¯¯Ù @€ @€ @€ ð‹«?¹æ)ÿû­›.µ—œúh¤ÀÇŸÿ[›Ö¾R†©‘‹kR4X@Œ©Á‹kj @€ @€ @€†\sÎo^µÏ=7ÌËyì¸ÿç¿~ø|¦UàUû<ø±Wˆ1éÃ4­+ë¾ h´€S£—×ä @€ @€ @€ hŘ~³}þžýEÔC†IÕL½@”÷¹/¬ÒÀ$“ ÓÔ¯¯  ÐP1¦†.¬i @€ @€ @€Xš@O’I†iilÞUoíó¿Ùu[Üb’I†©Þ+çî˜i1¦™^~“'@€ @€ @€h¶ÀWO^½~õÊŸü`{Ï4·~líÝ[æóó$“ S³ë¡a³{èþQÉ·^0×?¯â‹Å$“ SÃjÀth˜€SÃÔt @€ @€ @€´"¨1¦ˆzô‹ôg›"Ét×}ýúáGð˜(ãˆ+}ÿ«ë{nøþom‰ß*¾˜’L2LÓ²²î“™cšÙ¥7q @€ @€ @€& D†éÒ5«bēԴ¦Øé3«V¤ÉG $^ÿΗ×ýG‰ S¼9½³É4æÖÈ*Eǯi6ñ$^¬áüõÑ‹ÎdñÊÀl_#TL‚Ó- Æ4Ýëçî  @€ @€ @€ øÕC»£!Mä“"±O¢cMŠ}¤GêU½š"Æ”¾ŒwÆ{âI|/Fþ ,: lþÀš¨çH,EIGÝÆ“x%vJïÅ“ôzÔyªçx#^‰×%™ê¼¸î™cšÙ¥7q @€ @€ @€† ¤–K‘gJ‰WJ)¥|Ä+‘íH»ÎÅ{Rì)! ¥gO®†K™Þ äeñ»¼nSͧ”RÊíEaÇ+©Y΋О–cS¸æn™æ ˆ15Í @€ @€ @`R‹š˜x$6âIjB“Bñ<õª‰Gz1RMñþx’ö¡KcÑLyŠ¢Œ£¶S…§Š:O5Ÿ‡ðRyÇ;SÙÇëù;ئh­Ý*³# Æ4;km¦ @€ @€ @€3$ÙŽÔr)oHÑ¥<ä½j¢™MŒxC´«‰÷¤½çP¼SÈc†je:§šZ.¥ø]j¹5Y¥h”Bxy § _¼}›Ò\Så{ @€@ÝĘê¶"î‡ @€ @€ @€@ ‘aJ½j"íÏSŒ#•RO¦È*Å“x=~7½žö˜K_æ»t•p+NA`R§SD—"¢uõœFªüˆ+ÅoEUǓԖ,¾Œßµgâ2,ˆS @ 1¦‚ @€ @€ @€@ÝŠ9¤ˆn¤/‹¿Æ—ÑÌ&~+F~ó=_ÖmRî‡@ˆöKyG¥0E2)RJ‘Ì‹O¢°Sy§HSÊóÅ#žÄ—Z1©"ÔV@Œ©¶KãÆ @€ @€ @€ @€ÌŠ€Ó¬¬´y @€ @€ @€ @€¨­€Sm—Æ @€ @€ @€ @€˜1¦YYió$@€ @€ @€ ° pÍ9¿yÕ>¿Ù>Ï„@3¢¼Ï}y3§fVh®€Ss×ÖÌ @€ @€ @€ cRÍcjöúš cjèš @€ @€ @€Ÿú«¬Ó®Û h ÀOweå}Á85S"@€@£Ę½¼&G€ @€ @€ @` @ì·9xàά¼/>©‘“3)4XÀ& ^\S#@€ @€ @€ 0D@ŒIi4X@Œ©Á‹kj4Z@Œ©ÑËkr @€ @€ @€ ˆ1)Œ ˆ15xqMF ˆ15zyMŽ @€ @€ @€À@1&…Ñ`1¦/®© Ðh1¦F/¯É @€ @€ @€( Ƥ0, ÆÔàÅ55- ÆÔèå59 @€ @€ @€ĘFƒĘ¼¸¦F€@£Ę½¼&G€ @€ @€ @` €“Âh°€Sƒ×Ôh´€S£—×ä @€ @€ @€ cR cjðâšcjôòš @€ @€ @€\àÖK~sñIíqÊ~óª}¾Œ×õ T¦X 8/ï ^Ÿ•÷ûžµðJ¿Ô^@Œ©öKä  @€ @€ @€”"ðÃmY¶cà8ë°R®à$ªˆ2VáQü P{1¦Ú/‘$@€ @€ @€ P–À°œ‡GYÂÎS¡À° ž”^…‹âÒØ1¦=Ñò^ @€ @€ @€S-00ç!ä1Õkêæ‹ƒzRzŠ„S" Æ4% å6  @€ @€ @€”"Пóò(ÖIê Ðԓҫú¸,M@ŒiiNÞE€ @€ @€ @ =9!f,«Yä=A=)=µA€écšžµr§ @€ @€ @€J(æ<„¼ÎSý÷V{¼’|WÍGñ.ûüõÅê¿øÑÈ> Ýõ_þ‡ß~ÔïÿÁŠüõâ'"=ÿÃ?úãôÃT±ÝuÛ*ݬnÛ¥ÛªÞþî­áV畼=«ä®b.ÔóO²znTÒYUg…UuVØÝµ}S§¶óòî­ðV‘wê¼»Ô¿•z»Ú|_Í·Ê>¯ü¼ø;õ¿«]ÿÅÀí@ßag|b\ÑñYxÞ xÓI§u}" Šø\¼ûìÏ>ûÙÏ^ê’{¦D@ŒiJÊm @€ @€ @€Lƒ@„?¢KôR 0eãÞŸEŒé}­S 0eAV dh†©c*f˜òäGÊ0å±ÞÀG+ÆÔõøn;Æ”2L­G'ÃÔcº®ìèÊ0µ"]¦þS'ÆÑ‰1¥èFWŒ©Úè1e&1¦å¬ö,ÆtÔ±]¹¥B­¦ôRTrJ/ 0õ–n'ÀÔÂ+%Ô'óºÂy½¦…ˆÞèS+«7,ÃÔíõåöǘRz¯˜aÊbL­ ßèÓ•}y¾b†i!ÆÔJõµƒ}bLËù¡pnj" ÆT“…p @€ @€ @€MH=lÚ¡¥vt©«“ÍáGf1¦¦¼MjÂ4¬Óè Ó^·bz`¡S+Ætmw7¦E[1å1ެS¡M;ÃTLoä1¦‹S7¦®VL­nLw鯴ŸŠˆ1Eœ.Å•ºÊ5Ë-µ£KQÉyû¥LKÊ0E§±¥µbÊ3L[:-Ç¢à»{‹µbjw +4!ëkÅÔiEÖÝŠiS'É—‡ùÚmÉúZ1¥ÓšèÆÔaÊ[”m¸V7¦åød8'Õ ˆ1U¿î€ @€ @€ @ 1ÅðÇÀM¸^zä±ïýà‡{:0 ØH®» Sÿ\û0 È0µ:Ö¤íäòœÇB+¦ÞíäZÔ lÅôl;¹îVLKÛQn@+¦ÖŽrínL­ÓÀå"®aS¹Ò?)Æ´PŸÅ ã:{F%ÓKùæqÅÎa…-äú:0 0 ÜH.ßqô^r£ú0-9ôØvr½û'ÆFŠ­‚·Ó…M ;ÊhÅtEkwÅa1¦´ÍbŒKĘJÿT8!õcªÇ:¸  @€ @€ @€Fô„?ÚÝk ;ǽôÈcÞóo×îžÈB¦b€iÇO&?ŠÉ}ëû?I{ÉîÃ4*ÃÔ·\ÖŸæ¶ÔŠé¾æH£ôVL…SÿæYí¸FĘæÎúçýô—ùøÉÏ~Õˆb©lcŠ8]O¥žÐRTr¶kw]êm¡÷Roz©ØBìö¦‡u``êjÂtg¶=b]›$f¦¥î%·L¦«o¾':¥qU¶£Ü"ÛÉ-¥S1Æ”ï±XlÅ”bLO_ùÌâç"žÿG©¬ª\˜eˆ1•¡è @€ @€ @€Z=á…üGD@Z),Ætú‡ïØ9*ÿÑþµ÷VW€)ïXÓõøÑ­-·ôaZ,Ãtmw†ió7ïMµÚûjÝrol§•ƀǻ6µÆˆVLcúßý½ó.þưVL׈Ó»O;;21ù½_?,®1þG®c:¦˜Rêj֪ը䔴ëÎÛ ¨ÛžèR1½T á ÜBn`¦b€iŒ&LQä[o`kÞil¡Â³fcCö’³Ó3LC·“ëô$‹BŒÔ‡)u&{Þ!íMå²ÓuÙ(¶bJ1¦}÷{FñsÏ|HÂoüÏ…# ¨ƒ€SVÁ= @€ @€ @€4D`xø£•ÿØùàKŽ8æÝ§ŸÝß{©þèé^³h€i`¦ÖFrí½ä ½j–!ÃÔŽ12LY7š¯Æèd˜6mkǘº6Òj…6Rn£cÚ|ÙõY7¦Bb£ÝŠi`Œ)27bL{óI1¦bJ©»ÁRÔjcJ{ÇÝæå:°nS’&ÏÞõô^*¦—Ší—Æ 0õïØ›Ï‹ S+Àã†4¶Gz)û£ÍX>R¿±¼åX×+n$—…öй½ÂŠYzoi}˜ö4Ãtù–ì³bLy+¦ž “ÓÞÔ¿c ¨³€SWǽ @€ @€ @€L™@„?ú3ÅW^1¦Bo¡,ü1rã­Û~ø“´…\!öÑêÀT0µ:Ö Üo«¯ S'ä1,Þ10Ø‘ö’ëëô„ S§ÓÀ Ó­Æ3cZ×cJ‰j¤ÑßIŒi/?cŠ8ÝèB-VrOËŸ…È]§t÷,ºôƒŸÄNˆ ›!vWr±ýRq ¹½ 0nÂ40ԘڽǺ3LùFrÙ^r7 ÝKn¼ SŠ1ý]Š1õõaJŸ ݘöòSàpê) ÆTÏuqW @€ @€ @€S)áþÌGþJ$–"ÆtêigEì#íùh7^úit¬ÉšÖ H/ýdPzi‘ÓbÉ=Ç;®ûv¡9Mg#¹NgšeÈ0u¶ÐÊcL]‰N†IŒi9>cŠ:Q¨ñ[©’Û1»BØ®·n£€˜o:‡õt]*6^•^ê¤ñÚé¥bS±;þõ¦­ó±Ð]lT¦®&Ly‘lÂTìÃÔ߄难-³ÓÈ S¾b<¹rk{lܺsã½äR¦4Ú1¦!&1¦åø\8'ucªÃ*¸ @€ @€ @€†Dø#(õ>ú©‹c¤Ž5Ñr)Æñ'½'k¹”í±õÀß¼ñÄY·>F–öØþ@JuDÚcËö,äã’¯Ýú„'ïû•Ö¯yš÷ùÉÈvÄxŒlÇ_Þü¬çãÕ¯?!¥:yñÑÏúÓƒžù§ECšñåq'¼+¾Œñ©‹¯‰ñèÇ<ö¿<ñ©ç­¿fÓ»^uô3þë bdŽm;OûÈçW>ç1^pØËVÿÍ›¯hŘ:M˜î¾¬Ø‡©ÐxFŒiòÅ1¦ˆÓõjO­F%w3Ì+6OÚuÕm§t{ö:Ì÷=Œ¬Rp$ðRË¥Èá}ê¢+Ÿó¼ƒ£€SË¥H)wáÆ(æ7¿ýݶúo².b­ôRÔs*é(ã“ßsVD‘¾ºõû]úë7œ# ûs—|#•tJ,åã³_ÙÜÊ-uzŒ}óÞ“N=3Š‘ŽÈsį¿øès¼ëƒçFn#6ÒzåkOyŽHr¼þøµ`zÇÎGd8þãcþàìO]ò/_ûÎ~ÂSÿ2bLí]äºL…ͳR\CŒiò¥žÅ˜^rôèBí­äVÀnDݦÄR±tóç­ìÝòMâ"º¡¥(ãvt©ÕB,ž¯»pã…—^q¥È-Ee7ŒK1¦O~þŠˆ.Å>q×Þ1¦bD×¥´[\”w¼I¦Î¶q÷ýÕëOˆßÊwŽË{/½úu'DµG‘ì‚Ëýû]¿ñ¦h¼u~Ù7îˆ&L‘^ŠöKÑo,ÒKÑr,~ÜRTû®¸1ê?ýzÐa/‹²âçQöÑ{ìßÚг…bO†oLbL“ÿD¸"È»1¥$ÒĘ" •Z1å1¦ /žË @€ @€ @€L‘@„?ò4Ÿ¼è%/‹ÓÀ´G¼˜š-åH/E¼#Û-.¢KÇeÑ¥Ô¢¦Ý{©Ðu)Õä»kEÈ#¥—¢÷R$<"ÞãßÌ‚1ò}µ"Àô¸'í˜Z;jŸ'RéH#òm¼éqO|jt`J[È¥G¾…V4¡YýÚãÓþq)À饔Þ8þ”3þò5onõaÚqÙõÙÈv‘+˜6\—˜Ä˜ª*ìˆ1EŽ.ÔþJV´ÃâJ©ŒÛ{Ãuž¤ S$–Ò>q­'Y¿¥,¥ô…+bĔƋS÷nq÷G=âó—g…ý¤}£—Ø_½á„‘Ì‹>Lyt©¸m\´\ŠwfåFgÛ¸¨ùOÿË5Wß|O¤ô^öò×D³±¨öW¾î-ió¸(ø¨öDŒéµÇ§šSÔ|Œ(øÞñ¡xåÃçoˆôRŒh<é¥h®K€Àr Dû¥|ƒ¸t­¥Æ˜â°ž S,Æ´Ü æü @€ @€ @€Ó+áÑi½øeÿðî¹bV)-u>¶?{lÅÖZ'¿÷ìbt)µ¨I1¦ÈyDò#¢ÿøî³òmã¢?MŒÔx)‹z´¢Kñžè½ÁŽ|ó¸v|ü‚,Æ”6‹©Žˆ.¥HÇ+ÿ6Æñ67Z.E˜#ºÑĈGl¡•bL±…\cje˜"Æã¬óÚ1¦ˆnœµî’ˆ1¥S;½QØE®'±¡Óä«=‹1½øe£ µXÉívJÝ»¼nû³Ji£Ã4:{ÃeON~ïYWZ÷…+R§èÒÂóÏgÅüìç#®ù¤-¥z.v]J»ÅEã¥(ì“N=ë…/9:k¹ãÖ{ãõ¼ëR;¥×I/E…GhéŒ]—¾¸ñ¦¨ö«n¾'ÕyYV怜ÇX|ô‹:O5äûëcŠÛ&Fã±Nï¥VŒé†»£ñXÿ€öK ßÀ߆NŒ¯?À¤Óä?®H€ÀÄ"tÔ“aŠK/)ÆÔŸ~J7-Æ4±Ås! @€ @€ @€©ˆøE1ÞÑQzaĘNýP;±Ô‰zô¤=¢9͆«o Sòˆ¨Ç6|#b©EMä<>É7¾|Õ-‘ÛÈZÔ´r±¯V{|ó¾g=÷ HxD㥬÷Ò­÷¾ðÅGG€)¶‹í´Rï¥gþéAúø…cŠŒ'›nø~4[ÊBKÜRöB=· ;byç|öòVã¥{S2/Jú3ÿòõ<º”vEŒò.6^zÛ»æR…§ ã"À•Ü[Þ—bDyŸwñ5Ñx)FÊêEŒ)~ýÈù"½ÕûÇÅæq©÷R<ÿÄEWgeßé½e饈1|Ú9­ÊÏÆ¢í— 0‰1MþáŠLF G±)\ÿµ1ÍÏÏÇ–âøô(&¡Ä˜&³x®B€ @€ @€ 0ñ¯lÅö3ýÏ#ÆtÒ»>4,ê‘g>}é1‘ÏÈÇ_¿áÄH{󗯉´GŒØ$.rKñkñ=­ ã²GŒ”íH#/ÍsQj¼1¦x#žD¶ãmèÒ3ÿëA±—V¤:b/­v¤‘ÒKñ$‚1âIJ/½îøµ±…Ü[N9#ÂéHãø“ÏˆGüÏŸþì<4ß¼yÑ“M媪ðˆ1EŽ.Ô!•ÜÊ' J)KéyWŠÒ¦b¹¦ø]´\Š|RŒx÷YÅÜRk{¸(æ4²’Žd^4XÊ«:j8bLQÛ¯~Ý ñ<ÂIíÝâ:­Å¢¼ÏÿÒ5ÙëOÜ7Fd˜ÞõÁs£È/Üxcªêøõ¨?ÿë(òÔiiÓ¶]‘[Š×ã×è:¡½È-EÁGû¥ˆ+Eañg¡½xž÷^zús^eÿ·Ÿ}"Þ|ò]íÇ|í ßÓKyÂϦrU}:\—eX»vmÄ•ò$ÒÜÜ\~¡ÅcL»wïÞRxlß¾=?¸ø|™nÝi  @€ @€ @€L©@„?úóÅWYuTĘòWz¢)ð±°C\¡?MOsšžGÚT«]Š„Gj¼TÜ6.u¦I;j]uSŒ¬'MÚN+ß<î’¯7E:bDÔ#¶ÐJÝh6fãîHr¤ý³bD†ã⫾Sì@“µ_j86ŒìÀ¤Sµå1¦¨ÃÑ…:¢’ÛEÛê¨4p\{ÛýíÖJ…îjVhö¥M·ôsÖB¬»žó­âRUçý–Öv¡¼ÛÑ¥¼Èó:Oí—Rç#•zOÁk>•ýô^ºî®aÛÆ~]Œ©Úψ« Pº@ÄŠI¤&å—ˆ×óçû”~a'$@€ @€ @€ 0³þ–íH¯G|äíïüP+¨48ê10í±hÎ#‹w Jxä¹¥aÑ¥bª£+ϱ- sD+š³?µ! 0ÝP0-Ä8vä[h`Ò©ªIŠ1.ÔžJn•k_Ñv§”†•R¯Pà =–Ú‰¥!¼!%¢KÅÂn×v!™W çõä–òˆÞBt©Uê…èRwµB{ôÒBÙ·wNìï½4nzI7¦ª>®K€@MĘj²nƒ @€ @€ @  þˆ0ǰaŽƒWõ¶µgô´VÊ¿ìŽzd{i-’óhw¦Yh¹Ô“ðȺ.eñŽB×¥Bã¥þ†4=yŽO\øµžöK)ÉÑŸ^ZèÀtížµŸùG=úÜ/nÑ™&ÚÒ¼û´³oßñ`>îܵû×?Ò„r©h)Æ4¢Pã·¢’‡UéÀ×ûRJƒ²J#z,uBxý–úCKýý–ÚÍ–ZµFªíöètÞu©]Ñxéò-“H/‰1Uô™pYê" ÆT—•p @€ @€ @€ ÈÂß¼/ýÙŽƒ;ê­kÏè¼Þ* ‹+uí¥µÐl©+´4$·´'Ñ¥Þn4];ÇwÑÊÓKí&4×íÙþq³JbL“/ûˆ1EœnH“¤vÛ¤¨ä!ɤxິ\Úå°Ý*,ÒÊÞ Œ+ L,õ‡–š- Í-umé¥+ E^Ü!±'·Ô³gÜàèRï¥=Œî-e›9›ÊMþsáŠÔA@Œ©«à @€ @€ @€"ᯧQ´ ¿uó=ýÜ•UWÖf)K,í*òÒóžfK~Kƒ·ŠÝr©˜Õ‹­vKl…ö–ÒH©”÷ˆ1MþsáŠÔA@Œ©«à @€ @€ @€"áÑ!zä §|pDÂc¡ÁR;çÑ×fx£'Þ1h#­ÑÑ¥Á—ŠIŽR"Å“ˆ1M¾ô³Ó¡GŽ.Ôv%ß|ÏÕ#I+9먔F__¥®ýà •=–ºxéËA‰¥Q¡¥N³¥=Ú*n!·ÔÕr©œfcc^Ę&ÿ¹pEê ÆT‡Up @€ @€ @€ ˆðGoË™<ÒÑz1¦·œüÁñŽÞ„G„<öXžð‘[ê vº.-]ZÖ&4bL“/ýˆ1EËÒ¥RTr_ip,iÀÖo©t ªzRJí2TêÍ*uº+ Ž+Mg¥%f˜âmbL“ÿ\¸"ucªÃ*¸ @€ @€ @€†Døãò‘yŽçEŒé¤Ó;ïÉz)-;†d;†µ¢éo³ûg-='Q“wŠ1M¾ô#Æu8ºP«ä¾ÒÒE)ª7—F2©gt† ,æ´\ŒšÔê$oCŒiòŸ W$@ bLuX÷@€ @€ @€ ÐsýÏŸwÈkN:-½> ÕQè@Ó½\aÛ¬Èv4¨ÓäK?‹1rÄèBQɃë6¯çB2©¯†ûʸA•\nÈIŒiòŸ W$@ bLuX÷@€ @€ @€ ÐûÊ7ŽøG¼ß³ž_xÃqǾrÐxÅqÇÌÆø·ÿî·;rõˆÉ>öþøÝ§}ûŽóqç®Ý¿~ø‘†TLÓˆSÔáèB]´’×m^̯8îØÙ(àeúœFÙï÷Ìç8yäœöÝïÅÏE<ð¡_UQP®I€ÒĘJ£t" @€ @€ @€§Ÿ~úI…ljo}ûß¾ñ-ÅñâÃùóW¼¦çÅYþòùúš×½i´À¦Í·Š1•øáºóÎ;‹UÏßø¦{–à¹Ï?x–˲ò¹/åÅY=_Œ©ÄÏ…S P1¦:¬‚{ @€ @€ @€h¦ÀÏùpOÎÀ—{/ S韖÷ÿ|ï×Å*Щô† 0a1¦ ƒ» @€ @€ @€À ˆ1-G°CŒ©ôÓrêäÏ)ÆTúGà ˜°€Ó„Á]Ž @€ @€ @`†Ę–#É!ÆTúGHŒi9 uòçc*ý£á„LX@ŒiÂà.G€ @€ @€ 0CbLË‘äc*ý#$Æ´…:ùsŠ1•þÑpB&, Æ4ap—#@€ @€ @€˜!_ü÷‡'ehüï¸{÷¯~d†Êhù§z÷ý5¾lfa‚bLËÿYq–W@Œiy} @€ @€ @`Æ"É=™FŒŸýâ×£ß0k¿»(È/õðŒUéÓXØ¢e¶èº,zoØ¥ø—^NH€ ˆ1MÜå @€ @€ @€ @€ècR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X@Œ©âpy @€ @€ @€ @€ĘÔ @€ @€ @€ @€ ˆ1U¼.O€ @€ @€ @€ @€€“ @€ @€ @€ @€ @ b1¦ŠÀå  @€ @€ @€ @€cR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X@Œ©âpy @€ @€ @€ @€ĘÔ @€ @€ @€ @€ ˆ1U¼.O€ @€ @€ @€ @€€“ @€ @€ @€ @€ @ b1¦ŠÀå  @€ @€ @€ @€cR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X`‘ÓöíÛ{n°ÿ•Šgàò @€ @€ @€ @€Ô[`gëQ¼ÇžW†Æ˜Ö¬Y³²óHÑ¥þWê=wwG€ @€ @€ @€ @€@õ«V­Ê“Hénú_cЬS™ŽY¿~}ÖÿJõós @€ @€ @€ @€Ô[`ݺu«W¯N÷}”æææú_‰ßÚ)ß<.Řâ­ý¯Ô[ÀÝ @€ @€ @€ @€ P±ÀîÖ#ÝDŠ1õ¿¿54Æ”ß~´ešŸŸ/Φÿ•Šçêò @€ @€ @€ @€Ô[`Ë–-+V¬(Þcñ•Q1¦h¿‰¥hâ”ÜÿJ½çîî @€ @€ @€ @€¨^ v„‹$Rä–ò[éyehŒ)މ#ãÝù‘ý¯T??w@€ @€ @€ @€ @€@½¢R$‘¢ƒR~›ý¯ 1E§Øˆ.¢KñH§è¥ÞÓww @€ @€ @€ @€T,0??¹£ø5%‘vïÞÝÿJÜâàSjÙ”?V¯^ÝÿJÅósy @€ @€ @€ @€j/°fÍšb):+õ¿“Ú©ötƒ @€ @€ @€ @€4D@Œ©! i @€ @€ @€ @€¦W@Œiz×Î @€ @€ @€ @€hˆ€SCÒ4 @€ @€ @€ @€L¯€Óô®;'@€ @€ @€¡÷ð5K¾IDAT @€ Ð1¦†,¤i @€ @€ @€ @€˜^1¦é];wN€ @€ @€ @€ @ !bL YHÓ @€ @€ @€ @€ 0½bLÓ»vîœ @€ @€ @€ @€@CƲ¦A€ @€ @€ @€ @`zʦwíÜ9 @€ @€ @€ @€†ˆ15d!Mƒ @€ @€ @€ @€Àô ˆ1MïÚ¹s @€ @€ @€ @€ cjÈBš @€ @€ @€ @€écšÞµsç @€ @€ @€ @€" ÆÔ…4  @€ @€ @€ @€Ó+ Æ4½kçÎ  @€ @€ @€ @€4D@Œ©! i @€ @€ @€ @€¦W@Œiz×Î @€ @€ @€ @€hˆ€SCÒ4 @€ @€ @€ @€L¯€Óô®;'@€ @€ @€ @€ Ð1¦†,¤i @€ @€ @€ @€˜^1¦é];wN€ @€ @€ @€ @ !bL YHÓ @€ @€ @€ @€ 0½bLÓ»vîœ @€ @€ @€ @€@CƲ¦A€ @€ @€ @€ @`zʦwíÜ9 @€ @€ @€ @€†ˆ15d!Mƒ @€ @€ @€ @€Àô ˆ1MïÚ¹s @€ @€ @€ @€ cjÈBš @€ @€ @€ @€écšÞµsç @€ @€ @€ @€" ÆÔ…4  @€ @€ @€ @€Ó+ Æ4½kçÎ  @€ @€ @€ @€4D@Œ©! i @€ @€ @€ @€¦W@Œiz×Î @€ @€ @€ @€hˆ€SCÒ4 @€ @€ @€ @€L¯€Óô®;'@€ @€ @€ @€ Ð1¦†,¤i @€ @€ @€ @€˜^1¦é];wN€ @€ @€ @€ @ !bL YHÓ @€ @€ @€ @€ 0½bLÓ»vîœ @€ @€ @€ @€@CƲ¦A€ @€ @€ @€ @`zʦwíÜ9 @€ @€ @€ @€†ˆ15d!Mƒ @€ @€ @€ @€Àô ˆ1MïÚ¹s @€ @€ @€ @€ cjÈBš @€ @€ @€ @€écšÞµsç @€ @€ @€ @€" ÆÔ…4  @€ @€ @€ @€Ó+ Æ4½kçÎ  @€ @€ @€ @€4D@Œ©! i @€ @€ @€ @€¦W@Œiz×Î @€ @€ @€ @€hˆ€SCÒ4 @€ @€ @€ @€L¯€Óô®;'@€ @€ @€ @€ Ð1¦†,¤i @€ @€ @€ @€˜^1¦é];wN€ @€ @€ @€ @ !bL YHÓ @€ @€ @€ @€ 0½bLÓ»vîœ @€ @€ @€ @€@CƲ¦A€ @€ @€ @€ @`zʦwíÜ9 @€ @€ @€ @€†ˆ15d!Mƒ @€ @€ @€ @€Àô ˆ1MïÚ¹s @€ @€ @€ @€ cjÈBš @€ @€ @€ @€écšÞµsç @€ @€ @€ @€" ÆÔ…4  @€ @€ @€ @€Ó+ Æ4½kçÎ  @€ @€ @€ @€4D@Œ©! i @€ @€ @€ @€¦W@Œiz×Î @€ @€ @€ @€hˆÀ¨ÓüüüÜÜÜöíÛó¹Æ+ëÖ­Û¹sgCfo @€ @€ @€ @€,¿@„ŽzrGñe„‘ò+1­ZµjõêÕk×®]¹råúõëã€â+’LË¿v®@€ @€ @€ @€ @  +V¬X³fMJ"¥ÜQz%ñJšáàSt`Êß±eË–t|ĘÒ1qÆx4AÈ @€ @€ @€ @€XNØ.âJé )w=•òW"˜ñ¤ø­Q›Ê¥ƒãDÑ–)¿ÕÈ3ÅÁņNË9 ç&@€ @€ @€ @€ @ !CнäòÉDi‘nLù[#ëœò-äR—¦xÄ“†Ø˜ @€ @€ @€ @€Ë/¦<´WK_æÄêÆo SêÚT|D[§â— ®@€ @€ @€ @€ @€À Ä.rGñzl3cJq§¼S<É·–‹`“Ó…['@€ @€ @€ @€ 0AÈåÑ£¸l4Qš››K× Ó¨S„–¢SÊ:Å#Ñ¥x’2Lé` @€ @€ @€ @€ŒH;Â¥R<æççS6)ÂLñˆ'ñJ>¸Sü^~dcŠããy£âÔè  @€ @€ @€ @€ °¨@dŠI¤ZŠ_£ÅR<Ò—ñº©Ü¢ð @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ ¡1¦õëׯ\¹rÅŠ«V­*^i~~¾ç•RîÃI @€ @€ @€ @€h¤ÀÚµk#‰5kÖ'¯Ç#½24Ʀ-[¶Ä;æææV¯^Þ½{÷îx=ÎØH/“"@€ @€ @€ @€ @ \èšq£ÈÅi#†´nݺtþx=’H‹Ä˜â°H/¥"Ì”ç–âDñºS¹Kål @€ @€ @€ @€š*q¥x¤ÙÛ/¥æL‹wcÊ]b ¹”ŠSYL55Õμ @€ @€ @€ @€(W m·sçÎ8mtSZ¿~ý’6•K7¤åâøÈ3Å1¦r—ÇÙ @€ @€ @€ @€4^ ÒGÑ~)uSŠStSŠ'K1¥ÆMÉ(މ/#É¿F**e›< @€ @€ @€ @€ 0Z 'Eâ(e˜â‘2Hñk¼˜¿¾Ï°SÄ[c¹þßÕIÙ @€ @€ @€ @€ °DèÃY¥õ¿ñnL}JY§ôHÛÉ¥Gœ±øåïÆÛ @€ @€ @€ @€˜AØö­˜DŠèRްxŒi½L™ @€ @€ @€ @€ª†n*WÕ ¹. @€ @€ @€ @€³& Æ4k+n¾ @€ @€ @€ @€j' ÆT»%qC @€ @€ @€ @€fM@ŒiÖVÜ|  @€ @€ @€ @€ÔN@Œ©vK↠@€ @€ @€ @€Ìš€Ó¬­¸ù @€ @€ @€ @€¨€Sí–Ä  @€ @€ @€ @€˜51¦Y[qó%@€ @€ @€ @€ P;1¦Ú-‰"@€ @€ @€ @€ 0kbL³¶âæK€ @€ @€ @€ @ vbLµ[7D€ @€ @€ @€ @`ÖĘfmÅÍ— @€ @€ @€ @€@íĘj·$nˆ @€ @€ @€ @€À¬ ˆ1ÍÚŠ›/ @€ @€ @€ @€Ú ˆ1ÕnIÜ @€ @€ @€ @€Ycšµ7_ @€ @€ @€ @€µcªÝ’¸! @€ @€ @€ @€³& Æ4k+n¾ @€ @€ @€ @€j' ÆT»%qC @€ @€ @€ @€fM@ŒiÖVÜ|  @€ @€ @€ @€ÔN@Œ©vK↠@€ @€ @€ @€Ìš€Ó¬­¸ù @€ @€ @€ @€¨€Sí–Ä  @€ @€ @€ @€˜51¦Y[qó%@€ @€ @€ @€ P;1¦Ú-‰"@€ @€ @€ @€ 0kbL³¶âæK€ @€ @€ @€ @ vbLµ[7D€ @€ @€ @€ @`ÖĘfmÅÍ— @€ @€ @€ @€@íĘj·$nˆ @€ @€ @€ @€À¬ ˆ1ÍÚŠ›/ @€ @€ @€ @€Ú ˆ1ÕnIÜ @€ @€ @€ @€Ycšµ7_ @€ @€ @€ @€µcªÝ’¸! @€ @€ @€ @€³& Æ4k+n¾ @€ @€ @€ @€j' ÆT»%qC @€ @€ @€ @€fM@ŒiÖVÜ|  @€ @€ @€ @€ÔN@Œ©vK↠@€ @€ @€ @€Ìš€Ó¬­¸ù @€ @€ @€ @€¨€Sí–Ä  @€ @€ @€ @€˜51¦Y[qó%@€ @€ @€ @€ P;1¦Ú-‰"@€ @€ @€ @€ 0kbL³¶âæK€ @€ @€ @€ @ vbLµ[7D€ @€ @€ @€ @`ÖĘfmÅÍ— @€ @€ @€ @€@íĘj·$nˆ @€ @€ @€ @€À¬ ˆ1ÍÚŠ›/ @€ @€ @€ @€Ú ˆ1ÕnIÜ @€ @€ @€ @€Ycšµ7_ @€ @€ @€ @€µcªÝ’¸! @€ @€ @€ @€³& Æ4k+n¾ @€ @€ @€ @€j' ÆT»%qC @€ @€ @€ @€fM@ŒiÖVÜ|  @€ @€ @€ @€ÔN@Œ©vK↠@€ @€ @€ @€Ìš€Ó¬­¸ù @€ @€ @€ @€¨€Sí–Ä  @€ @€ @€ @€˜51¦Y[qó%@€ @€ @€ @€ P;1¦Ú-‰"@€ @€ @€ @€ 0kbL³¶âæK€ @€ @€ @€ @ vbLµ[7D€ @€ @€ @€ @`ÖĘfmÅÍ— @€ @€ @€ @€@íĘj·$nˆ @€ @€ @€ @€À¬ ˆ1ÍÚŠ›/ @€ @€ @€ @€Ú ˆ1ÕnIÜ @€ @€ @€ @€Ycšµ7_ @€ @€ @€ @€µcªÝ’¸! @€ @€ @€ @€³& Æ4k+n¾ @€ @€ @€ @€j'0*Æ4???77·}ûöt×»wïÞÒyÄóÚMÅ  @€ @€ @€ @€ PKu­ÇÎ;ÓÝE$)O"¥W†Æ˜V­Zµzõêµk×®\¹rýúõñÖx¾bÅŠø2oªå|Ý @€ @€ @€ @€õˆÐÑš5kR)%™R)=R—¥Á1¦ø½xGšMäžÒó6ÅózMÑÝ @€ @€ @€ @€ Pcè—¦tƒ‘dŠG<‰`SÏ-ÚT.½5Nm™âI„™âŒñk:— @€ @€ @€ @€–.1¤´µ\dây¾M\œa‘S´_ŠèSjåݘbw¹x%N‘'¤–~ÞI€ @€ @€ @€ @€ÀÌ D€)m ;Å¥}áÒ6qIŠGŘâÈÈ0õo$©¦þ¶N3ëkâ @€ @€ @€ @€ŒH»Àõ¿'JiŠ×‡Æ˜Rú)õaŠÇîÝ»ó½ä"%Ƥò @€ @€ @€ @€XŠ@lþüóóó‘MJ_ÎÍÍ¥ßcJý–"Ñ¥xÄ»ã­ñJ¼‡ @€ @€ @€ @€ÙH;Â¥R<"Ãx%ö’‹G$‘¢§RÈ Ž1Å[ó#óSd›ây¤ŸÒvt @€ @€ @€ @€-1¦b)‚Iñþø5Z,Å#e˜â1tS9¾ @€ @€ @€ @€˜Œ€Ódœ]… @€ @€ @€ @€¡bLŠƒ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X@Œ©âpy @€ @€ @€ @€ĘÔ @€ @€ @€ @€ ˆ1U¼.O€ @€ @€ @€ @€€“ @€ @€ @€ @€ @ b1¦ŠÀå  @€ @€ @€ @€cR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X@Œ©âpy @€ @€ @€ @€ĘÔ @€ @€ @€ @€ ˆ1U¼.O€ @€ @€ @€ @€€“ @€ @€ @€ @€ @ b1¦ŠÀå  @€ @€ @€ @€cR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X@Œ©âpy @€ @€ @€ @€ĘÔ @€ @€ @€ @€ ˆ1U¼.O€ @€ @€ @€ @€€“ @€ @€ @€ @€ @ b1¦ŠÀå  @€ @€ @€ @€cR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X@Œ©âpy @€ @€ @€ @€ĘÔ @€ @€ @€ @€ ˆ1U¼.O€ @€ @€ @€ @€€“ @€ @€ @€ @€ @ b1¦ŠÀå  @€ @€ @€ @€cR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€Š†Æ˜vîܹfÍšU«VÍÍÍå÷Ï{^©øö]ž @€ @€ @€ @€z ÌÏϯn=Ö¯_Ÿît÷îÝ)›”¿24Æ´råÊ-mÙ²%Ž_»vmOâàâ+õž¾»#@€ @€ @€ @€ @ b覴bÅŠˆ+Eî("IiŠŠ'ëÖ­+¾28Æ´}ûö-¥¤wÇéâ×|Nñ†Šççò @€ @€ @€ @€Ô^ âJùvpÑM)ñJžMŠTRtfŠI íÆ”O0:0ÅÁ)Ì”Z9åg©=‚$@€ @€ @€ @€ @ .©S„‘"€1¤x¤mââ±HŒ)¢O© SĘ¢¹Sêé”vª«ËäÜ @€ @€ @€ @€µÈCG]J»ÃE¦´»\Üû¨S™o$—º1¥ÉŸ×~ún @€ @€ @€ @€Š"z”7NJ[˥ʟ1õ´\ŠôStcJGO¦<ÒTñü\ž @€ @€ @€ @€z ä-—ÒmFû¥ØN.=_³fMŠ4 Ž1EPiŸ}ö‰ãÓ#%¡â˜x’z:¥Ýå< @€ @€ @€ @€ 0B âFÑ>)O"ÍÍÍÅ›ãË#Å#žÄÖrñÊàSü^ì—?¶oßž®OâDÑ™ = @€ @€ @€ @€ˆÄQ1‰”BKñˆ>JÑ–)?|è¦r‹^À @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Â8ÎIV­Zµ}ûöqŽt n¨¥•­ÇÚµk×­[‡‡$°sçÎ5kÖÄG#>#ëׯÇB`ùÒ÷áø5¾ÏÍÍ-ß…œ™@.ÿ×?ý °zõj8FÄ·¦T* FLF þƒ˜ÿ e2Wt•:ÄŒŠ?Ås?Õa]ÜÃ0¨X/7 'dâ§MÅ“ ô|C‹¿jðã÷¬•‡OĬ­øŒÌ7¾•õÔ¶ïoÓ¸ô±ˆóóóùû §¸ˆñ#M€¤¿7+*MãB»g=©¶ãߺã/aüÑF…4O@Œ©š5¬‰pª†¾‰W]±bÅ–Ö#~‹º’djâ"›Ó D†)>ñWùGC’i°d(¶øÞ›Š-ýùaɇz#1òªK?ø“꘎3sXüuFü¥Fª33Ë^ÍDwïÞß ¢äR±ùÏb5ËPÑUÓÿZ“_<ž¿¬è¦\–ÀP¨Øø6h @ÈÄ7s8¿¡õÿ«?¨Yð‰˜…UžÁ9Æ £¶‹ÙŽøÒ_jM]%ô¬šŸpòŒÈÿö,>uëë† H¦ôw/ñGï¨öøG1\š$ ÆTÍjÆ7—”8©æò®Ú,â¤ýMq³ÖÖlƈ¿X,þ«I|ËéÆ?# ŒHqÒü-¥êe=U7+ºÄT øqª—oºn>~âêù¡+~*‹lÓtÍÂÝŽ' Æ4ž›£ªð|#äŘzpò¥â?jú0Uõ™­öºbLÕú»ú2 ¤Ï¿­Å_Ÿ¦ÆÏËt9§]&ø‹˜ÿ)ÌO8Å¿¡-¦ôâÿôÍ|™ŠÐi+èù¸Ï~%«à¢Ë* Æ´¬¼ƒOÿ±L? ÆÏçT°»dO7&½1·Â&4Ž€àGÍ1ã ôÔ›¸À¸ŽÛžnL"{`7“oíéÆ4“&=!q6!èZ^&V?í±›éy-ïÔMÈ|¿QbL=8éÛšƒ³ü½Ã¿|Ïòê7xîé¶ÏË;ýs•ÓÔ­x¬`ü¥PZM?áäË70´äÇ¿©+o7õçêf-¯ÙŒ)Ðÿg ¿1)¶žSÏž†K8·ØcaÍ=&›ít‰›íõŸèìóÿ 8ýÅqú»c-y&ºÕ]¬g­}ç©n)\yIþk“SNú_ãÅÔ¶$þòmIEæM ð×­ ZLSYHÿ)Œ¿2oqñý-þ߃Éd5È¿A¥ ¾ý„“¯Wÿ·níjj^ÌnoüeËqyó4 ˆ1MzÕâ‡ÂH/åWÍÿ<éûp½ +¶mÐM…À ô|w?‡¿÷îñé@`¤@1P’:¸ú{m%³ÜbLË-ܰó 4lAë<´Eq§K³Vçõ*÷ÞĘÊõt¶åð|ýÂñçô¿qûgìœâRA䯖ûãYÃó‹1ÕpQÜÒÞ äÿ)L=5ãï²|ÿß{ÕÉŸ¡ø *ug‰uœümÔðŠ=›\û‚®‘[ÚÙ²7zŽ 1¦I/Sü‡³ØDïœI/@¯WÜ"$žk9ÓÄE6§qRÓ»”gŠél 3¢c–&г½—ïÃKcó®½è©:ÿ”²Wš3p°Ó ,r¦ÿ¾›vÞIOÒ¿ˆÔèþÜʲ ˆ1-­/‹€S?kú[ÊÔÈA#½¢OÏR|–å3Yï“ÿüå_õ^+w·ù Ó߯‘bL{ÀW›·öü_îûì³S¾8)¢çjS­n¤L?‘–©é\µcšô²ôÿáGŠI¯Aã®—6kHÆM΄ì•@D—R?ä½:‹ƒ ,&àûðbB~¿|bÕù |߯1Zã»ã4n~&T;ø‡ðh¹^9òÚ­ÍrÞP,wñ[ï<ˉíÜ%ø51¾Ç¢áôàô|C‹/ý=C ©:EÏŸ¿¦êÞÝ,¡ùwûø¶–ÿþ0uÓóŸ$+س‚á㦮ªÝðRzþ¾”C¼‡Àt ˆ1M×z¹[ @€ @€ @€ @€ cj࢚ @€ @€ @€ @€écš®õr· @€ @€ @€ @€(ðÿ×Q’úšê÷IEND®B`‚rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/easy-ops.gif0000644000177700017770000002535712633765070031721 0ustar michaelmichaelGIF89aç„÷ $$$+++444<<>í::ó56“ZZ¢NN±JK„dd‰`aŸy{´ac¨prÝABÞMOÏZZâDDîHHñKKÖaaÛtwÞxzênqÿÿ ÿ /ÿ/>ÿ>{•zLÿLYÿYfÿfsÿsÿjtny†t|…y~ƒt~Š}‚…}ƒŠ{„“u‡š‹™„„„†‹„ŠŽŒŒŒ†Œ’‰“ƒŽšŒ’•‡‘œŠ““””‘–›”šžžžž§Šª‹Ž¡šš£»œŽ—£Ž˜¤– ”›£™Ÿ¢“¨¡ž¡œ¢¦—¡­¤­“§·¦²Ÿ¨´“§¹œ­½£££­¦¦¢¦ª¤ª­«««·¢¢½¢¢¦½¦ §°¤«´©®´¦®¹¨¯¸«²µ«²»µµ¶±¶»³¹½½½½Ç’Ûšžæ„î®É®®Ø¤¤Þ©­Æº¾Ò½½à¬¬û¥¥ôµµÿ²²÷¸¸ŠÿŠ•ÿ•ŸÿŸ§Á¡«Æ§©Á©±Ë¬±Ä·³Â½©ÿ©²ÿ²»ÿ»š®Â¡³Ä®¶Á®ºÄ¨·È¬¼Ë²ºÄº¾Ãµ¾È¹¿É½Á¯À͵ÀÀ¼ÂƵÁ̺Â̾ÈÌ¿ÇÑÃÃÄÄÆÉÆÉËÍÍÎÜÇÇÑÇÌÃËÕÏÏÐÆÎØ×ÏÓÇÐ×ÉÒÖÅÒÝÌÕÛÔÔÔ×רÑÚßÚÚÚùÃÃÿËËãßßõÒÒùÖÖÃÿÃËÿËÒÿÒÜÿÜÔÝâßáâäääêææëëëðîîäÿäìÿìôôôýóóôÿôÿÿÿ!ù!ÿ ICCRGBG1012ÿ applmntrRGB XYZ Ù )2acspAPPLöÖÓ-applrXYZ,gXYZ@bXYZTwtpthchad|,rTRC¨gTRC¸bTRCÈvcgtØndinì>desÿc,ddscmBmmodÔ(cprtü$XYZ `5Ä*XYZ o‘³còXYZ 'Dó³ XYZ óRÏsf32 BÞÿÿó&’ý‘ÿÿû¢ÿÿý£ÜÀlcurvÍcurvÍcurvÍvcgt) ºvPEa”ÿÝ A º 9 ÁWèvþyæJ›ä6Zy ˜!¸"Ù#ÿ%"&F'j()»*å,-C.r/¥0Û23I4…5Ä78E9ƒ:¿;ë=>:?Z@{A BÅCæE F.GQHqI’J¶KØLûNO:PYQ}RœS»TÚUúWXDYoZ¢[Ô]^4_d`‘aÁbòd"eUfgÄhýj;kl¾noOpqîsCt•uðw@xbylzr{y|ƒ}†~‹Š€Œ‡‚}ƒx„h…U†B‡)ˆ ˆì‰ÇŠ¡‹uŒJ玳€V‘-’’Û“²”ˆ•^–2——ÿݘ³™‰ša›8œœçÁžœŸx U¡4¢¢õ£Õ¤¸¥Œ¦V§#§ò¨À©ª\«+«ø¬Ç­˜®h¯:° °Ú±¬²}³N´ ´òµÅ¶”·c¸3¹¹Ðº»M¼¼Ä½‚¾@¾ÿ¿¾À|Á=ÂÂÂÃ…ÄLÅÅÛÆ¥ÇqÈ=É ÉÛÊ­Ë€ÌSÍ%ÍôξψÐQÑÑâÒ®ÓwÔ?Õ ÕÕÖ ×lØ9ÙÙÕÚ¤ÛtÜDÝÝéÞºßàcá6â âêãÂä•åeæ1æûçÉè”écê6ë ëèìÑíÆîÆïØðÿòBó™õ ö¤ø\úFüeþ’ÿÿAäqÓ·°Çÿ÷= •  u ô}‚þnÏ*x·æ(H d!"¡#Å$ä&'((F)o*“+¸,ã./70d1Ž2¾3ð5$6S7Š8¼9ë;<=5>H?X@nAƒB–CªD½EÏFáGòIJK)L:MINWOjPwQ„R’S¡T±UÆVâXY#ZC[a\]Ÿ^¾_ß`ÿb!cJdoe—fÃgôi"jUklÆnoCp~qÄrütuvw#x'y(z({'|&}"~€ €üî‚ރ̈́¸…Ÿ†Š‡mˆS‰6ŠŠ÷‹ÓŒ«…Ž[3 æ‘À’š“ÿr”P•-– –ì—̘®™šu›[œC+žŸŸî Ú¡Æ¢¢£m¤=¥¥ã¦µ§Œ¨`©5ª ªå«¾¬š­r®K¯%¯ÿ°Ù±°²Š³c´8µ µà¶´·ˆ¸^¹3ººØ»¬¼½S¾%¾÷¿ÊÀÁnÂ@ÃÃçĹůaÇ5È ÈßɵÊËdÌ?Í$ÎÏÏòÐÝÑÈҴӜԃÕjÖR×9ØÙÙïÚØÛÂܯݛދß}àoáeâ[ãRäKåFæDçAè?éCêJëRì\íjîzïð¨ñÀòÚó÷õö<÷_øƒù«úÒû÷ýþ?ÿAÿÿ^Ã6®>äÿšc>*  " $ , +$ûÚ®v8ùµr0ï¯n.ð³v;Ì–a / û!Ì"Ÿ#r$E%%ó&Á'„(>(ú)´*n+++è,¦-f.&.ç/¨0j111õ2º3€4F5 5Ô6›7a8(8ð9¸:;F<<Ú=¤>n?7@@ÌA—BcC0DDÎEFoGDHHèI½J”KkLDMMôNÉO•P\Q#QìR¶S‚TQUUðVÂW–XoYFZ!Zÿ[ß\À]¡^ƒ_i`La5bccèdÊe¨f†gah@iiÿjàkÿÁl¡m†nkoOp7qrrîs×tÂu¬v˜w„xqy_zI{1||Ä}ƒ~EÀ€8ò‚¬ƒg„"„Ý…˜†S‡‡ÍˆŒ‰JŠ ŠÎ‹ŒRÜŽ¡ZË‘„’A““Á”„•I––ß—®˜™Yš3››ðœÔºž£Ÿ }¡o¢a£N¤2¥¥ê¦Å§¡¨~©_ª?« ¬¬é­Î®³¯ž°‡±p²[³E´0µ¶¶ð·Ü¸Å¹®ºž»À¼ä¾¿À3ÁSÂyèÄâÆ*ÇÈìÊpÌͿϤѴÓ÷ÖyÙZÜžà“åNë¤õJÿÿndin6ÿ™VÈU‘°'‘`P T9 =úá&f,E_x‘«Åßù0Lj‡¦Æç .T|§Ó5j¥ä$g¬ó;…Ïjº ]°[°  a º  q Í * ‡ æ G ¦ l ÕDµ&œ‹ýzú{ÿ… ‘¥2ÂSâv ¢:Ólœ1Ç`ú —!4!Ô"t##¶$Z$ý%ÿ&B&ç'‹(.(Ï)u**»+^,,¢-D-æ.‹/,/Î0z1D22ù3×4³5˜6{7g8Q9C:=;3<6=?>J?`@{A¢BÌDE9F~GÈIJQKLÔNObP­QþSOT¡U÷WJX£Yý[U\­^__`·bcldÃf7gÁiBjÈlSmÚoipør…tu¥w455é6Ñ7¾8«9 :˜;<‘=“>›?¥@µAÎBäDE$FLGwH¦IãKLbM£NæP+QqR½TUJV‘WÚY"Zn[´\ü^D_Œ`Óbced¬fg™ijlmŒopŽr sŒu vxy›{#|´~@Ópƒ„²†U‡÷‰ ‹OŒüŽ­`’“Ñ•Œ—N™ šÌœ“žV ¡ä£¬¥t§:©ªÂ¬c®¯§±R³´¯¶i¸%¹á»Ÿ½d¿$ÀèªÄnÆ+ÇïɨËcÍÎÒЋÒ@Ó÷ÿÕ¦×WÙ Ú¹Ü`Þß­áOâíäŠæ ç²éJêßìpíûïˆñò¥ô0õ¸÷GøÖúdûýýŽÿÿDj‘¸ß2^‹¼î$^žâ,Ü>¦ójã_Þ`á g î y  ¯ C á’Eþ¸t3ô·~C بzL%ÿÛºŸ‚h Q!>"-#$%%ø&ñ'é(ß)Ý*×+Ô,Ñ-Ï.Ò/Ó0ä23'4H5k6‹7¯8Î9ò;i?…@¢AÂBÝCþEF=G`Hÿ…I¸JíL)MaNšOÕQRQSŒTÉV WDX…YÆ[\I]Œ^Ð`aZb cîeBfÑhrjk¼mfopÙr”tRvwÙyœ{\}"~Þ€¡‚d„$…æ‡Ç‰°‹›{X‘0“”Ζ•˜Vš›ºgŸ ²¢R£ï¥ˆ§¨´ªY¬­Þ¯¨±t³=µ¶É¸ºP¼½Ø¿”ÁWÃÄÚÆžÈeÊ(ËôͻϋÑ^Ó"Ô”Ö ×‰ÙÚžÜ$Ý£ßà‹áñãLäåãçè@ébê{ëƒì…írî]ï7ðð×ñŸòWóó»ôXôöõ‹öö£÷(÷œøøƒøñùRù´úÿúxúÊûû\û¥ûîü7üvü¦üÕýý4ýdý“ýÃýóþ"þOþzþ¥þÐþûÿ'ÿRÿ}ÿ¨ÿÔÿÿdesc Color LCDmluc nbNOèptPTúsvSEfiFI daDK0zhCN LfrFRÿXjaJPnenUS|plPLŽptBR esES¸zhTWÊruRU$ØkoKR üdeDEnlNLitIT.Farge-LCDLCD a CoresFärg-LCDVäri-LCDLCD-farveskærm_i‚r LCDLCD ÿcouleur0«0é0ü LCDColor LCDKolor LCDLCD ColoridoLCD color_i‚rm²fv˜oy:Vh&25B=>9 -48A?;59Îì·ì LCDFarb-LCDKleuren-LCDLCD colorimmodœgÁ´Å1textCopyright Apple, Inc., 2009,ç„þÓ H° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹3jÜȱ£Ç CŠI²¤É“(Sª\ɲ¥Ë—0cÊœI³¦Í›8sêÜɳ§ÏŸ@ƒ J´¨Ñ£H“*]Ê´©ÍsÅÚD(0@@ lƒÈœÓ¯9-@¶¬Ù³ Þ€Ëö¥´ÎÊKöÀ¤¶xORÛ@·/]pò þ(ÎÄU¹"´NœWpÃÚt(@WÀ˜Á˜1¶‰{V@c ¥10w¢Ì¨!J; ×!¯£E8löèÔ¸š¡Mv@`‹à Ÿ °A\îãéÄ)nf£¸¼±žFŽzØ´k;J[~¶qê‚Íþt&$Òe³ȃgk.ÂÙÙGŽ‘»öz¦àH›52šþ² sßRÆ\W–w©´›Y\6àQˆðV5-Es^Y |÷ P♥€},™ÓÁY¸!P|™5AâH3Ì$ˆX†$MÂYYmœØ“9Ü•õF:ÔÀ±Á…)`Æm"ÚY€¨cMà)"m,éz&H3Òg å“5Ec`o³]éWÓ„È&˜0M›Ut@À 8€Ñ™U@‚IóYü œ'µ1Ü\Œa‰“IÓFl–u€% µ‡éD€‰ˆŠ4¢_ŒßBæb¥‡~Ôoþ*9”i¨‰“€_€QMŠ 6÷‘u ª7*…âÊ‘4Dvf&D€ (!H.MrPÌGù5"gª,FröeÀ˜t eCìJV·bt,YÑÙz.F\ÖiæYd›!• kGpô¹ß¾…ûïÃdÇ8îûQ1øE âplè¤cˆé“}(eó>AéÏ*Pýö§c>ý9y+ê>yz¾”¶A@X1ß8̱À2Ð1â Æ(pˆ£ã‡˜Áqxðƒ¡/È@Dï‚'hÞ 8È@s\p„ŽÁ` GøAÎ0†5ä ׇ¿¢Tþ¨ÛA4e âþ„ôP‡5¤ è‚@€‹õ…h ˆˆÌ‚6…¸P%8àÊ5ƒ €ÀC2ôÐ?@B¹p/-Œ^,B˜ÄüÃú >x Ç,ƒ3Î/Ps›*À&ó¾±ÍmÊÔ 4•)9§‘΢®³ïœÅ#‘‹[Ìb’€>eÉÏ:¤! (%.ˆ˜%hªÁ[FWõ…c¨€À€€@"ÐÂæÊ…ºžá®KTƒØà78ñ x(Ãò‡ÁÂyàÃøÀØÆ2¶|èƒt*?D²ŽÍla§@Ø7Àá ^ÀÃüz‡½¶Á•x-úÀ….T ˆþ­* xà O̱ªADWgA`YÍ\L€ lÁº†:è¡€`D# ñÔyæ"À†0„áÎd°#˜F1̉Îi˜·šÓè©7xú ž!z;X¯|yš^ôzüE%jQIP ¤¾Sº¸.-œzÏF4"zÀƒ¬º… d0„7>yq°‹{ ¹Œh~ÃPC2°Ü)àá¹€D#îùTEæBÛån2–±Œf@ƒÐ@…9Óyßóª·š<­f ¢×‚Ù¼ú=§:EŠ`,ãÉ0ìT¥>¢ƒ¥ìpÕ.0€ ØB¨Aá£xª,8ØþC^å2©EШ܅:8ºÄ=%a]ìjWÆ4~Æ3p\Ts"Ù¾Fö'tªMõÖ×¾H&ª~Á vvw»SnªS%qeªêaÁiÐÂ0‚ ð̺ý‰ÌÊ7ˆdÏ,  úÞœ¬r¹apî> ü>Ïó/Žqwkì ×bdžFoÕûi´@§.€F¢ih ÓÅæEwÝ©]`\÷´°ò©j‡WŠZ  àƒ4ÊŒE•¥¹z~'Žo# Ø*Ð18W–*ÞsŸ³»]wÒØÆ#€0Òéú>º§ß ´]`ƒù6ûâ÷í±¤ÏyNcÆ—–²·þ Õ+çsŸ ùŠT÷ð(\ä~»ªühVàˆÆ8à…3`€p%A J°…º:s ^ ʰô».“™hèœÌu5´¦4mÃh„è AÑÂÕ±Þ­g=œh§ú˜Y†e¶éJw¦3‹Î…-”€$0`/€á ŸÆ™bŽAaØ!DÀŠÌê ‚s˜ Ÿ‡9ìAò{€*?ùÊC^ó ýäEOÍ—^ó|Xó^ ù6Oô Ïƒæ3û̓~¸‡ÃòùÜï~Ÿ7½æ ˆI #àeSÀq#´J"?À‡\˜¢D“Àþ$¶þÏýî{ÿûàŸ+ÂÏ}#DOÛODôt@þö»ÿý“¨Dö‡QŒh\ƒÝK±Dm*!?‰IʀƀΠ ÆÀ ˜€h Ñ0€ ¨€è€¨€Ÿ=H €×<œ0Ø Ø€˜€È  ÔÐ^‘jC<`5‚Ña à×0ƒß`ƒ3˜ƒ:7¸ƒ9x‚à„>8ƒÈ<5؃ÑðlÌs?8„C„B˜ƒ=¸ƒSèƒdJLÑ#ð&á0ta-´>DC94†.ä.”†ës†lȆhˆ†„†-´AbH‡ô†j¸>ôB!$C9´†)˜æ0&ÎWæÀ-þ}ñû“?è£>õcPá?ù£>”8‰Œ¨? b^±ˆ–X‰è“‰˜H)¨‚KQ ´aA9‚…—óîF-è6~‹­8ˆHdåÆ8eñ9µHâ4 Daaÿr¿X¦h)±6£2ÉÁ3s  cÐ,íBŠÑX»Rd£q%+²Ac2¬¸Ô`ªØ&jFŽ=¡ràÐÎè2ð¡„#op[è°#;´c;¸sº“ñiæo œ@ÿ#ŠJÈ<Ï=ÓÓa‰ÚˆÔp#­Ö=곆êp0 & ˆ³²’,9Šæ`þ>æã>Í æƒ ï“/ ˆæó’%iP€ÈC&ù“0I‰0qMÐ ð‰æ ÒôR0%M‡ð›…ViÛOÏ ”@r–O}PUkМ_ P ø·è`˜N (Q ûWÊWVâ  ¥_žýTú„€0 û4 ¹ ™äÉ ¬ µðb¿ð •°F† ’ ŽÀHäH9¥SÕä gqp‡°n ‡Ð ¿ymÁii˜æŒ iVÖiûÔOb€¡Z€†/á ª CÖq5ĵ q– Fjp5W[ M\@xuÇ„\þ}•IOÄ€µX„•YŽ”ÅX!ÐX» Y}€Y‘Ũ-…X„e¢UZ}Åá´ uåZ[Yp ¥ß0x.† +Ñmb"Nã[ãp »0mPbw¦+ö-v]ÙU Ûh G ghé5 ͶMïÕ<;d%Ð «°MËöh׊dä¥N$€ ÁР;ú b:¡ú„Iý¤ °xwjš z +!7BÔÐ# ‰ ä –xà˵w6žÈi]¿@p€¶ Ï@ièÄp‡f^Ë6dÍÓܺl:®ÔZh#ÀNÍðd1fHíjr Oý´þZð Рnâðr) j³&±jørN"×0 $æd°Ç*]ÊZ]À±Üh7–_Ô¥Þ€ ŒVMZà±=Em Çq׆cþcÞÖTÕer€P¡)ׯ@³ƒÙR`˜Oà¡#oÂ@Ô€ +ºo]k(ÉZ]ÌúgGcÐÐ0Óz^ =Îð ÝÊ ‹µ§qÎ0i" NödQ&eTF`d[¡-»r €ëÖ¶¢¥àüJPâÆp@û¶kðD}à~ Ž$ .–]Ú5léDh;vhW„Ø4Þ`ô•^íe­Ò iæu¹Òþ _^ë]—6rŠdOö®wÐOh+P[` ¨ÖÜ¢åP!­ƒÛ™s» Xmàð!0#`¿ø{¿#`øÛ¿þû¿Lÿ+Àÿ‹w"ðÑà Ü<=À# SWý‹w!w$ÀL üÁý;÷k û`¿àÃJ Ê[¨«Uð¦,‘0Wb..t Êð"“ ˆðÃŽðÃB<ÄD\ÄF|Īç/pˆ€ÑC|@lÄA\Ä‹pÄV|ÅS\|Æg Ô1¬ z+14ÿ²4zH ˆ R¹ÆlÜÆnüÆm¬ѳ Q© ëÇnì Qi xÜÇ€ ÇþØÅ÷jÝ¢Ý0Æ!ð/4³± Ò@ , ’ É‘,É–|É•|Éh¼É” ÉÇ=IðÈÔ@ ÊÛ £<É–<ʧ¼Ê|Ê©œÊ”ŒÊ± Ëh ¢Ül*:+W@Ã,a íhÏ×’t…Æ|ÌÈœÌʬAá AG=Í,Íì ÑsË,ÍÆÍѼÌÛ|Íɬ†$Q˜«{ J0Á7sÁ«Û¹“AÙÎîüÎîÜ“í,Ïð\Ïö|Ï0¹>ß3”#¡ j«Q º 1Zx{_Üä@ êQ ¾ˆÀ.h–Ž ™TðÐ Ê ñ†5!F\˜Ñ Aþ«íbLm˜¯pTs†Òñ¡Nà … ·q 9›c@`Ó¡ õóÐ=äÐq«ÒpßHÔ 1Æ)¢÷¢¦Ðƒ,P-ÛPÎᦆ¹¾‰ M:S!4[M=* ÑuÏ%I”ø,”öÜ“æc rÏô<×|íΕm-Ö Š=3ʆ€HN)•M©—T9•`ÙYY—’•Á`ÙÍÀ•—í¬Å°Ù••­P SIÙ`éØyé”zŒÚ¾@zì e­`íúêφIý3n [Э”œ„Q–ù™¤™\P_Ÿª` óùY…umÀX~К‹þe«ù¿dË ´9_@6 ¬É«Én H ŠmÎРºE);nû„þ$ P^ x8í"ý¶‡9DÜ©ßÙ\g ž~0]wè™ hБŸÊ=šƒ`ŸŒåO'w̤eÔ„µÉØ­^ ShàMä´ ÖvÞ—öÚb³@Ÿì]UiМè†×¯ m˜÷mý#ŰJà‰\0ŠIzV£· ­©£¾À ¿` ×Å ¼P ‘Ð E HXzhH‹ ÌÆSP:m‹``YŽ¥ZZÞÖrº]ëÝTÕO1®èæ´Ë˜åÜÑ1q§þyúV"À§]ðJWxåJ JZN„ XˆÕè•Y–Å–5éŒåzÝ»¹›ŒšYh€X‡õðw êuðÛ¢ŠWdÀ^`ªZ[±…­ €[²z; ·ûÝaãð ÁêÄj¬Ï…¬,ök¹`ÏJ¸$à Òš_‡F¹?ö Sà­à:m=fæçº¹îD•&¦J5Œ€`0¾_V"`¯ë±ÒæœçÔP°y0[] °(†´Ik£Á&cƒ €m‰«¸ÛSZ ®ÚpÈfm$ ½P`TöT..K,ëO/ ‡€êæÅà±Ñ­ ·M ”@bFì~ËbôTì0þ±Ë S° ‘V¹ d%àì?&½äZh$`cœÛ¹†¤ $'U/ngiÐ`Y@§ ´=Ñ( –àpk{{¬)Ök|F kï„» %p¸ûÞòµé %à ¼°^RËM͆_…æ #0Áðµ/¶%—œ æOt¦¡¦;ȨñÐ]ŒàP e€§z ï»òŽä°û¬O[hËòÌ®%ÐõÑ›µ7ié”p–ö_(Krœ6nfË`Ë%W–pº5~¦pXpÝ397 yPvcP¿ö°û¯/Â"|¿(Ì¿øKÀÿ‹ûlû½À#`ÌÁÃÂ",°ÿû!µÿÁÉþ/û±Ÿ¿öûõëcðÜ“€|õ+¤Ã<<Ä„`Äá…@|†Å†0Äç?ÄÄÅäňþ?,ÿ?<þEÌÄGŒÿ?L|LìþLþQ‘!D Fš„«˜4pæÒ=„QâDŠ-^ĘQãÆŠæÌ…£ÍØ0_­|yjåÉÒJ•¸,©\9Le«•–zÕluç.K4‡Õìù².”8-í‰òçÊ”­R&…IsgÐ¥5]¶DéÉ—¥aÊE“nœCŽeÍžE›¶£9qà®IƒMn´iÒæÞÅ÷.3°yñÞµûWïß¼vöK¸ïâ»u©]‹NídÊ•-§ó(Ns8Îà:ƒ¡Î3è¶£EŸæ,ÚtçÏ¡C·==ÚóçÖ³]³¾½´kÛ»S·7N8ÙËŧèÐãræÑ5g ]útêÕ­_Çî¼:fäݽ{—üð¹Dâå'šˆž{ÄðdÕ«Ožûøôá‹Hüû~þýýÿ0@$°@D0Ad°A„0B '¤°B /Ä0C 7ä°C?1DG$±DOÌ0 ;././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/basic-trace-request-tab.pngrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/basic-trace-request-t0000644000177700017770000006771112633765070033521 0ustar michaelmichael‰PNG  IHDR JwÅsRGB®Îé pHYs  šœtIMEÙ6 šq{$tEXtCommentCreated with GIMPW IDATxÚìwXTÇ׀߭HG@EQ{o±—ØkbW,±÷KŠ]cb‰-–Ø[b½÷Þ{ V@@vÙz¿?)² &Íï›÷yÖGvöΙsfæÌ™&“$I" ظqcšïªW¯Ž@ ‚ÿ¿ÈE@ x_ÈRz4þüóO²ÈÁ‘„ðj@ðÿeÊ?$I†@ ‚,CL@ xo(ßö½.Ö„La‡‹«*™L”š@ ‚L‘®GCy›_‡—§ IôìC™’Å(à÷9ëŽßŘÅë8@ ü?24žÝÜFá Øðj gƒ¹º}+áaAXÕ‚ëÑbün4Ydl˜ :4-ZƒÉ§Q§û×™W11€ ‹I3ubÑÞc\§¯Áµëæö"¯]âT‰LMñZ½ÙûkM†ôgq•c kRèo¿Ø¦ES9wWªï» ÌËïqâÚ2ä7~§F»ïÓĵg.ŒæÒôº Yú8Ã÷}µà0#Z±fÖܦxÉFœ¸†Ÿ£P @ ²Š4'7²3ÆH§íÈg—v=F±O;RÇIÁ¬Ñûxñ7=/ƒÒª|-F®ÌÆÚƒ—xNxx8w®&WÈZPº ”Aþª]¹}l1GüÎÝ‚‚‚ â¯k‡éîH´ÖDÂ3#ß-ÙÍ­À‡Ü¿¶Ÿn*<«ýÄõ‡!üuý,Szåæ…!ý´FÞ9N¾æ Éí B ‚÷jh˜ ‰Îw{ÛØ»’ÓNÚÄhßý…m?´èÉuE}öœœI­b¹P$†9yá«y;i¡AŸhÈóÈ‹£R‰Z­F­VãâY„+Fái'¡ôFׯ¥qs¶ÃÎÙ… w_gÕ \<òÒ¶ß4r¥·†U2paÓJÚw*O6±ÐU ‚÷kh¼Æ^¥L§_ŽãŽÆ€òoôËN®egŒ‘fÃRÚ3íëe*_¦\@ž·xîîšÁM»äuq¥ýðθf`$dË]‡¯ÚµmøèBØ´=’F¥s m ‹IcM˜±º)tF“Ídj'Š:+¹nÓ;Ïœ˜yú(€<žNiž?y‚ …)"½›w’·ãáísœÍõ ÉíSÿ•.;zöÿ¨žß=ÅÍ2S)à&¼@ d5i\ .ž>„?ÇlãCt8¢ x–*OŽw]Ó é¾z€‚y]S™âøëì^úÔ¨B… eiÎïÚ9Ëœ(V«:ìÜÆÃ°X¨ì¤t¥v›¾x;=ãÓ^ ™1mE=íx¥±†7iÙž/Z&ïr©äÍ_ ÿ,óý#Ö®{°>B@ ø7<2¥ßl\º4øt_ê]®íü…€‰Çi<âwªzÿ­:g·®…8sã‘Ís+^/F5šô©‚7¦rJuœNÛR.h5þ®oãå½3s™DO¥Ð@ þ CÀ½Pî]ÞÏðÊ«¨]ª ÇŒ¡K1š9É´•ûùmH¿=ÕP¤V<ÔÜZÖ‹C¯Ò„+Ôé$ôÅ©rµ= ] mkNá¹1¥Á¢ÈdJÌ\Ý÷ÝGUÃAL›@ðï9K0tÑ výÖ+Vp,ÎL§qã ¨_âÝw"wðã»õsèÓ°›ÏM(”Ûµò‡l^µˆÓצú>G¥v ï×VJóìÜrj´—aI4G¥v,÷3òdKó\ìý?)Ñ1’ÀKƒÞ}­‰@ ‚¬34ŒÚgܾv•K¯qúø9bäÅ=gŒÍNü]0âÐhô˜QÍÁ'{õ¿’q‹!–(­ /7q¨@ ÜÐ@ xWä¢@ CC 04@ „¡!@@ „¡!@ @ ÂÐ@ @ ah@ ††@ ah@ CC 04@ CC @@ „¡!@@ ÂÐ@ðq¡E à5wïÞÅh4âææFBB&“ ™L†*• ¥R‰J¥Jú¿B¡Àl6£×ëqss††@ ‚ôQ(äΛ{Âs)éïÍ3žD¾z/ïz_qK&1™”Óÿ™¾Æ¨‹&4,òƒÕýÔºeæÅ“0^jMÿ³º•õゥ¤ÉÀ«˜4qúLë°F£A£É|ÞM†8b3¯QC¼!e¸™ø˜ ÿb=yçrÀÌ«˜b5Ú,­G …¹\ždT88:àé鉛›J¥¥R‰\.G¡T P(P*¬^ …Ba3¾ohH±Ì¯]–=÷â„‘µÒܦxÉ’ü:ªùüŠ2~wÐ{ëŒÎ®›ˆO^?*Öú’Hý¿›ÏˆkÛèRÔ—å+s6,>1M:v~Û„ÊUºŸÅ•ÿ=ÆýäâBj÷߇Q’2h`žñÇøþÿÓ2MÎk¿ ¯@ÿ2´~½$}pݲèÃÕ°mÆe,§ÿ¢neYý{_§Ðót-éO“o†S¬hAú-KþÊN¿*e8úïT”w-‡§GP²ý'Î`P¥bø–žÌ­ÇY#«×†„L&Ȭÿ —Ë“¦Mììì°SÛ¡V«Qª’§R>JCãUȦ‡Å3Í鬯àÿ€—Áç¸ÿÞŸIwd«àì¥Gi¾¼sœ|ÍÒç›AÔqR#›òãÈ25U;~Ç–éŸC¶(eÿnù{—ýœéÎ@­LNS‰Ž#øvÜ×äpÈbgqÜ)°‹ÛÖ1ðË*¨dé¢LéE»Áÿ§ešœWoúMÞÅw5ÜpÌ®þ×![º%S8ÓdÈP¾ (›¡œ2;ʼ~`Zé£Ð­,«ïià4°a{òŒÝÎéåK ½wù¼žŒ[wÝæïõQW(U³+Õgõ“Øyëw §ó¤Ý6;e‹>œŸ:´aÏ|+×§Œ·Š»'–R­ßêTƉEªKh\*ñ¡ÇhÕn!1rª”kH.u4[&tdþ¡¦$S8Ó;ö¢ôü¬9‰?ï° ÍNúN:šeý¨”â?‹…8M‹Å‚ÅbA’$,‹UÅÉXÿ>°¡aæÂ¦ñÜZ½€›‘&>ôQ7ø²IÂäïõ™ô%Ç–±-YsO—¦a¹°i%í;•ÇÉÙg¥ƒRùnq¼cÇäìäòÁäàè¤~Ó¡GñZù²{œÿaÚV^Ywª†NÂâm¹©]*×[«rvú°2• \Þ¿ž#7Ÿ¿wÙÊÕnäòµÿhtK¦t§e߯hTÎçÇrv%ÍmĨà£Ñ­¬©YÏõ] 9¦/K÷&¥­záàGß ÍY3îWî¾´¤ù}ÐÙM ª@Òù’~ßsú n-ëÏž¹Úú=ÚqeõDZ|µš±j°ô†Ñ+â’ÂËÿôö!bêv#Ÿ³ Uöütm¦bf¿úL9¹—f5”³Õ »4å`ˆyƉ$ Éì)Tª2ñ/ã0f…‘!Ih° ž>}ÊÓÈHâââÐéthµZâãã1˜L&ëï?VCÃôò2Ý×¶fÇ–`¼ÌÒ½×m6~—vÎÃÇdžÍäúk÷PFa@ÈÅ­4óˇÇýNÈK#]4—Nìdbß6,ܾ—ÙýJãããCõ>3¹¥Gu…Ö•›s,ÎÌ€Oýé1u7 ’ÿàSnõ’M+;í3º¨ÛLík¿\ëQ¹‘辞Nï>ß0jX_¦¬9ƉKöM†/å™^âÐ/º&‚m£¾ÅÇ¿''$5,›¶GÒ¨trââÐÚ‰Ö2ðïÉùÄú›qœ¹Æ¥;ù¾ÿO\øëbRºÆ®8E¬&‚Ó$•ãW™WUÍ“ëLí×–ö½zãããôM×0Jq‘Ù¿y1]J÷dõŸ+éRÔF/:Š&ᶈ áÔ¡õt©0*Ù¤—6[òzf3n—÷-IŠ»zŸ™\ z@\ä]voZL÷v£9uá0ÃÊøáããÜÍ×RÍ•FÞ=ÌãrÝÈïlz«Ü?¼LÍÜXõ+nD¦úVûä<_¶í͈1ÃønêF]âÇáÃèÑökN?ŠÇ yößÖ-ÉÀ“ר²b#¶¢•þ¾n=¹¸ŒíÆîÕ æeÉ¡tô6 uË>’e#û1l؆ ÃÞÓX6²½{·fÊÚK˜%!çX2¥?SÖ`_¢nUï3“Q¯¸qx©5>cÏgéw>¦æu,IË©G’FÍm8k§öOz~â¬Ù|7mwrfØ›é¸sò4ž•š“Û-Ùó+Ót¸“Ž_߃”&—_)nÞjð¶ÇÛ·þ…’wBx)‚·{²(iW‰l2J»ìø.‚»"¹{,T(?îʦÔn^”sS1®sU¶] ':ô#†o£[÷Š8d1+—ËA&Ã`0Âùóç9vô(Û¶mcùòå¬ZµŠ-[¶pêÔ)¢¢¢ÐëõV/ÒÇgh\ß1—6£ZR¾Rú{Û³cÚoÌaš9³ª'½·ãÊÃ0Bní!vëlLÚO‚dÊ L"ìâjô bÑ­G^ØŽ´y,5®ä…Q˽³»Y¼çÑퟑ~¤Ÿ¶´òªM¬¸O,nÌgÂ9~3˜°+ôUþÎçµJ³ï^,’9[æqèìJ:ö8LëÕ1'Ó‡ãÞëˆdàêŽÕ|Ñ»Ùdê·Êýc©›»Ô‡ÜŸ0áçÖ¬[±kZOrzÚsvËŸôš6žê¾Ž¼Š¼÷ŸÖ-ÉÇýëX6i!)±Qü{ºåU¦Nï ö Ùuæ&]jyÛÔÛ,Õ-•7=&!û‰õlØ£¡p©b¨ÎŸÄ±ñDFTDnŽã¯[™0oó¾íÉm·fIò¨S¶8£/zpðÀŸtÏ~‹¾fÛLYËÉÀí[ñD[J¦~ª]—õ´çAX¡wæ#_;ŸAzäÀýÃKißû† –æ3´Ooï½ÀåÓ1¸ûzb—Ò6Hô4\¿ŸÖè1ÝîFh’ýœ kÝ I°9uò}«6lHhÌžUã™·ã…ïO iÃ~„&æÓ¢ gÓöHê•Îc5" yû^”¾)}³uÿwlÀ¨ý¡M9È”>|µf!eÔr·¬B™jiºøÚÊo™Å‚Ùd"00={°y×1¶½ÊÙÛ‘<жð8JÏí{¡ì?pˆÍ›7sçÎ,™¡aÑ?bé5_5)2wºÍ šMl=‘Ü%D^¢ýècLÒ/;J×¢ŒžÜ›–µòayv9Ý0¥ù9ëϦp=/B¯åfH;cŒ1Pm.Zuj À‚Ý«i\¹MzüĪ‘µ b—ÃŒxzzà’ÝggÙÓnÆ®œ›ƒŸ£Ì†ÐÕiž¹¾k!ÇÌõ0½¼ÃÙ w0Ù[Ÿ[wì  jçQô÷¶glûÊT¸ÄÁÉ£G.ò9(põpÃÕÙ9Ñò6syÇ:õþ„l‰«Ö,ÑrÒN¦÷¬KñÒõèÒӇЋOˆ7§#— Ænš ª ¼°”Ú¥‹Ó´÷Pê8)è:û_4(O¹š™ÝÙ›óçd¸)•‘e¯ óˆz8ËdLÖ…@F“‰ìªÐ¹wgpnËŽß{S±\UFÌÞF5{7^A™ÿ“ ÃÓŽ<øWjDǶ2¥ª Ò–V^NiâÖ>>IÀ¤‡ŒZ0€‚ÙUÈ”^tþyeÔr¦-9I6ïÒ4ù´6Ø7äÈÙ©^¾ýÆ‚ñ2ž[A‹!œµëžÐ Bž¤û†øç´Kš_®Úi,UWÁÛÓ ³hƒŠ7R¶;`ÂdraãÆ-€ O¥£ÎZj•"©¨Ø´ L;Ñd¢J2á“•ÅÞ ¯ ¦”-¤xFÒtíEZöÃI&“ ¿FóØÒØ„c®<‰›7_®›ÃÂ:}ñ¨ÐœBn²T£w€xCjÃlíº' ˜z9·‡}R|K7%WˆÕCveÚ8dJGPzàøºcS(qVʱ—¥~o‚Æ€%“óýGž¦J˜Õ„n™IxuÆ:âï¿„¦ —,S£ãwÇÀ‹¢1§c9F_篰X”67›L&œ¼ Ëמ{‡£^—ò«¨hëZ 7Û‚*Z¯7!AI0«pB[£G*ýD¥oé)T³…lL­lÝø”¾|lxªÝiñEÀGYú臌ÜñŒ¥GàîâDŸßŽã‘«!CÖì'BÓg—fhF®Þ""ZG|¹ðôÈŽ«‹®®Ž¸¹¸àì考ƒ=*•w÷ì\>ÿŠˆˆ"##ñññù8¦NbœdºáK:4®FùJ•¨T©ËU¢u· LÿeIœhù¯Ûy6yËŽô‚%ƒÆð@cH7,XkÁA!cúô?ynL®YÁ'fòÓöd/E Á?¹wÞ:‚Éål3É€Îðö]1Ög¨„îêÏ™àäÃsƒî›ÐJm_µÁÒÍkéࡦOç¥©Ò à˜´¯ÌÌÕ}¿Ñ}Tµ4–cʽgª´-e¸ü C,魌 :t ³æF­¡ÿ‚“ÔðsDž¸ÅI¥´³iø!ÅqkÿuJ6/žjÅ÷Û•2E: vú˜©´©ÒÙáñúÜ™ÛaQ©›™|5+â¡~ÛÔ`8›W=¡Á»ÞMîï_¦*/J•*E©RÅ(V´4E*¹PºX)Šú£T©R”,æ—8Ugfߔި^ÍÜ!5Ùýc;ÝÍ’tX>2ݲücÝr"ôâ“tM…÷¥[‘WW°´ ›VŽƒ¿1qíå,i¯S–‘É #Á$Ìß²Å!v5£ô6…ÿäüRhß¾}šO@@+.ÄR¢îg9…ðèä:û4œÛ¦j‹Mo¸ä•j{œìeû} +Ÿé™8¼qª¶Q¯ËÜ!1A'Ùé0"žï6æþÐåð2̪s‰ëS¹Òð ë"äáË\¯×s7ô)ùóæ m³º4ª[™¢…}quvÄÍÙ 77ÜÜœÉáéNN¯ð+„V«%&&æík4d2§OŸÎÒOZoF[Æ¡Í÷õq}£Ót-X…ïj¸u掾Ä%9ú{Û³ozWzŽ[ÎÉ3‡]¡Au;S¦xùtà f/ÀgƒªuögtšÉé«78´v"5û…Ò«yÁdñ¹@ÌX·:ζŒ–?|IA9’ÉÚÈÞ}ÀÃë9ÿ(šká_¢//m¯šOõÌ‘-d«9€ÎõøóÐy.ŸÙÅgå›Óü»ú8`dßôÎäýq??©ÅW GÁóYLû#uÃpêÒeîß?ÇÖ}§Ù¼ê Ÿ}â›,+¹U™/†&V(3nìM£ç¯ãØvø!/ž†€îQ/•ÙlBc²Øh•IrûšŒ©ƒ,úGŒ¨Tÿ½¸¡#»ZÆÑㇹ˜4WzëÊ9n?@³‰»AÖCÎmbâÉ—Œøâ“D/OÆá¯•3F§·åÍP?òÛY2L[§<ÿDŽy«2»³7;Æ|Îñ kXBÄFîxÆà¾5¬s±¦WÖ'…¨”vÄg§ýÍ™ÚXÍHîJ¦)GÄF$ÌÆ´uÄÕUôÝÑ™oÛV§å€Ñ´pSѽýRž&I8‚ŦJׇÕ-Oé’ÒóOtËd^äVàöo9žzçÁ{Ò-‹öÃ:M`Ãæ®T©×…_{çaǘÏSƒVy$©X„ŠÔÃë2²èñm¥*Ö‹›Q Un @놹x?ˆ«'×3tMDÒ@©v³ J÷3£C ŠÔjO 7ó7Ç XôA,½ž®“zSÐÅš‚øÐƒä÷ócæÞ©ú‘£+‡ÐmÒq~ZsŠúþ®)²{(èïO³q»ÞºëãÆÁE6pz¾œr¥Ž“‚ÍÇo&T÷¯œ÷ð²ûdž†$I<O“O«Q®ta æÏG¿ü8:8`ï˜ GG\]\quu#»[v ùF«Õb2™Ò0KذaCšOxxxšÏÒ!¾ ¡ª ý²ñlrXX´zlgkXâgÃé»ÒÃkû¥AÕ\’¾?“©÷´]Rxx¸´ë·¡I¿i?f“"mœü¹õ;ç¶ÒæÍS%r~'¦ÈÛ”ÞÕ“žùvþfiã‚oSååÍ8þø}¦TÇI!’o“ï¥m{þL.;UiÑŽãÒŸÓû&Å1ðÇõÒúWm2PÚùúð´ÔÁC-Ò’g¥¯Ó¡ª -Ù°6© –¸!ü­ÒóeÔr æn9—Tf…_Ü»()½¨*Hs·œ‘6ÏI.'ÏOHû/?H_Âng˜¶Ôòš'­¶wèËҔ^¹%@êÔ£‡HãV¶¦o×¼¤4çkö“têô6©~›M IDAT…›*éù1rJmfzC¿3ûK¤É½>ŒL“Óx_šÕ2§Ô}þ±Tº}vëÏÖgr|-] “‚/oO–Mޝ¥][æ¾S:LX$í”3éïž“¬2ûPºõ럻¥ ÕR¤g½ö·uëêÁyIÏLÙpÔ¦Þf¥n=¼¶ÇZnö ¥—‚¥ð°«ÒWy’Þ9sÅÒ—MÝ­Û7”–ï9!mžÓ/)¼ûèåÒ®s“ÞéÛx ´~Ýü7êßÅTòYzä¶”J®EÚµ—©p§¹ÒƒÄ¶*3Ÿ{¶[ó§ª •QË¥ö£“Ûbk{½H¤>³IA·NI¿N’¨kßH;OÞH_Rù«*HGþ M÷½¡OKuœÒŸ—‚3Ö×Ï}èr—®ý=é÷ *ÙK¸v“¶Ÿ¹ûNyIï³wï^©à'­¥-»KWoÝ•.߸#»|SZµa´óÀiéÄù[ÒÕÛAÒýÐgRpÄ é¯‡¥!C†H»ví²ŸLJqÒÆÆ³tФzõêY“½Î€E¡Â>Í1u…Yï± ÀÙÍ9Ɇ¼‡â5û²êÄmêú¨Ñš8Ù«ßðPèˆ7¦ø^2 3Êm¾#Ýg£NC¼ÞL6'פ…]™Í³6N“2C,QZ^nï\n¯ãPd¥`¥8V ¬‰ÏˆSÔósD¯Ó¡´·Guƒj¥ŒÀ?Ðà;8sa"^’I턽:¹ Þžú‘^ÚÒ“—-âc¢‰Ó›Èæì«Cæ\¬ñ1јÜqQgõñ›ïI¦ ÿ#º¥×i°(ÞþÎK·2#ŸXԠД‹|ê›-)¯³gGÛ¾«Á´Øï8ò[«¤Ýq™-gF‹Biƒ}Úrx]ÖfÍ3‚"ðÎ W‡ôëmBäy 5>Å+ßàž^:$QÏ_ášÃãÝOVýÀå HÙh4QãäœumÂíÛ·éóÃBMw.OÌf &“…{áæêŠ›› NNθº:£VÙ¯aþÌÉ4iÒ„Ò¥K§~ûo´> ììíÿF¸Ø¸²6yá§ru6œl<'SÚ㔲tdjÞÒ¥}PÙ;ãfÿ÷òìà”hX¨]ñRÿÃ8²°£;6· gÊ,`^ââ«”å/Sª“ÓQ¨À…B© ›sÚÔ½%<+ô#½´¥'/[8ºyàøŽ)rtóxou!ëeú±ð¿£[vöΙ֓G·ÞÖ¹8<·9×® —o¶TyµK 7!ýírvvN¿Ì^—µÂÙ‹¢o)ZÉÁMX²æbúFFb›îéåùŸ,‡Tí³Ûû·ôúxq9Hfd‰.d2$I†Lf=x\¡R¢V«­÷¢¤ƒœÿgX ±\=}€9÷ôä%‚w£Lç,ê_5ÃQ@Ì“[ìZ¾4›8{î/ߨßý¶pÐ-¡[2å:î`AŠiGÎ’ðW8»/šÐ]C8|íñ¼‘Û¯üE“âîÿÏËáŸa4 ‹d¶‰Ë¶%, ³€LÂ"IH !“ɬ'ŠÚ Õxn÷Âq¬>z'ͪ4jK­šµ¨àŸó?_WŒš(Ì^-Ùºµ F£ŽˆÈWøæÎþ¿é†~O#êìo· _<ÓPé«l.Cûê91Ùíì2.º%tëã“»WvÛ£_³ŽðÐ8Ú.Ý@GL$$¼@/åÉ’ã°ßÙPÚãá&ÊáŸõ8 ƒÑˆÑhÆl6a2YÐéP«ÕdË– u‚•Ê…ˆѱ9•ÊÐhÖýç0nñ¾üy5 8û"œƒ+'2mô&ÚŽœC» ¹þÓUÅΣ µëmÆ{ƯlUüþA¸@ të?äìPºR¥^}QÿCå SÈ1').Ã:•b6KÈe2,æ^B˜_O³¤cP¥ñsØÛ[-5µÚdJ\=òÓ¼k?Î\Ê’›á@ |¼È•Jd¯™ ™L2°H2™õrWI².•^瑎¡‘©Å Æx­(u@ þßXÖÛ[__/I`1‘,ŒF#f“ “ÁˆI®Çd0 T*Ó]£‘îbP­V‡QCȳÌ»€6J¡zù1tÿÙ3IHÖË©´:]Ò ¢’ÉzÊ!€ÅGtÌÿšÁfæUL411šÄ[ uħszª^CTtÑ1šä“ßé=1Äj´éèÉÛÂSûì ¯ RÙ½¾@ìÄn2`0½ŸÅ†’)Ž ÷ {™tpSzèubbbÞú»¬MŸW11hâôïí&C±ZÓ¿ªÕZML’N ÿ/m ¹Wçl< Çb1a4[0[L˜% “ƒÑ€N¯C§O@gÐù,{{{›Ç¬ghhü6f]º÷ãÛq³‰®Ö—¹KVQÃÏ9ës$Å2¿vYöÜ‹ûq\Ü·Ÿ¼~+VŒÎJáï—Ÿ€o~f`Ùâ¸Äãû“ϯ(ãwý§²–yqí[ããã“ô»âFIÂs—ŸÛ—¢xÉ2”,Y _ÿžt-Y”#!©¯jÖFÞæ×áå)è_’=ûP¦d1 äÍËÚC·3ep< <Ê€’…è?qƒ*÷ôdn=ŽÏt8ÀÍ-“Rå¡DÝy¼¾(ñeðQºógÐÔit,S”Æc·™ÎZÒxv]Kú³ïÞ«÷ Wϙߥ £çO£jå |:x·Í[OÍšVŒë@ÁÒ_ñËÄÞÊŸ—u'¾wÝxzž®%ýiòÍpŠ-H¿…GÓ½•Õ¢bX¿T2xý9t?.CsטO»'ø_2œžñǸÊ.ý_÷(oéÉ<|iL7m‡ °™§‰›ïˆžJðŸF&“áŸ/O\äV`O#£yŒQoFŸ GŸ` A«'>.žØ—1„…ãææF¶lÙlÆ—îÔÉÈÙKqùk9£ŸAi§ÄÕ%Ûûi°B.0=,ž’kNÓx|Ãw?8å=ñ2ø¥(›/ý]î}8¿}ÕŒŸwE3rÁ.z5-ƒ£R†E÷Œ}«ÇÓw£‘ÏìfÉÛÖ À¤XV}ß‘ù÷{qéá7䲓yÿÃZæAès(l=™äÙÍm”o2ߦã9øyUÖÛO®¦a@#V÷Zȟ㛥{Ó d gzÇ^”ž‚µóÂŒØ1±.}'•áøoÍPšg®’ɰhï±`ÂeÆM£Ì€^¯Á»d3òØÉÐG]¡TÍ®ŒZsеócù¡ck4 ³LŶñÍÒ=hG2=cýüœ9¾Žcqfºüc±š¹~à ^5áí`}ç½ý³™2šàux°#>6ꆙ“+º2ûÎ îÝ뀃LFßv ¨ð ®o¥°ËûÙ½nÖÜf`Ãöä»?ÊbÑ1¨r=ƹlej@Ù4¿pl-LùuAMÔ2@Ið¡o™¼»&r:جWSº}EÙQsð­\Ÿ2¹TÜ=±”kÔìœßå{h#$;'·ä»]ݸzo9”FöM¯Kíú®\=7ˆª7.Æ‹ºÎÓN0aö|ò8Ùa”@“~CçP0¯»è©ÿi •Jbûñü¹ó(y¼sÝÕ7W'ì *T‰ÇÒMFärOŸ„áë“ ''§wóh˜Ívø×ëIçâö„îŸÇÜ‘õNY36àÖêÜŒ4}…¬ºÁ—M:–AC-80§?ïŠæë%ÇÒ²,މ  ÜÞ‹¦}g3«eNâM rvÂY)Ç üÀ††Ç–±-YsO÷¦­=Å*´°þ71ùC47ÎÄâéï‚câ)E9ýk0ã÷o9ûÀz©ŽE{q¾×n¬›ÛËjdÈÔ¯Õ›½¿vãÖ²þ,Þ—þèÛóŒ;SòAH2{ •ªLüË8Œ™¸½o.;•õ©W¿èÑ£+Y/£ :» T¨Q:ŸUn~ôœ>ˆ[Ëús!4ýé™Ò‹N_çç³²D,!gWÒlÐFŒŠdݺqôùÊZs–¿R+z¶,ksÏ~Ô㳫“*²{Ž<`¼LT\¬”×w-䘾,Ý›”N*·¾š³fܯÜ}iIÓ‡¾,ÊÕk“iݲ 7¦qãúT¯XÂÍ“Ï9­Ñ W»Q¿G;®¬žH‹¯V3¶C –Ò0ºsÅÔ¦e!ña§¸$œ 3?³25u¾˜‘SØy1"ÍïÃï?bý‰»ôjû7¦E“ÆÔ«ZìRµDÑS þÓÈårªRš’…r¯!>>½>½Þˆ.A.A‹N«E£‰#èþ]œìUøøø¼»¡a½ÎÜ™æÃÆPJ-çâš ì¹þ3¹¥Gu…Ö•›s,ÎÌ€Oýé1Õ¶Ë:!â"½}îèü©í²25¾_NÁGOꣃ8´v¢5½þ=S\äeæîÉ 4óËGïÞ­ñ)ðÇî¿ .:Œs‡ÖÓ½ÝhöÜB—¢¾ôžs”M¿hGûÞßУ•?_NÝŸ”N[ù8ôK#†®‰`Û¨oññïÉ…Ç D\Ûˆ{þz‘y%T»‘ÏAEÔ™ |>|YRü^å:3£e~ë(öäFvÆé4¢ùìÒv&Å>íH'³FïãE:.wµ›åÜTŒë\•mW‰=ňáÛèÖ½"2Ù[Ã-úG,» "§P«B)|}|Xuèî>=T':zù•àæý§o÷eʈøV­{Ñ®ß|¢,¡‰·j7ƒp­Ä“‹Ë¨ÑÎzëbµ‚yY¼÷?w(ËÐ5„îBûÖ­:ç¤íi&™¯‚… Ý5„#VÁÖÅ“ð¨þ ¥r[Ïx|–Kz,*øJ U«V”kõ5³g`ZfÝý’Ž;'OãY©9¹Ý’åêW¦ èp',&¡Z¿cÛTÉÁÆi{èÚ®¼m¦ÌoßBøJ> Á£H|¼Ýoæìºïñ)6”¿¢ŒImÁå}Ö¶ wïÖ ›Éôá}Ùw/6SÙ ½~ÞjÔ¥ðF¨Ý|èà¡æ­WÒ´ù«¶¢†_joçõƒ“)üy{ò:ˆŽJðß74r{{Ñ¢~òæÊΫ8š8-qñZ´ZqºâtD<~„#ÅŠ%Ož<88ØVþ4ClÎzRæër§‚ žØ—~ß-dõOƒÉ3ce}²¦&]ß1—6£ÆR¾’ý½íY8톷¯€Ÿ£,©>³ª'÷ÔæÊÃ0Üu7ù¬|sÄççÈo-¹’nX+ž_ú}uœ»õט+ŒlØ–{¸v¸1÷ÎîfñžópÐÄÒ «XRe=}ÆÌ¤þ5gnù‚ù&S£Õ÷ÌÜrŠ&żlºÐõZkV¸QÜÒ9Ü%oÊ=8(d¬Û&þÎ=Uø©}¾þi?G~k…,ú:õ: cÚŽë”÷àüª®´ ØÌí =ˆ¼w‰yƒ¿åXœ™C·âè[Ó…3/ <<6“ß5_prisB[R}x( ìâ›ù¾}¡7ŸtžI™ßÚQ|Ì÷Œn[';BîÜàéË„wðr¸ÓfÁ$¦·ø†»ÆScÃx~\º›ŽJ“7·µ¬Ì‰jWwÛÇ7Ëí]Éi§íb´àîhËsàÃWkrµY/·¬À÷+O1¨~þL…ËÕÞLœï[µAÛ{V&({-,;ºÒtt.ÎÜÙF>µÇ×&‚ˆW“)î©âÂú^´þ1/Çÿ ¥ ‹Ä™U_Ñ~Ô–öN|Øi¾ûzj_W›ï‹“$ ª%Á$h o5*%S; ¥ëÂòÍô¯@ðO ¥RI™…ñÎéÉ…«<~Å«W±˜z Žj,Njr{¹S°@~rçγ³3J¥ƒÁ±Gc÷ÂqŒ[|€ß÷fù¾¿0nê2¡o=~ÖƒÝןþãŒXôX:GÍWM Ìn3‡‚f[S,dKˆ¼DûÑǘ:¥+^v2”®E=¹7-kåÃòìrºaJósÖžMáz^„^;ËÍvÆ!b¡Ú\´êÔÖšÇÝ«i\¹MzüĪ‘µ b—ÃŒxzZïpÉ³m£êuÚ™F@k–h9i'Ó{Ö¥xéztééCèÅ'Ä›A¡´£Ž“‚ü93µÄœ%Z« pÕVŒÝìräüLÆ.¹ÆŽ1 Q©½=¼…k¡¯pÌW“_D2¥Ÿï‡‘&=r‘ÏA«‡®ÎΨd2ü?Áµ+×èZÍûäçS®=v3¨š £{7£éˆ?Ò,¤´W)Ó™yŠãŽÆjÌf4垣heêäH^´yßIž¥8R:Ãp™š¹óR²RM¾œ¸‘S[`þò³h% ßr5;îB^êIЄ']ù]µ¸wÖÔX™š"5ê§Ê§2qI)¥Ú 7'd¯CÁ¼nØ«í°³w#»« w'\ím_®”T|iذ\ÒßÑWp%8yqjîŠ]9wò £?/R»¦K¾æ¿Ò¬œõà=§Ü~tðP£“@¦PãšÃ›9rØüä-î…J ö  Û^(]&æWO§ðçímN›Èí|˜{ú [†Ö&üÔ26Zh=î$W.ýaõŽÉìi=þ .ß´^¼užÖ#Ž2qÉàÄ+µ”©ûYŠºªÄ»xîtóåÃ9:pn‹ž´õ=›³ì­w5h®²òeIªõ½”à™\Ž|óÒ¶E=voMïŽhß¼ÍëW¥q½šT«ò þþþxxx-[6dòLœ£Ñ¬ÿšõ·ýÒ¢õú²¡^ß,ËDø•Ýì|¶Ÿ<«á)ƒg—0ë‡ít«ÿ 9T2 Ú§`ßÿœvIvÕNc© ¼ Þžn˜EDP¼‘²…Ü&“ 7nLx*-uV‹K­R$ +6íÓN`4™°¼ÞÃ+YG47°ýtvvvHúWä¨Ð†ZÙ3ß%5úöIïó-Ý–\!Vn%ø#ð>g·Ò¥ÞHŽÅ™Áµ[RÇd6J tI¼ýUŽZ n¹ ƒn!ŸU+NƒÁ3™úu;ìÁæûõ-Þº#ü[ ιËðý†k4=°Šf½&poý÷ôÈ‘‡Í#ëbƺUTg4¥Óÿ:QÔYÉu˜$çw®çê vjHx¥§ZÛî”É­gí ºì­5•c*²yd &¬ÿžÏ5jö/l3¯2cd™¿RW¶L?Oë‰'xªm…_¦Z5žú_Œ§F©ŸSýÖ5›Ò¦Ü[$®ïÈZâððsÊpëxzi¹x& ‡Ç°çÒM,—Ñ|Àl:ÖëÆÞ‹›(å©™ŸÖ5(í3NžxIÓŸŠ§u›Ñš%ÔXמŒœð–¡ûs.¶'ÛFÂë:P2Ÿ{¦Fþ]æ•Î`ä¯ »‡ÕØ/üéHº8¹Z§‰<Ô)ú!#wýO®˜´-øÄL~Þ’¡å­ïS¥hxžÜ;oõär†èÔáù«vecÕ®o´.ùX:Ä—Þ¿nbÆÚ,è_5M㬾˵'®T*œØ™¨S·ÊGý!§Ö1ót,;¯õ"‡JÆ ƒ6UÇ`‹k»ÖáÕ¨#Þæèªé:ú7®?j–a¾G7—§M ×°³Ïü=ô*bè÷ý~ίk•Ô°f÷-L5Ì `¼•šÒß{ ç­à^·êËžÚïsa×zQ™=¾œJ£7õä¾u£Jñú|[W~1–ö%Fc §6ãpllÉ6êc)ܨ)Ç(Õö8aæÈ¢1¬|¦gåðÆ8Èd¶åžÊØMß8µtèɆ½Z–˜M|Nf•½"I¾N„^|’ªã~[i‘L<¾¯#oóät¬Ö˜?ò8È›(_J{{d‰mÁùÃW‰í[W™ ™\‘"ÍÏø¥GW«G-¸M‰ºŸÁš)„GÄÝÓš¿Ø§Ö©‡\Éë;LJµ:ÍÈ?_#Û#ÿ×éÌÜÆ3Z{5’ÉÚNœ¹N}ÿ¢©uÐ=¿N‡€AéGe߃{‹¸ôŒz~ ”§lˆ60µD®enÀ¢T§Jc’ñT*—è•ÿÃY’a!—Ë­×ÄgÒ°þ÷¯‰—âØ2n m¾¯ŸÊÈp-X…ïj¸u掾Ä%9ú{Û³ozWzŽ[ÎÉ3‡]¡Au;S¦xùtà f/ÀgƒªuögtšÉé«78´v"5û…Ò«yò‘“ç1cÝÎ:kØ2Zþð%]äI WàÝÜ8¼>ÅîT¾ XNw/;vÿØŽ ¥M>ôþÅ­,S§’:©1¿šèT0óèÆÞ$cBo´]àaà&X¦Wܾt‘Ç1‰.`Ó+R.Pn²áxÈœ¨Ý©'eÔrœ\ü2•ïS—.sÿþ9¶~H虥ô÷cþ¡tä¥ãö©í©†Ž*ÇDŸ˜•§Ð&®Æzp Ñ*÷ú”v2dJo®[º4øt_&n• \Ûù S~ð2ª¦¿Â)WQê8)Ø|üf’3æþ•Sà>€^vo ¿x&>þ=Ù5€§»i9âS†ÖIí¶—â8ºrÝ&ç§5§¨ïïš)U~ñ44Ñ M=Š·è1¢R üKôâÆÓë¢SÍ&N^ºOHàêõ_šMì9y£$YÃ_äVàöo9Ž0hÞî~’)½(ßÜ“5Ó÷®µÊAñˆ ÑêV´Wÿ  ¿?ÍÆí"ÁއϺå&ê̆NÝÆÃÐl_0…1Fìe ·ócå­û¥ûiVÜ•"µÚÓÂMÅüMç1c=kéèõtÔ;qć$¿Ÿ3÷>H3òïÚ©Lš‘ìƒ=IéÔ¾í 7ÉÀ¾iµ(ìïDzãa8ç)E 7‹¿ªÏªC×ytÿ“?œÜ®ø7Ï0OA‹)æ[™¥C|™1b Oõ`æØªo çw4¯”+1ýጩ\ŒšýV£I‘ÆÀëÈ×è 1m"|,†Æ¾ésâ›G|Ëú3a©#K¦2å”u{ÜÀ†¥9óØ…{·1¨š G—£Sû/p¾†‰mŠ Sz§ jöœÅϹˆ:7‹-šÒ}rûM!OŠ­–KG~ޝË6ÅØg9¿t/›ØÁ•¤»—Sú4côEgЧ³_Má\„‰çβ`Lg6þØ“²…óãããCÞüþ´›ľówiYÜÄšÉ#ÙcäÊÜn,Ø~ž3;X·Æj61qá1òUlB 7¿mK·YAôž5tè3èç·Î¢Á€Õ ;@­Ê£¸ñÔºB©r`F÷š|÷óUhD‘‘«¨ZÀ9Ã|Ëí|é:¢·–£nËõ.ã¤ÞBBäuF¶-ÇÐ5Ösz×-ÊØ§PåÌG 7–ƒ(œ7/ÍüòQ®AÚ_Ä’AU’F{î…pïò~FÖ[CíR©Þ³7>yýh>ä$Ó×fó· 3t5+œ‹0{çJ¤ð-ð=ZùÓb,lß5”*Ù[Ãí\Aw€^-ªàããC›™wÙé.•ódKr©oY1 Ÿ¼E}º ;OÞ [íü™0– œZ7jíÆ°è§X¾ãrÚ-¨º<~¡É² IDAT§`õ6´pS1¼Ã§Ô¸ÉŠ%ãÀ¹-v±QÄ›!W±Ê`¼L@Ã<ËáÀºo¿`äŽg„îB×~³¸™ÞGüɤë©R8/½{·¦HÕŒ[y˜…];Gkšnm½ÎKƒŠ†ƒ×2¼™;ç}Iíju¸aI}p›R©F­Nÿ£ä…™q`òyøøŒÅê XƘ6%’ý ‰ÛŽ4ñ¦#ÿ ¬|¦§Néj´fNoLH&ñÆ´ß§Ûðébˆ~©E¦ø¿öÎ;<ªjëÃïôLȤZ ª‚4¥‰"éEéED±PUÚ,E°pi6úQ‘""%¡wDP $HLH€d’™L=ß“LRȸw½>óàdÏì³Ëš³gí²4| 4nÓÓcÇ’¾™×ËÏ휯ûØlÁ­5âwÓ΄üêíýNš ƒŸ¯÷ï·;u‚b'-CŸQ‹ÍjÆb±£ÒûZg‹ù»ÐP<à6·º°˜Í8ÐãgòÍǵ^pºÓnÅjs¢Òòô¥ÝœÈ…„ J—)E€¯þîþ²”4¾Ñ”°±{hQÌO%͉¯É .\hr•Óf5ãÖøåšj¹lV3V› ¿€ÌEÃ9ã^*µ=ÊéC/gš»QüðQÿɘºO¢Ÿ´‰÷»U»íߥÙlA£ÍgÌÍS!ŠÓŽÕáÂ×h,@Øî§Rë=œ82ŠâE°“ëúó~ê[¬XÍû›M³:ñ5™°Çn£r£,ÙqšÖUn³-=±—ò+§ÓnÅqÓ”˜ÍjEíã#ÛZ…ÿ.]º„^¯Ç`0`41  ôz=:g!¨F£ñNŸ¸\.œN'N§“ÔÔ¼!´Fµ5 ¸9žþyWÙe/ü4 Öûà—¯[Úˆßm´ŽÎH)càß|z|sTãÖ"ÃSw_“©Èõö~Ç/·‡æ¶DFfYýŒYß5a0Þú+¾¦@|ÿFÿûšï(]«7b* zzS(ÕLÿ {u±ó“6D՚ϧùzÛÌä-ˆ&X2ÿ^A êÅy™wÚôã«UsLUfÛâðLÑÓkï¨_L&S!e2Þô›Ò{áæ-g<ï´éÃâå‹$2â~C›wåоª¹~³YűÛ<Óº;8·°û‰VoÌsÓ,ìó‚ Ü‹5÷·=…£{·0oÍf.\¹.V Üuj=¿…ÃÞO¹Á¼±ãWZV)žïoáÈö ¬N¶³ù‡Ä]·ÝÃròÆŽ_ióHÑâ„UjÃÙƒž8;7“’ÆoÞ`÷¾“¤ÿƒmAàAõhÜ=æ$\¡‰ŒìŠÃa%>!•ð2AhÄ„»†† àÀû¢$*­‘‚Šâ0'‘¦«Idd$ŠÃÊÕ¤TÊ•¸ïÊ™>¦àR\$ÇÇþì§D¶Wa·Z¹–æ¤X NÌRnPEQp»ÝÞ³þ?kÕ…¢(xÿ+`!÷ÿœÐ0W¤Y‹ŠbEÂÿ<ÿ¿ µ›!Ý+wAl(ÙB"KX àVܨÏW·â&+⪠AAЍ2rx,Üo†ËåB£ÑxÞ«²Ou»Ý¸]îûìdPAAî[Ün§Â•9]’õr¹\¨ÔžÝ&Y ·Û[qèѸ/ƒ:íÖ»u:¶¤%'p=ÇáaÆ]!ãY÷Ÿ(¯ÛžBb²å¶¾“aNæJBV»‚ÛžÆ ³M K„ÿ \.WöÚŒLát9½ÛX]N—÷}–øp:œ8œŽûTh()|Ö¬6›Î¥=P½Œ°°°‚_Õß&ÖòÏîñ'7òBµpªÕªËîÏö¾¸ƒ_òxÃ켘þ@´ëÝ,¯âLäË)=)Qé[.ù{¿mÿŒJuÆ2®Y]*G”£|D5>ßsEî>‚ üO (J.‘55âr¹²ÏÌp8q8Øív‡gA4ï¹ÐH9Àì¸t>[¾7ïÉŠ÷ë÷q,¶àÁ®BþœÞ¹€Öc—q6&Æ{¤ñ¯Ç¶3À÷ Ééδ̥k¶cöªÙd‹ј·^F¥ Ãaàw³¼*m(}FNà)? %|Š6KhKÚOËþï³!z KïcîØ>Ô®Z4ï‰-žèC—äN%ÂKÖ´H–¨p8Þ¹²D…Ãév‡ [Ö ëýêÑpq`í¿8µt>'œ÷E#Û’N0²MOâ2 ož¬¨‘*G1­Ö{¤±HU^úr!>ÿ|Ù‹ç>‡À·d-^7ˆJ!Æö¾»]^}`qJ4X‹¨a“/žS7J¨PJÓíÕQtÔápÁ6•4ÖOîÈòsV¹S ‚ðÀ¢Ñh<"Ân÷z4œYÓ&.v‡»ÍNFFV«‹ÅÊõk×Ñét÷ŸÐp^?Ì€]ø~ý‡à8Ì’ÍÇó¹yÛ9´áSï”DŸÑs8þgú­Ó€˜ƒ‘´‹(OXX#¦,#溷5™C»60mXW|·™¹/>JXX‡Îá·$¶¤#tiОi.^zº2gn$ã6=-gø“†ê”3éHK8ËÆµ‹Ð}"{lgt­˜·îXöº”Bëhåð–ÅÞ´ÆCçpèµ\í³Ý„=Ô‰]:Óí©AÙO×ö~;¸›Ùc†±í÷ÜÖDömßÀ´‡òì™ÙËs½1ËH´e×1é=¼Tã!:?W‰ÇºL`Íæ_Ø»+Џܶ˼S¿2Cæý\°J±s|Kv}FLžÏލ(ví>ÙigÇ¢ñô<„á£F3dÈFÍ‹c—‘d¹qSy ï«‚¸zæ'^¨NÁCh_¥«“íËq:h~vðÇ®%4è<Ìkyý¥ÑŒ=šÑ£'±áF¶JWœ×Ø´p<=7˜ª…ÓbôâÌžôm<ËëËãùvÂxÂ*âÀŸ ¤°uÑxO[<Ô‰¯ÛÛö$‚ðO¢ÕjÉÈÈÀb±dOd ›Í†ÃîÀjµ’‘‘9Õ̵ädT*&?Óý'4Žÿ ]'t¤Nýg^ÚÈ÷³¾áBº’Ëãõõ †,3pä|1§6‘9——¦ÿH†â,$M!îà|š »ÀÂS—8sà;”u“iÒê+®9,œ‹ÞÈ¢MûyçõTü5‹§?Ï¥ÍshÙf)Ö€|¶Úsªàœõ{øxDó[K:zÑ¢ˆŠŠb϶õLó1(ž QŠ+ƒS[?e[ôWô¸._®fB¯’Ì3…s×Ý·¬ã®E­é4ú"¿œ¼H\̆i—ñÜ“²å\ V ¦ëT{ODò庯èÛ­¤·\sûv,gÞªMžÈ¯¸öÇfmÜÌð.m±<:’¥ó^cת·XôãyO‹›OÓ¿UªÌÝAdä1ÆWÚʨ¡Ï3nÙQÒm.ÀÎof;£ \À{åÐÚ ™Á¦c±ÄûžÔ53é×£‡ã®áR’Ù·3€÷f~̧³¦Ò±Ü)V¯^M•§b²&ç*¯Ói-´¯Rò°S/nâ±gÒ}ÍAÖ|¾„y_Möˆ®L­P]¤( =ÏÊw:±¦þ‹éS§3yü+<å—}œ[LÔW ›ñë–/aÙ©½4üù}f}€ÇŸŸC-½šÞ“ßâô‘y–s¿ŸåìÙ³üvê8;Ó²‡`S™Z´yº[±#úשOŸ'ƒã0—®š ­£ãÊúL?Ï„ù/Q1H‡JÊóïM-½šY‹wcM:L—±?3sÉPÂMjPÐjàïµ Áé™YWµ>”Ö}_ç)? Ãæmc@›Æ4ïè ùn÷L d\¿Êq»›‡ÃK€Ê6C'0}â`ª•ôAmˆ`ÁÞ#ì^Ú-¦Ø9½JO!àž£qùÈF6$þHÙ¥ QAâá|ôöwôk9Š:vË_`lEå’™ UzöžLC õâw¦¹-¸î v¥â€§ÓŸ5kÖNB´nV·A¯ËzRÕP¯í 0k§wÖ4“â ñ'·òÝÞ  [*%êv¥Cý0o]ÚtìAÿŽ•¼ïëOæ×‘½uÅJ‚6ÉUS¥ÍžÇ*¬Žé±?P¥\vjÂy®Uq¦þxœ¸žüJ…ËN÷ñÌ(™K ®›ÂÀk´¹NÅÛ/á´y<%IWÍPÙ½Á“wÎ~ÁÁw¬J_@¸M¼y0þ*J”­?: ò£r%?P®²°×ËÌÜS¦h¹¹¼Yï ê«\âÕšÈ/›’hû^%oŒ‘œõSìi…ÚEA˜Ùiå&vo<[¿É°éËÖ-ÛžY…ÄKÑì¯p¢ lDddcTº2$Ò§ ÷)jµçÔχ"·X1.œ?ÙlÆœj&##£ÑH`` U«V¥JÕ*}Œ¸\®ûLh(׈5É‹WS/D P=þåJ`Ò±õh_žoŠ_°nåb‚ˆŸ›\1§e.©[§>äÞ-àt:±˜s ÈÑ5/¶´võë×§ÞcõéÒo*³?Ø‚YQp¹<ë+7Dg/üðCæ.Yǰ֕r7¢.·^Sëh¬gèÖtF®ëçGauŒµ{ÞŸŽKÊõ»ÙEù¦õÖ{ªíQòt¨æ¦Q6»®ù‡3fŽy*m(uÖ¤Æ ÝÐ¥]¥LÛ•ì^ØÓëqÏköBÔ ªPƒá¥ômÎÕx;£¶Ÿâå–Ùm–‘°Ÿñ¯}CH£)¼ÒÅæûò±Ý\ÎqîÈÍá½ ï+«Ðà«Qq`éaïú •Úó·¬0èE±‹›Õ‰I«F¥Õ€beËœñ”oÿ1ou­¸¸—‘çY×*S­&X·²ð»‹œ+«Æ÷àÀ_r˜ ÷'*• 2ïùZ­–à‚ƒƒÑd,žôÛðüóÞŒ4ÖO™D×·Zæz¨øo6 $)êm~>sÿ 1¼´‘-³û2hÊìŽÚÎĺõ¹Ðüyj=R§À´ŠAÑéå†$E¿Ï3½ç°÷è ¶­˜FÓcÜ>;ˆÔî}gpáÙÎúÑèÏéøöH*ú«Q2÷Ÿ9û'¶¯bçid=dï9t’ë6ÏŠ\‹ÅLüÅcÌØŸ­)¡SyÙ™ê=í2+ÖPhkTiÄÜçKóý¤çøå‚§ ñG÷}"¯ kBHyÏwWNìÀÒ_Îb6dzñë©à8ÌÒÛH°(Þ¾ô—gJÄž|‘ 7ÞÁ0Kxdy8Òc¢Ó„ŸiS«&“?zç5Μ¹@j¦èqÛ.1¾~uZ¿Uðnœ_#§³ÀÒŠ%ð÷%íÊyÎÇf.URXý¯á·»™7£ÅU*g"‘³"±*ä)ï­ú ÅÎöŸ¢Jå¾Ü§¦Ç¨¶0ƒÑ³6‘`6óë®Xlçç_¶r6©x‘ìóZ,™}eO¾Ì†.Ä¥’55»ývûƒ?ÎgÒ®kúq{O\ Ë'²çÐa~ÿ};Î1 ÔÀòq홸`#'Oä³—ž`yñ‘<^ÖGîf‚ Ü¿b#Çÿ¨ÕjŠùÃÏÏ/GºÊ»øS¡ðj•’ãpò5kÖÜÕ‚6nÜ8Ïß¶ÌjÌ/®.,ÿ”^ÊeŽÚvv,žD¿i˽Ÿ]½÷,õŠÅ0gDw>‹Jà•YkÝûqt*¶¤Ó¦)ÎD¾y»-o­ø+SÅôãÇ“©^Ò‡Ô‹›x¤é°\åj=v¿ú¾*.óy¦4kÅW‰6ê¼²åãÛæz¢ˆ‰þœ&ݧZÿ™ëð´>Š!]^å¸ÝMùvï±âíG˜Ù®;n8yü%–ÏM%Íùëá¶Å³â½N¼ùùzÈÊ/¿dÊWÛÚÒã °$fR«î¬NöxxZ?ëÏ–]O0õýÞÔ-gáƒþ¯z§êêòñŠiÄÌíܽ)`lÅ⯆s}ÏÆ}²€9ëÒõá«ô¯ß!ׂVJ¼Á¡£uÇ2¶As޶ú˜M³Úå» 46ê#õø0Ïß;Nÿ–w›%RóIOÛ—¨[Ÿ j8xð ôãÛ¯1·ïËÞò~²z-J-´¯Pìl™Ýœ!_"¸ñD¯lÅL`äÇ<ר£çê;ÃÆÌ C§ŽÔ.—Q ]ÄF/£Q÷·o3Š9#²óÓùdÓ5ÐÕeáúÅT5ÏS}þåé§™_PþòŒûd½§ËŒµÙ¿ôuzLøLÝØº{&a–CŒhÕÇÛž­Ç|ÎG¯µÊcO‚ ÷ qqq”(Q‚ÒeJ£Õj½¢Âáp’’’gêD­Vãr¹°Z­¤¦¦Þ{¡qg¸°Yí¸5:Œzím¤Aê¸Ñ` 4y' ²„Æ×»NÓèõ*À…Ý® ÷æïÂ’fÃàçëÍWqZII³¡5øþƒö$‚pgÄÆÆBÙ²e=BC¥ò¾vìØA:u¼bC§Ó¡Ö¨q9]dddä+4ÔFµ5ŒÆ|àÂÓÀ?0À›“ìÅ„Ôzc¾7•Öø …×£X`0%K–ÌGdx¾ëk2eîj¹s‘¡8ãùfì|üK—¢˜ÁH``0!Á!øhÒ9u ŸÌ­'Z½1_‘`ŽÛǘñ” Â`4LHp®´¿¨Ñ&ì¶w[¥¯â~Ã3“Ùճ†÷o£ÉûYm>mšŸ]­Þ˜)2ÏÉl6³qãÆ|§XnF+­)‚ B^±áù§mÛ¶´k×—ËÅõë×ÑëõhµZt:]¡‹@³¸/<N»—t© `1ßàÆ óýÜÖd⮤J# ‚p_qï…†’ÂgÍj³é\ÚÕp1ÑË ó¾ýŒ¿l‘S¸ÃŸ3‘o¦4 Ê£ýyc`Â}—ó×…‹’?wæ²Áò•k±?É!)Â}Å=Ÿ:I9Àì¸tj,ßKëµòFݼ×\¿¸KššÔ._,ßô ûrzg0ÕŸFùö³ýßó›.·TV6¼Û‘7èÇÑs/SBë`Ëìæ4kÀÑ}/SB—])v¶-Y@·Ñ3h\RÍnÃmªBۚť=AF6.¬ý§–Îçd‚ó¾h[Ò F¶éI\FáÍ£ÊÜgÙú™GDdwLzÜF,¾ÌÔ9<¢B¥ç©þ³ aÆçûŒÄƒŒX¼‡V-ž¢m·Þ¼0` ýº6¾­SWAþq¡Ñ£G;~Ý Î뇰¢ ߯ÿ‡Y²ùx¾On‡6|êu÷=‡ã¦ß: ˆ9I»ˆò„……1bÊ2b®;p[“9´kÓ†ueÁw›™û⣙Ssø-Ɇ-é]´ggš‹—ž®ÌÀ™+*æ+Ç™ùb7z BXX³Öá(¤%œeãÚE è>‘=¶3ºVaaaÌ[w,{Ž^±s|KvGLžÏލ(ví>Á©ÝKéÜe0Ý_üŒ$·Blô2:wLçîz#¡tí[åmv* ¤°uÑxOúCø÷ºýÞ¶pÛ.óNýÊ ™÷sv~7aM:ÍÌažö}¬Ëvœˆ\ÄžŒfé¼qô³„›{ò¯<ˆÝ¿§؆1™u+¬®ÙÊ ÕŸcø¨¡tîÜ™E[þ(8¿|m#‘}Û70íÅ¡üpàkföòØÕ˜e$Ú²âÅói¯tœ¹#W;ÎlÇ!CºÐgôfÆ–s)E²Øãû=^²rÙÞ}`=ƒõ|y$¯ý)vv,À°¶OP5¢#gF’씩;Aþ>ÉÉÉ\Ž‹ãôé_9xà {÷îe×®]ìÞ½›èèh¢¢¢ˆŽŽæÐ¡Cœ8q‚sçÎÏ7òÍïžNÿþºN˜LúÁ /mdÁ¬oÓ£.ÅT^GÔ׃±©GÎÇQÜz’NuÚóRzvü»#G LëÌÕCÿ¦É0+ûN]"àÆƵêF“MÛÞšsÑY´i?üädÉê¯YüÄ*†NšCËc&NEõç³ÕïÒ¤ó[ÌY¿‡6‡þ=o…bççÅ/òÉîœ92 ×ok©ñL{êÖ9KŸ Nmý”mÑר6ÐÍêe«©´b8B«§#y8HÍ•CKh7d›ŽÅòÇФ3ý¾p1zÖ7 ìÞ‹þ•?å•ïM¤Z!¢a_¦½p†6â°+…_»ED±Bó~ô‰ ¾Ÿö,[ÊÏåbÜ Îï˜OËþ]‰U¶ð~·€ßÌvNF%àzt7ûªÌ§Ú¤-ý×%n>¬~ûYúµýš5ûÿ TÆ_¬ž·Šãv7i! Ù´ásfõÆø·³£€)¨ Oô¤åO ©k ‘C^ã™e{è_'˜“ëGòïxk¾]wp~¾¶qrO'®ý±™E7ÃÆÍ¼³x5KçÕ¥ßko±èɆLìX Åeçô©t’-¸ðÔûÀªÁty§¿üKE…¨¯_£Ç„M,6›ô¸½¼ùÆ—èÃò-Kšª"}ºóõöd˜íäIUéiòÊ:võIäôÞ­¼4ñc"?Éï_6ÜGÓ‚ <˜BÙ²erUËo׉Á`ð¦TížM¸m—X2OÏkm*ª8ýæ¼æµDî:ïýLFÂ!zLÜÉÌ} 5¨ÐTcâ»Cèødy܉‡ LÓº®²ê•¹TiJì±hNÆÄ³á†â§k)EçÞݘ¿q)­}^œ ŽÃ\ºjÅΙè•Pz áÁ*´!u6ª ”xƒ¾½š¨ÓSµIKbÌ[´™#~Öû‚®}«¼}®îgÄâËTðËàÀîhâÓ=ƒö²YG°( jC öa÷Ònù ƒã?,`§«Îë¿}à7œFÏgVîüƒˆz­éöD åÛ̪ñmyô±–ôè]ºðFT^W·ÝÌŸV;+¿ÝF²M¡F‡1t¯”W÷9 ´‹×ƒhÝ÷užòÓ0lÞ6´iLóŽ=è¨#Ýî™ÖS™±c/ßÎx• [Ò~ºŒý™i‹_ñ„`d.êIDAT­GC­æ²‹­ÑRú‘2”(Q"ßWéþ¨±‚©•Ëæµ5“*ß©p"*צÀqœ?ö#B œú|0¯Øä.)Â}E.ÆÝŽÞZ—ldCâ”]º$^ÀGoG¿–£(¡Sa·üÆVT.ið6 {O¦!zñ»ÓÜ– \HwP»RqÀ‰ÓéÏš5ë'!Z7«'¤º^—u˜µ†zm_€Y»p8¸³ÏÏSeüÉ­|·÷ƒÅ–J‰º]éP?¬hUéi=n/OÄy¦0>Ù¸/×`©+V´I™Ñ@¥Õåú®_@¸M¼y0þ*J”­?:Õß¼ö-òN¼ä|þz'šÀFDF6F¥+ã Œæ\ÀÑߊ• ÇöQµã‹ø©Àétñ짬oí¤X©²˜Ê %Kéj¨\çiÒ—sÇí­6”¦ù€ÇùjÖhj}1šÉ‹72¸M­|Li…Ú-&möЮ¸ón4 -“-†o$^*Ûcáreïüð-ó8oO{¼Ð²ŸÙð˜—ñûŸïR>"÷âãŒÔ|<7a©ÎØÕsøªùˤ¦Û¹³ ‚p  å‘£æ1yñjê…èqªÇ¿ \éLúâ#¶íËó BQã Ö­\L°ás“+¦à´¬`uëÔ§QƒÐ\IN§‹9·€œQBóbKK`ÇÁC” À•Ã#Ú©š©ÉÉ‹ptÕ$ºŒ]ƪ]gyeBU ${:ÝRhUžÖ¾ óó_¯Î‚·VòÖÜŸ(’{ÜÅ• ¼vay_IŠc+Zµl–c*+³ ] hn}}kz)žhØð&W¾ {>ŸNû›í­¡ÅÈÏYWö3º¾6—iCÛ±eÌJþïõ¦¹c£ÜÂ6²ÇX‹¸Ü!kA°âÊÿ ö1<‹J›ßO͉Kˆ!ßïz2®ýD•"-ð4•}˜§ü4ÈæVAî7îÉÔIÊ»™mIÏÖ¨S¿>õë×§ÞcõéÒo*³?Ø‚YQ¼O†+7DçXxwÅ/Oâ³½À´‹7¾³gÿWÙ7ñ‹»æðÞw1Þ÷º7ÿ+çö{<$¥LyÒ+4ì˚ϗðá‡2wÉ:†µÎÅC­Ë;ˆ¸-¿Ò«Å®Þ8ËÔ Ë>7M"Š¡ÎÉu›»ÝŽÅ|ƒË1w`w|¶'Tå"H¯âç_¶súÂÖ}þ6§ŽìãôÅ«žp¦æ¸²ÄÀ¯‘ÓY`éNÅøû’vå<çc¼ŽÓ˜×²ûÐïÄœÙJ‹á À¼–M»Ïáp~íÂò6•¯Í€PËǵgₜ{‘´B< …ÖÕ¥°gî N&90W¥sžàS“Þ“ÿöŸ¢Jå¾Ü§)Ô6ìÉÙpÃA1½6—g!ËÑUïJæd’SÙštԱ赖|½í8—~ßǻϽ’mÓ•ÛsáÂ…‚_gñpx–¼·c×gúæbç×£ ä›´¯_*Ó..3©ÁÃ4}q) îç…já|´bf§‚Ûr‰zŒaø¼™Tñ—ðE‚ Ü%2ï{›6mbРA 2„W_}•#F0|øpÖ®][¤X'¹îJuÚ¿ÈŒ×< îúŽûˆU«W±ô«ÅLì]‹ý f2rhVþrž¿³‰nËìg™´ëëÆŽgUT\Ž ÙÙ±x&3öx¶ÇŒhõ(Qú3vó·¼ÜÈŸŸ¿˜Bïýñ³œi]«¢Ò–.0 44ôï÷)EÒ¾èÙ¡-ÞÍàÇ3(kÈ7KÆ=GxXk·Å1ô >P¿R5j`ÆÐvLYØÓ{Ø•#Ãã;ùx~4uæoe41ÿ—X0ú=6ï=Àª¹ãÙpÃÁ²×[²æ@Ž3-¬[ùóšµoÓþoµôj& hGã¶‹¨øJßÜÞ½¾à—VëYK3vŸôZG½Šåعoîo˶‡zŸârau)ÄJEmôL~8®W(Gùê¯ò𼟘رšÜA¸K"#û>üôÓO’+Ùd2Ñ®]»"Å:Q)9äÈš5k¸µ”qó62nî×Ô-cíƒû‘ÓF±êŒ•>oJ§Z%n™yãÆïR]جvÜF½ö6Ò õÆ Üh0š¼dêÅM<Òt_ï:Mó0=—?£>w;­¤;òþýN±Y­hF4x\àtèµ…wâ¼Æê·ŸÅÒéÿx¾N0‹ ÖÄý4ìŸÌ¹ý}=ó÷Šsš_“/\¸Ðäù][Çõ"å­8­¤¤ÙÐ|ó´…ÓnÅ­ö)´«™t› ¿ï‚׿gü…×UqÚI³Ú0ýò”ë̆W™ž4”khE+C ‹ú4¡ÒŒƒ<îãµ—4«_“ {ì6*7À’§i]%à¶íÄøy=:v+|0êUÞzøšn³ü‚ …pùòeŠS¶L´:ÏöÖ°páB222P«Õ 4ˆ¦M›¢×ëQ«Õw¶½Õåºiö\]œ¶#=‡­øl?ÿld £1_!QxøxÓ@’½ðÓ€ZoÌWL¨´Æ»&2 ™½'oý-E€9ncVÄS>4ƒÑDPp0!ÁA¸Òþ¢F›0ïîTzL&ßÌü5yü®]Ô¼UZ#ù¶…Vo¼e=tFwGd¡®*­“É”§\ñG¿á™ÉáÌêY£PÛ(ŠÐÙþI{޵ú’fá>¹ìÅ”9àÛmž©6V{Gv’ŸÈÈjo£^•«ž&‚ ÜeÜn7Š;·xüñÇ©Zµ*=ôõêÕóz3”[ÌsÜÖ„®Þ¿ÍŠi #sÆÚ€öŽîÝÀ¼5›¹påú}[Öb!átÔ1 yuÂÂÂèü\%¾Á哚ÿ­æ?™÷ýHP¥6œ=8Š0ß¿)xTëõ=óÖË·RbØðÍ»ìÞw’t9­S„ü¦Dz÷î @·nÝÐh4ÞϨ(ü¾zgÛ[Õ>èБÈaNÂÚ‘ÈÈ®8VâR /t_¬Suæ;Éè3h¶ 7Q¾\¡†û:ïûSðÝêЇæ"9>Žðg?%²½ »Õʵ4'Åur×áÁD,ÎСC©P¡*•ÊãùP”B…Þ™ÐpgàÊ:ùÃ\‘f-*>8ªRëG¥šµ©ô€åý¿‰†ˆÚM‰†á¿Æµ‘Cs( Õ«WGQ”l‘¡( P¨Ø¸­©KâE~Iw\ëQŠËჂ ‚ð_ÇÍ"" §Ó™Gd(d¾w{þÍ=Mn ¢8X7õSô¬‡8ƒAá¿›= Š[Áb±x†ËåÂåv¡vªAã'·!4<[æ.Å^¥Né0lé)\þã«>ø7'ín^õ Â|¥'Aá¿—Ë凇ÃÅbñnmU©2£¹:]¨UjWÃåÆåÊÿìâ\çh¼Ù·3¿‰Îû)]z¾Ð˜õë\ô9“¢œ£á´[±Ú4Z:t*6«Ã]ÜZúOaNäšÅ‡2%ýÿ9Õé´’|-ƒ Ð û~—ˆÃšL|’“²åJ¢¹Gí%‚ Üš³gÏâp8 $##§Ó‰J¥Â`0 Óé¼!â³þ_£Ñàr¹°Ùl.4îvôÖ»w`— ‚ "AA‚ ‚ ˆÐAA¡!‚ ‚ AADh‚ ‚ ˆÐAA„† ‚ "4AADh‚ ‚ BCA‚ ‚ "4AA¡!‚ ‚ AA„ÛB+M ‚ B—.]B¯×c00  z½N‡V«E£Ñ R©P©T¸\.œN'N§“ÔÔÔ<ù‰GCA„ÿ"4AA¡!‚ ‚ AA‚ ‚ ˆÐAA„† ‚ ‚ AADh‚ ‚ BCAA„† ‚ "4AA¡!‚ ‚ BCA‚ ‚ ˆÐAA¡!‚ ‚ AAþËÑæ|Ó£G;ÎhÍš5Òš‚ ‚ äB<‚ ‚ ˆÐAA„† ‚ ‚ AAþóü?!ED¿tÒ­óIEND®B`‚rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/basho-landscape.gif0000644000177700017770000000517712633765070033203 0ustar michaelmichaelGIF89aÜNçÿÿÿ¶³´¬©ª£ ¡À½¾¢ ¡™—˜àÞßÕÓÔÔÒÓÉÇÈÈÆÇ¿½¾µ³´¬ª««©ª™–˜¶³µµ²´¬©«£ ¢¢Ÿ¡š—™ywyxvx™—™Žˆ†ˆ‡…‡€~€€€xvy‡…ˆxwyqpr‘އ†ˆ€~€qpsiilhhkqqsppriikbcfhikbcebdfaceííìø—ù˜ø—ø˜ê’&é’&ê“'ߎ.ߎ/Þ.ÞŽ/ûµcýÈŠÞ/Õ‹5ÔŠ5ˇ;ʆ;ʇ;ˇ<„Aû´cüµdûµdì®hýljþÈŠýÇŠí½†î¾‡í½‡ë¼†ê»†èº†æ¹…áµƒáµ„à´„Ú°‚×®‚Ö­Ö®‚Ï©€Âƒ@¹€F¹F¹G°}K¯}K¦zOӫѪ˥~̦Ë¥˦Ä¡~Ÿ} }¾|ihgîíì¦yN§zO¦yOwS”tV”tW‹qZ¸™{³•y®’x®“y‚n\¥w¤ŒvŒqZƒn\ƒn]‚m\¥Œv¥Œwœ†t›†t“r’rŠ|p{k_’€rzk_Š{p‰{pyqkjfcumvn€umsibyqlzqlqlirmjjfdjecrljiggàÞÞÕÓÓÉÇÇÀ¾¾¿½½îíííììàßßßÞÞÔÓÓÈÇÇÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ùÿ,ÜNþÿ H° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹3jÜȱ£Ç CŠI²¤É“(Sª\ɲ¥Ë—0cÊœ‰ 0`ÐÜÉ“&Œ›8qÒø)CFÏ£HOæ¼i³èP›:“JÊñfNL‹ÅJµ«×‰W‰.Ízó«Ù³ Ÿ†ejs¨Q´pãZu V¡ £ÆÝ+s¨]œ9a`"$Š]ƒK†ú“¯c•?çÊÀ! áÊ4- ¸-[ÏCäì9GËP,äŒÕmàÖDÛ¶M»£[­4Lã°,DàëÄAí¾ö¬¶qíã¡>„£yŽÞÿ–½Kׯò§Åõ"ßþkl<6LþçðM¸uál½sþ›™»{†nýÊ/ðîϱ­I{F9½ö÷tÛP¦ ŸS‹­‡ Vcà ƒE(¡€Œµ—Ÿ_‰AEl@Ѱ€ƒ jØ^^ñÙ Z³¡¥qMµV!v­(£zoÁ'Ÿqïõ™ŠamX—U‘I×¢Œ2.æ]M• ‹Pñ[|‘ Un€@¤ƒ)õ_M)ùžr;šu’BiU‘AµµØ•v¸¥AÖ= w²¥\šc Åf²!YÁž ùfA± w"vC™Eæ…wú Ž:UcB¸]uâ]m™EkŒÉ€‚£ bj H.X‡b:(R›a þ£Æ â_“”'ŽîÍ€›‰^ù×ç}²ÊZ[ ]‡ÓœˆŽHU’-"HC°Á®—ÖX¸þã^iyFAædcµÞ—iE‚…‘¤÷½ +´±Ò•q5©¦”qz-¯Ö’‰ïAú!ÙdMט!q«Ô§«ÞU¦¸ë±+[ õ—iS÷Á¦fÁ1¨ïSœè]˜ÿ*徚]œ™–è¶Úеt¶héDuF¨ƒºÙ»âÆ,/‹$#ÄSæ¹h-Á5Iìb™‰f<¯ÅPΛtB CIíR¡çZºëÖ h‡ïžêZ~G'»P”Rbª_…âÚŠŸbj­4ŠVGp­U'îÏŸõlêþ[ •€Ö{Êh ١‹ «ÅqÄ3i²ãzûˆé½Ê([Ø.¿¨wtyö¹©¿†v:6ÎæM|…s‰;s|ª™ƒf.ßǧ :&œðBŽ-¡m#žfV>tÎ<ÇÙ™·͵.cY›î ®·:ÁÂmÝ]ü–Ý"¿W‘–bÉòþ´€àjgº T±¾o)Võ>"Ç·ŠÓƒæRš¬—ü!…®áœÒt4İ¥Zõ¡”–”ƒF|w›ÅvW¬¥Èè6õ T$…0é> ɇgÌ`l@‹’AèBˆXåZP›Ý¾`ã/øøË*GúËŒ,X?ù´‰+þ[üp·eµíe¦Z̸êö¾¦ˆŽc›³œ¿&…¾¡PbCTZóàš¡Î~‚Kòô—§#!ŽGÌ"ÓG(%š/„‹¢åÈD%z‘Y‘h+ˆˆH9yPè(%9ò®R%³ÝC^ø=õ].ITlè–±©On‹<WC"•îJ&ˆ’ºn²‚=9@=´Ž ™¥,»Q²`‚ß Ÿ”¨MR…:V}t´-]'yÒÙ#›"€´Mé)pÄ*!²˜Îq{y|Q 1T¢ÍQK€¸{¡Àî„M¨Ýp“ šö4%ÚmO¤(Cì3¾oÕ2œ¾[$ñÞ•¬B†ŒšIþ¤c}dHð±ÑF] Ö„#œ0²)H+34)íaÌŸrÚ[‹te¤6¶moìÑ 5AG ½’KOa—:({®“Eò”Žvb Î9Ò‹DÄ‹è@^ôQ¡o¥£ !ZeMñIâ:Ç Mj?ÝôÙuˆ:SµSy‘ÔÌtö…žzózL]MÃ~0˜’ª©T—H!­l}ºÌ$Rɧ¸ >ÉŸÒY™”þR/ ýE.l»v Í3•E¬+µüúO[)Έ±|h9êÂB:O,:µÑgz²áD6_s1ä7—¨´¢°nfÃX #«×¨ÖgrV}Èp Ê®Ì5«6Eþ ï‰ÒJìl…$Sîù¿KÎëmÁX†ªE½AB”béÖ'eUŠ2=0"@3ænÿ±@£¶S«¤¹›Nz'"+‚¯†– í W¸4a3eÇÂ-ê¥”Žº^#!¢ª£]hûQ§ÏvEÐ8Ql¸×õ6ÕK2–¢ðjÓ‘³f©8ÓViŠ“\ÙÄšµŠ–×ê`…í\¤N–´glÛŠ|8±²0r¾ 1„Ö‘Íëg2£Zrœü œ+~ñŠ7TQÍLÑ ÷ªT}0w!~ãG¦x°)Âvš/ÄìÅVìàC^ sÛÅeg:·ÿ^Ö7b«°«¦ÅË{Éx$0z_cGUªèH*+§ªÙÔ3ÆË€¿C,/ʸW+lå£ðq —­Ú]º™M*dtäÝ 9úÑŽ´¤'MéJ[úҘδ¦7ÍéN{úÓ µ¨GMêR›úÔ¨NµªWÍêV»úÕ ;rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/chash.gif0000644000177700017770000002453512633765070031244 0ustar michaelmichaelGIF89aääö  %" $) 1###""-,,,%%2,,7/.:33333;<<< H D S<desÿc,ddscmBmmodÔ(cprtü$XYZ `5Ä*XYZ o‘³còXYZ 'Dó³ XYZ óRÏsf32 BÞÿÿó&’ý‘ÿÿû¢ÿÿý£ÜÀlcurvÍcurvÍcurvÍvcgt) ºvPEa”ÿÝ A º 9 ÁWèvþyæJ›ä6Zy ˜!¸"Ù#ÿ%"&F'j()»*å,-C.r/¥0Û23I4…5Ä78E9ƒ:¿;ë=>:?Z@{A BÅCæE F.GQHqI’J¶KØLûNO:PYQ}RœS»TÚUúWXDYoZ¢[Ô]^4_d`‘aÁbòd"eUfgÄhýj;kl¾noOpqîsCt•uðw@xbylzr{y|ƒ}†~‹Š€Œ‡‚}ƒx„h…U†B‡)ˆ ˆì‰ÇŠ¡‹uŒJ玳€V‘-’’Û“²”ˆ•^–2——ÿݘ³™‰ša›8œœçÁžœŸx U¡4¢¢õ£Õ¤¸¥Œ¦V§#§ò¨À©ª\«+«ø¬Ç­˜®h¯:° °Ú±¬²}³N´ ´òµÅ¶”·c¸3¹¹Ðº»M¼¼Ä½‚¾@¾ÿ¿¾À|Á=ÂÂÂÃ…ÄLÅÅÛÆ¥ÇqÈ=É ÉÛÊ­Ë€ÌSÍ%ÍôξψÐQÑÑâÒ®ÓwÔ?Õ ÕÕÖ ×lØ9ÙÙÕÚ¤ÛtÜDÝÝéÞºßàcá6â âêãÂä•åeæ1æûçÉè”écê6ë ëèìÑíÆîÆïØðÿòBó™õ ö¤ø\úFüeþ’ÿÿAäqÓ·°Çÿ÷= •  u ô}‚þnÏ*x·æ(H d!"¡#Å$ä&'((F)o*“+¸,ã./70d1Ž2¾3ð5$6S7Š8¼9ë;<=5>H?X@nAƒB–CªD½EÏFáGòIJK)L:MINWOjPwQ„R’S¡T±UÆVâXY#ZC[a\]Ÿ^¾_ß`ÿb!cJdoe—fÃgôi"jUklÆnoCp~qÄrütuvw#x'y(z({'|&}"~€ €üî‚ރ̈́¸…Ÿ†Š‡mˆS‰6ŠŠ÷‹ÓŒ«…Ž[3 æ‘À’š“ÿr”P•-– –ì—̘®™šu›[œC+žŸŸî Ú¡Æ¢¢£m¤=¥¥ã¦µ§Œ¨`©5ª ªå«¾¬š­r®K¯%¯ÿ°Ù±°²Š³c´8µ µà¶´·ˆ¸^¹3ººØ»¬¼½S¾%¾÷¿ÊÀÁnÂ@ÃÃçĹůaÇ5È ÈßɵÊËdÌ?Í$ÎÏÏòÐÝÑÈҴӜԃÕjÖR×9ØÙÙïÚØÛÂܯݛދß}àoáeâ[ãRäKåFæDçAè?éCêJëRì\íjîzïð¨ñÀòÚó÷õö<÷_øƒù«úÒû÷ýþ?ÿAÿÿ^Ã6®>äÿšc>*  " $ , +$ûÚ®v8ùµr0ï¯n.ð³v;Ì–a / û!Ì"Ÿ#r$E%%ó&Á'„(>(ú)´*n+++è,¦-f.&.ç/¨0j111õ2º3€4F5 5Ô6›7a8(8ð9¸:;F<<Ú=¤>n?7@@ÌA—BcC0DDÎEFoGDHHèI½J”KkLDMMôNÉO•P\Q#QìR¶S‚TQUUðVÂW–XoYFZ!Zÿ[ß\À]¡^ƒ_i`La5bccèdÊe¨f†gah@iiÿjàkÿÁl¡m†nkoOp7qrrîs×tÂu¬v˜w„xqy_zI{1||Ä}ƒ~EÀ€8ò‚¬ƒg„"„Ý…˜†S‡‡ÍˆŒ‰JŠ ŠÎ‹ŒRÜŽ¡ZË‘„’A““Á”„•I––ß—®˜™Yš3››ðœÔºž£Ÿ }¡o¢a£N¤2¥¥ê¦Å§¡¨~©_ª?« ¬¬é­Î®³¯ž°‡±p²[³E´0µ¶¶ð·Ü¸Å¹®ºž»À¼ä¾¿À3ÁSÂyèÄâÆ*ÇÈìÊpÌͿϤѴÓ÷ÖyÙZÜžà“åNë¤õJÿÿndin6ÿ™VÈU‘°'‘`P T9 =úá&f,E_x‘«Åßù0Lj‡¦Æç .T|§Ó5j¥ä$g¬ó;…Ïjº ]°[°  a º  q Í * ‡ æ G ¦ l ÕDµ&œ‹ýzú{ÿ… ‘¥2ÂSâv ¢:Ólœ1Ç`ú —!4!Ô"t##¶$Z$ý%ÿ&B&ç'‹(.(Ï)u**»+^,,¢-D-æ.‹/,/Î0z1D22ù3×4³5˜6{7g8Q9C:=;3<6=?>J?`@{A¢BÌDE9F~GÈIJQKLÔNObP­QþSOT¡U÷WJX£Yý[U\­^__`·bcldÃf7gÁiBjÈlSmÚoipør…tu¥w455é6Ñ7¾8«9 :˜;<‘=“>›?¥@µAÎBäDE$FLGwH¦IãKLbM£NæP+QqR½TUJV‘WÚY"Zn[´\ü^D_Œ`Óbced¬fg™ijlmŒopŽr sŒu vxy›{#|´~@Ópƒ„²†U‡÷‰ ‹OŒüŽ­`’“Ñ•Œ—N™ šÌœ“žV ¡ä£¬¥t§:©ªÂ¬c®¯§±R³´¯¶i¸%¹á»Ÿ½d¿$ÀèªÄnÆ+ÇïɨËcÍÎÒЋÒ@Ó÷ÿÕ¦×WÙ Ú¹Ü`Þß­áOâíäŠæ ç²éJêßìpíûïˆñò¥ô0õ¸÷GøÖúdûýýŽÿÿDj‘¸ß2^‹¼î$^žâ,Ü>¦ójã_Þ`á g î y  ¯ C á’Eþ¸t3ô·~C بzL%ÿÛºŸ‚h Q!>"-#$%%ø&ñ'é(ß)Ý*×+Ô,Ñ-Ï.Ò/Ó0ä23'4H5k6‹7¯8Î9ò;i?…@¢AÂBÝCþEF=G`Hÿ…I¸JíL)MaNšOÕQRQSŒTÉV WDX…YÆ[\I]Œ^Ð`aZb cîeBfÑhrjk¼mfopÙr”tRvwÙyœ{\}"~Þ€¡‚d„$…æ‡Ç‰°‹›{X‘0“”Ζ•˜Vš›ºgŸ ²¢R£ï¥ˆ§¨´ªY¬­Þ¯¨±t³=µ¶É¸ºP¼½Ø¿”ÁWÃÄÚÆžÈeÊ(ËôͻϋÑ^Ó"Ô”Ö ×‰ÙÚžÜ$Ý£ßà‹áñãLäåãçè@ébê{ëƒì…írî]ï7ðð×ñŸòWóó»ôXôöõ‹öö£÷(÷œøøƒøñùRù´úÿúxúÊûû\û¥ûîü7üvü¦üÕýý4ýdý“ýÃýóþ"þOþzþ¥þÐþûÿ'ÿRÿ}ÿ¨ÿÔÿÿdesc Color LCDmluc nbNOèptPTúsvSEfiFI daDK0zhCN LfrFRÿXjaJPnenUS|plPLŽptBR esES¸zhTWÊruRU$ØkoKR üdeDEnlNLitIT.Farge-LCDLCD a CoresFärg-LCDVäri-LCDLCD-farveskærm_i‚r LCDLCD ÿcouleur0«0é0ü LCDColor LCDKolor LCDLCD ColoridoLCD color_i‚rm²fv˜oy:Vh&25B=>9 -48A?;59Îì·ì LCDFarb-LCDKleuren-LCDLCD colorimmodœgÁ´Å1textCopyright Apple, Inc., 2009,ääþ€}‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊÊ)|ËÏËÎÐÔÆÒÕØÃ×ÙܾÛÝà¹ßáä´ãåè¯zéíêÓîñ©çòõ¢ôŽ|ú}ûöþˆøé¨oÏÀ Ø“_A96X°¨!‡ ¼„ò>¨Ç‰D YÀѳï"Æv q„²eË‘$MžD—²>=yj¸tY#OÌ™ñj rÆ';[²Àãó Pn%`G”ŸUBEóใ4© wòäé÷TQ‹ ‹öìM=þxðÔ¡áU:L–æÖâž=z Ö#ÏàÃoÚ™“¦n¼M÷ s{8Ïœ/)H|ð`A@A‚H¤3‡©Ö:uΘ1’É™:všÊ”lË"ÉÀs¸À„(¾Œ13²4>¯ç˜ãÅ`±zº .$º²·áݼc¹ý‹óL ðrÏ"¡}ðœñB" ªq! `Œq¹é•ž,D‘]| %ˆ‘$ø’‡$`g \(ÇœLUµ +Ó8ÃN_€ c°3I†ˆè1†„¤Àd ž¨ÊM€å1†ÿ}!c%4*þ¢Ç¼øEnyt•¥¨XNZ$`f’$#ypaAZö—‰T†RP`w €@stò¥#s|€À væTš›Å^%@ŸÌùˆ$ PBE¥ cpSfdrV`uŒ ]Šž&y  €yÆôi$0v3g`Â{x¤€ §zY«¥n¦àS”€ B8“V: A8„’b(%w\7†nd¡ B9« »?AÖBÖ*{+'c$¢鈯éLÚj>å!k3¨,k Z  k¹0m;«®+ŸzÔöÍó­'yX€A©{&ÂÈ,#Wþnh/+òf"«…¦.‚n=#ò&°Ú ƒrF&ˆ­M!üêO¿*½5‡¹JÆšèás@kˆ¯)wòP°ð¼ <ÛèU‹P48ÕrS^ gÓW‡²ªB÷B@e]q½vÈâ4'v  Å®ú|œvÔÐåaÇò6'x@`‚az|`uØåœ5"H 3صè!Á €ð8F7™!ÀiˆßÓ¹(|‚n']ŠÇtëöçj¢^á/Ës©V"$@³9¬ƒB´$ä»; Še‚Îܾ:-U%ÁàzHið¹›À‘GCΠÝ}èA™Q::”CþSV³u] з Æ¿3‹á†à@f2ÔZá/³õ´mˆº± ¬ö„ˆ›w&À˜¡(@ÌÐ0³lMq_;Dú0–;M¤FýË`NP€)XÁ S(@:f¿¬ØALàÉ\ñ·y®V\‰\3\! 8ÌÂ#£Ap)AÄ1Aƒ½‚}ð@ îp‡¸P` 9Ìá(P¶c\ ø»"ŠxŠ €JB€pS‡X!Š8´Â|WAXÀŠ‹‰€£·ZÆE(Ž9s0#³`…@éwÁ( ì€HBŽž[Eò$‘ ˜Á €"§0È8/[à 0þ@ D‚‹ù’Ù$0P‚1¤ 7ÌỀ›îµERÜù"Á?Tø/D«Dà1„aFp‘¤[»ƒ i OÊé•ù@¢%ù…/  (€R` V6š©È ¼€L8s d„4/‘€xáïü‚ºÉÆÉÜD.ˆ”9W8Ç*Õ‘á‚g5 ´#Ø#+w88qNL¤3ëÌ„D0Ðyš¡˜L18MqÅ9 Y›h¨%ª’Zè‚,z†æ4‘tÀ¸ç@€‚Oˆ”·T“I/ŒÁ@-ÅÍKMµQ5‰SsEE??€QT-{À.Úþœ:°¡,x â ÑúáâAˆª©Ø–úLQDÔ'UéЄ®„d$ñ*ò^¥v 7ÅPRù±SP @ -UC]FÒÀZÜÓ% A)òê’öᬠ  ˜C¯ôdj¸(H]ÒQ0–ådAÒå¸u'KqefÁz‚!šâ³ŠÈé&úꉔò´.‹™r¡ºÚ.°8E+ÊSLJ 2¨ HÓ¹âÄ^°À*‚k/>u@AS‡&ò š• R¨ êB¶.,n*¸€/µ¶ñæ^/AW<صæD Gk Âp¡ >hÁ Và‚!”'A€lEoå¢þNº"¿MumI .X¸ ^g7ÃrLÃBG.ø,Ìû6þ¢â Àp†5<¢¼Èyp±ÃÖ ê¢7Ä•…WÌÒ9ó’êy\ê׎˜¬z­Äue‘ ÕÉX–h¹ˆªxÉhWgÁ¹|·`¬†õÂ[@€ ;‚Ò7ç«ä=¼Æ%ÀE^o¼ˆ5ç¢%h)sBhJ tC.nÊh‡€Í¸Šé2s1H±AÀ]m!Ò$åX»$õœ{c”:|¡œ»hèžó1aX$à ­œµ‡ó@eþ€Zçì´M¸Ì ˜ »Ýã-™Aà_8SÙZc6/Zäãæ:W.7ó/<)”Wû 8s+=¯×¬l–¹Fó °íh`¸ï6%b÷°jm-ÿBŽ)©w0R×Ê»¡tðž…Ç]‚¼#¾Ðí'u˜C‘‰ÁEFCüØÁø@ *Î[fs X‡QÄ܈V÷yzóáØ|@ÄŘà9ÌMŒ/|ÀÇfÒw$ \™ãKõ7_A> Qßæßœ«¡årG"Ãxßx92ÐmhY=Ï­ƒ€–ŒÛ9\àǘƒºÎaƒÿÈÐwê  šùOëɨ˜·‡þ“®‹1CàsV='âËÀ·Z3sç!ðª~ƪ°m'#”ª¸Ð7¢•¸Á±øÀ‡¨ÁÎÁ»úêWÏúÖ»þõ°½ìgOûÚÛþö¸Ï½îs_¥!KôŠDâÄ >` @ÿ®‚³’q¥­ú‡¼CY~iyäsó8ìÂEx¾\ÐÓ—…â­ï²‹£ÜXtG†Ö·~XØ!ôT>Š˜?‡1ÝŠˆïÃ7Úÿ` ¿åcàæeª3Ú¦tüÇ cg}ç}Cf^vtrJ× ¨ ˜|Øh¨&€s|‘ó&xbÐbò§H‚´Cb%‚#(AòþÖ ÆÆ€láxgFö hw^q4ƒ»ð&0"‘ƒÒ¡ S–çƒ?H|¾°=]— ½w±ñ¸ xwWH%8 0UtÐvÎõxb'æÃƒ0hØf^coX§wƒµ@…g à„™•†jØ]ø cXÐfq§ænc€ ¨ =ˆ[h}Ø ^`tø–‚ c Y¼…±õ¸ ’EOQBs˜%X¨‡Š˜2«A¹@&ÿ·[´–g_°¼EŠŠ ›x ˜7UòµˆT‹_–‡L·‹Ø„¹ _ÆwÑv µV‡"0ŒàE‹‰PŒÆx $€Øv¼Èþ„˜¸†<Ò8”A·Ü¤Œz±5cÛ‹f†"J„Ss‹‘@"f]¥Ž*ñ\ÒVFgᘉ•@`÷xU±Uåw½GlÒÁ! ¥)•@ŽLFQ²§Å\å=óWsÛÇ4ö ˜( kHD@x þ¥ápŤPsõ‡b‡¨Hñx Ôèé (–ac\–å†"ü‹%à`ð˜h˜“tÒ†®ð!½4¸¥E’bвh“Ðh’›°“ª°K\ÐKb0• ñÆ$ˆóç{cÀ$ä… ¡Ó•^ù•) b"ó”Iqejªpr÷% ?rþ“šÀ”pŠ« %a+5Üå;`GleØ5¨“ 'i‹uÙ «‚—c°RHP’æmkIum;:¤ä ˆ `I ]P ?šAà+ÀÖM òŽácb÷PÓYj’™‘𚜉‡ŸprÃb´RÕô`ðføfš*英іȩd­ÉT¡›‘å*µ+µRËÑ’9fZ°• :JÉT󥘢°KZ OT5g Óažs tv•f è‚óù  œ“ žœ°I*uQ°‘qþùŸp6i…E”CÖŽ¢’T%Ù ú Né „‘ÊTvpv`þZ¡ª5#œ]+×'† #J¢—© (°%oÖ̃ÄDÌ% Y ÍH)ðQœ@Ÿ¥°£<Ú w (šy¡A®¡Ab6 `õ^Hé* ê…§ÀÊžt‡AT H†uøY"–V¦fz ç ᲟžHT±~yjµ6“]й¥§°™!U¢J&²#t3%ý £ãpAu5CÌt§õi ŒJ—= )€B)jIa©Ùç{`p0\Ж\`ò‰cx¥Ó娑°Kª "€qLS[€ ZÀÃ’«ºº Ú8" “þ 5”J8´C(ÊHx£Ù­Ñ*­¼Ú( ZÐK¤&‰™=O´GS_à\pÀœG®QªŽÓŠ3†F¡AHü`z„F}TM] ‰œZïåÊ ÿZz€ rªÚhO™š°QÔGbP¯\C1;±{®‡à°®Aê]_ç âT IQ4¯¡ öšÛ#'‹²);ª„Àæ8°×)%ÂÚ&T]ܪCÀM¡)²¶*´Šú Rê ÿêQ&`­²†­ßæ¢g0ÀôAS0!ðSú ›(é‡? ª³¡v (.K„rȱrjJ °M,õþHmÙ°!p†û©XK ±é>"p·l:”1ÕŒ:,öŸþ9õÚ¬Ó3q»¨IÛ;© àZ"K:Ÿ»W”qÛ—ž`f¡˜;² úйž[ äÈPH]pª×¶´&œª¶pFF¯H«¥:0ˆÛ?·0| )€—(¹$N‹q¹– 34H¯ˆ \ *ßH Y; gÐ;–ÀÚ—©kiÍ£.ú¢P&×½\PÏ›ºã{œþјAÊ#À›Y˜ªqÑ¢Dº+8T6b-û£Ž#¾&'€¢#×Éë«do!¿ò ù wp™ÛHƒ7 ùë Šþ—#ëÚ¤¬” 1kEÄ‚hw "к^ )àù# ) 7°Lw 54% óC?H“0ƒ²ÌZd ´©ÄšàQ"ç²r`Ç”Á>bLzp$ bÛ–;+ °`ŘŸÜ1–SõtBÂ*` —¤T_b»©)P£ ±yê yà P)°‘ŠQ>a*‹PšIiì½)ð£Ù ¯ 8Ù½ü‰QåR±ÝpµØvIœZ€…+®·Ë n(°®Ü]°C Œ ¢<ÊÂ)´ÊÃ%Ð}¢Ç½j’ZлëéM=RËJL®“Àí¸Ã•Ü$þ𲨫Ф€Æì“;»r̬ z€ ú<ín²á½;pƒ ÖŒ JC!ÚŒ¾TÕ¢B9¨álEK,î{¹!Û°•¼-`œ˜l x€@SÛÜÉ@e†ÏÅ`ËûpBæ¾Ç+²•lM‚‚Œ“U"*äœÛLP.ÅF·ÑÂ@2ÃZ1è¬Æ\°•L°)Ï· Â|z#“£Í¥•Aƒö( ÈB¶¬š^°0Æ6Óƒž pš29& Í'€—epä2ýl.[/å°1 ²1š;Ñ¡Ú]>Ú'ðåˆöåi.né¯=ÚBéRMêyQAe¡ÿI°SPR°0½ú- €©ËL/DÀRÚ»è-™>ðN®àº^Ƀ-Ûž~á"½ì¡ìñädþ¤> ¸Ñ¢ªË>7P&°Å0ë}v­;ÕI¡-Zîu ^!` O!Þ^paãÝìZ .ì¢b>OæÙRUµ½ ÍS«áÜ^°PnÑã¢nàéùHBJ¤.êݨu›Ó ¡)à” +F¹!«žÄk¹Ue[*bÎ*ÕYåþ+WÚm½±ñH¯¢L1Àuñ¹Uå-uóWîò·ÉCoç²aåMògR1dx¹Oîê[ð6±5-Êè¿]YI!Å ¿: þ9ÀïZ¯õ/Ú¢LÜ(‚ªYGo奾±Lßô,öd=ÜÛë;\½½qÁþD,Zî. ïKí{?ô1ßÁ÷LM÷¾U5T€Î'`=Hï"O†fàè.ò¬Œ@¤¼ù»R@†OÑãC¤,÷Úöah¢ïÁí˽Û7á¡1 6Þ€ú¦ü¦qö”ê0kòúåâíÈ”ƒQôÝÇí.êä^ømAS1ýnñ=+ÍÍó«ßöXÑù8³º<ÕiQû)Uã)‚ý–býÈoEßSú!SÇK¼%uŒpÓXA5óïýI€PW7wVx6'ˆ—§Çר÷ù Yiy‰ùÈ'¹™éù *:JZjÊɧ—‡g'èZg§ÈØùIyz‹›«»ËÛËÙÇ·§ŠGlgw§¸8jëëü -ÙØ¨§š—-»çHëÙ<.>NZ-|>ëÈ\îþ¾YM_] Ÿ¯¿_Ú9l ¿ Ô„K Á… ~s1¢Ä> 'Z¼èŽ Æ;zü2¤È‘$Kš<‰2¥Ê•,[º| 3¦Ì™4kÚ¼‰ÓR ;rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/halfblankbox.gif0000644000177700017770000000202512633765070032577 0ustar michaelmichaelGIF87aódç·  !!!"""###$$$%%%&&&'''((()))+++,,,---...///111222333444666888999:::;;;<<<===???CCCDDDGGGHHHIIIJJJKKKMMMOOOPPPRRRSSSTTTUUUYYYZZZ\\\]]]^^^___```aaabbbcccdddeeefffhhhlllmmmpppqqquuuvvvxxxyyyzzz}}}‚‚‚ƒƒƒ„„„………‡‡‡ˆˆˆ‰‰‰‹‹‹ŒŒŒŽŽŽ“““”””•••–––———™™™ššš›››œœœžžžŸŸŸ   ¡¡¡¢¢¢£££¤¤¤¥¥¥§§§¨¨¨©©©ªªª«««¬¬¬­­­®®®¯¯¯°°°±±±²²²³³³´´´µµµ¶¶¶···¹¹¹ººº»»»¼¼¼½½½¿¿¿ÀÀÀÁÁÁÂÂÂÃÃÃÄÄÄÆÆÆÇÇÇÈÈÈÉÉÉÊÊÊËËËÌÌÌÍÍÍÎÎÎÏÏÏÐÐÐÑÑÑÒÒÒÓÓÓÔÔÔÕÕÕÖÖÖ×××ÙÙÙÚÚÚÛÛÛÜÜÜßßßáááãããäääåååæææçççéééëëëìììíííïïïóóóôôôõõõöööùùùúúúûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,ódúo H° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹3jÜȱ£Ç CŠI²¤É“(Sª\ɲ¥Ë—0cÊœI³¦Í›8sêÜɳ§ÏŸ@ƒ J´¨Ñ£H“*]Ê´©Ó§P£JJµªÕ«X³jÝʵ«×¯`ÊK¶¬Ù³hÓª]˶­Û·pãÊK·®Ý»xóêÝË·¯ß¿€ L¸°áÈ+^̸±ãÇ#KžL¹²å˘3kÞ̹³çÏ C‹Mº´éÓ¨S«^ͺµë×°cËžM»¶íÛ¸sëÞÍ»·ïßÀƒ N¼¸ñãÈ“+_μ¹óçУKŸN½ºõëØ³kß.= ;rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/more.gif0000644000177700017770000011354112633765070031114 0ustar michaelmichaelGIF89a@Î÷     %76+# "* ('"& 3 ; 6 : , 1#####,+++-##8''%%2-,5*)844433;;;;9000/9GV PdvsI66S++l&&x((t99k11 K G H R \WA'L<desÿc,ddscmBmmodÔ(cprtü$XYZ `5Ä*XYZ o‘³còXYZ 'Dó³ XYZ óRÏsf32 BÞÿÿó&’ý‘ÿÿû¢ÿÿý£ÜÀlcurvÍcurvÍcurvÍvcgt) ºvPEa”ÿÝ A º 9 ÁWèvþyæJ›ä6Zy ˜!¸"Ù#ÿ%"&F'j()»*å,-C.r/¥0Û23I4…5Ä78E9ƒ:¿;ë=>:?Z@{A BÅCæE F.GQHqI’J¶KØLûNO:PYQ}RœS»TÚUúWXDYoZ¢[Ô]^4_d`‘aÁbòd"eUfgÄhýj;kl¾noOpqîsCt•uðw@xbylzr{y|ƒ}†~‹Š€Œ‡‚}ƒx„h…U†B‡)ˆ ˆì‰ÇŠ¡‹uŒJ玳€V‘-’’Û“²”ˆ•^–2——ÿݘ³™‰ša›8œœçÁžœŸx U¡4¢¢õ£Õ¤¸¥Œ¦V§#§ò¨À©ª\«+«ø¬Ç­˜®h¯:° °Ú±¬²}³N´ ´òµÅ¶”·c¸3¹¹Ðº»M¼¼Ä½‚¾@¾ÿ¿¾À|Á=ÂÂÂÃ…ÄLÅÅÛÆ¥ÇqÈ=É ÉÛÊ­Ë€ÌSÍ%ÍôξψÐQÑÑâÒ®ÓwÔ?Õ ÕÕÖ ×lØ9ÙÙÕÚ¤ÛtÜDÝÝéÞºßàcá6â âêãÂä•åeæ1æûçÉè”écê6ë ëèìÑíÆîÆïØðÿòBó™õ ö¤ø\úFüeþ’ÿÿAäqÓ·°Çÿ÷= •  u ô}‚þnÏ*x·æ(H d!"¡#Å$ä&'((F)o*“+¸,ã./70d1Ž2¾3ð5$6S7Š8¼9ë;<=5>H?X@nAƒB–CªD½EÏFáGòIJK)L:MINWOjPwQ„R’S¡T±UÆVâXY#ZC[a\]Ÿ^¾_ß`ÿb!cJdoe—fÃgôi"jUklÆnoCp~qÄrütuvw#x'y(z({'|&}"~€ €üî‚ރ̈́¸…Ÿ†Š‡mˆS‰6ŠŠ÷‹ÓŒ«…Ž[3 æ‘À’š“ÿr”P•-– –ì—̘®™šu›[œC+žŸŸî Ú¡Æ¢¢£m¤=¥¥ã¦µ§Œ¨`©5ª ªå«¾¬š­r®K¯%¯ÿ°Ù±°²Š³c´8µ µà¶´·ˆ¸^¹3ººØ»¬¼½S¾%¾÷¿ÊÀÁnÂ@ÃÃçĹůaÇ5È ÈßɵÊËdÌ?Í$ÎÏÏòÐÝÑÈҴӜԃÕjÖR×9ØÙÙïÚØÛÂܯݛދß}àoáeâ[ãRäKåFæDçAè?éCêJëRì\íjîzïð¨ñÀòÚó÷õö<÷_øƒù«úÒû÷ýþ?ÿAÿÿ^Ã6®>äÿšc>*  " $ , +$ûÚ®v8ùµr0ï¯n.ð³v;Ì–a / û!Ì"Ÿ#r$E%%ó&Á'„(>(ú)´*n+++è,¦-f.&.ç/¨0j111õ2º3€4F5 5Ô6›7a8(8ð9¸:;F<<Ú=¤>n?7@@ÌA—BcC0DDÎEFoGDHHèI½J”KkLDMMôNÉO•P\Q#QìR¶S‚TQUUðVÂW–XoYFZ!Zÿ[ß\À]¡^ƒ_i`La5bccèdÊe¨f†gah@iiÿjàkÿÁl¡m†nkoOp7qrrîs×tÂu¬v˜w„xqy_zI{1||Ä}ƒ~EÀ€8ò‚¬ƒg„"„Ý…˜†S‡‡ÍˆŒ‰JŠ ŠÎ‹ŒRÜŽ¡ZË‘„’A““Á”„•I––ß—®˜™Yš3››ðœÔºž£Ÿ }¡o¢a£N¤2¥¥ê¦Å§¡¨~©_ª?« ¬¬é­Î®³¯ž°‡±p²[³E´0µ¶¶ð·Ü¸Å¹®ºž»À¼ä¾¿À3ÁSÂyèÄâÆ*ÇÈìÊpÌͿϤѴÓ÷ÖyÙZÜžà“åNë¤õJÿÿndin6ÿ™VÈU‘°'‘`P T9 =úá&f,E_x‘«Åßù0Lj‡¦Æç .T|§Ó5j¥ä$g¬ó;…Ïjº ]°[°  a º  q Í * ‡ æ G ¦ l ÕDµ&œ‹ýzú{ÿ… ‘¥2ÂSâv ¢:Ólœ1Ç`ú —!4!Ô"t##¶$Z$ý%ÿ&B&ç'‹(.(Ï)u**»+^,,¢-D-æ.‹/,/Î0z1D22ù3×4³5˜6{7g8Q9C:=;3<6=?>J?`@{A¢BÌDE9F~GÈIJQKLÔNObP­QþSOT¡U÷WJX£Yý[U\­^__`·bcldÃf7gÁiBjÈlSmÚoipør…tu¥w455é6Ñ7¾8«9 :˜;<‘=“>›?¥@µAÎBäDE$FLGwH¦IãKLbM£NæP+QqR½TUJV‘WÚY"Zn[´\ü^D_Œ`Óbced¬fg™ijlmŒopŽr sŒu vxy›{#|´~@Ópƒ„²†U‡÷‰ ‹OŒüŽ­`’“Ñ•Œ—N™ šÌœ“žV ¡ä£¬¥t§:©ªÂ¬c®¯§±R³´¯¶i¸%¹á»Ÿ½d¿$ÀèªÄnÆ+ÇïɨËcÍÎÒЋÒ@Ó÷ÿÕ¦×WÙ Ú¹Ü`Þß­áOâíäŠæ ç²éJêßìpíûïˆñò¥ô0õ¸÷GøÖúdûýýŽÿÿDj‘¸ß2^‹¼î$^žâ,Ü>¦ójã_Þ`á g î y  ¯ C á’Eþ¸t3ô·~C بzL%ÿÛºŸ‚h Q!>"-#$%%ø&ñ'é(ß)Ý*×+Ô,Ñ-Ï.Ò/Ó0ä23'4H5k6‹7¯8Î9ò;i?…@¢AÂBÝCþEF=G`Hÿ…I¸JíL)MaNšOÕQRQSŒTÉV WDX…YÆ[\I]Œ^Ð`aZb cîeBfÑhrjk¼mfopÙr”tRvwÙyœ{\}"~Þ€¡‚d„$…æ‡Ç‰°‹›{X‘0“”Ζ•˜Vš›ºgŸ ²¢R£ï¥ˆ§¨´ªY¬­Þ¯¨±t³=µ¶É¸ºP¼½Ø¿”ÁWÃÄÚÆžÈeÊ(ËôͻϋÑ^Ó"Ô”Ö ×‰ÙÚžÜ$Ý£ßà‹áñãLäåãçè@ébê{ëƒì…írî]ï7ðð×ñŸòWóó»ôXôöõ‹öö£÷(÷œøøƒøñùRù´úÿúxúÊûû\û¥ûîü7üvü¦üÕýý4ýdý“ýÃýóþ"þOþzþ¥þÐþûÿ'ÿRÿ}ÿ¨ÿÔÿÿdesc Color LCDmluc nbNOèptPTúsvSEfiFI daDK0zhCN LfrFRÿXjaJPnenUS|plPLŽptBR esES¸zhTWÊruRU$ØkoKR üdeDEnlNLitIT.Farge-LCDLCD a CoresFärg-LCDVäri-LCDLCD-farveskærm_i‚r LCDLCD ÿcouleur0«0é0ü LCDColor LCDKolor LCDLCD ColoridoLCD color_i‚rm²fv˜oy:Vh&25B=>9 -48A?;59Îì·ì LCDFarb-LCDKleuren-LCDLCD colorimmodœgÁ´Å1textCopyright Apple, Inc., 2009,@Îþÿ H° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹3jÜȱ£Ç CŠI²¤É“(Sª\ɲ¥Ë—0cÊœI³¦Í›8sêÜɳ§ÏŸ@ƒ J´¨Ñ£H“*]Ê´©Ó§P£JJµ*F}V³jÕ9ÀßÖ¯`av K¶ìɱfÓªí8`ßÚ·p+¢K·®Â¹vóêÅ«·o\¾~§,¸0X†[m«¸ñVÄŽ#7…,¹2RÊ–3Ŭ¹³On=‹æéÕ çѨKz--°´¿×°Û†ݚuêÛ Wÿ› »Ÿ?ßýÐÛ÷šø¾ã¼_ã^^ÑõlãÇõ½ã† š´d_hÙò%Ù3hÙ¸þ½Ów¹?â³ ÚfΜwù}ð°%«ÂB*œ@±²Å €dÉx¡…P8¡‚}8QE2ØŒg^z­±wÛjÏí£7_81@‚[<à =AF7Ïlá„8ñ7ä%'áhžwÞ>ÙxÁÂ$l‘Mh &Ð>ÜlAÂ,x‘ y¾)§Ü‹¹¶[q@VÑ€ ^p³^C>¤*4 7Ç%¹ä•LêUa7[< B2 ÊE&Dôð"Â[tcÞneV!=Éðd”åBðx ¼ ‡Þ›y¦Uá<^4Å; ÚÐ;T4°Å<2ÚèV£ÅZ´Y©§Ñ£EU¼Óé§þeõ¶O7T àl¡jÑ>^ @…èÁª•s3Î#¥2ºZd©Dþ(Ã*§‹&+ìQZè츂´ìDþ¬ªL‹KNë”srC 󘀴ͣ ,.Ч¸IU»Ï<™bƒÒ¶aÐêF/R°YˆM^°«¿ù)6ä7ïÀC¬*”ªÄðEï@ EÄáRüSÁÒ©E¶g)ÜÑ>P઼"÷ôZ?>Ó€2.mœ‘³Ï ©rÌ)Ÿ=TˆhÎ?{^€œ4Ъ7 V<}jLþX®>´A=Éñä(Óº3 ¸{ÝRqútó@23éÜ/tƒ¶Úk³ÍMþÐÐ$wGÐ4p$Ìx£DràÜÔôwG{láª=Y.ÝØ´xGïà`È‹Ä66šßtyGÙ4ñãTí… $~Ù8uÓ:¸V§®ÛÝ@ /N£{t°ƒn‘é¤í‘¼´4\Õ^Ò3FÓ®[zJÏÐÌúÌC‚;Á®“$ÌC»äòñ‚˜Ò'4›>ô°°O½ƒTE©å›ÂI ñ \w]>A3mcOí •èA}‡E1XŒX„ Ú_m†v0¬°Oy'ч鈾) D‚î&A¶ÁãÙðIA’¼c0Ô€/@¸@_lÀ€¨#Éèñ„õ}ƒþ(1Ñ;àñÐ( Ä€˜§ó ï $`bIV˜›ëu£˜! {±yP[Mtö–®ŸP$ô4¸1ÑY€‡¥È$'Z¯AÑÞO°!‚lîƒ 4¸!ÇImôø „rư  Ðx†,àXØè<¼˜ÃÂYì (#P ’y à¨ôÂû¾€ nhÒ{Ó¡…æÁŸÍÐ%ZpB$Ÿ h`£•šœã-'äDz”e=Ñ#PöÑ€/Dã;¾ Ï&…F¶Y¯o¶, 4Dhf£Cô"SWÌ>eGÉ6ÂÎ!Ò‚\qèm(Êþ J=[éÊpŽÃ¯G´ÔfÍd,òœÃL‰úút0BÕƒ#øƘ͈óëˆBÊ‘pC£àŒÇFJR=䳨™w”| E_¸")ô@Ò’ž"ž"›'%VØä}ÕêÙw° …L¯I²Á‚çU\ƒG7Ü{àŸ¤±rd.w-DÏn  “yŠ?@H ‹ŒËñi€þSd<Óõ«ìM† ük哨@õÕr÷:wl¡ k†J¶àä:çE§¦óÅICš±Ý(ïšMl ¡âÌpÑÜ ú)Ln­¦_´X«À±I¦ôHº/¼¦MÃÕ“2• ,#6©\žÎD)]U‹$£â¹5”Ù»7 ¦ú) öËÄçé0&ÆP ޲Ÿ,XûÚØÎ¶¶·Íín{ûÛà·¸ÇMîr›ûÜåžÐ,»Á w#Ï®òSöAf펚=ÇÁè;²SõÙ‚Ã4g§µW"fC¼V ¼K’Ñläùß˱æ½9<é§´÷›g£¶†þé9 úàNaµÅ³ŒqÜd•ÝaU´S¸Ö<#s½grOQÞl°À•ˆõµZ²:(€Å?†‚Åé=ìêM§ Vø´S¬ð¥B }èEÆÐœc|õ`E…ƵÓIÄß$Cå”Ón¹ËsM‰‹„ÍAáw+…œã¦›øáö°SÚ;÷Öá%†7tÎu§øäJ¤§³…/@Û)_Pz0õÌìf×hë<_ •/ò-çün×V×92ægÌû¨£w±·™w¤¸»)Sž»°ëën`CE´nJ†ZùŽ9žÒØØæÿšz¨Oš°sñÉRêyÜ[eO ÜͨŒov8ä[>¨šþÍ Ög)ïxxV<ŽW¼b´Ñþ°ˆ}ûÙ¿¶ºü&:щ¶˜ÔœÆÆÔ¬÷¥ <Û@VŽO÷× woLÕzEñzJ~ß‘ 3UW§`HêGD×}PàWÒW‘KϰN~@VwT€.aÔñÑg øWδNSEV¾+‹ µJñQÊðØ‚deVW•'×g~4T }KAT Ñ4WTew5ƒ‚‚òz1}:1fÖM؃5ÕZ”w‚g{Ñ =¶€J!gÊàMÙP •QvY›†ÇXÓ ‘ÂÑ‚EW[ ë4xÙðKœ° ›Ð þ¬õf6K‚‡ Ï@ÏÐRz踆üÄ ƒ÷KÐP Éõf“:uoÏ MÅ‚IñZàK˜xEì†]¿ÄNÓ´l2„Ó ÊÐG,ø‰ ÁGLôE_솉«èN¨Çph6xÐP"`ŠéTÈ[›4DôíÓD8‹ˆQìf‹ pry¤‹ ‘;kèJÓD@%0$N²HjvÔˆÑP€†FñÄ{†>èCõÀAé¥v'ˆ>D Ê@gXX}2Ž­1b!8„S´7vޏ `lYú`+ÏxÑ‚ŽSa1]Ö}ËÀG(|TÀ ÉrÉÁ¯6þ…üÃiÔñ ¼0Þ˜L I Ä ª(GÅ8ÃU¢x¸É€ŒÉ@$€’D!TÐ àáNt˜Sç1ó“Ið#P×!8s‘B! kbz+¶ŽS-  Iʰ €:q0°ͰNõ…cƒ7Pb?pDH0ÐÐ ¼@’)¹þð/kˆx çI•EGä où ÊÀ &ó©T`†Ïhs1é5vdDGD PÏ€â÷C? ¤5ŽÚU•zUbó`™4„™š¨ É0*‡Ÿy¦¤‘9‡;©zŒenDCðØÕM¾ "ð‰ÃYþ PþàöˆaÉ+ž%x H t`^½ùùÁ×I’ ÒˆA(Oíh{ >З4~˜8ˆù"uuù‰EóÇ©ˆ¶cMR6ˆ_ ZðªèJ­èˆÊàà~¯Ãê;ˆ| æjå\v˜‰Ý¾ø‹÷† Ñ 7“í ÊHùŒ˜&…²‚'ˆØOÖHD)Úš«²s4a—' yÉä8Ÿ ÚŽÔ(Œ<šŽ—¢Í0€d5ñ¢-‘ ÚŸàL VB‹U=ÒÈŠCTŽC z˜¼ –CŠZª\ rœtsKZb爎÷9~¤ ªFWzþS:~6g‚õ$3b@æÈAñ%xº¦Í4¤Ë·™Áf£Ĩ4CÄî!¦µ¨™_°3XŠK2j Ñà‹Ë¥¨òT2-é÷hæ§ÿ™&P064tr¨À”¶yH/iº:¢Õ±™^ ,`‘,Ѫ$¡[À4ÉÀ©T,ß©'ó²E9¢ ]²QÓ^F%ÙŠ¨xu¬Ÿ:=LJÖ ™âCçú½BÝ¡­B†ïº;DDÈØš *$`p(A­A$ Ê Êˆ}é¯ÝŠ¥ƒH°6R¥+¡°¤C$^«]Z›Hõ¯±CÒ˜‰šÉ ^þ)T ­$A¤¡VÐT²ÊˆÙ5«k€\6¦òꛩªP#᱑  ܱ®Åʳ=;!­Q“ÚŠ‘„ª4'9 HkÜ" [Ýñ€äX§Kd²¹!FC#p$º™©  à0ë];úð’Ò´kX ÙUHh‰¶!+Œ%eòª±Â——s{…Äe­KÛc«Šæ4€k(+°þ)´ª4$õ¿f8²ûM¼µ\7¹!±C$·pÉ _ DëtyuËï !* ¶¼àãNI«¦KzP‚£~êGͰ _ªZÀ @Ù E³‹þ $Ð, ^þr]£«DØø»$!4ùÕgV+ËÀº^`"(BV‚ÏË?ÜP+"à[À_° Lˆšd¬wâ½,¼ä£*{X»Z󤲵ѾÿÐ £ò丹˄»NÜû—ü«Ïá¨ÒH®øL˜;¿U `³Ðœ Q·K•)p»ý²¡ÜOrÁ/á¿“:È—ØÑºó«5Ó;Pð &| ϰ¼&ÙÂÇ›­½„¿,L JÃi¼b Àþ9YÉÀº<ÜW>Ü÷^ vCÄ Ñ6Ѐ¾ ÄïÃÄûºƒ¢Ë»{J±TL$ã¨Öؤþ ›à “P þ­ëç Âò.œÄj’PVÈ$ð 0BùAÛ1¿‚ÜÄʳ¢Ë£@ù¡¥YÇ.¾ù8ñФ×PYt•{°Åæ+ȃÜWfJèNÀ ,À¶¼VÐÆóÛÂ. ;ˆ\;Z¦Š«¢œöâKVyà ›ì›r¼ ˘¼ŒÜÜœÉ! _À ¹›­¨ÔMæÕOÈ ©µÌĮ̀ÅDOHTzp%úL¨DÍË€ú|¼`Íþ ɰ ›Ü ÐäM«È»åHª¾ËÎ_#©óð"èØ5ÑšXÐ`Ïš©™mZÌÇu\%úŠá!¡ôü?SÌÐ0aþ1òà…5eÞà¤N:уøK¿tž4MÓ2-ŒdN0ÄN³Ð(|"®„e:DàtEŒƒ¤Ó¬ØN#mPjŽ é"A]1Ýe ,}z0 ŽéØ£yLDšCDhÝ£zŠQæ8ªbÁY WœQTå f_Žú¨gŠ@=Ý×:ª i×ÔÒ]Ý  | –¥rÃï1€>ÙnØ2=¡LØAa)Ú †¸Z;[ÁÉA3º ‘ú’0©Ùã²¶„kÑOL§w#¼±.0 FQ«Ú·cØ$ʉ¼×[ºÂ‡pÛ XLâëŠPœiÉ¢ÀÂmó”ºNÊ»R|ÂËþÍ|ErÔÖ’+ÝÓˆ”§$-à ¡ÜÛ­ÕšmmÒ{8ÞÔ]¢ú@-Þê WP2#™Þñ+é—Ù ß÷½ÙNb5üÝß`à¾ñXàžà ¾à Þàþàá>á^á~ážá¾áÞáþá â">â$^â&~â(žâ*¾â,Þâ.¾Fûâ]e§2ÎH·]ãa…8¾:¾ã‚rã;žo>ÎQ@Žã=>äÊ’4àŠä+Á/1ÂäMNãñÉ åS¤03Óì ðpÜjå#‘%C,Ít,梯PÒ"Øû«æá#lÓ"Ø #ç1fþR>AèÓÕU¥¤z^<µ! Á¨bÄ è^ K¥;èÊš«ÉÁoùã"kŒ ‚ŒàÛ>åî\0ô Ùü6•ýìݧßèßÀén«²ÒúÙð›´|Ë Il°¼¼H™ gSÊMú òü ÈYä(=éÑaÄ[Ð2I\½–X¶_[¿©¼@N §á1ˆš0Vv°›€|+ãî‘ìÊ`" )Éàëž‚þ ë¶!ÙÎ ¦ÅÉ;;™HŽìô Ši³Ñ \=¢2ó ™B½ZÐK²ú¥L~éÙPDRÂÁ0Kõº`W§Ænº“~!«Bßrr£i³Ø©còþâý34 Së&1 –ÑÍâ'ðs¹âÜ0¤%Ú§vD‘Pð ÓVð·›Rßa¥“Û^±¯>£R*!qFªB*Ô QB ¸²Óô A!¡z-‰Ëãðe­7óÓaN@Ã]ßJs* ô!³±Sð‚ö¡öuÜöN%´Ä7)ƒLdqUà=_|ÿõÁ› šbeJæ™ ÎójŸøv±øæ#9÷Ò2C,g=PtÉRP€ùy¡ùSÞ¨-´Žæv’Žc‚—ŸÕª/”PB‘¢ô)a…¥Ó4…Ï?µ×·/9±¾Ëcå/¡º¼9þuø¸Í÷Í\:Ž÷tÏû/œsø¨o²ƒj8Üû£';Ð ÃYsúÓýý¹ï,^¿/©JÊð¡VðÝß{Ó %öðùS|1ïÁzûöUqâïßB† >„QâDŠ-^ĘQãFŽýqkÀžú:ž¤8@!J–õ‰ÐRŠ“}þV¶Ä™SçNž=ÚÜ—m 7}rTye?$X´©TêTªU9ÕG €nV3&õŠq«zúj ›VíZ–þöeÕ2ä;¶ÁÖ}èá>Z ö‹ŠWð`Á6Ýfõ"Ba·t /¼ûáÂ}"Èê3Œv¡æÇ=oþ\év=eL.dì˜0Îu­8i¨ï²²57ÿSÕðgÞ½- ­Á<‡©GLå Úy ¢<«;sfܾ­_MO¨ê†Æ#¯K gx ²A7l°Û †t;[ýúüÇéõ1îÑ;^Ö„Å·þ¿Ú Ú‡—lùå[xÇ À胰.¬æaá Šöc <µ¬¢/T˜‡ž²ôÉaŠA±˜`à&:#„±§ÜÞ¢g ,ÂP- ÃzíE†XØžçIá–S¼e³â‹±I©°¢›N«(ǰv´J<Œôix¾DàÄ#‹FÚt2Í£ç¸ÉÈJ«úcþ«ÇŒ¸yónfÌb„A DÌ|T³Ð‹ì£Ç‰-6’“*,§úo#¹áf„\üÌåA™4´Ó«hü‚„Ž•êQ¥¨€í*´È拈9r”çLOoÍ(=zº€ž“H=ÊTŸ"툞žÁ†z!†˜^x¢!¡"×[u /X¶':½"ö$/œ€š-@€ ¼ÈFÚyÌBÓZybSÊj/lÌ+awâðÞ‰üiÀ‹gž‘æ™h Á†im·áŸúÉj°É©[öÍIËœ°y šgÊE¸ÝwÕÍá†'üâF,Æ ã–Âʼn+@Î&…§…×_“#„’1âvþb™¥o•ò§_žæ9›šYÄœw–wB*í)è“\> f¶pÂfnÐygÚ3ã…ºP6¹`Ÿ£¬FŠ*£}Úgh˜þòHþøvöLç²yŠžyª zí|º'­yÚ‚ …¥uE;&¿C½ûöûïÁfÌŠW* çn'¬5ÒX*cE6‡rÕïhÇÁÜ4‡1»y¶°¢*¶1J<'÷ÉŠ*fduÊÉ9sØ%ô'«w†³êv‹F¿¨ (¼jÎfÉ…¯|ìãéŽxÆ ËyŠr¹C¯œ`Õì+‘Óí­³)+xDÈÏ+ñí2^¢¢Í·ÿl‚Ç#6E¶÷u&póx†¨þÔr?ˆ/kü ¼Ð õ ïB‚WáG#x@Ala C°“Ò©%CxÆ!V§‡Ot#ïrŸ ø–y,ÏW <œÐò÷ÞYEPÆ34±õù¡ÛXTdø]ÁC*L!³C†-!‚é‹2šÑŒ…laO[â õ1x8!ƒ‘¢3RºDCë¢ÒºÑ´ †±>n¯Ô†Ær壢N⦌ƒa#aÜ[ûvcÇÍ%Ï{_Ha½†ôp-è ™Í’è:F†Mï`Å:s?5RdwÓó 6T ´›ÕJ{,Ìaj8¥Ïˆ’ÿ°$[â–0i¹²x°Ä‹a"þôf.)eDNé›Ù Ò•®# 0½Â&xl¡ ¾a <42°Ñ3ZÐ7¦Mif45 ¥uØ6:(@ð3ÐxÏ3£YÎiâ6¼ŽÕ’éo~†!‘g éÙG Oиy‘~ò^‚¡@ŠYV³v m€6+²OÜä²3VðÂ;ÊÒ·‰²5„Â!tÌ”T«¡½yšÃ’V%pðè† à¡lŽÏ"õ 7TÐ EÖT-7ínÈÓŒNÄTílÒ?¿8O£ÊˆšÜ€“XÚÀ½ô:,ªU«jÓäÕ0ÅÔjS!‚¥vJT-"€ÆÈÄ:Ö'ôT“œþþ¨ªÉ _+MéÊ“›¾C …s’•À³ÌBmA aSâ`§RÐn¤ÔP Ñ(CrÔë@à ¬dugïuƒÙèf‚¯F(,X˜AD+šv§—Íá^Ò×Ô5°n-½hn ~¸uÌ]Z £w@œµ ®Odùnˆ ³ê)ÚŠ«ù!2¢À«Tka¶?¼½=òÑè–†Ô¥¥µÚå6‰KÞk{[2]´—0Ü Pµdc¦þ•&¼`7ØÁ†p„%dG™Ž¢ð hOŠ¿É“ü*HäÒA5}DŒU«¸Õô*+q¡qkúäÙ!¥ÌõWçVVÿº"ñó7¤ôâùÐ:%Ivoþ‰ wÙÙúî’Ë3c?dŸÙ®% ¸V_þ»Šò[2 T:ŸY×z£Ùê|¢qÚ©ZùÊ']²´¡r¯õ^è~Œ¬@e%ú[²Xéq2Ð ?k_„ØAø`Àk¢ÊÙÝÏæ/4@mÏTÜâ:Ëx]~8·zûã®´Wé›YúyIùZT¹nö¾Ü"µÅÞ“ã.s9O‹¨0‘ºÜç?¡l«bÍÄ¢ã®#H÷Šexþ—v»ÛÌÙö;CkãÝëT‰Û3lÜ>h¾îé?y/7ªA‚;{²ê¹8¾Õú˜l6ƒ‡Ýð‰{ÄÇáU» ÝæqDή(ÌÌf©¸åö¶È·o¦¶ÙPÆ-×twÈ·þdò2âßÁ±¾Ö‘´ó¸9L¡¡‚C †ì:4ýÞë‚ <£Ù ðˆç ×Ã>îØ¨‚ÊêBzdæäô:a•Ì¯ð•§æ’C/ö´Ô<'yǹîÓ·eL¿‚ÂÓC•_SÍcɳÆZê­“Èc[ü^yƦà¯N€ {½ŠâhÐ(R æëðãˆçC ¨‚1¤N¨>ʹ ë{»ŠZ²f¸¿')¸“¨?‹`@Ž@eÈ$løái! j¶§C*°C@ŸxÁô‰$(ø˜š©lØ@°=0¢µ#ì;)â†Ð[ª'q‚‹â‰Ô»ë2X†¿ónÈlþ™jÀo€¬ Ä>ˆ)­lx†!º©ˆAT ´-@!VêBËAC:¤-\A¬3hH†´á@{ó d 4œˆJ†¿kÃw DB£¯I¤ãÄ Ul^è=¦ §É QÆ#>[„:x;^è•ÑSÂ_´ aüciE‘·0ˆÇ%±õ¬!”¶gp‚Ç£³S”D¯Æ™@ïÑpÃsF`û<; ‰œ`ÇvtÇJþd”ˆBnü¥é(™{¬"ñ:³"¬Åh _¬ŠI< ô‡x@¦ëÆ’ Û@H¨ûFI“¶hHXŠª¼´FžÁ‘$AG³´ ÇŠõp XµƒiØ‚‘ëˆùCɵx¾ò‚f°™ßŠÉKdQlx†eåÓ'ÐðÈ>HŠp'hÉ-t½Žü°ä°`8’áhPXK†HB¶HÉÜʈ`KATÁ£DJ ‚c…&,Ù¡®†.RTèƒ<„Cø½NÓ1]=ìá„)±ë©vcªÆÛ/€[®j?–i%ögƒ9R$M¤!ÓB;ö@€`•9’ÓþFd†Æ©š6 Óy¨2j„õá84$„äÙ"ÃVøcÛ†£.hJ1kY<ƲØÓÆ}d/§Ÿ¦ë5IÕ"5RM|`\F®œü<Ä€Všâ6fCªBêæDBü1EFhÝZ´6RÔNèä6)Ò6D¯ñk§‰îõуvDBÄSC¤”üoÎïÇÑ“³ïG^ Xóömwaeõ¶©¹e\<µoœÙZ2ê?ÕQ„¤ᅱ۱ïw€ op_·0H.ý’ï–]Vð'IÑÑ`ÜF=Õôžoxh íàVÆ=ýëy€ÿëGFfÜUÁ‚X„qZDî×þÅ5Õe$oÆí†#^Op¦þÆGMFnrh i•¼8ŒR î‚Tr“ pz´Ó%ë?œí5Oz$€Ö<'ñ݈OÃXY5ïò$?ó%O/VxóìvîG;Wƒd—Ž0Ï•BßUtôX‚t¿§oæî©åB¥AןF§ÑVpLWØBêêïNìFÀ°ˆ>U7õKWT;Å©6›qRñ…õž´už)òX¼ð¹—_ö²)ò&Gò®Cöd7™g%UpLßjyvhvJ¯ ÉdlŸ(R7HŽŒuo/GI/=rG¼–¸vt/©ug÷r÷w/§¶þ”÷z·÷{Ç÷|×÷}ç÷~÷÷ø€ø'ø‚7øƒGø„Wø…gø†wø‡‡øˆ—ø‰§øŠ·ø‹ÇøŒ×øçøŽ·]àE×@,‘‡N5ù‘/ù”w’gyWž ”yR ]ù™Ï:šý¾›ÇùªP†1ô ™§ ðìy†ø!‡sy`¿.©õw§‚ÚÛCžÿùàs‰èà¢Ç4 z©÷UÏwp‡|8Hzi€#Äz°à%äz1w‹SЃ?PáVÀœ‡€†«ÄúøÝ`Yû„Ê)êSà›E”Ü»7ú°²¤7%ã{$~…ô š'|Ý%µ?”?ŸpÊa„ $—Èoˆþ×",=ÛB鶃‘ŠŠâ|‡(û«Ž:×êg-õ4Ÿ‡?XŸ?x—AùäMý†¨ßßàÕm'Õiר,×~ÈóÑ}„õy„ŠýÅzÔW\•ÍÕ¬(Õw¸P¼%Tpò‚–|¡e4պ݆õñx¨xéÏÝwˆ®©"ãcrÁÔÖ+&èÊ˸ÝMMgP¼`ëö®·lÓîØ¹sGjÝàÍÓ·Ï߃wÿ6rìèñ#È"G’,iò$Ê”*W²léÒ%6'ýÑÜ·O½œÝ¶°€@Ä@eØÞÑÓgÑæ¾/[5Jo^·g^œ@ð€”/Ï–yBþ„(T4lÜÞÍ£·‹—jײmëö-ܸ,ý ˜ç¯ßMZT4ÀâK¶¢6i†Tæe¤¿›8¹=³Ò·Ä/—”=Ö­[Y}, Éíìù3èТKÒ¤¹e‹ÓnV €¢¬[QÂ& £¬©ï2 ð-7ŠÜômü8òäÊ?–¾Ù­A·*¬¡@3ë%í¹ûèqÛÒ“‚𨀼ü<úôêM^¯™—^²œ@›wñev—wéeƒòsËï%Ûzx h‰ùãÔ<[@ÐNÜ·V~j%62 @QF]D`H„µ‡ ‰%šø{úÔ3Þ$T·Oú´U![0bEkþD™õáuõøO?ý”ö£HÝœx$’˜¹E^8uãÄNp£OZ$3ãaoÅ”Ø;8ÑM=ÖØ^bä@âˆ#¥Ü3$‘Ua’q–èO$XÈd^ðX1@ÝL¸<"` — Üp´Ï;Tä(xBò‡Cý±Î‡ i!ª_b8Á“L…î FR˜e[ï|ÚÑ>,z‘Ù`H‘)®Ø#$ˆUð̦Á¨O‹s…úT6$4Œ"EçªoQ,Húp#‚ØäT”Qø‚+®­PI`D#,ºêkgJ¶ÑÏxAO›õ3À©jÑø’> ÔÛ=_DIÖþ¶éèn¤ÖžP›.ÄËuÊ.i4á44 8ñN¾%U¡L´myÁªHþÀãDÉÄ<èŒð,ì¯G|3rë’Ôœ¨U  LÇ&½C±Kû¶DW³;Ÿ¥17Ýxó2¦ÀcV?>ÛŒ3Ö£ébMOuCÂÝüK’áGòKÑPÑî<,<M6¢À|‡9óÔ£¯ g½·q¾Ú‘»óZ=-)£…¾h»$‚ª)éãÅZ<³¸z¨2=TÐÌØ|{±£xìÙ  Â%”ôa‡‹t² fš+ÓùçÁ·5ñLî-<À›dÅÕ¬+Îþ}/Á£`\‚ &Î@Ó´Éü)<ø ·È3T"°PøZݨpöZô4°–>Þm‘Œ4ÏlïÉŒ>ÿpMœ²…¤­y.IÆóT²…/Ôè ØB3ž‘ ü}ALÊëÙCO½+cKyK2g¸¢ä^«ƒ2°…g°³²Hi2(ãÅÊSÑ€÷@ç¯ê Zmñ4Z€-¬R3<âIJã$àwr¡_ò€L½ÅøƒÂXÊò=$r$J|× P…Îp#-Ø!¡I²aÆ·xAØp!æŒØÅ9nAïÂ5#¸@`g| ²—6ÒDvÉ("ˆèÈÅ®ÁþCv_h öø–/ Q$t <—-¨ _@4¦f/¢H‘á³Ø»†£…Žù#’qqß[ò16ª€Hþp`p¨fË]Д³É»\ÔµR’mq6VÒº’Àè„-áäêü¡ÄQA¥¡Bè%"_îÍ&ú˜Ç;TÐI/ºò-ÙÂJ.É’º…“cÛRE«‹ì# øÀ"Ç£Rrb¶§@ErÓB @J–‰˜ƒŠlœ"ч ¬@–»> F1ŠAŒdaŸýL—çh@ˆ)§È*ù…ŠäFmqgIà1^¼ƒ"ôðÂ2ªÓbpÀ{[ü¨¦P n4àþ‘¤AiûÞ—–¢ÊPk©I2Vš‚ ;Íh.N0  ‹‘_c3™ƒTµ2%êLI7D÷ÌZ¦¤ $¸ 7pÕŒC3㪜BúŽ€"”=c… –ªÒPá\j*Jôñ*ˆÅ¿˜ë/4P‘qõ¯ç¹ÎMDD§¶ë¯s‰QBÛ‘~UV$ˆEë¾€ Ìb®K­JkYå0r8U-GŠÉ–†V%#;,[ ×e$·Øé-œŠÈq¶ ”!81Õná¾<®ov#¨tg ’f’D¿‡ó®„;3ßgºÁ•N±~dCQUH´³ß2†õ)•^íg´}’*4ƒ$X z.Ã#VøM*`V‡@@@‹7hôA*$#²~ì+’¡u[¥jT`¸?ó T†à"à  n4â`2H Ÿ¾æ[ã!Ù°%UZV”\.0ÒB4r‡8Ì (ƒô€òÓåþÉ|! ‚ÈÑ<Û6ÿ;EÂÒL¦¤çù”‘”`qˆÔ˜‹b§[ÈÍݸþ!<öA*'´ØêsI§:ÇÒY¼Ã9€ ð‚2TîEn9ÛÕß ’àGJÁ34=å” Ø’Ø ·-òÐQ7èÂÜÊA¦'þ‡þxW7°Ts$ÍkîõÕ9¢c­£Q)}—üJàá,ø –`ˆCô‡k`NL¥÷°¨¸Á î†äqªû’b¿‘)†äß¹î®7Ÿíh¨àú›I¬ ™Ix%å=âÿàÌV[2AL4XÍ™GK?[(Ìå=²bÍãþ${@ˆ€|A2(ƒ2@ƒ64 úõßñÁ7`C˜TI@[QÍÚ\ıüË2IZö9àHìÃ3,ÙÃþD€ ýØO eF"©ßƒ|AŽlÑ€TÀÍXìAA2a]qÜ®eÚg¨Ÿ@ßGª ™©] º`T`ƒ <Kìƒ2<ÀÎyØÕ}ÜJ%O€àGÈݲ=rĈÀ$ ‰•Yú1!{¸7@ɽ„­^úÕý‘Da]þm„û×¹7(ŠÜ`I¼CjIC‚Œ™¹á\@]6¤PÕåžÏlÑÚHPÒ‚Äo™–öñË@ÀfôØIƒXšQš#ÖÆ‚DW»åÙð„¢”Xˆ ÜÝ?À’GüèÚ?ìþCv„Vöä'ÆT@a‘hx$ààÂU¬K>% fC4<@†F=xþ‡ cˆx p–vY™GhÁFÖF4,Ù÷Æp `ÔUÙÂìÈ.£Å€S$¾#mUáî PäFìŸ6²Jæq„`âV74LDæLj}ÌU1ôÂ,ÌS2µaC ÕCz¨‘÷•axqæ.r%¶)ÃuÄhn›2³Ýag /À0Ì-LAl9älA 4x<4Œ\bɌեýÃYœpæH¨F¼›z,/¬À\Õ0€2^d:"uRZ¡‡ÜAÀ,v§$qxfÉ9u„O’„Ä!r† °ÀÈCFýÂ<Á‰Içtn‡|=ƒ@”žåØ´Eª€‘þ(lÄçH@› éåyh*Å \@\hxÀflÎÄ7É—4ˆgH<΋Õ"Gp#¥ýC&õÈ€VK(Žb‰,Ã,P2ð‚R€ÙöL(…âÕ¢U›2\’8ÀŠLäLàK‘ò‰~Ä=wjèÅ 2DИ­4]KÐnió̉3ºˆ-‰i/*Ã2¬Ù\G’rÄ<Ü2]©[ÀÃ!4Œ™§!£¢rU? 6xÙjJ7@AQ%Ínþƒ«,ÃØ'PÕ<–±ÌG7(Ø]ݨŠ4 " †yè?ðè½ÑÙê^k|¤œ‹$¹¹jþM¡ã¤~u’ŠŠ" Za2ífqBÁ g?@C÷&ºtʱÛDØT¬Êª›e4LªjÊA@2ÐC$ @–ѧþævjº‹¸ÐUN<¬:n$nPù㬌§?ÌÞ%MQäÞ"^Fk‰ÌŸtÁÀL*LñŦÚbƒT<±’È¡zäG 'O)/Ü_?øéLT¡mÊsTÁü^æÞ(xƒMµaâ½ÚdVÛ3€ë=P^Û$çWþCWâ"¯z7 L!É|iÁx%x‚!ðÁ!t‚6tÃ9nÕ*òûá.Øõèzèžák`z#`ªO†©ÿÎ[äP-‚È!û‚ˆ1ƒ3XÃ"j‘àB™œ…2ðB(þ¥žTôÙø÷yßPš¨êhc¥i!ã—í'‰l)ûº©ýX™1 VïÌÃ0<6`ƒ4| ܧr¼ƒÏœæHœiÖý'G`_ê2G6±ÍH<ã€Ù +«|Ò'=À,Ã0Œ±<4 ±¤’àžé?ì! sD'΄ñ†D<8Ò lf†…‰Éé ¥m¨h0&]ŸyÏ4¬[DŸ®F‰=rD‘úáVÒ±ÿ>ä×Þ*r ðBe¸*<ŒrNìÏà&ÆMl€U]U.l>ëÆE’@“Uyf¦veæ “†’ñéy‹×&` QDf´Wþ³Ñ?-æ\}A@ÍŸh m!®„`~„«äâå¹”Ô1IL®P*Q-° ·sÚæÅnŽ02@#j¦¶DFo„íå"Ú\Wˆ€´Iœ¯»â´Jô™fX?±tKKt=Cp€ü@¤€V ØTAð„¡Å?ªEO£öQrâWfrI(ðvzþF§x­‘Åþ@õ“H!„TdAle<q)²š±EGBÁî²DYÿƒgr´þ]ØG³53ÍÝa«…ZÉöˆ’]Ó‘»DWB<ê£bã>Ã;›Ï„uï7·…8Açx P3ó 5d›Ä†6[[X&Ãe;µíþ:CYB±e14<ÃðâHKdgÃEÖvÎë€D%æönsl›„žl“d¦ˆHÁÃ;D‚#Dy7À³ÿíIŸtFjÏV_]þþkÃöõr=+Óy.56B±[+¤cwË»<…Hµø('qóĉ.[ ÊEb›a†;1HDCpÚ÷t£§‚{„`±4_¤¤Ûº]°Ë‘I¨àĶ”‚Ç¡ý)Ê­rÞh$·E¨öÎà›sgø kf§D®ôIt l/xÌèÁ+˜GŠgPsx“‡HùPá®"CÀk4/Œt-ƒFŽs„2øÐ˜‹ß‘Ä>Ü÷„­I“„;ZÁüÄ.Ì0B#vî|^C4ð‚`G´›EÆ—÷’ÄÃH<·5 “úΚqúw2¯…[_4£BkÌÍä„Mܨ¢×|®n¸ÐEF…ŸD8úÛŽ‹o<çÖ²¯…ÜYáGzhÁ,C!ÌáÙ(¶·6=”<€ˆ¹©ƒ9Ã⪗{ÞÕFº³Z„]{” ó‚3غCˆçbû‚(_ į—{\,7F;ÚÀ“Da¥D£Ÿ¹ZÀC%ºã»‡ë3p‚’ ñ5`®Ó‘°Ázµ£"£ÀŒ‡Æ©o›‘{7ï˜Á“¼ZXíøÅ‘4Dƒ(Â!ˆÂù-ؽ£÷}YQД‰¶M7@žÆE¸£DH×Qެpêd³E×£6 Ó•iü?x ¾K¼Ã¼úwò—_,C6´¾x¿½G9¢#O8T¦’¯SÁH{Ææ£„ZOèÿƒ|½Ð¯§R›‹kwðûxÆ|ÿÀ PcÉd)Ÿ§öì·,Á7I\svý~ é«„L9A´ dMQ<`hhAS›sþ®£ÕÇáðR4žr¼JX4xýï¿ñ·3@¨Øò`Aƒ&,¥•-_žeëo=‹¹Q`þ¥›>†9’dI“'Q¦TùÏß>}óºaSæE Ce+CVqâo¥¾ýN&ûbò‹œ,Uø®“*^”aãF‘ž>«­Îû6žJÁ†;6ìG}ôÞq{–L  ôÕùU¥—A‡–¤×@©¿¤cý‘x@EËhÙÞUÜ·¯åâÅýüõÃÆâ7²—1gÖÜ’¼˜3«0Ô"vîÑôP =é[ß¿a•5€ò4êĪqçù4Í¿7ùÑ%ÌlÏxm¡¢bÀ;°¥qBƒ’RµÉlCÀú½«t/ *#Rô¸›'ÈòÂѧWÏ’ó»gÊ”-óº ¥Ðq’èF=oþI§ÁÚç5œ‚B ¨¤Rl7‚èZÏÁ1ÃMŸ,ø€Xø¢-ðm%üVꆕª3É‹þŽÐ(œ²©Ï¡d²!¬ÑÆìˆ bŠéq‡"æƒâ­yTq%(#JlËg£Í7½ò\ꌅX®mb Cq IpB¤]Uzt%i'É2v$†X U‰àqVߥmµ³l¸¥L]âÈÃ;ò¨ãŠ(Th  …N)û ^I…;==Ö ØTX6©:flA‘nÚθ‘ h‘E:î¨Úê:¤pâVP ª9%ÖŽJ—S*"ü4¡l aÞ-x‰F"-SMZîàZçn²‰†Š\Ãê¿ïh ­xÆ ¯Q‚‡âœUvÌT<ˆ›þDp‚Ô+§‚ß¹9DZ8ϲæ½eòÜê=¬4Þ\ÿA%-Ø ;â’´¸©ìíàù6ã§* e”U:¯óá#ôç,˜¸Ášf”±ÃôªíhKÒo»qý¤}x\vœÞa³¤æÑ}¶.úðC=þ„} cø÷û2ž»ñ]™ÒŸïc é9@…Í55¥ˆÍ$$pNfä®@ \pà£~4”È— l<ÃÏ»Ã$¾°?*,C(û{âU²`;`!þ`I°§½ËÌã-ØÈSöàÁNˆeInŽºÐ1ãw8ß<ÁŒg¼ç "   < 5bÙYX®X+î2݈— X<$‡€Óƒ<œu43N2ˆôLò á LhBœp4 Q h„!e °tO,_haIDt™lèÎrTÀ–Æç¢"=¤ä/ ²´y¨Qyш4°ldƒ”° !TØ… „´â+K"‚‡•k,°¡]né =<ÏÁ‹0)Ì»q™íä7T/(O(ü‹Â…} À‡sÂæœeP„ñB2š‘ (ú¡‘Uóþ<êq/tN”=ýæ:³Ánl4žÉHKè.!‰Hdo!Á6SR”±‹üäŽ ‚‚(ÇÜ JP–éÁ¸FæôÁIRԌ¼h7Þw°@ÍPjZBá‡=ì¡lˆ H0¨%ÿAXXZ*$I%Ü0iA¢ dfT-8å„(6Ñ kpLsC%*‰cÑyìu‰Œ†E†ÉˆqZÍ}”ÓÏtj¥ÿ$ <£´…o!’ U`›Z3ºQ"FŠÕðlfͩػ/¯W9‹³XÄϳÇը…$AmÃâJ±¨0%ðУjXY¶]I"IUêFþ¡Ee¾óTÂíh‘V!ºD¨…uõQGx°Ðt‚lE -*$–d kI’sDã-(`Á¼h‘?Q„¯Ç­H Ñ¤ 7Цnöá„xQ/¬éìP«)<«ñ"A‚¤Ëœ—$ûô!7(ó¼× 0Ê(Uªrx(8iEPe4ÿÕO€Ws¼?x0vÑBhX [8a…Ù f(L(@X!ôpËš¼)Ü/`6s).ðüöÊ üZd1v]qy°N˜8ðß !špë»*x‹¾ÀƒdjÂŽ-ÉÍBâ:6¸µ,/ˆ›¥@MQ¡G7LþÌ>ò\˜ÝØr%ûpxÌó»Õ`Ê}ÁWýÝ\ÄØÁ·6ŒG+&ÏJs¹¤›~8fKðÀÿØChtVué³gTq‡ê!›8&4¢¡Œ&¦‰* èLise&È$Q©­•!˜´!Òr–]òa&ÒKóT’8y¥ÇŽŸ+kÎÕƒÓœ¡_6¨ŠEÂÓX«-”.D‚ 9¨A±ÓðŒ,ºKœþA/|zÚ$0¸S†‹mñ±Ü±ÎÍWÅ=Ú¥]Õ˜Æ4¢‘Ìw¾ÞšPÙÊì†!à»ø¥7Â’f“dʨB¼@¨`èÀ.°þ/`Î6¾<£û"Nh‘]r™É\îFïFÄk6Y ˆ¯ÄßG¡‡2Ì @1ÔßÀ×Ë„ dÛçgw|œ-z\ÍN„¾Ã4Ç—ÿæ-hxpN06 ÞB9pc¼&YyAÜSRd‹Àà{t—s„kcØPÙ/qaºÝ¸{½È<ÄDÀB ¨· àôü-t®œ2:b^dzÜà…¦ôçËÜ›‰¬¬´ “]«ɸ}îÑÒþÞ÷~Þ«9„ÿ·þIx¾(ûC¾j0sæk?¦¬‡‚ª€"!¦ÏPÐB&´ÀÌn%êXûœàõ¨À à ¶àDX fÏlO¢Ò¯Y‚=bì,¬b¯bÐó¬F`ç˜(„¶€[¤ tàÞôô⥜oJ6Ì@¼`¤ ZÐ.¶ @ÏµÔ ‘r …Ë „$ P VÈÄ ¨ÌÊ<ðì¦Ë1¼pµ”êL¸àÁŠ)>Š¢ tmeÎà»r¬màpp`²nñrt0 •ðaO * x!”a`”† ¨°àì¥Êpo )J7ìxÒ"×쀧ôà°þá¾`ãàítíoì@ à¡`ÜpæXÑà\ÑŽÖ¤]Qæ¸/Ǽ ¿¯¿`Ÿ”°Á)Š\@~ z¶©z©ô$1÷Î+jæçn²Á6( ! 鈨ˆBÁµÜ  ¬À ¨àOñÝÐsì–f«ÀJOñ«u {ñèºATÖNy¾@'´ "”1’š±„.$ä%(Ny’éf¶À톉ˆø€»¼@÷çÆŽïÑñ]LžÀ F”àjÁöî±Oä JmÙêzO‘ã ™”‰ñªì yѲ+ƒ4¨è®¯öJ©þ<¨j 0xaú\ #3üª¿ª€©|¬rbÁäDQzñ0b21PÌ"®~ŠH™rr¿$*{R÷c~”jãÞ‰Q ß!îL'Œ ”zñ‚ >’Ò•ŠBr!Vvà Q­òªò¬Â é¡9Ìrã ÕØ²-ÑÎ’d©°¢ãa»ž§”‰­2Jƒ’ ”øò=îÈ ^åZhÁ2N*ÚÄ"‰ƒ ¾.;“ò–Q 5ÓY¢Ïê ¾À ¨Œºàr<¨é’N³8®è ¾Àf/F@*6 ĪbKÈHºüÁ¬«(ÛO<…s8±1¤ÑþÏ ijÀ&ré‹e¦¡¸F ÊË힊ˆJéb“Qbá ˜«.uÓ®>"¿JÐÏ|)3Ùó®¦k±ôaFbl"³¡Bá!ª´B»FÊF hmd¯L„A’¡Ét$>bª€DçsÛ"ô ÉSˆœ04C‰N”pR£¨Â1ºí ²@-`ï0À@1óMb2=â1C.G›ñ+pCqTLˆ,Ñ&5® Î}rÃ%@ ˆHV xà0@ °¤HŸ‹'¨@(G¹T3¿¢0¨”AŒ‡!Ó‚“*Æ_Z¶à£Öb]††Hù+DF$˜úôR³þ¨Ü"#&ï1µm=ƒQ‰NyÖêO>'æRUµ Îâ‚ôÊ?UÅâ,G"£–éPáæœN"oVµWgµÏËA!1XüQ;#é4ê1C B}µYµ´LK=ûKF‹Õ úS&e2V§ÕY¹GÜÓ sC½ä©‰ruµ[ÑLöT´>¾àÉBSZÓu^qÂK§õOÂ]K \û‹Yéu^íX¿€'h=ÿõ`ƒCžžõ^¶a!Ä]Â_vbMb$–b16c5vc9¶c=öcA6dEvdI¶dMödQ6eUveY¶e]öea6fevfi¶fmöfq6guvgy¶g}ög6hþ…vh‰¶höh‘6i•vi™¶iöi¡ö±˜1$ ¡.6j)I Èj$”¦öç°º”ÁgB¢kóIF!6lïªp¦$ºökB†jMm' {NÂlQ.nçnEâöN$Þ%ª`ø–sX`nM øMpàlE¸wnjH%úŽk½%vr“f ×f¦Ãm3×$’…ÈNÃ8×Aæa2 èÁ{DrBo÷®Ÿ(%uäVTÂ¥HbpMB PuK âFwÓ£j—$Tà€0WvÂà*êÖá´4!v y×CXB÷$2vOB´ 2ÜáÎ}îa[ ÂþÐzL{Ñx¡7!¢! ×o B†ž¡Úáyì¡` ÂÌÜw=ÞalÇ$ÞAD×~Do»­« ·w?7X¶`XÖÝh†µu28P¯Vi¡lCå QBÚ—ÓB¡õŒÌŒX„õ€"“8``ùô„“v#p{Èæ$¨ 5Òô ÷á `X_…h¨€Ä‡Å¡ìdØò!øázC"^øp ·P €‚p#„°‹ýøÊ KÊu,GЦ@øÎÁ\eÃJá|K!}Ã!’Aa´W#p¢ €-Õ=ÏX`˜F¬3‹h½þ ‘ `Ô #³°U©à!Þ JH¡¹ô¡àLGøáL "Yâ—n ˆU"¦Ê9}³E\îV찲Π˜½(˜{íð @´Ìèž¡Hñæ«—H ðòo¡•%É/Lw myݶ9òZ»Ô¤„JhM¬à LåSϘA^âBçÐÍù´à’A&Á´{"«v ÎÜV… °E‚[!jÇ è¡¸ÿÏ+ë´3€ôò!¾¬\ÙuMègmé§O¢¶UKí˜É· x‹$ºCb´E"{ZŠõ¡¸}ú0’ʽ]âyôàFXÄ7Øgmišº x“Št_ží]ø¢Æèu‰‚ÁõaRD *¸aàæ¡ªØµ"x7ê!˜cùf¼«\¢Ödì¦ÛÇ¢œ$ àÍ ±"hy$ ŒÛ­ ¡aÄLáÛaXçAŠ»°ñ~?¾|^ tc8|Þ;lZ°`¨N" V ÷iDDÔA¤ÌLAð˜Fáyu“Yý04Ï"X’Ç[y\ÃM6Êdó,èã’|*®È"OÝ<°EFùu“ÍtQ€6ÁMÏ0§ "¤UEV¸WQ6ÿÕÄ‚e7•AÝ @å•„È4_(°@àK[µHf™fþãO"¼#?úÐóN6ÏÜ%TE:ÖôEfž5paE[8I¤F"Ì$ %sÝ“ßidþ\xñÅ% €‹x` ïˆyf§žªÈÍaös7Ñ<€T4ÝI HjTE3AÃCÖYEðHG“DuÖdÖ˜m1@[@z ² -Ń‹걄æ§Ö^ë×>TDu4P(u«º6ð+DÝ <è2´ BïàQ€B䫚vT h±ÅVÁ<ûìØÐ%,¶ /LSKÒ,K†K–MÉè)h„ÂÝjkÂÏ8ÈÐgQ"”§¢#KH¥VÐ,Á/±…>(¦ÈpÍ6T=Ù€j8‰  ÐXUkЄïÐ}2D‘¼Ñ¢9A£¡G<¸LþpÊÌEíÍ^לsœÑ4&O@#äëfí"t¤­j× ÿÐBh"4¼Ú»ô 7Žã†0$¡?Àrñ, |Á}•/p 'ePÁ#Pp£^ò×᳉†!ý A úÉЊŒ!^@ΰÊ}8AáíÉ*Õ \@Ãp¶ÐÄøzþX…ùeÄ 0}<ƒ$¨_è4B$ ïXà6p…nF#A’Q´<íÆ`|éûâ¾@X+ÆàžÑúvÉ`;Œˆ¼Œq Ží0MºøÅU©Õ™Óoâé!Ägÿ#ÎìÆbDP Ay¢d<@^EC8€µŒܸ]îøÅœ!å ŠÑ2=´Ð+ä³&þ€¤‰ÂåðB›£Ã˜@¾@ìÒCÌQ‹O·]Mä¥ÄîË ëÈÕà ØA.|‘‹ œ ¬¾Š` E75îqÆ®•ñêgãQôåFIÍraFÒÍ6¶¼Ÿ§=µþžTÀ§_èÁX@##SZt@ƒ0×T,ÝÇQt«NØ@ólš$<@†YÁóÉåË]!Ï0kˆDü S üõ?º—$Çî9ŽõBx5Ä'@ Và/šËwRãñófí×Wêõg ŸÖµ5".*€ÖýÇ‚jhfX—=Ì4âì)‚]Ûd^h@j³i¢!@ |Tbž¹s¦÷ÎÏ º‘NöÁ°çDÇ*è+SDŠoco® êdF‹`$ÚˆãÆxòÞ&l°_ˆºšý#tc¹òâðíšÞg`B®Ú8ñ6T °êdlÒ°“Z³!‚ŒDÃÆþÙu:–Äp _¦¼(ÕdsœÀc ˆtNð'} ¼x†Ý1ŽùÓ“©É¦2Ë¢sò+4À žGÈ^S lµZÁ¦r»Íã2=赉¦YñN5ý¢ñÄÜyÀ”‹'Gdq~„;U‘}Ú·"þÀwÄc=¡mWb9‘_i¥1¨áFò‚?ë¢SW!ÞBluÂÒk€=ÑT e:Ñ n×Ck±A²„w X&Ü0¶”z§`lW Tf\ñ=#lÉ‘{ñÓä¹² !$ BAÕ{'%^´gý0e"@r}áàÆ @z` ö d4¸"¸&þ$ Ð ÓdÝð _@ PZ¸aŽ€Ñ+x'Æ‚`n4(ÿ0=àçbWóÂ]q³öÁ‚Æa'È$ T°˜ðzðõ€0 ˆ†8±ÑIºD6"`Ïð¡nr²$ EïAÌWj÷ΑhËÔeqc‚‘Ñ6E2@ÿ@•9¬EH"PÆj"@ÏÐ'¹gTÀâÀ5ý Ü ÷ÔƒŸ¸ó ¥ádT °” Ë@,Ìûoòö@%øk)7/²œAÉð9Ó ÿ!t³ˆ(”e?S‡Z@‹zÑ(‘`v– C,àþØÞˆó€ ^ÀwѕŌÇÁ"Ù ‘ÉY–ç[Q„¡µrŠa„È‹31Qmb/½—:ÎáN4¡_0j 'ûà…iPva 0[ð^¦‡‘gâð b õ%Ö å×ð€kZðiödp þ°‹ˆøÁÇ1G"7uR2S(#m·‚Àö-T×"1ð bv€4`ƒ3•Ri"BGÀ úP#Tð&T‘U·€GqséLj±L–ö"U‘vA.3(U‹0t”CõÁØà‰CáØ‘ Pqàv@Ñ`nPþy˜ò£q¢Ž®X9ûÐ Û(þá”™¯{ Cxt“ –¶ŒfF·Ò±@h‚iÜåŒ5oÓÖs\©Ù¸ ÷Ô7¤Õ ýÐ þуÐ^gïó›eB*HÁ UE¼öÙáŠ*pC©øáXhÅ`€R„Pј°^  ·ÒÜ€#[p:t4ó@P5óÀ|N0ž|¡‘^ðWn7™ú¤Pxpƒ` €gôš÷¹ûðKs9›Ï öóÊ@ {¡`Ð|’¸W'Òdñ¦ C +óÒ•Z¡RÜUø ›÷¸árø:P‰ÉÐ {PT¢þ€ ‚ ¦»` · å6-4*?6Ê ì6bi¶S‰ ‹iŠÉÀ %‡¥@Ø9  4EèUÀ ÿ¡.·RñxsCõAÁ^)€˜©:“'‘É˹s‡¤P²S ·_pqK'§¼1& Šù-wØ#úW0l¹y¸¥Aàó)ÓI(|S/T€¨MxÔMûð °— dÚ0ï@+ùTð[Ù¢C0à?p ÒàG†¹ª\Ú&E*q’ [ðW!Úš ©‘AØz±9#ž¿ ú1ŸCjKH;Óku4A·Eï9‘jÚxO7Rþ›¢$*ÀOf¥u Q®¾y®{QKDÑ !rNÝP ûÙ‘ÉÇÙ˜ ©œÉkÍo®)\—ŒÓ¹X„–&®óetÔXTZîH‰[xJY¢T83 Q GÓçJ¬–dû±=ÁQþÀ #`ðà§8šÌ™Æ© + nˆ8Ì&‰&[`‚)ÇŒ"s2OÀ tt°C@!ÝP‡U ²A¶Zп!¦Ðª¼p#_È/_  ÖW®+Qµ~ÁQûð€aÏ⠞󰆫"þð< ¤¤Ñ`ùùÇev!$^{ªË`‡iÉ " Ñ7òþÊ©žê)ïÉØ/LN­Vz¹ûWú·€5Ãp^°)`Ø2•´â£c× §QðõDáN/É‹ 0Å0töÓdû°$Páh¾#¸Žei¤ï.T`Ž$3‹þ õ«¹xlŸ#N°¶*Ÿ&?ºÐ¤\fêtÇ펻AícÏßño²J0ÅIðÀ]ì^P 7ø¡˜¢ÏZ6úî+3F@0ÄÐ ´`Qå‘÷#ï‚’øC>oCg/×)NÈ1SD}R|;@þà¶”ÿ¨Å3α‰*!a`uþp«·£gPßñZÝ  >P—²Ê@TÀÉÉzc« E[rªyù¡ä @†(“ÿP=VÀ9+çö<“0²=Ù¢Ê@ç ™@b0/ð:Ðë+¡;¸/‚¾Âã` ¿0; Mᬥ âUÞý#XРA_`;øO ß5Ø÷›“‚ûñßFn* RùR0[ƒy«ˆ€×Ð <+¶ÐsYÓæÍ‚DŒ±sÇç8df0@…l4q.eÚÔéS¨QB@ÂJ2lÝÞ…ÄV’+¾l¡âDÅRkîK&‚ijŠMá©€×àCþþDp#¨‚/Anÿ¥%H¢%„”õ5hIðdb“ ¼àÔ§J7µM»5ñÓ³ÏB^œ4ЭŠ-3¯fÝÚõ<þöé£7·l_  ˜²%Y²-U ¨x0 ñjnTh9ÞT!Æx —(Â`²Éƒ Vö¸ÁlÖ#«þ·o8ù†þ ‘ Í£kƒ`tþü=}³¹%£€HøpÀ›d« žn¸ÁfAh Q&™/´€‚P&3z¾€@÷ šG'ôqI:‚ºyÀ#+ž1È èûG™-þY콨ÈÎ1”‚¦ —ê ÉDP„L¨ï§@æÑGýiŽ@(£þd-¶Ùæ™'AܰÉ£‚Bƒ*›ÑR“*™º¢Œ ÀLÆú1H„Ä:*Q0( #hŸ¯!}X`A)œèñ¢*ülm Ž#í üö‰MJL3²ÚlÛŠP³Éìªp‚„¢ž2´ôô…k"‘ +n ¡8Ê(×lX8ˆh|Ì%eÒlÊŸfDPÁUµ²àÖè©>oàQÒRM³ÕöX*;…çp»I›g"‚ÐK$#4ªb£±iV‹HÈ«wßñUׂð%(Çcàƒ>¬Ë©À àÅ®¨bR–6>³ƒoÞ'?·Õxc‚þ¨œžÚ¬´r+l¼TA®iž-€"›ÕèTÈ5iäó8h 8Æœ ‚â¯/nìEqT÷…`vj-–;§8c!‡#§áæyè±4cŽ»Ö46Ù–yìyÞɦÜ*X €\RO¾ Y­gx¼‰Þœ(© ÞÜNMí ú"‚èi !`3Ö%xD°‚á¥Ø‚€¥›šçYj8ò=¶é&k&¹özô(Á{IÚè¹ ^$$Ý¢áišŠ¿V tлÙ4K$¡!Ãz. ¢¼¡*TþÓ%¼p3ª^EPFÎ¥¶Ð ¦ý,U,ÖúRÒ×2"°÷1ßüþÚºÁÆáŠ«âŸ~¢!A„dæÎlÇçÕ½ ÃUƒð޵íxÏ<Äó2¥çyYœKL´Ñá& ˜ NÀ¤A{ŸE7(µ5ñ…°tÿ0ùôàx,*JP¿±FfyAðö¨ˆ ÈØ;z¸‚ à^ï*щÒÀô¬¤hN©LœCð ÀQ,Ö‘ô  td ["äâ€È'›}Ìã @P+´ ÐäV³#Âáä†ÉØ×töfhhÁ .ê‹¢¼pÇ»èñˆs 7H¨¬‡ÑÈ æ¢lÐ3×À~"ØELJ¥|ð€,ŠñÉbü@þkD‹à£( †6Ü_AæÑ€¹ù–Ñ ÿ±yä•ÌÛ‹KØó¨23Ý ‚»ötAe=¡ n8Ò'®v1fRš™›>¬‹O# àÀBØO*Ø8$Snè0K¦lˆ ŠfËgÒxµ3H7 ºl ';ZFÌ•¨e`ŽTЂ á;"ܰƦùP¨€SóÀ0p±ƒáÅèÔ†.¡EETæR´àÑ} yÀ“H(Ä=ć»+^C¨ãKBºDCÀ5Ÿ!‚5~ Uð‚x¡‰IœВ¯>ˆF'T¢G7Ø‚ þü…NU˜Jå$ˆ´I† ºw@r!aÜïbŠ+\‰“„½Äé*_Ô€\fÆY¤d¾  e<ãш4°ñLK^Rª‹¥’4€ €^€”¹ð*…Lǧìà $ˆGSL%:½T® ÇÓ‘<ù5'Õø¦&iu£Ñ–BºÈµ)ÅA… (<£A ÒR6œšXÅ.¢óPNUžñ„$Hö“;PÁ—Dð¶A…ðBp·ƒÒšÜÔ ó€@vówÚ‚äé%lˆØYW¦$M¬R$Á@µ°6°¸•VæQ}ôƒ|Âå/AÇ6/Ü×l¸(‰A2´¡ :@‘À›ìC‰N¹þ!`Œx-`ö ,X¢-½ƒH¿Ô$´6ùeMàa•ÖÞ¤BnqB¾ jT¡ÆÕŠ÷0fÝþb’Cè†lÃg8ÀG@‚Іçz“)Ó­.…±ë’~<`‰å@ŠíôVðÔ” ÑX©‰)B✊ØyP¼‰!¥Ö›d@÷ïHV£¾5­m Ç9áû²ÛœÍ P8ƒ$í`CØmZx™o’¶KZAyI†i Bò‚W1ÝÅUŠ‘¦åAÚµˆZÀ1P@‚[‚ªØ:¬u'°M ß›316ÕáÑÀÄæìP Ê5y`«òd—`Ã^. 3A°q^ád×wù.þð˜Å@}2ÅZÁ”%EeAavÐC·Mç±m-C€«sÜ-ÛtcKÐð„$}b<À4‹&!¡ »K.Æ¥Sy5,i‚]ƒ:|F§Û’,  ŠÀÒæÎ¤ÇToŒ*¶ƒÐeœzŠ€ÓPAôMœðï‚„¸&, ³‡oÙìÀÚŒÆt¦²’î[܌ؑIJ}èló`/8Þߨè#ÝÙ¨%Ü};à€òþOǶzzØ.áÝj n/ÄæÐxßÎÚn“öà¤Ä7!ç¿/'Ыß!•‚êÓÏMUxäÙy¯ þL^ߪ|ã²{CúW“Ù„p‰ÍO Ì8Ý䕲]^SfØÓœ{SYNØç6¿Ÿ›„QO·‚6±A;ÐPÁüf,Ű7¥ÂQV_öˆpmHäo’Œ~×dî7‘^ÿ ~z ¥ÿƒ’šzÕSõÇ£ÒÄ»ñ0ˆ]#U!Ò…oÒVºù6 ÚMWùšï ÝpëM8´”åÛäCC`²]B°¢T¸¯Ã>Wƒµo•r‘]8Éʘ1¶€gÉωÍ1± 'Ƚá[Aû–ÀÀ ¼‰|J¸9a·*Ø‚.8?0J <@è’‰þ§P®bð…5j®K§h9œH'›à2¨‘+›{‘"ˆïÀ eH>å+6›H†¢`›æ*(^À„<˜–žÐâ»´AÚ@Q‚%P®#€€“›±³‘Æs ÝP±{›´šXÂnB8±®ÞcŠü“©¢ð?t/H†Àb†M…Oè„à ÃCþ*Õ—*ð®JPæR› +zCž9lˆ‰°4úà n8¿%\ŒšøŸ×*AŒ¶›XŒF'p£P†ÂÚ-ÃZ(HÜ"I„º}™­È^X€a †$€øbˆ`ˆy+ ,+E·¡«V Aƒø²¸~þ‘+¶Z i¨#¹£ÂÑŠ¾öjÁ/h—d•-Ñnø­Ðñµ`Ÿ¨«Ä-y‚ HH.b ;艞 ta"º.Ó.—0œàz™<´‰Ÿ© u4À¹š §§ù‚è€-à…gÈ D”¼Љ¦|.í» âY##¸…$ƒ#¡¨‰@qºÀ¥à† Ë®p<­%ü‡C¬‰[yÅ…œBuᆢà P#ª’¼šÀh‹±­Qº–œÄ}„l𾂰ҋÓÐ †áIœØ¢)ƒ³ >±‰¢<¶š`E¦xtLGòè´B`A/P†ùÊÊy@“-°83Ÿþ¾ëJ©¢*ëi€4{/¨„¼»ƒ ( £`Ȧ¨(D¶š ºÔ¿8Ì› t‰ŒtŠ‚‡¿|¨pƒLˆ•ÄbT›n¨9sL¯<1 ‚q‘†eà…D(=x‹¶Ñ¶”»a»‰–Z ìMºŒ ^iŠÇkŠü‡»Ã¶ nã¶oh(‹[4IÆ\=Þä/FinˆµQ‘†d°ÌÒ´¨)ŠÐF@a ¹ÛËš ‚ÓüÀƒp'›€Å›(;Õ»ÛãŒ0:üÈÆÜ‡¹|LOñé-ÈÕ!R±„Ë<ƒ­KK8œ¦x¹¥ -œ¥Ç‚Ðo4Ê&ä@˜»‰g %Î0þ+’}à‡¤C=@“k¤Ð‡ò¸²¡ºgH†7(½1¨=ÿ ¥.Û§21JkKjˆ¢ü‡x’<eŠÅH8Ã%̹«ûƒqpPÓ!¡€‡&ÒÇ\½É3Rù‚>Øœ(8•l]K¿ƒ¸ÎCÓȆèþÄ2úÓÑ-'eŠËѵ5Ú ÚVà» UÓWÓ¾q/à‚8E¨+H›5Úº“3 KKM)]<‚àé±)=ˆ‹x (Ê‚pJ¶B´ 5¸:;8ºH„Tsû¢2T·"õ-hƒ$„HÐ*X#'P›Ã+Š`Q?>lˆFó¬ÿGœx€ýÎËÏ}36´`G˜±þ ÕsÐ"`ÄÕ\õ‡‰"™fàÚ-`W/¨‚5âá`â0¿|’ \ Y,ÂlUÑ‚ B=ˆ-`Õ`«¿ÑL¾¡‚.¨=…J¢Ar}:IÝø š?ŠÛúuWp°mõ½œûOƒ¨†fMSU;œVý‹Ò¦°·).v Éäù Ò ƒ´P¨˜dɉ57ô1ÃY{D´¬fH†.ƒ¤ƒ¸Â€‚ˆØ³¦¹¥˜©›¨R:¿˜ûQ—¸™‚08„UØ‚ºÁª+ DjX¨J2ŸŸõ;tCÙ­/X£jhpw ¨…rÕx‡Òlˆ+ÍZþÊ ¼MS@6e]‹·É,ð‚eЭ-Y›*XQqª[[lÓwÀe`ßlȃ͙{]£Pt ã3§¼šH Ú8€k…Ý-p¤ BHƒ5ˆ„¿R³”\-•gzªÆ]¨ƒ5Û€‡†Ýn †¼£HË;­‡Bá!§P~õ×ѺCŠQ$¥ ‚€€ƒ‚ü‰ið-t—nPØ­Ïqe^:+±Á¶ÁšÀ‹‡nHã¤Æm%¥/¸¤¢z à£Ý›Ø> ÛÂ=TB‹WuMöÕÏÐp°˜SúýkqTý•[*á¶QI7T0N€® ‚þÚBc½‰Ëà ­ý‡\€MÞœtµ”­¡ ˜1åS!lȘ*‡QÁŽcö 9þàh *å xÚ¢ðRˆàšh`G.+’•ƒÅe FTlSš…WÐà#a2-S}ßh&Cz0›õQ!.¸,À-‚CGv¥‚>óÎØ“Í$%+ع†0 ¦Èaïxц¨¶ç+ô€ ø8p‚ú£TÛ6‰Û†>O·ùgI<õ‘uÝveW™,ʼ:10Q¢ÑúÁ »,ã%;YƒØ‚ ±ä+ô$PâØdhh€à¬ã= û.™æMI@Q×¢ò‚È­ÝŠ†J(½ŸFß6Q›Bçd›Å,eœC±`ÍÌÉ#àA€ièÅ¥‚iþQØ„¼í9¾¾¯vLs-CYk¢…«ì­Q)„ÒÓ Q{=d´p‚f "3j¦H»—H†„\#m€„€­R®ZHâxU†YzìÙå]ì1Ô¾bähðÈ©¬GÜðƒ,.€gÉÞú<äÞµ‚l¨ˆeãe¦è@z‡wb·ÞÖ„­­àÁbø¨G­—.ÞäýÅÜÖí¬âÖÃð‚zÄJu[|®2ö˜Ÿ·Í¾B/á/ȆUÊaµ‘ÀÛÒÌ6ÞTPþkmɲ…¸ßo°*¨/Ï=OhFï¨ÒÀ{‡´ÉÊÀ£[QÈ»(à)µÁo˜þè¢ þA´8ë- ÉÃz­<£[nˆ†-p º ÔFmÍ€QŠ@×t€ÿ@i*pZàÁ Ð:µo±žl}öY ŸéØè‡¡rª¤¡[hÀêú€ƒHƒ*øf(8VèÎØ‹=ÖUnRòÞmݧŒšÖ­s"Ïk´ð`_ð g°‚v…W[,#€äÍ+91a'ÞrÆ®â€Ô›oá†jXÕý ˜.Àiœ®+ šú`]6žè‰¶î!ÇëbU=€E—,H*€®?ú ëù€$0 @¬sÛ¤‡xH™eÌ ·tÆZ=-¨fVoVþV†Êœo:½á…ßš<:(®ÓsÈ=#GpήõÏs«Q×|® àAb¨_å¨Á,el*JwÐ%)Ýwpög‡vþš®Šø¢ü±õ©T,ˆ7`€ÁÑ­QM Õ8 ¸[è…\ÐD=GN[gFˆ…ÐìüÎoÌYðÀ&ô*x†ùÐÝ¢GïÑÍ…<6øôlâ‚È‹a4Ã^ÅévýeèEQÁO(=6p_ ØAÉR hyÎoØï`z6¹'€É–yåê-À†bÍŠPÁy_ÌrÓùê¡Û°Òõ¢ŠþàÃïA…ùþŒH€W ŠaàÁXp€›ªx€àA\€!€‚o*Ђ“ºz€gP ‚o—”¼ßÓÛ/3Í‹¼×ûäGry€j¹?}põú°„˜¸Åàn%³ò0Ùµ—, ‚ÎÇiGp€ZP.%g:‹H—_ ý'ž[uc/€x|ôt…ú°Dàس~˜v- ß*p\àî D¬›dxÈN†®€ö‹GŠlÝàÍ“6@½yó"œGOŸ¾~þüý˨q#ÇŽ?‚ )r$É’&O¢L©r%È‹ûÂ{×[6þ¸DØðáÌBw~Þ±sè4žy9Pl)Ób ž€áõŨ±š2ðå6lÙT|¡‰ ¯!  ‚Û;‡ô¨ Ho.]Šû.bd©w/ß¾~ÿÖ‹W.¼ÂÙ$‹Hwç;šB-òÔ šW"°=Û` «-Êž†âYKbXk9 Œ³›-2¹q m¶×nïàMÔÞ>о÷ݽø/oàâÆ#Ooï¹ó  pë[ŸóÆÙºRöš›*4•!HbºX­^(gËF¶h+.Œ/v˳ÁÂôž9yؘæu¯lRôÎ[ôÓpÁáEœr 2Ø ƒÊ1Ü[^ès þ?Â4SþqÍ_høÌœ…ÂkÙöNÐðððRß<¾óuó¼–l¶IT¡?$4 ‘"™¤’K¢”à™ p;Â3lWvóÅÙìw]3Ò4Ív¶!¤<°a“ŒVœ·][ví3ÀD½#“mIDOpÐ4ÍF *Ȥ ƒÚ ? @‘pÃ]D=…Ù™â;ë¦!v]Õ‡=[ìf]WŸâ¤Ó*póL…)¦'‚ ¡Q …«¬ͣūŠJx*ª‰ ÂCUòçc7Ýä¹)^Ók?¶%p=cë”ÓUK<tÛ¯¿ÿžäÒ½¿ ø ¸¿Þ¦X…û°KeL·ÅãÐÂx½C‚”"ø*ÀsÜ1£b¼O?¾3å\õ„›§… î\-êÏ©èpãœs·ŠÖ|§÷FÐváÅîB¿<±‚¾fijÍ:Cõ¬Äñü "\rÆÿ< to'¨‘ZR“]v¿OP…«Râu3F]³àÍÍe¶ÝwkÛM¶ ×7qO6Msàx^ø¿oxK†3ÞxÇþà¸ä“çüå—cž¹æ›s޹矃ºè£“^ºé§£žºê«³€Þºë¯Ã»ì³Ó^»í·ãž»î»ó޻ðÃ_¼ñÇ#Ÿ¼òË3ß¼óÏC½ôÓS_½õ×cŸ½öÛsß½÷߃¾øã“_¾ù磟¾úë³ß¾ûïÿüóÓ_¿ý÷㟿þûóß¿ÿÿ0€  hÀ"0 \ èÀÎ;rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/blankbox.gif0000644000177700017770000000223512633765070031747 0ustar michaelmichaelGIF87aóáç·  !!!"""###$$$%%%&&&'''((()))+++,,,---...///111222333444666888999:::;;;<<<===???CCCDDDGGGHHHIIIJJJKKKMMMOOOPPPRRRSSSTTTUUUYYYZZZ\\\]]]^^^___```aaabbbcccdddeeefffhhhlllmmmpppqqquuuvvvxxxyyyzzz}}}‚‚‚ƒƒƒ„„„………‡‡‡ˆˆˆ‰‰‰‹‹‹ŒŒŒŽŽŽ“““”””•••–––———™™™ššš›››œœœžžžŸŸŸ   ¡¡¡¢¢¢£££¤¤¤¥¥¥§§§¨¨¨©©©ªªª«««¬¬¬­­­®®®¯¯¯°°°±±±²²²³³³´´´µµµ¶¶¶···¹¹¹ººº»»»¼¼¼½½½¿¿¿ÀÀÀÁÁÁÂÂÂÃÃÃÄÄÄÆÆÆÇÇÇÈÈÈÉÉÉÊÊÊËËËÌÌÌÍÍÍÎÎÎÏÏÏÐÐÐÑÑÑÒÒÒÓÓÓÔÔÔÕÕÕÖÖÖ×××ÙÙÙÚÚÚÛÛÛÜÜÜßßßáááãããäääåååæææçççéééëëëìììíííïïïóóóôôôõõõöööùùùúúúûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,óáþo H° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹3jÜȱ£Ç CŠI²¤É“(Sª\ɲ¥Ë—0cÊœI³¦Í›8sêÜɳ§ÏŸ@ƒ J´¨Ñ£H“*]Ê´©Ó§P£JJµªÕ«X³jÝʵ«×¯`ÊK¶¬Ù³hÓª]˶­Û·pãÊK·®Ý»xóêÝË·¯ß¿€ L¸°áÈ+^̸±ãÇ#KžL¹²å˘3kÞ̹³çÏ C‹Mº´éÓ¨S«^ͺµë×°cËžM»¶íÛ¸sëÞÍ»·ïßÀƒ N¼¸ñãÈ“+_μ¹óçУKŸN½ºõëØ³kßν»÷ïàËO¾¼ùóèÓ«_Ͼ½û÷ðãËŸO¿¾ýûøóëßÏ¿¿ÿÿ(à€hà&¨à‚ 6èàƒF(á„Vhá…f¨á†vèᇠ†(âˆ$–hâ‰(¦¨âŠ,¶èâ‹0Æ(ãŒ4Öhã8æ¨ãŽ<öèã@)äDiä‘H&©$O;rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/images/WM200-crop.png0000644000177700017770000003445512633765070031705 0ustar michaelmichael‰PNG  IHDRÍnãsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÙ /d]~. IDATxÚí½ÙËž˜÷Eäž•µw7›½l6ÉCžåî÷ÎÍÌhd€`²``<º°½È/Ö ðŸz±l6,È’e c Ìh4ËÝeÎÆ}ï}­®½r‹ðCv›;ϹÝ\šñdWWVWeEF|ù‹ÈÈ_­µæ9!ûý/5 ïqºÍNÿL”¾‡ëÔßÈ>Hs ƒÁ`0â1 #ƒÁ`Äc0 F<ƒÁˆÇ`0Œx~I´Öãyž›1ŒxŽŸÃ“*-Ë2“* #ž×ñB&ÎDXm¼æý%…M¤c0‘xž”ÏÒ©F.¾gÓ—¿ý^ØáËæF:Ã×ã…­&Ë2~ñ?àÞJ Û¶©F.÷þÞ y8B2Ò1Ž8âQZ±7ÚåÒ‡0LÛô‡®Å{-ƒÁpÌ≳Ÿ/ÿÛ²q-­Þ‹—¹~lJÍ`0xépqê2ŽåÒ»L”§h„¦Ä Ãñ‰Ç¶fëgÐ:Á³¶©–L¤c0ކ—ŽŽf*¦¯˜’2 ¯O¸ò1¹R C:í=‚µ•šS“|üïâ‡Ñ¡“žDé!;ƒÿ›Áú¿!òÎ0HV^Òd¼ Ìá}ÖJÓÙ“´vÏÒœZdg¥E”R‹<¤,ºy¶²½»Êõ?ü—\š´q,AUX s­îã! â³øTIé4Fö^åÕ#žáhÄ[÷ª?(¡•"SÅK²\Ñë¶mX\˜§ì)Ô¨C©6I:à•Êãñ—w¦÷.mñ^ñ ¸so™‘ò÷#žeNŸžÃ²mÚí=”ÊÉs”¢ˆÜ~¿‡e—ª¥A‰v{Ʋl„°‰ã!Žã†e„%éw»ìííŽ#ßpn!Ç÷2&Ê?|á@oœ¥1%¯„h…”Aœ$,-o°¹—D ²<i–ûH5bñܵÈÅÊúh¥pü•§¸AÐHûå™)´R¨î&ÙÖmÜÅ_{õ1žÀ÷¹ri/®ßf8Д¢2äŠ\)z¡£Y8¿€´Ãö:¥ëlªËvбÛfúòw * Sc 'gŒGi²\!3M®4™RHÕZóQt¡ZkJQe<ŒÖäJј˜_åÒ@™Êþ1…VOŸðl+¢}@¼¸ë’«”Íî&77®Rñkd*-r¨Ï|›ZXÇ÷ÎÌÍ ô ­ªµ r¥ÈsEjÀùs ¸¾‹Ö){«èï®í_¹²–…_®3}ù;XŽû’¹(fD[ÎS'õ—.{žÇG—/òù—7Ùkå„Q™ÖΡ«YXXÀ±õ²Kn×УY’a¯T&éwއí¦¦Ny®Q¹&Ï÷kP*ýÄ\­Ñ¨qGD«q'ä±êq7I€(B!Šß‹±&ç%³^BRñ«\œ¼ŒÒšaÚDZ\|Ç?Ô¦]ÎÍÏ¢Ô2k;[D•:½^™÷ éxåÀÆ·-˜<å¸Å>‰V)nXAZG—‹ë¹ïä{.ßøèñÅ V–v˜¨E,,,`Û‚zäâØN¹Ž_®›i8ñí^Ï pÏÔDÃ{…m[œžžfjjšþ(#Ïfà1Ð],ÐZañ9^£e÷èèÿ‘Àù[Ô¢¿Šç¾þYþÏO}šŽ¸»uß P¹bg°É‡§¿EµtÙÔDÃ{‰%¡¾Û9Ç•1L6QJÞÆuðú{0Ï-ÅÀ øæÜ÷q,›A2ࢼBÙ3³ †w[ž!“•â9MªáÞÌ°É SŸ6£ ”‘ç÷¨Gß6GÍ`8h´Îy“SÖ^:Ó/WÃtË+ƒÁðúÄ£QŠ{; ƒáX»ZE´3àáÖ?c¹õÿ§ë¿uÂ"N#Sƒá­‹x¤p¨†â:.Õðƒ“÷í…Y‚Ø`xëÄ#„Cä~B%ÿÏÜSZƒáøÅ3¹zý!íÎW¯ß.®ýïsøña²,ÛOçøh{žç$iòØß‡·+­HÓ¥Tñï] ƒ÷z¬Ç¤5išîçëá©mq?÷û½ˆƒýÊó¼˜ÿŒËŸW/ìé½`ß †“Œý|錸vë.n©I%ÙÝÝæËk·øèÊEò<çáÇÌḬ̀±¹Vš<ω¢ˆÛ·oãº.Y–13;C§Ýass“ápÈ… p‡Á`@½^GJ‰ïûì¶ZÜ»{—?üápHÇxž7Î/âíç¶ÝÛÛcgg‡,Ë8sæ žçÑét˜˜˜`mmápÈää$ŽãàyEb±"ka‡ó 4›ÍǤsAMÐ+D@„ïûã ŠW¯^¥ßïS«ÕØÜÜdrr’(ŠÆÙ¥”8ŽÃ_|A¸Ÿ• À¶múý>.^`mu ×u h­±ö§£Z–Åææ&Ÿ|ò ¥RÉÔFÃû-žápÈÕ›wpÃ&~’¦9~P¦ÕióÅÕ[\¾´@»Ý¦ßïsýúu¢r™™Ó3dYÆÖö6R :I’`Ù–eñÙgŸ1Ž˜ŸŸ£Ñh2 öShÇaww—n¯Ç`P¤1í÷ûضC·×ű„ä¹Âó~ò“Ÿày>SS“h!°m›N·Ë`0 \.3Žô{xžÇ‡}D¹\¿Á`0nèÒ9xÇBLªøãC™œGï=O% ܸý€ i ¶”Å’R’)EädTýœ…Ù&iãxºž¥A–¦!‘–@ Q$½V ­žàØHH“­4ŽëÐÞÛÃq\\ÏÝÏQ¢I³lŠ7X¶…%$Y®ŠTJ„!Ãá<Ï‹”§–E<Ë–¸¶…Ú¾MºüÉÂoÐ8}þ)é<Ö"2â1â9±$Y‹öàFqáÈ>â»´"ïl’íÜÅ;ÿ—^-âÉóœ­í]ºCMTXkíú6– â ×±J>¼E¥{‹™fð(ç¨ÙõŽžL$ *)­‰9¸Ù®Hqšh$ãlüïm?#¯ëáOµÆ[<ÊäïŒÿFª”léSâŸþSþ yý…Òy´-25Ô`x]Oš¦Üºó€Ý¾¦Zo’g9™Ò FÅR§ýöͪϙ3g‰|Mº»J©9M:êáEµ"ú±läÛ´®•ÎÉZ«äíU¬¹qÜŠ‰xLÄc"ž·%âp‡‹‹ç¸vë.­*µEàÙìlnШxÌÏÏ#…B {lßýœë?Ãòi­‹e;†ÑSòÑD„a‰á oj¨ÁpLùðßøÐâì™3Ø–¤Vöpì“s¦O’7oÊô7ÿCV6”b¨6±á‰‘ŽÖŠíþ&··nPšäýãÿA¶†ï›nÁðFºZÍ(²ÑY¥3jÓ{ô’6ߘýõ¨v"¾x®Ýa‡µö Û½ºq ´f¢ú[8û ± †×( ò+|ÿܯ!…d”õ±¥Gàœœõ²,i1S›gª<ÒÙxñ2“ÞÕ`xƒ]-[Ú”¼×dÙ-Ê~ûEg{„®‡V›X²MÙ7Ò1ÞXÄs¥sÒ¼wb @JÇèÜTƒáG¤}F”J¥¯uO–RŠl?ß’”)å81œÒŠ4IÑZãºî¸¼²,ÿ Ãpüü3Ï+‡ŽƒÖš4KI“Ôd|4âysÒy¸¼Âö^ÌÔÌ I’qou ÌÏÍ’¤ Ÿ}úÝn—z½Îúú:͉ ¢R‰8ŽÇ•¹R©ðÅ_àyõFƒ<Ë‚€$)rL_¸p$IèõŠlˆ›››A0εœe¶mãû>IšðÍo|óÕ"Ö·ï­1yj´vwùòúm>º|,ËY^^æúõëÌÍÍ•+‚  \)³µ¹E†ø¾Ïµkטššbgg‡R©DEE²6­‘R„!ëkkãï\«ÕÆéh;Q‘e|ðQôt£ƒr:|#n©T§†mµZüâ¿ ÃqÞm)%“““ôz=677ÉóœÓ§OcYBòK’„N·K¥\Ævl<×#ÏslÛ¦^¯³¼¼q’R)— |ôÑÇD‡Ò³¾,Ò¹yw•úÄ I®PJãø»Ý=nÞyÀâÙylÛÆqó"£Fõ¶þÅ?ÃYüËô*¹³¼ƒ šÜ_ï2Y Ä)‚"y| GL•aaºB'X–Dkè÷{´Z»œ9{¶¸%Dt?–´‹ÏÑš,M‘ÒBZ•k,ÛB öWÚPäyŽ¢øîŽ!A ÑÃ6ñ½?!üþ‚”öSÒyü[ìdkú]¾·…·2ØI'Ks6·v +Óhý(ÏóœøÎ¯3*GxY‡Ak“RcŠdØ#¨4hœ |mgl%8§?Á>u‘J×oߥÛï°8× I ­¥iN–e :Ûœ¹x…žÈ‘ž (¨,Å-U‘R`{þ±í·Îbœ¹o#üò¡¨Æ¤—5ñ€”J!_^àÓ/ï…8®‹”‚~¯GÜoqéâ"žãàÊŒak;Ÿ³}Gãeâ^7ˆ8󽿌¼ž+#ÂvqN_À‘pùÂ_^¿ËîÎ6åJ­¹Êhï®saaž’ï2X½ÁNo•°•%µ)æ>ùU,Ç=¦ýô°gÆ‘Z¹\¦×{vzÙ(Šè÷z¦ñ¼OîD¥ßüh‘_|~›Äk µz$Ï£Ú”|ïÔ”ß|99YVŒçضÍÎnk¼ÝuŠQ#/,ã…eÓ"ßÞó¹ë‚(òùáwçøæ'§)•ÐKçmÇql¾ùñY¾ÿ &“ŽE9tߺ³m’$¢´b­½ÂÏü9ÛÃm[l o`;oÿêZkö»üäÞ󰵎å5Ø\Ãrâ·î®‰Q6äîÖMNÿúüW¬î-³¼»ŒÖÊ´>ÓÕzÿÐZ“ä1©JÙênж°-‹³gðÞþ½'ÍS”ÎÙîmÒuHó˜éêðvuWr•Ó‹» ÒA±¯q‡‰ÒÓµils³¨Ïû†%-æjg™©Î‘©)@×zûW˜BÒŒ&©†u@‘ç1Rúo徇NÈ•™o uNš ±­ ¸uAšû“MWë=–-qò$]{'¤3>pBâX6Jué¾Ä³½·òJŠ×r‘$ÄÙ=,‘àZžiy'¿Ka"žwZ2”¶ßÑ㛣Þ̉Ådi…6ÓOhCR¤qLžÅ8^ *³F<†7-œ$k3H6p펽“ss Ï'KbZË·è¬/ay>BZȇ÷q£* W°]ßtµ ¯¥Zý_pcí°ÚúÿLœ@„´ð¢ ~¹ZämòBò ñŽ­ét{ܽ¿N.Ÿþ9Ýn—F£Áúú:®ë233C¿ßggg‡<Ïñ<¯¨°¶]Üä[.óàþ}*• ®çá:B²,ãÔ©SlllP®T¨U«lmmÑn·Å1RR›™™aii‰4MljÝÄþ¶r¹ÌùóçÍñûªÒÙÚfe£Ecê4JA·«¹vóW.- µfuu•n·‹çyF<†c³nÛ÷WnÇ „´Á-sãîZCT ©Õ'£)mJå*–%iµ;¤iJT­a[6½^ÝV‡j½Bµ\EJ›0*“dšRÙ£?’ç)iš11yŠ$ÍiwºDå ›ÛŒâQ1§Èu°\¤E¦`0JÅ)Ò’8®ÃÂÌÕŠ¹YõëHçÁÊ.nÔ$I…í„tz_\¿Ëå‹gð½€V«C¿¿gÄc8Ž@GÓév¹sáV¤Ù`ÄVk@® ËÓõ:×n-siÚãâ„ *Ò2žš-º=*GŠ"¬e[ ›(­h4a ÎFØŽ½ÿ™>J+„H1âÔ¹*–ÕcâÔR°ŸçYi…e ˜XlÍbfÑþ{ÐÙì)ûjdYÆæÖÖZ·ÆN{D’åä¹.®h!Òã‹ë7¹°±pÑGÊЈÇp±Ž&Í2â$# Fý˜ÁHzý8ÃF¢ cÅÚÒ*Ó>ÖÁ¬kK9y„@B©ý²ïýè3¤¨C‹¿LMT³³3¸–—Šn·E{å6»÷¾Ä B’~hò43ÿÇ L¾Íòq]ÎÌO£ô*«ÛÛTëMr­†Ä½çæOS©–ñ"c»»fÄc8fùL4øÁ—·W°½*£a÷‘tlIµäbK3 DÍÓÅ8” u‘bÖHçÀs]Ι½Êƒ ¼ LÜ?Ne?3¦‹ÆæüäE#ÃñËgr¢Î•ò‹/¯211Ëìì,®-¨Fî8¡ãF2'@> ggÈÕW68¿pŽJµ<–N1Ø, Ý’áø.X¾¡IDAT¦¦jüZy‘,k`I‡rIbI3qþ¤á¸só9"¼M5ú„Àµ÷s€?þ:#ñ2LÜÙ¾IœŽhDSŒ’‡¸–C%º` ç§»,íüK6{?áT훔Þ™Ž×ˆÇp¬èý <–´Xo/3LúLU¦‹%}Í媇%}êÑ·pí:ž[}np#ñ¸!W¦¿Ò)iÞDZJac=#U‚átµ¬2è»xv’7÷Ü×™N¶áX)f®J”2ˆo¡ÔÐHçDG¸ ­Ó—fÅ4â1¼6!„0Ò1ñ^ÇYP§ “öz_ÐÝ1kjŒx ÇÒ9½Ñ=înÿ¶»?1ƒÊ3¸l8~®t,Ný§*¿0ç;ñ˜"0WK3êì,“Ξ™l0áØ¥£híu¸·´‰L²´ÞAk˜9]Ìå‡ôz=<Ï+²z.¶mã{>ý~Ÿ~¿‚É©I´ÒÄIŒ@°ÛÚ%ð‹lŽãŒ3j­Çs„Fãш0 q=)$I’ÐÚkQ KDQdá¤JçþÒ:a¥‰ãx —«» ajj‚ÍÍM®^½Êää$÷ïßÇ÷}|ßÇó_¦ÑhP¯M¢µæ£aks‹À/!°)W"Î[ 0ÉÜx 'O:­½w¬â„Mº#Eªb¶ZCâ,G"˜ª×¸ùp“³3ŠÓg| ¦qÊFc+B\󊧕Ù&j¤ ‹+d:aZ{ }Ð=´î"lÐ æÎ æÎ5PJ#¥F£Ô=z ¼b¦A!q¬ ¡7cÆx o3÷èäJ‘åŠ$É(—\ìQJ¦Š¥dÒ4§ÝË©5Ž%±/š\k´z†T‘žÍãYJ÷§ Šç¥(äsð\ñX Ͻ‡èY¤y‡þè!žÝÀ¶Bspx o§tµj…ųšwWˆ‚:®’gŠ’g3ŠSºm¦'›LOŸÆ‚TuYÞ{Àd42•rª2ƒg;oüû$Y ¥sL.f#û ŸZ•KçáÚí%Ò¬ŽëyÄqB·³ÃôD©SS8–"ô%›Ý.ý¸M’ ÙéoâÛ!õ°†gWß–¤9¨F<†wE>õZ•+4_ÜX¦? È“ÁX:ž-¨E.RJ¦«³œªÌ ).‡K!q,Çâ ÅŒ”^ƒ|j|táN÷§j!S§Náí§>•ûYmiãX®åâÙž‘މx †¯JS’QŸz¥Ì>9Ïțۢڇ®XŒx †#B«œîÎ;÷®byZåHkéºx³ç k¦LWË`8†3›çãE5´R¸A„V)ä)Â2yyÞ`!,¤xsÍßD<†ã«ÞÒ¢TŸ¢TŸBç)jØFU„¿ykd"ÃÉîvÅ=²Í›èQÏÆÛñ“t!ÄK¥f"Ãkªë¢8Ï 3 ü¦ÈUÎ é¡uNè_²<Å>¢4ËSºqÏ©„’å)BÈgæØ6â1^*î!½7{7|œ¸³}“ö`Ð-ÑíQõ|sþ»¿´|4šÎ¨ÍgË?Ãs|¤°é wYœ¼ÌùÉ‹F<à øä›×r,—Ó•9N•g¥CêaƒÐŽdÕ pB.L]Æ6½¤K³Ô¤Qš0]-ƒá‰ÇñÞñ8œªœ&Ë ã”rxîH¸!sîY²¼Gi4¢RZ|îkx †÷ˆ$MðÝÒø÷,ÏdzÇùÄžÒÚˆÇ`x-ÑÍ~ãWð4¥R‰~¿?nüë´Ûm\×%Ë2šM,i±¼¼Œã8ôz=\×¥V«099ùKgL,¤syõ€Û²Æò‡,--àº.I’ e‘.v4Q1;;ûLY=’Nïÿ0áßýY)ÄX>n‡÷àÁpœÒ9x<D!Þ’•}zOÉç¨ùwæŽß_ A¦rú½>7oÞ¤R©ñ ¯f‰O7­SFi ßi"¥ý”tËGó6äxî=ã÷èHß{vN±²,—›´èüè×Dà›ˆÇ`x)Z+ât½?Ķ_ž'Í{luÿˆ “ÿås¥sX>¼Qùô^ð|t$ï}z6geÙzæûÿþïÿ>¿ýÛ¿ ˜1ƒáºO[–q¬ ®]{l›÷(yçür!)¢çʧØvR‰ö#ž³ >þæ÷ȕ’҈Ç`x9Ç*S.<%ÐÔKŸ „…Öšr¹L¯÷´|4QÑïõÞ9<[ Gñþk+½g¾÷ÕÛ+„åi¦±\ñ ¯ÖÝB£2Ç?ÑâQ×¢Ûí Š|4•J…v» @«y‚þö ­¥[¤£NP&´ñ«“L_ù.®ù7(îF/äóƒ_Íùó?µÆbXÝú6•Ñzx‹îÖ Z+,Û!KF”š§™¾üíñ8Ö“äyŽcÛOÈí‘tê:•ÐÁw-ÓÕ2ŽERZã8YV4<Û¶ÙÙm·WK.R j§ÏR95_,"vp)Z¤<Ž”!¥ÕX>þ§½§¤Sl„p˜¼ð1ç¯PÜC®@HŠ@ž?ßDz,Ò,;$ž’NàÙ‡bHƒÁpä$Iƒ‡÷øñÌpc[šÚ8ó¢HËFÚNñÓ²I:‡å£‹F—ÎþT!‘–ƒ´¬â§´^i’¡eYã‡þ5§¤c"ƒá¸š¸ÌÏMóÿÑß§?ÚÁ„¾@¾§z¥5Jiú£¼—:$¯å)’AÿéQßzJ:&â1ŽLelvÖ¹ºv½Å0KiÅIÕè­ÙG)åЦRr~iéäIL{õÞSÏ·nÿŒ,~ú{›ˆÇ`8òˆB1Hû´‡mzq—ΰƒçxÔ‚:ž}2×l—–MPúNt¿Ò@:ŽÁpÜ8–Ã\í 3ÕY2K:¸¶wb¿³´Ê3O=ß<{éÙ¯7ÕÄ`8ZÛr"'I€îàÙ>“}шÇðš[£@Ø.È÷)ÈÖ(£unŽ¿áµ7¿tDºò£Oÿñ?B+õÅ>¥3S Œx ¯¿–Yè<%[úSTñž¬ *„@‰xžÄ .Ž¿Zöé±þÒßÃ[ø¼Wcf\ÇD<†7B–e¬wŸÇ³ÜߟsÏ“ÁD<ÃJgsk‡Õ6SóìuÚܺ󀋋gQJÓív‘–Ķmò,'Ë2”RÄqL·ÛŶm¦¦¦È²Œ••”RÔj5êõ:I’Ç1µzqÇø ?`mmz½N§Ó! C\×%Š"Z­Öø&Ís çÐJÓë÷ƒååe|ß§Ùlâ8Å„:­5ý~Ÿö^›éÙÚ‘L²3ñ^›t¶YÙìИœFkðKv»{ܺó€³ó3t:z½ëëëlmmá>““ÄIÂúÚÒ’4ê †Ã!q“eÅ@íp4b¢ÙäüùóÄqÌÎεZ{÷îÑívY[[߬éº.IšÐïõQJñóŸÿœ hÔLNNÒéthíµB†!RJvwwi4›œ=s¶ø2ÚO#ž#FótvüweôàYé8ߦHçÁÚ^©Á Îh÷F¤™¦?¤YJž/3=Õd8ˆ™›;Ë™³ XÒ¢T*á8ý @“eRÊ}‘ب\1Šc\×¥R.E%Î[`4J¨UxžÇââ%Ò4C«â~$زXÉ4IlÛ²lÊå2v›4ËÃÛ²èt{,œÓ”¢ˆjµ²OghÚ‰ÏQ7^,v»?c?<ò›&'ÏúXVé±¼-GóÞŠ<ñœÚ[U¦J+Z{mî/oRmαÕàÙÃ8G A๸ËòöƒìgÏ>J'ªµFkM¢Á­ ÐOôþ±ÒûwW<+ͨ_Œ !À 4ˆÜ€§ºHúÐû¡5C nuÿý´&×M£”¦5ÔdÙTÃËÆF@¶¸òAùÄÙ^ëânm¥ÕxÝ¥ÃCi…oO¤4Žx°´J¹6I<²¹µËÙ…sd3Uûi-Š:Âø±¶'Ч§ÐJ¡F ­Õþöƒú¢Q9 Msvw·¨Ö›¨Ñ•rÄÄÄĉ’ÎáÆ[$†ãç¿æÉm¯²ýeÂ9ü9¯*“—½îßüíÏøÃßý€,Û•i¤ý´dífsr, ö塵G6‡+z_PÏ–yT¹„³¿(<ûâé´Û4šŒF#ýmÚý”Jx²§ËçyÎÒò*[»CfΜc¯Õâ‹«·øøÃ‹Hiío_bg{‡~¿çyäyŽïûH)©V«Üð€J¹L£Ñ`4Ñív ‚¥3§g˜œœ|#ÆJÔM†Ã!I–ÑlLŽODúP)êA‘7¨(“ý:vð¥ÇòQZë_–¥ã¼<õÆ{;9»„r5ÇsN~7íÉþ¤\^¶ý¥cn‡^søýžG”ö+ÉImÃoý«EþàwïðoÿóÏùÑï}B’Å,-/Óëvq™eY®Ðò\£´ $WE2$}è,–T@åŠ<Ïɲ¼ø]éC‘PQ™r•£”"W ­r2¥Éµ8ÑÉ÷óÄ¿øë 䉓ÎÒò›»CªÍ)î­ ƳL!¥Mji>ûâ_¹È… ÙÚÞfvfË–Ôëuò<çÂ…K¸®ËúÆ:Y–Ѩ]ÓÍÍM¦¦¦ˆ¢"‰ùë$Nwè o"ó3hi¦ÈrM𦬬®±ºô×(•"Tž”"¶·6©Õx¾G<ŠÅ1½^Çqh4§HÓ„õõUòLQ®T¨Ô$ñˆáp„ãzãîú~Í9ñλÒ-|‡¥sX>ð»wøéß½Å÷þáEæçÏ»Ûí¢4ܺyƒ½½]”Rœž™c8Ñëu¨”kÄɈ$N–…Ðøa‰³gÏ3Žè9=>ÿôçh£ÁiYLNN±øÁGaé°Z±–þ õÙ?§/@õþ ÞÉ”@R fúYÐjîåg™[¼ÂÎ^Ÿv/Áu$½aŠëXÔO•YÛX¥÷éÿ΢K8a!´@¡édûƒ™B§§"q…`°Ÿ‰¯:m1P_Òï¾î3¦¦?zÈòÞÿ‰£ÑÉLYÍ’åEªP•+vvwQDdAÈü™³Ò²¨5š( KS¤°Hó ÇvÈ•&KS,ÇÆ±‹U!ÞŽê*ÑqÊðEãGy?õÜaéŒõäž#M-ü ¤TØ®¢Qøa‰ ,+Ú£BET©¯zdÔ˵F+°l­5sçÎóx'\+Eš<¾cÚö‘g¿KXúÕw2|ViÌÎû¤£þxÀ]X¥ú$Ó—¿‹ëx,.œáæ­{ìö÷¨Ö'ÈóœJ(éõ{ û->¸¸ˆï{Ha³Ý[áÆú—ÔKMò<#Îb¾sæW(yoWšÔ(X hwº(u‡ýÁ€8ŽaA¶w)mj³ç©ÍžáëÇæƒ è[w¹»tŸÀµ“N)(º˜å)&ÊSïNħq<"étÉ’n—N·7®/‡§a|­º$yVÔø~HÇ'füãUúW½|þU%ö¬ùBGÑíúõÿéþèÇŸ…ó,é”Ü»·»v̦UÔ+>£Î 8ujŠü=Y:Ûql®\Z¤TZE:ž÷¸tÞEßcnºÁÚÖé0%ô$ÝÕ#?;»2E£Î&eß#,…'J>Ïkôϒ˳¤ò²íÏ+Wx|ÒàWº^9ýèÄß,±º´Âì¾õ”t°ø+ß{-¬tÑõRJcÉ÷gÕÛ¶X8;Oœs]Jþ»}w¶ïû\¹|‰‹5A½ªƒ }´•f\_Š¡ŸG3»ßu^µ¡¿ìu_WÄ/û»V7{i·ëyäºÿgêϨN\¦äן’€Ý¬¸ŽY¼€ïž¬·¶%h”?rÓœø1æ·Žzù럳|È`´Z7¹c7Ÿ]L1ÞviŸ¾Núˆw."v'Y˜úz£ûTßû:³ ŸÁ`8†8õÅÝ9ñ ÇÌþi‰JpÑ„‰x ƒÁ`0â1 #ƒÁ`Äc0 F<ƒÁˆÇ`0Œx ƒÁ`0â1 #ƒÁ`Äc0 F<ƒÁˆÇ`0Œx ƒÁ`0ñ †cDk4/^Jæÿ¿7B4µÄIEND®B`‚rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/reftrans.html0000644000177700017770000000620612633765070030727 0ustar michaelmichael Webmachine's approach to resource functions and referential transparency

    webmachine

    Webmachine's approach to resource functions and referential transparency

    Webmachine goes to great lengths to help your resource functions to be as referentially transparent as possible. By "referentially transparent" we mean that given the same input {ReqData, Context} the function will return the same output {Result, ReqData, Context} and that side effects will be insignificant from the point of view of Webmachine's execution.

    We don't try to force you into pure referential transparency; we give you as big a hole as you want via Context. As that term is application-specific, you can put database handles, server process identifiers, or anything else you like in there and we won't try to stop you.

    However, all Webmachine really cares about is the rest of the terms. Since resource functions are generally referentially transparent at least with regard to those terms, many things are easier -- testing, debugging, and even static analysis and reasoning about your Web application.

    Note that there is one important exception to this. The streamed body feature exists to allow resources to consume or produce request/response bodies a hunk at a time without ever having the whole thing in memory. While the continuation-passing style used in the streaming API is friendly to general functional analysis, due to the necessary side-effect of reading or writing to sockets the stream bodies cannot be treated in quite the same way as other uses of the ReqData interface. Luckily, it is easy to inspect a ReqData to see if this is the case in any individual resource or request instance.

    rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/example_resources.html0000644000177700017770000001617112633765070032632 0ustar michaelmichael Webmachine examples

    webmachine

    Webmachine examples

    The simplest possible example is the one produced via the quickstart.

    For an example of a read/write filesystem server showing several interesting features and supporting GET, PUT, DELETE, and POST, see demo_fs_resource.

    For a very simple resource demonstrating content negotiation, basic auth, and some caching headers, see webmachine_demo_resource.

    Some example code based on webmachine_demo_resource follows.

    The simplest working resource could export only one function in addition to init/1:

    -module(webmachine_demo_resource).
    -export([init/1, to_html/2]).
    -include_lib("webmachine/include/webmachine.hrl").
    
    init([]) -> {ok, undefined}.
    
    to_html(ReqData, Context) -> {"Hello, new world", ReqData, Context}.
    

    That's really it -- a working webmachine resource. That resource will respond to all valid GET requests with the exact same response.

    Many interesting bits of HTTP are handled automatically by Webmachine. For instance, if a client sends a request to that trivial resource with an Accept header that does not allow for a text/html response, they will receive a 406 Not Acceptable.

    Suppose I wanted to serve a plaintext client as well. I could note that I provide more than just HTML:

    content_types_provided(ReqData, Context) ->
       {[{"text/html", to_html},{"text/plain",to_text}], ReqData, Context}.
    

    I already have my HTML representation produced, so I add a text one: (and while I'm at it, I'll show that it's trivial to produce dynamic content as well)

    to_text(ReqData, Context) ->
        Path = wrq:disp_path(ReqData),
        Body = io_lib:format("Hello ~s from webmachine.~n", [Path]),
        {Body, ReqData, Context}.
    

    Now that this resource provides multiple media types, it automatically performs conneg:

    $ telnet localhost 8000
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    GET /demo/a/resource/path HTTP/1.1
    Accept: text/plain
    
    HTTP/1.1 200 OK
    Vary: Accept
    Server: MochiWeb/1.1 WebMachine/0.97
    Date: Sun, 15 Mar 2009 02:54:02 GMT
    Content-Type: text/plain
    Content-Length: 39
    
    Hello a/resource/path from webmachine.
    

    What about authorization? Webmachine resources default to assuming the client is authorized, but that can easily be overridden. Here's an overly simplistic but illustrative example:

    is_authorized(ReqData, Context) ->
        case wrq:disp_path(ReqData) of
            "authdemo" -> 
                case wrq:get_req_header("authorization", ReqData) of
                    "Basic "++Base64 ->
                        Str = base64:mime_decode_to_string(Base64),
                        case string:tokens(Str, ":") of
                            ["authdemo", "demo1"] ->
                                {true, ReqData, Context};
                            _ ->
                                {"Basic realm=webmachine", ReqData, Context}
                        end;
                    _ ->
                        {"Basic realm=webmachine", ReqData, Context}
                end;
            _ -> {true, ReqData, Context}
        end.
    

    With that function in the resource, all paths except /authdemo from this resource's root are authorized. For that one path, the UA will be asked to do basic authorization with the user/pass of authdemo/demo1. It should go without saying that this isn't quite the same function that we use in our real apps, but it is nice and simple.

    If you've generated the application from the quickstart, make sure you've added this line to your dispatch.conf file:

    {["demo", '*'], mywebdemo_resource, []}.
    

    Now you can point your browser at http://localhost:8000/demo/authdemo with the demo app running:

    $ curl -v http://localhost:8000/demo/authdemo
    > GET /demo/authdemo HTTP/1.1
    > Host: localhost:8000
    > Accept: */*
    > 
    < HTTP/1.1 401 Unauthorized
    < WWW-Authenticate: Basic realm=webmachine
    < Server: MochiWeb/1.1 WebMachine/0.97
    < Date: Sun, 15 Mar 2009 02:57:43 GMT
    < Content-Length: 0
    
    < 
    

    $ curl -v -u authdemo:demo1 http://localhost:8000/demo/authdemo 
    * Server auth using Basic with user 'authdemo'
    > GET /demo/authdemo HTTP/1.1
    > Authorization: Basic YXV0aGRlbW86ZGVtbzE=
    > Host: localhost:8000
    > Accept: */*
    > 
    < HTTP/1.1 200 OK
    < Vary: Accept
    < Server: MochiWeb/1.1 WebMachine/0.97
    
    < Date: Sun, 15 Mar 2009 02:59:02 GMT
    < Content-Type: text/html
    < Content-Length: 59
    < 
    <html><body>Hello authdemo from webmachine.
    </body></html>
    

    HTTP caching support is also quite easy, with functions allowing resources to define (e.g.) last_modified, expires, and generate_etag. For instance, since representations of this resource vary only by URI Path, I could use an extremely simple entity tag unfit for most real applications but sufficient for this example:

    generate_etag(ReqData, Context) -> {wrq:raw_path(ReqData), ReqData, Context}.
    

    Similarly, here's a trivial expires rule:

    expires(ReqData, Context) -> {{{2021,1,1},{0,0,0}}, ReqData, Context}.
    

    And now the response from our earlier request is appropriately tagged:

    HTTP/1.1 200 OK
    Vary: Accept
    Server: MochiWeb/1.1 WebMachine/0.97
    Expires: Fri, 01 Jan 2021 00:00:00 GMT
    ETag: /demo/authdemo
    Date: Sun, 15 Mar 2009 02:59:02 GMT
    Content-Type: text/html
    Content-Length: 59
    
    <html><body>Hello authdemo from webmachine.
    </body></html>
    

    For more details, read the source of the resources linked at the top of this page.

    rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/blogs.html0000644000177700017770000000464212633765070030213 0ustar michaelmichael other writing about Webmachine

    webmachine

    What else can I read?

    In addition to the documentation on this site and the source code on bitbucket, some useful Webmachine writing can be found on blogs and elsewhere. A small sampling of these is here:

    The restful way blog is almost entirely dedicated to Webmachine.

    The BeerRiot blog contains multiple topics, including a wealth of examples and discussion of Webmachine.

    The blog of Andy Gross has some useful hints and tutorials.

    Paul Mineiro posted about dynamically loading webmachine resources.

    Kevin Smith teaches an excellent Erlang training class which often culminates with development of applications in Webmachine.

    There is a fairly low traffic mailing list for technical discussion of Webmachine.

    rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/diagram.html0000644000177700017770000000352212633765070030505 0ustar michaelmichael Webmachine decision flow

    webmachine

    Webmachine decision flow

    This diagram is illustrative of the flow of processing that a webmachine resource goes through from inception to response.

    Version 1 of this diagram, from Alan Dean, was the inspiration for webmachine_decision_core. Versions 2 and 3 were created in collaboration between Alan Dean and Justin Sheehy.

    A copy of v3 is found in the webmachine source tree for convenience.

    http diagram v3

    rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/quickstart.html0000644000177700017770000000453612633765070031301 0ustar michaelmichael getting started quickly with Webmachine

    webmachine

    getting started quickly with Webmachine

    Make sure that you have a working Erlang/OTP release, R12B5 or later.

    Get the webmachine code:

    hg clone http://bitbucket.org/justin/webmachine/ webmachine-read-only
    

    Build webmachine:

    cd webmachine-read-only
    make
    

    Create, build, and start the skeleton resource:

    ./scripts/new_webmachine.sh mywebdemo /tmp
    cd /tmp/mywebdemo
    make
    ./start.sh
    

    Take a look! Point a web browser at http://localhost:8000/

    To make this resource handle URI paths other than /, add more dispatch terms in /tmp/mywebdemo/priv/dispatch.conf; to make that resource to more interesting things, modify the resource itself at /tmp/mywebdemo/src/mywebdemo_resource.erl.

    To learn how to do more interesting things, check out some examples or read more documentation.

    rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/favicon.ico0000644000177700017770000000217612633765070030340 0ustar michaelmichael h(  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~|{ÿtrqÿvtsÿ…„ƒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿgedÿœ›šÿÑÐÐÿååäÿàààÿÃÂÂÿƒ€€ÿljiÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿjhgÿÜÛÛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ³±±ÿjhgÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿkhgÿèèèÿüüüÿÿÿÿÿúúúÿÕÔÔÿ•“’ÿÿðððÿÿÿÿÿ²±±ÿqnmÿÿÿÿÿÿÿÿÿÿ‹‹ÿ¶µµÿäääÿº¹¸ÿÿÿÿÿàààÿŒ‹ÿwutÿ][Zÿ³²²ÿþþþÿæææÿ|{zÿÿÿÿÿÿÿÿÿÿkhgÿïïîÿ”“’ÿ®¬¬ÿÿÿÿÿÿÿÿÿÿÿÿÿýýýÿííìÿååäÿååäÿ}|ÿ«©¨ÿ–””ÿÿÿÿÿÿÿa_^ÿ—–•ÿ`^]ÿ²°¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúúúÿ¹¸·ÿžœÿ‰‡†ÿÿÿÿÿÿÿ`^\ÿ^\[ÿ[YXÿ¢  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÃÃÂÿ‚€ÿÿÿÿÿÿÿgedÿdbaÿ_]\ÿ…ƒƒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½¼¼ÿŽÿÿÿÿÿÿÿŽÿ][Zÿecbÿa^]ÿÇÆÆÿÿÿÿÿÿÿÿÿ½¼¼ÿ“‘‘ÿëëëÿÿÿÿÿÿÿÿÿ€~}ÿÿÿÿÿÿÿÿÿÿÿÿÿb]Zÿdbaÿb`_ÿljiÿœ›šÿ‰‡†ÿ][ZÿXUTÿÛÛÚÿÿÿÿÿ¹¸·ÿmjiÿÿÿÿÿÿÿ‘Šÿˆ¢·ÿ˜¡ÿ_YUÿdbaÿca`ÿ][Zÿ_]\ÿdbaÿa_^ÿÊÉÉÿº¸¸ÿca`ÿÿÿÿÿÿÿ˜––ÿXOHÿ)ÂÿwÉÿÿ£¥§ÿb_]ÿ[YXÿb`_ÿcaaÿca`ÿ`^]ÿ][Zÿhedÿÿÿÿÿÿÿÿÿÿ—–•ÿ^XSÿZ}™ÿv²Üÿ™°Äÿÿÿÿÿÿÿqnmÿgecÿhfeÿ|yxÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ—–•ÿTRQÿd^Zÿ\XUÿxusÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŒŠŠÿyvuÿtqpÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþøðàÀÀÀÀÀÀà€ÿÿrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/mechanics.html0000644000177700017770000001072012633765070031031 0ustar michaelmichael Webmachine mechanics

    webmachine

    How does this Webmachine thing work, anyway?

    This page describes the basic mechanics of Webmachine from the point of view of a single incoming HTTP Request, documenting the behavior of Webmachine through to the HTTP Response.

    (This is a bit different from what you might get with a "Web Framework" as we're not going to talk about MVC, ORMs, or anything else about the rest of the shape of your application. We believe that you know better than we do how to structure your own app -- Webmachine's job is to help you make sure that your app's presence on the Web is well-behaved and well-structured.)

    When a request is initially received by Webmachine it is handled by the dispatcher. If the dispatcher does not find a matching resource then it will immediately respond with a 404 Not Found. If a match is found then a request data record is created and the matching resource is kicked off via its init/1 function.

    The resource then flows through the decision core, which is effectively just running the request through the HTTP flowchart. At each decision point (diamond) in the diagram, Webmachine will determine which path to follow. In some cases it can determine the path purely from the request data -- for instance, the path from decision C3 depends purely on whether the client sent an Accept header. In many cases, however, the decision is application-specific -- the path from B10 depends on the value the resource module returns from allowed_methods. Eventually the chosen path will terminate at one of the rectangles on the diagram. At that point Webmachine will send an appropriate HTTP response, with the headers and body dependent on the path through the diagram and the values returned by the resource's functions.

    Most of the time you don't need to worry about this big diagram, though -- just define the resource functions relevant to your app and Webmachine will do the rest. A good understanding of this central mechanism in Webmachine is most useful when debugging your resources.

    From the way that webmachine's decision core works, it follows that Webmachine's HTTP behavior is transactional. Each HTTP Request is fully received, and the resulting HTTP Response is then fully constructed before being returned. This means that while Webmachine is suitable for a great many Web applications it is not a good fit for an application that will gradually or continuously stream responses back to clients inside the context of a single HTTP Request.

    A useful way to build Webmachine applications is often just to write a single function such as to_html to provide the most basic of stubs; when that function exists (or any other returned by content_types_provided) you can produce 200 OK responses. After that, you can easily extend your application's Web behavior simply by filling in the other resource functions as desired.

    rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/docs.html0000644000177700017770000000436012633765070030032 0ustar michaelmichael Webmachine documentation rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/contact.html0000644000177700017770000000316412633765070030536 0ustar michaelmichael Webmachine contact information

    webmachine

    Webmachine contact information

    Have questions about Webmachine that aren't answered here? We'd love to hear from you.

    Subscribers to the Webmachine mailing list include both users and the core development team.

    rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/resources.html0000644000177700017770000003627612633765070031127 0ustar michaelmichael Webmachine resource functions

    webmachine

    Webmachine resource functions

    All webmachine resources should include the webmachine resource library:

    -include_lib("webmachine/include/webmachine.hrl").

    All webmachine resources should define and export init/1, which will receive a configuration property list from the dispatcher as its argument. This function should, if successful, return {ok, Context}. Context is any term, and will be threaded through all of the other webmachine resource functions. Alternately, the resource can go into debugging mode by returning {{trace, Dir}, Context} instead -- see the tracing documentation for more information.

    All webmachine resource functions are of the signature:

    f(ReqData, Context) -> {Result, ReqData, Context}

    Context is an arbitrary term() that is specific to your application. Webmachine will never do anything with this term other than threading it through the various functions of your resource. This is the means by which transient application-specific request state is passed along between functions.

    ReqData is a #wm_reqdata{} term, and is manipulated via the wrq interface. A resource function may access request data (such as header values) from the input value. If a resource function wishes to affect the response data in some way other than that implied by its return value (e.g. adding an X-Header) then it should modify the returned ReqData term accordingly.

    The rest of this document is about the effects produced by different values in the Result term.

    There are over 30 resource functions you can define, but any of them can be omitted as they have reasonable defaults.

    Each function is described below, showing the default and allowed values that may be in the Result term. The default will be used if a resource does not export the function. If a function has an "X" in the "Halt" column, it also has the option of returning either of the two following special values for Result:

    ResultEffect
    {error, Err::term()}Immediately end processing of this request, returning a 500 response code. The response body will contain the Err term.
    {halt, Code::integer()}Immediately end processing of this request, returning response code Code. It is the responsibility of the resource to ensure that all necessary response header and body elements are filled in ReqData in order to make that reponse code valid.
    {halt, {Code::integer(), ReasonPhrase::iolist()}}Same as {halt, Code::integer()} but supply a custom reason phrase for the HTTP status code as well.

    Any function which has no description is optional and the effect of its return value should be evident from examining the diagram.

    FunctionDefaultHaltAllowedDescription
    resource_existstrueXtrue | falseReturning non-true values will result in 404 Not Found.
    service_availabletrueXtrue | false
    is_authorizedtrueXtrue | AuthHeadIf this returns anything other than true, the response will be 401 Unauthorized. The AuthHead return value will be used as the value in the WWW-Authenticate header.
    forbiddenfalseXtrue | false
    allow_missing_postfalseXtrue | falseIf the resource accepts POST requests to nonexistent resources, then this should return true.
    malformed_requestfalseXtrue | false
    uri_too_longfalseXtrue | false
    known_content_typetrueXtrue | false
    valid_content_headerstrueXtrue | false
    valid_entity_lengthtrueXtrue | false
    options[][Header]If the OPTIONS method is supported and is used, the return value of this function is expected to be a list of pairs representing header names and values that should appear in the response.
    allowed_methods['GET', 'HEAD'][Method]If a Method not in this list is requested, then a 405 Method Not Allowed will be sent. Note that these are all-caps and are atoms. (single-quoted)
    delete_resourcefalseXtrue | falseThis is called when a DELETE request should be enacted, and should return true if the deletion succeeded.
    delete_completedtrueXtrue | falseThis is only called after a successful delete_resource call, and should return false if the deletion was accepted but cannot yet be guaranteed to have finished.
    post_is_createfalsetrue | falseIf POST requests should be treated as a request to put content into a (potentially new) resource as opposed to being a generic submission for processing, then this function should return true. If it does return true, then create_path will be called and the rest of the request will be treated much like a PUT to the Path entry returned by that call.
    create_pathundefinedPathThis will be called on a POST request if post_is_create returns true. It is an error for this function to not produce a Path if post_is_create returns true. The Path returned should be a valid URI part following the dispatcher prefix. That Path will replace the previous one in the return value of wrq:disp_path(ReqData) for all subsequent resource function calls in the course of this request.
    process_postfalseXtrue | falseIf post_is_create returns false, then this will be called to process any POST requests. If it succeeds, it should return true.
    content_types_provided [{"text/html", to_html}] [{Mediatype, Handler}] This should return a list of pairs where each pair is of the form {Mediatype, Handler} where Mediatype is a string of content-type format and the Handler is an atom naming the function which can provide a resource representation in that media type. Content negotiation is driven by this return value. For example, if a client request includes an Accept header with a value that does not appear as a first element in any of the return tuples, then a 406 Not Acceptable will be sent.
    content_types_accepted [] [{Mediatype, Handler}] This is used similarly to content_types_provided, except that it is for incoming resource representations -- for example, PUT requests. Handler functions usually want to use wrq:req_body(ReqData) to access the incoming request body.
    charsets_providedno_charsetno_charset | [{Charset, CharsetConverter}] If this is anything other than the atom no_charset, it must be a list of pairs where each pair is of the form Charset, Converter where Charset is a string naming a charset and Converter is a callable function in the resource which will be called on the produced body in a GET and ensure that it is in Charset.
    encodings_provided [{"identity", fun(X) -> X end}] [{Encoding, Encoder}] This must be a list of pairs where in each pair Encoding is a string naming a valid content encoding and Encoder is a callable function in the resource which will be called on the produced body in a GET and ensure that it is so encoded. One useful setting is to have the function check on method, and on GET requests return [{"identity", fun(X) -> X end}, {"gzip", fun(X) -> zlib:gzip(X) end}] as this is all that is needed to support gzip content encoding.
    variances [] [HeaderName] If this function is implemented, it should return a list of strings with header names that should be included in a given response's Vary header. The standard conneg headers (Accept, Accept-Encoding, Accept-Charset, Accept-Language) do not need to be specified here as Webmachine will add the correct elements of those automatically depending on resource behavior.
    is_conflictfalsetrue | falseIf this returns true, the client will receive a 409 Conflict.
    multiple_choicesfalseXtrue | falseIf this returns true, then it is assumed that multiple representations of the response are possible and a single one cannot be automatically chosen, so a 300 Multiple Choices will be sent instead of a 200.
    previously_existedfalseXtrue | false
    moved_permanentlyfalseX {true, MovedURI} | false
    moved_temporarilyfalseX {true, MovedURI} | false
    last_modifiedundefinedundefined | {{YYYY,MM,DD}, {Hour,Min,Sec}}
    expiresundefinedundefined | {{YYYY,MM,DD}, {Hour,Min,Sec}}
    generate_etagundefinedundefined | ETagIf this returns a value, it will be used as the value of the ETag header and for comparison in conditional requests.
    finish_requesttruetrue | falseThis function, if exported, is called just before the final response is constructed and sent. The Result is ignored, so any effect of this function must be by returning a modified ReqData .
    body-producing function named as a Handler by content_types_providedX Body The Body should be either an iolist() or {stream,streambody()}
    POST-processing function named as a Handler by content_types_acceptedX true

    The above are all of the supported predefined resource functions. In addition to whichever of these a resource wishes to use, it also must export all of the functions named in the return values of the content_types_provided and content_types_accepted functions with behavior as described in the bottom two rows of the table.

    rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/intros.html0000644000177700017770000000536612633765070030427 0ustar michaelmichael introductions to Webmachine

    webmachine

    How do I get started?

    If you want to jump in and start coding right away, the quickstart is the way to go.

    If you would prefer to watch a narrated slideshow introduction, this is roughly similar to the presentation that was given at Bay Area Erlang Factory 2009:

    Some blogs also have posts that can serve as useful introductions to Webmachine, if you prefer to start that way.

    No matter how you get started, you'll probably want to come back and read more documentation once you get up and running.

    rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/streambody.html0000644000177700017770000001231612633765070031253 0ustar michaelmichael Webmachine streamed bodies

    webmachine

    Webmachine streamed bodies

    Webmachine allows the resource developer to handle request and response bodies as either whole units (binary or iolist) to be handed around at once, or else to choose to "stream" the body.

    The body-handling functions are:

    • wrq:req_body/1
    • wrq:stream_req_body/2
    • wrq:set_resp_body/2

    The last of these, wrq:set_resp_body/2, is also called implicitly with the return value of any content-producing function such as to_html/2.

    The first of these (req_body) is the simplest. It will provide the whole incoming request body as a binary. (Unless the body is too large, as set by wrq:set_max_recv_body/2 or defaulting to 50M) For the majority of resources, this is the easiest way to handle the incoming request body.

    If a resource wants to handle the incoming request body a hunk at a time, it may call wrq:stream_req_body/2 instead. Instead of a binary, this produces a StreamBody structure.

    (It is an error to call both wrq:req_body/1 and wrq:stream_req_body/2 in the execution of a single resource.)

    A StreamBody is a pair of the form {Data,Next} where Data is a binary and Next is either the atom done signifying the end of the body or else a 0-arity function that, when called, will produce the "next" StreamBody structure.

    The integer parameter to wrq:stream_req_body/2 indicates the maximum size in bytes of any Hunk from the resulting StreamBody.

    When a resource provides a body to be sent in the response, it should use wrq:set_resp_body/2. The parameter to this function may be either an iolist, representing the entire body, or else a pair of the form {stream, StreamBody}.

    An example may make the usage of this API clearer. A complete and working resource module using this API in both directions:

    -module(mywebdemo_resource).
    -export([init/1, allowed_methods/2, process_post/2]).
    
    -include_lib("webmachine/include/webmachine.hrl").
    
    init([]) -> {ok, undefined}.
    
    allowed_methods(ReqData, State) -> {['POST'], ReqData, State}.
    
    process_post(ReqData, State) ->
        Body = get_streamed_body(wrq:stream_req_body(ReqData, 3), []),
        {true, wrq:set_resp_body({stream, send_streamed_body(Body,4)},ReqData), State}.
    
    send_streamed_body(Body, Max) ->
        HunkLen=8*Max,
        case Body of        
            <> ->
                io:format("SENT ~p~n",[<>]),
                {<>, fun() -> send_streamed_body(Rest,Max) end};
            _ ->
                io:format("SENT ~p~n",[Body]),
                {Body, done}
        end.
    
    get_streamed_body({Hunk,done},Acc) ->
        io:format("RECEIVED ~p~n",[Hunk]),
        iolist_to_binary(lists:reverse([Hunk|Acc]));
    get_streamed_body({Hunk,Next},Acc) ->
        io:format("RECEIVED ~p~n",[Hunk]),
        get_streamed_body(Next(),[Hunk|Acc]).
    

    If you use this resource in place of the file /tmp/mywebdemo/src/mywebdemo_resource.erl in the quickstart setup, you should then be able to issue curl -d '1234567890' http://127.0.0.1:8000/ on the command line and the io:format calls will show you what is going on.

    Obviously, a realistic resource wouldn't use this API just to collect the whole binary into memory or break one up that is already present -- you'd use req_body and put a simple iolist into set_resp_body instead. Also, the choices of 3 and 4 bytes as hunk size are far from optimal for most reasonable uses. This resource is intended only as a demonstration of the API, not as a real-world use of streaming request/response bodies.

    rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/reqdata.html0000644000177700017770000002100112633765070030512 0ustar michaelmichael Webmachine request/response data

    webmachine

    Webmachine request/response data

    This is documentation of the Webmachine Request Data API as embodied by the "wrq" module. This module is the means by which resources access and manipulate the state of the request they are handling.

    Given that all webmachine resource functions have this signature:

    f(ReqData, Context) -> {Result, ReqData, Context}

    we should explain in detail the ReqData input and output parameter. This is a data structure used to represent the request sent by the client as well as the response being built by the resource. The wrq module is used to access the values in the input parameter. Most functions in most resources have no need to modify the output ReqData and can simply pass along the one received as input. However, in some cases a resource will need to make some update to the response other than that implied by Result and in those cases it should use the wrq module to build a modified ReqData from the original one for the return value.

    A couple of nonstandard types are assumed here:

    TypeDescription
    string()a list() with all elements in the ASCII range
    rd()opaque record, used as the input/output ReqData
    streambody()A webmachine streamed body format
    mochiheaders()a structure used in mochiweb for HTTP header storage

    The accessors are:

    FunctionDescription
    method(rd()) -> 'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'POST' | 'PUT' | 'TRACE' The HTTP method used by the client. (note that it is an atom() )
    version(rd()) -> {integer(),integer()} The HTTP version used by the client. Most often {1,1} .
    peer(rd()) -> string() The IP address of the client.
    disp_path(rd()) -> string() The "local" path of the resource URI; the part after any prefix used in dispatch configuration. Of the three path accessors, this is the one you usually want. This is also the one that will change after create_path is called in your resource.
    path(rd()) -> string() The path part of the URI -- after the host and port, but not including any query string.
    raw_path(rd()) -> string() The entire path part of the URI, including any query string present.
    path_info(atom(),rd()) -> 'undefined' | string() Looks up a binding as described in dispatch configuration.
    path_info(rd()) -> any() The dictionary of bindings as described in dispatch configuration.
    path_tokens(rd()) -> list() This is a list of string() terms, the disp_path components split by "/".
    get_req_header(string(),rd()) -> 'undefined' | string() Look up the value of an incoming request header.
    req_headers(rd()) -> mochiheaders() The incoming HTTP headers. Generally, get_req_header is more useful.
    req_body(rd()) -> 'undefined' | binary() The incoming request body, if any.
    stream_req_body(rd(),integer()) -> streambody() The incoming request body in streamed form, with hunks no bigger than the integer argument.
    get_cookie_value(string(),rd()) -> string() Look up the named value in the incoming request cookie header.
    req_cookie(rd()) -> string() The raw value of the cookie header. Note that get_cookie_value is often more useful.
    get_qs_value(string(),rd()) -> 'undefined' | string() Given the name of a key, look up the corresponding value in the query string.
    get_qs_value(string(),string(),rd()) -> string() Given the name of a key and a default value if not present, look up the corresponding value in the query string.
    req_qs(rd()) -> [{string(), string()}] The parsed query string, if any. Note that get_qs_value is often more useful.
    get_resp_header(string(),rd()) -> string() Look up the current value of an outgoing request header.
    resp_redirect(rd()) -> bool() the last value passed to do_redirect, false otherwise -- if true, then some responses will be 303 instead of 2xx where applicable
    resp_headers(rd()) -> mochiheaders() The outgoing HTTP headers. Generally, get_resp_header is more useful.
    resp_body(rd()) -> 'undefined' | binary() The outgoing response body, if one has been set. Usually, append_to_response_body is the best way to set this.
    app_root(rd()) -> string() Indicates the "height" above the requested URI that this resource is dispatched from. Typical values are "." , ".." , "../.." and so on.

    The functions for (nondestructive) modification of rd() terms are:

    FunctionDescription
    set_resp_header(string(),string(),rd()) -> rd() Given a header name and value, set an outgoing request header to that value.
    append_to_response_body(binary(),rd()) -> rd() Append the given value to the body of the outgoing response.
    do_redirect(bool(),rd()) -> rd() see resp_redirect; this sets that value.
    set_disp_path(string(),rd()) -> rd() The disp_path is the only path that can be changed during a request. This function will do so.
    set_req_body(binary(),rd()) -> rd() Replace the incoming request body with this for the rest of the processing.
    set_resp_body(binary(),rd()) -> rd() Set the outgoing response body to this value.
    set_resp_body(streambody(),rd()) -> rd() Use this streamed body to produce the outgoing response body on demand.
    set_resp_headers([{string(),string()}],rd()) -> rd() Given a list of two-tuples of {headername,value}, set those outgoing response headers.
    remove_resp_header(string(),rd()) -> rd() Remove the named outgoing response header.
    rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/css/0000755000177700017770000000000012633765070027001 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/css/style-1c.css0000644000177700017770000000516712633765070031165 0ustar michaelmichael/* global reset */ *{ margin: 0; padding: 0; }* :focus, :active { outline: 0; } body { font: .9em Georgia, "Times New Roman", Sans-Serif; background: #fff url(../images/bg.gif) repeat-x; color: #333; } a { color: #3333FF; text-decoration: none; } img { border: 0; } h1 { float: left; margin: 20px 0 50px; font-size: 4em; color: #fff; } h2 { font-size: 2.4em; font-weight: normal; margin: 0 0 20px; } h2 a:hover { background: #3333FF; color: #fff; } .hr { color: #ccc; } p { margin: 5px 0 15px; line-height: 1.6em; } #content { margin: 0 auto; width: 900px; } #top { float: right; margin: 38px 0 30px 0;} #top li { list-style: none; display: inline; } #top li a { float: left; padding: 6px 20px; margin: 3px 2px 0 0; color: #3333FF; } #top li a.current { color: #fff; background: #3333FF; } #top li a:hover { background: #808080; color: #fff; } #intro { clear: both; padding: 15px 0 1px 20px; border: 1px solid #dedede; font-size: 1.3em; background: #eee; margin: 0 0 30px; } #left { float: left; width: 830px; margin: 0 0 15px; } #right { float: right; width: 0px; } #right h3 { border-bottom: 1px solid #ccc; margin: 0 0 10px; } #right img { margin: 0 3px 3px 0; border: 2px solid #eee; padding: 2px; } #right li { list-style: none; } #right li a { display: block; border-bottom: 1px solid #ccc; padding: 5px 5px; } #footer { clear: both; padding: 15px 0; border-top: 1px solid #ccc; } #r { float: right; } dt { font-weight:bold; } dd { margin: 0.5em 0 0.5em 1em; } /* table */ .fwf { font: 12px "Courier"; color: #111; } .lhcol { width: 200px; } .x_check { padding-left:3px; font: 12px "Courier"; } table { width: 100%; padding: 0; border-spacing: 0px; border-collapse: collapse; margin: 5px; margin-bottom: 15px; } th { font: bold 12px "Georgia", Verdana, Arial, Helvetica, sans-serif; /* color: #4f6b72; */ border: 1px solid #999; letter-spacing: 2px; text-transform: uppercase; text-align: left; padding: 6px 6px 6px 12px; background: #ddd; } th.nobg { border-top: 0; border-left: 0; border-right: 1px solid #999; background: none; } td { border: 1px solid #999; background: #fff; padding: 6px 6px 6px 12px; vertical-align: top; font: inherit; color: #222; } td.alt { background: #F5FAFA; color: #797268; } th.spec { border-left: 1px solid #999; border-top: 0; background: #fff url(images/bullet1.gif) no-repeat; font: bold 10px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; } th.specalt { border-left: 1px solid #999; border-top: 0; background: #f5fafa url(images/bullet2.gif) no-repeat; font: bold 10px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; color: #797268; } rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/css/style.css0000755000177700017770000000516712633765070030667 0ustar michaelmichael/* global reset */ *{ margin: 0; padding: 0; }* :focus, :active { outline: 0; } body { font: .9em Georgia, "Times New Roman", Sans-Serif; background: #fff url(../images/bg.gif) repeat-x; color: #333; } a { color: #3333FF; text-decoration: none; } img { border: 0; } h1 { float: left; margin: 20px 0 50px; font-size: 4em; color: #fff; } h2 { font-size: 2.4em; font-weight: normal; margin: 0 0 20px; } h2 a:hover { background: #3333FF; color: #fff; } .hr { color: #ccc; } p { margin: 5px 0 15px; line-height: 1.6em; } #content { margin: 0 auto; width: 900px; } #top { float: right; margin: 38px 0 30px 0;} #top li { list-style: none; display: inline; } #top li a { float: left; padding: 6px 20px; margin: 3px 2px 0 0; color: #3333FF; } #top li a.current { color: #fff; background: #3333FF; } #top li a:hover { background: #808080; color: #fff; } #intro { clear: both; padding: 15px 0 1px 20px; border: 1px solid #dedede; font-size: 1.3em; background: #eee; margin: 0 0 30px; } #left { float: left; width: 550px; margin: 0 0 15px; } #right { float: right; width: 280px; } #right h3 { border-bottom: 1px solid #ccc; margin: 0 0 10px; } #right img { margin: 0 3px 3px 0; border: 0 solid #eee; padding: 2px; } #right li { list-style: none; } #right li a { display: block; border-bottom: 1px solid #ccc; padding: 5px 5px; } #footer { clear: both; padding: 15px 0; border-top: 1px solid #ccc; } #r { float: right; } dt { font-weight:bold; } dd { margin: 0.5em 0 0.5em 1em; } /* table */ .fwf { font: 12px "Courier"; color: #111; } .lhcol { width: 200px; } .x_check { padding-left:3px; font: 12px "Courier"; } table { width: 100%; padding: 0; border-spacing: 0px; border-collapse: collapse; margin: 5px; margin-bottom: 15px; } th { font: bold 12px "Georgia", Verdana, Arial, Helvetica, sans-serif; /* color: #4f6b72; */ border: 1px solid #999; letter-spacing: 2px; text-transform: uppercase; text-align: left; padding: 6px 6px 6px 12px; background: #ddd; } th.nobg { border-top: 0; border-left: 0; border-right: 1px solid #999; background: none; } td { border: 1px solid #999; background: #fff; padding: 6px 6px 6px 12px; vertical-align: top; font: inherit; color: #222; } td.alt { background: #F5FAFA; color: #797268; } th.spec { border-left: 1px solid #999; border-top: 0; background: #fff url(images/bullet1.gif) no-repeat; font: bold 10px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; } th.specalt { border-left: 1px solid #999; border-top: 0; background: #f5fafa url(images/bullet2.gif) no-repeat; font: bold 10px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; color: #797268; } rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/debugging.html0000644000177700017770000002234012633765070031033 0ustar michaelmichael Webmachine debugging

    webmachine

    Webmachine debugging

    Having trouble with your webmachine resource? Try debugging it with the webmachine trace utility!

    Basic Use

    To get started, first change your resource's init/1 function to return {trace, Path} instead of ok. For example:

    init(Config) ->
       {{trace, "/tmp"}, Config}.  %% debugging code
       %%{ok, Config}.             %% regular code
    

    Rebuild and reload the module, then in your webmachine application's shell, type:

    wmtrace_resource:add_dispatch_rule("wmtrace", "/tmp").
    

    Now issue the HTTP request that you're trying to debug. Once it has finished, point your browser at http://YOUR_HOST/wmtrace/. You'll see one or more trace files available for inspection. Click on one of them to navigate to the trace inspection utility, which will look something like this:

    Basic Trace

    The example above is a trace of a resource that responded to a GET of the root path (as you can see in the Detail Panel), and ran all the way to a 200 response code (as you can see in the Decision Graph).

    The graph starts small, so you can get a quick view of the path your resource took through it. You can zoom in and out of the Decision Graph by using the Zoom Controls.

    The path your resource took through the graph is highlighted with a dark grey line. Hovering your mouse over the outlined decision points along that line will pop up a tool tip with the name of the decision, and the names of the functions in your resource that were called at that point. Clicking on a decision will flip the Detail Panel to the Decision Tab, where information about that decision will be displayed.

    If your resource traversed the graph all the way to one of the standard, non-error return codes, the box for that return code will be outlined. If your resource instead returned a non-standard or error code, a red circle will be drawn next to the last decision point your resource reached. Clicking on either of these types of endpoints will flip the Detail Panel to the Response Tab, where information about the response will be displayed.

    The Detail Panel has three tabs: Request (labeled Q), Response (labeled R), and Decision (labeled D). Clicking each of these will show information about the request, response, or current decision, respectively.

    Detail Panel Request Tab

    The Request Tab shows details about what the client requested. The method and path are displayed at the top, headers below that, and body (if available) at the bottom.

    Detail Panel Response Tab

    The Response Tab shows details about how your resource responded. The response code is displayed at the top, headers below that, and body (if available) at the bottom.

    Detail Panel Decision Tab

    The Decision Tab shows details about the currently selected decision. The decision's name is displayed in a dropdown at the top (changing this dropdown or clicking on a decision in the graph will change which decision is displayed). The list of the functions called in the resource's module is displayed in a dropdown below the decision. The arguments with which the function was called are displayed just below the function's name, and the return value of the function is displayed at the bottom of the panel.

    The Detail Panel can be resized by clicking and dragging the tabs or the dark grey border to the left or right. Clicking the border will toggle the panel's visibility.

    Configuration Details

    The Webmachine trace tool is divided into two parts: one produces the trace logs, while the other produces the visualization.

    Trace Log Production Configuration

    You may configure the path under which trace files are stored by specifying that path as the Path part of your resource module's init/1 return value. Every time a request is made to that resource, a new trace file will be created in the specified directory.

    Warning: Trace files can be large. It is advised that you do not leave tracing enabled on a large-content-producing or high-hit-rate resource.

    The path may be either absolute:

    init(Config) ->
       {{trace, "/tmp/traces"}, Config}. %% absolute path /tmp/traces
    

    or relative to your application's root:

    init(Config) ->
       {{trace, "traces"}, Config}. %% "traces" directory in application's root
    

    Trace Viewer Configuration

    The viewer is configured by its entry in the dispatch list. Two functions make modifying that entry easy: wmtrace_resource:add_dispatch_rule/2 and wmtrace_resource:remove_dispatch_rules/0.

    Call add_dispatch_rule/2 with the HTTP-exported path, and the path to the trace files. For example, to expose the viewer at http://YOUR_HOST/dev/wmtrace/ and point it at the trace files in /tmp/traces, type in your application's erlang shell:

    wmtrace_resource:add_dispatch_rule("dev/wmtrace", "/tmp/traces").
    

    If you know that you always want the viewer enabled and configured in a specific way, you can also add a line like the following to your application's dispatch list:

    {["dev", "wmtrace", '*'], wmtrace_resource, [{trace_dir, "/tmp/traces"}]}
    

    To disable all trace viewer resources at any point, just execute wmtrace_resource:remove_dispatch_rules/0 in your application's erlang shell.

    Trace Log Format

    The trace file is fairly straightforward, if you want to read it with less:

    • {decision, X}. indicates that a decision point was reached
    • {attempt, Module, Function, Args}. indicates that a call to Module:Function(Args) was made.
    • {result, Module, Function, Result}. indicates that the call to Module:Function(Args) returned Result .
    • {not_expored, Module, Function, Args}. indicates that Module:Function(Args) would have been called, but it was not exported (or not defined) by the module

    The format should be such that a file:consult/1 will give you a list of the lines as erlang terms.

    Special Handling for Funs and Pids

    Funs and Pids don't roundtrip through file serialization very well (file:consult/1 will blow up on a fun or pid written to a file with io:format("~p", [FunOrPid])). To deal with this, the trace logger prints a recognizable tuple translation instead of the fun or pid.

    Fun Translation

    Funs you might see in Erlang source as fun io:format/2 will appear in a trace log as:

    {'WMTRACE_ESCAPED_FUN',[{module,io},
                            {name,format},
                            {arity,2},
                            {type,external}]}
    

    Those that would be in Erlang source as fun() -> ok end will appear in a trace log as:

    {'WMTRACE_ESCAPED_FUN',[{module,sampletrace_resource},
                            {name,'-to_html/2-fun-0-'},
                            {arity,0},
                            {type,local}]}
    

    Pid Translation

    Pids are simply logged in a marked tuple, after being run through erlang:pid_to_list/1:

    {'WMTRACE_ESCAPED_PID',"<0.74.0>"}
    
    rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/www/dispatcher.html0000644000177700017770000001141312633765070031225 0ustar michaelmichael Webmachine request dispatching

    webmachine

    Webmachine request dispatching

    This page describes the configuration of URI dispatch to resources in a webmachine application. The dispatch map data structure is a list of 3-tuples, where each entry is of the form {pathspec, resource, args}. The first pathspec in the list that matches the URI for a request will cause the corresponding resource to be used in handling that request.

    A pathspec is a list of pathterms. A pathterm is any of [string,atom,star] where star is just the atom of "*". The pathspec-matching is done by breaking up the request URI into tokens via the "/" separator and matching those tokens against the pathterms. A string pathterm will match a token if the token is equal to that string. A non-star atom will match any single token. The star atom (* in single quotes) will match any number of tokens, but may only be present as the last pathterm in a pathspec. If all tokens are matched and all pathterms are used, then the pathspec matches. The tokens used are available in wrq:path_tokens(ReqData) in the resource functions.

    Any atom pathterms that were used in a match will cause a binding in the path_info element of the request's ReqData. If there was a foo atom that matched the token "bar", then wrq:path_info(foo, ReqData) will return "bar" inside the resource calls, and in any case wrq:path_info(ReqData) will return a Dict term with all the bindings, accessible via the dict standard library module. If there was a star pathterm in the pathspec, then wrq:disp_path(ReqData) in a resource function will return the URI portion that was matched by the star.

    The resource is an atom identifying a resource that should handle a matching request. It will have the args (which must be a list) passed to its init function before request handling begins.

    In the default directory structure for a new webmachine application, the dispatch terms will be in file:consult form in "priv/dispatch.conf" under the application root.

    Examples

    The examples below are taken from Justin Sheehy's slide at Erlang Factory 2009

    Dispatch RuleURLwrq:disp_pathwrq:pathwrq:path_infowrq:path_tokens
    {["a"], some_resource, []}/a"""/a"[][]
    {["a", '*'], some_resource, []}/a"""/a"[][]
    {["a", '*'], some_resource, []}/a/b/c"b/c""/a/b/c"[]["b", "c"]
    {["a", foo], some_resource, []}/a/b"""/a/b"[{foo, "b"}][]
    {["a", foo, '*'], some_resource, []}/a/b"""/a/b"[{foo, "b"}][]
    {["a", foo, '*'], some_resource, []}/a/b/c/d"c/d""/a/b/c/d"[{foo, "b"}]["c", "d"]

    Query strings are easy too:

    • Given rule: {["a", foo, '*'], some_resource, []}
    • And URL: /a/b/c/d?fee=ah&fie=ha
    • Then wrq:get_qs_value("fie",ReqData) -> "ha"
    rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/ebin/0000755000177700017770000000000012633765070026302 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/include/0000755000177700017770000000000012633765070027010 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/include/wm_resource.hrl0000644000177700017770000000007512633765070032053 0ustar michaelmichael-record(wm_resource, {module, modstate, modexports, trace}). rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/include/webmachine_logger.hrl0000644000177700017770000000063212633765070033161 0ustar michaelmichael-record(wm_log_data, {resource_module :: atom(), start_time :: tuple(), method :: atom(), headers, peer, path :: string(), version, response_code, response_length, end_time :: tuple(), finish_time :: tuple(), notes}). -type wm_log_data() :: #wm_log_data{}. -define(EVENT_LOGGER, webmachine_log_event). rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/include/webmachine.hrl0000644000177700017770000000017612633765070031625 0ustar michaelmichael-export([ping/2]). -include_lib("webmachine/include/wm_reqdata.hrl"). ping(ReqData, State) -> {pong, ReqData, State}. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/include/wm_reqdata.hrl0000644000177700017770000000064012633765070031643 0ustar michaelmichael-record(wm_reqdata, {method, scheme, version, peer, wm_state, disp_path, path, raw_path, path_info, path_tokens, app_root,response_code,max_recv_body, max_recv_hunk, req_cookie, req_qs, req_headers, req_body, resp_redirect, resp_headers, resp_body, resp_range, host_tokens, port, notes }). rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/include/wm_reqstate.hrl0000644000177700017770000000051312633765070032051 0ustar michaelmichael-record(wm_reqstate, {socket=undefined, metadata=orddict:new(), range=undefined, peer=undefined, reqdata=undefined, bodyfetch=undefined, reqbody=undefined, log_data=undefined }). rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/.done0000644000177700017770000000000012633765070026301 0ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/Emakefile0000644000177700017770000000013312633765070027167 0ustar michaelmichael% -*- mode: erlang -*- {["src/*"], [{i, "include"}, {outdir, "ebin"}, debug_info] }. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/LICENSE0000644000177700017770000002367712633765070026411 0ustar michaelmichael Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/rebar.config.script0000644000177700017770000000060312633765070031151 0ustar michaelmichaelcase erlang:system_info(otp_release) =< "R15B01" of true -> HashDefine = [{d,old_hash}], case lists:keysearch(erl_opts, 1, CONFIG) of {value, {erl_opts, Opts}} -> lists:keyreplace(erl_opts,1,CONFIG,{erl_opts,Opts++HashDefine}); false -> CONFIG ++ [{erl_opts, HashDefine}] end; false -> CONFIG end. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/rebar.config0000644000177700017770000000037612633765070027655 0ustar michaelmichael%%-*- mode: erlang -*- {erl_opts, [warnings_as_errors]}. {cover_enabled, true}. {edoc_opts, [{preprocess, true}]}. {deps, [ {mochiweb, "1.5.1*", {git, "git://github.com/basho/mochiweb", {tag, "1.5.1p6"}}} ]}. rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/start.sh0000755000177700017770000000014112633765070027055 0ustar michaelmichael#!/bin/sh cd `dirname $0` exec erl -pa $PWD/ebin $PWD/deps/*/ebin -boot start_sasl -s webmachine rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/docs/0000755000177700017770000000000012633765070026315 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/webmachine-git/docs/http-headers-status-v3.png0000644000177700017770000144573212633765070033302 0ustar michaelmichael‰PNG  IHDR Bˆå°vÍsRGB®ÎégAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<ÿŽIDATx^ìÝ œdey/~LâÕÄ«ÉÿÞĘ\·˜`î½IÔh”qÉ¢‰&¨j£(*Š‚ƒˆÄ]@EqAed†e€a‡a؆Fd“YØ5^ù?UO÷Û§OUWï]Këó~šÓ§Îò¾ßsªºéúÍó>áñÇßȃ @€ @€ @€ @€]ˆ“ @€ @€ @€ @€º(°QÏíÔ @€ @€ @€ @€1&· @€ @€ @€ @€]cêòpz @€ @€ @€ @€æQŒé¶Ûnk½Þk×®ÔM0Ùí'up @€ @€ @€ @€˜Ÿ3cЍÐöÛo¿xñâVÍêS{î¹glÖáGè¼Af’ÆÚ¦µ×_}l\ëUv©m¼©íÝpÀìºë®óóF1j @€ @€ @€ @€³'0ó1¦Í6Ûl¬SyêôÓOmòqØa‡Åú6•5±©£ê·Wª®yì±Ç¥u}lI£8`¶ªßÖH™aŠ-'cŠ Sl,Æ4{÷¢# @€ @€ @€ @€Ì[îĘªÜ‘"+ùT6‹¼QÛüÐXëcãxꡇª¡®ŠUF &cŠãDÊ*¶œ~Œ)椋„Vô*bàåQ»ÿªOårƶâÑ6tÕº}N~W;Kn–OµË¸¯„L˜`m~½±úܺ¾:œÖÓÅaË`óÙêš2eãZÇâhÕ½ªwE‡ÁÖNT¶Œ£µ?×ÔN4ÖÅ­ÝünƒØrùòå¡_[»É8`ÞQåöhK}‹Ç½¸6 @€ @€ @€ @€tK`0cL‘í¨æ“"ð‰¥’>ÉLR|üǸ1¦Ø+O%‰tÔ4«1Åî£É U°Ô”Ê› s]ùTyd%+HµÞ+åPeû¨›å,x幜OµK‡1ÏGˆÒV9-`ªsŸcËëeHeÊwRt£LuW ëD¾$zXzÕ6«”+ÆÔy­Ù 8Nç]Z‡»TãGa‡ÍlÍX«d‚gìcK&OT¢fÕÄO-x1²Lbu¸Ž­Ã‰{ IbL倭۴=W‡³dð®:мCJ©Ü-yäè[mD­Ú9ð)ß½v$@€ @€ @€ @€̪À¬Ä˜"TIŽÚ#£EµB;1¶Ìµ®¯; Ï´B´]ŸéjÞ%úSêU2‘SuûiƘb÷Rª5¬S‚2"A]Œ1e©¡Ú%ˆTM™¢®sÀ(vœƒS\èˆþDW«5ZCEYʨÃëªÕ¹dVcLåàåf¨v2‹`åšZŒ©\ˆ²}[í¸‚ó­ Ó%—\òOÿôOo}Û[·Ür‹-ãË[·|kõñ¶·ÆSok¶üOs¡ÙF=;Æc‹-·j[lñ–-ÞÒã-úüú׿þ‹_üâÃ?<«?Eœ @€ @€ @€̈À¬Ä˜2EÔú˜S™Z«:kXœ¨Z7¨VئÀÍeŒ)'§+§n1•lMfhâkõ‘;vˆ1ÅîÕí³|T‡Ó¥I‡]j·Wk‡«tèsÙlâ1¦Z .vÌ”[ç³d£<],”ÄXkð¨6É`ë ©Õ¹$áf5ÆTÎÒV»Ú«ˆ4Åcû¸ÏËH«i«o›ç›‘·’Þ<ÈvÛm·ù–o>ë‚3NYvÒ©g.]vÎégžæ9ËÏ>Åù+.½ð²•—®¼æÊ«¯]uõuW_s}£ÅªÕ+/¿ê²‹.[qþEçŸ{á9gæç.;í¬SOYvòI§-9aéâãO>Ž=æ„ï½xQ´EÇuÔqG6Ú±mG{DlÿÝŽŽãTÛ1K¾Gk<;áCuØòÄÓ–ìðÑžö´§}àèÍ«£W @€ @€ @€ @ *0+1¦¶¥•ƪº4ÍjL‘Xªå¥"Û‘³³å£sq£q'•«bM§S­šQkN¥ô3AJ*+:=jÍrUS\1„¶“ÊÕNQÛ¥ö:©!:SöÍXL‡>—ãÌHŒi,™8KµXQµþVÛ)Þ:w&‡S½¯J%ª™1u–qcL1Þ¸ 1äØ2¯~mŠÀ¶ÌI÷æÕ;à—¿òåsWœ}úÙ§yÞôÒEç­¸tù¥W^rõu«®¾~ÕE—\xÖ9gž¶ìÔÓÎ8íô3-Î8{ÙòD¼iõ«›y¦ /¸øüsW4òLËÎ9íÔ3O9yÙI'ž¾dñ©Çgžé¸9æÄïF)bIjKŽŽ£}ç¨oïÐ~{}ï¯î÷•½÷ÿê~ ÷=äðCŽ=ñ˜Å§?‰£}Ò8ÈÒ3OÙúý[o»í¶óê¢, @€ @€ @€ô©@ßǘÆedÔ£íå™ËjLµøKkN%RDYL¨7'•‹‡daÌ2NŶCŸË.1ÕbpŪóY2u”ùª\ÎS·²2VÔdëE[+ûTÝrfcLÕ²[Õ³´1Å|pÕ‚^ÕÎG˜¬v“·ÕŽqûzéÓ7²±ºý•½¿rá¥dŒé¼ ÏY~ñòKW^ºêš•—\vÑ·¾shÌ÷ìç<{£'lT}üÏßÿŸ¯}Ýk¿¼÷—/¸¨fºòê+¢nSäŸÎ>ÿ¬eç,kĘN?qÉ©'J#Ãtì’c¢,S¤—²,ÓDZlõ–>¿çç_ýšW?éIOzâŸø”§<%~ã7~ã…/zá.»íñ¦H Mü€N1¦÷m÷¾±n›»Ö†C€ @€ @€ @€ý.0ø1¦Zþ¦zÁz*ÆT õfŒ)缫ÍUW2=]1eħ:G^|}ŽË=‘àQíeÜa8eKkN®mý§ÖwŠg©ÕîÊ}ËÒZT©õPmcL¡4cL+.[ÉE†é‹/¸|Õe«®½êØãyã›Þø›¿ù›™^ú­ßú­§>õ©OúÓï÷~ï¿ý·ÿV"M/}ÙKúæW¬¼|åê•9æVœÖg~öéKÏ8å¤ÓOÌÙå¢xRVN*ÌuN2EòéÛG~k‹·mñ¤'?9Nú‚¼ ¦½ûò—¿¼óÎ;ÿÝßýÝÿøÿã Ox¦¯Þtÿ÷#O$Õy›SÎ8ù½Û¾WŒ©ßNë? @€ @€ @€æ‰À€Ç˜¢ÂM‡"@scªMjs´E5R¨ë1¦(VT‹+å‹¡:½]|›™˜ÈÖÄòÔbLµyÐÊY¦P©:‹\§¤‹ª¡¢¸"!S¹•ic¤9a_õÑa8yG• ø2>•y©òh1Mö,©öå£z‡Ä·qÒÚ³y!Ê£ím«mVøà}ûÕ½¿zÉ•;”aºüº›®Ýï€ýžýìggVéþÏÿùÿðŸøÄ'ân‰[⤓NúÌg>ó–·¼%6ˆlSlð»¿û»øàöË/¾àªÕ+W\ºâ¼‹Î;óü3¢¶SăNãÜe§uêÉËNjL-7º SçÚH'œºxÇ?üã?ú£cŽ9&Ïû­o}+Öl½õÖùíºuëÞµÕ»bÍæ[l1©idcê—U?  @€ @€ @€ @ <ÆAågÚÆ˜"êÕzÆ*49¹¢3µ,QoÞ‚Ó)Õ†Úö0Bš~ç#ÔZ iú‡Ô"¯6µE!0ñÎOù,1–¶·bcçg«™ëšÎl1¦•«¯¼øò‹¢Ó7=83LOyÊS¢êÒÏ~ö³ÎŒÚHÿëý¯Ø>fÛå»\wãµ—\yñÖùgŽd:åøãN<¶Qfé„Eç•‹éä¾ñÍ^ü’?íiOÛwŸ}~òãçÙ—.]úÿïÿýÜç>W:sÙe—=ç9Ïy泞¹ÇW÷ˆ½¦“dc€{Ø @€ @€ @€ 0f8ÆqHêÄL[­‚c=Õa—r8fÛ`ÍXëËŽ‘P©–Þ©õ*O]+¼Ô¡S<Õ9ßÓù¾‰M'5g7eky¡Ù8uhÌ͉:w>.èÄÓHSv˜›³tîÞ¸/–)®—wüÚ>_[uÝÕW_·êÌsÎxíë^™¤'=éIŸÿüç'Øç“O>ùÿøc¯?ÿ߾軋®½ñÚ—^xÞ…çžqÞ²SÏ\zÒé'F¥FA¦%Ç|wñÑcL'ž¾äc >‡zÛÛÞö_ÿõ_ÙŸÿüçwß}÷š5kn¿ýö˜`®ôj¯½öŠ-cú¹ØKŒi‚Ëf @€ @€ @€ Ðï3cêwŽÙîLéÕ!V5Ûgwüy+¡±(6‡ÿµ}¿u˜®¿åº/~ñ  úßøw¼ã?üðÄ)?üðßþíßnÄÞþ¶ëo¾î’+/.Ètú)ËNnÌ+wÊqÇžxLdúî $ÓX©£(Œôž÷½û OxÂ>ûìSÎoo¼ñûoÿíéOúATÖŸ}öÙO~òo¿âU¯ˆ½Ä˜&~±lI€ @€ @€ @€}- ÆÔ×—Oç è$°Ï¾_[sÇ­K—ú÷ÿ÷¢Jþççw^îÕÖ­[µ¸6lØðË_þ²¶ò¾ûîûÕ¯~+ï½÷Þw¿ûݱïŸþÙŸvÄw®¹nÕ…—,?wùÙËÎ9}é§œxÚ’ÅÍyå¾»äèqcLïÚz«ß}ÚïVg–<ôÐCãÈùØzë­ËHV­ZõüŸÿò¿ÛDŒÉýM€ @€ @€ @€óG@Œiþ\k#%0ïöÙwŸ»ÖÝuÐ!ýþü~”bÚn»í’à®»îŠÿê¯þêyÏ{Þ&›lrà>ðÀ1¿Û'>ñ‰¿üË¿ü“?ù“W½êUGydÖm:öØcë·~ëIO~òÇvþØM·ÞxÑ¥+FÍ+·tñq'{Ì ãWcŠÓSÿûS9æ˜r¢ÔS‰1•¾Å³+W®ü“çþÉߊ1ͻր  @€ @€ @€ 0¯Ęæõå7xƒ-°ï¾û¬»oí—öüb¤…~ÿ÷?bC1ÞH,Eé£X³Å=ëYÏzò“Ÿüßÿûßyçßÿþ÷Çʧ<å)Ï|æ3c¢·ßû½ß‹$SlAF¶)žÚâ­[¬¹ýÖ‹/¿èüçyþ§uÚÉËN:áÔÅÇ|ìD&•{ïû'ýâ¿XÌ£êR„¨båsžóœj•¦SO=õ7~ã7_õšWªÆ4Ø÷§Ñ @€ @€ @€ @€@U@ŒÉý@€ÀÀ ì»ß¾Xÿù/~>¢BñqÑEÅPO9唨®ô›¿ù›ýèGcò¸ÈmµÕVÿùŸÿù;¿ó;±r·ÝvûÁ~ðÉO~òMozÓÕW_ÛÇÜsïxÇ;âo|Ó¿wÇ÷.¹ââ .:ÿ¬óÏ<í¬S#Æ´äÔŽ?ù¸qcLKN;a×ÝwtÔk_ûÚÿøÇEüÛßþvy›m¶)kþë¿þ+2UQ;ê?Þó®ØkÑñGM¹E ê½Û¾wûí·Ø l` @€ @€ @€ 0@bLt1 …ÑÓƒë¿ð¥FŒé5¯yMä“âùÃ;,¾éä–-[V6?ꨣbåŸþéŸVWæ³<òÈŽ;îϾéÍo¼íΈ1]2…Säœ=âWÿëã8Ÿÿüç{ì±<ø¡‡kÞýîw—žœp O{ÚÓžÿçÏßÿÀýc¯)g˜bG1&/ @€ @€ @€è#1¦>ºXºJ€Àäª1¦W¾ò•·ß~{ìÄGDr(¦“;ñÄãÛŸþô§ëׯ?è ƒb峟ýì¨Õ”+×®]û³Ÿý,–£xÒ;ì0ÍS„Š¢´ÒîŸýTL`eŸ¾úÕ¯F:*óÇýßÿû?÷¹ÏÅò/~ñ‹ÓO?ýÏŸÿçQjëm¶žf)&1¦ÉÝ+¶&@€ @€ @€ @€n ˆ1uû 8?³&04©Ü>!¤ç?ÿùçœsNœêì³Ï~êSŸkb.¹[n¹åÃþð_þå_Æ´nÏxÆ3båvÛm+?ô¡EÎiñâűýÝwßý–·¼%žÚìM›MyR¹½xÑñ'÷Áà)Où'?éÉQáé†nˆëxà˜Û."V‘mzú<ý‰O|âë^ÿχ}ØwO8z:¥˜Ä˜fí¶r` @€ @€ @€˜1¦YauPzA`ß}÷Y{ï={}u¯¨oô»¿û»Qr)zõÐCí²Ë.ñm$“žÐ|üŸÿó>øàÏ~ö³OyÊSÊʘ`îøãí¯ºêª¿ø‹¿ˆõoÇÛoýþ-_~Ñù+Î;óü3N;ë´“—t©‹;ùؘý-RGTê<ŠmŽ=ñ˜wÙé™Ïz擞ô¤'?ùÉ/|á ·ÜbËø‡ˆdU˜~ÿ~ÿmïxë·úö4§“Ën˜T®nB} @€ @€ @€ @€ lôðÃßÙî1ÁýmF€ DÙ¡Ö7›{î¹g‚»Oa³}öÝçöÜ~äÑGn¼ñÆ‘CzÏ{Þ·Åq~ô£zè¡Qcé oxûÞõ®³Î:+VF÷¾ò•¯ÄšýוQ´é×ÍÇ‘GûþÎS~g·Ýw»áæëW\ºâ¼çžqÞ²SÏ\zÒé'ž°tñq'{Ì Š1eM¦ØþÀoøŽ­ÞñÜ?yîDý¥?|z´?þ_üú}ýÞûï9§qãP¬Ò$Æ4…{Æ.´ˆy0ýºèÞ @€ @€ @€˜mâC© Û=fûÄŽO€À|¸õÖ[[ßl®¸âŠÙsØg߯Ý|ÛMË/^þ¶·¿-¢HÏ{Þó–.]:©ÓÝqǯýëcß¿ü«¿<áÄÅ«V¯\~Éò³—Ÿ½ììÓO9ã”O[²ø”ã#x4ÁjL?Š”R–n:ê¸#<öˆl±OM¤¤Ó3Lª1MêBÛ˜Î6lð뢛„ @€ @€ @`¶Ęf[Øñ ˜ûÓ¾ûí{Óm7G’é€oìÿ;¿ó;‘FŠbK÷Ýwß/ÉÏþó/~ñ‹±×oþÖon·ýv·~ÿæ+®¾âÒ•—,¿ä‚s/<÷ÌóÎ8íìSO9óä¨Éy¦%§ž•™"Õ4ÁÇ.Õ6©Ý'r–3/8cÛn»ýöÛOp¼6#@€ÀXbLî  @€ @€ @€93ÆÔvê+  0eU«VÍq5¦=÷ÜsÙÙg\~ÕeW^uùû¶yïžð„È$½ï}ï{ðÁÇ}{ýÙÏ~¶ï¾û>éIOŠ]^ö²—ž~ÆiW_¿jé²¥G}Ä·ŽøÖ7¿}ð‡.<àà¯ïà~û}cß}¾þµ¯}}ïh{ïÿÕÞi}ëÀ-Þ¶Å;ßùÎ)_2; @ n¸áÕ˜ÆýÁa @€ @€ @€i Œcjûa••˜YYTnë­·~îsŸ»×Þ{]óu§œvòËÿîå‘IŠÇ[ßúÖk¯½ö¿øÅXo ëׯÿüç?ÿä'?96þ£?ú£}öûÚ-·Ý|Ô±G½bÓWDjšìC>2Y• µåižeè€OØèo|ãÌ^2G#@€@˜æ¯¡v'@€ @€ @€ P0©œû9˜ûIå"Æ ¡?þã?þŸ¿é{7->qñ‹_ò⌠ýÙŸýÙþûï%F¢2Ó£>úë_ÿ:¦{衇֮]»xñâW¼â¹Ùÿøÿã3Ÿýô÷ï¾í»‹Þäo7©&¦¼ü”§<åùÏþ ^ð‚§?ýéqßÿýßæÑžúÔ§>ç9Ï™ò‘ÛîhR¹9º¿†À@ ˜Tn /¯Á @€ @€ @€zE@Œ©W®„~xnŘ"Üóìç<û«û~õÆïÝtÒÒ“^ý÷¯~òo7Ê,Å#2C[n±åî»ï~Ì1Çì½÷Þ[mµÕ _øÂRiã7Þ{ß½¿wÇšS–òºyÝL¥‹¶Ûn»‡~øšk®Y¸páŸüÉŸl»í¶K–,yÆ3žñ¦˜ïÀœ©åqĘþ•e€æ@@Œi‚ @€ @€ @@ŒÉ=@€À t1Æ”I¦¯|í+×Þ¸úò«.Ûy—Ÿù¬gþöoÿvÛÀПøÄ§ÿáÓß²Å[N=ýÔ›Öܸdé’×½~Æ2LqÆ \|ñÅ/}éK?÷¹Ïí»ï¾¿ñ¿ñ|à ƒÚqÇ¿ùÍoþæoþ¦ÓÝ‘NC€À„Ę&LeC @€ @€ @€© l4õ]íI€ÞÈIåÊãþø>ý¹ÿ¼èÒ7ÝzÃ]°ë§>ùŠM_ñìç>;"Mdzžù¬g=ëEý¢í?¸ý)§|Ó­7^¹êŠC¾sèLÍ%Wºå‘¢ÓÊ•+£SÌm—ëwÛm·¥K—F¤if3Lª1õöªw @€ @€ @€ 0" Æän @``j1¦Èô<ñ‰¿µÙÿíèc>oŹW\}Åu7^wÃÍÑ®¿ñ–¢ÝpËõ×ßtݪÕW­¸dùIKOüðŽþý?øƒÏ}ò“Ÿ¼âŠ+¢Ó—¾ô¥o|ãyü˜Øî¬³Îšñs‰1 ìÍm` @€ @€ @€81¦»¤D€À°@kŒ)sBO}êS_ûº×~qÏ/~÷øïžxÊ’%'Ÿ°ä”F‹åã—·ßû½õío}Æ3ž1¡¢8æ[ßúÖ˜_鍊nŠS™Bn»í¶‹yåfãŒï}ï{Ý @€ @€ @€ @ ÷Ęzÿé!SØa‡:ƒžÐî1Y¢Ú1cò¸'>ñ‰qò²>;2ã§þíßþíOúÓSä³ @€ @€ @€˜C1¦9Äv*æV ænÛx~<ž÷¼ç=ó™ÏüÓ?ýÓÚp#Ãôë_ÿº­úÂ… 7m>baj—eýúõSÛ±ìµùæõ”CNðØÛl3t„\Ƚb@SÓ¨þÄ1׬™æ§ÞŸª@fµ7Ñ·¶ë'ÞãVÿ‰ïkK @€ @€ @€̸€ÓŒ“: æZ`Æ ^xáÃ?<ÁGziÁ‚«šm¶Ù&–'¸cu³Í§‚ÙxãúiË!'xìÚöùí{4Úô›núøªU£‡­­™ÈY¦ÖŸª@[èIôp:Vÿé; @€ @€ @€˜¦€Ó4íN€î L*Æ´hÑ¢Z)¿õ‘jÚ£™ŠJK±5Ãõˆ–/_žk–.]D §¨ü”•œjÇ–±WîËñ (b4ñdœ0‹'År¬Éoc!¾>òHce,ÄÊr˜QZ´hhÇ\({Å‘ËʽJ9¥ L*Æ¡¥Ì*ÕQ¢)ŸŠXRD”"® ¤Xi¤xÄB„œbM<߯r>ÇBl|*Žk2Æ9§“ÖEŒ&¦E‹8NăJr(¾Í€N$b!óL™pÊàQ)MûæÌk¹PöŠÁÅÆÖ‰ðM&ub9K+Å¡²‚Q5oTÛ&RGm4t´Ü+ÖäIc!ŽXkªOåªkb›X§ÎlVõQžÛäs÷8Nf¤R Œ.–³3I‘89–laÌ5 [Ž_ÎÏãĵçS)Ü:–oì5ÁBYóéõg¬ @€ @€ @€ÌŒ€ÓÌ8: º(0©SfŒZ{›A¥XÏÆLsÕ)çy䑈+ÅS%ÏËYÃ)K4åÑ¢žSìX]ÓÙ¤Z (絫MW7-B6µ¹ïÊ”je¡uR¹|ª:=\qâP­1¦Ší£cyê2…\ ?åšÖ§Ê–%'Tz••ª2ðìI9W,T³D¹K'j;ef«ä™ N¦âÙRö©vüê©«=ÏÍJ‚*1©ÚXªã³Ls&»Î·„g  @€ @€ @€˜ÏbLóùê;"0©Ó‚ j1¦ˆD5Æu•âÛ|D2)2LZÊåx*ÓNcН9Í\<²DÓbL%‘Óc*Ñ¥j¤)ÎÙ|ª,4;ÓXS(ej§Äzʳ­1¦ê6¹Wkâ'#GåD9êÜ,žÊM“*»³Œcʳ‡±W¶E~-£‹üP¬‰g³ŠRìR@òŒñl´ÌK•±äñ³·‰ºG­Õ˜2TbLYµ(ùT|›bCóÁM¤SÆŒ²ÀR>"®”ÓÌåXÊ0c³’èÊ(R ZµÕbLC‡nþ§ ³ô¼º&§ö«%¶l ?Ui™ @€ @€ @€3" Æ4#ŒB€n L*ưQ–MŠ…È0Õª1Åñl’b!&’‹ rû¨Æ ‘sŠmbÇØ&æ›ËóPQ·©cŠ-sã¶jÚ&³8YÍ(“4‘ÚÉ2E±&–cƒÌ U‹•oóø¹Wk5¦ˆe-¢,\²&Ž–ÝÈ,Qìžkrö´2½Z‰1e€) ÅK¤Ü7×äÆq®hÕmâÛœ®5fT6Žã4kc ¥”>ÊÉæÊ5cLÑÏZö<·ïcÊaæqªÏ#$NëXĘºùòvn @€ @€ @€óF`†cLW^yåâÅ‹gOʃ_ýõQ d¬~úé±Á”»ûÆÆ=Ë”?g;Ƶxì±ÇfötE¾ó%˜ÈI£o³z·L¤¶!0“1Ũ#oá¤x#…Dˆ¸RU#ª4UßfãÙXGn)y„œ].±P–˱¾ºÜJ]BBͳ=Ÿ+£S¥àPÒ¥Z^¨o*je^³œ¹¬Túi <åle¹c­@QíDÕøN9QìGhÛ‡RL(7.ñ r–ìX~›sÏÅfÙáêñ3UÍNµ]m›¶Y«ê]UMU#GÕüSn_ªCå·U̬¨”jÔ)ëBeZ«æ©¦Çªò­Óùå|‚µGµÃÕ^ÅrõZ”³”ÉûÊqjQ­ªŒeŠ€“› @€ @€ @€ú]`bL¥|QZä´k9›X†‡r}©WT%«Vú)¹–Zž&B6qÌêüqµèO5áT1mÃIÕþ”n”’N¹&ž}γä³"T<Ê wÕþä69äj«íèªÁ jE¢¶Õªª£¨v¾Š\RÝ`,Ì(”£‹þW§É‹oÛ²Wm‹I^Ù0*çªæ¨b˜­ ¤ê)ª÷C9KUµÚÉ~™é?Ù˜lŒiýúõ .Üc=-Z4Û}ëpü=ö˜îÉK÷«ãˆLiKѽ©œháÂÇyd*;Öö™~Ú^¥è[ôp:iú¯_ßpž¦Ò4q¦0@û @€ @€ @€ 0³Ó1e(§Vtg¬zH­³¹•yÇr6±Ro©3bCY+(žŠàK&oªQ¡,UŽ\ ÄÄS%~”“Á•I⪈9„œ7-NWž ùlNuÙl³Í2“޽òŒ¹q-ôÓvtÕmª‰ÚVŠÊˆXŽ¢Ì—uªE•r8Å*ûVŠEŸDÈ£•#d"ª”’ÊKYU›º®Š“+±Wémö°5ÆTN-â–Ã)“ÊUû0³w¼£HIŘ"ôñÆ/X° bLÛl³Í¦›nÚ-“7®Ÿyó͇֔…Î}+}Ï…Ü+Ò9Ó èäI㘫V:Dvjk&B7µþTÚ^¢èÉ4/]«ÿD†S¶‰qE©UiRqj8¥ÓG¨ ¹Ã7Á{rR†6&@€ @€ @€ @ *0ÝS­|N:")‹‰òBÕØP,Gº¥¦Ÿ•2¢!›͉xPfƒÊšLùÄ6qØj‚'–«ßÆ™ž‰ÍªYŸ¬ÔÚìO™ý-²ÏÕ³ä©óìq®øš{e'³>S°ÊÙsƒ¶£‹mJÀ¨º}mß:Ÿ¦èU³J72ÅUb!7®­•=ŽS2jÅ$ K9Qœ«ô°(U¯xu8ÕÎT{[[³¯vÛø–šÀ¤bL‘^Š S9BĘ֬Y“ß®j>ÊSe}.<Ò¬MT6ˆ8T,ÇײýX»u½"F‡Œæùc931™M)+c¡*Ë‘¡É¸R.”½2SÛ«Ùó‘ãĹJ¥¥rÀJ,Ç×ÄÁ«kâ©ÒóZu¨ÚÀc÷Ø2wÏTPK]Œ=;S(J!¢X+ cUa«7OAÎaÖpš—®ÍXÊxó\ùHÉšR9~Y¨ö'6Ž ]}t¾Xcõ'¡òk^∗•‹•Q³]v;£Nyõ+ù½Æ6¹2S½[µk÷d!/V‡ãªo @€ @€ @€O`ðcL0Ê FãQLîùÈEe£\˜Üζ&@€ÀŒ L*ÆgŽ$SdŒ"ÌÈÅš… –MY®©mŒ©l;f *¾F¤)Ž_sL™yšÈø²SnÊ W¬)å»r\e›Ì*å£R*gÌQ”ê\ÙùVíX™OUïɼŽ_•·L€ @€ @€ @€À¸ƒcŠ9Ñ"l4ÖtrãuØ i€éľ˜¾ÀdcLåŒñ©£Ì!EQ¥\Ÿ¦¶1¦Ì<Å#bLÕnÇöŠªF£ÆW9F‰†´Æ˜JÆ¥‰#Gh&³)e!–[+-eФÚÙÌú´Æ˜ªÛä^ùux¼ÿ–SµÎT)É+³8PÙ}سMŒ©úTœe£,­Œ¥:º,õÏ”U‰ÐOYŸ×§ k"©“½Ê…2¨RN©zêØ>~¬UÇlÝ+ð³8V«RkŒ©$º²oÕþT/Dq·?Õ‹•§«î’>µm²8SÜãÕ³§a¯Ê„Sé|M»<ÕcʧÊñǽím@€ @€ @€ @€ÀXƒcrí  0ð“Š1U+'…L$“Ê#¡"ÕÃM<Æ•œ"ÆT2,Å'šHŒ©ÄJ"}R,²;Y³§,ÄòX1¦jÔ&ò7Yü©THÊnÔâ8cL±q©ëSjÿd¨µìX²;¥ÖT¹k1£ZB+cF9–2º~))T­Æ”•œ2QT­Æ”çÊZAQj(cO±Pfö0¾–8nž:XK ';V®ËDbLe¼Y̩ڟ¶1¦qûSXJ@UCKe‰P®Td˜²DSÑ(‰®Ì6•qµj—§ZcLµã—«l @€ @€ @€É ˆ1MVÌöè9IŘ"o”sÉEÞ(H11Üš5kbedÊgãk¬Ì5‘jŠ…Ø8ÓN9ø˜].£Nñ5–c³,à 9ßÜ#<ï,ÕcÊŠAñˆ§"t’5u"Ê““‘e^¤L?—ÙÈÓäBÙ«5SªÅ¡ò¤±ù›ˆFåšœž,Ni¡X“›ÖjLñl†â¼¹{¦‹J‡s÷xäXb›Ø2ûßæ$zµSuãØ=ÓZyÀ2º ÖÄÑrñ5ó4cŠå$*IŒ1U9ÌX¬<ÖdÊ'0ÛŽ¥ZÃ)NZËTÿ2–êB0•µ›¢õb•vèO²§ÆÊšH*ÈY­*X­ {¥vjäˆòªµj—+R|òBäëø£è}C€ @€ @€ @€ÀxbLã yž=/0©SŒ&bFHвLñ5–s|‘dÊ R©«™¤ø6ÒH±&bIñµ:f¬Ïgs÷Ø8òL倉1•„M„{ò0‘ÅÉêAYÁ(“:ñTÎt–Ü«ÄhÊB¬Ì½b˲qIE„%3%ó”‡õYÕ©œ=ó@ñ(û–“ƾyüØ ÏUB9Ùó<~W®ÉŒQõ€ÕWÇ‘šÒ™<~utÙá uE+h¥'‘.Êþ´=þÐ ›­ñ-'r´ê6Ñ]wÝu¬nÌÞy'ÛÏ®lÿÐCu>ï¸t¥ÛNJ`€&cêŠÚlk³Úí •(U­fOëy«…šfµWƒqðêŒoƒ1"£ @€ @€ @€ @`6z1Ætúé§G„¨ÃhãÙ Ê\ýõpÀŒ»¬]»vûí·¿òÊ+ãøÕƒWÏÛ¹‡3Þ¥Þ9`\ÎæãnÐ;cÑ#0¨1¦êäesp±"ɳƒEËÙë:qäHÅ#V–ÅcMl•“ÊÁ3`ÈBÅrìOeu¥ÖkSíUž4ÖTO‘»´ž·Œ±Úɶ/'ãGgòø±¥žZûœa©ìpHìU’Âùhí|¢e9«µŒòÔf+aRÂ'6.õ“ª§(y¦’Œ‰sU£6Õ Oѯ–kÊ•cu ª!—«É8Q-ʨc¡š¬Ê«}¨n™ËeyüR䩊ƒdÈi¬Î…Vº]Û¡Õ[6+H•™ìâÚU§ºËaÆ6±ë«TÇ[íXlV;l¿Ht@Ï ˆ1õì¥Ñ1 @€ @€ @€˜¬À ĘªóµÕ2@Á‰tNLLVI¹A)ATº›ÅâÛR§šì)uŒªÇ/ɘê–e.¶8o)æ‡-á§rÆZ¨t Êí«ç­&uÊYÚ¼v1ª}¨–\Š,Tú$WîUê•…XYŠ0Õù*EégÛöí@µÃÑ¥œQ.I³‡e¯ZY¦2Õ]õ°e¼y„ZÛÃNö®µ=) ÆäN @€ @€ @€ @€˜S)ð“(XÉ9Ñ"=S&›++3îqœLäd´%·ŒÉÚr÷ئzœ¬á”ÇÌÂ?¯)ç¼N–>Šc–2Hµ°QkŒi¬Ôêå jç-a£rê±^n”Z¬ª0ûœ!¡œú-GWfÊ‹5iëKÑ£zåŒ%QÔö°m;P½­‹d†Ò?'΋…œ.°tu³Í6+W-7È©÷òBG -—óªåŪv`^NB`ŽĘæÜé @€ @€ @€ @`öf ÆTfË^f¡ œ‰,“+ñÈO®Ì˜Kmef˜"ÚRŽ–A™,/T›•Lõ¼™Ô)y 8Tdeʉ"&U¦B«RV{•ˆG¶,—kç-㪞¥íÀË¢¥$U®,}ާÊfee™“.“CµÑµÕ‹NVMªþ­‡«¥'%~TUÍã¤O,çÍ TV޵A¹ía«Å2xä‘G®m÷øÅ/~1ñƒØ’ @€ @€ @€ô‚À ĘzaƒÚ‡Ú\uƒ:Lã"@€ @€ @€ @€˜çbL=}D§Z±«žî®Î @€ @€ @€ @€˜’€Ó”Øæj§˜e/su6ç!@€ @€ @€ @€ Ð1¦î¸;+ @€ @€ @€ @€E@ŒÉÍ@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€.ǘ/^üØcÍÈe¸þúë—/_>#‡šþAfp\¥3§Ÿ~zŒqú}Ë#{tr¦Žæ8 @€ @€ @€ @€¦#ÐåÓöÛo?ÞW÷PN}fêhÓ9N$„öÜsÏé¡í¾»îºëm·Ý6S‡DTp¦Žæ8 @€ @€ @€ @€¦#0“1¦‡z¨µ+k×®m]™[F(§–¤i{„¶Ã›ø–ÑiÛÉÎ;Nj—‰÷¶ÃaKä«õhc¿íú\©¯Ã;l\œj­¬I yÜ#Û€ @€ @€ @€ @€@˜™S’âQ›މ LYY¦{»òÊ+seylذÁÅ#@€ @€ @€ @€ @`0FbLwÞyç7¾ñ‹ûáqÔQG-_¾|0.€Q @€ @€ @€ @€ 0*ÆtÈ!‡¬é‡Ç’%KĘܻ @€ @€ @€ @€F@Œi`.¥ @€ @€ @€ @€èW1¦~½rúM€ @€ @€ @€ @``ĘæRN} ëׯßxãÍÓ7uÁnï—/›o¾ù6ÛlÓíî8?^Xºt馛nš¯Ž ôJ·ôcªïÃñV3ôâ(©·Ê]W~è­þéM ì±ÇÕ{&Þ©z¬ƒº3Pñ¿–q•w'?êêvL\÷x·)›ÄrõÛùã`¤ý"wìªU«ú¥·sÜω·ñ9>i/Ÿ®ö†jðG†^¾^³Ñ7¯ˆÙPuÌ® ä/íÕnÄÿ·Øõë2ÙÄE\¸paÙËo8UÀÉâ«ÿ7™ì­eû(x‰Û;‹-êñëÉ ˆ1MVl·Þ~=íëëZýŸˆ1Ugíëqé<éÄçgñÒ(›ÅKÃÿ¨LÇÓ¾âf+Ä›°¿oºaæ@ z×ÍÁ霢ß„ úý öQÿã·¯ê?’‰¿£ù±ØG—oš]­}6àgšžvŸm¸cŘÆBcªÉTßÐ|:Û¯ÍÞ<¾ßgzóºèÕ4Z?ùδÇ4k÷9È@Õ ò¼~Ã)þñã;4Ræ‘G‰A¥çøætºY¨þRZû8lVÏëàæL@ŒiΨ{÷Dùƒ¼ü8ïÝŽêÙÕÿ‘ö—b· ˆÿ-©ÆÏã].Š3Á!0Kµ@IÜ~¥³Dí°E@ŒÉÍ0)¿"NŠËÆÓhýgþEàt<ûk_1¦þº^zëC¾÷€S §ü*å_ºÏÛ·1¦y{é{àùË[)¿¿·Ç/óbL}wѳS¹Ž~éþ鬤»be$™¼™÷Ýí­Ãjÿîµïn<1¦Á»¦“Qü}"†¬TÉäìzfëøÝ+ÿžQ­g.‹ŽtYÀü]¾óìôµûM\`ž]ÿî 7îºüå-fîÎe蟳æß¦Ë ¼ëŸ¾ëiŸ ø¬Ï.ØŒv·Ì×ÿ²?ÿGuFÏà`fRÀú;hŠ1ÕpÊßÜ|º?“/¾:–O¾ûêréìDòGa¹½ãÿã_z£›(_Ïl—W°ü£J¿áä•iûË œž¹mudâ~Ž?Ç­x÷®Ve›£;˜ÓÓg>ó™×¾öµ/yÉKâëÞ{ïÕæ§öX²d‰jfêæÉ‰–â=Nµÿ™"ûãäGyÆœ{gìM¡õæuÔ^‰1 ê•íåq‰1õòÕéÁ¾‰1õàEÔ.U&æì²,ƒz­[ÇUý+jüÿ©+5.}ŸŽÔçX.œS '~•Šgùg7Í>}ÉO³ÛbLÓ´{o äÂø„(ë§Æ[\|+ÆÔ›«C¯ò *ÊeˆÁo8i%ÆÔww²OV úïˆ2‡:Ù#Øž@ ÌQŒé¤“NzÎsž³ÑèGä™bý’LbL3xW•B>åÈgðà57µÿ‘öÿÕsÃî,=.¿ÃU¯ñ¿pñÿä=ÞgÝë_ZŒÉ¤rý{)û¨çš}t±z¡«ªÄõÂU˜'}¨M죮Õ9Ÿ'ós˜&•›Ÿ×½GíC¾Ökõ³d£S '«1ÅÊüØ?¯íßþ”{îÏ­S¦³c/ 䜯#’Lñcêåë5VßÊTN-ç7œ2µZÔÊÕôã®Ïc øc‹{càæ"ÆtÉ%—” S,TóL‘dcêâM¿ÖT?×ÏTÔÅþ8õÔªÿ#×Ô?˜˜£½L k —ÿQ‰÷:1¦»Ä=5œj $þúãï›=uuµ3bLƒzegi\bL³ë°­ùs°|¾›÷*\1On1¦yr¡f˜>äk½”ñ‡Áüg“ Õpª¿J…’¿¼ ÌûÀÄâó'neË>(? sFàè¹S]¾ÒÕêT|ÀÕ$â:öã@f¼ÏA®~"à‚vÀî ˆ1u×ßÙç@`.bL;í´S–aŠÐRDš"·3Ê•ÂLS˜]N5¦™º3jÕJâ°ÂÈ3e;—Ç)“5Ä‚?ÃÍ¥¼sõ¸@ü1ÿ'<2L=~±ú½{Õ÷áø{AüªÓï#ÒÿÞ¨Þu¹Üû}ÖÃ. ˆ1už:?ü· Ó¼ºjs-yç™WW¿›SçôcÏgµÏåÝÛ´UçÚšÏAgõ&ì̓×þÿ«7;©W&+P~FÚ#ÿ}{üdôÝ'ËØõí«ÊFâ7œrQâÞÎOÍ|@ÐõUf\ÀdÇ3Nꀽ&01¦-·Ü2‹0UKiÊ$S„œ&[IŒ©×n#ý!@€@Ï ”ôì¥Ñ1 @`°âoèƒ=@£#@€À@ øŸè¼¬E€æ­€ßmæí¥7púZ`ê1¦L&Å£5‡ôÚ×¾6ŸŠS‰(e¦ò(SË}æ3Ÿcêë{Hç  @€ @€ @€ @€LS`ê1¦(Ÿ›å”"TÍ!E\©D”b²ð¶¥±ö`žI5¦i^u» @€ @€ @€ @€è)©Ç˜ÆŠ+Eq¦Œ7Å´q­±¤x¶„œbᤓNš`t©º™SOÝC:C€ @€ @€ @€ @`šS1E®(&ËÄRuò¸Î³ÅE¶)w‰Gì~öÙg‹1MóÚ @€ @€ @€ @€@¿ L+Æ´÷Þ{׿•‹YäÚÎ4W²J1\dŠØSÙìàƒžl’I5¦~¿íôŸ @€ @€ @€ @€@U`Z1¦ˆ•ÚKiŠoK>©ZŸ©mJ©Ì=GcrS @€ @€ @€ @€˜ÏÓ1•4RÌWM5EY¦Îá¤K.¹¤D N:é¤I%™TcšÏ·¬± @€ @€ @€ @€ žÀtcL%™¤˜.§Š{ÉK^R%Å6TÊrMÕ‡ÓàÝOFD€ @€ @€ @€ @` Ó1E,)ê0•ôR.|æ3ŸiWª&™¢\Sn³Ï>[5¦)\<» @€ @€ @€ @€ ˆ1UI‘IŠKµLRÉ9ÅS9\ÔgŠŠMmK7M$ÏdR¹Á¸ùŒ‚ @€ @€ @€ @€@ Ì@Œ)‚Gez¸H&m¹å–µ(R[*ÄB>J)¦˜Šn"Ñ¥ê6bLn_ @€ @€ @€ @€ƒ$031¦vÚ©Ä’¢8Sk,)²JÕèRnkªÓÌM<Ì$Æ4H· ± @€ @€ @€ @€˜™ÓêÕ«#É”i¤Ï|æ31—\>b9¦–›xtI5&7+ @€ @€ @€ @€A˜™ÓÔÒHSÞK5¦A½‹ @€ @€ @€ @`~ ˆ1ÍÏënÔ @€ @€ @€ @€zH@Œ©‡.†® @€ @€ @€ @€˜ŸbLóóº5 @€ @€ @€ @€cê¡‹¡+ @€ @€ @€ @€æ§€Óü¼îFM€ @€ @€ @€ @ ‡Ęzèbè  @€ @€ @€ @€ù) Æ4?¯»Q @€ @€ @€ @€è!1¦ººB€ @€ @€ @€ @`~ ˆ1ÍÏënÔ @€ @€ @€ @€zH@Œ©‡.†® @€ @€ @€ @€˜Ÿ#1¦ 6ìµ×^‡ôÃãk_ûÚå—_>?/˜Q @€ @€ @€ @€<‘SŒ-’LwöÉc𮄠@€ @€ @€ @€˜·£bLóVÁÀ  @€ @€ @€ @€袀Sñš @€ @€ @€ @€†€“û€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º, ÆÔå àô @€ @€ @€ @€ˆ1¹ @€ @€ @€ @€è²€S—/€Ó @€ @€ @€ @€ Æä @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ @€. ˆ1uù8= @€ @€ @€ @€bLî @€ @€ @€ @€º,0ÑÓ‚ V­ZÕåÎ:= @€ @€ @€ @€}.°ùæ›·Ž`B1¦È0m´ÑFbL}~è> @€ @€ @€ @€n ¬_¿>2Lo¼qk'Æ1-\¸p=öØtÓMŘºy › @€ @€ @€ @€@Ÿ l³Í6‹-šbŒ)Ç.ÆÔç÷€î @€ @€ @€ @€è 1¦ž¸ :A€ @€ @€ @€ @`> ˆ1Íç«oì @€ @€ @€ @€zB@Œ©'.ƒN @€ @€ @€ @€˜ÏÓŠ1m¾ùæ«V­šÏ|ÆN€ @€ @€ @€ @€Àô¦cšþé @€ @€ @€ @€m6âB€ @€ @€ @€ @€î ˆ1u×ßÙ  @€ @€ @€ @€x\ŒÉM@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ @€]cêòpz @€ @€ @€ @€ĘÜ @€ @€ @€ @€tY@Œ©ËÀé  @€ @€ @€ @€cr @€ @€ @€ @€ Ðe1¦._§'@€ @€ @€ @€ @@ŒÉ=@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ @€]cêòpz @€ @€ @€ @€ĘÜ @€ @€ @€ @€tY@Œ©ËÀé  @€ @€ @€ @€cr @€ @€ @€ @€ Ðe1¦._§'@€ @€ @€ @€ @@ŒÉ=@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ @€]cêòpz @€ @€ @€ @€ĘÜ @€ @€ @€ @€tY@Œ©ËÀé  @€ @€ @€ @€cr @€ @€ @€ @€ Ðe1¦._§'@€ @€ @€ @€ @@ŒÉ=@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ @€]cêòpz @€ @€ @€ @€ĘÜ @€ @€ @€ @€tY@Œ©ËÀé  @€ @€ @€ @€cr @€ @€ @€ @€ Ðe1¦._§'@€ @€ @€ @€ @@ŒÉ=@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ @€]cêòpz @€ @€ @€ @€ĘÜ @€ @€ @€ @€tY@Œ©ËÀé  @€ @€ @€ @€cr @€ @€ @€ @€ Ðe1¦._§'@€ @€ @€ @€ @@ŒÉ=@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ @€]cêòpz @€ @€ @€ @€ĘÜ @€ @€ @€ @€tY@Œ©ËÀé  @€ @€ @€ @€cr @€ @€ @€ @€ Ðe1¦._§'@€ @€ @€ @€ @@ŒÉ=@€ @€ @€ @€ @€@—Ęº|œž @€ @€ @€ @€1&÷ @€ @€ @€ 0ß?üð×t|üMóÑy›yõì_þå_nºé¦‡|æ™gÎ÷Ëø'# Æ4-Û @€ @€ @€ @€ƒ(qœÏé«K–žUÚ §œ•mñÉöÖ·¿kË·¿ëø“Ïj'y\³{âюɶ$۲﷣OXmQ´ÅÃíøeG5ÚéG·#Ž?ýˆã¢íðc‡ÚaÇœí;ÕöÝS¿Ýlß:z¨ºhii‡,ZÚhGòÍf;8Ú‘ÙN>øˆ“j¶›ma´Ã‡Ûa'ã°“¢ð¡öõïœôõmÿoµý¾µ$Ú¾Ñiúçñ¡þk‡,i¶öþæp;ø„¯6Úâ·¿g‡­·Þzocš-1¦Ù’u\ @€ @€ @€ @ _"Ɖ¥µülí–vÏýfûÁýî´àSÑî¾ï§Ñîºw¨Ý¹á‘lwD[ÿÈíö“Û×ýäûÍvÛÚFûÞÚïžF[Ól·þ Ú¢Ýrw£Ýí®hßí·ol¶îˆöP´ëoo´ëšíÚïÿ0ÛêÛíšhß{0ÚÕÑÖ<¸ªÑ¸êÖ¡¶ò–¢]yËývóýW4Ûå7E»ï²h76Ú¥Ñn¸ï’îvñõvQ´ë¢mXíÚ f[½aùêõÑ.¸¦ÑÎo´uç_½î…/yù>‡.9wÕºhç¬Z{ÎUvv´•kÏj´{>þé}Řúåþï‘~Š1õÈ…Ð  @€ @€ @€ @ kcŠ’K%·TÒK`úA3ºô±ŸŠvw 0ÝûÓ‘S%Ô¦Q¦fŒ)3Lk¦FŒit†éG Ó]C¦fŒ©™aªÆ˜Fg˜1¦’aj‰1­¼µ‘aŠ1 g˜®hd˜š1¦Q¦ÖÓ†ZŒ)3LµÓyˆ1í,ÆÔµÛ¹_O,ÆÔ¯WN¿  @€ @€ @€ @€™ˆÓñ'ŸÕ -5rK]i÷Ř¢Ó¨ L#¦GJ¦IÖaÊ0ÕJ1Ê0M¶S3Æ4ÙRLÃÕ˜š¥˜*Õ˜†2LÕjLW¯ËSL'׬Æ4ªS³Ó=ÑĘfêæœ?Çcš?×ÚH  @€ @€ @€ @€öÍÓ™C¹¥á’Keò¸XøèÇw‹64\3½Ô:‹\ 0•¹äjE˜&P‡©QŠiò¦‘åÚ–bjÖa]ŠéƨÃ4ÅRL1£\5ÆÔvF¹³®còZ›´€Ó¤Éì@€ @€ @€ @€ ˜@ĘŽ;éÌÌ-ÝY)¹TfŽËS%½ôÈíë‡æ«Î"WLe"¹æ,r#ÉÅtr7G»+Zc"¹R„©9—ܬd˜®¸y8ÃTŸQîÞKn¸7Š0e»èºh-ÅT‰1UJ1]µ¶”b:³czËÛ¶ jû¯_ýzÀîÙA1¦Ät( @€ @€ @€ @ /"Æt̉gÜe–ª­Yr)«.íøñÝ¢Et©:y\kù¥’^Š:L#¦ü(ÒK•Sû‰äêu˜¾ÿеßÿa¶Õ·5Ú5Ѿ÷`´«£­‰ LÙ¸êÖFk[‡©s†©Ä˜.jĘÚg˜bR¹ ®i´óm]–b*1¦±J1cúÙÏÕ—÷‡Nω€Óœ0;  @€ @€ @€ ÐÃÓ’3"®4Ü~ÒH,UBK;î¼[´Zá¥ÖÚKYä†Ë/•)ä:˜Æ*ÂtÝèÓd˜†bL×n¸0Ûê `+Ãtîªu/|ÉË¿vÈ ç\Õ¨Ætv³Sµ“Sßì½Û51¦Þ½6zF€ @€ @€ @€Ì@ƾ»dY¦”ªí¶uCs¢}dçÝ¢ å–Öþ8ª.ekä–²UÓKÃå—êSȵ›E®aºîö‡­¥S3Ã4\„©Z‡©Y„iFê0™aª–b®ÃtÞªucÚû›S#Ã44ÜÚ³VÞ¦lm'•Sinîç>=‹SŸ^8Ý&@€ @€ @€ @€fL bLGŸ°,RJ¥}/²J¥ÝóãìôÉhµÜR5ºT­½Ô¹üR³ÓCÙ®¿}¨e†©6‹\k¦á¹ä†L%Ãtå-\yËýWÞ|Ì"×h7Ýy£ÝwY´íÒh7ܳÈe»øúF˹ä¦aªÇ˜VF€©‘a:k8Ã$Æ4c·æ|:Ó|ºÚÆJ€ @€ @€ @€´ˆÓ¢ÅËFJ+UË,5—?¼Ó'£ÝZ)¹ÔÈ-Uª.U£K7GÕ¥lw>¡¥Òn¸c(Àtýp€©c¦^ó½Ö"L¬j[„©’aj˜š¦`ªd˜2À4Í Ó9«Öf5¦j¦j†IŒÉël bLS@³  @€ @€ @€ 0Pc:êøeÃ)¥GD©Ö"ôÃÇ>Y¥j»ùî5Ú]Ù†£KH/E¦áÓÇ©ÀÔn¹F¦[­^„éæ±Š0 ÕaÉ0]רô"Ûµ.̶zÃòÕë£]0ö\rQ‡)2L1—ÜPŒ©]&“Ê Ôkc#Æ4‡ØNE€ @€ @€ @€ô¤@ĘŽ<þôZJ©|Y¥È0EN,5rKCõ–ÚU]jNW™9®eò¸ë¾ß&½ÔœB®Q~)ÚÕÙÖ<¸ªÑF*0•Y䚦Ê,ræR„©ãDrækG2L`jd˜®i´ómÝùW¯;/Ûªu`*¦ˆ1½ ª1|Bë\r™aR©'oó^ïÔ„bLË—/_¸páš5kz}4úG€ @€ @€ @€˜¼@ĘŽ8îôjJ©V`éCÛ5ZÎW›*.çŒkæ–:E—¾~Èw/¿þY{é¼Ënþäg¿ú­£OèR3½ôÃs.½é“ŸýÊIç\YI/5L‘[ŠöÍ£NùàN»ïòé/ŸqÑcT`jÎ"WHî†û–^pýv;îöé½îô©½&=‘\%Ô¦s›E˜¢5&’kƘ¾Úˆ1 …–JzIŒiòwß¼ÛcQó±~ýúÚÈÇ1m¾ùæÛl³Í{ì±é¦›.]ºtÞÉ0 @€ @€ @€ 0èÓ±§eD©mJéCÝ5ZÛÄÒ w<íúJÉ¥‘9ãbò¸fnié¹+ŸýÜçsÊZ:÷²›ÿúoþöÃ;ÿç›ßú®wo³CÔ^:tÑÒxv‡vó–ïzÓ–ïÊ L`Šö¢—lòÆ-¶úàÇvßê};<ë9Ï;áŒË¯¸ùþl—ßÔ~¹KohÌ"÷ª|Ã;¶þÐß9éßÞò΋®oT`šH®Y„iÑÒKßÿáOŽaj;‘ÜÕõ"L ÓÊFkƘ·¦—Ęýµ2Ýñm¼ñÆ ,È$R-É4NŒ)*0Å>yþU«V•åéöÈþ @€ @€ @€ @€žˆÓaÇœ6\QiT]¥L)}ð£»FŠ+N, - ç–²êR¶ˆ.ýÃëþµc:ù‚(¼Ñ¥(¼”3ǽè%{ö%7ýýkÿõ {œé¥-xÖeò¸H/E†©1\s ¹Ï}å ø6LÇ/»ìðÅ眶üú˜?.Úq§_é¥ïα§_¦cN»ô½É§÷\¦ïžzi˜N:ÿÚC9ûÄó®½ðÚ »iáÛßýÁ3.½í‚1&’.´îœj¦•ks"¹ˆ1}EŒ©gnà~éHL¦ìm$™âQíùøÕ˜ÊÖq (ËÔ/ÃÖO @€ @€ @€ @€À"ÆôcN@ÒXíƒ;îúw½.RJÕöý¡bKÕÐRæ–ªíÝQõè³_‰ÄÒwO:?£KGÇB#´ÔX^tÒy]:êÄóJí¥ƒçyQ~)f‘{泟·×GÆDr±ðïïùзŽ=û¯þúe‘aÚ}…±}‰¯{ìDd˜^ù¯ß÷Ð%\³þüF[wþÕëÎnm'’‹"L™a:ëÊ{^ðb1¦ Þ\6k/1¤˜Z®úÜDcLQŠ)j:µNJGš @€ @€ @€ Ðïcj(Å”p9+ÜvüD´Z\©5±饨·tÍmF±¥l1a\LWÒKÃÑ¥ósÚ¸ 0}h§Ý߸åV‘[ŠSÄ’>ø±Oeí¥H/Å·GDŒixò¸Ëoºï²›…—^øâM.½ñ¾h ;ù/Þ$Ê/EŒéœ+n¿øú{#À´íŽ»]tݽ/øë—zìÙÑ"·å—"Õu˜b¹%ç®þÔ—¾ñÍïže¡†2Lc˜Î‰YäšÉ ˜VÞ“ÓÆ‰1õû=ßÝþG€©uR¸ ŘbÏÈ0E’©»pv @€ @€ @€ @€ÀlDŒéÛß=µCQ¥í?ò‰hµ2KµÄRæ–"±4ÔÖ<%—¢ÞÒ!‹–.:éüH,}á«•èRN׈1-9/L[½ïC¯ù§7lõÞEkä–š¦˜9.bL1s\¦—rò¸S—_¿óî{½së]rÃ}‘^ÊS¤—"¥_c ¹(¿´íG>å—"½SÈEkĘVGŒéO"Ã-¢KÑ2ƘJ¦±f‘kf˜î‰–&1¦Ù¸çÕ1c^¹Ö SŒcÊô“:Lóêv1X @€ @€ @€ 0¯"Ætèѧ6cIÕ6RT)cL¥ÆÒ¨¸Rä–š‰¥œ'n¸=õ–¢ÒR¶$½ë};\xÍ]oÜb«Ïå æœq¼ð%›,»è†e+nX¾êÎŒ.E™¥Ó.¼!L]Š“ÇÅÌq‘^ÊÚK_9ਨ½ôãÏÉ L‘[:åüë^ð×›Dz)bL]·!ÒKQ~iÛ2Ê/UcL‘^ŠS˜b ¹?¹ÇÁGŸù¾vÍYä:˜†f‘«f˜TcšW¯Ž™lÌ%¶Ç'Æ饨è=š… ÎlÏ @€ @€ @€ ÐuFŒiÑÒ‘BJÕ¢JÍ”ÒvþD´–¬R†–‰¥U·6BKµõ–í–F‹ÂKG.9/f‹;øÈ“#«tä ç.øÏ/G¦ˆ.}î+m¶ÅV‡/>÷ãÿ¹×«ÿé ¥ðR¤—Î[yG䟶ßñS]úô^ £ðÒ—82ÒK]ŠÉã¾uÜ9¯ú‡7Dí¥0EŒ)2L+®Ýå—Þ?c:䘳¢Ež)ÒKo{÷_ÿæwüÝ3ãëÛþã}æ_¾èe‡Ÿtqf˜ÎYµ6æšB®Ý,rbL]¿K 9#\Æâ±|ùòê Æ‰1ÅÖeO1¦¸  @€ @€ @€hˆSLýV©¥4NʈҚ¶ûð.ÑZƒJeM5±”¹¥(¶¡¥¡vóý»üç—KÉ¥ƒŽ89j2}ࣟ*U—>ûå7{Ë;?¾û^¥ðÒ¥7Ü-§ÛùS{½êß°ÝŽ»sÚ¥9sÜÙ—ßé¥h»ï¹0ÓK]ŠvÆ¥·í÷­%Q~食ÜcÙ%·E‹ÚKQéükÖí¸ëQé#»î‘˜>ò‰=>ò‰/ 0­\ÛœB®}&“ÊyíLS bLÕ$ÒäbLÓ<·Ý  @€ @€ @€ @€½/1¦ouJÛ”Ræ“¶ýð.ÑJi¥ *•6WŠÜÒÍC-'‰+­™XÊÖ˜-®Zr©mt)LZ*-ÒK]­1sÜPkæ–²En©´ V7&Ëùã"½t~sæ¸Úüqç—_ªÀ4áS†™^ðâ—åàŵMÕowþô¾oyÛV·­ýIµýìç¿êý›A»%0N5¦nuËy  @€ @€ @€ @€s&1¦ƒ @€ @€ @€ @€³)1¦¯礋®‹(R¶‘@R.¿÷6fJixJ¸¨®T/°4\l)RJµV -Ô['·´n"Ñ¥³VÞÓ!„4ý§Ä˜fó~œ§Çcš§Þ°  @€ @€ @€ @€"Ј1}ûÄ !µm[àãÑFMW›®]u¥’[jM,u-5ª.­Š¸Ri£f‹;'ê-e]ui¶£KÕð““—ÏŒ ˆ1Í8© @€ @€ @€ @€}&1¦ý¿}bÌòVmÕâIïÙþãÑZ+*u*åôpÃsÃLW›!®%´T¯·TË-U'Œ›Ëè’SŸÝÖýÖ]1¦~»búK€ @€ @€ @€Ì´@ĘöýÖ’¡šI«×7š ¤Ò2ÆT[Y¾Tž.²JmâJõ2KYo©^l©sKµyèTcšé{Ðñcr @€ @€ @€ @€ó] c:tÉpiÝùEÝÞ½ÝÎÑ2™TZ£ŠÒXmÔ”p¦‡‹ÄÒ¡¥µQi)[-BÔ ßŠ1Í÷×Ì,Œ_ŒiP’ @€ @€ @€è+ˆ1ísè’±¤Œ17f8iTPi¨ºRÔXjF”ªíì«Öµ•kcn¸lg µÞ -µ§Ä˜úêïΊ1õÇuÒK @€ @€ @€ @`ö"ÆôµC–Düh¬öÛííœvɤ1ƒJ™X;®Ô¨´te/VZšHµ'1¦Ù»çí‘Řæí¥7p @€ @€ @€ @`H bL{ó„‘RI¥fÒð»¶Ý9Zk!¥v)¥‘ÉàʬpýW+Ò$ÆäÅ3ãbL3Nê€ @€ @€ @€ @€@Ÿ üË¿üË‹^ô¢3åãÕ¯~Í&/eµ=ç¹Ï{Ö³Ÿ[[Ù•oÿèÊyk'ý½ßûÿþê/îГçýÙó·~ÿ‡n[û“jûÙÏÕgw†îΡ€Ób; @€ @€ @€ Г6lX^yœwþGŸ°¬Ö?æäÖ•s½fÉÉß¾ø%s}ÒŠèÀD4n¼ý~1¦ž¼ß{´SbL=zat‹ @€ @€ @€è–Àýê×µüM|{Áš/²j£Ë¾Lôg²ÝP©[·t_œWŒ©/.“N @€ @€ @€ @€s'Л1¦5÷ÜÄ51¦ï^÷‚Éæ‡zd{1¦¹»‰ûðLbL}xÑt™ @€ @€ @€˜MÞŒ1e)¦l}ZIŒi6oÛ¾?¶Sß_B @€ @€ @€ @€fV cL¥SƘú´ “ÓÌÞ¨v41¦» †C€ @€ @€ @€LWàÿýú×ëxtí?ëÐnºóGwß;Î60©g/¾ý«¥S.¬ºûøIaV7þÁý^ÇÃãž"òaÓ½6ö\1¦Á½¶FF€ @€ @€ @€ „À¯þßc‹®{F-Æ´äæ Äà ‚À€“[ @€ @€ @€ ÐÓ×ß»_-ÔßÞùðÉ=Ýo#01¦ÉhÙ– @€ @€ @€ 0·mK1eŒIA¦¹½Î6»bL³ëëè @€ @€ @€ @€é<üØ-«Ö}6ÛÙßS¤—–ßùž²æÑ_n˜ÎÁíK wĘzçZè  @€ @€ @€ @ “À­1¦u?YމÀà ˆ1 Þ55" @€ @€ @€ @`0ĘóºUS@ŒÉ@€ @€ @€ @€è1¦þ¸Nz9%1¦)±Ù‰ @€ @€ @€ 0çbLsNî„s' Æ4wÖÎD€ @€ @€ @€˜Ž€ÓtôìÛãbL=~t @€ @€ @€ 0$ ÆäV`1¦¾¸†F€ @€ @€ @€ ”€Ó@]Nƒ- ÆäŽ @€ @€ @€ @€ô‡€S\'½œ’€Ó”ØìD€ @€ @€ @€˜s1¦9'w¹cš;kg"@€ @€ @€ @€LGà?:óU­Þ°×tb_½) ÆÔ›×E¯ @€ @€ @€ @€uŸüâΈ1­Z÷Y4O@Œi𮩠@€ @€ @€ @€ƒ)ð‹_=¼jýçÖÿdù`Ϩ淀Óü¾þFO€ @€ @€ @€ @ Ęzà"è @€ @€ @€ @ E`óã6§B`þˆ1ÍŸkm¤ @€ @€ @€ @€@߬Z¿JŒ©o®–ŽÎ„€ÓL(: @€ @€ @€ @`æÖ<¸fÓÃ6¶èºEfÚfé6±+7>`ã<É• ÷¸hXˆg£å–3w~G"Ð1¦. ;% @€ @€ @€ @ ³@„“¢ SlÑ¥Œ(Å·Wʽ"Ø´üÎåñ5òLñí#¿x¤<–@Ÿ ˆ1õé…Óm @€ @€ @€ @`²ðR5ºT*0Åú-­d}l5™²‰1 òÝ0?Æ&Æ4?®³Q @€ @€ @€ @€ý#¥Œ%U£KQŸ)*0ÅÊ 0eÂ)¾F‹õKo]Ú?ãÓSmĘÜ @€ @€ @€ @€Þ(E˜rò¸ì\†–baÁ9 "Ò fŠ…Ø, 2õÖô†À$Ę& fs @€ @€ @€ @€À, d5¦E×-Š|R9U|é¥hQx)ª4ÅúXÈ52L³|A~.ĘæBÙ9 @€ @€ @€ @€è Æäö @€ @€ @€ @€ @ ËbL]¾NO€ @€ @€ @€ @€€“{€ @€ @€ @€ Ðþ׆ÓÖ¼f̓‡÷Gwõ’ÀdĘ&£e[ @€ @€ @€ @€@÷~ò‹;YµÑªuŸí^œ™Àl ˆ1Í–¬ã @€ @€ @€ @€fV@Œif=­§æWŒécûØF&/°zõêžzݶíÌÃ?ü‚ýÍ™gžÙû]ÕCs&pçwþùÿù«¾x Ï™‰ @€ @€ @€ôµÀ}ÞõW/ú›ƒÙ¾¯G¡óÚ Ì¯ÓÖ[o½ß7Y÷àÏFµ~¶v¨=ºï7yÛ¿¿kíÞsÿHûÁý6Ú}Ñ~íîÒîýé]•vç½?½sÃ#Ùîȶ¾Ñnj?¹}ÝO¾_i·­ûÉmk‡Ú÷Öþ¸Ñîi´5¥ýàÇ·µÝúƒÝr÷H»ùî5Ú]vÓ]µ;¾±Òn¸ãáîx(ÛõÑnj×ÝþÐPûþ¯­´Õ·ý°´kn{ðšï µ«¿÷`£­i´UCí«ni+o}`å-CíÊ[¸ò–ûíæû¯¨´Ëoº¿Ùî‹vY´‡Ú¥7Þ×h74Ú%7Ü;Ô®¿÷âJ»èº{/ºnC´¥]»áÂJ[¾z}i¬^Á5CíükÖ7ÚÕë¢WÚªu玴µ‹N½üÿèYç\µ6ÚÙÙV®=k¨ÝsÖÊ{μòž¼øåË—/ïñwÈ0ýÍ&›uÂÙÿÚ7H2õøÅÒ½9ˆ ÓßlòŠãN½0¾J2Í» @€ @€ @€ÌžÀÈGÃÿä£áÙcvä® Ì»S•"¥Tk÷ ç–ö=à·þû»2Ã4fz)bLõÓPzi$ÃÔ 0uÊ0 ˜"É4¦áÓÄ2L?ìœaZµ¦CŒ©C†©cjd˜†cLC¦fŒi$ÃtÃè Óõ‘acºvÊjŒiõ†Ž1¦F†©cªd˜Ö³j$ÆT2LÃ1¦F†©_bLñƒê¥›lºø´ #ˆvÅ ë^ãÇU×ÞQ¸‡"ï‹3.\¯‹«nÉË$™zèêè  @€ @€ @€À|4<4»ô—Àü‹1pHµÒÒH\©™[ÚçëS½êR–_]Š:LwÞÛ’^®À4Á"L·UŠ0µ«ÃÔ(ÂÔ¦S³ÓÍ¥S,t®Ã4Í S³Óp¦X?Ã4“¥˜1¦Ù*Å4~ŒéÊ>¨ÆÔøAõ·‘aZµµ"®´Ë¯—dê¯÷a½yF†éo7=sŵåu±ü*I¦™wvD @€ @€ @€9ðÑðœQ;Qæ]ŒiŸ¯³}J©™UúÚ׿1¦¶¡¥œ?®L7jò¸úüq1‘\} ¹˜N®L!W«À4͉äÆÉ0Mn.¹–:Lsœašt)¦‘éä¢&S™N.š3ÊSŠ)&’ËIå:”bêñIå†~P¾"êl•¸FdÎ.½ní«ÿQ Á.¾µ:u72ÃtÖE×–×EÌŒ¯‹ V~_M¦n^ç&@€ @€ @€˜ª@ëGÃù˜†§*j¿˜w1¦*e ©m‹g·|û»š•–êÅ–Úæ–*U—ÚG—¦–^jSéî¬Àô£›J¦;§[„)S/¥]sÛƒÓŸKnZu˜&ašÖtr‘aj1µrm³ M'¦Œ1ºìœþøç¥ýìç¿ê…tþ :áô×ßþÐuߊ1åϪ«n}à’k#ÉôúÓ—Ñ ]Õs&¦³/º¶ùºh–(»í‡åuqþÊï¿øe¯Xuõ5sÖ'"@€ @€ @€ 0M OÐî}$0ïbL{ïÿÍZE¥ê·ñì–oßꎨ®TÚúG"«TÚíë#®”í'Yr)Zd•ªí¶Ñ…—†fŽ‹ùãîjkîùñPûÁojmæ»%¢KÃé¥Z€éÆIÏ"×ø8?rK¥0_„iÕ­#sÉ­¼õF»¥Ñ®l´ûíæF»¢´›î¿|¨ÝwùM÷]íÆ¡vé÷5Ú vÉ ÷–vñõ÷–vQc.¹ÑÓÉ]»aŵ.,mõä2Lç­ZwîHk˜ê1¦•kÏ®d˜Îj˜JŒéè–U‹iÅ=Óõyþ Z²ì¢š“–RL͸FãbÅE¹hõ=¯úÇןrê²Iõvýúõ›o¾ùÆÍG,¬Y³&v_µjU®É•ñˆ•e³òÔÃ<ãòåË7ÝtÓ|v›m¶É•±I¬,]Š#çѪ,çÍ•±}ŽO—ª O|DñYU~œŸÅAâcßÖÝ—.]š+ãS¶üÌ7¶ŒÏ£'~"[ÎCycúê~߬ƒjËñìoߪ’UWjM,ez©pÉåïEh©’[ªM·¦cz©]#½TŸ?î·o¸#ÚCÙâcûˆ³d‹7¯¡öýñLÃE˜"þ2ÔÖ<ØüÈ?Û™‰)­˜š¦v¦›[Læ¡S3Ã4V€)’LÈ0žK®2\Û¹äÆÊ0E’騜Tnì SVcêµS-ÃTûY+ã‘*[qÍ&›dŠŸ4 .ÌwÃø¹߯’Œ1•·ÈøT²Gµ§JÀ"2L±K|ͽ,Xé¥ü‘ßæúØ=×Ç1ËÊü1–+3®9Ø+3UÚ ” SfûZK”å»V¼.νâ{=¥$SføÊ dF.DÜám«ëpðx9´M>u(¯£¹RB€ @€ @€˜{ ç,=Óüh¸$â#°òð¸ÃŒsó®üy¬qó€ñqsl–oMê,ãvÃ)0cLg ¥j+µ”¾²ßÁ[¼m«Zu¥òmk\©¹¦™X+´”…—ZsK?øQ[ª¶Ñ饇;Mך^j`U~©e ¹ö˜&`É0T`ŠRL3^„éºÑE˜®³Ó׬o›aªaZwΪ‘:Lg_µ6Z‰1•¹äªu˜z³Sü zÙßnzⲋ¢(Wf×ZgÎjÄ5šy²¨ƒµüê¼ò&Z“)~l”²Iù–Ñ¢xÔ²J%{ŒcŠŸI‘Fª¾oƳH5EÒ"#M™p*‡ª¥C2)RýW~ä{±AMS 2Lñº8ûâë"ÜY/Å4\¢läuqã}g_>é$Sü‚7a~-½_ì2Û”¿áeb=¥ZR,äšüM.^_ùËY–‹GüÒ¬ýn—IÁüÅ®Z±,ÖÇ·q„|”Íj‡*'-½*ö:šæfw @€ @€ @€Àœ Ô>UÞ¢ñX3Æ4s —hóƒªR„"ÿÍ|ùô*‹0å'\cŠ5ùiWõ³³œç$?ð*Ÿ…å|>sèDý(0ïbLTj™ôm¤œÒWö=ø-oÛª]\i8«4:®4ªÌÒpb©ZŠ9ã†g‹'·ô£›ïê]ŠÀJ³ðÒèÚKSK/ —_º¦”_Š…‘òKÍ L•òK™ßÌ)äj³ÈM.À4E˜:O$·þü«×E;¯Ò:g˜¢ÓQKÕ˜J†©L$W]è©jLC?¨Îhd˜†JÎTg”«ÌœW§cj²_pÕÝL2ÅÏŒZ¥™ŒeV)¾æ#~•´ÓX1¦ÖâIeʹX(?ŸJŒ)~te!ÁøqXj8•wÕÚTtýøn«Ï³'¦s.¾näuñý¡™›Ó,ŽÊ¡7¦¹l¾.μtÍ_ÿÍ$f—‹;3_%„—·qÖFÊ„S¾LòwµøÍ,îÛ|¥T#P¹&~‡+õÉjÕ˜J¤¯l“¿–£årt&wŒnä1³S¾”âÛèU-2ïu4{7¡# @€ @€ @€fV ÍGÃÃ5>량†Ë¿Ì¯ö¼ü«ø2N|–,Ê µjLùmëggµÏªòc¬Rÿif¹m`æ]ŒéËû4T<©]¥xö-oÝ*ÂIÕÖ(§ÔÚ~P­±q¥‘ÄRD—j•–òÛÚlq£rK‘aº³Ñâ3øj›ht©Y'ê-UÛêÛ~XÚ5·ýðš1ÒKµS}þ¸Q¦ærÑ¢êR¥EVf¸Ý×È O!× ”6z¹K®¿7&+müYä&_„©>‘\K¦œHîÈFŒé™g­¼§µSI2õNŒ©þƒêŽÆÔYg+CiÕ¼m3ÆÔ¸1_PŸ·ò®Wþý¿œrê²Îo^ñc£VB©Ä˜6Úh£ŒeÒ¨§CŒ©6­i5Æ»—:OÕ¼m-“Õ•e޹yç5h“ajÉöÕrèåuqÆ%k^4á$SþRUñ•)s8Õ*e¹&v) ¤üõ.Ö”°y&ŸZg‚‹-Ë‹%guŒCÅB™Ø1ŸÍ9³XZž.•iª8o-èu4ƒwC @€ @€ @€fU`œò3ôÑpkŒ)>`ªfòó©ò)UνkÚÆ˜jŸÅfµSë‡Ñ³jèà}*0ïbL{í{PûXRsê·½öiĘbatE¥zJ)k,Ý2F\©]bit±¥1BK:"£'Œk”ÛÉvûP‹ØÊHë]jD[¦”^êP~iú¦jz)–'`Z¾z}LWZÛYäF˜ÚL$טNnåÚf¦¡SÛ"L½cj›aÊé䢵+93TŠ)cL]·áœ+ïÚt¼$Süh©F”â}-¾Íy¬Ê§Ú›ÝX1¦Ö mþXªþôŠ5QQ¦Ô¤©¹üäËoµr5}ú†«Û3.¦—Öê0• Sç×EóýgÅuN¿xBI¦ ×ÒE‰1Å+¨ìUûµ/#McLñlÎÜcŠ•¹{‰ý•CE’)§®+)(¯£¿÷ @€ @€ 0KÕ¹ä230RÞb6?ÎùFÊ´<ùUù Y“"¦cŠ}k©¦YÒsØ~˜1¦}*½µ.ì¹ÏA›¿õmk)ÕV•VÊKwU[en¸œ'®Yf©µÒRV]ªÕ[jÍ-E€©’[§êR&Zª…—:Í·æjí¥O/ÅœM )m ¦ W¯ÜRiT2LÍÓ$f‘;'¢KÙšE˜Ê,rGžÒ¨ÆÔû1¦øAY%ˆç’kþ Ê\C¥˜š5KÉ™Z)¦‹®kÄ5.¼vÃÙWÞÙ9É”u\J—Œ(ÅÊ)Ęr>¬R©T‚©&?âD9mj¼“–‰´b¹LÑÕïï°ú?«™a:»:—Üp†)³}YKs¬RL‘í[qmãuqÚE·¾p¼šLqV •e¥ê¯q±Au*ßLÆfe–Æœ¸dÌóµ>YW© U~í+³ÂµT®ºcõPÑF¬ÆgõZ88 @€ @€ @€ÀŒLû£á¡À&øÑp)'Qæ)å-bMÊšÎ1¦ÖÏÎb÷üû&.0ïbL{|í Q ¤2×[s!žSK2©cJ)³JcXŠ+µK,ZjäTÚä–2¹ÒaθZt©6mܪ[G¥—VÆ´q£fŽ{ ÌW«½tEëäq™?®Y ¨íüq A¶k‡ÞI#O­š^jWiL1‘\¤—Žè‡SùAÕ ½5êrÕ3LÕš·4¦ü‹iþ“ú5“dYŠ)U# væw¾â5f—ˉ±Ê#Sˆ1Å^ñƒ*SJñˆQ9—V­€Mä-ò‡_< ¹q™]5ßËTcšø{úüÙ²d˜ª¯‹òöXæÊ0 ½.î+¯‹,Å4ôº¸fýÒ·¼ð%/¿òª«Ç¬U#+‰¥åM›±ôüõ.ïä½'ç¾ÛãǘÊ[›jjîû:ý3n½õÖ{|íÀ¡ÔQ‰UâÙ7oùΑ † )u(§”)¥ÎY¥‘¸Rez¸œ'nô$qíCKcä–~ŸÓ—Ö¨;RÚš߼廞ýœç½è%û…½Žb$]zÍkÿõYÏy^|Í L]zÍ?5×üÓ¿®¼e8ºtËý]:舓_øâMâÙh›m±Udb¢}ࣟŠvYD—šé¥Øà[èÒÈÊd]{)Ó3c˜†ÒK­¦Õ£LÕòK1‘\û)ä®^wvΪµQx©´¶˜2À”mš1¦_üêáu?Y>ý;³Ã*?¨†¦Ì‚ÑþcÏó^ó±S¢½i÷3·Úã¼S/»;"hqù¶ÝgÅ«?zÊ;¿xîwÏ»­™a×8ÿêuË.»ãï:&™²?¥Ò48Ùãä1ù(ð௙Рj(ÃtÑuCï®Í÷ÒòVù™ÃWÆ‹â5—Æûpý¯‹¡ôd%Ï»zÝÉËÇI2ÍÈ™xy$Éôw @€ @€ @€@—}øñÕ'O¤c}4%Nª 7>[2öG`•É?Á†'ûyîDÆb¢jCæçªSâä.ãǘ"=—eÄrľ¶ŽÓ—ö>°<ª-dzcª­¼a¤RÎ÷PÛRŽ´fD©´QY¥áR:9#Xk«UZž'nì©âš'UK.}h§Ýß´åV‘UZqÍ]/zÉ&g^|c|»Ë§¿Ñ¥øúÆ-¶ŠÜR|åøt?×T /E†)ÒKqr¦—¶zï‡"±Ñ¥í?ú©hZ&7Þ÷‚oË3–^j-¿4Æüqñ>iƒ¡VI/E’©`J/µL!W 0M3ƦUë>{øêß»ð®­gïE‘?¨N8}EãÖºsF²ÔX²âŽ Ûîyô5[}鼏޻çÊm÷¹0.Ó1çݶÙngÔJ1E,ô‚ëôKoÿ»WwªÉ4{ƒrdc D†i»ßç5ÃLæk+¯‹¡ ã 32LïÚã¼Kn¸/^ñ¶ðÆÝÏ8â¬5»»ñºˆ·¬ÈöÅë¢VŠéükï*ñº8é‚›_б&Óô¯ÝÄcLÓ?—# @€ @€ @€t_ þ%|öÅu3ûÑp| – yÎ÷¢ªÅÒKî*åGã>[ݨâ£áî_}=h'SßDY‡xÄB-H7~Œ©TF‰jL1aM_#7bL_]8V)ÖdzoÚò¹Á¨XR~;:œ4NP©1%ܳµ+µÖXª$–&ZŠ·ªF½¥5#SÅ}âÓ_ŽS–\ŠÓQK΋XR³äR£êR,}m^Škr!sK¯þ§7|öË^žU—† /-<üäŒ1e†é3{õ–FZká¥f ˜Ëld渉LWI/M°üÒ¹Q~©RiÌÓpù¥R‡iÊ1¦[î¹ç¼5»E€éUE›½Sþ Z|ÚŠj€)o›k¢}ïÁˆ1°âŽ¼Ð‹—ßþÆOñä‹ïÌi³"òõªOiøÏÓ× m†ÀB, N½äû/õ?Ÿrê²¾~Qëü@ dŒ)Ûa¦Ì0µâÚÖ`_ΧE˜â&Ï×E¼×yÖšS.¹«ýë¢Yþ­üUÜâu±äü›^ðâN³ËM\±±iÚ @€ @€ ÐgcÊ6F˜©óGÃñX|4üéÃVæG`ª%Ÿ:㸠¾?îGÃY ÄGÃ}vÃ̃îFz©D—Ê´ƒeÜãǘbÓ8DÎYØï\cúâW¶M#eÁ¤/DŒi‹w¶)žTýíû#ù¤¥]j[]i¬Kù1|m†¸j¥¥ZŠyârz¸ÒoXÍ÷¬Ò>ò”¾d“ZÊ’KZŠ.5sK±Ü 0Ý—Ñ¥øö¸Ó/‹(L^ŠÖ0íØhïØúC‘aŠ–¦ÓÆÍFzé¼±Ë/eþ ÑV6ÚYvO¶Zni:1¦0sënß¹úw3À4«1¦øAõ7›42L×5ï·¼†n›¼CÖ4~Ví|à¥ÿyØÊÿüÎÊøAuð©7ÅuÌ«öÅ#¯Ž¼íW»6æï»°Yìª *9Óàj-½X’©ßßÕ«ÿÕS»0Sd˜âuqæŠkÇz]D°/bL%Ôozw¶Úë¢%Û×ø._WÞ³ä¼ÙM2 Ö53 @€ @€ @€ŽÕS»0ÓÄ>>#>^|áíQÞâ›§Þ՘μò“øhøJ »K{N j2m¾ùæFªõlB1¦Ø'æ•‹£ SÏl2ŠÓ¾²p¬ÚH±>ž}ãïè°ÁDÂI%·Ô(™ÓhF8©µµ+µO,U*-uÎ-e½¥lqrLwÄ çVë-]1ZjF—FrKZÊOºüúœ0.ZÄ•¶Ûq·lÏ|Îó>½çÂWýãb93LQ˜®Ñ&PxéÂfá“j»`bµ—&™^0Q~iŠ1¦·˜2ÆtâÍ/ŠÙåf¶-¿e׿ÙäÇŸva5½Ô(Â4`Ê4[NzzüòïG½™íöYI¦üA—,&›‹ Ó¿í¶lé¥w¥ùHÉ™fÞ¶¼†’L{/xüÔÏjº,pø{F¢è%“>\™©™azÅ®•êýº8aÅíñK[³øÜýµ Sëë"Þ‚j¥˜Êëb(Étð.]ñªìG ~ü—MæwÛ @€ Ð ¬ö| @€˜#ã?Úþ#°fe¦f†iB ǧ`oÜýŒøPx«/{ÐÒ›&ôÑp³Hý£aÓõtãC³U *åìrK—.­>;~Œ©Ì€I¦~/È1¦Ïea‡òHñìßòŽñê' ‡“ÆÈ'eb©žRj–Ï)­C©¶Æ¬pÕ‰áÚÄ•FWZúœ~8´ØçgöÙ>÷•ƒ2ÔóÄUë-År–\ªæ–²êRF—¢ØÒ—8²:gÜ þz“H/Et)ª1Etéäó¯{泟÷õïœÔvθœÂ¬´ D—U‚b²³œïl¤M®öÒDË/M!ÆôÒM_úí‹^^­ÀT]>ôê‘ÊLcm3Ùõÿ¶ÝF[¾ã½#%»Ê5tÏ •àŠSd˜†³÷ÇO¬cοmÙåw_2”-Û1¦£ÎþÞP)¦¦mµäL¡8ôøåÿç÷ŸôÃ÷?¥ýÏjšÄ2n ,xÆÖoù—òžó*Ö‚}Y„)~‹ ÓðD™÷xÊMŸúö•ñºÈØeÔ'«½.âEј›²ñ ÜÚêûÃ'¿tà¿müÔŸoÿ$¯ “ˆºb @€ô¸Àgþ÷¤ÕïÖÿ;/ @€,ð±ßûì¶[lÿ‘Otþh8>‹†ÿó;WÖþù,>¸o÷Ñpã#°œ¤| ¶ßw–¾èÅ/}ôç¿êñÿiÓ½ˆ SŽqæc1¦˜Ž®D—.\ú+bLŸûò7ÚÖFÊ•ñlĘj´ $µ›÷mìˆRÆ•†‚J­“ÁÕg…kW©±”%Fj¡¥’^ÊÐÒW¦ ®º£Ô[zõ?½á+ß8*rK ?ùÕÿø†ˆ+Å×X¡¥…‡5ÖTCK‘aŠÜÒ)ç_—õ–"À߯ÇÿÛ~d·h]Ú}Ï…õ×/‹@@„–j¹¥F€itÕ¥FŒ¦Má¥õ]ª¥—š‘‚ÒÖÆTñÞZZËÌq“«½Ô:Áܧ\þ‡ôÌÎϽàÅ/?ú„e+ïX¶øúW¶’θí_ÖýdùŒ·Ï~ö³ñãjäÞ`šñt÷ÆŒ§9!`˜"½?¨Þÿµ ¿päÕIý®ÝðªO9þ‚ÛëÓÉUò¶1ðØä导ðœóo»lù£7^øx|ú®è–Àùûµù#ò‚g<~Þ~QÞ&o~ó›~ûø¡×E3šï®ù.šáÎ^ÅÉòu±üšõ›}ꌽ¿¶ý뢖í«ÌAùÅý½ö_þíÆË/‹×ÅÏoò¢ 0a“>Ù¸‡Å˜úú—E'@€˜'»=÷ñøwÏÝúÿ_ç%@€ @`^ \ul›À>ö{ZP>ÿ–1†q?Þý;WæG`¥Óø G†©ò؋Ί†¯¾ùžÛÖþD’ižüïoosÑ¢Ee.¹Xˆ0Ò$bL±iL$I¦|”ÊL½9Ôq{ÕxýïõjU¤Úr<»Ù[ÞÑR*©V9©|;œLʈRósôέ‘>ÉvK½U烚nì¸Rä–2±4ÜÓÃ5Þ°š-2LQl©´ÃŸsÜé—E¥l±¡¥cO¿´¬‰åL,•Ñ¥¨·é¥h¯ú‡×÷ÔK#³íG>­D—þuówF«êÒ¤¢Kµiã²2J=ºÔ Š6²¢CížxíæF;G‘Æzvâ1¦x+Öfºð®­Ç½ñ¦¶A$™¶ûð'Jn(¨1œÕˆ([T ŒèR¶ÌjD¦Ó/»{³Ý–EØ6ÚG¾~q3ô~¨ÓèéäF2L—ߘ£óãjjWÊ^3&¿°VÓôærüL2ðíãG¥—†ßQK¦m›s,F‹—Ænߺ"ÞÙNkóº¨Ô'íÊ0Ý~y]üü—é3v‘ü@—.Æ4à—Øð @€F bLû¼f`Fc  @€ô´ÀƒwŽú¬`*ÝŽ$Ãg÷úFç†wÿvĘF2Lc|6üÑðèéäâ£áj†ÉGÃ=}ÃÌÎE¥Œ!µVSR¹$вL`•/þI£xöß6ÿ÷qÓHíg|#Ÿ”‰¥fJitQ¥Žu•j–jq¥’X*ÃåÂÈÜpÃ3ÄE½¥Riié×år‰+•’K9ÝÒE×ekÔ[ŠvÒù×6BKc–\ÚÐy¸ Ð4Z»ªKm¢Kã§—šÑ¥™H/•TÓdcLù†~õ]gœ¶æ5Y™iöbLñŠ‹$Ó¶Þ%§Ê¾‘†f¬&mó*_ÄF¦¥—Þ•I²’aÊpXµfàP¦J†É«x—ëï!”SK€©Œk(Éô­ãK$´ä>‡óCo†']tgû×E›lßÈtr­¦|]H2õ÷­5g½cš3j'"@€ 0M1¦iÚ @€‰ ”S»S9L 3äGÃc}6æGã?‹†õA†§“kÍ0ùhxâЖs,0ÑÓwk–N¯üÏìùÖJHeM<1¦”§ÚÇ’"™”m¸ÒX³¿•”RK]¥F¸Ò²ºR£5SJ¥µ+UKÕIâj•–òÛÖÐÒPbi8´Ônª¸zniÌ’K× ÍW›0®G¢KÕÊLS‹1ݹ¡1McL$a¦Y1ÅY"ÉôþvÉ›*o›Ì´å]wB‰¦e-/\É0Å%hNÒ7œa®8V†©õÇÕ÷–-ºæ;{üòÑ¡™)ËkóÑÖßµbé,½Tvž DŒiìS1É$Óþ‡×òºz·¬½.2‹9ôºhù®ší+ÃTM2­[µ<^ñµv¼"æéM[¶“û€ @€@¿ˆ1õË•ÒO @€ 1¦Ž¦2ÄÈ3|zÏ&øXëGÃ9EOëGÃce˜$™àæÈ!Ì»ÓÐ˾äFGŽ>½Çcª…Ê·ÕìÑ„–GÍûVŸ®: \kP©Mi¥È¬Ü0Ôª)¥‘åÑÕôR#±4Tii¨ÌRã­´kð· -5£0mê-EŸkFÚP½¥‰æ–Ö3ºäR£>Pi³0gܸ3ÍM'Æ”ïþrCÛ·†MÛtý#3SÃ,“L#•f†LCÁµÌ¥5/hÎñ×È0 ×ÁšN.ë0M,ÃTýqõÀÍ«–n³i$™ZÇIŽhù¶hP]ˆÙùØDÎ^’LÕ LCo›ÃÅÉF½.V¼.Æú®s†©$™ŽÛ|ãxEüèî5µ~zELä þ6bLƒ @`PĘåJ @€>ˆÏ¿âS°‰=I¦=ë£á¡’%>®—·èœa’dšØe±Õœ Ì¿Só5?V‹w„Ýü߯¸éþhÃó¸»0R<©M¥vµ”ÚOW™n¬ºJµ)áje–*q¥‘‰áF%–:TZjZj-¶42OÜ„sK°gÇÙâšñšFÂfÆ'Œ7ÃL?ÆÔöõºjýªØx̓ C|/y¦òЍ­÷Š˜½{ ,ÆÔ‹WEŸ @€´cr_ @€ ЫïØê?vßãëí?«–·hóÏø×5ʈTÊ[L$Ô ÷*†~ÍGycúÏxÁ—™ÚZâíà_ßüïõ FOèV›ß­Ó\o™L*m¸–Rç”R‰§´ nh>¸¡êJS‰+5 ö´”YʪKŒ®´4~héêu-óÄ5‹Ô•[j¾iç–º]š©Iå:¼a,8gATcZ¸ráò;—o~ÜæÑö¸hRŸ)rK±»o³t›hÕ§:3’Lïûà‚¡â[£Le¬öY)e˜¢'1mVž‰S,¬øÂ6Ñ¢ÞLd5r.¹x*¾Æš\߯féˆ reì8ßSy2É´ÏÁǶ}]”âdï‹uÓÌ0=ò£½`óh7¿0 2Õnõ|EÄ« ×ç×X Œ…9´qª. ˆ1u Þi  @€LZ@ŒiÒdv @€ @`îI¦/}}b þ¬òѰ ÓÜ]0gšQycŠWû¨hÑè¤Q<û†7ÿ{û *!¤2¹[.´Ÿâ-Šå´¶1æ}«&–†Š*µ *ÕK+u¬®ÔŒ+µ™n¬ÄÒTCKç‰ë½ÜR­DÓ,UcŠdR´x©Fž)‚JùšúL¹ñ¦x6N¹fÑu‹rûÎH2½÷ƒ †¢l9-`s¹¼Ð™B;?²ecLz:ñ:L¥™ÌˆjL‘ÛÈ•9sVÔ›ÉLF|ͧ"½-ñ5·Úïzz~2ÉôµƒéðºhÌ}9üºÈe5„>‘¹ä¢ÓÏÙ¡—;¼¼"râÅòŠÈ _lkb›êLs±^•²¸ä=~1¦¿@ºG€ @ ˆ1¹ @€èmH2}ê‹_ŸòGÃ2L½}yõ®“À¼‹1}ª„ÛÅŒâÙ7¼éíãÄ’®šÌk¬jIãTQÉ'ª¥¥6)¥JPi(°’±•j[=fu¥¶–*q¥õçWæ†ËùGµUQZ©Þ!€ÑÅ–™€ÒšÅ–zªÞRç©åf)ÆÅ–¢äR¼òb!ç+˜b9ÒK‘aŠxS<›µšba"1¦Ø·‘dúÀÇGLó]Ö±³SÈ0•dFœ7‹ÐD˪KYŸ)ÖGù¥X™%šbûx¶º¥w_s I¦½:¦ì+ÅÉF2LWM+ÃcÉÄR,Du¥¼Õ³ØRyEÄSñÒˆB–bŠ…Ø l)Æ4÷C—O!ÆÔå àô @€&, Æ4a* @€ Ð-H2íö…ýÇÿ¬åŸñË0uë’9ïŒÌ¿S3±8V‹<ãëßôöÖgG*$E©´ë"‡TmRkk¼­´m×6Jé”V'Õ³JI߯j­“ÁE¨eq¥ösõ™.K}Zj4ÍRŒ©^* ¥>S¼ncåúGÖG hé­ÙÙâõ™&þzŽ$ÓÖøx)µU 0e¦¡ËT™ôt ¦èOIfä,ZÙÃŒqDD#Ödž)·Œ¸FÎ(—›Å69÷œ9È$ÓW<¦íë"ã˜Cï]•׍ê0•û?âæÏ_¸HºH€ @ ) ÆäF @€ @ O"É´ëç÷ç£ááÀd˜úäªêf'ycjd[çe^ÏþËß>Na¤±vï8¹[§BJcG”FWTªÏ×f¸œ®ÝdpÃÓõ™nT¥J\©MbiåH`"!¡Þßf–bLQ])Ú#¿x$&+¯¿,Èu˜Jí¥H2ÅšI•b*G‹$Ó»·ß9“j¥ØLãR6L%«1µ:Ly–H)•B2iŠ–u˜â©üšÛ”§âÛÜ ZViò 0—™dúò7Ž®¼.† ÈU‚}SË0Å@Jù±XŽSÞçY„©¼"bMí%[Æ+e.)œ«kbL]£wb @€“cš$˜Í  @€è¢@$™>ñ¹ýÆúh¸|(/ÃÔÅkäÔ3(0ïbLTì0;[<1¦´>5T*) &u $Uk)UJ(e-¥u6n-¥L)M$¨Ô¬>ÒÚÎŽ˜Ki+‘—lÍâ=ÍøKiÃÍÞ"M§‡³cšÁ—h‡CE’é?¶Ûyd¹«†.b™N†in†à,fV “L{ptV& ö­*Â4å ÓÌöÓÑV@Œi`/­ @€ œ€ÓÀ]R"@€ 0Ø‘dÚå³ûuøhX†i°o€y5ºycŠ”âX³³Åúx6bL6h)T&t«ÌìÖH*ù¤6³¼•dÒp>©c-¥¬»Ó¬¨4‘ RûÒJó1®4VÔ©¯cLñVÕH2m»s#š6ºØLΗ·ÉË_yáå7Þ¶ö'Ú£?ÿÕ¼zË3ØÈ$Ó¯‹êìŠSžKnàÅ p&ĘfRÓ± @€̦€Ólê:6 @€³!I¦ŸÝ·íGÃ2L³î˜Ý˜1¦ZÑ£ê·cúçÍÞ6‰ÔQ-„4•LÒÐŒ`ãæ“†*‹TË)år›¢J£ƒJ7ÜtÊ/Õöí÷S¼qD’é]ÛîTf‘ËÊ0uë-Õy{A “L_úú¢Úëý‹û/zí¿üÛ·ßß!Ø·öŸýü—²}½pû³bLýyÝôš @`> ˆ1ÍÇ«nÌ @€ú^ ’Lÿ̾µÀd˜úþºÀhycÊJkcµxöu›½­ÃxjmTK)˜4Fͤq¦{k7ï[eê·–”’ ÒT§À€S&™¶zÿNæ’óöN d’)rKåu!Ãäö˜ 1¦¹Pv @€3! Æ4ŠŽA€ @€ÀÜ D’içO$™d˜æþ8ãl Ì»S”Yk•5ñìëþím6èðT£0RçV)›TJ(5ç<ª¶{ΊLR­M5£3ƒU‹õPƒcŠ·‰’dR‡i¶ß4¿_ªI&¦~¹j}ßO1¦¾¿„@€ 0oĘæÍ¥6P @€ƒ'P’L2Lƒwq(æ]Œéí[ï°÷7Oh´ƒÛ´·¿{‡¿yùkÚ>U[ùÕƒO£-þêÁã·¯¼XëO~éÀÿïþAçž<ïùqô ˪³Pݹá‘|ûˆ$Ó›ÿýý›¼ü•^~c‡9³â©Gnά¼€º4ó‘dú—7ükÔ*ûÇþsÉͼ¯#¶ ˆ1¹+ @€ô‹€S¿\)ý$@€ @ @$™â#°M^ú²«o¾ÇGÃ_1¦c=ö5£‘ù¨¶¼è%¶ñÿ®­ôí ¼t“W<ëÙÏí<ÀW½æŸ.[}[ïǘâ½i¶—a°÷hÙ¦À÷ŸýÏ[ÿ÷3®9¢Ã/pkøÙÏ)Û7Mi»7ĘÜ @€úE@Œ©_®”~ @€ ÐVàÁ;?ñ7¿}õ·¿(Ãä<ùcj½~_Õž%ÐV 7«1=þËÇ_ðŒ^vJ‡«¦ÓཉQgu?Y~Ȫ.»}ÑX¯ &·ÐL ˆ1ͤ¦c @€˜M1¦ÙÔul @€f]àÁ;ßn£.ÙÃGóNís. ÆôI“èÑÓyûÅϪǿø¢þøçmG$Ã4ço°NØ}Œ1Ýúàá÷>ôXëëB†©ûWhÀz Æ4`Ôp @€X@Œi€/®¡ @€˜ÍÓã§~ÖGÃóájÏ·1Š1‰1˜´@/Ƙš¥˜?«¢­>¹õÇ• Ó|{s7Þøù¯Ž$Ó£¿Ü˵$“ “›dæĘfÞÔ  @€ÌŽ€Óì¸:* @€s$Ÿ¯Yþx„™ÜGÃsdî4s% Æ4éËd+÷Ø~ðz1Æ”¥˜²}ñEµW2LsõŽê<]xätîAI2É0uùR êéŘõÊ @€Àà ˆ1 Þ55" @€ƒ(ð½e‹®ùο|´þØ£¬¿kÅÒ2âj’ÉGÃx#̯1‰1‰1˜´@ÏŘª¥˜† 2Å;Yþ¸òƒj~½©ÏãÑ.½ué6K· ’L?¸ÿÑŸÿòWãni“cš4™ @€tI@Œ©KðNK€ @€ÀĸyÕÒm6$Së.‘mŠV]ï£á‰ÃÚ²Çæ{Œé§ýW¼ž;´{ø³~ôXçm<;Hq¹ï{hœ+·Mo½°«¥˜*™¢“²½u¥ôfÖ¢Ó‚sìqQã×µ5®‰¯«Ö¯*˱°þ‘õyòÿ÷ë__qϪ|ÖƒÀ ˆ1Í0¨Ã @€˜51¦Y£u` @€fD *0]¾ÿ‚hYŠéGw¯‰TSaʃG¼)¾­­Ï†c}>åA Oæ{Œ©O/›nh-ÅT)ÈŠÀ<X~çòØ8’L‘gÚô°M7?nó¨Ì+K}¦XÑ¥H8ÅB¤b}lîë˧óÄ˜Ü EÀϪA¹’Æ1ƒbL3ˆéPã ˆ1od  @€½! ÆÔ×A/ @€˜¢€†§g·>cꃋ¤‹&$àgÕ„˜l4¿Ęæ×õîúhŘº~ t€ @€ÀĘ&e3 @€zSÀGýy]ôj&ĘfBÑ1ô‚À/{|ÍòÇã'–ÃbLî…9cšSn'#@€ 0 oýûã‹?6ýíJ€ @€® ˆ1u•ßÉgU@ŒiVyœÀÌ \ó=Î^°ù÷–-ªzݪåñÔÌŸÏ ô³€S?_½>ì»S^4]&@€ @€ @€ý' ÆÔ×L'* Æ4Q)Ûè¥Ûlúèë[;sùþ n<~atR7ôˆ€S\ˆùÒ 1¦ùr¥“ @ ?îZ±ô¸Í7Ž?¤´v·íÊþ•^ @€ @ Ę܃+ Æ4¸×ÖÈNà—>Y¥ø\Æ•âk”_*e™âpܼ*ÖÇšX_"M‘yŠo£ýèî5Gb@Æcr‹Ì©€Óœr; @€qV|a›H2µn*cr÷ @€ ÐßbLý}ýô¾“€“ûƒ@? Äà"ɤøs[•"·k2±ñ¦ø¦X“ë£åæâovÑü…®Ÿ®´¾Î€Ó A:ÌÄĘ&æd+ @€s ÉRLñW”ø«ÈÙ 6ÿÊ+N½nÕòXŽ…ÚúX{å–sÐC§ @€ @€ÀÔʦngÏ^cêõ+¤ª¥äR^Н‘jÊJK™RŠHSþ….–ãküõ­”kŠ-s/óG@Œiþ\ëž©SO\ @€ ЈšÖù/¾â!ñ§’ø6–óï*Yµ:¾ b}´ü[J¤—ò¯(ñוø‹ G @€ô®€Sï^=›®€ÓtíO`.ª€ËDkâpñW¶H)eOb9þú–ÿp0žÍD­Ä›æ²ÃÎE`î|tõ!«6«ÝùðÉsß%gdÕ'?¾ÝFc¶Ïä± @€ÈôRv0–£Sþ%ÿ%XþC¯Xˆ¸R<Ëe}<MA¦¾¶ºF€ @€ÀãÿxC㳉ã?Æ‚Àà ˆ1 Þ55¢Èâò¯lQö<Ê¿,Œ S¤—²üRŽ?ÿ$_c¯ÜÒ¿#Ø;ÃÀZÎþþ›ÛƘ–Üü"Zf^à‹/jcŠõ @€tI ”\Š¿‡d±êø;Iþó°üšüÇ`Yë:ÿÁX¶(ÈÔ¥Ž;- @€&&1¦#¶žØ¦¶"ÐObLýtµôuž Ä¿Ì(Rüq-âojñ5ÿôV*-Å·ù§· 0åB~-³ËÍsFßcdRŠi>\ý.Œq¬‚L±Þƒ @€. D&)K.•ÐR$“ò¯%ùÄbƒüGbùÏÀâ¯.¥Sü½%Ÿò @€ @€@ï ˆ1õîµÑ³i ˆ1M‹ÏÎæR **EË3f…ó\(_kOå·Q¢)¶ÉšLæ@kA&¥˜æÏÕïÂH[ 2)ÅÔ…Ëà” @€FÊŒr‘IŠåˆ(Å¿ûНñ¯¼ò‰EP)N±¦üÓ¯\ÎâL(  @€ ÐëbL½~…ôoŠbLS„³ô²@kA&¥˜zùzõ}ßZ 2)ÅÔ÷Õ @€ @€ @€@ ˆ1õðÅѵéˆ1MGϾ лÕ‚LJ1õîu˜žU 2)Å40—Õ@ @€ @€ @€@o ˆ1õæuÑ«i ˆ1M›Ð @ 'ª™”bêÉK4XªdRŠi°®­Ñ @€ @€ @€žcê¹K¢C3# Æ43ŽŽB ûÞùxü¬:õ³Ýï‰è,ȤSÏ\AïHdRŠiЯ³ñ @€ ‚Àyû?~Ùƒ0c @€ @`Þ ˆ1ÍÛK?ècô+l|óG@Œiþ\k#°@dRŠiÂ`6œž@dRŠizŠö&@€ 0»=÷ñ}^3'r @€Ì’€Ó,Á:l·æWŒiõêÕŸíøØ}÷ÝwØa‡ÎÛxvÀ¶ß~ûÎ#Úk¯½{ì±n¿T'pþï¼üÍ=¶d÷ ljóHà˜s¶ŸG£5Ôn ¬þ»Ýç'@€ @`|;?ô̇¿´éøÛÙbÂþîÚ/2¿…>üðÃãÜóŽ{L_ >ûˆO@:çÎ;ïœðëÞ†æ…À~ûí×ùUãý­æ3.H΋[Ç Ì€ÓÜ8;Ëœ ̯ÓÖ[oý/oØìãŸØ½´?±ûHÛe÷~ýfñ—/Øy—OEÛ©m[ð©|êcc´.Øí£oÓvüønCmçÝv¬´ì¼[¥}ò#; µïôɶm‡}²µ}èc»µîú¡JûàGw­·wýàŽ»~`¤}â;Ž´í?ò‰¶m»|¢Ñ>\m»l÷á]¶­µvÙv‡]Þ?FÛæC»4Û‚Z{߇4Úëí½\0ª}`Á{?ðñh[·kïÙþãmÛ»·ÿx£m·s­ýÇv;—¶ù;Þÿߟú´ÿØvçh覆޵íNïzÿNøGÏ\¾|ùœ¿6'}Â3Ï<óo6yÅ›ÿñåýºšôøì@`*‡~øŸÿŸ¿ŠÿšÊÎö!0I¸Óâ~‹»n’ûÙœ @€9ˆéãO(Ñ"{1§'è“UÿîZû‹ëλìkýç×ÿ[üÝuÔ_\ÇþCkëŸXÛþ}µõ/«ü›jë_S;þµÓ_PÛþítÔNÇø«iÛ¿—¶þ±´õo¤üióO££þ.šÝh£ Í?‡¶üE´ñ·Ðç=ÿ/&û?¶±}\Ü6ro\úÆÕÿv;<íw·þ÷ö±þÆÞáìíÿ´Þéêüsú¨`Ô_ÑÇùûyË 0úÏæcÿͼõ¯å¹úmÿBÞú·ñÖ«!ëþ‡ü¬×ýÛ[ǼúÛîôòWÿs¼–ú½ÊàLN ~gˆ·¯|«|˜Øø ±|Œl³í­V–Õ>"¬ýüªýðýÆÕüpø³¿‘7«vïTµÏø*íUÞšÚ½/Uß‘jïE#?†šŸÓUÕÞ|òç-ÍÝò=g¨ÕÜìô”§>Mbrr7¢­ tcr{ ¨À¼‹1í÷CÖ=ð³lk‡Ú£kjû~ã·þû»î¹ÿÑÒ~pÿ£v_´ŸF»»´{zW¥ÝyïOïÜðHiwlxäŽõCíöõ4ÛOn_÷“ïWÚmkRÚ÷Öþ¸Ñîi´5¥ýàÇ·µÝúƒÝr÷H»ùîÝ|W¶‡oÊvg£ÝXi7Üñÿ³÷'Psgž/ÌÌ9÷Nß™3sû;÷»§Ým Ý=—¹ýMO»ñбeÛm›Õ Œ1›mÚòÂb±ãÆľ#‹Ù$!B }G í•’Ú­ ±·ÀÆØúþ™ÿ¬§¢r«¬zkÉÌú׉óž|³r‰üGTdÄ¿xž·Vn|“iÒ† =¿áM/­Gzã¹JZ¾î KËÖ½±lÝ®e/yi©¥µ»úªiç’5Õ´xÍÎÅ/iÑ‹¯{iµ—:iÁ ¯ûé5¤g‘Vé™U¯yi¥—æ¯ÜÁôôŠjš·bǼ瑶#͵ôÜö9Nš½|›¥YË·ÍZ¤™Ë¶Í\¶uæR/ͰԷuz5m1qÁ_ýõ>Ó–l™jiñ–)AÚzÔQG‰d*i‹­ÇjLÑŽüîñhÜ0~ÉÔ˜v:ºqPÇ£¾}çèã5ø6~7!¤€R@ H) ¤@“ ø Ó€Is–?2qÎgD25©bÌi@Ìî5ºÂÖzã­ÝÕl­‰†ÖŠ•ÕL¬±öÕËj¼YµÆ¦jÕÀšêTÍšj¦T³£FÔ oš5T×|šd8XMÍdjöÒ°±4ÁRê›Ii’uÔ5ÖÚEiÆ4­o Ì¡U‹èâ-Sͺhó7ÿ^££Zìñ?غ+ÞäŽÒ_°tõÞûü-6\c{l¨1°WlìQëzš]=΢î•~`Q¯šÓSJ¶ôŠ=Æ„îÙÏãK&ô³¹ÙÌûWú^,äÏmŸk Î6n†q³Š³ôÿù3^w×–~PjKÿì_ß(Œ©uí¢®TÐmØgß¿­Ì'3‰›wÖÌ!¢}{¦ï¶i6oÈÖ¬öEV"d#V3-Xi»^¬Ì²Õ²@6Y|[Õ¼ªÖï)ç åÌ i²é“1LAŸ)‚19 ÓVôŸÂ“;l[¼yÊ¢b`Ld˜¿°Í+¾—vÝö»Ñ"™ZÝTêzÅSÀg˜N`û†ß\ʉd*^)'Ç>Ãt¾Õ·#D2§ì”S) ¤€R@ HžRsfŸ;`Àä9Ï¡÷aÔ„9Ÿù¼|2µ¦ }H±»ÂÜzí®é+E]€©añÖˆÆ.M^a˜ÚI±¸¶S[ÿéÌûVÓ˜eŸ5k>mÁgüjÏÐRÏ8ŒÉVxú‹7ì.﬇1yK:amcòÖ'XÝQúÏúSÆÒLü‡W·‰a “ÞJà4†É5žWÇ2LAé» ±Å,÷ ¯õmÄæbLFø[Pú˜ZÓ ê*%R=ÂŒL)V¦=t‰S`jŽa²ÙÀò²݆ˆÛmIŒ©†³´y½Ê¤_LÁ\^å­TõAPƒ1Õ8HÁ˜j^=Œ©2…&½ÖFS‰~"z”( Œ)… ,´CžÃ˜0`ºU7KUgK7Ür'F\Õ… ô½ƒ.E|/…©êL LpÅ0Uü0Å.rqìŒ~˜f˜B J²2Lž+&oiQÅS00ë'ÃäàÞÃÔ +&0àQŒ)äŠ)ÿÞ˜<†é[‡-^½Ý¦Ïa7¹U$S;ÚK]³8 x Ó1'` g¿ ˜“àÑ]$SqʰH9E½‚?g«opdˆúvøÀã]½Z¤gV^¥€R@ H) ¤@ð¦/ ˜2÷9  \ñʨñ³E2µ¤01ÕØ]=ßö5îí¯7»kÔÖZÏÉ}"ÀqoëÛ¾Q?L=ñd¤Xü ã°÷ú¦\1ÅxÂðüa4âŒ'ðÆ”äŒÇ÷Lß4ÆTµº;¥Ïø˜àÇ4?-í!c{8ÄA_sC¬s¬ë­%Ø22Lîà ŽA½ ¸bª5•[È‚p¼‚ÚU¾Ñ0QWLæÅÃ˜î ¼1…œ£0.0¦–´‡ºH™ Æäø>ð^m5sˆ;<ŒiþcŠú“ 9“³F,ÖS:Ãä»bª‰¾Â¸+t˜Å([FV‰wÅäNÞŸbª¼ƒª®àoLt.`-½1ÅbLþì›ÇË c*ÓoDÏÒ}„1u¿ ”ƒ¶(ÐsÌaJ©Â*a…oùþIn´8n‡\.µƒ.…|/…ãÇÕÐK¾£ÈÊ»(rÑ@rµ®ÍŸdµ+S‰%g>Ý$!€©~˜ZÄ0ÁeeáäÂëàA× 'GW–Ęj—žTWŸ`ä–sŒ‰ Ó’·‡¦ÏѽånùdjK£©‹æ_2L´9²¡#V‚ßÅOOÉ”ÿ,XÉ0yõÍ·`Á“Õ7‘L+KeW H) ¤€R Ô  Ó¼çÜ/¾#Ÿýiùdêwécб»:ÌŠkwÝäÌõV ­ÛÞƒ‰5Íý‚'ˆÂ˜ÖÆ…{±J¬—çåj 9ךjzÚÂ0ÕºbJd˜ZI±Ä»br1¦Xg<ýÁ˜¢kƒXÂ?¦ù£®JBA—²”~8 ÓæwÖ"¹¥_‰Ç[ú±‘»Â0‹~Í÷IBé{±œqÄeq¢Ž¸‚ r>Æc÷-á˜úÝêeS€Sˆ[ Í!î½Ï¾O/~!ô:KІióƒ^Ûå4_¡Xr«1ý~šÈ0Ùd_œ+¦°—¸ì®˜,vJöˆr˜†s1¦š¦•ˆrhj„1•íw¢ç鮘º«¿îÞ6zcŠRJ>¨ä±J×Ý ŒéDw Hu(U -9cªÀ«m]Â"!so`§ÐK1!äâ<0¹#®€Éx×xÁ8a âyWWù+Ò*îpk¢z{Èv…Ú®úŸŒwŒÌˆr­ðÃÔJ†É 'ÇøßUŒ)NÎ_}bÓ˜ñS¶ì|ßÒëoý¾m?É. †éß:¬ïÅí±Óç(š›ï~äÃŽØýþû \Ô?´¯òiôÄοvíÚ¶Þ´…ׇ¨-¼Z[ŸºÐÃtÔ1'xæ'ßõw°¾ÖؼšüäôsϿ𒦟åØô¹ž­0í»;ïÕ¾ë7úìÑãÓsÕ*ýçÖªß#¦ÓÎ<ŸõÍu‰‡ú†%êÛa:ìžæÿ½÷Þë@£»àÓ\»{VÕz6qVwSw—R@ H) ¤€h‰d˜¦Î{>vÅ L(#ÆÍÉ´s×›-¹]o^„SÌêЊ§%×†ÖŠßx%db]ë©_K‹¢‰/¦ÖR,ž£zßF:Å£è^{íE»¨²¸ÑŠ-Þ˜е…n{£ŽuÖ˜„µÁoLðcš?ꧤ\ ‹)ýt|-3ÀK°Å®vœ`åÒ.ÏÓ½p¹–ó?Lé¥??[8¹G\né/‹ &è¯ïÝbޘ¥_1†c:ö¸¸¥í?~ôçÞlÖôÔR crßn!-Ú·y‹_‘¸æG0êF.0¹s‚tc©Ä’K÷ÔÊ0íê« 'rÅTÅjãJú„3‡psÝIºåñ®˜ˆ1ýUà©&¢\àŠÉom€1-Xö¢ÛÔìz'“nªóR  c*d±)Óõè9Œ æGµ•‘óµ>ÆÄÞ†%š¶ô.±ƒXŠBKQni½.%8^ª¬ ‚Ç¥ÐKv¯ãCÈU<050…`>Àätçô4¬»; îîLîìY¬)±TqJÉXïæ#×íÍC¯ÈRËü0U& ׇÓS2ÃDoL#Ç<åBi¨Bõ[m>‚ ÓÒ5;°V,ºŽÓç W¿~Ó]|hc$¦xaÎà¸ß~û <¸}O³mÛ¶#F4zý &pv9äœtÝL2¤Ñ»àʡѳ¢Ç#«¸rˆÜâÓÿ ê I T¦·¢¿ Z‘ø»tÚàó.h†d:t(~¨´-,«ÌÑk¢Ú„ ܽ…·¶KYU¯{ý”ܶ#cnùÛIÊaT«è^­…¿Ç Ãô–;k&]Y};ì¨ã†ÞÑ ÉĸµÂF›J´M4­ÍUsWK'éu0hÐ HŠoqâìÙ³›»©Î’R@ H) ¤€(¢Ãôôóq+^üÞ;¢«¬~}øc³>ý¹/Šdjºˆ1¹v×*¨TÁ•®½©jwÚZݰq)ðJÇöÞpÜ¢PšRCÕŒN˜|7öÁ*P %æšOÓ §°E0eôÔ‘b±hba†)™b9”Sl@1.éÆtÍÃB tÓ+†1U×GKÞ"cŠ–|K{J黾—²”~]|-» ®Ú Mµ¥_³¸ŽÙöÄPé¿ÿûšnt¢(º>ÆäQ˜Ñ–ÍÚ40wÑ œ:LŒ‚ºùj#ç>°òæò09~˜Vn¬‰%—•Xrýa˜z>*n cª 'gá‚©ºÊ<_@³ÜÆgéV0LÆ41À˜èM Ôà°©Æ4gÁª¼Mº½®*ÿ½«€0¦Þ-û’?yÏaL0×bI.¢ôÞµ7 ûî÷O4P)–Uª2Ô?Æö®  ¥XnÉw™Ž.£¬„àqqî—‚î‹ëö¶J/ùˆR¢Èycï Àä."É 0ùtS0Å3L+_{¦!†©6Ú7"¾× ÑC+‚wiÍr“ÚXr5 úO†1 Î(ànÊ!Æd SÅŽœEÂÌ7޼vÃ7D2hpç†á¥£åóèn³ŠÛ51ƒŽSBxG]<¨îÑÆ¾Unm¨VZQòWMG צT]19¾h˜ÆØìÙ^ûqS$q´ºÌ\C­Ìvzç1¦º9OÉmÝs[r@ÿ1¦Vý=†é¬ó3Ö·C'™@Ë‘%m-pm ‹‹1%Õ¨ØÖžøO×Dµ%UZ‘R@ H) º¨zÛÑéŠ}(Þ.Ëóâ°þx夯M¬ÁÀ'Ëíbégš¾oÒ‰ýq f˜©’/ypìÌO‰dj¶ü€1¥Ú]ßõì®Çž˜dnm™Wû—=?î¢Ð½T3 Bl¹X„¥7<¾átµ—e˜jV{fˆ&žHNe˜ˆ1¥P,McL¾Q½ÆÒîÂjs­Â4K¿})X sº%cתŽLjã1Õ˜<ûª¥'L¾¦¸Ò¯‰``á ,`S¥Ÿ‘`«ñÔ™aBéW1¦`YïfÃaÆÔlû§óʬ1¦HûVãïÌY¸ŠS‡îëÌ|î—B0+-X½MwÂäø tZª¸6*ÕSV†É‹kYq7PË0A(‰1ņ“³ÖFS™3z¶Î+ Œ©óšëŽQ ç0¦knZÞáþ‹o1œN•Rˆ%Ô5+B’¸%Ç·-GYî ¡ÇK‘V(x\"½Të÷8?Î]< !×O€©ÒïiÒ S¼¦ÃTñTb½oÉQ†És–kÉ[qBŸÉÆ€ŸàycJa˜rèÉa˜".gÌ ˆá¾û«†ÊN2ÅbLt?CgB0òʱYvîÄw:œ´I `n“¸‡3Ít7rȺ.KWF8‘¶Tœ‚mlÐvbþâc—2GM¸ vâÞÛ–%>.NïS!›²aL<€Y¥5™Çó©íjø–ÏʿۘÛ:ÒÂ÷ÐM SªaÚó ·òµŸÚ˜O&Ð$Q‡@VyÈ6Yí2"Tð/]ÂðwäVf;×~¬cîoÄ ž¤:º>oļEŒx"«½¬Ì¼>ûÅY5rsËãy°ý -Ãü*)“Ñë»p·í\Þ™wÅ^!ª•µ9íø=†¦ õíÐ#¿ßO&6§VëB%Ȇ(©úYéXcËÓšJ·iˆbLѪhõÊ*§U'ÖO«<î‹ ÚròÊ–«Pƒj°B-3Îe9#“Äêê>£½¡ø[s/n—ê¡&R*¤€R@ Ä)À¾ zèQtÀ_cöu2Àš¦vl¥PZ=ºJÁöXw:u§¹åOÌ9¦?ÿ…Óž~&5:Ý ‚GV¼p%L(÷™!’©¹rÆT×îõòB[kÝ¥¡nظæ\Ú›7 × D,3À°¤’‹8½ð î‚Oc˜,ˆOtþ8¼È3[41³‹SÅÒ<ÆäÕ£æwLðcš?«e,ýÐÂàk­ë ÑKñæt‡^ Ò£Qä]pù~ÝbK?Í WBé›û“ØÒoša‚Iü“ôÆ”\úòÆÔ\¨³J¬1¦¤YE¶cÆäûJ Ïâ¿ÈÞö^a1á/Øj°Ëܶ \’aŠz „Ÿx7¾ŠCX:dmF?L3L˜ 0¦pôRš4÷˜Jü“Ñ£uAaL]]·ì„½‡1E<âºÃ'øËÅpº:r® GP)Ì*W KÕ8q¡qu·T³<.—B^—¼þŠç\¤ÖñR4rœgˆñl1ȸ+ÎýR \¯c±ré Ùz9þ0,ÞS“»²$À”ì„©Â0yN˜è¸ÒK!†©0¹~,+SxÝIn½1Ã三¸bªDÎò¼ÎøÖ¨}ÝYI&7¨ç›É@`þÛÜ&‘ÅÁ.î4ò)Š1átºÁŒ²MuÛÚPlDÍ‘Ñ᲌Ì5TÔ´Êém›òç¶Ûˆòw?20[½dOÄieÆM I±4bÉNá’© e٠Љ¦½Çîá0Lµl_È0]qQÃ4cYþë)çd.g« 4va|Ë:Àê:€¹he@â¯Æ~V™y«xذƒí'ÆQJ³SpYþìWý1Ú̲äbLÌ<+QÈû‘ûÓãO›²¸ø#)™Œ^ eÁ¥°+›Ë+f2D®D¯ÕŠ'¶ã÷è0LuXR›a};¤’ ùg}@pÃJú¤T?ûÊZ*Ûc­™5Ñù­”ªh~Œ¬òu« /m9Ýæ·àÚO&„…žŽÕ™gÅ&0Êûâ_VWÈÂ:Ég$ÿÊߚ뇀î{ƒk_õ¸R@ H) J«@*B‡ÁúÀض'z5ècð[ëT`§õêÙùaïÂ=ØŽ$ÒÍýî-Ø“áuØñ#ƺNÇ–ÉSBÎ;¹ˆd7Û²Çþ¶e˜6cÈ”»‡½¬P_1”m{F\Öô±g±oyüå0ʺmì³ñ°ô§³‡j´:º Sàµ7à ôÞï{tÆþŸUt¹FõÞãaLÉvW˜[¯¾ñŽÀîZ1±¦Z+ÜR̤odQèÛAüz+BãâÇÕXSÍ­Eü*PobØRm±æZíVîÒ oäÈd “ñ™[ñá2LÍÇµŽši´fm§³°ÓØo©®ê¬uKß4ƔĨÑö>{ÁJLó‡&øã+@k E_µ±»^—ܰq5Ž—’}/¥„2Èî)`rçõ0½ðLµžµ–)#ÁV»Ê7c$AÇ0^]Ù /\Æ4ÌØ<'Lµ~˜T®áVO'ô†èN ùŠR˜.€ûñ½÷E+ |F0ã¼Ç…âÇÅ:KŠ"翪_q±o¨8¼2Þ”-_Fµo¢Æü0ñ½3r¢ç; )œœ‚ÊõÆïFOÙY„1uVoÝ­c ôÆ„³ÑHî:^…áô÷N¬:x$¢ä€JNÏ£f(`ÔNG¤ÆŸm5NœçÖ¸:´®q›äâ8hÅ¢KÇKñ¾—¢Áã|z©Žû¥ÊÜ]GâúÂu–’4à©>À•Îȃsw‰‰ë'9À$çºM~ÐóÆ´w4\>1¦†)b€óÏNä,Ã5°vçºÛ3‘LÄŒpaRMøàrœKƇÖX×ÄiÛv¬$®« Z0£“o7r/kóÓ¼µåÁææ95NëªÛ’òZ¿ôádŽ:B†lû—b:2áeí03´e&šfƒWèXãÞ;72†ÉY\°}žÃ9õ pÌJ˜EŸí«`Lø]œœ™dB¡ãç€r¤wŸP…gevë«DôWÙ ~‹_.h¿#Ô[ó@ÃB·º¬·ý"²ü]DÉõuÄ_ Ÿ4 c²Ÿ™À³mºÆIÊdôúð‹šàN~0QŒ)z…¨V”¢å¿ÇÃÄÅÜ|óf©o'“O&<>[|¢ÍŽ5)n+ǦÛÕœUÈê‹’ÍÌT…¦¦x|´*Z-ÅBœh’7¦PËIFÍ* (šg{:û Ì6™<»ïK, Ø”6çax@ûa¿¡]¦Œ6¤€R@ HžUö"\Ä;±‡}ZãõÑqãÒ²7E&ûéåa÷†›ªtl]SvÒÜ[°s…芰lWÃ5ynðÏ˺ùg§‹Ý¼þÅïÑftLæ9z…¨Víø=Æ1L!fn—±¤Ñ‰Ö·,$'X^6Éä–[Nk<­ú…ŠØ*¤GY0¦Øªh xˆx³ŠdÙcÆ¢-§ÛÀrªÅÊ3ë ®€ÆÙ¾bãɉ={(W\¢1o®Ç)\×±#‰Ò¶¼!Ò¥€R@ Hâ*À¾+ûä¬büu?l ;çè±Ø콸#ÊâvEB] Þ‚øµ‹YÜž:<ìDµy;vÙ¡²î"¯cR»ˆÛ½·n˜ O¬›m·Ðíq¤õc٥繮±C•ô§³‡Ê^Ó0ãø¹/ ˜êÇ’ ûar½ö&¯xA×ýžG¦Ë'SvÍq$0¦ v×\sk’­5€–+kÝE¡¾'ûºèRØ“}]÷KuðÔ "Ö„Å[ä™HÎõOo “M'Ã(êcL5Á}B¶Ðoþ½¨c­ôÊûŒoTÛmÏÌgW`š¿¹Ò_Í•À–6½U\‹ePÇ ¡ÒÐT5ž¯vB5y*™|P j3¯ç‚+`˜Rœ0U*ÀÌeÛf. (H$Øü@rðÆtí°GSÖô*¨\Cížîˆ1ŵoUôÌxvEüŒa0]˜ØˆÙË+Îe`µÕ²&+ì’Qä,ÊJM¹³’3?LQw€ž£'X _@ÖþÐ`¥åÙ‚i¸*ÆTñü€ÆÔ ¿=cçÆÔ9­u§Ž*ÐsÓ•×ßêL¸ÿâÛß;!z@uð*Õ.rT±¸GY¡¡uZJt¹T'`\(nÍ’‘°ã¥„Èq5¾—ªÁãšs¿TãÙqDrŒœ´²$ƒ¦: ot˜,¹cõêz£Å›_ ŒÉ&vj¹z,ðÿQ1À™Ë™Nî…—3\¸3ÇÕCëLfÐdSÄic.åäì/&2F0ÐjÉÅv6,ü–]–_|E~È¥Ìl½‘™_Í Ù#3‰bƒžð9w œÄ#ù-­¨\ñÉÕ¢<×rËœ˜ ÛlÇt¹¯Ü {æFg˜h] åŸWÃÔò—›Ã0½Éa^<Ôl˜ö~Ë·Ãûë‘L4ÁÛ#°òÐ(ÏpüQX…$†­ 8€UÈs¼c¥b=¤C&VïÐÁ¶|9¶Ž¹¿ˆèÜ@ôÇh{HþYÅÆ6áE[nn¹Å²J”…?pþ´qY†HÉdôú†6â DXìçÌ)ôFµbY´ð÷è1LgžÌ‚4Uߨ£¾}»žO&Ða±B·¼°RýP QjèII­¹sËԆȮE«bc2ïG¶ªÞšV|Åù°hËÉ Ãß‹Ur^ÙòÌŒÙÓ±¦á[¶ÞøkÏB•XßX]ÍOßY|䧦¸åM±.(¤€R   °o™go„ÝZöUðáëÕËFw†¥îÁDšì`»rhñ@ôÖ“±‘,»²îÕÜá[ä|6óéöp’0&ìg‹£ZYX76°‰yàNöôBʸåîbL¦6B^œM7à’åž}ºF1¦†Éõ¢Zwzïw?<ýŸ?sàÎ]o´žw8ÛÀ˜²Û]kl­5+B#nìãÜíÄ»\Š'WÒÐ¥¤àquØþ-ªæS¬c±T¬'»&µUÕ OV„%Ñ “k­µ‹nö0¦H 9w޹YŒ)ƨnföÏxS8|Ax=p“¥Ÿ3®^ƒe¾gåï%§ô=+º9ßrÝ/5„¯¹QäÒcº¦rr!#y8Œ`ЦŠm嬋H/áxŒÀŸ˜³âÒ«oç,9Ž#±Ã>ᓟ> ƒáO~ê¤_]t•C/¥ööW–lß{ß¿‹™»>*èÝzH†‹öœúƒ1}ô§Vì¸iÑ– ZQ7¯A†©ïÅí³‡Õ8ò’ÉG^쥓†Ìøê™ãåè³^8¹#.šôÐŒu4À™+&(IцܚF25ñD!ß!M\¡U§ÐÏG«®V÷:0ÓM4üVÝsu@Ó €a:ò˜\«4¹OZ¥ñ‹ð“~vÃ\c˜b~þ0 †iþ.~ðÓD’©é¬†Nt×4·êšÝºŽëð)vÝy·2Öòû‚a:õÌó£õ Ó?üpÛaÖ·GgoHªoæŠÉêÛ·O$™Zõík™1Å>¥ù@ª›gLåFó¬{¢R@ H) ¤@›0fšnl… az. utas»X\¥`kfb{Ť½IŠs¬Šë»·À÷:ü7„1ÙEx.Ž1軎cé6‰Ô¸ÑB¼ ÝçâºXn{Ü‘ 9šm+Ó„´ýbòamNça\AA¸§îÓÙCÕ­ Ã4ï9ócmË]ŒaŠtݹ&”ï\4iÔÌuI+^0Z6j*ü—È'ô÷›žX{ÐÖwgÇ–EŠÝ•ÆÕ+’í®ßøöá°©"}ì¸"ôècOªì9Ɉ¥{GM„55´"†V˜"¯¼a˜Tô“_ìû‰¿wç€ã½.Å9°w]ïÀ"jü –HzÖEØóÏŸ>À'‰cÝ/Å;à©õXï#,Û}Õ§L~1HýÁ)@X~|ÚùH°l¤#,tÂÔ&Œ FõX{;KA1ÍŸbfwêÀI´®‡êÀ7|+º¥ sm®­÷Œíx¨!Nøamp½.¥ KQßK^pVÿô/‡¢ô±ÓjÂ觤ÇËŠ¯¹Ð@(~S\ AÐK¾v*ÀÇ÷ý»Ä(rà †ÉÃ×Xú˜ê¾Jt@*0ú¬=/ݳû­èãcжonƒ†Ê6-K…¼¬qjà8^¢qû¨ïô‹³/ñ_[p9ÿ¹WðF[Zyaíÿ™/øé€Ë®½ƒ/,{O]ûpLöÙêÄ=-Ú:=pÛÞtžE‘«LáUÞGæ ®^ 9(k˜.Þò ‡1í¼RÞ˜zôW¦ÇnŸ˜ڧ­®Ü)h$ Ý-Æ£}Gw*«íº†Ó0¯DL77¡Ó½@oW\{»?5^¤ÎQSlÂP '8U"_rFNâXzà±'a…ÑÔ‚•›q=7ÐÇÒ/ιCnZß|×Cø74´®‰«…–²pKîxÛ§þêb,ላ -Ù±è’3ö~ý«ÿrh°~Èw€|ߣÓ~~æE^G‡ie°R-ä ÷wLÛ{ß¿O¤—¢‹ŠœÎ1¦$÷K5“³Ä$fˆîCß•q–›øCµÅÞP-”šÃ˜6lÛ €iÄó»«o¯9/ŸÜ®úºg¦¯ë°%`˜*ëÉÌ•(j&Î኉l0Lß¹xRÀ0½ðÚO®Ÿó•3Çœ¾=Øù`úÜwÅD\\ü[ZI2µo²¼!yaýDN¢®˜ºHCÓ&K{t'ïÛP&Kv0¦(ØG«ô)7Í;çŽgÌ?Ù‰WL¿qÌ ²}ÎïÂ[SRý]¼½0”'µ™dBU Em(héÐyežn¨ ú,éÙ&Ã[ßà‡é ³ÆÛ2͛Ƭ¨¶Ã¡úV1AzTn¥¾á=…®I>™Z"fûZfó½d~Y2ÌÙ,¶™YŽ×1R@ H) ¤€h·Сcãb@¸#:·`µ1ŸWÝп ÖfùŒuÁ‹Ø·¡[ð¦6R°ÃÜ«Ñi“»‡§X>Ý<à07jž{ßhNBKqö„nÄ‹G³mûíîÈS¹{¨§K;1ç?ŽŒÕÖ­!d˜¦Ì{Ηª Å-ráߣs6âH#­ÿôIDATc2/ª?½a†š±ŽÞ¬C®˜Ì„rÇH‘LžØÀ˜` CŠ…™hw­ÁõÌ­–*v×°¡õªïÂBV 6Ò'f,A2\ K@A/Á²jëBCìah…õ ÉŒ«8“¾ñäJ=tɆu1=lþ-Žøî‰§œ‰% ~ŒžJð¸¦ð¸˜l‘§ëýÂ]äé®ðüÒס Ó¿žv>ÌL¡(r†°Ð.Ú>Œ)2…_-ý©óžÿ›½÷M2³_iu`C¸ è­0‚5·»$8Zög¨ãsËóº”6ŽVô¨ 5!;½„æ¥Æÿ–=°!ÿ[¾fNP*SPô‘Ò÷ ãŽI\S»»º~Qxàä=àÎúË(ÌDŒÉ}9ÛÁ íÛTŸ¢vÆGbñã $ù ¼àÒkÑv~öÅœ¼qØH@KûþíßÓýÒyÿvõI?>啕Ë^Édó}h¦à~ 핹ˆC…fêö¯ñJà9#H˜ž2ên+31»d“tUÿµïø~#Æ”îöOÞ˜ŠúKQ¾ó©€0¦|–‹r•Y.kc¢ èr`L—_;4XÁc·/ÄøöÈïžàzNŠns,ýè§¿À¨Ø<Öb,}ïCÞ’ ÐXl]h #jÀÔ.·tóÆ„¡õ×C§äkß< 9ÊB…xõ~ú¯.†Áź,§ýêb$ ´ðý*ỷèÁL~z¶ò.rÀo¯¹ã¼Õ!Ÿ9`Ìä6êv;4¶lÐ†ßø‹oáu _ýÆ¡èè`ܶ±ñoWÝKpÓKz Ûî0 Û÷ø×!ÝýðÔúÔç¿üõCð÷–ß=n‘ãlÏM÷ŒuûCÀ˜œØº^¯+Šþ×þŸÇâ Éð=åâ_&ô“ð÷KŒ¿ßçïn>ièðI¶ç¶á“ÌYnJ¸÷F1¦µ›_Ÿµöê–ÿ­6mŘ<†é›‡-Y½Ý¢™löb1™»ŽÐïœøp ŽŸ¯ôù³n›Ä…“|ŒÉwÅTër†Z b/¿yDJt¹ÌÍ‹”SÀc˜¾{‚­· [¥_ÚuЙÀJ*1_|õßc˜üßÅ™þïbÄôuU†ÉqÅäý.<'Û›Oüɯ’¢Ëuî9u§|(à1LgœŸTß’†êæ?ž¹¾¡úÖn’)B*R@ H) ¤€R`Oû {ˆë1L ˜2÷¹Jï=ð×8aª0L0¡cÂòzQ½ö“oÖ˜¨ó§èÊí#¦`ú¿Ç}2Æ 3cб»:Î'’ì® kAa#¹àEXY½Õ¡•å €T0üÇßßù¦×P8Zéz‡Ž+Ÿ¶®,è»b丙fk½kÄâÁ¿\‹rçðñ0Ÿ¢Jà¯ÙQaa›4o쨞ÓÏxNw\×õ¼âÙß°Ú †S˜L‘`#ý·«oDzϟŸqÑñ'Ÿ¶÷ßþý¯¯ _õ_ùÆ¡HtZ XM¯ºåØ%ŽûÑ©4bψ ÏÀ^zØÀhAE"ÀtìOý'ß zÈQÇ£B90“šiô#‡Éôà#Ätþe·b›k;O?÷Š“O=/„°´c –œ…Lî• €Ÿ'¦ù“,íá:ðlPhöAѳ0¡Lvµ»$øt«¾E½^8€k€­  u! P40¨¾ã¥Hظׯ0v Vt”>ë}/a#¦Üo}𞇧¡”?é1ÊšìÚ÷ýš€tèQÇ£Üï50’ãï…W܆ @Ãø…—ßêÆï1™¾‚E Uâ‘Éˈ¯aÛ"" „1é},â ÆÄT 3¡á5_nãæ¼ÚØ¬á€j'¤&È©ç× …[r¢íÂä æ9ˆ·fÇM]ˆ9A¶Zh¦Ìa¶ÍUš©Á—\Ìõ8sñF2L'œ|ƒ¨ š (¸!À_LHôÈWÚ(Î%…£È¹eÅÅ@È MëHY&Ý„1é—(Z©€0¦Vª©kuZ,X‰äú“¶Ô÷Æ„¥óQ7Ú~‚ÝÃéË®Z+ÝíRlxßzäžÛ¤ÀsÌ¡®ÆŒgWsÍFMn˜mKî ŠÃfðIŽw¥7ÐÁΊûGoiÈMÃFN}æl<ýÜ+c_~Ý0ôW¦Î¡2´Þuä1'Z². 1&¸ŽÄHÛó¹f'º)çþúêSϺC/,ˆ ÿ]‚ÇcÄêvƒµ‡ ŸsÉU{cô… tk®¹m8¶É-ÑëŽGÿæÞÑÓ~vÆ…ØÀP –~}åPôxÇKÞ’5oÕÚ=OÅðÛè¢ëƒq8é%ìG{0ã¨Ìã–÷KwÓÁ9ºÓ;.’ùFÆ1wŒ˜„†å¿8ï ŒÓž¼ ¦ë†½4jÒRìI÷ZÉ!\–Fw#Ç<L˪S[1&2L‹_ØŠ0¸ãò{±Œatâ30aîüþ)kQŽ“¾zÂåÓQL®1í%7œœ¹ p _‘L-j]t™N(0L•±_5Ú¦öat‡èø-í«ÆX|áµIÑß…?£kóè†Öƒ-ƒH¦Ngîï†é0Lõê]7³¾1EPßV8íp¤¾‘%e}É”ûº  J) ¤€R@ ´@èÚÊ\Ô¿æ?{À€Ésž‹šPhE1ªè½ž½ývôÞ'/òì'0|c –%x³æ´ºî"™BSfªow½†v×[+ÊÁ`E<8ÃV8ê¥Äð:H£÷L¯ž›%ßÖ­…­6XTQÜXð ÷\ Ëêˆq3±1bÜ ˜79üØ”…ØøÎ1'>ÖT˜Rý1çw«@=ûê%W£†À§…!,œ¼‚=¤—°=ôþÇaõ¼×ûNë.=üä3°šÒ^Š[(&Œáè SŘ$†áôÊ[€itʳëA±À^Šô“_\€D3)§A®ÜùÐ ,°‹Òõè¥_ž?qÄ,‚¬ Y` Å OúÀ0|ÚùiÂ"ÊûûnÔSKca´ÉSuÕY­½¦xüB1Ío¥××§ÜÝ:b ÉJ?¦¬Ö(qÌý»u€¶ôaŽÇ2àƒþå0®þeéã/€«†˜Û-”¸‡1ùñ &Î^ËÎX´ÆX€k °ÁrGðÊýäÓ`3»z Ë}=³ùsÞ¢S°g^xåÅC†æÓKHà–θ`Š5á©ùë`$G¹?:u9*Š%Îr(w²ð{Pô(qü=æ¤S¼ °xËy¿½õÛß9>).‚ʵ꽣ë”Pcª…™ˆ1ÅÏ*V¦qÀ¤9ËC¸’­¿M rꆹĜ p[ó_`AW,©‡1Áö ­ù^Zø‚Y…Ñ4=ò䳈¬‚„ x% ½„„ µŒ¦BÞäÝÃSѯ¤åÛÑyÁ ™òÀD/•„¼CÎÿ̧@ÆI7aL%ü鑺¨€0¦.Н[÷[0L yß°7&8‚fàx{.‡7¦Ë®Û™àN|ûï²zDýa°û=ŒÉß`zèñYðXË¥?–¦ù|Hjo–ÝOô±„õ@TcŒí§gbÛBÛb{Äc3Ð/±Õ!è¾`;è² TÜY3ÑÙWa©Ð˜I H)a…ГsWbÄ… th*#.oÔMKìÊ ‘ËÆ)ØfÀ8`ZùÇ]ÞÐËǘп!½4~æóƒaÜrï8s¼Dt‰¸é™Çf<‡ž7&÷c˜ð×Ð%ËýÎç{ÉØ*‘ÝI/ž²—aƒsŽÍ¸ÊÄ<$cî—ð†è^úçÏa@þ»1sÓWfìQ}úóÜ?õgD&kî^¸e2ÿLýß8kèÿþµoºè…mnݳ­YßÀ0=:{çÎoxtè ®¿|úC3Ö¡t€1 Ÿö’Nn›ùBw§ÏE2õ»Õ:¤&´Ï5? ƨ,«èùij¯à‡b˜Ð¦9¿‹§†OuÕ0‹f˜6’鈟üûÿsÖ ªÀá?Ûë”3ÎK¯oXÆÔ7%7^¯Ä˜²Ö7Ç©»G2ü7ÕU_¶üKR ]ÁÛóêòµÂºR@ H) r©€Ï0} s‡!Š;Z¤mCÅѳ<Œ ó|è·£÷^Y–൷âŠÉìK$™nœù¿t¤Ó¾l#ÌÜœÅî5´†V„"¤°UñGýž_ ?¼ÒC¾w%3±Ò ¯°šÂÙ&€a4óÿzTz¬·i`:±ÀšO¬ÿ´`a´©Â(Š„S¯pb˜vT?pX5fÑ%Ø0= ó)]\0Á"Šb˜OiA½š*†½”^êi5½D¿;Ę`&¥—úA§_0ì¡)ƒN?æP:^Â&’+œ?·Ïô0c‚¡ïäSÏGÂ,ò·¿sÜy¿½åÞ1s¿xÐÁIvÑ6aL®Q=j~ÇÓüé¥ÏoA¤¡ø¸RPîVPâ0³c1pPÖz‰³þ•:°u€Vt«\L€u­Æa°­ø¥uå~ÿ£ÏûÀëRmÐ@Ôs¼„u¿°œ{À÷k‚'¾æ©Æôy¬øõ æ~¼úÜ"¾†mp¨]qñ5Éi*G)[ä&àk VÀ¢÷9¶-°£ô cBxxÒ2ü z å~í°GSLâòÆ”ËWY2µkÓž ?!ÃTŒgýå[ÃÏü‡Oì4«È†ëo>¾ïSµ]ǯAÍtaõæ7_ŒGÇKçýúj´]lÐb#œ¢E2‡nK…WÕßõ˜Zâ•À•¼W’ß4aÎHÖb‚Í%4MÞ\ÞsÛú‹ Ðá„V‹Þ˜ðJÂë¦ÆÔ[laLCSÂÒg'LÖòdñ Œ)?{e¡D c*QaöÚ£]BD9uÉCÏ2ÖÖ3bÅÇ`©imºeüg¿0àÍ]º±&‚{¥GXßÖìÆëçÎQ¾ÞôùŒuÇ_>ÝK—MÿÊã¿ð©Ñ³6@yPbÃäcòær†ýë>öÄmo¼ÿ§?ÿ¹Ð?pe¾Ü ÀEð¾…«¶ñwa+ûh•V2uñfþ.àßûòáK# ò»˜f¿ ˜‡ª¿‹J˜E·ÑVò“KŒ^~xkݺZQ8ëªúÉõ )êC °¾áßI ^©o>­›Ä’Nxzý_ýö½?ùæ×¾ç†ƒ”¤@V.ßß³¯=s¹=R@ H) Òxë­·:è ‡'Ω1¡8Ë]l"ËÀö.c×ãÄ#`?™½‘QTèµ×ï½{&oÅ‹³>­¿ðµÿuý“?›ðâ7Š2ºia>ǯùB5çå“~Æ1Q»kÅÊêùOªØ]öVXVï1Áu«sþ¥×À©’-=ÿß®¡‰«@Íu=­H6ã ;ê wŒ¡b A½å /z¶$àJp¶D¿¹æNQ¸M³*È•YK6ùÕw˜01ìÂ+´ záÃ>ufˆa5ešºpÃOyáOyÃôëŸó=^TÜÕc{ìôå0‚_1~þ _\n‰ ×y`‚÷Ÿ~>øl€^BºÜÓæ€‡î—à™6RcZLŒÉ !„ ËwOüù¹¿¹¥ÓÓÑ5kÏ‚HItµî'1}|ß$c»Õ.FªÖŸTCà2àhpgý­Zbéó/¼myEÏ:P)wÖ,ÆJŸiôSÏr­/Ëݼ.1d05ÒYˆ°ôïAzxŠžø*ËÝð5bL´“£ôÁ0!n <0_»ñî± :Ž—BËzY>ñ€Ê Žœ£|’3”ò†Ðèyx ’ï± ’õHð•-˜ £k/0Ü‹ÁŠl`QÙbpÅ·¾‹ã‹0ÊÂ¥è+]Œ²ÐkÁh clô]Žøî‰ç\r5 % ½µÌ\²£ƒ1ö9{Ñâèi ûáLò¾ÑÓÀ-11h76È-`⬲rh0m ´èréâ+‡¢¯X›èR5UBŹè| c$vÅMp4Ž!Ö…WÜ “Ðå7Þo£2ÒKô‹ËtûˆI¶¬„K‹à×ñìϱÀƒ´ó~s V^ÂhCtlc×BŒ AåÖmy÷Ùõ£¢0Ì4ýýÆ¿|ùr˜áæômpz·AÖÁîvã˜0Àaùà×búåè-öz~Ê ¼ÎÔමJ$#c˜ðtH"™ÚQ”ºf É„¦oÁŠ­)¿‹!#–᧺Fï¾Ékñ»¸wÒÿwáµ]ø]<8u-Ù>†“‹5LƒaºæÆaü]¼ñÎï[øºT€0¯KP³4ªÒûFpD£@{dÖú‡g®C;ü“ë瀙«´ÃÕúVÃÌEXÒ€a9Nõ­@u#/Y];[S^ÊBùR@ H*3½·ïÃÕ„Yn]w8a„–d ψ Xp#®Q´~Þ¾ßß{ï=÷"¸£ë ÞFI|°NãŠÃ%”öUC#É4j§÷6¡ØòôÞ1f„q,èº{Þ¬“½ö:Á éÍú›¾jÃëè½?³jç?ê¹Å`±Aå`Ã~–6fw­ØWÁ0M™·ü$l\vݰ)ó_pö0eþ*˜XÌu°D[ë©¿º c4˜XñíØÉ ]gK ”Pú×ß>TNÃÊ Ó(Ö‚rñ' ª°£ÎZ²ÀÁì¨G}‚gRxt3x%˜&¼â›O™0O|ØÑ'À7uÁz,ø|hâ3`˜¸à8 ­¦tQsÕc¶Ø|/\Ë2ì!S!B€ ôÒ wÅž‰ó^‚íâà#ÿÅyWÐRÊå°‹dáÚÎÇç¬Ãô£SÏ£- K:ËÒ&oLiFõ—v=1{¦ùCnHÌÆž\^ž·üe+M놬™™n–²ÀêÀ˜É ÍÙI5”ûu‘:0ú)¯Üî[×aHÇÚ$=¬è¬(ú T˜c×Xð½›xôÒ¯.¼ˆ@€¯Uʽ‚¯yåÎЀØ`(@¹ÃZŽ„2}rþK(zì¹àò[ƒøqþ*_˜Êý °å{¾C&w}/1&TcòÊVq”»Uƒ$ø0¦†Þ/=t01&Øzö *÷TþÊ1/¨œÛ|ÕN)²YÃOÌZfmšùXªlxЭ5\¡Ìp[rKt^À~ ½ !Ä ¼.¡±Bë‚,A/Ñ÷b›¢uºõÞqhšðzºê–ñn M(Ä3§€x%Ñà÷ŒÅ+ÉbYžqþLn¹Å>äM'Lê-Œ©g=zðî+ Œ©ûe ôWf¼1Ù=a˜(º+&§/½ê¶H¢ê¹ßbÄåö-¸¬§&Õ"ÒŒ§Î„m Kö/‚¬c”Déú;FX_„”̶]LÌ{ðqKô[‹o§Jc‚=„–ãöÒ«ïÀˆt‹s.¹ Ãlô]ð/vÒi$Z ¯‘®¹m8F\ÓŽ ¸%ŸÅœ-îŽ}o·„–ÐÅõ„×Å·\ Ão ¹ÑÅ9ñÀ¦,𢶛ç[ŒÃáý˜1ËÜ„UD¾î¹d3m9Æ`Lt¼„Þ¶çqOÊ/}í`úÈEbdwŒÒ±„ÀÞ{½·€U²ðÞ˜á_þe' °áo–ˆrÙ½1cbÌ4ÊñÌÔ&Œ Õ•$Óì%ëkúµdðýþëOo˜ ÓÒMÂôùcó6Ärtí¸brú S­Ž~˜ìÑD2õ·•ÕùíW€$Ó³+¶˜[2¶®ö»Àˆî†GŸÇ²Zð%øi¸ ~?¾vvÌïÂtÙ@Ëe˜D–´¿Hs}Ÿd:Î ¤H­¾Ÿÿ2a¶Ã×~Îe˜âê[e1w¥¾…&Õ·\׆fNS EY’R@ Hâ(ÐÕzf†ƒI-]˜¨Á®Uˆ¨ <)îÎ<Ø¿¶ÑÏ#§å^$Ä!¹“¹mÛ6ðLÈ’•É*\P¿j4cÉ4~v’ Å\¨Ž›· &c˜@ ºn\1ËÀ–9‘Ç“&vÝ{d aL0±¼2Û]öVâ)0¢"1’ü*qÏe×ÞAT ˆmªî¤/ ­H0 Œ™´Ͱ¿OÎ]‰ $ØNɬ[á4°—à—ëäÓ<[kÅŽê¦?ù4ü K)’‘+°¹Á¡ö^¡g Ô¤ã~t*XM¯¼ù Kg^x%é%ì¤Õ~w`2¼Gõ؆½î£Ž§ôÂËoÅ6l¤øK§¿håúœ©Ã´¼Èœ÷W``ôý-áÍeÜ›"a*ï,4Yh¾øÂ¢Ï4Vh²à¤Àæûøª"YËè–ø{É•C¹¬÷,Ÿ°D´„v‰ÍcYÂÞJx%ÁZ!Ï¢Lž1“ɃhëLlTN­Šè´˜:­¸î×z ŽÑåÜOVoL­ÏN7®Èát”z¶=øöðÇÅ÷0*æØ‡;~®Ìq.éø1H~wÄí”R]ݨvPª=¬ B ØN4nsklž–ÜEB6Ò6jG\ÕQ·3ðfϦš*¡âB.—nºg¬ÃÙã1n‰¾dÏÙ‰Œ3‚ÛbÆUƒéVPîj(Ü+ Âëºp7Æä×ø¡¾ÇÍY“Ñ÷Rt—¥G…E*.ÆCÕ¦íïmzëñ±«÷‡'íöaLø‰dš¹x}µS[‰^ÄFt²eýTúaò Ë¡'ࢠ“|2u£YÒ=V$oóŸÛ÷»¨:{·õ‘lÖŒ¹Lgû¢ “È’†K¨\'€dBÇ J/U@RÚO‡¤„iËN¯o3Ë0©¾•«ú´ùi„1µY`]^ H) Ê­z/7ïAðÄ=!Oæ‚®Îq ¿‚} <˜ž“¢{Hð¸ËÍ_:µ={6¯`÷ãÊ@yH2át3xðàP‰àâI_!3üЏó€!Ùö‡®yYÞÎnA 'ò©í²¼ KeÁ˜p)†LƺBÊXI2||vh­ ¦PïËÀ¼Þ»T¦J$èŠU3C¹~˜ÜÅ`½F2ƘXF Ù]Lªkh5T%£qµ2ï[5«z¥_–,þŽë·žäJÈŽj¾vlÃE—Òl§µ >CVS†‹ÚKÝužµ'˜6ŽN'8À°Ež4™v8¨\Ô¨îÚØ'Î\ö×ß§º&-›¥Ý/ýZ{=Ózmð ¥&Jßu¸תöó8Ëyhů[†=4…>·èv+âï¤â5Ü1•ÓùV :Pú(ti’7¦Œï( Œ‰S-ÀDq€1Yó•4·ˆ&Ì\–ôF«iÇ’1‡[BÃÅ~‹Ø4vâÏ}UÙKÊ}CÙ¼žÛ4Ù\ž½’⚣X€i³»8©É2éöW½÷œ«Ü>&Ýô{”R I„15)œNË»=‡1ýÛ•·E‘#Ûƒo1⊠¹(R–TN2'1”’gL±Ë*²ö–ƒ8áÜ€Üa\©_Ç·ëAKá8qSão °6üßÓ®íñTÇá¡ÁX¿Ð%ÇKŠÛ1‚¿%:^Âß”pïé P²ô¨b1¦  ûÖã+vÜû+ßöÞ¶÷þЂŽI¦‹ÖtãPÜ&Y‚áteî<†a꣦-f€Kb˜D2å½ÍVþ|<’é‡<½|³ó»–Q²mtWÖšU:&ÆbíâÚ$†)…,Y»«áUÂ*ÃÂ)@’ÉES µ Se1nu$½¾¥0L¡ú¶ìÞ!S|驚ÀÔpîeƒ '¦2ÜJ„1µRM]K H) zN€2@pðî'*ÂC¤œD]Àôu¢!là_Ì=ø»‡ÎŠp$¯ÉÅ…Àž¸ÇÍ€ˆóÖæ6 ‘K2 ÃíAì-QoLÌŸž‚ò‰è—Û8‘¹ÂGhÈeÄ”1ê‹26]I27Ë5¡¤/?ˆ2LÕÈã{TÄ®û#‹g÷É´ûÃí±‹ SŠÝæÖ_vWgÁgÈâê¬ÿtãéDWFX¥À¸Z ¨O,E¡%3¯ÅN ÓéNÿÐ¥`µ§ ¯ÔÚK·ÄÐK¾ß‹jìžTz &PxâÁRÏtWL8¬MÞ˜l Pìrßñ3<Œ©f¹o³¥oR§¦õ:Ä’o2Š-ý¬Ü’Ï>†çQpÍYñ¬õõÙµa#'ÃßI,½ÔOv …Ž¢Ï@Aåš~Å”üDaL“¯b¹è‡S쬢ñI8`üŒ¥YÝÔL:ÍW”[ Ý5 mÒ{*xIÕ¶QÉôRí[ÉdI?pÖFÄK˜§kÎw€0¦’7)z¼+ Œ©Ã‚ëvR ç0¦_¹5ÆR…1·‡ <.倸¯âɤšE?@më?"•âý*UWñã«d\)˜O­%–b=-Õ…–ØÑIô·TY?T[ÚêÆê{]ÊÜ%J§”ê~ÛOŒ)åwºß­žI®%’LÓ® Ö‘fsÐÿGeaغ¿‚Ç3yT–a¥3LœAýíZ’y]D ´II“&}å‡Ì]¶ÙÖ¦„µ+k˜’êï"aâïâÝݺ3ð‘³7ÍnÓê²¹Rà¾ûî;ì¨ãl wœ&Ï^u%·o²ä›&€PLϺ ëÛ¿ðGˆ0aЀÝ;·EÕØÚ7xS®TRf:­€0¦N+®ûI) ¤@©@c&úC¢g&n×± œ‚¯ c2‡ç€rp|ÝãbL8‘çE\‚‡§×Œ5|DÉe•ð/om@T¸nj(¿â-¸§À1I¡%-rsEhÉ2ŒLº¡è¨^`1{!Œ‰·èg=Éô¥_þجŠ¿ Ì÷U¸ìu–~˜b˜†LûÝ/»]÷W_ßÝÏl—ãt`L-±»Æ!JK­°}Õ™ñ±¬&KQfʼnD y܉ZPSœîTÕÇy©÷‰–BöÒx×;­6“¶ cJ7ª?>})¦ùëZÝ[^ú kIKt¹”¦À-}¨zÞª²kž×/%;ÖªkúŽ Œ©ímëŸBS²¦Ä˜Ò›/€V®æ˜¸ +Õ·Xíû«ê¿ @-¹¥PTÓXt‰ÝKQßKî\^ô}û&j¨µÉ2é&Œ©õ¿b]±—ÆÔË¥_êgï9Œé’!·&‡^Ç·•yÊšá±ë-)ÞsRœkb×ëc§bשReD*Å®ªqhŒ²"Ãl['ä·bˆ¥ˆ§¥zÐRBœ8ÌÔ:#ðŒÑâjÖµzH–±_•¥G•â)©q2o0¦¡‹‡Â!Ó„5FÃT1yda˜¶ì|ÿOþs©›>=\?ñ)L³—¾ö1À"£Ä3%1LÛÞ¨ù]àÇ‹Ÿùài^¨þÀñ[Žý™£ÀWö«/ƒô=ù wÝs/zY! ’ÖÖ7†U­e˜‚ú–‘aÚñæî~oÁ̓¸ßªÑÞ+™à™‰Ûø`)º{p ¾zyn7KOc¹ZS¹ÊSO#¤€VJ¤…\ŒÉe’1ºÂ_¸)2Œ g1ÏÀ˜ÀáÛèž$ŒÉÝ+r èC¾Êö»î…IP¹tskWã²`L<+„1™ÿ$>]ŒÉ¸Ë-á©› 'ªA2zä÷«¡<+˸³×·ì sˆ°q ™Þ~e-þb{çê> JtÂ/Møl÷ã/cÌa?ŽÁlÀcSsOª³Š¡€0¦b”“r)¤€9U€Žˆ˜9 B j\fð þµ¬¾ã•3À×Y»v-N‰îqÁ »¼(×aŒ6Þ"„þ`Àa¸¬eù1'F8W¶s!oLîƒð¦I“›PJtÝd¹¢,&2‹1írËØÍ'ö‘îr3I‹®úï~)¶†‘dºÌ Ç„Rõc»Ü¥!† ˜žß´ã«w;|ñ“¿ÿð#Œ á¬—ËØ¸Öì„];9r„ýÇäô÷ТlcjÎîšhn­µ¯¦-M Ub•hx¸Ø•ŸQ#jÈW}·6œ&˜LŒ×*‹hû0¦£úcSû0Í= í¥Ÿ!X-çnj´ô›×¢èRGVù cjQƒWºËcJ.RbL)í¾Âhåb´šYÂ0®”Ï4Ö9\LDËZ¯KÑp–Kk饸ÈqÁ,^#L뾌²Lº c*]#¢êª˜º*¿nÞ>zc 1Fî¿lzäqÙñ£4>)yüœ¼&•J)TŠw­-U‘a»v™ýI†FÝáq—ïO"‹³¥,ÜRk½àÖí0Õ= Kª Œ F+.¿sÁØ­€;`'éضð-Û°jeáH2MzfmP1*ìGcQÖúÿðѱÍÔA~˜Ú×’êÊ]T€$ӌůÔü.|ß¹¦eS'¶W¿ü0ñaÒß²£C?sü䱇ÇcnémÖ]¬»5H¦CŽü>_ÖEÎ@Rÿ•šXße˜¼·ƒÏ*aƒÁ3[ÂNlÃKþ‚X¿ØoßfÂÞ˜è®IŸÒ* Œ©´E«“R@ HN(@oL`hÜgÜZȆzcâ~¢<ÜÃq¢Ø=Ęx5";ü‘¢#%° ycbNHGñþkÒb–’Nç·Ä˜˜swdÌ?‘ÝšÏèzKâÒÎE¾°c'Î¥¿(^*ÄZa?¯æJÝ*oL¼#I¦{¬sü§1ÇS—]~óˆo|øª ¯3âslúŸ7ÃÄ•-t¼sFˆÁ#W°f ô¬ ;QÅ»qbLYì®u|ÖPÏÄê¸VJ5«¶ÌW}ýPqþ‚Ït)ˆÑSC®TÖy¶4dX][(hÆäÕ£Õ`,0¦¿Ù'=ALŨWú©‰T6ª§”¾ïÆ;&D`Œ³%oÈÓkŒñ<¦ _àš[+„1u£u,Â=…1%—’‡1ùÍW4ùŽ”<8 Œ™º$éí–äÅ ‹kÀtÈÒÆ…ÂYz3z•äIJŒ¼˜ZJ/YS“eÒMSÚå±8 c*NY)§ )ÐsÓE—ßþœ= |‹éÉtßHu¿ :UïÄ„“ÂéDÉq§”Îq½ëZ)˜¹OÕª#®ÌÄRxì b©ZŠ„û.—² ž»xL–UWÚy&¿ ºäÙì|>ô% Ëõ˜2œ"ÉôÔÓk][A'µ0Ųb˜jup±ðI¦ƒ§/zÙ<“E­ÒÁÊÚ%¾•°b"lΓûC޵SÛÏœçìgnäb±äUnC d `âJ°ùH;¼%í=ØÄû’U¬œ0KâßÝ;·f‡`]4á/·™, ±œ c*g¹ê©¤€R  ¸Û‚‚Ê-åà (‡OØŽ\µ$<\?µ H¦Ñ3jL(Œ9î/?°0ОËY–…ašºzÉ—ïýrH÷ÛÌ*=0aƒ ذí K¿²í®I¦×&ì®U+kFãj…VIZÿ™è¨>bJ­»ìÓ™Îä¥~Š_Ç‚Ôqtɵ¾¶ cú~J陲äc³O]»zL€‚„M¬þM³¥ûk}-5Zú!j-ºÖ×/ý®k˜úù6é‰Ó…1%30¦ºÍ@+—ôYÔ2Ý3\ŠSÀ4t)â ®åÓsY&Ý„1õDâ‡ì˜˜:&µnÔYzcºðò["`ÃŒv\x™‡1U¨£Düˆ ¹BÉóÊ”œ!t>©B)͉¬ÉâWÉq­DKÁ‘Fp¥xb)#´”7gKu{`YzTM`LF,Ù XfÕ¢‘Ë–èa›ëö²|H2=1o Aõ-–ÕÔEXSh@2 øÚÁSmªL®U:`±éXr¦’K+ºvj÷gî:]cpÉB‹¬Ì› ™þÎ÷k<á¥Ö·æ&c•À-!¨ï8 ¡âàu N˜Ì÷ý6á_PM<ÛîÎúfQáRaL…,6eZ H) J¢@ÓSIž¿8A’éžG¦;þz«~¬JÕ•u†iËÎ÷/Ÿ}ýj㯭L3+ì<ðÌä:èÅx0‹îâH“S`LÝ5@ŽªWÚZ»kŒeÕ5´Æ›Xkí«Ñ@`¶§Ù•ŸivÔ´ÅVª¶Óh¨¸Ž «kµÚ„1yFõ˜e½A5xt²‡1Å.ôÍdcÏn]O6ª‡ÂÖ†)Hö´èQkrKù±™ËS¡›Ù6f^S²¸Ä˜¼ö-þíæ½ÑpÀ£“×iÍÒAÛÊRÉð<`2aéº\ª¦ç0äx©²Lº cjãÏY—îA„1õ`¡÷Æ#÷ÆtÁe7§ðFøöïx.²¤”ÑrüWË·§ÃIÖAñÆTqî”"ƒ«P)žUJ —ˆ+ÅKþ¢4gÕuuåPöÁyÊ‘YzTÍaL°a]²•v\‹ÌXä™`ÀâÓ¨’Lç®!©ÆåƒtÂZA¨Xr½Ñ’ë)=H2M^¸É]VkViwemÿ&Ü?düœ±avêèÏœßâ0üÆ dTi•C’L$†mwl}kŽa‚Jd•°ðp¨A€™ð/ü3WÕDOKøÛø {Â)ØC§MF8•Cp=EŒ˜T-¤€R@ tO¸/ y0Šîé^îtçH2Ýýðt¯÷ž`B1WF† ±ähÏÁš4óÀÄ -?øŠëXhó¡-Ȣ˕µ„€1ÅØ]+kºÝ5«¡5uågŠ—zgñgWʼò3#,ên§b;Í…¿¥t«iû0¦«{¥Œž´ÓüI&÷–~½u¿1Ð’_úþ9K¡(*}aLemûû\˜’$ÆnßjçqZ¹$G€Õ&.ŽU ÖI6ê°6–e|ÕAtÉ}ïd™tÆÔß߬Η®˜TJª@/bL)ã" §1+éö*æøìQFü(i­Ou 'Å#JŽ;¥øÀÛã6;àZª«CjÇZIQá\Éqt\ b)vŸ¥GÕÆËS®%ìa¤9þÅËò°Ýœ‹$Óø9/Íx³ª+Å0•´ÝÖc%*’éK”n]„1¦¨”Q) ¤€R û d6jªkBq—»4Ê0uÿ‘ò—`LQ»«ke Û]@9)ÆUÇ‹Ršq5–Sñv&ÚTc\ì$¹¨úÚ)´‹úöaL!«»[ú£žZ„iþº Z´&D¬ëÕi~ZÔÓÄǃK³¥WÝ,•Y‹ÚÉ…1å¯íÌGŽ„1ÕØª’M:³‡hßF=¹(óDa§€ñaLS}ÂÑ&¤nQÉ2é&Œ)¿|å¢, c*KIê9B ôÆtÞonŠC‹‚a0¾ýv#&=JÀlÈ”eì X[Oªƒ(¥ƒJ‰®• µB¨!,©Ñƒ³ô¨r‹1áÇL’é±™«£1þÎþõG{âº-捻-;ßÿÓŸÿ¬fQ ”LL_<èà‰ó7àwjZ⇩dréqú©€G2~l`BÅÃÔOauz}„1Õ×HGH) ¤€R ªI¦;FNå$Ÿ;ZÃÔ’ŠŒ)³ÝÕ·²f°µ&ÂIÙüÓ{¿#áÀR\Ô;¦ÔÊdp¨m˜âŒêUûCOz#³·¬ôë,ýM,ýXK=Rú˜ZÒÜ•ð"˜êaL)³ŠhÓо=ôäÂèDagOÙÖCl«qârÄ-…,ðY&Ý„1•°Ñ#uQaL]_·n§=‡1û››RÀø–bê¤>o)SœûÙº;·TGÑq±Þâ#mû!üTñ É ê4âT©ŒcìF¥,ÇgéQåc2’iìŒÜçÃÔÎfS×.€ ™üê·Á‘¸¿ 1L(¹bf$j—[ÙÄ0³$‹–kaLE+1åW H) ¤€èº$™n1E S;ÊS¿ì®ZëWkÜê$TËŒ+%™FÛ…1¥ÕG>±Óü)N³1³×/ýÇZ=‚+%•¾0¦v´~e¸¦0¦zSúŒ!Ú7´rÁ1õ' FlÉ–ÄÙÀšqù…–¢­M–I7aLeh7ô ùQ@S~ÊB9i©½‡1]zS xtî¥7!:Ll`l€G5ìQÂR·Ï»Bœ”Æ'9}”Üx†Ì åÿ˜,=ªœcLQ’I SKI]¬¨ „H&1LE-È‚äÛ%™Ä0¤ÐŠŸMaLÅ/C=R@ H)ÐyB$“ü0µ°<Œ)«ÝÕ³²6mk7®Ö.ûLBU  ®U†Ö6aL Fõ`¹ïȉ ÿêoö©XÝ»Qúþ¢_UaL-lôJu)aL©“Ó|…\­9qAàÿ¯QÏI¸RÄyd«Þí¾N–I7aL¥j@ô0]W@S׋@h=‡1 ¾ôÆÒß"4LiäRGÑíÈ€Ù<'9>“â<'œ$/J Ü›¥G•ŒÉ%™Ä0µ§©ÔU ©€‘Lb˜ Y~EË4I&1LE+·"çWS‘KOy—R@ H) º¨€‘Lb˜Z[ À˜’ì®´µž“ÝîšÉÄê8R¢eÕ‡TĩԟnÆtø±IVw”þð‰ þê¯÷Éduo®ôE)e3ª cjm»Wž« cJǘþzŸhûæ6hhßÐÊÕ4qqMYbd•ÚX·u›ñœeÒMSyZ=IÆ”‡RPÚ @ÏaLû|âÿùägLJûþÝ~ÿŸÿëÿN9 ÓWŸ>ã¥B(ð?ÿé³ÿûÿþŸÒ³ú_þë9æ©u[Þµ´iû{mø1ö÷’}K—í¿ÿþG{¢›Õèö–ïÿéÏîïÍt¾(ˆãGÄ èšß\šþ»Øö†~)Ñ|góÆÛ‹ú6ôþaéõmÇ›äû9”»‚( Œ© ¥lJ) ¤€9T€$Ó7>|Õ†×Szï0¡üþÃr˜ÿ|f S+í®2®¶Mÿðÿcº-æñ›n¿/ôÓH¯u÷ߺQý~Ò·Á&›åÃ_µíñ a²n_&ÿëûË¿ßïS®_ññ?*ý÷¯–0Ÿínër%Œ)cªÛ|ý§¿ø?þáŸ>ßÄõ^köÿëÓ$½ƒ¤s¬Êÿ¤[ë~cº’h§˜ک®®ÝEz cÚ¾}ûìÚð”Pºýž‘ÑÚSb²”xhä–OŒ íÈúa§ïyg{ºN S\ݺ ¬½ñÿyݤ‡R~b˜ºP.%½åš]÷_õÔ~ö¥Ù)õM SI ¿%Œ©ªëžR@ H) ¤@iX¾iäÓ«ÇŠajaö‚ÝuÄè ¿¹ëÄ¢›I›°…â—’^U>øàƒÕ}Ìø)峺£ôQ ]²”þÒÕ›…1µ°m,Æ¥„1¥–Ó‚ Ü&nâSÓòپͽý¤<´Qu›š1geÒ­?aå²ÇÆÔã ¼ß[S´Óý%è[)«@N1¦w¶ï9ý/þøÈÙ¨ç±Ù–¦ò¶äz²düiþÝsLjÍÄ0©ö´P`Lwõíµ~ל¤ú&†©…jëR{„1©H) ¤€R  Œ]½ÿ˜>SI’ E~˜ú¡npjù슓WÜyÍôÿÑ·¾¯|V÷‰­I?®º7Êí(w”>ê@nsؾŒÉS£õ¿xÇ cj¤ÌÞxç÷íû¹õçÊ¿ÿ·O"õç ]<7§“nT +º¦€0¦®I¯·WaLÕHa]|CëÖÅR §=ªÑg×ðH¦7·GI&1LímJuõÜ*°yùžëÚ³jòîßmgÄ0å¶Ü š±Wß™üÄÚƒví^[ßÄ0´Xó›maLù-åL H) ¤€È»›Þz+6¼ùx¶P,¹V•_±Ì}us»öÕ]·Ì> ˈ…?«{pùh´V”cB¹£ôQPÊW¾éO$Œ©Ñú_¼ã…15RfùʶÍåMýl/l±Êé¤[#CÇJ®) Œ©kÒëÆíU@“0&)аyìQù®˜ØOÝ3ú¬?~ôg—dÃÔÞvTW/ˆ!²D SAÊ­¨Ù Õ71LE-È<ç[SžKGy“R@ H) ò­\1cÂÆŸþüg—·ÃÔ¢+â4jJžéЉ©25Z1J†1ÑS:dÆÔhý/Þñ˜)³|bLðÃÄé¡‚:dÊã¤[#µBÇJn* Œ©›êëÞmT@SÃKÉFàzœ&ÈcŠ®˜˜À3½³ÝH&1LmlAué|(°{ç¶ ƒ ½ýÊÚPŽæ^6hkßlÛid‰¦|]±s1dÞô°ú&†©Ø%ÛÜ cÊmÑ(cR@ H) ¤@¾0WL$™Ö¿ñ°‘Lb˜Z[tMØÜr{йb"ÈÒƒ™­%Ø芉©2 cj´þïxaL”Y1&sÅT\‡Lyœtk¤VèX)ÐM„1uS}Ý» ô:Æ„WcúðxéÚ]«6¾Û!´2ÖrPÜ(ôôËbÞÆe—v]1U2á2 ™Ä05!§N)œ/=5bÁ̓c³ ¶ “ûÈ1L…+âf S]Œ Ùþ÷þ(†)‡ÅW’, c*IAê1¤€R@ HN+`®˜ˆ1xþcýé’L¿ÿð£Nç¦Ô÷+“ÝÕuÅT2‡L«_y{ñ‹o¤ÛB›˜]ÆX8ýšYl°-7ü6wA×SÉ2­Ýü΂Õ;ÓeÙ°õ½?üñO¥n«ôp{öcj¤¼»ûÃô_M–_VsÍQÒYæŠ)Ÿ™ž_ÿ&RÁ&Ý©:V tYaL].ݾ] ô:ÆÔ.]u])ÐI\WLŽC¦NfA÷’ÝR Ó#÷®„—çN˜:x Ò²{79ø ƒ—&î‡s&æpÏÎÕ}Ýʹî[\FR@ ôˆ˜z¤ {ï1…1õ^™ë‰K¦@Ô“2•¬ˆõ8õ Ë%|€%mí› J {à tË„st×ÄÃð-3ò©Þåõ½+D  öº|@¥Ù›fóP°M œpLß¶>&9dR5j½˜Z¯©®(¤€R@ ”\XWLrÈTòRï÷ãźbbµ‘C¦~«[€ D]1 ,@±)‹* Œ©QÅòs|¬+&ÎÉ!S~ŠI9‘mU@S[åÕÅ»§€0¦îi¯;Kþ+ðá{n9xÏ yéê/ìùù^{.úDð/ö`ø¡(»æQ –À*aÁ&7f¸%üK/Mø–„“qNeIÏ×b€+KrÑ%z`ÂN|‹mFšÃ_&O-΄.'„1©H) ¤€R AžÝ|Ökbz`ù_Þ»ì/ìßkðb:¼WxõíÉVOF­ø–ñ/~Áöìþp{¯ѓωòµ²¦/·Ñ«þÁö nô¤*zè2* Œ©¸¥ŠUîœB:ë/½dÿâ+}¤€è„1õB)÷ä3 cêÉb×C—R]›<Ä~⥥|8=”HR€Aâð­ùd†Šã_| oL<Çà/cÏáHûJ Kì LÂñ†.a˜xÒK†:ah§ k¼°†úHV* Œ©•jêZR@ H) ¤@Ï)aÔÊOôÜcëû§@ßÖK²¼û‡Mý»ŒÎ.¤[ßÒ_³ëþBæ^™–é c*G !À¤½¦€0¦^+ñžy^aL=SÔzÐÒ+ Œ©ôE¬ŒS˜ài ß`Ü\.LÂßÝ;·câ]1ZbŒ9R  àZ ÃÆÙéØÀ„4xÚ`D‘Ã~lc'ö4q"ê( ŒIUD H) ¤€ýP@S?ÄëÝS…1õnÙïÙ#Œ©—K¿üÏ.Œ©e,Œ©娧* Œ©QÅt|AÆT‚R6¥@]„1Õ•HH) ¤€(˜JS”z) ¤€R  cê†ê…¿§0¦Âa?@S?ÄÓ©¹W@Sî‹(S…1e’IIÒ) Œ©tEª¢˜T¤@YÆT–’ÔsH) ¤€¨¯€0¦úé) ¤€R@ $* ŒI•£ „15!ZiNÆTš¢ÔƒÄ( Œ©ÕBS9ÊQO!U@S£Šéø‚( Œ© ¥lJº cª+‘R@ H)P„1•¦(õ R@ H) ¤@7ÆÔ Õ OaL…/Â~<€0¦~ˆ§Ss¯€0¦ÜQ¦ cÊ$“’¥S@SéŠTD„1©&H²( Œ©,%©çh¥»ßÚƒ™þ···òšº–HP`÷‡ÛaÖüýGoI!)Ð „1uBeÝC H) ¤€(­˜J[´í|0aLíT7ïׯ”÷Rþú£€0¦þ¨—Ÿs…1å§,”)ÐI„1uRmÝ«ƒ cê Øº•h«˜Ú*¯.^P4Í_Ђ+f¶×ìºÿ®¾½`Ù,fö•ë¢) ö­h%¦üJ) ¤€¹R@S®Š£(™ÆT”’jG>…1µCU]3/ cÊKIô/˜ú§ŸÎ–EU@SQKNù®£€0&U)P„1•¥$õ­T@Óü­TSת£€0&U‘Ž* ö­£rëfR@ H) ¤@ÙÆT¶íÈócêˆÌ9½‰0¦œŒ²Õ„1µDÆ®_DS׋@]Q@SWd×MÛ¯€0¦ök¬;HÎ( Œ©3:ë.ÅR@ÓüÅ*¯‚çVSÁ °hÙWûV´S~¥€R@ H\) Œ)WÅQ”Ìc*JIµ#Ÿëßx˜1ðoÇÅuM)Ðe„1u¹ZtûË÷ß’I) zMaL½Vâ=ó¼Â˜z¦¨õ ¥W@Sé‹XØ„šæoB4Ò¬˜šUNç5¥€Ú·¦dÓIR@ H) ¤€ ˜TšP@S¢•æ”Ñ«þ`¦Ò<‘D TÆT‚ÚðÎö=@n9¸¢GR 1„15¦—Ž.Œ˜ STʨ¨£€0&U)U@ÓüªT@SÅÖ­öìQû¦Z ¤€R@ H~(0uýQ£V~¢Щ½¨€0¦^,õÊ3£ÅÿâzY={™ÆT‚ÒåôŠR) zMaL½Vâ=ó¼Â˜z¦¨õ ¥W¸ýõ©ŸZúrÖ6¦€¦ùÓKG÷KaLý’O'7ª€Ú·FÓñR@ H) ¤€p˜óòɘT#U`í®ûáÇk÷·7z¢Ž/+_»yí®Jð z)£ÀªÉÞÌÂæå§À pzE©½¦€0¦^+ñžy^aL=SÔzP) ¤@* iþ,ôî=²0¦îiß“wVûÖ“Å®‡–R@ H) Z¥€0¦V)©ëH) ¤€R@ H)Ð5„1uMzݸ½ cj¯¾ººh­»wn›0hÒÛ¯¬ ]ù¥§F,¸ypko§«IÂ+ iþÂa‘@S‘J«yUûV‚BÔ#H) ¤€ÝS@S÷´/Æ×îZ;aÍ„bäU¹lµØêKêzR  L<3 «F 冓¹È¢2QOÌ¡°P”*ÄzRé{)Ð3 cꙢîµÆÔk%®ç-¶)¬ÒÜËáÛb?žr/Z®€¦ù[.©.˜¬€0&ÕŽŽ* ö­£rëfR@ H) ¤@ÙÆT¶mõó ¸o@ß¶¾V_U×+€(waL('e±qRX%L+`r¡ñKêŒ.(†éÃÝïEo¬BìBaè–R ' cÊIA(­V@S«Õõ¤@Û@Oô‘û¡ŸŠ xcqd ºhŠîyî)È©m%£ çXMóç¸pÊ—5aLå+Ó\?‘Ú·\2'¤€R@ ä]aLy/¡®æoЄAûݺYl™7ÛCñ|°€Ð0|‹mQ/]-®VÞ^¸@°!¡¬Q Æ6ŠEŒ¯p'üeqó+$ÔVæ@×’íQ³˜>Àägð—SŒù?tÑÚ¯™…ö”FóWE‘Ýõ™½èŠ)©—Ý;„…‹âÃa6a¤PÍë®3¥@ÎÆ”óRöšU@S³Êé<)Ð 0ØØ¹Ú[ fè}¢cŠ=„à¯uOÑ‹ÅØckßlâùHØÀ’‹näZ÷”ÝS@ÓüÝÓ¾ï,Œ© ½›¬ö­›êëÞR@ H) ¤@áÆTø"lçl{oðÜÌ x&P,ïýá=À+柉ßbÁ&ÐË2dÈý*ŸþgíZ$(ßOŠO±žË ¥ V‰™G5àJ;ñ×JܧŒiE?ÀÿNŸŒéý@ìë“K³ì‚µýHc•lÁ30Æ’ã\fHº`Çhf¡íEÒø –ἤB$¯†P œ0²‰$Eóh\o! ¢€0¦‚”²Ù¨˜ULÇKn*À®'»¡H$ë1®À6»§ lŽ—ì[€~*(}¤@) iþ*ìî<êî·o}w6ÓÂ-çßշ׊7Ù|Ûlé®eU`÷[{Ь1ͼiƨãίîÙµ©¬Ï­ç’R@ H) ¤@ËÆÔrIËtAƒT\>‰è>³7Í&¹ÂÀsL 9d¹~Å:t(€2 hÏRDŒÉˆ%Û`Yó¡@/¡zÐ Ü5ÑSWCñ1ܳmÛ6ü[Vˆ •\S®~׆³`©³AKdb8éDtË„frU|Ì æƒ¸¦=©±…ˆI".hGirV sF+»¶Hè¼ÆFM.Ìó+£R  „15!šNiD€J¿[ö —¢ û…15¢¥ŽÍ À‡ìü1^ŠM¯.Ïp "¤€R@ H)à) ŒIõ E¸ÛÀ„€ªZ†ùgÂ6¾5~…H<>ã'„1õËÂs DÿLüGòß ¼Ø@îžÙ³½ŒáxB0ø‹m Î º¾eûy¯Áƒ#?ØÀìʼ¾rïèn‡.‹¼ñ^6£,y8ÌuÄeè ×uËD]F°Y¨ÁŒùw1&œQ^ذÂ1ÂsññMC^Ùö° ¬Ä­ °Ç ÑêkEôú–[Üwä½Pô¸¸•u´¾¹¼·CÙÆby¬B˜2ÖŠÎFV‰Þz0YÀeÏØ0ÿ=øì vâHÒ0šYèLÑd¿ Y´ôBÄÕPp(>zÛb4Naæ(û½t¤…Q@SaŠJmLaL饣¥@0VÉVN˜kPŒ.Ðeg”94—¡ì›ÕÅüëÖR  cê‚è=wËg7Ÿ‹1aÏi¡î€3|'LÑtÇQ¸¹n!¤€R@ HÒ( Œ©4EÙŽ¡›%\àZ° µ ºúdâÝA;MX`FYòàrôTD¤‰¬È#ZHÑiÓ{ï½Gd‡‘J!ùPÉHìáÁø‹cð/X"lã\|H5…®ïfW#=ÃÓ±a>¢ìØÆ‡Ã;F/KR‡÷-ÆdÍàq”ˆ¤š§Éâ¡tÑ„¢'¸†¿ 9âÂ)2²è±A‚Í ‹z’ "»†Ã¬hH± ¬ÄYjø—µg¹erÄñÑë[é³¢°p¢}DEë.ÅÌà‚±—µ13˜²49ÆX%w³ X29wú€ûñW3 )ìwá¤OR!â+À¥ì¤—øÿb' T«Ü³K­#¥@‘ÆT¤ÒR^P@SbéP)Ð]È*!ôÆ—K膮„HÜOÊGÒ,÷(¢\w‹Owº£{oÝ5Ö!“\1õV%èäÓ&9d’+¦N–‚î%¤€R@ _aLÅ/Ã6>À²)æ0øìÚbØ 6p’ñ.ód)ó´ä²M¤”ð—°¯l’°séu‰¤ˆ‹1qO4 [ôú–as… òv¼ ý*…ãÁ¸;Ý….ëâ5@^Š…1Ñ&ðItÄ…Ü/±J`5wÿmècä5méE‰EF/VÐ–Žšè+Z±“+´eÞ¢×·<[=‰^0Zß,È$¶£—ukqº†ÄÑÁíS€¬®Ož ó˜kà”6ð-¾â$þ2ÒœfÚWÍ]™³?é…ˆR¶"”µ;aÄRÖG H* Œ©„…ªGòƤz ¤€åU@SyË6WOuÈ$WL¹* ²e&êI®˜ÊVÆz) ¤€R í c‚SÕ¶ßF7q Ðÿ ¿èã¢'æ¢ p’‰^‘Ì÷öðDóäÔÆÄë[î\ŒÉ½ ë{ ó0sÃÃ̸.ëÒ0Ø.ÆÔ ëú(²ˆr.„m:å'DÐ-䋚71ÙõÝŠ„íXŒ)Tßp={±ÒF³íbL¬ T·R@ H)ÐÓ cêéâ/óÃk¸^æÒÕ³I) z]aL½^:ôü!‡LrÅÔ!Ý{ö6Q‡LrÅÔ³•A.¤€R@ 4«€0¦f•Óy-PÀŘp9PJtkd®•EŽ ïǯ,|÷0ê9eq $^-t}÷I’0&ܾÂé=ˆ.yŒ¾ ]ÖÉèi-¬D—p1&(I@Í-,F‘+F„ˆtQ´ \êˆ×ŒrH,,œ½¾)šâ)ZßpÑ%ÖÌèeC1…1•¨æêQ¤€R ¯ cÊkÉ(_ýT@S?ÔéR@ H)c„1å¸pJ–5×!“\1•¬póø8®C&¹bÊc )OR@ H) ¤@ÞÆ”÷*uþ‚Ø#2xœa(€NÈàÒBøËãIq'90L8—aÈx þ;‚¼6ð1÷ú–c•ìtRS8€ÐoÊgøXc/K¦Š¹ÆªË.Æ„¯PŽÔ™…ee’5ÙIªE ÂJ“á۬ȬPXj¬¡ë[®\ŒÉª%«A´¾±½â¢—u÷c*uK¦‡“R@ H|( Œ)å \´\aL-—T”]Ràý·ö<ñ›=€6ô‘RÀƤÊÐ)Ì!“\1uJòÞ¾ëI®˜z».è饀R@ HæÆÔœn=~Ö¶wg÷mûÍ>z«­:¸±ÞÚq£6]¿M—m‡Í]sÆÆã´f©9étV€a3 »6 «Êb’œ’H5D ô ˜z°Ð{ã‘…1õF9ë){A 3ð®šxi/<«žQ dU@SV¥t\  C&™5[ ¥.‘E:d’+¦,Zé) ¤€R@ DƤJÑ„}[/Å ïÝ?ljâ\RtF­üÄk*úS(ÿR ^gî÷, Z ]èúÁé!¥>R@ ôš˜z­Ä{æy…1õLQëAK¯€0¦Ò±° „15!šNiV8dºù_âo³ÐyR èIËìÑLÇJ) ¤€RÀƤÊЄ˜š­4§c*MQêAbÆT‚j!Œ©…¨GÍ) Œ©9ÝtVîè-Œé¦›nÚK)Рÿå¿þ·M›6åþ·¼gÏ;ÛÏú§½–ß~F²ª,JŽ) Œ©cRëF{ö¼õÖ[ÇŸôü•R  |ðÁÇÿ¯Åè¢t@ÝB H) ¤€ * Œ©AÁt¸§ÀS‹ÏûÊw÷zý5’£8þ¬ÿûò{?Ûƒ®GîÞšyïÉÿc¯·–<Ñ [Ögüൗ=3ÑØëÊú€z.) ƤÊQRz c:ùä“oºí®­»Þ§ïoñÒîo»ëØãNÂÆf¤×«éÕ×w{é5¤ÅI/ïøw7mÚþž¥ÛßÛ¸-H¶½ç§w7l}w½“Ömy·’ÞyiË;/mÒÚÍïxéÕwÖéí5¯¾ý"Ò+AZýÊÛ^zÙK/¼üV6½µÊI+7¾µrã›L+6éù oiýÏ9iùº7,-[·kÙKAZúÒ./­õR_vö­Ù¹¤’¯Ù¹øÅ -zqç¢_÷Òê×:iÁ ¯ûé5¤g‘Vé™U¯yi¥—æ¯Ü¤;žvÒ¼;æ=´i.ÓsÛç8iöòm–f-ß6kYf.Ûæ¥¥[‘fXêÛ:½š¶Œ˜¸à¯þzŸiK¶ MeZì¥)^ÚŒ4yÑæO~úÀÙ³gç¿@õ|ñÏð¥åË—ç?·Ê¡è˜:$´nã1Lh{ÍЃ:H$“*D»Ãôõozñe×£Ö‰dj·Úº¾R@ H)PJ„1•²XÛúPèx£ûNøQG…y[ïÕ­‹¿çbï¾víÚ¾¾¾ne¬ë÷½ôÒK|ÊY_ûæ¡“'Oîzfú™%®Ršøª—ËºŸòñôªEë«_‘E«ˆ%ˆ<ûf¢Ãd&*hñ)ÛR ¿ cꯂ:?§ ôÆP ”Rlºtã­w}︓ `r饀©–^ɘ* S"À´Õ&l´aÚ†)À˜<†©‚1ec˜Þ3L>ÆTa˜°Qe˜3ÕbLÃTƒ1 “‡1y Sc &cª2L+ë3L`LÃäbLôuZ_cŠe˜ „1aºìš¡ÑæömøÌçE2å´ÁU¶º €0¦.ˆÞ‹·ô->F?1íðÃæˆdêÅJÐÁg¦qêŽûE}{rö2¼÷E2uP~ÝJ H) ¤€(‰˜JRz Ÿa0iÎrt‡þntÉH¦mÛ¶1Zñ?QQ 4pàÀÁƒï·ß~…XíÙÚz†é”3ÎÇzà…«¶ô/ý%™bnm†S®> E‰P”±‡ 0Å6’˜¶ŽåV7ꀰh}N­ÝÎ[ÈLÔNuum)P„1¡””Ç&è=ŒéÖ»\7K!béc¢×¥ã%Ï S*½’)‹&xcrœ0½ã„)ꇩ℠ޘ2ùaê'ÃTqÅøaê'ôš~˜ZéŠÉŘsÅ´´ÆS}ŒiQ1¼1aºüÚ¡KÃ’mΑLM4†:¥¤ c*iÁæê±<‹Ï<úÄ\k‡GÉ”«"*Uf<ãÔ·»ãþ1Vßž˜%’©TE¬‡‘R@ H) :£€0¦Îè\Ž»€a oòÜçØ ‡ÉôÖr‘L@[ÈÖÄbLpÞ¢…E9aÂÛ.GáÖ} 0L§žqþó»ë‚•[ûI2‘"êú'c:t(&æ ÔZw‰«®KÔ E«¥,3Q Q ú«€0¦þ*¨ósª@ÏaL7Ür'%7Yœ¸ëo¹SðoZbü8×ñR€.ÅÆ‹†«ë)5\À0ùäV[ 9l¤Ç’kÔSó S+ÂÉ5êŠiùöTŒ©Ž+&’cP¹WLù*G† ~¶l:~³f-^/ŸL9mt•­+ Œ©Ã‚÷Þí‹Ï“s­†EíðCÏ–O¦Þ«mb§¾ñ­Ã†Ý?&Tß&ÎÉÔvñu) ¤€R d c*Y¶ïqÈ0M™ûÜóë=ãÛ2c ïÖ{š÷É:Œx |°Ì$Â6üeoA'ôbcÕî ã9í®óŸÛòÕo2iÒ¤&Í´…˜ŒÚF8,¥ Ý¯Há«BÜãV*ì!œD<äáB{¬"1vAîQMM<©Nɳµ­7eÑÊsa%å-j&¢¿@6S2±L•g)Ф˜šN§å]žÃ˜®»ùÎ;%÷_|{Ì÷Oä/Bœ¥mïm¬¤ Û€+1½Kn ¸’›Ü°qièR„^ Ln¹4LÀ´î—*˜ª“?½š0Uœ0a0Ä’[» ‹KÐãñÓNÎ--^³sñ‹AZôâë^Zí¥…Nj,–\£~˜žK÷ômæRÏÓ K!†©Ïc˜j0¦Å[¦.Þ2ÅK›½Ta˜ˆ1ó”[¦`àòðËö¦ën÷JܦÏKŠ×OEM_´îÓŸûÒ¢%KÊ-Œ¡eUI«¬0BîÌ¢ ¼9xFNh¬Éø±åDYŽ…{Ç£ÙB%n¸ƒù,´cg®{³¥l ®ƒû¥€0¦~ɧ“Ó ÅgìSóB6Mÿí¹/J¼‡›uà—¾ÒÉd†ãÎC´©¯»Ä­b¡í×Ì?>IÍ{Cšpy´‹[^j4NÝùÀX¼÷CKÙIC}{|úR¼÷ׯo’dBþ;S ´ÑãÅj3.ëQ¤”KR}NéK´»Ð[^‹tA) ¤€RÀU@“êC]* Óó)ƒ>LzD£$ˆ³aýaP&f†Úk¯½6…¸dØx&‹þ†‘#¶éN‰“Ñ'ØÏíƒcÈ»ØÄQO4¨ôð`ÊP˜ºÒ•à0L§y~Åî†<`w}zùæ¯|ãqãŸhôaMs·Ð©­•]¨ ‰£ñFt§äzÌ≡€€(;s×äÖlÂ~#ÕpM‚tø`C S£ÅZ¬ãÛgÑ2çp¡ IÛ ìVÓ ÍæÜoæB6yšnh]W C«i®™ÓC©ƒfÉ~š‰lf$ÿ‚§˜õB¿J{(Ò½î4“}åÎvY¥µæ±î„Qh‚©¡f!£•5ãa ݺ­kj¬­òV/.Œ©CBë6V ç0¦ko¾3N"¥tíMÆ„ ‡UªC,‘^ qK £Kµî—2ÒK«¢ôRƒ“OÙï ;aª˜‚NOÀ”î„éõ/¼†ô,Òª =L¾&¤ù+wiÅŽ§4oÅŽyÏ#mGšËôœ—æXꧦ ÃŒi8ƒÊ%3L±(·NÿR#÷«0Lo¥XR@•M_øÒ§?÷ņH&w}o+ûC£‘6iÂUhè#"cEg'™êÎÁ[žÍ^c{Ðé´El0-a»¹É]æOA»@öÌ·IÏž»¬0¦ž+ò=°Y|̦r‰›&°´ÃÛÙÉDûNkñGZ±c5Š6õI¿nVõ‰ÞêÛàͦ>É>›]¼nhé E£Õ9Ý2NE]0›C}7­ïSŸûb$ƒ4 ìÆ>rl}cô ¾aqåjy"¥ª'•ëCôÛ¤¾D» ½åµH”R@ H) B <»ù¬»úzË.ª:ÐÃôôóî Ïõ¿ë úüõœ7Þõp£$“‹1‘G1‰]ed5 ÆÄn0¶’‰6×X`ّ͋Ù&[#ÃØL™´Ù4Y¸š;²¡5¸œ»­™½ ¸º7:7«ºÀñô}ÖTÚûÂmYà¡,Ù^ŸÇ„žÑjЉÃÇwÛ^Ûæ¹ö aL¡+à")š„²áŠSÿj´vÓ8u×cclèWáÕúöÂkc§6C2qòõ\×­o¡Š‘^ßøÔ ÃDà‚KH+¼•Ž•µí±ë³|Y”ö[pK$TÕí^¼>k)».Vñ¬'ªc4ª²|C7mk¡7ZIt¼R@ H)Є}[/ÆÔ„n=rŠÃ0Ń,tt†‰ƒ¾†5F2¡3ɱ{Èø‹¹ˆÅìrY0&v¤í:貤‚ø–CB.W@?×dP9ëÍRÃcì+f,4{ÝÜ¿ÂÕa:Ëc˜ê.[ÂòÝÙK_ýò×óÉd%k›HÁ˜XO &ŽÄ ÌÑ=+[¬8˜_Yl¸Œ‰0œ;ÀÁ¹ýñ)R¸ï© ›E+“…¡q‹–kH‡°¬x48˜ÎhI¸ßZ0~åú·ÆWöspçÜŸIOœû°!3QR¤ŽÀ,Ù¸™Ê»+±íEbu´Ã&}\ 2Ï9³Ã`‡!ÛN’¡‰Wà·Ì›µx¬®!ÈÌY¡¹·RÙè/Ü•õ Õ4ìq5 ÕsžîN0Ùƒ„ÚR›£®,$­k ÉnfÕÐT®2½ÚC™Ô|‰G‹ʸE“dótí«Vš|R÷t÷ú®yÖ}Iõì·.Œ©âêÒÝT ç0¦kn¥”ÖNòù¤knvô±'F]+qÏK[Þ©¦Íï€U²T-Õ„Š{ÄSˆ[zñ•·k½.…Ñ¥Ré%]Š÷½”?ŽAŽÃî—‰¬rý˜úå„)[ 9—ašîÄ’›æ8aÀÄ4|‚ç)…aÊ¡7&aºÞa˜".Cµ§%šOyvmv’) cb?iÐ ‚®ú@<‘]:l`ù²=6f6ÀˆŽdqeןÅmc;…ÿX‡’¡»³¯Él®çb³ŠÎ™M퇚d7†:™Ëe|KZŸËž¢÷²«ñ”Pï¹›ÍÜ[St“ŸÇžš—fÓ¬Z´=g„h‡ï{tFC>™Ð¬Ñm‹_­y¡±2Ô ¢mÁñlޏÁØ´r Í5‡Át$ã~e­™™/Ùbóv\¨ä2.¼>ö[°´A„ÞvdñhI7#)oÍ’=¾â1Ñg´’g;ÏÖ†ÌØÛ„M7vR®¸²ü›a"t¤IJ6h}na} ŒSz SȆîv"Ú êÛ˜)KòÉÄBD¶-0AÝú­)õÍ>¡ZįP¨¿•NlyÙ«–u½‹ØŠaUÝnmÝ›b-uP¬¬',JÎôà_[Ýn7uªµ…ÞÂú£KI) ¤€) cRõHR }Óž~>´€fÕ¥îB‚còÏÃßüõÃFe÷ÉD´ÝH")Ì ¶Ù©æD£ŽqÝ YÏýU|È?áÃE€ØãÌÙaæ•y/žË›áÄ‹¸_á›FÅ‘=⩆aJˆèí.[BéÏê{¥!’‰CfÚ'Yè,…”‚渕emCiŽYl[v8†_Ù ½Õ»‹;Š1FŠµÂ½”Š2)МEëþF,Z®!æzƒ–\%m Mà Ù÷€qb_…<—©t2>KŒ™(ÃôPCf"Ú=ðâp'2’¬Ž´ïY»²Xš†íÂ.f<4CP’¡‰76pYN$рÛš!ˆÖ›2aC•ŠùqUiküØêÚ›Ô- Ø+›`²‰ÁÌtF_eœk3ÑøP4Ør#d¤BøÛÉbz =8N¡õ×gÑD¯oMy©)ß)QãÏÕÔXÆxó‡ cj^;™kzcºúÆ;jh$—LÚò¾=ú{'º|R"¨DK5n–ªÄR,´å–V».—°á–Baã¼é«DzéßK½”!~\ß/nnÝrô™l ¸ŒŸBÈE£È­¬EÎ$W"‡mǼ1ÍBªøaÊà„ik Ãä’{ÐØöž²x3}/EÓ'?}`~¼1Õ0L¡±t²%1û&Í_»ÿg3ùdâ#Ô-s»)ìŽpû[<غŒØfÒí²K„l;Ñí¥Y‡¦n§Ð½—Í,ZNxw\„'æ{ØÿCW,šUæ6¶µv{¥6ø7×ͦ³½—]GºÖŸ\¿Ê”9aLe*ÍŽ„JlÏ‘=ükÔ©e ¤)½B’&IÙH²²5]së§j]1ùS0ƒ‚úöèäÅxïgŒ.g¢ÓS·¾™aÂ*FJ}3’$ŠÖ™¤òbM ½R£%‚ Z². «±Õy^ÇìõÌ?íGn=g_"zS>TË ½éÚ¢¥€R@ HFÆÔ¨b=r| Ù!®ôÁìYô]wGV’ÉíçSXýùÌ[ûrå0L.ØÛiW¯l‘eKóW옱$ÓÁãÆ?Ѧ¼¹€–ßÂ]Ôò‹ë‚ùQ ŽE+ÎÙs-޲ùA‚xlíu DIȦ¤[H[æGÒÎç$l&J™ò'ïš6Ñ¡Š åBkdŠÕÑ,oÆÄ°|] Lh¾‰æ›ŽáœQº¡É®Àzåšzl®Š† ‰+‡À8ÞK+­~vãºY²Ë²pùD¬Ìf§â-\£¦µnõ&¥gUžâ,÷›W`%·{ET†1™z6¿2½º¿&Ì£[4Ñë»%E˪íq1&^Ü5 ™é8TôöŒško‹!Œ©½úêê]S ç0¦«n¼#ì9É ‡o1Ÿ¡”*Õ°JI¸R•X‚Ë¥—-9qâ|h)™[ŠÄŒËæxé9då&×÷’·jß’·|ßÒξµz©?ޱSãǵ`ªa˜–o¯‰"˜¶…£È-ݚ䄉ä¼ä3LpÂ`L SÞ‚Ê9 SÍXš«Áâ]2T,)Ò÷äÓ™H¦hÀöTÜž¥áAè©ØZ.wLÂéCûÊ:I˜Èò³·gýEëù¹#–P·Ïºè`Ùt¾uͼb“—–Oö5ùq!}>»VìÌYGÖZåP¯ÿº¦œÐÒ%\$t/^'”á®5ù=xcaL=Xèm{ä˜UkfÎŽ·i.ñ`Óœ·bÇÜç·ÿnt&ŸL&¸t’&ƒP#lªû¬nãÃѵÛ@Ù(—-Ûp×m÷زv?îÂ)^“ËÙº²ÁŒ¾/BcàÐ1ö€n–Œ¦²á.³äfƵ ðA(ÛsüåRþkžÿðúp öòŠ^Á^+¦OLÊ_­ª€iÆ©ôúæcsxï?2)+Édõ¦ÃïØú­Iõ óÝŠlM›©k‘¹ûæNÖ«¤òâ18˵rFK$Š1¹ÇXVùî}ùÊæïŽ= ;8tS«™-,ôVU]G H) ¤€È¢€0¦,*õÚ1Œ%Wã‡Ée˜âÒÿ® ú®½=É”sŒ‰¾1zmÆ1Ä0ùqšÞ¤±Ý\á&-[Âøkú¢—|­]$“YP[þ“ä@Þ\·üº`[´\ü¥ž…¡!‹VÈnç¬u¡ŠG÷3<2ºd(d&ʃªÎC¬™ˆ¨e³ÀÚ˜§ŒŽÒ™Èt8UDCeÈ"Gë E€å„vH.°ŒZ`\à±ÎwbÔÐäÞ®`; Ê¡aÇ Aô9Ç«¹u,Z©p–­ë³Ò$WŠ­ÉvLl=w'˜ìÈÐëÞ2ïîw­”Ì­R| ‡ŒTfà5Œ‰‹š^£yˆ-÷ú¡_ïeWŽÅ˜ÜÚ{}>‚;—×áN¯ÜNS¯”tÏ=gïaL7ÜaQÞ¢WÝpÇÀïpR(QájX%BKµÄR2´Tñ·”[ò†Oa¯KñèRÔñR8r¦1¾—¢ô¦ZßKŒZRã~é/h ý ù=¤jZ‘ÉSSR¹éN¹(ÀDLĘ’ü0å cò¦ë*±ä|¬þ·bÇÒ!Ö~ÞóÞô9¼[=1oMŸLèš®NÞˆÁP߈{ˆÛ£cŘð­uPlÛ¦ Ñ›D‹½±P¯×m‰q¢»Ì‚]F÷^œéŒÞèP?‰¾ ¢[/3úõJéź­Ö³öȼ/¨ ò]{» cêšôe»1,>0gucÉUÌÙ.KšbÓä îžG¦×.çnØ”¡©t‡|„A ¿]A†Òp 6×8ÀZ!kÉ9¼´ƒí:¡ÖÌÀ¸»-KB\bÃFÎÖî%¥í"ô‹1Åf‰·³7QôYÏÜVÝ |=áÃ76ìA\AÈê#í Iš¤d£Uõ>0N=P‰%ç[yï^-~jQ]ŸLæh™çk·n}‹VŒ”úæÊz«âß5eïôØòÂ¥`U±¯Ì¤ªü!ŒÉ5Ä >Ð0Š¿ôÉy)\™F.ÖUëKDoju¯U…®ëH) ¤€V@S‡ÏÿíÈ0MucÉE®ÀšºØ!vü¡dñ}Ë·_sûCÙ£Ëå_–É¡Ç0y> õ^0„Ô`Ãxê¢Mí#™z¤ ô˜íP lѪXˆ¿d¡ô²[´bñ[oƧ3"ãq›nÀ~‹~@Ó„Y½L“^æíúm&ÚÁBÌb&rÍ;´–cŠZ a¡×"Y¬&c ™c Mv‹Œ2i0\QŠ­T49†¬Ø²•qa›UÅtŒÉµ@í²ëbL–yºK©²›^í¦6¯-šèõ]5¨¹)µ—ºEF”Í~¶f|Ã45ÖŽ†=|MaLPY÷è‚=‡1]yýQ‰{À$ ¹Þتp’¿Óq§Tõ«*UX¥XKÅKÑ8qÞ0ÉMëƒY++nŠñº”]ªu¼äM¸:èRÕ÷R½Ô¼û%ûö<xN¼á=Ós† <0¹ÓŒ>× Ó–¤(rðÀD€‰Qä_ Œ ÓÞ˴±tˆµw\1Adã›0wÍ?æÀEK–¦´7\t…~ Wä4J˜øU¬‹#z-"÷chvà, {ÌÞ° ï‡òfÞ5Øæˆ;9Ôa.câSðúìfñôXŒ »^F’z¥ìµ»dGbÖ¿݈g±ïB«ßk·ÆÔk%Þžç5‹ šÞ‹ÛMó¥cñy1ðÛ¬Ê]¸b‚±Àk‡—m»ëáié$“5˜|‹e-*[QÖ²ñ06Ȥ? ñ`ë ˆ•µTtiÃAi¨5ã~A‰¢†LHlºÝûb½…°W^„ (ŸŽfæÍ "6Ô¶‡WæYöâ=#%ââ0f’¯ îw·M.^ŸYBþùFˆ½B’&Q©ív-©€4NÝi »…n}‹±¡W\UÖØõmù¶‡ž\„÷~Jt9CŠ]1íÕiåªoÑŠ‘Rß\YðÊæÛ™U—¯i·Î°\’Ê‹—r_µöq+¿û^æ)nþQ‚fƒ#®dõ¿«K¬E8׺4!³—kÆjIéë"R@ H) ¤@ÇÆÔ1© q#c˜Bƒ¾¤i~. ¹b²AßÕ·ÉTˆrg&†éÍ4†)Õî ‚ CþÉ 7}é vùd*¤Êj~ˆµhEVIí VåE,Z˜Íáêèì-×;‹é€6N®yŸËϸß,?<%JœÐÅN~„ídN:l&¢ÝÆLŽ”=Öêè–5ír±ìŒÅ˜lЦ•XCSCmžî´‘‹ÅbL|´¨Šæ 3BrRÉ = câ“Ù< ír|"×fvQ.û´_ ¶£F*Ͳ˜^í¦îÁ!ãXôúT‰Ù ÉŽzÒâÊ"¶Ò´"3[tèúÌåwò'Ó‹÷ÆÔ‹¥ÞÏ\c²Òl4 ­ cr½u•TÙƒo:æ„øüpÑHpßøöáD”˜žœµäª›îòG¼oÝ7jâƒ/a¶7 bÚðæ7¾uø3–`ƒS¡=iâŒ%þU&h‰1¹—9ÜR(`œ_¬&lz¢nòÐ¥ÇK‰‘ã0,?ç’«‘\÷K_ýÆ¡G}‚ë{ {ξè*×ýú¸n½tØÀšø 6’&tˆÏ¼`È?}êóAÚÿóÿ´ÿç=êxÌûÎdZºµ†^ª !WÏSÀ0™û¥þcL»v/o÷‚ S@¼9s™§Ü4ïÈ‹'#sÇ3W\ÆÕ`puñï]ä§ ïYèû ­l@½ñs^¬K2a>æ–É…¦ÍQêì~YgÎØ9Il*á+»¦ïöc×U`'ú:¡Q¯½šÝ_Ù)Øp[°hV±'öÖÑ¡—Ûíæ|¼› ´hÁÂШEË’GÍûVG÷»ƒt»B¬é>‹9<¦%f¢\9cäôuK+KÝ~vãÜ Ï¼Œé¼+F,³7ÿG§‡ÒÍDfA¹„fm\ÃK¨8Bÿº˜Xã Ùšù%dh Ù3™±èD’kGrmžföቱ•Š_ñ¾î\˜Ý ;£ÓâI¶ ›`ŠZ–B™wm§f˜µc\[nèR|ØŒ¦W{ðuÔŒc|ö¨…-jLf&M^ûMÅÚÐÜë‡r›ÃcI²$Œ©$Ù£a ãñ^pÛ+ÈQc""Í—J 0&º´IJøSÊ+}ײ•ôæÉ?ýÅß~â¿sœƒôäÌ%Ÿúì-W:ãœKŽ>ö$üEºwÔD×ÇÒ¾ŸøïŸeâpÖ¨ñ³Rœ-eá–jÑ¥_ÕE—N=ë¢ÇNOç--:åÌ‹~~æEÏ:‘ãöùÛ¿Gò‚Ç­ôÒÃO>³×^{ýìŒ g7D/™ï¥O~êów?¹­íŠÇ0];4X ä84F•ÀHã–ÇVŽ™»ñÑ9ÐIýÙ sYŽ_=s¼×O½Ç0¦ÊH£bI™Þ·uܬ՟¬ç“©­ÏUЋÓ?ª-,ÀSDWôÑJ›maL¥-Ú=->cžœm‡ÇÍÛtÐYãÇÎ݈v °’_Ý>í0¨_¶Ã´ø€â­aJ–m…Eí𰇦Ö.×χä~^¤%§³3‰Ìp5OÆkâHZ²B oÆÓsuØÖwgßÕ·ú é0¦¯ë°a÷Izï\æ{iôìõ¨o˜A‘ï}`L5õÍyïýŸLý—+?õ­ÿÏ¢+H) ¤€½ €0¦^(å,Ï0Lóžs:áÏ»~¸¥ƒÎ0Ls6`¬wã˜ô¡þ“ëçpÐwÏSkB üAß–!"™²@›Ž¹ð{.ßÏòÇÓ/†éTŸa²ÅÆ®ße˜^1þ2† ËHÀ0ýô†¹Ý;iM°ŒÄ&hÆûO>³á‹òÉÔ¦’Õe¡À3÷ï9ý/öŒ>+fJ±hafá±¹Ѹ¡’“aBõ¾rIJøá¨‡g®Ã¤Ú:aò1&—Òë˜E«ôåÜ3Ì’(AÑ`™=k=¦‡`&:ë¶ùœB‹ÐÖí|¤{›7uñ¤P9`âvsÓü w`Â|$§$ÛWQc/ÃT 2hiÆ0âXš# o5ØE“PˆÏ\ÂåÓQRDÊ‚Õ`΂ ZR ר™/|òÓu¢ËµïÑ ze œ!˜.ÒTЇ*y¶…1•¼€Ûûx´ø<úÄÜ ^ï’[÷&3g£F{ +"–ÂâãµÃ+kÛáŠMo4 ÐO]²åö‘SÚJ2¡½ ÑëíÕ+õêÀ@Ñ`6êC˜$>c›úCû”õba¦*Ãx^¬©o|ïÃï—…&»ŒuÀW _®oÎ{ß«o}^}{p¼÷ÛG2媾º¶(óR@ H) ¤@g Æô‡ÞêÌít—|*@†iÊÜçb}¾%6XŒûò\­ €µ÷,)ãµyì ‘LýhPtj!ÆTˆbÊe&añùìÃä·ÃÁ[žïqr%Æd«ÖhñÔÖûo´cB;¼hóí#ÚK2åRÚ^Ì”kŸŠ…™<†é›‡Ýqÿ˜¤úÆ÷>ŒS|ïcúdüü—ñÞ3‡„÷þN1m]¬ë¯à½ïÓÛm%™z±hõÌR@ H) ¤@a Æ”1òoaŸROS }“ç>—Ô § óÁè„ãï_ÀBÌÃjŠ1ÍãÛñ—M E\²„X] ƒäå7‹dêF=4Œ)fÃtÊç§Ø]Qú NH°Áî:áéõ"™ºQö=pOØ`¦º-X°:5F†+G.ƒE 5ö„+¦c‚§gXо!]óðsA8¹Šsq³0È¢ÕŸªÖ ™(~zfIÌÍ¡œúRÅ,¹¨%Z*o†èŒñgÜ:_f¢þ“Ε…Q@SaŠJ +€X™`àS úº>Ædœ°Æºè$“Ç…\3”î‘,¹N’ðíw¾{¼»'i{à÷NúÝCÉ*¹|)!q6à` dô—^ûµo†YOK8 Ð,!c«„„ Ɔ;ò˜“FŒ›ùµo†qSZ„8EŒgÓþŸ9£)¤ß^sÇI?>ýÁ±3-yý‹¯ÿæš;'rÖEHk!aÏß=ñþG§Qââ!¸_ºïÑi‡+½ÿql#a?ùéˆ.}ÑU Ç„¾È$ûûÐÏ6ðø[bÂ6"Ç!aã¸JKX“„\ Ð1¦áãç]3mù±?d:ä°ÝÏOU¼s þXஆœG-Ìä3Lç™Ù?X°TY³Ä!?ŠÞØfo0† ös„“›µtÌã—=¸´.Á†¢H¦îê܃÷ì§§ü±ócªwÅ3S‹7 z¨ážy™®±ì†GŸûòÐŒu¿{jÍmãVÁB诜ñø#³6X$2Y´Zehj‰™È3K®Ù †‰…H³$¦¢yδVìtÝœß<Ðvè{웉ÖolË»V•R 3 cêŒÎºK@8‹à1hРP4ú“›¥·NmÈyë/ Œé·× 9FrÿÅ·ß9úø”øÕøi‹Á!~ö%HþÆÅÆ'aÛý×@%l¯õ¦?áT ”’£x ôþ1n˜¤¾ ¥¿J/LÂNpE¿½ötJ°Ah‰Aâ;ýÄŸFhéÁ1œOK@—-a{¾ú/‡^;t¸-½gKØD 1êF‚›%ü‹á7® nÉÒ½£=Œ‰ÜÒ½LcÀ8KÀ˜0P¨tÉ•CÁ*ÁëR€1ýâ|J‰ cbW `˜îÆ´ÿçÑ:ô¨ã±7KHˆgôR<®ÏǘFLŽã§-øwÂܵ¤—†Ÿt ý-t¦± ÷K'Ÿz¼1ýãþŸûÇöH¦bL¿›ÿO±³Øy÷Ò FLÒMì?üg{¹õ>B­þp ͱôèÙë9wÎõ@ž;kYÅ£õ·>}þ] Œa ¹qY®ï³ïï?ü¨õ?9]Q t]aL]/‚bf Ôa0Š”ÖLÚ²¹×&:m†½ ˆéé¯ËüeL;ì…õäª\KgÿúÆÏü_îìûM¼2tJ 8ûÂýü—çYÿÓ}ï³£hïýKî]dï}NŸð½ÏuÀ‡_øÔð©/Õ¾÷½úæ¹`têÛ5Ã=àãÿù?ÿßbìž®‰_Û%Và¡SŠÙ6+×R@ H) Z©€0¦VªYÀktÐA÷ŒœXí„W–ºƒ>†éÁ@ÏÓó:\•œuÛüh@1Ló3œœqÉfˆ9î;ñ'¿:ç³ÿõO?ûê„w]Ù—‚-vü*}†¤Ý ŠÞÓdËH¼µ£!G5‚+Hÿê¯÷Þü¯ÿµë® ô„gýåÉßûŽ;±h z¨átá3yÑ«p3†Œiäôuæi «£yËÓçݹ€kÎ1A#‹VglPÍDf–hKÖ–fI›ºõ±•°e2øå?~ôç¾Ì•e) |„1©"”B &À-“û(u0&¸r2LÑ“ § f%sõm®W¤Ð6¾>’r€aItž„>  19ýW#aÌ3nê"øRâä‚ÄTâÄ'ÓAß<ì²kïà¤ÔÜe/!šüô*pKžk%Œ×x”Òð±3ŽÐÒõ· %ÉS°J§žuA%BKt¼äxZò÷œyâÄ´tÂɧž–üÙ¯ŸŸqÑ}£§1NÜôEÈ-ZõÄ3GnéW¾7&¿ÿêM’!Uz –€+Áy2q%DŽûþN¥'€›î‹tæC¾ÿÃSá…#:àJw>4 (Ò0ÿ/Ñ¥cpÊO?ßè¥ ·äaL·˜„Î1Ó÷N:èÒ—:ôÐ%œŽi`àx Óéç^ñÝL˜ŸCj!Æ4rÌS÷ÆÄºêÒK6‘D;¾Ø‹vLwÖ³—mC·þ~rýœÛ_…2B¡ “z׫Ãci‡µçXú€¿NÌÓ½w ÃøëÝyðžrJÔ³[ÏS]‹j8VGûæà‡iéO¯Ÿ[, ^´úéëàÂø §x¿à©;'®®iÜdÑjEhŽ–˜‰h–äôJÿ™Öu<œÂêJ€héÓC™hÁ*L‰dêñ®‘¿À c*páõzÖGŒ¸pTAåBqåê{c÷'N¸6úúú -'1&†ƒ‰M¿¹ê¶#Ž>>ô•ùLŠÝ€_%ƒ“°ÁXoœã“tä1'â_lе’Í}޲@Òw¾{"œ-q}GpKˆ<-áïAÿr(þâ†Ã¿ØŸ„ ðI€–p:âÄax¦YK62$ÜGŸ\ {f.Þˆ¿Jø _MœµÜ’yZŸ„íÛî÷ë+‡‚[¿‡}†d‡}‚-î¯|ý8[·¤ç|ŒÉ‡ rKæu T¸%ü‹á{aãàr aã|ziò°‘“±ñèÔå ”@/aÞÄ€qæxišöû‚ÇÑU)Ò½ÍÞ놽„Èq؆Ë% Kð½4nÎŒ ±têyØøÝ˜¹­Å˜ÐCŠÂLs^n×<ªë¥WÝV©uÕÊcfÆ”aÂܹ7ØX± f1/¸kÆ?¾vvM£`,]uâ2L|@‘L…nâ”ù„1©Z4«I¦Qãç…l/q¶ÃX”ù?å¶Ã0àín‡Cë2k™2LKWof#¼eçûú³?5[f9>ThÅúïþa“eqå@2Ýú»Ñéï}/¨\å½Wÿcs7žyÛü#.| ï}Ì\=j¹oœÚVµ0Æ2L¾qŠI&ªך¶eíÂOcj›¸º°R@ IaLE*­öä•$ÓÄY˃>M)C‰!¡ŠÅs†ºò5‡Ù LtÂayƒtôز¶ÆOm'Üc˜>|Õ†×Ùßö†}í)ÎÐUÑéu½«V&; $ÓÏ~q^Êø‹šjÆ_ó6ò@¹_p·WîN]ëzᢣ×.#ÊÝ;rœ¿ÞÝýaG^7)»ÏÜ_S½+áäì±k-ZOqÑÃ"y z ”i€&,ZÆ4í%0Lhèоará_¯daE«?õ¬%f"£lñ†ÂêJX)š¾îÉg_Añ!L¦€²•™¨?E¥s¥@!ÆTˆbR&ãضmbÁ` ¹bÂáõ1&z 0.Tt…+\HàÉÅÊ ÔÈá3Þ(ˆñIô¢4¾–½ÌE$“~{Í“æ­â¿‹‚äÅ€Cöàãð·4fÒt"äÑI 8BžÝ·‰ØóÀ£ÓG?µ€Qá ]Ì™>´Vé‘'ŸÅý-ÑÓ÷ÐÕ-½Ý"H-!ÁÙ’EˆûÝ#Ó¦-ÜgK=ñÌU·<øÐÄgèr ÐÒÝOEÂÆ”gד[bº{ÔTocù¶ãç3`ܤgÖ!Ñëü-Ýx÷XN¤ùi+Ð¥Ç=ýÄÓ/ÑåÒãžÆßÑS–#fÜýãžÆà‰.Y¢Ë%†óF€~º÷KŒr냓È*aÃÅ•ðoF?L< °9üú¦OŸüôðÆdNlÌßp稕Ÿà|dû0&üÜXcmŒaëÆãO¿ 7¡^š±î©¯˜³Ð‰Ï¼|ÍÃÏa,M†Éuúꎥ£ “H¦¢7qÊŒ˜T-ú¡í>=>;¶Æùa6Â~;ìÆ’«¶Ã.SaIC‘Lý(«¼ŸêÚ§B“e= ™îTßz“Õ70sæéýÑÙñÞ=kCˆ]¦³w 'ç.°s{5"™ò^{Zž?aL-—T”R@ Hb* Œ©˜åÖâ\$ÓÌe5ü¾#|ó¼‹N¸MlÄ´uÓ—l™±½ôì “H¦—_Êå cŠLvH¦ŸþâÜ èÿ[ï&¯« Á0þ@?L罄ñ×øù›jã4m ¦Š£š(ÃÄÒÉÔ¹:Pâ;Ƙì¡ëZ´0»clܸ*ÓCcæläjøU£–ß?emÀ0É¢ÕêêÔ3Ì’n¼Kx d@@âÝO¾è…épÜÅEQK™‰Z]ªºžèž˜º§½îÜfûŸè¥2aL-ÉA.(äß®º¼Ql·À˜ˆeL!2‰|R|8ɇ@ñ©‚(«„~¤%oÅ¿è'”Ðˬ†‡óq%$°JæiÉ %#–ÜJ¸ N¹%ó·„¾ŽË-“O,¹‰Ü’› ]bÀ¸ T\eÃq¹äù^Š¢Kt¼ä¢K·´xóy¿½¾—ài‰È1¦,þ–ÒicÚ´ý=Ôç5»îÌÔVŒ wñ*í•·Y²´”©e¯tRéñµ–a ¥“&‘Lyh©”‡V* Œ©•jöâµh÷ñø,FtuaÏ«¼·w•Ç  “z•oÏJl¯À/NÔXË0‰d*k%£}* `²§&ÉtËÝ£Ý÷>;‡Vßê¾÷ý¾VepņždœŠúdÚ¹ºïÃÝ^?'ôÁþ²–NÏ=—0¦ž+r=°R@ Ä+ ŒI5ƒ d?cidÐØcCƒ>ØNi& úhät„ü0¹k à“é½×·Æö±Ñí«¼SÞd€É.å‘L§Ÿ›ÅîJ†‰¥OÛx8’ ã…+‰aÊB2¡V¼ýÊZÈ+î^;S2ÀdbТ5òñÙÍX´bñ—Š…A­þ׸™‰úÿ°º‚mW@SÛ%Ö º£@ÏaL¿¾òÖÒÈ¥Ž^|ßcJâ²2I!V)Qò¢ÕÆ€J ¬’Å[ªàJœ4¾hÃÙ]e¸üñÀ¯Ò¯.º*Ä-yÄ’7ÖªK™ ¥Ê¨¬!n)Œ.UCÅ1fÜ–tt©âxÉC—èx‰|,vîÆ$!ŠœûoÓ·”är);~Ôª#Û„1 Ä óÖýà6£o[þ¸oþb'ý3á/¶±1âùø Ûø[÷÷’éâ+n±j;6wÖIs™Yü0‰aª[: H c*Riå:¯´û<0ff€×LfЬkÎÎÂ0-X½L‰+Þx­àeÁ7ß,xÅðm‚6ð/7øZÁ)¹T™KU€&ªî|8ã{¿fúÄa—³3Lô·DoLä™°_zÊ«H؉ ¬ç~FMØiGªH £€0¦Â•2*¤€íU@S{õ-àÕI2Ú;è3?%u}u¦™£¹ûûûÉ×ÐÆjö¨‘ »ÜØ@ÛzÚôØÄc¬‹^@seL?>mpdüU ?'m ÉÆè'ÃÄ¡k‚7דpDݯY®kUn2X´ÆÎ¬‰íPYÝ‹¬[¶|èâ¡\¶'‹VJ•iÖLÔäR71L¹ùù*#R ›˜²é¤£ §@ÏaLõ~TÙƒo=긔¢ÁÝè6©Žó¤«äÏ}¦§Z¿Jɬ’ã])W Âu»á’ˆ%o)I¶‚ƒaÂÄXMÊ-1„Yo´Tá–ª.—ZÅ!õó:m˜¬ó.8æ’ßûÃ{h¬kŽ©e„œÛöÞ6£—pN©Û|€dºèò[ `òœ0ùQäj‚²/³¥`ÍÄ’ÃT·t@ÁÆT°Ëuvi÷¹ïÑ®'¼ ¦AÓG $õâ¨âmè8mnŽa¢(öÁ%×?_(À›ø6Á{' ›k¹{>s4Q]?lTúV}ï‡ë[v†‰b›eœ$ö˜&L–€sZvïÚзöÍÆ16Å‚=ø ëƒ{¾Ð "€0¦‚”²)¤€íV@S».âõI2™²$¥îÙN}c)ü0M‹ úê2L°¼mÙù>&t§Ñ¯6§§èr£û=¤Xð/W § TÝoö·?ÜýžÂ=·©jy$Ó©ƒ+v×°ó{[;J;¹Wú¾õÛ‹0Ð † Å‚¶BçcÒ?Gd6@C5@=ш¬M5¡”—Í›E +ñÌl[ÖìM³eѪ[ñ¢f¢êôo–Œ§l_ê&†©nYè);„1å®H”¡Ö(ÐsÓEWܦÍ'ðí¡G~?倘¯êI!\)à“<ÚÝÒvt8Ü4xŠ›*aàâA%‚,•žJƒ¸¸¥*±” Z †èª¹)[Úl¡âúɵéô6aLX:€Î7~£èŽs+ Ü®9I&ÆIhlg ’éÂËnöªG À™;W,¹Ö´“ºJ‘ÆTäÒËaÞi÷¹÷ÑuÛá¨9»? “½D\Cy`2.„_+„hs( ²Ô4Q]wǨ&ê[£ “YƱùL–p©7Íè4ÓcöcrÿbÆÛ8’xþ6ôt:¸k cêšôº±R@ äKaLù*Üä†$Ó£“W;á5ÓÃÃä›FÝ…+¦ßø‘Åc_šnx@¥Øò-t•JWLØfÇISû* H¦=å x>¼pÔ_ý[Fз»¶Šaâ‹°× ôY1lD† ×#—Fdí« ¥¼r®,Z¶RÃ~»–,ZYj]ÌDb˜²„Ž‘¹S@SîŠDj½‡1UœÙÄ:C‚«›CŽü~VWIŒìVßdRKâž0œÄ=¢”F)¥‚JˆH<8Ç»R=\)>6\Lx8¢Ku-q—ÿÔ&Œ‰oüF]ç¨`•ø«ÅNNHf„46è±)Ë$Ó—Ý\õÀDçþ@:i)˜bÉeVÇ”SaLå,×n>í>¿=Ãâàm[i„mQf«ü0áiñšÀº4l¸†×É‘&FšCA;a·rWŸ¢+@Õµ·r=/†ßû‘é“&&Eû8£WÐÍè¶äÆtìä„ ‘&lã[$l`ApÑÕî•ü cê•’ÖsJ) ¤@„1©Š$)@’é‘I‹ëúh¢ºzèȘ÷¾_ß (oŽaB6±Ì—ñ ðÁz_F‹ƒMôæTEŽ‘æød˜$:jÒ§ c*F9)—R@ H)ÐvVì¸é®¾½Þýæ¶ßI7(¦$™zb¡3è‹Y=Ø(Ã1ÐÁ6G§ìNù)ãÇ‘Jq{Úô½D¯“jÝ&Kª'ùŽ”’})ÑõÎoüÌñ«”Â*ù˜K°jÄ[»oiQǽ 4RÓÙ.4Æ„¶$ÓàKo¤÷,׃¦|7¼Ê]ÆÔA±{ðV´û {hªµÃîûH SV‰¶>2MTCn[ßÄ0µUüR]\S©ŠS#¤€Í+ Œ©yízéL’L#&.¹ááЯ¡Xr½$[IžÕ#™~zv¬ÝU SIʸ‡C­~KÌDb˜JPôR`0&U‚’*Ћ“‹…¶1}ûˆcSHó”ê6©–äFKã“,p˜7‚rS%œ*ù\‹X¥TB«èI¦sþíF‹&C3ŠbÉ•´ÅÖc5®€0¦Æ5Ó )@»Ïí#§„Úa1L ɨƒ3*@Õ·ŒÕ71LÔaž˜T¤€R@ ø cREȨI¦',­¢ÔQÀB’餟þ v·ôÅ0ºL•yS@­T†~š‰Ä0• è¤€§€0&Õƒ’*Ðs‚pÑ×Q(ù.޶âÛoq,·[‘ŸI n“B¾”ÂpRmÜ·ZD)B)XêU§J=ë‰íH¦³}£‰ †©¤Íµ«)„15%›NjHÀî3bеÃb˜P7¤MT˜2±ú&†©!u°0&Õ) ¤€T@“jBvH2¡ãmp1LÙÕ+ú‘ ™Nüɯ¬èÅ0½@•WY´JPš6‰a*Aéë¤@ €0&U…’*Ðs"p±Øâ"²áÛo~ll˜¶†vÆÓHæ<Éñœ2‰©ë-.â›Ï' QjšUJ9±Þ˜Ø4É$†©¤mµ«Y„15«œÎkH×î#†©!étp ¸&*1LMØë§ÈS¯×=¿R@  cRUhH—dÃÔt%8ØH&1L%(M=BHY´JP%š0‰a*A¹ë¤@UaLª %U ç0¦s.½1…1·À˜ªÄñF¹µ’Ë$Õ†u« ñ&2©dRC×, Æ„ $ÓÏué~yâÔùë¶¼›’ÔI-i{®ÇŠS@“êE§ðì>_ßx|áKKWoNi„¬Þ¹û÷u*_ºO9 ‰êç_ùùœ³`Uú{_õ­œ• é§ÆÔ´t:Q H) Ê¥€0¦r•g'ž†$:áß<øðU^Oé„oÙùþï?Ô ¯…Ò±{€d:öG§øÕoß;r\úøkÇ›t,Wº‘h‰$™<‹Ö_–E«%’vþ" ™‰4=ÔùÒ¥@{ÆÔ^}uõ®)Ð[Ó¥—^º—>R AþÓú‹©súÜê¦íïuí'›zãŸýð1Lù,åªk cêšô½xã7fÞ{ì?ü—¥ÓžÃÔ‹ÅßñgÞ´sÎü/#§Ý,†©ãÚü†Â˜ ^€Ê¾R@ ´JaL­R²§®’験ŽÃÔS…nûëß\.†©7‹¾ž$Ó±Çý@ S¡Ëzç;›²˜‰Ä0º”•y)¯€0&ÕŒ’*Ð[S´Ó'~ô­ˆU ·ÓžË÷ß1‚ü0•´¹Öc5¥€0¦¦dÓIM*ðÌýúùܲdNR;,?LM «ÓâØúîì;—ü‡ùF¤¼÷å‡Iu'FaLªR@ H) |ˆ1¡O%=¤@vví^þàò½_yí­¤N¸ü0e³ˆG¾ñÎïSÆ_òÃTÄ2UžM?ýùÏhÁdÑ*n•x÷›êš‰Ä0·|•s)¦€0&Õ’* Œ)-ö– )P$Œiùã{ð®Éôæ±ÙV'µ¤Í¸+UaLª Tàíí{ÖÎþÓ¿¿k÷ÃÔÉ¢è…{aÊ o«wÞ¿íx;£¦^¨Í<£0¦fTÓ9R@ H)PB„1•°PÛÿHS×…Nøòm·ÄúÄ0µ¿º‡$’I S÷ËF9è·I$“,Zý–¶Æ”n&ÒôP'ŠA÷]Q@SWd×MÛ¯€0&aLR arêéòý=Œ iùãQ’IÔö7§ºC.Æ”Ëb)z¦VºìÞ!ѧØÚ7ûíWÖbÔî#‹OÑ =‡ù‡}ªoÛov½¿õ-J2‰aÊa‘å%K˜òRʇR@ tYaL].€Þ®˜0CŒ4âùýþÃ÷C$“¦i“YŽ’Lb˜š”R§åOY´òW&Ysô‡ÞJ1iz(«Ž:N QaLE,5å9ƒ˜FXä H äc¢+&&ðL{ö¸$“:©CRR„1•´`»øX˜æ^6襧FDó0aЀ«û¸ßµûˆaêby•æÖïýá½”g ‘Lb˜JSîmyaLm‘U•R@ Hâ) Œ©xeÖíÓÓŠ7ýñ£j&1LÝ.œNßß%™Ä0uZ}Ý¯Í È¢Õf;qù™HÓC]÷]T@SÅ×­Û©€0&aLR aòˆ1™+¦ŠC&´$™ÔImgªkç^aL¹/¢beΖÀ*Ãhɸ%<È#÷ããp?í>Ï®zLIèÈb=µrÛu&¬™0h ôl˜‰J S×Ë+ïÆ”÷Rþ¤€R C cêÐe¹¹b2‡Lýé’Lb˜ÊRÈ=I&1L©¦£ ¢€kÑ*H–{.›î°í½m)mf"Mõ\åÐ÷ ˜z°Ð{ã‘{cÂ+CŽ”´uçîo~Œ¾-“¯½ùÁö7v§?Qîz~®+&Ç!ºªšËì–\O™¬€0&ÕŽ–*€pr`•àéÃÝïgZpó`lcc÷Îm$œp·©ƒb?ŽD;¼c=”ôá„-ÍŽ.Ö ÀÓàiƒ‡Ìóâ®ÝåE-ìÛæ9ýâ6>f·B}{öå>~«HT@“*‡R@ H_aLª )àºb2‡L¸H¦ßøQC—ÒÁ¥Qàß?øcižE"B ÀÂðþïÕ¸å´^Àò³ß­ûÑ.„¿° ᯙ‰Ìd„B|~Ûœ<åô!•-) ²+ Œ)»V:²P ô:ÆT¨ÂRf¥@‚!WLŽC&I&z]aL½^ZüüÆ*aãå¹xuÆ’ƒ‹&€Jøô]4yíªikßl;²ÅÒåz@Ù›fÃ8’ <Û |d <3a§ùgÂNؤ`®Âh'ìÇÁ= Œ±Y„15«œÎ“R@ H’) Œ©dÚÖÇ ¹br2µõ¾º¸R@ H¨0ûÀ4tñPX‡`&B‚9Èü3ÁF„mœ’û•Ä”R œ c*g¹ê©öcR%W êŠÉqÈTðgSö¥@¿ÆÔo uWc•*Obb,9xZb°9àM›°¨¼4áÛБ’T 4ª0&ž‚ :[‚ æ*Û‰ TDX¯¸‡æ*}¤@¼˜T3¤€R@ ø cREÈ®@Ô“ë)ûut¤R@ Hþ+£vƒg²Enf;‚½ß’pâ½F8Ò8IN)][E‡ ³@Ñ.B'LpsWày`]{Ê~ÙC cê¡ÂÖ£J) ¤@š˜T?2*ëŠI™2ª§Ã¤€R å ˜QŒ%g¶#lsð&ºôF¢÷î–gC”R / cÊKI(-V@Þ˜Z,¨.':ªÀ‡ì¥Á´äá=xWÝÿ£êží/v43º™È¡˜rX(EÎÉ$<@0IôÉDP‰>™W û1á+ìÁ·ØF\9lc*ráw-ïXEÇ q¶ØÛ*1Ša&fHÓ„5AÄîeZ7γ˜ò\:Ê›R@ tPaL»Ø·z÷›¶¾;›iö¦`Z÷æÃ¶ç½UìÇSR h ¸N»™÷ɦ!ÐKf2ÞE{PåW Hl cʦ“Ž*œ˜ WdʰHP`×&cšx©’R ª€0&Õ†–*°ìÞ`é`&lƒO2LØæ­°Á¯ø/œ0á_$L-Í‹.Ö+ ÀEŒ (z`‡Ñåà;ñ{€1Á,…õvØÆÔ+•£¹çÆÔœn:K H) J§€0¦Òi'¨oë¥À˜6uâfº‡R@ H8hr—´Ñv„Øà:7‹è´ÉöHK) J«€0¦Òm¯?˜0¦^¯zþò( Œ©‹F¹’mW@SÛ%Ö º£€0¦îè®»JÖ+ Œ©õšêŠÅW@Sñ˰HO Œ©H¥Uø¼n}wö]}{aú­ðO¢è°˜:,¸n'¤€yU`Ó[£7…>U^3¨|åQaLy,åI H) öìy÷›d&RE=ª€0¦-øò?¶0¦ò—±ž°WÆÔ+%­çlDaL¨¥cû«€0¦þ*¨óP@SbéPWaLªR@ H) |Ø›ƤêИ’KK) ¤@ÇÆÔ1©u#);„1å®H”¡Ö( Œ©5:ê*R û cê~(ùS@SþʤÌ9ÆTæÒÍݳ cÊ]‘%C˜ŠRRʧR@ ´YaLm¸œ—ÆTÎrÕSI) Н€0¦â—¡ž@ 4«€0¦f•Óy9W@SÎ HÙ“™Æ”Y*ØC cê¡ÂÎÁ£ cÊA!ôN„1õNY·øI…1µXP]N H) Šª€0¦¢–\Wó-Œ©«òëæR@ H)¨€0&U)л cêݲ/ù“ c*yëñzHaL=TØzÔÌ cÊ,•l˜Z ¢.‘UaLY•Òq!„1©JH) ¤€ðƤŠÐ„˜šM§H) ¤@ÆÔ‘u )S„1å´`”­þ* Œ©¿ ê|)>ü`ˆ ÀLúH)` cRe褘:©vÏßKSÏWfÆÔ¬r:O H) J¦€0¦’hgGSgtÖ]¤€R Q„15ª˜Ž—åQ@SyÊROR£€0&U)P0^zjIJ{‡|¸û½P¾wïÜöòÜ {eW ´[aLíVX×wƤúÐA„1uPìrÝJS¹ÊSO#¤€M+ÀÞÔ«oOnú :±ÆÔƒ…®G–R@ BaL…(&eR ´EaLm‘Uí¾˜º_ÊÈ®ÀÎÕ} É=lRöKéH)Ð cê‰bÎÍC cÊMQôBF„1õB)·å…1µEV]T H) Ч€zSÅ+³äXS AYR@ H„1©ZHÞU@Sï–}ÉŸ\SÉ XW&àiÁ̓‘èŠéíWÖ‚j‚&>#ð&üÝ=ØÏ¯ô‘=§€0¦ž+ò®>°0¦®Êßk7×Ä[¯•xËžWSˤԅ¤€R Ø ¨7UìòëRî…1uIxÝV H) ê( ŒIUD ô®˜z·ìKþä˜J^Àz¼2)°µoö#÷Æ„¹— B‚û%ÐKŒ%‡¯ð{¸ÿâ0ìÁ„Ÿ°Q&5ô,R “˜2ɤƒZ¤€0¦ ©ËdQ@oYTÒ11 cRµR@ H)à+ Þ”*B cjB4"¤€P@SDÖ-¤@NƔӂQ¶ú«€0¦þ*¨ó¥@' «oL«Få}K>™H)á/¿ÄäFšÞ$ŸL,,Ý+ cÊE1ôL&„1õLQçáA5ñ–‡R(d„1²Ø”i) ¤€h½êMµ^Ó¸¢0¦(d=¢R  c*d±)ÓR % cj‰ŒºHþÆ”¿2Qޤ@‚Æ*áû©ƒ2Ñëý3a?"Ía§ë¢ Û<Ò¢ÎI`)ÐC cê¡ÂÎÁ£ cÊA!”; »?ÜþÄÚƒ˜Æ®Þÿ®¾½F¯úÛóêÛ“Ëýøzºæ¸ç¸=7¤ÓÿbϹ«þ;ú¬æ/«3¥€R@ YaLE.½®å]Sפץ€R UaLª R wÆÔ»e_ò'ÆTòÖã•Ic•À$™7&ÀIÀ›àu {È3á‘~ø ×MÁN)“&z)PGaLª"T@S'ÕîÕ{M]è¥hñüÇ>úÓ½ªŠž»ž3nÚ‹FlZþx½“õ½R@ Hr* Œ©œåÚæ§ÆÔfuy) ¤€hRaLM §Ó¤@ ÆT‚BÔ#Ä) ŒIõB F²JÈ.1&Dˆ[pó`âJô´ôÒS#¸ñòÜ ÜMŒ%‡¿8¸0ªŒJV) Œ©UJê:YÆ”E%Ó?ví^‹1­ØqSÿ.¬³K­À‡ìü±ŒéòýKýØz8) ¤€i cRýhBaLMˆ¦S¤€R  cê€Èº…È©˜rZ0ÊVÆÔ_u¾è˜ ”̵&$úaBøc_q€'ìÁþŽåS7’9R@SŽ £²"Œ© 9uÈ$WLy(—¼ç!Ö!“\1彨”?) ¤€h£˜Ú(ny/-Œ©¼e«'“R@ [aLÅ.?å^ ôGaLýQOçæXaL9.eM H) ú©€0¦~ ¨ÓR@SCréàfˆ:d’+¦fµì¥ó¢™äŠ©—Ê_Ï*¤€Q„1©V4¡€0¦&DÓ)R@ H)Є1u@dÝB äTaL9-e«¿ cꯂ:_ H) ò«€0¦ü–Ms&Œ©Œ¥šÏgr2ÉS>Ë(¹ 9d’+¦<’ò$¤€S@Sç´.Ñ„1•¨0õ(R@ HR) Œ©TÅ©‡‘ ) Œ©!¹tpqÆTœ²RN¥€R Q„15ª˜Žï˜ú£žÎmD×!“\15¢\oë:d’+¦Þ® zz) ¤€€˜T šP@S¢é) ¤€è€˜: ²n!rª€0¦œŒ²Õ_„1õWA/ò¢À®M{ð®šxi^ò£|H<( Œ)¥Ð;yÆÔ;eƒ'¥C&¹bÊAQ* æI®˜ UnʬR@ ´CaLíPµôׯTú"ÖJ)  ª€0¦‚œ²-Z €0¦ˆ¨KäQaLy,åI 4£€0¦fTÓ9eW@SÙK8_Ï'Œ)_åQòÜÐ!“\1•¼˜[þxtÈ$WL-V”R@ H* Œ©€…Öý, cê~(R@ H)§€0&Õ )л cêݲ/ù“÷ÆôÖ[oÍ®÷yâ‰'ê¢ïK¥@–ÿàƒ ÐìÚ´ý$yc*@A)‹U@SGåîù› cêù*Ða&ôýð£?¡‹Òa]t»TÞå‹•HR@ tWûï¿ÿÒÔÏ™gž™~€¾m«_|ñ9眓~‹Ç¼»µHw￘ú¯a^ASºY H)P„1¢˜”I)Є1µEV]´û ôÆtÊ)§ü?ûý¿_üÒWÜtà—¾bi¿ÿ÷ÿ÷Wûë¿ôåÄôÅ/øÅ/¡ÁtÀ¿¤¿|@bpÀAúüâÓ|>.}î 2¥|­¦/}ö€úé3|ÉKŸÏš>ýù/ŤÏ}éÓAúâ§?WMŸúÜ3¥Ï~ñS~Ú¿‘ôÏŸý¢ŸüçϤ¥ÿôÿÇ?~ò³8擱éÓþÕ_ï}ÕUWuÿÇZ/Ë—,ú»ÿ¾ß¥?ÿ~½õ½è%„1õRiwÿY…1u¿ z(“'Oþ›ï‹‰ðzf=j¿À¢ôÿ:ê¨b0úý~^]@ äSM›6ý·ÿóÿ<缋™ÎvÓ¹Ÿ}îEH8`ÐÏNÿÕ¹UÓà‹~5ø¢³"éÌÁžyNM:㜠ƒtö…gTÒ/Ͼ°’.øå¯¼ô‹¸túYÔ¦óO;ËOgVÓ©gž_MgœêçŸRMçrF~þËóBég¿<ÏK¿°tîOá¤ÓÏýééçþ$. :í\? ¶ôãÓ{éÔjú×SWÓ)ƒÿõ”sNަŸŸó£HúáÏÏùáÏÏþáϪé?;û‹}û¿ÿÄÆ~꥓ÂéW'ýäW{íÕ[ö´|þšú™+aLý°7OÆÔ›å®§–R@ ä_aLù/#åP ´KaLíRV×í²½ev9ùä“oºí®­»ÞÒÎ÷·î|‹—v3ÝxÛ]ÇwÒæ×w»éÕ×w{é5¤ÅM;þýe'mÚþž¥ÛßóÒ6/mÒ»¶¾»ÞIë¶¼ké¥-ïxi³—ÖZzõ5Az{Í«o¿øJ5­~åm/½ì¥^~+H›ÞZ夕ßZ¹ñM¦H‚ôü†7½´é眴|Ý––­{cÙK»˜–2­ÝÕWM;—¬©¦ÅkvzéE/-òÒë^ZýúB'-xáu?½†ô,Òª =³ê5/­ôÒü•;‚´bÇÓ•4oÅŽyÏ#mGšké¹ísœ4{ù6K³–o›µ,H3—móÒÒ­H3,õm^M[¦õmù«¿ÞgÄÄÓ–l™Ê´ØKS¼´ÙK‹6Ÿø“_af—©õn¿|ùrjó–n„¥8ÿ¹­÷4ú^ ´NaL­ÓRWª¯€0¦úéˆÖ(†éëßð8ùdêÕ‘é¹=†é Ä• Ö]¼U$S&ñth½À˜@)ÕØ%<ßÏžûgã–pÀ3}/Dm›BôRªè°ñÁ]:õê;®ÙÁ|?§{}6—Ïa†©ÖÈuÅd Se}Ôξƒç¶¹bª.‚JrÅ´¬fá7“ïŠ)ðÆäºm^ä­wÆÔúßFǯ¸ãßÜշך]÷wüκaÆTàÂSÖ¥€¥V@S©‹W'RƤ RRzcºþ–;c(¥J¨8|û½ïŸä®q´í·L®Ûv]B¹°ï¥½´Î !—â©™@r›H.ˆ%ç[K®_~˜úÁ0erÅä"W.Q®ÖS ôÕüÃcNŒ)N¦ÉœcLd˜žyn–Àr:b„ÿCÔ¿Ÿž.’©¤Í¶«!„15$—ú) N¯§¦%/n¾÷E2Õ¯w¿¦'çZµ!õŽîâ-÷È'SïV =y Æ»zÊPá€ùK^ 9ÂE—B†ˆ¬!ìã}?ǯw#×',—ê7Äkl89ß»sBxz‹(uÅdáä<‚늩֑s4}’+&cºÑ *—QކaL]üµêÖšík•’=uaL=UÜzX) ¤@PǦ@…¥¬J+ Œ©Å‚êryQ 1¦XJ‰;1óýÝ q¶@K•ÅŽà–ê¢KÙé¥Ê:Èw€.…è%,‹´‘pÂô‚9a ™€ie,ÀT× Óº]˜Ò`Ь•ô쌮©Ó‹‘ÒcÉå€aJ'G£dÆDÓ$1¦³Ï½xËÎ÷-íxóƒ?ýùÏ]ÿ“azö¹M+¼Âõ0&xì7Œ ¥ó“ÓϽð¢_w=ŸÊ€è¦˜º©~ïÝ[Sï•y'Ÿ Ó7¾uXß‹Ûý÷¾ïS§ö½ØÀã†Ýõ»¦³Ô×××ô¹ž¸víÚÐ)MÜ=z‘F³Ñòãßó?¸lRÞ}pÈÒÏÇ$Ã4æÉ¹^µ‰Pïè.Þ|÷#‡ñÝï¿ßœÈ¹­èà~ú© ³Ê*×’KEŸ½‰ËòÛ*£.žˆ1EíÞÒ©Š³¥½÷Ù÷éÅ/Б}UßÏk<ßÏõ¦Z—϶VÊ55TbÉÅG«Æ’sÖGµ’aš¿¢•ÞI¿i.S\89oùÓ² ySm zºbB ŒépcŠqÛ\1cr­Ø~w÷‡ù©fÊI4Û—E%îµn½N¼Py¤ŒR@ H\) ŽM®ŠC™‘U@SGåÖÍ:§@ÏaL×Ý|g,¥Dãàµ7{SÈJ!–K¶¾ P)”\»¡¿ýÎKɾ—êÓK`˜ê†ëÀÄ9°T€©f­d0U¦E/ú+&ýE“5ë&ƒ@rÍÄ’k•¦, ScJpÅDŒé—g_*Ù?~ÔeŒ‰ Ó‚ç_ÆZØÐÚzg€ÌP( W¿>è´sÏ»à’ε(º“È›˜òV"åÎ0¦r—oWŸŽ ÓÒ5;Òßû‡Õ$Éêb¿ýö1bD Ÿr„ I0Ç€BÄîÞЭq:.ÒÐ)éoÛ¶­ÿ?Äÿ¤ä-ûƒC:ÅSF†iN#áäÀ0Áss ÆTk+°õNÀ˜BV¬wj®Jè¬n) Ù¾n)_èûÊS¡‹O™—R@ ”XulJ\¸z4)PGaLª"%U ç0¦koº“XRœô¾ýî÷Oô³¿¤­1â ]Š@K©ÜÒæwÀ-…Ð¥xßKè¥UQz)B.ÕS<Àäǘ¨ÃSkœ0­z확¯Í_¹ÃRøøÈ2Ê9XR™!–\F† k+=oL ¢Ü/möRey¥ycÊÆd S0)·¶žÓ‚^ûñiƒE2•´×ceP@S‘tHËÆÔ2)u¡ŒaªÀ(áH²€QH“ã½hS$ø 3­ƒôÄ–evš'©*´c‘á–Ô¼–`Là` «ŠÊ•%Ÿa†©Ò]dD9—zGµ¹ñ·› ™CÔœF´ôÌÇnÑrبµÙÎR"IulèСfágتz˜%K:¦[ cªÄƒƒñ!šÞÅs®Š_:UË-Á(á.Z ³ƒ¥]J£—V›¿ç—ß‚‘ÁRš¦Z; –2:a"FÉdË¢ðc2€ ­Sç¦é}žÏfbLæŠÉlÆ01¨œ0¦nýˆZu_ÍöµJÉžºŽ0¦ž*n=¬R @ ¨cS ÂRV¥@‹ÆÔbAu¹¼(ÐsÓ57 ‹ºP²=øö»Çžv°±VlUaOK/m~)d7ŒrK  Kµ¾ÜiR Ûãé%o~ËMaÛbrÙ&ß “YƒcÛœ0=·Nà-Í 9„‡Oøe[k¦¥Oxz†ÇªJ’c¢Q’SÔCoL`˜>ïûaBM»dpÖÖ£h`ÿ…Ù÷™U¯ýøT‘Lyis•N+ Œ©ÓŠ÷öý„1õvù·éé†)òÞ÷aó©ã½÷}XüÐ#¿ßht9Løkþ“H5Ñ!¾°‚m×3·±“´ ¶bغwâí\søÄ+ã`ÛcLIè²®ªîW Bp ogô•À=ÀAyÞ‚“žÿ?ªP¶é‰ù™={6.Å=Ì1”7¦V=82Öh20Lè.>öÔ<Œè@%6!{òì.Þ0lT£$žR@[€8T¦n=±zEÅPŽtAD%Y‘¢ŽÁb1&«rv<2–³*A6þì׳ªN–1œB‹BµGòIæ)TëìÑà¨,”O«ç8ÝÄlS“¢ËæAbL)v |…æ,\·nªZ › ê­›rÖ¿•°~càÉk=*Ö† „\€É R_Ï “Ï0ÕúuŽ:aò^mLÎj¨š¥PÏ'Æ’kÔ¦ŒÉYïä2L˜òðSê8Û·|ûUý¿”®Ð; cê²Ö“J) Š¥€0¦b•—r+Z©€0¦Vª©kåHÞØnk äÎknvô±'ÚÁ¢ÆÚ¨p4†q¥Š§¥,ÐÒ‹p¶ÄŒÃ†cCLD—jݹ'ÐK˜¢H¢—RÜ/¥x`Bx2/EÖJö`Z¹£íN˜j¦-.Ãd«*á„ ÓƒÆäùa Ù%sè‰ ÓÂç_ö6NJE\2T"ÊÙt&œíÿkf’‰ó‚n+•´Zsu9jϺLJÕÍ‚D«+Q‹ÆÔbAu¹T„1©‚´Zc˜êÀ(Œ˜ë…·Kt±i„d¢OäݼÂ`EÅÂW€?Ð`¬+¼Èð¾3n{ÙË ~Áƒy$=èð Ø07Ev°õ:xJô²¦¨}…l0˜K>á_ò4<×§çsrcùG&q…袞rb³M8_áv”‚w´GvƒÊµäÁ ë4T³\†)ä¹3ÎS@¿¡æ\×ÉD$3À+¥ž°ÔBõ eá–# ž$oLDøaM³ RA܃rÁ+ƒ‹l²=v_V7Üc? ^ÖíñF+žŽ(³aõÉ áŒ‹_4U±€iCÈ!ÕÚaˆlÔ ÓŒª-²ÆiN˜`‘¤Qò¯þzocª $çòL'þäW9 *Ã0…ãƒì¢K×§3¡íɧœ“%ºœ0¦¦[n›ñM¹‚0¦¦åmòDaLM §ÓšR@SS²é¤$\†)Ä.Œ’òÞ?ä;Y}2”1ßEÈOèm’æ2%`5€•`Y%|ˆŒ¸Aåp€¹áᡃ‰E/kâ.±Ý,áFäZˆÑç ‘£Oû é;*z£Xz&”mþ‹Ó ÂÕ쎦››·~>¸Kbeü¥Ôa˜j=w2!|œXwñºÛ³údBÞÈ÷àA ~l=qKGR|:Ó·ia›{Xj¼2· ‘7‡D[%Ø ‘÷n5ã¥ÜSŒ|â5ù/ïË\`ú9ÄÖR`I/E8É®ªuöhx>¾ëx ·³Ö2>¤¡KQgϼ¥2.½”´PÊ‹Wññ¼Ñ*™ªêwö%Ú^§¦8¿Î‘(r)N˜üAn¼ ayÕ€`.œ=€)™a ­z:çß<Œ)6–œÙ T®¸¿A˹0¦bçASç5×¥€R ‹˜²¨¤c¤@9ÆTÎrÕSíé9Œéªî ù/”¸~ßüÞ‰•µŒaD‰ R «TÅ•j<-Å8[zÁJþòÇ*·äÍW9^Ü«–Ä`5d×¥xt †Å—v1¹†Åï¥z)ê~)bg\ø‚³ÌO¯!!X2¯ïî¢INXr—Nö`ª $˜œ%•®&³Hcz`ü‚X?L¹òƆés~,¹ª&c˜Ö½ò…Ç~o.3êŠÉ—ph°ý¼>É”„1a¢…kè1ÅÂ)@›Ôá‚uNX2$‡¹CÀtãn˜ó¶»<8€§ÛÅÝé.;˜á”'Æõ]fˆËëÝ+Gs‹cx=…ùç1œ3‹îáSóNnñFÔ„3R<‘ǘŒ>û۔ª^AP@S'TÖ=* cR]h1 “Ë.»0ŠãŠÉëwaZ·òÞ?8ÉDŸ:ˆð•ír8 „§ÐûN+ ‘I8‹8$!ìâÂ"䜨O4Œ)J«ØaÖCÀ¹!î×çë/\{¢}‚ý<†ÐUèFQŒ)šmæ–!êØ!Á‡TM¬7¦þ?¸õ—2Ö,0Lè.2–\ØS†î":äè.^sûCY¢ËáéЋc±²c[OÜRC‰àH«l,Gë±Ch˜¢ýÃtŒ‰™qƒ$²Üí:é“)Ûnç-ZyP:¤ôX1\ÜZªc¨«ì6³p‘=…“ËXÏKp1¦¸õQ4Ax Ì|v…™ Z¸bjerœz'rœ‰²)÷Káðô¶8jÛÀª`Š"‡·[¬%!º*Ñ S(½c70†É,À˜¾éaL‰>›å©¿D<‚0¦r”c‡ŸBS‡×í¤€R £˜2 ¥Ã¤@ ÆTÂBÕ#y ôÆtåõw˜‡¤è¾ø½RÖ5ÆxWаJŒ·ÉKQb)êl© -ÅF‹ó½¸‡,‰uÑ¥tzÉu¼Dü%&xœodlØý’¿b²`rlŽžg ï÷=0®à}+d“ëN˜ 1¥0Lð¶UYöêyÒJrÅDïú0éÖ%™’0&.aÇDÀé% ºÁý6™‡ .+Ç)øp®‹S•œ­äL&o8ÊI,Î0¹Í3 5e¡:èõÁæ¥BÓEœ Šæ×áyæÙa²é[柹â1¡=ä´xG|Å9Z›³‰(; Ïhn¨ g4õþ霘:§µî´g0&Õ‚)` w²ììøÁûE<»\ëSÇ{ïû¾(¾]d²WóÎwwè Î75_‘ Ëe/D¾Úx_yá Ç˰ÐZ3+z°a@|ÏÚeMÑÐ+8Š1‘ÁñìfÐ3“½sÙÁ·ÄS¢ùwyÞ4šm>>ö³¾ 9cêÿƒ»½º•‹ ÓØ8†É«9—”jw1âŠ) ÞQm®Z‡dŠºb¿(©ž°ãdõÊ*’u¨Øû"e`“=rÈ«bc²N#Š˜49/Å*Án›Û‘³‹„ª“ubÉðá\·ó­‚1Rn­³G³N)q>&;ÌuKY”CbL)f|…f<³"ìÝ9}¹T\xzÏòÌ-Õ¬•Šêûx^›Ñý’0Õ*k¢¼eQîš([…EPAJ˜|GÎEnÎòmÆ0etÂä’3† Kž|Œé{)>›…1•ãÇ(Œ©åØá§ÆÔaÁu;) ¤€Ȩ€0¦ŒBé0)PB„1•°PõHžY1¦èú×"êwòÉ'¹þŽ0Šä˜ñíÀcNXý2˜$7½µšLRlòA¥$VÉ1Ö¸YŠzZªñÜø[Šá–Ð¥ÀåR£Ž—zéE}a ÖGF}/y!'Ý/¦Æ(½Të~)`ŠÄs°Bšý±B/Á|ãÓ/„\`¢³¥ücLÆ0ÕÆ™ËŒ™” ¹d¨D”#Ãäk¸õ‡?;;%º\ Æä΢ Ácñ;Ü .µw²Óö¢›à‰ˆr'®l›¥¡ˆ!ø6Ê$…f.q ïhüS,Æd3I\cB{¢ËúÝñ`›îâ|*‘&c³}¦ˆígQó,Œ©¨%WÌ| c*f¹å-×Ãä;欼÷'-ÜüؼMcçnD3wãs6]ŒòøÓ›<ßµ®˜‚÷þÒ­ß>âØawý.é1É»ßb]ÈÐ ab¾]Gƒ|±A2‰Çð‚dV,ì/Åw%Y(÷`{á†.ëf̸̮^éÆyæéø;ͽ¹‡4D&t#$<×˜¡þ1W‹äZ%ÞÑò½B£žÝ“1Lè.†Ð·qó6=T›Aµñ»‹?ýrPmBÝÅå^Ü¥«n™â“É5“ Y%Á­'ÜÃá¤yßdwˆ}$À=Ñ‚ÀN|‹ÃìcµÈª®/åV'þKàŒB4O¡Â¡êdCy$»µ¡ªèV~ÆSèÓ®ªuöhæ¶ÓNĹòÆ”·¦¸­ù!Æ1;ÔX!pÀôùϧ[!žœµ$ÆÇ³-=9sIÔòðÈ„YO˜5qÆÏ÷Rè’ÏD&s- t¿ôàØéxUÍîÛ„Ä(r4,Œ~êY`rM IÓCŸ¹çá©Hwûiʳë€)ˆ"7é™uO=³ÃÞáÏ ‰kŸ¶Ü7n‚ÎGãÎà 1¦ŸÍ˜ÚúéØÅ…1uLê2ÝHS™JSÏ"¤€(“˜ÊTšz)И˜ÓKGçQØÕ¼õ1&Î@ðÓЂàjàcL·'š_~kÈu·uÌ Ä’RȤäxpaV)ÖÇÒ7¾uø§>û¤¯ëpºmÿÑO±ï'þ{FŸežÛg<»úëß:,´{ŽúÞIXˆObéô³/FŠ wã°‘ˆ2†€q3î o6ü±qèRÕ»{ÈñÒNÿê¿j‘ãâJÆÑK®Ë÷XzéÊ[ÀºÉš¥“>g㦽÷ý;X™0›â§VLýǘÐ5\´å‚¶Vu2LÏ>·Éf¤`k&Íöƒ+gtÖøƒÎäÅ“O2câÿŸ½?º¢:÷}aîýƽgŸ{î9ãܱ¿s’½wº}ÌÞ÷ËÞÆ£QQ‰‰‰½ ‰ ˜Ä„hì[T@ FÁ^x;}餕¾WîDD@Pà[DQùþUOÕ³æªnÕê«ù¯1ǵjÕªšó?çš5k>¿ù³÷ô3zO¿ÌË–øîU5gÎiÛõ›‹£H&'d:ŠqHŒvhÿߊí/ùVÌ6b1bCò¯§—_ɲ~UX+c2M‰9JÏ,§îJ®%†Iÿ)«ê¥øú2e11&9À¼¶‰1Õõ/ã=91¦†Êû‹cÊ}¨^a˜Ú6îV€IïûgÝ:÷}ÜôϺe:R·¾sq߇©7ý€û¾íŠ c§¹«vá¾ÿ‹Ó£H¦ê³í¹•×ä„< xiǵû¬))…0Lãž!yw›Ór&/ÙÜlìˆræp±ßÀ(’©d®â`Ž‘âß°c0F5ñý´?7L7^(¦‚1æ%Üùs"Ìzqm _gÙÙû/÷~ÄǪô?ûåéc¦Ì—Àô]|¥Ì9 9Ä’=óðì¤ù:tЯ0 )ˆÒ^—¼è’7rœxvWFûæ·¿‹GÔK¯í}é5½1±Ðí÷—cVᩱ³OøÙ©’>0}`0úCxäéš^wY“}¿ÓÔýŠžHŽœùï‡)³¸j Q¢È=òÌtc2LwN˜®¿SÌæœîÈ1¥»þš”{bLMž—¥T€ P cb¡ùU€S~ë> %Ÿ)òò”§4Æ$øñ3Læª?¥ªcê{ÿ#Søö¬_uµ§=ÉZÖ˜d–ÐI[­ófJ©(myOp%IàQú=8¤Ë¯/Ä>â+™C|bÄ™[´ˆ%Z·tØ~‚©F J‚.]qÝ-H6®¤Éá–-™aã0î°õÌø¹þ¹Eº¤ë#1É8lìì~”éã½0ÏX¦ï% ¦1‚Çwâ)¾ßM÷K‚1ÓK¶MÎH;1)+)=‹)=0™«*+óÆôþ'o,Ü~ÑcmF­ûNýþÂ0-yy[ÁY×–w5¦ ™ðÇ€ªGEß5bu·¾sPwƒ'¿ÚµïÌcÆöø«'M}éMÈnºbs&Tº0œdÀHÊ¥QÞün‡tðI~Œ ¿ÕÅñâ~'D—"=‘¬†0„í0ŒIŽ—ðDöx47/-Çûs‹ HW&ûbR’[ÿdXý:H©=Â:{½¯N楾ê×lxæ"ˆ1±A4RbLT;‹×Ã`}%&wô(t»8_Ä}ÿÏO­<] $™¶O5K‰I|;ù1&ìÔÜJ08n%“ré=?hÉÌ­I¦M˼}.òéQOöˆ'*zcjèM„SCåÎýň1å¾ T#€Å0Aß°[¢ü(ÀdÞ÷o{j…É0á¾Â5“0v5w3¢†É}_`Ó“ pßG|œˆèrÕdž¿­“‚1I „™,†é¨Žc§. .âñ“É0*@³Y Íæ§Ùˆ‡TÓ“ï|¸5"º\ ÎÓRl+Œ ”R輄M&မ‹^ö¬’RÈ~Á'¹¬Ò{Ø:ÒZ¥Þ'ÏY!÷‘‡µ0&å–FM´0&](5rÂ<™sÀ»$t˜‹@Âö÷vV¦°, ó xöÄœ¶‘0« aãdzSHèdž_´˜UÀ;æ%0±€é¤3ÎIoLxb:fö¡‡%“ ‡NÀ Û§Ýó ˜1ù+ÙŽœcRßK­“c'fþã°#Oí|V@u¿âf¤Á#ŒI6Žýé)x¤u:nˆ÷?:ÎÚÓéd¼[“2LÅÓƲýÔÒcÊIE×¶˜Ä˜j«'ÏF¨ µR€S­”äy¨@ú Æ”¾:cŽÄÈ.®Rü¢”Ƙ`ׇé§À†‡JÆÀ˜î¸¯%ÀC’»äßžuNW¿ÿ$“€%I „“ü;=ŽÙõã•×ߊyCàJHVx8{Ƴ‡ØÙÃæ º„ |,ö´„Žj0èÒY¿ê†ùDÁ˜°ayZzÎò´„ DÌ*b£ÓÏO³Ö[KÚ`%Ì!7 S‡x_°r6n¸õØÀÎ8§ë ·ÞÉDìÁ;¸%Ì*þùžG°YE01ØFÌ3ZBÂfo»«óŒ˜pÄD$J^×ënÌ6úœ½Ï\º³€“îzx8VLâ`¼Ïxi‹½1ÓŽø ïýŸiÇi‹7ÇÉǾý‡Ã<&8èuç@`L (m'L•»_òÀLñ1&ÀTWŒ ÓGu\¼z›69iB2ãŒæ†€2×?²äÖ¡+nº Ó)¯Â??6þøÀBD”;£×ô«¾è1J©+&kºÖž¨ #™ðﲓx1~7åkRe xfŠuY/ˆ1ÕKYž7HbLl•* ÓŠWw{ïûöMFe¹ïƒ>Áû™H½§_üà"Ü÷±§ësz=±,ü¾oßð3!ã’L•VQs~gbL~˜ †‹Ãä>¡ø‡‹@ÌfsI`³ ñÜi[÷­fC’©9ÕÏ«fWÁ˜"æ%ð˜±ðåÀYˆßýñJxt_Î:¿¿…1MôFˆÃ´Ãã#&KHz$Ì<`:BbÓ#aÂA¼;c¡Të„yè10Ï 3 H˜Àr)ì¹ìº[0ðpÕvL2`”ÐK˜aÀF[ï‘qêŒ9‡acçÈô‚,‹²0¦õÆß&½„YL&`Mfð޹øÄdÂu½îÂdÂÐc®À CoF”Ã|æ0{€9 @/‹ þpÅÍHB/aÞï<6\æè«ÿé›ÿŒ"ö´<3ýÛ7öýþaGʪ'ÿz'bLÙýÿ•ŒSN*º¶Å$ÆT[=y6*@¨¨•Ęj¥$ÏCÒ§1¦ôÕsì( <€À“ˆSubaLr´ø2Iµ®ÆtoK‡„oÏ<ç‚À°$ÿ~' œ N' ±ñâËoÎZòª€J˜4|¼u²ƒ.Ù*lÛ³‡Ö6p%ÀI¦Ïö®dsK<ÒzÙµ· yz’ -a¢SŠX ©ŽÜeC¦‘°»’¬ŒÔYEY‰¹E¤–§&N’Å‘xÿÆ·¿ ßKH`˜0½ˆyFk’‹þmŒ èVÿ?þì,L,Âñ¦/¾²ç¯´6àx öËŠÉó~{Ùc6ÆÔÑv½„ÉG$ñÀ„YÅ!#f½$~àK³ýÀ¹‚šˆ¬ÆÓõ¾ÜôÀ¤Ëâ±ñäê¿›º©SmÓ€IGqÔ±/®~CâÈ8){ÞYm™h 0dö÷ ü0 Ÿ¹ F)X4Q•˜`Ë´ý1ìAP¹1 Þû˜Ø-0L¶K$‚dJõÿ½ÜÌ×c*7<¾. cª‹¬r0 Í$a—qßâe—Ý0²æ(øòYÝÿ}ü+§T9\áÏ @Æ4~ÃaÓ^x¨S§NÓ®‰.â!“<&`¸h5›õn³±£Z“}Øì…2\TÏÒxiyÔ!ÿôÚ§IŒ‰ ÄWàÏÿvSiŒñU¬€…1ýÓ·Âæ%dþÉ3WˆéBAO:tÚM·Ýc:iÇG+ Ük{®ÞnqK.±\  ál·í˜C|ÚC¼ôÚÞ˜mÄ;&±!3‰}D+ÈÈÏO·ò q¶$I1&kA¤mú²0&{nQfÅëf‘àŠéºÞwËôâDY%¹v7/ÁÁ&1]BÒyFÁ˜né;èÔÎÈl#0&Y.‰ G˜FÄëû‘3AÕ`VÓŽˆ‡iGñ½Œ©çO9ë‚«nê‡ùÇ)/lÂD$f5aQ¸“|¾—* —Ôž?¨Ü ›‡øa&û¨Gc‡c D[·«¸9†L44 pKXU/ &ñÇWLWZŒšÂ´¯åiþVÃ(µË1J¯­ô~ë;›w~ôգ,<'h¦Ęš©~þ®MŒ)u^«ƒdr† …¥3tœ]îû×µ,†&Üô­4w3†pˆ${ÇðU˜ xnðå’0 ¦«®ï…›>ÒG>¯Uþyž:)à*€iÛûår !@2M]°Z½uš¼»4<>`ˆ(ÃEa˜œfóô* šÍfµ0LÃE‹a:ú¸Uv Ù´¿ûÉ—_}U§òò´YS€·ÅŒ)zÚ8ÿî õQxH„gO zYeM>ØXæ-!!0œrK‚1霃ÝQX}…åÑÙî1°JJ–H-°&L5`ÂáŒsº¡×%v_Ë3ØoM5Øâúh$z{†‹£0«€¹Ì'ˆ×%ñå,âËyÖÒ-O<; ¾—]º¥_ fú=l…Ã3,ÞųD¢½$3 H–çæ‘30 Ì¥øo¾ã¡aè¸ðncL;ùÍHˆ2LR:“dÂ_Æ¿¤·2_UºDŠYŠf•·ÁòæîrĘrWåM-0íµM•?í’IoúâyQIÜ÷/¶È"á¦/iü¢7àÊ¢ûý .ŸÇì’ì²É0‘dJEƒ11&`ÒÌ É4eþê€áâFk¸ˆÔµï,lÇŒÿe¸èm6áÃE“a’fC’)'™äm1¤cŠœv؇ä¯íMöâ($ÀIgýª›9B,=0¸ÕŒ ,Iq%8uÆ3¦Î9Ès¥ørVïÎð·$s –$}×ß_ŽÉk>aìlL5\ËÝòÐ:–gŸ_"ÐÒõ½ï5u ú£Ç´öŸvvWܪ®ëuf°& “𺄠L&<7÷e|”Ô:i±L&`C¸%lKä8õ½4|‹0 vùÀcã홄“.|ÖO=÷•7õ½â¦¾wò™È츥ïöc¼?9n‘Ì`éw—ÝôË3Ï'Æ”ˆ¾¢y™ ÆÔ<íS|ebL)®QlEɆ–< – +­Ý#k"%Tœ“lKHB,Íxi‹l,´GšÉ\%)sŽöl£3á¨Ë%9G;fœ‘ŠbÆÐ¥…‹FÊŘÄ~³á§Ä°T?Œ Í$¦¯Ýé6§B›1WÕŒRvLTÐä%Û j”rÂÊìT5$–œøa2H&‰ )/ Œ­­­1ûô5ñ‘#ÿÁø-vÂëÛ‚ ôŠÕ‡³DJæ˜&xM\›W/ùCtˆ1%½†²•?Úk³UŸ/ H& Dul)ffÊðO¼é80Š{ß/ ‡Qü I¦ÆWq¹W”Ñf À¤§’iò¼Õq‡‹v,9Þ»ÃÅvÇ“}Xú&’LåVb®çm1¤úñ·ý‡úfô´˜2oµyLaÂõß2ÿ`L>Øsž™sÚÁ†>p¶Á?Ïà™džaXku5þ¹g>!hVÁœRLŸFöÜ\é§ëo{è¤Ó=“СCÏ£ôž÷>Íõ_>……'Æ”ÂJk~–‰15¿˜*@¨R€ÛȯĘò[÷/yî0¦?ß5È?Ù§{ð­e=òM º4R“¤|’1E1QX˜4´cÀùç £Y%1_’Í*àJB/EBK2«hN,>þ¬N¡¥ˆFËæ!Éuð^‚[ÂrÉ$¡KætdeÓß¾°¢i¼¶oØÔMÂ:‰Mû6UßX$ÓÏNyqÍÓ©aAœª·+ZªÒ†Ì‚RÖjTw7Œa’yX¸àR¿mð²^Ý┤dL×G8›ÿ`ðCÀ‰ÀNµ´´èå€1ŸÂEåŠB}Æ),I‡ĘÒQOYÉ%íµY©É&–CH¦â›~!˜‚Ë!÷}×ÿ¢Ë.ë}?Œa $™j2€i¢†Yºô¬-5„\D¹„dš4gUŒá¢…¼2LÆä‰>Æ0’L‹îè>¹{ÇÞôŽ~wµ-X=´(¨y–*ˆe)¡o‹! Æ1/¯pÀ¤¹«ÖD…Ì?xÖD…³J%ÖG•„–„£5“.‹òÏ0˜k¢dz!b5TÄ:(ï"(èyOÜùJé%( Æ”“þSN*º¶Å$ÆT[=y6*@¨¨•Ęj¥$ÏCÒ§1¦ôÕsKÜaL·õ¨ëýø¦£ˆÀÒ_ÀIÂ*9¾”Š(¥ §J^PÉ¡Éë])W’€âfÉN^hIlž‰ÅÖÉK-9Ü’-ù¹¥R.—à~©™^—ÂVRVƒ1EüɺŒî²`Û‚XÿÂR É´hõgu¬Ë±œ13LŽ-Óo”Šf˜FO^pÂÉç~ðñçš/u°Ex©c7pHp_${€á0OØ–èlدl¶x<÷NæÁz! SâÉã ?‘S)`„c䣻ԼÉ1MS~¥Þ˜ôñ/%ù÷¸›ÂW8¬Tðûô(@Œ)=u•…œÒ^›…Zl~@2Öù|Çí¢ëI™ug€g(~ÿ‹€QF'&Ã$HÊÇŸþMJ^ÃLó¥ÌS@EÛñø ³W9ì4|wE#ïå2LÒlÔïX%`LöPïKî±~LOÏS°¬ò¶Ò cŠž[Àç¬*9ÿà[å|p|9ûfŠp%cÎ!®;çÀIßô‚®± säÛ…sÑL‚ãxÉï¼¹jz‰SÞz.bLy«ñš”—SMdäI¨ T æ cª¹¤k¾ߺv#¿«$ÝS$yc½…D|ÓÐo”RP)ĵ’,‚ Ä•Šü·KgK¾q‘ΖBâÄø[*Í-Yþ¬´ÃIµ›vŒvÿ^+oLaÿ¶–-‡ <¤Çìûÿºòk“[×¶b¨&›ðQ~‹~/ôÃ1ÑÜIS¦ÿ³S®zËšnvc:µ/µ­6aV!ËT¯;>þ¤ÎânÊ|R'IÂ*ŠH<6aC,áA‘€ÉWêcIÝÅtÝ ÊäðÑ$$W¸€$É­€Sš[ý9öhXMœÐÌ¿g–¯ÊëGyt’ Æ”äÚÉ^Þh¯Í^6©DC{#RgÐç¾aØ*+\ïlŸCh?L£ìÜûÉ—_Y÷}ÀÈ6Æ-¥`0¶ÁW:ži’N¼l‘›6oùá}nV[Ðp±(œ'–\e šÍgŸ€ašÕ£ 6ðÐÜ/½>Í I M{7XD»g¿xi¢£¦Œ7bÞC*X0¦ˆy |…\0Ñ»&Ê»2*dqTÙ룂|9»ìlaYTD z7}”Ë¥Âj¨U»°ʳ*Vèyã¥;â?ûÇ?’Þ˜2Þ;¹Å#Æ”“Š®m1‰1ÕVOž P*@j¥1¦Z)ÉóPô)@Œ)}uÆÇR wÓ-}˜D‘gߊÑ(~ò®b ŠøV—’xTŠ•"X¥2p%+ÜX»Ç‹»|ô„‡3<- %¯³¥ª¸¥&£KõƘÚÚÛ:>Õï0òaCL€ˆ´¡ 'üAñìrpI×MÉtâ)óÛÞT7þâdKƒj=JMÚ2£ý0‰-óÞ‡Ÿ8îø€HyÀƒ4´x }IO#Œ”L·LòêСƒDmÓxsæÁ äT¦&³÷2ƒÊá0@Kx×ó‹£&/çoOò½œøgÒüˆ&9‚MrEùm¬¾“¥EbLi©©lä“öÚlÔc2J’éÔ³Î3LJN,`\vÈ®Á8­=â¾_Ärë¦};Æ*º€´ö`jc'Æ;9ÉŒ¹°’iܬ•Þá¢ÄvÃ9E#ïѱä}† ¯Ïì«nI6€+[‚s&qÂ4º‹5è•Ø/Gn_4Yð&ìÿÄÊˬ¼-†T­`LÑs8T¢ÿ˜ÐùÃ…shÐy{ÚÁN?úcÃN5…žŠçŸ^ˆr¹d?·©¤×%w&¡Î+ ˆ1e¶_*.1¦œTtm‹IŒ©¶zòlT€ P*P+ˆ1ÕJIž‡ ¤ObLé«3æ8–yĘŠ&þŠ'û€1zÖùf7ÿvpX7E‘ü¯ìY²®Ñœ@t& }1à“•xÜÑäzkW„Å;™+Z*Ž Wnµ³&²2h AL<Þ]K â–56f*æ–l?‚¶+AI¡ãà¹Îè’9Q@Œ)›’¯T>ßýX[P)9)/‹Yˆ1ÕDFž„ P*@j®1¦šKÊRÔ(@Œ)5UÅŒ–§@î0¦Þ}DÌâ[ká» I [ªgL*ÀIEÎØƒ%#æ CA¥p×Ja–Â|,Kñ<-M2Ú–3Iž8qœmŒï%^¬Æ&I°$µüa[<0á%ßÂì‡oñ.)fX›d:yÎòíE“¦I 9Ǔϖ“a’Xr yè®$TÈ!Ù)qâðnb@Š1Ià9|3„ éˆ1i”ºˆ~ËãIü6álà$«TIP9É›xf’ÜjÌxÏã‰áäÊ»¤âhbL©¨¦Ìd’öÚÌTeb "$S4Àdù_´ïûÖÌ5ñVÀ0éźéÏî’Idð `$ðœ`”ÉNŒf̈C2™¾¢äpÑj9úV䬒8[±€ `>Âñx&©Ù‰8‡Në,³ ð¶Rµ‚1‰¿½°É‡¯ÿã7ÇÍ\gÚÁëN)deT˜çÐ9‡xŽœ]OKQ^œ£¹¥Â¬BÐ|Bø5ù 1¦ÌöK¾‚cÊO]ת¤Ä˜j¥$ÏC¨ µU€SmõäÙ¨@š Æ”¦Úb^ËP wS¯;ÑE˜ã3¾uV½ËN+h—?Y â#R‘Û¤p/JQ|’„ ‰*¹VªW‚S÷HæšHïÊÈ0h©±K$k2AYŒI"Ê™–?ñÀ$M !³Ÿ± 1ÿ¸ ™:þôäYË·¢Èe¬ŠóÙ2Ëb˜$à{$ €$%TÅ9Ž?¤’0C À„ÃäçÂá…„üG”Ýt’¤WÄ%äüÂ!!‡’1œYÏa§äÖD²°G²äÏ?ާ7¦˜-0e‡cJY…¥<»´×¦¼“™}L'Ÿyž ©›äŒû~ÁMEe “ QdƒMû¬Û·cº“”°¹ÉÔ-ç¹’èrÏN[2\4Ð7×}We tVV ¢Åaü-‰&@Kø‘ã$Àœì‡O&õÀ´«mð¦œWV–‹ÏÛbHíc¥0/aL>à€±3Ä­ZÀR(s:"xþÁðß¹2*À»RŒeQá.œ½A⬹ÏÄBˆÿæð&h¥º\Š˜O Ɣ宩¸lĘòS×µ*)1¦Z)ÉóP*@¨@m ÆT[=y6*&ˆ1¥©¶˜×2ÈÆÔóއ#0#|k-y÷°G>÷H²`Ñ“¼aÝE ÜYÚ(3†…yCPJq@%#\°k¥`ïJ¡¸R¤›%#<\b&«á™ê„1Á,i¶@¸.€µû…g‚ÙOöà˜r=É4sÙ¶bC¦e‘ò¬ª‡20Let!<” $\bL ¯ ŒeöÚŒUhbŠ#$“x^Ô(râ„É߯˜aBq1DÁ@êÉ?€‘oqF/Šh'F*f¤ €L£ž_®ÃEÇggy/à3L¸ž°J²ÈqÀ’ð.“«„ØÌsòQ£Ë±ò2¨o‹!•*SÔò§µ»q|ªÎ<”ðÙlÎ?¬Ù½0ræ!ÖlÃ*Zòó>¶aJÁ“"WC…øo®æq¾N¿%Æ”Á)¤HÀ˜–ï왟ò²¤Õ+@Œ©z y*@¨¨‡Ęê¡*ÏIÒ¡1¦tÔsY¶yĘ"x#`L°•’Ö´GOš(’Ûš(Ô´ÚŠæO†cvÛ^%É= •BY¥²q%70\Öˆ¥À)Îz`LíûÛÅ™éc †@Ù)ïxÉaâí ÜH¦c;<}é2q,+\­…­Fd2LåªÊã3¨1¦ Vj‚‹D{m‚+'íYÉôË3Î żïK$_áTÃ0éÈæàÄ?€TñßKÿôIDAT‘ÁŒŽgÒ®m†ó/$Óˆ©ËÜ–<\¬†a‚z&‡„@rHØi¾ã#<0éW"¸çc†k!×Eãm1¤úcŠžvÀ£%4¤…"• ‘§ œi‡Òs±f|¸’ëfÉ~5Sˆ³%cn!þ–¢ù'bLù黀1-Ü~Q~ÊË’V¯1¦ê5䨠T  cª‡ª<'H‡ĘÒQOÌeÙ äcºù/ý#0#|«a;‚#Å€bI€“‚ù¤(Dɦ”‚Ö;ŠAË ç›FŒˆ†+%Ä‘{VzN[Œ©ì?bE?’éù—¶š“YwôÃT‘®üQ¶ Æ”­úLzih¯Mz ¥; ™~qƹaà2†7U2LéV‡¹Q@H¦Ö)KMß]æp±J†‰ÂS(x[ QG0¦èåO8q!K®€*µ&Êv0ÖD•¿,Êv°4ÏP –Ü ó6\[´ª1õ5¿ 1¦ütnĘòS×µ*)1¦Z)ÉóP*@¨@m ÆT[=y6*&ˆ1¥©¶˜×2ÈÆtÓíý#fúðí/Ï<¯Ø’ GžäzHòùI2}&•`’€%iŠâ“bQJÞ0pî4"@¥`VÉŽ—+\)lf3½þè ™ŽétòÔÅ[á‰ÁtÆ@?Leô‚<4Û cÊvý&­t´×&­F2—‹d:ý\ñ¼èÅ‘aÊ\m׬@B2=3y©¸H†©f*óD ð¶‰1EO;c)A!ÃW@•=ùNCÂ…²J¹Š8¯“ĘòÓ«cÊO]ת¤Ä˜j¥$ÏC¨ µU€SmõäÙ¨@š Æ”¦Úb^ËP wÓ·÷/ÀC&Hdoã[ ØQI²Q¤H‡I:EX˜+,éE)À—’;L¥(PÉgâªù"Å œ0Õ“C2ðËÉ/n1ë‚~˜Êèyh¶ Æ”íúMZéh¯MZd1? ™N:ýמ¦,Vu-Ë$$ÓðIKÍ–C†©–ó\ĘÊiâ)zÎHDÈÐTz)TÑ´ƒãQ)Žóæ’k¢Ò®Ê™ bLå´ètKŒ)Ýõ׌Ücj†ê¼& T€ ”V€SixȪƲZ³¹/Wþ0¦>ýílÁéÆ>ý­#â÷++‚›¦Â„`ˆ¯uA‘ü©È»ÀIÅ3†ÅˆR‘ovYNMJUÎNâçiǘ„d:Ú ™È0å¾c§†ĘØ©1¦FªãkyH&2L9n eÝC2‘a*C;Z±¼-†HŒékÿøÍèi0bÊ2ãgþ¡‚ɇ€icA”á¼¹xÂ!ßΛ‰1Uü¿O݉1¥®ÊšžabLM¯f€ P*@ ÆÄ†Aò«1¦üÖ}ÆKž;Œ©GŸ‡Â "ìÇ·Õq@@ì6ÅüÅ“ƒ>ÏI˜% "“È'5vqg0&“d"Ôñ>›Å+WbLå*Æã«Q€öÚjÔãoËQ@I&2LåÈ–÷c•d"Ô÷¦Ð°òó¶1ýÃ7£§¾ößl²4îüCÐ̃=Û É^åI}î®~R#Ï@Œ©aýDÓ/DŒ©éUº cJ]•1ÃT€ Pœ(@Œ)'ÍbRˆ1±YdTÜaLÇœpò…_–àÒæ_¾÷ýˆܯ®»ðâØé×]h'Ø™˜¨Àù¯ÿ­óyÝ#2vèáG_u}¯Í;?2Óß¾ø*i}|2!«'|úú­ïxrk~ܹ÷“f>ib2?ÙQ€Svê2 %¡½6 µ”™<üèw¿÷ý«.¹$⦯pßÿò«Ä Z2S ©+H¦;ì_ýñ÷VmØ=\üìó/RW:f8q ð¶Ž1ýŸÿç:ôGGG$ðoÿqxô1Þo?σL5Qà›ßþ_ÿÏßÿèSuèÐÁÓ‘îyïÓÄý ™¡R c*¥¿÷*@Œ‰m‚ P*@’©1¦dÖ sE¡1¦F¨Ìk4A|aLkÖ¬éSüžb¦K®¸îüßüÁ³“³­ÀÙ¿îV²€ —®O>Æ„þcÁW®ß´‹ SºR^2± cJlÕd2c´×f²Z[¨M ÿê¿lž>2ú¾O†)±جŒ=4ýŸL½™ S³ôÏ×uy[ ¯ï¥K—.0^S¦Í1nš™ú~ʳ']‡Íºä™ÉƒÒ•g3·ÃFM|ä‰ÑùŸ2k11¦ ôiĘ2P‰ .1¦ ÎËQ*@¨@Lˆ1ÅЇQ *@Œ)ƒ•Ê"Y ä cò×yôúu~KÂH¢C£w¼âïÌ–gúab¯ŸGˆ1å±Ö›WfÚk›§}¯¼cÍÁ:}´jFÄ}Ÿ SF©2Z÷9[º/Y¿7°å`¸H?L¥$ä÷±àm1¶Tï~øY–½7íxgøê¯MXz– §,ôÆ»É'è@bL ªŒ”d…SJ*ŠÙ¤T€ äNbL¹«r˜ ¨ĘØ2ª1¦¢Haqf¦x €IĘÆ\{÷ª_?°ÿc‘aÊhÎb•R€S)…ø}- ½¶–jò\qøèÀç÷}2LqÌÙqÀ˜n¿¬’Ÿd"Ô³¶Pÿâò¶[ãŒaLó7Ý4iÍ6¯¿¢lO&cŠÝät 1¦UFJ²BŒ)%ÅlR*@r§1¦ÜU9 Lˆ1± d]bLʨ@% $c²]1YÒÜþ>ûœ &Ôõžœå W€[G# ½¶‘jçãZö¶OîÞéƒ77yJ¼èŽî»ÚÈNÉ„û>¦|4ªJé!™È0U¥&¨o‹±F–0&qÅ$SÞ2cŠÝät 1¦U³B¨ T€ T¡1¦*ÄãO©@Ê 7¦”W ³¦1¦J–l¯ déâ(8ŒI\1IêñõƒŸª$&Þr­1¦\Wà O{mÃ%Ïü_ŸÖºôáÅÛÈI¿R’‰ Sæ[Eü¶µ·E¬$¦øªòÈ2àm1¶XY˜ÔS2cŠÝät 1¦UF"³²iŸw-A"³ÉLQ*@¨8HŒ‰€ äWbLù­ûŒ—<ïÓÖöý˜µH¯lý`óÎÇDŸß¦K7÷X¹éÝèNVV3Þ£²xÉS€Sòê$Ë9¢½6˵ۄ²aÝåàJØ€7¦Y=º Á “d_áÝÜ’é­w¬ÚOŽÜ»¡ÂÒ„"ñ’ TV·ŽOu,yALÛvïÇ{É#y([ÞcKöÁÇáAÍÕ5¯½õáKë߉³Þ¦¹Ç˜®˜2æiù†}¯nÇìPÔB8àh±ëœ&EbLI©‰Dæ£Ëè. ¶-HdÖ˜)*@¨ ^ˆ1±MPü*@Œ)¿uŸñ’çcáñÉg_D¤?ý[ôü6{ ”¬ôÄYzLWL†C¦Œ÷^,ˆ£1¦8*ñ˜Z)@{m­”äy\À0 ¤pδzh?ìÄì®´}ÑdloZ?¦_ ç¤PË|*°ÿ¯û{ÌîŒ ¶7$¸ejYÑ‚~/ôA9‰Y®};v"ÑÙ@>›J}KÍÛb}õMâÙ_ÙÓ_è%3í;°&‰yež¨€­1&6„00v:dà!PáGÉÈJ~‚²Ñº¶C)ýHI© T€ 4EbLM‘¥‰P€S"ª™¨½yǘj¯(ÏH¬€ß“á©Áyáå¨@â Æ”¸*Ét†h¯Ítõ6¥pâr /`IH ”À- ®„„ý šÄ]“†ãwµ-ƒ…sâ+· tŸÜæ4ðLØ€/ØLÿLblÃÔiòk“‘â¸nÊ­˜,x… ð¶X¡piýÙ_~Úºöë~ŒiÖ–Îi-óˆ1å ’+,"(pŒŽðŽñx& ¨0^»bL؉SƒsÂN†wåÅ+¼$F¨ T  ˆ1U!JR®1¦”W ³¦1&¶ *rü®˜è)åUÊì×RbLµT“ç*¥íµ¥â÷e) ((%0I —dÞ͘qà–ðQöcÂI9§²®Èƒ³¤ oâ` 66±·á6)£˜åðx“ì{²¤ËÒ|x[l~44®˜„j¢C¦†Ö/VŽĘÊQ+_ÇbàeÆ`I6dª 9 ._×Ãò¥KK¨ ÉP€S2ê¹ ÍP€S3Tç5 1¦ˆÌKPº)ðù§œ|ðÁNVºç'ÿÔá`ïï8±gýŒº]˜'¦)Q€SJ**#Ù¤½6#™”bˆ×%äF#Ê ¨${ðŽoáI²+ûñþùýØÀoõ«¤”‡ùh¬â!/µ®TÒp'ò-Þao“¤ØSc³É«eZÞ3]½þÂÍ}ãü©›:IºúùïúqÍî»s&‹›ˆ1¥¦ªžQ‰º‹Ëb¥Ø·Ž¯ä[ <§£)åÅžY^ P*@¨ÀAbLlT ¿ cÊoÝg¼äĘ2^Á,^ŽØ·í îUSúä¨È,*(©1¦’ñ€*@{m Åä©\tGwxZ‚â .—@&T:°·]0&ÙWL-IŒ9ÙI ó¬€x€Ø0ýˆ¿%˜âä[õ( ±çò¬Ë^x[¬‹¬é8é¨ußÃ”Ž¼2—ùV€S¾ë?ªôâºRÆKâáRÇW²îš0¦Ò¨&7GU© T€ 4^bLלW¤IQ€SRj‚ù¨±Ęj,(OGš¦1¦¦IÏ 'XbL ®œ föÚ V*‹DR©ÌlKNüHÀ3Á€&ìÁ·0ÂÉ»ºHe™éd*ÀÛb2ë¥!¹"ÆÔ™y‘(@Œ©"fôaԄ©&ÀLØÆÀ ûÕÛ%öà#`&Ý“Q=X,*@¨HºĘ’^C̨ŸĘê§-ÏÜTˆ15U~^œ ÔPbL5“§ÊŒĘ2S•©(íµ©¨&f’ äCLð±„d;a3÷ã#v¶ïoχ*,ecàm±±z'êjĘUÌL„ĘØ<ÂÀèH¼1‰+&yÉÀ ò./l›)) T€ P¦(@Œ©)²ó¢T  cJD50µW€Sí5å©@s ÆÔÝyÕd+@Œ)Ùõ“µÜÑ^›µey¨ T  x[¬B¼´ÿ”SÚk0?ùrõß-Ü~Q~ÊË’R*@¨ YU€SVk–墥 ÆTZ#‘Jˆ1¥²Ú˜i* €`Lv:øù§Ô‡ PGbLl T€öÚFªÍká¾?õöƒo­¡T€ P„*ÀÛbB+¦Ù"ÆÔ•yZ(€¶JŒ©BòT€ P*@¨@“ ÆÔä àå©@ ÆÔDñyéz*@Œ©žêòÜT ‘ €^úó¿Y$ìš|Q* cbKh¤´×6Rm^‹ýÛ@E ¼ýñÒ÷?ÝXÑOù#*P¦¼-–)X–'Æ”¥ÚÌvYÐV§o>9Ûedéj«ÀGŸmÛõÑ‚/¾äÂÚêʳQ*@¨@µ cªVAþž ¤WbLé­;æã%'Æ”ñ fñò¥1¦|Õ7KCšùcˆÄCj¦íµ5“’'Š¡û·"ñ¿T† 4BÞ¡rB¯A4$¡Ãlù`[e£(WbLå*Æã© T 1 cjŒÎ¼ H¢Ę’X+ÌS àv Dä)¨@R Æ””š`>£Íü‰©Š\d„öÚ\Tsb Éþ-1U‘®Œ,Ü~1¦tUYŠsËÛbŠ+¯Ú¬ ©VAþ¾Q °­6Jéì\‡Svê’%¡T€ dKbLÙªO–† ”£1¦rÔâ±)R€SŠ*‹Y¥¥ ÆTJ!~Ÿ;hæÏ]•7µÀ´×6UþÜ]œý[6&ÆTy–8 ð¶G¥ŒC4$£›Áb±­f°Rë\$bLu˜§§T€ P  ÆT¡püÈ€Ę2P‰,BĘØ.¨@†€©àN?Ü¡"±(T :hæ¯N?þº<h¯-O/]ìߪÓ/·¿&Ɣ۪oBÁy[l‚èI¹äÜ7ÎiǵIÉ óAÂ`[eë(WbLå*Æã©@SX°`A?ûÕÞÞÞ” Ä¿èþýû[ZZâäP(][[›ù“M›6ÉWØ0÷·¶¶b§ž_Ï Ë©â\:Î18[ ‹sªÆƒ&”–¶DŒ©1M‚W¡IT€Sk…yªĘj "OA¨  U€fþ„VLF³E{mF+6¡Åbÿ–ЊIz¶ˆ1%½†²”?Þ³T›,  T€ Ø cbC ÉW G]ºtôäC™™ð•)‘žÇà‡òÑS=FÔÓÌ›ê…Iç9•ªóxÄ—#¥RÌz׋ªtšëiµîô`ˆ,µæ©M³.—¦½6—ÕÞ´B³kšôé¾01¦t×_ºrÏÛbºê«üܽ ÐCÒº¶µeE R—Ñ]°Ý}rw|…óµïoÇ66à_É·å_‡¿ Õ*€vˆ†Šˆa.İ« R¾’o¥­V{Iþ>» cÊnݲd™R@(Ð*@O„ãш`Àt„¤Á»øæ›"!lð+lãxuVGX"=XeÒH>â*Âɵôø­„´3}#éaBÕèWÂåÈy«òXR"ez$cz ͘ž'ƒŸà¥‘æôþú–̘…Õ‚èÁz9Âd¿ê)ù·OâúH&9L+B¤Võäç8›†ÿócLòάgÃÏE@óü‚%ÉåÔO•Ö¦‰1IÕ›d’Ô¾çüfÁM ýê%a1¦$Ôó@š£1¦æèΫÖ]bLu—˜ 5Tàóû…UÚ»¡ 0>bø({ð`?’ÐN —^ŸfM¯Óž©†™á©¨@  ™?•”¡,Ò^›¡ÊLAQØ¿¥ ’’˜EbLI¬•¬æ‰·Å¬Ö¬Q.0¨KÈpKØ/"‡,ضà´Óþ¿îG†Ãh¤huâ6 €Ú'&´F´XõÏ$ß*i‡„Àã‹ ø¨Æc¹²b;OµÚ@*6ðã‡~o1©Vƒ™O”Â3Yã“â—é‘H0áH‰kÖ¡Cópù¹§\8³8ûÁKøÿ%Äð`Læ¯<¾ #¸’¸Ò—8 Âñf´@oL7NÂ3éŸ4,¨œ`L& „Kk$úQ‘ G$’â˜P!)Ž HêIKg:sò\ÅQSdù¡y~%Òä‡&_¥ÕdÖ¦§tžJTN î©*îâ<ͦ®‰1ÕU^žœ $ZbL‰®f®rˆ1U®I¯€²J¸4¶wµ-€+&pKÀ•°!n™@/WÂWØÆ~…œp<25¾ÊxÅ&(ðán+–œ¤yýb 7áæÂž}Ûš%^2' Ð^›“ŠNH1‰1%¤"Ò}Öìúh¤é›O~¬­ƒ~ÄÆ_~š†B0)Q-†a†acºƒ4¾²¥€bI@C„OR^Û=f÷Mx/‚4„½²ÕÒQq†¼š|’ÆCi‡V*ÞŤ¡"Ñ!S:ª¶¹¬Æ$h…àx™„A3ŠUí5áפb˃T›þ>÷ x(èáaY°G}©Zâ•Gý!™ÿ`ù• â‡NO(¿ªc¿I\1‰S(Ol5Ø„Ã$œYíRÓ±Y‹Æ˜T19§ ]zþ8“,°¦BŠ`˜ÌŠ0)(‘Ýì üLNÈ^žó›ÅT:-Г–NF†ýç—ÃP¹Š¬%ùFŒ)ɵüQú*@Œ©¾úòìMS€SӤ煩@ («P n–'‰& JØ–sb?襥÷ÀñuN2UpQþ„ ¤LXÈ®ø;Ël˜ÞZ“²â0»)R€SŠ*+Y%Æ”JlT^ÙÓèR`¿á°Få‚×ɇh…Á°ŸÃ°Ìµq¼d¢KÊ‹`¿@!81¼$l‚œÌÉÀ%]!êKqæi´øVÚ'Ð%m«r<_TÀ¯@m1&=¿I€?0ñØÎÅÞ¯$îÑxX²¡,΀ î€_y~î9¿æûÁà`lÈNÙ#|’^T¾2Y l›“çüz¤rž »€_iqQúg⿯€ÅW„A ^†wl£± ^ƒ=&u$’6~‰Œ&ˆ¡ü<ÐÃ$ò_¢,ŒI.*ð N+DŽ!òcLÖÝ­{w)¯dXq%‰%'ÿ/u†„ã#0&¿³€•8 %RDR#%1&QLtƶÀaøh†ç“>ÄãI*CÎÍN@/*âàHþókÝáºr Ù#1ædÖ¦\T[…ÿüRjbLÕüù[*@¡1¦F¨Ìk4AbLM—¤+ ¬’ KxL’Xrò޶/²´Šß&ødRLÀžä+¾¨@ösm° mpçì—%l¢Ęš(~/MŒ)‡•^i‘áo©uí×1¦mïO¬ô¬üQí@’‰Ã°Ì5 JâÏF‚ÇIù„‘9áGôøÌ)Á%]!ê¤5ŠÛ0màêÐPñQ|2II4ZbÒ Æü5CÚbL~oLŠAȆØÔ…»»Çèn5l_Ô*ìû=~Ž_á' xÎoJ¨ÄƒÚþeÌÿzQÅ5„™ÀÏ£ 䄞_ýKyü øK¤ À"R¢fÔ-¯™)ÐV¥5*™„âIÄ1õæA‚üq°þÜωç&è¹>z(Ck°ä†Š8F)@!üðQQ? aqë)°¼RdáŠÌâ8”Pr¤¸&ò{YÓ™dœMÏéù­ ÊbÊaæÏUd)¸ðFf1õ¢ÒçˆòZ"Ïù¥txéiå'xaC~e_ðMÝã?¿'·IþŸÐS’k‡y£õU€S}õåÙ›¦1¦¦IÏ S V /0IØ¢—Kx?°·]¾¨ {ð>™°G¶Å9SWäO¨@*sÈD©¬ÎôdšSzê* 9%Æ”…Zl\2ÑSã* WW sÈÄaXæš‚pÿ€û%pKx—òM~m2H $'Pöà0l+J’9%X ¤+€æ'­QÉf’f WLJ/I+EÂΤ‰ùkž5ĘÀ÷ÀT6Ô‚Žmq©"îR$ª”Éa(´ ÑĘü˜Äµ‰çü¦Êù#1©wÁ•Äý ®®yPŒÉôX#Žd<SX‰ôHœÜãý¥yµÍ+S(Lö…JU¯€@“8cªþä991¦œT4‹I ÆÄf‘Qˆ1e´bY,*@¨@Îð;d¢€œ7‰ŸSDæ%TbLl å(艮˜Ê‘Ç–£€ß!‡aåèÇc© T ± ÔcRw#JЬl“N€~à)ßb¿crBBQDcLŸ+þó«Ô&<$WÑkIfô%¨ä_ÞcBnM*’1Æ„ƒ=%Òü‹‡'¨æo&±­‚˧ø#øåSŠZ•Z:C¼V²2I‰1U¦E² 1¦,Ô"Ë 1&6 *@¨È¢~‡LôÅzNV™ˆ1%«>²žbLY¯áš—Ï㉮˜j®0OXPÀï‰Ã0¶*@¨È„õÀ˜ Œ¸;  A…—„@ô#÷Á»îîG1 ua¢{$¾•ü\b0yÎoÖ‰òFz݃ éE5º“DªŸL¦7&Í¿‡…’ð[%ßQÂ0™ T&š A¨hĘ$4/C¨1¦V ³T ˆ1ÕBEžƒ P*@¨€é‰>XAÙË1¦ìÕi’KDŒ)ɵ“ȼy2ÑS"k)C™22q–¡ŠeQ¨ 9W N“F¬&Aâ€ûèB¾GŽ”d|…wÀFê!IÀ ý9Î _ùϯ*ŸälâI1&q³„¯ô<ø;;tè G*ÆdfF*œS€'9¹¿D ]É•»ÊyKcñ© å*@Œ©\Åx<ÈŽƲS—,I‘Ä˜Ø ¨@†€Esêí?y?CEbQ¨@ ˜™è  !ùÓ¸ cŠ««…Ęj¡bÞΡ™èŠ)oUß„òš™8 kB4ù’o¼tß5MÎ/Ob(À¶C$R¤@­0&¸,òDMÂGñc$þŠÌo )–„@;yöèGù•çÌžƒýç— G…ƒñ.{<±dîñ Å Ì¿:j2³d)‘騿¨ T ˆ1U B2¢1¦ŒT$‹áU€ÛÈSúÄíjß¶ ‰E¡Õ) ™è :ùë¸ cŠ««…Ęj¡bÞΡ™èŠ)oUßœòŠC&Ú£~“¯:jÝw¦nêÔäLðòT †l«1Dâ!E Ô cJ ¬ê{©)y#%›šru^” P*ˆ1e Y*P¡Ę*Ž?KºĘ’^CÌ(CbLeˆÅCó¡€8d¢€|ÔvóKIŒ©ùu§cÊSm×°¬pÈDWL5Ô“§ŠR@2q–ËVB4$—ÕžÊB³­¦²Úššé cLñ­Y/¸€jnšUp^— P*P+ˆ1ÕJIž‡ ¤ObLé«3æ8–ù˜ž}öÙN‘¯Ÿüä'ÿþïÿ} ¿Í’Çü÷¾÷½è|òÉ»wïŽõjöAïï3¤#½15»Ru},w‹nÿÇsLÉÿHÂû„›N;4á9ŒÎôG-Dƒ»[ªÚ]v3KŒ)»u›Ä’cJb­¤ O[¶¾vû=W¤ £ÌbúøôÓOû_}AúËÁT¢À¥}ÿ¿&QÉ/ù*ÐXz=úÍÛŸ<´±×äÕÒ­À ›útëÕ¦âtƒ¹/_aÆ͘1£üßñT  `èÞ§O¼§#»ÌeĘØ.¨@~ ƔߺÏxÉó…1]tÑEW^Ócüä™iÒÌq“f^qõ N< Hc'Ò˜‰3Ý4cÌD#M˜1ÚHÏ>7]Ó¨ç¦[i¼™¦?m¤‘FŒ›¦©uÜ´Ö±ÅiÌ´gœôü3cžÚHÃÇq°‘>QSËð‰-ÊÓS[žš8è© N:a ‘ `§ç éÉç6Rÿ'Ækzè‰ñ=||¼“ÿ@!ëÝoðÿó÷ÿãþGÇÒq÷wŸ•ÆJúî÷¾Ô#ù=Áûï¿ÄQÇþê‚ßã‘#ù¹e¢ZËyüÆÛ%Ú} ¤ÛûÞ÷ý?TûCO¨}à³fu€Å½Ÿv}#Æ;ýžÕéyú½ Ïß×iG÷Ô³á½\Pçسi·Ô§y{³Ð~¬¸Ó,¢ï*ê¸|½–Ù_ýË÷¾Ù ·ßÿ˜ÑM¡Ë2º©swîn iQyÏ1¦¼·€Æ–ŸScõÎÆÕ¶mÛ†áb·‹.åp1šäRÀÒ¹sg46ŽR’\MuÊ ½gžsz›5kÖÔé<-¨‰ ~zÒ©HDj¢gN™·<Ôr`åÖÆî"· óÇÐýÄ“NýÓU7aO’)½ÕMŒ)½uÇœSj ÆT­‚ü}BÈÆôРÇvîýÄNüé¡ýúü w¼s@Ò[’ÞFúéM3íùx»‘¶íÞ¯éÝû­Ôn¥­NúhkûG[w}´ÅH›w~ä¦_ßùáë;œ´iLJNzëÃ׬ô¤oÒ†7?ذ]Òû¯JÚöþz#­Ûöþº7ÞCzEÒV+­Õ´åÝ—´fó»šVo~wõëû$­Ò´i_[!í]ùZ!­xmïŠNZ¾ñ+m°Ò2M¯¾³ÔIo/}õí—Ö;iÉú·­´îíÅëöhzñ•=š^xeÏ k‘v#-’ô²•iÁšvMó×´Ï_í¤y«Ûç­Þ5o••æjjÛ5ÇM³Ûv¶NYúµøæì•;giZ±s¦•vHš±|Ç¡‡|ŒÉžIé8fêBÔ#9hšJh›¼l¡©\ã-þÎpÇ^§Àtô±Ç™¡ö„}`@hö{»´ßûHû=ÔÝôuE½\xçïÜœž-¬O³;´åVòöfÚ•i?æïÄŠz0³û*î»ü½–vYÚ_IgõƒýÀcãÐMI²:«VÒžêúÛ¢0)ÿ-bLI©‰|äƒS>깆¥´¦ŽÓ®Áñk¨,OåS@¦Gž‹Ævû=ƒ8PÉU¡÷¬sºb¶aѪ7~D’)WuŸ¶Â]:ñ¤Ó–¿Ú¾|}{§Ÿ“dJ[ý5#¿ žykkkëÒ¥K`AKÎRêo±Ñ±cGœï%Õ QÓqM½µ-cw‘Žc.ËSÀf˜N“¡{Ë“cH2•'_’Ž&Æ”¤Ú`^¨@c ÆÔX½yµ†)?ŒiàcJ)y6`§ÐƘb¢K0áoC*0dŠ˜lC¾Ë0ù&‡aÚh0LÀä2LÀ›a*`L[Þ[Á0m®˜a²­þ¶á¿À0m(Í0U…1 °€b†©ÝË0­*0L€0¦b8`æòt`L˜IùñO:Žº“ÅxÞ¢qÉ•$™Ö‹¦ûBÀ˜®»±·¿Wt¸¥wÀýÒÑÇâ &8ƒØÍ€~Ï 6+a˜<¤fPÿ¦€¦2L«‚0&å2ý½™Ÿa‘1)…€`šð¥I^c—Š1ÁSaò`LËwcJПS‚*#Y!Æ”ƒJ®aÁ0a¸8cÑË.ÖPUž*Pa˜' kcúÜM’)/E ½k·¼'U¿°m뎤O¦¼Ô~ºÊ) ÓŠWw[muó»K×í"É”®l|n›2ó¶iÓ&IA&õë×/Z¡—pŒÒKØsÈ!‡4^· \±èÖÆî"5Ê"+`1L¿8ͺ"É”ÚFBŒ)µUÇŒSª ÆTµ„7“Ãn=aQ7hD޳z?¿ç¹¢ß+t}Žû%7næ›h ¹˜N˜LR³ÏV²Ÿ·5¡[“T~,9ÇSÕ ÓžàIÒˆ+&ÇÜ|7æ¼ÕíóVï2]1®ãvaLÅ=•xŒÆtö¹ÝÌ> Û$™šóß'ÆÔÝózUbLy­ù²Êí2LkÙ.ÞÔóÖ²N«c„Ö°áÆ–žkù÷TVŠø¿ÒAoÉ`.ñÏ=Æ#ŠéÏFDÆ`×Ä·bݬÇK¦G‡x6¹­ßÀsÏ¿ð˯¾*+ò /Øn#ì”uÂì>*yÑT?×¢™Á0i0wùæÃ|ìò•«Jêà9@Ÿ+aà÷4`QÌ|êDÛ(÷¿³¦äŸXVæ+è ¤Œx‰;¾ê¡€0Lmwk[Å3£x(Ä|Úê‹kvÿ³S&M™VîÕÍnJýß ›S%ÒÞ°Ó3ß"ÇÔ»—.·D<^¨ßÌ0# EÒLïJØ–;†C‡€=8RÛ’bLدm Ûr¤d[Ð(­Dü\)¾â+࿵դ»ÐQ þò¨J³Ã—»^ž¡Žt: 6ÇEr¼|•êDüzᑵR@¦è¡ûÃ>ùÔ3|òI­.ÊóÔ[bLõV˜ç§ÉU€Srë†9«JÜaL÷=ühÁ¯~•\Ûü}ý-ŒI‰%ÃN_ –¶ìZòsK›w~Š.‚(9V|ï%XôÕ–¿a{‘û¥W‹&ÛýÒ{’0e,î—"<0ÉÊH¿¿0Ùþ´1‰ã&ÀH®ˆazõõ\²ôÕ·5ÓK@—$­³Òâu{4© l¼€´Ö"‚!;0Sd,¹X~˜À0!=#Aå¦@Œ „GU»ZüXgRÌÉbϵTJ÷Ë{”K2áAÚœ )9,Íf±0?âyêÆŠéËû÷„ # Ëäܳž¬ZæúÆtC¯¢^Ñ@6ÑŽ?ý¨cŽó@Kþn0]Bè£—Ìøqf¿gõx.²ÈkvtÀd»"óL& ‰‰i+ÝZ[—éÇ´ÿ8š*òÃTÃ4·à:Îò'“ºb2ÃÉE`LðÌ”ë–ݬÂcj–òù¼.1¦|Ö{9¥v¦׺ÃEð5íµ.âN‡ábe$f5P¢QŒµþ¶j¼bˆy-Sa˜V½¶'°­¢§’njÑêJH&Ôš¨´(ÁSdÒÃì¯8ÀÖž »Þ½tL‰x˜GºÎ¼¡yh›A“þMú1cÂNuÔ$¬R Æ„3€ž4û@óŽSóÑZæ›Jô­­šîÂÕ˜Õ-q=}ˆt#r’N @1&ívpKõ@"óÍ)T†©äнÿcÏ’dJ` †e‰SŠ*‹Y¥5V€Såé’¢@þ0¦þz})‰G%;Ý×È9çv •‰¥üÐR‘Ë%›[rí÷‘èRˆï%/½ä`2é¥`L>€Ékéw¦:aZüÊžò&× `&ug2ßrgb§UENM `—Æ’† X€bLJÌ´½›˜Éï©éfRŽ´ý0훀Cav)Ðc¸¬<’)ÌX‚™s©¦H°G׌â+6&Y3mBK{ô·²ÎU®%=¥¹ì,>ü””^6ÙùÆtõ ½´,l¸ñ1GŽŸvÔÑÇiïÖ VLmFÓKa®æbLïÍ s/Wä[n£eW3û4À„ÿQÇT3ÄT ³b?L† =UcZ±3°§ ôÆDŒ©9ÿÊËs†Àæöç5ôF­®±ÑŒ¨g-}ý‡e’LÒ!HoãéjÐ0Ðÿ˜t£ Vzþn°þêÏÍ>GþÔžz÷Ô8> DåwÈd¶.ó/o¶.O#D6ôTfï$Î6¤=Ä«bÞ x˜*  S¨ÉÖŘÐV®zë¸ËóÉ„~Éì½¥› Ę´ "q’ðöYï™7ô` bÊR@ôþ rB¹‰VÒ%â%{tȤñæt†™K¸ÈÉÌž÷Öæ‡³îbA™Ý…gT#(jÙëË]ÏB+l»f·Ã‰Ód¶¥dæJ¦øC÷%ɔ̚ È1¦ÔT3Jj®1¦šKÊ&CÜaL÷öâ·Çë|ëÍS©Çõ±d8) –bIR!j’Á-½Uˆ$A”L$Eaã?.8r\±ï¥ôR€û¥!ä¬dÞreL®É†ÿõNªÐ “Œ ¾— iM{‘¦Õí —$iT&30“—a²é%e˜,Œi²å)‚aJ 7&™IynÚ 6áQðÛ_äŠÉx¢F-€·ø}9$“ç9YçÖež“ñ€-Çèê1Y¤óÈ:u"È#™Ôóì‘)i™ƒ–‹òHožM{KY[Fû5¼}XÓõ½(%70"*cò,s %¿¿%·÷‹¦6Kú^²Ú¶Ý¼ ~æÜ¾®l€©'LÑäLrážäŠÜÈ}WÁ‡\D,9?ÄþêPñÆÂ0…•#ÆTÿI§"ÆT†X<´jˆ1U-a†O† ÃÅÙ/®5†‹A®˜\¶cu.–E2 À$c9Óש ²¾ÈxO{22ÄÐ;Ù“™âB‚¡˜KÏ^ÁÏu1ºYý§Õʸ"Î&¾Udä©™D¡äÒj~FõºÂˆíÙ?j5ëñ| ƒ[üDx3Ú ~…¯Äâh’‚2h1=g0ÕÓ²ÈEýlÄo'«òà0LO[ “çÙÄÊ%NSáÙÄÂ˜à—·÷eLƒ xBe©Úø(„Šh+ÇCaSù‰I‡(d 58Þl-øè?¿jåùJRp9¹¢Fèµ¥NÅ“4oiuÒ¼=fËt=ï†^.é'Ø^µ3Ï|iSY$“ô¨tyÞ4A"©M©;H*–~©VÏŸE üòsóOŠ?<ޚϞ¸œÇiÎŒ#=W|Œ•çYù§ë?×Ó,qÁ¤ahïgþµIWù÷äÏUƒaŠÛVç·½YÉT%ÆT¿^šÍ 20ó&÷üße"éÐdX¢Ý‘ƒwéÐÿȈHçåð­ÜeŒ[êJ0W¦j*~UÁ­­¬îÂ3ª‘q‹ÜL}„i“Á¾ $ªÍnG›®D*šDÆ2é0LeÝ2Š>™Rш1¥¢š˜I*Pˆ1ÕEVž´ù äczhˆaÿ°àEÉŽwÏCƒ1Yz7’gÃA””UòºY*KV¼$´äã–Œ€q6·€.Åt¼TVIâ+Åt¿Th©ÙSh ¹r0­‚ï¥BB`&ÀdEhZ±óicÚ1s…× “:dJ”7&g&eºÁ0¹«‚ÄN šåZF–;ۓŰKÁåÕï/½!ft9L|tèÐÏÃò’fa—éxu’)xéÏô+™nöì÷ï1§hå·æÙLóºÙo~Ç™¡cºêú^è d’Ä´7ZÇcêhö„Þn0ÈÕ\Ü@™>^Ó<.’^ ‘é„‹0m|'` tÂdÄTOr¡0•a „/•¼œ»j—$£Ë²bÉ)piaLCÆEЖôÆ” $1¦UF²BŒ)•\Y¦ á¢„Îï8æp1>ɤã48[s\‡~bÔÇ Ûbu“ê${„KP¼FMt¿I†ˆæàSL>²'ð´r•è+"KþLŠíG²¤lŠƒåºøJ1&ëʳ8ŒIWÏ›pƒDA‘‘U”WmTz~†ðŸA/gêé©QOe´xUÖÒð«†ÉllÅ ‹øãÑÆÖ뎇cF—ƒ泉È%jˆ†ÑÁ‘T¤¶"GÔL("C9Æl-8‰ Gžó«Pþ¯¤ ð’ a#†ImR5x&OlÕZ;ØN×óŽzÅ —×Þ…(D®ôlpÆ<}ɦΈ]N°Ù’ERQÿAùkˆE_ªÕÿg‘¿’4Q^H5Ï“lüÿ‚ÿ1Vš“¢úO÷4Kyà•ƒ%Ÿê»K®.'‰ŸYRe˜L´Wž%£ÛêÜ• ™Nž4eZÉKHÓ’N@^rwÀ†‰&H£•³is5OŽž¤¶½tœœó¿™y«•ò~Gqµ:sÏSñ­-~wNÀì.䮤£Õ\o"‚YËô¬çîàï.Ò5Èakz‘¦ØC÷û“djz–Î1¦Òñ*Uˆ1eµfs_®ÜaLw?48Er±$|{ö¯»°ÍóÅñà*±Ja¸RX*ĉûÀïoÉÏ-¹A”bx]²' e®P“]zwµß÷’mÝ7è%¯û%Y2+–ìXKHïXiƒeí0,vzÛ±÷Wàé•=/¬E*raâqÂT \‘&øa²¢È•å„ “¸6±1¦oD0L‰òÆäIyã=x¦‘Ù·Õ¥&à€Y ÊÕEñH&ÓJ$¤‰É cR LÌ)¤“t2qlNÛ©UFžÆå¥3þr]sõ×Mçɹï½k#0¦+¯ëÑ+c:òèŽA=áèý4‰{93Åw5g;^*Ã÷R½+„œÛ³vkn‡EÎöÓ S¡3øKoÌâ^«ˆa*vŒé> c ¥-‰1ÕæÏP“³cª‰Œäão„/×s§9\,I2aȧ»¬ü†¼¦ýU!‘{F˜2ðSÐÄÃ"˜žœä´æÏ…°—=§Õ±¥iò\Q‡¦:ŽH&ûâ9¿ønÑlûG­ú[ÕD[¾’A¯™a¡XÄàIÕòdbRz¼ÿ ~õ´"<lɆiM¯òïà0LÃÝXr³ÄÂ÷lâqÅä4¶—wßü—þ%}2)Æ„<‹ã%)YÃaAÄΧfB))öHõÅÁ˜Ä9–ÿüfmê¶´+yÒG%l´ýËÙµA)„rö¦VÌ´<ï˜w†©.éÄ@ZV×ÀkéÔ^‹ã“Ƀ1A:é 4rd4ÿG¢³ÿψ1yº©²ÿc¬Ô¯ß“§YJÏ#]4a³d[ÖŒGjšNæJÑK^ßrÅ[€W9¯K¹õo{pLõÀ0 &¨iM»2LÊ_ÚQäÚ=®ã"œ0‰Ç8ôT‚1EЖĘù—)q-bL ªŒd…S*¹¬"*Ã$Ïò@¡O þèÊ•X \WL¸—9ÃÅK® ™üŒŽ 8:®«¼gà'e< S®Xv1ü I!9FÌ6Ø/ŽLÄÅ…l/2@‡£þÓªtW”o&ðgוK#cx†Á’m¼ûG­ø‰üV|ð˜5ˆÂrIdùJ\òÑ" ÈuÍQ±‰1yÎàWOÎì`Ëåje †éÑCˆNÎ _hû¶T8@ÛM·— ™<?e>Tm݃š’¦"Ð’ì×VäiEE–ÊUšD+ÐÐ~­PÏWP°$%lp9T«<éˆÝQ.!­-Y*W·¤ÂúhzíõWFW#¾QÛ6Ù¥&bT‚ µ?yÑk?øÑÑËW®Šèë<“y¤þ¡›þcòüYp0ZªFëNz!¿7&Ç•Eàc¬8RŠÎì Ìf)ûÑT$øhZ©‰1•uã‹>X&gÎÍl«®7kA{-äe5¤­Î\¶íØN%|2bLr»”ö`vør"ÆTÃê®É©<óV“<ó$5Q êÖVÜ]H¤‚jº‹@ŒIî².T†1Š+¡£Ð!±ŒO´ÈĘjRûy8‰0L…¡»¬–wcß숅ÈãAC÷{ZFdJl³!Ɣتaƨ@Ý ÆTw‰yæ(PcÂèÙ|5'›5ºêE]ÔïÁ®Ï¤÷Á!ic|¿éü«®†y%–lD)TŠÀ•‰%´äŒ#ÍPqbèûÀ5ç?1bJÏ>÷Í~éUE—o|çýCf-yUó(ºtùu·˜iÑêí˜Uô8^²#ÇYþ…«¶Ýxë=&½´ mÛ ·ÞcZú[†OD‚¥_Ò’õo· ›ˆäñ½à~)Fü¸…†ùßãÉJ„ ˜” €I˜€ê1¦¿~ñ~šgèit&Å?ûÖgØÊ?[4nÑsÚvÊdñèù[ž·eÔ¼ÍH#çn;02ÂûËo.‰"™§nÍéxäÕ<Ù˜‡•)`™…×)xÙ/f-ñ¥äß#Fý­9u‹ _Õ%Óúõn 5?¿1Ýìé Í>pøè©@èbú–sz¿â q½ÿrŸv}CGMé}û}ó–nTsS殼ê†[§ÌYá Žyåõ·Îyiƒôx@—zö¹wñËoJw縗‹ŒŒ9ýÅõ—]{‹Ó¡—B¼Ê½Ùj+™“Ç™\„&ûÏõÇ+{: “‹`bOt¹¹m»\†i§b—³Vî´RÁiœ\Â!ܽÕ`L›æÕ¼Ùð„¡ cbãh¤Ę©vâ¯e0L^°`äÜ-Öpñ©·Ù鮫124‡‹Ï½ðFa¸hßÈt¸F2a8ç1ó Î0®3±"jÈ$qM¡cŒ[ûbè5Yɵ[,\òÞQ/˜»E&p!ÏÌ~ýéY¯cìmw5Öc騹›GÎÙ¬®˜„`CtøI 7F“Lª‰_ÙÓþYäÿ%j›pó_,—ˆ‰1á<ž™ùÿÒN ‡é_[›%.$ÖßÕ˜ù‰ù—Ì×aû¶Å,¯0Lm÷HOeÛk´O—÷ŒZƒù+´Õ± ·Ž]°uÌü-ÒV%ʪ,_WLÚV§/}#šd’J÷gO€,ÓŽ‡É‹çøˆ^:fÁy˜WØý[ÄÌ&%pk31Í[‡.Ÿ´x»yw.®Ì™7VV}ˆ]õE·¶âî·6Ô¬éü^» ¹µÉÂѲº ÿ¨FuÀmBX[s.TnB¾šcì÷w;MHÔ·.yö0tÿâËOãH£ “è³Â½£Ö˜‡ÏÜ3šðhýºšdè~×@’Lq´oÂ1Ęš :/I¢1¦„T³Q¾êu[`$›•3•À˜Ä·¿¼0ŬKÊÏF"~Œ©ïýxb™ñ-få"(6ÒøUˆ00*\@l8{¾~OKΖ:ÿúÂÃŽøÉêÍ–ÿ·Ý¯ÀÇ+®¿å°ýD¸¥ŸžtZç_]\ {f.~UfÛl\é›ßþ®bL—]wËÂUÛÅ´o£K½„F1ð7燅 áî‘ÆL[zÆ9]ÍÈqº¦7è%'­{û’«{!©Ï3x\\÷KÅñãdªHS °8  €ÌÀ<˜L§&Õ`Lû¬™µ¥óÂíÕµqËLʸçéRW}ÃLJ§k'‰àúG–œpͤ§gmš¼xû™½§#Ñ{úñ×L:£×tÿd±±úÍÅ%|2Õµ\^¦!ÃÆ‰Ç/Ó¯ƒ—œuË il—<´è¬[¦c$VÔÞ®žtõ Å…Ææ2sx6éÑç¡’Ñåb–…‡•­@¯ï~ÑÁR€ ½gY S•T| õnÙøíñ9Æä·]!6~ï“©aã3ª~Âü p>í“©ìñYUmupçƒo­‰.&ÿÒÖcJùdʪð).×”>ï<ìàš‰ÑEˆžyü&ßÔÕÚÌ%.šø¢ÕÅaæÍš|»Úš|+J­–¡gÞš×vª¾µ¡Þe%€ÜÚdp·¾sÌ[Ûó/½é‡³­îb »‹æU}>®ŒA{ëÚ¯¿²§4Ì$ †îaf³sƒ=wÃ[†.Ÿøâ6§ëeõo§÷šæ<'C÷~$™ÙÒˆ1%²Z˜)*Ј15Df^¤ `Õ$‘̰ì¸\\ë&`(ÓÛy=2Ú€sZÓ}øcº {„Ô÷¾™˜ LN$™¶s'ïdöÖLêe¤°a³J¸R ±¤HZBê?d¬øHâ†~1çßqÿ³~u!¸%Øû-niÓ^!–L£>lùÊ-©×¥i/¬{zÜœqÓ—Š]¬½†iØX cº4lìlÇÆÿêÛ£ŸIü”<5v6’…1]Ý[|/ 3I0&¡—FM]òäèÙ“æ­•àq#§,ÁÝãÏÎ1e é½Áãüô’0…º_²ç4™ñã SÁI!„œ?*SeÓ+o-ÀôX[¤ºbL2“2 “¸{µ#ƒèì›5“rMa&E&‹%>*kþªvL¦ž¨µõN„ºðâ뢣Ë5à_ÉK4W`L—]ssX§‡ýOš‚F¨x»ÁÈÞ^—À'¡¿’v«ýöHw7iö x›3Ãb ÆtsŸ{¥¯Cï×:až K­ÏÍ}æ¹¹ÒËÝqß`KJg*š‰~ŽåÎ<§›I/¡3í%¥—г¡CSsÊüWЛ=ûü‹a²»2thèÍFNE'¶gÖÒ-‡þðHteÒ=>jRëä%Æ´¦ÐÒø9k5sÜœ5B/aLcg­>Jׇmø–9ÑêÊÀh±\ßû‡h'ÜÒ·¾ýÝ ³–ã}æâõèëг]znæ2l€Ô<óWÝ:ýü44{0Lذ¼.¹]æ•ÐÅ À„NÌõ*÷ú7 ˜gœmunx Gß…"ýÛäùko»»èÇЭÝvW z³Cx¶/¾ªçñ'žrþï.0ô9tbèÊðoúyÞï.CØ8°JèÖà¸O<¥ûÖž;ûÀôOÀ˜VíêyçÀ?ìÈ?\qsÇŸžÒóŽÂ0™äe€Ó87äee¦/®ý€‰SƒÿƒÄ˜,xÎ/GŒ)ç @¦£:ÎXô²=\´ aÿpQ 0ÞKܯ*Vä=0—¸bÂp>Mq?Âp±®$k2 ¨-$ f†ið°qaÏ&æn¼D½cºí‰BއG€,㾲ȳÉõ·‘djFsP[oÌd1LçtužÌ~S6Œ µïÄçZ°åº–Å– Ì6ôÂÆ¯O¦ö€BäJ]]ƒ0Êãç¾J’©uŸ¶kzÚªf²¦“N[±a·Þ «í¶* c,ŒiÁVa˜ðÀxñƒ ï|f•N.€G±M¶h«“_Ür4I¦5ŘB`¦83oh6ðP‚µšh90ó†RöÝÍê↷qæ-q¢ê[êÝE»È£â¹ŒY‹z ÊlÞÚØ]$®Ud(Cž¡»f²¦“N‹º  ‰0Ðp¡jq½ÞÄ!\ï'—«oÂî÷/üËð63άÏT³Â“dJV«"Æ”¬ú`n¨@# ÆÔHµy­ú(†ÉQ׉…1!|{ÚÃɉ¤À˜î¸·E©#ÿ¾=ëœ <Š¿†(é~‡Ur½+âJ²,Ì5É ×:a.’K°å+º$Û-Ÿaø‘ÆÍXjrK0äkêôóSÅ´?å6<}Í_ù†mæþ{=#þ–°-îI`ì‡ÿ©1Æ%x—@K ™`쇫˜ù%fÜù]t Ž—`æ·\•¬Ý}×€á°ôcê{f¼´ãÝkzÝ«¿]’ùÁã¬èKz©8x\P®û%Ìß“`’)þé›OÞõÑ‚š§o¯=â¨cÇN]èÁà¤åèìfRºõ›+>± §Öb'˜¶ôM{­³±ˆÐ³¶Þž€5H2Õ§ËMÇY1]zõM½¢´½'GNAS,ÙúûÀ+¯¿µgŸûÐõcB£ió—Ò€N‚ÄuèÐáŠën‘€“ì9e; æ&+&º»›n»§ÓI§aC0&K<Ò*1Ñ›^‚W¹Ë®í­.—dㄟŸúÈð‰èÙ@dÞpëÝøS€ÂìsÏ#Ò³f‚&œ_:´AOM4tz*q¿4{ÙVlã¿óîÃ¥C³z¶—wƒÈDW†íšžý¤CŸÖýÊžâ{iÚâÍ —îì? Üz0`Lx¶Çû° /â Ê ¯c;`òz`2{ª˜Þ˜‚&™«}Sƒèÿ3Gðyý2Qz+ðìV{›p³å–‰)— l[ý"îÑÓ®1é%Ü‘•w—»* 0%jzvÞf.Þ?æe`"‘Û  ÃEL5ñò„ÉQ`ÙΛͥ˜Éa˜žñlã®s²˜Îx²ô`[yïýr÷ª•ã( œ †ãÙÄ!™Ú7°gkœ=¾î…à ÏL6ÃT˜$ñ@!v 9Ë· :3>j_&÷ÉÔrhê\©f0Œ~’iáìÆ<—÷ŽtËØV]˜Éf˜N]þj{Ô[|[”E€h«cl†iÆò·¬pr¶»ñ”à²Z0Ù¢­:hÂø±é3'íØïú7×3¦83oh3VØÁ[¦cò -–Å%tá½(œ\É™7„D̉òM/fÕ·6Ô»‘yè EÍ•áät%€ÀÙÚ]ŒŸ469C>æ$ Ýf²¦S‰ºã9QM¼ƒaÂs_×¾sÀ0!É ~45œ\ÄÐ]H¦û–eCØ´—bó{Ïâ9®d ðt-˜K*@ÊR€SYrñàä)ÐÚÚèØ>Æ„@tžXtÉ+`¬ Æä™è7­ï¹·å̳/(É$ù|)ÁR°G%…N ŽF VI¦üŠ“e¿o³'V4dÒY¿êû=b'Á?~æ²gÆÐ%lÿàGG9Ð’½ÀúGž‡dõÕ‰Ä@L%€•‘VZoL‚.Ip%¼ƒ^Ò€q@—e $Ð’DYÆô„½Î~àx >Kn Pìýš0M‰mD\Â`á–c’ K’""ÇÅ¢—l¯BEî—|¾Lý0ÉÎ8ÓáG5tÑñþi}Ùóøª‚g¦°c*Øÿ‡ñ̸YEœø?·ÛÚŒ4ëIÃ]X?xò«Öì›m'¸fÐâ«-FÕè‚WKjÇUam½*sÚÙ¿¹÷Á±þE<([ cúÓU7EtzOŒ°0¦ˆìÞÏÛζ}ÈOBÆ$VXL›Ô—r¦c9“Δ¶mEôÍ`@—n¼íttOŸcù–³]Ê¡‹ƒ'9$„—rnz{êÂWp¸%$q2‡?:1™Ò³I4Lì‘M’Ùqa½ % ‚ (!ä°Gè¥Þ}aû?;ô<0¡tIøK˜@/a»¾ùÏ<3]Ý/Åïµâ`L›ÿ÷“³TŽT€ P*9Þ¿¨Ãßÿÿ9qÖ²€á¢‹‹_#î°ë‡ÉuóĴׂ±×ç„9Š>éô_wíýW0¬åOR¡À£†»YO†fî—§Ÿ}Oÿ'<ÍæÐØ®d‰˜ú0TëŒéÉå]ïœ_®VÞ'¦mT'òlâ·öI“ûýå=¯üáÿýå%ÿ‡7MW`A¿ßyž SFW(Ä4ôŠ LÆÞÖ“éÀ‹½p›K ÉôµøÆžßÿ§¦œHï?ÿ_ÿßÿX¾¾½ÐS¹kÀÜ™7ë1Sž1Á£Œž¿E¦È®´©À0™Þ¬ChKA¾û½ï¯9ï?§N(f¸ À‡ÅœyC›Áä›Ä’ôۃcת«̼¡‹+cæíøÿÆ*hº1omÁ£h3Hn9ÝÅŸÇüçT ™É´(1tÌtÞ…§ÁÈÓ¬@søÌM}[W?5cÆo½žX†¡;ð&tnVÿfûÑô Ýá²W@=IX„ðãSþ¯GWþoiQ/óù|å퇳e¾`i¨ˆ¡1¦"ñ$+oJ*çÏa,Œ)ÐS’K–7`L·ß;ÈŠà˜^ßwû=ƒ€1™®’¶‹°$åK\Ê$Щ’éhÄÃ*)´$ÖÄŠ=·‚4äéI—]{ R·?\Û<ÌùÓ^Xg¡K¶-Èð‰ˆôü¢uA F}˜íM£>~¥Ð¸%$ì¯$bÝŸ2ÿÁ•Ôº/sÍ×õ¾Ž—`’w a±bûÖ»Z-]²ü-ÁUÉË»oéׂXK0óc6nÍnpKkI ÿŽš {¿—^² ÿñ#ÇEù^Š F2ÅÁ˜À´N1}ãåO¬ú;ÿ0÷¹ ‡µíêSó4dÔŸ~ ×Yëv9æ—^R€IZfRd!fßf,{ ÕN`…lXðê."4äz¤uæQG·jÃŽ=ï}šÆÿ5ó\‚1Ƶ”Þá,aºð÷„¡}  *½¸æMxW’„ÀpxGl8€˜Âh>úÌ$Йˆ'.—ÔÉ\`4Ìi‹Ö‰?9éÜð.}ÝçtësÏàacç\z 0&‡ËDÿgK‹)]Ü:«‹ƒ¿%íâ¤gS.}ÜÈÁë’z’CŸ†® ÿôf­“—ØÓ‘N?&Ó3£[7{ è%ôiݯ¸Y}/Á7|‹@š`B8ËÓJ Dj†©»Œ€,Ë *·ÿ¡3þéžìõíƒL SàÖCÞÜÁN`¢P`À/>wóAË`Ê¥ï¿!d¸è,‡ë­pŠ3t¹ ÕyÞ㯞äGÞ=aôf„U¶'þâçã—ß³àõ~5÷ò„IP`æ–³'ô§nê„EÉkÖ¬Á€pQÛVÿ³ låöéY¯ƒ qš46B,ŒÉFÆÑÞŠžMV Ãðl‚´£Ž:zá#··»çË\þµ›Ð¥_ó߯ǃh¹¶OkÌ“-Ð*f% AW#O¦˜|°0¦'œ¥ügôš6váŽ&ÓO‰ƒKZ‘+5—¼·× ›G=ðÙ¤¿4A¶·ä+ØVásenÿƒŸê<Û*½T˜E)ܵ‰òì¼-²´ÝÔs/¼aûa ñfmDYÕ¶ ŸÖWuÿÚê‰w²­&Z<—²ì¶/xðŠ3ó†fƒÙ6JÁÌmø™3¿ÕÅ-p»¸¡2óväOV=yçžqw'Z±ä÷1sXÅ­ÍØØät­aRϽcøªž[êÖ†î¢ûU¿›²æ%ÛîLÂyȆaC÷Y[:ï;°fÛ¶m:uz~Áꈡ»šÀ0!¸ª,Ä$¾ áŠiÌ‚7†)rè~äÑÇŸÙoöÆ{V쬽‰$õÕ°RŒzå;x¦ÛùÑÜjŒü- ©T€S*«™.(pÈ!‡Ê c ûqê– ¸ ßžqö !ù7|Γ‚|)Ù‘·›ü…ƒa¦Ä¶?fŒ P*@ªS@†‹/E%¶—<hМÖ9›ax ÅJЇ‹`˜N:ùôõ[ß‘{Í»~V]®ùë$*€ÐŒI&Í+H&Œ ®Üñl‚P;0ôm]5jÞfx79þšIbiýºÆ¤w¼áäÄW.ÖW,\º^[û»Ÿ|ùÕWIÔ+cy±dšù]€IKiM¤Ü=(´ê7ZPˆà’2ó†ÉµYO¦Â0ù—ò›‘+QûÃôЩz¤Ï>ÿ"c2³85PÀÓV]€IÏl=Þ^y“¹†Ð™E±¹^‰ %uÐMɺôT†©d[µ¦ë{i[=ðÛj ê¶^§òâÁ˜Ü(„rÅ83oVäz crppôop1(f~íâì»›Aèræ­^5û¼eÞÚË–)zé.pkÓ0[¸µ þêµÿÌì×cÞÚØ]Ä®0Xžþ¡»Lz!™¦Î_mV@]¢cU0&tnxNDÿæ2Lº—W;Mü- ú—Ì\ºô’W½\ –þ‡Ÿ|N¼.á#,ýýŸ/S“ݯìyîo/ëÕwÐKŠ.=ÿâë°úcºڬ¸F*B— Ž—üa㪦—”g* c’Y*ÀL3_»âÉÕŽg¦úaL:Ÿ²díNu~.ÏÒÂyXOÔ6À$«]åqÚö˜µû/ÃÛœ¯¦À·àÕÃ0‘djvÕ„ëÛó¼7FôŠ=3 &«²;@{ÞGœÉ¹Ó@{Á*Áub_*  D ö×Ûïlv}èèlKާ1xs“_ÏÀÿW’eOJÞ`ë ˜4“˜Nùó]ƒJV½„T.Äç‡Éf˜Šý”2LU’Lh ý*IRZ]eù@C ˜ô”ÖCî7–ÛV ¼]¸O@(muå‹ËwoyReµZß_ Æ0饛5ó†{Y=F†õ•4-g¯ç­-Ï-¾µ…uÓÒ‚žOº‡Lšy!™&Ï]]òž¨K£=f Ýí)Ъ†î 3KÙ#Æ”¥ÚdY¨@y c*O/r‡1Ýv×À"7H¦K¤ïà[`L¡I%±¤"Ë}œä¥”ŠX%Ãr+•M,•-ɃY\n)0Zœ3Ø-×ë’‹.Uä¼$>1P1Æ$qÀLo}0#ìïÞï…~5é ìù”S^X³Ã];h-tÀ{U½9S\Ä‚É6"&’L5©µ´œ3¼ÔÞâþPzÂ!OO<üÈcõq×Ãeªc°0PÉh´á€fq§WDg†¡™®³%¥—?ýøŸ²hõ[‹TÑL±Ç ºm”*8B7<—d˜ð\½dÝ;Ÿ}þEûž.y ˜Ó»]ßàáÆäÿ*¼tú½hOr–⣙gK¥=ÉE☊.•t çéÊ|˜6Nç­âtAqŽ©cJ^«cލ ùT`ý˜?x!RÀâ^½&“¦Ls†‹.UàÜX€©Èg§,ð¯¯-É0a¸øæžÿöÅWšóÚŽ~«„g¨Ÿ«V¯>üÇÇÎYözégÃéWÃdx,(É0yb6…ý_"þbõ“"‡g¾ Ûoní7 PõF”%›• êjô±Ôµ¤æ’ jÏ{±°­ P¡a@I®ZìM=oí~y[u—•h«žÐ9ŽU¹àçÒMíx瀩0Û[êÚ[ƒgÞ@¿½4gAàÌ[MF†©Ó¿‰»µÅì.lƒ… ¹Ý…bLíï~ÒÄòVpiŽó+-9?ÙúÆ?9æ¸ ³ÛJÝ5°gùAECw6›Æ·bLלW¤IQ€SRj‚ù¨±¹Ã˜0ã¦t‘ßžÖù|ÿ~k˜‚<'™ˆ’NŸ$ÛÅH4¥¤^vãÁãJAQá"cÃiï œ-yãÄaRÒ*®4·äñYRsÃ8ÇÔ cj]ÛzÈÀC:>ÕQ–´¬hé2º‹¹¡Çìøˆ3ôø ©­= ˆùwÓÔ‚Uo)êa®ª×…Îžà ŽQÊx؈Ã0-Ý°×³Ž°ÆO—€1an7¢W|Óñâ˜Ú†÷½_©N/ª¯+3üåÂRnä"Ð%3`œõ²½Sh å/ÝEº1;Ÿø‡cJÌß…¡T€ T®ÀëÓZa‘‚e€™°!epF8g‹;‡È~¼‹Ç&9F~çÚ&M-. Àä:aò Þ½2†içÞOLÛ9úÅÈ`Œ„1¾Å¶ä\‡»2ôÅ·øIœBñ˜d*°|åªþø˜YK_÷=›sÅë+Ê7„|tàsÑÿü•ä¿£áÐBþ)žýØ©ÿ¬dŠ™º\×õ7·ôà­zÓß›àk>\N$Aw؇a‚¡÷˯ ¸dI­ÄÿxcžÉìE¥‘H¯+mI<6I·Œè¥äEy@bÉô‡Ë{VËß%Ô¸´U+ĪÁÛy¢^F@ Q€1á}ݲ•“þxœ¿½±SJlóÌXÃfÞÆÜ~ã½?ýÞÔÏG¯U¿‘aºÄonn=·6`*ÿÖ“a*ëÖÖ\epuŽó›^Õg`Ë–7Ž>öøñ³ÚÊ4+xcÇ\~€¡;›MõµVÁˆ1U B2¢1¦ŒT$‹áU w¦Û<žÌøS({¤’gÃ`’J“I&ÉÉoÂ7<Ž@¥ïJ‘–Â|,éd ækÌä±îÇ–ü–~¿¿%/·Tçhq1:aLøŸÁ6³ÿ¯û±ž ж3©&|Û¾¿%ôl<ØS²Â|Êq'ž2å› 0YNhì©7'.»Ì¾­5J‘a*)rÞŒ)Â?\˰‰°QEõŠÅ Ó¿iGçÙˆì÷<áÊð$烖üý›Ó³­ÚàrÉû2(`\ ë¸º¡KfFŒ)oÿJ–— P¬* pÒ®¶ê“ {`eÇa2ðQ ꫇öƒ¡Öt8rÀÇÏì* $†‹óìá¢`ÒábQl¯òcÉa¹‡a’*àW7Q2àÊXWø~l`lgô›ÕÆr É4sÉ&÷ÙĈZh“ÁN¿ª`˜ ›ü5ôo"JŠ× üM` VO<øãàŸ¥˜ üDþS|U¯Ì½½ûðT½iÏ—å€Yºõ`˜¤\ ´ É„=Ú*¤‘ %H?ŒîWVz mT¯Ï,’é²N[ åz‹C^Ú~ÚV£¡„ycFƒGÁmqá loì”’Óbæ¤13oëÖ¿1îâŸKGTבaÌRó0(Pý­-“ “´ Žó3ð’iÜÌ•f…ú ÝÙlßlˆ15^s^‘ $EbLI© æ£Æ äcÂ\[„•ßžzÖy%Ìð™ç=ˆ’Ã'9N××ëb³×´HÜ)izÙV$É¢±€dËwÌù6àR’XŠ-E:[ ‰§s@1£ÆV'Œ ˆ’fàrI‡ì0Û,ضÀ|üÃW؆)&Æ„ßÊ|ÊÜÛ SÑ“FÔ B2L5î>3q:`L˜Õèô=5ªÒ½b .3̇\¸’Kì•øÒß³År¹TÔ›Ùãê3®d_GŒ)5‚ P*Pˆ'tqÆBÑ ñØkº¸bÂ6¾’cÂ…dÂpÑzŽp ¦$j¸'–\ ÄA¯Œ~Ía­z`Ò±1F¿Â6!cÊÀ¿BH¦é‹7•|6ñ;ýŠ¿˜Û ÿA‘FÁÿEþJò—‘#Mo(ò_“ÿ¶ñžÙR˜{{Ýñ°Ü9ji®ã/Ü©Ãq„UÂÀPÔ¸´•¤‘ˆÇ&ì= Çã[i$Ø)$ _YR$Óï/íÝVçÚ+[d=^YÁ¡&Üç‚gž€c•°öÆN)m©Þ3o ·,[(;^õ¦± š•çjnmf˜8ÎoVƒ¬ùu…d;cEÉ¡»x¦7¡Þr‡îl65¯¾8'$ÆG%C²©1¦lÖ+Ku0ÓÎ’ÁÀèE½ïpÊYç…6*ÜÍYñ,LR0™ìHÉð¥T‚R²LøÖªÖ°$®°Ãq%ËOx" À•‚bÃÙ–~oL% ®äDVrÍü®³%kÉZ³Œý%iÿu˜'I ¬D‡+&éiÄ6ð­DÙ0 9ꨩd·dͧüôäÙË·«Ÿ-Ǻí„Igß<d˜J ›Ï€1ýÞ]œØÅ jaL½bʬ-—i‡cLþŽ®|r!¡â¼šÓ›UзÔð'Ęòùßd©©Ș°‹«Ë%@•à*F]Èà[|DSö‹ó¼‹»&ñÒÿe‘L2\tï§¶ÃÎÀ¤ÆZsnºb†I½âdÔô?ª4?¾¤IÆÀHO~­¼BÅ/>l¤ ™;â˜ç_ÜõlRµ!DK$„ þA ÿAO„öÿ|ÄMb2Ê_ ò/ã«V ÀÜÛóŽ‡Í€õ¾®Æ™:0¹º2L(št­¦SÚƒÐoÚHrrÛÒåj#©•8ûB)v¹[Õ{d¿à<²²[[œî¢Ü0©É© Žó“SÕçDH¦ÑÓW”eV(—aâãaõ5UÙˆ1U¦E² 1¦,Ô"Ë @î0&Y/–ð-0¦ˆœõ[?Iþ†ç¤Ò.”Ô¯R¸Ù^mù–ý¾V)WòFP²–Å"–R-5 cÒ`˜$¦^jÈG %ì‘Às°÷(í§£Â|JÇŸžkyk¸Ó¸ NÏÛ㉩՛p¥Ð^.!/µË"Æ”ÞÿsN¨hºɤÃE70´8 ÔMõ SÓ‹É $AL?øÑÑl4ŸM<Kņ$yˆPæÞoﯓ²’º´¦~˜XAT ŽÉtÉõÑm5”†é˯¾ŠsE“vj5óf2Li×$'ùsk‹Ó]¤aÊIuç°˜B2˜²ŒC÷,Õ>1¦,Õ&ËBÊS€SyzñèÔ(;Œé¦¿ôW;º‹1EPò«b ɉààÇ’N ‹øæØïÛvÍ ¶ÜÇ€+v: *¹K!1œO\)ÌJª1&t3˜O9¦ÓÉÏ/ÙªK]Í™b2L©é‰›—QÁ˜"z¶‡·0¦v}Á”’pK¡=žÎ××ù},wqIŒW[&bLÍûðÊT€ P,(’É3\4oFd˜²Plj)ƒLæo|6!Ô˜ŠªKF`îíÑç!`*b%É0ÕEqž´R@2ýæâë ÁU ®m5”@†©RíÓú»êgÞÈ0¥´î£omqº 2L)­úœd[H¦Ö)K9tÏLcÊLU² T lˆ1•-ò‡1ÁÛ¹¸;2“ cúåç*cTr#ÊâP¤™ Qr‚Aœd&›R 6äïRÖ]+UÀ¤crH¦Nž²x‹ 01–\::àäV£FôuÀ˜`ŽòP^ïW‚ȬÄ{œAdº¸RF»8bL ø£0 T€ Pt+`‘LAÃE2Lé®×Dæ$Ó¡?:zü¼WM_x6!ÔÈêªq¦`î½áÏyªž SUæéj¡H¦ /¾ÞßVã@ d˜jQé;‡E2U:óF†)}õmä8ìÖ§» ÔêªÏIæ…dzzòRYC÷”6bL)­8f› Ô@bL5‘§H¢¹Ã˜àê<ÂúŽo1‰SO²NWœvÎW"AEÔR”#%°J¢êQɶâ{ÆÀ=ùùI0&!™Ž>á—“_Ü¢G?LIìn™'Á˜B{Ŷ]>faL±ùKO'·ë‹Adæ(Ø¥§&Ɣȿ3E¨H™ ™<ÃE2L)«Âôd×"™?züÜWuHCCHzj¯ÚœÂÜ{ým™£Ù“Nÿõ½ ?"ÑÐ[­îü}ù €d…`¶Õ8P¦ò•ÎÎ/*›y#Ô࿵Åé.xkË@Õç¤B2a¸Î¡{jœS*‘E *@Œ©Báø³¤+?Œ©ÏC ŠÌT ‹Úv ú/Î8×Ü<ò£H%˜¤â(o&¢4s¬õ’ #º½|G~£”4“‡d"Ôô~7IùÆô›K®èô\ìòþÇÆcª¬'ôÂI>“Dfœ^ŽS’þ1Ì  T Å ˜$¦Wd²n’Ld˜ÒPcµÌ£iî%ÃTKey®Z+`’Lq 2Lµ®ôÏ$™â̼‘aJ_‡äؼµÅé.È0e¦êsR“dâÐ=Õ•NŒ)ÕÕÇÌSª ÆT•|üqrÈÆtCŸ‡,ën\6|û‹ÓÏ8@B—LŠÉ$¹Þè?)Ž-¿ÇdcR’©ÿÐÉG}ܪ ;"V».ݰ÷Àg_$·[bΨ0&¸Óèôît"ƒ„¯ôw†¾Þ/Çd§¿C#ÆÔÀ?/E¨ȸB2ýù¾'O:ùôõ[߉.ÂXûÙç.f¼=ÔµxB2‰•wáÒõÑÎx>:ðy]3Ó7X1÷’aj°ì¼\ ÉJ ÃT¼™ü‰LqfÞÈ0e¬È­-NwA†)cUŸ“âÉtﱺ§ºÆ‰1¥ºú˜y*P•Ęª’?N®ù˜®½öÚ|Qò˜2k±9ó¾m÷þdþ§1ŸòƒÃ'ÔÌÚIf®† Vþ‚¿HœW]ßËcü„¨b2ÿrÌ T Ù €d"ÃÔìJÈËõg¼ðô?þË7ïi2Ly©r£œ0÷2–\ë=EÉä˜òôZd˜ÒX³õË3fÞ;üÇÑ3od˜ê§Ï|Þÿáª_Æ0©M¬^º® l™ùôÑÿøŸNÏ¡{]u®ëɉ1ÕU^žœ $ZbL‰®f®rò…1ùuŠ–ñ[*¨@b1¦ŸïûJ'úaª¼Gä/Dóæ? câ¿™ P*@€çúabóh€»>Z0xùšûêȈöF?L ¨ˆf]bÏ{ŸFT=U4«^x]¿ï~øYômñ˯¾¢nTÀTΣ' è=› ¦×wöÜ×™·¶lV.K– ûÛŸþ+rèžÞæ@Œ)½uÇœSj ÆT­‚ü}B ÆôQÌÕ,BƒH,ÆôÒŽkkë°ñíI‚0–\B»á„e‹Sƒû“:]ŽSÂþXÌ T Y „‘LŒ%—¬zJyn€1áÙdÝžáa£2L)¯áÒÙ#™È0•ÖŽG4V0’‰~˜[iºZÉD†)MYV^{}çàƒxk+K3œ&– ;xI‡¿m\ˆ{_àèC÷ä×&1¦ä×sHê¥1¦z)Ëó6YbLʨ@Ù $c‚+¦'WÿLã7æŸO!ÃÔä¾6=—'ÆT'®¨Á§%Æ”žÿsJ¨hŽ~’‰ Ssj"»Wýè¯ÛÚÚoß÷ÉšÏ>ðZACHvk¾¨d~s/¦œT}êŠé'™È0¥®œá@’‰ Sƒk¡¡—³1&\‘·¶†Ê΋5L·ÖœzûÁ}ÛþöÅW~’‰C÷†ÕC5"ÆTzü-H·ĘÒ]Ì}¨ĘÊFXlŠæå¨@21&qÅ$iÛûÍù2L¼ ÄW€Sûœ ²DŒ)~›ç‘T€ PÜ*`’Ld˜rÛ SpÉDCHcdOÈULs/¦„T ³¨€I2‘ab#‰£€‡d"ÃG´ãbL’‰·¶×i^³¾wCÛçöûKý²ÓC2qèž––BŒ)-5Å|RÚ+@Œ©öšòŒ‰P€1&*P¶ ĘÔ“`LpÈ„FæSÈ0%¢¯MO&ˆ1UÀ %ð'ĘÒóŸcN© ÍT@H&2Lͬƒ¬\»Çì›ömŠ(’L4„d¥ÎË(‡L4ô–!m’B2‘aj’ü©¼¬’Ld˜RYeeÚÀ˜ð;ÞÚÊ'GÑ]YtG÷í‹&{²ôÁ››&wï¨;•dâÐ=9uW2'ĘJJĨ@f Ɣ٪Í{ÁòŽ1á‘ÓiÓ[mÛóqô1ü6K  ºQéÑ%Ú÷ágIë9LWLê ™Ä4 gR’VY ÏÏ{ý5ºýoÙµÿÝû³ô¯OWYÞzçÀÆ·>ŒÎó®½0Ýð–ÆìQ*@¨@BÀÄ4ø’„d†ÙH¯‡ <¤dæÑÒh)©RVøàãÏ¿üŠÔ¬Vo¦ÊõÁÇe[ÍTÖ¿0œy«¿ÆÉ¸B1Æ„<ñÖ–ŒŠa.ÊPþ–LVÉüåú1-KîaîÁÔ"‡îeˆ›€C‰1% ˜*Ð$ˆ15Ix^¶Þ äcª·¾Œ)}E`Žó­€ø[oLÂ3ÍêÑï¯Ok…0؉{Ûe?M`›° ä[¿”žS *‰Y¤uR€S„åi›­1¦fׯOªVÀïŠÉtÈTõéy*@¨ T€ P*@¨@¨À•-ák¼QÚÿ×ýØÆ¨&l´ïoǶ¼Ë)L‰²R*@¨ T  cJA%1‹%V  É„ õÏP œÓê¡ýÄ'Ó®¶r°ÒK`›p%N²Ę’\;̨¯Ęê«/ÏÞ4ˆ15Mz^˜ ÔD@WLtÈTmy*@¨ T€ P*@J*€õÚ ¶-Àa•d/ 3'LpÎÔc¶µ¬¶{â‹ P*@¨ éP€S:ꉹŒR@X%OK –Ä“€Jp¿„wñØ„ýÀ˜ðQ¾Å‘r°O|%VbL‰­fŒ Ô]bLu—˜hŽĘš£;¯Jj¥Àž—¶íê#I†ª/½uîäT« ñxs“¿ØŸâR1ëT ZbLéo!ĘÒ_‡,¨TbL•*Çß%\bL ¯ f ”¡1¦2Äâ¡T€ P*@¨ T€ ÔSQë¾Ã rõ˜ç¦T€ P*@j¬À¬]–>ÜÃs^€M“»w¬ñÅx:*ˆ1%§.*Í 1¦J•ãï¨@ú Æ”þ:d  ÆÄ†A²£1¦ìÔ%KB¨ T€ P*@R®1¦”W ³O¨ T w ŒîrH`™×iñ³M¹S‡ΰĘÒ_¹Ä˜Ò_‡,¨TbL•*Çß%\bL ¯ f ”¡@ûG ÚÚoÿëï—ñJ¨ T€ P*@¨¨ƒÀ˜fmé\‡ó”T€ P*@¨¨½ðÃŒ ïˆßKØÀûëÓZq¥Ewt— qׄýB5a§Yû ñŒT a cj˜Ôu»1¦ºIËSÄ+@Œ)ñUÄ V¦1¦Êt㯨 T€ P*@¨ T€ PP€1MÝÔ‰Q*@¨ T  €I®„¬â$6„gÂÞWN?~~`?`¦{Û5ÒÜê¡ýà±)Åd&©@€ĘÒß,ˆ1¥¿Y*P©Ę*UŽ¿K¸Ę^AÌV‹ƒ(  T€ P*@¨ T ± cJlÕ0cT€ P*@¨€_8Xiû¢ÉÀ’Äë’€MlÎtÑ„ãñG"aïT• ¤UbLi­¹B¾‰1¥¿Y*P©Ę*UŽ¿K¸Ę^AÌP ­½[ T€ P*@¨ IV€S’k‡y£T€ P*@< ˆË%0LØoL6©&Ù¹«mÀ~ 9‡HØ€‹&JJÒª1¦´Ö\!ßĘÒ_‡,¨TbL•*Çß%\bL ¯ f xØ´oSǧ:"µ®mí÷B¿³{`»eEË!‘C±ýدºO¶– ñE¨ T€ P*@¨h˜ã7Æ r S›¢T€ P*@ªT@\.‰k%lN¼ƒXOKòâ{ ûÅW“€MU^?§ÍT€S3կ͵‰1ÕFGž… ¤QbLi¬5æ9†ĘbˆÄC¨@€+&8dB¦€(UÂ>b[² hiÁ¶€œ”^Âñ€ŸVf‡ P*@¨ T€ P,+†‰S–+˜e£T€ P*!ìm& /„Š“hqØÿL€–*a?5ÉWz$6dË,Jþ Æ”þ:'Æ”þ:d ¨@¥ cªT9þ.á cJx1{T @u¼ä÷À„£Á3µïo'LpË„¤ØÕ¤T€ P*@¨ T€ ÔOWßÒ¶«¤Q¯|I?â«ú]—g¦T€ P*@¨ T  ÖÏ8ø`''ýùßþ©ÃÁ;+ìÁ·|¥JbL©ª.f– ÔTbL5•“'KŽĘ’SÌ ˆ¥€ J8T¢ËÉo*Á6ð­°Mx‡‹&IðÌëÔ<ˆ P*@¨ T€ P*P…¯ìéÿX[‡À„¯ª81J¨ T€ P*@¨@íøüÓƒ=¾~ÆoÂ~|ËWª Æ”ªêbf©@M ÆTS9y²ä(@Œ)9uÁœPX hü8ÀIQ/ðLf{€4aï-+Z°wÙàT€ P*@¨ T ® |ñå§­k¿îǘ°_ÕõÒ<9 T€ P*@¨ e(0·0Æ„ý|¥MbLi«1æ— ÔNbLµÓ’gJ”ĘUÌ (­€xcÃ>I<0á…`•&¿6Yè%øj’=-Wú¤<‚ P*@¨ T€ P*P <Î1ÑS-¤å9¨ T€ P&)ðÄùÇ^Û¤kó²T n :d¢+¦ºé]×cª«¼<9H´Ę]=Ì\å cª\;þ’ P*@¨ T€ P*@¨ð(0~Ãa&ÉDWLl!T€ P*@¨@ºèõƒvJw˜{*¨€ß!]1¥³©cJg½1×T  cª…Š¿øåϰš(ó%e© T€ PŒ+@Œ)ã\¯âuîÜùûÿq¨X£ ;TÁüô¯ÿöÿûÚ×ÿ¡¤É)ĺbN2LH¡f£"S‘e$úé1G™Ö¢h«P‘ ¨Øîjî)eÙSÎßÿ¯}ç_þÕcÐ1 7ßüÎÿºôÒKëUai>/1¦4×óNªS€Suúñ׉U _ÓE]ÔÐc»ö}RH{?Ùµ÷“V:€ôРÇÎ=ÿÂ{ìx§Þz瀕ÞFúéMM{>Þn¤m{öoÛí¤7vï·R»•¶:飭»>Úb¤Í»>Ú¼ÓI¯ïüÐJ;¬´IÓ[¾æ¤^{ëƒoÒ†7?°Òv¤÷_Õ´íýõFZ÷ÆûëÞxOÒ+H[´vë{VÚ‚ôîËFZ³ù]M«7ï[ýº“V½¾ÏJ›¬Ô椽+_+¤¯í]±ÑIË7î]¾ñ嬴ÌHK_}ÇNo#½„´ÞIKÖ¿m¥uVZ¼n“^Ùó¢›^xeÏ k‘v#-Òôòî…FZ°¦]Óü5íóW;iÞêv+­Ú…4WSÛ®9…´³uÊÒ¯ýÃ7g¯Ü‰4KÒŠ3´cæŠ3–ï8ôð£±J ±ÿaÍØŒ3~zÒ©g-ÃóƶmÛ’Ÿaæ P*@¨ T€ P¬*†éÒ«ozdèXoH2eµ–Y.*@¨ yQ€S^jºÆåìÔ©ÓøÉ3Å¥F(Ø¡ÔüôàÀÇ~}þ…ŽÉÉ56mÛó±XšÄÆä˜\ӒڕĢ䘓\C’X‘\ãÑ–ñ¨ÈfT°¹v"ÇH$¶¡ÕH¶aHLBŽ=È5‰%Hm@b»}ÄÜ#†ž‚•Ç6ñXöŸYG :óV[vœ_žqî·÷w-8–ÕÆ1ܸ&›n{f¾×S&NGŒ)ÕÈBPŠ ÆT‘lüQòÈÆPIˆ%M&´ô=jÄ ÒA—bÐK ™”^rF–.ÀÅ0¹H¦*&{*)šar1&gljaL “3TuF«>†©mS0ÆäŒ_mŒ)ˆar‡³.Æä0LƸÖ3ºÅ07cz¹h°»pÍîHŒÉûš“Á0íšÝVÀ˜”ar1&‹aJƆéÄ“N[þj;6ž_°Þ³H2%¿ÿe© T€ P*@¨@&°¦›±l'ƒžC’)“µÌBQ*@¨È‘ĘrTÙµ,*0¦q“fŠ)Ê´C¹+ç?~`À£‚1é‚ù¢¥òå2LîbxÁ˜<–#Y÷®+ÞÅT¤ ÝMŒIW¶Û“± Ý^Í.ëØÕTcROÆäšudQº½"Ý‹1Á|CŒ)~s$Æ_+I²¦1¦¬Õ(Ëã(?ŒiàcŠºX%×ßÒƒ,Œ©Èå’ø^*v¼$cJ“^òLLí>'L!“œ‡+&Ë S€&Ë S9~˜ªd˜Lî¾xØ ŸLÅ®˜Þ pÅäøaJ¢+¦ÒÓòtxc²¦_œ¶bÃn±à1cÊ|’Lìå© T€ P*@¨h‚`˜.»úf8Æã Ösãñd I¦&Ô/I¨ T€ ÔNbLµÓ2WgÆ4vâÌ";”ôC#~cúÕyzìMëÃ63 L%ü0Å`˜c tÅdyc*åŠÉƒ1i‰¿áºb*òÆdcLn¨ ×S!¼†bLv< ËSÇ“`LÅ14v\OoL!!bL¹ê[XX*P¤1&6ˆŒ*;Œ ãÂBT83Bœ½íÀïAÐ’Å-aã ^=}/ùé%#„\LLáäB0!¨\‰XrUùa*Bïc1LŽOÑJ¦x®˜ áä0ðÕpr&¿አƒ` *áŠ)ùAå„aZ¹a·i'À:‰)óH2e´Ûf±¨ T€ P*@¨@R°¦knFLs8C0&¬áø}2%µÎ˜/*@¨ T ¤ĘJJÄ‚Æ4fâ ¯AÊ0? ÆäñÀäFù(Z!£’iWòÆ’« ô٠'WXÙ^­+&ËÊ+¢\»Øq Œ)À¢gc û«cb'Dò«1¦üÖ}ÆKžGŒIýsú7œQ£ÏÓR´À-ÙP¼]ÚRŒ.y襂û%0vB;˜6ºƒNO$ã‚#P_¹€©'LvØckZÀícÇ’s|Û•hQ8¹rý0Á’ã1LÅáällßãƒ4šaòcL3ÝËNNÒ¡‡=eÚìw?üLÓÇŸþ-!¦Ÿýâ´¶»a'WL–ÀvšGY“æ®:üÈc·ly#!¹e6¨ T€ P*@¨Ȱ`˜.Ãô†ŸÂóxòðã£Ï<ó¬Ÿ|’aX4*@¨ T › cÊf½Ö½TÀ˜FO˜á±Cm3ÌO÷? Œ©›å~©ÝJå¦%M09Ö%Ø’$9¥¢h±äJûaŠf˜—à 'WQNÂÉ!»bÚ³x•`âq­z)ÂýÒpKš¶½hÉL^L¥&á]4ÁÏ¿`*HζF®ÅáÙõ&Ú(?L†+&£l2LsÛvÍ)$äÆôŒzcr¦˜L†I0¦㦙Պ6ÓÜÿ­\Ýe˜öxìpÅ$¾²ãoâœU‡ÿø˜ÊH¦ÖÖÖC9$º¤ ,ÀýìWLMÚÚÚºtéó`=Ls‚ßv´_ñ¯Xîµx< T€ P*@¨ å* “e +&w•…íŠÉ~<ÍcÃ; ™N>õŒ²H&óAÛxHÑŒáÑÀóÀ‚=aÏ›6mÚ¿?à9®¬g&a¿ »~ÎÇ™rÛ§T€ P*ˆ1%¢Ò— `LÏ>7Ý´@9ã\ÛÓ}ý=ç¼nžàq3Óë;-»RÁ´0©IGj9Â]FéVÚò.,D¦‘H–¸cèn%ktQ\B&ËúS`˜Ö#–œ?œœQÎ '·p³:}¾mÓQk&¤_8AåŠ\1Ͳl7ŽÕÓÙçvóØà>:ðyúG­sLŒ©ÖŠò|T = cJO]1§e);Œ ãBa’Ʋ1¦`€éåâ@r^'LVå"'L«L'L»Ô©‚c Œ%g•KÆäe˜‚"ÊÁ“Ø Pãg•M2µ··Ã ïÒGgR¤I–8Ëêg˜ 0õyYX¬VÙƒN‚ƒñ?Ç`°-?—vÊ™qÙ£“þ=zôÀG/F “[¯mMíQyq*@¨ T€ P*;,†éZ‹a uÅd{еO¬ÇÇ”A2Ƀ :tèàñ´$.Zu'žDðà Ï/xpÐg <5à£NØÐ¯tI†ÿYF«Pj°Ä’>Ýà·ò|äy™™¢½1ÉÓ„ä´°!}ú§}QoL8^–CàéC–dxže´¼ê›VO‹G$ìÄ™å*âÉ Ï2òQ8'Ù/—ÀµÄ]®e2L|œáߊ P*@¨@Ê Æ”² KJv1yH›Ö(@K÷<4©€åñNä8ÇÆ´1€^òº_’@rûQQ¹÷œ09F"'\!–œ’3íAb rÍ@޵랰/¬ucÉÙ¡6$ÎF ä‹ÒÁ0™“é‡É4Üc kÜĘ’ò·g>¨@ã ÆÔxÍyņ(;Œ ãBú7¬Q㯃F‚(izëÃM…qdibÉïo©(ZœÍ-x]*F—"é¥w5žqˆï¥xî—loÿšt¨Zˆ|\€Ér.ŠdkC£ÈÅsÂdúa’Q¯›œPÊŠßvFŠô´…1}Ãb˜ŠÉ)ÄC?:9Þ˜”a*¬uÞb=„X¶Z{Qq¦+&Á˜ óØ+‹M2a"“õ˜|Ç„»ÐEf´?Æ$Ë‹ñNfÄYô¬Î“<“bRÂ9ÉUÄÉ“éoÉ„–ÔÑN’¡T€ P*@¨ T Xƒa²–XXklìg¤Ãäy<±#ŒãðþÁ±H&Æ„' Y!òÀ"+(Ä««>8àHðFXž¡È‘M…ç1Gže´¨¸´<žÈŠz™ÕðÖò•<þ NÉ95‡È²gž–3ü;Q*@¨HŸĘÒWg‰È10¦Ö±Ó RblºÛ6HYÛÅÜ’µ0Þƒ.ÁýÒv+9ÁãŠÇ…ú÷ €É2%(Àä.q0 É‚öâ¥ì…°;ØN˜¬á½ ü±äÊb˜æ´íüÅé–7&a˜lWLÞÅçĘÂZ61¦Düç™ *Ј15Ev^´þ äc¸ÐC#a€¨éîwùu7Û‘’'}€£™ÌA¤ºñ,8ótÇ”2²ôBK!Ü’ ¦\.ù¹¥²/Ù‘ãœñh‘ï%ð8?½äw¿T<`õ ÷•…«`r'¯¶¢È’óLve?Àd’Û!“ -ù·“ƒ10Lf89s­³²A&€bˆÓ7zz,’I–{¦ìãcL~PIöÈT¾ù-vj:lÃÆ •}¥ÛާXëIÐ^–}ß#¥I&Æ$aãÌ•xpT/}ÖÐPnoLžGAŽÌ%fÜjcÂ1êWɃ1á$ ”ÄQ“ÐNŠ1á+ u‡ýX%""òq†'*@¨ éS€Súê,9¶0¦1ÓL ”Çðd¤ºŠá)Â̈.yÌI?®`BÚòn L;ÑÞ6wq{i'Lvh$—a²&e˜t½:,í—Ë0ÁˆŒé`L! l7ĘÂZ61¦Düç™ *Ј15Ev^´þ äczp°—F2ˆw=`=ãÅàác!ö°CÁGàJ~OK®‡Ïr¸%{a«=ýcPYój¡Kþ°qöÔ9NǦâ~É¡ÑKUij1| ‡ìñ=ôRLL/ÙŒš 0E‘+PüÈÿô¤Ô`Lf,9 qC{P†)b­³ëŠ :‹ãÖQÓ–ÿ ”O&1hÿ£N’€É½zc’=þ©Ô û1&œV~./|”0v²ÅÓºÓ½Sý;F^ P*@¨ T€ P(,†éš›±Ž&ƒa XbñŽeí°×j Æ$'÷´ŒŒŽ.W2¨r)`6”RÒ_™@" `-ÃSŒ®£=æ: ó£F‹ÃÙüAåÄç“yœ×Ò_á+¹› T€ P*Vˆ1¥µæšœo`LOyÞZÄꤩ ^{Óû‘è’7xœA/¸_²ÍF–û%¿&ÓHäF‘³ C>'LÖRv˜Ü}‘&{ï˜{Ü@rKnþšö‚eÇX—aaL¶0&¿&YNŒ)¬Mcjò¿—§MT€SÅç¥ë©@î0¦~ vF„2.,Nø¶Ë¯ºº.”L>Éò¨àT ~•\×Ja¬’5±ë¸Y*ò´TÂÙ’ ©Äá–¢½.yÑ¥bÇK½d9. uå{ ñßvÜ/ÙÃV½wüz)ØýR1˜ï “lÑKî·¶“D‘žŒÉ`˜Þs‚5ø¦6»rCÖ:[®˜ä™2Žœºì?:zË–7Âú3$Ž‘H’eÍ2õÒH¢'˜“¬-–ŸÈ‘fˆ1-È1z6|”¸uúÓ `^Q2ÌåËõ¼)ðÜT€ P*@¨ T „q&;œL K_}ç¥W½®˜ôñäžA#"H¦ŒIŸ ðø Þ[åYCäá_ɰdBBW ؤ5þg-¼@Qò’ÀpòX„pZÒËÉÕõZÒN¾Õ¸r|œáŒ P*@¨@ú Æ”¾:KDŽ1 ó|‘Ê ßáØžÄ U –Bâxñ0/ù I²âÝ´!ⳕ6íksR`¹S˜&{•‚íoU’Ë0Á!ÉÃ0Í]µK’0L³Ýxˆ%'SÃDŒ)¢YcJÄž™ MQ€SSdçEë¯@iŒIfî0ßgúM©Æêr…‹.º¨ß …Cr¾í,£ÆmEIœ'E§0V©€+ÙKTÍdJš¶XÐÒK¯¼õ­ï|W-ø‹Óðï:ôÄFÿGG^qý-‚Ï+DÃFL˜§^—~zÒi­æmºÅLq/ >‘ã.½¶÷¥×ôƤ³JÓKßøöwÅ÷Òb7²ÙÈx|—^úÆ·¾+è’•Üq­gtëÆkŸW"„\,L0IªcÚ·íàŠgëÒX“ ÃÔ¶q·:a’˜Öh ®d¥k&]ØoîŸZd1Lß=Ë™½§Ÿpͤk-ÖµÎÖÃÚÝx`˜·ºO#¦” ™ê](žŸ P*@¨ T€ P4* “óœk,¿ÁãɈ9›ñ`‚ǤnýæNYò¦,ã¾®e1OÎè=}äœÍv¤‰Â <âáñä®Q$SsU’Xr|Q*@¨ ¹V€S®«?²ðî>8·ÿÁÏ? <ȘFOõ¤ ÛSßû-ƒ”ÇðdCKEKâ—­ßñ­ïü‹ÆŒ;ñ§ã#ÞÍeðKÖZv%½„=7÷¹·Øf4WMEf¹yÆãé›ßþ®™ž;Û^ÁnyWï„IƒlÀ*ÑýŠ›‘L€ÉÃ0Á ÓI.ƤϽ1…5GbL쥨@~ ƔߺÏBÉeµ¡zE1‹TcR·êfȧ”ªŒ ãÂÉ3j4È$ïÀ“¶f²ähŠ`•ÜIÞ@7K‚. ·$ÃÍο¾°gŸû'®gŸ{±-Ķq0&%è¢ÿÖ·¿ksKض‚ö££žy®xH/ff™‡#ôÞ‘°pÖJ1|/ =[¸¥bzÉð&ZÌã]²0¦5–— 3‰ã%ÃýR»7~œ‹êœŽºÌ>"(Ûw’DÙñAjLÕbL˜†_t°þ÷0Lh+7îÖ§i'ÖZŠ×÷a²kßÂÔ.ypÑ]#V£úÀ0š·Ñ©ÿøÀÂ;ž^%Ë t­3”´:ìl²ôÐHŸL)ý›3ÛT€ P*@¨ T€ ÔI0L—]s³:ˆÕ8×x<™¶ì-<ž´ÎÙ,'ýǽt 'Ž}åââñdäÜÍÇ_=Éz<±±ˆI'b½è—`’©Nbò´T€ P*@¨@j Æ”šªjxFa&€ Ç×a&`LÞhV©ï}œõ«®–&ÃÆ„!·pK¾£Ë¯/ìuû}0àÛºú]ìJ…Èq¶ï%ØŒf.~U†èb3RzIE‹ÿÔN??Cw$]І©‹#ÀTÒ Ó®¸I0ÁBSNÁšc’Æôën{(Œa¢7¦ˆöMŒ©á~^ $Fú›ªSTf$k ˆãs, Ä >•Ê,aiŒ ¿‘Õ‡â2=ÕòXÓ}-I?b*öÎûZ0j,b’N*&“B=*ù\+©S%ÿ†é]I·-ýöWêpS6WÂ6Þáo©ó¯.üM÷+.¿îõÿ)܆•&·$CÒñ3–]ví-gžÓ­ÓÏOëö‡ËeTzÙµ½1*EêöûË10;})—KgœÓmÌ´—Nøù©8[Ÿ{ùÓ5½Ï8»ë ?;õÐÃúó=`êéOW÷>þg§" zj¸ûë{ß}Û]-‡þð¨»>˜¬oOD:åÐy]¯»ÀÐÜ5`øq'ž‚tK¿q¼tÞï.ÃÇS;_ðoý³ß¹heî—Ì!¯>YÒ+˜ÌApÞ˜¶¯_¿H7ëáD`¦º½,†é¤ÓVnØíxír&a˜Ð°ÊYcÉÝ:tù-C—£a-€€¨šk-îùIJÃäºb²ì ½Vì|zòÒCŠ.W·’ñÄT€ P*@¨ T€ ¤L‹aºúf<Ë㉮¯Ç“Kû¿p÷È5…P×ßyhÜ+x<éûÌ*q;·m0¦¢%¶+&}<éûpkDt¹”‰ÅìR*@¨ YR€S–j³¶eŒI’fÆôÔ¨)¦ʳÞ2HÓUíMEá;,hÉâ–€+ýζÉð[×ÀcnÙ6;KßÛý 1!©ï%Yú~Óm÷t‚‰ÁŽ×aÙŒÆÏ½ßKb!êqë=ÖºèsºÁÛ‘Ã^ÐŽ=–=¨`:ýì®bš8o-Ö'ÀÄ#Qä®éuÖ«ÃâóÇ+{v<ñ”Ž?=E¬<=>ÛH§t¾à—ßì$;…mͱì8À˜ào‰S”S¢ñ'T # ÔÙT•XŒD*n “dM=+iNKcLêÊ f mÛ°q_Ë3°)`e»FäÕìø-L?’®ë}·,_¿õ®€ð‹&+Ô†½j$ òaîéÕw =€–B¾Wÿé[ÿ0ÉcɇœÒ§æiÆ¿ÿéI§.µ]âÇy&ÛÐàxiì‚­clÁBç®}ç\ײ•#Áýc^1gs÷ûö|li!^CñZg±dÊõÍ…§T€ P*@¨ 1°¦›<ËuÔs°K¬g“…[…a¶¤ÞO.`ÌÚ îœƒÇ“AÖÞkš?ÚµxŠUºÉÔ©ãñ·Öü!‹'l´o­‰Ñ¸x T€ P4(ŒéÚÿ~ðÁNLTÀ«À=?)xcR·L®g¦N'ÿäÈ)% Ra&'ؘ~ú‹Óf/yUˆ%~›.—„[²íJë%^‡šÄxdaL÷N{a6¦-Z'6#؉à„I¢s<2|¢0­9ðnº_úF1Ƥ‹ØÅOëä%Æd/Që =Öªu× BÈ`½$˜zÞ1ð÷—ß\$gÓP« 1¦Š;DbLKÇRÔ+@Œ)õU˜ßˆ7¦ €D’ S‹“üF~ ÑéR-$¼1ýåÞ– ßžyö‘þ“lJÅ^”NÒ$1à¼iS‘3Oׯ’£X!á6ím0CI¸÷DêСƒøùX^’Œ8%!N’C,Ù¡‹‘d *Ä’õ±ài CÒ·/½¦7襖áqª®]Ž˜qê{ ˆ’ŒP±1tÌl$¡—„µhI\.áÝöºÐè%M‚.)}Q¬?ÎÂ*ÆÔýÊžW÷ìtéёƄ¸ð& $_ãj’¡­›vÎv!}O¼ä˜ÁãÂÜÆÄ˜¶Þþóà§óɤ¦Û¿ûÿyhp«—^²W9K›±V9Ûª^CVã㨹›1¡¾PAS^Ú;ž"àï*p­³ÊÒùü?Þrû=ûâ«TÿÁ™y*@¨ T€ P*@j®Àûï¿Øa‡M[¸Æ gÇ+˜¬õHÝúÎÅâ }<Ábn<˜ô~b9ÞÁ0áñŒXhqϨ5ö“ NÎuÅ$'“_ܱSÎþÚ—úßüÆËÕXzF`¯y;ç © T€ D)ðÄù5¾KÖt&™yK¨wÖéÈÞ1% u»m ´7ÁÀ4bÂ<@K ”`3»¹^¸%è(²+ýü41!‰ñ_ÉøÜbtHtŽ3Îé Ûø^’%î° c²ãÇY Ú‘`_€­Ç²2X†ËÖ0aÞË–¦—­Q=V&`û±Q3-‰õ¡û=‘`ƒ€ï%1ô`²0¦Vc‚}ç‘g¦cše¯aÐ(rà 1¦Š»bbLKÇRÔ+@Œ)õU˜ßÀƒ’:Q‚[%øT2µ(1ÒXr“'Oö{sJ—®À˜n¿g‡:2?â[kÔÈ!EÂIf¼ábDÉ¡”„UÂÈÒ ®ˆŽbÉeä±oŸ<ÒŠáæ§­HpÖÐÓ&–.»¶÷¥×öVbI6º½@ôÀ•0BºdzZB„8‰†Iý‚>eCK —dx ÄÑâ€+ÁÓ©‚1YCUczâÙYÇŸxÊu½îRâ1ã.¶A{ñ*ô=ü-÷ÛË0~•'¢Ø#¾—0–ÅG8Ì„áìó/¾Žqm^*B—À09þE‹Ð¥Â0× ‹V–ï%?Ìc1nZpD¹ºÝ>ýôÓÎ;zrŒÃÃ9ôR`ÒUάáÎgVÁBðÜ oرäö Ž<·îü;fK¼¨m3a–¤æZghÒí×]u}¯Í;?B"É”®>¹¥T€ P*@¨  P`Û¶mˆˆ1uÁêâÇçñVcŸžµ Ë*†ÏÜdÅ’[ÿöôeoác¯'–ÁbÉáñŒXe1zþÖ‹¶0cH´ke˜Ž>á—CGLÀ³ÉνŸ|ùZ4 zës‰º=,×'»<+ T€ P*@*RÀTN8¬™ˆÓaýxëäˆeð0Hqö:Æ3“»’YÖ3;&8^[À?8¸Cž™„m]ú¾Ü¶+© IlFسÌ6!ÁëX(Xˆn¸åî3Îî*¢ÓÏîz}ï»%‡ÐK’Ô÷’µÁ¿ëÏã£faT?~Θð>mñfO91÷`B¹13WÓØw~uá¥]v³».}‡zc5­6Ę*j…Öˆ1U,HR¯Ÿ¾S_…ù-@KK‹¢K=zôÀGS‹ÒAåð‰H‡¨¦T iaLw  Z#Â>w[£F‡¤ãÅ¢£C&EÂI”’=ÃëIb\+¹ŒÂ`$ô¸%$‰„^‚mÛê{ &!Xˆ$‡¬`GêÿÄxµ a±:ìçþö2ØwÎýÍ¥ð½„A>V­‹¡gp«å{ öˆ›ïˆŽítòÉg^ŒÉZ—î®aðÛeˆ1Uܦ‰1U,HR¯Ÿ¾S_…¹.œ( †ä÷¦TcåÒ0I)€1a\æ ûñíé]Î8ÀüJý9>8ÉáMJÉÙ¶ý* Œœ\L~êÂu~bI†žfV iôó/I„8Ó ¨º]ìõJÖ®A-ï ’ÄÞ§ª§P°bC-é|‡ŠË%IÖô´,À0N3ÇŒ t¼d 8ÑøQœoËŘd2}ÇÆW‚^ß¿uØÐb’é‰1B/™“:a’ÕêëUê4fþ–CWÃT¯ÁôÃ$E#É”ë{ O¨ T€ P*@ÂpH¦y«K>žL[ú¦3)¦Aª`o XoEˆ3íJÏ/ZWdTrmIºâ=ÀrdÅŒ+ gú^’Èq¦ï¥‚1hMÁ¤6 5ý…Ú(Ùð„‹˜ä¡€SÅÿbLKÇRÔ+À§ïÔW! p°½½Ý¯B\Œ)úcúó]ƒüÎt¾Æq€í6I’1p4·]8©¢$èRapé8öT×J#ï’ò¸’Ã-Ù¸R0±dx -¹Ü’I,ÉvIn©€.­ B—¼ãv5 ]2ñ¦Ê0¦m»÷[ÿ<¢€a ˜^ŸÖºzh¿Ï؇¯]m >x³<—fB2=üøhõÀ$“ÕB\³Ÿ=_¯.ÄÐ~Ž‘`µá‡©8^CÃD’)ÝKA¨ T€ P*@j®€L“æ®Ò9ºäÆóxb¯ävVo˳dÄ ¿¦rI&©(\¥äó«äÌÿºÞ•âàJ>–7KÖ`T’ÏÓR8´´Ðžhö$¿¥Ü’Ïå’5À ÉΆx]*ÉæÇñ·}LU“ü§>ÿÔóßÚ»¡mr÷Ž ™üÿ9ìÇ·åöF ™Î:Ë"™-Â0 ”aj³¬g×_k4ÃD’©Ü:âñT€ P*@¨ T ' €d:þ„&ÎYå,®(^_á:aªÃ3ºÜè.‡àÌ¿hlRNª&YÅäDj²êƒ¹¡T€ P*@š €…1 Ÿf‚í ©Óºœ¬£d¤ Óá.w/pKºþÙYíÚBÑ¥âÕìž—¬ØÐAôRÑzuÃýRy½1UÙ@‰1U) NR¬Ÿ¾S\yÌz”yÄ˜Ä ’&]çVŒ;Ÿoî‰Ü~ÛtžTp×).”‚))_Yš¬R¤_%fúU*rûéÕŠ£ááá,¾¾,hÉgŽYôÞërÉË-`ŠF—ª'“Ê:C 0¦âÿ<0-}¸’¸bÂ4:¸%¬–£0·.žý؃Ã"§Ÿ|rò©g<ôè³æg& S°ÐÙFǬ¥å0LŒÝÀ[ T€ P*@¨  lÙòÆÑÇÿܬ6ÿ㉳¾ÂŽs-'0~X!'ìåÚX¨-„ºÄ"Ú“údÚóžwõˆ™1LX1" ¾ð`¥<“®$ñì/ùƪ¯VN¤V« O¨ T€ ¤^`Lƒ‡O ÊáDç0 R^c“e`ZïMEv%'FG´äá–ÜõÏ^—ÄšàÄa.e·#Ç…ÒKÖªuwÉzÅî—<Özcª¸ÑcªX:þ ¤^>}§¾ Y€`r‡1ÝÒo@12y#{ßcòKî Æ’Qrù¤°Ðo‚(EƒJ×JÕàJ!Ä’L.û’™œAª;Nõ°ö·ä‹ç÷·T’[j€Ë¥°©æ¢€UÆ„EwtGÂÚ_L#fÒ±?"öÈ~)aæ°_vâ‡a}•LyÖl'âdËyä@r>#Ã0¹Ž[ãøa"ÃÄ; T€ P*@¨  É4~V[ñ㉓BÌ!…8×õe˜°€dV.HëÇ´Ïd>[ÉJ}§¾ Y€`ò‡1õaÔxjçó=N8eŒèO&{kû+øWt2F™Eaà¼~• ×JžÑg`èâ’±á áá OK~gK:T56Êö·Ô\nÉ3z®9Æ„ÿ™L”c2Óèò·“@˜R¨$3æò&Ó‘0áŽw92z]H¦†Œ²˜6˜ŒUÎÃä.ð.t&ÃÄ[ T€ P*@¨ 5U@H¦q3WЦÀdúˆµã\×Ï“H©ôL"}Ó¹’GbŽ1#Íá­‚Àß52£'ãDjF+–Å¢T€ P*@â+`aLÃ&FØ›,ƒÔYçÛ«ß½N•<&'¿]©Ø–T -¹ö£‚µÈ]fPà–Š—µÛô’….† £—,«+vX©:z‰SüFv$1¦ê5ä¨@ZàÓwZkŽù.¡@î0¦Þ}D GøöԳΠ8 ~ N*€ðÎ$¯Lõ:¾6’R”^¶–±J*nší®aÉï`ÉÀ• £Ò7KÁž–ÀÚ—†–\îÞ¿Ön[¿ý«šcL:Q.“é’ÄëVú‚dÂ~¸_ÂNqÑ„ãñ­ydô_VH¦ûÒVáD‘s&ÇBàÖ臉7*@¨ T€ P*@j¨€Lcf¬ð>ž¯¯xv,9ÇÂQ“XrZ!–ðÏ\òl%ΖÄE®† }§µæ˜ï äcêyÇÃ?0·5Fà|UÌ!©Ï¤ž“C @”Ì®ÈÁ’+KªÖåoÆJI×õiB¤9Þu0þˆ²,X¾ÂG9I¼4Å|9$Ó xðZž]ˆÔPXèL†)¦ž<Œ P*@¨ T€ PŠ’iäÔe…ÇY_a’Û©’5÷Ä «¿[l`’+qÂ$!ääÏ3—)Q¿ùª‹œH­‹¬<) T€ P*&€1=üäs± R–¥iwXPŽèEïq9Š %¿¿¥Ü’»ŽÝö¥ÚÈDŒ©âöMŒ©béøC*zøôú*d‚ÈÆtó_úGŒñ-0¦¸ƒE@H’l·ù1“1¦Ô¸oÖrUOòŒ2ÃIù P©x *îyrŽ+… µkî©‘=Lw ¡“¹ÊYŠÜí×]u}¯Í;?ŠH;÷~òåW_52ç¼ T€ P*@¨ S@H¦S–…=žÔƒaʘ†™*'R3U,  T€ P*P‰À˜ú?1¾¤AÊ13•µèݵ(’ŠV¶»±8¹%3Zœ†n$ºd^‹S%íÌþ 1¦Š¥ã©@êàÓwê«V wÓM·÷àð-0&ÿAì‘BH®«$Ÿ·$“LŠÂ’‚=yzø$ùh»S ¡”¼ R°k¥¢xpÙó®Tîð:ÕþÓB2õ8B&O…’abÇO¨ T€ P*@¨@Ã’é™)Ký'd˜V I¹'R“RÌ T€ P*Ð4€1=ôøx½É46Á õË3Ïs÷Ø9|q9BMK^\É0!¹+Û½ëÛWH¸gI;$•kR©ëñĘ*n¬Ä˜*–Ž?¤©W€Oß©¯B€ÓÁƒ]tÆ…JùÇ7bÔxƹ±#3Ž›»m×ÜàAd œdñI%¥J)¨äC[ê:ÊLÝÉÓŽ1)ÉÔ÷áVød˜ØëS*@¨ T€ P*Ð`„dzzÒRóñ„ Sƒk!—ãDj"ª™ T€ P*@š©0¦aoŠ2HE˜\sR1®TdB²‰%?´”ð•íĘ*n¯Ä˜*–Ž?¤©W€Oß©¯B€“1ÝØ§¿íÖ(8áÛ_œqnÄ!_Y£Æ‡TÊg’Fy ˆõ2I’;Ê,kaòÊË'|è™d¶)“’Lw$&vùT€ P*@¨ T€ 4E!™ð¨%O‚d˜šR Í¿('R›_Ì T€ P*Ðd€1=ðØøØ)Ÿ™ÉG)X” C’ÇÍ’?zC’-5’7bL7YbLKÇRÔ+À§ïÔW! @ŒÉƘzôyÈC™ñí/N?7â€X’¢H!LR™TëÍõçI>©Þël`L’‰ û{*@¨ T€ P*@š¨€’Ld˜šX M¾4'R›\¼< T€ P*Ð|€1Ýÿ踘)g}{¤uÉ•|æ$›Ê@"ÆTq«%ÆT±tü!H½|úN}²Ä˜lŒé˜N¾ðâëÃÒÑ'üò_¾÷ýˆB¾ºî‹c¤?^wá¯b”:Ÿ×ý¿ü×ÿŸ¯ýÃ7FŒ›¶yçGš¶íÞŸÀåÀ'Ÿœ|ê'œtæU×÷2sëßÞ¹÷“/¿ú*E`–¨ T€ P*@¨Ȇ ™Ž8úð#Žî4tÄ„èÇ“=ï}š"³E p"• ‚ P*@¨ȽÀ˜°l¾ƒT¨™)9&•ºæä»ßûþÑÇÿ"â0á}n7ÏóÅG>Ï}[;HŒ‰m€ äW>}ç·î3^ò/_qñ,XЧøàÃL¿ûãågÿº›g'?fX˯¾ñ—§U²€«6ìH>ƄƒiHï+È0åª[ca© T€ P*@¨@2ùÂy—?ü?É0%³vêž+N¤Ö]b^€ P*@¨Hº% R—\q R¦uj@“h{gÍ97ˆ1áŸ@Œ)éÝóGê§Ÿ¾ë§-ÏÜTò…1ù¥ŽžQå·T Pdzc²š÷š‰_^ñŸÛß|3¬â臩©ý-/N¨ T€ P*@r¤ÀÂí Yñà$ìñ„~˜²Ü8‘šåÚeÙ¨ T€ P  Á¥ cBs$ÆTá’?£P€OߨD!HbL…Haõ?ñœ™T ¹Ó‡¼¤Ã—c®m7ÀT@†‰w*@¨ T€ P*@¦0¦ÇÚ:ü틯I&2L «ˆæ\ˆ©ÍÑW¥T€ P*@­@&Í%M/1&bL‰þÛ3sT Þ ðé»Þ óüMR€1&*P¶ ŘÖLÃd¥+þîËÚ=$¦&õ±¼, T€ P*@¨È©ïºq×G Px?ÉD†)ûm‚©Ù¯c– P*@¨([¦?™Ì1&bLeÿù*%øô¥ÚdY ˆ1•°drœÇB•¥@B1&Û““Æ\ûåW_)ÉD†‰Ý> T€ P*@¨ õS }ûþ¿î8¿I2‘aª_E$èÌœHMPe0+T€ P*@¨@R(Ë Áƒc*@Œ‰SRþáÌhŠ|únŠì¼hý ÆDŒ‰ ”­@1&uÅä:d:øán!™È0Õ¿#娠T€ P*@¨@®8dà!%Ë’iÇ;È0•*#p"5#ÉbP*@¨ µT &—ÃÃÊR€1¦ZþKy.*:øôº*c†ã)wŒé¯ûò“ϾˆHø[ôü6c |üéߢ …fïÿÕÀ£LWLB2¹—É„ÔÀ|ðRT€ P*@¨ T€ äK~/ôÆÔ²¢™&¿6¹um+¶l[€$Bà£l \öÆ1ù(Ÿ¥åDj>륦T€ P*@"(i*i›È˜9¦dqâÂF¦¾vÂcmvü"Õ T w ðé;wUž—çcÊK=³œÙVÀãŠÉpÈ”ír³tT€ P*@¨ T€ 4]PJÝ'wß´o¦ŽOu¨€ {c_Mø G¶µ·aC¿jzæ™z)À‰Ôz)ËóR*@¨ T€ P¯ĘØ&¨@~àÓw~ë>ã%'Æ”ñ fñr¡€ß“á) °T€ P*@¨ T€ 4I³{ˆ¿% K`˜$`•Ú÷·cC¸%NøV¾‚7&=¬IYæeë¯'Rë¯1¯@¨ T€ P*@DbLl T ¿ ðé;¿uŸñ’cÊx³xÙW Ð2e¿âYB*@¨ T€ P*@)UBV]¶x` ÄR—Ñ]ð-Þ%i˜¹D€™¨‡œH­‡ª<' T€ P*@¨R€Ûȯ|úÎoÝg¼äĘ2^Á,^¾˜Òç nWû¶å«Ô,- T€ P*@¨ ÍS@‰%ÝL’# !WLpÈ${°½ÿ¯û›—_^¹! p"µ!2ó"T€ P*@¨ T cb3 ùU€Oßù­ûŒ—œSÆ+˜ÅË—ĘòUß,- T€ P*@¨h¾ —à] èÜ,In6íÛ„p„xsÂ3d’=8F£Ë5?ëÌAýàDjý´å™© T€ P*@¨@±ĘØ"¨@~àÓw~ë>ã%'Æ”ñ fñò¥1¦|Õ7KK¨ T€ P*@š¯ %$äÃô±„=iNÞñjßߎm9’¯ì+À‰Ôì×1KH¨ T€ P*ˆ1%¥&˜*ÐxøôÝxÍyņ(@Œ©!2ó"T 1 cjŒÎ¼  T€ P*@¨ T€ D(À‰T6*@¨ T€ P*Ð(ˆ15Ji^‡ $O>}'¯N˜£š(@Œ©&2ò$T  cJF=0T€ P*@¨ T€ P\+À‰Ô\W? O¨ T€ P*ÐPˆ15Tn^Œ $J>}'ª:˜™Ú)@Œ©vZòLT é cjz0T€ P*@¨ T€ P*À‰T¶*@¨ T€ P*Ð(ˆ15Ji^‡ $O>}'¯N˜£š(@Œ©&2ò$T  cJF=0T€ P*@¨ T€ ,Ü~ÑcmœsÈkCàDj^kžå¦T€ P*@¨h¼Ę¯9¯H’¢Ÿ¾“RÌGà”båé¨@3 ÆÔLõym*@¨ T€ P*@ cÊukàDj®«Ÿ…§T€ P*@¨h¨Ę*7/F¥Ÿ¾UÌLí ÆT;-y&*Ðtˆ15½ ˜*@¨ T€ P*@lˆ1åº!p"5×ÕÏÂS*@¨ T€ 4TbL •›£‰R€O߉ªf¦v cª–<h®ŸzðÏÿv·«}Ûš›^ P*@¨ T€ P*@Œ)×m€©¹®~ž P*@¨ T ¡ cj¨Ü¼H”|úNTu03µS€Sí´ä™¨@s½„{Õ€“›› ^ P*@¨ T€ P*ˆ1åºp"5×ÕÏÂS*@¨ T€ 4TbL •›£‰R€O߉ªf¦v cª–<h®‚1!®_T€ P*@¨ T€ Pf+@Œ©Ù5ÐÔës"µ©òóâT€ P*@¨ ¹R€S®ª›…¥E ðé› "£ cÊhŲXT€ P*@¨ T€ P*@š§1¦æiŸ€+s"5•À,P*@¨ T€ äDbL9©h“ (ðÿgïO å¨ÎtM˜î¿‡ªÕ]·ïß÷ïUU]¶Ëö-nßÕUEácd—'fmflcËÌ3¶0 FƒBLˆQbš%40‰£Yh@H$el¶þ7â‹Ü¹3"r:'2OfÆsÖ^gʼnŒŒáÙ‘ybïýìï£õÍmÑ¡И:´b¹¬%°{{÷ÄýT>xs]ì_›“"-É^2WÉÐØzm©õZp TÁqÍ€ @€@SìþÓ¶{—üUªÆ´âíáM9ÒèHmzà, @€ò@)µÌ5B ­oîŒ%€ÆÔ¡Ëeu"s•teI!—$-9]i÷ön[¯ßæ3½1o¢6°5d”ëÄ›‚k‚ @€@kH ÈD(¦Öª¤&œ ©M€Ì! @€ @câF€@~ ÐúÎoÝwø•£1uxsy€ @€ ¦H ÈD(¦¦ño•Ñ‘Ú*5Áy@€ t>4¦Î¯c®åÐúæÞèPhLZ±\ @€ @ /Ä2Š©/*¡¯IGj_×LJ @È4¦üÔ5W 8ZßÜJ©C+–Ë‚ @€ ôX@&B1õE%ôõ1éHíëàø€ @ù!€Æ”ŸºæJ!'@ë›{¢C  1uhÅrY9$ð§÷¬›³gǦ^:— @€ ´‰PL-U/Í;:R›Çš#A€ äSÞï®?Ïh}ç¹ö;úÚј:ºz¹¸\À¤ÿU“†æê¢¹X@€ @  ¸€L„bjÁÚiÆ)Ñ‘Ú Ê€ @4&îä—­ïüÖ}‡_9S‡W0——#hL9ªl.€ @­N@™ÅÔê•Ô¸ó£#µqlÙ3 @€J  1qG@ ¿h}ç·î;üÊó¥1Í™3ghÅŸK/½ôg?ûYåmxµœxâ‰C† ©|!›6mj³OÿŽMSÞëã'†´Ùisº€ @€@'è~wݘ§/èÄ+ãšj @Gj Ø€ @™@cÊ#;@[ õÝ–ÕÆIW'/éä“O>èÃ/ºdˆ• ýrñ /òƒƒûçÙç‹/S¹ Y^vÁÀËÎ/SÎxÙy N–s/• Ÿë•s.ì•Aç\•³/”,g?(µœyþ¥Q9ïÒ3½rÆy—–”s/=ãÜKO/–KN?·XN;ç’Ôrê9—ål¿\|Ê٥嬋O Ë/Ë”g^–~ùÅ™£rÆÀ_xåçg ,)§üù驜œV~vÚE©å§§]ôÓÓ.üé©ñò“S/tåÿ›ÿÔÿ¸_þä” OŠ— N:å‚“~yÁ>_Ü_’SõP+m1zôè¾ù£~ðí?þ¸•΋s @€rG`çÎ_Þó;S§NÍÝÅsÁ"@G*· @€šE©Y¤9Z­ïÖ«Î(¹Ó˜†ß>jëößo‰Êî-ÛKÊÍ·:ú¸“6¿»ÛÊ[®¼ó»·ÞùÝ›®¼ý»7J˦m»\Ù¸mWPºƒ²!*mØúÑë^Y¿å#W^Ûòák›£²nó‡QyëõAù@eÊ›QYýæAy#(¯¾±3*›v®òÊÊ;Wn|ßÊ • QY¾áý ¼®òÞ²BYºþ=W–¬oÉúK^ ÊbWÖíè*–í¯¬-–Ek·/Z•…kÞ Êêw_öÊ‚Wß Ë;*/©¬ŠÊ‹«Þ ÊÊ ¼°òí¨¬xûy¯Ì_þöüåÛTæYY”¹^™³´Û•ç–t»2{I÷ì%[g/Þ:Ë+3»¶Ê–][þöï?=vÒ‚¯l™neQP¦e³ÊÔ…›Oüåí¥1Éa:òG'¨*GÜûøQG…É”É÷#; @€z@ t˜ú=þÌÜ…«ºüî!˜L=`Øöo¡#µí« € @hhLmSUœ(2'@ë;s¤ì°5äNc’¨ä,¥äÂM·S`/½£Rª.ÉaJÚKoÿ..0…öRSÁaJL‡© 0ÉdÊÀa 4¦¢Ã$™)®1…SQcªÓa*§1¥8L¡ÆTt˜V–:L+ä0UÒ˜J¦¥1‡©[S‰ÆTt˜$35¦T‡©5&s˜T³ªMÕÝí˜L­ñõÊY@€ @ ‡ä0}åkýÆ=3ÏÚ› VnÅdÊám@4¦ö¤x¸ÒK ¿¥+dŽ«{I‰äÖ«ÄRÈ¥E`ª"0Õ”H.Ê%$’+ä’‹É…ScrÉõÐaª#\˜Q®l:¹x(¦ S¥PL¯l1éAÓ˜JÓÉM ¦6J*g“ªÛiL$P@åþ»õnL¦†|i²S@€ @ •€9LãŸ§Ìæþ,‹®uÛ_X¾å[ß9˜ìr9ºsèHÍQes©€ @}L©+€ÃC  ÐúîCøº‘ò¨1ù–Ò&)Jž¥tã-Ò˜NŒç‰sÞRR»ÉdÝåê=wZ’þÔ)G69X=ø‰,‘œ~4KXÚ€…JÒJ­‘d{Ó^ÕJ[ÐÐoÛ¾0u,Û³ÖÛqmcûm“ûqbSû|Ór¦€ @èLr˜¾úµ~ONžη)›ðÚͲPóä¹®7¿QÉdµÔXжBãEñ“¬A¡v‡ ïjo·iö’š$Ú‰Z%®ybRlâ„iLjªÄÐZÇ '½Ë5U´¥­±ý¸HNÚ^'f (ý¶íÝ™ø·ˆ­l㛆ŽÔ6®Ý™tèw2—@€ ö ‡Éw˜^ šœQ¤ØBÂk›e¡É-ŠÈ;sÑý¾]“ÉÓ˜,–’~L9²æF²ñ¢ JÖ/ÚÆiL±6Ej›¥–:°´îÇeÁ¶Pµ®Md‡¶ÓpiéÜÆ–ÂÛ¢4Ù[,n-'ÐÒÛБÚÒÕÃÉA€ t4¦ŽªN.u õ].6n¹Ó˜®½éε%éÞ$$Y ¢(éÕþGŸ`Ë~Y“È秇‹,Y¤¥ 7œ•¯ÆJš´Tˆ·”ð–ÊG]Š©K–PÌ/å2ÇÅb/¥ØKa22+Šù•Õïjâ¬+šA[(ï,xõ—TVE% ¿”H!×ËLJ'—šE®$S,‹\™ L˜,‹œ4¦1øá—bË'þò‚s. ÜõŸü¥?Ú~¦(YCíƒ+ÞVª¾¹Ë¶]ÇÃU³Ë¹N|›OìkLþlãÔhLþ€u¾×®19¶æK¹pM±N|›âÌ @€ Їä0}åkýžp¹ä¼l×jœé˃¸¿Ûâ·N®ŠÉfY(“øŒ…5™LÉhLj2X°Ø 5d,’k\¤jLÚ¦7“Ó•Ôl±ltnâ‡ÉEx²H·ÚÌÚY.“µ³ÕÝ™÷a÷öÐt¤ö– ï‡ @€@­Иj%Åvè<´¾;¯N¹¢@î4¦k~{§o Å–õª4¦²ŠR‰¥TÆU2u©Œ±”*-Eñ–ÊzKïWõ–,§˜²Å¹ô[)Iô#WÈWÁ^²a‰ÛK5†_ ºªÃI·ê°ú¬­TL!×I“Œ¥¶Ó˜<‡)J,¸<Õaª8H0wé6!½nD“Éuâ«K]=éJ*§o ’LcÒ‚VÚK±hL¶¥¨_>– ¡B4&õþÛž]·¾[˧€ÆÄ?/@€ ô-¸Ã´á}×< §‡) ÅΊ æÀ¸PL…YjžL{yÓV‰ÉT5©œh$/¦1©‰¡…/rŒ¬¥c™²]§ÜÔ‹ZÚ6ãB{³=kÁ2kë|th•LNRcG§ášT¶^Û«I¥Í´ÞO¥ÆÔ··7G‡ @€@Û@cj»*ã„!4¦ÌP²£Ö"P“Ƥž8SÚýçä“OöÛ;½€I~ð¤`yØoïèÿãR)¥ÅUJæƒKË Wf)i,)I\Iž¸ ï¾âç-Mœ¹èì‹.×oriÂŒEg_x¹~Þ’§.uá+=5{ú ¯V¼¤Þä¹KÞ¸øW×/dÏ8ÿ2+W\ç˜ñ3á— öR-á—ªæ«&0=—]¦éA¦(“ ¹Ô^SÌaÒÁò׃\r×?²ì×£_ùõèEcg®vÁ›n@ªÖÕc?5S”¯Á$óñm½öö‡*Ädò;Í]ß½zám2±´R_úZp?¶Þ6Ðof°/ o¶}l¥¿gõìûÓŽíX±ïŸZ†Úý›Šó‡ @€@Ëp“K€î;LÍ\ÿëûýêþEÎxÍæÉ¨i©†ØÕ-—ðZZl–…Ò…OY°±²ÉäÚnÁÁ©Ðx‘cd ½ËotX‹CÚ³£RÛ,5¶;$EiK5d¬¥£F °dõ›TZví›bo±3±`N±æRËÞÕOŒŽÔêŒØ€ @Ù@cʆ#{@; õÝŽµÆ9{Ì:H"©®1ij &ªOͦ-¶5Õ@cºñ •äŠï]}ãGýøM¹å•å'¹ò¾:pý²B¡•¬„–’+€â—׃HK~°¥a7üÌg?oÒÒ-w=ü…/MÒ’~kYÒÒð»Þ÷K_“«¤ßÃG>ä‡\úÌ?~þÌ †¨üdÀYZ5vB,g\à¸x9ã|bÖ¿}i?—6náêw?ýŸ?ñçgž~þe*‡ÿèDýY%öR2y\©½f (~éÿ~°rœei·:¯]ñ&õh‡ekIþ¸Å[gÕ‘B..0™ÉÔcé“?¼âíáÖ|­i9LGþø„ÀnÝ!G™zÑ/Ú Á‘C¦\~ß"Uè˜ië¾uÞ„Ëî]øËßÎUqùÜ Á¬Å[gvmv[%“©iWÇ @€ 6"`Óøgç¹<×6ŲœŸ4l–Šš'ÖB9õ¦yr˜F—¶PÔH´„×|×Úz“_Úðõj1™Úˆ§ #•û€ @Í"€ÆÔ,Ò­G€ÖwëÕ gT; HšKÍdo¯¢1Y`vÛT³-(zûþHcºú†;J $ßFÚyõ #L©\ÊYJÉÐJ‘´”ЕÔÏëŠuøªÌ|iµŒ%iL–$nß/íé Æ‹¯Ê[’´¤ßOÍX¨Å[Òr——0Nê’Kg>“%{bÚË2–T —Þ?uÁOÌ9æéûâ~.ä’ä-7Ó©Kzuèuw(ì¿Êýãf¨¼(o)T—Tî{|ƣϾ8sáͦÕï/o.£rïc3œ½tÏ£ÓU¢äqË·=4ñÅ»™þä¬eê°Ö¿~á«c'¼j/…ƒÂ²8.0É¿ñÊ–][f¼•é¯l Ê¢ ¸ðK–B.Yz 1­Ûüî²î›Ç.ÿ»Q]{=²ò³Íù˜Ãd>œ Âdw‹n iLãçm´z7gÃC¦¨O¸zæMã–«¦T5‡ž2~îÆ’A‚%Á ÁÌÛÕ·b25§9  @€:€9Lãžç" [«Ö°×?²ôô›ç«•jSh4ÅâˆË¦(êRÔBYYl¡˜Ãd¡˜l–…š'ϼ°áëßúÁ„I“;× t¤r@€ @ YИšEšã@ õÐún½:áŒj$ ˜åЦdÇR6iM©««K”½Ù_®ñØ­¶™4¦«n‹äÿ©WüÑ ©Ä)¥Uòã*ù¢’ëÛuÆ’¿àÒÃÉLzø©ÙÒ˜d¨ÈUÒBoiÝŽÐRŠ~›½¬ E%+’lAýÅGüèÄß\§¼¥“~q––•'îÀï¢HK ¹¤eùIŠ·¤ß¦1…Þ’Ê;¡Æ4ã¥0gÜìEõçˆÑOˆÙç‹ûpò™*ßúÎ!2cT´æø“Ï<ì‡'ìó…ýä-zî`•ùaì¥O}æóó—o{xÒ‹²”N9gСýOPQÏõ/Ï–õ[ë‡Ý2æ¼AÃ>õ™Ïé·MÀu¥œ½T~i«o/©¿».©ј$0=·îº1KþV“•æhLÃô£ &\ä½ÙÝ!¡Æ´ÁrÉ]óÐÍuVUj¨à‘Ù냚ZhL÷L^Mt.$49^WÝ2¶Bv¹Vûür>€ @€@_¦ýú{fž›_á‚0¹æ‰²];‡IÍϰ½ùNÐB™´P4ãåðÁ“ïy¶ÐB)„b²Yš‹2ñù×÷Çdê« Îü¸t¤fŽ”B€ @  4&n ä—­ïüÖ}Û_¹ÒÁéÇ.C 2™üKªžTNј,Þé"3µ)iLWÞ0"EH ¢%ùÝ®¼^Óñ–è-–î-©%ÅÖ¤*Jneä*­ß¡ÞX1WI©â.zýâÐOÒïTiɹJÎ[ òÄ…‹^:𻇪(Uœ–rI“_/¾ü:ë;3~¦IKzé¹W6Iv¹aăZ£>åÀ[ Õ%½äŠD¥ÓλLQ—.¼ìZéJf/I]’®tÁe×jÁb/Icºç±§œ3XÆ’ì%Eý‘ƤßJ7dØË'oÉb/™´4åÅõ*Zè÷íƒãöR˜<.–?®žðKQþ¸iiá—b™jŒÆ”˜š¦1ES!jWñF ï»C”¦AåÄ«g)“ÉÝ4n…*ÔÒÉ©¾î¼ö›çN4jA,_ƒ$0&˜LmúmÆiC€ @ iä0}9p˜æÆ‚ [ÛV-5O9˰䖥™´dÞ’~/ Ê»*úSÆ’IK7Þ(JZ¸sÌÓŠÃd—LZÒf‘º´êEW²œq–-N/Ýÿø ©K¿ºöŽOýãç'>·\*Œ¼%™I®|ó;‡hÍ)н´\±—¶É^RÚ8ýV ’Ç- 4&S— oùœ¢.)Ó¨G¦…+?'{éÁ§_À¤?öRÝöR2\ ö’“™jј†Ž<ÈÀäB1 ‹£°L%+ ±šz¿ò—×ìuÐa?Œ‡ìò&K$'‡I¹äTûªk]šL¦©/¿¥<ïöŽ¿jæ¹·=¯òàô×,äÕì(\¯!Ì»W̵'“éÛßùÞŸÿò—¶ÿ¶ã @€ ¬ |üñÇûìûåÇ&Í-i¡&kÕúÍ5KÍaR E“Ú•®…rÎmÏ?0}¥“S0H'ׄ×õ›'2™¾¼ÿçßùW½oXuÞ_õß³®Þ†íŽÔ†¡eÇ€ @ˆ@câ–€@~ ÐúÎoÝw•;ÖL$-¸ÈLvaÕ5& Ť-¸ìtmJEј®¸~„g…ù¹¼¢W¥1•³‘ÊRªj)™«ä•íÒPü”pó–¼qæC¬H':ã‚!Ò•öýÒ~Sæ¯2iIË2–iiòü•æ-IK2iÉŠÞe Š´ôÌÜ•¡®¬¼cÌÓò–î7CÛ[È%S—&ÍY¡KÀ´2(êY–ºtßã3,ð’\%Kš/«‹½¤œqOÏ^þôìeEiiù6å‰S¤¥SÎ$QÉb/ÓÒnKÃïyB}Ó*˜4Ñö®‡§Yì¥s û—}¿*¥&Иoå—® Û+[üäqQ渤½äé8±Kþ¬Ecºà²s§¬9óžÅ)½çc–ýç®­CW&½|Þ׿ñÅgç,q“›]&˜,‘œ‚0=þÜëVé ©¥A%k˜¼àMåà³àX‡ ž<á…M%ƒ¢ô½Ã޾þæ‘Ýïý“©M¿Ù8m@€ 4”ÀСCO;ç×"öš'jçFÉÍ/¿o‘ò\—­ÎÃ/›2øž—Ÿ}éMµò‚ʲB ¥˜N®0Ë›”rÇØi_øê>οêÅMW5®ÍÕŽ{~bõ¾³ZÑYÔ,i²/@€ T"€ÆÄýü õߺï„+W@%» å…“Éä_Rõ.0 PŠÃd1™œÒÔ¦TéºÛS¬£B´$½zø/Ù 6É‚'¹øI 3©’¥dÞI¬¸|p&*¹ÄU E¥3οìˆøÀø™ú­euŸ®Q†8ýÖr¡ƒ8°Xô®Óϻ̊Œ¥N>Ó¤¥ëoP“ÃiYÒ’ÖkYQ—$'Ic2i)(+Þ–tïc3,[œ%Œ»`ðµR—öùÂW¯½uÌ݉᮹uÌS³– ·Œv˽E“òÇit¥cz†â-I]ÒKZ#uéêáÚæsãg,=ø¨ãùé#šzî¥Ã´,{é>ó¹+ohL¥ö’¯.qƒ¬,ŠÊ´0Œ•Ú¥¥ä–µhLç\8xý–V½µ>)3=²ò³þlÚ´éÀ|æ¹%Þ-W˜Â@\ïqÙ” F¼ YΖ¦AƒªÊ[6àÆ¹ÎxíŠ1]Ç]9# Åêb–N.Åä ˜Ã¤+UÁdjtµ²@€ ´)™L§ž}IJó$œb´aW-”®žyÓ¸åÊ%§Ê7Ï› T×7X ezÔB‰GŠ- Å$‡i¿ý¿±xõfk¡ìþÃ'mŠ«§=÷“ј–}B€ @ Ý  1µ{ rþè94¦ž³ã}L@¹ä$ IC’ŒË(§3«®1éý²ŸôÓî“®VÓÐko¯` éÕÃx\*É/kK"'¥:Iµ[J¦+¹dpf,Y>8+æ'Y¹âú;e, ¼ü:‰JV†^wçá?:ñ¢Ë¯UŒ¥(=Ü«Á<×Óλ̕£Ÿ¶ù‹>˜»ÿ´mé¶k+B‡Í–ÕÐ/ÿôIDATGØL¦ 3Û LÎar#æ0F ƒ–K.ŒÃ8LʼnÎå&L¦¬*Žý@€ @ # ÈdúåY{ÍoŠ…Mªñ¦XTq˜ ¹Â+8L©&Óĵ×íXבx+\SÞjœë… @€@ИjÅfè@hLX©\R@ wÓ¯†Ý–ŒäÖèÕCûWaƒØKiZR”ýÍ÷“Šá”ÊXJ.¬NZh¥”èJUt¥(ÌR¥HKµHK Sê-ã-Õê-É¡iuÉ÷™zÉ4¦ª?]Ý]ýîïWu³Ú7É´ÿß|jÆb‹ÀÝ-%#i“4²R‡É™a•&'xïÃ?Ô~†l @€ ä‡ÀàË~5àÌ‹£v®Åˆ-Dv‰äâab“q˜jv˜Ô<™·üí?ÿ¥ØÛû¶½óCÛ])S+K† @€@-Иj¡Ä6èLhLY¯\Uþ4¦Ë‡ÝVÆ= ¢"]>ìÖC:.f •’ÊOª”ú­ÐÉk àÂÞÞ2¢RakjJ¸BïpIb¸ÔÜp)ÆRt,ž!.UZÊÒ[R@ EQQX i‹6GeáæÌƒ-UÝaã4&Í –ä^õ±ËÇŽX4B¥ÿcýµ¬ßö}£yÃZi Zi¯Vý*zýõ2™ž˜ÞU!°)Î~"9ËÔšg–ÑÏâ0©À œkq˜ºßû½?HPõôØ€ @ÈK]þ‹3Æ&—ç:&¶Ûš'Å\rõ8L Voßý‡O^µ¡Ôà0q€_g Ô‚‹ÏÔ½«[ËZПÖàÒ6Q5hLQ\ @€2'€Æ”9Rv¶!€ÆÔ6UʼnÖG wј†\}kjÖ6[©W¥1U—LEŠ•‚–T]N’Ÿd%4Q*”@RI„VŠ»Ja*±ô¬p^Š1 .±’Œ´T]ZJÉW>ÞR+yK1±©q“>ê4—¢¤ë4W7º¹MöÑTº¼¥9›æhÍ®?îRÑ‚¶©úÁ5“iüôWì†qSr„Àw˜,—œŒ1#€ÃT•3@€ @µL¦3ºV­ª.Ïõ\ŠÅ’hŠE&“NLí)3“4?D)µ­Ôªrñ™ô§iLzIr­VËÔ‘Z.¹o·Acê[þ€ @-K©e«†ƒ@à  151èyÔ˜\$Ï7²Hï\võ­‡ylä9Ù¨®…jf’“–J¥b8ëü­à*¥GW*`) Ï“È —4–Ì}‰—`¾l¬Ä“Ä)Ø\™¨¤Æ[*84Uƒ$5mƒ†jLNKROºùI®ŸÝ:ÓmZ°úÜÕ«®¢^uë^¯úc&Ó¸©¯D·G¨©Í]êa Gz“KŽ8LUk @€ # “éçg L LA;T1bý0±Ê6NtqS,î;m¿ý¿±xõfËjZbq˜ì NKr¡mÕìòçXX\kg©¨96lþ°¨24¦¨D.€ @ €ÆÔªìíA©=ꉳ¬›@î4¦Ë®ºµBô#½zð‘ÇVŽT)Å[Ið¤xº·²~’Â)y•ÊZJC+Õ +©y«\%+)ÆRä¿ÇÒR牫Kj¨Ædó€ýžtú¯½ªßêI·¢™Äš=\ãg×L¦Ç§,rSr„ šåL.¹™² @€ ÐS2™N>ý¢ yF`*æ¹.b‘•äӴ™!¶`g-QÉ"0ÙJ©Kú­v–kp)DSO¯¯…Þ‡ÆÔB•Á©@€ @ • 1µRmp.h.4¦æòæhM#;ið•·Î_n‚Q¬_y‹4&çU^ܣʥë­rÒ7ëðõ»}“ àÜšÔLpšçêEWª®+ÍJ‰±TÈ ΑõK™HKž´ÔzÁ–ª*MÓ˜¬Ç\`—ËÀõ¤kAÝèöªå>Ђ۾öϼ™LN^X˜ü‚Ä,grÉÕΖ-!@€ z ÈdúÙiyS·Ës]2Å¢Ðrìq&;1—?ÎiL¦+Y+Ì^5‡I –Å»öy#õ^{3·Gcj&mŽ@€ 6"€ÆÔF•Å©B chLew­B wÓ +oqRQrA¯|ıå6ð}£:–à ©µ”@QJËþf–R9Q©\h¥ ÞR])èJNèJ%¹áÂhÿV¦Ee³‚ÿeáæª’PëoÐ8IÓ‚Õoni ôÛ>èêCW×¹%’³Îô‰k'j3­±¹Âõ~˜Éôð³ aËe‘s#~¦¦zÙ²= @€ P/3™ü,rÊNnÓc¬yâ’½t˜tbjIYÂ8IÍ+×àR#KÛXp\kp¹vY½ÕjÛ£1µZp>€ @hhL-Rœú€S@çÍ G)n -íž[(ƒ~3ü #Ž­E9ªe›HKªh&%ü$ÅR* §T!\yQÉÃ…®RͺRÁX*èJ$-%µªÆiLÍøÔ†Ç0“é¡g^Žê:m„‡©iÕÁ @€ s2™~zê…aód«µCÙ7œSœ Ó{‡)Ïјò\û\; @€*@câö€@~  1å·î;üÊs§1]ò›áE»È¢yå’+ÉE?êñB¨"ÅÊV’bÅBé”-éá”ÌR D¥rq•â¡•¼èJ)–:%ÆRíQ :@cr&ÓØI RGp˜:ü˛˃ @€@‹Éô“S/ŒZ£¥A˜Ô<Áaêeu¡1õ o‡ @€@§@cêÔšåº PSuFlÑ–ò§1]1<Í1Šb IcúÁÇ(QW±¤¹Gõ©HIK©«\º7ç'yŠRZ8¥(88½µX iàhLõñbë¶!/éôÓOÿôgÿiŸ/í_®|ö¿þ?ÿåÿúÛ ¤¿ôÅý÷¡´¿þëÿíÿý×/W¨5yNC®¸ný–üòŸü¥•?Ù2™þë?ýÓõ7ŒvìÏî÷~ÿç¿´ô…´2dÎ € @¨‘À%?þÖ¾ÿ÷ß,^½¹B eÁêí»ÿðI;ÌùfhL9¿¸|@€ ”#€ÆÄ½ü@cÊoÝwø•çKcÚ¹sçœÒŸ‡ÆOŽ•Ñ<\Éš#PK-'»Ú[\cÒwÕÄ•G­zkq…A¦ÿFçò @€ Ð:ÆœÜ}Êÿ‰Ã”U… 1eE’ý@€ @ Ã 1uX…r9¨ƒS°Ø´äKcJÖLå¸5¼ 6ŠÆ´c÷ÒQ]{M}íG[¶ÿ>µâp˜Úé»™s… @€@»sòžS÷zïÃ?¤6OˆÃToõ¢1ÕKŒí!@€ hL9©h.)И¸-:”SIÖ0¬T Ðâј¦¿~”4&•·?Zš4™p˜:ô;œË‚ @€@«˜vݞߨ“KšL8L=¨34¦@ã-€ @È4¦<Ô2×thLÜJ µheÉB1Y‘ϤSõM&¦ýç² @€ ÐÇ>xsÝöÕ]É“Ðz¥o2á0õ¬ÎИzÆwA€ @ ã  1u|s(K‰›£C  1Õª°¦­¬1¹PLf2Éjr&S‡~{sY€ @èc«1q@¿yWHžÇcý÷Ž­4“ ‡©Çu†ÆÔct¼€ @M©³ë—«ƒ@%hLÜJ ï“ ­©PÖ¼õá†î]•·áÕv'ðÖ»»WlÜYù*¶nßýç¿ü¥5¿üPL. “NU&Ó»;ÿв§Ýš09+@€ @ FÓößÚ5'¹±B1IoJ®ÿ£?îþÃ'5îœÍbИ¸% @€ ThLÜÈ/4¦üÖ}‡_yÞ5¦¯^./b¡˜\@¦|\=W @€ ôaõ¥½d2IZÒo©K n¨SymòX Ѥ?µRE¯êO¥Ÿ³eýŽeëƒ h·C¢1µ[q¾€ @h4¦&æ0hAhL-X)œRИ² È> Ðw’¡˜ü€L}w^€ @èd»·w[È¥%÷ “·d—j¹äd/)ßœýù§Ý»´ «ÉB4ÉdÒŸŠádb?µ@cª[B€ @ WИrUÝ\,J 1qCt(4¦­X.+7RC1)7õÏ…B€ @ o8I~’L&‰J2“LcrÁ–,“^ÕJm¯Wµl%5ë\ß\I›©M*ŠÓ„ @€@³  15›8ǃ@ë@cjºàL2%€Æ”)NvæøäÏwmj奷Γ½¤§U·æ­¦6÷t8 @€ R‘rI1™$'½1o¢.[¿-Æ’ÉL–6N˜ádª“¢1©hK ËÄOíИjgÅ–€ @È4¦\U7 hLÜJ©C+–ËÊþ¸I“¦ü]:W @€ 4›€eˆS±¸JJg—,yœÖH]²Ôr’–,>“~k3ËF‡ÆTo…¡1ÕKŒí!@€ hL9©h.)И¸-:”S‡V,—•?hLù«s®€ @}FÀ/éG™ã´¬HKŸIÒ’e‘“·¤õV,2“ÖÛŸ½‰Ÿº 1Õ…‹!@€ hLù©k®qhLÜJ©C+–ËÊ4¦üÕ9W @€ ä…S^jšë„ @€@ИêÆæè hLT™\ŠO‰ûB©C*’Ë€ @€ €ÆÄM@€ ¤@câÆ€@~  1å·î;üÊј:¼‚¹¼ü@cÊO]s¥€ @€@Þ 1å­Æ¹^@€ ÔH©FPl$€ÆÔ•Ê%И¸ Ð!И:¤"¹ @€ teöV$€ @€Z—S¦uƒÆ”)Nv@€ Î!€ÆÔ9uÉ•@ ^hLõcû6!€ÆÔ&ÅiBÀ#Ðïþ~]Ý]  @€ кИ2­4¦Lq²3@€ t4¦Î©K®õ@cª—Û· 4¦6©(N&Øëнú?Ö_&“–¥4é÷°ùÃF,a›ì}ÛÞú­pMzI›é7ð @€ 4›S¦Äј2ÅÉÎ @€ Ð9И:§.¹ÔK©^blß&Иڤ¢8M¬Û±ÎÌ$©KZØõÇ]Zvñ™ºwukÙ~Û;|à Š€ @€šD)SÐhL™âdg€ @èhLS—\ ê%€ÆT/1¶ohLmRQœ& uiàŒúK¢ÒœMslµE`Ò‚0)8“6P& L*ZÖoøA€ @h*{ŽÛ£Þ4~2"ÐÓÔk÷LUýUûÿ\ôhFØ  @€ '€ÆÄ=ü@cÊoÝwø•Ó¥ØáÌåuYJr•t]N]rñ™´R¯Ês’á¤m”uNE ±‰@€ @Í#0ø³{~ýß›w¸N?RhLŸˆk©eéÓ^?\ @€úŒSŸ¡çÀèshL}^œ@c 15†+{…@ÃXþ8?mœþ´r Î$·IV“L&ùL¶Æe—kرc@€ @ Ò˜n:.YhéÃm{Îú«Ia™ø @€F©ahÙ1ZžSËW'Ø3hL=ãÆ» Ðg,aœ\%?UœÖ¨8{I''ÉVjË>;W @€ ä–S¦Uß“®75 ¡˜2½Ø @€bИ¸% _hLù­û¿r4¦¯`.€ @€ ÐИ2…ÞS2 ¡˜2½ Ø @€’И¸+ _hLù­û¿r4¦¯`.€ @€ ÐИ2…Þ“.9‰PL™Þì € @IhLÜÈ/4¦üÖ}‡_9S‡W0—@€ @èhL™BoÉÈD(¦Lïv@€ ThLÜÈ/4¦üÖ}‡_9S‡W0——»ÿcÛ3ë\·ct~.™+… @€Z—S¦uÓ6“®Úd"S¦÷;ƒ @€@*4&n ä—S~ë¾Ã¯©Ã+˜ËËþ¸iT×^][‡æç’¹R@€ @ u  1eZ7í¤1Y@&B1ez°3@€ ”#€ÆÄ½ü@cÊoÝwø•£1uxsyù!€Æ”ŸºæJ!@€ ÐИ2­¤vÒ˜tá ÈD(¦Lov@€ rИ¸7 _hLù­û¿ò|iLC‡Ý‹ÔIàù_þ×5kÖ´þ7Á;;ÞØgß/|ä´Ö?U΀ @è|hL™Öq{iL'ŸtÂèÑ£3ÀÎ @€ thLÜÈ/4¦üÖ}‡_y¾4¦“O>yøí£¶îø}IÙþû-QÙ}óí£Ž9î¤-Ûwo~·XÞzwwPÞQùÊ›®¼ý»7¼²éíßmÚ¶ËÊF+ÝAÙ•6lýèu¯¬ßúÑú-QymˇAÙ”u®¼õáÚ¨|°ö­Ö¼Y,«ßü (oåÕ7vFeÓÎU^Y¹qçÊï[Y¡²!*Ë7¼•×ß[æ•¥ëßseÉúK^‹Êâ×ve]Pº¢²ý•µÅ²híöEk¢²pÍö…kÞ Êêw_öÊ‚Wß Ë;*/©¬ŠÊ‹«Þ ÊÊ ¼°òí¨¬xûy¯Ì_ñöüåÛTæ¹²lÛ\¯ÌYÚíÊsK»Ÿ[•ÙKºƒ²x«Ê,Wº¶Î,–-c'-øÛ¿ÿôŒW¶¨L·²((Ó‚²YeêÂÍû|qÿ9sæ´ø7ÁÎ;¿¼_¿ÇOÿö÷™:uj‹Ÿ-§@€ t>4¦Lë¸4&õ½\yýˆ#~x<&S¦·;ƒ @€@:4&î ä—S~ë¾Ã¯ö¤0ÒR<ØRª·äE]JW—zf/¥D`zÓ"0}𪠴©·A˜ÌzqEñÞ{ŸK®Wq˜êv˜êK'7«k«Ë(§8Lr˜’Ó´E[²ÙÒÉYÙç‹ûOš<ã½ÿàÊïÿðI+|1˜Ã4þÙy+6¼¿üõHcZüZ:K=Å/,“Étð¤g&·Â©r€ @€@î 1eZå-®1Éaºú†;‚ÆiAcrÓEk“é¾ûîÏ”;ƒ @€"hLÜ È/4¦üÖ}‡_yî4¦o¹+QÉÿS¯þøØ7*º’+Ý»ä*¹²¡[º’•,ä’Š\%¿¬/ ¼eŽSþ¸ÍQY·ùè¼õáÚ¨¤ä[#u©`/ŦUug‘“æòž¼%WªL‰ L]k‹¹ä­Ý”5AY”wƒ²:(/»òê» ¢ò΂WßyIeUT^\õNPVå…•o»òüŠ·]™¿B‰ä‚\rÅtr˶Í[¶m®+K{î0Í,8L%Ó¢-Ó=‡iZÁa2é¡ñ“ý`Zºgúü‹Á¦'&Ï_& t¡˜Â €Ae©Ræ/ÝüÍï5mÑf•T‡©¥’Ê¥8L~7qi(&7ÛUÝIJÄf-zãß>h¤ɵ|WX¥ueZ?oì]®CÓúUõªõçZ±›„j›9ÉY2fähÏþ,Xmæzrõ.ëfõ«>VS…R5&¿Õú¸M2wÇâ0Ù!Ü,FQ…ƒV>ØôãkL®ÛÚÎÁQ#OwJæŠé¬Ûzí“§”ª1¹s‹u=k}lÿFØj¹7Ø€ @µ@cª•TMÛµšÆTâ0ùéäÖ¿W'8Lwô¬ ’ËS˜–×d2¹–Žßäq¤ÊiL®]c-Jÿ½z‹YDÖ@³¬íÐ#ßêÔö§köº $î]î¸H)Y£¦i?. ¯Ó˜\£Lkü¶9?6-Ç®%Ö¾K¾¤f£VÆ®Ô<-ÛÉ5Òmc¥Ø³9LÉ~€šnS6‚ @è hL}AcB 5 1µF=p™ÈÆtíÍw¦kIaê·ko 4&-”FTŠ[JciM])ÍX* ¶TFZ âë”&Œ ÂíXÙ• ƒ˜+ÕÕ¥÷z`/U¿Ô{©îLõg‘+˜¶¦a’ÀF`*hLiA˜œÕÔ"јü\rvcèN°\KünâµA¾¿°›ø] ÅTè)Þ6cáýj3™\ߨÅRgÌqñ5&ëÜLjLNJÕ˜,,ë0µ·ûF‘uຯ<; '¹®g{£‹½dÛ[Ÿ²¥rs¯J²xûNcÒ²u1»^æØA+Ÿ¡ËUg-§1Ùz;D-<-î”ýXG³MÀ5¥,yJõjLÉýëº:©3ÿÿÊ!@€@Þ  1ez´”Æ”t˜lnUÐ> Ök–T<SQc rÇtD•ìrIÉkVÕ˜¬qÓ˜¬B¬µå+A¶Æ×˜Re#¿ÙkÍdýXcÊ5™]ÐNU»M¦h÷Û¡î4ìþ®ìlµ;–ü½¥¾ä·ß]SÔšÆÖ¨´ íÜR–;¹ÊVºÀ™Þ¿ì € @ И—]C Å  1µxqz=%?é¦;]¢·äÂ57ÝÙÿèRc)ÅVF¡•,ÆÒ~ñrÃYž¸0ÌR2Ò’E]ŠÅ[JzK˜ÖSï0Z6ºäþ{ú¿ƒ÷A€ @ 4¦j„êz½u4¦Àaº±K.½qº#Ö8æØ„¡˜¬qªÆ~e“)©1ù¸\67­´E¾×éDU5&méhÚ›ZL¾¾ãÅ6#Åþ´ý[KÓNFµÐ¹nM2“Äu'ov]³1¦1ù»Òé™n¥ ´·ûû±³Š½d F×î³£h?&?(-XcV+¿ó®êºKÙ€ @ O 1õ v – €ÆÔÕÀIdO wÓ°ßÞYb ¹\oá‚^•Æ”0“*ZJæ*•°éJiÆRi)ðTR¼%›àXš0®’ºK×µ¶ræ¸ –eŽ‹Å^z9™<. _%\4Þ•ùa¯åüåÛ¬¨û2(Ë‚¢~LW|{IËÏ-)–¬&Ë"7¦4&ç0…Ò[—+Ía*t— ÅdÝÄRÁ¦¾¼é€«d—³žMs’Ô¿©ß&è¸×Óê¢ø¨?×zB-¨¾ýX€Û‰ÛÀú^­ûU½«¶¥S‚lþŒÅ²©±¶ÞwƒÜnMÓ±W]'ó~t ê!ìŠÊ4y†4& ÈËRgWa徭§Ã嘫[Ù]—u1'¡9à.o‚»XëgwÐ’û7DcÊþ¿+{„ @@cÊôhIÓÕÎaJ6N]®óXœàÒPLs—íSµîpø1#Gݛʩ²ÆäÚ_¹ÖæÃÔ¥1Yê4µÔ¬…¥·›Bdk*hLÖ(³¦Ÿk~º5j[Åd#×Ôzkšùâ˜ÆÛ¹NÉšØvVnÚ‹½dL\*: ¬k,kÁµ‹uÚ•¶´†§]ˆ«½„É”ég—A€ †@cj8b–%€ÆÔ²UÉõŽ@IÝ.Óõ¹Ô½;nß¼ÛžGÖ‘Ó¼½zÔO(nP¤T!œ’YJ•]¥ïüà°(7ÜÆ÷/»â†ï|ÿ0ý¶ç¢Ë­ ¾â‹¯cåß¿hÿ£O²e“–´fÐÐ,‰XP¼KÓ_|ÕB.}û{‡Ê[ª¬.¹ÀKGüèÄ'¦¾Äï Õ¥ñSøÝCætmR,+úS¹É åøyÉJ{éÔsöÃ,“Ô%-?òÌ‹*Zð¦È^J LaW¦+~ø%™L¡À´µß·îe&˜¬ôVcÚ½sϺ9 ½›ÍaÿìüHzÛðþO®™}àùTŽº|êIÃf=ûò[ ²eu:ý•Í'^=3H'†b:ïö¾yî„ÃO~pÆk‘Ɔ°šüÒÆ¯W3™zyQnJh/÷ÃÛ!@€ v%€Æ”iÍ5NcšûF·êùšÃä§gÜ2ÿ†G—¹\r×=²ôÚ‡—ZãT= 7_ñôóoXœà'çoüåoç¸qýÆ©"+¿¼ÉädšrV †äÎÜ-»6©[ãz·LôÑ[,€“[ïÖh½ _d[ºmü½iž‰…ε·«Ôæ°^Õ©&ÏÁ?º{£íÊíÜÂ&¥Bð_ÒÛÝ[´`—YîJý¾>ÿt!8LU?l@€ZS«Õçæ@cjkŽ”1?ñ‘‹“â‚•TÒ˜ä0íµ×^®;ÃÅVÑÄ,÷þŒO¶Á»s³}÷È_Vœ4¦Ø«+‹”,Üû©Å‰JÁB¨(Y9ù”³?óÙÿj‰áä*õ?æ¤G'>'?IËêì{dÂs_øò×ξèriL~¤¥Ï|öó*&0IZzzÆBUÇY1{©˜*NËë{ÉÆ}æ?¯lqé ãÂŒc®¨Wñß¾´ßOÌt—ÆŒŸ©CÈmr—>ýŸWŸcd/yêÒiç]vÿ¸ꋌeŽÛç‹û}ê3ŸŸ0{¹…_Úç ûÝóØŒ{±Ï¾ZŒ½TKø%/“~I Î?|æsQ ¹®­åRÈM/“BΘz«1I`š4tÏùÿyϘ“wÛ¦yvS…A˜Þ—½ôÔüMÁ]ñÚuËd²n⦯;â²)*ÖMüÛÇ—«›XöØØ¯6x²…bLÑ·g_ÜðõoU‰ÉÔ¸ëbÏ€ @€@ç@cÊ´Ž§1êÚëžÅÿSU™)èQ¹aD¬q:tô+Ö8Uůî_¤¢Æ©ºîšôê·Î›ðèìõ–Nîð˦ÜþôªÛŸZ©Æ© ÅdS¥€ÿþaec2eŠA€ @ 3  1uf½rU¨…S-”ئÅhò•& ÚâXÛ\,-Ø­²“f‰YXiÓ˜,¶¶] ¦»Å.¹ÊéX§[9Iëõê‘?>Á6(Ñ’ìOONŠ-›¥/¯¿wßÓBI6’U’±4ë¥Õ¶lŠÒÙ^n–\‰"-­ß¡ Ž:ú¤«oi‚?p–\%iLlé’__æCnùÔ¥Qc'È^ÒŸÒY$Ýõà-_ò«ë¬÷pÊüUgœ?DeüÔ—]Ô¥3οìâ˯û·/î'uÉÅ^=n¦Ö¨Ü0âAS—´7 ¼4ôº;¤.]8äZù1³nüÖw9þä3g.Ü`—^¥¥Ûî{ê›ß9D™N9w°Å^’½tÏ£Óï~tú¿~á«–<îüÁ×üòìAÃn£ù—úýäÌ¥Òkž˜¹ô¼AÃ̳9wÐ0^?c逳©<ðôóR—T®¼yô/κtÐU·Icòí¥™][f¨¼•²S!ü’‹ÃÔciÃë›w>28˜ô¡‘ÿÌa÷Ì<'0Ù#éÉù›mÝŽñó69dŠU´â0i¶«4&ë&>þª™÷N^Øc˶©§X’SÑʺ‰»¶Ô¤^ßÿ[?˜0ir{}Š9[@€ @ = 1eZO Õ˜d2U–™Ôr•¦Âì×8ýõèW¬ËB]r˜.—Æ´fû5c—¨}ªÆé#³×«áÆÇ—slÂÆé9·=ÅèW¬qjLA[~Ú¢-ß;ìèrÙå2¥ÈÎ @€ ÐИ:°R¹$ÔH ‘CÕ5ž›A ^5ÉiL“_Év"CI?Z¨’TÎiL¾ºÔÖ“õ»%‹HWJcúÑ éN’³”^WDœ÷\q9à’ /­xKÞÒ‹ËßrA•Ü‚¤%-ËXúö÷•œ¤å}¿ôµ‡Ÿší‡YÒJYJ–$N‚Ú@&“ü$EZÚ÷KûÉRzðÉY~ïÐ+o¸sÞ’7´FJg‘x¤pJ>1ëÀïzñ¯®›<¥B.ýöŽUôÒ¸) ž·R 7ÞñàÀ˯Sì%©K.gÜèq3ä0=öìKÚ`ö¢²a´ >ÇN>SYáî|†~[Î89L¿ºv„…\rEÓ­÷=õôìe.ö’ì%9Lw?hLò–ôû¼ÁרŸò–TŽýé²—ŽùéŸúÌçÌ^ú×}¿:nÆR¹JWÝ<ú滟ø—}¿:æ©çe/iáαS>òx§1ùö’ú=#iÑ–é‹‚>P^²ó–z£1I`zïáÁ>÷ÿˆ¦FjLr˜¾¼_à0)ü’K5h®Û‘C¦^tç‹¿ç¹Êaºë™Õ&ÔTWõ«ÊTG‡ž2vÆzÙc"/iÌ´uJÉçf»†”6O|“©ÞïU¶‡ @€j#€ÆT§·j‚ÆTNf’äޒ0Q“Št%“–T~sÃZÖdGIKú½pM 1YÈ¥‘cž>ñçgž~þe*oéŠëï”átúy—©„êÒ;ßúî!Ê §¨KrIËÒ˜$Á(ð’t%EôÑÞÔçø©ð·å‰SÎ8…\º÷±˜‚¨Kaà%M¬T:¹ äÒò@WºõÞ'ÕqhLD“ÙK’–,ü’–Çë÷¾_•½¤ßý¾}ðȇ§ ¾ú¶g]ªrðQÇßùÐT-ó“ÓÍa² LÒ˜\ì¥4{© 0• ¿Ô3iÜ#ãR&Ó˜®Ú7È.—iÙùè¥_Þï€ÇŸ™ëwaºÂI®ê)¾åÉ•ãçmxpÆk§Þ4ïˆ!SÌaRªX±úUMªiLÚ@ÝÄ.iô´uE‡)˜í ^˜LmÿÏ@€ @ 5  1eZ/¦1i|"óböR¬¸4sÃTèH)†‘.4N¥1™Ã¤8L'^-i¡5NÕàÆéóÖ+xó @cZ Æ©ÒÉÓ] ü8Áš†äÚéÉô«s³m_³7T"°nN¦Sv@€ú†Sßpç¨hhL­P œC 1±©÷í7ר` éÕ#~x|… ßÞ“œ”PNJ-’“$*)œŠ-HQ2QÉ\¥ÐOrÒÒv‹±$3I‰á¬H!ÒoÙKr•NúÅYOL{ÙrÃ)Ò’^ÒÆ ³¤ràw‘´ü]½dÒ’²ÅÉI’¨fˆ º-Ø’%ó–´ uIÞ’-ï#ieËG Š·$éÑg_”ºäB.iùžÇf(mÜ=κ„…‹²ÅIcúÆ¿¬"EI¿-üÒ¨G¦©Xø%Å^RÚ8yK*~I~ÒO¿ ‡éÜK‡É^Ò‚b/)yœ\%½dE˜ôûޱSÌ^:àÀƒŠöR8q³®ðK=ИøÊWÞº|ÿ’L&05¬Œì·×ÿ¹Ý‡f/EaºÂF˜ÆÍÝ`‰äTõšáúØs¯IW½c“ée‡žüàô×ÔMhLƒ&žºÖEìˆyš×ðû&îûůìþÃ'=ú†áM€ @€Ò 1ez_,Ü2(Õ7jèÊkü7ͱñí%C:lœN•À¤Ž kœÊarßBs˜ÔÃhL3׫}*‡iШ@cRãTÓ%w½‹ìÚéOÌzõþÓÿ²ùçÓ¸æ6{†@ }Mñ@€ÚŸSû×!Wž@cê)9Þ×ç²Ñ˜tÚÑ®]»´ PNJP×çÖƒÆtÅu·Wpôª4¦ØŠS¥„f’+NNûÔl+2–Æ>5ËD¥§¦½¬>¾©Ï¯Ò²”N)á´ ß27%ìT þ\³ý‰©/+Ò’t%õ žqþe*ã§,dÒ’2Ä)7œ¤1Ù”G½Ë—–x鄟Ÿiñ–$-)=ÜEC®Õoó–¾õC”*μ%•û4&‹åóÈ3/JKRѲ~OyCr)X–ºtÊ9ƒ”-.˜–ÅŒ¥±_ ¦W3,KÉB.9鮇§Yì%˧ù—xIÞÒ¸éKMZR¼¥s.vôONc/m¹qÔøï/ué77ÝoöÒ?|úsžºTkò¸r©åÆLXð·ÿ©Ê‰çöùâþŸ¼åÅÉ¿¿æ)ý}·´G³÷üòá¶Üœ±· :ôÔs.‰n¼‚ú¦[(0Û¤1ÍÙ`1·$0}ë¼ S¾eÝÄšêª LÆ´|ÛoÆtsÛóê&žúòæCMN Ť ¿cì´ýöÿÆâÕ›×où“©÷Ç @€ ˆSÖ·ÂÔו´´âíáÙ–Tê±Uÿ´íwÏë F­~’b¯H4+jœ*“9Lê‘Ã4äÞ…Ö8µDçÍ\¯Æé=Ï®9îÊjœª7àç7Ì9iµÚûÖÀ÷ÁËaRãtÒ„Éë_šóÑŠÒVv¬ÑÍŸÈ„€¢k£1eý5Åþ @èhL}‚ƒB % 1µD5p=!à4¦uëÖõë×ÏvÑ¿ý©…½*ïRÛuuuÙ6cÇŽÕûí§''Òï 4¦ko÷•£Ø²^=ü‡Ç{A’Š)ÞÒV!”Š¥EÉ…SŠÅUÒŸ¿½s¬ì¥3.¢ß¿½c¬:ûf)Xsþ‰JJúfnŠ• =ÜêwU´ ôpêtâ”îð0=œ|¦¡×ÝiéáÿÑ ³_Ù¨ý q³m”™$oIE/Mzn…¤%­9þä3U´ uɼ%å‰s—Îç”s;iiŸ/|Uê’b,÷³3ä-rö )J·Üû¤yK˜ä-YÂ8+‡(ÜOÏ·${ɦÙKºlIÒ’Ô%éJWÞéôŸŸlyß“óU´pò—tÄñÒ˜s^}A©-s\K©vI–JŠÌ4æäÝÚÉtö%áè2ÅMú¥.YQ(¦›Æ-wÝÄê#>þª™Aˆ¬°^ÔS¬8Lr˜®yxIj7±ï0Ùb25¨6Ù- @€rG)ë*·¼rYïuOLcr“;L¦BWIÐb}jŸjŽ"0¹,çr˜.»w¡9LÊ%'iìŒ×¬qªDçgßú¼ŠÚ§Aã´+ˆµì§“‹¦é/XËTå£ÝÊüJÙ!JÜt · @A©3ê‘«€@O 1õ„ïi NcÒÙ 8Ð4¤ØÉÕÝÿÕÝÝÝ—Õ£“Æ4ôÚÛ“š‘[£Wë\… ’/Eñ“,ŠR!’…SrEiàÓƒŠ“ç¯”®4~ê‚ÀU -%EWÒšqSX28W”Î,=>yXzî•*’–T”îú>3g…IK*–ÎO÷س/Y¤%¹J¦+Y1cIñ–f¼¼Áe‹“·¤`KOzÑRÅY¶8r顉/ÞýÈôb¼¥eÛôç”×›´¤…±^p ã4Ãrò ë|ú%Œ“½¤¨K<õ¼~Ë[ºó¡©*н4+¶s˜xéþ§æ[Ú8+#œ¢8Lši±—™²äö§<2eñ}OÌë½½äĦz5&ëNݶ`ÊõvYR¹†iLºÇe2röÅîÖŠ·ð& o‰ ÞƒÀZa-[.9ç0ÙT×§žßÅa*t;zI‡ “©Gß+¼ € @H#€Æ”õ}Ñh))0¹+Éd½%®ßCíÓ‰/¼!KÉú+zŽ¢//îv¥ÆÏÝhSÐ8]Ú}פÕ*%¹Îm¶¶yÒaÂdÊúÞaiИ¸/ @èhLR“\ê'Ðà¡êúOˆw@ ukLÙ¶ö"é××ÜsŒü?õª:æ*là^rZ’?©¸úI®Äü¤ØŸÖåç•ÀR²$ƒ³Rp•lÁRÂËÊ@dq¹áœ®ä¤%ç*Ť¥0O\QZ ’ÄòÄYocIYt>ÆŠ¯.I𠤥 l•´dE}”ÅRP—L`’ºdS0] ¤%+¡ºTŒº”Eà¥Ô˜L=Ó˜6m ²+‰äÔç•Иvoï^rß°U§$^L]YùÓ “é—g]lÒ›Ý9‘ÀTp˜\-[múÝĪ s˜Ô!U±¿œÃ„ÉÔG_N€ @G)ë*mœÆTA`ra&S¢qLU&Ø, ; ÂÎ(N°×8-ç0%M¦lÛÚYWûkChLmXiœ2 @©И¸1 _hLù­û¿òÜiL¿ºæ¶¸xäùF¿v[Ð+W*!Õh#¥¸Jq?)Pœ¥TATJq• ;t%ÅlOêJQ„ž0Ò’3–,ÒRi)œ1™"-…1~\©Ó[ŠBÇWS—2ËW!œ½Ô+ɾ>Üû’˜8 Ÿt¥7æMŒ­ß¾ºK/õàÅL¦‚èim~¦ –à 5íÌâ0yÝÄõ9L˜L=¨#Þ@€ Ä  1e}O4HcÚö»çk“ú[„É¢.9QÉÉi¥â6ÙW‘f—Öò$“éäÓ/²LIIq˜¢:"S-4Ù€ @h4¦¬Á¶”Ƥ‹“ÉtÐÇú)ÎÃŽˆh~”5NcA‚Ÿ˜õê~ûcÒô\NóÔ…÷>üC ^ÚÚYWûkyhL-_Eœ  @5@cª›A   1u`¥rIÜiLƒ¯¼ÅwŒb²Ñ +o‰fšiTK sº%Kz–·dê·òyß\2¸ \˜/,µÌz ­”„V²äbµXŠU6– éáÚ(ÒRå8Löjæ“å3Iê’%u¶JW²¢—ô§t%½$I ’œ´FêU®©ê—“L¦ŸvQÁTóúˆ-S0ÏuË´ðUÈ%W•'@€ @Ù@cÊši«iLº>3™ 3©‚N‰’,祉Î{ì0é@Íikg]c쯵  1µvýpv€ ÔN©vVl N#€ÆÔi5ÊõDr§1ITª éU›JØ“²t[…änÎIŠ-TV”J#*Õ&*• ­´µ^])ÅXZ´ÙÉ1µHB­¿M¶ÓŸvïr•$0ÉL’¥´µkŽŠ¥I;ý6¥ÉrÏéG ú³ÆPLî«K&ÓOO½Ð4µ¨fó\q˜ø¦‡ @€úŒSÖè[PcÒ%ÊdúÁÇxSI&ׇЇ©™mí¬+ýµ04¦®N € º 1Õ…‹!ÐQИ:ª:¹˜"ÜiL—þfx9£Hëõª4¦ $_Š<$ ˜T>fR,’B©H©–XJ.ºR—™+©%Ì—Z©$œ])ºR9¡*[©É_-2™~rê…Aî?˜,Ó¢(S“«ƒÃA€ @%И²¾!ZScÒUÊdúþáÇYäüÁ^ã´7SÖÙ И¸ @èhLR“\ê'€ÆT?3ÞÑr§1]rÅðrÙÙ´^¯ºpè5$qsÙÜü…­Éänš•h%%Ë[le×ÖY•%/¢R-¢Rº«˜.ÅRH=Öú‘“q†m­1é+&0™N¹0)0á0µÅ÷/' @€ N&€Æ”uí¶¬Æ¤ L¦ÃŽQã4œ(Uȇ)ëýeD)#ì€ >'€ÆÔçUÀ @ Ï 1õzÜXyÔ˜œT”\ÆôƒÃƒXèµZG•ͤšœ$?¢R¥@J.âNÐ-è—EA/¡•0O’W©í©Ý5&}=Èd:é” b{ÇØiûíÿÅ«7¯ßòQ…²ûŸ4ö †½C€ @¹%€Æ”uÕ·²Æ¤k•Éô½ÃŽŽe¢ÇaÊú.`Ù@cÊŽ%{‚ @ o  1õ-޾$€ÆÔ—ô9v äNcºxèðò騶êU „Þ‹²EI¾‚<_®„ ¿ª–¸œd¢’§(U²”Jg:Ö¢ï°èI_2™NüeÑdÂajàW&»† @€j$€ÆT#¨š7kqI×a&“ëpÀaª¹nÙ°/ 1õuŽ @€@# 15‚*û„@{@cjzâ,ë&;iàЛ+EzUQЫ*G©¤{HeÂ&¥ÅOJ‹¢dÙßò÷­¡ÆUghLúÜ;“ ‡©îoAÞ@€ 4‚SÖT[_cÒ;“ ‡)ëúgY@cÊš(ûƒ @ ¯ 1õyŽ ¾'€ÆÔ÷uÀ4„@î4¦cO>ëÆ»ÆedJ9ö§g}yÿS_Š­¼aäø2eÜ #«—ëGŽ£´AWßñÿý/ÿWå3ùüûç‡ÆOöS³mÚ¶«!ÇÞíT&Ó¡?ü ¹äzG‘wC€ @@cʤÛM[hL:[3™¾´ß—&M¡r¢ó÷>üCÖØj&€ÆT3*6„ @ Å  1µxqzh 4¦Âe×}I _Ó£>z`霿ì³ï—þiïÿ[ÉŸLà+ûðéÏ|¶ò~óÀï¾´t}ëkLú"ùí…¿\¼bCånâÝø¤/¿r86 @€ hLYWt»hLºîŸþêo®ø'8LYßì/ShL™âdg€ ô!4¦>„Ï¡!ÐÇИú¸8|£äKcJR¬Ü§Æ«H%Кјöüéã=ÿî½É·W¨5¦F}•²_@€ @ F)ë[¢4¦Q]{M[{Z…Æ)q˜²¾;Ø_ýИêgÆ; @hMhL­Y/œšA©”9F@cúSõhQiÖð=ú_%“é½S¯‡©¾b9$ @€rK)ëªo/IgûÑî?¥6Nq˜²¾5Ø_ 1õo‚ @   1µ`¥pJh4¦&æ0Í&€Æ„ƺ ´¢Æ†b 4&•YÃÕ)ë,Æajö—+ǃ @€@Î  1e}´‘Æ´õ£9;?^#I“ ‡)ëû‚ýõ”SOÉñ>@€ZS«Õçæ@cjkŽÔThLu+,õFîaûÎ#Њ“…b²"ŸéOû&SS¿V9 @€ hLYßm¤1ù—î›L8LYßì¯Иz·B€ ÐRИZª:84•SSqs°æ@cBc‚@ÝZNcòC12é[ÄL&¦æ}¡r$@€ @À@cÊúfhA©{Ww¿ûûU½P3™p˜ª‚bƒ¦@cj*n@€@  15.»†@‹@cjñ âôzJ ïÓï>þõ£U(o¿÷ûím(9! ê~çý*5®Û¦§Ÿ¸Æ¼ÏÅädÒÁþã“¿4æì€ @€@EhLYß -¨1]>¶ÿcýwýq—•u;ÖéwWw—»týiË ÞzÅ_Ÿ5öú  1ÕÏŒw@€ КИZ³^8+4ƒS3(sŒ> w©sHdK ŠÉ È”í¡Ø @€ Z  1ÕJªÖíZMc’¢$‡iÀÄs6Í8c -O\;ÑÅg6˜Š.Ok´J-¡›jÅÁvè%4¦^äí€ ´ 4¦–© NM'€ÆÔtä°9ИšÃ™£@ a’¡˜J25ìÀì€ @€@yhLYß­¦1éú¤%YŒ%-ŒX4B úS>“]ºô§“™´Fž1™²¾/Ø_O  1õ”ïƒ @ Õ 1µZp>h4¦æ±æHM%€ÆÔTÜ (Љ€Lƒfw€ @€@ИêVuóÔ˜ö¾mo;m·àKK¶R¿%9IiRqÚSÕ‹e4œSÃs@€šD©I 9 ZS V §”4¦,(²´›öèÕ¤¡­p.œ @€ whLYß­¦1­Û±Î’Ä)À’ËçD%ešs“ÒÏ ‹ØÄZ‚SKT'@€@И2€È. ЦИڴâ8íjИªâu´ 4¦v©)΀ @y €Æ”u-·šÆdö’%ÉI Âd—«5c—•äüq*Zc ÚX¿Î˜5öž@cê)9Þ@€@«@cjµá| Ð<hLÍcÍ‘šJ©©¸9H©pÙ5 @€ P'4¦:UݼÕ4&°ì%K*Ý»ºíü¢I+%6iAëm¥yNÒ›ª^#@ yИšÇš#A€ ÐXhLåËÞ!ÐÊИZ¹v8·^@cê<Þ –"€ÆÔRÕÁÉ@€ @ çИ²¾ZPcÊúÙšH©‰°9 @ %€ÆÔP¼ì-M©¥«‡“ë94¦ž³ãh-hL­Uœ  @€òM)ëúGcÊš(ûË74¦|×?W@è$hLT›\ ê#€ÆT/¶nhLmSUœ(ª@câ @€Z‡SÖuÆ”5Qö—ohLù®®€ ÐIИ:©6¹ÔG©>^lÝ6Иڦª8QT!€ÆÄ-@€ ´4¦¬ë¢4¦Q]{él³Àþ )4¦Lq²3@€úSÂçÐèchL}\¾QИE–ýB ÙИšMœãA€ @å  1e}w 1eM”ýå›S¾ëŸ«‡ t4¦NªM®õ@cª[· 4¦¶©*NU 1q‹@€ @­C)ëº@cÊš(ûË74¦|×?W@è$hLT›\ ê#€ÆT/¶nhLmSUœ(ª@câ @€Z‡SÖuÆ”5Qö—ohLù®®€ ÐIИ:©6¹ÔG©>^lÝ6Иڦª8QT!€ÆÄ-@€ ´4¦¬ë)k¢ì/ßИò]ÿ\= @ “ 1uRmr-¨S}¼Øºm 1µMUq¢¨B‰[€ @hhLY×SÖDÙ_¾  1å»þ¹z@€@'@cê¤ÚäZ P4¦úx±uÛ@cj›ªâD!@€ @mC)ëªBcÊš(ûË74¦|×?W@è$hLT›\ ê#€ÆT/¶nhLmSUœ(ŒÀ¼+LÐïƒ7×Å€líš³ä¾aP‚ @€ ÐИ²®4¦¬‰²¿|@cÊwýsõ€ N"€ÆÔIµÉµ@ >hLõñbë¶!€ÆÔ6UʼnB@ä*IcÚ½½;IcÁ-W=>J€ @€Z‚SÖՀƔ5Qö—ohLù®®€ ÐIИ:©6¹ÔG©>^lÝ6Иڦª8QÈaš>°¿ŠDCÒ’Â/½6y¬‘Qˆ¦í«»’ë哤%½ªtr–`έזŠÌdk™©m/‡ @€ÚÀÒ§Ëv¥é%~zG •5&]ÙŠ·‡—GÙ±{iï.wC И•]B€ ÐL÷.ùëÔ'ð±Ëÿ¾™§Á± f˜5<½ï嬿Úóá¶fŸ ǃ@c 15†+{…@˜«¤kAN’¢.é·iLiik×ý©õÚÀrÌiY öÛe—kÀ©±K@€ @!Ô€LZÉO¯ ´¸ÆT. Óô×êõ¥³4€S ²K@€šI \@&B15³8ú€@¹€L„bêƒÊà"€ÆÔ(²ì™ðSÂ)‘œŠáÿÖŸŠ½ä^²л´Æb2ñ@€ @ ±R2Š) è-®1éS2Š)‹Êg €ÆÔ¨ì€ &Hd"S“«€ÃA o$2Š©oj‚£6ŠS£È²_@€ @€@ Ä2Š)£› õ5¦d@&B1eTùì¦И•]B€ ÐdÉ€L„bjrp8ô d@&B1õMMpÔF@cjYö @€ @È#X@&B1et´¾Æ¤ d"SF•Ïn@©PÙ% @Í'àd"SóùsDô? ¡˜ú¬8p£ 15Š,û… @€ 䔀 ÈD(¦ìИü€L„bÊ®òÙS 15*»„ @ ùü€L„bj>Ž>#àd"SŸUn4¦F‘e¿h6›öœº×žIC›}\Ž@€ @ FÀd"Sv÷F[hLº\‰PLÙU>{j4¦@e—€ ô  ÈD(¦>ÏA!З, ¡˜ú²8v£ 15Š,û…@³  15›8ǃ @€ÊP&B1ezƒ´‹Æd™Å”iå³³@cjTv @€@Ÿ°€L„bêø}IÀ2Š©/ë€c7Š@¾4¦¥K—­øs饗žvÚi•·áÕ#ð³Ÿý¬ò]{íµüq£>‚îwǦGíõñC2Ü%»‚ @€ Ð3›&Ú9ÿ¡ž½—w¥hI'?ñ…Á[ß[H=B ¥  1µtõpr€:Àœ9sªk8IÃs¤«ü óuÂÍÑ€k¸æÁkÀ^Ù% ÐêÜyÉÇï¼ÑêgÉùA ~ùÒ˜N>ùäƒ9ü¢K†X¹0V.òƒƒÿçÙç‹/S¹ Y^vAXÎ/Sλhpj9÷¢ÁQ¹pð¹^9çÂÁ^tÎQ9û‚AÉrÖƒÎ:?¥œyþ¥Q9ïÒ3½rÆy—ÆË¹—žqË%§Ÿ[,§sIj9õœK‚r¶_.>õì‹O‰•³.>嬋Y¦ 8óâ° Œ•_œ90(gÄËÏÏXRNøóÓ/R99­üì´‹RËOO»((§^+?9õBWúÿËÿýoþÓON¹På¤x¹à¤S.8é—üíßJíú?\Í~ÇÔ©S¿¼ßG}·_{HWÍÆÃñ @€ æØ´i“š'xàÎ;›wÔN?R»hL[Úgß/uÔQ4N;ý–lóëCcjó äô!´>= {üOJ†¢.â?}ÿàÃ4 •rŠ 3ÅF— ƒJ)ÃI±Q¤ØÈQqÀ¨8TÅÆ†J‡„¼Á ÄPlÜÇî)â‰îÄÆtl(ç¿þ·>àÀGpâ7|ý[?Ð0_ëW}óÏPXÔþ=ztóÍ!>$ ÓúîÃ:àÐ #;iøí£¶nÿ½Ê–¨ìÞ²½Xn¾}ÔÑÇ´ùÝÝ®¼õîî ¼£ò;•7]yûwoxeÓÛ¿Û´m—+·íÚØ• Ý»Âòц­½î•õ[>råµ-¾¶9*ë6•·>\”¬¬y³XV¿ùÁê7¬ì|Õʦ ¬òÊÊ;Wn|ßÊ • QY¾áý ¼þþ²×ßseéú÷\Y²þ½%ëw,y-(‹]Y·£«X¶¿²¶X­Ý¾hMT®y7(«ƒò²+¯¾» *ï,xõ—TVEåÅUïeeP^Xù¶•çWËüoÏ_®²Mež•eA™ë•9K»]yni÷sK¢2{I÷ì%[g/Ê,Wº¶Î,”][ÆNZð·ÿé¯l™îÊ¢-Ó¢²yÚ¢ÍSnÞç‹û·¾Æ¤Tÿþ½C®êqïãt7ì “C€ @Õ „S¿)s—>6i.&Su^5oÑ“&ÕþóK6ޏoÓšë– û‚S_P瘀rE@OÂOL˜E¡ü±§›n ¤¢Q§ÂxSl˜)6ºT²±$7d£H…ñ£häȆ܀‘Ɖ¢A" ƆÜÀPa<È ÙH² pè§8ècÃ=±â±Áhdgé6Ó±7”óƒÃ¹øŠá…œ-¸‰Æn C6ýêf4¦ä‡HL®¼~„jðˆÉ”«/.6çŠCô¾s~+tèåçNc’¨´y{ÑRò%-ß|[ðÔXV]’ÃTj/ÉdŠÛKµL[K¦¤Ã L t˜–{“d¦R)r˜ŠÓº‹=‡©+æ04¦…‰GXïA6x–­Åaª[cò¦à©·à0ùϾ¾Æä&-¤hL‹¶L÷¦i ÛCc²T‹^íZ¯í¸“©C¿¯¹,@€ ´>9L_Ù¯ßÔ¹ËÔÒÔ@È#1™2«´Öטä0©ö_X²‰ÆifµÎŽG©qlÙ3 „¤1›0-6å?ýöֻɟ0ΖæÉ‡#Mµ8Lë óáÝLxÓ˜l¼›ún“›ñîÏu÷¦¸{“Û£!¡hB»›ÍnóØ£Iì…éë6qÝÍZ÷5&7SÝטŠóÒÃTIÃ7IéB4¦Ä‡+p˜naÃ| Lp8&ß?Ȇ†óQϹ¾ÊÜiL7Ý6*zLŒb,#-)ØRôÔX>ê’E`J‰½”j/UÀT)Sä0Ń0â0EA˜Â8L%A˜<­¾\¦¾p˜ J~!SôDë¹ùMÅ43|¶hLB1µ~4¦àÕ÷]´z›=§òÙº·ÝCL¦\³sñ€ @èÃôµ~Óæ-S«Ó5O™0‡˜L™TG‹kLÃôµ~/.ÝTÒ8ešM&uÏNA©TÙ' xô üøÓÓ é>R2~h@êÇÇžä9• LA–—âÃâ0¹Ì±œ©“<*†b ³vX(¦X²ŽÔPLnN{!S© 1Y(¦`úºÓ˜i7B©˜jâ1ù¡˜")̧DcEc*:LʤL>²g 1Å>ar˜®ºa„Õ¦iLJ«rXÿãˆÉÄW:›@úÐ0­ïήõü]]î4&=ÃyâLxwO~¸XÈ% ¿äž&-y\!s\Jò8=e®÷Â/EšÉO!W°æë˜ª$’+ä’‹„¹äЉäA˜Š¹ä²ŽÃ”‘Ãäõvc¼y¿»B:¹ÀaJjLi¡˜Z\c²T¯¬Ù{NU ×[ïÆdÊß7:W @€ ¾#9L󗹿‰Í²èZ·ý¡§1™2¨˜VÖ˜"‡iÙ&¿ö5ˆBã4ƒŠg "€ÆÔ °ì€ BiªË—Ìõqã-Ò˜N,9• 6Ŧ¸ÃT´ö­ ‘œŸN.š_˜Ÿê0¹¡¢b(¦D:9=Æ[F¹*¡˜B©öPLs]F¹ÒPL¥SJ(&4¦¤Ãtõ #/íõ÷-' iLª2L&¾‡ ÐÁîàÊåÒ|yÔ˜bŠR¤º¿ÈIþScIâÊÞR"ê’ ò.Kq¸ð¡Óä_ ÓûS˜º¸`/yQã´Lõ LÕ¦ð!µ(0EÝÍÁCOX¢ÖØck˜ 9ž¹4—\k8L‹·ÆÒÉ™Ë_ŒÆTÆa2é¡ñ“ýÚ|wçZá{Dÿ¨¾óýC»Öl ŸS£ÜÕî9UUsËÝ|è»ÿûz϶««Ë‹ý¹k×.-ØÿªÖë§ÞC$·í¶Þ®[·®—{¨÷ˆl@€ 8æ0MŸ¿Ü¦wû³ƒ‘5ÛÇ>õÜý¾ùÞûï× Í5Cl¡7­µ*Ýß@Çòÿ´Qìíõ¶AʵžbÇ*w’-«1™ÃôÒ²M6ˆ’¬}5N9¬WÓîîîmÕŽ3dÕ2uð]CØÅn¿ªw‘öº5Zu!îµìªö;¶ÞO–moç¤WgO»Æû¼gÒ“w¡1õ„ï :Hczì©©©)>løé†Pc**ÿцpt)6ÆT6Sa8ÉÉ­É%sɉ;¼8L•¦âÀPqHHóáH—NnµÆ} C?‰PLϯxÛJ]¡˜|Éf¡Gi4‚PLA4& Ö(Ó9±tèí£?þǟ먕NÙTq˜®¾ñe LÎ!‘v¦Ê:´ÿq#GÝ[ï妎UÞIò±¹ÞƒÚö-÷¬Ø³Ëà]h0Ò¡á õí+Œ…¡áÃëntûºÁTŠ»g°¸i¨›p ÜiL•б”œœTXðŸíÙ±4ÒRl©Œ´”ð–Âðžå쥷>ŒÇ^*o/¹GÏà´4…œÒÉ9•>J!—©'S8e6˜\àÐ4‡é]{x-¦CІ°…€¢…˜¢E%¿Þ\r½ŒÃTÆaÒsðƒ–T.æ0…Ä®$5&ÝBMøpV>„ý£Z¼öí Ï©ªˆá£;èúþ]éaqï½÷ön6L ýŸþýûkyâĉ¶^?þö±?kd;hï²Í  S8p v2gΜºÞËÆ€ @€@/ DÓóËm€¤˜Q®08öXýîƒO>·ÿõ™Ljžìµ×^Ö ±Ÿ#Fèlõð_ï9kWj5T~—öo½ðjbhÙoÚhYg2vìX·k€¤îPm¥TÕ#ÙzÒf:v¥s«zz­©1™Ã´`ù©Su#¨Ó gS±5ÂR´㓬 ž5EËÝ®!l»µÛOíͪդ[H[ÆvëßÃv÷ÖrCV½Éu2õºtÉÓRÛõåxºIòôÊ}0ëºÏ«^uf 1e†’A€@:iL<9%Êì‘6Uþ†áwýèØ“CNNÓñ˜bYä\¦@` ¦X¦pðèýhب|.9Ëí'èˆMk/:L=J'e” Ók¸trʰ¡¬…Ä[•XC“Ê÷£¤r願ÊiLíþSÞnAs˜¢ÆWÚ{?ô¨úL&¿ñec@µ4»b͵ׅò­yբϊµ_ [B Y74l-VwÉb³.±WÇa°¸WøZï͹Әô\è%€ó“ÁŠÒ ÃGº§Fßywò{Ñ‚[*¤%.d‹SÈ¥òQ—¢ÀK~´ÏbÌÏBì¥Úí%ÿIÔ%6É•¦KÉ"—©D`Ê.“VôE/Aò +#1ßÓóƒdÉ~¾äy…gÜØ“nð°[xÞ-›K®¼Ã$—ßiL¦ó[ñ¦ÔhL}®1¹T…A‚”Ù®öœª¼Ô7Ýõh]&SÉÿ¦~yû3ùϬj¯nê7a5&{Ƶ}º³j½/[΀ @I î0ºÑ]F9› lÍ“ž˜]—É”lžÄž5:ªV€ó3’¢†>1ÓHÛ”kÅhãT¹$µõäÔ¨ vˆy jLÎaŠ ¢¨ö-Ÿ…_û7×Ù8Õ%árbPÌ3k„Æäî™Ú[¬É³•{§îTW=hTõ®wƒrw]…në 7j¹¦Ö×~Ÿ×{ =ß©çìx' ÔD Иž˜R: Í“·á§ë5 ủÉäUì%?SY©Äa F‹ Q35N䆊ãè0­³|Ð%©9êq˜ÞÑXî ã0=óü9ê.œ¯1&åÓ5¦›-“†Š©8j“)o“¦a7Þ!M->‹ t‰ hTîzL¦XãKá9ky®e›ÔŒÉôÖ¸kÅgÅš>ålæhèаiL®MÝŽƒÅÍ»›u¤ÜiLz.L:InM¹§ÆXŒÊ(C\i¤¥¸´¤´qQª¸b¸¤·KS—*Ç^*o/U ¿d)ríÙ4–B®—ÓËQ¦ ‚0•u˜ ¹˜Ò¦@Ûwæ~àïwù¹ä¶X$Rÿ!øÁ‰A4¦ S jLÞ?ªÄsj¡así9UI©oùHí&S/5&=nºi²ZÖ¿==ƒê·EÎO®‰u [‡¯½Åâ*iÙüYíÖžem'¶Y¬“T/5h<£YßÉ€ @íD@ÓW¿ÖoÆóË­½\Âk ßûÒ«AódôøYµ›L©“j˜bâ RŠõÁiKüÆ5%´“˜Mb~†í_Ëþ«êÅóÃ/é%ÛÌoæX›E/¹·û ­×N\{Ç÷Z¬Ê“ç»ZMcò¦QÂÚ¯«qꘘ1#æ÷±jKëfµêóo ^²ÀWÚ›5Qõ§Ý*¶s­täO+×[‹ËBY“Ó¯YSÖÔ€uïÕ‚_wÖ†uéä쾪pCº†s¹c¹Û)Ù|»jÿ¦•>å&ÐkAº=»öµÝó®“ÚnÑäÇGGtŸ,½×.9öéó?˜1°>ª÷yó¾јšÇš#AÈ)iL?19u@ʆœ®¿y¤K‘æÒÆ•Œ4EcLhhÉ]*¤KÀTs¦õÞ ‘Ëα6Ê%'=c‡iٶذÎì%ÝÅÑœp(GÓ@_còÒÉÙäs4¦Àaúmà0•âîÍ! †‡V¾sð‘ÇÖ˜].Uc²‡X÷àgc4å›]cJO†ÉæXãÈôqß-ô¬˜Óï-.»E TÆà«»7CÃ6&ë>€®…èêZ Ú¨5X~û×õœh³ä—€û&q U·ÆIÖØtíe#¶&¼kfºÇ®!›HÆ`q‹ÞÇužVþ4¦›G&œ¤ày±ðÔx§ž‹ÉàJC+Y€¥])n,yÁ–JSÅ¥…\*AÉOŸû`ú]Æ©s-÷yåOA–¯¢1eI“}A€@ iLŸ*?mþðº›ïüáÑ'–OëªKÞSÜ^ G”ô0feåÆtÉeíÐ ‚•’ L¯¥aò¦pB‚MœV€UMNЃ}”#x¼¯!Se‡©RÃiLA(¦‚ÃäÜä\c*q˜6¶,°–÷EÁPÝ÷pÅǪÑdJ6¾¬µ¥':÷dhC0å›í)ÚeS˜ýÆ‘=…úŸœÖzVä[ -CÀ.(ŒQ\½´¡a¯õ]óа5 cyxüÆ©µò\šu7;Hïò»2üNØ—€k[S×¾[¬nßNÉ[ÖÇš™ÖzMm)3XÜ2wnoO$w“ž ”t’® Ÿ£Ã’“\y+­T]©è*E"|š±”¶¤Å¡®äJš·ä?q³‡[­D!@£@ ÁW•_ÜÃhì‘4~) … 5UÓçÚÇŒ{›D[úØ=¼úϯÅr…~j (”½Ê"ç²&Çr'ׄIOÀöü@éSÉDr­©1¥ý£òžS“¡˜¼çT¸ºñŽšL¦ “û7æ&nÚ?›ä³¦Öû½œúÓÞâÿ3‹õÚ›Kë÷öºYgÑêÿ¢vâ*üÿyv·eo¿y? @€ P‘@‡©´Ý2ʹnt%˜¸ïñšL&kž˜Œb?vR.«:­Ô±4ë>sG¬©â[#¶“d¿yLcR‡šíDñ¶à÷ÙYÄveaoôvkÑ8)ÖêñOÉ:éìí~O_ê­£1Y¦‡©ü J¢ökmœ:Â®î  µ@cšš­uŒÚ=ãš™®:lc'¥ÙÍ`Õçî1W•v¸˜ÆäOò‘ig!¸\ÝY÷®»gÜz‹È¥-õj¹2ÖεCÛ¹éÇŽåvh'ì‚"».àØ™¸û6y¯Ú’ôìüÝ~ü[W·ºQŠ}úÜÓ®ÑNX îÓZã}^á#ñKhLew€ ' iì¸ÉeçÆoþðÚ›‚©µÅ´ñ¨K±&\©‚½TB*ŒU˜vtÕ„)ÕaŠÆ}äÊæ«o‹ç’«ÍaR2ïDc*q˜A˜\ɳÆä9LQ$T jV³•<†•o+ÁŸRûtDõ˜L~ãKrþŒ÷8ª§;³öS›cÏÞ±‡ØXã(Ök¹gE¾Ò ÐR††ýÖwFCÃîCmÚ¢k!ú­Qû[KÙ¾"lÄÖ%…´Î ×L¶d­…¨·X¿þtA‹íî4Ü—‰[ãïÙj¦\K™ÁâÖ¸s38‹ÜiLz.ô -Ý[±èÕþGŸ`ZR¬øÎ»UòK`Á»ò†\%+¥ÆR™`K´ä™ò©ÞROÔ¥BDÐò™ã‚©±)öRA´¢ÏYì¥dø¥È»÷òÇü¢À´2šhë&{uÅeG.›BnÙ¶¹aò8Wž+¤L–ÃD ƒŽ–Lmßâ0%³ÈÙ°ùMcòŸƒ“Ëû|qÿØœ‰MÛ—¼É?UþQùƒklbD8B3!”…:|N»lÛõw<\Kv¹¤`dÿ{\ç¯=ÎÚ—ä71ÚuVÚ¿¿çÔÖø íO¥ç»·zÕW}õ§í·Ø €&W ‡ƒ @€@> Èa’Å2=Ì%ÃT¡½0Xm@5OîylfÕìrÖôHB¶¶†…7W»ÀfDhcËœeÛÇ‚-e¢1i·:f(ZŸ¾ëÅ3Æ·m¬[ß?y'‹Øéù]ÿjËÔV¶E4&—K®¾Ú§éƒ[õ7N}°®kŠZuû'±Jñ«ÃÞëß-Ö\-7ãÞëßEVãö«ë˜ÆäÛuÚ2æ ¹›Äîÿ¬©›jò%ï"]‚%Ôó?/¶Ò€.0†¥ÇSòÓ§ãÚÑ­ƒãîíïóæ}©¢155G‚ SÒ˜||rb@ª8ödRéƒM…a¦Tu)6Þ’;'í% ÕS1SI‚›Ü¾Ð†A˜lÄÁ²¡ŸÒŸm‰Šw¬,­˜K®0 cC9Ò˜.’Æäâ0•:LyN*8L7rÉryC1•z ÉYVUM¦XãË>Ör±üPö£95jL˜í%§;è(-÷¬˜Óï-.»µÔ?4\ ÅT×аûP뮨ÉLÖ8}m:µ1õÛÒ¸˜Æ{¯µpÕi£CØø¯k-Zó¼FI]@vž©ûg°¸µnâ^œMî4¦k~{gRBrkôjÙ§ÆK©Œ«T>=\Û3!-%SÅ%½%ùÓ^J‰ºä©KUì%/ð’Ez÷Ã/Õ`/ySøä ¿d™R¦À^ :.ëH!D`ê…Àäg‘󟀄iÌ„öИbIOíöˆRË ”†b žSÃÃu#ª›Lêy´Nyý'pÝ ¾Æ¤—´ë ôŸ5]w¼´þ\ml±ëcküï.7`Þ® ]è?Ûm Âž•ýµôû÷âÛ’·B€ @ S”Ñ J7z4ËBÍ“»­b2YOºß3eýjX„$×r±‰6ÕAM{£ßTqvHÌñ+Õµ>üfH¬3΢.Ùi¸É–7Á^²ž;³©, ¬,Ѷߣç¢Æ¶L+hLÎa²¬%ÉÆ©% úÒòY³˜ÂA”§F8föX¨®­Ò­ýhÝ þ–U5&kuZÝYMé-Öãé†p\•ÅÎÄÕ¬ÛÒ¯ëXO®3~´gë«­ÉnokJ[Œýä±ÜMk[jaÒï˜Æd{s÷¼b÷ª¯1Åí|ì“¥÷ºQ«ä§Ï}0ÝÆîì„k¼Ïýdc—јË—½C€ÀiL<þl…©aနKŸŸHåáÒÆE#J±ô¯CÉñ£%…a#Åì Š—£#™#M`ª3‘œç0'¨/é.¦×X¼u–•p.º?=И~}³Òhhì&5‡F>£1ÉaºÚs˜‚l-aE§¤“‹¦¸Óy»Y–çäG3rÔ½å>œ1Éž±­ÙeÉö(hFS›ý§ñÊÌzUû¶AË=+ò¾&à —›?¦Ö·Æ÷í«[y?•ôÓ ƒ]GëÛï Ðg_a€­=èÖ[ËTk,°uth!Öõ;=b_Öt5¨öMbcÇúÓ†õ[X_Šë]q'k“êíåZÊ|™ôõ›Ùñs§1é¹°*ÉÅL*.O?>AQ”R)¥%ƒó›¢4gáÚb0ÏPWzîåµ`É•Ù/¯ ìx/IÜ3³^ytâs*“f½>‚DO!•³ÅE9ŒS£.…£Þóhx©¼ºôà³"Å>ü¦?e¥3~¦•0çq1yÜc“_2uÉì¥ûÇÍÊãA¹/,1 ß (Zj/…O´*c'¾¹ù…ø¢ÉÜB¦ üR˜*Lu©-4&ïUpÛÈÄzúùMO=¿Én€BÃ#ê&ž¾hs,Ó3/½i¡˜ì9uö’­×ÞþPÕ˜L¦ÐêÇ=Gê?GÌ`µ ¦Z \o“þOØ|Vý¸7&׸/3ûïeÿ¥ìÇþÓø¾íÇþ9Ù?3ׯJ4¦Ìþ-°#@€ ”'à&7v¢6¬Âè>5“J0&‰,–5調t¥²«m8ó•-QódiawÔ#3*Äd2çÃÿ±FM·pÍ›)h 39´Æ¥¾²«qM×qf³ýku­äT`×ð±öˆ½Ëthk¡¨#ÏÖXÿšõ빎–ýÖS¬¥SKG[ŸkLžÃ5NÕ“àfù[-¦Xœà•o?ûÒ›ŠÉ¦*ÕÒ85žåš{æ!©»S¿Íãñ·mýé¯qç*ºbõãš–6c' `ÜinËä™hŽëš®®®Ý Žk™É”zªÉÒºwõãy$e;·»Èµ‘ý“qG÷û‘“÷ªíÁ]¦;t²¥o··±Ò[R?}n”m¬KnéöhLü³ƒ Æ4æ±gÓ¤¢<Ã~{ÇQ?>!Š·”–¢Yñ¡;þÜËkb“ᣱ¤‚Ñ2ë¥Õ6œ” ¿4ýÅWzjöSÓŒJ†ŠÜüvwA˜ÜxÅõ˜÷س/i (œ¾Í`wA˜îyl†žñÊ%’³Q pÇ&˜|‡I™4 Óæi^"¹œ'•3‡ÉM!ã¥:rSè+¼c¡ TƒáØPY!¨…Å[¿xY“Éo騇ø5¥@xöÔm/%›cÏíå˜íXR”íÁ²mð‡’ÝC mƆ5Mèé‚¡a}©6bh8ÖâB[ Ñ,¶–¯¥ëÑ»Üw‚‘5$c_®Ak€»ïëÒŸnHÚ?1×&uiì’_2 ·Í-ž¨Ë*èNÛ_SEcRõÛ 0÷“\ÓF8,î¢Ü£Ô¢‡B= è©ÑyH• ™àWÉ)J_üòןôœ{ ¼ï‘I_øò×,ž§+Z#c)Е¬¼þžÖ|泟×oWì¡3o)é-U ¹”¢.ÙÓÌçÑ÷ ¼ôéüüãgº'Ôûâ~½4n¦tK-«|뻇h›~~¦Xõ´ª5z<²¢ç×}¾¸ŸÊ§þñó*Zøæw)—<.5ÜÝLÿ×/|µzþ¸% ©ð¤›L!WU`ê½ÆôÇOvvmúÒæóúÐ?ªÿþ¡]k¶™÷¦æ¨Ë§Z9éšYž?áîg׸n⦯;â²)Ñ A˜¯áÞÉk<Ù…bÒ µ†ÝVÝdjèuõxç Ê=(ÇFz¼[Þ@€ T%9L󗹉€š„sÆðùÖB9rHPÆÏÛèºÑ‡Ü·pȽ ý逃î~yÐÝ Š³,Â1Œ‘L¯š]®ê¹ÙêAsÝa6¹¢Æ7¶Åf}«1™ÃôÒ²M~ãtè˜W¢žŠ×vüúþE¿º‘3ØN¼z棳_·¹Ojœj¶ý7ÏàB1Ù J[7NÛâžá$+@câþ€ 4¦GŸñG£bCN±©p¤©8ØdÃL'Ÿr¶6²¥knºË­1uI#¶æ¨£OÒð¶†ÜÈ‘Öìû¥¯Yùö÷M ¿”šB®É Ù0Ðñ'Ÿi£?§ž;ØÒn|ê3ŸïY"¹™a"9(ç{a4&ß[Š-WˆÆ´õ£9Ϭ;ð£?njp­6u÷Ãtƒ¦(,‚rq˜ôø­e\ýnø¾>šCæE9îÊNÍÍ"°á!ébb25õ 9òFàì¿ÞóÔ ª¾bÌ+:^ }/5 »´¾«Bgƒ¦°Ì€þackÊjL滹 PÚErMÓ/§·,üË·gÁ”¢‚#|B,xRêŸQ8¥Ò J?<æ¤Ï|ö¿>6ñ9ÓMιèrý©gG§+ÉXê´¶ùü#žó#-i›³/¼ÜIK?ýåÙ*U¤¥”xK¡·o÷K,aœÔ¥¿{H”6® ×KQ’·d˜$ÁÈR=næèq3´Þ\{•Ù‹6êO‹½¤§Uy÷±Ìqû|a?=¹–&BŽb/¥ÚK.5ò¨G¦Ic²ðK~ò¸‚¡tnÆÂ/¹p£¡À´Å'—<ò¾²EQ‹JRÈ¥ùû=‹Æ´¾{‹¦ÑKÿ󨮽ÔÜÛû²üûíÕ+r˜"ã-ˆ «ÿRÑ,ç×vÈa:rÈë&¾ü¾…ß:o‚4&7H0øž—ÕM|ØàÉ~(&{N««omW“ÉÄrŸ=C€ @>s˜¦Í_fSt,ÏõÅ#_:}ø|,Ñôî[ž\©ŠM>õ¦yj¡Hc &ÀhÒöŠ·üv®Z(—ŽZPèFfY¨yrçC™™L0Fíɦcê±5&s˜^”ÃT˜‘eÓ¡£_q3AÝ ÊÄßPËTµÿÈìõæ0xzÕყ¨ö½Æi±ö‡µmã´cn­œ^SN+žË† Ð<Ò˜îä™ÄPT1qÇÕ7ŒpR± öÐ5{Á1-X¹Y“~ö˳_qƒžÁ4ÀôÒŠ·4~¤A%•«;òÛß?Ô2ÇÉUzjÆBKà ¢LŸùÇÏ»1£#|â%¿º®$üRɆll(,ï¸Q!=Ëi0è××Þaù7T4‰Ý¦oþû!6îhLaÖ`+±<šY­œÅñ´ Lnç{‡-Q©^iýö™˜4X£ÒI“4¯ºa„k|Y"9›@òëÑ‹TË ‚«'ðË¥1­Ù>ñï <Œ˜õļšâ®'ðHc*Ì"Ðhš_ 5&Só¾ 8S÷Ú£RQfJÖ "}ö#EuÝŽÓnž(Œõ Óúæfl.º¶;Ÿäš²“6µ(è.SrM‹\gí§ý×7÷È/…PIz&8òG'Ä‚'ùC(¹XJ…)ðzޔ䥳/ºüÞ‡ƒhLÎXvÓHùIÁ6O?çGZÚ÷Ë_;ëÂË]ŠâŸ8+°æ_ÛqÕ#Í‘×o{î<ó‚!&ÎÿdÀYZûÔ,gÐø½C|r–Œ–“~qÖ¾_ÚO刨¯°)óWýÛ—ö“º¤ßW\§Šl$ýéžM_~5ˆÆ$oÉžPU¤1Yž¸@c*D]šjL“ž[¡œqzru­Î[2É|=¿÷³3öùÂWå'ÚÿËwìÏÎП¶fîÒâã¬iL¾À¤GÛ~ß>Xå_öýꀳ.•yó‹³.=æ'§Ûšƒ<ÞÂ/iù€ÒïøôçîxpŠž½‚R´—¢ Êåö ©ÜšÍ›g¬|ßâÿÞ‰ª1ÿ¨¾wè¢ÕÛ,Ï  «TOÎÛh©w?»úÄa³,ª–&:žDcrƒҘF“µ\(&›ß ÜÒWÝ2¶jv¹Ú?_l @€ t*ÀaگߴyËbÍM|nÉÖBªë —ܤ—ÞTóDÝè7_!‡é2iL…nô[6hÔ‚Hc*t£k^Š5Oî;-«˜LZ }¥1Ó~ý^\º)Ù8µ”0AÉvDQíß5éUkœSXûjœŽŸ»1И®ŠÉQhœvêÛê×…ÆÔê5ÄùAh{Ò˜”¯£Âx“ H¥Œ:½þž9+~ј‘Œ% -i€ÉæÀ?üÔl ¹ÀKÏ/{SN{áU „eûÔçWiLç®'X´Ô¹‹ß°¡„q¦eáÐR0Nôê»'þ;oåÀ˯ӂ¦‚VyKz–•´d§*NcRR9‹êâ…ê(И¾°_2mœVžrÎ ð‡\3ÂÙKZ8oð5C†k,sÜ!GÞ aQø¥%Ýw=_cJÈL±¡aç/곯Djw[d•ptx}ök6…‘Ö7·dëˆ%•Ó‰ùkò§1]?¢‚“äžýgÄZ–å0=üôszŒÐ£¤¯(¹gJ}ÅÈCÒc¥zxõd,„Ñ•¬Xt¥±O;ä××ëYó©é/K¥”¢¤‡K‹«dšEiiÍö‘L8ãü!ò–ôÒÂРW°¥ž˜)iI[šJoϦã¦,°5§ŸwÙ3sWª+Y¤Q\ÐBÂ8Ó˜¿>,’–î|†t¥OýãçõÛÂ/¹œÇ÷>hLÁ3k!ð’©KЍ$É/ÉX’·dO±w?2]/I]ºìêÛM]ºKá—BoÉÊȇ§ÉU²Ìq¦ÚèÏqÓ—Zú3 L®Ø3®"0é·¶qá—´|ûƒSaßJZþ¸T¥©–¤r_é÷•Ñ3Oð#0ùvÿÝ‹£°LþÊ^.ÿlè^ßþÞ! Wu»{/ÊÑNrÕsêøylþÄðñ+ô¿ªîõMuÕsª?H`“)b.\£µèxa2µÎ÷5g@€ V#:LL™»ÔoÛ„ÍèU?šFMÔ¹^4¦"v)Ìz.,šËæ/{åŠð©1x@´â=&VXÖ¤­XP¥ ýpè'ùÏ”ÅmB9É\¥®°¿O*´’õý)9±X2iI¢’_ä*ÙsçÈž–±ôÀø™zô´ôpZ3~¦C{Iâ¬<>yå‰=nÆ ??Ó’ÄéÁÔ¥Šó½%—'NO«½ôØ =ú9㮽íõ>ßó¨4¦¯šº•P]’«ô˳™º¤üq.ÞÒð{žÐí±?=ãÜAÃÌ[ºùî'"?LŠ<ò¡à)Öb/%Ì7ú©ç-sÜÑ?9]Q—~~æ¥*– M“~k›ûž˜oáFÿy߯SÍö’ûš®EcÚç‹û?ðÌu垌Ǯø;å]ζÜ:áËê)~vîR»ë‚ýQ”þ T Æ4ÅÙ¢¿jò„f¸>:ûuKV­©®zNõ dãê9µÂ PœøË ιpp÷{¿ÿó_þÒ'_R€ @hY;wîÔÌ£“æúƒ(®…¢æÉƒ3^ "‡-µL5ÑBs­É)‡I%öÚ‰êF4¦»TèF—ÈòµoÿËý/5ií·³mguÆÞnÔÌ[E›jß5N£öi”¦DÓõ¢ºÚ—ä4‚f°Ù Š^8ƒMµ/Éæå‡ý’8ÁÖH¿ðW7ÿð€}ºoìÿg…É¡@ ÑÎøŸöœþ?5óű @ oôuÏC“¢8:%CQÑðÓ×Ý H•êJÑp@aPàªGZ’¸PZúšÆ•\Ê !ø½CŸœöòÈ'èi\ESßUlÉ/iÀÈÆäškÀȦ»k¨HÓÚ­<öìK§{Ù 'ŸiÚUyæE~éáIA ¹h0(Òôõ@`ZhL6k]“?_}ÀY—ó“ÓIö’Šzî;%ИÂÁ c:¡À”ȧQ‹ÆtìOž±vp¹içÖ~­Ýû/¾a?ÿ®(7<¤JQËëÔ›æé Ü¿5Àwø`{¦P2;lÐäÑÓÖ–›âþĬW÷ûÒ—&]xÄG7ÜÉßgýÕ=øÿŸ)è{å¦d\õ…M ¦ú­ïØg_Mï [ahØ9L5 ûYz¬õ­¡á£Oí÷PWÿIk3ãn÷/á k¾&jíŽÑy{hé“ëEc*јô\Xòè‘pA¯þÃãS6ð"'¹J…Ö‡2*zŽÔÓdà'…el¨"ùaÁ!S„I™4ÅyØØ%zTU][¦jÅ Õsªë&VEÓ É ÌaÒÕ©`25¢*Ù' @€Ú€™LLœkÍa¿yr×3«Õ$¹yü 5WÕ:Sºþ|jþ&ëF—Ã4H“×.‡é’»^*v£'¦~ï ÃVmxWÍ“-Û™hÑ7Ž™LÏÌIoœj¨ ’©›Bµ¯ø[Á JØÛ ÆéØpÅ 6µO)Êu¾5Ç*8LÇœHã´%j=''¡¡,4¦œÔ5— @ è!êî±+ H]HŸ±K›lŒÉÒtX¤%7À¤$ ýæú;•¸CIsošÛµIcCR—Ì[Ry66RÎ8‰æÏÌ]qøOÐhшÑOk»F‹ô̤»ìÚÛïJkf¼¼A£BZ£"›‡`ö’2o¨<9k™ên¹÷IIKš¸®G; )ü’&­1UÝznºû ý¶råÑõ; 4¦ÊS½IåÖlÞœ*3}ôÇM}TÛYvôèщ# €ªÛ`È—ÅûΉ¯*®žÀ­ñõŠð |ÆkÎaÒðÜ¡ƒ&ß?u­¥óSøêXà0íÿIÓ_°'ðvÿ)Ëkh©} þl iñV Ô˜®úž-ËíÔ¢ÖwÚа‚0éãïZßAÉ2CÃj}§ {æ(CÃîýAcjÚg¥WÓ€Ö­[çŸkrMÓ®¤÷R4¦¡×ÞžªÙJ½ª‡'!¥,„“*=GJ~wŠÒÓ^>âÇ':?ÉôpùÄÔ—-œ­Q¨OuüY‘œ$iiN×&KZУ§6p¾¼RÂi~Ëš×Ó§b/iYE çÕcd2þÎ!zîÔ ¶¤GO­‘¨tÝm˜´¤W}6rêͬV~a?‰JÚLнžPõû›ÿ~°r鸟qÊÙƒÆN|Q­‘½öEZQÚ8‹À¤g#=¼*ö’t% "jO±ç^­ùÅY—ºÀKz~’·d!F­˜ÀtôI§KWR¹â¦ûÕ¹yÖÅW«˜¤oö’žkvÆ%_?ð û݇Io©Kc²‡9ÉLãW~ÃE¥kÆdÿ®¾ôÕ&=·$ ÑÎoV‘_¯LVN¹i®X7±’"¸q®å<¶nâÇfoøù sʹöþ?*:‹{ÿ à @€ Щ"“iÂ×v1x˜¶îÄ«gºÊ”—߲扚™W>°øÊ1]Ånô%ÝCG¿òëû_ ºÑéرæÎa²æ &S‹ÜNÖ—ê§QGØ8½fì7 ôê_õàbWûjœŽŸ»Ñ¯ýc3£œÁæ;L4N[¤Þ;ÿ4И:¿Ž¹B@}L@OP£ÆNL HEsà5ü Hõ?ÎRv¤=rÿöα~÷PM}× ‘ ŒŸŒI]ÒØÙäšñ®1#ËføU rt¨HZÒØ½ ­ †~uí iH£B6<ô«kÂ5_Øï”sqf°kúº¤%éJŠÀ$‡Éb/iÜG£9<ý¼Æ€l¸gÌSÏ|äñzÔtåm|û ½ª zæ¿ïÉùq|¹LþÈN-јœø®‡F“™î_òŸÝxMghLºqC“é¸dãKOà^(&“:ÿöôn“êQOàãæl´8L–ÍYÃCÏzÝ"¡úéäbS‡›LhL}ü]Èá=¾Æä Ln‹XëÛ:^T®yh‰>þ~¦:††Kû^®|G¢15óÛ¿ÿØáü5{5óTúüX¦1UôêaýKŸ ¼˜I.xRLKJþé+JÎUr–’=Y–+…§L{Ö,>nÙ­¬ Šž8Ub¹áì;ËŠ‹´ä\z8¡l)’ë“©âb!—ì(VÌ[r%–‚$Œ³RL挳lq…²Å%EÖƒT1²høPåÇ ¢Œziã~tâi×§gܧæ®UĦ¦iLzžÛ´m—’b*,žŽ§19“iâ¬%QœÀÂ$W»7ìfp¢}”ðØs˜T#ª…rÝÄÉTt÷ùw'@€ –%`&ÓCOϱ&°›˜Úf©®ý8Laó¤;jžй&žrÉÅ&L¦–º¬/5Ù8µÚ/iœ†[1—œ ¢øÓh"ø׊O:L4N[ªö;ödИ:¶j¹0@­B@Ow=8¡‚¢ôëp@*x*$ëpãM%ÃL…9ðñq¥h©8ä†J‚£â˜QÚQ{)˜Öîgáðæ±»a hÈúIî±ðKRÈ%ÇtêÕ˜ì¡ñ½]ïvm:zi 3uŒÆd&Sp{ÔØø hùq˜,¸@ê÷T‡©“M&4¦VùRä<öì1)M`Š™L ÷Õí‚ÆÔWä“ÇÍÆôëknYGá³`T~uMðÔX Ñ’ÒןTANr/%,¥4Q©à*™±dÅâ*¹¢tÅ*©º’3¯cÞR`,E]ÉuHKÔ§²·dýѾºTâ--ŽyKú³u)ÊŽì«Kþsí½ãçýó¿}Eq˜ôûâ+nm²ÆdŸ%ÉL¯¾;2õó”:4l£ù©3ˆÜ8{††ú×;”z7S£ÈÖ¿ßÜiL¿v[ÙH¯ê=Ô¢%½\òìèB(¥ÄR*†SJ³”Râ*U ­ÅX ;ˆ“¥Š±JÙV¢ÜpÞBRZryâ*„\ŠyKUC.Õu©g~RïêAR9‹ÆTõ³¶÷m{WÝ¦Æ “é+<5c± ¤”ˆöÉT¢„l-´*ÿ£²GÕw?ø¸ÆÓc3@€ @ ?d2Ðï›>ù\r~EÔ‡î;L ‹¥^‡É™L>aÍéw¿ü0o+Uãôëý¾5Ncúš x³ÀS{Q£dƒ­²ÃdµÿöûAãTc$«¡q”$ÇúgÖúnÔœI3 15ƒ2Ç€ kÒ˜îót}R)ãMQz8?ÌR|ê{” £$GGÊ,÷0Zj,#‡?Bä UнT2q=ȰQ̳Qgø¥Ø8No4¦>¹Õ4¹¢Ñ “ûî»ÿÐ£Ž³Ì-nÑ L)Hzç0Ùøþô‰ñ¬à*i.^íìu©nd¼¡ï ­ï ­ïž û3ˆz04,‡ ©ïo…ŸAî4¦Ë‡Ý–)²Žôª{ pɃË-D)ÞJs½ùñ“*ÄRŠ‚*À• ªT©S]¥¨‹0`©ä1´¢±”i©i)ž'.%UÜÖXª¸2ÞR!äRi¸%¤ÞoÖ ©¿ºQoÛ{ÀÄê^8c ¬X|¦î]ÝZÖ‚þÔ–*Ú¦ò·Ðºõ¯ñ+_bz—‹ÀMqNÎr6ÙÖ Mä<®åÕ–í¿ÿó_þ’ã/F.€ @(Kà½÷ßßÿ€o>ðÄìbó$TX\ºËe›bÑc‡Éu£ëœvýq—P-˜³iŽŠFF,¡×¹¦v–þ´–—uºe(—¼þúFÕþ“~ã´¶Ú·.‚0«ÈfkË×â0©qúŸüE“Ù2™uI&Ó’û†©lí jyûê.Í×Bl½ÖhXE›é½ÔÒ  1qg@€@ƒ HcºcÌÓt\>ìÖp@Ê•ªÎ/ *ùIâ|©Å%æºÞRqÌ(1¹=U]*æßð3ÇU°—¢Ç¼*6ªè´—Æd“+44vùX5IT4Ö£eý¶;K);´Òl$H¯öà¦9ê^Ý'i¯âüvo AÏã0EIú>üƒ¤§õ®‡m-¸Ø¨²—¢« C4%׿1o¢EQm!É ©·oiÖú®04ìç‘L.´¾{04¬ï+}¿é[NßuÔ¶¯8[66꙱έ±¯¸`–Á))ˆí"wÓ«o-gi½^ÕÓ@걜neÿôÌ$ÉI•ý¤Ê•›z")&ƒ‹[ó•u%[JË —j,%3ÄÕ"-%óÄ%½%? ²:.]ßeՇׯmÐ I_îf&ékݺ×ÕÕîâ3éOû–×K– AV}~•Éô…¯|}üôWbSRË›åì u÷àUF_5ì€ @èf2?Ëš'±DQzé‹L&#h=hjdYg™S~|&yKzU“\0Piô éΩ×Ú®ÄúR]ãÔôµ`lÌÂ<[ã46 ¼“NJ®’FPôÛ²ZhhÄÖhÔÄ”&mcëU´^›ÉyÒ‹6ÓoÛ€Ä  1qO@€@ƒ Hc1úéªR)ƒM%àKb,¥K¥3ÞK½%÷V&#‡‹ºòóo$3ÇGz~©Ý£1©=¢æ†î#ÂWÄo˜hHM©=¢Æ‹Š´Mî;™L‡y¬…¿-6¾¼,ÞþÕªÌêÈ ÃUÍ%s˜ì$õŒ­'jAÙötm!Q¥+é \ zêÖüÍ4Ð[4÷@E ©±T{pù½} So òþ>#k}Gñc­oŶH oÑ ‡É.ؾ»´ n}¡iY-n ™}¡9AS/9éÏxeq`4¦,(f³µú®77_›IcRѳl-qùÌd7õ•hòD¡áaÕmµiuç=¤ŸSq˜²ùÖd/€ @€Àž=f2Ý7nV‰Â²,PX\ó$%Ll¡íª[Æ~ï ÃVmx׺ËS‹"ñøq˜u›h]ixÉͱŽ65²ü¹"j‚Ù~²"`}©ã¦Ó¢ÀTsíׇÉNØ…\²hLnÖkàÄÂ2iÅ/Ém2ÛÉÞ«·h›¬.œýt4¦ŽªN.€@+4¦ûŸö‡¢ÂJV‚ѥ˂©ÀMI-5ä舌¥Xž¸äàQlÀ¨.u)6ƒ= Blö6öRrúz{Ec²¦‡iIj˜Ø‚›ân¯ZF ÙH õìf•Étð‘ÇZ°ƒy‰)~ –hI¯&{Æväzö–À¤Gk=u»çsYM®É6s¯ÚtS úþ©ïë€3è9¨õ]Ïа¹ÇCÃn\[ßc.N‡¾Ä¬ƾ÷LÜ´ï7•ÎÈ„ÆÔó›5ëwæNcºìª[Ë=üi½^Õs@… ª¾ê”–T4“R¢(Åó¾;ô|銟“8¾ö —+þ3¨ž]¬&fTŠºRб”–.zN­UZê㫤yM±ˆ¦ÇØ‹X˜ØÞ8LÖYfcsE\WšmcS¢U\­C¸·ÆeX_j²qö?D³kÜ›žå’sª‘ èO h˜Ä,Ù˜ŠÓ•¤.i½VjKBgÉ,T\æ‹Ö ÇY´ 4¦–© N€@§ÆtÛ}Oõ`@ª8Ì8+%9:Å•ÂpRlü(9r3 ‡ŠRæ´»¨KÑ<öÂ$v§.•L\/ =Ô5"Syã¶Ó˜¬aâOb÷gSØ«úmÃ@6d¡Mzö˜LGUw!K4üçæ·' ö,“ÎйJöîì%­×²‹xªIzä¶Çr=„[´TK ݳ+Íø]hLewÍ&P®õíaÊ|hXÃÖ¦%ÅìLS6-Μ¾Ö´ûг4šíþƒÆÔ:5˜;ið•·†}éE¯tæt÷È&ÆJɃ£ÿ™&'™¥TQQR öJ–R¹LpYèJ5„YŠGZj'i)ùˆÜ )Ù«n_âöÍn¯šÃ¤ %Zûë™LN^XœâöGA˜¼‡T¦ÖùªåL @€ БÌdºç±™®¡Z¶-‹8LbhsBlÁMõs »Õ¿f¯º‰Ñ–{®#á÷ùEY_jÔ8-Dv!¸R{QëÃd×(É…\²±KW¡û­ „I JiaÓÁº¤{/?ˆ@c➀ Ætë}O¥FEcLƒ¯¼%J ª”p•ÒÇ• .‹¯.¥IKQÊ¡øÌö®`H¨¶œqÑHP†ÒR»Gcr “dhXÝYýq ›Äî¶ïÍ}'“é #Ž-ÓøŠÉùSzì0é$«äRËYfg÷|n®’]Ž›c`ÏÞNêÍÅfö^4¦ÌP²£>#PÒúŽÂ—$††ÃlY »qmËiWÍ^rª“^rI6ûŒQFFcÊd»ÉÆ4èÊ[Ruu³‹ôª\f?$Rêr% ©œ¢´´ºœEÖQß_ØýW®”‹«”Z)=º’=˜¦d…+¦4óæêqÇJ Ô3–¼ïÁ†>¶6zçÓ˜,:¨ë.W‚d=³ZøPëj7Cßf»5~¦ÍdzøÙ…6ÉÕ&×Gì?¤‡©F¤l@€ ôŒ€™Lw?:³T`J ¤æI/ã0é Õβ\rê2sSýÔ°RÏš+Ú̆ ìw½ ®žqÈ绬/õ‘°qê Léµß3‡I`5pb¹ä´ ‘Kf¡e›ù­õZ£?õ[ö’ ¥hE úÓ…kÊgqÕ• 1q@€@ƒ „Ó“–ÿ+µØ€Tõñ¦4W©8œT:–TLÊ‘o©0”àÔ¥’A¢DÔ¥f¨KþP{Ec²DKjk¨ÑáZj’¸‘ ›Ç®±!‹ë¦^ôò¾3“É5¾Jæ·CPkFµ7“NÒÍ%°hLzðÖ¶Ó•ô|n©œíÉÜÂ5©À¢¢:ó©—›ÍÛј²áÈ^ú˜€µ¾mh86}(;“¡aõ·¸Ì˜I?öýf=0–"Ó¾Ü,QÊèðhLÌ`7yÔ˜*<ê©QÿþçÊ‘•*$ws/ZR59©4ï›%€+Éþ¦¯¤úE¥‚«”ÈWNWê`c)ÕˆjÆ”ÁG³Ú.d2ýÛ—öè™—mª„Ÿ¦Á=¤fòªÚ‰ð: @€ wf2zdFÔ<±±¥}è™8LZeб‹h«•Hð×ëO­tÝmy¯¤†]¿õ¥§ej¿Ç“N\“¹ÝékÙ/é·"3¹DúÓ½dëOÿ ÀŽÛ–SÛV'@ ]HcºåÞ'K¤ŠcOÛ4~téo†[d ¥ÂÐRUc)!-Å'·GÞRaB{ÉTö䌫:k½½4¦>¼e2ýàðc*Ïoï¥ÃÔ‡W—ý¡Ñ˜²gÊû†@¼õ¦þLö½œøË ιpðú-U([¶ÿþÏùKß\Fk©uê'w“ž S좂ftIøÔX´Ž*FEª0)‘ßÍ´¤ÐLJ““ÊúIa Y¥=ý ŸÅ Ji¢RÜUò¢+åMW*÷|ܾ“¾DÌd;iATÑžeo×Ë?ªÖùªåL @€ ÐÙÌdùÈt¿yâ‚™gè0u6Æ6½:ëK­Ð8íÃÔ¦L8í6 €ÆÔ•Ä)BhoÒ˜n¾ç‰’ñ¦Òï—\H•IÍáååHZ², ~IŽ%3r¤yK…,}á-ÅnИj¿ãe2}ÿðcJæ·{5ˆÃTB©ö‹-[ž@ÕÖ7Cý¬C4¦^Ìðí¹Ó˜ô\Xúðç£`A¯þÀ‚1:åÈÄ£2î‘EHòKòÙ1}MWU9)J=h–±”j•J“ÁuJ>¸ªæ~-´µÆd&Ó>_ÚÿÁ‰ üt§8L~E²+@€ @ Ff2ÝùÐôdó¤÷¹äj<6ë+Ö—šÚ8Åaê«Já¸U 1q‹@€@ƒ ÓÝO¤ HE£Ná€Ô1õ 3¥OzsÃ%F‘*IK-9N„ÆT×-˜L‡ãg‘Ë$—\]çУ1µG=q–µ¨ÐúÆaªbùíИzÏ0«=äNcºøŠáL#½j‘Ë–P?²’pÛk\Sx ,o&™@¢(•†Sò"*!*E¹~kQ—ümÚ]cÒA`2}q]ˆ]ü£Êê+’ý@€ @µ0“鎱Óüæ SíÛzKëK5Nq˜ÚºN;üäј:¼‚¹<@}O@ÓMw?QÓ€Tõ!§-f¼u%o)´[¼‘£¶Tuø©Þ»V&“ ù`‰Ã”©ދí[ž@j뛡áLê )Œ™ì$ÓÐáô£‹‡WFËÔ+‘ÌnJ{ ’S‘ü…’§É0]eTm‘“ä—Â#f郦y+íðÄYõ‘´6è)i2ñ*“/Gv@€ ô€@ÌdÂaêÃö}K¬/‡©}«2gŽÆ”‹jæ"!ô%iL¿õ„7 uºxèÍA^°Ú†œR]%o®{að¨ÇИzp¿ú&S:@4¦ÜX¼¥å ÄZß gUchLY‘ìý~r§1 zsL0òþ.ÒSãaÇ”•|ñ¨¢„TŸ“äÉIøIMv›:CcòM&þQõþk‘=@€ @½!àL&¦Þ`lÓ÷º¾T¦6­Á6SŽ*›K… Ð7¤1Ýx×ø²™7^Ù’2 •˜ñž«¤hL=»SÍdÂa*K©g7ïjy®õÍÐp†u…Æ”!Ì^î*_Óé§ŸþéÏþÓ>_Ú¿\ùÌçöþ/ÿ×ßVØ ÊK_Ü_é½(mDàÿý×/ÿ¯õוOøû›ÿ4~Òìõ[>reÓ¶]½üà5âíÊ.÷ùÿöÏç\8Ø?Õäò–í¿ÿó_þÒˆ`Ÿ€ @€Œ@`2ý?ŸúÞ—þßUÞ­ÐBQóäúhF@}©ÿô¯ÿç÷ŽÜ¿jãô?>¡qÚa•ßV—ƒÆÔVÕÅÉBhGtÐýoÿÜé\Ž4ý—ÿßßj®ÂxøŽÿÉ€ØCæG»ÿÔŽ·G¶ç,“é>õ™IÓ_¨üþÞ‡Èö¸í±74¦ö¨'β'Ôúþç¿ýßÎ9úભo††k䋯T#¨&l–/içÎsJ?9Vî3.¹’5L jÇ&ý'hMIßOt3gùúʃü£jÂ+‡€ @€Þ»ð³®9 ‡)ŸwÂõSÿç§–ŸW¹öq˜òyo´ÐU£1µPep*€:“À¶mÛªkh©ê`ö¶xõf4¦äæ“?¸êñö~Ú€¦] úRå3IZÒ²d&ŸI¯vïêÖŸ&6ÉaÒšv¿dοs 1uN]r%€ œH†bò2åJò²Ñ˜¸Ú™€æ‰©kE“Ô‘¢¢þõ±Ø,2¿[Fëõ§6Ózm`òS2Tv;Ãhƹ£15ƒrmÇ@cª[A U $C1©UëŠó‚ @€@ç°¨æºYJZ–Ÿd]fÖ_fsþ´ .6ëD“Ædë­©n)J¦%)ä’4&»"Ks65®[©ßZ#‡ ©*½£.©£ª“‹ äŽ@j(&2¥ÜhL¹ûptÚ[O‹ú^4%Ì®ÍrÉ)&“uËè·½¤î?ÓœúdˆÉT× ÆT®†nŒÆÔP¼ì%°ûOÛžYw • k¾¦'ÔGV|Ö­Y»ctcÏÞ!@€ ¼pýb6ÉO=e2™¬ͺØìÇVjK“.ÑÒÏiA¿ºÉ.š)dõV>S½Ä·=SãØ²g4•SSqs0@€ 䛀³—Ü$?Ó˜~ɦJTRß™MþÓJ­±e ΔoxrõÒ’oIåd,Y&ýhþT‘±¤PLZ£­´õrå\Fg@cêŒzä* @؃ÆTñ&@câ3ÒÎ\4kÓ˜4OL=*¦+Y¤%‹­ë„ÑzõÉX.9ý¦û¥ÞÊGcª—Xã¶Gcj[ö ¦@cj*n@€ @€@û@cjߺãÌ!@(%@4¦JwŸ—v& KÉ…V’Òd1°õ[×d¿õ£mÜK¶F“M3kçKï›sGcêîiGEcjºàL Ð+hL½ÂÇ›!@€ @È4¦üÔ5W @èthL•j©Óï®@cÊf/w…ÆÔK€¼­B©Uj‚ó€ @€ @ Å  1µxqz€ ÔL©*4¦šo$6„ИZç@cjºàL Ð+hL½ÂÇ›!@€ l ̺eÏKc²Ý%{k[?š³óã5ír¶œgN  1å´â¹l@€@@cªT©hLxËsIh4¦F‘­¿hLõ3ãhIhL-Y-œ @€òJ€Îâ¼Ö¼®{T×^sß89Ǹôv €ÆÔµÄ9B€ P 4¦J”h™Ör±Mû8u¯=ch}gVhL™¡ìõŽÐ˜z@ 5 1µF=p€ @€@H€ÎâßhL9®üö¹t4¦ö©+΀ ÊИ*ñ¡eÊç§³  1eZ¿hL™âìÕÎИz…7C u 1µN]p&€ @€Sžï4¦<×~Û\;SÛT' @€@hL•¡1ñêlhL™Ö/S¦8{µ34¦^áãÍhhL­Sœ  @€ €Æ”ç{)ϵß6׎ÆÔ6UʼnB€ P…S%@hL|€:›S¦õ‹Æ”)Î^í ©Wøx3Z‡SëÔg@€  1åù@cÊsí·Íµ£1µMUq¢€ T!€ÆT  Î&€Æ”iý¢1eгW;Ccê>Þ Ö!°û?¶=³îÀu;F·Î)q&€ @€@~ ÐYœßºßƒÆ”ãÊoŸKGcjŸºâL!@¨L©Z¦|~:›S¦õ‹Æ”)Î^í ©Wøx3 @€ @)è,ÎñmÆ”ãÊoŸKGcjŸºâL!@¨L©Z¦|~:›S¦õ‹Æ”)Î^í ©Wøx3ú„ÀØåcUúäЀ @€@Mè,® Sgn„ÆÔ™õÚaW…ÆÔaÊå@€rL©RåÓ2ÍñG#—ŽÆ”i5£1eгW;Ccê>Þ >!Ðïþ~]Ý]}rh @€ @ &tׄ©37BcêÌzí°«Bcê° år @9&€ÆT©òi™æø£‘‹KGcÊ´šÑ˜2ÅÙ«¡1õ o†@ó ˜8`¯+öêÿX™LZ–Ò¤ßÃæ±h„ÌÞ·í­ß פ—´™~7ÿ$9" @€ wtçø@cÊqå·Ï¥£1µO]q¦€ T&€ÆT‰-S>?M)ÓúEcÊg¯v†ÆÔ+|¼Í'°nÇ:3“¤.ia×wiÙÅgêÞÕ­eûmçæNÍ?[Ž@€ ä”Å9­øà²Ñ˜r\ùíséhLíSWœ) @•  1UâCË”ÏOg@cÊ´~ј2ÅÙ«¡1õ o†@ó (êÒÀu\‰Js6ͱ°LúQ&gÒŠÃ$IEËúÝüó䈀 @€@® ÐYœ³êßúÑW¤1MYûsÇî¥9ƒÁå¶*Eí™=<*gÿõžÓÿÇâŸZÏ @hOhL•ê–i{ÞÕœu­Иj%Uv;©KúµòÒ[ç©CcúëGº5o}0µ×G`=!€ÆÔj¼}H@–’\%€S—\|&­Ô«òœd8ieSÑ‚El†@€@óÐYÜ<Ö-q¤é¯¥Î¾Ô²âíá-qŠœî|/~ P'£Ž:ª'Ÿ­¦¿çÃß½ýÕü›unÓÌ!@€ $ÐYœã›bèUNž21Ǹô6 0uÂמrœ(§@€ª@cªDˆ–iµû‡×Û›@s5¦9sæÔ9ÌÞ~›ÿ—ÿ»ýιÞ3>ÿüó[ÿ¶Ï—ÆtòÉ'¿}ÔÖ¿—í¿ß”Ý7ß>ê˜ãNÒÂf•w‹å­wwå•ß½éÊÛ¿{Ã+›Þþݦm»\Ù¸mׯî l(–^ßZ,ë·~´~KT^ÛòaP6e+o}¸6*¬}ëƒ5oËê7?ÊAyõQÙ´s•WVnܹrãûVV¨lˆÊò ïåu•÷–yeéú÷¬, ÊŽ%¯e±+ëvtËöWÖË¢µÛ­‰ÊÂ5Û®ywáê ¼ìÊ«ï.ˆÊ; ^}ç%•UQyqÕ;AYùÎ +ßvåùo»2ÅÛó—«lS™geYPæzeÎÒnWž[ÚýÜ’¨Ì^Ò={ÉÖÙ‹ƒ2«PfvmueF×–Ÿœr¡ÊŒW¶L·²((Ó‚²9( 7™°à³Ÿýlë’?þøcéV× ¿çËû°téÒÖ?a΀ @èptwx—½¼¡C‡þâôó¿ý½C¦NšW\w«ÐÍ©[ô积۵ÕÏ•óƒ @Õ 1U"DË´ÚýÃëíM ¹ÓèÑ£9þ'%¢EÁ²_¡²`ÉêO}úͲ(øérŦ·Ëk¾PQÁ¦Hó(’…Ó'VnJq' âDÑš(Q&|_bÝŽÅi²„3%G"Ô$œ#á gG85·#J½ˆ)Â%:DèB„"DwR„øþáÇ\<ôfYò|Âù×wà¶þmŸ;I¢’}Šbż¥›ouôq'•|´’ö’4¦RI2SªÀä9Lmð>o’™êv˜<©f‡)ú(¦8LÆ”î0ESø™,jL¥Ë.Ïa’ÏTª1Å?Ÿú Vq˜z©1Ur˜"É9LZð4¦-£1™ÃtçýãT}óº6|高L­ÿÝËB€ @ Ó ÐYÜé5œz}’BN?÷R5N_^Õ}àw1™ry´üEËaú÷ïºðÕnݨ§žs &SË×'@€@hLhL|HòK ùSÆ/~t˜‹©zt˜Bh˜ .LIh˜§ÂE„ÑB<"LmÓ«i!`œ;á‚¿”üRêKb¾”| £½¤†z© 1¥‡wIÄvIjL.¤‹‹çR!Â`.‘Æ:LhLmóÍ hL•ü0KnÙ|À›BÉ¢.•^ Õ¥êöRácV£Àä䲎Ãä9L…PLÑG±W“b2UÅ9L ÅFcêq(¦Y^(¦™¡„X9ÓÔvˆÆdÓÈÑãõ Xh¯í˜û &SÛ|)q¢€ @èXhL[µe/L:Èç^ªySÖ8]°b+&Sþî‚V¿bs˜­Þf½( C~êÙ˜L­^kœ @•  1¡1ñÉ/¦kL."L̲ýŠÝ/u½*©–ÜV iW<(Œ‡)LiU´)Ê9LQ2«”LV.Uà0Å܉rÙ«²ŤtUÉDUÉU)ù©ü¨.‰´T±œTÒ˜*S©ÃTÌFµp3јZñëBÓM·ÞeŠ’+ÅÒ;¿ûí­w鳬I“–‚¨K¥—„ÉÿŒU°—‚L…[d/²ÈU˜ÊaZí%’ó-BEE«’K®SZ:¹ª¡˜V–f”óÒÉéCf” "§•Í(W9Si:¹d(&§1•Ë(×ú“s˜ä¨9I*ès‹^'&S+~qN€ @È4¦üÔux¥ÃtÞ¥~ãTáÖ_Z±å[ÄdÊÙÐÊ—8Lß?ô•ÕÛœl'IöN9ûbb2µrÅqn€  1õü eÚsv¼³ô…Æ”FrEX^ 5&9~‰gµ* ¿´kCw"«UõDr®}ë•5oF%™K®r¦R&¬Tt˜üÔUÉPL^:¹H“péäütUÉŒr…b 2ÊÅB1Y4¦¤Æä2ÊI~@cjŶ4&‰JÉ JW|ìIîOÿCå–ËxKág,ñ1‹ÙK1iÝæ‹%ÒãŸ:}üü,rEI&“-E`J ˜.©QÑjÈ%×8L~ÞG}bo˜Ã´dkÉG·$ÜV—RјN:åÂ@cZ÷ž¶p³>Ʀ1ýã?~ö÷øÄ/þË_Záþv“}Õºy„úU²¿Ù‹^ÿâWX¼dI+œ*ç@€ äŽÅyªrs˜4£1Ù8}aÙ–o}çà)S¦ä‰×ÚŠä0}GÓšm1ÙN“zŸyÖÅ¿:´Ï›s‚ @Õ©!Z¦Õî^ooMט|•"¦+éÏ^ 4¦˜bQcP˜ra"›¢²JñÆ~‰®”ÄaÚð~Q`ÊÚaòÓUÕ’Nî/¼‹‹íâB1“S• ÅTÏE“§1¥„q åiLßüæ·bòC ~ öjÁsjÜ)Icºñ–»Rå$[©W|쉶}¢¼™ºn*6† ô€S%h´L{pKñ–6"ÐS¤R¤óIcúL¥ 0[?’Já—*öRÒ¦ð#0EYä>pEY©|"9_œpÖ„ó%gº–8L5:L¾‘y:¹PcÚòýâhLÉ0.ÃEÓ~û#&?|´ûO­v×çNcºaø]f#¥½*iC·%¿„a–Ò"-Ùgl}i¸bÈ¥Ô´q‰›ñÌBŸÕ~©ÆL=˜ü¤&¥©ÛÑ•R©¶DrÒ˜V%J÷¨…•ï¸hi)A˜z™K®¶8Lr˜ôéuS1“ç0•Ó˜Þûð}ûIö¦þl×@D³nâµAÕH,›ùòk_üÊ×k7™ÔµäzÙ’]c}xÕÖI×ÕÕ¥ŽÑÚOcï½÷¶ÎDëŠUï³Öø]õïŠ-!@€ úÐY\¯vݺà0¥4N-È5Nç-©ÃdR»O­¿ºˆhû¤õ¢ µ íG~Ì^{íUUޱ£KŠ2áIŽ;VV}c²ÅZ¡ùé6¶…Øõê´ý5=Rž;´.ÐÜ/;œ»ä ïõ; l3khë·ö pýÙãID¶7íD y :uÝå66‡iñÚ·Óf‚E²:5oÀ™ë2™Ü «2»s´ÒéhIt=»4Û­W–ë*ÑAS?J½9™r•[áXôÉô¬®y @ vhL•XÑ2­ýNbËv$ÐS9ÑB~ż…ÆŠ‘\±!é-•š¯I¨Hu*ª‡_ª-S\`*É^U)ì‹'0u¥É -ÚËê ÓÕ q˜êw˜¶Í)„bzni·‚¹¤Çs)Äa’Ã$ÿÁ4&ŠÉO'‡ÆÔºqEcºaøÈècóÿgï?Àæ¨Î}O”û²oéZYïè#­ ÕlF‡eí#­£‘5-˜;¥/½cCcú–Æììë¶ ggµÛ²ÞÑÊV7½ì8¶­ùÏݪJö­ôž¡¨ @€òD€Áâk;îú7tµî>Rs¢—íÑzgÛ¬k²Gè¬íVÛoHÖ1t¦‹93É);¡1ÇÙª§-›‘c‘ Miš”­µãÉs˜ª†Ež“l§'ÁÔK•5üM›L6Èàú•tCFÌ1 õ=ëZþÈItT$´YpÃÈÌèa"ª~­×™~dG‡{Ìí"½£— ¿øš5Ðz……ÒíË?6Ý–“i­ó-@€@3Иâ(qeÚLbìè¾ÆTÊS/ùËŒ¹+>½û5äŠoË©°²Æ/UZEÅ©¨L×3UÙ^z«¡½T–(B…g/µ&0ù¾D©‰$L=Uy“›HN ³–†s»ô$v©$a ŒˆR¦Æy˜*"„²1S‡‰IåRz¬Kcºê†!U6’9I•¢O¿ÿ£ãÝQTûpr‡V鸪i,Õ”–¢ÞÒ*eZreC¬KÍ&^ZW%FÂ{)&ýR“Sã Li¶§Gi­µI˜¦…¦ŠÀä;L:€KÓ9õ¦´ec ;Lëß\ê¿8¡n˜Øžvµ8Až0{Í>_j<»œdÙ«{‚ÓdІÆü1e23iÉÏÚ:nœW ö0ŸjpF‘¶5ó¨lU öXgtR9½zÖªá×Í—–l¼LÛLéé‰jA€ @ g,ÎY@«›ã9L±vH%“=c£‹Óióe24fÜøõ5&[ÙÆôr©›ÌÜÒWtµîl*·em'd5µp<9‡)š0¬V*¦ò“`6Šrâ)ç53»œ£}hÊ0*M‘=sU¯ï¹ŽêSŠŽŠ¸æÛf]–/n­=L¬·û}Ì2jGÇyü¾ˆöbÚ“ ®Z¤w\ª3{ß*:6mˌɴÐù  @ yhLq¬¸2m¾'±f t]cRF˜°ká)JÓç.ÿôgö¨¡+™_QKZj4‡U]u©†G¶—ÂEür530U LåYäü‰äšMÂäMQV#^Øê{n"¹°ÃTÏejõ\r.“K 1ýy˜ÈÆ”ÞC\Ó•7 ©Rüª?}*É¡ˆ¢¤¼J=©•zr,Uû€föK^r³*i©4U\t¶¸ÊñÖDÖ¥@]j`/‰—T^ªNƒVJš²—bÒ/Yx“ ëLîX ¹Ø L}˜|ë°·I˜œ(‡IÅå^Š.¤'SM‡I¹ïì„»¨ä0UçB/ ÀU4&ÍÓ÷Ô³M&SˆÜ“‡Æsý!6÷© L¦Ùx«]º¼è˜rhŒÕFÜløXiÁ^VŸ¨ÆdµÒûN·²¯ûcµî¡[Û‚[3½')j@€ Ü`°87¡Œ4$ä0)¢_OÔU•ŠÉ{ÆF§Sç½²ÿ7ãL¦¨Æ¤«?½ij‹)5¦%Ù5 åî5½F—“ör¤öì.WJ"çÆŸͬ gç„Ìëã®UmÁ%-6HþE¨þ´Ô5vaëŒ+[3ª1…jî;OV_F±Jú“aÑËVö­[ÍÇêjšÓ˜üKr“ºÜÆm§f,Ùµ(”ZêOÿð9[mý}Y(-¸n-F5¦¦ŸÓC±DnÆd iL>‡×ROYÛ£}ÏuTë.X®§ it³îq2—TL_&¡Îì`ún5#bSÚätî»–êLï;wÍ:mèØt‡c2-wf¾@hH)W¦ ;+dš@÷5&©¡ŒJž¢ôÌsÆTr*\)çX*Ï^Uˬf‹ëq*f°8§ p˜ÎºÐ†m²û*‡ÉÏ\ŠI‰™õÄ¡]œNž·!ÆdŠjLN¡°ÉÇ¥S¸9Úlž¸è“3Âo—„ºÔu¢]®Úå­ïåØýëÐølLþ%§¾e¹vLïˆÊ7¶åš!ª1ù«¹kj½i»Õ+I»]¶GëYScò[¡ªþþ;ÑlL¡©ßŽÉç잃2z¡—ðÍ:L/OPªR1I¶S/ÕHÔÏÝ 'SHcòƒèwcQ2[.Ú÷\Gu#'5GEÜ–Ýfµ ~âwŒÐabHM5sZ˜z…ŽvTc EÄ=rf™ÙwµM×Ál ¶¯è±i5ïc@sz6¥Y€ ¶@cŠCÉ•iÛ:J%®kL¦RÔ+Óæ,“Æu*šÍSÓ[*?H¢° D”Æ"¬wÌ­TÏ™<.’ù¥JœØéç|ñ•‰ø)ä|S¢¦#Q%0óSmUÑÀHPšL´xs|.›œ 1yÁ¦ ÌÊwËÙ˜j;LL*—ÊÃøã¥1]qݘ#gÐuÆT6þª¼¿@NòJµXí*Õ̱dž`é«%-y[Ô[Š?êÌô³.Å«K&»´Ç^ò¦ò‘?.$zóÇÕ;Jm¨È•g¼Iëf`ê½À4i^pôÊaJ¿ÆdÓíÎaòÎÅe‡©Æ0qí8Á;óÅÏ}q¿y Õ ec qöéÙ.Œ›¥óiÈ°Þ Îa*p—FQÊUg³¶'Á‡©*aXY¶³þ?;ùܘÙåšÔ˜ÌE3tѾW’?*âë¢ædü¾:LÜâÇÔ¥%³m†4&×O\D쳚ûŽš?tc—­:6m/ŒÉ´ÜŸù" @ hLq”¸2m¦±Nv $¡1…\ ߬˜ZÒ˜ªµŠ:)`jK5…Š·Ô;uimyÒª}¢¾½T#ýRiº*=úâJüru30U‰š“ŸØE¡VžJ 0ùSÝ$L%‡ÉÒ¸|÷°÷Ûb¦¢ÊI6&]»ºÿ˜°L'õž$Kÿ.iÐu·­tÖQdAŸõÃãj¬PšÎ•Pî²Z©Ìº’sŸ_±ñÌó.±rñï¯1=pÀï¯ùÖ÷Ó¿þfö!G[}¬Ö8\§µ*0ÙÑÛWéí­«tòå&7úvêM³Žºd¢Jÿ¡Ï]ýð›NÎN¬BÏ<Û À]ûØ Çþqê™·Ì~|Æz“³ޢͣ§¯®g2idÍ=u§fiÙž¥soú'Øu­×:.I¾[-´‚Ê}äÛEþm˜Ì^ö|¡Ü ~­B5±•Mir[Àaêd?eÛ€ @ˆ`°8w¦òãëÞÔÅé5¼à’_õð’+Zbs˹aIJ1³_у‰zêéž /þêºý®›q˨åþÅ鄹ëkšL6Iœ{HwÝç®%íÿ:4tݽêŒ^Hús½i}m!tý½¼ÕWLœò¯7CW¬Íßm¹ÞåªöbÉ¢¶VÉšWë1—íÖ]YG›æ¿#»+Ǿ븊é#›ÝÌÞq«9&º„·¼>!a&k¦7ƒTë˜Ã´põ¶‡©4ãáO¯˜¦'ƒ„奲so›ã²Yß7iÍI×ÍP¼’ŠIO‚iàXãN?­o2ù½1TÃPÓ¡ uÝz”üQ‘š} æ Œmͯ˜í×ßiÍžãïÂH¨ÆŒÆhÑ}Ùf“i²³ @ 5hLqܸ2m­Wñ­¬èºÆT[¥¨HSf/•ÆTv-*rEŒYÑL ˜ž|K¥”K~þ©r'~ö«ßŒ™2ß2¿ÜxûCßÔ;ýN—>á ŠQSæýñÚ¡q¢äN”r¾L|vÅ ¿<}Ÿ/î{àw½î¶áÁEbPv¥¶½ÌUåOTÕL¦‡ÆÍ9ôèã L•Ä.%©î,rSÖNÂ䦢’ÆtnF4&7á’Ž6]ÿÚ³4.ïoܤrZÉæ¹·ãTÔØD(_tVŽbÕSÓå×Þs¨èS{õV¨H5’*U%1«NeJhöÈØg>ÿ¥¯œqÞ%*ò–4’ò›ó.9úG'<<æý«eÔÁ¦Õ~sî%=É–Js‡íñÙ=÷ùâWÜQ§åG=­!˜Ò(Œ_v~ó»‡ú)—xbšÂê9ãj«K¦šºtÊY«Ô9®Qî¥Ú“Ç-ÝzçÓOúÍE»tÅO¿dóÇÝþФÝçËÙ°,0ið¨§xóÇùG¬æ«7…œe`òKë“ì¥ÇÎþøôO|ÜôPZ GŠ9LCïQNÔ_ÊÕ/I#¿£fmxbæúSnœõëf™Ã¤™ãN¾~æOâµbûu-=üâ N]{ë¨å‡ oTmNªæ¨gVí]?'S Uå+€ @€ª0Xœ¯!‡éÔ’ÃäF9tqzé°.Iðoï¯bsß>nå7ÎóÈÓkuq:aîkœ5æÖÑ+†OyI§w>¹Z×§îâô©9ë¾Z''S¾øÑš¾¸þÀ`žÊ9÷ÅoE“†°®Þꢔ<ðì1ÎaRGUÿ´éä4F¤åÛÆ¬|hÚÚÃL¸küê a˜÷$˜†P”¨ÿ„“âr2õ­m|€ ô•SA®LûÚ¿ø~º $¡1Ÿ“Ÿ 4&·Âòž¹ªª¦« ›•â"“VÕ˜*Îå¹üº¡²)ýŒÔ¥}¾èwkîÄ…—^-S ŠQ“çéÍÓΚ±j³+vÿÇ=ÏÿíUŒœ6ôþ1Ÿûâ¾×Ýö@ïì¥Û}æÅ÷<6eöòmVª¦[ZžBîÎG&ÿë翚B®*S›&S ²¢1)¡¯ËL¬Gt´,7I&’Ë\Wc’±d¹ ÝsZ.Ÿ³}?݇líÚÓ5ƒÝÔ‰Ñ}zäóß/§)só,VÏþæ¦] T=³0†­@‰Jf/¹4K:À¦>·Êt%YJúwô”ù:Ø”iéôsš*è¼%­ ÷Úïtó–tÔ õ´&Í^¡ÃOEY—4hxÁo¯²Ïe]Ò(I áÐûG˜8÷üK®:õì‹5^símœröÅúWË· ýØø¹¦.=9c™\Â_Ÿu±Š†Ÿœ¾Ì–}ê9e]š6oý­÷Žú핃O>sÀ#OÍQÑÂ9_iç-÷Œ:éÌ'1Àæw¼ùž'7çìWH]zpì ýäç§~ý[ßt÷:Do¼kä¯~s‘Šy6ò–μhP¿Ó/pù­ÿ²Ï—£ÙÒBé—B“?õ£Kž¦üiQ©ålLë׬}oøÀ¤•ŽiL=Sy¹àñA?1kCÐ%Ö¼>bæú#N°(K`R*&ý«x)FzŽpäÌõÁÌ}/lÕHñý“×X*¦À`‚Ì‘O¯Üû ug—ËâN!@€ `°8EÁèkUÌaêú¨\œ^z߯и„iLº8½âÁÅÇ_>U§?½V&*Oðe÷/Òƒ7zôðÂ;æªø§z iÜìuû}ã߯Œß×ZòýÆdƒ0õe&s˜¬ÚZî¨^vsõÒ@c*åa:~Ð4=&uÉá»þñ¥|`‘ 7_t×óÝ9·ì0y²]ð°ÜüM'üꜘÙårÌž¦A€ ~hLq1âÊ4ý=˜ö…@×5¦JÒ-&ÏzáSŸÙ#ìWx–R(ÿKO¦¥—kKþ¤UfSÔœ´Ê쥣~x‚˺¤wFM~^E‚„f¬’Daù_œ;qÄŽ—,a‰—T† }ü/NÓuâï¯rÍàÎ+MW%wÂÉÁý÷ÛwÕmÁ;g^,;bê¼u|ûcOoÒ’\ê³ûGLýÜöÕ±'iI ò–4[œVÖA¨CQ ò–d/飫?péU·évdŽ›¾L^}ËR—öþ¾:,å~æ÷Ôqxå-÷f=u|Þý蔽?¿ï%W ¾òæa{þËw=2yàÁ1©aJÙKZtÓ°³\¡•u”¼üÖŸüìÔ sÖêM}tûÓ$-Yî%M$wðQÇ}h¢&•¾¦_ª/0µ 1I`zëžÓ>:­"0uRc2‡iÈ}#‚ÞèIoêBGœxóË¥(Éaúõ 3/) ›úÈÓ/k¤XçP€³aâ±s^9àLuµ £•I`6§“ÚÈi˜LIØ/ @€òN€Áâ¼DXÓ)g^Xº8-?]c£º8=aдߕì%Ù!—Ü3_#€z–Fƒ}¦1•/N—§ Ð36·?¹Ê¥b²Ñ7]œŽ}öeL¦¼ô—δÃiLud¦Àaúî¡óWmµÁ:7Ò­a7g;ð¬1öè­†JÔK¥1•ÒÃÐzÌ:êáÆßõÔêK¶Ú•ž³TLÖK5ޤ”Þ˜L 0[… @ OИâðqeÚ§ÎÅ—SO ûÓŽ«éZ˜_1qf 1Õv-š0+|§"$-9›Â©–pWeÒì•2(Jù_ö>jšMg…yK§ž=PÅ&­*Ï·z‡ä‡a#¦Ú,Uþ\UzÿðwÞ%W^}ë'î}|ŠÔ% ºx<÷â+ûþqÒ$”êE¦„®"åHÈ^ÒÂ1'ž¦™ã$HóóSm 9ý«¢)ªäBSéJÓ³—*Óf]~Z.+º­”ž)äüÙ¨ÜrÑL.™Ð˜ÌDr“˜5ÎÆdkG5&ÉPMŤæHcºìêÁõd#½¯OøÁ±1+ÄøI5«Š šX¹èÒ«GO™§…‡F=-iI˜ýkGšcV,»Ri¹îRv•ÝÒR?ÑHñyCæhŒøÜÛæhÜMÿZ 5§1bM$¤­“ÃhL[ÅDÃÄW=¼Ä&Ñ À‰&SêÿB!@€ M g3n¡Z—¦ ¢§Ö0É&=`süåÒ˜æÙÅ©ÆtqªYºtqZzÆ&ÈÜïš¿¼fº³C‚äʲɮÓË&Óýw†/±CWÜüYLܧœÉ†bªe&9Lßüî!óVnñ;ª˜ìÉ@ŸØŒ‡6—\IcÚnÙ¬Íaêwí •žéäBO‚•ziÙd:÷z) PP¯-ÉÅo;€rH )‡Ýš&5I ëS¼J1aÆiLÍd~‰šÁEÜÚ²Pš®Ê©.óKE¨Ø9kÉ+ò%.»fHH]2‰¢t (éâ ñR)ë’“–Lc*=ßb%P&T,Õ‹ŠÔ¥s^yïcST´¬l/Jõb×Jï"AB šŸê®G¦hÐCj~*Í'A²ºØ¿*ÃÇÌ6AÂÍL˜ü¬.5&6ª)[“ÊÕÔ˜”¢ÉMW7SMI_Ë®ÃdÓ®\Ï7Òûúôˆï³‚—©L’•ðáTû¸ªˆJ~v%›ÎS—vjÙš©˜Æäþ Rœ•4&SOøåé*š¦ñþ‘Se,Ùd*NWÒ›ÁqX9öî{<Иt*åR0OÜÊíò–ôŽ%@Ó±g“ŽCÁ1{ÉiJ¶dE&Ó]¥ÜK–MÉ( ².Ic*%^òËY rsÆéàÜÿ[Ë^’´¤iãtˆZÊ%Wθp4¦ò±ºpó×¾y°;VÛk/9™IÒ©„Ü&ÿÏacæ~ïŸ?ùá™ÿ{ñ2쬭Ë7î·Ûñ'žÒ#™z³ ꤬‘âÇg¬s£oz3û•`˜xÅö²ÆT&~`òKœ9F“—±¿’Š©2§ÆÞ6|Òûç½ßÿÛMþ ² @€ ÆИ3JûÓ§OÿÒ¾_«z²’@Zƒº8•Àd6J ‘Ã4ðžyæ0iœÁ4&ç0雲ÃÉì®Áõ˜ÍßÿÃg¶üâÿÓÍ pö• ¿öì¥ê˜·.ßÿSŸÞcÖ¢õ=Cvn¥ü `0ȦÁç0©—êOßaR¦‡)4\%“ë¨{a¿qGüÇlpkëhM†ooMû7õƒ I ©ŸF—t_cŠU)ÆKcúôu¥ºfEÙRr•4K.ù‹“–,É®+Ê·$wâ× ±©âL]²¹ªL¢0}BsU©„².I“PÎS—Ì[ÒtUÍÐ-k¯ô ¿h–ª[î%ABÉ)÷’ Kò"uIš„þô‰ácç|fÿâr/‚Dlú¥¸ùãJ“,ùÉ\bÄ}”‰lLvô†²1ICr“>í…ÆäÛO=1HcúýU·ú9ÇBËúTS½jB‘ÃÉŸ.rhy•¾ùÝCg-~EG×ÌůXj%QOLz^ 67œéJ:Òªó›•Sœé+nŽF]æ êÀ³É%-ÉRÒr0"óC$-9sÐIK.å’Þ  -/‡Ê´$iI™–,—B‰„¦1é°ÔÑXÊî³M"¡ŠR¢Ù„qvXê©J¹„¦+}ý[kª8;,å0iæ8½ÙO¹—Jçþß ŽÒ¡Æt¡’éÏ?ÞpŸyKr˜ž|ö%iLãf½${é¾R6¦ÙK½Ò˜>½û½ËÆÔŽ'#OüÙOÕ{ºœ7ôväÀ Ò˜lôMä5ô6úÙ ¦£iŒøðl˜øñéë5L|ÿä5áéäªàäií»ß×gÌ]±vÓ;˜L=³Qm@€ ¤‘S£Òë:)ӯϸ 'g{%´Æ7tqZžå|u0,(‡iàÝóìâTC Ò˜œºÖò0Y’`=ÔNÎ]ž[6¦{† ]ûÜôwWÌ(hžvŒ'ä]ÃlLz–oùæÈºåÑm ¡hðÄ¥²Ö µþôæ’›põ£/X&—Í:”0Ìec:ã7g©—¾±¤:37±ƒrO`؉ÁmÂ×7ôú§”/@è<4¦8Æ\™v¾²‡$ $¡1ŸOM_,©öp½Ð*vúsUùÞ’=Ie9_FN|^fÅý·´ÃЉó/¹Êt%›¥ÊŠô K¹Tv'Vl—2qø÷+bh¸W~ãÛ‡H“Ðlq,±|›t¥+o¹ß&§’,1åùuÒ'®¼ù~?Ï‹2¼(ý’å^šøÜËv])5BÿJc?g­nÓ?0z¶æ§ ®4‡'óí¥à Ô›“Êe`j˜~)d5eTc’äIáüC©YIOàí¶Ûnú¾½|*É#³—û4¦+ouù¢ úôðïë'Lª¥"•'}ó>*KV<0tPÙŸJ¡¤#êÔsêß?\=DÇØu· Þ9;xGËîHsùÍüIå-¹?o6ZAQš¥glС¨#SE+<9c™9-wâiîØsÒ’æ‰Sѱ'oI“‡NZÒ1&“Iù–tdÊ[:録u4îýù/k*G›3îÁ±slÂ8Ë„VN‰V:&U,1š~ü³SuLêàTâ%•ÒÁhL²—†>8Qº’¼%›9î—§]ø£Ÿž¢ÙK]v‹~qÚ…_;ð @cZ$™¤JSÚùAñR Å‹‡õ>m&“4&)>*µe&]¢wæ¥îzé•·–g¬¸¥:5k¤ø•‹Ëå¤ëgX”LJ¦“ sÙ”Î}ØEã-•‡¦½¬sŸHºŒýbâ;LÖFL¦Î“­B€ @ x,ÎKÌe2ü› ܳ6¸a§ÊÀäÔ9Lß=Ï.NUtq:|ÊKzöéÂ;æ§Ê§¿»g³CÜE}Ùazp”]™ª¼û> ƒóÒÚÒŽë¬J£ÓËœûü k^9e%nÙfEq½ÔžS‘·Tžñ°4„¢?m.€‹î|^y¬Õ?­\zß [éY;PãQóƒ(ÿY¸3Îàzéo¿ß–Ʊ@ Æ]ŠÆ”HQK’S\ع2-äAQ Fw]còUЍkñä3ÆëW4«U¸Ì/&-Y±LKVt (BŽ„•Ç'Ì}jær-ÈX:üÇ[Úó–,É‹¥\rîDpaøíCT”ÒEj„¬‰`θeÛl¶8•‡Ÿœ#ƒBÓÆóóÓdJèþû¡G§"_BY]´šR.ɈqÓ]O\|ù­&HrÔ±*$è}¾,GBv„œ»Òt¥æäqµ¤ˆ^YÔ˜ ¤ÌLÎD¦¦~ÔðÍò±ä9€þAåZ;GLœûû«‡è_—WiüÌåzGG—o,M_¸AÅY\Qr3;ÞL|tüs¤<õX*ã¦/³âìñ2›¯qê¼u*îðs ´t¦¤%Íà8Y%Pa–n4÷e91*R—nºû S—‚yÇαÇÔîxx’-È(4©pÄ”%7Ü9R3Ç™ºôÔì—žzö%;8å-Ùñ©å[Ò!úؤ%×Ý1rÈð N0¼÷‰Y·=0AÂÍ=O̲$i~ž´¶ØK½ÍÆä†¨LfzoøŸþ‰òZÇ4&\Öc}±T}fììW}æåGžVY;qÞköœ«¾©Œ˜±Þ’c)Ó°Ékî›´æÞ‰/Þ;áE&HVܯ¨Ã„É”­µ… @€@ª 0Xœêðô®r2™NúÍùÑ‹S]~–Õ•Û§—r0[‚çòÅéÒàâô±gÖéúT§÷éâtâ‹O=÷Zȉ:L˜L½ OÖvSD`r­7“iÎÒMn°Û†¶m¨M£(ÁHš{ ¬<ãá¶Çg¬`òK*Á(ʤ5æ¾Öã0Ug³Öƒp¾Ãd½“©½6B L‰®¤˜S\p¸2Mq×¥jm Ð}éècL®¨éNŒ{zñ?|z÷†ZEyx¡ŽVá»JΦ°g¨ü¢«T”ðÅŠ“–47œ” gPhaÚüõ*vK݉NŸP¦%MQe÷ÙUîztŠæ§²”K£Ÿ~A³TÓÆ•d ó%,ý’oJhr*™ʺtùÃôoi¢¤ ÷Òý£žUn_蜽ää‡ iL’ìzä›H“ôf© Oš6!)äwWÞZåÙáQ)úTST?Šy§t õxNôªèq:Ì|Q©²Üã*ù“2F=Á²·T:êBž~6€*Á q¥Iâì ´"yP%˜*®r(:iÉÜ ŽnA9áÝTŽ•c²'%ZÈ+¬NŒ¦'Ûªr£õ†‘)Û«.ù™™z•©êy;̓þØÙÌT_czw疫ʇŸüíÝ]*Mê´¿½â–r¿*­‡Ø<¾ÃT h;‹”¥ë¯5{oáC d‡SvbEM!P@hLqAçÊ´€‡D¡šÜu)P)œ\áåI2›bì´@cªgVÔÕ*VWpVB…û³Ú¦¨ö(*i–Bɖ̈ê ­‰@–¨øU²DéâÑ/54‰EÁÌq~â¥ffŽ«JéÒ·Ù¨2¤1Å©…Ó˜zŒJÂ1_<Ò§:öB’;lü…z‡PôýZŠR9ƒ™ŸWɬ”hqÙ•ëJ•|<µ¥¥ÀXª’–ÊG '-)Ù’ŸoiFõqhÇdï¼¥RîêÒŒºÔ¶9ãÎ4׺Æd–d&•Z/ N=zô^3/ë'™)ôùäþG÷jŒ50™ÝÒ3ôV{ôm›Ok9LáDèñ&S¡þ{Cc!@€ Ð) wŠlbÛ•Éô«ÓÏ÷’FW«!¥A yð/N[v˜B&“.¥UæÞÔ?Ô~]}í·bPØqw4 »d2¦êÓ•;ž÷æt«ã$…µ$7é[9‘REÉŸ|±GWªˆµS+ÕO°Tˆ‰äX²ÇË¢ÒR(ÓR]i©Wù–d6ò–Bgç&Œkè0i…¾jLõû›Æ§¢£«¶º†´z{üü丟^2èæ‡´2Q`Ïè[ø B—‡)ü¨k3“ãÞy÷o½­$ëC€ @è!À`q{Ãù ìwZÿPz`7ËyOz›I‚{—‡É9";Þz?þR:æê; M Œ7þ€o=øÈŸÄ¬Ð“ŽÌ²%¹²ÔÒ&ÕÐ’êÊIì«V”â,¥:GZYa±L<‘ìJÞ×3+\m]©Nš¥&3-…“-%:O\3°[§C“ŸÒh©¤l ˳ô¯>Õ“y*zSUrµÇFõ¯Šȳ,Mõ^2™.ºì&Ën“KÂäžs †‰½'q˜2y¢Ò€ @È4‹3¾&*/“éÄSÎë¹8õ2—/N#Ø´æ0¹ j=ä¦âÒ…³iö ùº ÖŸ2Hlºv»Ê¶ì8M4ˆUrH@&Óþß×?£cA¦Ü™·dR=̦÷-͘þµtM¼ ô@cJol¨ ð1S\'àÊ”C$ß’Иb\‹Ç'ΗÆÔدˆ8á©ßBBEå¹'B¥/©^J·×«JÝdKiõ–BþS&xiLJc#éÓƒŽøIƒã¤¦‡ä¿¹dKÍe5«˜yß"ó/ÚDŒ›ƒRšˆ±®¨T;µRYs©™`©JWòÂì¦Yj2'S‡4& ›Úv6&¥"IÿêÉQ³—ô²ø*–{É$µ¤÷Í]2™.øýžÀŒ»Ñ·I•ù5q˜šÉ:€ @€@û 0XÜ~¦iÜ¢L¦Ÿýú¼ª‹ÓZØôÅaò/¥m¶8{þGæ‡þ”¨ä_SG/ºíòœW‘ ÈdúÚ7š8w½ž =æ§²î‹ÃdМ¤ÐXÞqŠ’MçÔ9íO×o‹&Ú´@cJ{„¨ M).ü\™úà(@ã»®1Å«N4¦f]‹%µç}kRTªž–ªñÌTQc©lMÔœ!.&ÃKå.|“6B—WCcÊäa/I9lêéDz_ŸêØ‹Y!æ£ò´nõçwsZR%‰ŽiI®TùI ,¥’¨ÉiæTÁMõ\¥FºRNr,5:èÆÔÃC&Óù—Þ<äZkŒXp˜ºö@€ Ô À`qaº…L¦Ÿž|®qRCúâ0†" í,Àd:ð ñÏ­·<ÖÑÇÀúè0u¶ölH4¦4D:@u 1¡1qp—@SŒ/ñÈøyÒ˜šq-ÊfEdÒ7_¨ˆW)ì1•%’`©<£QkÓR¥[ZŠJhL™<HcR›Näÿ©O¥1ŬP'CRHHªäLòÒ&¹üIq)”Ü‘VûèòšÅ‰J1®R%»Rát¥zbS¦5&„2™ú_zC0ñŸ—¨ß‹Ã”É“•† @€@n 1å&”M4$0™N:×]œº Áº8Åaj‚«tƒ€L¦¯xÐSsÖ¹Ôãþ`QËsÉu£êìH4¦4D:@hL-ô®L[€ÆW2D )F¥xø©@cŠ®P-$5ÈóÒØ¦¨«RÔ5(‚ñ Wæ7ÖójM 1eèðí©ªiL¾QZÖ§ÿvøk®PWè«'úùïÇeN M¸X9ºjù€ö¸XØRªž®ö!7£ÆýaÄæóå{ͬkLêÜ2™ÎûÝ ¡àâ0eò E¥!@€ ' ç)šM´E&Ó '3i~ð\+8LMc•îL¦o4nöË¡Á.¦îÅ€=A »И²;j S\¹2-À!Pè&v]cª§R˜_ñГÏKcjì!õ.‘RUª—`’¢:E•«3+\IœÈ«Æ”É‚4&MÂeÓ±ùÅM…¨O¿wøkÍŒ’šù3’z¦TŒÕ’êúIu¥êtJ:Ø•Z:Ýä@c2“éÜßÞàζ8L™<=Qi@€ 䌃Å9 h͑ɤ«l¦&P±Jbd2í÷“`ç:*SbÁ`ÇÈ4¦lÅ‹ÚB `ИИ Öåi®G )F¥xpÜóÿ©Ý{éZôB¨¨'*yy^ÂsRåØXªib¡1eò!I3p•½Z^‘>ýÞa?vRQË áC¨Vš2KVæÊ¤`R0+%')TÈ¥Ô’¥ÔУ̇Æä›L8L™<7Qi@€ äSþbÚD‹œÉD¦&h±J2|“ ‡)™°Wd‘S£F!PhLhL…éì44B ë“2ÂÄÃÇÍýûؽyÅ¢®SQíQÔµ”Èó1(И2yšÆô“O¿ööõÊO~~ú—ö;ðÚ¡#z[®:"R¿fhãrõÐÇ) øÎ¡?R‰©ÀE—ßöéÝ÷X»é¿¼ñöû)<”“é§]´ï~_Ÿ1wE¨Â¡?ßy÷o)¬?U‚ @€rE)WáìEcd2ýøç§+áÍ=ŽŠ¿8Ýöæ{½Ø.«B }ÌdRG=ãÜñ½tÓο|øÑGíÛ3[‚2K)³¡£â(4¦¸(seZ„c ÈmìºÆ¨!×Â3+.¾|ÈÿñŸþsŒhQË©eQשHÐ"Èè® ýì´˜ÊÿúœK¥¤_Ø­PÇõСC¬~)H~ùçÙç¿ìù‡ÞäÏø§ÿç¿«Ä7ðØŸö˄Ƥcù¤ßœˆÃT¨s… @€@z 0XœÞØt¼fGœòÜò¦Žƒf} ð»;÷;âä=q˜ú€¯B `И pš l@cBcÊV¥¶í$Ð]iîܹ!×b¿¯àßgÿû~íSŸÞ=ÇjAú›&×eï}¾_Ï¿¿ ©‡a'¶?ZÁ§¨I Ù˜t€Œ\µÏÂWÆÆDuƒ @€Ú@€Áâ6@ÌÀ&výuW|-}“ ‡)-d}“ ‡©]€FC  hLM@b@ )hLhLIõ=ö›<4¦vH<½Uò·~ ]4&4&ôš@ 5&—ŠÉ%dr&S Ï;Éÿ¨S@€ @ ÓИ:M8Ûï?¥ÿð¥ÃVÄL&¦† X¡Cö¿wÿ-»¶ÄoÜL&¦…€ÍB ИòEÚÜ@cŠ -W¦¹íø4¬D ©R¨]cRH4šS6ï|wçŸÞ‹_‡OóD`Sÿo¤ê·ÑOÅä'dR%ÿò~ºªš*nT€ @è ‹;7›^óúÙ!c_«Ú,ܲÐþUr&—ŸI+XEeÌ~eû3µ§…! n¹×-{Y÷Ó¿êú×ïnyÙ–l^ØPx* 9 T@c¢G@)&€Æ®LSÜu©Z$­1éNt¼' ÑbëïæÉ%È\[¤»4¬ó‡}Ô†ÞØÖM]cj+L6d„R1ù ™’©{… @€ À`qÞûÀàùƒe‡ š5H •Ϥ¢äL~~&}ª”®Ii5ç<å íKõIõ=u×é¦ýèÑ*ÖMW’ä¤e-ôÛOÅÿ(]Í 6€@âИ€ê@cŠë\™rìä›@ÒS¾éÒº  1%Ÿ]C  ¢©˜B ™Ú°6@€ @ ·,î-±¬­ïüÙ!&‚襗öÆÞÔ¿–ŸIÖˆ ’¬µ’úfž€Ì$“íä3IT²ö˜c§—ô&}j†“½#ñÎÖç@ ŠH14¦¸àpešâ®KÕÚ@© ÙD  1¥1*Ô Í¨™Š‰„LÍdM@€ @ #,îÖmÔÙ!Z b5óíË̤w,Ž•5€ªƒ€D:›ôÐ9vÎÀÓ›ê“r˜¤7éS뢖<¬lh% ÐhL½¡Åº€@—  1ÅçÊ´ËÝ‘Ýu™S—³»n@cêiöøàÃ÷6¿3ÝÊÚ7‘½4}ÃÏÝ;o½·ºûd“€ @€š À`q2½Šùj‚ÓDBvˆ&éM’™¬™c_k‰šxA ›œZ眧jèM˦þiµrN^7+ɾ @cÊ@¨"ŠK).ö\™÷È(FËјŠç¶©€A§Éù$ðÎ_7HcÒÿVóÙí’/C¹$€Æ”˰Ò(ä…S\$¹2ÍK?§µ  1Ñ3rJ)§¥YÅ#€ÆT¼˜Ób@€ ¤˜ƒÅ)N[ª&9ÉæÞ2™É^˜ô¦™LöŽ26Yò¦¶`g#½% ®¨²ë¯»,y˜½\ŸtUÝØŸ±·{a}@ ÿИòcZ @cŠ W¦îÚT½ hLM@b•,@cÊbÔ¨3j@c¢[@€ @)"À`qŠ‚AU @è4¦¾ñãÛ€@G  1ÅáåÊ´£'N)ñPÎ@cê W¶ ®@cê:rv@€ Ô'À`1½€ Ü@cÊM(iòH).ª\™æ±ÏÓ¦hLô†œ@cÊi`iVñ 1/æ´€ @)&À`qŠƒCÕ @è4¦Þñbm@ «ИâpseÚÕÎÈκN©ëÈÙaw 1u‡3{@Ç  1u1;€ @€š'À`qó¬r·æ“k|aÛU¹k Êç6ž=mý1¹j:J©£xÙ8 Ð7hLqü¸2í[ïâÛi'€Æ”öQ¿  1µޝA mИÒê@€ B`°¸Àá¿cán3^9±ÀhzH¶{xùg3PQª¤„SJA5 ZИâúW¦5ù&€Æ”ïø¸uhL>MÏ4¦|Å“Ö@€ @ ã,ÎxûR}4¦¾Ðã»Ý!€ÆÔÎìù!€Æ”ŸXÒäS\P¹2Ía—§I4&ºCN  1å4°4«xИŠsZ @€ `°8ÅÁétÕИ:M˜í÷Sß²‹S±âMk!1hLqãÊ4cÝ™êö’S/±zV 1e%RÔ l~gºFŠWî )@€ @É`°8ù$V4¦Äг㦠 15Š!4&: bhLqÁáÊ4Å]—ªµS ²‰4@cJcT¨Z `Ó‹¯ß×Âwù  @€ 6`°¸Í@³´94¦,E«¨uEc*jäi7Z%€ÆÔ*9¾tSd®L»ÐÙE‚И„Ï®;I©“tÙ6ºHàýÞ’Éôîß¶vqŸì € @€@ ¸k 18ø™i:SfBEE!hL) Õ€j@cŠë\™rÔä›S¾ã[àÖ¡18ø4€ @€ Ð! wl6‹Æ”…(½ŽhLEï´½%€ÆÔ[b¬t‘Sl®L»ØÙUИ€Î.»A©”ÙÚK`ÿ{÷ß²kK{·ÉÖ @€ ´“ƒÅí¤™±m¡1e,`…¬.S!ÃN£!ÐhL}€ÇW!N@cŠ#Ì•i§ûÛO–S²üÙ{Ç 1u -†@g,ܲp¯[öZóúm^ÿÊgÒ¿ö§½Ü²´2ÂSgâÀV!@€ X ¸ƒ 18ø™i:SfBEE!hL) Õ€j@cŠë\™rÔä›S¾ã[àÖ¡18ø4=›úOé¯lLƒçž¾aúÑ­2hÖ —ŸIÞ’–Õ²~cû©øe³¹Ô€ @È&‹³·¶Ô©-ÙHG  1u/‡@  1å0¨4 ù!€ÆK®LóÓÓiI-hLô‹œ@cÊi`iV~ ÈLRQûä3IT²†*?“-HoÒ§f8Ù;×·õyA€ @è‹»Ç:u{BcJ]H¨P„è4¦Þñbm@ «ИâpseÚÕÎÈκN©ëÈÙaw 1u‡3{@Û(Ù’R.isZ°ùã\&-Ë^’Ã$½IŸZ®&- 1µ>‚ @€š$À`q“ ò¸S£š‡6-Ùz¥ì%+ÖüÝ=‹?áþœ¶þ˜<´6@í%0羯?°\.þìÇ¿Þí㫾ÒóÎÛ[Û»7¶@ ehLqè¸2m¹cñÅL@cÊD˜¨dï  1õž߀@¢\â%·àò3©^zsË®-²—ƾ8Öª©üL‰Ö—C€ @…$À`q!ÃnFc*pðSÝô×ß]¢ÎY³,Ûvcª«Nå DHT:ýëî`´ 9*‘±S@5  1Åu ®L9lòM)ßñ-pëИ |šžM•”~Iy˜”fÉZ IÌéM-Ø›šHÎ’6¹w²ÙVj @€ d–ƒÅ™ ]ß+ŽÆÔw†l¡C&¿|TTc¾ô“|ø^‡öÈf!lxììÚÓkK²Ý.jä‹S\<¹2ÍWo§5ahLô‰œ@cÊi`iV~ (»’Ê®¿îÒäq®•–Iy˜\î%™Lz‡TLùí´ € @é&À`qºãÓÑÚ¡1u/ï š ™HÅÔ¤|9'P3!©˜rušì@cŠ‹W¦ÙëÑÔ¸7ИzC‹u3D)CÁ¢ª€ @€ Œ`°8#êD5ј:A•m¶‹@(!©˜Ú–í@ ·¢ ™HÅ”Û`Ó0d•S\ä¸2Íj¿¦ÞÍ@cjŽkeŽSæBF…!@€ @©'À`qêCÔ¹ ¢1uŽ-[î;PB&R1õ)[€@Î „2‘Š)çñ¦yÈ$4¦¸°qešÉNM¥›&€ÆÔ4*VÌ4¦lÅ‹ÚB€ @€²@€Áâ,D©CuDcêX6Û..!©˜Ú…”í@ çü„L¤bÊy°i2I).l\™f²SSé¦  15гE)[ñ¢¶¨K`ó;Ó5Rüâë÷Á€ @€@ò,N>‰Õ)1ôì¸9.!©˜šÆZ(<—‰TL…ï €@:  1ÅÅ…+ÓtöZjÕ.hLí"ÉvRF)e¡:h•S«äø @€ Ð wjV6‰Æ”•H¹žJÈD*¦"wÚ^°„L¤bê58¾tƒSe®L»ÑÙGrИ’cÏž;J XÓ† .} 8ð¼ó΋_‡OsFଳΊoÑ7ÞØÑƒ°]—ÆtÅ8²1µ 'Û @€úF€Áâ¾ñËô·Ñ˜2¾‚T~óóžYvYAK3ÛH`ëÖ­mܛʷ·n½î¨,U˜ºBE"€Æm®L‹t,±­hLEŒz!Ú\,éÄO<èÃÏ»` +ç^0°§œ?ðß>üŸÿeïsÏ¿ØÊ9ÑÒÿâsú_|vrVÿgW£œyÞ€r9wÀ™^9ãÜ^¹èŒsÊå7ç\T³œ~öEÑrÚÙ–ËYžæ•SϺ0\μðÔ3/<¥§\pÊ™=å×g\P³œ|ÆAù_Î?ù7çŸ*§ŸÒéçÿªNéwÚù¥Ò?T~yZÿ œ.¿8µU9¥ÿ/N9OåÄZåç¿>¯fùÙ¯Ï ÊÉç†ÊOO>ו£ýÕÿ÷û?=é\•ÂåœN:ç„_ó÷ÿð™éÓ§§ÿ|0æÉ‡?»ç^ý/î—þªRC@€ @ ÿ,Ό붩ÀÁÏFÓß{ï½£Ž:ê_÷ù’žxÌF©e:èIH ¾-Y²$Õ¡]%@ô»Š›A½$€ÆŒ+Ó^v'VÏ4¦ŒŒê6K pÓ·Þ±ùõ¿egP6å]Wn¸õŽsÂÆïºòÚŽwƒ²]åÏ*¯zå•möˆ­»\Y¿uWP¶e]¹¼³nó;/{eí¦w\yiÓÛAÙ”5®¼öö‹åò§_ûÓêW{ʪWÿ´ê+o­teÃ[+¼²|ý[Ë׿ie™ÊºrYºîÍ ¼¬òÆ ^Y²ö +‹ƒòúâ—‚²È•5¯/ì);¼ØS濸sþêr™·zGPVåy¯Ì]¹£T¶«<§²¢\æ¬Ø”åA™½|›•g—õ”Y˶ÍZª²Ue¦+/lá•éK¶¸òÌ’-Ï,.—§oyzñæ§eš+ 7Oí)›†›û÷ÿ°û”›&»2Ó¤rÙ8iþƉó6îý…ýÒ¯1Mœ8ñ[ß=dÞŠ-rÑtQÝì €õ @€ tˆƒÅ›…Í¢1e!JÅ­£9L·ÝûøøK¾¸ï×0™ŠÛzÙr ¸é‰ÐY‹Öi߯a2õ^æW'ú™! €@Þ  1ÅE˜+Ó¼÷ÿ¢·©è= ·í/œÆ$Qɤ¥*ž®dË7ÜhL1êR 1…ì¥mî­À$™És˜z¦ZS 0µßa 4¦ÚSIc*;L=Óš×yÓÂÃTјæ­Þé4¦^8L%É9L5¦¶Îô5¦%[«4¦ŠÃ$™©¦Æä9L›§,ŒhLó7Mö¦Ió²¡1•¦Cç­Ü„ï¥×•: “)·çl@€ ¬`°8+‘ê@=ј:•M¶‡€9LCî¡Gû4ŠòäôÅ_ü2&S{Øæ{+%‹åBë63®S·ÁdÊwÄýÖýâÄš–B »ИИ²Û{©y_  1õ• ßO)ÂiL×ßrGÙR²4KåLKådK×ß|»4&?åRÔ[² L¾º¤åZé—”‡)’©J`zÇe`êE¦J&? ÓÊ^åajà0LU*¦Ã´¦q*¦ZSŠ)ÈÃTIÅTÎÃÔG‡é…j‡)œŠiK|*&%a gcªÖ˜”Š)ýÙ˜‡é{‡Î_µÕFR;åÍÒ”˜L)=éR-@€ „SA]«™hL~ª›nÓÐûF(I¹FQ”\iÈÇ=ƒÉ”ꨥ¡rd;õÌ •ÞÞßÔm¦/ÀdJCdºQ‡ úgýn f€@_ 1¡1õ¥ÿðÝl@cÊvü¨}]…Ó˜®»ùö°¥äæ‰Ûög}úßœš-.–"ÞRH]ªš<.b/U§_*ÙK•)䚘4£\+ÉUæ’+O$˜ìÚÛ›N®y˜4¯\ãéäÊsÉ5;ÜìvN'q˜ùÓÉ©˜œÆTžQ®V*¦”kLæ0-XµÕI‘Ƥèœt:&§~@€ @ 9hLɱO|ÏhL‰‡€ D 8‡iYi|Ìž+eß9öéÅ_ '¦³XªºMð áÎg濬nCN¦|w/úo–&1$6 ½*údäÊwèi2G )s– ·SÛP²¡t(¢Æµ”Ê –¶ýùÚ@c:>”i©ÇXRÖ¥-=eÝå[²d]R‘®äoæ¸`¹&í¥SÈU20­zå-? Ó / Óò o-_¯ò¦Ê2+ëÊ¥žÃT-0E’0•‡r‚ ³R‰$ajv.¹fó0ùӳ˶ÍRYª²Ue¦•ðtr[jN'WšK®)‡©Jc 9Lóƒ¸ÒÄp×ÜhL¾«dËž±T’–jå[ R.Uϧ.m|{Íko¿X.’ºk/ý©Sȵ 0­m”„©áDr«wÌ[µ£Ö\rÛËsÉ­Øþ\©´8—\Éašá•*):—ÜâÍ¡éä¦.ìIÅdy˜¬<0nîßÿÃîA6¦ù›&•ËÆIžÃdÙ˜1Þ—ÒÔ…?!T¦mõFRæ­"Òï´þ-˜LG}ô^{íÕ|uŨ¯hýzßÚÿýCWÝÑwÜh—>êß¿¿6hÛä@€ d’ƒÅ™ [{*ÆÔŽl¥MœÃ<û¤bê™QÎZëI0kš²è ÿ㫽2™Ü0ˆ†2ôš>}º«²½ãþTzõ½AÚ¦vêß¶íÈßÅØ±ckšÍTFmѰLTF‰o‚ ­¦ >¼æwUÿ~¥—Z}Ø«-˜ÅRî6ÞŒr=ÝfõŽ©óÖªÛôÖdR-pöRóU±zñНsÃ<n…@+Û¾ì¥xí¶ÛnÚ¯{§áÖšh›õw¤î¤wj91}#Z™nö–E߈ZŸ÷O Z%ÿHÑiȈªjì€O}EËÍæÑutÆpS V™f6ÕLLj_Çê]§Þ™Su³1äƾׄ-@ £ИâÇ•iF»5Õn’S“ X-k §1]sãíÕNR•¢¤Oð“ã¨T3Ç’Ë·•–ÖÚlqÞ„qUsÆ5R—Ê3ÇÕɽ´Ò˽¤–§•[È'Ì9€ @H‹S†d*Æ” wö!`Ó÷, ©õ¤bÒ™FÃüœ:%)H">bò‚æM&7H¢*¡{í÷ÐЊÙð3â¸1KªdÚ˜‰ ƒX~7¨â7KoZ{Sb‡­¬e{ß½¸¬*ZpY%U™Ð¸M4‹’ÖÑ·¢AhÇš©mÊSÑún;n5UÏÆ‘lDÈjr5¬-Ú‚Ó³ïËÅrvà0…R1i(µÜmzì· ýüäçzg2EžšñrÃhÁšè\'@äÍ1´¾g©˜ÜíSS^ô©“ÉÜ ‹ ¹eú3´}û®þ…”,÷‘{BÒ*o«…ý:‡z—*:4\£:Ú[b¢_<ætîco£oÌëÒ²?ò)Ô~ú%}d«Y«C[ÇßÎZÁ dúbÍsŽmÊÎö ¹ƒ–Íq¶êÙ¦¬Úþ€°>r'+;ÒݩƣܦBY‡7Î8Xý•̵ËÎ]Ö |¶/÷2›3ñ“€@âИâBÀ•iâ” t”SGñ²ñäOcºa¨?;Xhùê†~ÿÇÇW)J‘ìJJ°α¤4KU™–l¶¸Š´ôÚŸä*ùe•ò-YyÅÊ[=sÆÕR—*öÒ›ºr¶¢§Çô ˆ•žÜKAZìªÜK5ì¥hú%iL=öRp%Ö9I>ÍìåÛÊÅËÀÔ”ÀT„I ™žYÜSž^¼åéÈDrÓª¦ž‰ä4—œ9LšH®¢1•¦y%-EKª&•s“{LAžª?'à"ü‹Sš5™t­hãhî¡]Ú@’7é:Ù].Úµ·{ÐÇ.ueëòQÛ;ZͶàžãqíîj9$-ÙøHrçFö @€ ôƒÅ}ã—éo£1e:|¹©| ‡ÉϪRÒüœ:Jh-I£(#&-øü—šš]ÎÝ;ÞD·q»%oC%zYl#¬q»7ïŒKGäËCQWÃ6ë†n´`6ƒ¶£•m<ÇÒ˜y`÷øM°›šÚJ3’™aõ·aÛ»Û íÚÏcëë[p5Qóý=úGÇÕ\¡GQªÊ«Tž.<1\EWªi,Õ”–ÊSÅyù–Nš3®¬.Õ™6®ñÌqmµ—bÒ/ÕžB®Õ LO/Ú<­Rz%0˜æo6&“s˜–¯[ß(£Ô~ˆp‡ùdþHÊŒ’ö³X“É¿¶Ëf{¢Å`Òµ«]HÛÕ¦?dæ.­môÊ¥>Övì+~êi» ¶Çí9E7D‚ÔÓ_š@€ P$ )Ú¡¶¢18øÉ7ݦۇ Æß4„RÊÃq˜^/O'WÿI0 ¡<üÔ¼Ï}q¿uë××kUHcòWóµ †(]Æ@l ÅnÕkœÄ†D|WÃÌ$}×ÒóÔ›TÎFlÌEð-³o¹)·,㎭l;µ ÖÔ˜šЉãh_6ó”¹NVð¨˜ÆdµgÛ¬’N]Rµý æ’êCÅrÖ…®Û”2ñx“?¡X¹Û”ß*©˜d¿éBu›q3_üÜ—ö‹ÏÉ$\¾fÑqñÒ§¡PšÌd£gÎA1P½Õ˜|¼¾vfѱ­¹Îé"Õ˜b3ÔFBÉn³Ö™ýNXsPÑú†ë]nƒ55¦õ–f£_'WOôg5ˆ~HcòÃáL;„}—+Ç?~R9ÿðwYú'sÈÜËfy³ƒ44'¦ß[L³s'+7®ë¶ìöå¶ýÈl­ÐX±ÚåF•CzVè¬b[Žê€I@Ø/'€Æ®Lï T £И:Š—'G ×“Ë(›\[ßó‰'ž8èº!«^1÷¨FѧGÿð¸ÊGoÕ“ä'¹RÊ«T/»’.z=])7ñË“O/d”Š´ôôÜÕi©<Â2í¹UyfìÔùrV¢ÞRìK£&Ï[Ì5¦²SÅŸ6.”xIóÇ)ëÒˆ‰sg,Úàr/M_¸A¥ôt‘+•ÜK½O¿t×£Sf-Ý6yîË*Á“mV¼ôKÃÇα ~W†™ýÌ’-Ï,.—§o ʢ;½$),0-ìIÂ䦫d` ’0©X²¥LhLžÃô5dô³F=»Á¢¿¨4ŒbÁUg½°Õ쉙ë]*&QI¡ûÙÉçÖœ]Ξtñ0Kamï¸kE´¬—=J¨ut]m_´uì)1½lÂ>µËW½ì"Üå[²+swjû"Së§9¾ @€ ”`°8%H¢hLIPgŸç0é1°Àa*=&‡IC@å„:¥Q”© 7)¹ÆÁlÈkÔ¬ 5ŸÓÔƒO>c2¹¡’hFÐȆ³vܘ‰qßµD#j…콩ђaà˜¸7&cÙtLnpã3ö|šîôÛG6Èãç³±zº4ìFþ0Ž ÙWlâ³he¬ ²lÉróزÛWçòë4lŽ[!d±Œž½Áw˜FÎ\?{ùvJµ¤õê6ÊLoÝæ©ç^µ ^6ª©Á·±3V«ÛĘL_÷ Å+J5nf¡ùí²ïúý-:¸gý*Ê9wÛ‹m\Ñ´=šSRsûÖ ýràüÍêS»›`[ˆ*º¾áïÔÜWƒè-¡èë¤1iÞ¦ž,\Î`{qçäýèŸûj)Û¶æ£ïHF?]Óü@Ô‹ˆñÑËé_¡cÙmÍEÊu wB¨ S4¡ÍEÖV EÁ‚ng½œÓÚ—ë«¡j¸tSwýéêot{·úX9×d·Yǧùƒ5!WhLq‘åÊ4¯ýžv4&zBf „¼£ÐŸ 4&ýGÐ)ív™}æ#CdJÓmÎ=Š. ºö¶£~x\½Jf&…Je28 Ž„]% —œÙÿ’=>ûÿ³ræy—hôäŠëoÿü—¾b%IY÷æ·¾w˜ýyôN0WÉ•£~t‚[ù[ß;´’o©Îlq/½®”K~֥ᣦ}ó»‡ÖP—ê'^úÜö=åì‹5ˆc唳.V)9Lá™ãâ&+Íï™4º¢ûÌ{êªþ¤3.R LºÎ¿óáÉÿúù/;IöÒíMú×}¾lSI` ì¥Ó‚)°—œÀÔiÎ}»´£‡€9L WouI˜Žºd¢•®˜vàÙcî|jµs˜.¹gÞÀ{æ#)+¶ß6zåg9|À„ÃŒ|úzKÅ$Œf}ýô¤Ú&SGÛÂÆ!@€ `°¸@Á7©ÀÁO²éæ0 ½od9åy%•µžÓ(J0)XIGx`ÊKGœ`2ŠF‡Ž¸xÂá¥rí£/„Ÿ[¤pÜÜøœLI¶™}ÇШJ/Y,§žu¡ßm4àæ,–SnœuäÀ‰nðíøË§>úÌË)ÕàÛÙ·Î.¼ƒoe‡©2ø6zz“©‰z•WÑh¾Pü,VÍo¡ˆkö&úÊÂåG_êŒá‹} nã¬1öø¨¢Ü§Zôû];£sÑ/bìh3 Ð4¦8l\™¶Ô©øRf 1e&TT´Š€M¿îÞ2Þ—ïëjL2ÜÍ»7ÉRȺ|¶)™°¼·Ñ–Ætùµ·ÕV‘‚DÓo]~ÍmGþð¸’T[Kò3*•Ó)YR¥êÉà¤+Ùó^Gÿø„›ïxÈt%{ükÏîùܲ×t%ü›ó.QtýPùIæ-ÉX3e¾®‘¬hY++ÝÎâÒëb=]¤k3+z̨\–—Ó&ë©#WjÚKR—zr/IcúÍE*ººsÅÔ¥;žd“K¿$é_öùrmiaU¦)^ú¥) 6E20Õ˜úª1ébXÿõéðoƒ&ur˜*]HýDÒzLÐz‚& ½Y¦“¯Ÿ©kéwϳ0iîîñ/êû–Q˹lŠKÅTÒ˜ÙëL¦ÞžAX€ @hžƒÅͳÊÝšhL¹ iTq˜F¸ÇÀ\6¢HC1‡é·÷Î×àI 1•ÄNº~ÆÅwÏÓ¼`zjî€3Ç”sêT? ¦!”ÆÍÝ;vv¹ *`õä¡îôc+3™Ãê6Ò˜Ìb‘Ãôëf™Å2nΫ’ÞÔyúe ¾Mxþ5=@8máfu›3oyö÷úÁ7=@¨±Ê'žY¥n?»\“aqO“{¦IbÁs§­F_g _|´èß>nÕƒèÛã£×=¾ôØ?N-¥bÚzØ€ñM_ß¹è7ÛdÖƒŠM).þ\™ûèÈë;|«:ÿialfa§1¹ŒÂª‹›^¹®Æ¤/ÛôÆÑ †õü‡¥ ÍÜKÓ¯Öœ‡´þM}zäŽ3 )¦ôhIÎO*[J¨dÅ™I7Ýñt¥»§w4=œ\%³”ݳ¬?g/}mŸ/}eÊs+u…leÊœ•Ò˜î>Ö¤¥g_xÕ’-ý´ßéû|ñ+*Gþð]G)åÒ‘?<~÷ÜSÿîóÅ}-÷ÒÐÆøÝC9íÀï*ÁåWùÜ÷=ð;‡¨h˜æþS¥+iYÿ1ÕŸ3Î4¦À[*©Kr˜iÅö½¿°ï7¾}ˆŠvôÈSsä-ðíCTôþÞŸßW×lZ¾åžQÁÅÛ²mzç¡qs.¹bðÞŸÿò׿u°’0 ¼b°’ëjAêÒ¯~s‘Šô‘ŠÔ%³—nxÒgöø/J¿¤²ÿ7–½4ô¡‰Æ´hóE¼E zSÿ6ž?NÓü L JI`*ÍW³´0©Üö§†þû{WÂV†Ø¡!p˜”LkÕÖ’÷¦›UPÒš*ÎFßî|jÕñƒ¦)Äcç¼rÈer˜‚Ñ·RFëÙ¥XèZZÃ(¿¼fºä0—ŠÉL/‘9þWçÔœ]®C-b³€ @€@0X\ `‡›ŠÆTàà'Ótç0U#ìEÑóE)eÓy]#f—Ü;ÿþÉ/IF±Ñ0{L£(N]«„:Êîæ³tà ¡lÒÒÞ_ØoÝúõÉ´½¶@ÀD+ud¦Àa:óÂÊäƒ=ÝFSÈaÒàÛíãV›´Fçá§×z³nS·Q>ž«^RJ'ßÓm489rÚJu›¶˜L-(ôWúý'<ñÑO?fö+Ò˜ÜIæ“ÓùAÓ˜Ùˆ~¡û‡@  1Å+ÓtQªÐA¼UÝÁj³ébÐ|ÁÊ©ägc2Ê©$=Éf—k0©\Hc²Mze¬4¦Ë®\WBZ÷¦>•Æä†<äŽ8-É™I¡yߢºtJZ‡ô³_ýæ7ç^"{éòë†J]’«d –õ´T$3–.¿v¨Ö”ŸJ³tÃеÎÿ¸§æ†»ìÚ¡ºpºìÚ!ò“ÌU’·tÁo¯zà‰iR‹f,~E—ÓÒ˜FN|^ Güàø¡÷¾äTÙKãg.× Ón&‰;ûâko{@®Òa£5XóäŒà£ž ãVn×Gæ-YÊ%Ó˜ôPšV»ç±)Ö9öÄÓN>sÀ­÷ŒÒ‚å^’´t÷£Sn¾gÔß:DÒÌè§_½¤ øC>nÔ´d/Ùlqò5¦ïù“Ÿj¹—ä-)ñ’Š4&˽tðQÇžyá !Óã“—|zÿò䬗4rtÑe·|í›Û#MºJt%’~©±ÀÔB6& Ló¦NjLæ0Í_¹Õu0ëWê-zS9aÐ4 LºxÖè›kÙè[YcZ ÀÙó@Êä§ {f]p-]€ ¸iÎ`2eôlFµ!@€ v §=B¬Sá²és˜†Ü;Âݹ¡9Ke=²¤1©¬KÙ¬{æe™(¾Ãô«ëfhðäêG_Í e“= ¦!L¦Œõ>_d©%3Éa:åÌ Ý£ƒ6‹œ ¾Ic:å†Yž5æÊ[·qƒo¦1¹GÌX/‹EEƒœ=.ìé6˜LÉt›>DßÎ&>†¢¯‘XÿñÑk}A§Ž3n~–è'eö xИâºW¦,ù&€Æ”ïøæºu!Iy”ôŽ2ÑZ£{§1Ùw4£\FØÓÕƒc<$}zÄŽ ­àkI —KŠRy8—WI £§Ì“¨ô`I]2W©¼\J°¤¢K#eWºàwWk¡<7\)c­ÊÄgW\vÍ)J§3PEF‘–U´ dKJ¹¤e›$îüß^uü/NS¾%}$¯E™–,ß’þ}~e ¹XѧzÇÊn»íöèSϹ ã”]ɼ%]ËXRÑÂgþqOe÷‘#cIïhA¹—N:s€Ô%ÉIw=2YÆŒd/óóSÏp…ì% ýœ5àŠŸüüT—oI–’.ê,“¬šîÙïô‹”cI–ÒЇ&)÷’ì%Sm®¿s¤Þ7iÈð‰ZA V>½û黽ä235™é¹›Ï©!0ÙÈùŸüøúÛ[9á¿ó»‡Ì[¹¥gÜ­4†b=GÒ#f®³ éG,«LÊL¨TLß5Ï9L…;ž\uÀ™£COƒÙ&S®Oþ4€ @‰`°8QüÉî)Yþ…Ú»9L·Ýû¸sP Å¢”Ü4Š¢Yä4ŠŒž­ÚñhIcr)Ul¼ëÉç^)=V53ÔÔÒCtîI°“ià~íbk! Ÿ!—É_(ef*9LÔë6˜~}ÃLu »=>}MA¨o+·.iÚZë6åY_ØúûûüäSüƒ<ñ•‘·²Étî¾if»‡%sRÉ>DD 1Mˆ:LŠ~ 1yÚЫ²à_zß?ÑÏI/*ÚÁ%ùW–  1ÅE+Ó,÷mêÞ˜ScF¬‘RÑlLª¨æ…“Œ¤…^hLn"9M3—Ñ„LÒ˜þpõàIŸñýc+*REHZûº’'ùNRÍåžDJÝDïS•,¥É³W*©Ò¨Éó¤1•D¥×‡zZ9–FM~þŽƘ®d–’-«üáš!§ž3ОùP1]éÔ³ÿËÓ•fÉʈ sm†8]K[Ñòï¯"™I—Ö÷=|dÿÊq±©â$-Icº÷ñ)®Xâ%S—œ·:n†©KV¼Q”`„M£(K±Q iEc)–ReðèÓn6E u&:3”ÿ$˜|”}ÿy¯%ç~éÃë¿É}ú´¨'²œþ‰;ûÄã¢qàò p¤ÛÈV ,–Õ;¯xpqÏ„+ƒTiLM[kƒoW?RÎà¥Éæ½h¼›…Ðeð²Á·±Ï¾¼ß7þíž_øþußI;´Üx}ˆ¾1ÜЫ3Ø}u {|TY¸îzjµ ½^pûÜ nŽèÓ·³Màì¿ &ßä•ehLhLYî¿Ô½oИúÆo'HÀiLšnúôéVÍ7§—z¡1iC˜ô9Pz%ؤ–w-é÷WÝZÓ7²7õéáß?6fs’übfI­²sÒìR—†šfÀðËÓµ IÓÀÙ;ʱ4ô1zGSÂÍXôŠþpõ“–TÆÏZ!ßHN’ÆYÆÏZ®yâN=ûâ¡ÃFËI²âôNÿK®²dK.ÓÒá?8^ßzlüsòZ$*é#Ù-úWËZ8ìûÇ;ðÊo|ûß]y›¤¥{›¤Y*KV”cIÆ’þÕõØ•·Ü¯å‡žœ£y¾µ ‹s%^:錋T$-iˆGӯ飛î~B—mO”–¿þ­ƒuýfÒÒ„9k5gÜvª¦Ó0ÍWÒ˜.TùñOOўͧôK–ué±IK”²[3Ç]vý·•&=÷¦?0AC§_pù×<(x¢¥\6j,É=ÛÔ¤ºä¯Ö¤Æôàˆñk7½ÓåIåüÎ!s—ovö’ÍÅôœ”„é±é/+ ú á‹ƒIÙKÃ( ¨&Å+H‹uÙ”«^¢@\ù𤈪=Dè?d“ÊÉaRëT0™Z>·ðE@€ @ L©À}©ÀÁO éf2=h¾¬Ù:>Dß4&7”¹ME§ýÎcÛ]ãWK|´Ai»^ñÐb¢ßz°øfHaDcJC úP4¦8x\™ö¡kñÕ @cÊ@¨bmNc’ä$J»J/-Xr¥“t%ÙO¶á±cÇj.9}3£“]^zå­õÅ£×õ©4¦êvº)Þz* “\æ¤z × ~àw•Ÿ$‡É䤑Ÿ×Lpîy«wJNúÜ÷UÑ‚ sEÃ+C†–Ëb³¿röÅ6àréUC¾Qzó”³.Öà‹Œ¥ÃpœeZÒ5ÕàûFþýãl’8%^’·¤kl9LR—TŽ=ñ4Ó•øö!š?Nÿ>üäK³äŠì¥½?¿¯„$å[ºòæavY.9IÿjXçÁ±s4UœŒ%½£rèÑÇ)åÒY 2u风½ñ®‘ºz·¬KÊ®¤¢ÄKúW“šÿ.Ú|Æ…ƒTd/٧ʺôËÓ.<ã‚A÷zV _ûæA•~qÚ…nî}bÖAG+{I“Þ”ÌôoGxKV*™™[°—z;©œiLV$3ýû{ôd¥vb‡Î='NTôŸ[¶Éõ.KÍ¥Ñ=fEÃ(£fm°a…õ²û]6l‘"%«L‰Ðe2vÑx%µ~xÚËÁµ´9LÕÓÉ9‡ “©Cqd³€ @((‹ ø ÙhL~2M/›Lc¦÷ØK•ìæz8pììW4–b“†Ë4ò«ëf¸IÁ¤1IGÐÊMO,ïq˜*ÓÉùó‚9‡É†PÔTL¦dâÝä^}‘¥Z`r¨Œ—í%—ÿøË§º‰äf,ÙrܧÊ~3õMG™xlðíæ'–ÿä²)²Xä0•’ñ„ 9L˜LM†® «õ!úcç¼â†^ƒÑ×ëfXò6EÿØ?Nµ¡rEÿÂ;æêÔ¡èWR1ý6ÄM$F)1ômÛ1SJ®LÛÖÑØP*  1¥2,TªRÜjÊÀ$ I/KŤW©™dh»4qôéaGSs…à:6T*i“\þ$A~R©ì¨*ž¥dõK0°*Û5Ôâ&†3KÉ•ò¬pöTPez8óZB%d,XYfsÉÙ´P× ²Ê£(¡2 åçar£C˜LiïŒ&²Ô˜\å5\ü»+oõ»˜Ì{«ÑmJƒo64|ó ¬é0a2u©Û´;úN|´¡W¢ß¥8²›®@cêêŽí)-W¦ëxl8:|«:m¤…$P8éwW”¯KkºGúTSi°Ã•j)¤%•´’P©+'9i©†¥<æŠK­Ô²®dˆÄJKµ¼¥’´Ôo)¬.U{K–e7F]ªØKåÄK}É·Ô)ÉÎ’™tU\ýzeæØÉýžyY‰k¾æ L¦oüì’ÞÐ[Àd²ZÏè[èBzqÈaêÉhíÏ%çÀa2ò‡€FC€ @ ,îÔ¬l)+‘ÊY=Íd>ú÷è ˜z+¢Øã|u¦p6ëzSÍœL‹ï¤A¡—Æ9ðý׿…ÓõQ΀§½9¯ô§‹©­L¦ß^qK¸ÛD¦Òƒ =Ý&þ‡iÉÂÃÏÿõøþ?ŠVID]%í`3Q¿´F¿¦ÇVï¼!Ò- &g">T2uИR’^W)W¦½îP|!SИ2.*Û<ÂiL¿tKŒf¤O=ú˜ÆR4‹Rm3©ü¼W E©2\HT*?âãò*y©•jfWª§+U§YŠË´Ôš´ ÕHýçO¯®!P]&ÐLôCâcL üøè»§Iýè×;oÈikm0¹ËÙ] 1e?ŠhLq1äÊ4û=œÄ@c¢ä”@á4¦ÊitÖ¶à}zèQÇÔ›ÐÍ·‘™“LK*=¦S³¿UÏWWTª“Z©œƒ§gV¸]©æÜp5Œ¥Êìc5fˆ«ž$®-Þ’•Kç'Œkè0i…¶kLzzæÑ£÷²ìôìÜ(•–í}{OÅ liý©4NõÎ3£Æ<)“iú¢×\"kKÂT~¬z¥êBº¤ŽMRFëy H3Ó–7þòáGá‘”œži @€ Ð w†k&¶ŠÆ”‰0åµ’o¼ùæ~_;àþ‘O—GáJy¬«+¥²ž±¤4—œ=¤WžK®‡IRÂ;ïþM0ÿöî.¹J² êqi™ì™·è`‘††lŒy%ñù“ã~:ðò›ktKÂäw›ª)]·)'A·X$0Ývìwd2mÚü†‹¾ËÀ¤þ#Ñ÷ÝXbâ”òZ¦¢_cÊÞEß9LÛÞ|ÏH†Îõ“Cï»3LÌ`r^#E»:E©Sd»·]4¦8Ö\™v¯'²§$ 1%A}v@á4&]ŽÆhFúTS¼ŠT#a’Ÿ<)b&INŠó“4’k)Å»J½Ð•‚š`Êöhy&b,5#-M‹ÌÍ·ÔÐ[êNÊ¥Ÿ©í“®*mdJCWÊú«[Ùs3.K“-è}-ØûZÖ;ZˆI-“éëß:ø™…¯–‡ÞJc(îI ˜Ñ·Ò }8L]8² @€ @À#À`q»SƒŸŠ¦›Ét߈iö XÍÇÀœÃ4mÑæ©¥1®ò09‡Éš­ IHrC=zǬ&ÓS4jdƒEúWE¶ŠÖ”ˆ bcD¼’% —åâËoîñÞ*“KÂT_}+?@Ø0Ï‚gçIcZ=¾‹¾úƒº‡º ÚP¡õ ½¯Õ¬{øcŒÉRÊëÞ»}Ó˜œÃ:oÔL7šLÎk¤hWG 1ukW7ŠÆ‡›+Ó®vFvÖuhL]GλC ˆ“yE5‹4¦CŽ<&ôQpíÚZ) ”4,ABªŒJUI•¢R)ïŽ+ÁÓcÑRzž¬÷ÆRðð™+Ä©*½•–”u©V¾¥Ä½¥ÒÔvÉ¥\²gì4ab“±Ò;ƒ°ge´Ž]ˆÚÑ®7-]S½—™LÓ¼Zî•Ð[¬M>³¨y£oäaêι”½@€ @Õ,.p@c*pðÓÒt3™î}|Ú¬¥åT:å$å–„ÉFQ*C(Áƒy½ŸK.ä0©å.å’ ÙCn–iɆ†ì‘6K¼¤5"äÒ5iMû¯d .ËoŽë6‹Ë#o¾úfž &õiLž|˜Ú¨4<–¦Ýì%³”Ô ôŽËée]ÅŸiÝ­£Ý£ýj}­üìhyè5ýf ¶šSô¼L7z5˜ÜQ\l¸ÆºR­‰áJ‰|4‚“Gi)ªIµ]c2WIn|ÊÄ&˺ä†ì<ÿÁ;-ëI¬†§™Lûó Éó6ØÐ[)âe­»Êè›Ë}uü¯Î9ãÜñ£o[ÞøË‡}Ôpï¬@€ @ ) 7…)Ÿ+¡1å3®l•™Lw?:­Îc`ÁDrír˜Ül6#˜hiÇ ™âr[öýkùx´¦û(ƒ˜sXåÀeùÃMUݦÎà› 66é0Ébq®’ú† jÌÐÍ%g“%a²¹äBFÆçqÏa$’hRç¢m‹o½Áäèy£…Áä$(²Ï¬@cÊZÄ¢õEcŠ‹!W¦Ùïá´ Žý#§ §1ÓD UÞѧҘzVˆ¸Gþ„n¶\{Z·zï/iEÉÍd·®c)…E¥F©•‚LK5²+Y²¥º’¥Ñî)¥¹áj¤YR¾¥tgZj&·S‡4&h0Kɼӈ•eZ’ÆdZÙ¨–†*´‚%mj~ÄÊL¦IÏo°ÄZ6‹œ{Ì‚Pp˜rzö¦Y€ @H7‹ÓŸŽÖ©£xÙx¯˜Étç#SŸ®Ì"g£(öüž†¿,§¸ "µœ‡IUr°iÈF~lPH¹LKúÓžj3=Åì_7»\¯ZÇÊ# —å‚ßßtO`ª9øÖ¼ÃdÁÜ5-Xg°ä:zÇz‹ëê?ö¤j™”] whËŠ~´þî¼3˜:o´6˜Ü5tì(«И²¹žz£1ÅÅ+Óì÷pZG‰þ‘SEÔ˜bÄ#iLñ“+”ô£øyÜœTo¡l&Õ—“*™utyìÊæÐp5ç€3Q©«É®TOWÊ«±TÓjj»ÆdÏKé¥ÙK¶àþµô¾ŠYè¥ý龨ä©F&Ó×:L©Ì:.ǶüØû×ràmøÈ# ™i¥\–óc¥ÛTåîrÏvöÊaŠvØ04¨èº•vÙ¯h'¢¥âŸ7&»¯·6˜œý˜Ð‚N@cê$Ýîl)Ž3W¦Ýé…ì%)hLI‘g¿&P8éÂ?ÜãéSiLá”H–©‘~dR´xNRœœT×O*åÚ‰µ”‚4<õò*9»¥8 –šIÂäÖi»ÆÔá¶jóf2=5g]ÙHó´’‡©›á`_€ @€@‹ Ü!И ü”6ÝL¦Ûž\ï1°¾äaJi›©V;.Ë¥7Ôë6½u˜ÚQ#¶Ñ=¥èßHô»Gœ=%H)AømÚ5SH®LÛÔÍØLJ  1¥40T«¯ §1U²ûz–õé¿ñ“ZâQ@¸§, fòŠ/{ÔL‰Ë¢d3…U¦~«•NÉ®£Ây•”»2\íÔJ¹˜®WºR½•3­1éè—ÉôÕzrö:å?Íñ‡ÃÔ׳#߇ @€úB€Áâ¾ÐËøwј2À|VßL¦!Mög‘ëû\rù„E«<rYλô†h·Áa*B7±è—ØËSOÚIƒè!úÅj#SöãÆ„Æ”ý^L Z%€ÆÔ*9¾—r…Ó˜,p½¢Oÿíð7¥yI’êÏææ<¤èB%’ä¤^ùIR”ª-¥º¢®Réª2¾d]c*›Lßø7]<û-ÅaJù™—êA€ @ ÿИòãº-Dc*pðSÝt3™n>ÉB!Sªc–ŽÊÉe9÷·7øÝ‹%‘éF-ˆ~7(³Ä  1%‚>W)!W¦}î`l ÕИR*×:âiL—ÞXIqTÃ1RžØïþãú+îQyú6ÓIH.[’¿P5¿›iI®xY”ü裮ՊA€ @%€ÆTÐÀÍFc*pð³Ñt™Lû|ùÿùç/}vÜäÙñ£(ï¼û·l4‰Zv…À?ú®Æï~à±øn³íÍ÷ºRvÒUGþè ¢ßUâ쬛ИºI»3ûBcŠãÊ•igz[M 4¦´D‚z´™@±4¦­[·N¯~IOñË}¾í®Coòg¾ Ü8äÞ† M¤ScÒ¹aài«^ýSÌH S›Ï l€ @¨G€Áâ÷ 4¦?3Mdþ×Þÿ¯8L™ X:*ª›ÄýïùOK7¼Ósp˜Ò«öׂ跟)[L4¦ôÄ¢Õš 1Å‘ãÊ´Õ~Å÷²A)q¢–½&P,)Š'~´‚O!P“@:5¦—7ïúÞ…Óyú•zQÃaêõ ’/@€ @-`°¸etÙÿ"Söc˜ÿ<¹æÀ‡–ï¹iç_ꢇ)ÿ ÷-´›Ä붯­×mp˜z53ß ú™ mS ÐRö4¦¸€peš²îJuÚL©Í@Ù\Z 1õ̆²& ¤ScúýË¥1ýäò9¯¿ý>sÉ¥åK= @€ PX 6ôL*WàÐg¨éÒ˜^þÙ?ú¨¦É„Ô¡Pv³ªî&±t¥èàS7cÑý}ýî3gÝ#€ÆÔ=ÖÚS§úÛM?4¦ôLj¶D ½&BÉR1YõìF ·ùƒ)äajéôÈ— @€ >@c꼬•lLY`¡ê5™p˜ ÕZnlÈdÂaj™d¿Hô³5êG)ûý )û½˜´J©Ur|/åИz­°4™°‡ÕrL …“¥b²¢„Lý÷ɄÔò³0Õƒ @€@>  1å3®Mµ ©)L¬Ô-c_»æõ51{óM&¦n…%íû4kPÃ*:—‡©!«Ì­ÒPsˆ~æbJ…ã 1e¿ 1ÅÅ+Óì÷pZG‰þ‘SEטä£ÄÛ6ó_ܹbýŸrläдeëßZ´æõx,¯íx7U'?“KȤjèmóÎw5—ªÚR@€ @ ,.D˜k7©ÀÁOcÓ÷ºe¯†ÕÒà‰F{p˜‚*È ·,ÜÿÞý›i¬\¦f@ek£=zú†é ëLô"b…Ì@cÊL¨êV).†\™f¿‡Ó‚8hLôœ(ºÆ”Ó°Ò¬bðS1ù ™ŠEÖB€ @©"À`qªÂÑÝÊ 1u—7{‹# AS¿±ý”[¥ÿ”þZ°b©V¶ìÚ¢e-èO­©¢uZpê r˜Ôm†/>xþ`u -ë_#£ü^zÓ¬ÛèÓ‚CËSó\EßNZ–ϤÔ\ú׉M}½w}äþÌÚR8hLÙ9S\ ¹2Í~§qИè9%€Æ”ÓÀҬˆ¦bò2 … @€RF€Á┤›ÕAcê&möO@žÓä¦HDØõ×].?“þ4I)ô'J JÝ@Š’8˜¥$ÝÍÜ&#£¥N¢Î£wÔT´ uà––‹Kÿ*¦&Aª3è_§1Ù Ä´H­¦›™‚0phEn  1e?´hLq1äÊ4û=œÄ@c¢ä”SNK³ C šŠ‰„L… > … @€@Š 0XœâàtºjhL&Ìö›'à´$—2Gj‚ï£XºÓT,½JóÛgÍ\pZ’„󓜧e}jé»Ôs¬ÛXÿÉ%Š6Jº’eÞòSp¹.a’“‘Çæ2uMÎ 4¦ì).†\™f¿‡Ó‚8hLôœ@cÊi`iV1¼ùÎ_Ï¿c‰•SoZðoNïwÝ<÷΂ß(Z @€ ¤ƒÅé‹I×j„ÆÔ5Ôì¨!3N´šS—¤&X&{Ó¤%V‘½¤¢—s¥áÆY!¯,ÝŽ¯ªøiºìSýk}ƺ\–¼Ò(Z»,¦jµ¥Ý²æ»nö©M¶ž44¦¤#Àþ;D©C`Ù,ºM©ÛÄÙ @€ C€Áâw4¦Ÿ¦C€ 5hLY‹X´¾hLq1äÊ4û=œÄ@c¢ä”SNK³ŠG©x1§Å€ @H1‹SœNW ©Ó„Ù> @h4¦¶¡LlChLqè¹2M¬c²ã®@cê fvÒ}hLÝgÎ!ÐhLÁÊF!@€ Ö0XÜ·\| )aÌy#^wÉö?ÏÍy#i^» ¼óþ†ÍïLÿàÃ÷Ú½a¶—D?A¢Š-@cj]j¾ˆÆ ®LSÓQ©HG 1u+MžSò1 h 4¦¶`d#€ @€@{0XÜŽ™Ü S&ÃV°J?¹æÀ‡—¶`¦¹}%ÀMâ¾Ìò÷‰~–£GÝ@cjD(ýŸsŽŠ‹W¦éïÁÔ°/ИúB輦SŠƒCÕ ÐhL½¡Åº€ @€@‡ 0XÜaÀiÞ<Sš£CÝŒ=¡Ü$nZn¾BôsJRƒSö»稸rešýN â 1Ñ?rJ)§¥YÅ#€ÆT¼˜Ób@€ ¤˜ƒÅ)N§«†ÆÔiÂl¿ïИúΰ€[à&qƒîšLô‹ýü·)û1æC®L³ßÃiA4&úGN  1å4°4«xИŠsZ @€ `°8ÅÁétÕИ:M˜í÷Sßp Ü$.`Ð]“‰~‘£Ÿÿ¶£1e?Æœ£âbÈ•iö{8-ˆ#€ÆDÿÈ)4¦œ–fSñbN‹!@€ b §88®S§ ³ý¾@cê;Ãn›Ä ºk2Ñ/rôóßv4¦ìǘsT\ ¹2Í~§qИè9%€Æ”ÓÀÒ¬â@c*^Ìi1 @€RL€Áâ§ÓUCcê4a¶ßwhL}gXÀ-p“¸€AwM&úEŽ~þÛŽÆ”ýsŽŠ‹á]Ç|üøÙÙ2-€@hLtœ@cÊi`iVñ 1/æ´€ @)&€Æ”âàtºjhL&ÌöûN©ï ¸n0è®ÉD¿ÈÑÏÛј²cÎQÙ!-€@«ИZ%Ç÷RN)å¢zh–S³¤X€ @è4¦.@Në.ИÒêÕC‰ÞÐn·-7_!ú¹ % ©A)ûÝ‚sÔÜ›úí·ÿäþG‡‚ùîÎ-z?û¦¨O‰Þ‘ShL9 ,Í*9+v~ïÂéú·xM§Å€ @€@ú 1¥/&]«S×P³£–  1µŒ®È_ä&1Ñ篊 ¶ç–SöCË/”\¥¿½»+É—ÆŸyY¿ìG˜@ >4&zGN  1å4°4«x&/Ü*I9™Š×tZ @€ ¤SúbÒµ¡1u 5;j™SËèŠüEn}4¦"÷<·)ûÑ-ø/”’0ÝñÅÝ,Óâ{iAå•™cõ§²4­xlpôý?½ºÆVÓ Ù?-(64¦bÇ?Ç­GcÊqpiZ± 1+Þ´€ @)'€Æ”òu²zhL¤Ë¶ÛC©= ¶•‚ß$.X´ÃÍ%úï9o>Sö\ðs”Œ%ç0Yî%efzôè½´ ,M;W-”´dSËiÙ_ïh}elÊ~ &€ÆTààç»éhLùŽ/­+4¦›¦B€ @ ýИÒ£ŽÕ©chÙpÛ 1µ e‘6Tð›ÄE u¹­o½·zó;Ó­Lßðsýº­}ó÷Î_?x«€Lhr>  1e?®ÿ…R&…Qö’D%iIúÓt%û÷Ý[´ ÄKZПÊÏ${Ikº•³ßhA  18øùn:S¾ãKë D©@Á¦©€ @H?4¦ôǨc5DcêZ6Ü6hLmCY¤ ü&q‘B]n놷Fë­f¾ô“|ø^™Ðä|@cÊ~\ þ e)—F-ÈUÚ¼pºL&-»$Las›”ºÉV3ùÉÖÏ~ &€ÆTààç»éhLùŽ/­+4¦›¦B€ @ ýИÒ£ŽÕ©chÙpÛ 1µ e‘6Tð›ÄE uO[G®Ú§¦Æ´lÛÅB«óI)ûq-ø/”¥\’Éd3Çé¥dKR”$3ÉRÒŸZA‰š´`ö’ý«?õ¦¾bñ‚@V  1e5rÔ»4&ºrB)'¤€ @È4¦|ı¥V 1µ„/u•SWqçeg¿Iœ—0ö®52‘Š©wY;ýИÒ£F5,ò/”æ‰sö’&÷?ZÅ4&ý+“Iðä-ÙG–¢É¾bÚ ¼ ahLU#€ÆDÿ€@N 1å$4€ @ù €Æ”8¶Ô 4¦–°ñ¥®@cê*î¼ì¬È7‰óÃVÚMÈD*¦V8ò4@cJstš«¿PÍqb-ä‘S£J›D‰nœ@cÊI i @€òA)ql©hL-aãK]%€ÆÔUÜyÙ7‰óÉÞµ#”‰TL½ÃÇÚ™ €Æ”‰0ÅV’_¨ìÇ@ UhL­’ã{)'€Æ”òQ=4K©YR¬@€ tS §uhLi õê!€ÆDoh7‰[€–¯ø ™HÅ”˜ÒŠ*hLÙïüBe?†´­@cj•ßK94¦”ˆêA YhLÍ’b=@€ @  Иº9­»@cJkd¨W4&zC ¸IÜ´||Å%d"S>J+ÂИ²ß'ø…Š‹á´›>~nXöƒL P‡]#§ИrXšU<hLÅ‹9-† @€@Š  1¥88®S§ ³ý¾@cê;Ãn›Ä ºk²%d"S‘û@žÛŽÆ”ýèò C®L³ßÃiA4&úGN  1å4°4«xИŠsZ @€ `°8ÅÁétÕИ:M˜í÷Sßp Ü$.`Ð]“•‰TLEî9o;SöÌ/T\ ¹2Í~§qИè9%€Æ”ÓÀÒ¬â@c*^Ìi1 @€RL€Áâ§ÓUCcê4a¶ßwhL}gXÀ-p“¸€AwMÞ°aÃiçü¸Èh{ž  1e?ºüBÅÄpâq»O½«!Fcê*nvÖ=hLÝcÍž ÐQhLÅËÆ!@€ Þ@cê¯\­Æ”«pæ´1hL9 lg›ÅMâÎòMëÖKÓþf,Y²öß_u+&SZE½ú@©ðRòU~¡jBêÒ·¾{輕[æ­Øràw0™Âô·ûîÿ¸iç»~Ù¸ã]+¯•Ê~_ýºì¥W·ÿùÕm~¥T6¨lÝ¥²^eKPÖå—7—ËÚM屮´éí—6¾½ÆÊko¿”?­~µ\V½ú§U¯üiå+o©¬ØP.Ë׿µ|ý›ËTÖe©ÊËo¾ðò*ú ¶²xíë‹_z}‘•5¯/ ÊÎ/e¾Êê Ì[½cުϗÊÜ•V¶?·"(sT–oŸ”m*Ï. Ê,•¥[gZyaëŒR™¾d‹•gåi•E›|òùO~j÷i 7O-•) 7MY°i²•ù›&eãÞ_Ø)%'Fª‘uhLY õ‡@™]€ @H4¦£ÛUAcê6qö×{hL½gÆ7>æ&q;nñþ¯ì?qæ vU7M/½“©€!ïMFcÊ~„ù…ŠÆÐ¦ù+·–Ü—7æ.ߌÉ¢¤ß¸ÏìþÎ[òí¥×¶ÿYEöÒW¤1šhSà0•&ç0•¦]ëœÀ´9˜œÃTÖ˜*“Ó˜|‡ieµÃhLÎa 4¦Àar“â(‡©¬1•¦×–&§1Í«¡1mhL=S¼ÆôL-ɦ©%‡©¬1Í7i#SöϦ´ EИR ª¾@cê =¾ @€ ´™S›fishLYŠVQëŠÆTÔÈ÷©ÝÜ$î¾ ~Ù¦I3_PB§1)ñ&SƒI•c  1e¿ƒð Šaà0}ïЫ¶Êƒ 4¦Ræžç–mú9™x̸ñM‘õVr§G;7ÿ²“ª‘š9£ê§!ôÑü¾zµ¦iL~¦%7g\Ù[ÚºKÓÃ#'¬·Éã‚òŽ›Bî劽žEΘBÉ­zåO+_y+(ѹ䪦ª¹äJÓF¦f¦“Û™Nnûìå¡TL[g-Ý:S¥’Šiú’-VB©˜LcúûOíQÎ¥b2éÁãmr=+¯íx·WqéõÊ'ïöñ°{ý-¾Ô@cJ}ˆ¨ š#€ÆÔ'Ö‚ @€ºB©+˜Ó¹4¦tÆ…ZùИè-à&q вøç0³ÛÔ¹ >oÕŽçWí8èæÞšLº3m:ÎÑGÝ¿ÿ^¸Þßk¯½|{¦_¿~z§!C[G+K{Ò‚þÔ¦´¬wâ¿ë*ãVÓMz}]ÓGúúþûï¯T¥¾;=joÆį`ÍŒVF•\¸paÍïÖû(Æ;v¬¾e&“5¿/4¦ì‡™_(‹¡9L‹^ÜVSB5Ig{m2I-²³«^:¡5<Áº>¥³–Ö׿vFªwFÕûv*ÓXײþm~/­uá’Æ´Çú­»zÊ–]2–¬˜·´o 1÷Õ¥°½´éí—6e•×Þ~1(rÓêWÿT"¹`.9K¿¶^¦f¦Š¦¹Å ë¼ ì°_ç 41ܳË4—\d:¹*ÓÉùÓ¢Ír˜iœiL›4—\y:¹›&ÓÉ3ÊÉaª©1É k-@Í~ ©YR¬—1hL Õ…@=hLô @€ @ EИRŒnW©ÛÄÙ_ï  1õžßø˜›ÄE躧ûeÍ%÷ìÒåëߪw\7Ju‹tîÊÏ­Ø>ðòÞ™Lv \îgû©˜ÄÖ7‡ µÖñ5&ÝÕö})GúÓÄ#­l“ÞÑŸ¶š½c ¶¦‹ m*ª1éÝAw«©ú®Ò‡Xž'· ·eÛc´Vþ ¶5·N´2~UýeÛ²Û”5ÓUƶi$£Sè#cåVy5Ó%¾ò?’4àܲA*oÇSö#Ê/”b覲„ZÉ¥·(˜4˜QÎré•NàÛg,zíëßêEN&‚ü³¨ÎîOÿâΓvÂÑyFg;áØ)Å?‰ÙùÐzŸÖ±_úlÆdíKç5)H°ä—ÍUù–öÝïë¿ÖK¼äç^ªm/½ö'©Ke{IS$ÓŠ ²—)ê0)ý¡e`²¢TˆA6D+ANÄòì®1“~ Ke»~¦UæXY^•‡©ÊaŠOÅTq˜œÆ4Åט*Ó¤’ÄÆÔ—Éw!"€ÆD—€@N 1å$4€ @ù €Æ”8¶Ô 4¦–°ñ¥®@cê*î¼ìŒ›Äy‰dÝv˜Ã4åÙ¥¥;¬õS1Uî‚붨榹ø½0™ÌRÖ KzäO!g¹[ã’i´‚S”ô¾yNv‡[ŸZ^ýiëØ rK餵lÉ„,Ÿ‡mÙî—[Û¸Þ÷qØfu+Ý¿[ïl'}¤ïÚ.”µÈvjwèm_ú¢ÕS«…$-«¤5Á*c[°—ÞtëÛ²¿/·«³­` «BSè#K°ä[bú¢j¨Æše…²ž(4!k!Ïý)ûÑåÊs˜"ªÓ˜”°Ç$Ô•×òÌÂW›4™ìäí&þ9ÄNÎZÍΓv"ÒyFÚ Ç¥í$柜uÒ³}þ‚}¥£}Ó4&eWòKÈX’Ƥ)Ò^RÊ¥JÖ¥u)”{©b/¹ôK½˜–F&ßa* LÕÓêy˜Úì0-ÞütEcÒ\r–©'“s˜*©˜Ð˜:ÚcÙxÑ 1-â´7oÞzë­ûî»ï˜cŽùæ!Ç|÷ÌßüîaZ~ä‘GÞ{ï½¼5•ö@€ @"€Æ”¡`µ»ªhLí&ÊöÚO©ýL °Enç;Èe‡i¶ç0U2yy *é‚™k¼»àÒ˜”ÑaÀe759»œS‚¢™~ì#ÝÆ¶ÜlR!swt{ÛI?v;ܽc¶Ý;7›Çþ4I·Ø]2³y즻…Ò<¡PXmãú–“œ|Én±«†&c9õGËVËDâjå6î*i­óó‘èOW+Û»>uÓØù{ךö§>uY£B$£©á¡”Næ{X_Ÿr:”å¸ ™XyîÿhLÙnÁ¡œÃ'¡ö¤b ré¹y–m›¶@&ÓAcÆï¦%E׉žœ£éNk¡Ó¾ý韜uÞ³‰,}#S'®¨£Ùö~ª¾Oヌ²+•,™«Tm,í»ßþÃ_ž0®ä-ùÓÆù3ÇÕ°—^yk冷+õ209É%aZ\; Óë «'’+Í%çM$WúuV¦¶åaªv˜JÓÜ¿ÿ‡@cš\šK®4ÜF7Ù˜ÚÞEÙ`Á  1¼ÐülÐÎ>ùÉOîVëõ_ÿë;wn¶›Gí!@€ ì@cÊnìú\s4¦>#d'€ÆÔqÄyÜAÁoç1¤=mª‘‡É9Lkß虨tÇÔ&$rwÁg-Û6séÖ‹š3™B÷³åÜèž·^&Ù½m»Yn‰=Ìþñç²Õ|wÇ¥‰jLzG#Çæ$ÙËeiÒfÍæñëàGÙHå ‰Dî‹î}÷-G¡ð¾\¥eÕ94ñœ%ari™´_­£7Mågcòwº÷ýÈ6ë¶æê¯Û¾{9©Kë;*ß=¿Ü:4¦ì‡¹È¿P5¦úªÀ-—^iZ±­Sç½²ÿ7˜LÑlL–²®™“sMÉ?[ï Ê¢ªk':i 1}fEI–’_JÆÒ—÷ÛÿÇÆ¿øÚÛ2–¬¬ö².ù3Çõä^jd/-[÷æR+• Lf‘k<‘Üón"9.¹`"¹Vç’‹8LSn^Ò˜b&²1u¢£²ÍÂ@c*lèix¶ ( Ó‰'žXS`ò߼袋HË”íHS{@€ d”SF׎j£1µƒ"Ûè,4¦ÎòÍéÖ‹|“8§!-7K÷qÿÇWöŸìæ’[Ü[u·Tå0Y*¦ù/–&¯‰¤bÒ]ð™/l±dë…¸±aN¦Ðýl¥ÒÍl½´àdv‘êç’¹,&úøw¸M{ª™)t§ÜöårŠ˜¢ä×!4œU©É2ùwôC½9É ›;å÷+¹ìMÛ”Y¡½‡ª¤,m•Û”¯1ÙGj”s’\5ÌXÒîdkÙwýXr©|wûªÖ¡1e?Ø…ý…jà0¹é䢩˜*ÓŒ¶Nž·!Þd² mþiÁ,OÿT=9›cÚPcÒO§Ð¨‘Ù…^i“ó“¢ 2–4×êý=%]É•U¯þ)(¯Xyk¥+^⥚¹—ØKõ20­Ù¹ ©$LeÃX’qà[­åÛ¬HY ¬µ’¸üjÛw¥L_²ÅÊ3‹ƒòtPªæ’S&9LJÂTÖ˜êäa"S:-»(4¦B…›Ææ‡€fŽkè0Ù §œrJ~šMK @€ ¬@cÊJ¤:PO4¦@e“m&€ÆÔf ÅØ\aoç;¼a‡É˱¤tKµj:¹:©˜t+Ôn^ðû&Sè~¶ÏÖ}$‡ÆI<¦Ý˜ô#ÏFwÍí›!NïØÊz§¦Ædïk­©[ì6›{G·Ø]þ!«‰œË~d[¶ Iõ4&}dÓ'ÙäGúSÛ7s(j)Y%­¶‚›ÎAÐ:ö¦iLZÍ2BÙ›~6¦Ð®})ú‘iLZG»¶zšËeê€qsM°Ê 1åû¨ÏeëŠù å&ÍV¶lý›fɘ„ªYÉ,‘^c µtŸôü†¯—“Ée“S”ªR+Ur,)[á°GŸ\¹á-s•ü"¬TÞ´RC]Z÷æ€ß_ãÔ¥±SçÿæÜKÆL™oª™Ô¥;‡ýãµC-^içÂJú¥Ë®rê9ÿpõ ˆ%{IE¿ÅA©)0•’0ýöÊÁ'Ÿ9à–{F©T’0Õp˜â“0M+ L›§”ò0©h.¹ÆÓ¤ùUœ·ZØû û=8büÚM︲ak‡Óû¼ÛÇÃNléÌÁ— 03ìý—N‰î§1™Jþ)-4”í3áö±{ŒÀÖ­[?ùÉOöJcúìg?ËÔrë&4€ @I@cJ: î)AøìºIhLM‚b5Ÿ@oç»”¦Y/¸º>êÙ G]2ÑËÃôzp üÅ÷O^ó³ÆÓʲä;£‡˜pÑsý»àÒ˜4ïLÿKoh8»\¾ÙÒºŒ@cÊXÀjT·h¿Pr˜¾8L[Ý |Ò¼:{Ÿrã¬ßÝ·à¼!s»§ÉÁ7ÝþÐç¿ô•ÓϽdŸ/~寡J]úæw=ê‡'œ~Î@½3jò<¥Îré—FNz~÷Üó„_ž~êÙøÁñŸû¾e{©ä×ÈÀT™Eî‘§æ|æ÷”ÆtÎÅWªÌZ˜ÎpÅO®‘„©ÎDrÎaR¦ûé3êlõ&²1eñ¡ÎI¯éÏG¬jØ žÎ㬫1It’qï§¿Ó—-©SRád¿o¼±W“­|ë»>üè#B€ @è4¦.NãnИÒêTM‰Ñ¢Ý$nQ†¾bÓ$9L•Én,WĨY޼dbe.¹²ÃtÎm³¸xBIcÚÜ_¤b:ëÖÙ‡ÑsýTLº n Îû&S†ºC᫊Ɣý.P¨_(s˜¬ÚZ>¿LUöÓ+¦]ýð å‰ÉÖ¼~çS«Ž8A)|&/ب¸ÊÅwϳDzr˜ž|îÕÃŒ—Ædó*SIB NàOÎ^÷ÕoüÛ˜qã³ß)Ê-°¾¡•™ôSø©Ïìár)Õ\Ðoå= t1ÏXªš*®Ú[ò猛úÜ*yKÒ˜,ñ’\¥ÑSæÉ^š>y7 RMàÔÿ)5‡)i…@~¡V¯^­ø¼[zNàcF'áÏã T;ë¤ýÈÓÒ˜ýEÓ€»ž/M'÷Ц“Ó üþÉk¤1Ý7i›NΗPÍdÚóŸþùwý/Q(7ï ™úߥ19ž5¤1ÝõสÍjcÉý†Ú/©¼%•I³ƒiã†zZ)—d/)Ù’IKnÎ8-+L÷œö¹/î{àw¹î¶ôo9ýÒÊOβ19{ÉÍ÷orõ-è·XŦ» þµlÛ¬¥Û”{éÎG&«Hc’¦&‡I厇'éÏ obe9iLCšØ3‹\MÉœ6KÂäý¦£1µrzâ;¨OÀiLn:9-è¥9âô¥f³1Y&½†®´LR¢`$Bà“Ÿüd &“ËÆ$iÝæ]ÿþÁG‰TžB€ @E!€ÆT”H×h'SƒŸ™¦£1e&Tiªhn§‰w§ê¢dßÔ½Òå›{î¼–¦³Y䟱N“Ý/%a*%Pâ‡Û8kŒnë^©&›Nî˜Ë¦üäSn·ªç.xé–§s˜n>iß/eÑ}W¿1rÐÇã.¥@ ¥NÿÄǧü¿;uȱݮ(È/Ô¥—^úë3.pù~Lš±Yätê¾ãÉUÎ@6iÍO°>ÊÜ#‡IE¦‹R.Y"=•¯Ÿ9ú‚ÛŸs xl>P_BíwÆÏÇ-¹nΆ? ovË“/~£¦w5ã•W¼ôì§>½GEÉJ%—’¿ éÎácî’g,Ùh¥ì4™læâWN;g  I§ž3P¡Ñ´qf­áÕ;d/)Ùáa£M]ÒÂá?8Þ~sÍ^Òäqƒï$^*EPI˜4sÜÉgP±ÜK¿½bð¡ß?Né—ö.å^²ôKw>-hLø—I ›w¾›ÊÆQ)@€ @ /ИòÉÚÆÔ4¾ÒehL]žÝä&q>‚ß ™LÊú0wÙfwÛU÷\-EÄãÓ×)Ç%÷̨r÷¼Ë‡/2‡I‰8sL)ßÃÖ™/lUš¥v¸àö¹º^/“Gà0í÷õE«6Ú¨ìo¿_¶´1“Îþ;4¦LΫtq~¡d2ü› |oÆNàîì­‰än±LgòÛÆ¬4F'p9LÝù¼L½g, Nà’Z¤1Õ“P•HïŒs¸{jï¾ÿAv{ˆõ ¿H`zç¯Ô¢`R¹OïQ΢TILhé”\ùâ—©ÚU ¼1+?Tôc*iÉ•òlq«wœzöÅGüàxM§O9ûbÙKr•®üÀ}O ¤¥a£-ë’ýìÊaÒ{åmʺ$ué3ÿ¸ç˜§—>üd0CÜ•·Üó=£´pó=OXî%û]Vî%9L.ýR¿ß\¤ÄK ô¿îóå3/4ôÁ‰ÿ²Ï—/»á¾_ž~áÁG;nÖKá)äb&ó™Ð˜²{ Pótp“«^/&•«™u‰TLéŒ4µ*ý/­é²+oô5&-“© †fB€ @ hLÉpOÅ^јR*K‰ÒâÜ$nNæ¾b&Óœ¥›Ü7–ÃcÖ [M`R¹øîy|`‘ÝW⇋‚L=“îŒ*ÓÐq«jN'r˜0™2×CŠUa4¦ìÇ»P¿PºGvÒoÎwú©é2:Ož¿Q'ðã.ŸªøÄç_s“Nàwñ®ñ«}‡IsŠo©˜J xüDz!‡ÉNàÙ5™|É LÖåKÓîÎIªZ¨ÈIÒ˜n`L]]©ÚX*¢4%«Êª ÈU2cÉÊ¥W QÖ¥ó.¹Ê².=9c™Ò,©ø‰—ìgWeì3K%0ðíCôï”ç×ÙÌq›£ÉãTä0É^šøÜËg ¸Â"{ã]#'ÌY«"iI¿Ñ7Ü9RåéÅ›k©K*r˜ñÇ&-ùåi^{Lj&30ù ™Ð˜²²¤é" ôI¡ )“¥bÒ«A6¦t5…Ú@¼uëÖO|â½2™þóþûç–¬ iLï¼û7pB€ @è4¦N‘ÍÀvј2¤ÂW©ð] …ºIÜ  ¬}G&Ó7¾}Èì6¹®•Yäv”ç!ª¤ñæ’[Z•‡I÷GŸ^¼ÅÒxL]Xš‰FsÐTf#ªé0ŘL;W-üÓ«k¢üj¾™5ÌÔ7 И²¥ø:í*0™N?ßM!gŠŒ? ¨eÑ›]š},0P«ó0Im©—H¯¦Ã”i“ÉúFH`²î$é>½»¯(‰”ª‹4¦¡÷ñ³+U¼±Š®T1–LZª*Á$q®”g‹s)—,ë’ÙfN]2ɦ³bö’‚hq J)÷R¹”rkYy¦”dË~ ƒ¢iã\ñç+ýj—§›7…\hF9²1eÿLI 2F)c£º¡C‡öJcºñ¶{CyŒéH€ @€@g  1u–oª·ŽÆ”êðP¹4&:B Šv“¸D™ûJÉd:xÖ’õ¦ð-ðÒ\rµ¦ùÁt3*1SM“irÿ£UæÞÔ?JïÑ£÷ÊR*œIhL™ [U¥ ø %“éW§Ÿ˜ÊfL%‹^y&Ð’ÃT6]Á%ä0õH¨1S=“éèGNy÷ÙüÎt›B.ú2©ìòZ ¥Hù‚4¦a£-µ’K°Ö•d/EŒ%%[2'¸¾·TκԤºäÛKN]ªi/ùSÉ6Êß^*ÉÇ”ÎBŽzK¡wÈÆ”òÞNõrF)g¥9E!pà6i2vä£SQ: í„ @€@RИ’"Ÿ‚ý¢1¥ T¡4&ºH  x“¸J™ûʸ'Çðíƒg.~ÍIˆ,„ \ÖôÝaÒ¨ì«Ûþüï|ä@Õs•”Šil¿ý3Ç“ g’S&ÃVUébþB]pÑ%ýNëè2¡x9 SU½Ê ¼â0•¤–Àb©$Òkè0é¾qÇ»>÷…[¦_cŠéݦ1Õp’¼¤JÒ˜† -K©ZT*ç¾²¹ájK¡dK¡|K5R.ÕʺT/ñ’E3”{©¦½d[N¿„Æ”ý³#-È04¦ ª™€þ{ñ•¯|¥¡ÉtÀßY´jcMéOfR¹"÷ Ú@€ @cê0à4o)ÍÑ¡nF‰žÐbÞ$nTæ¾2f\`2M_ôš»ÉZžÈÆ›¼&šÆ£g.¹¦ó0ivÓο¼ÿ·"åa’ƤõŽ¥e’ºd™™^?|æeýj¾¯ulÍÌ¡¦Â)%€Æ”ÒÀô¢Z…ý…’ÉôËÓú÷(2=ÓU&’³,z–H¯4ŘKÌSJÆSN¤×ŒÃ¤ø‡õH¨k^_³ÿ½û« _:|ЬAý§ô×òàùƒ÷º¥œHOËz_Q´Tú Îêéy™ÆäT¤š _ø_{G©w¼X»D °7‰‹™L_ÿÖÁÏ,xÕ L³J7S5Q9 Sõ-ð¶8Lë\¥Å÷ Ò²¡¶üL’™V<6x窅¦+ýíÝ]R—ÞݹÅÙKúŠV(BthcÇ  1uqÇwPä_¨Àd:µùì˜1Àd'pÏ@õ¦Rnž>:LQ‰¨JȤ)Jr•‚ÿ*lY¨eûTÒÒô Ó%99{IëK~êxohz¦1…æ}ëImUÊPøyiL÷ŽŠJ5]¥èôp=qñ¤¥rŒ*‘Šñ–ü9ã*êRJ_]šV™6Ο9.±•vØKNfbR¹¦;+B  ИڑM@ AúÆ€K.Ûw¿¯ÿ‡ÿøL²—´<ð÷W=·dmŒÃ´nË._O°þì€ @È'4¦|Ƶ©V¡15…‰•%€Æ”(þ¬î¼È7‰³³ÞÔÛL¦ió_q÷¿ëÞ/ÍPãß¿mø$ ÉÖKŠoƒ´¡’Ætã]#k®XJQÉIK=ºR­4KžgVwª¸ZÞ’æÜh¥µtJ}üS>z>­È 4¦¬DŠzB )ï¾ÿÁ†­»¢2“’0½ùÎ_›Ú+A€ @è;4¦¾3ÌìИ2ºU©@Án_S¹IÜ>–Ø’L¦¯xÐSsÖYâ‡ÐÓ>æaÊ@û©b¡ 1e?ÜüBù1”Éôӓέi â0ù Lc %L ý)é†;GÖOªTš}µ"*)–K…e¢’+%±,Tª&‰ë‘–*ù–J?¾ {K!í )û'KZ%hLYŠu…@“$3½ñöûJδå¿háwÿ¦\MM~—Õ @€ ´S fuhLY\‘êÆT¤h·­­Ü$nÊŒl(0™¾qиÙ/û9<ÈÔ‘èQÍÞ@cê ­t®Ë/T(.2™N8éÜhΞãuÎ爟ÕdÓο䆚iLe©ZE2!Iås_ÜOS=9©ÊUª!*™·TÒ•J© ýRž!®Ž´”T¾¥øtMhLé<R«¼@cÊkdi @€ @ 9hLɱO|ÏhL‰‡€ 4$€ÆÔ+D p“¸€½B&Ó~ßø·±Ï¾ìîk’‡©€Ý ÿMFcÊ~Œù…ŠÆP&“¤%ßJÁa Q2)”6)øsaO‘ÆtÝ#kåRr©•6Õ•LZêÑ•ÂÆRO¦¥tJKQ¥ )û'KZ%hLYŠu… @€ dƒS6âÔ‘Z¢1u+m+4¦¶â,ÊÆ¸I\”HW·Ó7™p˜ŠÙòßj4¦ìǘ_¨š1ôM&¦("iLÿ©Ý{$$—6ÉËŸ$éÚÛG„)ÕÍ«ä‰Jš®2+\•®JpŸý(mŸ¢1eÿdI ²D)KÑ¢®€ @€ l@cÊFœ:RK4¦Ž`e£m%€ÆÔVœEÙ7‰‹éH;Ídºñž±ûî÷õE«6ÆÌF¤©ˆÞÿÛ…EóJ)«‘ë©7¿Põbh&SM>Æô»WeK %OZ°ioiLCG˜“*“æËOre£2*õ”yÓf µ¥>hLÙ?YÒ‚,@cÊR´¨+ @€ @ И²§ŽÔ©#XÙh[  1µgQ6ÆMâ¢DºV;o}ð¬=þÛ'æ­XÃTänÛ¶£1e?´üBÅÄð×§žö›s.ˆ9{ë#I¨~ôQö;BïZðÖ[oýÝßýÝn¼ÚJà?ü‡OLž±Ðïo¶îê]`z»öÉ»}<ìÄÞ~‰õ!~hLé5„ @€ dSÖ"ÖÆú¢1µ&›ê4¦Í÷f¹IœïøÆ·NÑ¿íùÿué†ëÝ'S‘»GæÛŽÆ”ù~Ì/TL —m»qÎË·ÆK¨t˜j{çÝ¿Åû^|Ú4¦ìŸbiA2И’áÎ^!@€ @y&€Æ”çè6hSƒŸ™¦£1e&Tiª(7‰Ón×Å¢¿ýõ5ï_â0u;쯽ИÚË3‰­ñ Uú¾7|é'Uv¼õv½8“£‡ÆÔ‚¥Ôð+hLIœÙg 1å!Š´€ @€ .hLéŠGWkƒÆÔUÜì¬%hL-a+ú—¸I\ä°åé ·üþ¯¼õîû„nXâ0¹cä¤íhLÙ$¿Põb¨TLº6QÑÂo¿=ã0ùèИ:I-¬€Æ”ýS,-H†S2ÜÙ+ @€ @ ÏИòÝmCc*pð3Ót4¦Ì„*Må&qš¢‘d]|“ ‡)ÉH°ïv@cjÉä¶Ã/TMö–ŠÉ4&-èOßdÒ ‡)Ä ©K©áWИ’;5²çl@cÊvü¨= @€ @ ИÒ•.Õ ©K ÙM 1õ^q¿ÊMâ‚Ä~øÒá*ñ5“ ‡© ]"ÿÍDcÊ~Œù…ªC—ŠÉ%dÒjf2á0Õ$†ÆÔÐIja4¦ìŸbiA2И’áÎ^!@€ @y&€Æ”çè6hSƒŸ™¦£1e&Tiª(7‰ÓÖeÿ{÷_¸eaÃÈdzÿo4\ hLRƒ*ò ä§bò2iÍ?ýù¯äaªÙ¥þúïJðŠ)¯íxwõkoǯS¨O7lûóÚÍ»â›üúÛïwösòn;±³»`ëH‚SÔÙ' @€ @ ßИòߨ֡18ø™i:SfB•¦Šr“8MÑèT]úí·Ûïw;úÑ£µùLZпƒf <°ír¯[öÒ¿òœÜ§k^_Ó©Ú°]t‡Sw8wr/üBEé†R1ù ™: ¶ ®@cê:rvØhLÝáÌ^ @€ @E"€ÆT¤h‡ÚŠÆTààg¦éhL™ Uš*ÊMâ4E£Su‘“$?I[—¨$cÉÒ2¹üL[vm±OÝ;Ó7L7ç‰2L)ÃÁ+W_¨P £©˜B ™²sZ 4&úBN  1å4°4 € @€ 4¦á'½k4¦¤#Àþ@cj̈5"¸I\„N¡¬Ký§ôWK•Éô² Lz _:\隤.é­`ÅÄ&^È04¦ ¯\u~¡B1¬™Š‰„LÙïé´ 4&úEN  1å4°4 € @€ 4¦á'½k4¦¤#Àþ@cj̈5"¸I\„N!KI®’ZªK–ŠÉågÒ²>•ç$uI úTeì‹cm5^È04¦ ¯\u~¡B1\¹c¨˜X¶äï^öY÷§>Ê~Ài<hLt‡œ@cÊi`i @€ @ AhL ÂOz×hLIG€ý7&€ÆÔ˜kDp“¸ÂÍçr,ÉR²eKÂ$«ÉĦ]ÝesÌ¡1¡cä¼hLÙ0¿P11|xùgõ¿ì™@ 4&ºFN  1å4°4 € @€ 4¦á'½k4¦¤#Àþ@cj̈5"¸I\„N¡‰ä”‡I-U¾%×^½£¢»ç^6l(2Úž[hLÙ-¿P11DcÊ~§±Иè 9%€Æ”ÓÀÒ,@€ @€@‚И„Ÿô®Ñ˜’ŽûoL©1#Öˆà&qa;…¦#~pìøK¾´ï×0™ Û òÜp4¦ìG—_¨˜¢1e¿ƒÓ‚XhLtœ@cÊi`i @€ @ AhL ÂOz×hLIG€ý7&€ÆÔ˜kDp“¸˜BÓ‘?8î…—ßX²ö§¦/þâ—1™ŠÙrÝj4¦ì‡—_¨˜¢1e¿ƒÓ‚XhLtœ@cÊi`i @€ @ AhL ÂOz×hLIG€ý7&€ÆÔ˜kDp“¸€"p˜~xÜÒuošÆ´è¥×Ç=ƒÉTÀŽ÷&£1e?ÂüBÅÄ)ûœÄ@c¢ƒä”SNK³ @€ @ @cJ~Ò»FcJ:ì¿14¦ÆŒX#B€›ÄEëæ0-[÷æÒ—ߔô¸¤1-\óú¸§1™ŠÖòÞ^4¦ìG˜_¨˜¢1e¿ƒÓ‚XhLtœ@cÊi`i @€ @ AhL ÂOz×hLIG€ý7&€ÆÔ˜kDp“¸PBÓQ?¨ôÒ:öÝéÓ§kaÿý÷×.\ÿÝÐî´²¾¢ïê}½úõëçªÚpS}éÚ×àÁƒ}½ÚÕYíÕ¿j~_jRôï¢1e¿ð C4¦ìwpZK‰’ShL9 ,Í‚ @€ $H)AøIï)é°ÿÆИ3bn¤S˜Ã´bÃ[JÅTšQî F¹@cZ½sÞªsWîxbÊÂÏ7m29s(ªÉÂÑË›LHŠî4&SÜŸkÖ¬i©šu;v¬}Q“™LÍl*~_²‹¶lÙRo³¦Ü jr¯4&g/é[Ñ5„À =И²ßø…Љ!Sö;8-ˆ%€ÆDÉ)4¦œ–fA€ @€$€Æ” ü¤wÆ”tØchL±F„7‰‹Ð)ÂS%“?£œR1=_Ò˜ž[±}ääfM&ól”:h·Ýv eZ’Ž# ɽ)ŸI‘Ó˜´lÉ™L÷‘dê}ËÆ¤e}Å” û®éGÒ’lM'Hõïßß¾•~ôŽSˆvíÚeJ“mJ “´Kzä6eÖ«Þ¾¬·¸Úú’–ëH–É5ÜiLnãúº*ã²CùMÓ}ç ©O‡'SŸð¥âËüBÅ„)}”JtŽSçØ²åD  1%ŠŸC€ @€rI)—am®QhLÍqb­$  1%I?³ûæ&qfC×lÅ=‡é­eë{¦“[¼öE/½^žQ®”Š©¤1mŸ³bûìåÛFLZðù/5ž].>“ŸOHZ,"Ó˜œ„$kÇÞ1ßHrÉOöŽþuÙ˜L’¤­fѵ‚ù@æ<… Ø›¶M—„É6¥wlS®’nS6­[t_¡kƒ&fY…ÝË©]6µœÛÕÓv'yKïë_½ô§L,k‘Ÿ)JëÛû¼Z$€ÆÔ"¸}_¨˜` 1¥¨§R•N@cêU¶™hL)U€ @€ äŒSÎÚ›æ 1õ†ë&C)îß+7‰3ÀÕw“7Ü›/ØŒr/½¾h4¦ó_Üé§bš³<Иž]¶íñ‰ó÷id2…4&Y8Òt,Ÿé;rq,e‘Óƒ´ìûF¶šËÒ¤•c4&Khdn“e`ò§l³XüœF’ä9[ÈyEN?²/†f‹î+ÊÚ4,—WÉV°Ö™Ÿdº’5Ð)JªŒ 'ý«¯ë¥W· 7^¾ûgg[‡ÆÔY¾ÝØ:¿P1”јºÑÙG‚И„Ï®;I©“tÙ6 @€ @ ˜ИŠ÷R«Ñ˜ üÌ4)3¡JSE¹Iœ¦h´¹.5&:¹ú©˜ä0ÍZºmæÒ­Nh`2…4&óŠLÙqù“,÷’M—f)ˆœ´¤‡4&Ë“¤÷kfcòÕ"-KòÝ#›ÇÍæ‰Ó¿Ê´dùì¥?m›Qɾ£1پܦÔsô¯MŠç¿›ZÎ5Эi–™‰e¬”YÊס˜N® S &¼ ~¡b€Æ”pïd÷&€ÆÔiÂl?!hL g·€ @€ @cÊqp5 ©!>OžSò1È` ¸IœÁ 5Ue.¹åëß\¶Î›NNy˜œÃJÅTšQ®¤1mñÂÖéK¶<<~Þçêçdj8©œêjb“ülL–-ÉOYd­’£1É…r®V³?M0r–’OGÕS*&{Çí½žÆÚTt_nËfeÕ ƒo ITÚm·Ý´k-8Êef² ï¬ÕZÁUµ©³RChL ¥~~¡bB„Æ”úþKûF©oüøvj  1¥64T € @€ YhL™ ]ß+ŽÆÔw†l¡ÓИ:M8—Ûç&q.Ãê9Lo.3‡éåÊ\rkß0‡É¦“›¿zç¼U;æ®TÙ>§Ça R1™ÆôÌâ-=ùü羸ßË/¯²ŠÑ˜l9}Å-˜Í£ù:–0Iÿšd³³Yv¢š“Ûš%|ÒŸ¶)½ÜŸ~’'ûH)ŽL¢²—ÕÇ6e)‘lµÐ¦\­¢ûj¦·ø“yZÚå ²& ˆmGÛw@Bé—ÈÆÔ êë 1µb›à*&hL ÷NvßihL&Ìö"Ð@cÒÝÔÈ–wÔ^~^ЄjÎn!@€ @H+4¦´F¦ õBcêdvÑGhL}X̯s“8q7‡I˜\¦ÑÏnøéÓ–¬}cqÉaZTr˜”¦ã/Ÿú| 1mnÅö_]7ãð‹'>@eücÓ×Ó’-O/Þ2mÑæÇÕ5™20:õ[&ªM%ûD©OøRñe~¡b€ƔŠ>J%:G©slÙr‡ 8?^ûq.»dœq“&Kãi5ÔŸ²—ô§^Ê;Úáj³y@€ @€2K)³¡ë{ÅјúÎ-tšS§ çrûÜ$ÎYXå0ùÃã,“›HnÔ³ŽºdââÒ\rÎaš²`“¦oœ5F©˜ä0)“¦[G¯>å¥&¿äR1=½hóÔ…›§,ÜôÀ¸¹{×ÉÉ”3†4''И²H~¡bbˆÆ”ýN b  1ÑA2H@Þ¼&?§¦ì%%5ÉTWc’±¤L¡.}¨V5õÉ}3ƒ@¨2 @€ @]!€ÆÔÌéÜ S:ãB­|hLô‡p“¸h©ýJà0ýà8³—T^xù %a5kÑ'º¹ä,ÓÉ×ϼaÄ2iLÏU¦“S¦'Ÿ{õ)‡©’Š)Иlš<Óýcçîý…ڳ˥– +.4¦ìÇž_¨˜¢1e¿ƒÓ‚XhLt Pî%M”Ò˜ä6ù&RƒIå|I² ‰ý73ˆ…*C€ @€ ÐahLœæÍ£1¥9:ÔÍ 1ÑZ ÀMâ ¥ó+æ0SÉ^2)˜Hî¥×GÎ\/i¡7—ܼÕ;JsÉíÆ¤{ù¶g—m1cý̶j:¹3n~ö77?ûôâÍÓlF¹R*¦IóÉ™Lc枣ÎC) —ßx$…‡@*¡1e#Nqµä*†Sö;8-ˆ%€ÆDÉ,?“&…³vô/½´Ð i×®]‚¿ÑÌ’¡â€ @€ t†Sg¸fb«hL™SÁ+‰ÆTðÐZó¹IÜ·´}ë ƒºížÇuɳ—$0- 20IcZwäÀ e‡iU9“æ’{nE 1™Ã4kéVéJr˜”‡é¦‘˽h|ÃTIÅd“Ê7¾{ÄqÿÃÐùÿ“~)E# y"mý¿v}И²§¸Zò C)ûœÄ@c¢ƒd–€o9É%TjVc’å20 J! ªÔ9Yú¡Acê\?èÖ–ù…Š!ÆÔ­nÈ~"€Æ”xvÛwNc’}Ô¯_?Û ô§hLÒ•Ü\rJßš‘®ï•c € @€ äSƒÚl“Иš%ÅzÉÈÒÝåä(±çnç¦K˜ÉtËÝ-\³SÅ&ËÀôØô—•uÉ•ãþ8Õ&åa:àÌ1ÊÃ4si0—Ü1—M9lÀøÃ./©j:¹ùå$L!‡ “)7§ù†d釩ù¸¦uM~¡b"ƒÆ”ÖnK½ÚD©M ÙL÷ øÙ˜d%™‰ä|¦S´º[¶lé~Ø# @€ @Y"€Æ”¥hµ¹®hLmÊæ:@ Kw—;Ð|6Ùn·Æ-ß*›Lw=fö’ŠËÀôüªsWî°‰ää0I`š½¬<—œ9L3–ÓÉ=³xËÓ‹6×›NÎÏÃd&S:{Bçj•¥4¦Îõƒnm™_¨ÒhLÝê†ì'!hL g·&Ðk©Óbû€ @€ džSæCØzИZgÇ7»E Kw—»Å„ý4$ÀMↈ²µ‚™L7Ýù¨æ³)äL`š[˜, “&’+Í%WÎÃdsɵæ0Õ3™nY˜-tÔ¶Yú¡Acj&¢é^‡_¨˜ø 1¥»óR»>@cê3B6NhLéŒ µ‚ @€ d™S–£×Ǻ£1õ _ï,Ý]îvÑn7Ç)KkÉd:òÈÀd*ÛKÕ“9L³ÌaR¦‚$Lu¦M“æ•§“«—‡©^N¦5¯¯ÙÿÞý³Dº6G K?4hLÍÅ4Íkñ 4¦4w]êÖhLm€È&ÒH)Q¡N€ @€ l@cÊvüúT{4¦>áãË]!¥»Ë]ÂNš!ÀMâf(enwÿò—ƒ9ü†Û±)ä,S( “s˜ž åaZ¸iò‚M“æ÷ÎaÚòÆ_>üè#µë¯»úOé/iú†éƒçVZ¦A³éMýk+HrÒGZпzÓ½Ÿ9άp–~hИ²ßAù…Љ!Sö;8-ˆ%€ÆDÉ)4¦œ–fA€ @€$€Æ” ü¤wÆ”tØcYº»Ü¸5¬Ñ%Ü$îè®ïÆL¦ë‡>˜\¦K‚8LÖÐ~cûI`’º$™éèGûâØ-»¶¸üLò–ô©ÞÔ;’œ´¬uºNˆ¶B K?4hL­D8]ßá*&hLéê¬Ô¦íИڎ” ¦ƒS:â@- @€ @y"€Æ”§hö²-hL½Æê ÈÒÝåð°ËÚ¸Iœãža&ÓuC¶)äz&"¹Å[$0ùS_ò09˜ò“”rIêÒ^·ì%™Iï+ñ’Ü&[Áì%[ǽ“ã@ä©iYú¡AcÊ~Ïã*&†hLÙïà´ –$§ИrXš@€ @HS‚ð“Þ5SÒ`ÿ déîrãÖ°F—p“¸K Ú™L×yئSQ¦h¦© 7Y¦¶8Lj«ì%ýë«KšfNY— ƒ>•À¤•„É•„±ÛÞÈÒ Sïb›Æµù…Љ S»,uj#4¦6ÂdSi"€Æ”¦hP@€ @€@> 1å#Ž-µ©%l|©«²tw¹«`ØYn羘ÉtÍm—¦òDrA¦r&s˜4‘Üü“æmœX*ß=ìGWß0tí¦wbÊ–7þòáGEZ¦%½o“ÇÙ –I ×ײ?Çœl'­™û@ä£Yú¡AcÊ~Ÿã*&†hLÙïà´ –$§ИrXš@€ @HS‚ð“Þ5SÒ`ÿ déîrãÖ°F—p“¸K Ý™LW ~è™Å[žV©LSn–Àä&˜úè0©¡Ò•”iIr’?mœ².)!“+ZMïhš9½ã¯–('vÞ˜@–~hИÇ3íkð !4¦´w_ê×GhL}È×ÓJ)­‘¡^€ @€ ì@cÊnìú\s4¦>#d'¥»Ë‡Áš%ÀMâfIe|½²Ét냖)˜ü‰äæ—¦¾;LÆI&Ó®¿îÒÌq>6½©wô¾Š[ÍR4ñÊ ,ýР1e¥WÕ¯'¿P11DcÊ~§±Иè 9%€Æ”ÓÀÒ,@€ @€@‚И„Ÿô®Ñ˜’ŽûoL Kw—·†5ºD€›Ä]‚ݘÉtÅ-:É&’sI˜Úå0¥ ­T¡S²ôCƒÆÔ©^нíò é{‘=%B)ìì´óИ:Ϙ=@€ @€ŠF©h÷Ú‹ÆTààg¦éYº»œ¨ù¯(7‰óc¯…f2 ºåA˜&Uf‘kË\r…"YØÆfé‡)ûÝ”_¨˜¢1e¿ƒÓ‚XhLtœ@cÊi`i @€ @ AhL ÂOz×hLIG€ý7&¥»Ë[Ã]"ÀMâ.NÍnÌdºü¦á~&ò0¥&>i¯H–~hИÒÞ›×_¨FhL;kdšS¦ÃGåë@c¢w@€ @€ ÐnhLí&š¡í¡1e(X…­j–î.6Hék87‰Ó“Ž×ÈL¦?z&ÓwûÑÕ7 ]»é˜²å¿|øÑG¯;H7,ýР1¥»/5S;~¡b(¡15Ó…X'ÃИ2<ªG‰þ@€ @€@»  1µ›h†¶‡Æ”¡`¶ªYº»\Ø ¥¯áÜ$N_LºQ#ßdÂaêñ¼ì#K?4hLÙïuüBÅÄ)ûœÄ@c¢ƒä”SNK³ @€ @ @cJ~Ò»FcJ:ì¿1,Ý]nÜÖènw túv˜LßùÖ—ö;#d€ @€ „ 1¸K 18ø™iz–î.gjþ+ÊMâÜÇxñ=ƒ&÷?ú¥ñã-yY?÷¦o2á0å¾W´ÜÀ,ýР1µæÔ|‘_¨˜P 1¥¦ŸR‘Î@cê W¶š84¦ÄC@ @€ @¹#€Æ”»6ß 4¦æY±fR²tw9)Fì7B€›Ä¹ïcûíÿîÎ-Ñfn^8]z“ÿ¾™L8L¹ï}i`–~hИúét|—_¨˜8 1¥£“R‹Ž@cêZ6œ,4¦dù³w@ÿöþÚ®ªÎ÷ÅwüÇ{õÆxï¾úûƨÆÒ²¼—ûêë^ %jÔÒRA!TÙ ¨h”^ÚУ ,A1ôBГ„.}K’œä¤O šä¤%A"RRHþßµ{ϳöÚÍÙ{Ÿ½ÚùÙcŽÃ:{¯µæœŸßÜk-2?ç7!@€ "@c*bT[ìS‹ Ø-Eyš]NUW`’¸À#â­7.þŨGF¾öÑ1ê¦2)3“më¥m•Èû2™T´>zeÞäákÈÓ©³gé(îPM¢Æ”¥¡J[b €ÆTN™hLYˆm€ @€ ‹S±âÙVoИÚÂÅΩÈÓìr*€¨´&‰‹=.´lœL¦×~Ó§ŸÚÞ»¾GŠ’%aR–&ý*·ÉÞ×O[cNïk½£ el*6z×.<ÝhИÚnööçÕ$&hLÙ°´¨«ИºŠ““e‡SvbAK @€ @E!€ÆT”HvÐ4¦ qHÂò4»œ0ªkL€Iâbs•ÔGû)ŸIÞ’ÞÔ¶²4é§Œ%ýª÷ݧ&3é¥lL–®‰<ÝhИò?p¹C5‰!Sþ8=hJ‰RPhL ,Ý‚ @€ ¤H)EøiWÆ”v¨pyš]¼7ì‘&‰R5æ*é%WII˜¤%ÙÏ7öö›Ì¤—‰M–¢I?mÛŠ[.¥æSmæäéFƒÆ”¹áÓvƒìõÆ[;Û>ÒƒИ<²ß]Dcò;þî=SƒK× @€ @)@cJ |ªEcÊBhCsyš]&–™!€Æ”™Pt¿!ÎU’·¤Eå¬ÉIZ*NEY—”„Éå^²¼MúUV“í©í·Þ8ØýfqÆ<ÈÓ)Ï#ÍÚnw¨ü÷#– 1Å‚•“f‡SvbAKºJ€»ZWqr2@€ @€DÉãa€ÆäqðsÓõ<Í.çjñŠÆTà›«¤jy8YJ’™ô«ò3IW’Õd™–ô«¶õ‘vö¤CôŽ%mr†Sѵv äéFƒÆÔnt³·?S“˜ 1eoÀÒ¢®@cê*NN–hLÙ‰- @€ …SQ"ÙA?И:€Æ! ÈÓìrÂh¨®14¦åRré””xIö’:« ÷Óú®÷í#{IfÒ¯¶/DäéFƒÆ”ÿá‹ÆÔ$†hLùàô )4&HA  14°t € @€ "4¦á§]5SÚ þÁ äivyðÞ°GBИM5(<ÝhИò?äИšÄ)ÿœ4%€ÆÄ)(4¦‚–nA€ @€R$€Æ”"ü´«FcJ;Ô?8<Í.ÞöHˆSB ©… § Sþ‡S“¢1å€Óƒ¦И %€ÆTÐÀÒ-@€ @€@ŠИR„ŸvÕhLiG€ú'§ÙåÁ{à @cJt6«Ù·õPßœCo½™ÍÖѪ ÈÓ)ƒ¨Í&¡15†ÆÔæhb÷¼@cÊ[Äho‹ИZÅn€ @€ ´L©eTÅÛ©x1-^ò4»\<ú¹íSnC׆?}õ!MJfâÖäéFƒÆÔZL³¼S“è 1eyèÒ¶.@cêDN‘EhLYŒ m‚ @€ ä›S¾ã7¤Ö£1 'B O³Ë‰¡’V 1µB©°û 16´qu,O74¦¸FArçEcjÂ)¹HM©@cJ;•ÆO)~ÆÔ@€ @ð“oõÉãàç¦ëyš]Î Ôâ7©ø1nÒC4&¯ÃßIçót£Acê$ÂÙ:©I<И²5XiM×  1u)'Ì4¦lÄV@€ @€ŠD©HÑl³/hLmc÷äiv9O74¦N"œ­cИšÄ)[ƒ•ÖtSבrÂl@cÊFh @€ @ HИŠÍ6û‚ÆÔ&0vO@žf—SÀC•õ  1y=2И¼'ÏÓ©“gë4¦&ñ@cÊÖ`¥5]'€ÆÔu¤œ0И²Z@€ @(4¦"E³Í¾ 1µ ŒÝS §ÙåðPe}hL^ 4&¯ÃßIçót£Acê$Â@ И²ZÑuhL]GÊ !@€ @Þ@còx 1yüÜt=O³Ë¹Zü†¢1?ÆMzˆÆäuø;é|žn4hLD8Ícæl“fõ®»ÿ`ÿÁ?Ìpib €ÆTN™hLYˆm€ @€ ‹S±âÙVoИÚÂÅΩÈÓìr*€¨´4&¯Ç“×áï¤óyºÑ 1uáÔŽ³t̨é£R«>Û~ëáÙn ­ƒ@ Иb€Ê)³@) Q  € @€ b@c*V<Ûê S[¸Ø9yš]N•Ö#€Æäõ¸@cò:üt>O74¦N"œÎ1ÊÃ4â‘#'TÎ!ùL=ý=£ç¶mkÐä“-‘öÔG*é44ZÕYiLB!â0~ÕxmÛ¯Ö½czS;kŸ4šIè64¦nå|!€Æ”‘@Ð @€ @€@ 1(˜ív©]bìŸ<<Í.'O‡@còzh 1yþN:Ÿ§ S'Nç9Ãîfþ6¤4™¯ãò3é;}}zS’œäëhŸtÚšx­ê¬/u_@Ô}‰Jr¹´a  C¡wÌÓËó%%*ŒS P9e 1e! ´€ @€ P,hLÅŠg[½Acj ;§B O³Ë©¢ÒzИ¼hL^‡¿“ÎgýF3ÿžC³n)—sþCgü§_õþ:é3Ç$BÀÖMë?د Ë3$‡Éå²OMf²æ8'‘Ö¥Y‰8XV*ÉL. •ë¾å¦(}j­”ìåU¶ª4cCݱ@cŠ/'OSzì©€ @€ PThLEl ýBcj»¤L ë³Ë)ã¡úúИ¼hL^‡¿“ÎgýFó“ÒÌwÝ"«‰WV X!µNi„œŽã¤%ûT“d&er%«½ér»,•Nª i^FÉ%£²Oõ«e±²âãërS8’$€Æ”$mêJS‚°© € @€ à 4&O]¯›hL?7]Ïúìrn@úÕP4&¿âé-“×áï¤óY¿Ñl_ÕPczê²N:Ì1‰°”BªJ?‚c˜ô’ؤŒD2x\ "y<þ$r܆ÃeÉ« ‘Ë\¥mKgÅ ù&€Æ”ïøÑú†И€ @€ t›S·‰æè|hL9 –·MÍúì²·ÉvÇј²Ÿ˜[‡Æ3àâ>7šº ™HÅ”í±(/G9„$ß„—“ £÷%0é#yKê6Li ï–ížu¡uâ µËR.Ùéô«¶MfrY¬ —!êB­œ©@cJ=4 hLñp嬀 @€ Ÿ  1y}4&ƒŸ›®ç`v97,=j(“GÁ®í*“×áï¤ó9¸ÑÔMÈD*¦N¢è1¶nšVŽsµ*ÕÞÔÏð›zÇöôç¥îpŽ%ÇÁÁ1\aVþ ¢§Å$€ÆT̸ҫChL @€ @€ºM©ÛDst>4¦ËÛ¦æ`vÙÛØd¸ãhLNüMCcŠŸqÁjÈÇ&’‰TL…tð“Qö²hL^†NC€ @€b%€Æ+ÞlŸ)Ûñ¡u|Ì.«Œ@cÊX@’mS²¼ P[>n4‘„L¤b*ÀÈ£ €€oИ|‹¸7ýEcò&Ôt€ @€ 4¦ÄPg¯"4¦ìÅ„E äcv™¸eŒSÆ’lsИ’å]€Úrs£q ™HÅ”ça÷ú¿oÝñúœ<÷ ƶïþýâ}oôÆX§†@ºИÒåOí±@cŠ -'† @€ xKÉÛÐ:„ÆäqðsÓõÜÌ.熨 Ecò"Ì:‰Æäuø;é|nn4.!©˜:‰sVޱ;TVZ“±vLXó^}3Ö(šî@cêKΔ)ÜÕ2@€ @(4¦B„±³N 1uÆ£’$›Ùå$¡P×`И#TèÏј Þ8:—§2‘Š)ŽAà9јšÀFcJp$RUИҠN @cJ2U@€ @€<#€ÆäYÀÃÝEcò8ø¹ézžf—sµø Ec*~Œ›ôÉëðwÒùÝhz§=6ö‚;é$Çd†ÀÓ/ž÷Õ ™ð­Ëï|÷/'™™XÑt›S·‰r¾Œà®–‘@Ð @€ @€@ 1(˜ív©]bìŸ<Í.'‡@còzl 1yþN:Ÿ—Mooï‘GóåO;vl'ýä˜ غu«‚xò©g\}õÕhN¶š0eÊ”O}ö‹â£¡ž­–Ñt‹S·HržŒ@cÊX@h @€ @ И ÄN»€ÆÔ)9ŽKŽ@^f—“#BM-@cjRqwAc*nlcêY.n4%‡iØ +¶ônzõK˜L1 …˜O[r˜†=?·WA<ý—`2…yËaúôg]²®þò-ÂdŠy(rúÔ 1¥†žŠã%€Æ/_Î@€ @ð‘“Q/÷Éãàç¦ë¹˜]Î MoŠÆäM¨ëuÉëðwÒùìßhä0}ø¨a z·®Üüª ˜å/íÃdê$Ò©#‡éÃG›2o¥ âiç`2•CbÓÒu;5¼WlzunÏËú9™R¯T4¦˜ÀrÚ´  1¥ê‡ @€ SñbÚrИZFÅŽ©Èþìrjh¨¸14&¯G“×áï¤ó¿ÑÓÑÃön]µy¿IÒ˜zúö7âë¬.×I¼Ó8Ʀ©óV*ˆÒ˜\¿ÎÅäd ¦Ï»lýÎU%KoÅKû–÷훳l3&SC•:c&€Æ3`NŸ4¦´ÈS/ @€ @ ¸ИŠÛA{†Æ4("vH@Æg—SçCê@còz` 1yþN:Ÿå9L‹Vn]õr ¿8É£§oïÒ{1™:‰wâǘÃ4mþÊÕ/ï›:ÄïíµÉ$‡é3r˜6쌌ðe÷ÎZºùƒädJ|¸Ra¼ИâåËÙS#€Æ”z*† @€ –SaC;xÇИgÄiÈòìrÚl¨¿!4&¯“×áï¤ó™½ÑT¦WVoÙï$KÅ$Éc醽K6ì9vÄ×ïºçÞv»=f̘ѥWOéå·7ÝK»é#ý9ínsæÌiå̓êTýýý¶³6Úmyîö/;L/¬ ÑAÜQ&ÓåWü°Ý®¹ ~8ˆ:O__ŸÖFø´ãÇ×›V½Ü\ìt*½o»ég»Mjws˜z6ì ¯Š¨á3—lúà‡Y²ly»gv= põ×:h/më•:„v»Æþù&€Æ”ïøÑú†И€ @€ t›S·‰æè|hL9 –·MÍìì²·ÉEÇјr¦¸‰ÆÙž7›7s˜¯zeÍ–ýY|*+Ê•5¦õ{¯Ûsì m›LÆ 1b„©ÚÖË¢{øá‡5*¢1éÍHìkws“ûÈìýÖ›¤1I]Ò›RdôÒFij)Ø sS%ˆU+ʹ ¾¸~ÏȳFµk2…ƒ¨hº *‚ÚvÁ9r¤QÕ›ÚÖûÚAä‹‘ýjû+ŽúU»ÉþÑOwlq1‡iùÆ]‚S•Š)õö‘™ñ¢L¦µk2…‡¨uÜ„<ërºâË93M)Óá¡q@cêœGB€ @€ PŸ“Ç#Éãàç¦ëÙœ]Î >_ŠÆäkäKýFcò:üt>ƒ7šÃt 6‹-F¦,>’<¤1-Z»û‹Ç·g2E|³[ÄNòG$¯½ÁZw7Û'ü‘9R‘c-Ó½iI'1ËÃ1r˜>¢µä^XµfKý ÊÔ ñ»g¶g2E‚¨_;yHæúUÌõQø}¹J.'“> ‡XF”£[ún;LáTL‘Цɇ’ç¬#u5&ëQ*º“óä‰Sž¢E[Û €ÆÔ,v… @€ @ %hL-a*æNhLÅŒk±z•ÁÙåb.foИŠ×{…ÆÔ"(v«ÈÚF“ô—W½²vëf©˜ÊÓî…kw/X³ë Ç­õÕå">‡s_ИÂãNÆL+—¥2ÒÍašþªPƒTL½‘|ZÕAüN;&S]Éi®×"lf’¥\ªM1xܵFT·H†¦Á+¼f¢Yzë‚>uQ_[&Ó5¦ t &çÉ4¦œŒæ¶J©URì@€ @€@«ИZ%UÀýИ ÔÂu)k³Ë…\Ì¡13®-ö ©EPìV!©M‡éå²þb‰jjS1™ÆôÂê6L¦ˆãRõHþ¿\ЦÈ`©»›íÉÆtØa‡…wŸÇ-õU¼‘Xv˜„¦š †—T>-ÄïœqQ‹«Ë  ØÚš€ne@mLž<9ŒÔW«ÈIr²p„W‹««1é$Mrn %dÎaª+xÕákv/X½ëù…}GÙêêr2Ê>¥6·žÉ:„¡äØ|@cÊwüh}ChL @€ @€ºM©ÛDst>4¦ËÛ¦fjvÙÛ(ä®ãhL¹ Y7ŒÆÔMš^œ+;7šA¦p¢šê,>r˜æ¯Ú5oÕÎϹ¥œL©gcRŠ °IS¤qV'“s˜¤b 4¦’©3uÄS[3™DÙ9’ôr9–êfcŠ,3g>“ã_Wc²%꺗:STðÚç/[QÎ ^óWí|î…VM&iL¶”ž^ê¯uDY©Â‹†×4LBשrÂ<@cÊS´hkИڀŮ€ @€ ´D©%LÅÜ ©˜q-V¯²3»\,®ï SÁܼ{hL^‡¿“ÎgäF#‡éÃG[^K®®þ²qô'œÅG’ÇÜ•;çôö·b2E4&ç¾$¶¨œ,Ó«“heû9L â4·–Ü–ý«*A´åäÂÙ†–„M³|Z ⼕;çöîüöéƒçdŠÑÀÈ݉HK¶rߘ1c"˜Ünu ž°îÓ-äƒ8LÎÒ‹Œp ^8áÏÌߨJN¦º#Y²´Löa±íÄ t &çÉ+4¦¼FŽvB‰!@€ @€@·  1u›hŽÎ‡Æ”£`yÛÔŒÌ.{Ë?§GcÊiàºÓl4¦îpôè,Y¸Ñ8‡iÍ–k¶ì_ýr•þâ–“kœ¨&ÈâcÓìýÿü¥¯ÞuϽMB(…Å2Óè%™Ã-’?äyØû.WÞ¬}§v7«.²¨\äX§.RcŠ:L¥ ®ÚüêÊͯÊajÄH*&ÄovaóÕåêjL ªàŠ°ÔœHpõ«Þ4ÕÉ­=—ŒÁã¦Ú¾¢’¤ÊL\ºaoCÁ«4Ÿž·ñ?ôÑ%Ë–7áu5&¥e²©.kkÛ%jJ‚GWUºÚˆc£ ј”3ðàÁƒ®ïúU×b—H° Lè @€ @C#€Æ44~¹>)×áó¤ñY˜]öu‘º‰ÆT¤h¶Ý4¦¶‘ù~@L7š}o¬j‘lÈaÚÿðìÍ?·lɆ½æ¾¨<÷âotßÒž¾Êb[öŒ›Ú·x])ÓšÝÏ-þ͵÷/¿ç¹ –Ågvoÿ¬ý3—ïø\S“IIhœ™$©Åµ3¬+9)ò¦v®»›D¹™J™4‘=ó§1ýng‹AtS`¡•D´kÆ-›ÛÛoA”ÃôÓ‡z¬Ù]Ñ6ì¹ãéuå ® ² ýì‘•7=²Ò‚(SÇ‚øÍ¦&“‚Ø(£•b*MGÒR8¸êˆådÒGá¯ÚÜK-ecjNÈa*ÃQOozxåÕc—=8s³KRep&/xEŸj99áOÎßrù=/>>wKYð*Á™4wCs“)<Ô·¤Ìás“vèB‹ãƒÝ `И ¹%àäWëî#º§¸ i3I;…W*uWá°Q›[,4€ @€ Ø 1ņ6û'FcÊ~ŒhaL³Ë€-64¦bÇwÞ¡1yþN:Óf\ïŸ_õW/¿úHó6™Ã´håVç¾ ?² §¿œqóüáçM Òb[§ý|Þ•¿^²hÝî…kwßûüÆ/]þüew¿8ògspë –ŠiÖò2`fôlÿÜqƒädê–oÇŒ;õÐχê›Ó¼ße‡iþJ b) ÓþáçOúæõ3]¦ã¯œòØÜ—-ˆ£Ç¯øòÏ[/ñÜ[œ{ë Ç]þ\$ˆßüþ 9™Ò ˆþ/R|ömmÞ9LŸþܱ=v:8c&®œQw,úÑØegÜ2_d”‡É¦i˶‰Ìó6Û‚‰˜NúÉŒËî^,2¿|rƒ3£gÇSsÖ¿°œLi¡nÔ%€ÆÄÀÈ'IKÊ`çÚ.Ô–£uiíjL²Ÿ¤+…Sä¹)SD¶Í'Z @€ @€@<Иâáš‹³¢1å"Lž72¦ÙeÏ©¾ûhL…q³¢1yþN:ÓF“´TšÈLæ0-”ÃTq_®·ìÌ[æŸpÕ[ikyß>IŸ:gËO'ô–^Γ³Ö¿ÿƒƒ¬.—*†@]hL ŒP?3‘¬íRš¤1Ù¶$%Kï×Pc²•ã\6&-áiI˜ä@á0åp0Ðd@€ @€@‚И„µªÐ˜²ÚSK ¦ÙeP›S±ã;HïИ¼'éFã4¦F2Sà05lAïVKÞcî‹–ÙR‘º4kÅãg¼tám %vH™¿rçÔ¥Ûä0]!iMYò?ý¥ËîZ|͸žHiLS—nŸ²d&S'cÂã4¦2Sà05lʼ•á Z&-É:Ͼø[eÒ’“¤TCÒ˜³yÉú=ÌÞüð¬Mòu,ˆrÑ´& ‚(mÒ‚­á|Z.ˆ'/“&“Ó˜ÈLÃôÙc—®ßY‚ o•[ŸZXz%‡Iv—ò0)s˜ðI ^ÑB{"hLkv?4s“àüê©5‚sã„•¶Öž’W‚WÏöiÁßöÄÌu˜LCáœ04¦„S]7˜¨ä4&[.ÖV§uK”6[TN‡5¦Ã;LGšÏÔÒ ¦Ýèç€ @€ @ Иò³®µ©k(9Qlbš]Ž­½œ8И2†´Æ”ùÜÖÓ&¢1Ed&9LGuÌ‚[Ìí0ñEåGc—ª(?Í õÊðP–šÇæ¼Hë÷¼¸~Ïâu»å0©Hyau«FËÉ=0í¥ïÞ4çk?ž.ói ‹ÏÒ@òÆ„É4¤јªe&9LGÊašÛkAtq”££"IšÎ ­8yôL%Óú²4¦Ù›-ˆÒt¾tÅóD™:Z1íîg7\3vÙ'ÎX•Š)Ä,šL©Zf*9L_\²®¿v„kx[†*·–œFx‰L'ИfnœglúûoMä.D—ܹ8:ÂKÓiH#œƒ&€Æ”0pªë°Æ¤m¥RRN%m ’ÉÉÆdošÉÔ½r&@€ @€ŠE©Xñl«7hLmábçTÄ4»œJ_¨41hL‰¡ÎbEhLYŒJ¦Û4qãÑæ%Vn›ó®÷¾ïðùË·8{IKÈY~9L?¼o鳋£ä=Jásòu3•¥¦"yìÖ2dr˜´™ô—ù«I+‘y˜zû?~îIJÃTITc“•#?:|Òÿ¬¼˜é&”¡xóÆO(ˆÏÍí­ ¢­•¦-WŽ=ñ›·|<Aì½ñäÿuÄ‘KÖö×Âùå“k”l¬,0mÜ«µä´Z¢F¸9L‚#2ÊÃ$8ã§o’½d#|Ü´>Á ¯µç,=3™Þ÷ßÿ¡oÓæL_hhD‰a[aIËÌY?,3“6ZÍÆ¤5æÜ‰Ð˜r;h8 @€ @ hL‰`Îf%hLÙŒ ­ @cb!ýå'¿ÿÙáÃ×ÞÿÓ7&þä¾ ”Ö üäˆú¾—²4íÛ:vìØ/ŸxRmGEPQS&§éèW­%gA´åÒÄù«v~ýÚé7>¬˜¦ ÊÔ¹Ï4& b%Ÿ–LÛÆO=êÃYþ럼þÔuY‰ày^Îù4ï§žzê5?ýU-œ™Ëƒ%ä´œÈHÑSš±+ï]òýŸÏ+ð5ƤÒrr#GŽ´µ­1é˜#Fèr˜l#]£ € @€ d’S&Ã’L£Ð˜’áL-C!€Æ4zÞ‹Æäm胎£1yþN:¿qßX=íx}N'7>¦vQ9˜Ü2™N;ç’ÊêZå¶ä0]ußR˜d{HdQ–múËšÝZiKÓeÒ˜V휷rç¥w-Örrã¦öóËùß¹iN]ý%p˜>ÜÚ—÷HòPyãßñ<Ú‰sí¢r%ÉB&Ó—N<)D9L˜‚¥KšŽD´ëƯÐúhJÂ$‡É–K 4¦R•ŠI9‡Ä&¬0S'p˜–Õ8LýøòõÛ,ˆ¯¿ñV;}ˆmßÈ¢rÉÕ˜L7üªÎ-O¬–¥wóã«•žJ“@MYò[‘±.2ÊÃ$KOy˜äxi­=ÁÑš‰?ºoYÝî&ƒƒÉ[¼9q7 1uƒ"çH…€Ó˜T»Ö‚ÓŠrZNNʯ¤wÉÆ$]éàÁƒ®ÝúU“Ö¥K¥'T @€ @€@> 1å#N±´)¬œ´«ИºŠÓ—“¡1ùéºýDcò:üt>)"0¹VÊdúþ9ÛÒc–¹çþi/Ý?­O/–¢F əᡕ¶îynã=ÏmЧ¶ØÖ z« jý%â0a2µ=>ÂSµÀäN%“é¸_Ñò ]uï Ln­´Ÿ<°|öò~ ¢tœkÇõ¸ ÞùôzYhçübþ“ó¶N/¯ 8°œ\‡)ä0eÈdrSÀäàÈdºú†_Õ¹jŸ¦o\7ãºñË-C•á׎[.‘KÃ{no0¯»L#üú‡VÔ¼"&SÛ#œ&€Æ”0pªë[<Î^ýýýZWN9™d2Ù;ƒhLÝkg‚ @€ @ÀhLÞ„º¶£hL?7]GcÊM¨²ÔP4¦,E#ñ¶ 1%Ž<ïƪ15˜´Àd:ûâò[•ä=%÷eÏ¢ÊBrr_LÑJ[–¥Æ&-C6kEÿÌåZik‡ô[lË-'W×aÂdjo¸šÆÔ@`r§2“)İÃÖtDËÃÔ(ˆá5ë:LY1™ô‘&G&Ó®ÿU½¾»j„¯¶¾³<ÂKSi„ï(ðš$Uu&L¦öF8{'L)aàT—4¦¤HS @€ @ÀhLþ妧hL?7]GcÊM¨²ÔP4¦,E#ñ¶ 1%Ž<ïƤ1Í}edx ¹&”d2}ïì‹e½TÄ—É¥¨i`xT9Lþ²tÛ”%Aiâ0ÕšL¯Ì›üȈÃ'VÛȺoæ=âm´éÃá%äšh&S“ .ˆh:5"ÚŒ’ˆb‡©ÖdjÄy׎ÜÑ3§^·¸ëÜ;½q •}e2ýpô­!8Ó`#¼â0ÕXzM&L¦V‚Â>é@cJ‡;µÆN)vÄT@€ @ðŽ“w!è0“ÇÁÏM×јrª,5)KÑH¼-hL‰#Ï{…1iLma¹üŠŽ<ëb[B.¼ÆV9 “e©©äï‰d©©Õ_u˜äyüvÏzçk¤4I0µ ~co¿ïS;Q¼ëž{=áëA+i´ÌÑ© ¢%ÓH5TÑ:p˜Ä­;Dõ@AT(ÛéJ÷÷=éäo^5úÖ:#¼lw5á–i,,x ê0 Îö½è~78#†Hiˆ9<«И²Ú@€ @È/4¦üÆnÈ-Gc2BN;4¦Ø±4¦"Fµå>¡1µŒŠ@4&5ã’Ë®úîY£Üêc–¼Ç%aê®Ã$Ãã?Þp˜,Ók¿é“Ì4mÔ•÷ŽV“”ÂGÛÚˆ¼¯wd>ÙžŒ¢0;îúõOøú@KKvÄAó0™¦óïo½mµ+‚¨OõQÝ *ÊĽë{ˆã×¾ñÍ+¯ûed„Ï/$gªl-¹åUy˜:p˜œà•@ר­@cj•ûåŒSÎFs!@€ @9 €Æ”ƒ ÅÕD4¦¸ÈrÞî@cêK΄ÆäQ°k»ŠÆäuø;é|F4&5=0™ÎU^}¬¢w˜ÀTÎßÓÛ?«©áÑJ¦°Ã¤Jßzã i.rY$3éWmkC¿Js1ŸI;è}³$¾¼ôÜx½¿öÑ1h:^Üc“éø¯…-4—IË1¬ét–‡)ì05¢…µ6ˆŠ¬ÅÎí@Ld2]qÝ/ËjWÝ®áÔ@$¨"-hLi‘§Þ˜  1Å ˜ÓC€ @€<$€ÆäaÐ+]Fcò8ø¹é:SnB•¥†¢1e)‰·)qäy¯0;“HÊdúΣñ¥²Šœ&¥¨©,$×,KM“j [,ÚV& .ò–¤+™Ì¤}´!åEiÛ½¯THÈT;þe2}áø¯)ˆSËAl7“ÕÞ$ˆÎE Q‡(Ä ¨1É¥e2]~í/«Fxi‰=7ÂgºNŠÆ”8ùÝJ4&¿ãßaïј:WŒÃИŠÇ{‘)Iý–Ét꘸/3zvL¯1<:s˜TÓ\$*©(Í’¼ËÏd?í¥÷%»,þÅ([‰ÌŽRQB¦c•›ª“éË_« ¢­•¶"X+M¥n;s˜š1¼fœ ¢…ØÑrn%ö’ÉtÙµ¿p9Æj½r†ªeÛ§.Ý>uɶ)¥ráo>ñ«'k5½&EIªp˜‹#uB©j“hL9M„ @€ äŒSÎÖÍæ¢1u“&犇S<\ ~V4¦‚¸y÷И¼'ϚƤ>Èdúöé™Þq_ê;LªËi.NZ’™$cé½ý–¤G;¼2o²6,mRø¸ LÒžì#^µd2}þË_ qVE`ª âÒ²¦Ó±ÃÔ$ˆú¨nõ¾-¨ …[vZ”Étéo˜ÂvWÏöÀÒ“À´tSÂq¡ºØ  1ÅŽ˜ Ò!€Æ”wj… @€ ™S‘£;HßИ<~nºŽÆ”›Pe©¡hLYŠFâmAcJyÞ+Ì Æ$¤2™¾uúEJÞr_‚$LÎð°5*Cq˜T‘[PLN’¶¥(IjÑOeîÑ;ÚA¢’”½£Oõ¦Þ±mKΔ÷èÇÚ~3™Z âP¦&At.Zm; bZËÊdºäš[Â驜Ýe“áäaŠu”ròD  1%Š›Ê’#€Æ”kj‚ @€ øBÉ—H×é'“ÇÁÏM×јrª,5)KÑH¼-hL‰#Ï{…ÙÔ˜D50™N»P«Ùd¶\°ÌVÈð¢Ã”÷Øe¿ý2™þùK_-Ñò ÕqˆSö!4j¡L¦‹¯¹¥j„W'ab-¹ü—–×'€ÆÄÈ((4¦‚–nA€ @€R$€Æ”"ü´«FcJ;Ô?84¦Á±G 4&¯“×áï¤ó™Õ˜Ô™Lßüþ…æ¾DRÔ =S'°8¦}2™>÷¥¯6 ¢·“”É4êê›ëÚ]8Lí5ŽÈ<4¦Ì‡ˆvF©3n@€ @€@chL4&ƒŸ›®£1å&TYj(S–¢‘x[ИGž÷ ³¬1‰­L¦S¾¡20M­¬"וµäòµ|µ?0™Žûjm=w˜,ˆ2™.úÑÍác6ÂYK._ƒœÖ¶D©%Lì”?hLù‹-† @€ dSÖ#cûИb„Ë©»D©K ý: “_ñŽôÉëðwÒùŒkLê’L¦“¿w¹8LÄ8ÇÈdúìq_ ‡É…E&“¤¥0¦ ŒYš4¦ rÊ,@cÊBh @€ @ XИŠ϶zƒÆÔ.vN…S*Øó^)SÞ#8¤ö£1 Ÿg_cRTÂ&ÓO~1þ³Ÿ?níË{6m½QÙ¾÷ÿñö;>†3Ã}›L8L‘@…M&¦ bš64hLCãÇÑ™%€Æ”ÙÐÐ0@€ @€@n  1å6tCo8ÓÐr†¸  1ÅM¸çGc*dX[íS«¤Ø¯L “Új&S®®™L8Luƒh&S®G8„C¤ И Xº@€ @H‘SŠðÓ®)íPÿàИgÄ5И¼hL^‡¿“ÎçEcRß¾~æþÇQÿy˜: sfŽ‘Éôÿû‡÷/_¿­y2­ëíÌ49¹†|íƒï:ñÃÿ­ }¤Lcz‡LcÉ…šºI©›49W† 1e(4€ @€ PhL d'Ý@cê„Ç$K)YÞ© © ì¬hLqóø¨iLº'Þ»äÖ’Ëûh}ý·p˜êñò÷îºé„æpp˜ò>þ½n?“×á/rçјŠ]ú@€ @H‡S:Ü3Q+S&Â@#š@cb€t@©hÅ9©8±L¨'ùÒ˜&¬yï«¿û÷ºž‡²ÔüÇÛd©IhØ ±šF&“‚èg¦2ÏÒÿ™îÚÿf£ŽÃ4ÄÇá)@cJ9T4¦¸Èr^@€ @€€¿Иüý!4&ƒŸ›®£1å&TYj(S–¢‘x[ИGž÷ s§1 x­É„Ô»qXk2ùî0)„3qhÑ8ý·Ödb-¹Üp\‡â И Xº@€ @H‘SŠðÓ®)íPÿàИgÄ5И¼hL^‡¿“ÎçQcR?Ã&S'ÏÀ1a“É+‡iïúž×~ÓW½ïÞ ›L8L­4¡ИºA‘sdSƒB“ @€ @9'€Æ”ó¥ùhLC¡Ç±É@cJ†sÁjAc*X@ÛëS{¼ØûPŽ4¦}oôîþýb33™p˜r=ˆÍdòÊaš6j„Êâ_ŒŠNbÓä‘ÃÂošÉ„ÔëNã« 11 J© ¥[€ @€   1¥?íªÑ˜ÒŽõNipFìQCÉëAÆäuø;é|f5¦ƒ<8h^ûý[ÿñö;ƒîÆY& “éßßz;Ë-ìnÛqxÝ®}tL­Û$WïOï0»Ζ4¦ôØSs¬ИbÅËÉ!@€ @^@cò2ìÖi4&ƒŸ›®£1å&TYj(S–¢‘x[ИGž÷ ³©1MÞ8yää‘ygKû!! “ÞTцR4姯´5И%€ÆTÐÀÒ-@€ @€@ŠИR„ŸvÕhLiG€ú'€Æ48#ö¨!€Æäõ @cò:üt>ƒ“¼%Ó’´!WÉze˜´aI˜´®œd&}jÅiO à$EÀR.…WŽ“¨d«ÅY¦%í`&“å^Òû¶‰MI5“z 4¦x¸rÖÔ  1¥@€ @(4¦Â…´õ¡1µÎŠ=Ó"€Æ”ù\׋Ɣëð µñhLC%èÝñÔ˜”uɉS& ‰•l9“™ì#)M“7‰mxA Ë”„Éœ$½lµ8ýj®’~•¨¤÷-9“}d{ÚÂs*Jã”åÞÑ6 NipFì‘KhL¹ † @€ dšS¦ÃoãИâåËÙ»A©½;“w!wÉëðwÒù jL•LcRš%ËÀ¤—­.7~Õx½©ŸzG“„'­+§ 4¦NbÏ1€’$€Æ”$mêJS‚°© € @€ à 4&O]¯›hL?7]GcÊM¨²ÔP4¦,E#ñ¶ 1%Ž<ïfPcR¦%™LÿxÐt%{ITÒ›ú©¢ôŽ’0Yº&™Lyí‡ P|hLű§=Dcò4ðt€ @€ #4¦áfýÔhLYí;t‰QÐ4¦ ç4¦âÄ2¡ždPcJ¨çT@I@cJ’6u%H)AØT@€ @ð„“'®×M4&ƒŸ›®£1å&TYj(S–¢‘x[ИGž÷ јòAÚ_3qhѸât‡ž@ B‰!QPhL ,Ý‚ @€ ¤H)EøiWÆ”v¨phLƒ3bhL^ 4&¯ÃßIçј:¡Æ1ˆƒÿgUΙhLÙ‰-é*4¦®âäd€ @€ ˆÿXìñ0@cò8ø¹é:SnB•¥†¢1e)‰·)qäy¯0G÷ļ6Ú?þÏ”!RlhLÅŽ¯Ç½Ccò8øt€ @€ þ±8&°y8-S¢ä{™²õ}tÔ4¦Ž°å 4¦¢D2±~ 1%†šŠ 0þÏ”!RlhLÅŽ¯Ç½Ccò8øt€ @€ þ±8&°y8-S¢ä{ј|õ©#lE9©(‘L¬hL‰¡¦" B€ÿ3eˆ›S±ãëqïИ<>]‡ @€ ÄD€,Ž lN‹Æ”‡(ùÞF4&ßG@GýGcê[QBc*J$ëSb¨©ƒàÿL"Å&€ÆTìøzÜ;4&ƒO×!@€ @1à‹c›‡Ó¢1å!J¾·É÷ÐQÿј:ÂV”ƒÐ˜ŠÉÄúÆ”j*‚À ø?S†H±  1;¾÷ÉãàÓu@€ @€@LøÇâ˜Àæá´hLyˆ’ïmDcò}tÔ4¦Ž°å 4¦¢D2±~ 1%†šŠ 0þÏ”!RlhLÅŽ¯Ç½Ccò8øt€ @€ þ±8&°y8-S¢ä{ј|õ©#lE9©(‘L¬hL‰8l–ÿôIDAT¡¦" B€ÿ3eˆ›S±ãëqïИ<>]‡ @€ ÄD€,Ž lN‹Æ”‡(ùÞF4&ßG@GýGcê[QBc*J$ëSb¨©ƒàÿL"Å&€ÆTìøzÜ;4&ƒO×!@€ @1à‹c›‡Ó¢1å!J¾·É÷ÐQÿј:ÂV”ƒÐ˜ŠÉÄúÆ”j*‚À ø?S†H±  1;¾÷ÉãàÓu@€ @€@LøÇâ˜Àæá´hLyˆ’ïmDcò}tÔ4¦Ž°å 4¦¢D2±~ 1%†šŠ 0þÏ”!RlhLÅŽ¯Ç½Ccò8øt€ @€ þ±8&°y8-S¢ä{ј|õ©#ly>hí”C²—¬üÛ'išðÑóÞùÝÎ<÷¶ÇN _Ó¯WüÙo1¤cTþÏ4îÔš4¦¤HSOÂИNu€ @€ ðŹQј<~nºŽÆ”›Pe©¡hLYŠF"mùmo .Õ-?9"‘PIŽ äHcêÝyƒÞv¼>'Ǹi:šÐeüž¯C…%€ÆTØÐúÞ14&ßGý‡ @€ tŸS÷™ææŒhL¹ •Ç Ecò8øw©svù=òöêkL½óÛ'Zž iL9jj2±£–¢@ò(ZDéO5F8#¢ И Xº@€ @H‘SŠðÓ®)íPÿàИgÄ5И|u2‘ŠÉÇ¡ÐvŸsä娩m‡ H ƒb`„;¾÷ÉãàÓu@€ @€@LИb›‡Ó¢1å!J¾·É÷ÐQÿј:–ÿƒj2‘Š)ÿQM 9rƒrÔÔG$€äQÀ Ò¥F8á И Xº@€ @H‘SŠðÓ®)íPÿàИgÄ5И<‘„L¤bòt´Ýí¹A9jjÛaàˆ’àØáÅŽ¯Ç½Ccò8øt€ @€ 4¦˜Àæá´hLyˆ’ïmDcò}tÔ4¦Ž°â pB&R1"¤ t"GnPŽšš@ਢ€< Tº"Àg8”SAK· @€ @)@cJ~ÚU£1¥êœÓàŒØ£†“¿ƒÂ%d"“¿ƒ ížçÈ ÊQSÛ@@<Å&À/v|=î“ÇÁ§ë€ @€ ˜ 1Å6§EcÊC”|o#“ï# £þ£1u„­(YB&R1%ž ô#GnPŽšš@ਢ€< Tº"Àg8”SAK· @€ @)@cJ~ÚU£1¥êœÓàŒØ£†“׃B ™HÅäõh»ó9rƒrÔÔ¶ÃÀ$†A± 0‹_{‡Æäqðé: @€ @ &hL1ÍÃiјò%ßÛˆÆäûè¨ÿhLa+ÈAS¦L9úÈ8p  ý¡ñÈ‘”£¦Æ7j("$"F•> `„3 J© ¥[€ @€   1¥?íªÑ˜ÒŽõNipFìQCÉÛA!‡éSŸýâO>|8&“·Ã ÝŽçÈ ÊQSÛûC €äÁ8(6Fx±ãëqïИ<>]‡ @€ ÄD)&°y8-S¢ä{ј|õ©#l¹?HÓ§?{ì’uý½›^}xò\L¦ÜG4©äÈ ÊQS“Šõ‹’G±âIo¢ጉ‚@c*h`é @€ @ EhL)ÂO»j4¦´#@ýƒ@cœ{Ô@còpPÓçŽ]º~çÊͯJcZþÒ¾ “0™<t9GnPŽšÚI$8HŒb`„;¾÷ÉãàÓu@€ @€@LИb›‡Ó¢1å!J¾·É÷ÐQÿј:–ãƒÌaZ¶~çªÍû¥1­(iL=}ûš8‡œL9ŽkRMÏ‘”£¦&=ê)$bÅ“ÞD 0Â%€ÆTÐÀÒ-@€ @€@ŠИR„ŸvÕhLiG€ú'€Æ48#ö¨!€ÆäÕ Ãô™ÏÛ³açê—‡I©˜V¼´oyŸ4¦½K7î?qö'‡uÿ~¯˜ÐÙ¶äÈ ÊQSÛ ;C LɃ¡PlŒðbÇ×ãÞ¡1y|º@€ @ˆ‰SL`ópZ4¦:ê?SGØryPÅaÚµzËþU!I©˜–m 4¦%ö<ðÔìó‰M¦žžž#F´ËbòäÉ‘CF}øá‡Ï™3ǽ?f̽ÓüÌ®vµAÛÚyذa:JgÓ«ù±îVïv¶vŽ9Ò•‘–«…j˜^ÚèëëSóÚê`ÂøñãER/¤¿¿?òiŽÜ 5µ•qÈ>ˆ@ò`L›#¼Øñõ¸whLŸ®C€ @€b"€ÆØ<œ)Qò½hL¾€ŽúÆÔ¶üdÓò»ÖlÙ¯TL«,SeE¹@cÚ°wÉú=‹×í¹ÿÉY-šL’‡$»´Ë¢Ö|’ ¤ó„õ ’šŸÙÕnâŽûõ`éÕüXßÌ'{É ªõuܧnçÈQÚ!õ–« â6jÔ(k­HÚ0&¼ÄAä  d²Ú`åÈ ÊQS;ˆ‡@à’ƒ ØáÅŽ¯Ç½Ccò8øt€ @€ 4¦˜Àæá´hLyˆ’ïmDcò}tÔ4¦Ž°åì ¨ÃToE9¥bz±¤1-Z»{Üã-™Lu5&™=r_ôrn<{Gn<K&¨C´³ó–dÒXz!ÛÇn¦‘}jç7eG;èÌf>i[ò^z_oFZb^Ž^µ“½¯æÕ†ÖvÖ™u~m‡ ¡˜Z®„U‘ö4j¹Z«=­¿ö²mc¢—Zh]8ÜÉ--V-%×AÙ]µšZŽÜ 55gš›H ͈‰#<&°œ6mhLiG€ú!@€ @Å#€ÆT¼˜¶Ü#4¦–Q±cjИRCŸçŠÑ˜ò½–Ú[h9¹†©˜ÊÓî…kw/X³ë¾Çfš“©Vc’øâ%³dÕ˜@£,ßRÝlL&?Ùºr:Äl'ÛÙÔ"—gȽ£³™dc¹Æ¸EåtK¹¤èeRŽò éM÷Q˜ ô;gdMºæÙ˜ºÞr×Në¾d£æ-7…K/ë£õÈ1±žª×¶áN¥w´å^ Sr@ì´µ+æÈ ÊQS[ú&³"<Å&À/v|=î“ÇÁ§ë€ @€ ˜ 1Å6§EcÊC”|o#“ï# £þ£1u„-7…¦ÊrrûWÚŠr/í[Þ·¯§oïÒ{é˜Lczaõ®{3™êfc2OH*’ù1ò`´!ÃÆ-âf“íf†‰G•œçdÚv /-g™ÂI›šhLæ*Ù™-Õ“Ó›tZU^TÎ…Ód©ðòvú(¢1© Ör}GËÍ‹²3kC©my¸ ÖxµÇV¸«ËD;X§²£"” §nnª¹A9jjn.(44S<2ÓuŒð®#å„Ù €Æ”8Ð @€ @€@‘ 1)šmö©M`ìž4¦ ç¿J4¦üǰaê8Láåä^’ôoÙÆ½K78©œŠIÓüU»æ­ÚùëG›ådª›É¤%óÌõ±¥Íœac“<'{Gέ1QÉ,"G¹‚‹šÙ Ãb“ªn6¦° cç<ÚkLªÈ–¨ÓO[º.üŠhL–±ÉšGËÓ¶Ã|Ô*ky¤ µ­0q6јÂ©ŠÚ¤YVKŽÜ 5µÀW!º#$árê `„g 4!hLqP圀 @€ ¿  1y4&ƒŸ›®£1å&TYj(S–¢ÑͶ4s˜6½ºÜ9L R1Í_µsîÊszûï~dF£Õåj5&K}dݰlLzÇ-LæÖ‰S²¥pW@#;Ç--ç²1™odËŸiÃIE:m“lLaÊÖ³sÙžÂ'±f裺™‡ìÓˆÆwËÃík›Kåãš!bRìW·T\#)|*CíD1·ê_óQ˜#7(GMíæ7ŸsùCÉßXûÙSF¸Ÿq÷ ×hL™.B€ @€&€Æ”0ð,U‡Æ”¥hЖúИ@cêZöqS°œÊËûW¹z šQŠ01,aÚÙÔ¨ZJ™lLÙÿšÓBß yø>ŠÞFxÑ#ìmÿјÜJÌzÂs²öüê-2:@€ @€À И<"hL?7]GcÊM¨²ÔP4¦,E£;m1‡©gîÀa* L_ØúÍëgönzuEÃtòu3JÓžëXþ¥+žÊå*ÏüÙܹ½;g÷öÏZÑ?sùŽ;˜LÝiqœg‰d~гª”Ï6ÃÚmJë”r”â(GMm7^ì€’ã ØáÅŽo¡{çŒ#·†²ùHf7Ó˜ä0vØaε7Oß~—{³Ðèè @€ @@cê[1Bc*F‹Ý 4¦bÇ7¦Þ¡1Å6­ÓÊaútà0ítI˜Vm~õ©¶žpÕ”ˆÃ4}Ùv9LŸ'ûß4¦ìLj‰’Çðqpæ 0Â3"؈@DcRŠ&­çvnOc’Ã$“ Ö€ @€ @ 4&Ç“ÇÁÏM×_øÍ¨´Kà×+þìoÈÍ@§¡õ}ôÑ<>Í¥_’½dÓò Ó¾Çç½|ü•Ï/­ÎÃ$‡Iy˜¤1Y¦ù«vÍ[µóçNš´`kt9¹ SÙa2“éØ¿ù/þïìùOí6ö/onÈþ)û1¢…C"€ä1$|œyŒð̇ˆ6"јôkxQ¸ö4¦Úêà@€ @€¢И<hLŸ®€¾Â¬ýoEè }€@=>|ø„Ésu©b/¹Uä›hLZHnÉúòZr‹J“ò0}â¼IÎaztέ(^NnFi9¹iK·O-ÙKVNþÞ?¸ðòMÛ_ß¾÷zçl@cÊf\hU× yt %'Ê$Fx&ÃB£Z!VúúúÂ+ÊéðA4&¥_êééqÕ 1µBœ} @€ @¾@còx 1y|º^hLEˆ"}hJ l2Mšëì¥` ¹R¦GçlVÖ%W¾ñ“ K“ò0)ý’åaš»rçÓ^úúµÓg¯èŸµ¼þrra‡I&C2ËИ²ÚÖH]€È)2L€žáàдæÂê‘”$‰Iáýј€ @€ @€Ú&€ÆÔ6²â€ÆTœXÒ/  1yvï:m&ÓCçöRe 9ËÀ¤²xJ) ÓÚ@` ¯%'‡inïÎr¦!‡©z99—‡É&L&ïFX®:ŒÆ”«pÑØö y´ÏŒ#òD€ž§hÑÖ6 1µ‹]!@€ @h‰SK˜Š¹S1ãJ¯¼!€ÆäM¨}神Lã'ÎvKÈE&K´`õ®ÒZr;-Sc‡i{íZra‡ “É÷—áþ£1e884­<ºA‘sd—#<»±¡eC"€Æ4$| @€ @€@hL 4&ƒO׋@©Q¤­ÉôÉáÃxjv)ýÒ@¦ª$Læ0I`Z$aŠæaêÙ>-Èô}ê’m¦1ÕÍÃÔ$'SÿÁþa÷ k­½ìX 1Å‚•“f‡’GvbAKâ Àƒ*çÌ4¦ &@€ @€ F©`m§;hLíÐb_dŽSæBBƒâ$ðêþý=æ÷?9Ë– L. S‡iú²íÓÚq˜ä3mßû‡?½óŽëÓøUãG<2âàöíëÓ›=ý=î§í£lCÙ§¼ Ð]hLÝåÉÙ2GÉ#s!¡A]%Àï*NN–hLÙ‰- @€ …SQ"ÙA?И:€Æ!È4¦ìÄ‚–$CÀL¦qÏ –[,!W˜’0Y¦Ù½ý³VôÏZ¾cæò3zvLïÙ^v˜–¶š‡©Öa’¢$‡iää‘s¶ÎQN&Ûçg=´Š '}ª }:jú¨d°P‹?Иü‰µ§=Eòð4ðÞt›îM¨}ë(“o§¿€ @€ ø  1ÅÏ8³5 1e644 ­@cj…ûŒ€™L÷=6s@`ª³\ÈaR&ËÃ4‡ÉÊO²K‡ßz¸KÅ$ŸÉ>Õ†ÞÔOyNnÿ‚Á§;©@cJ=4 ^Hñòåìi`„§ê‰SL`9- @€ @ÀchLÉãàÓõ"@c*BéCûÌdº÷±™óVíTú%ËÀdI˜f+ ÓŠr¦ SÉaš:´µä\e/iÛ\%{Ó20Ù¶>Ur&ýÔ§Vl^è"4¦.ÂäTY$€ä‘ŨЦî`„w%gÊ4¦L…ƒÆ@€ @€ A©aì¬hLqã(d„SFA3’'`&Ó¯Y-0 $aša ÉuÏa²ÕâÔÓ°ºäò3)“¤%·v“Ò4yãääÉPc±  1;¾ôî’ƒ ØáÅŽ¯Ç½Ccò8øt€ @€ 4¦˜Àæá´hLyˆm„@ChL Ÿ ˜Ét÷#3J˜ÂS„)p˜B ÉMY²íäï]ðƒ /ß´ýõ&eûÞ?üéwêRU&IKÿxг}ôÎøUãå0œ¥V’®¤ã$*ÉI²bY—,'“6¤7i[ïKuÒþúÔí‰ÆÔ>rŽÈ 4¦¬D‚vÄDÉ#&°œ6#á Íè64¦nå|€ @€  1y<И<>]/4¦"D‘>´O@KÅÉLÒq.å’Ô%ËÏd2“e`² ½ïVšÓ;Ò›$6µ_'G@ И2$øØræ,`„g! ´!hL1@唀 @€ Ï  1y<И<>]/4¦"D‘>´O@f’©H’–¤%YN&[TÎd&åjRѯ˜ô‘$'ÛSò“K×Ô~µô  1¥Z+$XñròÔ 0ÂS ˆ‡S<\9+ @€ @ÀghLGÉãàÓõ"@c*BéCûVÜ;Ú’̤m¹JÚÐÏ=sTì#ýjÙ¯z_¿ªØ’s¼ ShL9 Ín•’G«¤Ø/ŸáùŒ­”Ó ˆØ€ @€ 6  1µ ¬H»£1)šôÅChL.C>@cò9ú^ôÉË0{ÜIF¸ÇÁ/v×јŠ_z@€ @HƒSÔ3R'SFA3 Ð4¦Î¸q œ@cÊiàhv«FÝ‹>£1yf: @€ @H”S¢¸³US¶âAk Ð&4¦6±»Иüˆ³Ÿ½Dcò3îõÉã`{ÙUF¸—a÷¡ÓhL>D™>B€ @€’%€Æ”,ïLՆƔ©pдK©]bìï4&/Âìi'ј< ¼?ÝFòð'Ö~ö”îgÜ=è5“A¦‹€ @€ „  1% ÷Éçè{Ñw$/Âìq'á¿Ø]Gc*v|é @€ @ hLiPÏHhL Í€@gИ:ãÆQ'€ÆTð{Ý=4&¯ÃïCç‘<|ˆ²Ï}d„ûýB÷©Ðá¥s€ @€ T 1¥‚=•¢1e#´@cꇛS±ãëwïИüŽ¿½Gòð È^w‘îuø‹Üy4¦"G—¾A€ @€Ò!€Æ”÷LÔŠÆ”‰0ÐtJ©SrWhhL…¯çCcò|¿ûHűß=d„ûÿ÷©ÀÁ¥k€ @€ ” 1¥> Õ¢1e! ´@cê™S‘£ë{ßИ|…ï?’GáCìyកâv©¸±¥g€ @€ ´ 1¥E>zßþÓ›ãWý¥Ô‡ºeѶóÓhuB­øã¸{ùjô~rÃZ=ûA `fÞrHSƒuËÙvèw; Ö]ºã-4&oC_ØŽ¿õæ¡QÙðþ(ÿoRØÈ{Ú14&O_ün£1?Æô€ @€ 44¦¤‰§\ßê]·Ôu ~½âÏÞx‹‰Þ”£Cõ”À´M'4Ò˜ö½±jÐÃÙÅ$Ðd"œYðb†ÜÓ^¡1yøbw»‘‡Š„Zì¸ûÙ;4&?ãîA¯Ñ˜<2]„ @€ $L)aàiW×(!©˜ÒŽ õC %2‘Š©%|ìT`u'™/pĽì“—a/z§y¨H¨E¼ýCcò1ê^ôÉ‹0ÓI@€ @€@¢ИʼnÊj2‘Š)¡h@Ý„L¤bj {—@݉pfÁ‹p?{†ÆägÜ‹ßëZ µøQ÷²‡hL^†Ý‡N£1ùeú@€ @H–S²¼³P[mB&R1e!.´-¨MÈD*¦ѱ[Á D&™/x¼}ì“Q÷¡Ïµ*ªq÷°hLÝ.£1ùgz @€ @H’S’´3SW8!©˜2V D2‘Š©UpìWl‘‰pfÁ‹n/{‡ÆäeØýètïÄC2<¬ ¡ús{‰ÆäcÔ½è3“a¦“€ @€ D  1%Š;+•…2‘Š)+Q¡h™@8!©˜ZÆÆŽp ™˜÷ ÚvÉà{ÔåŸQÖ˜P=Šºg]Ecò,àþtÉŸXÓS@€ @€@RИ’"µz,!©˜²Ú ¸„L¤bj‘»yAÀ%dbÜ‹x{×I4&ïBîU‡-!ªWA÷­³hL¾EÜ›þ¢1yj: @€ @HŒSb¨3V‘%d"SÆÂBs Ð*KÈD*¦Vy±Ÿ?”‰YpÂíYOј< ¸ÝUB&$TÿÂîQј< ¶_]Ecò+Þô€ @€ 4¦”ß|óÍn¸áꦯoûÛÍwÈø§7Þw쯿(ãlÒ¼K/½ôôÓOoÞþ‰'&ñ=¢¤Aà®g?ÿrÿ‚4j¦N èrÚüz{^é•ú=å'?ºrÆEŸI½j@+ [·nõq0ÑçN ø 1éK1è÷÷k_ûÚ ûø³ƒ.¼ƒ>;¶ÓA—èqsÆÞxà·}‰VIeH’S’´©+AhL ¦*@€ @€€'ИzΜ9ï~Ïß^tÉ•V.tåâ+/ Ê*ÿùÿþ¿Gžvö_1PF]q~½rÞE—Gʹ]^.^~n¥üàÂË+å²\”sjÊÙç_VS.=ëüR9o œyÞ¥åÜKÏ<÷Ò3Ê%gœ[.§ÿà’H9í—åW.þþ9¡röÅß?ûâïÕ”‘g]\*£Âå»g Ê™å;gŽ(gŒúÎZ[N¿èÛ5å[§_ô­Ó. —ožvádžÿóýïÿ o~?(§T• Nùþ#¾þ½÷¾÷½ž|•é¦oz{{<ê˜áÇ8pÀ·¾ÓßTèrúý3Ω¹!wC» ý±«\Ps¬û‹ÞøêÜò"7»È.|«ÜàêßÚÞÔêßËndá[Xó›Wø¶ܰNnXÿçÿõŸO<é{ÁMÊJôVuÁû?øQ™©D“JsJÀI_Šó‰&—={ë ¼Î¥fÔá«Mä1»ùvøjÓäRzœ®sµ©~„nöðylnø´\óyB¶ÇãcJÏÃÚht©qR>ž‡§L™rÌ'>ÃMN¯N4»%hL-ab§ü@cÊ_Ìh1 @€ @ ëИDHÓGùÄŽ½°²=(o¸²mÏ*óî¿]¼|ýo÷¼”Ý*¿ÿM¥¼²ë÷®lÝyÐÊ+ý_.—×_ÞñúæJÙ´ýu+/mÿÝKÛ‚ÒçÊo·1(¯©løM¹¬ÿÍkë_ ʺWe뵕²fë5[ö[Y­òrPVYÙüêÊJéÝôª•*/íSYn¥/(=å²wÙÆrYºqïÒ AY²aOPÖïy±R¯ÛS*»©¬-—…kw/\”kvYyau¹Ì_½kþª*ó¬¬Ü9·Ræôö»2{E¿•Y*Ëw¨Ì¬”=;.¾ú–Ï}é«Ó{¶O_”iV–nŸ”m*ã&-FcÊú%ˆöuD ä0 {aÅ–‡ŸžË„_G9¨mºœ¾¸bCén8pC´»¡Šîƒ² Tì>XÿXsï«{׋Üïìf¹Ó­ÙR¾Í…op‘»[Õ­­öŽºUßËndv ß¿J7¯àþUuçêÝi·­ÖŠà†õ—ýîŸyQw+•ª[Uå>uò÷.@cj{ ú}€'“þ` z©Ù;p©Y´|½žÀËÜ•çí­»~?ð°íž´Ý3öŽªgìòvåéÚ­#ÏÕÕ¡ÇéȳôÀƒ´{ŠvÏÏÕÏKìá¹ê±ywðØ\zf®½ÔèÙ•#ÏÉåKMøj³|ÇÅ×ÜòÏ_úª]jf„ŸŠ+—šû'çàyXÓ§?{ì’uý<Øø}‘+zïјŠaoû‡Æämèé8 @€ @ 6hLÍ4¦oÓ¬IeâÄMÖÚ|­Š&Qõ¬ ÛK¿ ÙKšÄ­˜Â“˜´1T‡é•‡Ió.ó»Q‡i¿›åÕFHc ¦°ÆÔÔa*ÏÄ4ט‚)™ÐpØa æfJÓÀn&¸®Æ4»fJØ9L3KS5e©ä0¡1ÅvàÄ™# ‡éÃG [°bkà ¾´oÂdL¦ÌŨ ’Æ´xÅúÈ=1,òZ2Bw¬² Þ†ònH,pv[ Êžn­¡[ç¾VÏÊ­õq«Ä‚ZiàæenD½5ïV7,4¦B~Òí”'“²»…ŸºÝƒ·ýÍÀžuÆÔèÚu˜*!ÐĘŒüI@Ƥ{T®oL–žƒKMɘ\cʼÖoÓÒuý<ؤ{…¡öØ  1ÅŽ˜ Ò!€Æ”wj… @€ ™SS©X¦¡:LÑTLÎaê©ü)¹2u;S?1æƒ[NÅј\*¦lLKÈÆTäK—·} ¦£‡-ìÝj&b`öí›0i9™¼‰u\“’ „½¥ˆÅkSp §E ç ¬I@É>Ø(ï`ÝTLC JÉ#™#9ëçGq©˜ByëæG)kLO[6¦n»Ô²)ÉÆ”Øè-LEþhLM.5 –Sä‘ÛÒV¶[Ñ%ƒ§ë -8L.³i©˜ú5&ÃSÝÄoÏN8LŸ;vÙú<ØæJEG@cbp”SAK· @€ @)@cj¬1ý±»Eâ6Bü­IM¥„§l#‹Ç…&T´\ÕrÑ L­-$Zó¢´\kÉ5ÊÃÔ5‡)¼¢\“TLnEž!¦b*iL76JÅ4)Å UÇC ì0­ÜªÉT7Û'ïP¢áƒ1™âÎY+¤1™¹YËÉ­wÞE—«„×uðw]AµfíÔÆy˜‚åä­—Zg¥Ôš5R«¬Ü8R1•ò£„5¦ºbÁÔ%hL|»Ú&à‰Æäuk|©y!ИÞÓh½æÅš«’s‹5—tÉ’ÃT½LsÕ+K™M:L›j³™†–cv‹WFbn¶xeýTL•ÄoUÉJK—iLZd¹‰1™eIÓgä0mØÉƒMÛ—È#4¦i[GéÍpíWÍ{…Ï£=¤I5}äfÅt†Ã;¬¶%Vï¨Q£T«±S–×!iL2wîƒvC,Ý í>xîE—«´—z°¡ÀT¹ß5° \r”fÓ`y˜–T¥bªŸ¥±Ày·ñ×ï~ðé¥bj¤1ýÇÛhLQóDc „ÈðSwõ¥fÞ’@cjr© ?i÷é»ú»y&÷\Ý<å[°¨kó$«ÛæºZט4§¥kf»“±ünv°î" ÈÖ7D“ì&æ®ÖGsK¤Õñ š' g ßï*é#wºÚ•RëeFÙ×SJ+d ßÔ*Sw¦ð*¨nýÓÒʧҘƗ4¦ºbSZ#9×õú¢1U„ÈÈǹõìí– nz©©o/ $7máRãþ$À¦AuI—Ç4òülºdÕZrͦæËÉU/µ\Ö˜JÏÆ&÷—ŸŠ³ªõ‡¦î?ؘg£Spô¤!Çå†t ޽cb´%†´¬Eæ?éW=ŸØy&OžìTÌ®Öûa»Ú.).‘¤êuж=äØi%WYKLZ²ýÍ1ŠœSGé}× KHiz–Içö‘9èÚÕd‡hÃÞ´Ú;nÃ:>›5/r6{ÇNâºï.›µÏõ5…Æ£1¥*“ €Æ”eê€ @€ øE©A¼McªU”Ü;š8Ñ$ÊœÅkÂi–”i©*ÙRU¾¥o©‰ºÔhå¸ Es{©:ý’û“ñʤKu¦&«È Ìõ–ÿˆÜ­…ÑúBr Vï’½dÅ9Ló4%Sš•Q)§²XY^#C+eÌÏk±ŒÆkəär‘ecr³5¡O4¦j!2ú·zöÖø/5å¿ ( LåGëR²ÃV]É©tµ©½Ô è’åõ—«“0E˜Ût˜ìÙ¸¼Èr泓â0 ö`£«q+6Nñ±{>qO#î©fÐlLvÍp:TXf²Â“~ kLNZÒŒ-!çòPª=&ˆ‡5&w}²sÚ£Žt+»¹‡4Û¡‰Æä29¹*"SØ·¤˜µgs]Sk];ՆȳbQ.«Éö)YÞÔ–4¦ÄPS @€ @ÀhL BhLG««%¹75‰2sájûµì*U’L˜®TµB\½•,LZФ\Šd]ЍK«šÛK¥?ø{ñªÅãªþjca 15¼ÔÔ·$ƒ›iý´¦›µZk§®äÀBÌ{ÂÓ@¾·JÊ·Ê¥¦j!9—µ´=]²’¦Ôùý¶ÈrƳ“:‡©Ñƒe·Ò:¹C|°qRŽ=̘ m’žsLâÑ£EDcÒ¯zrêe‹4ý(,B¹g•°ßcW§©Fm»³Ù†=eÙu&m;=¨öœúH;kÓŒt;¹=­ÙsZm6&ílKÝYúÕÉ[ö‘ÄZîr>©åµg³§/ÛÙe`BcêÎå©;9Kæ ¢1éÂgKuÚËþÆý©JæzCƒ @€ @È4¦Q0ÉÙHu74‰2}ÁªÜNT åXzvö2ç*ÕJK³_Ü Rë-=õBiñÓª•O¥1ÝhL S¢1µ9Ùý?S“Kž½õ^{© ?o·°"sQòº»CeúÂuîO~ò³;TÂKÈ]{Óí*fÛDþ à±çŸqÞ*åççµ»g-Ýrá•78]òágžvîåÓ_|¹’„©áBrÎõf*­·Îò@vÒ¥Áj•µ%u­?ä0 <Øüjâš«Ç.»õ©5µrö¸©}ö`£ÿãxrÞ–Ëïyññ¹[Z|°q¶fÌÝƒŠ“~ô޶%ú؆~µ‰uKJä1ëHï¸çð¤ø¸3»«’;•ÞÑÃŒö×n–¾È¤%«ÚÞ ·Íš>§•\íj°-Âkga£(ì Ûû¦%ÙI´³m˜3`ÕÙÜ>uÏfMr¹¬¬hLݹ¡1u‡#gI€.áZuñ ÿŸZ3ÉìN÷1&oêþË:D•€ @€ dœ€çÓ£çzúêCo¨’þ­öÃG³ß"ÅM“heÚ «j-¥r‚¥­®øñÏ>xäÑö÷ßV>óÏÇ=òôì@MÐöçŽûÀ‘G[X*îåýOš}Øa‡¹ÞóÞ÷M˜80•Y3.¢.•ü+{­^dÇfyßý·ïÓÏ3Φ^4×{òwÎÒäÁ}Mÿäg¾¨)„r¾ŠHú¥ÒÂU®hÞwþª`2æ}à#árÞå×Soÿ@‹Þþ‘g_¦rçCSÿç‰L3+Ó3¶ŠÜwκTeÚ²íA LšÖ$Í…Cјöm=4îÔC Çfü Jó|#`Ó¢•[À´ª´Ì}ñ¿rÊî[jËÉé÷Éó&™Ÿ¡/é÷þmî—®xþK—??ògs]*¦@c*¥m¸c´AM&ßPÓßZ;^Ÿ3mó ûÞè­ GÓôV5º!êÆwÖy—ª„…Ý[ïžð·ïý¯ºªH]Ò¨¾þæ;ëÜø6ï¿üš›ô~d9'Ýþ¾õ½sœOpćŽ~ð©YáÛœ¾*S^XûcY¡%äÎ<ÿ ÝF¯¹ñvgå꾦;ÝÀ-äãºÙ=LÿŽÒìãŸþ‚4\9Lóž÷iû{ç\¦X•UP;5IE_1ÝÎnÿü€t[ºa™ÆÔ$e _Ãv x¢1éJ¾ÔDž´õì­'ðê¿ ('[ªM¹TÓ´~Ž7»Ãœ‘gŸ}ᕺÔL[¸N—m|säÙ*G|è(»Úhã”ïž­¢ K¿ätI]dþñƒGéAúôó®ÐÆ—Nü†ì%=K¿ÿƒG-X³KåÞG§ë’òÃëǸgæ–’0…V[.¹’Q]²²ÈòW­°<È"Ë¿í=tû ±>ËaúôçŽíÙ°Ó=ØL]²ý„«¦œqËü]vÑí ‡Ÿ7éñy/—LnØsÚÏç]ùë%öc&®ÕƒÍew/>îòçn|xeÙÏŽÿÁÆòuëνԭsrž¼@cÊkä|o·þq,|a´”½z¹Är 5&K(g –Ew¢p.8ßÓ@€ @€j x®1IdÑ?&žÿçµ2“iLk¶(— D¤ìÿkiLóW†-%·­©fÖ²÷¼÷¿j^V3(*ÏÌ\¦m½£4K’–®ÿù#¾zŠ%[úö÷ÎÑ ®Mߪ(ÿ„¦R\ ŠË®&w5¿bS¹Í׌‹¨KVŽ ç¨0©´þÅnËTQk/…Ó/5[?®¤1)wEm¦ðp)CLÿNѼ¯› L;Ü2r˜N5©´Š\Ó"”Ö¢3iïËIqWAc⪘%æ0-”ÃTJNc É•&-$÷Ò>iL?¼o©¾×w>½þËW>/)p˜Öí~jþV9LúnjrTS}L{©’Š©ß Ù·?ˆÉ”¥`g²-Ò˜îê9L¥®Ì$iÚüU5·Â{àÌó.U kºyÝ;áiç[ïzèÓŸ;NCZ7ÁÅk¶éÞ÷ƒ‹®:碫l„Ož±Tw=íI1¨7Uî?Y>)㟚Ukè>ðÄÌ3Ï¿2P *K£ÊÊþO_üä?}ÑnmúŽÈ*ÐÎr¢Ô&4«@yu ĂҚŒº—é׿I˜*VAIcz ИÂ7¬¿ø«¿Q4¦Lö¼6Ê©t%‰>u»gl={ë ¼®±dÜP½`\$¡iðh½©ü\}éÕ7JW²´@g]p¥Ê]ã' ÿì±f/ÿ¯'Ë•¼ãþIÃÿéX»Ô|ù_N6QÒ\ÉÛÆMÔE&œìMöÒn¸Mê’iL¿.Y’úiÒT`*%P,_mÖ¬Œê’ÁÝ<œò­ì÷oël‘å}k—SÌÏÃæ0-“Ãdq)™Ùß¼~æV–ÿ£oßÝÏ®?þÊ祢N[¶íËW<¯rů—èr-nr˜ÆÏØ$\z°Ñãå˜LàÁ&’0rˆ× %grK³ ñTž{hL¹¡0]ÉÙGa5ÓeYj¨1Y.ßp6&[­ÓÎIñä#]ú @€ @€@#hLöÏ÷52“iL–6©ª”&H¬he꼕îת‰“—÷kÊö—w=dZ*M¢hû×=­_e)é_ð­þ­ŠÍà*Û„\%ç-)÷’&nÝÌÊCOͲ'|彿ž¢)–O}öX½íÏnלîOÎÔß…kºE?Ÿœú¢–º°¿WÑD‹¦[”šB&®i]ͲèMº<;o¶5Ëk“»šzÑŸ«èÏÇõëq'~ã¾GƒlLöç㚃ùÄg¾¨ ˜[ï}J‰+´¡_?ñé/êÏʵøNx2ÆiLn>fü¤ÿëˆ ûÔôó 'œ$iäÙ—ªÜ^јnøLÇ|ê .›…ì%m[9õÌKk&›nWczeíÚßÝ~r9Ü1OÛpÉ@»‡é¨a {·ºy>7áê¦ú4Ï'IS}WÝ»dÒ‚WJSy99iL ¸lû'Îôèì-úZ›õ”Z!ð¶ñSÉÉÔn\¼ÚßiLue&iLSç¯,ßC·Bw<óÜKUÂÉËÛ›_•ª;â+§èöçR.éNç¼%MrßrçCº£E<Ý÷üíûî?Yï[ŠAÝÑt³“R ›ÝïÌ^Ò­M·­°R „(áôK<»H75í³`ÍîÈMÓ/ï}êýøˆ².Y*A LA6¦’Ãô7ïù»/žp’eÔêòë~¥»’ngæàêËõ…ãO²[Õ»Þýwcx¾Jº]² É«¯O2õEc:÷ÒðÓud[ÏÞz¯{©ii!抺To‘ÊàR#iIËÆ™Ìd‹ÇéRS*W¨Ø_¸ ¦ö7_ú—oè:œ¾ô‡7ŒÑ£rpÁ)ÙKz`¾ça9L;ËSÉ•´˜Ìõä{+'aªv˜Üãq»ÏÿíYðû›Kày8p˜>{ìÒõ;Ã6êïðó'|»¶ëª®ç™É _‘BªÇ{¥b 4¦5Ƥåä”cRÓÈ›æþà—/ˆLÙaâÁ&™+µtSבrÂø Øj˜‘lLôÒ›¶Øe³EåôqXc’äÃ" –Çß j€ @€ @ oИœÆT-3ékŽóûç\f‰+¬„W”öé/h2F³¿×Ý2.˜’Y±ã]ïù;MÌ|÷ìKULc²µxþí®ÇeZ<2e…f‚õSïØdð?ù¤Sϼ$œ)œÖ¢õi›:SÞ®UÅn¯&]p¬Øâ²²•ÓÒ”æù*«hí•ÆtÕ½KõÕ¶ šö &MKS}çýj&Mø¹UW\Æ‚ ŸYIþÃd*ö@bï"SDf’Æ4eÞÊèm1ðtUWåŒs/QqcØmÈRÒMmÒô¥auI÷>ó–´ŠÓu?»Cª®~ ö`z[w=Ýæl '[ÎI‰—t/»ø‡?µ„(Òp{~ñ¸ÇgèWY?.P œ•û£ŸÞ¦”ß8õ¬ŸÞzÿßÓÀMKÈ•îh¥$‚º£­Ü©UPMcÒÏ»&LU‘}kw1•ǦõêöÌ /ékuÙµ·J½ÕÏÏ’-$g“³ ìV…Æ4ÄÉáµ<јΨ"+×]jžŸÛ«'ðÚKM$ÙR$»Û ÙLKÕ*˜t©‘½dê’]jL` ԥʥF®¤ŠK¿$ÝÿÆ_=Pºwäpú%]gô -WòÊëǸdoQ)¼`eUäê&a ìävµþ:SlÏÃe‡i]äÁæÉy[”ZÒ=ØØZrJ0ùÈìÍ–?OÓ÷,Cý¯Çøé/éÁFy˜T~ñij»,Ç$6\!sI)—a£Ñ°Æ¤ s¦!¹Üu­jLJÎäN$ ª»¹ï @€ @…" )âñðk)3ÓÖ[¿ý©UwŽÄ½ù×ïzÏss{]%·qσOkÖV¿º)ÛÒºÁªp𦕥䤥›ïxÐ2-s·%YAÅŒ%û+p[ÕBÿÄoù–lŠÅÒ,Y‘¤ ]ýtë阺äòRh~W½6ÝR^3(õAoJ` VØY»[³/šz9íÜËU4m ?×êT¶þŤY«ôÓÜÑt¯¦a4Ý«)Íøª(_…2I“1½å¿&×ìï×ýê·¦Z)ÙKý—ÿäV¥_R Íkú!ИκԒ0Íè f]î¥Ã;L3ÁúÕ&ƒoºã1iLVäiEcúäßÿU4##Ðû/‡yÔ1/¬Ø¾˜¸,¥\ûlÈ’Æ´ÄéÒ˜ÌaúÕĵ'];Có£ú2~÷¦97LèÈXPZåÊMvšÉô÷ü/7ÏùO&©P Ð -3wÔð¿–=ÐD8ý—¨ÔÞuû»ûÁÉ2™,¹ mó–´`œ2 Ú¯”uioxÍ8ÝÚ‚T(¥»ž$ÝüÐQ÷?1C?Ÿ›·ÆL>Kˆ2ö±î§»›³rÇÜ71¸ÙMmM à†îhAN˜ô¾3q•‡I Þ·[˜4¦pAÝÂÜÝJÛJ¨bÒí¿žrƯ©l 1êQ9KñFcª#Dºk‹ž½õ^÷RãR™ÖJKöŒm·Ôȥƞ®]*SY5N]¸Ô”®6îRc®d9ýÒšÝÊ÷fÐ&ߨüðú1z~V&]atyðé…Ú?ya‹“[j¹j¹ð"Ë%W²uIÏÃÑ Lq> Í9î°c>ñ™%kû]˜ìÿƒtñ×_5 ?o’]ê-Ù•hëyæáYÒ˜‚ ¸&%aCý¯‡&eiÒeY=ýø¹¦š›ÿ÷ƒ΃M+wó¶ö™°æ½oÿéÍ,]óß4¦üÇÐÛ8ûHÙ”ÜB™ZoN¿ŠI«SxE:åq’ å-P:@€ @€À æÞqèçÃý-ÿe}‹ë'G¬ÿ‰UV©H¡¢I”gç®'R²íË®¾QÓ±¶è[° ÜWN)[J%)–JS)×þìýúÔ´%á9•ž’±¤¹[›Sq3+JAüuø†àŸûµ!KI³¹Ay|ÆÜž Á’M´¨È[Òb:]õSû›æÛÆMÔÊqnºEÓJ¶dê’–3BÛúi“¦ 4㫟ÊTL«vZ¾ [9N“»NfblÆ4¦ðršôÕÔoyEŒÒ”k!9å^R ÍûêO¨å0©Ü6>Е\ ÙKV4üG|Ø&ƒo¼ã±oMczßß¾{ï“?}û‚¿¨èý½¿ƒßç/~Æú~àºaÃ?ô?~z®»˜„sÒè",$WIW0zü ûjßåó&ÙŒéew¿xÙÝ‹mmšŸNèýÎMsl99i‚úŠI Œ¤1þ¥÷_ö/OoüÔ3}Ã)pžXDÝ Î±½Þ³ãê¿ÿ‡*s·ú†ÜûLc ßu7t·?Ý u¿«¬xKºK^ò£ŸºQu#S®A7±­›]ÉÐ f¸ï¸¢Ô[s•©ô-ØSºÙÝ %×|§œ~î¦èîví÷ŸtêYúš¸l‚n!TÝÑdw´Š‰+I÷/»‘ÝñÐT[<®œA°¤ÞJÀÕÍë¶‚rêY—ªAéô_Ýÿ|Dº%á]'à‰Æ\Ijžº¢ôìœz_jÜu&üW•§ëŠ·z®vO×ö\mE¤2]¤2Õã´e6u—š«z›ŠV^¶Kr¼ýè†Ûì)ZEKÈé™Ù&Sÿ?ñé/\uý LºÎXÖR=0k»þr¡ LN`²;xvÈJéR$(­Ö%[_dy÷³w¼uÉ{ê?ßvü¡§¯îb9ðð¥ÃüŸîÁÆÅÅ‚"'û®gÖ›À$Úã¦ö}ùŠçíÁFHå0©ˆ¡®ÕÒ˜Œ˜ŒÒc/{îÉy[=ØüÓñGM[wã²í×ènEé =è‘àõ?níúuÌë¢1yþ|wÞiL£K/ëÌøñãMijUcÒ®R—¤>ÉgÒ‘îDùfCë!@€ @€@× Œ;5ú¯ù?9âPïDÕ£Eå>tÔ1ÑyË™T)šDyfΊð”‰ùIî¾+é%þø[óµãŸš)WéÎ&i‚V?%-©Ì[ñJØX RPT¦Ul×RPØäŠ[!nNÏV›Ð•¨tõOo×\‹&tµ}ã˜ôþ¬¥[LZÒ¼KyÁ¸Òô€å¥Ð¯þvÜ–½Ð$®æ]LcÒì‹fb¦-Þ¬eã‚©—’ºtåè1š€ý‹q¶àÎß¼çïlRAkîhVF“¾®h–÷އ¦Ø¢Vôε7•Q¡ŸÒ˜ôgå–ÁBsÀ¶xÜ1Ã?ÉoÕÜŒ&efÒÒWÿð¾µ4üÏ_Ö²uCÊÆô®w¿gÓö×7¿²§¾Ì´pl×Ç'„@80|øð “ç†sE¸k‚&üî|zÝü•;å-M|á[Å&ø.Ÿ7ÉfLo}jÖ[™¶d»¾•A6¦‡VT­ºšòT³¿z²¾*Û÷þáOï¼ÓAk9¤¨j•3éoP—µ¨ÜÀ-¯únh÷ÁÓ~pÉiç\¾ JT’°«Ië’¶{”Òo Ã=9Sc[Æ’o*KKòwCª®K.6te,)]Ÿ/iC‹¢ê[ðÌœÕÚA?¥1év^ÎÉY¹˜tG{è™…¦äÖÞÑô•‘º¤$‚³{ûϽl´¥_ ndN±•O©¤ÞÚ¨ºsÉ*8û’ëtçúÙÿÙ8w£Š»m…M&4¦¢~SRì—'“.&MžÀŸ™hLÕÙ•Ü“výLKîRö–ÂyL%-ézbËÆ)å’þ@Õz–¾iÌZ-NfI‹ÇÝú€Šý€Ë½¤{±®BzÀþå½OêùùØß0{Iº¿=9Ûc³®6_ûÖ™î™9HYº<0þËÏÌ|\Z1­e©õlLö<¬R_fŠáy¸ü`3©ÎƒÍcs_ÖóŒ²K>:{óͯÖöm“× bKZ˜&ÉÙ–`räMsõT#Ïéêû–}íÇÓ–“ãÁ&þËîþhLÝÇŒÆÔ}¦œ1!Nc²uá´"œeVÒ¿›©ƒhLò–üI÷=9_À*÷>9ÿó_>©ô—åÛ?6üóÊÀ¤Ÿ¿~|ž¦dä0i[嬋¯SÊ¢rnÚÆÉLº0”™)†i›Ü} hpFT&üæ„Ó°Y®Íó)QÊ•¿^âòÍè»|ÒOfXºÍ•^z×b™LÇ]öÜ%w.j´êJØaÂdÊHÜ3ÕŒ°Æ˜¬‘Ò˜J·¼è­ÐÝO;çbyºn ë~7_ôDcÒ•¤ÑuFW˜É³Vè <Ÿ—šêôKã?X(­Í L‘µb;xÞµÿÍà1øò÷Æú<ÜèÁÆþï¦êÁÆœ°&6¥Åõx°Iì’…Æ j4¦X°rÒô  1¥Z@€ @€@¡Hg)-!Wû2©VHªäL 2'ieÒÌåUZ’S”B~R#EÉM܆D¥´uu¥r"–jcÉ–`¨*-zK¥$.UÞ’ì¥ÞòÊÎ^ªQ—¢s0ÁÔoåïÈKöÒÀdÌ€½40û;T{ÉÍÜt¦1Ó6z½õf 3­R¨ñLgb&ðÆÞþÉ#‡©¼ö›¾HU/=7~ñ/F ½~›ðÿÔì°ÈèæùÊ_öòT_`¦Úaê/ça*͆NSª³ŠiÑÈajd2õí뛼qòлÃòE`ß½n ¹Ú–Kcš…Æ”¯ñŸ‹Öú¢1}qõÚÊå|¥vyѳ·žÀ»x©¸Ú´{©)=H7%뺒µé—:s%;ÎÆ¤»ùyXã^2Sƒçá®<ö´ò`SÎkUÊœ×TÎîüÁÆ}ÁyÂiñZ‡ÆÔ"¨övCcj{ç†SnBEC!@€ @È;iLüÈ1áÕmj·5‰2qÆòæûÔ(JU¢Ò€«T])ª+É[*ͬÔ1–*kèDçtKÐÍ·T×[ZYã-ÕɺTO]ø#òª…04SÏ^*Íþ.­Zp§õÄKu÷’Æ”÷JûÓ ÐÄUšwíH}Ú•FiÂïcÇ|â'g—¯¦-VlE·~M–—ª©ÎÃTv˜*_·æ“™Lý¯þ!Üøa÷ ëéïéJw8IaHcj~Ë3©êžXå*Õxº¡œ‚õ¤¥*C7|«Ÿu)âTßÚœ[^uyý ·t «£´ÿBc*ÌàÏNG<ј¢W’êå&u!ÒxÓKM° ¥•HúRËcZNíV~®îê¥&"J6X<.z©ÈTÚÉ£r|ÏÃÝzì l†Ul\ìÁ¦’„)È;èƒMkr¶=Ø xZÕ_`žpZ¼ ¡1µª½ÝИÚãÅÞ¹!€Æ”›PÑP@€ @€òN И>|L Éæb÷hå©é=n¦$²Q^ú­ÆOj¸\ÈUª«+Õ® WþÛå²±ÔPZŠæ[ªñ–ê­¬N¥Õâ" ÆUg]*嫈Lú–fb¬Lm?wE[bS|Ó6y½´?šÌ{dÄáJŤ ecš6j„Šì%«ËR4Õ¾¿âÞѶçÞõmXA{÷íÿè1Ÿ÷ĬˆÀTZo%ÈU0øT_;Óö½ø·ßqÐFNyø­‡xd„ÞÑöèù£µ=fé˜ñ«Êž–}¤|ÚP5½ i¨âçì.iLOM_ÞÄÍyÖ(•*{ Á0² jé–M+ØÄ[Ь…: %¢.…”ܺ« º„(ÝU Ü ©»#³‰€'Óȳ.n”©TW={ë <ÆKMéV[»ìrË—š†iÞê^j:ÈôyZŽéy¸³ÇžWæM¶ÇžˆÛýêþš˜=Ø(Õkéï%ì4Œ’Ë>uâWO6W©Qу͟Þx°i÷ Çžì!ÇÛ+S,¡GcŠ+'MŸSú1 € @€ xB ¤1},¬ÕnkåÉi=îýyY÷wÞáJ:¥FI•ܪp‘¹[÷kðýMŒ¥J¦¥ZiinoxI@Zª›o©â- ®.U’UD².% .…gnbš¶ñd„ÓÍÈU2Émh!9‰JzG†“~jÞNxÚÞ´öÑ1úÈ<'¥CÚªÑL¦±ÏtþbyJÕÖ¯)-þ¨/r g yª/ì0©‘ýû•«@•ä3I`:øÇƒšÉsù™ìS—Ï@S}Îpj«ìœ/Ҙ·¼Ú{¢iLun…¡Û_­®¤{_í]/t¿«– jR.EB ßÝʉ—ª³¡Ø¼¸•ºn\4¦|ð\´ÖiT“'p]ˆôžÀ¥&òD]wyÊÊšqeû?Xg¹Rš‹’ágæ¶$þÚã{n÷±gGÏòÖU´¡5éÂ_+3™ÜƒMD`*?ØÙ%»ð`S×ajý GÏ<ö`£G =ääââÐõF¢1uipB4¦X°rÒô  1¥Z@€ @€€'¤1}àÃsK¹ÕÝø«¿~÷ãÓ–9ýhðÒŸ7/u]¥Ì•D,šY±þÓpÛŽKµÒRdÆ%*-iö¥2Å[™€©J¹ToÁ¸à/¤ƒRYëaˆó1-ß´'ƒœn¶KÀ\%½¤%©X¦%éJÎR’Õdéšl7í¯)=Û¹])¨¥d2ÝûØÌ*©j!¹.LõE&Õ«©;›´ ÏÞ™º¤×œ­s,9“ö‘ؤ¢ý•±©]˜ìŸ;Ò˜ž˜ÖS{7,™IA.¥ïž9J¥Ñ­°C·l,UÝòêÝ隈¹ƒªKA6”¦+ÇuñF†Æ”»Ažý{¢1éJZLÙ®09Ûôì­'ðü]jªWŽëâ:Ëñ=·ûØãŠôØ#»6¥™Lö`ãRKV¯ÛoX`šŠX÷ò0Ù·»•'9Ü&j[ñ6!S,w4¦X°rÒô  1¥Z@€ @€€'Lcj®ý¥4¦©Ë5“–~«J§4°bEtéŠW©®®T›cÉfv#™–j¥¥Zo)ô÷â–£¢·TY0®”¬"u‰lLž|3ØM§"ÉR’“äì%½o‰—¬Íò–4g 4ÿ§÷]é Se“éÑ™aI±ü¥®Ìó¹©>ûV¶µäJ­Ã¤Fj‘8YJÚ¨$iI.?“}*iI3|¶¡¢ ÛW± Hcj~ËûΙ£T¦VªÉ&ØÈÐè¹ÍÝܰ·¹»U¥Bi°þi¬÷24¦b#Ré'SÝ+‰»¶èB¤'ð„/5•Çé: .‡Ÿ¢-µë¥&&©ÝÇ}#Â=»•“©ökR6™Z°©ü„ºÙñZr®­<áØZºö„£bOD¾Ð˜b :S,X9iúИÒ-€ @€ @ÀÆtäÇæ¯’lÔ°hå±)K„Ôh#økãÚRI§Ô(©Ry·´tTÝR«+…Œ¥òÚu2-ÕI¶Ô¦·Tñ$ZÌ™ßn1MÛx2Âéf»œ«äÖX1QIçQÊÙKÒ•4ig§µ÷õÓæðt¬û¨ÝzÍdºç‘¤¸"(³*‹d•¥ÃRº‚p:´§úê:Ljž[-N˜ô޲X6&­.§eæô«9LöŽ>ÒÏvûÅþ¹# é±)Ë܃DJß9ã"•ð­°ù½¯6›`d…¸ºnno©:•`MÖ¥*·”A0æÛSîyöì‹ÆtƨšKÍ@¶6={ë ¼þ߸çíÐcöP/55 SF²–6U—ÊÒ|Ã:sLÏÃ<öèICú5OBi&SäÁf SÉ:íìÁ¦ÑZrî«ÝÊŽe´CäsOÞ,ìá )– £1Å‚•“¦O)ýÐ@€ @€9S^ÆvŽÚ鉯dW’FEÏÞz¯ÿhØ¥¦6Á[(™Ø¥&¦çá{^™7YÏE.'e“o–™Lw•lœÀ¤ƒƒ͠S‹O8¶›o,ñdŽ®Ým*Swy–φÆ VNš>4¦ôc@ @€ @ð„€iLÍæHzé‘ç–JEÔFj˜N©’^Å’¬„Keî¶”y¥2}[w7ô¯ÿQc©vy¸*iii @D¥%%¨¨,ߨLgÅ4mãɧ›ù"`&Ó]¦›•h&b)WÁÀBr]q˜ò……Ö&I@Ó#Ï/Þ7(ºÍ}ûô‹TeH­ÔàÆWk, *-Eîqeo)ñ¬KnahLIŽOOêòGcrIIí NÕöðsKôÞÅK=H‡KäZ¿Ô¤òÓçá²ÉälL`êôÁ¦‡É“«D·º‰ÆÔ-’UçAcŠ+'MŸSú1 € @€ xBÀ4¦ÈI)T4‰2á¹%µR“wBr’ü¤:ŠRQ)˜_‰¦V2oi{]]©nš¥üJKµóÄ9¶ñäD7»NÀL¦;&L+µ«&¦®ç„Ò˜‚[^õ}pà×e©µ;ààznm*ÁÚ;]o)™ rŸBcâKÔužhL"£—šë?áÙ@cjt©©~ÒŽïR“¡”¥ù}6“鎇†ú`ƒÃÔõKNˆÆÕChL±`å¤é@cJ?´€ @€ OHcúÇ#?Vc™{T.šDyèÙk³%™Š)µê]çú–RÙUª] .ºtNh:ºR~Ò,µ˜œ)¿Ó6ž|‰èf× ˜ÉtûƒÓ¦Ö|‡¾–\×[Ë F@ÓCÏ.ip[ \o~¡J{·¿nnÝû]=i©bdò‡ÆT°¯@ºã‰Æô­Ó/ªc#YvÒ;ôì­'p.5îi9×ÏÃf2 åÁ‡)¦KS,`јbÁÊIÓ'€Æ”~ h @€ @ž4¦}´¹{¤I”Ÿy±®Ô mRdÑ·ê\JZ%ª´PTÝ20}[í*ù +5²šr=mãÉ÷ˆnv€™L·Ÿþ^à0u3'¬% ©þ-¯²Ó·N»PŶp,ÝòêÝõªîwy^ü‰ïQ× ø¢1Ù•¤AÑ…HOà-^gÊYÜ }©Éûó°™L=Øà0uý"ãNˆÆ [4¦X°rÒô  1¥Z@€ @€€'LcªYÔ¦ÊCú iLO/¶5ݦIl^¶±±”¢~R¥T_T*ežÈ¢9-fNŠc·¼OÛxòU¢›]'1™p˜ºN˜Ö%hLO¿X}[,ßþì&øÍÓ.T)ß» Öu• &æ¢1ñUê:O4&]I*—šª‹Œ]jÆ?½XOà­Øà0uý >!S,xјbÁÊIÓ'€Æ”~ h @€ @ž0©61RxFä/þêÝ<½¸¾‡d6’J%“DíÆÔ¥Z Çʶ:Å{KiPó©Ó6ž|›èf× 8“©Å©¾ÿxû®·úF@“ìú‹™–îw§|ÿB•F~’» 6¼÷-Ù6èe?_; 1ùöI ¿¾hL‘+‰{¨.mèÙ[Oà‘U&?f׿ï¿ý÷ì?Ëd:úcÃZy°ÁaJàò…Æ d4¦X°rÒô  1¥Z@€ @€€?d2)'“{=õô´.\n»çÁÈ;üš$±&Þ=î±æ5N›Û“ýi¾Sô´»¶mï—¥ÔDcÂaê.pÏ϶uëÖð=qêôY‘˯.Ⱥ,'yÈx]­<$¬}y“ç߬¶ºïƒÆôæ›o†/5Ú~|ÒÔÚ«MÆ¿þ 7oÐçá¹‹×æâyxÚÚ³Öþvyó¦¶.ïŒÆÔ1ºf¢1Å‚•“¦O)ýÐ@€ @€¼% ,>ͳžði.ÉÛ¯p!;®Ä-L&¦BF<;úÿ¿‹k~îI6¦ì ò ¶Ä©{sa7wßñŒ48ƒÏÃo¼µó×+þlê¦Mlp˜».¡1Å‚)¬œ4}hLéÇ€@€ @€ à-4¦ŒÌ» ±œ¶ñö;EÇ»B ®É„ÃÔ¶œ¤ 4¦!ÞŒŽÆÄ÷® 4¦˜¾wž6ƒÏ˶WÏa*{~ß[k2é¦$/hL±ÐFcŠ+'MŸSú1 € @€ xK©s<œ¶ñö;EÇ»E b2á0u ,çAcJþƇÆÄ÷)B€lLq\ˆ²öÔ!€ÆÄ°€ @€ @€ @€€wИ¼ ¹gFcJ7àûÞèUê–'Ö‘nÛ R;SAI7¢И€ @€ @€ @ðŽ“w!÷¬ÃhL©|ÚæêjL[LL½mEhS¢Hê@cbX@€ @€ @€ @À;hLޅܳ£1¥𺠙HÅÔµ¸ 1u %'Ê4¦lŃÖ@€ @€ @€ @ hL @¦Š  1¥ßU]›‰TL]‹ S×Pr¢l@cÊVmiP¦e›ÊgûÊØ±ccÌõO‹Æ”(n*KŽSr¬© € @€ @€ @!€Æ”‘@ÐŒ˜äKcz|ÒT'-ÙÆ6•’·¤ró­Æ4ˆÀ´ë÷USlÓ+“d¦*éåÆTÏa 4¦’ÃÔ\cZºÑ9Le©ÖajQcš¿ZS 1SDcêÝ9 1•¦æÓôŠÆ8Li SLßcNë#4&£NŸ!@€ @€ @€<'€Æäù(|÷ó¥1=6qª“–².•/½ñó_Þ)©nú%åaröR9 SiG9 Sçy˜Zu˜ö»_Ó#OM [J‘í’Ætr8ëR9ñRT]:ørÿë/ïx}s¨(ñ’+/mÿÔ¥{iÛïúBÓÆß¾&uÉJT`zåÀº­kɹ…äÖlÙ¿Z¥ÁZr-æaj×ajq9¹*ËÉ•W”[Ùj*¦™Ëw”KÏ L¥²ÝiLnE¹p*&Ó˜îºçÞ?üûÛ®üû[oÇû5;í°CãN· Î4 1¥A:!@€ @€ @€ *4¦TñSyìò¥1=üäóK)üëM¿4¦-i)šu©V] å^ ¯N¿˜œ½4¨ÀÔ, ÓËûWm~Õ­%ç’ÓÆŠMûV¼”åVúöõ”ËÞ„¦ËÉÍé퟽¢\f­¨¿œœ4&-'g“s˜¦-Ý^Ö˜J©˜Lcºñæ;ÂÒ˜¶ãåhLñòåì©@cJ =C€ @€ @€ @ -hLi‘§ÞdäKcšðÄó&'Õ–—ûÞtËÿòµ“µ$[ª‘–,÷RD  /Ur/5²—Âé—:˜”‡i••ÀÔ, SµÃ´,¼–܆½KK%XH®ÁZræa²Ã$i@cZº}ÀaZZv˜Ð˜’ùRS‹'И< 4Ý„ @€ @€ @€À4&FC± äMczN‹Á…Kxa¸o¹ã_¾zr£¥âL`ªï-iÙ¸•ã~'oÉJgé—ÂKȵ.0µ“„©ä0­Ê‹•²xÝžRÙ½Hem¹,\»;(kv/X³ËŠ–seþª]ZH®¼–\7&Ó˜‚TL &4¦b_Lè]ÂИNu€ @€ @€ @HŸSú1 qÈ—ÆôàÏmRF%+%-)\´ZÙ‰_=Ù½S6–BÉ–ò-µà-•/ýæµõ¯eÝ+Êeë­çÊš­ÖlQÙ_¶—¶ì—º4`/µ©žÀ¤åäöº$LK7–30u„©®Ã4µ¦Ã´r缕;çVŠ–s¥Åµä$0Y 4¦ÆSœ_eÎí4&ïBN‡!@€ @€ @€ €ÆÄ(6|iLãn@Nª^NŠÒOo¾ýįœ¬¨®TÊ´¤²q ”ó-ER.…׌«R—ä0uÉ^êÝôê •—öYYn¥OÞ’+­ LJÅÔI¦ÀaªJÂ4à0õî˜zûÍašeeù•™•2£g‡•é=eI“ò0™Æ45(ÛTä-EÊgûŠl³ˆïWì´Ã;5Þ*8;Ò €Æ”uê„ @€ @€ @€@ªИRÅOå±È™ÆôØsÁêoµ¥d)Ýðó@c ¹JËÃÕ.g Æ­·RÊ·õ–šªKíæ^jd/…¦½=»/0…’ë0 ÓŠ*ifE`š!©â0 ɕ֒“ÆTv˜j&ó™Ð˜bÿJS7И¼ 5… @€ @€ @€@…c¡Øò¥1=ðè³&$Õ9I×ÿÛí#¾ò ó“jKÄX*yK•uâlck4å’VŽs Æ5[6®ñÊqe{iSuî¥Æé—´œ[BnɆ½K6ì Êú=J¼äJ‹˜š L«ªV‘›Û~¦Àaª,$ç& L%iÛÔS±/&ô.ahL §:@€ @€ @€ ¤O)ýЂ8 äKcºÿÑgÃ~RÙLª$U-é_¿áR+U6ª]¥ÆÆR -5õ–VKWreóþU›_]Y]$-¹Rgå¸Ö쥥!{),0Uì%-$·{‘ÊÚrY¸vwPÖì–·äÊ «w¹2UãUäV¬"§åäl¹ÊBr’0 ,$ç&·œ4¦Ú…äÂï)Îo3çö‹À Óøñãûúú ÉÁƒG5räÈ9sæø‰ÞB€ @€ @€ @ XИŠOz%/iÜ#Ïi“”ÑÿvÛ ÿúò§õR+ITrEÆÒì7žúýsNüê)·ÞýK¶¤w>ó¹ãn½ë!IK*OÏ\6â«§¨h#ì-Mž±ôG}ÙÕ79oiÆ¢õGyôÄéKV¼T{©oߥ?ºñ’ÝØÓ·oê‚u=}ÁÊqÃ?{¬~†s/•쥽_þ—“~q£ôKN`ºèÊÞÿÁ£T.¼ò˜Ž;ñ?»°y¦ú óVîœ[)ò–\i&0-ß1£²œ[EN©˜ÂI˜‚ L¥$LhL\b ÐERÜÙ¤$ICÒ;ýýýöf3iòäɇ~xOOí:lذ1cÆèWmè£.6‘SA€ @€ @€ @I@cJ’6u%O _ÓØ‡Ÿ «H‘íë~hLöf%¯RtU¸ðÚpò®¸æ¦G&ÏÖÆ½ž–´ôéÏwù57=lï<ô´¼%mü⮇T´¡ÜKNZš0qö{Þû>½é².]võ’x|jÖòRÖ%yKVκàJ•°½tæWÊ[²âVŽ“½ôÓû_øÈy—_÷„iÁÆe£e/ýÍ{þN?¿ú­3¿xÂIw>4U?Gž}™¦w½ç﮽yìÏï~âñ™L—]{ëŽ?éöñS~pÉuÇ ÿ|‹“ÉLhLÉ…©±ÌDj¤1ÉpÒ§Í•ÓÇNc²m©OsæÌ‘…ÆTÈC§ @€ @€ @€Þ–À„Æäí5„ŽÇG ²¨ÜøÒK&’^ª´ I{['•‹/Zœ€ @€ @€ @ @cJ2U¤H _Ó=>]×F²7,éÄ“";”— ƒ ü¤ÚâR+Y‚¥å}ûTlÛò*•Ô¥òÂp2–¬HW2I?ŸŸ¿vø?+iIÛ÷?!©,-¹¬Kgœ…Šì%K¹¤RÒ˜vëW·fœt%˜L] — ®¸Á¼%•“N=ëûç^>Õ.­g‹Ç]yý§.Ùâqóž÷)ýÒ×¾u¦-!gê’~*ë’ì¥àgiå8+Ò˜ô޼%+Ÿ?þ$ÙKç\r¶ßõî¿û×SΘ¶tûÔ l J)åR“B6¦¿ËT]<áÄI}}}ÒÆŒ#“iEå D8“ —v«Ó=‚ @€ @€ @€@á  1>Äžw0_ÓÝã'×U‘ìÍk~ú+iLn·\t£$*M[°N¢’eWºùŽmû=û>K*J­tÊwϾóIÃ?{¬yKÇÿëÉw<0iéÆ Ç’ÊOÓ’ {/þáO¿ü/'«HZR.%­ç¤%—uéŒó®P){KëvK]’ƤŸr•ÆŒhkÆé¥\Ò;÷>:]+ÇýôÖûÍ[’Ã4ýÅ—µlœ©K¿¼÷I¥V’½”•;•uIÒ’Ô¥R¦©æ-IZºkÂÔÿuÄG¤.©Ü\Z-nÖŠÒ•ä-éç3/¼¤G§ö*ý’r/)Óôží²—”I嚟ßwï“óe/MšÛ'“©E‰lLž_Iè~œÆ¤5æ$0YZQN«Ãi£lLJß${I2“ܦþþþ8ÚÊ9!@€ @€ @€  1%™*R$;ɲ%Õ-Wßð«/x’[÷­f#ð“Ê¥d&IQ’œ¤|KRˆ~~ûx½#uIïœyÁ•–cÉ,éM• ¤¥=å²~ÏýÏ´$QéÙyktøíã&j[ïŒ}lÆmã&êyKJ¶èJëvŸ~Þ*ò–>ù™/wâ7f.Ý¢÷¥.YÊ%-'oÉ–ŠÓšq¿~dú„gjCY—¾þí³Þÿ¸ÄK¦.}ýÛgJZúÞ9—}íÛgÊaºâº_I]Ò;R—¹—†}ê Z-näÙ—Êaºöæ±&0éçe×Þªw¾{Vðþ¥×Þ*{I_9åŒSKïÜûÄüŸÝñø?ñ‘Sϼä_O9ýcÃ?ß<ýRäS²1¥ø]¦êâgc’€$ I2’6¬§ƒhLJß&"õÉì'^€ @€ @€ @€@~  1å7v´¼ùÒ˜îz`’[Ö­vCÓq#¾Þdû(Ȩd¥”TéÇ7ÞnÆ’Š²+=>åÅkn¼ý¹ùkci}Pî7Ñ,¥Hyô¹Å¶BœÔ%eZRyä¹E’–¤+=òì"­÷ÌœÕÚP²%yK*ò–T”lIY—ì§\¥[ï}ʼ%˽ôÐ3 -ëÒÄY+•xé™º¤b ÆYyrF¯ì¥[îy≽ºÔÛÿÀÄ–{IËÆÝñÐT-§rûƒST›Ö+{iFÏŽÛÇOÑO•ûžšÛÏß÷ä|9LÓJeÌÏË^*-¬7áùå·Þÿ¼J[“vFcjåKÇ>h‘@OOOxO­~g©Å:Ø € @€ @€ @È4¦‹¦v@ _SxY7ÂåG×SíûNQ’¥4QÉR+•D%+µ¢’½c®R¨Æ’J`,•¤%W‚åá\)IKr•ªJÉUrEÓ=L7o©*åR=uiniÁ8W¤.™·dêR©ê’Ф%WÌ[²b+ÇY1{)(eu)°—TÚõ–ÈÆÔÁ—ŽC ÐhL]ÁÈI @€ @€ @€ 'hLyŠmmŸ@Î4¦û'6ñ~8úViL­˜IµÆR#W©®®$o©ÖXTZ2{i¾JÅ[ºàòë§.Þä[ªë-­Üö–,ëR»êÒ ©KµöÒRg/êÒÐí%'3‘©ý¯ G@ ChL‚ã0@€ @€ @€ ä—S~cGË[!/©îânÎI’Æt숯×I Ó)U%UªÎ«d –ª\%ýZJ°TGW*¥\ §YrÛaiið|K5ÞR .UR.µžu©¾ºTJ¼TɽT²—– 5÷Rmê&4¦V¾tì®@cê FN@€ @€ @€ <@cÊS´hkûò¥1Ý6nbÔ=r‹»­Û}åè_{Â×k×z ¯ûV¸ê•àš¸Jt¥Pš¥z+Ä5H¶4··Y¾¥æÞ’– /תº4äe㚯:‡ÆÔþW# Ð!4¦Áq @€ @€ @€òK)¿±£å­È—Æ4fìÄh†¤PΤ+¯ûåOøzÝåÞ\"¥F¹”ä' ”ÒêoJ%ÁÒ€®¤4Kå…áBËÃÍ[¹sn¤ÔHK‘uâõ–föt¨.Å‘x©®Ï„ÆÔÊ—Ž} ÐhL]ÁÈI @€ @€ @€ 'hLyŠmmŸ@¾4¦_Ý÷T•ovÖìºBÓñ_«³CS-)¢+–’Ê*+;Ã¥ÊUª$Xª£+É^ªg,5––úg­Ø1kyP”c©ª4õ–¦k8W" ÆÅœu©QN&4¦ö¿‚  1uŽÃ @€ @€ @€ _hLù-o…@¾4¦[ï}ªIž¤+~òË/ÿ5·CYH2-iÀLªã'™«µ”B¢R}W©±®Tk,ÕfZª#-E׉Sî¥íÓU– ”zÞÒö©K·eɶæ+¾%ð)S+_:ö@W 1u#' @€ @€ @€@ž 1å)Z´µ}ùÒ˜~yï“‘ IîWIH—]û iLul¤°¢´r§œ¤p‰.ýV³ÜÜÞ~iIÊìÞ~)Já2k…²+Y)çXj-ÓRi©A¾¥ yK5 ©ý¯ G@ ChL‚ã0@€ @€ @€ ä—S~cGË[!/é¿~²‰u$éó_þÚ Z’YJ½*Íä$'-–R¨dÒR«º’Ö‰‹® 'c©%iiÚRKi)ù–š§tBcjåKÇ>è 4¦®`ä$€ @€ @€ @È4¦‚¯4?¿‚ïPGcŠ—/gOSjè©€ @€ @€ @i@cJ‹<õ&C ×S2ˆ¨%ßИò?Z߃€ @€ @€ @Þ@cò.äžuɳ€û×]4&ÿbîIј< 4Ý„ @€ @€ @€À4&FC±  1;¾ô И Xº@€ @€ @€ ÆИÅ&€ÆTìøÒ;4&Æ@Q  15²ô € @€ @€ @  118ŠM©Øñ¥whLŒ¢@c*jdé @€ @€ @€@cbp›S±ãKïИE%€ÆTÔÈÒ/@€ @€ @€ 4$€ÆÄà(64¦bÇ—Þ¡11ŠJ©¨‘¥_€ @€ @€ @hH‰ÁQlhLÅŽ/½Ccb •SQ#K¿ @€ @€ @€ Ѓ£ØИŠ_z‡ÆÄ(*4¦¢F–~A€ @€ @€ @ !4&G±  1;¾ô‰1PThLE,ý‚ @€ @€ @€@ChL Žbx¦oøÊ]?-vé×N;ìиS½&@ç J© ¥[€ @€ @€ @hL‰Ñ@ ÇИr<šÞŒã€ @€ @€ @Þ@cò.äÅíðä“ûöõ·ô õ 11. J© ¥[€ @€ @€ @hL‰ÑQ‡ßzxaúBG Ð*4¦VI±_Π1å,`4€ @€ @€ @C'€Æ4t†œ! F<2BÓÈÉ#•iÔôQÚ°bù™úök[úU{ªhŸ,4›6@`¨И†Jã3J)£¡Y€ @€ @€ @ˆS|l9s’ƯofÒ˜¥c†Ý7lÎÖ9ÿxÐågÒ¯¦1飞þmèW’d © ±@cŠ+'MŸSú1 € @€ @€ @H˜SÂÀ©.&NKR¦%ó“”IÒ’U'ÃIz“Šv“Ƥ¢}FÏSc8-’#€Æ”kjJ”S¢¸© € @€ @€ @Y €Æ”…(І¡±dëÇ9uI¢’e`²7¥.é§|&ÙK*ÚPЦ¡×Ë 24¦”@õq@cŠ‹,ç… @€ @€ @€@f  1e644¬-ný8§1™®¤“HW²OÍaÒ†Ö›ÓnúÙVì ,@cÊbThS 1u"§€ @€ @€ @€@¾ 1å+^´¶‰J¶`œËÀ4yãd¹JZcNkÉé§´eæ´­Ÿ¶ð/äžSîCHê@cbd@€ @€ @€ @À;hLÞ…œCE"€ÆT¤hÒ—4&† @€ @€ @€¼ pàÍ =;®¶2móñwõ6gë·Ý;úÔ t€@ 1 ˆt¡4&Æ @€ @€ @€¼ ðöŸÞ¿ê/e/Õ½¯O½ @'!€S‚Hê@cb\@€ @€ @€ @À«wÝRWcÒû¾  Ÿ~èé¿æ•×&ùÑWzé%4&/ÃîC§Ñ˜|ˆ2}„ @€ @€ @€@@ nB&R118ŠG@ºÞÜWN-^¿èÊИ %€ÆTÐÀÒ-@€ @€ @€ Ô#P›‰TLŒ”â@c*^LéQ4&DA  14°t € @€ @€ @õD2‘ЉaRHhL… + €ÆÄh((4¦‚–nA€ @€ @€ @ pB&R11L I©a¥SИ %€ÆTÐÀÒ-@€ @€ @€ 4 à2‘Љ1RThLE,ý*@cb(”SAK· @€ @€ @€ И€%d"c¤¨ИŠYúU&€ÆÄP((4¦‚–nA€ @€ @€ @ 1%dzbýú $’S!ÃJ§ 11 J© ¥[€ @€ @€ @hL ··÷¯ßõýŠGàÍ7ß<æŸùÎùG¯kôehL …‚@c*h`é @€ @€ @€½täQÇ<77ø‰ÉÄ0)9LŸþì±·Ý÷Øé?¸äꫯ.XïèÊИ %€ÆTÐÀÒ-@€ @€ @€ Ô# oéÃG {aÅ–ÞM¯ÎëyùCÁdb ‡€9L·ß÷¸†÷ŠM¯ž†ÉTœØÒ“jhLŒˆ‚@c*h`é @€ @€ @€jÓÑÃôn]¹ùÕÀóxißœe˜L ”‚¦Ï{ÇØÇWU†÷ò¾}§s19™ `º&€ÆÄx((4¦‚–nA€ @€ @€ @ š€9L Wn]õò~Ó˜–¿´¯§oß쥛ÉÉÄ`É;9LŸ1‡©2¼eéIcZ¶qï÷1™ò]Ú_K‰QQPhL ,Ý‚ @€ @€ @€@ˆ€9L‹Vn]ýòþr®šŠÆ$ÏcÖÒÍüÈ1K{–à y$Pq˜ž†wµ¥§á½tÃÞï}ñ•Wý(]£Í¨O‰‘QPhL ,Ý‚ @€ @€ @€@…€9L‹W½²zË€äa¹jzúö.ݸwɆ=3–lúà‡?¶dY&Óˆ#/½´1lذɓ'×EÞÓÓ£ê~Ô××wðàÁÕ¨máªG—^zgüøñêŽ^jvÍ£Š¡0‡éÎqO¬Ù²ÀÒÓð.%3iÉú=#Ϻø’Ë®j½" Þ6ÂõÒpmýðøötuÐ*Ôf}ûšï¦Þ zžXwp×Ú9sæÔ­‘/f4¦XÇ%'OSzì©€ @€ @€ @ñpSEò¨ZQÎI/®ß3ãÅ—>ÐŽÉ$ÑǼ½ä ɇ¨ëH¤Ðžu;ªÃÕ,ºB¨‘G>¹Ù!ò–Ô“«ÆŒÓÊ]i!'éŒ@Èa:ÐÄÒÓð^¼N&Ó¨ÖM& †ð¸ÍÎ`ÐàlQþSûý~¥®1¹‹€Ybj°»ª„‡_Ì詳KGežSæCD!@€ @€ @€ Ð)ÃT_ò0É$EkwO[Ô†ÉÖ˜Ô@çyHG°ì5£FÒûaiäÈ‘ö‘Þ×nR(tmD w·ö#D¢ƒ;vv¿ZzI«²´¡$.–PÇ* ·MïH½²wì´¶D5°: Çu“€9Lw{bíÖU©˜B &Z*¦Òß½píîïžÙªÉј4ŒñÆáÁfãG_ 97ü¬Ãnˆšê§3Ø>Î4r#6¬ÚI´g˜šÎ¯—$òE{í`'wûë§åé›bcÞuÊȨ̂Úö¸6X÷urk˜ë¯{'ÜÚÈi#_ô‘}=Õ$ƒãΣm™[|1«¾ê€b“Š:8‡ ‘Àê]·¼ý§7=‰s˜lx›¢wÓÃ+O¸jÊðó'å”]ÚÓ·/Þ‹¢Ã{Áš]'ýd††÷ׯî,½YËwh„³±ÉmÒïvZ;ÅÞl2„œf4hØ¡9ÈŠràª"€ÆÄ€È!S'íeÍ8Çz§¾Æ¾Hš6eRž£]‹¹ìæp0Ðd@€ @€ @€ ‚¨8L[á!½CåÖ§Ö¬¨,¶5ü<ÙÏ/ݸWÓͯ^¼n¦/]ñ¼$9Lã§oÒz[#6÷§z•ŠiÖŠ@ò˜Ñ³ý©Ùëßß8'SÁ±Ò½ø ÜÕsØøUÙ\f’ÃôéÏ{ÇØÇÝð^µyÿÕã–i„K¹“¢'OŠÞ…·-, ï™ÞZNîáY›¾|ÅóÊ4ö½›{íý˵`â5ãz¾{ÓKÅTÞ;¦/Û~Ê÷æd*÷^Ó£ç:ûÏ;uP̧Ѝ•”xEŠ‚ËñÖÊ!~íƒÆäW¼‹ÐÛð—ú‚+›­°i}“˜¤Å^µÑ0“ËÌf“[°VÇ„·‹€Š>@€ @€ @€ @ çÌaZØ»ÕRÔØ2[2<®»LnÇò—ö-ïÛ÷‹'WŸ~ó @€ @€ @€he˜žþµ­ßËÓK‘ðH»Èzâ%Ÿÿê÷^}ÚUч)B±ÓÖóß=¶ò Ó)Ÿ¼!v”‹Gl'˜RÈãÜ Û>þËù~[—vBy’é¼ ¯ßr÷I²zbLÅ0ÓÏúñs8è̶˜ÏË*ü;DmÇ&‰)¢—2LÑf,Êû3W~7õaJå}õÍ÷\ÕŠ1EyoÚ–Uø3"Æ”¶“Û²#:¥ Sí$ÓÀSŠ1ò„ß\|’A z1¦Fü|';ÂE)2H{cJ¹¥|§ÉâŽtñ[±ÍÜ jš2 @€ @€ @€º uÔQ§žþÏ©ýRJ/e{lµZÔDŒés_½ã“—}'ú0þ¹›OûÜÍ‘ðˆœGêÃ]j^vÊå‘aºê¦{â=cŠ„GŒsZ1¦!ÈyÿŽ3ÿœwÖµÿóÀè‰ ”(ðÑ­ÿË™çÿÅþÏüÓ妈1Eg¦Û² S´‹-ä¢JóòŽ S«Âc#¹,ÆåÛÉEŒ©+¥×É0Åç~qóÿûÿýçïvl–X2Ô\àÂãëöß#÷C`´@ôQŠ$R¾_dì+»Ë¥C¢3S|O†n*œâ‘XŠG:Ež‡Z½zujÑäA€ @€ @€ @€@µ±åÖa‡ö¡^E—:l¥5±ÁÖg7Ý ØH.5aúôÆ,Æ!7|èê´ÙV4ªI›mEÎcõwEÈãï?üõ·üú,ÆtýެS!äqÊÖpà!·Þqßí;ü寮vâ®ÞþäS˜¾~×úÕ®˜ã9çœó¢¿,/ï´…\êÀôÆ3¯yÕi_M¦(ïW¾ÿ«¯|ÿ¦¼¼ó Sì–xÔÉ—}ð ·DyǾŠGþãeíòînŦ}÷{ƦͷFyÿè¶~sÖa’Lç¾¼1ì&B€I ÌÏÏG)~MI¤Ý»wïܹ3’Hñ$ñ$¾ŒûcJMœòGä–â­fŠ&Lñb†šä|\‹ @€ @€ @€)ÉtÆG/Èãi­´‹\$<Ž›»ú˜w\;m¿ñö£O¹ü+›øÌ×1rKùˆÍ¶N=Û!Ç9ú0µ[1E†©;äQÌ0EÎC’I5–%PŒ1Lùù#Éô¿¬XÞ©Â#ÀtÜ™WG¦çÅH¦¯|£¯¼oÜuÁ•wD¿±TÞŸºâ»íäväÛÉ3L©¼ôÓ_þæ‡ÛzÃLbLe­ºó 0c‘5*&‘Rï¥<ž”wSÚiƸL— @€ @€ @€À ´“Lÿ|AÊv´÷Øjµ¨‰¦´‘Ü51n¹÷ê[ÒN[Y¦hT“o¶µqëÝ^uçÀF5ý&I¦).—šÝzŠ1 0åwI¦CV••w¾…\k¹TÞ}íΞòN{É-”÷¶·îLå}ù–=Æú3L I¦¸ƒb˜IŒ©fÅãvh˜€SÃÔt @€ @€ @€fT %™>ð‘ÏDû¥ï`ZØi«µ—\ôašß¶36ÛŠÇ7DÂãîhT! …íä†e˜F$™vÿ÷Ý3º ¦½ç£LùùR’©¯¼ïûz'¢ù¼vDoP†iã w·+<í–xÝ]©Ó° SW’)n"…™Ä˜ö|}A€¥ ˆ1-ÝÊ;  @€ @€ @€ÔZ ’L‡¶’L­öKíLƒ»ÔŒÌ0C£3L“Lk.[³î¦uµ–rsuxèW»–x;‘d:xÕQ ù¼îcň^O¦ñ2L½I¦¸Ë‡~¼Ä[õ6C@Œi 4‡ @€ @€ @€¨©@$™^pð Oû§O·ÓK·f[ÈeãæöFrŶ:}˜Ú]j6Ûê4ªYJ†iÇý?ÿõÃäÛؾòã+×{}¼²eç–ôk4gÊû3ÅÒ›wîÞ¿•YSP·U3³ÿé£vT^Þi“Ävy§&L}½® SÖilI}˜R†)ƃýªfn‡cjìÒš @€ @€ @€Àl ¤$ÓûÏþt¾ÇÖײxG!áqck#¹ö^r¶Z{Éíi¦ž S€Ï]7·âŒk¯ZÏ#Ï#š3û3ÅïÆoE»¦ø­x[žyšÍÅ2ë1"ÉtСGuåó:¦¼ SÏV‰Ùn‰QÞ2Lcp;„cš ¶K @€ @€ @€˜ˆ@J2½ïìó‹¦þ„ÇB—š’2L1¹h°ɤx2ç|zx’º.¥^Mé•ÔŸ)z2­ú̪‰¨¸Hs"Éô‚CÌÊ»;À´iÛ€ˆ^»Í˜ SsÖßLh¬€Sc—ÖÄ @€ @€ @€fY %™Þ{Öù±ÇV 0õ'<®¸áîÔ¥¦”>LI;,¥VLñktfJ/¦LñˆWRg¦x%ÒKù˜å•2÷ñR’i¡¼[=Æò&L#"zç~qó¾û=cÓæ[ómã>±—Üxëâ(ì€ÓÞè9– @€ @€ @€@}R’é=gžŸLý B—š®»ë’k³qÊÖpà!·Þq߈Gÿ^r¹B$“¢S|ý–¢3S<Éû3ÅóøÝÈ0¥0S:dý·×§FMöT ’L¾èÈÞòÞší“8,¢'ô§ÈÞO€I ˆ1MRÛµ @€ @€ @€LT %™N=óSWnݹ1F+ÞÑNx6’ÛÐ 0í}†)æé¥*Å“¼SŠ1ů‘^Šc¹ñ$LñÎø­ør¢(.Ö ”dj—w!À40¢'ÃÔ •7š) ÆÔÌu5+ @€ @€ @€I dúÐyy€)Ox\zÝB¦R2Lq¹'¥MåR˜)="À/¦$Sz%:6¥íçd˜ê^ D’éù/:¢PÞ]û$æ=¦½tv8& Æ4d— @€ @€ @€ P¥@J2½óŒóR€)F 0å ²2LUNÒµgX ’LÏ{á—o阮òîŠèÉ0Ípu˜:Ó$ Æ4M«å^  @€ @€ @€Œ'’LkÏ8¯`êJxÈ0Gê¨Z dI¦Cޏ´ÑK›$¦!ÃT«•r3! Ƥ< @€ @€ @€Ì„@J2½ãƒëŠ ¦™XûÙ˜d$™8äðb1¦ÙXy³$@ 9bLÍYK3!@€ @€ @€ 0Z %™NùÀB’)žpà!·Þqßí;6vÜÿó_?ü[õHI&}˜ê¿RîĘ @€ @€ @€(&™d˜fhágfªy’É^r3³æ&J€@sĘš³–fB€ @€ @€ @`)Y’éÀóŠãxÞAú0-EÌ{¦K ’LÏ:àEû>鉛6ß:¢ÍXüÖƒýjº¦æn  Ðl1¦f¯¯Ù @€ @€ @€ ð‹«?¹æ)ÿû­›.µ—œúh¤ÀÇŸÿ[›Ö¾R†©‘‹kR4X@Œ©Á‹kj @€ @€ @€†\sÎo^µÏ=7ÌËyì¸ÿç¿~ø|¦UàUû<ø±Wˆ1éÃ4­+ë¾ h´€S£—×ä @€ @€ @€ hŘ~³}þžýEÔC†IÕL½@”÷¹/¬ÒÀ$“ ÓÔ¯¯  ÐP1¦†.¬i @€ @€ @€Xš@O’I†iilÞUoíó¿Ùu[Üb’I†©Þ+çî˜i1¦™^~“'@€ @€ @€h¶ÀWO^½~õÊŸü`{Ï4·~líÝ[æóó$“ S³ë¡a³{èþQÉ·^0×?¯â‹Å$“ SÃjÀth˜€SÃÔt @€ @€ @€´"¨1¦ˆzô‹ôg›"Ét×}ýúáGð˜(ãˆ+}ÿ«ë{nøþom‰ß*¾˜’L2LÓ²²î“™cšÙ¥7q @€ @€ @€& D†éÒ5«bēԴ¦Øé3«V¤ÉG $^ÿΗ×ýG‰ S¼9½³É4æÖÈ*Eǯi6ñ$^¬áüõÑ‹ÎdñÊÀl_#TL‚Ó- Æ4Ýëçî  @€ @€ @€ øÕC»£!Mä“"±O¢cMŠ}¤GêU½š"Æ”¾ŒwÆ{âI|/Fþ ,: lþÀš¨çH,EIGÝÆ“x%vJïÅ“ôzÔyªçx#^‰×%™ê¼¸î™cšÙ¥7q @€ @€ @€† ¤–K‘gJ‰WJ)¥|Ä+‘íH»ÎÅ{Rì)! ¥gO®†K™Þ äeñ»¼nSͧ”RÊíEaÇ+©Y΋О–cS¸æn™æ ˆ15Í @€ @€ @`R‹š˜x$6âIjB“Bñ<õª‰Gz1RMñþx’ö¡KcÑLyŠ¢Œ£¶S…§Š:O5Ÿ‡ðRyÇ;SÙÇëù;ئh­Ý*³# Æ4;km¦ @€ @€ @€3$ÙŽÔr)oHÑ¥<ä½j¢™MŒxC´«‰÷¤½çP¼SÈc†je:§šZ.¥ø]j¹5Y¥h”Bxy § _¼}›Ò\Så{ @€@ÝĘê¶"î‡ @€ @€ @€@ ‘aJ½j"íÏSŒ#•RO¦È*Å“x=~7½žö˜K_æ»t•p+NA`R§SD—"¢uõœFªüˆ+ÅoEUǓԖ,¾Œßµgâ2,ˆS @ 1¦‚ @€ @€ @€@ÝŠ9¤ˆn¤/‹¿Æ—ÑÌ&~+F~ó=_ÖmRî‡@ˆöKyG¥0E2)RJ‘Ì‹O¢°Sy§HSÊóÅ#žÄ—Z1©"ÔV@Œ©¶KãÆ @€ @€ @€ @€ÌŠ€Ó¬¬´y @€ @€ @€ @€¨­€Sm—Æ @€ @€ @€ @€˜1¦YYió$@€ @€ @€ ° pÍ9¿yÕ>¿Ù>Ï„@3¢¼Ï}y3§fVh®€Ss×ÖÌ @€ @€ @€ cRÍcjöúš cjèš @€ @€ @€Ÿú«¬Ó®Û h ÀOweå}Á85S"@€@£Ę½¼&G€ @€ @€ @` @ì·9xàά¼/>©‘“3)4XÀ& ^\S#@€ @€ @€ 0D@ŒIi4X@Œ©Á‹kj4Z@Œ©ÑËkr @€ @€ @€ ˆ1)Œ ˆ15xqMF ˆ15zyMŽ @€ @€ @€À@1&…Ñ`1¦/®© Ðh1¦F/¯É @€ @€ @€( Ƥ0, ÆÔàÅ55- ÆÔèå59 @€ @€ @€ĘFƒĘ¼¸¦F€@£Ę½¼&G€ @€ @€ @` €“Âh°€Sƒ×Ôh´€S£—×ä @€ @€ @€ cR cjðâšcjôòš @€ @€ @€\àÖK~sñIíqÊ~óª}¾Œ×õ T¦X 8/ï ^Ÿ•÷ûžµðJ¿Ô^@Œ©öKä  @€ @€ @€”"ðÃmY¶cà8ë°R®à$ªˆ2VáQü P{1¦Ú/‘$@€ @€ @€ P–À°œ‡GYÂÎS¡À° ž”^…‹âÒØ1¦=Ñò^ @€ @€ @€S-00ç!ä1Õkêæ‹ƒzRzŠ„S" Æ4% å6  @€ @€ @€”"Пóò(ÖIê Ðԓҫú¸,M@ŒiiNÞE€ @€ @€ @ =9!f,«Yä=A=)=µA€écšžµr§ @€ @€ @€J(æ<„¼ÎSý÷V{¼’|WÍGñ.ûüõÅê¿øÑÈ> Ýõ_þ‡ß~ÔïÿÁŠüõâ'"=ÿÃ?úãôÃT±ÝuÛ*ݬnÛ¥ÛªÞþî­áV畼=«ä®b.ÔóO²znTÒYUg…UuVØÝµ}S§¶óòî­ðV‘wê¼»Ô¿•z»Ú|_Í·Ê>¯ü¼ø;õ¿«]ÿÅÀí@ßag|b\ÑñYxÞ xÓI§u}" Šø\¼ûìÏ>ûÙÏ^ê’{¦D@ŒiJÊm @€ @€ @€Lƒ@„?¢KôR 0eãÞŸEŒé}­S 0eAV dh†©c*f˜òäGÊ0å±ÞÀG+ÆÔõøn;Æ”2L­G'ÃÔcº®ìèÊ0µ"]¦þS'ÆÑ‰1¥èFWŒ©Úè1e&1¦å¬ö,ÆtÔ±]¹¥B­¦ôRTrJ/ 0õ–n'ÀÔÂ+%Ô'óºÂy½¦…ˆÞèS+«7,ÃÔíõåöǘRz¯˜aÊbL­ ßèÓ•}y¾b†i!ÆÔJõµƒ}bLËù¡pnj" ÆT“…p @€ @€ @€MH=lÚ¡¥vt©«“ÍáGf1¦¦¼MjÂ4¬Óè Ó^·bz`¡S+Ætmw7¦E[1å1ެS¡M;ÃTLoä1¦‹S7¦®VL­nLw鯴ŸŠˆ1Eœ.Å•ºÊ5Ë-µ£KQÉyû¥LKÊ0E§±¥µbÊ3L[:-Ç¢à»{‹µbjw +4!ëkÅÔiEÖÝŠiS'É—‡ùÚmÉúZ1¥ÓšèÆÔaÊ[”m¸V7¦åød8'Õ ˆ1U¿î€ @€ @€ @ 1ÅðÇÀM¸^zä±ïýà‡{:0 ØH®» Sÿ\û0 È0µ:Ö¤íäòœÇB+¦ÞíäZÔ lÅôl;¹îVLKÛQn@+¦ÖŽrínL­ÓÀå"®aS¹Ò?)Æ´PŸÅ ã:{F%ÓKùæqÅÎa…-äú:0 0 ÜH.ßqô^r£ú0-9ôØvr½û'ÆFŠ­‚·Ó…M ;ÊhÅtEkwÅa1¦´ÍbŒKĘJÿT8!õcªÇ:¸  @€ @€ @€Fô„?ÚÝk ;ǽôÈcÞóo×îžÈB¦b€iÇO&?ŠÉ}ëû?I{ÉîÃ4*ÃÔ·\ÖŸæ¶ÔŠé¾æH£ôVL…SÿæYí¸FĘæÎúçýô—ùøÉÏ~Õˆb©lcŠ8]O¥žÐRTr¶kw]êm¡÷Roz©ØBìö¦‡u``êjÂtg¶=b]›$f¦¥î%·L¦«o¾':¥qU¶£Ü"ÛÉ-¥S1Æ”ï±XlÅ”bLO_ùÌâç"žÿG©¬ª\˜eˆ1•¡è @€ @€ @€Z=á…üGD@Z),Ætú‡ïØ9*ÿÑþµ÷VW€)ïXÓõøÑ­-·ôaZ,Ãtmw†ió7ïMµÚûjÝrol§•ƀǻ6µÆˆVLcúßý½ó.þưVL׈Ó»O;;21ù½_?,®1þG®c:¦˜Rêj֪ը䔴ëÎÛ ¨ÛžèR1½T á ÜBn`¦b€iŒ&LQä[o`kÞil¡Â³fcCö’³Ó3LC·“ëô$‹BŒÔ‡)u&{Þ!íMå²ÓuÙ(¶bJ1¦}÷{FñsÏ|HÂoüÏ…# ¨ƒ€SVÁ= @€ @€ @€4D`xø£•ÿØùàKŽ8æÝ§ŸÝß{©þèé^³h€i`¦ÖFrí½ä ½j–!ÃÔŽ12LY7š¯Æèd˜6mkǘº6Òj…6Rn£cÚ|ÙõY7¦Bb£ÝŠi`Œ)27bL{óI1¦bJ©»ÁRÔjcJ{ÇÝæå:°nS’&ÏÞõô^*¦—Ší—Æ 0õïØ›Ï‹ S+Àã†4¶Gz)û£ÍX>R¿±¼åX×+n$—…öй½ÂŠYzoi}˜ö4Ãtù–ì³bLy+¦ž “ÓÞÔ¿c ¨³€SWǽ @€ @€ @€L™@„?ú3ÅW^1¦Bo¡,ü1rã­Û~ø“´…\!öÑêÀT0µ:Ö Üo«¯ S'ä1,Þ10Ø‘ö’ëëô„ S§ÓÀ Ó­Æ3cZ×cJ‰j¤ÑßIŒi/?cŠ8ÝèB-VrOËŸ…È]§t÷,ºôƒŸÄNˆ ›!vWr±ýRq ¹½ 0nÂ40ԘڽǺ3LùFrÙ^r7 ÝKn¼ SŠ1ý]Š1õõaJŸ ݘöòSàpê) ÆTÏuqW @€ @€ @€S)áþÌGþJ$–"ÆtêigEì#íùh7^úit¬ÉšÖ H/ýdPzi‘ÓbÉ=Ç;®ûv¡9Mg#¹NgšeÈ0u¶ÐÊcL]‰N†IŒi9>cŠ:Q¨ñ[©’Û1»BØ®·n£€˜o:‡õt]*6^•^ê¤ñÚé¥bS±;þõ¦­ó±Ð]lT¦®&Ly‘lÂTìÃÔ߄难-³ÓÈ S¾b<¹rk{lܺsã½äR¦4Ú1¦!&1¦åø\8'ucªÃ*¸ @€ @€ @€†Dø#(õ>ú©‹c¤Ž5Ñr)Æñ'½'k¹”í±õÀß¼ñÄY·>F–öØþ@JuDÚcËö,äã’¯Ýú„'ïû•Ö¯yš÷ùÉÈvÄxŒlÇ_Þü¬çãÕ¯?!¥:yñÑÏúÓƒžù§ECšñåq'¼+¾Œñ©‹¯‰ñèÇ<ö¿<ñ©ç­¿fÓ»^uô3þë bdŽm;OûÈçW>ç1^pØËVÿÍ›¯hŘ:M˜î¾¬Ø‡©ÐxFŒiòÅ1¦ˆÓõjO­F%w3Ì+6OÚuÕm§t{ö:Ì÷=Œ¬Rp$ðRË¥Èá}ê¢+Ÿó¼ƒ£€SË¥H)wáÆ(æ7¿ýݶúo².b­ôRÔs*é(ã“ßsVD‘¾ºõû]úë7œ# ûs—|#•tJ,åã³_ÙÜÊ-uzŒ}óÞ“N=3Š‘ŽÈsį¿øès¼ëƒçFn#6ÒzåkOyŽHr¼þøµ`zÇÎGd8þãcþàìO]ò/_ûÎ~ÂSÿ2bLí]äºL…ͳR\CŒiò¥žÅ˜^rôèBí­äVÀnDݦÄR±tóç­ìÝòMâ"º¡¥(ãvt©ÕB,ž¯»pã…—^q¥È-Ee7ŒK1¦O~þŠˆ.Å>q×Þ1¦bD×¥´[\”w¼I¦Î¶q÷ýÕëOˆßÊwŽË{/½úu'DµG‘ì‚Ëýû]¿ñ¦h¼u~Ù7îˆ&L‘^ŠöKÑo,ÒKÑr,~ÜRTû®¸1ê?ýzÐa/‹²âçQöÑ{ìßÚг…bO†oLbL“ÿD¸"È»1¥$ÒĘ" •Z1å1¦ /žË @€ @€ @€L‘@„?ò4Ÿ¼è%/‹ÓÀ´G¼˜š-åH/E¼#Û-.¢KÇeÑ¥Ô¢¦Ý{©Ðu)Õä»kEÈ#¥—¢÷R$<"ÞãßÌ‚1ò}µ"Àô¸'í˜Z;jŸ'RéH#òm¼éqO|jt`J[È¥G¾…V4¡YýÚãÓþq)À饔Þ8þ”3þò5onõaÚqÙõÙÈv‘+˜6\—˜Ä˜ª*ìˆ1EŽ.ÔþJV´ÃâJ©ŒÛ{Ãuž¤ S$–Ò>q­'Y¿¥,¥ô…+bĔƋS÷nq÷G=âó—g…ý¤}£—Ø_½á„‘Ì‹>Lyt©¸m\´\ŠwfåFgÛ¸¨ùOÿË5Wß|O¤ô^öò×D³±¨öW¾î-ió¸(ø¨öDŒéµÇ§šSÔ|Œ(øÞñ¡xåÃçoˆôRŒh<é¥h®K€Àr Dû¥|ƒ¸t­¥Æ˜â°ž S,Æ´Ü æü @€ @€ @€Ó+áÑi½øeÿðî¹bV)-u>¶?{lÅÖZ'¿÷ìbt)µ¨I1¦ÈyDò#¢ÿøî³òmã¢?MŒÔx)‹z´¢Kñžè½ÁŽ|ó¸v|ü‚,Æ”6‹©Žˆ.¥HÇ+ÿ6Æñ67Z.E˜#ºÑĈGl¡•bL±…\cje˜"Æã¬óÚ1¦ˆnœµî’ˆ1¥S;½QØE®'±¡Óä«=‹1½øe£ µXÉívJÝ»¼nû³Ji£Ã4:{ÃeON~ïYWZ÷…+R§èÒÂóÏgÅüìç#®ù¤-¥z.v]J»ÅEã¥(ì“N=ë…/9:k¹ãÖ{ãõ¼ëR;¥×I/E…GhéŒ]—¾¸ñ¦¨ö«n¾'ÕyYV怜ÇX|ô‹:O5äûëcŠÛ&Fã±Nï¥VŒé†»£ñXÿ€öK ßÀ߆NŒ¯?À¤Óä?®H€ÀÄ"tÔ“aŠK/)ÆÔŸ~J7-Æ4±Ås! @€ @€ @€©ˆøE1ÞÑQzaĘNýP;±Ô‰zô¤=¢9͆«o Sòˆ¨Ç6|#b©EMä<>É7¾|Õ-‘ÛÈZÔ´r±¯V{|ó¾g=÷ HxD㥬÷Ò­÷¾ðÅGG€)¶‹í´Rï¥gþéAúø…cŠŒ'›nø~4[ÊBKÜRöB=· ;byç|öòVã¥{S2/Jú3ÿòõ<º”vEŒò.6^zÛ»æR…§ ã"À•Ü[Þ—bDyŸwñ5Ñx)FÊêEŒ)~ýÈù"½ÕûÇÅæq©÷R<ÿÄEWgeßé½e饈1|Ú9­ÊÏÆ¢í— 0‰1MþáŠLF G±)\ÿµ1ÍÏÏÇ–âøô(&¡Ä˜&³x®B€ @€ @€ 0ñ¯lÅö3ýÏ#ÆtÒ»>4,ê‘g>}é1‘ÏÈÇ_¿áÄH{󗯉´GŒØ$.rKñkñ=­ ã²GŒ”íH#/ÍsQj¼1¦x#žD¶ãmèÒ3ÿëA±—V¤:b/­v¤‘ÒKñ$‚1âIJ/½îøµ±…Ü[N9#ÂéHãø“ÏˆGüÏŸþì<4ß¼yÑ“M媪ðˆ1EŽ.Ô!•ÜÊ' J)KéyWŠÒ¦b¹¦ø]´\Š|RŒx÷YÅÜRk{¸(æ4²’Žd^4XÊ«:j8bLQÛ¯~Ý ñ<ÂIíÝâ:­Å¢¼ÏÿÒ5ÙëOÜ7Fd˜ÞõÁs£È/Üxcªêøõ¨?ÿë(òÔiiÓ¶]‘[Š×ã×è:¡½È-EÁGû¥ˆ+Eañg¡½xž÷^zús^eÿ·Ÿ}"Þ|ò]íÇ|í ßÓKyÂϦrU}:\—eX»vmÄ•ò$ÒÜÜ\~¡ÅcL»wïÞRxlß¾=?¸ø|™nÝi  @€ @€ @€L©@„?úóÅWYuTĘòWz¢)ð±°C\¡?MOsšžGÚT«]Š„Gj¼TÜ6.u¦I;j]uSŒ¬'MÚN+ß<î’¯7E:bDÔ#¶ÐJÝh6fãîHr¤ý³bD†ã⫾Sì@“µ_j86ŒìÀ¤Sµå1¦¨ÃÑ…:¢’ÛEÛê¨4p\{ÛýíÖJ…îjVhö¥M·ôsÖB¬»žó­âRUçý–Öv¡¼ÛÑ¥¼Èó:Oí—Rç#•zOÁk>•ýô^ºî®aÛÆ~]Œ©Úψ« Pº@ÄŠI¤&å—ˆ×óçû”~a'$@€ @€ @€ 0³þ–íH¯G|äíïüP+¨48ê10í±hÎ#‹w Jxä¹¥aÑ¥bª£+ϱ- sD+š³?µ! 0ÝP0-Ä8vä[h`Ò©ªIŠ1.ÔžJn•k_Ñv§”†•R¯Pà =–Ú‰¥!¼!%¢KÅÂn×v!™W çõä–òˆÞBt©Uê…èRwµB{ôÒBÙ·wNìï½4nzI7¦ª>®K€@MĘj²nƒ @€ @€ @  þˆ0ǰaŽƒWõ¶µgô´VÊ¿ìŽzd{i-’óhw¦Yh¹Ô“ðȺ.eñŽB×¥Bã¥þ†4=yŽO\øµžöK)ÉÑŸ^ZèÀtížµŸùG=úÜ/nÑ™&ÚÒ¼û´³oßñ`>îܵû×?Ò„r©h)Æ4¢Pã·¢’‡UéÀ×ûRJƒ²J#z,uBxý–úCKýý–ÚÍ–ZµFªíöètÞu©]Ñxéò-“H/‰1Uô™pYê" ÆT—•p @€ @€ @€ ÈÂß¼/ýÙŽƒ;ê­kÏè¼Þ* ‹+uí¥µÐl©+´4$·´'Ñ¥Þn4];ÇwÑÊÓKí&4×íÙþq³JbL“/ûˆ1EœnH“¤vÛ¤¨ä!ɤxິ\Úå°Ý*,ÒÊÞ Œ+ L,õ‡–š- Í-umé¥+ E^Ü!±'·Ô³gÜàèRï¥=Œî-e›9›ÊMþsáŠÔA@Œ©«à @€ @€ @€"ᯧQ´ ¿uó=ýÜ•UWÖf)K,í*òÒóžfK~Kƒ·ŠÝr©˜Õ‹­vKl…ö–ÒH©”÷ˆ1MþsáŠÔA@Œ©«à @€ @€ @€"áÑ!zä §|pDÂc¡ÁR;çÑ×fx£'Þ1h#­ÑÑ¥Á—ŠIŽR"Å“ˆ1M¾ô³Ó¡GŽ.Ôv%ß|ÏÕ#I+9먔F__¥®ýà •=–ºxéËA‰¥Q¡¥N³¥=Ú*n!·ÔÕr©œfcc^Ę&ÿ¹pEê ÆT‡Up @€ @€ @€ ˆðGoË™<ÒÑz1¦·œüÁñŽÞ„G„<öXžð‘[ê vº.-]ZÖ&4bL“/ýˆ1EËÒ¥RTr_ip,iÀÖo©t ªzRJí2TêÍ*uº+ Ž+Mg¥%f˜âmbL“ÿ\¸"ucªÃ*¸ @€ @€ @€†Døãò‘yŽçEŒé¤Ó;ïÉz)-;†d;†µ¢éo³ûg-='Q“wŠ1M¾ô#Æu8ºP«ä¾ÒÒE)ª7—F2©gt† ,æ´\ŒšÔê$oCŒiòŸ W$@ bLuX÷@€ @€ @€ ÐsýÏŸwÈkN:-½> ÕQè@Ó½\aÛ¬Èv4¨ÓäK?‹1rÄèBQɃë6¯çB2©¯†ûʸA•\nÈIŒiòŸ W$@ bLuX÷@€ @€ @€ ÐûÊ7ŽøG¼ß³ž_xÃqǾrÐxÅqÇÌÆø·ÿî·;rõˆÉ>öþøÝ§}ûŽóqç®Ý¿~ø‘†TLÓˆSÔáèB]´’×m^̯8îØÙ(àeúœFÙï÷Ìç8yäœöÝïÅÏE<ð¡_UQP®I€ÒĘJ£t" @€ @€ @€§Ÿ~úI…ljo}ûß¾ñ-ÅñâÃùóW¼¦çÅYþòùúš×½i´À¦Í·Š1•øáºóÎ;‹UÏßø¦{–à¹Ï?x–˲ò¹/åÅY=_Œ©ÄÏ…S P1¦:¬‚{ @€ @€ @€h¦ÀÏùpOÎÀ—{/ S韖÷ÿ|ï×Å*Щô† 0a1¦ ƒ» @€ @€ @€À ˆ1-G°CŒ©ôÓrêäÏ)ÆTúGà ˜°€Ó„Á]Ž @€ @€ @`†Ę–#É!ÆTúGHŒi9 uòçc*ý£á„LX@ŒiÂà.G€ @€ @€ 0CbLË‘äc*ý#$Æ´…:ùsŠ1•þÑpB&, Æ4ap—#@€ @€ @€˜!_ü÷‡'ehüï¸{÷¯~d†Êhù§z÷ý5¾lfa‚bLËÿYq–W@Œiy} @€ @€ @`Æ"É=™FŒŸýâ×£ß0k¿»(È/õðŒUéÓXØ¢e¶èº,zoØ¥ø—^NH€ ˆ1MÜå @€ @€ @€ @€ècR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X@Œ©âpy @€ @€ @€ @€ĘÔ @€ @€ @€ @€ ˆ1U¼.O€ @€ @€ @€ @€€“ @€ @€ @€ @€ @ b1¦ŠÀå  @€ @€ @€ @€cR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X@Œ©âpy @€ @€ @€ @€ĘÔ @€ @€ @€ @€ ˆ1U¼.O€ @€ @€ @€ @€€“ @€ @€ @€ @€ @ b1¦ŠÀå  @€ @€ @€ @€cR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X`‘ÓöíÛ{n°ÿ•Šgàò @€ @€ @€ @€Ô[`gëQ¼ÇžW†Æ˜Ö¬Y³²óHÑ¥þWê=wwG€ @€ @€ @€ @€@õ«V­Ê“Hénú_cЬS™ŽY¿~}ÖÿJõós @€ @€ @€ @€Ô[`ݺu«W¯N÷}”æææú_‰ßÚ)ß<.Řâ­ý¯Ô[ÀÝ @€ @€ @€ @€ P±ÀîÖ#ÝDŠ1õ¿¿54Æ”ß~´ešŸŸ/Φÿ•Šçêò @€ @€ @€ @€Ô[`Ë–-+V¬(Þcñ•Q1¦h¿‰¥hâ”ÜÿJ½çîî @€ @€ @€ @€¨^ v„‹$Rä–ò[éyehŒ)މ#ãÝù‘ý¯T??w@€ @€ @€ @€ @€@½¢R$‘¢ƒR~›ý¯ 1E§Øˆ.¢KñH§è¥ÞÓww @€ @€ @€ @€T,0??¹£ø5%‘vïÞÝÿJÜâàSjÙ”?V¯^ÝÿJÅósy @€ @€ @€ @€j/°fÍšb):+õ¿“Ú©ötƒ @€ @€ @€ @€4D@Œ©! i @€ @€ @€ @€¦W@Œiz×Î @€ @€ @€ @€hˆ€SCÒ4 @€ @€ @€ @€L¯€Óô®;'@€ @€ @€¡÷ð5K¾IDAT @€ Ð1¦†,¤i @€ @€ @€ @€˜^1¦é];wN€ @€ @€ @€ @ !bL YHÓ @€ @€ @€ @€ 0½bLÓ»vîœ @€ @€ @€ @€@CƲ¦A€ @€ @€ @€ @`zʦwíÜ9 @€ @€ @€ @€†ˆ15d!Mƒ @€ @€ @€ @€Àô ˆ1MïÚ¹s @€ @€ @€ @€ cjÈBš @€ @€ @€ @€écšÞµsç @€ @€ @€ @€" ÆÔ…4  @€ @€ @€ @€Ó+ Æ4½kçÎ  @€ @€ @€ @€4D@Œ©! i @€ @€ @€ @€¦W@Œiz×Î @€ @€ @€ @€hˆ€SCÒ4 @€ @€ @€ @€L¯€Óô®;'@€ @€ @€ @€ Ð1¦†,¤i @€ @€ @€ @€˜^1¦é];wN€ @€ @€ @€ @ !bL YHÓ @€ @€ @€ @€ 0½bLÓ»vîœ @€ @€ @€ @€@CƲ¦A€ @€ @€ @€ @`zʦwíÜ9 @€ @€ @€ @€†ˆ15d!Mƒ @€ @€ @€ @€Àô ˆ1MïÚ¹s @€ @€ @€ @€ cjÈBš @€ @€ @€ @€écšÞµsç @€ @€ @€ @€" ÆÔ…4  @€ @€ @€ @€Ó+ Æ4½kçÎ  @€ @€ @€ @€4D@Œ©! i @€ @€ @€ @€¦W@Œiz×Î @€ @€ @€ @€hˆ€SCÒ4 @€ @€ @€ @€L¯€Óô®;'@€ @€ @€ @€ Ð1¦†,¤i @€ @€ @€ @€˜^1¦é];wN€ @€ @€ @€ @ !bL YHÓ @€ @€ @€ @€ 0½bLÓ»vîœ @€ @€ @€ @€@CƲ¦A€ @€ @€ @€ @`zʦwíÜ9 @€ @€ @€ @€†ˆ15d!Mƒ @€ @€ @€ @€Àô ˆ1MïÚ¹s @€ @€ @€ @€ cjÈBš @€ @€ @€ @€écšÞµsç @€ @€ @€ @€" ÆÔ…4  @€ @€ @€ @€Ó+ Æ4½kçÎ  @€ @€ @€ @€4D@Œ©! i @€ @€ @€ @€¦W@Œiz×Î @€ @€ @€ @€hˆ€SCÒ4 @€ @€ @€ @€L¯€Óô®;'@€ @€ @€ @€ Ð1¦†,¤i @€ @€ @€ @€˜^1¦é];wN€ @€ @€ @€ @ !bL YHÓ @€ @€ @€ @€ 0½bLÓ»vîœ @€ @€ @€ @€@CƲ¦A€ @€ @€ @€ @`zʦwíÜ9 @€ @€ @€ @€†ˆ15d!Mƒ @€ @€ @€ @€Àô ˆ1MïÚ¹s @€ @€ @€ @€ cjÈBš @€ @€ @€ @€écšÞµsç @€ @€ @€ @€" ÆÔ…4  @€ @€ @€ @€Ó+ Æ4½kçÎ  @€ @€ @€ @€4D@Œ©! i @€ @€ @€ @€¦W@Œiz×Î @€ @€ @€ @€hˆÀ¨ÓüüüÜÜÜöíÛó¹Æ+ëÖ­Û¹sgCfo @€ @€ @€ @€,¿@„ŽzrGñe„‘ò+1­ZµjõêÕk×®]¹råúõëã€â+’LË¿v®@€ @€ @€ @€ @  +V¬X³fMJ"¥ÜQz%ñJšáàSt`Êß±eË–t|ĘÒ1qÆx4AÈ @€ @€ @€ @€XNØ.âJé )w=•òW"˜ñ¤ø­Q›Ê¥ƒãDÑ–)¿ÕÈ3ÅÁņNË9 ç&@€ @€ @€ @€ @ !CнäòÉDi‘nLù[#ëœò-äR—¦xÄ“†Ø˜ @€ @€ @€ @€Ë/¦<´WK_æÄêÆo SêÚT|D[§â— ®@€ @€ @€ @€ @€À Ä.rGñzl3cJq§¼S<É·–‹`“Ó…['@€ @€ @€ @€ 0AÈåÑ£¸l4Qš››K× Ó¨S„–¢SÊ:Å#Ñ¥x’2Lé` @€ @€ @€ @€ŒH;Â¥R<æççS6)ÂLñˆ'ñJ>¸Sü^~dcŠããy£âÔè  @€ @€ @€ @€ °¨@dŠI¤ZŠ_£ÅR<Ò—ñº©Ü¢ð @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ ¡1¦õëׯ\¹rÅŠ«V­*^i~~¾ç•RîÃI @€ @€ @€ @€h¤ÀÚµk#‰5kÖ'¯Ç#½24Ʀ-[¶Ä;æææV¯^Þ½{÷îx=ÎØH/“"@€ @€ @€ @€ @ \èšq£ÈÅi#†´nݺtþx=’H‹Ä˜â°H/¥"Ì”ç–âDñºS¹Kål @€ @€ @€ @€š*q¥x¤ÙÛ/¥æL‹wcÊ]b ¹”ŠSYL55Õμ @€ @€ @€ @€(W m·sçÎ8mtSZ¿~ý’6•K7¤åâøÈ3Å1¦r—ÇÙ @€ @€ @€ @€4^ ÒGÑ~)uSŠStSŠ'K1¥ÆMÉ(މ/#É¿F**e›< @€ @€ @€ @€ 0Z 'Eâ(e˜â‘2Hñk¼˜¿¾Ï°SÄ[c¹þßÕIÙ @€ @€ @€ @€ °DèÃY¥õ¿ñnL}JY§ôHÛÉ¥Gœ±øåïÆÛ @€ @€ @€ @€˜AØö­˜DŠèRްxŒi½L™ @€ @€ @€ @€ª†n*WÕ ¹. @€ @€ @€ @€³& Æ4k+n¾ @€ @€ @€ @€j' ÆT»%qC @€ @€ @€ @€fM@ŒiÖVÜ|  @€ @€ @€ @€ÔN@Œ©vK↠@€ @€ @€ @€Ìš€Ó¬­¸ù @€ @€ @€ @€¨€Sí–Ä  @€ @€ @€ @€˜51¦Y[qó%@€ @€ @€ @€ P;1¦Ú-‰"@€ @€ @€ @€ 0kbL³¶âæK€ @€ @€ @€ @ vbLµ[7D€ @€ @€ @€ @`ÖĘfmÅÍ— @€ @€ @€ @€@íĘj·$nˆ @€ @€ @€ @€À¬ ˆ1ÍÚŠ›/ @€ @€ @€ @€Ú ˆ1ÕnIÜ @€ @€ @€ @€Ycšµ7_ @€ @€ @€ @€µcªÝ’¸! @€ @€ @€ @€³& Æ4k+n¾ @€ @€ @€ @€j' ÆT»%qC @€ @€ @€ @€fM@ŒiÖVÜ|  @€ @€ @€ @€ÔN@Œ©vK↠@€ @€ @€ @€Ìš€Ó¬­¸ù @€ @€ @€ @€¨€Sí–Ä  @€ @€ @€ @€˜51¦Y[qó%@€ @€ @€ @€ P;1¦Ú-‰"@€ @€ @€ @€ 0kbL³¶âæK€ @€ @€ @€ @ vbLµ[7D€ @€ @€ @€ @`ÖĘfmÅÍ— @€ @€ @€ @€@íĘj·$nˆ @€ @€ @€ @€À¬ ˆ1ÍÚŠ›/ @€ @€ @€ @€Ú ˆ1ÕnIÜ @€ @€ @€ @€Ycšµ7_ @€ @€ @€ @€µcªÝ’¸! @€ @€ @€ @€³& Æ4k+n¾ @€ @€ @€ @€j' ÆT»%qC @€ @€ @€ @€fM@ŒiÖVÜ|  @€ @€ @€ @€ÔN@Œ©vK↠@€ @€ @€ @€Ìš€Ó¬­¸ù @€ @€ @€ @€¨€Sí–Ä  @€ @€ @€ @€˜51¦Y[qó%@€ @€ @€ @€ P;1¦Ú-‰"@€ @€ @€ @€ 0kbL³¶âæK€ @€ @€ @€ @ vbLµ[7D€ @€ @€ @€ @`ÖĘfmÅÍ— @€ @€ @€ @€@íĘj·$nˆ @€ @€ @€ @€À¬ ˆ1ÍÚŠ›/ @€ @€ @€ @€Ú ˆ1ÕnIÜ @€ @€ @€ @€Ycšµ7_ @€ @€ @€ @€µcªÝ’¸! @€ @€ @€ @€³& Æ4k+n¾ @€ @€ @€ @€j' ÆT»%qC @€ @€ @€ @€fM@ŒiÖVÜ|  @€ @€ @€ @€ÔN@Œ©vK↠@€ @€ @€ @€Ìš€Ó¬­¸ù @€ @€ @€ @€¨€Sí–Ä  @€ @€ @€ @€˜51¦Y[qó%@€ @€ @€ @€ P;1¦Ú-‰"@€ @€ @€ @€ 0kbL³¶âæK€ @€ @€ @€ @ vbLµ[7D€ @€ @€ @€ @`ÖĘfmÅÍ— @€ @€ @€ @€@íĘj·$nˆ @€ @€ @€ @€À¬ ˆ1ÍÚŠ›/ @€ @€ @€ @€Ú ˆ1ÕnIÜ @€ @€ @€ @€Ycšµ7_ @€ @€ @€ @€µcªÝ’¸! @€ @€ @€ @€³& Æ4k+n¾ @€ @€ @€ @€j'0*Æ4???77·}ûöt×»wïÞÒyÄóÚMÅ  @€ @€ @€ @€ PKu­ÇÎ;ÓÝE$)O"¥W†Æ˜V­Zµzõêµk×®\¹rýúõñÖx¾bÅŠø2oªå|Ý @€ @€ @€ @€õˆÐÑš5kR)%™R)=R—¥Á1¦ø½xGšMäžÒó6ÅózMÑÝ @€ @€ @€ @€ Pcè—¦tƒ‘dŠG<‰`SÏ-ÚT.½5Nm™âI„™âŒñk:— @€ @€ @€ @€–.1¤´µ\dây¾M\œa‘S´_ŠèSjåݘbw¹x%N‘'¤–~ÞI€ @€ @€ @€ @€ÀÌ D€)m ;Å¥}áÒ6qIŠGŘâÈÈ0õo$©¦þ¶N3ëkâ @€ @€ @€ @€ŒH»Àõ¿'JiŠ×‡Æ˜Rú)õaŠÇîÝ»ó½ä"%Ƥò @€ @€ @€ @€XŠ@lþüóóó‘MJ_ÎÍÍ¥ßcJý–"Ñ¥xÄ»ã­ñJ¼‡ @€ @€ @€ @€ÙH;Â¥R<"Ãx%ö’‹G$‘¢§RÈ Ž1Å[ó#óSd›ây¤ŸÒvt @€ @€ @€ @€-1¦b)‚Iñþø5Z,Å#e˜â1tS9¾ @€ @€ @€ @€˜Œ€Ódœ]… @€ @€ @€ @€¡bLŠƒ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X@Œ©âpy @€ @€ @€ @€ĘÔ @€ @€ @€ @€ ˆ1U¼.O€ @€ @€ @€ @€€“ @€ @€ @€ @€ @ b1¦ŠÀå  @€ @€ @€ @€cR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X@Œ©âpy @€ @€ @€ @€ĘÔ @€ @€ @€ @€ ˆ1U¼.O€ @€ @€ @€ @€€“ @€ @€ @€ @€ @ b1¦ŠÀå  @€ @€ @€ @€cR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X@Œ©âpy @€ @€ @€ @€ĘÔ @€ @€ @€ @€ ˆ1U¼.O€ @€ @€ @€ @€€“ @€ @€ @€ @€ @ b1¦ŠÀå  @€ @€ @€ @€cR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€ŠĘ*^—'@€ @€ @€ @€ @@ŒI  @€ @€ @€ @€ P±€SÅ àò @€ @€ @€ @€ˆ1© @€ @€ @€ @€*cªx\ž @€ @€ @€ @€1&5@€ @€ @€ @€ @€@ÅbL/€Ë @€ @€ @€ @€ Ƥ @€ @€ @€ @€¨X@Œ©âpy @€ @€ @€ @€ĘÔ @€ @€ @€ @€ ˆ1U¼.O€ @€ @€ @€ @€€“ @€ @€ @€ @€ @ b1¦ŠÀå  @€ @€ @€ @€cR @€ @€ @€ @€T, ÆTñ¸< @€ @€ @€ @€bLj€ @€ @€ @€ @€Š†Æ˜vîܹfÍšU«VÍÍÍå÷Ï{^©øö]ž @€ @€ @€ @€z ÌÏϯn=Ö¯_Ÿît÷îÝ)›”¿24Æ´råÊ-mÙ²%Ž_»vmOâàâ+õž¾»#@€ @€ @€ @€ @ b覴bÅŠˆ+Eî("IiŠŠ'ëÖ­+¾28Æ´}ûö-¥¤wÇéâ×|Nñ†Šççò @€ @€ @€ @€Ô^ âJùvpÑM)ñJžMŠTRtfŠI íÆ”O0:0ÅÁ)Ì”Z9åg©=‚$@€ @€ @€ @€ @ .©S„‘"€1¤x¤mââ±HŒ)¢O© SĘ¢¹Sêé”vª«ËäÜ @€ @€ @€ @€µÈCG]J»ÃE¦´»\Üû¨S™o$—º1¥ÉŸ×~ún @€ @€ @€ @€Š"z”7NJ[˥ʟ1õ´\ŠôStcJGO¦<ÒTñü\ž @€ @€ @€ @€z ä-—ÒmFû¥ØN.=_³fMŠ4 Ž1EPiŸ}ö‰ãÓ#%¡â˜x’z:¥Ýå< @€ @€ @€ @€ 0B âFÑ>)O"ÍÍÍÅ›ãË#Å#žÄÖrñÊàSü^ì—?¶oßž®OâDÑ™ = @€ @€ @€ @€ˆÄQ1‰”BKñˆ>JÑ–)?|è¦r‹^À @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Âè$ @€ @€ @€ @€Œ/ Æ4¾#  @€ @€ @€ @€(E@Œ©F'!@€ @€ @€ @€ @`|1¦ñíI€ @€ @€ @€ @€@)bL¥0:  @€ @€ @€ @€ã ˆ1oçH @€ @€ @€ @€Jc*…ÑI @€ @€ @€ @€_@Œi|;G @€ @€ @€ @€ PŠ€S)ŒNB€ @€ @€ @€ @€ÀøbLãÛ9’ @€ @€ @€ @€RĘJat @€ @€ @€ @€ÆcßΑ @€ @€ @€ @€”" ÆT £“ @€ @€ @€ @€ 0¾€ÓøvŽ$@€ @€ @€ @€ @ 1¦R„ @€ @€ @€ @€ñĘƷs$ @€ @€ @€ @€¥ˆ1•Â8ÎIV­Zµ}ûöqŽt n¨¥•­ÇÚµk×­[‡‡$°sçÎ5kÖÄG#>#ëׯÇB`ùÒ÷áø5¾ÏÍÍ-ß…œ™@.ÿ×?ý °zõj8FÄ·¦T* FLF þƒ˜ÿ e2Wt•:ÄŒŠ?Ås?Õa]ÜÃ0¨X/7 'dâ§MÅ“ ô|C‹¿jðã÷¬•‡OĬ­øŒÌ7¾•õÔ¶ïoÓ¸ô±ˆóóóùû §¸ˆñ#M€¤¿7+*MãB»g=©¶ãߺã/aüÑF…4O@Œ©š5¬‰pª†¾‰W]±bÅ–Ö#~‹º’djâ"›Ó D†)>ñWùGC’i°d(¶øÞ›Š-ýùaɇz#1òªK?ø“꘎3sXüuFü¥Fª33Ë^ÍDwïÞß ¢äR±ùÏb5ËPÑUÓÿZ“_<ž¿¬è¦\–ÀP¨Øø6h @ÈÄ7s8¿¡õÿ«?¨Yð‰˜…UžÁ9Æ £¶‹ÙŽøÒ_jM]%ô¬šŸpòŒÈÿö,>uëë† H¦ôw/ñGï¨öøG1\š$ ÆTÍjÆ7—”8©æò®Ú,â¤ýMq³ÖÖlƈ¿X,þ«I|ËéÆ?# ŒHqÒü-¥êe=U7+ºÄT øqª—oºn>~âêù¡+~*‹lÓtÍÂÝŽ' Æ4ž›£ªð|#äŘzpò¥â?jú0Uõ™­öºbLÕú»ú2 ¤Ï¿­Å_Ÿ¦ÆÏËt9§]&ø‹˜ÿ)ÌO8Å¿¡-¦ôâÿôÍ|™ŠÐi+èù¸Ï~%«à¢Ë* Æ´¬¼ƒOÿ±L? ÆÏçT°»dO7&½1·Â&4Ž€àGÍ1ã ôÔ›¸À¸ŽÛžnL"{`7“oíéÆ4“&=!q6!èZ^&V?í±›éy-ïÔMÈ|¿QbL=8éÛšƒ³ü½Ã¿|Ïòê7xîé¶ÏË;ýs•ÓÔ­x¬`ü¥PZM?áäË70´äÇ¿©+o7õçêf-¯ÙŒ)Ðÿg ¿1)¶žSÏž†K8·ØcaÍ=&›ít‰›íõŸèìóÿ 8ýÅqú»c-y&ºÕ]¬g­}ç©n)\yIþk“SNú_ãÅÔ¶$þòmIEæM ð×­ ZLSYHÿ)Œ¿2oqñý-þ߃Éd5È¿A¥ ¾ý„“¯Wÿ·níjj^ÌnoüeËqyó4 ˆ1MzÕâ‡ÂH/åWÍÿ<éûp½ +¶mÐM…À ô|w?‡¿÷îñé@`¤@1P’:¸ú{m%³ÜbLË-ܰó 4lAë<´Eq§K³Vçõ*÷ÞĘÊõt¶åð|ýÂñçô¿qûgìœâRA䯖ûãYÃó‹1ÕpQÜÒÞ äÿ)L=5ãï²|ÿß{ÕÉŸ¡ø *ug‰uœümÔðŠ=›\û‚®‘[ÚÙ²7zŽ 1¦I/Sü‡³ØDïœI/@¯WÜ"$žk9ÓÄE6§qRÓ»”gŠél 3¢c–&г½—ïÃKcó®½è©:ÿ”²Wš3p°Ó ,r¦ÿ¾›vÞIOÒ¿ˆÔèþÜʲ ˆ1-­/‹€S?kú[ÊÔÈA#½¢OÏR|–å3Yï“ÿüå_õ^+w·ù Ó߯‘bL{ÀW›·öü_îûì³S¾8)¢çjS­n¤L?‘–©é\µcšô²ôÿáGŠI¯Aã®—6kHÆM΄ì•@D—R?ä½:‹ƒ ,&àûðbB~¿|bÕù |߯1Zã»ã4n~&T;ø‡ðh¹^9òÚ­ÍrÞP,wñ[ï<ˉíÜ%ø51¾Ç¢áôàô|C‹/ý=C ©:EÏŸ¿¦êÞÝ,¡ùwûø¶–ÿþ0uÓóŸ$+س‚á㦮ªÝðRzþ¾”C¼‡Àt ˆ1M×z¹[ @€ @€ @€ @€ cj࢚ @€ @€ @€ @€écš®õr· @€ @€ @€ @€(ðÿ×Q’úšê÷IEND®B`‚rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/CONTRIBUTING.md0000644000177700017770000000424512633765070024740 0ustar michaelmichael## Overview RabbitMQ projects use pull requests to discuss, collaborate on and accept code contributions. Pull requests is the primary place of discussing code changes. ## How to Contribute The process is fairly standard: * Fork the repository or repositories you plan on contributing to * Clone [RabbitMQ umbrella repository](https://github.com/rabbitmq/rabbitmq-public-umbrella) * `cd umbrella`, `make co` * Create a branch with a descriptive name in the relevant repositories * Make your changes, run tests, commit with a [descriptive message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), push to your fork * Submit pull requests with an explanation what has been changed and **why** * Submit a filled out and signed [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) if needed (see below) * Be patient. We will get to your pull request eventually If what you are going to work on is a substantial change, please first ask the core team of their opinion on [RabbitMQ mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). ## (Brief) Code of Conduct In one line: don't be a dick. Be respectful to the maintainers and other contributors. Open source contributors put long hours into developing projects and doing user support. Those projects and user support are available for free. We believe this deserves some respect. Be respectful to people of all races, genders, religious beliefs and political views. Regardless of how brilliant a pull request is technically, we will not tolerate disrespectful or aggressive behaviour. Contributors who violate this straightforward Code of Conduct will see their pull requests closed and locked. ## Contributor Agreement If you want to contribute a non-trivial change, please submit a signed copy of our [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) around the time you submit your pull request. This will make it much easier (in some cases, possible) for the RabbitMQ team at Pivotal to merge your contribution. ## Where to Ask Questions If something isn't clear, feel free to ask on our [mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/.srcdist_done0000644000177700017770000000000012633765070025151 0ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/license_info0000644000177700017770000000021712633765070025062 0ustar michaelmichaelWebmachine is Copyright (c) Basho Technologies and is covered by the Apache License 2.0. It was downloaded from http://webmachine.basho.com/ rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/LICENSE-Apache-Basho0000644000177700017770000002367712633765070025737 0ustar michaelmichael Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/hash.mk0000644000177700017770000000003512633765070023754 0ustar michaelmichaelUPSTREAM_SHORT_HASH:=e9359c7 rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/Makefile0000644000177700017770000000002712633765070024141 0ustar michaelmichaelinclude ../umbrella.mk rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/package.mk0000644000177700017770000000102112633765070024420 0ustar michaelmichaelAPP_NAME:=webmachine DEPS:=mochiweb-wrapper UPSTREAM_GIT:=https://github.com/rabbitmq/webmachine.git UPSTREAM_REVISION:=e9359c7092b228f671417abe68319913f1aebe46 RETAIN_ORIGINAL_VERSION:=true WRAPPER_PATCHES:=10-remove-crypto-dependency.patch ORIGINAL_APP_FILE=$(CLONE_DIR)/src/$(APP_NAME).app.src DO_NOT_GENERATE_APP_FILE=true define package_rules # This rule is run *before* the one in do_package.mk $(PLUGINS_SRC_DIST_DIR)/$(PACKAGE_DIR)/.srcdist_done:: cp $(CLONE_DIR)/LICENSE $(PACKAGE_DIR)/LICENSE-Apache-Basho endef rabbitmq-server-3.5.7/plugins-src/webmachine-wrapper/10-remove-crypto-dependency.patch0000644000177700017770000000412312633765070030670 0ustar michaelmichaeldiff --git a/src/webmachine.app.src b/src/webmachine.app.src index eb949a2..2c46c3f 100644 --- a/src/webmachine.app.src +++ b/src/webmachine.app.src @@ -7,7 +7,6 @@ {registered, []}, {applications, [kernel, stdlib, - crypto, mochiweb]}, {mod, {webmachine_app, []}}, {env, []} diff --git a/src/webmachine.erl b/src/webmachine.erl index 47f1ce2..2e5be1b 100644 --- a/src/webmachine.erl +++ b/src/webmachine.erl @@ -28,7 +28,6 @@ %% @doc Start the webmachine server. start() -> webmachine_deps:ensure(), - application:start(crypto), application:start(webmachine). %% @spec stop() -> ok diff --git a/src/webmachine_decision_core.erl b/src/webmachine_decision_core.erl index 194c48d..3379388 100644 --- a/src/webmachine_decision_core.erl +++ b/src/webmachine_decision_core.erl @@ -722,32 +722,17 @@ variances() -> end, Accept ++ AcceptEncoding ++ AcceptCharset ++ resource_call(variances). --ifndef(old_hash). md5(Bin) -> - crypto:hash(md5, Bin). + erlang:md5(Bin). md5_init() -> - crypto:hash_init(md5). + erlang:md5_init(). md5_update(Ctx, Bin) -> - crypto:hash_update(Ctx, Bin). + erlang:md5_update(Ctx, Bin). md5_final(Ctx) -> - crypto:hash_final(Ctx). --else. -md5(Bin) -> - crypto:md5(Bin). - -md5_init() -> - crypto:md5_init(). - -md5_update(Ctx, Bin) -> - crypto:md5_update(Ctx, Bin). - -md5_final(Ctx) -> - crypto:md5_final(Ctx). --endif. - + erlang:md5_final(Ctx). compute_body_md5() -> case wrcall({req_body, 52428800}) of diff --git a/src/webmachine_request.erl b/src/webmachine_request.erl index 2a5ff7a..ee459a3 100644 --- a/src/webmachine_request.erl +++ b/src/webmachine_request.erl @@ -624,7 +624,7 @@ parts_to_body(BodyList, Size, Req) when is_list(BodyList) -> {CT, _} -> CT end, - Boundary = mochihex:to_hex(crypto:rand_bytes(8)), + Boundary = mochihex:to_hex(mochiweb_util:rand_bytes(8)), HeaderList = [{"Content-Type", ["multipart/byteranges; ", "boundary=", Boundary]}], rabbitmq-server-3.5.7/plugins-src/README0000644000177700017770000000024212633765070017600 0ustar michaelmichaelThis is the released version of rabbitmq-public-umbrella. You can clone the full version with: git clone https://github.com/rabbitmq/rabbitmq-public-umbrella.git rabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/0000755000177700017770000000000012633765070022150 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/priv/0000755000177700017770000000000012633765070023130 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/priv/www/0000755000177700017770000000000012633765070023754 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/priv/www/js/0000755000177700017770000000000012633765070024370 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/priv/www/js/tracing.js0000644000177700017770000000336412633765070026363 0ustar michaelmichaeldispatcher_add(function(sammy) { sammy.get('#/traces', function() { render({'traces': '/traces', 'vhosts': '/vhosts', 'files': '/trace-files'}, 'traces', '#/traces'); }); sammy.get('#/traces/:vhost/:name', function() { var path = '/traces/' + esc(this.params['vhost']) + '/' + esc(this.params['name']); render({'trace': path}, 'trace', '#/traces'); }); sammy.put('#/traces', function() { if (this.params['max_payload_bytes'] === '') { delete this.params['max_payload_bytes']; } else { this.params['max_payload_bytes'] = parseInt(this.params['max_payload_bytes']); } if (sync_put(this, '/traces/:vhost/:name')) update(); return false; }); sammy.del('#/traces', function() { if (sync_delete(this, '/traces/:vhost/:name')) partial_update(); return false; }); sammy.del('#/trace-files', function() { if (sync_delete(this, '/trace-files/:name')) partial_update(); return false; }); }); NAVIGATION['Admin'][0]['Tracing'] = ['#/traces', 'administrator']; HELP['tracing-max-payload'] = 'Maximum size of payload to log, in bytes. Payloads larger than this limit will be truncated. Leave blank to prevent truncation. Set to 0 to prevent logging of payload altogether.'; function link_trace(name) { return _link_to(name, 'api/trace-files/' + esc(name)); } function link_trace_queue(trace) { return _link_to('(queue)', '#/queues/' + esc(trace.vhost) + '/' + esc(trace.queue.name)); } rabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/priv/www/js/tmpl/0000755000177700017770000000000012633765070025344 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/priv/www/js/tmpl/traces.ejs0000644000177700017770000001207112633765070027331 0ustar michaelmichael

    Traces

    All traces

    Currently running traces

    <% if (traces.length > 0) { %> <% if (vhosts_interesting) { %> <% } %> <% for (var i = 0; i < traces.length; i++) { var trace = traces[i]; %> > <% if (vhosts_interesting) { %> <% } %> <% if (trace.queue) { %> <% } else { %> <% } %> <% } %>
    Virtual hostName Pattern Format Payload limit Rate Queued
    <%= fmt_string(trace.vhost) %><%= fmt_string(trace.name) %> <%= fmt_string(trace.pattern) %> <%= fmt_string(trace.format) %> <%= fmt_string(trace.max_payload_bytes, 'Unlimited') %> <%= fmt_detail_rate(trace.queue.message_stats, 'deliver_no_ack') %> <%= trace.queue.messages %> <%= link_trace_queue(trace) %>
    FAILED
    <% } else { %>

    ... no traces running ...

    <% } %>

    Trace log files

    <% if (files.length > 0) { %> <% for (var i = 0; i < files.length; i++) { var file = files[i]; %> > <% } %>
    Name Size
    <%= link_trace(file.name) %> <%= fmt_bytes(file.size) %>
    <% } else { %>

    ... no files ...

    <% } %>

    Add a new trace

    <% if (vhosts_interesting) { %> <% } else { %> <% } %>
    *
    Examples: #, publish.#, deliver.# #.amq.direct, #.myqueue
    rabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/src/0000755000177700017770000000000012633765070022737 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/src/rabbit_tracing_wm_file.erl0000644000177700017770000000345612633765070030127 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. -module(rabbit_tracing_wm_file). -export([init/1, resource_exists/2, serve/2, content_types_provided/2, is_authorized/2, allowed_methods/2, delete_resource/2]). -include_lib("rabbitmq_management/include/rabbit_mgmt.hrl"). -include_lib("webmachine/include/webmachine.hrl"). %%-------------------------------------------------------------------- init(_Config) -> {ok, #context{}}. content_types_provided(ReqData, Context) -> {[{"text/plain", serve}], ReqData, Context}. allowed_methods(ReqData, Context) -> {['HEAD', 'GET', 'DELETE'], ReqData, Context}. resource_exists(ReqData, Context) -> Name = rabbit_mgmt_util:id(name, ReqData), {rabbit_tracing_files:exists(Name), ReqData, Context}. serve(ReqData, Context) -> Name = rabbit_mgmt_util:id(name, ReqData), {ok, Content} = file:read_file(rabbit_tracing_files:full_path(Name)), {Content, ReqData, Context}. delete_resource(ReqData, Context) -> Name = rabbit_mgmt_util:id(name, ReqData), ok = rabbit_tracing_files:delete(Name), {true, ReqData, Context}. is_authorized(ReqData, Context) -> rabbit_mgmt_util:is_authorized_admin(ReqData, Context). rabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/src/rabbit_tracing_app.erl0000644000177700017770000000150612633765070027257 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_tracing_app). -behaviour(application). -export([start/2, stop/1]). start(_Type, _StartArgs) -> rabbit_tracing_sup:start_link(). stop(_State) -> ok. rabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/src/rabbit_tracing_wm_files.erl0000644000177700017770000000254212633765070030305 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_tracing_wm_files). -export([init/1, to_json/2, content_types_provided/2, is_authorized/2]). -include_lib("rabbitmq_management/include/rabbit_mgmt.hrl"). -include_lib("webmachine/include/webmachine.hrl"). %%-------------------------------------------------------------------- init(_Config) -> {ok, #context{}}. content_types_provided(ReqData, Context) -> {[{"application/json", to_json}], ReqData, Context}. to_json(ReqData, Context) -> rabbit_mgmt_util:reply(rabbit_tracing_files:list(), ReqData, Context). is_authorized(ReqData, Context) -> rabbit_mgmt_util:is_authorized_admin(ReqData, Context). %%-------------------------------------------------------------------- rabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/src/rabbit_tracing_consumer_sup.erl0000644000177700017770000000222712633765070031222 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ Federation. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_tracing_consumer_sup). -behaviour(supervisor). -include_lib("rabbit_common/include/rabbit.hrl"). -export([start_link/1]). -export([init/1]). start_link(Args) -> supervisor2:start_link(?MODULE, Args). %%---------------------------------------------------------------------------- init(Args) -> {ok, {{one_for_one, 3, 10}, [{consumer, {rabbit_tracing_consumer, start_link, [Args]}, transient, ?MAX_WAIT, worker, [rabbit_tracing_consumer]}]}}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/src/rabbitmq_tracing.app.src0000644000177700017770000000045312633765070027541 0ustar michaelmichael{application, rabbitmq_tracing, [{description, "RabbitMQ message logging / tracing"}, {vsn, "%%VSN%%"}, {modules, []}, {registered, []}, {mod, {rabbit_tracing_app, []}}, {env, [{directory, "/var/tmp/rabbitmq-tracing"}]}, {applications, [kernel, stdlib, rabbit, rabbitmq_management]}]}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/src/rabbit_tracing_files.erl0000644000177700017770000000325212633765070027601 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_tracing_files). -include_lib("kernel/include/file.hrl"). -export([list/0, exists/1, delete/1, full_path/1]). %%-------------------------------------------------------------------- list() -> {ok, Dir} = application:get_env(rabbitmq_tracing, directory), ok = filelib:ensure_dir(Dir ++ "/a"), {ok, Names} = file:list_dir(Dir), [file_info(Name) || Name <- Names]. exists(Name) -> filelib:is_regular(full_path(Name)). delete(Name) -> ok = file:delete(full_path(Name)). full_path(Name0) when is_binary(Name0) -> full_path(binary_to_list(Name0)); full_path(Name0) -> {ok, Dir} = application:get_env(rabbitmq_tracing, directory), case mochiweb_util:safe_relative_path(Name0) of undefined -> exit(how_rude); Name -> Dir ++ "/" ++ Name end. %%-------------------------------------------------------------------- file_info(Name) -> {ok, Info} = file:read_file_info(full_path(Name)), [{name, list_to_binary(Name)}, {size, Info#file_info.size}]. rabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/src/rabbit_tracing_sup.erl0000644000177700017770000000317412633765070027311 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_tracing_sup). -behaviour(supervisor). -include_lib("rabbit_common/include/rabbit.hrl"). -define(SUPERVISOR, ?MODULE). -export([start_link/0, start_child/2, stop_child/1]). -export([init/1]). %%---------------------------------------------------------------------------- start_link() -> supervisor:start_link({local, ?SUPERVISOR}, ?MODULE, []). start_child(Id, Args) -> supervisor:start_child( ?SUPERVISOR, {Id, {rabbit_tracing_consumer_sup, start_link, [Args]}, temporary, ?MAX_WAIT, supervisor, [rabbit_tracing_consumer_sup]}). stop_child(Id) -> supervisor:terminate_child(?SUPERVISOR, Id), supervisor:delete_child(?SUPERVISOR, Id), ok. %%---------------------------------------------------------------------------- init([]) -> {ok, {{one_for_one, 3, 10}, [{traces, {rabbit_tracing_traces, start_link, []}, transient, ?MAX_WAIT, worker, [rabbit_tracing_traces]}]}}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/src/rabbit_tracing_consumer.erl0000644000177700017770000002171312633765070030334 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ Federation. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_tracing_consumer). -behaviour(gen_server). -include_lib("amqp_client/include/amqp_client.hrl"). -import(rabbit_misc, [pget/2, pget/3, table_lookup/2]). -record(state, {conn, ch, vhost, queue, file, filename, format, buf, buf_cnt, max_payload}). -record(log_record, {timestamp, type, exchange, queue, node, connection, vhost, username, channel, routing_keys, routed_queues, properties, payload}). -define(X, <<"amq.rabbitmq.trace">>). -define(MAX_BUF, 100). -export([start_link/1, info_all/1]). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). start_link(Args) -> gen_server:start_link(?MODULE, Args, []). info_all(Pid) -> gen_server:call(Pid, info_all, infinity). %%---------------------------------------------------------------------------- init(Args) -> process_flag(trap_exit, true), Name = pget(name, Args), VHost = pget(vhost, Args), MaxPayload = pget(max_payload_bytes, Args, unlimited), {ok, Conn} = amqp_connection:start( #amqp_params_direct{virtual_host = VHost}), link(Conn), {ok, Ch} = amqp_connection:open_channel(Conn), link(Ch), #'queue.declare_ok'{queue = Q} = amqp_channel:call(Ch, #'queue.declare'{durable = false, exclusive = true}), #'queue.bind_ok'{} = amqp_channel:call( Ch, #'queue.bind'{exchange = ?X, queue = Q, routing_key = pget(pattern, Args)}), amqp_channel:enable_delivery_flow_control(Ch), #'basic.consume_ok'{} = amqp_channel:subscribe(Ch, #'basic.consume'{queue = Q, no_ack = true}, self()), {ok, Dir} = application:get_env(directory), Filename = Dir ++ "/" ++ binary_to_list(Name) ++ ".log", case filelib:ensure_dir(Filename) of ok -> case prim_file:open(Filename, [append]) of {ok, F} -> rabbit_tracing_traces:announce(VHost, Name, self()), Format = list_to_atom(binary_to_list(pget(format, Args))), rabbit_log:info("Tracer opened log file ~p with " "format ~p~n", [Filename, Format]), {ok, #state{conn = Conn, ch = Ch, vhost = VHost, queue = Q, file = F, filename = Filename, format = Format, buf = [], buf_cnt = 0, max_payload = MaxPayload}}; {error, E} -> {stop, {could_not_open, Filename, E}} end; {error, E} -> {stop, {could_not_create_dir, Dir, E}} end. handle_call(info_all, _From, State = #state{vhost = V, queue = Q}) -> [QInfo] = rabbit_mgmt_db:augment_queues( [rabbit_mgmt_wm_queue:queue(V, Q)], rabbit_mgmt_util:no_range(), basic), {reply, [{queue, rabbit_mgmt_format:strip_pids(QInfo)}], State}; handle_call(_Req, _From, State) -> {reply, unknown_request, State}. handle_cast(_C, State) -> {noreply, State}. handle_info({BasicDeliver, Msg, DeliveryCtx}, State = #state{format = Format}) -> amqp_channel:notify_received(DeliveryCtx), {noreply, log(Format, delivery_to_log_record({BasicDeliver, Msg}, State), State), 0}; handle_info(timeout, State) -> {noreply, flush(State)}; handle_info(_I, State) -> {noreply, State}. terminate(shutdown, State = #state{conn = Conn, ch = Ch, file = F, filename = Filename}) -> flush(State), catch amqp_channel:close(Ch), catch amqp_connection:close(Conn), catch prim_file:close(F), rabbit_log:info("Tracer closed log file ~p~n", [Filename]), ok; terminate(_Reason, _State) -> ok. code_change(_, State, _) -> {ok, State}. %%---------------------------------------------------------------------------- delivery_to_log_record({#'basic.deliver'{routing_key = Key}, #amqp_msg{props = #'P_basic'{headers = H}, payload = Payload}}, State) -> {Type, Q, RQs} = case Key of <<"publish.", _Rest/binary>> -> {array, Qs} = table_lookup(H, <<"routed_queues">>), {published, none, [Q || {_, Q} <- Qs]}; <<"deliver.", Rest/binary>> -> {received, Rest, none} end, {longstr, Node} = table_lookup(H, <<"node">>), {longstr, X} = table_lookup(H, <<"exchange_name">>), {array, Keys} = table_lookup(H, <<"routing_keys">>), {table, Props} = table_lookup(H, <<"properties">>), {longstr, Conn} = table_lookup(H, <<"connection">>), {longstr, VHost} = table_lookup(H, <<"vhost">>), {longstr, User} = table_lookup(H, <<"user">>), {signedint, Chan} = table_lookup(H, <<"channel">>), #log_record{timestamp = rabbit_mgmt_format:now_to_str_ms(os:timestamp()), type = Type, exchange = X, queue = Q, node = Node, connection = Conn, vhost = VHost, username = User, channel = Chan, routing_keys = [K || {_, K} <- Keys], routed_queues= RQs, properties = Props, payload = truncate(Payload, State)}. log(text, Record, State) -> Fmt = "~n========================================" "========================================~n~s: Message ~s~n~n" "Node: ~s~nConnection: ~s~n" "Virtual host: ~s~nUser: ~s~n" "Channel: ~p~nExchange: ~s~n" "Routing keys: ~p~n" ++ case Record#log_record.queue of none -> ""; _ -> "Queue: ~s~n" end ++ case Record#log_record.routed_queues of none -> ""; _ -> "Routed queues: ~p~n" end ++ "Properties: ~p~nPayload: ~n~s~n", Args = [Record#log_record.timestamp, Record#log_record.type, Record#log_record.node, Record#log_record.connection, Record#log_record.vhost, Record#log_record.username, Record#log_record.channel, Record#log_record.exchange, Record#log_record.routing_keys] ++ case Record#log_record.queue of none -> []; Q -> [Q] end ++ case Record#log_record.routed_queues of none -> []; RQs -> [RQs] end ++ [Record#log_record.properties, Record#log_record.payload], print_log(io_lib:format(Fmt, Args), State); log(json, Record, State) -> print_log(mochijson2:encode( [{timestamp, Record#log_record.timestamp}, {type, Record#log_record.type}, {node, Record#log_record.node}, {connection, Record#log_record.connection}, {vhost, Record#log_record.vhost}, {user, Record#log_record.username}, {channel, Record#log_record.channel}, {exchange, Record#log_record.exchange}, {queue, Record#log_record.queue}, {routed_queues, Record#log_record.routed_queues}, {routing_keys, Record#log_record.routing_keys}, {properties, rabbit_mgmt_format:amqp_table( Record#log_record.properties)}, {payload, base64:encode(Record#log_record.payload)}]) ++ "\n", State). print_log(LogMsg, State = #state{buf = Buf, buf_cnt = BufCnt}) -> maybe_flush(State#state{buf = [LogMsg | Buf], buf_cnt = BufCnt + 1}). maybe_flush(State = #state{buf_cnt = ?MAX_BUF}) -> flush(State); maybe_flush(State) -> State. flush(State = #state{file = F, buf = Buf}) -> prim_file:write(F, lists:reverse(Buf)), State#state{buf = [], buf_cnt = 0}. truncate(Payload, #state{max_payload = Max}) -> case Max =:= unlimited orelse size(Payload) =< Max of true -> Payload; false -> <> = Payload, Trunc end. rabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/src/rabbit_tracing_traces.erl0000644000177700017770000000733712633765070027770 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_tracing_traces). -behaviour(gen_server). -import(rabbit_misc, [pget/2]). -export([list/0, lookup/2, create/3, stop/2, announce/3]). -export([start_link/0]). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -define(SERVER, ?MODULE). -record(state, { table }). %%-------------------------------------------------------------------- start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). list() -> gen_server:call(?MODULE, list, infinity). lookup(VHost, Name) -> gen_server:call(?MODULE, {lookup, VHost, Name}, infinity). create(VHost, Name, Trace) -> gen_server:call(?MODULE, {create, VHost, Name, Trace}, infinity). stop(VHost, Name) -> gen_server:call(?MODULE, {stop, VHost, Name}, infinity). announce(VHost, Name, Pid) -> gen_server:cast(?MODULE, {announce, {VHost, Name}, Pid}). %%-------------------------------------------------------------------- init([]) -> {ok, #state{table = ets:new(anon, [private])}}. handle_call(list, _From, State = #state{table = Table}) -> {reply, [augment(Trace) || {_K, Trace} <- ets:tab2list(Table)], State}; handle_call({lookup, VHost, Name}, _From, State = #state{table = Table}) -> {reply, case ets:lookup(Table, {VHost, Name}) of [] -> not_found; [{_K, Trace}] -> augment(Trace) end, State}; handle_call({create, VHost, Name, Trace0}, _From, State = #state{table = Table}) -> Already = vhost_tracing(VHost, Table), Trace = pset(vhost, VHost, pset(name, Name, Trace0)), true = ets:insert(Table, {{VHost, Name}, Trace}), case Already of true -> ok; false -> rabbit_trace:start(VHost) end, {reply, rabbit_tracing_sup:start_child({VHost, Name}, Trace), State}; handle_call({stop, VHost, Name}, _From, State = #state{table = Table}) -> true = ets:delete(Table, {VHost, Name}), case vhost_tracing(VHost, Table) of true -> ok; false -> rabbit_trace:stop(VHost) end, rabbit_tracing_sup:stop_child({VHost, Name}), {reply, ok, State}; handle_call(_Req, _From, State) -> {reply, unknown_request, State}. handle_cast({announce, Key, Pid}, State = #state{table = Table}) -> case ets:lookup(Table, Key) of [] -> ok; [{_, Trace}] -> ets:insert(Table, {Key, pset(pid, Pid, Trace)}) end, {noreply, State}; handle_cast(_C, State) -> {noreply, State}. handle_info(_I, State) -> {noreply, State}. terminate(_, _) -> ok. code_change(_, State, _) -> {ok, State}. %%-------------------------------------------------------------------- pset(Key, Value, List) -> [{Key, Value} | proplists:delete(Key, List)]. vhost_tracing(VHost, Table) -> case [true || {{V, _}, _} <- ets:tab2list(Table), V =:= VHost] of [] -> false; _ -> true end. augment(Trace) -> Pid = pget(pid, Trace), Trace1 = lists:keydelete(pid, 1, Trace), case Pid of undefined -> Trace1; _ -> rabbit_tracing_consumer:info_all(Pid) ++ Trace1 end. rabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/src/rabbit_tracing_wm_traces.erl0000644000177700017770000000254412633765070030466 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_tracing_wm_traces). -export([init/1, to_json/2, content_types_provided/2, is_authorized/2]). -include_lib("rabbitmq_management/include/rabbit_mgmt.hrl"). -include_lib("webmachine/include/webmachine.hrl"). %%-------------------------------------------------------------------- init(_Config) -> {ok, #context{}}. content_types_provided(ReqData, Context) -> {[{"application/json", to_json}], ReqData, Context}. to_json(ReqData, Context) -> rabbit_mgmt_util:reply(rabbit_tracing_traces:list(), ReqData, Context). is_authorized(ReqData, Context) -> rabbit_mgmt_util:is_authorized_admin(ReqData, Context). %%-------------------------------------------------------------------- rabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/src/rabbit_tracing_mgmt.erl0000644000177700017770000000226012633765070027441 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_tracing_mgmt). -behaviour(rabbit_mgmt_extension). -export([dispatcher/0, web_ui/0]). dispatcher() -> [{["traces"], rabbit_tracing_wm_traces, []}, {["traces", vhost], rabbit_tracing_wm_traces, []}, {["traces", vhost, name], rabbit_tracing_wm_trace, []}, {["trace-files"], rabbit_tracing_wm_files, []}, {["trace-files", name], rabbit_tracing_wm_file, []}]. web_ui() -> [{javascript, <<"tracing.js">>}]. rabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/src/rabbit_tracing_wm_trace.erl0000644000177700017770000000724112633765070030302 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. -module(rabbit_tracing_wm_trace). -export([init/1, resource_exists/2, to_json/2, content_types_provided/2, content_types_accepted/2, is_authorized/2, allowed_methods/2, accept_content/2, delete_resource/2]). -define(ERR, <<"Something went wrong trying to start the trace - check the " "logs.">>). -import(rabbit_misc, [pget/2, pget/3]). -include_lib("rabbitmq_management/include/rabbit_mgmt.hrl"). -include_lib("webmachine/include/webmachine.hrl"). %%-------------------------------------------------------------------- init(_Config) -> {ok, #context{}}. content_types_provided(ReqData, Context) -> {[{"application/json", to_json}], ReqData, Context}. content_types_accepted(ReqData, Context) -> {[{"application/json", accept_content}], ReqData, Context}. allowed_methods(ReqData, Context) -> {['HEAD', 'GET', 'PUT', 'DELETE'], ReqData, Context}. resource_exists(ReqData, Context) -> {case trace(ReqData) of not_found -> false; _ -> true end, ReqData, Context}. to_json(ReqData, Context) -> rabbit_mgmt_util:reply(trace(ReqData), ReqData, Context). accept_content(RD, Ctx) -> case rabbit_mgmt_util:vhost(RD) of not_found -> not_found; VHost -> Name = rabbit_mgmt_util:id(name, RD), rabbit_mgmt_util:with_decode( [format, pattern], RD, Ctx, fun([_, _], Trace) -> Fs = [fun val_payload_bytes/3, fun val_format/3, fun val_create/3], case lists:foldl(fun (F, ok) -> F(VHost, Name, Trace); (_F, Err) -> Err end, ok, Fs) of ok -> {true, RD, Ctx}; Err -> rabbit_mgmt_util:bad_request(Err, RD, Ctx) end end) end. delete_resource(ReqData, Context) -> VHost = rabbit_mgmt_util:vhost(ReqData), Name = rabbit_mgmt_util:id(name, ReqData), ok = rabbit_tracing_traces:stop(VHost, Name), {true, ReqData, Context}. is_authorized(ReqData, Context) -> rabbit_mgmt_util:is_authorized_admin(ReqData, Context). %%-------------------------------------------------------------------- trace(ReqData) -> case rabbit_mgmt_util:vhost(ReqData) of not_found -> not_found; VHost -> rabbit_tracing_traces:lookup( VHost, rabbit_mgmt_util:id(name, ReqData)) end. val_payload_bytes(_VHost, _Name, Trace) -> case is_integer(pget(max_payload_bytes, Trace, 0)) of false -> <<"max_payload_bytes not integer">>; true -> ok end. val_format(_VHost, _Name, Trace) -> case lists:member(pget(format, Trace), [<<"json">>, <<"text">>]) of false -> <<"format not json or text">>; true -> ok end. val_create(VHost, Name, Trace) -> case rabbit_tracing_traces:create(VHost, Name, Trace) of {ok, _} -> ok; _ -> ?ERR end. rabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/README0000644000177700017770000000262612633765070023036 0ustar michaelmichaelAn opinionated tracing plugin for RabbitMQ management. Build it like any other plugin. After installation you should see a "Tracing" tab in the management UI. Hopefully use is obvious. Configuration ============= There is one configuration option: directory: This controls where the log files go. It defaults to "/var/tmp/rabbitmq-tracing". Performance =========== On my workstation, rabbitmq-tracing can write about 2000 msg/s to a log file. You should be careful using rabbitmq-tracing if you think you're going to capture more messages than this. Of course, any messages that can't be logged are queued. The code to serve up the log files over HTTP is pretty dumb, it loads the whole log into memory. If you have large log files you may wish to transfer them off the server in some other way. HTTP API ======== GET /api/traces GET /api/traces/ GET PUT DELETE /api/traces// GET /api/trace-files GET DELETE /api/trace-files/ (GET returns the file as text/plain, not JSON describing it.) Example for how to create a trace: $ curl -i -u guest:guest -H "content-type:application/json" -XPUT \ http://localhost:55672/api/traces/%2f/my-trace \ -d'{"format":"text","pattern":"#", "max_payload_bytes":1000}' max_payload_bytes is optional (omit it to prevent payload truncation), format and pattern are mandatory.rabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/CONTRIBUTING.md0000644000177700017770000000424512633765070024406 0ustar michaelmichael## Overview RabbitMQ projects use pull requests to discuss, collaborate on and accept code contributions. Pull requests is the primary place of discussing code changes. ## How to Contribute The process is fairly standard: * Fork the repository or repositories you plan on contributing to * Clone [RabbitMQ umbrella repository](https://github.com/rabbitmq/rabbitmq-public-umbrella) * `cd umbrella`, `make co` * Create a branch with a descriptive name in the relevant repositories * Make your changes, run tests, commit with a [descriptive message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), push to your fork * Submit pull requests with an explanation what has been changed and **why** * Submit a filled out and signed [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) if needed (see below) * Be patient. We will get to your pull request eventually If what you are going to work on is a substantial change, please first ask the core team of their opinion on [RabbitMQ mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). ## (Brief) Code of Conduct In one line: don't be a dick. Be respectful to the maintainers and other contributors. Open source contributors put long hours into developing projects and doing user support. Those projects and user support are available for free. We believe this deserves some respect. Be respectful to people of all races, genders, religious beliefs and political views. Regardless of how brilliant a pull request is technically, we will not tolerate disrespectful or aggressive behaviour. Contributors who violate this straightforward Code of Conduct will see their pull requests closed and locked. ## Contributor Agreement If you want to contribute a non-trivial change, please submit a signed copy of our [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) around the time you submit your pull request. This will make it much easier (in some cases, possible) for the RabbitMQ team at Pivotal to merge your contribution. ## Where to Ask Questions If something isn't clear, feel free to ask on our [mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). rabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/test/0000755000177700017770000000000012633765070023127 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/test/src/0000755000177700017770000000000012633765070023716 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/test/src/rabbit_tracing_test.erl0000644000177700017770000001601512633765070030436 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_tracing_test). -define(LOG_DIR, "/var/tmp/rabbitmq-tracing/"). -include_lib("eunit/include/eunit.hrl"). -include_lib("amqp_client/include/amqp_client.hrl"). -include_lib("rabbitmq_management/include/rabbit_mgmt_test.hrl"). -import(rabbit_misc, [pget/2]). tracing_test() -> case filelib:is_dir(?LOG_DIR) of true -> {ok, Files} = file:list_dir(?LOG_DIR), [ok = file:delete(?LOG_DIR ++ F) || F <- Files]; _ -> ok end, [] = http_get("/traces/%2f/"), [] = http_get("/trace-files/"), Args = [{format, <<"json">>}, {pattern, <<"#">>}], http_put("/traces/%2f/test", Args, ?NO_CONTENT), assert_list([[{name, <<"test">>}, {format, <<"json">>}, {pattern, <<"#">>}]], http_get("/traces/%2f/")), assert_item([{name, <<"test">>}, {format, <<"json">>}, {pattern, <<"#">>}], http_get("/traces/%2f/test")), {ok, Conn} = amqp_connection:start(#amqp_params_network{}), {ok, Ch} = amqp_connection:open_channel(Conn), amqp_channel:cast(Ch, #'basic.publish'{ exchange = <<"amq.topic">>, routing_key = <<"key">> }, #amqp_msg{props = #'P_basic'{}, payload = <<"Hello world">>}), amqp_channel:close(Ch), amqp_connection:close(Conn), timer:sleep(100), http_delete("/traces/%2f/test", ?NO_CONTENT), [] = http_get("/traces/%2f/"), assert_list([[{name, <<"test.log">>}]], http_get("/trace-files/")), %% This is a bit cheeky as the log is actually one JSON doc per %% line and we assume here it's only one line assert_item([{type, <<"published">>}, {exchange, <<"amq.topic">>}, {routing_keys, [<<"key">>]}, {payload, base64:encode(<<"Hello world">>)}], http_get("/trace-files/test.log")), http_delete("/trace-files/test.log", ?NO_CONTENT), ok. tracing_validation_test() -> Path = "/traces/%2f/test", http_put(Path, [{pattern, <<"#">>}], ?BAD_REQUEST), http_put(Path, [{format, <<"json">>}], ?BAD_REQUEST), http_put(Path, [{format, <<"ebcdic">>}, {pattern, <<"#">>}], ?BAD_REQUEST), http_put(Path, [{format, <<"text">>}, {pattern, <<"#">>}, {max_payload_bytes, <<"abc">>}], ?BAD_REQUEST), http_put(Path, [{format, <<"json">>}, {pattern, <<"#">>}, {max_payload_bytes, 1000}], ?NO_CONTENT), http_delete(Path, ?NO_CONTENT), ok. %%--------------------------------------------------------------------------- %% Below is copypasta from rabbit_mgmt_test_http, it's not obvious how %% to share that given the build system. http_get(Path) -> http_get(Path, ?OK). http_get(Path, CodeExp) -> http_get(Path, "guest", "guest", CodeExp). http_get(Path, User, Pass, CodeExp) -> {ok, {{_HTTP, CodeAct, _}, Headers, ResBody}} = req(get, Path, [auth_header(User, Pass)]), assert_code(CodeExp, CodeAct, "GET", Path, ResBody), decode(CodeExp, Headers, ResBody). http_put(Path, List, CodeExp) -> http_put_raw(Path, format_for_upload(List), CodeExp). http_put(Path, List, User, Pass, CodeExp) -> http_put_raw(Path, format_for_upload(List), User, Pass, CodeExp). http_post(Path, List, CodeExp) -> http_post_raw(Path, format_for_upload(List), CodeExp). http_post(Path, List, User, Pass, CodeExp) -> http_post_raw(Path, format_for_upload(List), User, Pass, CodeExp). format_for_upload(List) -> iolist_to_binary(mochijson2:encode({struct, List})). http_put_raw(Path, Body, CodeExp) -> http_upload_raw(put, Path, Body, "guest", "guest", CodeExp). http_put_raw(Path, Body, User, Pass, CodeExp) -> http_upload_raw(put, Path, Body, User, Pass, CodeExp). http_post_raw(Path, Body, CodeExp) -> http_upload_raw(post, Path, Body, "guest", "guest", CodeExp). http_post_raw(Path, Body, User, Pass, CodeExp) -> http_upload_raw(post, Path, Body, User, Pass, CodeExp). http_upload_raw(Type, Path, Body, User, Pass, CodeExp) -> {ok, {{_HTTP, CodeAct, _}, Headers, ResBody}} = req(Type, Path, [auth_header(User, Pass)], Body), assert_code(CodeExp, CodeAct, Type, Path, ResBody), decode(CodeExp, Headers, ResBody). http_delete(Path, CodeExp) -> http_delete(Path, "guest", "guest", CodeExp). http_delete(Path, User, Pass, CodeExp) -> {ok, {{_HTTP, CodeAct, _}, Headers, ResBody}} = req(delete, Path, [auth_header(User, Pass)]), assert_code(CodeExp, CodeAct, "DELETE", Path, ResBody), decode(CodeExp, Headers, ResBody). assert_code(CodeExp, CodeAct, Type, Path, Body) -> case CodeExp of CodeAct -> ok; _ -> throw({expected, CodeExp, got, CodeAct, type, Type, path, Path, body, Body}) end. req(Type, Path, Headers) -> httpc:request(Type, {?PREFIX ++ Path, Headers}, ?HTTPC_OPTS, []). req(Type, Path, Headers, Body) -> httpc:request(Type, {?PREFIX ++ Path, Headers, "application/json", Body}, ?HTTPC_OPTS, []). decode(?OK, _Headers, ResBody) -> cleanup(mochijson2:decode(ResBody)); decode(_, Headers, _ResBody) -> Headers. cleanup(L) when is_list(L) -> [cleanup(I) || I <- L]; cleanup({struct, I}) -> cleanup(I); cleanup({K, V}) when is_binary(K) -> {list_to_atom(binary_to_list(K)), cleanup(V)}; cleanup(I) -> I. auth_header(Username, Password) -> {"Authorization", "Basic " ++ binary_to_list(base64:encode(Username ++ ":" ++ Password))}. %%--------------------------------------------------------------------------- assert_list(Exp, Act) -> case length(Exp) == length(Act) of true -> ok; false -> throw({expected, Exp, actual, Act}) end, [case length(lists:filter(fun(ActI) -> test_item(ExpI, ActI) end, Act)) of 1 -> ok; N -> throw({found, N, ExpI, in, Act}) end || ExpI <- Exp]. assert_item(Exp, Act) -> case test_item0(Exp, Act) of [] -> ok; Or -> throw(Or) end. test_item(Exp, Act) -> case test_item0(Exp, Act) of [] -> true; _ -> false end. test_item0(Exp, Act) -> [{did_not_find, ExpI, in, Act} || ExpI <- Exp, not lists:member(ExpI, Act)]. rabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/.srcdist_done0000644000177700017770000000000012633765070024617 0ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/Makefile0000644000177700017770000000002712633765070023607 0ustar michaelmichaelinclude ../umbrella.mk rabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/ebin/0000755000177700017770000000000012633765070023065 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-tracing/package.mk0000644000177700017770000000037412633765070024100 0ustar michaelmichaelRELEASABLE:=true DEPS:=rabbitmq-management WITH_BROKER_TEST_COMMANDS:=eunit:test(rabbit_tracing_test,[verbose]) CONSTRUCT_APP_PREREQS:=$(shell find $(PACKAGE_DIR)/priv -type f) define construct_app_commands cp -r $(PACKAGE_DIR)/priv $(APP_DIR) endef rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/0000755000177700017770000000000012633765070025021 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/priv/0000755000177700017770000000000012633765070026001 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/priv/www/0000755000177700017770000000000012633765070026625 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/priv/www/js/0000755000177700017770000000000012633765070027241 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/priv/www/js/visualiser.js0000644000177700017770000000013712633765070031766 0ustar michaelmichaeldispatcher_add(function(sammy) {}); NAVIGATION['Visualiser'] = ['visualiser/', "management"]; rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/priv/www/visualiser/0000755000177700017770000000000012633765070031013 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/priv/www/visualiser/index.html0000644000177700017770000001322412633765070033012 0ustar michaelmichael RabbitMQ Visualiser
    Vhost:
    Help

    RabbitMQ Visualiser

    Click to hide.

    The left of the canvas displays exchanges, the right displays queues, and the top displays channels. All of these items can be dragged around the canvas. They repel one another, and snap back into their predefined areas should they be released within the boundaries of those areas.

    Shift-clicking on an item hides it - it will be added to the relevant select box on the left.

    Hovering over an item shows at the top of the screen various details about the item. Double-clicking on the item will take you to the specific page in the Management Plugin concerning that item.

    When hovering over an item, incoming links and/or traffic are shown in green, whilst outgoing links and/or traffic are shown in blue. Bindings are always displayed, but the consumers of a queue, and likewise the publishers to an exchange, are only drawn in when hovering over the exchange, queue or channel in question.

    By default, up to 10 exchanges, 10 queues and 10 channels are displayed. Additional resources are available from the left hand-side select boxes, and can be brought into the display by selecting them and clicking on the relevant 'Show' button.

    The 'Display' check-boxes turn off and on entire resource classes, and resets positioning.

    Click to hide.

    rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/priv/www/visualiser/js/0000755000177700017770000000000012633765070031427 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/priv/www/visualiser/js/model.js0000644000177700017770000010666512633765070033103 0ustar michaelmichael/*global octtree, vec3, Spring */ function searchX(elem, tree, xIncr, xMax) { var found = tree.findInRadius(elem.pos, xIncr / 2, 1); while (found.length > 0 && elem.pos[octtree.x] + xIncr < xMax) { elem.pos[octtree.x] += xIncr; found = tree.findInRadius(elem.pos, xIncr / 2, 1); } return (found.length === 0); } function searchY(elem, tree, yIncr) { var found = tree.findInRadius(elem.pos, yIncr / 2, 1); while (found.length > 0) { elem.pos[octtree.y] += yIncr; found = tree.findInRadius(elem.pos, yIncr / 2, 1); } } function bezierMid(startX, startY, ctl1X, ctl1Y, ctl2X, ctl2Y, endX, endY) { var start_ctl1X, start_ctl1Y, end_ctl2X, end_ctl2Y, ctl1_ctl2X, ctl1_ctl2Y, mid1X, mid1Y, mid2X, mid2Y; start_ctl1X = (startX + ctl1X) / 2; start_ctl1Y = (startY + ctl1Y) / 2; end_ctl2X = (endX + ctl2X) / 2; end_ctl2Y = (endY + ctl2Y) / 2; ctl1_ctl2X = (ctl1X + ctl2X) / 2; ctl1_ctl2Y = (ctl1Y + ctl2Y) / 2; mid1X = (start_ctl1X + ctl1_ctl2X) / 2; mid1Y = (start_ctl1Y + ctl1_ctl2Y) / 2; mid2X = (end_ctl2X + ctl1_ctl2X) / 2; mid2Y = (end_ctl2Y + ctl1_ctl2Y) / 2; return [(mid1X + mid2X) / 2, (mid1Y + mid2Y) / 2]; } function stringifyObject(a) { var b, e; b = {}; for (e in a) { if (a.hasOwnProperty(e)) { if ("object" === typeof a[e]) { b[e] = stringifyObject(a[e]); } else { b[e] = "" + a[e]; } } } return b; } String.prototype.toTitleCase = function () { return this.replace(/(^|_)([a-z])/g, function (str, g1, g2, offset, totalStr) { return g1.replace("_", " ") + g2.toUpperCase(); }); }; var Consumer = {}; Consumer.render = function (channel, queue, ctx, consumerTag) { var yMid, xCtl, dim, mid; ctx.beginPath(); yMid = (channel.yMax + queue.pos[octtree.y]) / 2; xCtl = queue.pos[octtree.x]; ctx.moveTo(channel.pos[octtree.x], channel.yMax); ctx.bezierCurveTo(channel.pos[octtree.x], yMid, xCtl, queue.pos[octtree.y] - channel.yInit, xCtl, queue.pos[octtree.y] - queue.fontSize); ctx.moveTo(channel.pos[octtree.x], channel.yMax); ctx.closePath(); ctx.stroke(); dim = ctx.measureText(consumerTag); mid = bezierMid(channel.pos[octtree.x], channel.yMax, channel.pos[octtree.x], yMid, xCtl, queue.pos[octtree.y] - channel.yInit, xCtl, queue.pos[octtree.y] - queue.fontSize); ctx.textBaseline = "middle"; ctx.textAlign = "center"; ctx.fillStyle = "rgba(255, 255, 255, 0.67)"; ctx.fillRect(mid[0] - (dim.width / 2), mid[1] - (channel.fontSize / 2), dim.width, channel.fontSize); ctx.fillStyle = ctx.strokeStyle; ctx.fillText(consumerTag, mid[0], mid[1]); ctx.beginPath(); ctx.moveTo(channel.pos[octtree.x], channel.yMax); ctx.lineTo(channel.pos[octtree.x] - (channel.fontSize / 2), channel.yMax + channel.fontSize); ctx.lineTo(channel.pos[octtree.x] + (channel.fontSize / 2), channel.yMax + channel.fontSize); ctx.closePath(); ctx.fillStyle = ctx.strokeStyle; ctx.fill(); }; var Publisher = {}; Publisher.render = function (channel, exchange, ctx) { var yMid, xCtl; ctx.beginPath(); yMid = (channel.yMax + exchange.pos[octtree.y]) / 2; xCtl = exchange.pos[octtree.x]; ctx.moveTo(channel.pos[octtree.x], channel.yMax); ctx.bezierCurveTo(channel.pos[octtree.x], yMid, xCtl, exchange.pos[octtree.y] - channel.yInit, xCtl, exchange.pos[octtree.y] - exchange.fontSize); ctx.moveTo(channel.pos[octtree.x], channel.yMax); ctx.closePath(); ctx.stroke(); ctx.beginPath(); ctx.moveTo(exchange.pos[octtree.x], exchange.pos[octtree.y] - exchange.fontSize); ctx.lineTo(exchange.pos[octtree.x] - exchange.fontSize / 2, exchange.pos[octtree.y] - 2 * exchange.fontSize); ctx.lineTo(exchange.pos[octtree.x] + exchange.fontSize / 2, exchange.pos[octtree.y] - 2 * exchange.fontSize); ctx.closePath(); ctx.fillStyle = ctx.strokeStyle; ctx.fill(); }; function Channel(tree, elem, model) { this.name = elem.name; this.pos = vec3.create(); this.findNewPosition(model, tree); this.next_pos = vec3.create(this.pos); this.mass = 0.1; this.velocity = vec3.create(); this.ideal = { pos : vec3.create() }; this.disabled = false; this.update(elem); tree.add(this); } Channel.prototype = { yInit : 100, yIncr : 50, xInit : 100, xIncr : 50, xMax : 200, yBoundary : 200, attributes : [ 'acks_uncommitted', 'client_flow_blocked', 'confirm', 'connection_details', 'consumer_count', 'message_stats', 'messages_unacknowledged', 'messages_unconfirmed', 'node', 'number', 'prefetch_count', 'transactional', 'user', 'vhost' ], pos : vec3.create(), fontSize : 12, spring : new Spring(), details : undefined, object_type : 'channel', detail_attributes : [ 'name', 'user', 'transactional', 'confirm', 'node', 'vhost', 'prefetch_count', 'messages_unacknowledged', 'messages_unconfirmed', 'consumer_count', 'client_flow_blocked' ] }; Channel.prototype.spring.octtreeLimit = 10; Channel.prototype.spring.octtreeRadius = 500; Channel.prototype.spring.equilibriumLength = 0; Channel.prototype.spring.dampingFactor = 0.1; Channel.prototype.spring.pull = true; Channel.prototype.spring.push = false; Channel.prototype.findNewPosition = function (model, tree) { this.pos[octtree.x] = this.xInit; this.pos[octtree.y] = this.yInit; this.pos[octtree.z] = 0; while (! searchX(this, tree, this.xIncr, this.xMax)) { this.pos[octtree.y] += this.yIncr; this.pos[octtree.x] = this.xInit + (this.pos[octtree.y] / 10); } this.yMin = this.pos[octtree.y]; this.yMax = this.pos[octtree.y]; }; Channel.prototype.canvasResized = function (canvas) { Channel.prototype.xMax = canvas.width; }; Channel.prototype.update = function (elem) { var attr, i; for (i = 0; i < this.attributes.length; i += 1) { attr = this.attributes[i]; this[attr] = elem[attr]; } }; Channel.prototype.remove = function (tree, model) { tree.del(this); }; Channel.prototype.render = function (model, ctx) { var i, dim, consumer, queue, publisher, exchange; if (this.disabled) { return; } dim = ctx.measureText(this.name); if (model.cull(this.pos[octtree.x] - this.fontSize, this.pos[octtree.y] - (dim.width / 2) - this.fontSize, this.fontSize * 2, dim.width + (this.fontSize * 2))) { return; } this.yMax = this.pos[octtree.y] + (dim.width / 2) + this.fontSize; this.yMin = this.pos[octtree.y] - (dim.width / 2) - this.fontSize; ctx.beginPath(); ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.lineWidth = 2.0; ctx.strokeStyle = "black"; ctx.moveTo(this.pos[octtree.x] - this.fontSize, this.yMin); ctx.lineTo(this.pos[octtree.x] + this.fontSize, this.yMin); ctx.lineTo(this.pos[octtree.x] + this.fontSize, this.yMax); ctx.lineTo(this.pos[octtree.x] - this.fontSize, this.yMax); ctx.closePath(); this.preStroke(model, ctx); ctx.save(); ctx.translate(this.pos[octtree.x], this.pos[octtree.y]); ctx.rotate(3 * Math.PI / 2); ctx.fillStyle = ctx.strokeStyle; ctx.fillText(this.name, 0, 0); ctx.restore(); if (undefined !== this.details) { model.resetHighlighted(); ctx.lineWidth = 2.0; if (undefined !== this.details.consumer_details) { ctx.strokeStyle = "#00a000"; for (i = 0; i < this.details.consumer_details.length; i += 1) { consumer = this.details.consumer_details[i]; queue = consumer.queue_details.name; if (undefined !== model.queue[queue] && ! model.queue[queue].disabled) { model.setHighlighted(model.queue[queue]); Consumer.render(this, model.queue[queue], ctx, consumer.consumer_tag); } } } if (undefined !== this.details.publishes) { ctx.strokeStyle = "#0000a0"; for (i = 0; i < this.details.publishes.length; i += 1) { publisher = this.details.publishes[i]; exchange = publisher.exchange.name; if (undefined !== model.exchange[exchange] && ! model.exchange[exchange].disabled) { model.setHighlighted(model.exchange[exchange]); Publisher.render(this, model.exchange[exchange], ctx); } } } } }; Channel.prototype.preStroke = function (model, ctx) { }; Channel.prototype.animate = function (elapsed) { if (this.yBoundary > this.pos[octtree.y]) { this.ideal.pos[octtree.x] = this.pos[octtree.x]; this.ideal.pos[octtree.y] = this.yInit; this.spring.apply(elapsed, this, this.ideal); } }; Channel.prototype.disable = function (model) { model.channels_visible -= 1; }; Channel.prototype.enable = function (model, tree) { model.channels_visible += 1; this.findNewPosition(model, tree); }; Channel.prototype.getDetails = function () { }; Channel.prototype.stringAttributes = function () { var obj, i, attName, attNameTitle; obj = { Channel : '', attributeOrder : ['Channel'] }; for (i in this.detail_attributes) { attName = this.detail_attributes[i]; attNameTitle = attName.toTitleCase(); obj.attributeOrder.push(attNameTitle); if ("object" === typeof this[attName]) { obj[attNameTitle] = stringifyObject(this[attName]); } else { obj[attNameTitle] = "" + this[attName]; } } if (undefined !== this.message_stats) { if (undefined !== this.message_stats.publish_details) { obj.attributeOrder.push('Publish Rate (msgs/sec)'); obj['Publish Rate (msgs/sec)'] = "" + Math.round(this.message_stats.publish_details.rate); } if (undefined !== this.message_stats.deliver_get_details) { obj.attributeOrder.push('Delivery and Get Rate (msgs/sec)'); obj['Delivery and Get Rate (msgs/sec)'] = "" + Math.round(this.message_stats.deliver_get_details.rate); } if (undefined !== this.message_stats.ack_details) { obj.attributeOrder.push('Delivery Acknowledgement Rate (acks/sec)'); obj['Delivery Acknowledgement Rate (acks/sec)'] = "" + Math.round(this.message_stats.ack_details.rate); } } return obj; }; Channel.prototype.url = function () { return "/channels/" + encodeURIComponent(this.name); }; Channel.prototype.navigateTo = function () { document.location = "../#" + this.url(); }; function Exchange(tree, elem, model) { this.name = elem.name; this.pos = vec3.create(); this.findNewPosition(model, tree); this.next_pos = vec3.create(this.pos); this.mass = 0.1; this.velocity = vec3.create(); this.ideal = { pos : vec3.create() }; this.disabled = false; this.bindings_outbound = { exchange : {}, queue : {} }; this.bindings_inbound = {}; this.update(elem); tree.add(this); } Exchange.prototype = { yInit : 250, yIncr : 50, xInit : 100, xBoundary : 200, attributes : [ 'arguments', 'auto_delete', 'durable', 'internal', 'type', 'message_stats_out', 'message_stats_in', 'vhost' ], pos : vec3.create(), fontSize : 12, spring : new Spring(), details : undefined, object_type : 'exchange', detail_attributes : [ 'name', 'type', 'durable', 'auto_delete', 'internal', 'arguments', 'vhost' ] }; Exchange.prototype.spring.octtreeLimit = 10; Exchange.prototype.spring.octtreeRadius = 500; Exchange.prototype.spring.equilibriumLength = 0; Exchange.prototype.spring.dampingFactor = 0.1; Exchange.prototype.spring.pull = true; Exchange.prototype.spring.push = false; Exchange.prototype.findNewPosition = function (model, tree) { this.pos[octtree.x] = this.xInit; this.pos[octtree.y] = this.yInit; this.pos[octtree.z] = 0; searchY(this, tree, this.yIncr); this.xMin = this.pos[octtree.x]; this.xMax = this.pos[octtree.x]; }; Exchange.prototype.canvasResized = function (canvas) { Exchange.prototype.xInit = canvas.width / 6; Exchange.prototype.xBoundary = 2 * canvas.width / 6; }; Exchange.prototype.update = function (elem) { var attr, i; for (i = 0; i < this.attributes.length; i += 1) { attr = this.attributes[i]; this[attr] = elem[attr]; } }; Exchange.prototype.remove = function (tree, model) { tree.del(this); }; Exchange.prototype.render = function (model, ctx) { var i, dim, channel; if (this.disabled) { return; } for (i in this.bindings_outbound.exchange) { this.bindings_outbound.exchange[i].render(model, ctx); } if (model.rendering.queue.enabled) { for (i in this.bindings_outbound.queue) { this.bindings_outbound.queue[i].render(model, ctx); } } dim = ctx.measureText(this.name); if (model.cull(this.pos[octtree.x] - (dim.width / 2) - this.fontSize, this.pos[octtree.y] - this.fontSize, dim.width + (2 * this.fontSize), 2 * this.fontSize)) { return; } ctx.beginPath(); ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.lineWidth = 2.0; ctx.strokeStyle = "black"; ctx.arc(this.pos[octtree.x] - (dim.width / 2), this.pos[octtree.y], this.fontSize, Math.PI / 2, 3 * Math.PI / 2, false); ctx.lineTo(this.pos[octtree.x] + (dim.width / 2), this.pos[octtree.y] - this.fontSize); ctx.arc(this.pos[octtree.x] + (dim.width / 2), this.pos[octtree.y], this.fontSize, 3 * Math.PI / 2, Math.PI / 2, false); ctx.closePath(); this.preStroke(model, ctx); ctx.fillStyle = ctx.strokeStyle; ctx.fillText(this.name, this.pos[octtree.x], this.pos[octtree.y]); this.xMin = this.pos[octtree.x] - (dim.width / 2) - this.fontSize; this.xMax = this.pos[octtree.x] + (dim.width / 2) + this.fontSize; if (undefined !== this.details) { model.resetHighlighted(); ctx.lineWidth = 2.0; ctx.strokeStyle = "#00a000"; if (undefined !== this.details.incoming) { for (i = 0; i < this.details.incoming.length; i += 1) { channel = this.details.incoming[i].channel_details.name; if (undefined !== model.channel[channel] && ! model.channel[channel].disabled) { model.setHighlighted(model.channel[channel]); Publisher.render(model.channel[channel], this, ctx); } } } for (i in this.bindings_outbound.queue) { model.setHighlighted(model.queue[this.bindings_outbound.queue[i].destination]); } for (i in this.bindings_outbound.exchange) { model.setHighlighted(model.exchange[this.bindings_outbound.exchange[i].destination]); } for (i in this.bindings_inbound) { model.setHighlighted(model.exchange[this.bindings_inbound[i].source]); } } }; Exchange.prototype.preStroke = function (model, ctx) { }; Exchange.prototype.animate = function (elapsed) { if (this.xBoundary > this.pos[octtree.x]) { this.ideal.pos[octtree.x] = this.xInit; this.ideal.pos[octtree.y] = this.pos[octtree.y]; this.spring.apply(elapsed, this, this.ideal); } }; Exchange.prototype.disable = function (model) { model.exchanges_visible -= 1; }; Exchange.prototype.enable = function (model, tree) { model.exchanges_visible += 1; this.findNewPosition(model, tree); }; Exchange.prototype.getDetails = function () { }; Exchange.prototype.stringAttributes = function () { var obj, i, attName, attNameTitle; obj = { Exchange : '', attributeOrder : ['Exchange'] }; for (i in this.detail_attributes) { attName = this.detail_attributes[i]; attNameTitle = attName.toTitleCase(); obj.attributeOrder.push(attNameTitle); if ("object" === typeof this[attName]) { obj[attNameTitle] = stringifyObject(this[attName]); } else { obj[attNameTitle] = "" + this[attName]; } } obj.attributeOrder.push('Outgoing Queue Bindings'); obj['Outgoing Queue Bindings'] = "" + Object.keys(this.bindings_outbound.queue).length; obj.attributeOrder.push('Outgoing Exchange Bindings'); obj['Outgoing Exchange Bindings'] = "" + Object.keys(this.bindings_outbound.exchange).length; obj.attributeOrder.push('Incoming Exchange Bindings'); obj['Incoming Exchange Bindings'] = "" + Object.keys(this.bindings_inbound).length; if (undefined !== this.message_stats_in && undefined !== this.message_stats_in.publish_details) { obj.attributeOrder.push('Message Incoming Rate (msgs/sec)'); obj['Message Incoming Rate (msgs/sec)'] = "" + Math.round(this.message_stats_in.publish_details.rate); } if (undefined !== this.message_stats_out && undefined !== this.message_stats_out.publish_details) { obj.attributeOrder.push('Message Outgoing Rate (msgs/sec)'); obj['Message Outgoing Rate (msgs/sec)'] = "" + Math.round(this.message_stats_out.publish_details.rate); } return obj; }; Exchange.prototype.url = function () { var name; if (this.name === "") { name = "amq.default"; } else { name = this.name; } return "/exchanges/" + encodeURIComponent(this.vhost) + "/" + encodeURIComponent(name); }; Exchange.prototype.navigateTo = function () { document.location = "../#" + this.url(); }; function Queue(tree, elem, model) { this.name = elem.name; this.pos = vec3.create(); this.findNewPosition(model, tree); this.next_pos = vec3.create(this.pos); this.mass = 0.1; this.velocity = vec3.create(); this.ideal = { pos : vec3.create() }; this.disabled = false; this.bindings_inbound = {}; this.update(elem); tree.add(this); } Queue.prototype = { yInit : 250, yIncr : 50, xInit : 400, xBoundary : 300, attributes : [ 'arguments', 'auto_delete', 'durable', 'messages', 'messages_ready', 'messages_unacknowledged', 'message_stats', 'node', 'owner_pid_details', 'vhost', 'memory', 'consumers' ], pos : vec3.create(), fontSize : 12, spring : new Spring(), details : undefined, object_type : 'queue', detail_attributes : [ 'name', 'durable', 'auto_delete', 'arguments', 'node', 'vhost', 'messages_ready', 'messages_unacknowledged', 'consumers', 'memory' ] }; Queue.prototype.spring.octtreeLimit = 10; Queue.prototype.spring.octtreeRadius = 500; Queue.prototype.spring.equilibriumLength = 0; Queue.prototype.spring.dampingFactor = 0.1; Queue.prototype.spring.pull = true; Queue.prototype.spring.push = false; Queue.prototype.findNewPosition = function (model, tree) { this.pos[octtree.x] = this.xInit; this.pos[octtree.y] = this.yInit; this.pos[octtree.z] = 0; searchY(this, tree, this.yIncr); this.xMin = this.pos[octtree.x]; this.xMax = this.pos[octtree.x]; }; Queue.prototype.canvasResized = function (canvas) { Queue.prototype.xInit = 5 * canvas.width / 6; Queue.prototype.xBoundary = 4 * canvas.width / 6; }; Queue.prototype.update = function (elem) { var attr, i; for (i = 0; i < this.attributes.length; i += 1) { attr = this.attributes[i]; this[attr] = elem[attr]; } }; Queue.prototype.remove = function (tree, model) { tree.del(this); }; Queue.prototype.render = function (model, ctx) { var text, dim, i, channel; if (this.disabled) { return; } text = this.name + " (" + this.messages_ready + ", " + this.messages_unacknowledged + ")"; dim = ctx.measureText(text); if (model.cull(this.pos[octtree.x] - (dim.width / 2) - this.fontSize, this.pos[octtree.y] - this.fontSize, dim.width + (2 * this.fontSize), 2 * this.fontSize)) { return; } ctx.beginPath(); ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.lineWidth = 2.0; ctx.strokeStyle = "black"; ctx.moveTo(this.pos[octtree.x] - (dim.width / 2) - this.fontSize, this.pos[octtree.y] - this.fontSize); ctx.lineTo(this.pos[octtree.x] + (dim.width / 2) + this.fontSize, this.pos[octtree.y] - this.fontSize); ctx.lineTo(this.pos[octtree.x] + (dim.width / 2) + this.fontSize, this.pos[octtree.y] + this.fontSize); ctx.lineTo(this.pos[octtree.x] - (dim.width / 2) - this.fontSize, this.pos[octtree.y] + this.fontSize); ctx.closePath(); this.preStroke(model, ctx); ctx.fillStyle = ctx.strokeStyle; ctx.fillText(text, this.pos[octtree.x], this.pos[octtree.y]); this.xMin = this.pos[octtree.x] - (dim.width / 2) - this.fontSize; this.xMax = this.pos[octtree.x] + (dim.width / 2) + this.fontSize; if (undefined !== this.details && undefined !== this.details.consumer_details) { model.resetHighlighted(); ctx.lineWidth = 2.0; ctx.strokeStyle = "#0000a0"; for (i = 0; i < this.details.consumer_details.length; i += 1) { channel = this.details.consumer_details[i].channel_details.name; if (undefined !== model.channel[channel] && ! model.channel[channel].disabled) { model.setHighlighted(model.channel[channel]); Consumer.render(model.channel[channel], this, ctx, this.details.consumer_details[i].consumer_tag); } } for (i in this.bindings_inbound) { model.setHighlighted(model.exchange[this.bindings_inbound[i].source]); } } }; Queue.prototype.preStroke = function (model, ctx) { }; Queue.prototype.animate = function (elapsed) { if (this.xBoundary < this.pos[octtree.x]) { this.ideal.pos[octtree.x] = this.xInit; this.ideal.pos[octtree.y] = this.pos[octtree.y]; this.spring.apply(elapsed, this, this.ideal); } }; Queue.prototype.disable = function (model) { model.queues_visible -= 1; }; Queue.prototype.enable = function (model, tree) { model.queues_visible += 1; this.findNewPosition(model, tree); }; Queue.prototype.getDetails = function () { }; Queue.prototype.stringAttributes = function () { var obj, i, attName, attNameTitle; obj = { Queue : '', attributeOrder : ['Queue'] }; for (i in this.detail_attributes) { attName = this.detail_attributes[i]; attNameTitle = attName.toTitleCase(); obj.attributeOrder.push(attNameTitle); if ("object" === typeof this[attName]) { obj[attNameTitle] = stringifyObject(this[attName]); } else { obj[attNameTitle] = "" + this[attName]; } } obj.attributeOrder.push('Incoming Exchange Bindings'); obj['Incoming Exchange Bindings'] = "" + Object.keys(this.bindings_inbound).length; if (undefined !== this.message_stats) { if (undefined !== this.message_stats.publish_details) { obj.attributeOrder.push('Message Incoming Rate (msgs/sec)'); obj['Message Incoming Rate (msgs/sec)'] = "" + Math.round(this.message_stats.publish_details.rate); } if (undefined !== this.message_stats.deliver_get_details) { obj.attributeOrder.push('Delivery and Get Rate (msgs/sec)'); obj['Delivery and Get Rate (msgs/sec)'] = "" + Math.round(this.message_stats.deliver_get_details.rate); } if (undefined !== this.message_stats.ack_details) { obj.attributeOrder.push('Delivery Acknowledgement Rate (acks/sec)'); obj['Delivery Acknowledgement Rate (acks/sec)'] = "" + Math.round(this.message_stats.ack_details.rate); } } return obj; }; Queue.prototype.url = function () { return "/queues/" + encodeURIComponent(this.vhost) + "/" + encodeURIComponent(this.name); }; Queue.prototype.navigateTo = function () { document.location = "../#" + this.url(); }; function Binding(elems) { this.keys = {}; this.set(elems); var elem = elems.shift(); this.source = elem.source; this.destination_type = elem.destination_type; this.destination = elem.destination; } Binding.prototype = { attributes : [ 'arguments' ], offset : 150, fontSize : 12, loopOffset : 50, object_type : 'binding' }; Binding.prototype.set = function (elems) { var i, elem, attr, j; this.keys = {}; for (i = 0; i < elems.length; i += 1) { elem = elems[i]; this.keys[elem.routing_key] = {}; for (j = 0; j < this.attributes.length; j += 1) { attr = this.attributes[j]; this.keys[elem.routing_key][attr] = elem[attr]; } } }; Binding.prototype.render = function (model, ctx) { var source, destination, xMid, xCtl1, xCtl2, yCtl1, yCtl2, xMin, yMin, xMax, yMax; source = model.exchange[this.source]; if (this.destination_type === "exchange") { destination = model.exchange[this.destination]; } else { destination = model.queue[this.destination]; } if (undefined === source || undefined === destination) { return; } if (source.disabled || destination.disabled) { return; } xMid = (source.xMax + destination.xMin) / 2; xCtl1 = xMid > (source.xMax + this.offset) ? xMid : source.xMax + this.offset; xCtl2 = xMid < (destination.xMin - this.offset) ? xMid : destination.xMin - this.offset; yCtl1 = destination === source ? source.pos[octtree.y] - this.loopOffset : source.pos[octtree.y]; yCtl2 = destination === source ? destination.pos[octtree.y] - this.loopOffset : destination.pos[octtree.y]; xMin = Math.min(source.xMax, xCtl2); yMin = Math.min(yCtl1, yCtl2); xMax = Math.max(destination.xMin, xCtl1); yMax = Math.max(source.pos[octtree.y], destination.pos[octtree.y]); if (model.cull(xMin, yMin, xMax - xMin, yMax - yMin)) { return; } ctx.beginPath(); ctx.lineWidth = 1.0; ctx.strokeStyle = "black"; ctx.moveTo(source.xMax, source.pos[octtree.y]); ctx.bezierCurveTo(xCtl1, yCtl1, xCtl2, yCtl2, destination.xMin, destination.pos[octtree.y]); ctx.moveTo(destination.xMin, destination.pos[octtree.y] + 1); ctx.bezierCurveTo(xCtl2, yCtl2 + 1, xCtl1, yCtl1 + 1, source.xMax, source.pos[octtree.y] + 1); ctx.moveTo(source.xMax, source.pos[octtree.y]); this.preStroke(source, destination, model, ctx); // draw an arrow head ctx.beginPath(); ctx.moveTo(destination.xMin, destination.pos[octtree.y]); ctx.lineTo(destination.xMin - this.fontSize, destination.pos[octtree.y] + (this.fontSize / 2)); ctx.lineTo(destination.xMin - this.fontSize, destination.pos[octtree.y] - (this.fontSize / 2)); ctx.closePath(); ctx.fillStyle = ctx.strokeStyle; ctx.fill(); }; Binding.prototype.preStroke = function (source, destination, model, ctx) { }; function Model() { this.exchange = {}; this.exchanges_visible = 0; this.queue = {}; this.queues_visible = 0; this.channel = {}; this.channels_visible = 0; this.connection = {}; this.vhost = {}; this.rendering = { exchange : { enabled : true, on_enable : {} }, queue : { enabled : true, on_enable : {} }, channel : { enabled : true, on_enable : {} }, connection : { enabled : true, on_enable : {} } }; this.highlighted = { exchange : {}, queue : {}, channel : {}, connection : {} }; } Model.prototype.permitted_exchanges_visible = 10; Model.prototype.permitted_queues_visible = 10; Model.prototype.permitted_channels_visible = 10; Model.prototype.rebuild = function (tree, configuration) { var elem, matched, i, binding, bindings, source, src, destination_type, j, src1, destination, dest, dest_type; // Channels matched = {}; for (i = 0; i < configuration.channels.length; i += 1) { elem = configuration.channels[i]; if (undefined === this.channel[elem.name]) { this.channel[elem.name] = new Channel(tree, elem, this); this.channels_visible += 1; if ((this.channels_visible > this.permitted_channels_visible) || ! this.rendering.channel.enabled) { this.disable(this.channel[elem.name], tree); } } else { this.channel[elem.name].update(elem); } matched[elem.name] = true; } for (i in this.channel) { if (undefined === matched[i]) { elem = this.channel[i]; delete this.channel[i]; elem.remove(tree, this); if (! elem.disabled) { this.channels_visible -= 1; } } } // Exchanges matched = {}; for (i = 0; i < configuration.exchanges.length; i += 1) { elem = configuration.exchanges[i]; if (undefined === this.exchange[elem.name]) { this.exchange[elem.name] = new Exchange(tree, elem, this); this.exchanges_visible += 1; if (elem.name.slice(0, 4) === "amq." || (this.exchanges_visible > this.permitted_exchanges_visible) || ! this.rendering.exchange.enabled) { this.disable(this.exchange[elem.name], tree); } } else { this.exchange[elem.name].update(elem); } matched[elem.name] = true; } for (i in this.exchange) { if (undefined === matched[i]) { elem = this.exchange[i]; delete this.exchange[i]; elem.remove(tree, this); if (! elem.disabled) { this.exchanges_visible -= 1; } } } // Queues matched = {}; for (i = 0; i < configuration.queues.length; i += 1) { elem = configuration.queues[i]; if (undefined === this.queue[elem.name]) { this.queue[elem.name] = new Queue(tree, elem, this); this.queues_visible += 1; if ((this.queues_visible > this.permitted_queues_visible) || ! this.rendering.queue.enabled) { this.disable(this.queue[elem.name], tree); delete this.rendering.queue.on_enable[elem.name]; } } else { this.queue[elem.name].update(elem); } matched[elem.name] = true; } for (i in this.queue) { if (undefined === matched[i]) { elem = this.queue[i]; delete this.queue[i]; elem.remove(tree, this); if (! elem.disabled) { this.queues_visible -= 1; } } } // Bindings bindings = {}; for (i = 0; i < configuration.bindings.length; i += 1) { elem = configuration.bindings[i]; if (undefined === this.exchange[elem.source] || undefined === this[elem.destination_type][elem.destination]) { continue; } if (undefined === bindings[elem.source]) { bindings[elem.source] = { exchange : {}, queue : {} }; } source = bindings[elem.source]; if (undefined === source[elem.destination_type][elem.destination]) { source[elem.destination_type][elem.destination] = new Array(elem); } else { source[elem.destination_type][elem.destination].push(elem); } } for (source in bindings) { src = this.exchange[source].bindings_outbound; i = bindings[source]; for (destination_type in i) { j = i[destination_type]; src1 = src[destination_type]; for (destination in j) { dest = this[destination_type][destination].bindings_inbound; if (undefined === src1[destination]) { src1[destination] = new Binding(j[destination]); } else { src1[destination].set(j[destination]); } binding = src1[destination]; if (undefined === dest[source]) { dest[source] = binding; } } } } for (src in this.exchange) { for (dest_type in this.exchange[src].bindings_outbound) { for (dest in this.exchange[src].bindings_outbound[dest_type]) { binding = this.exchange[src].bindings_outbound[dest_type][dest]; if (undefined === bindings[binding.source] || undefined === bindings[binding.source][binding.destination_type] || undefined === bindings[binding.source][binding.destination_type][binding.destination]) { delete this.exchange[src].bindings_outbound[dest_type][dest]; if (undefined !== this[binding.destination_type][binding.destination]) { delete this[binding.destination_type][binding.destination].bindings_inbound[binding.source]; } } } } } bindings = undefined; // vhosts matched = {}; for (i = 0; i < configuration.vhosts.length; i += 1) { elem = configuration.vhosts[i]; if (undefined === this.vhost[elem.name]) { this.vhost[elem.name] = elem; this.vhost_add(elem); } matched[elem.name] = true; } for (i in this.vhost) { if (undefined === matched[i]) { this.vhost_remove(this.vhost[i]); delete this.vhost[i]; } } matched = undefined; }; Model.prototype.disable = function (elem, tree) { elem.disable(this); tree.del(elem); elem.disabled = true; elem.details = undefined; }; Model.prototype.enable = function (elem, tree) { elem.enable(this, tree); tree.add(elem); elem.disabled = false; elem.details = undefined; }; Model.prototype.render = function (ctx) { var i; if (this.rendering.exchange.enabled) { for (i in this.exchange) { this.exchange[i].render(this, ctx); } } if (this.rendering.queue.enabled) { for (i in this.queue) { this.queue[i].render(this, ctx); } } if (this.rendering.channel.enabled) { for (i in this.channel) { this.channel[i].render(this, ctx); } } }; Model.prototype.cull = function (xMin, yMin, width, height) { return false; }; Model.prototype.vhost_add = function (elem) { }; Model.prototype.vhost_del = function (elem) { }; Model.prototype.resetHighlighted = function () { this.highlighted = { exchange : {}, queue : {}, channel : {}, connection : {} }; }; Model.prototype.setHighlighted = function (elem) { if (undefined !== elem) { this.highlighted[elem.object_type][elem.name] = elem; } }; Model.prototype.isHighlighted = function (elem) { return ((undefined !== elem) && (undefined !== this.highlighted[elem.object_type][elem.name])); }; rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/priv/www/visualiser/js/octtree.js0000644000177700017770000003276012633765070033442 0ustar michaelmichael/*global vec3 */ var octtree = {}; octtree.top_nw = 0; octtree.top_ne = 1; octtree.top_se = 2; octtree.top_sw = 3; octtree.bot_nw = 4; octtree.bot_ne = 5; octtree.bot_se = 6; octtree.bot_sw = 7; octtree.children = [ octtree.top_nw, octtree.top_ne, octtree.top_se, octtree.top_sw, octtree.bot_nw, octtree.bot_ne, octtree.bot_se, octtree.bot_sw ]; octtree.firstChildId = 0; octtree.lastChildId = 7; octtree.x = 0; octtree.y = 1; octtree.z = 2; octtree.randoms = []; octtree.randomIndex = 0; octtree.i = 0; for (octtree.i = 0; octtree.i < 100; octtree.i += 1) { octtree.randoms.push(Math.random()); } function Octtree(xMin, xMax, yMin, yMax, zMin, zMax, parent, childId) { this.xMin = xMin; this.xMax = xMax; this.yMin = yMin; this.yMax = yMax; this.zMin = zMin; this.zMax = zMax; this.parent = parent; this.childId = childId; if (undefined !== childId && childId !== octtree.lastChildId && undefined !== parent) { this.nextSiblingId = childId + 1; } this.xMid = xMin + (xMax - xMin) / 2; this.yMid = yMin + (yMax - yMin) / 2; this.zMid = zMin + (zMax - zMin) / 2; } Octtree.prototype.isEmpty = function () { return (undefined === this[octtree.firstChildId]) && (undefined === this.value); }; Octtree.prototype.hasChildren = function () { return undefined !== this[octtree.firstChildId]; }; Octtree.prototype.hasValue = function () { return undefined !== this.value; }; Octtree.prototype.add = function (value) { return octtree.add(this, value); }; Octtree.prototype.del = function (value) { return octtree.del(this, value); }; Octtree.prototype.update = function () { return octtree.update(this); }; Octtree.prototype.findInRadius = function (pos, radius, limit) { return octtree.findInRadius(this, pos, radius, limit); }; Octtree.prototype.size = function () { return octtree.size(this); }; octtree.findNode = function (tree, pos) { while (true) { if (pos[octtree.x] < tree.xMin || tree.xMax <= pos[octtree.x] || pos[octtree.y] < tree.yMin || tree.yMax <= pos[octtree.y] || pos[octtree.z] < tree.zMin || tree.zMax <= pos[octtree.z]) { if (undefined === tree.parent) { return undefined; } else { tree = tree.parent; continue; } } if (tree.hasChildren()) { if (pos[octtree.x] < tree.xMid) { if (pos[octtree.y] < tree.yMid) { if (pos[octtree.z] < tree.zMid) { tree = tree[octtree.bot_sw]; } else { tree = tree[octtree.bot_nw]; } } else { if (pos[octtree.z] < tree.zMid) { tree = tree[octtree.top_sw]; } else { tree = tree[octtree.top_nw]; } } } else { if (pos[octtree.y] < tree.yMid) { if (pos[octtree.z] < tree.zMid) { tree = tree[octtree.bot_se]; } else { tree = tree[octtree.bot_ne]; } } else { if (pos[octtree.z] < tree.zMid) { tree = tree[octtree.top_se]; } else { tree = tree[octtree.top_ne]; } } } } else { return tree; } } }; octtree.add = function (tree, value) { tree = octtree.findNode(tree, value.pos); if (undefined === tree) { return undefined; } else { var displaced; while (undefined !== value) { if (tree.hasValue()) { if (tree.value.pos[octtree.x] === value.pos[octtree.x] && tree.value.pos[octtree.y] === value.pos[octtree.y] && tree.value.pos[octtree.z] === value.pos[octtree.z]) { tree.value = value; value = undefined; } else { displaced = value; // make sure we add our new value last value = tree.value; tree.value = undefined; tree[octtree.top_nw] = new Octtree(tree.xMin, tree.xMid, tree.yMid, tree.yMax, tree.zMid, tree.zMax, tree, octtree.top_nw); tree[octtree.top_ne] = new Octtree(tree.xMid, tree.xMax, tree.yMid, tree.yMax, tree.zMid, tree.zMax, tree, octtree.top_ne); tree[octtree.top_se] = new Octtree(tree.xMid, tree.xMax, tree.yMid, tree.yMax, tree.zMin, tree.zMid, tree, octtree.top_se); tree[octtree.top_sw] = new Octtree(tree.xMin, tree.xMid, tree.yMid, tree.yMax, tree.zMin, tree.zMid, tree, octtree.top_sw); tree[octtree.bot_nw] = new Octtree(tree.xMin, tree.xMid, tree.yMin, tree.yMid, tree.zMid, tree.zMax, tree, octtree.bot_nw); tree[octtree.bot_ne] = new Octtree(tree.xMid, tree.xMax, tree.yMin, tree.yMid, tree.zMid, tree.zMax, tree, octtree.bot_ne); tree[octtree.bot_se] = new Octtree(tree.xMid, tree.xMax, tree.yMin, tree.yMid, tree.zMin, tree.zMid, tree, octtree.bot_se); tree[octtree.bot_sw] = new Octtree(tree.xMin, tree.xMid, tree.yMin, tree.yMid, tree.zMin, tree.zMid, tree, octtree.bot_sw); tree = octtree.findNode(tree, value.pos); } } else { tree.value = value; value = displaced; displaced = undefined; if (undefined !== value) { tree = octtree.findNode(tree, value.pos); } } } return tree; } }; octtree.del = function (tree, value) { tree = octtree.findNode(tree, value.pos); if (undefined === tree || (!tree.hasValue())) { return tree; } if (tree.value.pos[octtree.x] === value.pos[octtree.x] && tree.value.pos[octtree.y] === value.pos[octtree.y] && tree.value.pos[octtree.z] === value.pos[octtree.z]) { tree.value = undefined; tree = tree.parent; var valCount, nonEmptyChild, child, i; while (undefined !== tree) { valCount = 0; for (i = 0; i < octtree.children.length; i += 1) { child = octtree.children[i]; if (!tree[child].isEmpty()) { valCount += 1; nonEmptyChild = tree[child]; } } if (0 === valCount) { for (i = 0; i < octtree.children.length; i += 1) { child = octtree.children[i]; tree[child] = undefined; } tree = tree.parent; } else if (1 === valCount) { if (nonEmptyChild.hasValue()) { for (i = 0; i < octtree.children.length; i += 1) { child = octtree.children[i]; tree[child] = undefined; } tree.value = nonEmptyChild.value; tree = tree.parent; } else { break; } } else { break; } } } return tree; }; octtree.next = function (tree) { while (undefined !== tree) { if (undefined !== tree.nextSiblingId) { return tree.parent[tree.nextSiblingId]; } else { tree = tree.parent; } } return undefined; }; octtree.defined = function (a, b) { if (undefined === a) { return b; } else { return a; } }; octtree.update = function (tree) { var root, parent, v, movedValues, i; root = tree; parent = root.parent; root.parent = undefined; // do this to stop next going up past tree movedValues = []; while (undefined !== tree) { if (tree.hasValue()) { v = tree.value; if (v.next_pos[octtree.x] < tree.xMin || tree.xMax <= v.next_pos[octtree.x] || v.next_pos[octtree.y] < tree.yMin || tree.yMax <= v.next_pos[octtree.y] || v.next_pos[octtree.z] < tree.zMin || tree.zMax <= v.next_pos[octtree.z]) { movedValues.push(tree.value); } else { vec3.set(v.next_pos, v.pos); } tree = octtree.next(tree); } else if (tree.hasChildren()) { tree = tree[octtree.firstChildId]; } else { tree = octtree.next(tree); } } root.parent = parent; tree = root; for (i = 0; i < movedValues.length; i += 1) { v = movedValues[i]; tree = octtree.defined(tree.del(v), tree); vec3.set(v.next_pos, v.pos); tree = octtree.defined(tree.add(v), tree); } return root; }; octtree.findInRadius = function (tree, pos, radius, limit) { var acc, radiusSq, worklist, x_p_r, x_m_r, y_p_r, y_m_r, z_p_r, z_m_r, xd, yd, zd; acc = []; radiusSq = radius * radius; worklist = [tree]; tree = undefined; x_p_r = 0; x_m_r = 0; y_p_r = 0; y_m_r = 0; z_p_r = 0; z_m_r = 0; while (0 < worklist.length && (undefined === limit || limit > acc.length)) { tree = worklist.shift(); if (tree.isEmpty()) { continue; } if (tree.hasValue()) { xd = Math.abs(tree.value.pos[octtree.x] - pos[octtree.x]); yd = Math.abs(tree.value.pos[octtree.y] - pos[octtree.y]); zd = Math.abs(tree.value.pos[octtree.z] - pos[octtree.z]); xd *= xd; yd *= yd; zd *= zd; if ((xd + yd + zd) <= radiusSq) { acc.push(tree); } continue; } x_p_r = pos[octtree.x] + radius; x_m_r = pos[octtree.x] - radius; y_p_r = pos[octtree.y] + radius; y_m_r = pos[octtree.y] - radius; z_p_r = pos[octtree.z] + radius; z_m_r = pos[octtree.z] - radius; if (x_p_r < tree.xMin || tree.xMax <= x_m_r || y_p_r < tree.yMin || tree.yMax <= y_m_r || z_p_r < tree.zMin || tree.zMax <= z_m_r) { continue; } if (x_m_r < tree.xMid) { if (y_m_r < tree.yMid) { if (z_m_r < tree.zMid) { octtree.randomPush(worklist, tree[octtree.bot_sw]); } if (tree.zMid <= z_p_r) { octtree.randomPush(worklist, tree[octtree.bot_nw]); } } if (tree.yMid <= y_p_r) { if (z_m_r < tree.zMid) { octtree.randomPush(worklist, tree[octtree.top_sw]); } if (tree.zMid <= z_p_r) { octtree.randomPush(worklist, tree[octtree.top_nw]); } } } if (tree.xMid <= x_p_r) { if (y_m_r < tree.yMid) { if (z_m_r < tree.zMid) { octtree.randomPush(worklist, tree[octtree.bot_se]); } if (tree.zMid <= z_p_r) { octtree.randomPush(worklist, tree[octtree.bot_ne]); } } if (tree.yMid <= y_p_r) { if (z_m_r < tree.zMid) { octtree.randomPush(worklist, tree[octtree.top_se]); } if (tree.zMid <= z_p_r) { octtree.randomPush(worklist, tree[octtree.top_ne]); } } } } return acc; }; octtree.size = function (tree) { var count, root, parent; root = 0; root = tree; parent = root.parent; root.parent = undefined; // stop the traversal going above us. while (undefined !== tree) { if (tree.hasValue()) { count += 1; tree = octtree.next(tree); } else if (tree.hasChildren()) { tree = tree[octtree.firstChildId]; } else { tree = octtree.next(tree); } } root.parent = parent; return count; }; octtree.create = function (xMin, xMax, yMin, yMax, zMin, zMax) { return new Octtree(xMin, xMax, yMin, yMax, zMin, zMax, undefined, undefined); }; octtree.randomPush = function (ary, e) { if (octtree.nextRandom() > 0.5) { ary.push(e); } else { ary.unshift(e); } return ary; }; octtree.nextRandom = function () { var r = octtree.randoms[octtree.randomIndex]; octtree.randomIndex += 1; if (octtree.randomIndex === octtree.randoms.length) { octtree.randomIndex = 0; } return r; }; rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/priv/www/visualiser/js/glMatrix.js0000644000177700017770000012114212633765070033555 0ustar michaelmichael/* * glMatrix.js - High performance matrix and vector operations for WebGL * version 0.9.5 */ /* * Copyright (c) 2010 Brandon Jones * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not * be misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source * distribution. */ // Fallback for systems that don't support WebGL if(typeof Float32Array != 'undefined') { glMatrixArrayType = Float32Array; } else if(typeof WebGLFloatArray != 'undefined') { glMatrixArrayType = WebGLFloatArray; // This is officially deprecated and should dissapear in future revisions. } else { glMatrixArrayType = Array; } /* * vec3 - 3 Dimensional Vector */ var vec3 = {}; /* * vec3.create * Creates a new instance of a vec3 using the default array type * Any javascript array containing at least 3 numeric elements can serve as a vec3 * * Params: * vec - Optional, vec3 containing values to initialize with * * Returns: * New vec3 */ vec3.create = function(vec) { var dest = new glMatrixArrayType(3); if(vec) { dest[0] = vec[0]; dest[1] = vec[1]; dest[2] = vec[2]; } return dest; }; /* * vec3.set * Copies the values of one vec3 to another * * Params: * vec - vec3 containing values to copy * dest - vec3 receiving copied values * * Returns: * dest */ vec3.set = function(vec, dest) { dest[0] = vec[0]; dest[1] = vec[1]; dest[2] = vec[2]; return dest; }; /* * vec3.add * Performs a vector addition * * Params: * vec - vec3, first operand * vec2 - vec3, second operand * dest - Optional, vec3 receiving operation result. If not specified result is written to vec * * Returns: * dest if specified, vec otherwise */ vec3.add = function(vec, vec2, dest) { if(!dest || vec == dest) { vec[0] += vec2[0]; vec[1] += vec2[1]; vec[2] += vec2[2]; return vec; } dest[0] = vec[0] + vec2[0]; dest[1] = vec[1] + vec2[1]; dest[2] = vec[2] + vec2[2]; return dest; }; /* * vec3.subtract * Performs a vector subtraction * * Params: * vec - vec3, first operand * vec2 - vec3, second operand * dest - Optional, vec3 receiving operation result. If not specified result is written to vec * * Returns: * dest if specified, vec otherwise */ vec3.subtract = function(vec, vec2, dest) { if(!dest || vec == dest) { vec[0] -= vec2[0]; vec[1] -= vec2[1]; vec[2] -= vec2[2]; return vec; } dest[0] = vec[0] - vec2[0]; dest[1] = vec[1] - vec2[1]; dest[2] = vec[2] - vec2[2]; return dest; }; /* * vec3.negate * Negates the components of a vec3 * * Params: * vec - vec3 to negate * dest - Optional, vec3 receiving operation result. If not specified result is written to vec * * Returns: * dest if specified, vec otherwise */ vec3.negate = function(vec, dest) { if(!dest) { dest = vec; } dest[0] = -vec[0]; dest[1] = -vec[1]; dest[2] = -vec[2]; return dest; }; /* * vec3.scale * Multiplies the components of a vec3 by a scalar value * * Params: * vec - vec3 to scale * val - Numeric value to scale by * dest - Optional, vec3 receiving operation result. If not specified result is written to vec * * Returns: * dest if specified, vec otherwise */ vec3.scale = function(vec, val, dest) { if(!dest || vec == dest) { vec[0] *= val; vec[1] *= val; vec[2] *= val; return vec; } dest[0] = vec[0]*val; dest[1] = vec[1]*val; dest[2] = vec[2]*val; return dest; }; /* * vec3.normalize * Generates a unit vector of the same direction as the provided vec3 * If vector length is 0, returns [0, 0, 0] * * Params: * vec - vec3 to normalize * dest - Optional, vec3 receiving operation result. If not specified result is written to vec * * Returns: * dest if specified, vec otherwise */ vec3.normalize = function(vec, dest) { if(!dest) { dest = vec; } var x = vec[0], y = vec[1], z = vec[2]; var len = Math.sqrt(x*x + y*y + z*z); if (!len) { dest[0] = 0; dest[1] = 0; dest[2] = 0; return dest; } else if (len == 1) { dest[0] = x; dest[1] = y; dest[2] = z; return dest; } len = 1 / len; dest[0] = x*len; dest[1] = y*len; dest[2] = z*len; return dest; }; /* * vec3.cross * Generates the cross product of two vec3s * * Params: * vec - vec3, first operand * vec2 - vec3, second operand * dest - Optional, vec3 receiving operation result. If not specified result is written to vec * * Returns: * dest if specified, vec otherwise */ vec3.cross = function(vec, vec2, dest){ if(!dest) { dest = vec; } var x = vec[0], y = vec[1], z = vec[2]; var x2 = vec2[0], y2 = vec2[1], z2 = vec2[2]; dest[0] = y*z2 - z*y2; dest[1] = z*x2 - x*z2; dest[2] = x*y2 - y*x2; return dest; }; /* * vec3.length * Caclulates the length of a vec3 * * Params: * vec - vec3 to calculate length of * * Returns: * Length of vec */ vec3.length = function(vec){ var x = vec[0], y = vec[1], z = vec[2]; return Math.sqrt(x*x + y*y + z*z); }; /* * vec3.dot * Caclulates the dot product of two vec3s * * Params: * vec - vec3, first operand * vec2 - vec3, second operand * * Returns: * Dot product of vec and vec2 */ vec3.dot = function(vec, vec2){ return vec[0]*vec2[0] + vec[1]*vec2[1] + vec[2]*vec2[2]; }; /* * vec3.direction * Generates a unit vector pointing from one vector to another * * Params: * vec - origin vec3 * vec2 - vec3 to point to * dest - Optional, vec3 receiving operation result. If not specified result is written to vec * * Returns: * dest if specified, vec otherwise */ vec3.direction = function(vec, vec2, dest) { if(!dest) { dest = vec; } var x = vec[0] - vec2[0]; var y = vec[1] - vec2[1]; var z = vec[2] - vec2[2]; var len = Math.sqrt(x*x + y*y + z*z); if (!len) { dest[0] = 0; dest[1] = 0; dest[2] = 0; return dest; } len = 1 / len; dest[0] = x * len; dest[1] = y * len; dest[2] = z * len; return dest; }; /* * vec3.lerp * Performs a linear interpolation between two vec3 * * Params: * vec - vec3, first vector * vec2 - vec3, second vector * lerp - interpolation amount between the two inputs * dest - Optional, vec3 receiving operation result. If not specified result is written to vec * * Returns: * dest if specified, vec otherwise */ vec3.lerp = function(vec, vec2, lerp, dest){ if(!dest) { dest = vec; } dest[0] = vec[0] + lerp * (vec2[0] - vec[0]); dest[1] = vec[1] + lerp * (vec2[1] - vec[1]); dest[2] = vec[2] + lerp * (vec2[2] - vec[2]); return dest; } /* * vec3.str * Returns a string representation of a vector * * Params: * vec - vec3 to represent as a string * * Returns: * string representation of vec */ vec3.str = function(vec) { return '[' + vec[0] + ', ' + vec[1] + ', ' + vec[2] + ']'; }; /* * mat3 - 3x3 Matrix */ var mat3 = {}; /* * mat3.create * Creates a new instance of a mat3 using the default array type * Any javascript array containing at least 9 numeric elements can serve as a mat3 * * Params: * mat - Optional, mat3 containing values to initialize with * * Returns: * New mat3 */ mat3.create = function(mat) { var dest = new glMatrixArrayType(9); if(mat) { dest[0] = mat[0]; dest[1] = mat[1]; dest[2] = mat[2]; dest[3] = mat[3]; dest[4] = mat[4]; dest[5] = mat[5]; dest[6] = mat[6]; dest[7] = mat[7]; dest[8] = mat[8]; dest[9] = mat[9]; } return dest; }; /* * mat3.set * Copies the values of one mat3 to another * * Params: * mat - mat3 containing values to copy * dest - mat3 receiving copied values * * Returns: * dest */ mat3.set = function(mat, dest) { dest[0] = mat[0]; dest[1] = mat[1]; dest[2] = mat[2]; dest[3] = mat[3]; dest[4] = mat[4]; dest[5] = mat[5]; dest[6] = mat[6]; dest[7] = mat[7]; dest[8] = mat[8]; return dest; }; /* * mat3.identity * Sets a mat3 to an identity matrix * * Params: * dest - mat3 to set * * Returns: * dest */ mat3.identity = function(dest) { dest[0] = 1; dest[1] = 0; dest[2] = 0; dest[3] = 0; dest[4] = 1; dest[5] = 0; dest[6] = 0; dest[7] = 0; dest[8] = 1; return dest; }; /* * mat4.transpose * Transposes a mat3 (flips the values over the diagonal) * * Params: * mat - mat3 to transpose * dest - Optional, mat3 receiving transposed values. If not specified result is written to mat * * Returns: * dest is specified, mat otherwise */ mat3.transpose = function(mat, dest) { // If we are transposing ourselves we can skip a few steps but have to cache some values if(!dest || mat == dest) { var a01 = mat[1], a02 = mat[2]; var a12 = mat[5]; mat[1] = mat[3]; mat[2] = mat[6]; mat[3] = a01; mat[5] = mat[7]; mat[6] = a02; mat[7] = a12; return mat; } dest[0] = mat[0]; dest[1] = mat[3]; dest[2] = mat[6]; dest[3] = mat[1]; dest[4] = mat[4]; dest[5] = mat[7]; dest[6] = mat[2]; dest[7] = mat[5]; dest[8] = mat[8]; return dest; }; /* * mat3.toMat4 * Copies the elements of a mat3 into the upper 3x3 elements of a mat4 * * Params: * mat - mat3 containing values to copy * dest - Optional, mat4 receiving copied values * * Returns: * dest if specified, a new mat4 otherwise */ mat3.toMat4 = function(mat, dest) { if(!dest) { dest = mat4.create(); } dest[0] = mat[0]; dest[1] = mat[1]; dest[2] = mat[2]; dest[3] = 0; dest[4] = mat[3]; dest[5] = mat[4]; dest[6] = mat[5]; dest[7] = 0; dest[8] = mat[6]; dest[9] = mat[7]; dest[10] = mat[8]; dest[11] = 0; dest[12] = 0; dest[13] = 0; dest[14] = 0; dest[15] = 1; return dest; } /* * mat3.str * Returns a string representation of a mat3 * * Params: * mat - mat3 to represent as a string * * Returns: * string representation of mat */ mat3.str = function(mat) { return '[' + mat[0] + ', ' + mat[1] + ', ' + mat[2] + ', ' + mat[3] + ', '+ mat[4] + ', ' + mat[5] + ', ' + mat[6] + ', ' + mat[7] + ', '+ mat[8] + ']'; }; /* * mat4 - 4x4 Matrix */ var mat4 = {}; /* * mat4.create * Creates a new instance of a mat4 using the default array type * Any javascript array containing at least 16 numeric elements can serve as a mat4 * * Params: * mat - Optional, mat4 containing values to initialize with * * Returns: * New mat4 */ mat4.create = function(mat) { var dest = new glMatrixArrayType(16); if(mat) { dest[0] = mat[0]; dest[1] = mat[1]; dest[2] = mat[2]; dest[3] = mat[3]; dest[4] = mat[4]; dest[5] = mat[5]; dest[6] = mat[6]; dest[7] = mat[7]; dest[8] = mat[8]; dest[9] = mat[9]; dest[10] = mat[10]; dest[11] = mat[11]; dest[12] = mat[12]; dest[13] = mat[13]; dest[14] = mat[14]; dest[15] = mat[15]; } return dest; }; /* * mat4.set * Copies the values of one mat4 to another * * Params: * mat - mat4 containing values to copy * dest - mat4 receiving copied values * * Returns: * dest */ mat4.set = function(mat, dest) { dest[0] = mat[0]; dest[1] = mat[1]; dest[2] = mat[2]; dest[3] = mat[3]; dest[4] = mat[4]; dest[5] = mat[5]; dest[6] = mat[6]; dest[7] = mat[7]; dest[8] = mat[8]; dest[9] = mat[9]; dest[10] = mat[10]; dest[11] = mat[11]; dest[12] = mat[12]; dest[13] = mat[13]; dest[14] = mat[14]; dest[15] = mat[15]; return dest; }; /* * mat4.identity * Sets a mat4 to an identity matrix * * Params: * dest - mat4 to set * * Returns: * dest */ mat4.identity = function(dest) { dest[0] = 1; dest[1] = 0; dest[2] = 0; dest[3] = 0; dest[4] = 0; dest[5] = 1; dest[6] = 0; dest[7] = 0; dest[8] = 0; dest[9] = 0; dest[10] = 1; dest[11] = 0; dest[12] = 0; dest[13] = 0; dest[14] = 0; dest[15] = 1; return dest; }; /* * mat4.transpose * Transposes a mat4 (flips the values over the diagonal) * * Params: * mat - mat4 to transpose * dest - Optional, mat4 receiving transposed values. If not specified result is written to mat * * Returns: * dest is specified, mat otherwise */ mat4.transpose = function(mat, dest) { // If we are transposing ourselves we can skip a few steps but have to cache some values if(!dest || mat == dest) { var a01 = mat[1], a02 = mat[2], a03 = mat[3]; var a12 = mat[6], a13 = mat[7]; var a23 = mat[11]; mat[1] = mat[4]; mat[2] = mat[8]; mat[3] = mat[12]; mat[4] = a01; mat[6] = mat[9]; mat[7] = mat[13]; mat[8] = a02; mat[9] = a12; mat[11] = mat[14]; mat[12] = a03; mat[13] = a13; mat[14] = a23; return mat; } dest[0] = mat[0]; dest[1] = mat[4]; dest[2] = mat[8]; dest[3] = mat[12]; dest[4] = mat[1]; dest[5] = mat[5]; dest[6] = mat[9]; dest[7] = mat[13]; dest[8] = mat[2]; dest[9] = mat[6]; dest[10] = mat[10]; dest[11] = mat[14]; dest[12] = mat[3]; dest[13] = mat[7]; dest[14] = mat[11]; dest[15] = mat[15]; return dest; }; /* * mat4.determinant * Calculates the determinant of a mat4 * * Params: * mat - mat4 to calculate determinant of * * Returns: * determinant of mat */ mat4.determinant = function(mat) { // Cache the matrix values (makes for huge speed increases!) var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3]; var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7]; var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11]; var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15]; return a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 + a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 + a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 + a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 + a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + a10*a21*a02*a33 + a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33; }; /* * mat4.inverse * Calculates the inverse matrix of a mat4 * * Params: * mat - mat4 to calculate inverse of * dest - Optional, mat4 receiving inverse matrix. If not specified result is written to mat * * Returns: * dest is specified, mat otherwise */ mat4.inverse = function(mat, dest) { if(!dest) { dest = mat; } // Cache the matrix values (makes for huge speed increases!) var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3]; var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7]; var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11]; var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15]; var b00 = a00*a11 - a01*a10; var b01 = a00*a12 - a02*a10; var b02 = a00*a13 - a03*a10; var b03 = a01*a12 - a02*a11; var b04 = a01*a13 - a03*a11; var b05 = a02*a13 - a03*a12; var b06 = a20*a31 - a21*a30; var b07 = a20*a32 - a22*a30; var b08 = a20*a33 - a23*a30; var b09 = a21*a32 - a22*a31; var b10 = a21*a33 - a23*a31; var b11 = a22*a33 - a23*a32; // Calculate the determinant (inlined to avoid double-caching) var invDet = 1/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06); dest[0] = (a11*b11 - a12*b10 + a13*b09)*invDet; dest[1] = (-a01*b11 + a02*b10 - a03*b09)*invDet; dest[2] = (a31*b05 - a32*b04 + a33*b03)*invDet; dest[3] = (-a21*b05 + a22*b04 - a23*b03)*invDet; dest[4] = (-a10*b11 + a12*b08 - a13*b07)*invDet; dest[5] = (a00*b11 - a02*b08 + a03*b07)*invDet; dest[6] = (-a30*b05 + a32*b02 - a33*b01)*invDet; dest[7] = (a20*b05 - a22*b02 + a23*b01)*invDet; dest[8] = (a10*b10 - a11*b08 + a13*b06)*invDet; dest[9] = (-a00*b10 + a01*b08 - a03*b06)*invDet; dest[10] = (a30*b04 - a31*b02 + a33*b00)*invDet; dest[11] = (-a20*b04 + a21*b02 - a23*b00)*invDet; dest[12] = (-a10*b09 + a11*b07 - a12*b06)*invDet; dest[13] = (a00*b09 - a01*b07 + a02*b06)*invDet; dest[14] = (-a30*b03 + a31*b01 - a32*b00)*invDet; dest[15] = (a20*b03 - a21*b01 + a22*b00)*invDet; return dest; }; /* * mat4.toRotationMat * Copies the upper 3x3 elements of a mat4 into another mat4 * * Params: * mat - mat4 containing values to copy * dest - Optional, mat4 receiving copied values * * Returns: * dest is specified, a new mat4 otherwise */ mat4.toRotationMat = function(mat, dest) { if(!dest) { dest = mat4.create(); } dest[0] = mat[0]; dest[1] = mat[1]; dest[2] = mat[2]; dest[3] = mat[3]; dest[4] = mat[4]; dest[5] = mat[5]; dest[6] = mat[6]; dest[7] = mat[7]; dest[8] = mat[8]; dest[9] = mat[9]; dest[10] = mat[10]; dest[11] = mat[11]; dest[12] = 0; dest[13] = 0; dest[14] = 0; dest[15] = 1; return dest; }; /* * mat4.toMat3 * Copies the upper 3x3 elements of a mat4 into a mat3 * * Params: * mat - mat4 containing values to copy * dest - Optional, mat3 receiving copied values * * Returns: * dest is specified, a new mat3 otherwise */ mat4.toMat3 = function(mat, dest) { if(!dest) { dest = mat3.create(); } dest[0] = mat[0]; dest[1] = mat[1]; dest[2] = mat[2]; dest[3] = mat[4]; dest[4] = mat[5]; dest[5] = mat[6]; dest[6] = mat[8]; dest[7] = mat[9]; dest[8] = mat[10]; return dest; }; /* * mat4.toInverseMat3 * Calculates the inverse of the upper 3x3 elements of a mat4 and copies the result into a mat3 * The resulting matrix is useful for calculating transformed normals * * Params: * mat - mat4 containing values to invert and copy * dest - Optional, mat3 receiving values * * Returns: * dest is specified, a new mat3 otherwise */ mat4.toInverseMat3 = function(mat, dest) { // Cache the matrix values (makes for huge speed increases!) var a00 = mat[0], a01 = mat[1], a02 = mat[2]; var a10 = mat[4], a11 = mat[5], a12 = mat[6]; var a20 = mat[8], a21 = mat[9], a22 = mat[10]; var b01 = a22*a11-a12*a21; var b11 = -a22*a10+a12*a20; var b21 = a21*a10-a11*a20; var d = a00*b01 + a01*b11 + a02*b21; if (!d) { return null; } var id = 1/d; if(!dest) { dest = mat3.create(); } dest[0] = b01*id; dest[1] = (-a22*a01 + a02*a21)*id; dest[2] = (a12*a01 - a02*a11)*id; dest[3] = b11*id; dest[4] = (a22*a00 - a02*a20)*id; dest[5] = (-a12*a00 + a02*a10)*id; dest[6] = b21*id; dest[7] = (-a21*a00 + a01*a20)*id; dest[8] = (a11*a00 - a01*a10)*id; return dest; }; /* * mat4.multiply * Performs a matrix multiplication * * Params: * mat - mat4, first operand * mat2 - mat4, second operand * dest - Optional, mat4 receiving operation result. If not specified result is written to mat * * Returns: * dest if specified, mat otherwise */ mat4.multiply = function(mat, mat2, dest) { if(!dest) { dest = mat } // Cache the matrix values (makes for huge speed increases!) var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3]; var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7]; var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11]; var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15]; var b00 = mat2[0], b01 = mat2[1], b02 = mat2[2], b03 = mat2[3]; var b10 = mat2[4], b11 = mat2[5], b12 = mat2[6], b13 = mat2[7]; var b20 = mat2[8], b21 = mat2[9], b22 = mat2[10], b23 = mat2[11]; var b30 = mat2[12], b31 = mat2[13], b32 = mat2[14], b33 = mat2[15]; dest[0] = b00*a00 + b01*a10 + b02*a20 + b03*a30; dest[1] = b00*a01 + b01*a11 + b02*a21 + b03*a31; dest[2] = b00*a02 + b01*a12 + b02*a22 + b03*a32; dest[3] = b00*a03 + b01*a13 + b02*a23 + b03*a33; dest[4] = b10*a00 + b11*a10 + b12*a20 + b13*a30; dest[5] = b10*a01 + b11*a11 + b12*a21 + b13*a31; dest[6] = b10*a02 + b11*a12 + b12*a22 + b13*a32; dest[7] = b10*a03 + b11*a13 + b12*a23 + b13*a33; dest[8] = b20*a00 + b21*a10 + b22*a20 + b23*a30; dest[9] = b20*a01 + b21*a11 + b22*a21 + b23*a31; dest[10] = b20*a02 + b21*a12 + b22*a22 + b23*a32; dest[11] = b20*a03 + b21*a13 + b22*a23 + b23*a33; dest[12] = b30*a00 + b31*a10 + b32*a20 + b33*a30; dest[13] = b30*a01 + b31*a11 + b32*a21 + b33*a31; dest[14] = b30*a02 + b31*a12 + b32*a22 + b33*a32; dest[15] = b30*a03 + b31*a13 + b32*a23 + b33*a33; return dest; }; /* * mat4.multiplyVec3 * Transforms a vec3 with the given matrix * 4th vector component is implicitly '1' * * Params: * mat - mat4 to transform the vector with * vec - vec3 to transform * dest - Optional, vec3 receiving operation result. If not specified result is written to vec * * Returns: * dest if specified, vec otherwise */ mat4.multiplyVec3 = function(mat, vec, dest) { if(!dest) { dest = vec } var x = vec[0], y = vec[1], z = vec[2]; dest[0] = mat[0]*x + mat[4]*y + mat[8]*z + mat[12]; dest[1] = mat[1]*x + mat[5]*y + mat[9]*z + mat[13]; dest[2] = mat[2]*x + mat[6]*y + mat[10]*z + mat[14]; return dest; }; /* * mat4.multiplyVec4 * Transforms a vec4 with the given matrix * * Params: * mat - mat4 to transform the vector with * vec - vec4 to transform * dest - Optional, vec4 receiving operation result. If not specified result is written to vec * * Returns: * dest if specified, vec otherwise */ mat4.multiplyVec4 = function(mat, vec, dest) { if(!dest) { dest = vec } var x = vec[0], y = vec[1], z = vec[2], w = vec[3]; dest[0] = mat[0]*x + mat[4]*y + mat[8]*z + mat[12]*w; dest[1] = mat[1]*x + mat[5]*y + mat[9]*z + mat[13]*w; dest[2] = mat[2]*x + mat[6]*y + mat[10]*z + mat[14]*w; dest[3] = mat[3]*x + mat[7]*y + mat[11]*z + mat[15]*w; return dest; }; /* * mat4.translate * Translates a matrix by the given vector * * Params: * mat - mat4 to translate * vec - vec3 specifying the translation * dest - Optional, mat4 receiving operation result. If not specified result is written to mat * * Returns: * dest if specified, mat otherwise */ mat4.translate = function(mat, vec, dest) { var x = vec[0], y = vec[1], z = vec[2]; if(!dest || mat == dest) { mat[12] = mat[0]*x + mat[4]*y + mat[8]*z + mat[12]; mat[13] = mat[1]*x + mat[5]*y + mat[9]*z + mat[13]; mat[14] = mat[2]*x + mat[6]*y + mat[10]*z + mat[14]; mat[15] = mat[3]*x + mat[7]*y + mat[11]*z + mat[15]; return mat; } var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3]; var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7]; var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11]; dest[0] = a00; dest[1] = a01; dest[2] = a02; dest[3] = a03; dest[4] = a10; dest[5] = a11; dest[6] = a12; dest[7] = a13; dest[8] = a20; dest[9] = a21; dest[10] = a22; dest[11] = a23; dest[12] = a00*x + a10*y + a20*z + mat[12]; dest[13] = a01*x + a11*y + a21*z + mat[13]; dest[14] = a02*x + a12*y + a22*z + mat[14]; dest[15] = a03*x + a13*y + a23*z + mat[15]; return dest; }; /* * mat4.scale * Scales a matrix by the given vector * * Params: * mat - mat4 to scale * vec - vec3 specifying the scale for each axis * dest - Optional, mat4 receiving operation result. If not specified result is written to mat * * Returns: * dest if specified, mat otherwise */ mat4.scale = function(mat, vec, dest) { var x = vec[0], y = vec[1], z = vec[2]; if(!dest || mat == dest) { mat[0] *= x; mat[1] *= x; mat[2] *= x; mat[3] *= x; mat[4] *= y; mat[5] *= y; mat[6] *= y; mat[7] *= y; mat[8] *= z; mat[9] *= z; mat[10] *= z; mat[11] *= z; return mat; } dest[0] = mat[0]*x; dest[1] = mat[1]*x; dest[2] = mat[2]*x; dest[3] = mat[3]*x; dest[4] = mat[4]*y; dest[5] = mat[5]*y; dest[6] = mat[6]*y; dest[7] = mat[7]*y; dest[8] = mat[8]*z; dest[9] = mat[9]*z; dest[10] = mat[10]*z; dest[11] = mat[11]*z; dest[12] = mat[12]; dest[13] = mat[13]; dest[14] = mat[14]; dest[15] = mat[15]; return dest; }; /* * mat4.rotate * Rotates a matrix by the given angle around the specified axis * If rotating around a primary axis (X,Y,Z) one of the specialized rotation functions should be used instead for performance * * Params: * mat - mat4 to rotate * angle - angle (in radians) to rotate * axis - vec3 representing the axis to rotate around * dest - Optional, mat4 receiving operation result. If not specified result is written to mat * * Returns: * dest if specified, mat otherwise */ mat4.rotate = function(mat, angle, axis, dest) { var x = axis[0], y = axis[1], z = axis[2]; var len = Math.sqrt(x*x + y*y + z*z); if (!len) { return null; } if (len != 1) { len = 1 / len; x *= len; y *= len; z *= len; } var s = Math.sin(angle); var c = Math.cos(angle); var t = 1-c; // Cache the matrix values (makes for huge speed increases!) var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3]; var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7]; var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11]; // Construct the elements of the rotation matrix var b00 = x*x*t + c, b01 = y*x*t + z*s, b02 = z*x*t - y*s; var b10 = x*y*t - z*s, b11 = y*y*t + c, b12 = z*y*t + x*s; var b20 = x*z*t + y*s, b21 = y*z*t - x*s, b22 = z*z*t + c; if(!dest) { dest = mat } else if(mat != dest) { // If the source and destination differ, copy the unchanged last row dest[12] = mat[12]; dest[13] = mat[13]; dest[14] = mat[14]; dest[15] = mat[15]; } // Perform rotation-specific matrix multiplication dest[0] = a00*b00 + a10*b01 + a20*b02; dest[1] = a01*b00 + a11*b01 + a21*b02; dest[2] = a02*b00 + a12*b01 + a22*b02; dest[3] = a03*b00 + a13*b01 + a23*b02; dest[4] = a00*b10 + a10*b11 + a20*b12; dest[5] = a01*b10 + a11*b11 + a21*b12; dest[6] = a02*b10 + a12*b11 + a22*b12; dest[7] = a03*b10 + a13*b11 + a23*b12; dest[8] = a00*b20 + a10*b21 + a20*b22; dest[9] = a01*b20 + a11*b21 + a21*b22; dest[10] = a02*b20 + a12*b21 + a22*b22; dest[11] = a03*b20 + a13*b21 + a23*b22; return dest; }; /* * mat4.rotateX * Rotates a matrix by the given angle around the X axis * * Params: * mat - mat4 to rotate * angle - angle (in radians) to rotate * dest - Optional, mat4 receiving operation result. If not specified result is written to mat * * Returns: * dest if specified, mat otherwise */ mat4.rotateX = function(mat, angle, dest) { var s = Math.sin(angle); var c = Math.cos(angle); // Cache the matrix values (makes for huge speed increases!) var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7]; var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11]; if(!dest) { dest = mat } else if(mat != dest) { // If the source and destination differ, copy the unchanged rows dest[0] = mat[0]; dest[1] = mat[1]; dest[2] = mat[2]; dest[3] = mat[3]; dest[12] = mat[12]; dest[13] = mat[13]; dest[14] = mat[14]; dest[15] = mat[15]; } // Perform axis-specific matrix multiplication dest[4] = a10*c + a20*s; dest[5] = a11*c + a21*s; dest[6] = a12*c + a22*s; dest[7] = a13*c + a23*s; dest[8] = a10*-s + a20*c; dest[9] = a11*-s + a21*c; dest[10] = a12*-s + a22*c; dest[11] = a13*-s + a23*c; return dest; }; /* * mat4.rotateY * Rotates a matrix by the given angle around the Y axis * * Params: * mat - mat4 to rotate * angle - angle (in radians) to rotate * dest - Optional, mat4 receiving operation result. If not specified result is written to mat * * Returns: * dest if specified, mat otherwise */ mat4.rotateY = function(mat, angle, dest) { var s = Math.sin(angle); var c = Math.cos(angle); // Cache the matrix values (makes for huge speed increases!) var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3]; var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11]; if(!dest) { dest = mat } else if(mat != dest) { // If the source and destination differ, copy the unchanged rows dest[4] = mat[4]; dest[5] = mat[5]; dest[6] = mat[6]; dest[7] = mat[7]; dest[12] = mat[12]; dest[13] = mat[13]; dest[14] = mat[14]; dest[15] = mat[15]; } // Perform axis-specific matrix multiplication dest[0] = a00*c + a20*-s; dest[1] = a01*c + a21*-s; dest[2] = a02*c + a22*-s; dest[3] = a03*c + a23*-s; dest[8] = a00*s + a20*c; dest[9] = a01*s + a21*c; dest[10] = a02*s + a22*c; dest[11] = a03*s + a23*c; return dest; }; /* * mat4.rotateZ * Rotates a matrix by the given angle around the Z axis * * Params: * mat - mat4 to rotate * angle - angle (in radians) to rotate * dest - Optional, mat4 receiving operation result. If not specified result is written to mat * * Returns: * dest if specified, mat otherwise */ mat4.rotateZ = function(mat, angle, dest) { var s = Math.sin(angle); var c = Math.cos(angle); // Cache the matrix values (makes for huge speed increases!) var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3]; var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7]; if(!dest) { dest = mat } else if(mat != dest) { // If the source and destination differ, copy the unchanged last row dest[8] = mat[8]; dest[9] = mat[9]; dest[10] = mat[10]; dest[11] = mat[11]; dest[12] = mat[12]; dest[13] = mat[13]; dest[14] = mat[14]; dest[15] = mat[15]; } // Perform axis-specific matrix multiplication dest[0] = a00*c + a10*s; dest[1] = a01*c + a11*s; dest[2] = a02*c + a12*s; dest[3] = a03*c + a13*s; dest[4] = a00*-s + a10*c; dest[5] = a01*-s + a11*c; dest[6] = a02*-s + a12*c; dest[7] = a03*-s + a13*c; return dest; }; /* * mat4.frustum * Generates a frustum matrix with the given bounds * * Params: * left, right - scalar, left and right bounds of the frustum * bottom, top - scalar, bottom and top bounds of the frustum * near, far - scalar, near and far bounds of the frustum * dest - Optional, mat4 frustum matrix will be written into * * Returns: * dest if specified, a new mat4 otherwise */ mat4.frustum = function(left, right, bottom, top, near, far, dest) { if(!dest) { dest = mat4.create(); } var rl = (right - left); var tb = (top - bottom); var fn = (far - near); dest[0] = (near*2) / rl; dest[1] = 0; dest[2] = 0; dest[3] = 0; dest[4] = 0; dest[5] = (near*2) / tb; dest[6] = 0; dest[7] = 0; dest[8] = (right + left) / rl; dest[9] = (top + bottom) / tb; dest[10] = -(far + near) / fn; dest[11] = -1; dest[12] = 0; dest[13] = 0; dest[14] = -(far*near*2) / fn; dest[15] = 0; return dest; }; /* * mat4.perspective * Generates a perspective projection matrix with the given bounds * * Params: * fovy - scalar, vertical field of view * aspect - scalar, aspect ratio. typically viewport width/height * near, far - scalar, near and far bounds of the frustum * dest - Optional, mat4 frustum matrix will be written into * * Returns: * dest if specified, a new mat4 otherwise */ mat4.perspective = function(fovy, aspect, near, far, dest) { var top = near*Math.tan(fovy*Math.PI / 360.0); var right = top*aspect; return mat4.frustum(-right, right, -top, top, near, far, dest); }; /* * mat4.ortho * Generates a orthogonal projection matrix with the given bounds * * Params: * left, right - scalar, left and right bounds of the frustum * bottom, top - scalar, bottom and top bounds of the frustum * near, far - scalar, near and far bounds of the frustum * dest - Optional, mat4 frustum matrix will be written into * * Returns: * dest if specified, a new mat4 otherwise */ mat4.ortho = function(left, right, bottom, top, near, far, dest) { if(!dest) { dest = mat4.create(); } var rl = (right - left); var tb = (top - bottom); var fn = (far - near); dest[0] = 2 / rl; dest[1] = 0; dest[2] = 0; dest[3] = 0; dest[4] = 0; dest[5] = 2 / tb; dest[6] = 0; dest[7] = 0; dest[8] = 0; dest[9] = 0; dest[10] = -2 / fn; dest[11] = 0; dest[12] = -(left + right) / rl; dest[13] = -(top + bottom) / tb; dest[14] = -(far + near) / fn; dest[15] = 1; return dest; }; /* * mat4.ortho * Generates a look-at matrix with the given eye position, focal point, and up axis * * Params: * eye - vec3, position of the viewer * center - vec3, point the viewer is looking at * up - vec3 pointing "up" * dest - Optional, mat4 frustum matrix will be written into * * Returns: * dest if specified, a new mat4 otherwise */ mat4.lookAt = function(eye, center, up, dest) { if(!dest) { dest = mat4.create(); } var eyex = eye[0], eyey = eye[1], eyez = eye[2], upx = up[0], upy = up[1], upz = up[2], centerx = center[0], centery = center[1], centerz = center[2]; if (eyex == centerx && eyey == centery && eyez == centerz) { return mat4.identity(dest); } var z0,z1,z2,x0,x1,x2,y0,y1,y2,len; //vec3.direction(eye, center, z); z0 = eyex - center[0]; z1 = eyey - center[1]; z2 = eyez - center[2]; // normalize (no check needed for 0 because of early return) len = 1/Math.sqrt(z0*z0 + z1*z1 + z2*z2); z0 *= len; z1 *= len; z2 *= len; //vec3.normalize(vec3.cross(up, z, x)); x0 = upy*z2 - upz*z1; x1 = upz*z0 - upx*z2; x2 = upx*z1 - upy*z0; len = Math.sqrt(x0*x0 + x1*x1 + x2*x2); if (!len) { x0 = 0; x1 = 0; x2 = 0; } else { len = 1/len; x0 *= len; x1 *= len; x2 *= len; }; //vec3.normalize(vec3.cross(z, x, y)); y0 = z1*x2 - z2*x1; y1 = z2*x0 - z0*x2; y2 = z0*x1 - z1*x0; len = Math.sqrt(y0*y0 + y1*y1 + y2*y2); if (!len) { y0 = 0; y1 = 0; y2 = 0; } else { len = 1/len; y0 *= len; y1 *= len; y2 *= len; } dest[0] = x0; dest[1] = y0; dest[2] = z0; dest[3] = 0; dest[4] = x1; dest[5] = y1; dest[6] = z1; dest[7] = 0; dest[8] = x2; dest[9] = y2; dest[10] = z2; dest[11] = 0; dest[12] = -(x0*eyex + x1*eyey + x2*eyez); dest[13] = -(y0*eyex + y1*eyey + y2*eyez); dest[14] = -(z0*eyex + z1*eyey + z2*eyez); dest[15] = 1; return dest; }; /* * mat4.str * Returns a string representation of a mat4 * * Params: * mat - mat4 to represent as a string * * Returns: * string representation of mat */ mat4.str = function(mat) { return '[' + mat[0] + ', ' + mat[1] + ', ' + mat[2] + ', ' + mat[3] + ', '+ mat[4] + ', ' + mat[5] + ', ' + mat[6] + ', ' + mat[7] + ', '+ mat[8] + ', ' + mat[9] + ', ' + mat[10] + ', ' + mat[11] + ', '+ mat[12] + ', ' + mat[13] + ', ' + mat[14] + ', ' + mat[15] + ']'; }; /* * quat4 - Quaternions */ quat4 = {}; /* * quat4.create * Creates a new instance of a quat4 using the default array type * Any javascript array containing at least 4 numeric elements can serve as a quat4 * * Params: * quat - Optional, quat4 containing values to initialize with * * Returns: * New quat4 */ quat4.create = function(quat) { var dest = new glMatrixArrayType(4); if(quat) { dest[0] = quat[0]; dest[1] = quat[1]; dest[2] = quat[2]; dest[3] = quat[3]; } return dest; }; /* * quat4.set * Copies the values of one quat4 to another * * Params: * quat - quat4 containing values to copy * dest - quat4 receiving copied values * * Returns: * dest */ quat4.set = function(quat, dest) { dest[0] = quat[0]; dest[1] = quat[1]; dest[2] = quat[2]; dest[3] = quat[3]; return dest; }; /* * quat4.calculateW * Calculates the W component of a quat4 from the X, Y, and Z components. * Assumes that quaternion is 1 unit in length. * Any existing W component will be ignored. * * Params: * quat - quat4 to calculate W component of * dest - Optional, quat4 receiving calculated values. If not specified result is written to quat * * Returns: * dest if specified, quat otherwise */ quat4.calculateW = function(quat, dest) { var x = quat[0], y = quat[1], z = quat[2]; if(!dest || quat == dest) { quat[3] = -Math.sqrt(Math.abs(1.0 - x*x - y*y - z*z)); return quat; } dest[0] = x; dest[1] = y; dest[2] = z; dest[3] = -Math.sqrt(Math.abs(1.0 - x*x - y*y - z*z)); return dest; } /* * quat4.inverse * Calculates the inverse of a quat4 * * Params: * quat - quat4 to calculate inverse of * dest - Optional, quat4 receiving inverse values. If not specified result is written to quat * * Returns: * dest if specified, quat otherwise */ quat4.inverse = function(quat, dest) { if(!dest || quat == dest) { quat[0] *= 1; quat[1] *= 1; quat[2] *= 1; return quat; } dest[0] = -quat[0]; dest[1] = -quat[1]; dest[2] = -quat[2]; dest[3] = quat[3]; return dest; } /* * quat4.length * Calculates the length of a quat4 * * Params: * quat - quat4 to calculate length of * * Returns: * Length of quat */ quat4.length = function(quat) { var x = quat[0], y = quat[1], z = quat[2], w = quat[3]; return Math.sqrt(x*x + y*y + z*z + w*w); } /* * quat4.normalize * Generates a unit quaternion of the same direction as the provided quat4 * If quaternion length is 0, returns [0, 0, 0, 0] * * Params: * quat - quat4 to normalize * dest - Optional, quat4 receiving operation result. If not specified result is written to quat * * Returns: * dest if specified, quat otherwise */ quat4.normalize = function(quat, dest) { if(!dest) { dest = quat; } var x = quat[0], y = quat[1], z = quat[2], w = quat[3]; var len = Math.sqrt(x*x + y*y + z*z + w*w); if(len == 0) { dest[0] = 0; dest[1] = 0; dest[2] = 0; dest[3] = 0; return dest; } len = 1/len; dest[0] = x * len; dest[1] = y * len; dest[2] = z * len; dest[3] = w * len; return dest; } /* * quat4.multiply * Performs a quaternion multiplication * * Params: * quat - quat4, first operand * quat2 - quat4, second operand * dest - Optional, quat4 receiving operation result. If not specified result is written to quat * * Returns: * dest if specified, quat otherwise */ quat4.multiply = function(quat, quat2, dest) { if(!dest) { dest = quat; } var qax = quat[0], qay = quat[1], qaz = quat[2], qaw = quat[3]; var qbx = quat2[0], qby = quat2[1], qbz = quat2[2], qbw = quat2[3]; dest[0] = qax*qbw + qaw*qbx + qay*qbz - qaz*qby; dest[1] = qay*qbw + qaw*qby + qaz*qbx - qax*qbz; dest[2] = qaz*qbw + qaw*qbz + qax*qby - qay*qbx; dest[3] = qaw*qbw - qax*qbx - qay*qby - qaz*qbz; return dest; } /* * quat4.multiplyVec3 * Transforms a vec3 with the given quaternion * * Params: * quat - quat4 to transform the vector with * vec - vec3 to transform * dest - Optional, vec3 receiving operation result. If not specified result is written to vec * * Returns: * dest if specified, vec otherwise */ quat4.multiplyVec3 = function(quat, vec, dest) { if(!dest) { dest = vec; } var x = vec[0], y = vec[1], z = vec[2]; var qx = quat[0], qy = quat[1], qz = quat[2], qw = quat[3]; // calculate quat * vec var ix = qw*x + qy*z - qz*y; var iy = qw*y + qz*x - qx*z; var iz = qw*z + qx*y - qy*x; var iw = -qx*x - qy*y - qz*z; // calculate result * inverse quat dest[0] = ix*qw + iw*-qx + iy*-qz - iz*-qy; dest[1] = iy*qw + iw*-qy + iz*-qx - ix*-qz; dest[2] = iz*qw + iw*-qz + ix*-qy - iy*-qx; return dest; } /* * quat4.toMat3 * Calculates a 3x3 matrix from the given quat4 * * Params: * quat - quat4 to create matrix from * dest - Optional, mat3 receiving operation result * * Returns: * dest if specified, a new mat3 otherwise */ quat4.toMat3 = function(quat, dest) { if(!dest) { dest = mat3.create(); } var x = quat[0], y = quat[1], z = quat[2], w = quat[3]; var x2 = x + x; var y2 = y + y; var z2 = z + z; var xx = x*x2; var xy = x*y2; var xz = x*z2; var yy = y*y2; var yz = y*z2; var zz = z*z2; var wx = w*x2; var wy = w*y2; var wz = w*z2; dest[0] = 1 - (yy + zz); dest[1] = xy - wz; dest[2] = xz + wy; dest[3] = xy + wz; dest[4] = 1 - (xx + zz); dest[5] = yz - wx; dest[6] = xz - wy; dest[7] = yz + wx; dest[8] = 1 - (xx + yy); return dest; } /* * quat4.toMat4 * Calculates a 4x4 matrix from the given quat4 * * Params: * quat - quat4 to create matrix from * dest - Optional, mat4 receiving operation result * * Returns: * dest if specified, a new mat4 otherwise */ quat4.toMat4 = function(quat, dest) { if(!dest) { dest = mat4.create(); } var x = quat[0], y = quat[1], z = quat[2], w = quat[3]; var x2 = x + x; var y2 = y + y; var z2 = z + z; var xx = x*x2; var xy = x*y2; var xz = x*z2; var yy = y*y2; var yz = y*z2; var zz = z*z2; var wx = w*x2; var wy = w*y2; var wz = w*z2; dest[0] = 1 - (yy + zz); dest[1] = xy - wz; dest[2] = xz + wy; dest[3] = 0; dest[4] = xy + wz; dest[5] = 1 - (xx + zz); dest[6] = yz - wx; dest[7] = 0; dest[8] = xz - wy; dest[9] = yz + wx; dest[10] = 1 - (xx + yy); dest[11] = 0; dest[12] = 0; dest[13] = 0; dest[14] = 0; dest[15] = 1; return dest; } /* * quat4.slerp * Performs a spherical linear interpolation between two quat4 * * Params: * quat - quat4, first quaternion * quat2 - quat4, second quaternion * lerp - interpolation amount between the two inputs * dest - Optional, quat4 receiving operation result. If not specified result is written to quat * * Returns: * dest if specified, quat otherwise */ quat4.slerp = function(quat, quat2, lerp, dest) { if(!dest) { dest = quat; } var eps_lerp = lerp; var dot = quat[0]*quat2[0] + quat[1]*quat2[1] + quat[2]*quat2[2] + quat[3]*quat2[3]; if (dot < 0.0) { eps_lerp = -1.0 * lerp; } dest[0] = 1.0 - lerp * quat[0] + eps_lerp * quat2[0]; dest[1] = 1.0 - lerp * quat[1] + eps_lerp * quat2[1]; dest[2] = 1.0 - lerp * quat[2] + eps_lerp * quat2[2]; dest[3] = 1.0 - lerp * quat[3] + eps_lerp * quat2[3]; return dest; } /* * quat4.str * Returns a string representation of a quaternion * * Params: * quat - quat4 to represent as a string * * Returns: * string representation of quat */ quat4.str = function(quat) { return '[' + quat[0] + ', ' + quat[1] + ', ' + quat[2] + ', ' + quat[3] + ']'; } rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/priv/www/visualiser/js/physics.js0000644000177700017770000000667112633765070033461 0ustar michaelmichael/*global octtree, vec3 */ function Newton() { } Newton.prototype.friction = 100; Newton.prototype.update = function (elapsed, obj) { var incr; vec3.scale(obj.velocity, 1 - (this.friction * elapsed)); incr = vec3.create(obj.velocity); vec3.scale(incr, elapsed); vec3.add(obj.pos, incr, obj.next_pos); }; function Spring() { } Spring.prototype.k = 1; Spring.prototype.equilibriumLength = 2; Spring.prototype.push = true; Spring.prototype.pull = true; Spring.prototype.dampingFactor = 0.5; Spring.prototype.octtreeRadius = 4; Spring.prototype.octtreeLimit = 40; Spring.prototype.apply = function (elapsed, obj1, obj2) { var damper, vecOP, distanceOP, x; damper = this.dampingFactor * elapsed * 100000; vecOP = vec3.create(); distanceOP = 0; x = 0; vec3.subtract(obj2.pos, obj1.pos, vecOP); distanceOP = vec3.length(vecOP); if (!isNaN(distanceOP) && 0 !== distanceOP) { x = distanceOP - this.equilibriumLength; if (distanceOP > this.equilibriumLength && !this.pull) { return; } if (distanceOP < this.equilibriumLength && !this.push) { return; } vec3.scale(vecOP, (damper * (((1 / distanceOP) * x) / obj1.mass))); vec3.add(obj1.velocity, vecOP); } }; Spring.prototype.update = function (elapsed, tree, obj) { var damper, vecOP, distanceOP, x, found, i, obj1; damper = this.dampingFactor * elapsed * 100000; vecOP = vec3.create(); distanceOP = 0; x = 0; found = tree.findInRadius(obj.pos, this.octtreeRadius, this.octtreeLimit); for (i = 0; i < found.length; i += 1) { obj1 = found[i].value; if (obj1 !== obj) { // F = -k x where x is difference from equilibriumLength // a = F / m vec3.subtract(obj1.pos, obj.pos, vecOP); distanceOP = vec3.length(vecOP); if (!isNaN(distanceOP) && 0 !== distanceOP) { x = distanceOP - this.equilibriumLength; if (distanceOP > this.equilibriumLength && !this.pull) { continue; } if (distanceOP < this.equilibriumLength && !this.push) { continue; } vec3.scale(vecOP, (damper * (((1 / distanceOP) * x) / obj.mass))); vec3.add(obj.velocity, vecOP); } } } }; function Gravity() { } Gravity.prototype.bigG = 1 / 20; Gravity.prototype.octtreeRadius = 5; Gravity.prototype.octtreeLimit = 20; Gravity.prototype.repel = false; Gravity.prototype.update = function (elapsed, tree, obj) { var vecOP, distanceOP, found, i, obj1; vecOP = vec3.create(); distanceOP = 0; found = tree.findInRadius(obj.pos, this.octtreeRadius, this.octtreeLimit); for (i = 0; i < found.length; i += 1) { obj1 = found[i].value; if (obj1 !== obj) { // F = G.m1.m2 / (d.d) // a = F / m1 // thus a = G.m2/(d.d) vec3.subtract(obj1.pos, obj.pos, vecOP); distanceOP = vec3.length(vecOP); if ((!(isNaN(distanceOP))) && 0 !== distanceOP) { vec3.scale(vecOP, (this.bigG * obj1.mass) / (distanceOP * distanceOP)); if (this.repel) { vec3.subtract(obj.velocity, vecOP); } else { vec3.add(obj.velocity, vecOP); } } } } }; rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/priv/www/visualiser/js/main.js0000644000177700017770000005224512633765070032721 0ustar michaelmichael/*global octtree, vec3, Model, Channel, Exchange, Queue, Binding, Newton, Spring, window */ /*jslint browser: true, devel: true */ var tree = octtree.create(0, 10000, 0, 1000000, -0.5, 2); var updatePeriod = 1000; // 1 second var configuration, detailsInFlight, mouseDragOffsetVec, hoveringOver, dragging, selectedVhost, ctx, canvas, tick, mouseMove, setCanvasMousemove, requestAnimFrame; var client = new XMLHttpRequest(); var detailsClient = new XMLHttpRequest(); var model = new Model(); var mousePos = vec3.create(); var mouseDown = false; var highlight = "#ffffc0"; var faded = "#c0c0c0"; var eta = 0.1; var max_v = 100000; var newton = new Newton(); var spring = new Spring(); spring.octtreeRadius = 500; spring.equilibriumLength = 50; spring.dampingFactor = 0.01; spring.pull = false; spring.push = true; var rendering = true; var lastTime = 0; var fontSize = 12; Exchange.prototype.fontSize = fontSize; Queue.prototype.fontSize = fontSize; Binding.prototype.fontSize = fontSize; var canvasLeft = 0; var canvasTop = 0; var scrollLeft = 0; var scrollTop = 0; var clientWidth = 0; var clientHeight = 0; /****************************************************************************** * Fetching details from the broker * ******************************************************************************/ function update() { if (undefined === selectedVhost) { client.open("GET", "../api/all"); } else { client.open("GET", "../api/all/" + encodeURIComponent(selectedVhost)); } client.send(); } function updateReady() { if (client.readyState === 4 && client.status === 200) { setTimeout(update, updatePeriod); configuration = JSON.parse(client.responseText); model.rebuild(tree, configuration); if (!rendering) { lastTime = 0; requestAnimFrame(tick); } } } client.onreadystatechange = updateReady; function getDetails() { detailsInFlight = this; detailsClient.abort(); detailsClient.open("GET", "../api" + this.url()); detailsClient.send(); } Channel.prototype.getDetails = getDetails; Exchange.prototype.getDetails = getDetails; Queue.prototype.getDetails = getDetails; function repeatGetDetails() { if (undefined !== hoveringOver) { hoveringOver.getDetails(); } } function flattenAtts(a) { if ("string" === typeof a) { return a; } else { var str, e; str = "{"; for (e in a) { if (a.hasOwnProperty(e)) { str += "" + e + ": " + flattenAtts(a[e]) + ", "; } } return str.replace(/(, )?$/, "}"); } } function setDetails(elem) { var details, strAtts, visibleRows, columns, column, str, attName, i; details = document.getElementById("details"); if (undefined === elem) { details.innerHTML = ""; detailsInFlight = undefined; } else { strAtts = elem.stringAttributes(); visibleRows = Math.floor(details.clientHeight / 16); // line-height + padding; columns = Math.ceil(strAtts.attributeOrder.length / visibleRows); column = 0; str = ""; for (i in strAtts.attributeOrder) { column += 1; attName = strAtts.attributeOrder[i]; if (undefined !== strAtts[attName]) { str += ""; } else { str += ""; } if (column === columns) { column = 0; str += ""; } } str += "
    " + attName + "" + flattenAtts(strAtts[attName]) + "" + attName + "
    "; document.getElementById("details").innerHTML = str; } } function detailsUpdateReady() { if (detailsClient.readyState === 4 && detailsClient.status === 200 && undefined !== hoveringOver && undefined !== detailsInFlight && hoveringOver.object_type === detailsInFlight.object_type && hoveringOver.name === detailsInFlight.name) { try { var details = JSON.parse(detailsClient.responseText); if (undefined !== details.name && details.name === detailsInFlight.name) { model[detailsInFlight.object_type][detailsInFlight.name].details = details; setDetails(model[detailsInFlight.object_type][detailsInFlight.name]); setTimeout(repeatGetDetails, updatePeriod); } } catch (err) { // We probably cancelled it as we were receiving data. model[detailsInFlight.object_type][detailsInFlight.name].details = undefined; window.console.info("" + err); } } } detailsClient.onreadystatechange = detailsUpdateReady; /****************************************************************************** * Rendering / animation * ******************************************************************************/ requestAnimFrame = (function () { return (this.requestAnimationFrame || this.webkitRequestAnimationFrame || this.mozRequestAnimationFrame || this.oRequestAnimationFrame || this.msRequestAnimationFrame || function (/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) { setTimeout(callback, 1000 / 60); }); })(); function recordMousePos(e) { var x, y; x = e.pageX; y = e.pageY; x = (x - canvasLeft) + scrollLeft; y = (y - canvasTop) + scrollTop; mousePos[octtree.x] = x; mousePos[octtree.y] = y; } mouseMove = function (e) { recordMousePos(e); canvas.onmousemove = undefined; setTimeout(setCanvasMousemove, 10); }; setCanvasMousemove = function () { if (rendering) { canvas.onmousemove = mouseMove; } }; function resizeCanvas() { var e; if (undefined !== canvas) { canvas.width = canvas.parentNode.offsetWidth; canvas.height = canvas.parentNode.offsetHeight; Channel.prototype.canvasResized(canvas); Exchange.prototype.canvasResized(canvas); Queue.prototype.canvasResized(canvas); clientWidth = canvas.width; clientHeight = canvas.height; e = canvas.parentNode; while (undefined !== e && null !== e) { if (undefined !== e.clientHeight && undefined !== e.clientWidth && e.clientHeight > 0 && e.clientWidth > 0) { clientHeight = Math.min(clientHeight, e.clientHeight); clientWidth = Math.min(clientWidth, e.clientWidth); } e = e.parentNode; } canvasLeft = 0; canvasTop = 0; e = canvas.parentNode; while (undefined !== e && null !== e) { if (undefined !== e.offsetLeft && undefined !== e.offsetTop) { canvasLeft += e.offsetLeft; canvasTop += e.offsetTop; } e = e.parentNode; } if (undefined !== hoveringOver && undefined !== hoveringOver.details) { setDetails(hoveringOver); } } } function canvasScroll() { scrollLeft = 0; scrollTop = 0; var e = canvas.parentNode; while (undefined !== e && null !== e) { if (undefined !== e.scrollLeft && undefined !== e.scrollTop) { scrollLeft += e.scrollLeft; scrollTop += e.scrollTop; } e = e.parentNode; } } function clamp(elem) { var x_vel_abs, y_vel_abs; x_vel_abs = Math.abs(elem.velocity[octtree.x]); y_vel_abs = Math.abs(elem.velocity[octtree.y]); if (0 !== x_vel_abs && eta > x_vel_abs) { elem.velocity[octtree.x] = 0; } else if (max_v < x_vel_abs) { elem.velocity[octtree.x] = max_v * (x_vel_abs / elem.velocity[octtree.x]); } if (0 !== y_vel_abs && eta > y_vel_abs) { elem.velocity[octtree.y] = 0; } else if (max_v < y_vel_abs) { elem.velocity[octtree.y] = max_v * (y_vel_abs / elem.velocity[octtree.y]); } if (elem.next_pos[octtree.x] < 1) { elem.next_pos[octtree.x] = 1; elem.velocity[octtree.x] = 0; } if (elem.next_pos[octtree.y] < 1) { elem.next_pos[octtree.y] = 1; elem.velocity[octtree.y] = 0; } if (elem.next_pos[octtree.x] >= canvas.width) { elem.next_pos[octtree.x] = canvas.width - 1; } if (elem.next_pos[octtree.y] >= (canvas.height - 100)) { canvas.height += 100; } } function initCanvas() { resizeCanvas(); setCanvasMousemove(); canvas.onmousedown = function (e) { recordMousePos(e); if (e.shiftKey && undefined !== hoveringOver) { model.disable(hoveringOver, tree); mouseDown = false; hoveringOver = undefined; dragging = undefined; } else { mouseDown = true; mouseDragOffsetVec = undefined; } }; canvas.ondblclick = function (e) { recordMousePos(e); if (undefined !== hoveringOver) { hoveringOver.navigateTo(); } }; canvas.onmouseup = function (e) { recordMousePos(e); mouseDown = false; mouseDragOffsetVec = undefined; dragging = undefined; }; try { ctx = canvas.getContext("2d"); } catch (e) { } if (!ctx) { alert("Could not initialise 2D canvas. Change browser?"); } } function drawScene() { ctx.font = "" + fontSize + "px sans-serif"; ctx.clearRect(scrollLeft, scrollTop, clientWidth, clientHeight); ctx.lineWidth = 1.0; ctx.lineCap = "round"; ctx.lineJoin = "round"; ctx.strokeStyle = "black"; model.render(ctx); } function animate() { var timeNow, elapsed, e, i; timeNow = new Date().getTime(); if (lastTime !== 0) { elapsed = (timeNow - lastTime) / 10000; for (i in model.exchange) { e = model.exchange[i]; if ((undefined === dragging || dragging !== e) && ! e.disabled) { e.animate(elapsed); newton.update(elapsed, e); spring.update(elapsed, tree, e); clamp(e); } } for (i in model.channel) { e = model.channel[i]; if ((undefined === dragging || dragging !== e) && ! e.disabled) { e.animate(elapsed); newton.update(elapsed, e); spring.update(elapsed, tree, e); clamp(e); } } for (i in model.queue) { e = model.queue[i]; if ((undefined === dragging || dragging !== e) && ! e.disabled) { e.animate(elapsed); newton.update(elapsed, e); spring.update(elapsed, tree, e); clamp(e); } } tree.update(); } lastTime = timeNow; } tick = function () { drawScene(); animate(); if (rendering) { requestAnimFrame(tick); } }; function visualisationStart() { canvas = document.getElementById("topology_canvas"); initCanvas(); update(); requestAnimFrame(tick); } // Used to start/stop doing work when we gain/lose focus function enableRendering() { lastTime = 0; rendering = true; setCanvasMousemove(); requestAnimFrame(tick); } function disableRendering() { canvas.onmousemove = undefined; rendering = false; } /****************************************************************************** * Model callbacks for rendering * ******************************************************************************/ function draggable(model, ctx) { var inPath = ctx.isPointInPath(mousePos[octtree.x], mousePos[octtree.y]); if ((inPath && undefined === hoveringOver) || dragging === this || hoveringOver === this) { ctx.fillStyle = highlight; ctx.fill(); if (hoveringOver !== this) { this.getDetails(); } hoveringOver = this; if (mouseDown) { dragging = this; if (undefined === mouseDragOffsetVec) { mouseDragOffsetVec = vec3.create(this.pos); vec3.subtract(mouseDragOffsetVec, mousePos); } vec3.set(mousePos, this.next_pos); vec3.add(this.next_pos, mouseDragOffsetVec); this.velocity = vec3.create(); clamp(this); } else if (!inPath) { if (undefined !== hoveringOver) { hoveringOver.details = undefined; } if (detailsInFlight === this) { setDetails(undefined); } dragging = undefined; hoveringOver = undefined; mouseDragOffsetVec = undefined; } } else { ctx.fillStyle = "white"; ctx.fill(); } if (undefined !== hoveringOver && hoveringOver !== this && ! model.isHighlighted(this)) { ctx.strokeStyle = faded; } ctx.stroke(); } Channel.prototype.preStroke = draggable; Exchange.prototype.preStroke = draggable; Queue.prototype.preStroke = draggable; Binding.prototype.preStroke = function (source, destination, model, ctx) { var drawBindingKeys, xMid, yMid, bindingKey, k, dim; drawBindingKeys = false; if (undefined === hoveringOver) { drawBindingKeys = ctx.isPointInPath(mousePos[octtree.x], mousePos[octtree.y]); } else { if (hoveringOver === source) { ctx.strokeStyle = "#0000a0"; drawBindingKeys = true; } else if (hoveringOver === destination) { ctx.strokeStyle = "#00a000"; drawBindingKeys = true; } else { ctx.strokeStyle = faded; } } ctx.stroke(); if (drawBindingKeys) { xMid = (source.xMax + destination.xMin) / 2; yMid = source === destination ? source.pos[octtree.y] - this.loopOffset + fontSize : (source.pos[octtree.y] + destination.pos[octtree.y]) / 2; bindingKey = ""; for (k in this.keys) { bindingKey += ", " + k; } bindingKey = bindingKey.slice(2); dim = ctx.measureText(bindingKey); ctx.textBaseline = "middle"; ctx.textAlign = "center"; ctx.fillStyle = "rgba(255, 255, 255, 0.67)"; ctx.fillRect(xMid - (dim.width / 2), yMid - (this.fontSize / 2), dim.width, this.fontSize); ctx.fillStyle = ctx.strokeStyle; ctx.fillText(bindingKey, xMid, yMid); } }; function frustumCull(xMin, yMin, width, height) { return ((yMin > (scrollTop + clientHeight)) || ((yMin + height) < scrollTop) || (xMin > (scrollLeft + clientWidth)) || ((xMin + width) < scrollLeft)); } Model.prototype.cull = frustumCull; /****************************************************************************** * Showing / hiding / removing resources * ******************************************************************************/ function selectInsertAlphabetical(selectElem, optionElem) { var preceding, i; for (i = 0; i < selectElem.options.length; i += 1) { if (optionElem.text < selectElem.options[i].text) { preceding = selectElem.options[i]; break; } } selectElem.add(optionElem, preceding); return selectElem.options; } function show(hiddenElemId, model, type) { var i, e, hidden; if (model.rendering[type].enabled) { hidden = document.getElementById(hiddenElemId); for (i = 0; i < hidden.options.length; i += 1) { e = hidden.options[i]; if (e.selected) { model.enable(model[type][e.value], tree); hidden.remove(i); i -= 1; } } } } function showChannels() { show("hidden_channels", model, 'channel'); } function showExchanges() { show("hidden_exchanges", model, 'exchange'); } function showQueues() { show("hidden_queues", model, 'queue'); } // Called when the resource is enabled from being hidden function enable_fun(type, postFun) { return function (model, tree) { if (model.rendering[type].enabled) { delete model.rendering[type].on_enable[this.name]; } this.remove = Object.getPrototypeOf(this).remove; this.postFun = postFun; this.postFun(model, tree); }; } Channel.prototype.enable = enable_fun('channel', Channel.prototype.enable); Exchange.prototype.enable = enable_fun('exchange', Exchange.prototype.enable); Queue.prototype.enable = enable_fun('queue', Queue.prototype.enable); // Called when the item is removed and the item is disabled function remove_disabled_fun(hiddenElemId, postFun) { return function (tree, model) { var hidden, i; hidden = document.getElementById(hiddenElemId); for (i = 0; i < hidden.options.length; i += 1) { if (hidden.options[i].value === this.name) { hidden.remove(i); break; } } model.enable(this, tree); this.postFun = postFun; this.postFun(tree, model); }; } function disable_fun(hiddenElemId, type, postFun) { return function (model) { if (detailsInFlight === this) { setDetails(undefined); } var optionElem = document.createElement('option'); optionElem.text = '"' + this.name + '"'; if (undefined !== model.rendering[type].on_enable[this.name]) { optionElem.text += ' *'; } optionElem.value = this.name; selectInsertAlphabetical(document.getElementById(hiddenElemId), optionElem); this.remove = remove_disabled_fun(hiddenElemId, this.remove); this.postFun = postFun; this.postFun(model); }; } Channel.prototype.disable = disable_fun("hidden_channels", 'channel', Channel.prototype.disable); Exchange.prototype.disable = disable_fun("hidden_exchanges", 'exchange', Exchange.prototype.disable); Queue.prototype.disable = disable_fun("hidden_queues", 'queue', Queue.prototype.disable); // Called when the resource is deleted / vanishes on the broker function remove_fun(postFun, type) { return function (tree, model) { if (undefined !== hoveringOver && this === hoveringOver) { hoveringOver = undefined; dragging = undefined; } delete model.rendering[type].on_enable[this.name]; if (this === detailsInFlight) { setDetails(undefined); } this.postFun = postFun; this.postFun(tree, model); }; } Channel.prototype.remove = remove_fun(Channel.prototype.remove, 'channel'); Queue.prototype.remove = remove_fun(Queue.prototype.remove, 'queue'); Exchange.prototype.remove = remove_fun(Exchange.prototype.remove, 'exchange'); function toggleRendering(hiddenElemId, showButtonElemId, type) { var hidden, i, e; model.rendering[type].enabled = !model.rendering[type].enabled; if (model.rendering[type].enabled) { hidden = document.getElementById(hiddenElemId); for (i = 0; i < hidden.options.length; i += 1) { e = hidden.options[i].value; if (undefined !== model.rendering[type].on_enable[e]) { model.enable(model[type][e], tree); hidden.remove(i); i -= 1; } } document.getElementById(showButtonElemId).disabled = false; } else { for (i in model[type]) { if (! model[type][i].disabled) { model.rendering[type].on_enable[model[type][i].name] = true; model.disable(model[type][i], tree); } } document.getElementById(showButtonElemId).disabled = true; } return true; } function displayHelp() { document.getElementById('help').style.display = 'block'; } function hideHelp() { document.getElementById('help').style.display = 'none'; } /****************************************************************************** * VHost * ******************************************************************************/ Model.prototype.vhost_add = function (vhost) { var optionElem, options; optionElem = document.createElement('option'); optionElem.text = vhost.name; optionElem.value = vhost.name; options = selectInsertAlphabetical(document.getElementById('vhosts'), optionElem); if (options.length === 1) { selectedVhost = options[0].value; options[0].selected = true; } }; Model.prototype.vhost_remove = function (vhost) { var elem, i; elem = document.getElementById('vhosts'); for (i = 0; i < elem.options.length; i += 1) { if (elem.options[i].value === vhost.name) { elem.remove(i); break; } } }; function vhostChanged() { var elem, i, e, j; elem = document.getElementById('vhosts'); for (i = 0; i < elem.options.length; i += 1) { if (elem.options[i].selected && selectedVhost !== elem.options[i].value) { selectedVhost = elem.options[i].value; for (e in ['channel', 'exchange', 'queue']) { for (j in model[e]) { model[e][j].remove(tree, model); } } break; } } } ././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/priv/www/visualiser/js/glMatrix-min.jsrabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/priv/www/visualiser/js/glMatrix-min0000644000177700017770000003027412633765070033730 0ustar michaelmichael// glMatrix v0.9.5 glMatrixArrayType=typeof Float32Array!="undefined"?Float32Array:typeof WebGLFloatArray!="undefined"?WebGLFloatArray:Array;var vec3={};vec3.create=function(a){var b=new glMatrixArrayType(3);if(a){b[0]=a[0];b[1]=a[1];b[2]=a[2]}return b};vec3.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];return b};vec3.add=function(a,b,c){if(!c||a==c){a[0]+=b[0];a[1]+=b[1];a[2]+=b[2];return a}c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];return c}; vec3.subtract=function(a,b,c){if(!c||a==c){a[0]-=b[0];a[1]-=b[1];a[2]-=b[2];return a}c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];return c};vec3.negate=function(a,b){b||(b=a);b[0]=-a[0];b[1]=-a[1];b[2]=-a[2];return b};vec3.scale=function(a,b,c){if(!c||a==c){a[0]*=b;a[1]*=b;a[2]*=b;return a}c[0]=a[0]*b;c[1]=a[1]*b;c[2]=a[2]*b;return c}; vec3.normalize=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=Math.sqrt(c*c+d*d+e*e);if(g){if(g==1){b[0]=c;b[1]=d;b[2]=e;return b}}else{b[0]=0;b[1]=0;b[2]=0;return b}g=1/g;b[0]=c*g;b[1]=d*g;b[2]=e*g;return b};vec3.cross=function(a,b,c){c||(c=a);var d=a[0],e=a[1];a=a[2];var g=b[0],f=b[1];b=b[2];c[0]=e*b-a*f;c[1]=a*g-d*b;c[2]=d*f-e*g;return c};vec3.length=function(a){var b=a[0],c=a[1];a=a[2];return Math.sqrt(b*b+c*c+a*a)};vec3.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]}; vec3.direction=function(a,b,c){c||(c=a);var d=a[0]-b[0],e=a[1]-b[1];a=a[2]-b[2];b=Math.sqrt(d*d+e*e+a*a);if(!b){c[0]=0;c[1]=0;c[2]=0;return c}b=1/b;c[0]=d*b;c[1]=e*b;c[2]=a*b;return c};vec3.lerp=function(a,b,c,d){d||(d=a);d[0]=a[0]+c*(b[0]-a[0]);d[1]=a[1]+c*(b[1]-a[1]);d[2]=a[2]+c*(b[2]-a[2]);return d};vec3.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+"]"};var mat3={}; mat3.create=function(a){var b=new glMatrixArrayType(9);if(a){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9]}return b};mat3.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];return b};mat3.identity=function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=1;a[5]=0;a[6]=0;a[7]=0;a[8]=1;return a}; mat3.transpose=function(a,b){if(!b||a==b){var c=a[1],d=a[2],e=a[5];a[1]=a[3];a[2]=a[6];a[3]=c;a[5]=a[7];a[6]=d;a[7]=e;return a}b[0]=a[0];b[1]=a[3];b[2]=a[6];b[3]=a[1];b[4]=a[4];b[5]=a[7];b[6]=a[2];b[7]=a[5];b[8]=a[8];return b};mat3.toMat4=function(a,b){b||(b=mat4.create());b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=0;b[4]=a[3];b[5]=a[4];b[6]=a[5];b[7]=0;b[8]=a[6];b[9]=a[7];b[10]=a[8];b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return b}; mat3.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+"]"};var mat4={};mat4.create=function(a){var b=new glMatrixArrayType(16);if(a){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15]}return b}; mat4.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15];return b};mat4.identity=function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=1;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=1;a[11]=0;a[12]=0;a[13]=0;a[14]=0;a[15]=1;return a}; mat4.transpose=function(a,b){if(!b||a==b){var c=a[1],d=a[2],e=a[3],g=a[6],f=a[7],h=a[11];a[1]=a[4];a[2]=a[8];a[3]=a[12];a[4]=c;a[6]=a[9];a[7]=a[13];a[8]=d;a[9]=g;a[11]=a[14];a[12]=e;a[13]=f;a[14]=h;return a}b[0]=a[0];b[1]=a[4];b[2]=a[8];b[3]=a[12];b[4]=a[1];b[5]=a[5];b[6]=a[9];b[7]=a[13];b[8]=a[2];b[9]=a[6];b[10]=a[10];b[11]=a[14];b[12]=a[3];b[13]=a[7];b[14]=a[11];b[15]=a[15];return b}; mat4.determinant=function(a){var b=a[0],c=a[1],d=a[2],e=a[3],g=a[4],f=a[5],h=a[6],i=a[7],j=a[8],k=a[9],l=a[10],o=a[11],m=a[12],n=a[13],p=a[14];a=a[15];return m*k*h*e-j*n*h*e-m*f*l*e+g*n*l*e+j*f*p*e-g*k*p*e-m*k*d*i+j*n*d*i+m*c*l*i-b*n*l*i-j*c*p*i+b*k*p*i+m*f*d*o-g*n*d*o-m*c*h*o+b*n*h*o+g*c*p*o-b*f*p*o-j*f*d*a+g*k*d*a+j*c*h*a-b*k*h*a-g*c*l*a+b*f*l*a}; mat4.inverse=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=a[3],f=a[4],h=a[5],i=a[6],j=a[7],k=a[8],l=a[9],o=a[10],m=a[11],n=a[12],p=a[13],r=a[14],s=a[15],A=c*h-d*f,B=c*i-e*f,t=c*j-g*f,u=d*i-e*h,v=d*j-g*h,w=e*j-g*i,x=k*p-l*n,y=k*r-o*n,z=k*s-m*n,C=l*r-o*p,D=l*s-m*p,E=o*s-m*r,q=1/(A*E-B*D+t*C+u*z-v*y+w*x);b[0]=(h*E-i*D+j*C)*q;b[1]=(-d*E+e*D-g*C)*q;b[2]=(p*w-r*v+s*u)*q;b[3]=(-l*w+o*v-m*u)*q;b[4]=(-f*E+i*z-j*y)*q;b[5]=(c*E-e*z+g*y)*q;b[6]=(-n*w+r*t-s*B)*q;b[7]=(k*w-o*t+m*B)*q;b[8]=(f*D-h*z+j*x)*q; b[9]=(-c*D+d*z-g*x)*q;b[10]=(n*v-p*t+s*A)*q;b[11]=(-k*v+l*t-m*A)*q;b[12]=(-f*C+h*y-i*x)*q;b[13]=(c*C-d*y+e*x)*q;b[14]=(-n*u+p*B-r*A)*q;b[15]=(k*u-l*B+o*A)*q;return b};mat4.toRotationMat=function(a,b){b||(b=mat4.create());b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=0;b[13]=0;b[14]=0;b[15]=1;return b}; mat4.toMat3=function(a,b){b||(b=mat3.create());b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[4];b[4]=a[5];b[5]=a[6];b[6]=a[8];b[7]=a[9];b[8]=a[10];return b};mat4.toInverseMat3=function(a,b){var c=a[0],d=a[1],e=a[2],g=a[4],f=a[5],h=a[6],i=a[8],j=a[9],k=a[10],l=k*f-h*j,o=-k*g+h*i,m=j*g-f*i,n=c*l+d*o+e*m;if(!n)return null;n=1/n;b||(b=mat3.create());b[0]=l*n;b[1]=(-k*d+e*j)*n;b[2]=(h*d-e*f)*n;b[3]=o*n;b[4]=(k*c-e*i)*n;b[5]=(-h*c+e*g)*n;b[6]=m*n;b[7]=(-j*c+d*i)*n;b[8]=(f*c-d*g)*n;return b}; mat4.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],g=a[2],f=a[3],h=a[4],i=a[5],j=a[6],k=a[7],l=a[8],o=a[9],m=a[10],n=a[11],p=a[12],r=a[13],s=a[14];a=a[15];var A=b[0],B=b[1],t=b[2],u=b[3],v=b[4],w=b[5],x=b[6],y=b[7],z=b[8],C=b[9],D=b[10],E=b[11],q=b[12],F=b[13],G=b[14];b=b[15];c[0]=A*d+B*h+t*l+u*p;c[1]=A*e+B*i+t*o+u*r;c[2]=A*g+B*j+t*m+u*s;c[3]=A*f+B*k+t*n+u*a;c[4]=v*d+w*h+x*l+y*p;c[5]=v*e+w*i+x*o+y*r;c[6]=v*g+w*j+x*m+y*s;c[7]=v*f+w*k+x*n+y*a;c[8]=z*d+C*h+D*l+E*p;c[9]=z*e+C*i+D*o+E*r;c[10]=z* g+C*j+D*m+E*s;c[11]=z*f+C*k+D*n+E*a;c[12]=q*d+F*h+G*l+b*p;c[13]=q*e+F*i+G*o+b*r;c[14]=q*g+F*j+G*m+b*s;c[15]=q*f+F*k+G*n+b*a;return c};mat4.multiplyVec3=function(a,b,c){c||(c=b);var d=b[0],e=b[1];b=b[2];c[0]=a[0]*d+a[4]*e+a[8]*b+a[12];c[1]=a[1]*d+a[5]*e+a[9]*b+a[13];c[2]=a[2]*d+a[6]*e+a[10]*b+a[14];return c}; mat4.multiplyVec4=function(a,b,c){c||(c=b);var d=b[0],e=b[1],g=b[2];b=b[3];c[0]=a[0]*d+a[4]*e+a[8]*g+a[12]*b;c[1]=a[1]*d+a[5]*e+a[9]*g+a[13]*b;c[2]=a[2]*d+a[6]*e+a[10]*g+a[14]*b;c[3]=a[3]*d+a[7]*e+a[11]*g+a[15]*b;return c}; mat4.translate=function(a,b,c){var d=b[0],e=b[1];b=b[2];if(!c||a==c){a[12]=a[0]*d+a[4]*e+a[8]*b+a[12];a[13]=a[1]*d+a[5]*e+a[9]*b+a[13];a[14]=a[2]*d+a[6]*e+a[10]*b+a[14];a[15]=a[3]*d+a[7]*e+a[11]*b+a[15];return a}var g=a[0],f=a[1],h=a[2],i=a[3],j=a[4],k=a[5],l=a[6],o=a[7],m=a[8],n=a[9],p=a[10],r=a[11];c[0]=g;c[1]=f;c[2]=h;c[3]=i;c[4]=j;c[5]=k;c[6]=l;c[7]=o;c[8]=m;c[9]=n;c[10]=p;c[11]=r;c[12]=g*d+j*e+m*b+a[12];c[13]=f*d+k*e+n*b+a[13];c[14]=h*d+l*e+p*b+a[14];c[15]=i*d+o*e+r*b+a[15];return c}; mat4.scale=function(a,b,c){var d=b[0],e=b[1];b=b[2];if(!c||a==c){a[0]*=d;a[1]*=d;a[2]*=d;a[3]*=d;a[4]*=e;a[5]*=e;a[6]*=e;a[7]*=e;a[8]*=b;a[9]*=b;a[10]*=b;a[11]*=b;return a}c[0]=a[0]*d;c[1]=a[1]*d;c[2]=a[2]*d;c[3]=a[3]*d;c[4]=a[4]*e;c[5]=a[5]*e;c[6]=a[6]*e;c[7]=a[7]*e;c[8]=a[8]*b;c[9]=a[9]*b;c[10]=a[10]*b;c[11]=a[11]*b;c[12]=a[12];c[13]=a[13];c[14]=a[14];c[15]=a[15];return c}; mat4.rotate=function(a,b,c,d){var e=c[0],g=c[1];c=c[2];var f=Math.sqrt(e*e+g*g+c*c);if(!f)return null;if(f!=1){f=1/f;e*=f;g*=f;c*=f}var h=Math.sin(b),i=Math.cos(b),j=1-i;b=a[0];f=a[1];var k=a[2],l=a[3],o=a[4],m=a[5],n=a[6],p=a[7],r=a[8],s=a[9],A=a[10],B=a[11],t=e*e*j+i,u=g*e*j+c*h,v=c*e*j-g*h,w=e*g*j-c*h,x=g*g*j+i,y=c*g*j+e*h,z=e*c*j+g*h;e=g*c*j-e*h;g=c*c*j+i;if(d){if(a!=d){d[12]=a[12];d[13]=a[13];d[14]=a[14];d[15]=a[15]}}else d=a;d[0]=b*t+o*u+r*v;d[1]=f*t+m*u+s*v;d[2]=k*t+n*u+A*v;d[3]=l*t+p*u+B* v;d[4]=b*w+o*x+r*y;d[5]=f*w+m*x+s*y;d[6]=k*w+n*x+A*y;d[7]=l*w+p*x+B*y;d[8]=b*z+o*e+r*g;d[9]=f*z+m*e+s*g;d[10]=k*z+n*e+A*g;d[11]=l*z+p*e+B*g;return d};mat4.rotateX=function(a,b,c){var d=Math.sin(b);b=Math.cos(b);var e=a[4],g=a[5],f=a[6],h=a[7],i=a[8],j=a[9],k=a[10],l=a[11];if(c){if(a!=c){c[0]=a[0];c[1]=a[1];c[2]=a[2];c[3]=a[3];c[12]=a[12];c[13]=a[13];c[14]=a[14];c[15]=a[15]}}else c=a;c[4]=e*b+i*d;c[5]=g*b+j*d;c[6]=f*b+k*d;c[7]=h*b+l*d;c[8]=e*-d+i*b;c[9]=g*-d+j*b;c[10]=f*-d+k*b;c[11]=h*-d+l*b;return c}; mat4.rotateY=function(a,b,c){var d=Math.sin(b);b=Math.cos(b);var e=a[0],g=a[1],f=a[2],h=a[3],i=a[8],j=a[9],k=a[10],l=a[11];if(c){if(a!=c){c[4]=a[4];c[5]=a[5];c[6]=a[6];c[7]=a[7];c[12]=a[12];c[13]=a[13];c[14]=a[14];c[15]=a[15]}}else c=a;c[0]=e*b+i*-d;c[1]=g*b+j*-d;c[2]=f*b+k*-d;c[3]=h*b+l*-d;c[8]=e*d+i*b;c[9]=g*d+j*b;c[10]=f*d+k*b;c[11]=h*d+l*b;return c}; mat4.rotateZ=function(a,b,c){var d=Math.sin(b);b=Math.cos(b);var e=a[0],g=a[1],f=a[2],h=a[3],i=a[4],j=a[5],k=a[6],l=a[7];if(c){if(a!=c){c[8]=a[8];c[9]=a[9];c[10]=a[10];c[11]=a[11];c[12]=a[12];c[13]=a[13];c[14]=a[14];c[15]=a[15]}}else c=a;c[0]=e*b+i*d;c[1]=g*b+j*d;c[2]=f*b+k*d;c[3]=h*b+l*d;c[4]=e*-d+i*b;c[5]=g*-d+j*b;c[6]=f*-d+k*b;c[7]=h*-d+l*b;return c}; mat4.frustum=function(a,b,c,d,e,g,f){f||(f=mat4.create());var h=b-a,i=d-c,j=g-e;f[0]=e*2/h;f[1]=0;f[2]=0;f[3]=0;f[4]=0;f[5]=e*2/i;f[6]=0;f[7]=0;f[8]=(b+a)/h;f[9]=(d+c)/i;f[10]=-(g+e)/j;f[11]=-1;f[12]=0;f[13]=0;f[14]=-(g*e*2)/j;f[15]=0;return f};mat4.perspective=function(a,b,c,d,e){a=c*Math.tan(a*Math.PI/360);b=a*b;return mat4.frustum(-b,b,-a,a,c,d,e)}; mat4.ortho=function(a,b,c,d,e,g,f){f||(f=mat4.create());var h=b-a,i=d-c,j=g-e;f[0]=2/h;f[1]=0;f[2]=0;f[3]=0;f[4]=0;f[5]=2/i;f[6]=0;f[7]=0;f[8]=0;f[9]=0;f[10]=-2/j;f[11]=0;f[12]=-(a+b)/h;f[13]=-(d+c)/i;f[14]=-(g+e)/j;f[15]=1;return f}; mat4.lookAt=function(a,b,c,d){d||(d=mat4.create());var e=a[0],g=a[1];a=a[2];var f=c[0],h=c[1],i=c[2];c=b[1];var j=b[2];if(e==b[0]&&g==c&&a==j)return mat4.identity(d);var k,l,o,m;c=e-b[0];j=g-b[1];b=a-b[2];m=1/Math.sqrt(c*c+j*j+b*b);c*=m;j*=m;b*=m;k=h*b-i*j;i=i*c-f*b;f=f*j-h*c;if(m=Math.sqrt(k*k+i*i+f*f)){m=1/m;k*=m;i*=m;f*=m}else f=i=k=0;h=j*f-b*i;l=b*k-c*f;o=c*i-j*k;if(m=Math.sqrt(h*h+l*l+o*o)){m=1/m;h*=m;l*=m;o*=m}else o=l=h=0;d[0]=k;d[1]=h;d[2]=c;d[3]=0;d[4]=i;d[5]=l;d[6]=j;d[7]=0;d[8]=f;d[9]= o;d[10]=b;d[11]=0;d[12]=-(k*e+i*g+f*a);d[13]=-(h*e+l*g+o*a);d[14]=-(c*e+j*g+b*a);d[15]=1;return d};mat4.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+", "+a[9]+", "+a[10]+", "+a[11]+", "+a[12]+", "+a[13]+", "+a[14]+", "+a[15]+"]"};quat4={};quat4.create=function(a){var b=new glMatrixArrayType(4);if(a){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3]}return b};quat4.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];return b}; quat4.calculateW=function(a,b){var c=a[0],d=a[1],e=a[2];if(!b||a==b){a[3]=-Math.sqrt(Math.abs(1-c*c-d*d-e*e));return a}b[0]=c;b[1]=d;b[2]=e;b[3]=-Math.sqrt(Math.abs(1-c*c-d*d-e*e));return b};quat4.inverse=function(a,b){if(!b||a==b){a[0]*=1;a[1]*=1;a[2]*=1;return a}b[0]=-a[0];b[1]=-a[1];b[2]=-a[2];b[3]=a[3];return b};quat4.length=function(a){var b=a[0],c=a[1],d=a[2];a=a[3];return Math.sqrt(b*b+c*c+d*d+a*a)}; quat4.normalize=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=a[3],f=Math.sqrt(c*c+d*d+e*e+g*g);if(f==0){b[0]=0;b[1]=0;b[2]=0;b[3]=0;return b}f=1/f;b[0]=c*f;b[1]=d*f;b[2]=e*f;b[3]=g*f;return b};quat4.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],g=a[2];a=a[3];var f=b[0],h=b[1],i=b[2];b=b[3];c[0]=d*b+a*f+e*i-g*h;c[1]=e*b+a*h+g*f-d*i;c[2]=g*b+a*i+d*h-e*f;c[3]=a*b-d*f-e*h-g*i;return c}; quat4.multiplyVec3=function(a,b,c){c||(c=b);var d=b[0],e=b[1],g=b[2];b=a[0];var f=a[1],h=a[2];a=a[3];var i=a*d+f*g-h*e,j=a*e+h*d-b*g,k=a*g+b*e-f*d;d=-b*d-f*e-h*g;c[0]=i*a+d*-b+j*-h-k*-f;c[1]=j*a+d*-f+k*-b-i*-h;c[2]=k*a+d*-h+i*-f-j*-b;return c};quat4.toMat3=function(a,b){b||(b=mat3.create());var c=a[0],d=a[1],e=a[2],g=a[3],f=c+c,h=d+d,i=e+e,j=c*f,k=c*h;c=c*i;var l=d*h;d=d*i;e=e*i;f=g*f;h=g*h;g=g*i;b[0]=1-(l+e);b[1]=k-g;b[2]=c+h;b[3]=k+g;b[4]=1-(j+e);b[5]=d-f;b[6]=c-h;b[7]=d+f;b[8]=1-(j+l);return b}; quat4.toMat4=function(a,b){b||(b=mat4.create());var c=a[0],d=a[1],e=a[2],g=a[3],f=c+c,h=d+d,i=e+e,j=c*f,k=c*h;c=c*i;var l=d*h;d=d*i;e=e*i;f=g*f;h=g*h;g=g*i;b[0]=1-(l+e);b[1]=k-g;b[2]=c+h;b[3]=0;b[4]=k+g;b[5]=1-(j+e);b[6]=d-f;b[7]=0;b[8]=c-h;b[9]=d+f;b[10]=1-(j+l);b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return b};quat4.slerp=function(a,b,c,d){d||(d=a);var e=c;if(a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]<0)e=-1*c;d[0]=1-c*a[0]+e*b[0];d[1]=1-c*a[1]+e*b[1];d[2]=1-c*a[2]+e*b[2];d[3]=1-c*a[3]+e*b[3];return d}; quat4.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+"]"}; rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/src/0000755000177700017770000000000012633765070025610 5ustar michaelmichael././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/src/rabbitmq_management_visualiser.app.srcrabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/src/rabbitmq_management_visualiser.0000644000177700017770000000032212633765070034051 0ustar michaelmichael{application, rabbitmq_management_visualiser, [{description, "RabbitMQ Visualiser"}, {vsn, "%%VSN%%"}, {modules, []}, {registered, []}, {applications, [kernel, stdlib, rabbit, rabbitmq_management]}]}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/src/rabbit_visualiser_mgmt.erl0000644000177700017770000000171012633765070033050 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ Visualiser. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2011-2014 GoPivotal, Inc. All rights reserved. %% -module(rabbit_visualiser_mgmt). -behaviour(rabbit_mgmt_extension). -export([dispatcher/0, web_ui/0]). dispatcher() -> [{["all"], rabbit_mgmt_wm_all, []}, {["all", vhost], rabbit_mgmt_wm_all, []}]. web_ui() -> [{javascript, <<"visualiser.js">>}]. rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/src/rabbit_mgmt_wm_all.erl0000644000177700017770000000372412633765070032144 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ Visualiser. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2011-2014 GoPivotal, Inc. All rights reserved. -module(rabbit_mgmt_wm_all). -export([init/1, to_json/2, content_types_provided/2, is_authorized/2, resource_exists/2]). -import(rabbit_misc, [pget/2]). -include_lib("rabbitmq_management/include/rabbit_mgmt.hrl"). -include_lib("webmachine/include/webmachine.hrl"). -include_lib("amqp_client/include/amqp_client.hrl"). %%-------------------------------------------------------------------- init(_Config) -> {ok, #context{}}. content_types_provided(ReqData, Context) -> {[{"application/json", to_json}], ReqData, Context}. resource_exists(ReqData, Context) -> {case rabbit_mgmt_util:vhost(ReqData) of not_found -> false; _ -> true end, ReqData, Context}. to_json(ReqData, Context) -> rabbit_mgmt_util:reply( [{Key, Mod:augmented(ReqData, Context)} || {Key, Mod} <- [{queues, rabbit_mgmt_wm_queues}, {exchanges, rabbit_mgmt_wm_exchanges}, {bindings, rabbit_mgmt_wm_bindings}, {channels, rabbit_mgmt_wm_channels}, {connections, rabbit_mgmt_wm_connections}, {vhosts, rabbit_mgmt_wm_vhosts}] ], ReqData, Context). is_authorized(ReqData, Context) -> rabbit_mgmt_util:is_authorized(ReqData, Context). rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/README0000644000177700017770000000402112633765070025676 0ustar michaelmichaelRabbitMQ Visualiser =================== Usage ----- This is a plugin for the RabbitMQ Management Plugin that provides an HTML Canvas for rendering configured broker topology. The current main purpose of this is for diagnostics and comprehension of the current routing topology of the broker. The left of the canvas displays exchanges, the right displays queues, and the top displays channels. All of these items can be dragged around the canvas. They repel one another, and snap back into their predefined areas should they be released within the boundaries of those areas. Shift-clicking on an item hides it - it will be added to the relevant select box on the left. Hovering over an item shows at the top of the screen various details about the item. Double-clicking on the item will take you to the specific page in the Management Plugin concerning that item. When hovering over an item, incoming links and/or traffic are shown in green, whilst outgoing links and/or traffic are shown in blue. Bindings are always displayed, but the consumers of a queue, and likewise the publishers to an exchange, are only drawn in when hovering over the exchange, queue or channel in question. By default, up to 10 exchanges, 10 queues and 10 channels are displayed. Additional resources are available from the left hand-side select boxes, and can be brought into the display by selecting them and clicking on the relevant 'Show' button. The 'Display' check-boxes turn off and on entire resource classes, and resets positioning. Compatibility and Performance Notes ----------------------------------- Does work in recent versions of Safari both on OS X and Windows. Does work in Firefox (at least version 4.0). Does work in Chrome. Does not work in Internet Explorer. No error is given, but it doesn't work. Best performance is with Chrome. Note though that in some cases it has been seen that hardware rendering (use of GPU) can actually slow down performance. Some experimentation with browser flags and settings may be necessary to ensure smooth operation. rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/LICENSE-BSD-glMatrix0000644000177700017770000000243012633765070030220 0ustar michaelmichaelCopyright (c) 2011, Brandon Jones All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/CONTRIBUTING.md0000644000177700017770000000424512633765070027257 0ustar michaelmichael## Overview RabbitMQ projects use pull requests to discuss, collaborate on and accept code contributions. Pull requests is the primary place of discussing code changes. ## How to Contribute The process is fairly standard: * Fork the repository or repositories you plan on contributing to * Clone [RabbitMQ umbrella repository](https://github.com/rabbitmq/rabbitmq-public-umbrella) * `cd umbrella`, `make co` * Create a branch with a descriptive name in the relevant repositories * Make your changes, run tests, commit with a [descriptive message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), push to your fork * Submit pull requests with an explanation what has been changed and **why** * Submit a filled out and signed [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) if needed (see below) * Be patient. We will get to your pull request eventually If what you are going to work on is a substantial change, please first ask the core team of their opinion on [RabbitMQ mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). ## (Brief) Code of Conduct In one line: don't be a dick. Be respectful to the maintainers and other contributors. Open source contributors put long hours into developing projects and doing user support. Those projects and user support are available for free. We believe this deserves some respect. Be respectful to people of all races, genders, religious beliefs and political views. Regardless of how brilliant a pull request is technically, we will not tolerate disrespectful or aggressive behaviour. Contributors who violate this straightforward Code of Conduct will see their pull requests closed and locked. ## Contributor Agreement If you want to contribute a non-trivial change, please submit a signed copy of our [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) around the time you submit your pull request. This will make it much easier (in some cases, possible) for the RabbitMQ team at Pivotal to merge your contribution. ## Where to Ask Questions If something isn't clear, feel free to ask on our [mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/.srcdist_done0000644000177700017770000000000012633765070027470 0ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/license_info0000644000177700017770000000023012633765070027374 0ustar michaelmichaelglMatrix is "Copyright (c) 2011, Brandon Jones" and is covered by the BSD 2-Clause license. It was downloaded from http://code.google.com/p/glmatrix/ rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/LICENSE-MPL-RabbitMQ0000644000177700017770000006051412633765070030121 0ustar michaelmichael MOZILLA PUBLIC LICENSE Version 1.1 --------------- 1. Definitions. 1.0.1. "Commercial Use" means distribution or otherwise making the Covered Code available to a third party. 1.1. "Contributor" means each entity that creates or contributes to the creation of Modifications. 1.2. "Contributor Version" means the combination of the Original Code, prior Modifications used by a Contributor, and the Modifications made by that particular Contributor. 1.3. "Covered Code" means the Original Code or Modifications or the combination of the Original Code and Modifications, in each case including portions thereof. 1.4. "Electronic Distribution Mechanism" means a mechanism generally accepted in the software development community for the electronic transfer of data. 1.5. "Executable" means Covered Code in any form other than Source Code. 1.6. "Initial Developer" means the individual or entity identified as the Initial Developer in the Source Code notice required by Exhibit A. 1.7. "Larger Work" means a work which combines Covered Code or portions thereof with code not governed by the terms of this License. 1.8. "License" means this document. 1.8.1. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. 1.9. "Modifications" means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications. When Covered Code is released as a series of files, a Modification is: A. Any addition to or deletion from the contents of a file containing Original Code or previous Modifications. B. Any new file that contains any part of the Original Code or previous Modifications. 1.10. "Original Code" means Source Code of computer software code which is described in the Source Code notice required by Exhibit A as Original Code, and which, at the time of its release under this License is not already Covered Code governed by this License. 1.10.1. "Patent Claims" means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. 1.11. "Source Code" means the preferred form of the Covered Code for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control compilation and installation of an Executable, or source code differential comparisons against either the Original Code or another well known, available Covered Code of the Contributor's choice. The Source Code can be in a compressed or archival form, provided the appropriate decompression or de-archiving software is widely available for no charge. 1.12. "You" (or "Your") means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License or a future version of this License issued under Section 6.1. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. Source Code License. 2.1. The Initial Developer Grant. The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims: (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer to use, reproduce, modify, display, perform, sublicense and distribute the Original Code (or portions thereof) with or without Modifications, and/or as part of a Larger Work; and (b) under Patents Claims infringed by the making, using or selling of Original Code, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Code (or portions thereof). (c) the licenses granted in this Section 2.1(a) and (b) are effective on the date Initial Developer first distributes Original Code under the terms of this License. (d) Notwithstanding Section 2.1(b) above, no patent license is granted: 1) for code that You delete from the Original Code; 2) separate from the Original Code; or 3) for infringements caused by: i) the modification of the Original Code or ii) the combination of the Original Code with other software or devices. 2.2. Contributor Grant. Subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor, to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof) either on an unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger Work; and (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: 1) Modifications made by that Contributor (or portions thereof); and 2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). (c) the licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first makes Commercial Use of the Covered Code. (d) Notwithstanding Section 2.2(b) above, no patent license is granted: 1) for any code that Contributor has deleted from the Contributor Version; 2) separate from the Contributor Version; 3) for infringements caused by: i) third party modifications of Contributor Version or ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or 4) under Patent Claims infringed by Covered Code in the absence of Modifications made by that Contributor. 3. Distribution Obligations. 3.1. Application of License. The Modifications which You create or to which You contribute are governed by the terms of this License, including without limitation Section 2.2. The Source Code version of Covered Code may be distributed only under the terms of this License or a future version of this License released under Section 6.1, and You must include a copy of this License with every copy of the Source Code You distribute. You may not offer or impose any terms on any Source Code version that alters or restricts the applicable version of this License or the recipients' rights hereunder. However, You may include an additional document offering the additional rights described in Section 3.5. 3.2. Availability of Source Code. Any Modification which You create or to which You contribute must be made available in Source Code form under the terms of this License either on the same media as an Executable version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an Executable version available; and if made available via Electronic Distribution Mechanism, must remain available for at least twelve (12) months after the date it initially became available, or at least six (6) months after a subsequent version of that particular Modification has been made available to such recipients. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party. 3.3. Description of Modifications. You must cause all Covered Code to which You contribute to contain a file documenting the changes You made to create that Covered Code and the date of any change. You must include a prominent statement that the Modification is derived, directly or indirectly, from Original Code provided by the Initial Developer and including the name of the Initial Developer in (a) the Source Code, and (b) in any notice in an Executable version or related documentation in which You describe the origin or ownership of the Covered Code. 3.4. Intellectual Property Matters (a) Third Party Claims. If Contributor has knowledge that a license under a third party's intellectual property rights is required to exercise the rights granted by such Contributor under Sections 2.1 or 2.2, Contributor must include a text file with the Source Code distribution titled "LEGAL" which describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If Contributor obtains such knowledge after the Modification is made available as described in Section 3.2, Contributor shall promptly modify the LEGAL file in all copies Contributor makes available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Covered Code that new knowledge has been obtained. (b) Contributor APIs. If Contributor's Modifications include an application programming interface and Contributor has knowledge of patent licenses which are reasonably necessary to implement that API, Contributor must also include this information in the LEGAL file. (c) Representations. Contributor represents that, except as disclosed pursuant to Section 3.4(a) above, Contributor believes that Contributor's Modifications are Contributor's original creation(s) and/or Contributor has sufficient rights to grant the rights conveyed by this License. 3.5. Required Notices. You must duplicate the notice in Exhibit A in each file of the Source Code. If it is not possible to put such notice in a particular Source Code file due to its structure, then You must include such notice in a location (such as a relevant directory) where a user would be likely to look for such a notice. If You created one or more Modification(s) You may add your name as a Contributor to the notice described in Exhibit A. You must also duplicate this License in any documentation for the Source Code where You describe recipients' rights or ownership rights relating to Covered Code. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear than any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. 3.6. Distribution of Executable Versions. You may distribute Covered Code in Executable form only if the requirements of Section 3.1-3.5 have been met for that Covered Code, and if You include a notice stating that the Source Code version of the Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously included in any notice in an Executable version, related documentation or collateral in which You describe recipients' rights relating to the Covered Code. You may distribute the Executable version of Covered Code or ownership rights under a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable version does not attempt to limit or alter the recipient's rights in the Source Code version from the rights set forth in this License. If You distribute the Executable version under a different license You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. 3.7. Larger Works. You may create a Larger Work by combining Covered Code with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Code. 4. Inability to Comply Due to Statute or Regulation. If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Code due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be included in the LEGAL file described in Section 3.4 and must be included with all distributions of the Source Code. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. 5. Application of this License. This License applies to code to which the Initial Developer has attached the notice in Exhibit A and to related Covered Code. 6. Versions of the License. 6.1. New Versions. Netscape Communications Corporation ("Netscape") may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number. 6.2. Effect of New Versions. Once Covered Code has been published under a particular version of the License, You may always continue to use it under the terms of that version. You may also choose to use such Covered Code under the terms of any subsequent version of the License published by Netscape. No one other than Netscape has the right to modify the terms applicable to Covered Code created under this License. 6.3. Derivative Works. If You create or use a modified version of this License (which you may only do in order to apply it to code which is not already Covered Code governed by this License), You must (a) rename Your license so that the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", "MPL", "NPL" or any confusingly similar phrase do not appear in your license (except to note that your license differs from this License) and (b) otherwise make it clear that Your version of the license contains terms which differ from the Mozilla Public License and Netscape Public License. (Filling in the name of the Initial Developer, Original Code or Contributor in the notice described in Exhibit A shall not of themselves be deemed to be modifications of this License.) 7. DISCLAIMER OF WARRANTY. COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. 8. TERMINATION. 8.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which are properly granted shall survive any termination of this License. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. 8.2. If You initiate litigation by asserting a patent infringement claim (excluding declatory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You file such action is referred to as "Participant") alleging that: (a) such Participant's Contributor Version directly or indirectly infringes any patent, then any and all rights granted by such Participant to You under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively, unless if within 60 days after receipt of notice You either: (i) agree in writing to pay Participant a mutually agreeable reasonable royalty for Your past and future use of Modifications made by such Participant, or (ii) withdraw Your litigation claim with respect to the Contributor Version against such Participant. If within 60 days of notice, a reasonable royalty and payment arrangement are not mutually agreed upon in writing by the parties or the litigation claim is not withdrawn, the rights granted by Participant to You under Sections 2.1 and/or 2.2 automatically terminate at the expiration of the 60 day notice period specified above. (b) any software, hardware, or device, other than such Participant's Contributor Version, directly or indirectly infringes any patent, then any rights granted to You by such Participant under Sections 2.1(b) and 2.2(b) are revoked effective as of the date You first made, used, sold, distributed, or had made, Modifications made by that Participant. 8.3. If You assert a patent infringement claim against Participant alleging that such Participant's Contributor Version directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. 8.4. In the event of termination under Sections 8.1 or 8.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or any distributor hereunder prior to termination shall survive termination. 9. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. 10. U.S. GOVERNMENT END USERS. The Covered Code is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" and "commercial computer software documentation," as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Code with only those rights set forth herein. 11. MISCELLANEOUS. This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by California law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. With respect to disputes in which at least one party is a citizen of, or an entity chartered or registered to do business in the United States of America, any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California, with venue lying in Santa Clara County, California, with the losing party responsible for costs, including without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. 12. RESPONSIBILITY FOR CLAIMS. As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. 13. MULTIPLE-LICENSED CODE. Initial Developer may designate portions of the Covered Code as "Multiple-Licensed". "Multiple-Licensed" means that the Initial Developer permits you to utilize portions of the Covered Code under Your choice of the NPL or the alternative licenses, if any, specified by the Initial Developer in the file described in Exhibit A. EXHIBIT A -Mozilla Public License. ``The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ 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 Original Code is RabbitMQ Visualiser. The Initial Developer of the Original Code is GoPivotal, Inc. Copyright (c) 2011-2014 GoPivotal, Inc. All rights reserved.'' [NOTE: The text of this Exhibit A may differ slightly from the text of the notices in the Source Code files of the Original Code. You should use the text of this Exhibit A rather than the text found in the Original Code Source Code for Your Modifications.] rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/Makefile0000644000177700017770000000002712633765070026460 0ustar michaelmichaelinclude ../umbrella.mk rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/ebin/0000755000177700017770000000000012633765070025736 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/package.mk0000644000177700017770000000026712633765070026752 0ustar michaelmichaelRELEASABLE:=true DEPS:=rabbitmq-management CONSTRUCT_APP_PREREQS:=$(shell find $(PACKAGE_DIR)/priv -type f) define construct_app_commands cp -r $(PACKAGE_DIR)/priv $(APP_DIR) endef rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-visualiser/LICENSE0000644000177700017770000000054612633765070026033 0ustar michaelmichaelThis package, the RabbitMQ Visualiser is licensed under the MPL. For the MPL, please see LICENSE-MPL-RabbitMQ. This package makes use of the following third party libraries: glMatrix - http://code.google.com/p/glmatrix/ - BSD 2-clause license, see LICENSE-BSD-glMatrix If you have any questions regarding licensing, please contact us at info@rabbitmq.com. rabbitmq-server-3.5.7/plugins-src/all-packages.mk0000644000177700017770000000070012633765070021574 0ustar michaelmichaelUMBRELLA_BASE_DIR:=. include common.mk CHAIN_TESTS:=true # Pull in all the packages $(foreach PACKAGE_MK,$(wildcard */package.mk),$(eval $(call do_package,$(call canonical_path,$(patsubst %/,%,$(dir $(PACKAGE_MK))))))) # ...and the non-integrated ones $(foreach V,$(.VARIABLES),$(if $(filter NON_INTEGRATED_%,$(filter-out NON_INTEGRATED_DEPS_%,$V)),$(eval $(call do_package,$(subst NON_INTEGRATED_,,$V))))) test-all-packages: $(CHAINED_TESTS) rabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/0000755000177700017770000000000012633765070023765 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/src/0000755000177700017770000000000012633765070024554 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/src/rabbitmq_auth_backend_ldap.app.src0000644000177700017770000000171312633765070033337 0ustar michaelmichael%% -*- erlang -*- {application, rabbitmq_auth_backend_ldap, [{description, "RabbitMQ LDAP Authentication Backend"}, {vsn, "%%VSN%%"}, {modules, []}, {registered, []}, {mod, {rabbit_auth_backend_ldap_app, []}}, {env, [ {servers, undefined}, {user_dn_pattern, "${username}"}, {dn_lookup_attribute, none}, {dn_lookup_base, none}, {dn_lookup_bind, as_user}, {other_bind, as_user}, {vhost_access_query, {constant, true}}, {resource_access_query, {constant, true}}, {tag_queries, [{administrator, {constant, false}}]}, {use_ssl, false}, {use_starttls, false}, {ssl_options, []}, {port, 389}, {timeout, infinity}, {log, false} ] }, {applications, [kernel, stdlib, eldap, rabbit]}]}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/src/rabbit_auth_backend_ldap.erl0000644000177700017770000004050712633765070032221 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_auth_backend_ldap). %% Connect to an LDAP server for authentication and authorisation -include_lib("eldap/include/eldap.hrl"). -include_lib("rabbit_common/include/rabbit.hrl"). -behaviour(rabbit_authn_backend). -behaviour(rabbit_authz_backend). -export([user_login_authentication/2, user_login_authorization/1, check_vhost_access/3, check_resource_access/3]). -define(L(F, A), log("LDAP " ++ F, A)). -define(L1(F, A), log(" LDAP " ++ F, A)). -define(L2(F, A), log(" LDAP " ++ F, A)). -import(rabbit_misc, [pget/2]). -record(impl, { user_dn, password }). %%-------------------------------------------------------------------- user_login_authentication(Username, []) -> %% Without password, e.g. EXTERNAL ?L("CHECK: passwordless login for ~s", [Username]), R = with_ldap(creds(none), fun(LDAP) -> do_login(Username, unknown, none, LDAP) end), ?L("DECISION: passwordless login for ~s: ~p", [Username, log_result(R)]), R; user_login_authentication(Username, [{password, <<>>}]) -> %% Password "" is special in LDAP, see %% https://tools.ietf.org/html/rfc4513#section-5.1.2 ?L("CHECK: unauthenticated login for ~s", [Username]), ?L("DECISION: unauthenticated login for ~s: denied", [Username]), {refused, "user '~s' - unauthenticated bind not allowed", [Username]}; user_login_authentication(User, [{password, PW}]) -> ?L("CHECK: login for ~s", [User]), R = case dn_lookup_when() of prebind -> UserDN = username_to_dn_prebind(User), with_ldap({ok, {UserDN, PW}}, fun(L) -> do_login(User, UserDN, PW, L) end); _ -> with_ldap({ok, {fill_user_dn_pattern(User), PW}}, fun(L) -> do_login(User, unknown, PW, L) end) end, ?L("DECISION: login for ~s: ~p", [User, log_result(R)]), R; user_login_authentication(Username, AuthProps) -> exit({unknown_auth_props, Username, AuthProps}). user_login_authorization(Username) -> case user_login_authentication(Username, []) of {ok, #auth_user{impl = Impl, tags = Tags}} -> {ok, Impl, Tags}; Else -> Else end. check_vhost_access(User = #auth_user{username = Username, impl = #impl{user_dn = UserDN}}, VHost, _Sock) -> Args = [{username, Username}, {user_dn, UserDN}, {vhost, VHost}], ?L("CHECK: ~s for ~s", [log_vhost(Args), log_user(User)]), R = evaluate_ldap(env(vhost_access_query), Args, User), ?L("DECISION: ~s for ~s: ~p", [log_vhost(Args), log_user(User), log_result(R)]), R. check_resource_access(User = #auth_user{username = Username, impl = #impl{user_dn = UserDN}}, #resource{virtual_host = VHost, kind = Type, name = Name}, Permission) -> Args = [{username, Username}, {user_dn, UserDN}, {vhost, VHost}, {resource, Type}, {name, Name}, {permission, Permission}], ?L("CHECK: ~s for ~s", [log_resource(Args), log_user(User)]), R = evaluate_ldap(env(resource_access_query), Args, User), ?L("DECISION: ~s for ~s: ~p", [log_resource(Args), log_user(User), log_result(R)]), R. %%-------------------------------------------------------------------- evaluate(Query, Args, User, LDAP) -> ?L1("evaluating query: ~p", [Query]), evaluate0(Query, Args, User, LDAP). evaluate0({constant, Bool}, _Args, _User, _LDAP) -> ?L1("evaluated constant: ~p", [Bool]), Bool; evaluate0({for, [{Type, Value, SubQuery}|Rest]}, Args, User, LDAP) -> case pget(Type, Args) of undefined -> {error, {args_do_not_contain, Type, Args}}; Value -> ?L1("selecting subquery ~s = ~s", [Type, Value]), evaluate(SubQuery, Args, User, LDAP); _ -> evaluate0({for, Rest}, Args, User, LDAP) end; evaluate0({for, []}, _Args, _User, _LDAP) -> {error, {for_query_incomplete}}; evaluate0({exists, DNPattern}, Args, _User, LDAP) -> %% eldap forces us to have a filter. objectClass should always be there. Filter = eldap:present("objectClass"), DN = fill(DNPattern, Args), R = object_exists(DN, Filter, LDAP), ?L1("evaluated exists for \"~s\": ~p", [DN, R]), R; evaluate0({in_group, DNPattern}, Args, User, LDAP) -> evaluate({in_group, DNPattern, "member"}, Args, User, LDAP); evaluate0({in_group, DNPattern, Desc}, Args, #auth_user{impl = #impl{user_dn = UserDN}}, LDAP) -> Filter = eldap:equalityMatch(Desc, UserDN), DN = fill(DNPattern, Args), R = object_exists(DN, Filter, LDAP), ?L1("evaluated in_group for \"~s\": ~p", [DN, R]), R; evaluate0({'not', SubQuery}, Args, User, LDAP) -> R = evaluate(SubQuery, Args, User, LDAP), ?L1("negated result to ~s", [R]), not R; evaluate0({'and', Queries}, Args, User, LDAP) when is_list(Queries) -> R = lists:foldl(fun (Q, true) -> evaluate(Q, Args, User, LDAP); (_Q, false) -> false end, true, Queries), ?L1("'and' result: ~s", [R]), R; evaluate0({'or', Queries}, Args, User, LDAP) when is_list(Queries) -> R = lists:foldl(fun (_Q, true) -> true; (Q, false) -> evaluate(Q, Args, User, LDAP) end, false, Queries), ?L1("'or' result: ~s", [R]), R; evaluate0({equals, StringQuery1, StringQuery2}, Args, User, LDAP) -> safe_eval(fun (String1, String2) -> R = String1 =:= String2, ?L1("evaluated equals \"~s\", \"~s\": ~s", [String1, String2, R]), R end, evaluate(StringQuery1, Args, User, LDAP), evaluate(StringQuery2, Args, User, LDAP)); evaluate0({match, StringQuery, REQuery}, Args, User, LDAP) -> safe_eval(fun (String, RE) -> R = case re:run(String, RE) of {match, _} -> true; nomatch -> false end, ?L1("evaluated match \"~s\" against RE \"~s\": ~s", [String, RE, R]), R end, evaluate(StringQuery, Args, User, LDAP), evaluate(REQuery, Args, User, LDAP)); evaluate0(StringPattern, Args, User, LDAP) when is_list(StringPattern) -> evaluate0({string, StringPattern}, Args, User, LDAP); evaluate0({string, StringPattern}, Args, _User, _LDAP) -> R = fill(StringPattern, Args), ?L1("evaluated string for \"~s\"", [R]), R; evaluate0({attribute, DNPattern, AttributeName}, Args, _User, LDAP) -> DN = fill(DNPattern, Args), R = attribute(DN, AttributeName, LDAP), ?L1("evaluated attribute \"~s\" for \"~s\": ~p", [AttributeName, DN, R]), R; evaluate0(Q, Args, _User, _LDAP) -> {error, {unrecognised_query, Q, Args}}. safe_eval(_F, {error, _}, _) -> false; safe_eval(_F, _, {error, _}) -> false; safe_eval(F, V1, V2) -> F(V1, V2). object_exists(DN, Filter, LDAP) -> case eldap:search(LDAP, [{base, DN}, {filter, Filter}, {attributes, ["objectClass"]}, %% Reduce verbiage {scope, eldap:baseObject()}]) of {ok, #eldap_search_result{entries = Entries}} -> length(Entries) > 0; {error, _} = E -> E end. attribute(DN, AttributeName, LDAP) -> case eldap:search(LDAP, [{base, DN}, {filter, eldap:present("objectClass")}, {attributes, [AttributeName]}]) of {ok, #eldap_search_result{entries = [#eldap_entry{attributes = A}]}} -> case pget(AttributeName, A) of [Attr] -> Attr; _ -> {error, not_found} end; {ok, #eldap_search_result{entries = _}} -> {error, not_found}; {error, _} = E -> E end. evaluate_ldap(Q, Args, User) -> with_ldap(creds(User), fun(LDAP) -> evaluate(Q, Args, User, LDAP) end). %%-------------------------------------------------------------------- with_ldap(Creds, Fun) -> with_ldap(Creds, Fun, env(servers)). with_ldap(_Creds, _Fun, undefined) -> {error, no_ldap_servers_defined}; with_ldap({error, _} = E, _Fun, _State) -> E; %% TODO - ATM we create and destroy a new LDAP connection on every %% call. This could almost certainly be more efficient. with_ldap({ok, Creds}, Fun, Servers) -> Opts0 = [{port, env(port)}], Opts1 = case env(log) of network -> Pre = " LDAP network traffic: ", rabbit_log:info( " LDAP connecting to servers: ~p~n", [Servers]), [{log, fun(1, S, A) -> rabbit_log:warning(Pre ++ S, A); (2, S, A) -> rabbit_log:info (Pre ++ S, A) end} | Opts0]; _ -> Opts0 end, %% eldap defaults to 'infinity' but doesn't allow you to set that. Harrumph. Opts = case env(timeout) of infinity -> Opts1; MS -> [{timeout, MS} | Opts1] end, case eldap_open(Servers, Opts) of {ok, LDAP} -> try Creds of anon -> ?L1("anonymous bind", []), Fun(LDAP); {UserDN, Password} -> case eldap:simple_bind(LDAP, UserDN, Password) of ok -> ?L1("bind succeeded: ~s", [UserDN]), Fun(LDAP); {error, invalidCredentials} -> ?L1("bind returned \"invalid credentials\": ~s", [UserDN]), {refused, UserDN, []}; {error, E} -> ?L1("bind error: ~s ~p", [UserDN, E]), {error, E} end after eldap:close(LDAP) end; Error -> ?L1("connect error: ~p", [Error]), Error end. eldap_open(Servers, Opts) -> case eldap:open(Servers, ssl_conf() ++ Opts) of {ok, LDAP} -> TLS = env(use_starttls), case {TLS, at_least("5.10.4")} of %%R16B03 {false, _} -> {ok, LDAP}; {true, false} -> exit({starttls_requires_min_r16b3}); {true, _} -> TLSOpts = ssl_options(), ELDAP = eldap, %% Fool xref case ELDAP:start_tls(LDAP, TLSOpts) of ok -> {ok, LDAP}; Error -> Error end end; Error -> Error end. ssl_conf() -> %% We must make sure not to add SSL options unless a) we have at least R16A %% b) we have SSL turned on (or it breaks StartTLS...) case env(use_ssl) of false -> [{ssl, false}]; true -> %% Only the unfixed version can be [] case {env(ssl_options), at_least("5.10")} of %% R16A {_, true} -> [{ssl, true}, {sslopts, ssl_options()}]; {[], _} -> [{ssl, true}]; {_, false} -> exit({ssl_options_requires_min_r16a}) end end. ssl_options() -> rabbit_networking:fix_ssl_options(env(ssl_options)). at_least(Ver) -> rabbit_misc:version_compare(erlang:system_info(version), Ver) =/= lt. env(F) -> {ok, V} = application:get_env(rabbitmq_auth_backend_ldap, F), V. do_login(Username, PrebindUserDN, Password, LDAP) -> UserDN = case PrebindUserDN of unknown -> username_to_dn(Username, LDAP, dn_lookup_when()); _ -> PrebindUserDN end, User = #auth_user{username = Username, impl = #impl{user_dn = UserDN, password = Password}}, DTQ = fun (LDAPn) -> do_tag_queries(Username, UserDN, User, LDAPn) end, TagRes = case env(other_bind) of as_user -> DTQ(LDAP); _ -> with_ldap(creds(User), DTQ) end, case TagRes of {ok, L} -> case [E || {_, E = {error, _}} <- L] of [] -> Tags = [Tag || {Tag, true} <- L], {ok, User#auth_user{tags = Tags}}; [E | _] -> E end; E -> E end. do_tag_queries(Username, UserDN, User, LDAP) -> {ok, [begin ?L1("CHECK: does ~s have tag ~s?", [Username, Tag]), R = evaluate(Q, [{username, Username}, {user_dn, UserDN}], User, LDAP), ?L1("DECISION: does ~s have tag ~s? ~p", [Username, Tag, R]), {Tag, R} end || {Tag, Q} <- env(tag_queries)]}. dn_lookup_when() -> case {env(dn_lookup_attribute), env(dn_lookup_bind)} of {none, _} -> never; {_, as_user} -> postbind; {_, _} -> prebind end. username_to_dn_prebind(Username) -> with_ldap({ok, env(dn_lookup_bind)}, fun (LDAP) -> dn_lookup(Username, LDAP) end). username_to_dn(Username, LDAP, postbind) -> dn_lookup(Username, LDAP); username_to_dn(Username, _LDAP, _When) -> fill_user_dn_pattern(Username). dn_lookup(Username, LDAP) -> Filled = fill_user_dn_pattern(Username), case eldap:search(LDAP, [{base, env(dn_lookup_base)}, {filter, eldap:equalityMatch( env(dn_lookup_attribute), Filled)}, {attributes, ["distinguishedName"]}]) of {ok, #eldap_search_result{entries = [#eldap_entry{object_name = DN}]}}-> ?L1("DN lookup: ~s -> ~s", [Username, DN]), DN; {ok, #eldap_search_result{entries = Entries}} -> rabbit_log:warning("Searching for DN for ~s, got back ~p~n", [Filled, Entries]), Filled; {error, _} = E -> exit(E) end. fill_user_dn_pattern(Username) -> fill(env(user_dn_pattern), [{username, Username}]). creds(User) -> creds(User, env(other_bind)). creds(none, as_user) -> {error, "'other_bind' set to 'as_user' but no password supplied"}; creds(#auth_user{impl = #impl{user_dn = UserDN, password = PW}}, as_user) -> {ok, {UserDN, PW}}; creds(_, Creds) -> {ok, Creds}. log(Fmt, Args) -> case env(log) of false -> ok; _ -> rabbit_log:info(Fmt ++ "~n", Args) end. fill(Fmt, Args) -> ?L2("filling template \"~s\" with~n ~p", [Fmt, Args]), R = rabbit_auth_backend_ldap_util:fill(Fmt, Args), ?L2("template result: \"~s\"", [R]), R. log_result({ok, #auth_user{}}) -> ok; log_result(true) -> ok; log_result(false) -> denied; log_result({refused, _, _}) -> denied; log_result(E) -> E. log_user(#auth_user{username = U}) -> rabbit_misc:format("\"~s\"", [U]). log_vhost(Args) -> rabbit_misc:format("access to vhost \"~s\"", [pget(vhost, Args)]). log_resource(Args) -> rabbit_misc:format("~s permission for ~s \"~s\" in \"~s\"", [pget(permission, Args), pget(resource, Args), pget(name, Args), pget(vhost, Args)]). rabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/src/rabbit_auth_backend_ldap_util.erl0000644000177700017770000000234512633765070033254 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_auth_backend_ldap_util). -export([fill/2]). fill(Fmt, []) -> binary_to_list(iolist_to_binary(Fmt)); fill(Fmt, [{K, V} | T]) -> Var = [[$\\, $$, ${] ++ atom_to_list(K) ++ [$}]], fill(re:replace(Fmt, Var, [to_repl(V)], [global]), T). to_repl(V) when is_atom(V) -> to_repl(atom_to_list(V)); to_repl(V) when is_binary(V) -> to_repl(binary_to_list(V)); to_repl([]) -> []; to_repl([$\\ | T]) -> [$\\, $\\ | to_repl(T)]; to_repl([$& | T]) -> [$\\, $& | to_repl(T)]; to_repl([H | T]) -> [H | to_repl(T)]. rabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/src/rabbit_auth_backend_ldap_app.erl0000644000177700017770000000355112633765070033057 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_auth_backend_ldap_app). -behaviour(application). -export([start/2, stop/1]). %% Dummy supervisor to get this application behaviour working -behaviour(supervisor). -export([init/1]). start(_Type, _StartArgs) -> {ok, Backends} = application:get_env(rabbit, auth_backends), case configured(rabbit_auth_backend_ldap, Backends) of true -> ok; false -> rabbit_log:warning( "LDAP plugin loaded, but rabbit_auth_backend_ldap is not " "in the list of auth_backends. LDAP auth will not work.~n") end, {ok, SSL} = application:get_env(rabbitmq_auth_backend_ldap, use_ssl), {ok, TLS} = application:get_env(rabbitmq_auth_backend_ldap, use_starttls), case SSL orelse TLS of true -> rabbit_networking:ensure_ssl(); false -> ok end, supervisor:start_link({local, ?MODULE}, ?MODULE, []). stop(_State) -> ok. configured(_M, []) -> false; configured(M, [M |_]) -> true; configured(M, [{M,_}|_]) -> true; configured(M, [{_,M}|_]) -> true; configured(M, [_ |T]) -> configured(M, T). %%---------------------------------------------------------------------------- init([]) -> {ok, {{one_for_one, 3, 10}, []}}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/README0000644000177700017770000000104512633765070024645 0ustar michaelmichaelRequirements ============ You can build and install it like any other plugin (see http://www.rabbitmq.com/plugin-development.html). Documentation ============= See http://www.rabbitmq.com/ldap.html Limitations =========== Currently this plugin is rather chatty with LDAP connections when doing authorisation over LDAP - every time RabbitMQ needs to do an authorisation query it starts a new LDAP connection. However, RabbitMQ does have a per-channel authorisation cache, so this is not too awful. There might need to be more types of queries. rabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/CONTRIBUTING.md0000644000177700017770000000424512633765070026223 0ustar michaelmichael## Overview RabbitMQ projects use pull requests to discuss, collaborate on and accept code contributions. Pull requests is the primary place of discussing code changes. ## How to Contribute The process is fairly standard: * Fork the repository or repositories you plan on contributing to * Clone [RabbitMQ umbrella repository](https://github.com/rabbitmq/rabbitmq-public-umbrella) * `cd umbrella`, `make co` * Create a branch with a descriptive name in the relevant repositories * Make your changes, run tests, commit with a [descriptive message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), push to your fork * Submit pull requests with an explanation what has been changed and **why** * Submit a filled out and signed [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) if needed (see below) * Be patient. We will get to your pull request eventually If what you are going to work on is a substantial change, please first ask the core team of their opinion on [RabbitMQ mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). ## (Brief) Code of Conduct In one line: don't be a dick. Be respectful to the maintainers and other contributors. Open source contributors put long hours into developing projects and doing user support. Those projects and user support are available for free. We believe this deserves some respect. Be respectful to people of all races, genders, religious beliefs and political views. Regardless of how brilliant a pull request is technically, we will not tolerate disrespectful or aggressive behaviour. Contributors who violate this straightforward Code of Conduct will see their pull requests closed and locked. ## Contributor Agreement If you want to contribute a non-trivial change, please submit a signed copy of our [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) around the time you submit your pull request. This will make it much easier (in some cases, possible) for the RabbitMQ team at Pivotal to merge your contribution. ## Where to Ask Questions If something isn't clear, feel free to ask on our [mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). rabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/test/0000755000177700017770000000000012633765070024744 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/test/src/0000755000177700017770000000000012633765070025533 5ustar michaelmichael././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/test/src/rabbit_auth_backend_ldap_test.erlrabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/test/src/rabbit_auth_backend_ldap_test.0000644000177700017770000002237312633765070033535 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_auth_backend_ldap_test). -include_lib("eunit/include/eunit.hrl"). -include_lib("amqp_client/include/amqp_client.hrl"). -define(SIMON_NAME, "Simon MacMullen"). -define(MIKEB_NAME, "Mike Bridgen"). -define(VHOST, "test"). -define(SIMON, #amqp_params_network{username = << ?SIMON_NAME >>, password = <<"password">>, virtual_host = << ?VHOST >>}). -define(MIKEB, #amqp_params_network{username = << ?MIKEB_NAME >>, password = <<"password">>, virtual_host = << ?VHOST >>}). %%-------------------------------------------------------------------- ldap_only_test_() -> { setup, fun () -> ok = application:set_env(rabbit, auth_backends, [rabbit_auth_backend_ldap]) end, fun (_) -> ok = application:unset_env(rabbit, auth_backends) end, [ {"LDAP Login", login()}, {"LDAP In group", in_group()}, {"LDAP Constant", const()}, {"LDAP String match", string_match()}, {"LDAP Boolean check", boolean_logic()}, {"LDAP Tags", tag_check([])} ]}. ldap_and_internal_test_() -> { setup, fun () -> ok = application:set_env(rabbit, auth_backends, [{rabbit_auth_backend_ldap, rabbit_auth_backend_internal}]), ok = control_action(add_user, [ ?SIMON_NAME, ""]), ok = control_action(set_permissions, [ ?SIMON_NAME, "prefix-.*", "prefix-.*", "prefix-.*"]), ok = control_action(set_user_tags, [ ?SIMON_NAME, "management", "foo"]), ok = control_action(add_user, [ ?MIKEB_NAME, ""]), ok = control_action(set_permissions, [ ?MIKEB_NAME, "", "", ""]) end, fun (_) -> ok = application:unset_env(rabbit, auth_backends), ok = control_action(delete_user, [ ?SIMON_NAME ]), ok = control_action(delete_user, [ ?MIKEB_NAME ]) end, [ {"LDAP&Internal Login", login()}, {"LDAP&Internal Permissions", permission_match()}, {"LDAP&Internal Tags", tag_check([management, foo])} ]}. internal_followed_ldap_and_internal_test_() -> { setup, fun () -> ok = application:set_env(rabbit, auth_backends, [rabbit_auth_backend_internal, {rabbit_auth_backend_ldap, rabbit_auth_backend_internal}]), ok = control_action(add_user, [ ?SIMON_NAME, ""]), ok = control_action(set_permissions, [ ?SIMON_NAME, "prefix-.*", "prefix-.*", "prefix-.*"]), ok = control_action(set_user_tags, [ ?SIMON_NAME, "management", "foo"]), ok = control_action(add_user, [ ?MIKEB_NAME, ""]), ok = control_action(set_permissions, [ ?MIKEB_NAME, "", "", ""]) end, fun (_) -> ok = application:unset_env(rabbit, auth_backends), ok = control_action(delete_user, [ ?SIMON_NAME ]), ok = control_action(delete_user, [ ?MIKEB_NAME ]) end, [ {"Internal, LDAP&Internal Login", login()}, {"Internal, LDAP&Internal Permissions", permission_match()}, {"Internal, LDAP&Internal Tags", tag_check([management, foo])} ]}. %%-------------------------------------------------------------------- login() -> [test_login(Env, L, case {LGood, EnvGood} of {good, good} -> fun succ/1; _ -> fun fail/1 end) || {LGood, L} <- logins(), {EnvGood, Env} <- login_envs()]. logins() -> [{bad, #amqp_params_network{}}, {bad, #amqp_params_network{username = <<"Simon MacMullen">>}}, {bad, #amqp_params_network{username = <<"Simon MacMullen">>, password = <<"password">>}}, {good, ?SIMON}, {good, ?MIKEB}]. login_envs() -> [{good, base_login_env()}, {good, dn_lookup_pre_bind_env()}, {good, other_bind_admin_env()}, {good, other_bind_anon_env()}, {bad, other_bind_broken_env()}]. base_login_env() -> [{user_dn_pattern, "cn=${username},ou=People,dc=example,dc=com"}, {dn_lookup_attribute, none}, {dn_lookup_base, none}, {dn_lookup_bind, as_user}, {other_bind, as_user}]. %% TODO configure OpenLDAP to allow a dn_lookup_post_bind_env() dn_lookup_pre_bind_env() -> [{user_dn_pattern, "${username}"}, {dn_lookup_attribute, "cn"}, {dn_lookup_base, "OU=People,DC=example,DC=com"}, {dn_lookup_bind, {"cn=admin,dc=example,dc=com", "admin"}}]. other_bind_admin_env() -> [{other_bind, {"cn=admin,dc=example,dc=com", "admin"}}]. other_bind_anon_env() -> [{other_bind, anon}]. other_bind_broken_env() -> [{other_bind, {"cn=admin,dc=example,dc=com", "admi"}}]. test_login(Env, Login, ResultFun) -> ?_test(try set_env(Env), ResultFun(Login) after set_env(base_login_env()) end). set_env(Env) -> [application:set_env(rabbitmq_auth_backend_ldap, K, V) || {K, V} <- Env]. succ(Login) -> ?assertMatch({ok, _}, amqp_connection:start(Login)). fail(Login) -> ?assertMatch({error, _}, amqp_connection:start(Login)). %%-------------------------------------------------------------------- in_group() -> X = [#'exchange.declare'{exchange = <<"test">>}], test_resource_funs([{?SIMON, X, ok}, {?MIKEB, X, fail}]). const() -> Q = [#'queue.declare'{queue = <<"test">>}], test_resource_funs([{?SIMON, Q, ok}, {?MIKEB, Q, fail}]). string_match() -> B = fun(N) -> [#'exchange.declare'{exchange = N}, #'queue.declare'{queue = <<"test">>}, #'queue.bind'{exchange = N, queue = <<"test">>}] end, test_resource_funs([{?SIMON, B(<<"xch-Simon MacMullen-abc123">>), ok}, {?SIMON, B(<<"abc123">>), fail}, {?SIMON, B(<<"xch-Someone Else-abc123">>), fail}]). boolean_logic() -> Q1 = [#'queue.declare'{queue = <<"test1">>}, #'basic.consume'{queue = <<"test1">>}], Q2 = [#'queue.declare'{queue = <<"test2">>}, #'basic.consume'{queue = <<"test2">>}], [test_resource_fun(PTR) || PTR <- [{?SIMON, Q1, ok}, {?SIMON, Q2, ok}, {?MIKEB, Q1, fail}, {?MIKEB, Q2, fail}]]. permission_match() -> B = fun(N) -> [#'exchange.declare'{exchange = N}, #'queue.declare'{queue = <<"prefix-test">>}, #'queue.bind'{exchange = N, queue = <<"prefix-test">>}] end, test_resource_funs([{?SIMON, B(<<"prefix-abc123">>), ok}, {?SIMON, B(<<"abc123">>), fail}, {?SIMON, B(<<"xch-Simon MacMullen-abc123">>), fail}]). tag_check(Tags) -> fun() -> {ok, User} = rabbit_access_control:check_user_pass_login( << ?SIMON_NAME >>, <<"password">>), ?assertEqual(Tags, User#user.tags) end. %%-------------------------------------------------------------------- test_resource_funs(PTRs) -> [test_resource_fun(PTR) || PTR <- PTRs]. test_resource_fun({Person, Things, Result}) -> fun() -> {ok, Conn} = amqp_connection:start(Person), {ok, Ch} = amqp_connection:open_channel(Conn), ?assertEqual(Result, try [amqp_channel:call(Ch, T) || T <- Things], amqp_connection:close(Conn), ok catch exit:_ -> fail end) end. control_action(Command, Args) -> control_action(Command, node(), Args, default_options()). control_action(Command, Args, NewOpts) -> control_action(Command, node(), Args, expand_options(default_options(), NewOpts)). control_action(Command, Node, Args, Opts) -> case catch rabbit_control_main:action( Command, Node, Args, Opts, fun (Format, Args1) -> io:format(Format ++ " ...~n", Args1) end) of ok -> io:format("done.~n"), ok; Other -> io:format("failed.~n"), Other end. default_options() -> [{"-p", ?VHOST}, {"-q", "false"}]. expand_options(As, Bs) -> lists:foldl(fun({K, _}=A, R) -> case proplists:is_defined(K, R) of true -> R; false -> [A | R] end end, Bs, As). ././@LongLink0000644000000000000000000000015500000000000011604 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/test/src/rabbit_auth_backend_ldap_unit_test.erlrabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/test/src/rabbit_auth_backend_ldap_unit_0000644000177700017770000000253512633765070033614 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_auth_backend_ldap_unit_test). -include_lib("eunit/include/eunit.hrl"). fill_test() -> F = fun(Fmt, Args, Res) -> ?assertEqual(Res, rabbit_auth_backend_ldap_util:fill(Fmt, Args)) end, F("x${username}x", [{username, "ab"}], "xabx"), F("x${username}x", [{username, ab}], "xabx"), F("x${username}x", [{username, <<"ab">>}], "xabx"), F("x${username}x", [{username, ""}], "xx"), F("x${username}x", [{fusername, "ab"}], "x${username}x"), F("x${usernamex", [{username, "ab"}], "x${usernamex"), F("x${username}x", [{username, "a\\b"}], "xa\\bx"), F("x${username}x", [{username, "a&b"}], "xa&bx"), ok. rabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/README-authorisation0000644000177700017770000000004612633765070027534 0ustar michaelmichaelSee http://www.rabbitmq.com/ldap.html rabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/.srcdist_done0000644000177700017770000000000012633765070026434 0ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/Makefile0000644000177700017770000000002712633765070025424 0ustar michaelmichaelinclude ../umbrella.mk rabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/example/0000755000177700017770000000000012633765070025420 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/example/groups.ldif0000644000177700017770000000031712633765070027600 0ustar michaelmichaeldn: ou=groups,dc=example,dc=com objectclass:organizationalunit ou: groups dn: cn=wheel,ou=groups,dc=example,dc=com objectclass: groupOfNames cn: wheel member: cn=Simon MacMullen,ou=people,dc=example,dc=com rabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/example/README0000644000177700017770000000060612633765070026302 0ustar michaelmichaelThis is a very simple example, designed to be set up with the modern Debian / Ubuntu packaging of OpenLDAP. Running setup.sh after "apt-get install slapd" will wipe out any existing LDAP database and get you: * A domain * An admin user * A couple of normal users * A group containing the users * An OU representing a vhost These correspond to the examples mentioned in the documentation. rabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/example/setup.sh0000755000177700017770000000107712633765070027124 0ustar michaelmichael#!/bin/sh -e # Based on instructions found at # http://ubuntuforums.org/showthread.php?p=8161118#post8161118 # - yes that does seem to be the most authoritative place. sudo apt-get --yes purge slapd sudo rm -rf /var/lib/ldap sudo apt-get --yes install slapd ldap-utils sleep 1 DIR=$(dirname $0) sudo ldapadd -Y EXTERNAL -H ldapi:/// -f ${DIR}/global.ldif ldapadd -x -D cn=admin,dc=example,dc=com -w admin -f ${DIR}/people.ldif ldapadd -x -D cn=admin,dc=example,dc=com -w admin -f ${DIR}/groups.ldif ldapadd -x -D cn=admin,dc=example,dc=com -w admin -f ${DIR}/rabbit.ldif rabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/example/people.ldif0000644000177700017770000000075512633765070027553 0ustar michaelmichaeldn: dc=example,dc=com objectClass: top objectClass: dcObject objectclass: organization o: example.com dc: example description: Example dn: ou=people,dc=example,dc=com objectClass: organizationalUnit ou: people dn: cn=Simon MacMullen,ou=people,dc=example,dc=com objectClass: person cn: Simon MacMullen sn: MacMullen userPassword: password description: can-declare-queues dn: cn=Mike Bridgen,ou=people,dc=example,dc=com objectClass: person cn: Mike Bridgen sn: Bridgen userPassword: password rabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/example/global.ldif0000644000177700017770000000126712633765070027526 0ustar michaelmichael# Load modules for database type dn: cn=module,cn=config objectclass: olcModuleList cn: module olcModuleLoad: back_bdb.la # Create directory database dn: olcDatabase=bdb,cn=config objectClass: olcDatabaseConfig objectClass: olcBdbConfig olcDatabase: bdb # Domain name (e.g. example.com) olcSuffix: dc=example,dc=com # Location on system where database is stored olcDbDirectory: /var/lib/ldap # Manager of the database olcRootDN: cn=admin,dc=example,dc=com olcRootPW: admin olcAccess: to attrs=userPassword by self write by anonymous auth by dn.base="cn=admin,dc=example,dc=com" write by * none olcAccess: to * by self write by dn.base="cn=admin,dc=example,dc=com" write by * read rabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/example/rabbit.ldif0000644000177700017770000000025612633765070027526 0ustar michaelmichaeldn: ou=vhosts,dc=example,dc=com objectClass: organizationalUnit ou: vhosts dn: ou=test,ou=vhosts,dc=example,dc=com objectClass: top objectClass: organizationalUnit ou: test rabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/.travis.yml0000644000177700017770000000150212633765070026074 0ustar michaelmichaelsudo: true language: erlang notifications: email: - alerts@rabbitmq.com addons: apt: packages: - slapd - ldap-utils - xsltproc otp_release: - "R16B03-1" - "17.5" - "18.0" install: - if [ ! -d "$HOME/rabbitmq-public-umbrella/.git" ]; then git clone https://github.com/rabbitmq/rabbitmq-public-umbrella.git $HOME/rabbitmq-public-umbrella; fi - cd $HOME/rabbitmq-public-umbrella - make co - make up services: - slapd before_script: - IFS="/" read -a PARTS <<< "$TRAVIS_REPO_SLUG" - export TEST_DIR=$HOME/rabbitmq-public-umbrella/${PARTS[1]} - rm -rf ${TEST_DIR} - cp -r ${TRAVIS_BUILD_DIR} ${TEST_DIR} - cd ${TEST_DIR} - ./example/setup.sh script: make test before_cache: - rm -rf ${TEST_DIR} - cd $HOME cache: apt: true directories: - $HOME/rabbitmq-public-umbrella rabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/ebin/0000755000177700017770000000000012633765070024702 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/etc/0000755000177700017770000000000012633765070024540 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/etc/rabbit-test.config0000644000177700017770000000337512633765070030157 0ustar michaelmichael%% -*- erlang -*- [{rabbit, [{default_vhost, <<"test">>}]}, {rabbitmq_auth_backend_ldap, [ {servers, ["localhost"]}, {user_dn_pattern, "cn=${username},ou=People,dc=example,dc=com"}, {other_bind, anon}, {use_ssl, false}, {port, 389}, {log, true}, {tag_queries, [{administrator, {constant, false}}]}, {vhost_access_query, {exists, "ou=${vhost},ou=vhosts,dc=example,dc=com"}}, {resource_access_query, {for, [{resource, exchange, {for, [{permission, configure, {in_group, "cn=wheel,ou=groups,dc=example,dc=com"} }, {permission, write, {constant, true}}, {permission, read, {match, {string, "${name}"}, {string, "^xch-${username}-.*"}} } ]}}, {resource, queue, {for, [{permission, configure, {match, {attribute, "${user_dn}", "description"}, {string, "can-declare-queues"}} }, {permission, write, {constant, true}}, {permission, read, {'or', [{'and', [{equals, "${name}", "test1"}, {equals, "${username}", "Simon MacMullen"}]}, {'and', [{equals, "${name}", "test2"}, {'not', {equals, "${username}", "Mike Bridgen"}}]} ]}} ]}} ]}}, {tag_queries, [{administrator, {constant, false}}, {management, {constant, false}}]} ]} ]. rabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/README-tests0000644000177700017770000000060012633765070026001 0ustar michaelmichaelThe tests *require* a locally installed LDAP server with some predefined objects inside. If there's no LDAP server running on port 389, they will be skipped. On Debian / Ubuntu you can just: $ ./example/setup.sh $ make test - but be aware that this will wipe out your local OpenLDAP installation. Poke around in example/ if using any other distro, you can probably make it work. rabbitmq-server-3.5.7/plugins-src/rabbitmq-auth-backend-ldap/package.mk0000644000177700017770000000057712633765070025722 0ustar michaelmichaelRELEASABLE:=true DEPS:=rabbitmq-server rabbitmq-erlang-client eldap-wrapper ifeq ($(shell nc -z localhost 389 && echo true),true) WITH_BROKER_TEST_COMMANDS:=eunit:test([rabbit_auth_backend_ldap_unit_test,rabbit_auth_backend_ldap_test],[verbose]) WITH_BROKER_TEST_CONFIG:=$(PACKAGE_DIR)/etc/rabbit-test else $(warning Not running LDAP tests; no LDAP server found on localhost) endif rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/0000755000177700017770000000000012633765070021702 5ustar michaelmichael././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/0003-R12-drop-all-references-to-reference-type.patchrabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/0003-R12-drop-all-references-to-reference-type.patc0000644000177700017770000000317312633765070032665 0ustar michaelmichaelFrom 4db80ab7bacf04502ad2d29d4760e04a6d787a83 Mon Sep 17 00:00:00 2001 From: Marek Majkowski Date: Thu, 26 Jan 2012 12:52:23 +0000 Subject: [PATCH 3/7] R12: drop all references to reference() type --- src/cowboy_http_protocol.erl | 2 +- src/cowboy_http_websocket.erl | 2 +- src/cowboy_listener.erl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cowboy_http_protocol.erl b/src/cowboy_http_protocol.erl index b80745f..0183785 100644 --- a/src/cowboy_http_protocol.erl +++ b/src/cowboy_http_protocol.erl @@ -57,7 +57,7 @@ buffer = <<>> :: binary(), hibernate = false, loop_timeout = infinity :: timeout(), - loop_timeout_ref :: undefined | reference() + loop_timeout_ref }). %% API. diff --git a/src/cowboy_http_websocket.erl b/src/cowboy_http_websocket.erl index 5f59891..5100213 100644 --- a/src/cowboy_http_websocket.erl +++ b/src/cowboy_http_websocket.erl @@ -52,7 +52,7 @@ opts :: any(), challenge = undefined :: undefined | binary() | {binary(), binary()}, timeout = infinity :: timeout(), - timeout_ref = undefined :: undefined | reference(), + timeout_ref = undefined, messages = undefined :: undefined | {atom(), atom(), atom()}, hibernate = false, eop :: undefined | tuple(), %% hixie-76 specific. diff --git a/src/cowboy_listener.erl b/src/cowboy_listener.erl index c19d079..86e87f1 100644 --- a/src/cowboy_listener.erl +++ b/src/cowboy_listener.erl @@ -23,8 +23,8 @@ -record(state, { req_pools = [] :: [{atom(), non_neg_integer()}], - reqs_table :: ets:tid(), - queue = [] :: [{pid(), reference()}] + reqs_table, + queue = [] }). %% API. -- 1.7.0.4 rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/0002-R12-drop-all-references-to-boolean-type.patch0000644000177700017770000001426312633765070032517 0ustar michaelmichaelFrom 257e64326ad786d19328d343da0ff7d29adbae4e Mon Sep 17 00:00:00 2001 From: Marek Majkowski Date: Thu, 26 Jan 2012 12:51:30 +0000 Subject: [PATCH 2/7] R12 - drop all references to boolean() type --- src/cowboy_cookies.erl | 8 -------- src/cowboy_http.erl | 1 - src/cowboy_http_protocol.erl | 3 +-- src/cowboy_http_req.erl | 2 -- src/cowboy_http_static.erl | 5 ----- src/cowboy_http_websocket.erl | 2 +- 6 files changed, 2 insertions(+), 19 deletions(-) diff --git a/src/cowboy_cookies.erl b/src/cowboy_cookies.erl index 6818a86..7f5ab60 100644 --- a/src/cowboy_cookies.erl +++ b/src/cowboy_cookies.erl @@ -112,7 +112,6 @@ cookie(Key, Value, Options) when is_binary(Key) %% Internal. %% @doc Check if a character is a white space character. --spec is_whitespace(char()) -> boolean(). is_whitespace($\s) -> true; is_whitespace($\t) -> true; is_whitespace($\r) -> true; @@ -120,7 +119,6 @@ is_whitespace($\n) -> true; is_whitespace(_) -> false. %% @doc Check if a character is a seperator. --spec is_separator(char()) -> boolean(). is_separator(C) when C < 32 -> true; is_separator($\s) -> true; is_separator($\t) -> true; @@ -144,7 +142,6 @@ is_separator($}) -> true; is_separator(_) -> false. %% @doc Check if a binary has an ASCII seperator character. --spec has_seperator(binary()) -> boolean(). has_seperator(<<>>) -> false; has_seperator(<<$/, Rest/binary>>) -> @@ -228,7 +225,6 @@ read_quoted(<>, Acc) -> read_quoted(Rest, <>). %% @doc Drop characters while a function returns true. --spec binary_dropwhile(fun((char()) -> boolean()), binary()) -> binary(). binary_dropwhile(_F, <<"">>) -> <<"">>; binary_dropwhile(F, String) -> @@ -246,8 +242,6 @@ skip_whitespace(String) -> binary_dropwhile(fun is_whitespace/1, String). %% @doc Split a binary when the current character causes F to return true. --spec binary_splitwith(fun((char()) -> boolean()), binary(), binary()) - -> {binary(), binary()}. binary_splitwith(_F, Head, <<>>) -> {Head, <<>>}; binary_splitwith(F, Head, Tail) -> @@ -260,8 +254,6 @@ binary_splitwith(F, Head, Tail) -> end. %% @doc Split a binary with a function returning true or false on each char. --spec binary_splitwith(fun((char()) -> boolean()), binary()) - -> {binary(), binary()}. binary_splitwith(F, String) -> binary_splitwith(F, <<>>, String). diff --git a/src/cowboy_http.erl b/src/cowboy_http.erl index 95a7334..d7261c8 100644 --- a/src/cowboy_http.erl +++ b/src/cowboy_http.erl @@ -755,7 +755,6 @@ urlencode(Bin, Opts) -> Upper = proplists:get_value(upper, Opts, false), urlencode(Bin, <<>>, Plus, Upper). --spec urlencode(binary(), binary(), boolean(), boolean()) -> binary(). urlencode(<>, Acc, P=Plus, U=Upper) -> if C >= $0, C =< $9 -> urlencode(Rest, <>, P, U); C >= $A, C =< $Z -> urlencode(Rest, <>, P, U); diff --git a/src/cowboy_http_protocol.erl b/src/cowboy_http_protocol.erl index baee081..b80745f 100644 --- a/src/cowboy_http_protocol.erl +++ b/src/cowboy_http_protocol.erl @@ -55,7 +55,7 @@ max_line_length :: integer(), timeout :: timeout(), buffer = <<>> :: binary(), - hibernate = false :: boolean(), + hibernate = false, loop_timeout = infinity :: timeout(), loop_timeout_ref :: undefined | reference() }). @@ -440,7 +440,6 @@ format_header(Field) when byte_size(Field) =< 20; byte_size(Field) > 32 -> format_header(Field) -> format_header(Field, true, <<>>). --spec format_header(binary(), boolean(), binary()) -> binary(). format_header(<<>>, _Any, Acc) -> Acc; %% Replicate a bug in OTP for compatibility reasons when there's a - right diff --git a/src/cowboy_http_req.erl b/src/cowboy_http_req.erl index 92d96ad..d729d6c 100644 --- a/src/cowboy_http_req.erl +++ b/src/cowboy_http_req.erl @@ -515,13 +515,11 @@ set_resp_body_fun(StreamLen, StreamFun, Req) -> %% @doc Return whether the given header has been set for the response. --spec has_resp_header(cowboy_http:header(), #http_req{}) -> boolean(). has_resp_header(Name, #http_req{resp_headers=RespHeaders}) -> NameBin = header_to_binary(Name), lists:keymember(NameBin, 1, RespHeaders). %% @doc Return whether a body has been set for the response. --spec has_resp_body(#http_req{}) -> boolean(). has_resp_body(#http_req{resp_body={Length, _}}) -> Length > 0; has_resp_body(#http_req{resp_body=RespBody}) -> diff --git a/src/cowboy_http_static.erl b/src/cowboy_http_static.erl index 0ee996a..d370046 100644 --- a/src/cowboy_http_static.erl +++ b/src/cowboy_http_static.erl @@ -207,8 +207,6 @@ allowed_methods(Req, State) -> {['GET', 'HEAD'], Req, State}. %% @private --spec malformed_request(#http_req{}, #state{}) -> - {boolean(), #http_req{}, #state{}}. malformed_request(Req, #state{filepath=error}=State) -> {true, Req, State}; malformed_request(Req, State) -> @@ -216,8 +214,6 @@ malformed_request(Req, State) -> %% @private Check if the resource exists under the document root. --spec resource_exists(#http_req{}, #state{}) -> - {boolean(), #http_req{}, #state{}}. resource_exists(Req, #state{fileinfo={error, _}}=State) -> {false, Req, State}; resource_exists(Req, #state{fileinfo={ok, Fileinfo}}=State) -> @@ -227,7 +223,6 @@ resource_exists(Req, #state{fileinfo={ok, Fileinfo}}=State) -> %% @private %% Access to a file resource is forbidden if it exists and the local node does %% not have permission to read it. Directory listings are always forbidden. --spec forbidden(#http_req{}, #state{}) -> {boolean(), #http_req{}, #state{}}. forbidden(Req, #state{fileinfo={_, #file_info{type=directory}}}=State) -> {true, Req, State}; forbidden(Req, #state{fileinfo={error, eacces}}=State) -> diff --git a/src/cowboy_http_websocket.erl b/src/cowboy_http_websocket.erl index 0f0204c..5f59891 100644 --- a/src/cowboy_http_websocket.erl +++ b/src/cowboy_http_websocket.erl @@ -54,7 +54,7 @@ timeout = infinity :: timeout(), timeout_ref = undefined :: undefined | reference(), messages = undefined :: undefined | {atom(), atom(), atom()}, - hibernate = false :: boolean(), + hibernate = false, eop :: undefined | tuple(), %% hixie-76 specific. origin = undefined :: undefined | binary() %% hixie-76 specific. }). -- 1.7.0.4 rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/README.md0000644000177700017770000000002412633765070023155 0ustar michaelmichaelCowboy requires R14 rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/0008-sec-websocket-protocol.patch0000644000177700017770000000123112633765070027702 0ustar michaelmichaeldiff --git a/src/cowboy_http_req.erl b/src/cowboy_http_req.erl index 92d96ad..dd772df 100644 --- a/src/cowboy_http_req.erl +++ b/src/cowboy_http_req.erl @@ -288,6 +282,11 @@ parse_header(Name, Req, Default) when Name =:= 'Upgrade' -> fun (Value) -> cowboy_http:nonempty_list(Value, fun cowboy_http:token_ci/2) end); +parse_header(Name, Req, Default) when Name =:= <<"sec-websocket-protocol">> -> + parse_header(Name, Req, Default, + fun (Value) -> + cowboy_http:nonempty_list(Value, fun cowboy_http:token/2) + end); parse_header(Name, Req, Default) -> {Value, Req2} = header(Name, Req, Default), {undefined, Value, Req2}. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/CONTRIBUTING.md0000644000177700017770000000424512633765070024140 0ustar michaelmichael## Overview RabbitMQ projects use pull requests to discuss, collaborate on and accept code contributions. Pull requests is the primary place of discussing code changes. ## How to Contribute The process is fairly standard: * Fork the repository or repositories you plan on contributing to * Clone [RabbitMQ umbrella repository](https://github.com/rabbitmq/rabbitmq-public-umbrella) * `cd umbrella`, `make co` * Create a branch with a descriptive name in the relevant repositories * Make your changes, run tests, commit with a [descriptive message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), push to your fork * Submit pull requests with an explanation what has been changed and **why** * Submit a filled out and signed [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) if needed (see below) * Be patient. We will get to your pull request eventually If what you are going to work on is a substantial change, please first ask the core team of their opinion on [RabbitMQ mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). ## (Brief) Code of Conduct In one line: don't be a dick. Be respectful to the maintainers and other contributors. Open source contributors put long hours into developing projects and doing user support. Those projects and user support are available for free. We believe this deserves some respect. Be respectful to people of all races, genders, religious beliefs and political views. Regardless of how brilliant a pull request is technically, we will not tolerate disrespectful or aggressive behaviour. Contributors who violate this straightforward Code of Conduct will see their pull requests closed and locked. ## Contributor Agreement If you want to contribute a non-trivial change, please submit a signed copy of our [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) around the time you submit your pull request. This will make it much easier (in some cases, possible) for the RabbitMQ team at Pivotal to merge your contribution. ## Where to Ask Questions If something isn't clear, feel free to ask on our [mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/0001-R12-fake-iodata-type.patch0000644000177700017770000000255112633765070026772 0ustar michaelmichaelFrom c2303fb756eeb8bd92dc04764970a43f59940208 Mon Sep 17 00:00:00 2001 From: Marek Majkowski Date: Thu, 26 Jan 2012 12:48:41 +0000 Subject: [PATCH 1/7] R12 - Fake iodata() type --- include/http.hrl | 2 +- src/cowboy_http.erl | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/http.hrl b/include/http.hrl index c66f2b0..c98f873 100644 --- a/include/http.hrl +++ b/include/http.hrl @@ -47,7 +47,7 @@ %% Response. resp_state = waiting :: locked | waiting | chunks | done, resp_headers = [] :: cowboy_http:headers(), - resp_body = <<>> :: iodata() | {non_neg_integer(), + resp_body = <<>> :: cowboy_http:fake_iodata() | {non_neg_integer(), fun(() -> {sent, non_neg_integer()})}, %% Functions. diff --git a/src/cowboy_http.erl b/src/cowboy_http.erl index 32b0ca9..95a7334 100644 --- a/src/cowboy_http.erl +++ b/src/cowboy_http.erl @@ -46,7 +46,8 @@ | 'Expires' | 'Last-Modified' | 'Accept-Ranges' | 'Set-Cookie' | 'Set-Cookie2' | 'X-Forwarded-For' | 'Cookie' | 'Keep-Alive' | 'Proxy-Connection' | binary(). --type headers() :: [{header(), iodata()}]. +-type fake_iodata() :: iolist() | binary(). +-type headers() :: [{header(), fake_iodata()}]. -type status() :: non_neg_integer() | binary(). -export_type([method/0, uri/0, version/0, header/0, headers/0, status/0]). -- 1.7.0.4 rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/0000755000177700017770000000000012633765070023765 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/CHANGELOG.md0000644000177700017770000001576512633765070025614 0ustar michaelmichaelCHANGELOG ========= 0.4.0 ----- * Set the cowboy_listener process priority to high As it is the central process used by all incoming requests we need to set its priority to high to avoid timeouts that would happen otherwise when reaching a huge number of concurrent requests. * Add cowboy:child_spec/6 for embedding in other applications * Add cowboy_http_rest, an experimental REST protocol support Based on the Webmachine diagram and documentation. It is a new implementation, not a port, therefore a few changes have been made. However all the callback names are the same and should behave similarly to Webmachine. There is currently no documentation other than the Webmachine resource documentation and the comments found in cowboy_http_rest, which itself should be fairly easy to read and understand. * Add cowboy_http_static, an experimental static file handler Makes use of the aforementioned REST protocol support to deliver files with proper content type and cache headers. Note that this uses the new file:sendfile support when appropriate, which currently requires the VM to be started with the +A option defined, else errors may randomly appear. * Add cowboy_bstr module for binary strings related functions * Add cowboy_http module for HTTP parsing functions This module so far contains various functions for HTTP header parsing along with URL encoding and decoding. * Remove quoted from the default dependencies This should make Cowboy much easier to compile and use by default. It is of course still possible to use quoted as your URL decoding library in Cowboy thanks to the newly added urldecode option. * Fix supervisor spec for non dynamic modules to allow upgrades to complete * Add cowboy:accept_ack/1 for a cleaner handling of the shoot message Before, when the listener accepted a connection, the newly created process was waiting for a message containing the atom 'shoot' before proceeding. This has been replaced by the cowboy:accept_ack/1 function. This function should be used where 'shoot' was received because the contents of the message have changed (and could change again in the distant future). * Update binary parsing expressions to avoid hype crashes More specifically, /bits was replaced by /binary. * Rename the type cowboy_dispatcher:path_tokens/0 to tokens/0 * Remove the cowboy_clock:date/0, time/0 and datetime/0 types The calendar module exports those same types properly since R14B04. * Add cacertfile configuration option to cowboy_ssl_transport * Add cowboy_protocol behaviour * Remove -Wbehaviours dialyzer option unavailable in R15B * Many tests and specs improvements ### cowboy_http_req * Fix a crash when reading the request body * Add parse_header/2 and parse_header/3 The following headers can now be semantically parsed: Connection, Accept, Accept-Charset, Accept-Encoding, Accept-Language, Content-Length, Content-Type, If-Match, If-None-Match, If-Modified-Since, If-Unmodified-Since, Upgrade * Add set_resp_header/3, set_resp_cookie/4 and set_resp_body/2 These functions allow handlers to set response headers and body without having to reply directly. * Add set_resp_body_fun/3 This function allows handlers to stream the body of the response using the given fun. The size of the response must be known beforehand. * Add transport/1 to obtain the transport and socket for the request This allows handlers to have low-level socket access in those cases where they do need it, like when streaming a response body with set_resp_body_fun/3. * Add peer_addr/1 This function tries to guess the real peer IP based on the HTTP headers received. * Add meta/2 and meta/3 to save useful protocol information Currently used to save the Websocket protocol version currently used, and to save request information in the REST protocol handler. * Add reply/2 and reply/3 aliases to reply/4 * Add upgrade_reply/3 for protocol upgrades ### cowboy_http_protocol * Add the {urldecode, fun urldecode/2} option Added when quoted was removed from the default build. Can be used to tell Cowboy to use quoted or any other URL decoding routine. * Add the max_keepalive option * Add the max_line_length option * Allow HTTP handlers to stop during init/3 To do so they can return {shutdown, Req, State}. * Add loops support in HTTP handlers for proper long-polling support A loop can be entered by returning either of {loop, Req, State}, {loop, Req, State, hibernate}, {loop, Req, State, Timeout} or {loop, Req, State, Timeout, hibernate} from init/3. Loops are useful when we cannot reply immediately and instead are waiting for an Erlang message to be able to complete the request, as would typically be done for long-polling. Loop support in the protocol means that timeouts and hibernating are well tested and handled so you can use those options without worrying. It is recommended to set the timeout option. When a loop is started, handle/2 will never be called so it does not need to be defined. When the request process receives an Erlang message, it will call the info/3 function with the message as the first argument. Like in OTP, you do need to set timeout and hibernate again when returning from info/3 to enable them until the next call. * Fix the sending of 500 errors when handlers crash Now we send an error response when no response has been sent, and do nothing more than close the connection if anything did get sent. * Fix a crash when the server is sent HTTP responses * Fix HTTP timeouts handling when the Request-Line wasn't received * Fix the handling of the max number of empty lines between requests * Fix the handling of HEAD requests * Fix HTTP/1.0 Host header handling * Reply status 400 if we receive an unexpected value or error for headers * Properly close when the application sends "Connection: close" header * Close HTTP connections on all errors * Improve the error message for HTTP handlers ### cowboy_http_websocket * Add websocket support for all versions up to RFC 6455 Support isn't perfect yet according to the specifications, but is working against all currently known client implementations. * Allow websocket_init/3 to return with the hibernate option set * Add {shutdown, Req} return value to websocket_init/3 to fail an upgrade * Fix websocket timeout handling * Fix error messages: wrong callback name was reported on error * Fix byte-by-byte websocket handling * Fix an issue when using hixie-76 with certain proxies * Fix a crash in the hixie-76 handshake * Fix the handshake when SSL is used on port 443 * Fix a crash in the handshake when cowboy_http_req:compact/1 is used * Fix handshake when a query string is present * Fix a crash when the Upgrade header contains more than one token 0.2.0 ----- * Initial release. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/README.md0000644000177700017770000002616712633765070025260 0ustar michaelmichaelCowboy ====== Cowboy is a small, fast and modular HTTP server written in Erlang. Cowboy is also a socket acceptor pool, able to accept connections for any kind of TCP protocol. Goals ----- Cowboy aims to provide the following advantages: * **Small** code base. * Damn **fast**. * **Modular**: transport and protocol handlers are replaceable. * **Binary HTTP** for greater speed and lower memory usage. * Easy to **embed** inside another application. * Selectively **dispatch** requests to handlers, allowing you to send some requests to your embedded code and others to a FastCGI application in PHP or Ruby. * No parameterized module. No process dictionary. **Clean** Erlang code. The server is currently in early development. Comments and suggestions are more than welcome. To contribute, either open bug reports, or fork the project and send us pull requests with new or improved functionality. You should discuss your plans with us before doing any serious work, though, to avoid duplicating efforts. Quick start ----------- * Add Cowboy as a rebar or agner dependency to your application. * Start Cowboy and add one or more listeners. * Write handlers for your application. * Check out [examples](https://github.com/extend/cowboy_examples)! Getting Started --------------- At heart, Cowboy is nothing more than an TCP acceptor pool. All it does is accept connections received on a given port and using a given transport, like TCP or SSL, and forward them to a request handler for the given protocol. Acceptors and request handlers are of course supervised automatically. It just so happens that Cowboy also includes an HTTP protocol handler. But Cowboy does nothing by default. You need to explicitly ask Cowboy to listen on a port with your chosen transport and protocol handlers. To do so, you must start a listener. A listener is a special kind of supervisor that manages both the acceptor pool and the request processes. It is named and can thus be started and stopped at will. An acceptor pool is a pool of processes whose only role is to accept new connections. It's good practice to have many of these processes as they are very cheap and allow much quicker response when you get many connections. Of course, as with everything else, you should **benchmark** before you decide what's best for you. Cowboy includes a TCP transport handler for HTTP and an SSL transport handler for HTTPS. The transport handlers can of course be reused for other protocols like FTP or IRC. The HTTP protocol requires one last thing to continue: dispatching rules. Don't worry about it right now though and continue reading, it'll all be explained. You can start and stop listeners by calling `cowboy:start_listener/6` and `cowboy:stop_listener/1` respectively. The following example demonstrates the startup of a very simple listener. ``` erlang application:start(cowboy), Dispatch = [ %% {Host, list({Path, Handler, Opts})} {'_', [{'_', my_handler, []}]} ], %% Name, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts cowboy:start_listener(my_http_listener, 100, cowboy_tcp_transport, [{port, 8080}], cowboy_http_protocol, [{dispatch, Dispatch}] ). ``` This is not enough though, you must also write the my_handler module to process the incoming HTTP requests. Of course Cowboy comes with predefined handlers for specific tasks but most of the time you'll want to write your own handlers for your application. Following is an example of a "Hello World!" HTTP handler. ``` erlang -module(my_handler). -export([init/3, handle/2, terminate/2]). init({tcp, http}, Req, Opts) -> {ok, Req, undefined_state}. handle(Req, State) -> {ok, Req2} = cowboy_http_req:reply(200, [], <<"Hello World!">>, Req), {ok, Req2, State}. terminate(Req, State) -> ok. ``` You can also write handlers that do not reply directly. Instead, such handlers will wait for an Erlang message from another process and only reply when receiving such message, or timeout if it didn't arrive in time. This is especially useful for long-polling functionality, as Cowboy will handle process hibernation and timeouts properly, preventing mistakes if you were to write the code yourself. An handler of that kind can be defined like this: ``` erlang -module(my_loop_handler). -export([init/3, info/3, terminate/2]). -define(TIMEOUT, 60000). init({tcp, http}, Req, Opts) -> {loop, Req, undefined_state, ?TIMEOUT, hibernate}. info({reply, Body}, Req, State) -> {ok, Req2} = cowboy_http_req:reply(200, [], Body, Req), {ok, Req2, State}; info(Message, Req, State) -> {loop, Req, State, hibernate}. terminate(Req, State) -> ok. ``` It is of course possible to combine both type of handlers together as long as you return the proper tuple from init/3. **Note**: versions prior to `0.4.0` used the [quoted](https://github.com/klaar/quoted.erl) library instead of the built in `cowboy_http:urldecode/2` function. If you want to retain this you must add it as a dependency to your application and add the following cowboy_http_protocol option: ``` erlang {urldecode, {fun quoted:from_url/2, quoted:make([])}} ``` Continue reading to learn how to dispatch rules and handle requests. Dispatch rules -------------- Cowboy allows you to dispatch HTTP requests directly to a specific handler based on the hostname and path information from the request. It also lets you define static options for the handler directly in the rules. To match the hostname and path, Cowboy requires a list of tokens. For example, to match the "dev-extend.eu" domain name, you must specify `[<<"dev-extend">>, <<"eu">>]`. Or, to match the "/path/to/my/resource" you must use `[<<"path">>, <<"to">>, <<"my">>, <<"resource">>]`. All the tokens must be given as binary. You can use the special token `'_'` (the atom underscore) to indicate that you accept anything in that position. For example if you have both "dev-extend.eu" and "dev-extend.fr" domains, you can use the match spec `[<<"dev-extend">>, '_']` to match any top level extension. Finally, you can also match multiple leading segments of the domain name and multiple trailing segments of the request path using the atom `'...'` (the atom ellipsis) respectively as the first host token or the last path token. For example, host rule `['...', <<"dev-extend">>, <<"eu">>]` can match both "cowboy.bugs.dev-extend.eu" and "dev-extend.eu" and path rule `[<<"projects">>, '...']` can match both "/projects" and "/projects/cowboy/issues/42". The host leading segments and the path trailing segments can later be retrieved through `cowboy_http_req:host_info/1` and `cowboy_http_req:path_info/1`. Any other atom used as a token will bind the value to this atom when matching. To follow on our hostnames example, `[<<"dev-extend">>, ext]` would bind the values `<<"eu">>` and `<<"fr">>` to the ext atom, that you can later retrieve in your handler by calling `cowboy_http_req:binding/{2,3}`. You can also accept any match spec by using the atom `'_'` directly instead of a list of tokens. Our hello world example above uses this to forward all requests to a single handler. There is currently no way to match multiple tokens at once. Requests handling ----------------- Requests are passed around in the Request variable. Although they are defined as a record, it is recommended to access them only through the cowboy_http_req module API. You can retrieve the HTTP method, HTTP version, peer address and port, host tokens, raw host, used port, path tokens, raw path, query string values, bound values from the dispatch step, header values from the request. You can also read the request body, if any, optionally parsing it as a query string. Finally, the request allows you to send a response to the client. See the cowboy_http_req module for more information. Websockets ---------- The Websocket protocol is built upon the HTTP protocol. It first sends an HTTP request for an handshake, performs it and then switches to Websocket. Therefore you need to write a standard HTTP handler to confirm the handshake should be completed and then the Websocket-specific callbacks. A simple handler doing nothing but sending a repetitive message using Websocket would look like this: ``` erlang -module(my_ws_handler). -export([init/3]). -export([websocket_init/3, websocket_handle/3, websocket_info/3, websocket_terminate/3]). init({tcp, http}, Req, Opts) -> {upgrade, protocol, cowboy_http_websocket}. websocket_init(TransportName, Req, _Opts) -> erlang:start_timer(1000, self(), <<"Hello!">>), {ok, Req, undefined_state}. websocket_handle({text, Msg}, Req, State) -> {reply, {text, << "That's what she said! ", Msg/binary >>}, Req, State}; websocket_handle(_Data, Req, State) -> {ok, Req, State}. websocket_info({timeout, _Ref, Msg}, Req, State) -> erlang:start_timer(1000, self(), <<"How' you doin'?">>), {reply, {text, Msg}, Req, State}; websocket_info(_Info, Req, State) -> {ok, Req, State}. websocket_terminate(_Reason, _Req, _State) -> ok. ``` Of course you can have an HTTP handler doing both HTTP and Websocket handling, but for the sake of this example we're ignoring the HTTP part entirely. As the Websocket protocol is still a draft the API is subject to change regularly when support to the most recent drafts gets added. Features may be added, changed or removed before the protocol gets finalized. Cowboy tries to implement all drafts transparently and give a single interface to handle them all, however. Using Cowboy with other protocols --------------------------------- One of the strengths of Cowboy is of course that you can use it with any protocol you want. The only downside is that if it's not HTTP, you'll probably have to write the protocol handler yourself. The only exported function a protocol handler needs is the start_link/4 function, with arguments ListenerPid, Socket, Transport and Opts. ListenerPid is the pid to the listener's gen_server, managing the connections. Socket is of course the client socket; Transport is the module name of the chosen transport handler and Opts is protocol options defined when starting the listener. After initializing your protocol, it is recommended to call the function cowboy:accept_ack/1 with the ListenerPid as argument, as it will ensure Cowboy has been able to fully initialize the socket. Anything you do past this point is up to you! If you need to change some socket options, like enabling raw mode for example, you can call the Transport:setopts/2 function. It is the protocol's responsability to manage the socket usage, there should be no need for an user to specify that kind of options while starting a listener. You should definitely look at the cowboy_http_protocol module for a great example of fast request handling if you need to. Otherwise it's probably safe to use `{active, once}` mode and handle everything as it comes. Note that while you technically can run a protocol handler directly as a gen_server or a gen_fsm, it's probably not a good idea, as the only call you'll ever receive from Cowboy is the start_link/4 call. On the other hand, feel free to write a very basic protocol handler which then forwards requests to a gen_server or gen_fsm. By doing so however you must take care to supervise their processes as Cowboy only knows about the protocol handler itself. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/0000755000177700017770000000000012633765070024554 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_bstr.erl0000644000177700017770000000520612633765070027617 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @doc Binary string manipulation. -module(cowboy_bstr). -export([to_lower/1]). %% Binary strings. -export([char_to_lower/1, char_to_upper/1]). %% Characters. %% @doc Convert a binary string to lowercase. -spec to_lower(binary()) -> binary(). to_lower(L) -> << << (char_to_lower(C)) >> || << C >> <= L >>. %% @doc Convert [A-Z] characters to lowercase. %% @end %% We gain noticeable speed by matching each value directly. -spec char_to_lower(char()) -> char(). char_to_lower($A) -> $a; char_to_lower($B) -> $b; char_to_lower($C) -> $c; char_to_lower($D) -> $d; char_to_lower($E) -> $e; char_to_lower($F) -> $f; char_to_lower($G) -> $g; char_to_lower($H) -> $h; char_to_lower($I) -> $i; char_to_lower($J) -> $j; char_to_lower($K) -> $k; char_to_lower($L) -> $l; char_to_lower($M) -> $m; char_to_lower($N) -> $n; char_to_lower($O) -> $o; char_to_lower($P) -> $p; char_to_lower($Q) -> $q; char_to_lower($R) -> $r; char_to_lower($S) -> $s; char_to_lower($T) -> $t; char_to_lower($U) -> $u; char_to_lower($V) -> $v; char_to_lower($W) -> $w; char_to_lower($X) -> $x; char_to_lower($Y) -> $y; char_to_lower($Z) -> $z; char_to_lower(Ch) -> Ch. %% @doc Convert [a-z] characters to uppercase. -spec char_to_upper(char()) -> char(). char_to_upper($a) -> $A; char_to_upper($b) -> $B; char_to_upper($c) -> $C; char_to_upper($d) -> $D; char_to_upper($e) -> $E; char_to_upper($f) -> $F; char_to_upper($g) -> $G; char_to_upper($h) -> $H; char_to_upper($i) -> $I; char_to_upper($j) -> $J; char_to_upper($k) -> $K; char_to_upper($l) -> $L; char_to_upper($m) -> $M; char_to_upper($n) -> $N; char_to_upper($o) -> $O; char_to_upper($p) -> $P; char_to_upper($q) -> $Q; char_to_upper($r) -> $R; char_to_upper($s) -> $S; char_to_upper($t) -> $T; char_to_upper($u) -> $U; char_to_upper($v) -> $V; char_to_upper($w) -> $W; char_to_upper($x) -> $X; char_to_upper($y) -> $Y; char_to_upper($z) -> $Z; char_to_upper(Ch) -> Ch. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_sup.erl0000644000177700017770000000244112633765070027452 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @private -module(cowboy_sup). -behaviour(supervisor). -export([start_link/0]). %% API. -export([init/1]). %% supervisor. -define(SUPERVISOR, ?MODULE). %% API. -spec start_link() -> {ok, pid()}. start_link() -> supervisor:start_link({local, ?SUPERVISOR}, ?MODULE, []). %% supervisor. -spec init([]) -> {ok, {{one_for_one, 10, 10}, [{_, _, _, _, _, _}, ...]}}. init([]) -> Procs = [{cowboy_clock, {cowboy_clock, start_link, []}, permanent, 5000, worker, [cowboy_clock]}], {ok, {{one_for_one, 10, 10}, Procs}}. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_listener.erl0000644000177700017770000001443612633765070030477 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @doc Public API for managing listeners. -module(cowboy_listener). -behaviour(gen_server). -export([start_link/0, stop/1, add_connection/3, move_connection/3, remove_connection/2, wait/3]). %% API. -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). %% gen_server. -record(state, { req_pools = [] :: [{atom(), non_neg_integer()}], reqs_table, queue = [] }). %% API. %% @private %% %% We set the process priority to high because cowboy_listener is the central %% gen_server in Cowboy and is used to manage all the incoming connections. %% Setting the process priority to high ensures the connection-related code %% will always be executed when a connection needs it, allowing Cowboy to %% scale far beyond what it would with a normal priority. -spec start_link() -> {ok, pid()}. start_link() -> gen_server:start_link(?MODULE, [], [{spawn_opt, [{priority, high}]}]). %% @private -spec stop(pid()) -> stopped. stop(ServerPid) -> gen_server:call(ServerPid, stop). %% @doc Add a connection to the given pool in the listener. %% %% Pools of connections are used to restrict the maximum number of connections %% depending on their type. By default, Cowboy add all connections to the %% pool default. It also checks for the maximum number of connections %% in that pool before accepting again. %% %% When a process managing a connection dies, the process is removed from the %% pool. If the socket has been sent to another process, it is up to the %% protocol code to inform the listener of the new ConnPid by removing %% the previous and adding the new one. -spec add_connection(pid(), atom(), pid()) -> {ok, non_neg_integer()}. add_connection(ServerPid, Pool, ConnPid) -> gen_server:call(ServerPid, {add_connection, Pool, ConnPid}). %% @doc Move a connection from one pool to another. -spec move_connection(pid(), atom(), pid()) -> ok. move_connection(ServerPid, DestPool, ConnPid) -> gen_server:cast(ServerPid, {move_connection, DestPool, ConnPid}). %% @doc Remove the given connection from its pool. -spec remove_connection(pid(), pid()) -> ok. remove_connection(ServerPid, ConnPid) -> gen_server:cast(ServerPid, {remove_connection, ConnPid}). %% @doc Wait until the number of connections in the given pool gets below %% the given threshold. %% %% This function will not return until the number of connections in the pool %% gets below MaxConns. It makes use of gen_server:reply/2 %% to make the process wait for a reply indefinitely. -spec wait(pid(), atom(), non_neg_integer()) -> ok. wait(ServerPid, Pool, MaxConns) -> gen_server:call(ServerPid, {wait, Pool, MaxConns}, infinity). %% gen_server. %% @private -spec init([]) -> {ok, #state{}}. init([]) -> ReqsTablePid = ets:new(requests_table, [set, private]), {ok, #state{reqs_table=ReqsTablePid}}. %% @private -spec handle_call(_, _, State) -> {reply, ignored, State} | {stop, normal, stopped, State}. handle_call({add_connection, Pool, ConnPid}, _From, State=#state{ req_pools=Pools, reqs_table=ReqsTable}) -> MonitorRef = erlang:monitor(process, ConnPid), {NbConnsRet, Pools2} = case lists:keyfind(Pool, 1, Pools) of false -> {1, [{Pool, 1}|Pools]}; {Pool, NbConns} -> NbConns2 = NbConns + 1, {NbConns2, [{Pool, NbConns2}|lists:keydelete(Pool, 1, Pools)]} end, ets:insert(ReqsTable, {ConnPid, {MonitorRef, Pool}}), {reply, {ok, NbConnsRet}, State#state{req_pools=Pools2}}; handle_call({wait, Pool, MaxConns}, From, State=#state{ req_pools=Pools, queue=Queue}) -> case lists:keyfind(Pool, 1, Pools) of {Pool, NbConns} when NbConns > MaxConns -> {noreply, State#state{queue=[From|Queue]}}; _Any -> {reply, ok, State} end; handle_call(stop, _From, State) -> {stop, normal, stopped, State}; handle_call(_Request, _From, State) -> {reply, ignored, State}. %% @private -spec handle_cast(_, State) -> {noreply, State}. handle_cast({move_connection, DestPool, ConnPid}, State=#state{ req_pools=Pools, reqs_table=ReqsTable}) -> {MonitorRef, SrcPool} = ets:lookup_element(ReqsTable, ConnPid, 2), ets:insert(ReqsTable, {ConnPid, {MonitorRef, DestPool}}), {SrcPool, SrcNbConns} = lists:keyfind(SrcPool, 1, Pools), DestNbConns = case lists:keyfind(DestPool, 1, Pools) of false -> 1; {DestPool, NbConns} -> NbConns + 1 end, Pools2 = lists:keydelete(SrcPool, 1, lists:keydelete(DestPool, 1, Pools)), Pools3 = [{SrcPool, SrcNbConns - 1}, {DestPool, DestNbConns}|Pools2], {noreply, State#state{req_pools=Pools3}}; handle_cast({remove_connection, ConnPid}, State) -> State2 = remove_pid(ConnPid, State), {noreply, State2}; handle_cast(_Msg, State) -> {noreply, State}. %% @private -spec handle_info(_, State) -> {noreply, State}. handle_info({'DOWN', _Ref, process, Pid, _Info}, State) -> State2 = remove_pid(Pid, State), {noreply, State2}; handle_info(_Info, State) -> {noreply, State}. %% @private -spec terminate(_, _) -> ok. terminate(_Reason, _State) -> ok. %% @private -spec code_change(_, State, _) -> {ok, State}. code_change(_OldVsn, State, _Extra) -> {ok, State}. %% Internal. %% @private -spec remove_pid(pid(), State) -> State. remove_pid(Pid, State=#state{ req_pools=Pools, reqs_table=ReqsTable, queue=Queue}) -> {MonitorRef, Pool} = ets:lookup_element(ReqsTable, Pid, 2), erlang:demonitor(MonitorRef, [flush]), {Pool, NbConns} = lists:keyfind(Pool, 1, Pools), Pools2 = [{Pool, NbConns - 1}|lists:keydelete(Pool, 1, Pools)], ets:delete(ReqsTable, Pid), case Queue of [] -> State#state{req_pools=Pools2}; [Client|Queue2] -> gen_server:reply(Client, ok), State#state{req_pools=Pools2, queue=Queue2} end. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_protocol.erl0000644000177700017770000000541512633765070030510 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% Copyright (c) 2011, Michiel Hakvoort %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @doc Cowboy protocol. %% %% A Cowboy protocol must implement one callback: start_link/4. %% %% start_link/4 is meant for the initialization of the %% protocol process. %% It receives the pid to the listener's gen_server, the client socket, %% the module name of the chosen transport and the options defined when %% starting the listener. The start_link/4 function must follow %% the supervisor start function specification. %% %% After initializing your protocol, it is recommended to call the %% function cowboy:accept_ack/1 with the ListenerPid as argument, %% as it will ensure Cowboy has been able to fully initialize the socket. %% Anything you do past this point is up to you! %% %% If you need to change some socket options, like enabling raw mode %% for example, you can call the Transport:setopts/2 function. %% It is the protocol's responsability to manage the socket usage, %% there should be no need for an user to specify that kind of options %% while starting a listener. %% %% You should definitely look at the cowboy_http_protocol module for %% a great example of fast request handling if you need to. %% Otherwise it's probably safe to use {active, once} mode %% and handle everything as it comes. %% %% Note that while you technically can run a protocol handler directly %% as a gen_server or a gen_fsm, it's probably not a good idea, %% as the only call you'll ever receive from Cowboy is the %% start_link/4 call. On the other hand, feel free to write %% a very basic protocol handler which then forwards requests to a %% gen_server or gen_fsm. By doing so however you must take care to %% supervise their processes as Cowboy only knows about the protocol %% handler itself. -module(cowboy_protocol). -export([behaviour_info/1]). %% @private -spec behaviour_info(_) -> undefined | [{start_link, 4}, ...]. behaviour_info(callbacks) -> [{start_link, 4}]; behaviour_info(_Other) -> undefined. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_cookies.erl0000644000177700017770000002556212633765070030310 0ustar michaelmichael%% Copyright 2007 Mochi Media, Inc. %% Copyright 2011 Thomas Burdick %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @doc HTTP Cookie parsing and generating (RFC 2965). -module(cowboy_cookies). -export([parse_cookie/1, cookie/3, cookie/2]). %% API. %% Types. -type kv() :: {Name::binary(), Value::binary()}. -type kvlist() :: [kv()]. -type cookie_option() :: {max_age, integer()} | {local_time, calendar:datetime()} | {domain, binary()} | {path, binary()} | {secure, true | false} | {http_only, true | false}. -export_type([kv/0, kvlist/0, cookie_option/0]). -define(QUOTE, $\"). -include_lib("eunit/include/eunit.hrl"). %% API. %% @doc Parse the contents of a Cookie header field, ignoring cookie %% attributes, and return a simple property list. -spec parse_cookie(binary()) -> kvlist(). parse_cookie(<<>>) -> []; parse_cookie(Cookie) when is_binary(Cookie) -> parse_cookie(Cookie, []). %% @equiv cookie(Key, Value, []) -spec cookie(binary(), binary()) -> kv(). cookie(Key, Value) when is_binary(Key) andalso is_binary(Value) -> cookie(Key, Value, []). %% @doc Generate a Set-Cookie header field tuple. -spec cookie(binary(), binary(), [cookie_option()]) -> kv(). cookie(Key, Value, Options) when is_binary(Key) andalso is_binary(Value) andalso is_list(Options) -> Cookie = <<(any_to_binary(Key))/binary, "=", (quote(Value))/binary, "; Version=1">>, %% Set-Cookie: %% Comment, Domain, Max-Age, Path, Secure, Version ExpiresPart = case proplists:get_value(max_age, Options) of undefined -> <<"">>; RawAge -> When = case proplists:get_value(local_time, Options) of undefined -> calendar:local_time(); LocalTime -> LocalTime end, Age = case RawAge < 0 of true -> 0; false -> RawAge end, AgeBinary = quote(Age), CookieDate = age_to_cookie_date(Age, When), <<"; Expires=", CookieDate/binary, "; Max-Age=", AgeBinary/binary>> end, SecurePart = case proplists:get_value(secure, Options) of true -> <<"; Secure">>; _ -> <<"">> end, DomainPart = case proplists:get_value(domain, Options) of undefined -> <<"">>; Domain -> <<"; Domain=", (quote(Domain))/binary>> end, PathPart = case proplists:get_value(path, Options) of undefined -> <<"">>; Path -> <<"; Path=", (quote(Path))/binary>> end, HttpOnlyPart = case proplists:get_value(http_only, Options) of true -> <<"; HttpOnly">>; _ -> <<"">> end, CookieParts = <>, {<<"Set-Cookie">>, CookieParts}. %% Internal. %% @doc Check if a character is a white space character. is_whitespace($\s) -> true; is_whitespace($\t) -> true; is_whitespace($\r) -> true; is_whitespace($\n) -> true; is_whitespace(_) -> false. %% @doc Check if a character is a seperator. is_separator(C) when C < 32 -> true; is_separator($\s) -> true; is_separator($\t) -> true; is_separator($() -> true; is_separator($)) -> true; is_separator($<) -> true; is_separator($>) -> true; is_separator($@) -> true; is_separator($,) -> true; is_separator($;) -> true; is_separator($:) -> true; is_separator($\\) -> true; is_separator(?QUOTE) -> true; is_separator($/) -> true; is_separator($[) -> true; is_separator($]) -> true; is_separator($?) -> true; is_separator($=) -> true; is_separator(${) -> true; is_separator($}) -> true; is_separator(_) -> false. %% @doc Check if a binary has an ASCII seperator character. has_seperator(<<>>) -> false; has_seperator(<<$/, Rest/binary>>) -> has_seperator(Rest); has_seperator(<>) -> case is_separator(C) of true -> true; false -> has_seperator(Rest) end. %% @doc Convert to a binary and raise an error if quoting is required. Quoting %% is broken in different ways for different browsers. Its better to simply %% avoiding doing it at all. %% @end -spec quote(term()) -> binary(). quote(V0) -> V = any_to_binary(V0), case has_seperator(V) of true -> erlang:error({cookie_quoting_required, V}); false -> V end. -spec add_seconds(integer(), calendar:datetime()) -> calendar:datetime(). add_seconds(Secs, LocalTime) -> Greg = calendar:datetime_to_gregorian_seconds(LocalTime), calendar:gregorian_seconds_to_datetime(Greg + Secs). -spec age_to_cookie_date(integer(), calendar:datetime()) -> binary(). age_to_cookie_date(Age, LocalTime) -> cowboy_clock:rfc2109(add_seconds(Age, LocalTime)). -spec parse_cookie(binary(), kvlist()) -> kvlist(). parse_cookie(<<>>, Acc) -> lists:reverse(Acc); parse_cookie(String, Acc) -> {{Token, Value}, Rest} = read_pair(String), Acc1 = case Token of <<"">> -> Acc; <<"$", _R/binary>> -> Acc; _ -> [{Token, Value} | Acc] end, parse_cookie(Rest, Acc1). -spec read_pair(binary()) -> {{binary(), binary()}, binary()}. read_pair(String) -> {Token, Rest} = read_token(skip_whitespace(String)), {Value, Rest1} = read_value(skip_whitespace(Rest)), {{Token, Value}, skip_past_separator(Rest1)}. -spec read_value(binary()) -> {binary(), binary()}. read_value(<<"=", Value/binary>>) -> Value1 = skip_whitespace(Value), case Value1 of <> -> read_quoted(Value1); _ -> read_token(Value1) end; read_value(String) -> {<<"">>, String}. -spec read_quoted(binary()) -> {binary(), binary()}. read_quoted(<>) -> read_quoted(String, <<"">>). -spec read_quoted(binary(), binary()) -> {binary(), binary()}. read_quoted(<<"">>, Acc) -> {Acc, <<"">>}; read_quoted(<>, Acc) -> {Acc, Rest}; read_quoted(<<$\\, Any, Rest/binary>>, Acc) -> read_quoted(Rest, <>); read_quoted(<>, Acc) -> read_quoted(Rest, <>). %% @doc Drop characters while a function returns true. binary_dropwhile(_F, <<"">>) -> <<"">>; binary_dropwhile(F, String) -> <> = String, case F(C) of true -> binary_dropwhile(F, Rest); false -> String end. %% @doc Remove leading whitespace. -spec skip_whitespace(binary()) -> binary(). skip_whitespace(String) -> binary_dropwhile(fun is_whitespace/1, String). %% @doc Split a binary when the current character causes F to return true. binary_splitwith(_F, Head, <<>>) -> {Head, <<>>}; binary_splitwith(F, Head, Tail) -> <> = Tail, case F(C) of true -> {Head, Tail}; false -> binary_splitwith(F, <>, NTail) end. %% @doc Split a binary with a function returning true or false on each char. binary_splitwith(F, String) -> binary_splitwith(F, <<>>, String). %% @doc Split the binary when the next seperator is found. -spec read_token(binary()) -> {binary(), binary()}. read_token(String) -> binary_splitwith(fun is_separator/1, String). %% @doc Return string after ; or , characters. -spec skip_past_separator(binary()) -> binary(). skip_past_separator(<<"">>) -> <<"">>; skip_past_separator(<<";", Rest/binary>>) -> Rest; skip_past_separator(<<",", Rest/binary>>) -> Rest; skip_past_separator(<<_C, Rest/binary>>) -> skip_past_separator(Rest). -spec any_to_binary(binary() | string() | atom() | integer()) -> binary(). any_to_binary(V) when is_binary(V) -> V; any_to_binary(V) when is_list(V) -> erlang:list_to_binary(V); any_to_binary(V) when is_atom(V) -> erlang:atom_to_binary(V, latin1); any_to_binary(V) when is_integer(V) -> list_to_binary(integer_to_list(V)). %% Tests. -ifdef(TEST). quote_test() -> %% ?assertError eunit macro is not compatible with coverage module _ = try quote(<<":wq">>) catch error:{cookie_quoting_required, <<":wq">>} -> ok end, ?assertEqual(<<"foo">>,quote(foo)), ok. parse_cookie_test() -> %% RFC example C1 = <<"$Version=\"1\"; Customer=\"WILE_E_COYOTE\"; $Path=\"/acme\"; Part_Number=\"Rocket_Launcher_0001\"; $Path=\"/acme\"; Shipping=\"FedEx\"; $Path=\"/acme\"">>, ?assertEqual( [{<<"Customer">>,<<"WILE_E_COYOTE">>}, {<<"Part_Number">>,<<"Rocket_Launcher_0001">>}, {<<"Shipping">>,<<"FedEx">>}], parse_cookie(C1)), %% Potential edge cases ?assertEqual( [{<<"foo">>, <<"x">>}], parse_cookie(<<"foo=\"\\x\"">>)), ?assertEqual( [], parse_cookie(<<"=">>)), ?assertEqual( [{<<"foo">>, <<"">>}, {<<"bar">>, <<"">>}], parse_cookie(<<" foo ; bar ">>)), ?assertEqual( [{<<"foo">>, <<"">>}, {<<"bar">>, <<"">>}], parse_cookie(<<"foo=;bar=">>)), ?assertEqual( [{<<"foo">>, <<"\";">>}, {<<"bar">>, <<"">>}], parse_cookie(<<"foo = \"\\\";\";bar ">>)), ?assertEqual( [{<<"foo">>, <<"\";bar">>}], parse_cookie(<<"foo=\"\\\";bar">>)), ?assertEqual( [], parse_cookie(<<"">>)), ?assertEqual( [{<<"foo">>, <<"bar">>}, {<<"baz">>, <<"wibble">>}], parse_cookie(<<"foo=bar , baz=wibble ">>)), ok. domain_test() -> ?assertEqual( {<<"Set-Cookie">>, <<"Customer=WILE_E_COYOTE; " "Version=1; " "Domain=acme.com; " "HttpOnly">>}, cookie(<<"Customer">>, <<"WILE_E_COYOTE">>, [{http_only, true}, {domain, <<"acme.com">>}])), ok. local_time_test() -> {<<"Set-Cookie">>, B} = cookie(<<"Customer">>, <<"WILE_E_COYOTE">>, [{max_age, 111}, {secure, true}]), ?assertMatch( [<<"Customer=WILE_E_COYOTE">>, <<" Version=1">>, <<" Expires=", _R/binary>>, <<" Max-Age=111">>, <<" Secure">>], binary:split(B, <<";">>, [global])), ok. -spec cookie_test() -> no_return(). %% Not actually true, just a bad option. cookie_test() -> C1 = {<<"Set-Cookie">>, <<"Customer=WILE_E_COYOTE; " "Version=1; " "Path=/acme">>}, C1 = cookie(<<"Customer">>, <<"WILE_E_COYOTE">>, [{path, <<"/acme">>}]), C1 = cookie(<<"Customer">>, <<"WILE_E_COYOTE">>, [{path, <<"/acme">>}, {badoption, <<"negatory">>}]), {<<"Set-Cookie">>,<<"=NoKey; Version=1">>} = cookie(<<"">>, <<"NoKey">>, []), {<<"Set-Cookie">>,<<"=NoKey; Version=1">>} = cookie(<<"">>, <<"NoKey">>), LocalTime = calendar:universal_time_to_local_time( {{2007, 5, 15}, {13, 45, 33}}), C2 = {<<"Set-Cookie">>, <<"Customer=WILE_E_COYOTE; " "Version=1; " "Expires=Tue, 15 May 2007 13:45:33 GMT; " "Max-Age=0">>}, C2 = cookie(<<"Customer">>, <<"WILE_E_COYOTE">>, [{max_age, -111}, {local_time, LocalTime}]), C3 = {<<"Set-Cookie">>, <<"Customer=WILE_E_COYOTE; " "Version=1; " "Expires=Wed, 16 May 2007 13:45:50 GMT; " "Max-Age=86417">>}, C3 = cookie(<<"Customer">>, <<"WILE_E_COYOTE">>, [{max_age, 86417}, {local_time, LocalTime}]), ok. -endif. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_http_handler.erl0000644000177700017770000000410612633765070031317 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @doc Handler for HTTP requests. %% %% HTTP handlers must implement three callbacks: init/3, %% handle/2 and terminate/2, called one after another in %% that order. %% %% init/3 is meant for initialization. It receives information about %% the transport and protocol used, along with the handler options from the %% dispatch list, and allows you to upgrade the protocol if needed. You can %% define a request-wide state here. %% %% handle/2 is meant for handling the request. It receives the %% request and the state previously defined. %% %% terminate/2 is meant for cleaning up. It also receives the %% request and the state previously defined. %% %% You do not have to read the request body or even send a reply if you do %% not need to. Cowboy will properly handle these cases and clean-up afterwards. %% In doubt it'll simply close the connection. %% %% Note that when upgrading the connection to WebSocket you do not need to %% define the handle/2 and terminate/2 callbacks. -module(cowboy_http_handler). -export([behaviour_info/1]). %% @private -spec behaviour_info(_) -> undefined | [{handle, 2} | {init, 3} | {terminate, 2}, ...]. behaviour_info(callbacks) -> [{init, 3}, {handle, 2}, {terminate, 2}]; behaviour_info(_Other) -> undefined. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_http_protocol.erl0000644000177700017770000004516612633765070031556 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% Copyright (c) 2011, Anthony Ramine %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @doc HTTP protocol handler. %% %% The available options are: %%
    %%
    dispatch
    The dispatch list for this protocol.
    %%
    max_empty_lines
    Max number of empty lines before a request. %% Defaults to 5.
    %%
    timeout
    Time in milliseconds before an idle %% connection is closed. Defaults to 5000 milliseconds.
    %%
    urldecode
    Function and options argument to use when decoding %% URL encoded strings. Defaults to `{fun cowboy_http:urldecode/2, crash}'. %%
    %%
    %% %% Note that there is no need to monitor these processes when using Cowboy as %% an application as it already supervises them under the listener supervisor. %% %% @see cowboy_dispatcher %% @see cowboy_http_handler -module(cowboy_http_protocol). -behaviour(cowboy_protocol). -export([start_link/4]). %% API. -export([init/4, parse_request/1, handler_loop/3]). %% FSM. -include("include/http.hrl"). -include_lib("eunit/include/eunit.hrl"). -record(state, { listener :: pid(), socket :: inet:socket(), transport :: module(), dispatch :: cowboy_dispatcher:dispatch_rules(), handler :: {module(), any()}, urldecode :: {fun((binary(), T) -> binary()), T}, req_empty_lines = 0 :: integer(), max_empty_lines :: integer(), req_keepalive = 1 :: integer(), max_keepalive :: integer(), max_line_length :: integer(), timeout :: timeout(), buffer = <<>> :: binary(), hibernate = false, loop_timeout = infinity :: timeout(), loop_timeout_ref }). %% API. %% @doc Start an HTTP protocol process. -spec start_link(pid(), inet:socket(), module(), any()) -> {ok, pid()}. start_link(ListenerPid, Socket, Transport, Opts) -> Pid = spawn_link(?MODULE, init, [ListenerPid, Socket, Transport, Opts]), {ok, Pid}. %% FSM. %% @private -spec init(pid(), inet:socket(), module(), any()) -> ok | none(). init(ListenerPid, Socket, Transport, Opts) -> Dispatch = proplists:get_value(dispatch, Opts, []), MaxEmptyLines = proplists:get_value(max_empty_lines, Opts, 5), MaxKeepalive = proplists:get_value(max_keepalive, Opts, infinity), MaxLineLength = proplists:get_value(max_line_length, Opts, 4096), Timeout = proplists:get_value(timeout, Opts, 5000), URLDecDefault = {fun cowboy_http:urldecode/2, crash}, URLDec = proplists:get_value(urldecode, Opts, URLDecDefault), ok = cowboy:accept_ack(ListenerPid), wait_request(#state{listener=ListenerPid, socket=Socket, transport=Transport, dispatch=Dispatch, max_empty_lines=MaxEmptyLines, max_keepalive=MaxKeepalive, max_line_length=MaxLineLength, timeout=Timeout, urldecode=URLDec}). %% @private -spec parse_request(#state{}) -> ok | none(). %% We limit the length of the Request-line to MaxLength to avoid endlessly %% reading from the socket and eventually crashing. parse_request(State=#state{buffer=Buffer, max_line_length=MaxLength}) -> case erlang:decode_packet(http_bin, Buffer, []) of {ok, Request, Rest} -> request(Request, State#state{buffer=Rest}); {more, _Length} when byte_size(Buffer) > MaxLength -> error_terminate(413, State); {more, _Length} -> wait_request(State); {error, _Reason} -> error_terminate(400, State) end. -spec wait_request(#state{}) -> ok | none(). wait_request(State=#state{socket=Socket, transport=Transport, timeout=T, buffer=Buffer}) -> case Transport:recv(Socket, 0, T) of {ok, Data} -> parse_request(State#state{ buffer= << Buffer/binary, Data/binary >>}); {error, _Reason} -> terminate(State) end. -spec request({http_request, cowboy_http:method(), cowboy_http:uri(), cowboy_http:version()}, #state{}) -> ok | none(). request({http_request, _Method, _URI, Version}, State) when Version =/= {1, 0}, Version =/= {1, 1} -> error_terminate(505, State); request({http_request, Method, {abs_path, AbsPath}, Version}, State=#state{socket=Socket, transport=Transport, urldecode={URLDecFun, URLDecArg}=URLDec}) -> URLDecode = fun(Bin) -> URLDecFun(Bin, URLDecArg) end, {Path, RawPath, Qs} = cowboy_dispatcher:split_path(AbsPath, URLDecode), ConnAtom = version_to_connection(Version), parse_header(#http_req{socket=Socket, transport=Transport, connection=ConnAtom, pid=self(), method=Method, version=Version, path=Path, raw_path=RawPath, raw_qs=Qs, urldecode=URLDec}, State); request({http_request, Method, '*', Version}, State=#state{socket=Socket, transport=Transport, urldecode=URLDec}) -> ConnAtom = version_to_connection(Version), parse_header(#http_req{socket=Socket, transport=Transport, connection=ConnAtom, pid=self(), method=Method, version=Version, path='*', raw_path= <<"*">>, raw_qs= <<>>, urldecode=URLDec}, State); request({http_request, _Method, _URI, _Version}, State) -> error_terminate(501, State); request({http_error, <<"\r\n">>}, State=#state{req_empty_lines=N, max_empty_lines=N}) -> error_terminate(400, State); request({http_error, <<"\r\n">>}, State=#state{req_empty_lines=N}) -> parse_request(State#state{req_empty_lines=N + 1}); request(_Any, State) -> error_terminate(400, State). -spec parse_header(#http_req{}, #state{}) -> ok | none(). parse_header(Req, State=#state{buffer=Buffer, max_line_length=MaxLength}) -> case erlang:decode_packet(httph_bin, Buffer, []) of {ok, Header, Rest} -> header(Header, Req, State#state{buffer=Rest}); {more, _Length} when byte_size(Buffer) > MaxLength -> error_terminate(413, State); {more, _Length} -> wait_header(Req, State); {error, _Reason} -> error_terminate(400, State) end. -spec wait_header(#http_req{}, #state{}) -> ok | none(). wait_header(Req, State=#state{socket=Socket, transport=Transport, timeout=T, buffer=Buffer}) -> case Transport:recv(Socket, 0, T) of {ok, Data} -> parse_header(Req, State#state{ buffer= << Buffer/binary, Data/binary >>}); {error, timeout} -> error_terminate(408, State); {error, closed} -> terminate(State) end. -spec header({http_header, integer(), cowboy_http:header(), any(), binary()} | http_eoh, #http_req{}, #state{}) -> ok | none(). header({http_header, _I, 'Host', _R, RawHost}, Req=#http_req{ transport=Transport, host=undefined}, State) -> RawHost2 = cowboy_bstr:to_lower(RawHost), case catch cowboy_dispatcher:split_host(RawHost2) of {Host, RawHost3, undefined} -> Port = default_port(Transport:name()), dispatch(fun parse_header/2, Req#http_req{ host=Host, raw_host=RawHost3, port=Port, headers=[{'Host', RawHost3}|Req#http_req.headers]}, State); {Host, RawHost3, Port} -> dispatch(fun parse_header/2, Req#http_req{ host=Host, raw_host=RawHost3, port=Port, headers=[{'Host', RawHost3}|Req#http_req.headers]}, State); {'EXIT', _Reason} -> error_terminate(400, State) end; %% Ignore Host headers if we already have it. header({http_header, _I, 'Host', _R, _V}, Req, State) -> parse_header(Req, State); header({http_header, _I, 'Connection', _R, Connection}, Req=#http_req{headers=Headers}, State) -> Req2 = Req#http_req{headers=[{'Connection', Connection}|Headers]}, {ConnTokens, Req3} = cowboy_http_req:parse_header('Connection', Req2), ConnAtom = cowboy_http:connection_to_atom(ConnTokens), parse_header(Req3#http_req{connection=ConnAtom}, State); header({http_header, _I, Field, _R, Value}, Req, State) -> Field2 = format_header(Field), parse_header(Req#http_req{headers=[{Field2, Value}|Req#http_req.headers]}, State); %% The Host header is required in HTTP/1.1. header(http_eoh, #http_req{version={1, 1}, host=undefined}, State) -> error_terminate(400, State); %% It is however optional in HTTP/1.0. header(http_eoh, Req=#http_req{version={1, 0}, transport=Transport, host=undefined}, State=#state{buffer=Buffer}) -> Port = default_port(Transport:name()), dispatch(fun handler_init/2, Req#http_req{host=[], raw_host= <<>>, port=Port, buffer=Buffer}, State#state{buffer= <<>>}); header(http_eoh, Req, State=#state{buffer=Buffer}) -> handler_init(Req#http_req{buffer=Buffer}, State#state{buffer= <<>>}); header(_Any, _Req, State) -> error_terminate(400, State). -spec dispatch(fun((#http_req{}, #state{}) -> ok), #http_req{}, #state{}) -> ok | none(). dispatch(Next, Req=#http_req{host=Host, path=Path}, State=#state{dispatch=Dispatch}) -> %% @todo We should allow a configurable chain of handlers here to %% allow things like url rewriting, site-wide authentication, %% optional dispatching, and more. It would default to what %% we are doing so far. case cowboy_dispatcher:match(Host, Path, Dispatch) of {ok, Handler, Opts, Binds, HostInfo, PathInfo} -> Next(Req#http_req{host_info=HostInfo, path_info=PathInfo, bindings=Binds}, State#state{handler={Handler, Opts}}); {error, notfound, host} -> error_terminate(400, State); {error, notfound, path} -> error_terminate(404, State) end. -spec handler_init(#http_req{}, #state{}) -> ok | none(). handler_init(Req, State=#state{transport=Transport, handler={Handler, Opts}}) -> try Handler:init({Transport:name(), http}, Req, Opts) of {ok, Req2, HandlerState} -> handler_handle(HandlerState, Req2, State); {loop, Req2, HandlerState} -> handler_before_loop(HandlerState, Req2, State); {loop, Req2, HandlerState, hibernate} -> handler_before_loop(HandlerState, Req2, State#state{hibernate=true}); {loop, Req2, HandlerState, Timeout} -> handler_before_loop(HandlerState, Req2, State#state{loop_timeout=Timeout}); {loop, Req2, HandlerState, Timeout, hibernate} -> handler_before_loop(HandlerState, Req2, State#state{hibernate=true, loop_timeout=Timeout}); {shutdown, Req2, HandlerState} -> handler_terminate(HandlerState, Req2, State); %% @todo {upgrade, transport, Module} {upgrade, protocol, Module} -> upgrade_protocol(Req, State, Module) catch Class:Reason -> error_terminate(500, State), error_logger:error_msg( "** Handler ~p terminating in init/3~n" " for the reason ~p:~p~n" "** Options were ~p~n" "** Request was ~p~n** Stacktrace: ~p~n~n", [Handler, Class, Reason, Opts, Req, erlang:get_stacktrace()]) end. -spec upgrade_protocol(#http_req{}, #state{}, atom()) -> ok | none(). upgrade_protocol(Req, State=#state{listener=ListenerPid, handler={Handler, Opts}}, Module) -> case Module:upgrade(ListenerPid, Handler, Opts, Req) of {UpgradeRes, Req2} -> next_request(Req2, State, UpgradeRes); _Any -> terminate(State) end. -spec handler_handle(any(), #http_req{}, #state{}) -> ok | none(). handler_handle(HandlerState, Req, State=#state{handler={Handler, Opts}}) -> try Handler:handle(Req, HandlerState) of {ok, Req2, HandlerState2} -> terminate_request(HandlerState2, Req2, State) catch Class:Reason -> error_logger:error_msg( "** Handler ~p terminating in handle/2~n" " for the reason ~p:~p~n" "** Options were ~p~n** Handler state was ~p~n" "** Request was ~p~n** Stacktrace: ~p~n~n", [Handler, Class, Reason, Opts, HandlerState, Req, erlang:get_stacktrace()]), handler_terminate(HandlerState, Req, State), error_terminate(500, State) end. %% We don't listen for Transport closes because that would force us %% to receive data and buffer it indefinitely. -spec handler_before_loop(any(), #http_req{}, #state{}) -> ok | none(). handler_before_loop(HandlerState, Req, State=#state{hibernate=true}) -> State2 = handler_loop_timeout(State), erlang:hibernate(?MODULE, handler_loop, [HandlerState, Req, State2#state{hibernate=false}]); handler_before_loop(HandlerState, Req, State) -> State2 = handler_loop_timeout(State), handler_loop(HandlerState, Req, State2). %% Almost the same code can be found in cowboy_http_websocket. -spec handler_loop_timeout(#state{}) -> #state{}. handler_loop_timeout(State=#state{loop_timeout=infinity}) -> State#state{loop_timeout_ref=undefined}; handler_loop_timeout(State=#state{loop_timeout=Timeout, loop_timeout_ref=PrevRef}) -> _ = case PrevRef of undefined -> ignore; PrevRef -> erlang:cancel_timer(PrevRef) end, TRef = make_ref(), erlang:send_after(Timeout, self(), {?MODULE, timeout, TRef}), State#state{loop_timeout_ref=TRef}. -spec handler_loop(any(), #http_req{}, #state{}) -> ok | none(). handler_loop(HandlerState, Req, State=#state{loop_timeout_ref=TRef}) -> receive {?MODULE, timeout, TRef} -> terminate_request(HandlerState, Req, State); {?MODULE, timeout, OlderTRef} when is_reference(OlderTRef) -> handler_loop(HandlerState, Req, State); Message -> handler_call(HandlerState, Req, State, Message) end. -spec handler_call(any(), #http_req{}, #state{}, any()) -> ok | none(). handler_call(HandlerState, Req, State=#state{handler={Handler, Opts}}, Message) -> try Handler:info(Message, Req, HandlerState) of {ok, Req2, HandlerState2} -> terminate_request(HandlerState2, Req2, State); {loop, Req2, HandlerState2} -> handler_before_loop(HandlerState2, Req2, State); {loop, Req2, HandlerState2, hibernate} -> handler_before_loop(HandlerState2, Req2, State#state{hibernate=true}) catch Class:Reason -> error_logger:error_msg( "** Handler ~p terminating in info/3~n" " for the reason ~p:~p~n" "** Options were ~p~n** Handler state was ~p~n" "** Request was ~p~n** Stacktrace: ~p~n~n", [Handler, Class, Reason, Opts, HandlerState, Req, erlang:get_stacktrace()]), handler_terminate(HandlerState, Req, State), error_terminate(500, State) end. -spec handler_terminate(any(), #http_req{}, #state{}) -> ok. handler_terminate(HandlerState, Req, #state{handler={Handler, Opts}}) -> try Handler:terminate(Req#http_req{resp_state=locked}, HandlerState) catch Class:Reason -> error_logger:error_msg( "** Handler ~p terminating in terminate/2~n" " for the reason ~p:~p~n" "** Options were ~p~n** Handler state was ~p~n" "** Request was ~p~n** Stacktrace: ~p~n~n", [Handler, Class, Reason, Opts, HandlerState, Req, erlang:get_stacktrace()]) end. -spec terminate_request(any(), #http_req{}, #state{}) -> ok | none(). terminate_request(HandlerState, Req, State) -> HandlerRes = handler_terminate(HandlerState, Req, State), next_request(Req, State, HandlerRes). -spec next_request(#http_req{}, #state{}, any()) -> ok | none(). next_request(Req=#http_req{connection=Conn}, State=#state{req_keepalive=Keepalive, max_keepalive=MaxKeepalive}, HandlerRes) -> RespRes = ensure_response(Req), {BodyRes, Buffer} = ensure_body_processed(Req), %% Flush the resp_sent message before moving on. receive {cowboy_http_req, resp_sent} -> ok after 0 -> ok end, case {HandlerRes, BodyRes, RespRes, Conn} of {ok, ok, ok, keepalive} when Keepalive < MaxKeepalive -> ?MODULE:parse_request(State#state{ buffer=Buffer, req_empty_lines=0, req_keepalive=Keepalive + 1}); _Closed -> terminate(State) end. -spec ensure_body_processed(#http_req{}) -> {ok | close, binary()}. ensure_body_processed(#http_req{body_state=done, buffer=Buffer}) -> {ok, Buffer}; ensure_body_processed(Req=#http_req{body_state=waiting}) -> case cowboy_http_req:body(Req) of {error, badarg} -> {ok, Req#http_req.buffer}; %% No body. {error, _Reason} -> {close, <<>>}; {ok, _, Req2} -> {ok, Req2#http_req.buffer} end; ensure_body_processed(Req=#http_req{body_state={multipart, _, _}}) -> {ok, Req2} = cowboy_http_req:multipart_skip(Req), ensure_body_processed(Req2). -spec ensure_response(#http_req{}) -> ok. %% The handler has already fully replied to the client. ensure_response(#http_req{resp_state=done}) -> ok; %% No response has been sent but everything apparently went fine. %% Reply with 204 No Content to indicate this. ensure_response(Req=#http_req{resp_state=waiting}) -> _ = cowboy_http_req:reply(204, [], [], Req), ok; %% Close the chunked reply. ensure_response(#http_req{method='HEAD', resp_state=chunks}) -> close; ensure_response(#http_req{socket=Socket, transport=Transport, resp_state=chunks}) -> Transport:send(Socket, <<"0\r\n\r\n">>), close. %% Only send an error reply if there is no resp_sent message. -spec error_terminate(cowboy_http:status(), #state{}) -> ok. error_terminate(Code, State=#state{socket=Socket, transport=Transport}) -> receive {cowboy_http_req, resp_sent} -> ok after 0 -> _ = cowboy_http_req:reply(Code, #http_req{ socket=Socket, transport=Transport, connection=close, pid=self(), resp_state=waiting}), ok end, terminate(State). -spec terminate(#state{}) -> ok. terminate(#state{socket=Socket, transport=Transport}) -> Transport:close(Socket), ok. %% Internal. -spec version_to_connection(cowboy_http:version()) -> keepalive | close. version_to_connection({1, 1}) -> keepalive; version_to_connection(_Any) -> close. -spec default_port(atom()) -> 80 | 443. default_port(ssl) -> 443; default_port(_) -> 80. %% @todo While 32 should be enough for everybody, we should probably make %% this configurable or something. -spec format_header(atom()) -> atom(); (binary()) -> binary(). format_header(Field) when is_atom(Field) -> Field; format_header(Field) when byte_size(Field) =< 20; byte_size(Field) > 32 -> Field; format_header(Field) -> format_header(Field, true, <<>>). format_header(<<>>, _Any, Acc) -> Acc; %% Replicate a bug in OTP for compatibility reasons when there's a - right %% after another. Proper use should always be 'true' instead of 'not Bool'. format_header(<< $-, Rest/bits >>, Bool, Acc) -> format_header(Rest, not Bool, << Acc/binary, $- >>); format_header(<< C, Rest/bits >>, true, Acc) -> format_header(Rest, false, << Acc/binary, (cowboy_bstr:char_to_upper(C)) >>); format_header(<< C, Rest/bits >>, false, Acc) -> format_header(Rest, false, << Acc/binary, (cowboy_bstr:char_to_lower(C)) >>). %% Tests. -ifdef(TEST). format_header_test_() -> %% {Header, Result} Tests = [ {<<"Sec-Websocket-Version">>, <<"Sec-Websocket-Version">>}, {<<"Sec-WebSocket-Version">>, <<"Sec-Websocket-Version">>}, {<<"sec-websocket-version">>, <<"Sec-Websocket-Version">>}, {<<"SEC-WEBSOCKET-VERSION">>, <<"Sec-Websocket-Version">>}, %% These last tests ensures we're formatting headers exactly like OTP. %% Even though it's dumb, it's better for compatibility reasons. {<<"Sec-WebSocket--Version">>, <<"Sec-Websocket--version">>}, {<<"Sec-WebSocket---Version">>, <<"Sec-Websocket---Version">>} ], [{H, fun() -> R = format_header(H) end} || {H, R} <- Tests]. -endif. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy.app.src0000644000177700017770000000200312633765070027341 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. {application, cowboy, [ {description, "Small, fast, modular HTTP server."}, {vsn, "0.5.0"}, {modules, []}, {registered, [cowboy_clock, cowboy_sup]}, {applications, [ kernel, stdlib ]}, {mod, {cowboy_app, []}}, {env, []} ]}. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_dispatcher.erl0000644000177700017770000002746412633765070031005 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% Copyright (c) 2011, Anthony Ramine %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @doc Dispatch requests according to a hostname and path. -module(cowboy_dispatcher). -export([split_host/1, split_path/2, match/3]). %% API. -type bindings() :: list({atom(), binary()}). -type tokens() :: list(binary()). -type match_rule() :: '_' | '*' | list(binary() | '_' | '...' | atom()). -type dispatch_path() :: list({match_rule(), module(), any()}). -type dispatch_rule() :: {Host::match_rule(), Path::dispatch_path()}. -type dispatch_rules() :: list(dispatch_rule()). -export_type([bindings/0, tokens/0, dispatch_rules/0]). -include_lib("eunit/include/eunit.hrl"). %% API. %% @doc Split a hostname into a list of tokens. -spec split_host(binary()) -> {tokens(), binary(), undefined | inet:ip_port()}. split_host(<<>>) -> {[], <<>>, undefined}; split_host(Host) -> case binary:split(Host, <<":">>) of [Host] -> {binary:split(Host, <<".">>, [global, trim]), Host, undefined}; [Host2, Port] -> {binary:split(Host2, <<".">>, [global, trim]), Host2, list_to_integer(binary_to_list(Port))} end. %% @doc Split a path into a list of path segments. %% %% Following RFC2396, this function may return path segments containing any %% character, including / if, and only if, a / was escaped %% and part of a path segment. -spec split_path(binary(), fun((binary()) -> binary())) -> {tokens(), binary(), binary()}. split_path(Path, URLDec) -> case binary:split(Path, <<"?">>) of [Path] -> {do_split_path(Path, <<"/">>, URLDec), Path, <<>>}; [<<>>, Qs] -> {[], <<>>, Qs}; [Path2, Qs] -> {do_split_path(Path2, <<"/">>, URLDec), Path2, Qs} end. -spec do_split_path(binary(), <<_:8>>, fun((binary()) -> binary())) -> tokens(). do_split_path(RawPath, Separator, URLDec) -> EncodedPath = case binary:split(RawPath, Separator, [global, trim]) of [<<>>|Path] -> Path; Path -> Path end, [URLDec(Token) || Token <- EncodedPath]. %% @doc Match hostname tokens and path tokens against dispatch rules. %% %% It is typically used for matching tokens for the hostname and path of %% the request against a global dispatch rule for your listener. %% %% Dispatch rules are a list of {Hostname, PathRules} tuples, with %% PathRules being a list of {Path, HandlerMod, HandlerOpts}. %% %% Hostname and Path are match rules and can be either the %% atom '_', which matches everything for a single token, the atom %% '*', which matches everything for the rest of the tokens, or a %% list of tokens. Each token can be either a binary, the atom '_', %% the atom '...' or a named atom. A binary token must match exactly, %% '_' matches everything for a single token, '...' matches %% everything for the rest of the tokens and a named atom will bind the %% corresponding token value and return it. %% %% The list of hostname tokens is reversed before matching. For example, if %% we were to match "www.dev-extend.eu", we would first match "eu", then %% "dev-extend", then "www". This means that in the context of hostnames, %% the '...' atom matches properly the lower levels of the domain %% as would be expected. %% %% When a result is found, this function will return the handler module and %% options found in the dispatch list, a key-value list of bindings and %% the tokens that were matched by the '...' atom for both the %% hostname and path. -spec match(Host::tokens(), Path::tokens(), dispatch_rules()) -> {ok, module(), any(), bindings(), HostInfo::undefined | tokens(), PathInfo::undefined | tokens()} | {error, notfound, host} | {error, notfound, path}. match(_Host, _Path, []) -> {error, notfound, host}; match(_Host, Path, [{'_', PathMatchs}|_Tail]) -> match_path(Path, PathMatchs, [], undefined); match(Host, Path, [{HostMatch, PathMatchs}|Tail]) -> case try_match(host, Host, HostMatch) of false -> match(Host, Path, Tail); {true, HostBinds, undefined} -> match_path(Path, PathMatchs, HostBinds, undefined); {true, HostBinds, HostInfo} -> match_path(Path, PathMatchs, HostBinds, lists:reverse(HostInfo)) end. -spec match_path(tokens(), dispatch_path(), bindings(), HostInfo::undefined | tokens()) -> {ok, module(), any(), bindings(), HostInfo::undefined | tokens(), PathInfo::undefined | tokens()} | {error, notfound, path}. match_path(_Path, [], _HostBinds, _HostInfo) -> {error, notfound, path}; match_path(_Path, [{'_', Handler, Opts}|_Tail], HostBinds, HostInfo) -> {ok, Handler, Opts, HostBinds, HostInfo, undefined}; match_path('*', [{'*', Handler, Opts}|_Tail], HostBinds, HostInfo) -> {ok, Handler, Opts, HostBinds, HostInfo, undefined}; match_path(Path, [{PathMatch, Handler, Opts}|Tail], HostBinds, HostInfo) -> case try_match(path, Path, PathMatch) of false -> match_path(Path, Tail, HostBinds, HostInfo); {true, PathBinds, PathInfo} -> {ok, Handler, Opts, HostBinds ++ PathBinds, HostInfo, PathInfo} end. %% Internal. -spec try_match(host | path, tokens(), match_rule()) -> {true, bindings(), undefined | tokens()} | false. try_match(host, List, Match) -> list_match(lists:reverse(List), lists:reverse(Match), []); try_match(path, List, Match) -> list_match(List, Match, []). -spec list_match(tokens(), match_rule(), bindings()) -> {true, bindings(), undefined | tokens()} | false. %% Atom '...' matches any trailing path, stop right now. list_match(List, ['...'], Binds) -> {true, Binds, List}; %% Atom '_' matches anything, continue. list_match([_E|Tail], ['_'|TailMatch], Binds) -> list_match(Tail, TailMatch, Binds); %% Both values match, continue. list_match([E|Tail], [E|TailMatch], Binds) -> list_match(Tail, TailMatch, Binds); %% Bind E to the variable name V and continue. list_match([E|Tail], [V|TailMatch], Binds) when is_atom(V) -> list_match(Tail, TailMatch, [{V, E}|Binds]); %% Match complete. list_match([], [], Binds) -> {true, Binds, undefined}; %% Values don't match, stop. list_match(_List, _Match, _Binds) -> false. %% Tests. -ifdef(TEST). split_host_test_() -> %% {Host, Result} Tests = [ {<<"">>, {[], <<"">>, undefined}}, {<<".........">>, {[], <<".........">>, undefined}}, {<<"*">>, {[<<"*">>], <<"*">>, undefined}}, {<<"cowboy.dev-extend.eu">>, {[<<"cowboy">>, <<"dev-extend">>, <<"eu">>], <<"cowboy.dev-extend.eu">>, undefined}}, {<<"dev-extend..eu">>, {[<<"dev-extend">>, <<>>, <<"eu">>], <<"dev-extend..eu">>, undefined}}, {<<"dev-extend.eu">>, {[<<"dev-extend">>, <<"eu">>], <<"dev-extend.eu">>, undefined}}, {<<"dev-extend.eu:8080">>, {[<<"dev-extend">>, <<"eu">>], <<"dev-extend.eu">>, 8080}}, {<<"a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z">>, {[<<"a">>, <<"b">>, <<"c">>, <<"d">>, <<"e">>, <<"f">>, <<"g">>, <<"h">>, <<"i">>, <<"j">>, <<"k">>, <<"l">>, <<"m">>, <<"n">>, <<"o">>, <<"p">>, <<"q">>, <<"r">>, <<"s">>, <<"t">>, <<"u">>, <<"v">>, <<"w">>, <<"x">>, <<"y">>, <<"z">>], <<"a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z">>, undefined}} ], [{H, fun() -> R = split_host(H) end} || {H, R} <- Tests]. split_host_fail_test_() -> Tests = [ <<"dev-extend.eu:owns">>, <<"dev-extend.eu: owns">>, <<"dev-extend.eu:42fun">>, <<"dev-extend.eu: 42fun">>, <<"dev-extend.eu:42 fun">>, <<"dev-extend.eu:fun 42">>, <<"dev-extend.eu: 42">>, <<":owns">>, <<":42 fun">> ], [{H, fun() -> case catch split_host(H) of {'EXIT', _Reason} -> ok end end} || H <- Tests]. split_path_test_() -> %% {Path, Result, QueryString} Tests = [ {<<"?">>, [], <<"">>, <<"">>}, {<<"???">>, [], <<"">>, <<"??">>}, {<<"/">>, [], <<"/">>, <<"">>}, {<<"/users">>, [<<"users">>], <<"/users">>, <<"">>}, {<<"/users?">>, [<<"users">>], <<"/users">>, <<"">>}, {<<"/users?a">>, [<<"users">>], <<"/users">>, <<"a">>}, {<<"/users/42/friends?a=b&c=d&e=notsure?whatever">>, [<<"users">>, <<"42">>, <<"friends">>], <<"/users/42/friends">>, <<"a=b&c=d&e=notsure?whatever">>}, {<<"/users/a+b/c%21d?e+f=g+h">>, [<<"users">>, <<"a b">>, <<"c!d">>], <<"/users/a+b/c%21d">>, <<"e+f=g+h">>} ], URLDecode = fun(Bin) -> cowboy_http:urldecode(Bin, crash) end, [{P, fun() -> {R, RawP, Qs} = split_path(P, URLDecode) end} || {P, R, RawP, Qs} <- Tests]. match_test_() -> Dispatch = [ {[<<"www">>, '_', <<"dev-extend">>, <<"eu">>], [ {[<<"users">>, '_', <<"mails">>], match_any_subdomain_users, []} ]}, {[<<"dev-extend">>, <<"eu">>], [ {[<<"users">>, id, <<"friends">>], match_extend_users_friends, []}, {'_', match_extend, []} ]}, {[<<"dev-extend">>, var], [ {[<<"threads">>, var], match_duplicate_vars, [we, {expect, two}, var, here]} ]}, {[<<"erlang">>, ext], [ {'_', match_erlang_ext, []} ]}, {'_', [ {[<<"users">>, id, <<"friends">>], match_users_friends, []}, {'_', match_any, []} ]} ], %% {Host, Path, Result} Tests = [ {[<<"any">>], [], {ok, match_any, [], []}}, {[<<"www">>, <<"any">>, <<"dev-extend">>, <<"eu">>], [<<"users">>, <<"42">>, <<"mails">>], {ok, match_any_subdomain_users, [], []}}, {[<<"www">>, <<"dev-extend">>, <<"eu">>], [<<"users">>, <<"42">>, <<"mails">>], {ok, match_any, [], []}}, {[<<"www">>, <<"dev-extend">>, <<"eu">>], [], {ok, match_any, [], []}}, {[<<"www">>, <<"any">>, <<"dev-extend">>, <<"eu">>], [<<"not_users">>, <<"42">>, <<"mails">>], {error, notfound, path}}, {[<<"dev-extend">>, <<"eu">>], [], {ok, match_extend, [], []}}, {[<<"dev-extend">>, <<"eu">>], [<<"users">>, <<"42">>, <<"friends">>], {ok, match_extend_users_friends, [], [{id, <<"42">>}]}}, {[<<"erlang">>, <<"fr">>], '_', {ok, match_erlang_ext, [], [{ext, <<"fr">>}]}}, {[<<"any">>], [<<"users">>, <<"444">>, <<"friends">>], {ok, match_users_friends, [], [{id, <<"444">>}]}}, {[<<"dev-extend">>, <<"fr">>], [<<"threads">>, <<"987">>], {ok, match_duplicate_vars, [we, {expect, two}, var, here], [{var, <<"fr">>}, {var, <<"987">>}]}} ], [{lists:flatten(io_lib:format("~p, ~p", [H, P])), fun() -> {ok, Handler, Opts, Binds, undefined, undefined} = match(H, P, Dispatch) end} || {H, P, {ok, Handler, Opts, Binds}} <- Tests]. match_info_test_() -> Dispatch = [ {[<<"www">>, <<"dev-extend">>, <<"eu">>], [ {[<<"pathinfo">>, <<"is">>, <<"next">>, '...'], match_path, []} ]}, {['...', <<"dev-extend">>, <<"eu">>], [ {'_', match_any, []} ]} ], Tests = [ {[<<"dev-extend">>, <<"eu">>], [], {ok, match_any, [], [], [], undefined}}, {[<<"bugs">>, <<"dev-extend">>, <<"eu">>], [], {ok, match_any, [], [], [<<"bugs">>], undefined}}, {[<<"cowboy">>, <<"bugs">>, <<"dev-extend">>, <<"eu">>], [], {ok, match_any, [], [], [<<"cowboy">>, <<"bugs">>], undefined}}, {[<<"www">>, <<"dev-extend">>, <<"eu">>], [<<"pathinfo">>, <<"is">>, <<"next">>], {ok, match_path, [], [], undefined, []}}, {[<<"www">>, <<"dev-extend">>, <<"eu">>], [<<"pathinfo">>, <<"is">>, <<"next">>, <<"path_info">>], {ok, match_path, [], [], undefined, [<<"path_info">>]}}, {[<<"www">>, <<"dev-extend">>, <<"eu">>], [<<"pathinfo">>, <<"is">>, <<"next">>, <<"foo">>, <<"bar">>], {ok, match_path, [], [], undefined, [<<"foo">>, <<"bar">>]}} ], [{lists:flatten(io_lib:format("~p, ~p", [H, P])), fun() -> R = match(H, P, Dispatch) end} || {H, P, R} <- Tests]. -endif. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_http_websocket.erl0000644000177700017770000005335512633765070031702 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @doc WebSocket protocol implementation. %% %% Supports the protocol version 0 (hixie-76), version 7 (hybi-7) %% and version 8 (hybi-8, hybi-9 and hybi-10). %% %% Version 0 is supported by the following browsers: %%
      %%
    • Firefox 4-5 (disabled by default)
    • %%
    • Chrome 6-13
    • %%
    • Safari 5.0.1+
    • %%
    • Opera 11.00+ (disabled by default)
    • %%
    %% %% Version 7 is supported by the following browser: %%
      %%
    • Firefox 6
    • %%
    %% %% Version 8+ is supported by the following browsers: %%
      %%
    • Firefox 7+
    • %%
    • Chrome 14+
    • %%
    -module(cowboy_http_websocket). -export([upgrade/4]). %% API. -export([handler_loop/4]). %% Internal. -include("include/http.hrl"). -include_lib("eunit/include/eunit.hrl"). -type opcode() :: 0 | 1 | 2 | 8 | 9 | 10. -type mask_key() :: 0..16#ffffffff. -record(state, { version :: 0 | 7 | 8 | 13, handler :: module(), opts :: any(), challenge = undefined :: undefined | binary() | {binary(), binary()}, timeout = infinity :: timeout(), timeout_ref = undefined, messages = undefined :: undefined | {atom(), atom(), atom()}, hibernate = false, eop :: undefined | tuple(), %% hixie-76 specific. origin = undefined :: undefined | binary() %% hixie-76 specific. }). %% @doc Upgrade a HTTP request to the WebSocket protocol. %% %% You do not need to call this function manually. To upgrade to the WebSocket %% protocol, you simply need to return {upgrade, protocol, {@module}} %% in your cowboy_http_handler:init/3 handler function. -spec upgrade(pid(), module(), any(), #http_req{}) -> closed | none(). upgrade(ListenerPid, Handler, Opts, Req) -> cowboy_listener:move_connection(ListenerPid, websocket, self()), case catch websocket_upgrade(#state{handler=Handler, opts=Opts}, Req) of {ok, State, Req2} -> handler_init(State, Req2); {'EXIT', _Reason} -> upgrade_error(Req) end. -spec websocket_upgrade(#state{}, #http_req{}) -> {ok, #state{}, #http_req{}}. websocket_upgrade(State, Req) -> {ConnTokens, Req2} = cowboy_http_req:parse_header('Connection', Req), true = lists:member(<<"upgrade">>, ConnTokens), %% @todo Should probably send a 426 if the Upgrade header is missing. {[<<"websocket">>], Req3} = cowboy_http_req:parse_header('Upgrade', Req2), {Version, Req4} = cowboy_http_req:header(<<"Sec-Websocket-Version">>, Req3), websocket_upgrade(Version, State, Req4). %% @todo Handle the Sec-Websocket-Protocol header. %% @todo Reply a proper error, don't die, if a required header is undefined. -spec websocket_upgrade(undefined | <<_:8>>, #state{}, #http_req{}) -> {ok, #state{}, #http_req{}}. %% No version given. Assuming hixie-76 draft. %% %% We need to wait to send a reply back before trying to read the %% third part of the challenge key, because proxies will wait for %% a reply before sending it. Therefore we calculate the challenge %% key only in websocket_handshake/3. websocket_upgrade(undefined, State, Req=#http_req{meta=Meta}) -> {Origin, Req2} = cowboy_http_req:header(<<"Origin">>, Req), {Key1, Req3} = cowboy_http_req:header(<<"Sec-Websocket-Key1">>, Req2), {Key2, Req4} = cowboy_http_req:header(<<"Sec-Websocket-Key2">>, Req3), false = lists:member(undefined, [Origin, Key1, Key2]), EOP = binary:compile_pattern(<< 255 >>), {ok, State#state{version=0, origin=Origin, challenge={Key1, Key2}, eop=EOP}, Req4#http_req{meta=[{websocket_version, 0}|Meta]}}; %% Versions 7 and 8. Implementation follows the hybi 7 through 17 drafts. websocket_upgrade(Version, State, Req=#http_req{meta=Meta}) when Version =:= <<"7">>; Version =:= <<"8">>; Version =:= <<"13">> -> {Key, Req2} = cowboy_http_req:header(<<"Sec-Websocket-Key">>, Req), false = Key =:= undefined, Challenge = hybi_challenge(Key), IntVersion = list_to_integer(binary_to_list(Version)), {ok, State#state{version=IntVersion, challenge=Challenge}, Req2#http_req{meta=[{websocket_version, IntVersion}|Meta]}}. -spec handler_init(#state{}, #http_req{}) -> closed | none(). handler_init(State=#state{handler=Handler, opts=Opts}, Req=#http_req{transport=Transport}) -> try Handler:websocket_init(Transport:name(), Req, Opts) of {ok, Req2, HandlerState} -> websocket_handshake(State, Req2, HandlerState); {ok, Req2, HandlerState, hibernate} -> websocket_handshake(State#state{hibernate=true}, Req2, HandlerState); {ok, Req2, HandlerState, Timeout} -> websocket_handshake(State#state{timeout=Timeout}, Req2, HandlerState); {ok, Req2, HandlerState, Timeout, hibernate} -> websocket_handshake(State#state{timeout=Timeout, hibernate=true}, Req2, HandlerState); {shutdown, Req2} -> upgrade_denied(Req2) catch Class:Reason -> upgrade_error(Req), error_logger:error_msg( "** Handler ~p terminating in websocket_init/3~n" " for the reason ~p:~p~n** Options were ~p~n" "** Request was ~p~n** Stacktrace: ~p~n~n", [Handler, Class, Reason, Opts, Req, erlang:get_stacktrace()]) end. -spec upgrade_error(#http_req{}) -> closed. upgrade_error(Req) -> {ok, _Req2} = cowboy_http_req:reply(400, [], [], Req#http_req{resp_state=waiting}), closed. %% @see cowboy_http_protocol:ensure_response/1 -spec upgrade_denied(#http_req{}) -> closed. upgrade_denied(#http_req{resp_state=done}) -> closed; upgrade_denied(Req=#http_req{resp_state=waiting}) -> {ok, _Req2} = cowboy_http_req:reply(400, [], [], Req), closed; upgrade_denied(#http_req{method='HEAD', resp_state=chunks}) -> closed; upgrade_denied(#http_req{socket=Socket, transport=Transport, resp_state=chunks}) -> Transport:send(Socket, <<"0\r\n\r\n">>), closed. -spec websocket_handshake(#state{}, #http_req{}, any()) -> closed | none(). websocket_handshake(State=#state{version=0, origin=Origin, challenge={Key1, Key2}}, Req=#http_req{socket=Socket, transport=Transport, raw_host=Host, port=Port, raw_path=Path, raw_qs=QS}, HandlerState) -> Location = hixie76_location(Transport:name(), Host, Port, Path, QS), {ok, Req2} = cowboy_http_req:upgrade_reply( <<"101 WebSocket Protocol Handshake">>, [{<<"Upgrade">>, <<"WebSocket">>}, {<<"Sec-Websocket-Location">>, Location}, {<<"Sec-Websocket-Origin">>, Origin}], Req#http_req{resp_state=waiting}), %% Flush the resp_sent message before moving on. receive {cowboy_http_req, resp_sent} -> ok after 0 -> ok end, %% We replied with a proper response. Proxies should be happy enough, %% we can now read the 8 last bytes of the challenge keys and send %% the challenge response directly to the socket. case cowboy_http_req:body(8, Req2) of {ok, Key3, Req3} -> Challenge = hixie76_challenge(Key1, Key2, Key3), Transport:send(Socket, Challenge), handler_before_loop(State#state{messages=Transport:messages()}, Req3, HandlerState, <<>>); _Any -> closed %% If an error happened reading the body, stop there. end; websocket_handshake(State=#state{challenge=Challenge}, Req=#http_req{transport=Transport}, HandlerState) -> {ok, Req2} = cowboy_http_req:upgrade_reply( 101, [{<<"Upgrade">>, <<"websocket">>}, {<<"Sec-Websocket-Accept">>, Challenge}], Req#http_req{resp_state=waiting}), %% Flush the resp_sent message before moving on. receive {cowboy_http_req, resp_sent} -> ok after 0 -> ok end, handler_before_loop(State#state{messages=Transport:messages()}, Req2, HandlerState, <<>>). -spec handler_before_loop(#state{}, #http_req{}, any(), binary()) -> closed | none(). handler_before_loop(State=#state{hibernate=true}, Req=#http_req{socket=Socket, transport=Transport}, HandlerState, SoFar) -> Transport:setopts(Socket, [{active, once}]), State2 = handler_loop_timeout(State), erlang:hibernate(?MODULE, handler_loop, [State2#state{hibernate=false}, Req, HandlerState, SoFar]); handler_before_loop(State, Req=#http_req{socket=Socket, transport=Transport}, HandlerState, SoFar) -> Transport:setopts(Socket, [{active, once}]), State2 = handler_loop_timeout(State), handler_loop(State2, Req, HandlerState, SoFar). -spec handler_loop_timeout(#state{}) -> #state{}. handler_loop_timeout(State=#state{timeout=infinity}) -> State#state{timeout_ref=undefined}; handler_loop_timeout(State=#state{timeout=Timeout, timeout_ref=PrevRef}) -> _ = case PrevRef of undefined -> ignore; PrevRef -> erlang:cancel_timer(PrevRef) end, TRef = make_ref(), erlang:send_after(Timeout, self(), {?MODULE, timeout, TRef}), State#state{timeout_ref=TRef}. %% @private -spec handler_loop(#state{}, #http_req{}, any(), binary()) -> closed | none(). handler_loop(State=#state{messages={OK, Closed, Error}, timeout_ref=TRef}, Req=#http_req{socket=Socket}, HandlerState, SoFar) -> receive {OK, Socket, Data} -> websocket_data(State, Req, HandlerState, << SoFar/binary, Data/binary >>); {Closed, Socket} -> handler_terminate(State, Req, HandlerState, {error, closed}); {Error, Socket, Reason} -> handler_terminate(State, Req, HandlerState, {error, Reason}); {?MODULE, timeout, TRef} -> websocket_close(State, Req, HandlerState, {normal, timeout}); {?MODULE, timeout, OlderTRef} when is_reference(OlderTRef) -> handler_loop(State, Req, HandlerState, SoFar); Message -> handler_call(State, Req, HandlerState, SoFar, websocket_info, Message, fun handler_before_loop/4) end. -spec websocket_data(#state{}, #http_req{}, any(), binary()) -> closed | none(). %% No more data. websocket_data(State, Req, HandlerState, <<>>) -> handler_before_loop(State, Req, HandlerState, <<>>); %% hixie-76 close frame. websocket_data(State=#state{version=0}, Req, HandlerState, << 255, 0, _Rest/binary >>) -> websocket_close(State, Req, HandlerState, {normal, closed}); %% hixie-76 data frame. We only support the frame type 0, same as the specs. websocket_data(State=#state{version=0, eop=EOP}, Req, HandlerState, Data = << 0, _/binary >>) -> case binary:match(Data, EOP) of {Pos, 1} -> Pos2 = Pos - 1, << 0, Payload:Pos2/binary, 255, Rest/bits >> = Data, handler_call(State, Req, HandlerState, Rest, websocket_handle, {text, Payload}, fun websocket_data/4); nomatch -> %% @todo We probably should allow limiting frame length. handler_before_loop(State, Req, HandlerState, Data) end; %% incomplete hybi data frame. websocket_data(State=#state{version=Version}, Req, HandlerState, Data) when Version =/= 0, byte_size(Data) =:= 1 -> handler_before_loop(State, Req, HandlerState, Data); %% hybi data frame. %% @todo Handle Fin. websocket_data(State=#state{version=Version}, Req, HandlerState, Data) when Version =/= 0 -> << 1:1, 0:3, Opcode:4, Mask:1, PayloadLen:7, Rest/bits >> = Data, case {PayloadLen, Rest} of {126, _} when Opcode >= 8 -> websocket_close( State, Req, HandlerState, {error, protocol}); {127, _} when Opcode >= 8 -> websocket_close( State, Req, HandlerState, {error, protocol}); {126, << L:16, R/bits >>} -> websocket_before_unmask( State, Req, HandlerState, Data, R, Opcode, Mask, L); {126, Rest} -> websocket_before_unmask( State, Req, HandlerState, Data, Rest, Opcode, Mask, undefined); {127, << 0:1, L:63, R/bits >>} -> websocket_before_unmask( State, Req, HandlerState, Data, R, Opcode, Mask, L); {127, Rest} -> websocket_before_unmask( State, Req, HandlerState, Data, Rest, Opcode, Mask, undefined); {PayloadLen, Rest} -> websocket_before_unmask( State, Req, HandlerState, Data, Rest, Opcode, Mask, PayloadLen) end; %% Something was wrong with the frame. Close the connection. websocket_data(State, Req, HandlerState, _Bad) -> websocket_close(State, Req, HandlerState, {error, badframe}). %% hybi routing depending on whether unmasking is needed. -spec websocket_before_unmask(#state{}, #http_req{}, any(), binary(), binary(), opcode(), 0 | 1, non_neg_integer() | undefined) -> closed | none(). websocket_before_unmask(State, Req, HandlerState, Data, Rest, Opcode, Mask, PayloadLen) -> case {Mask, PayloadLen} of {0, 0} -> websocket_dispatch(State, Req, HandlerState, Rest, Opcode, <<>>); {1, N} when N + 4 > byte_size(Rest); N =:= undefined -> %% @todo We probably should allow limiting frame length. handler_before_loop(State, Req, HandlerState, Data); {1, _N} -> << MaskKey:32, Payload:PayloadLen/binary, Rest2/bits >> = Rest, websocket_unmask(State, Req, HandlerState, Rest2, Opcode, Payload, MaskKey) end. %% hybi unmasking. -spec websocket_unmask(#state{}, #http_req{}, any(), binary(), opcode(), binary(), mask_key()) -> closed | none(). websocket_unmask(State, Req, HandlerState, RemainingData, Opcode, Payload, MaskKey) -> websocket_unmask(State, Req, HandlerState, RemainingData, Opcode, Payload, MaskKey, <<>>). -spec websocket_unmask(#state{}, #http_req{}, any(), binary(), opcode(), binary(), mask_key(), binary()) -> closed | none(). websocket_unmask(State, Req, HandlerState, RemainingData, Opcode, << O:32, Rest/bits >>, MaskKey, Acc) -> T = O bxor MaskKey, websocket_unmask(State, Req, HandlerState, RemainingData, Opcode, Rest, MaskKey, << Acc/binary, T:32 >>); websocket_unmask(State, Req, HandlerState, RemainingData, Opcode, << O:24 >>, MaskKey, Acc) -> << MaskKey2:24, _:8 >> = << MaskKey:32 >>, T = O bxor MaskKey2, websocket_dispatch(State, Req, HandlerState, RemainingData, Opcode, << Acc/binary, T:24 >>); websocket_unmask(State, Req, HandlerState, RemainingData, Opcode, << O:16 >>, MaskKey, Acc) -> << MaskKey2:16, _:16 >> = << MaskKey:32 >>, T = O bxor MaskKey2, websocket_dispatch(State, Req, HandlerState, RemainingData, Opcode, << Acc/binary, T:16 >>); websocket_unmask(State, Req, HandlerState, RemainingData, Opcode, << O:8 >>, MaskKey, Acc) -> << MaskKey2:8, _:24 >> = << MaskKey:32 >>, T = O bxor MaskKey2, websocket_dispatch(State, Req, HandlerState, RemainingData, Opcode, << Acc/binary, T:8 >>); websocket_unmask(State, Req, HandlerState, RemainingData, Opcode, <<>>, _MaskKey, Acc) -> websocket_dispatch(State, Req, HandlerState, RemainingData, Opcode, Acc). %% hybi dispatching. -spec websocket_dispatch(#state{}, #http_req{}, any(), binary(), opcode(), binary()) -> closed | none(). %% @todo Fragmentation. %~ websocket_dispatch(State, Req, HandlerState, RemainingData, 0, Payload) -> %% Text frame. websocket_dispatch(State, Req, HandlerState, RemainingData, 1, Payload) -> handler_call(State, Req, HandlerState, RemainingData, websocket_handle, {text, Payload}, fun websocket_data/4); %% Binary frame. websocket_dispatch(State, Req, HandlerState, RemainingData, 2, Payload) -> handler_call(State, Req, HandlerState, RemainingData, websocket_handle, {binary, Payload}, fun websocket_data/4); %% Close control frame. %% @todo Handle the optional Payload. websocket_dispatch(State, Req, HandlerState, _RemainingData, 8, _Payload) -> websocket_close(State, Req, HandlerState, {normal, closed}); %% Ping control frame. Send a pong back and forward the ping to the handler. websocket_dispatch(State, Req=#http_req{socket=Socket, transport=Transport}, HandlerState, RemainingData, 9, Payload) -> Len = hybi_payload_length(byte_size(Payload)), Transport:send(Socket, << 1:1, 0:3, 10:4, 0:1, Len/bits, Payload/binary >>), handler_call(State, Req, HandlerState, RemainingData, websocket_handle, {ping, Payload}, fun websocket_data/4); %% Pong control frame. websocket_dispatch(State, Req, HandlerState, RemainingData, 10, Payload) -> handler_call(State, Req, HandlerState, RemainingData, websocket_handle, {pong, Payload}, fun websocket_data/4). -spec handler_call(#state{}, #http_req{}, any(), binary(), atom(), any(), fun()) -> closed | none(). handler_call(State=#state{handler=Handler, opts=Opts}, Req, HandlerState, RemainingData, Callback, Message, NextState) -> try Handler:Callback(Message, Req, HandlerState) of {ok, Req2, HandlerState2} -> NextState(State, Req2, HandlerState2, RemainingData); {ok, Req2, HandlerState2, hibernate} -> NextState(State#state{hibernate=true}, Req2, HandlerState2, RemainingData); {reply, Payload, Req2, HandlerState2} -> websocket_send(Payload, State, Req2), NextState(State, Req2, HandlerState2, RemainingData); {reply, Payload, Req2, HandlerState2, hibernate} -> websocket_send(Payload, State, Req2), NextState(State#state{hibernate=true}, Req2, HandlerState2, RemainingData); {shutdown, Req2, HandlerState2} -> websocket_close(State, Req2, HandlerState2, {normal, shutdown}) catch Class:Reason -> error_logger:error_msg( "** Handler ~p terminating in ~p/3~n" " for the reason ~p:~p~n** Message was ~p~n" "** Options were ~p~n** Handler state was ~p~n" "** Request was ~p~n** Stacktrace: ~p~n~n", [Handler, Callback, Class, Reason, Message, Opts, HandlerState, Req, erlang:get_stacktrace()]), websocket_close(State, Req, HandlerState, {error, handler}) end. -spec websocket_send(binary(), #state{}, #http_req{}) -> closed | ignore. %% hixie-76 text frame. websocket_send({text, Payload}, #state{version=0}, #http_req{socket=Socket, transport=Transport}) -> Transport:send(Socket, [0, Payload, 255]); %% Ignore all unknown frame types for compatibility with hixie 76. websocket_send(_Any, #state{version=0}, _Req) -> ignore; websocket_send({Type, Payload}, _State, #http_req{socket=Socket, transport=Transport}) -> Opcode = case Type of text -> 1; binary -> 2; ping -> 9; pong -> 10 end, Len = hybi_payload_length(iolist_size(Payload)), Transport:send(Socket, [<< 1:1, 0:3, Opcode:4, 0:1, Len/bits >>, Payload]). -spec websocket_close(#state{}, #http_req{}, any(), {atom(), atom()}) -> closed. websocket_close(State=#state{version=0}, Req=#http_req{socket=Socket, transport=Transport}, HandlerState, Reason) -> Transport:send(Socket, << 255, 0 >>), handler_terminate(State, Req, HandlerState, Reason); %% @todo Send a Payload? Using Reason is usually good but we're quite careless. websocket_close(State, Req=#http_req{socket=Socket, transport=Transport}, HandlerState, Reason) -> Transport:send(Socket, << 1:1, 0:3, 8:4, 0:8 >>), handler_terminate(State, Req, HandlerState, Reason). -spec handler_terminate(#state{}, #http_req{}, any(), atom() | {atom(), atom()}) -> closed. handler_terminate(#state{handler=Handler, opts=Opts}, Req, HandlerState, TerminateReason) -> try Handler:websocket_terminate(TerminateReason, Req, HandlerState) catch Class:Reason -> error_logger:error_msg( "** Handler ~p terminating in websocket_terminate/3~n" " for the reason ~p:~p~n** Initial reason was ~p~n" "** Options were ~p~n** Handler state was ~p~n" "** Request was ~p~n** Stacktrace: ~p~n~n", [Handler, Class, Reason, TerminateReason, Opts, HandlerState, Req, erlang:get_stacktrace()]) end, closed. %% hixie-76 specific. -spec hixie76_challenge(binary(), binary(), binary()) -> binary(). hixie76_challenge(Key1, Key2, Key3) -> IntKey1 = hixie76_key_to_integer(Key1), IntKey2 = hixie76_key_to_integer(Key2), erlang:md5(<< IntKey1:32, IntKey2:32, Key3/binary >>). -spec hixie76_key_to_integer(binary()) -> integer(). hixie76_key_to_integer(Key) -> Number = list_to_integer([C || << C >> <= Key, C >= $0, C =< $9]), Spaces = length([C || << C >> <= Key, C =:= 32]), Number div Spaces. -spec hixie76_location(atom(), binary(), inet:ip_port(), binary(), binary()) -> binary(). hixie76_location(Protocol, Host, Port, Path, <<>>) -> << (hixie76_location_protocol(Protocol))/binary, "://", Host/binary, (hixie76_location_port(Protocol, Port))/binary, Path/binary>>; hixie76_location(Protocol, Host, Port, Path, QS) -> << (hixie76_location_protocol(Protocol))/binary, "://", Host/binary, (hixie76_location_port(Protocol, Port))/binary, Path/binary, "?", QS/binary >>. -spec hixie76_location_protocol(atom()) -> binary(). hixie76_location_protocol(ssl) -> <<"wss">>; hixie76_location_protocol(_) -> <<"ws">>. %% @todo We should add a secure/0 function to transports %% instead of relying on their name. -spec hixie76_location_port(atom(), inet:ip_port()) -> binary(). hixie76_location_port(ssl, 443) -> <<>>; hixie76_location_port(tcp, 80) -> <<>>; hixie76_location_port(_, Port) -> <<":", (list_to_binary(integer_to_list(Port)))/binary>>. %% hybi specific. -spec hybi_challenge(binary()) -> binary(). hybi_challenge(Key) -> Bin = << Key/binary, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" >>, base64:encode(crypto:sha(Bin)). -spec hybi_payload_length(0..16#7fffffffffffffff) -> << _:7 >> | << _:23 >> | << _:71 >>. hybi_payload_length(N) -> case N of N when N =< 125 -> << N:7 >>; N when N =< 16#ffff -> << 126:7, N:16 >>; N when N =< 16#7fffffffffffffff -> << 127:7, N:64 >> end. %% Tests. -ifdef(TEST). hixie76_location_test() -> ?assertEqual(<<"ws://localhost/path">>, hixie76_location(tcp, <<"localhost">>, 80, <<"/path">>, <<>>)), ?assertEqual(<<"ws://localhost:443/path">>, hixie76_location(tcp, <<"localhost">>, 443, <<"/path">>, <<>>)), ?assertEqual(<<"ws://localhost:8080/path">>, hixie76_location(tcp, <<"localhost">>, 8080, <<"/path">>, <<>>)), ?assertEqual(<<"ws://localhost:8080/path?dummy=2785">>, hixie76_location(tcp, <<"localhost">>, 8080, <<"/path">>, <<"dummy=2785">>)), ?assertEqual(<<"wss://localhost/path">>, hixie76_location(ssl, <<"localhost">>, 443, <<"/path">>, <<>>)), ?assertEqual(<<"wss://localhost:8443/path">>, hixie76_location(ssl, <<"localhost">>, 8443, <<"/path">>, <<>>)), ?assertEqual(<<"wss://localhost:8443/path?dummy=2785">>, hixie76_location(ssl, <<"localhost">>, 8443, <<"/path">>, <<"dummy=2785">>)), ok. -endif. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_http_req.erl0000644000177700017770000007605312633765070030503 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% Copyright (c) 2011, Anthony Ramine %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @doc HTTP request manipulation API. %% %% Almost all functions in this module return a new Req variable. %% It should always be used instead of the one used in your function call %% because it keeps the state of the request. It also allows Cowboy to do %% some lazy evaluation and cache results where possible. -module(cowboy_http_req). -export([ method/1, version/1, peer/1, peer_addr/1, host/1, host_info/1, raw_host/1, port/1, path/1, path_info/1, raw_path/1, qs_val/2, qs_val/3, qs_vals/1, raw_qs/1, binding/2, binding/3, bindings/1, header/2, header/3, headers/1, parse_header/2, parse_header/3, cookie/2, cookie/3, cookies/1, meta/2, meta/3 ]). %% Request API. -export([ body/1, body/2, body_qs/1, multipart_data/1, multipart_skip/1 ]). %% Request Body API. -export([ set_resp_cookie/4, set_resp_header/3, set_resp_body/2, set_resp_body_fun/3, has_resp_header/2, has_resp_body/1, reply/2, reply/3, reply/4, chunked_reply/2, chunked_reply/3, chunk/2, upgrade_reply/3 ]). %% Response API. -export([ compact/1, transport/1 ]). %% Misc API. -include("include/http.hrl"). -include_lib("eunit/include/eunit.hrl"). %% Request API. %% @doc Return the HTTP method of the request. -spec method(#http_req{}) -> {cowboy_http:method(), #http_req{}}. method(Req) -> {Req#http_req.method, Req}. %% @doc Return the HTTP version used for the request. -spec version(#http_req{}) -> {cowboy_http:version(), #http_req{}}. version(Req) -> {Req#http_req.version, Req}. %% @doc Return the peer address and port number of the remote host. -spec peer(#http_req{}) -> {{inet:ip_address(), inet:ip_port()}, #http_req{}}. peer(Req=#http_req{socket=Socket, transport=Transport, peer=undefined}) -> {ok, Peer} = Transport:peername(Socket), {Peer, Req#http_req{peer=Peer}}; peer(Req) -> {Req#http_req.peer, Req}. %% @doc Returns the peer address calculated from headers. -spec peer_addr(#http_req{}) -> {inet:ip_address(), #http_req{}}. peer_addr(Req = #http_req{}) -> {RealIp, Req1} = header(<<"X-Real-Ip">>, Req), {ForwardedForRaw, Req2} = header(<<"X-Forwarded-For">>, Req1), {{PeerIp, _PeerPort}, Req3} = peer(Req2), ForwardedFor = case ForwardedForRaw of undefined -> undefined; ForwardedForRaw -> case re:run(ForwardedForRaw, "^(?[^\\,]+)", [{capture, [first_ip], binary}]) of {match, [FirstIp]} -> FirstIp; _Any -> undefined end end, {ok, PeerAddr} = if is_binary(RealIp) -> inet_parse:address(binary_to_list(RealIp)); is_binary(ForwardedFor) -> inet_parse:address(binary_to_list(ForwardedFor)); true -> {ok, PeerIp} end, {PeerAddr, Req3}. %% @doc Return the tokens for the hostname requested. -spec host(#http_req{}) -> {cowboy_dispatcher:tokens(), #http_req{}}. host(Req) -> {Req#http_req.host, Req}. %% @doc Return the extra host information obtained from partially matching %% the hostname using '...'. -spec host_info(#http_req{}) -> {cowboy_dispatcher:tokens() | undefined, #http_req{}}. host_info(Req) -> {Req#http_req.host_info, Req}. %% @doc Return the raw host directly taken from the request. -spec raw_host(#http_req{}) -> {binary(), #http_req{}}. raw_host(Req) -> {Req#http_req.raw_host, Req}. %% @doc Return the port used for this request. -spec port(#http_req{}) -> {inet:ip_port(), #http_req{}}. port(Req) -> {Req#http_req.port, Req}. %% @doc Return the path segments for the path requested. %% %% Following RFC2396, this function may return path segments containing any %% character, including / if, and only if, a / was escaped %% and part of a path segment in the path requested. -spec path(#http_req{}) -> {cowboy_dispatcher:tokens(), #http_req{}}. path(Req) -> {Req#http_req.path, Req}. %% @doc Return the extra path information obtained from partially matching %% the patch using '...'. -spec path_info(#http_req{}) -> {cowboy_dispatcher:tokens() | undefined, #http_req{}}. path_info(Req) -> {Req#http_req.path_info, Req}. %% @doc Return the raw path directly taken from the request. -spec raw_path(#http_req{}) -> {binary(), #http_req{}}. raw_path(Req) -> {Req#http_req.raw_path, Req}. %% @equiv qs_val(Name, Req, undefined) -spec qs_val(binary(), #http_req{}) -> {binary() | true | undefined, #http_req{}}. qs_val(Name, Req) when is_binary(Name) -> qs_val(Name, Req, undefined). %% @doc Return the query string value for the given key, or a default if %% missing. qs_val(Name, Req=#http_req{raw_qs=RawQs, qs_vals=undefined, urldecode={URLDecFun, URLDecArg}}, Default) when is_binary(Name) -> QsVals = parse_qs(RawQs, fun(Bin) -> URLDecFun(Bin, URLDecArg) end), qs_val(Name, Req#http_req{qs_vals=QsVals}, Default); qs_val(Name, Req, Default) -> case lists:keyfind(Name, 1, Req#http_req.qs_vals) of {Name, Value} -> {Value, Req}; false -> {Default, Req} end. %% @doc Return the full list of query string values. -spec qs_vals(#http_req{}) -> {list({binary(), binary() | true}), #http_req{}}. qs_vals(Req=#http_req{raw_qs=RawQs, qs_vals=undefined, urldecode={URLDecFun, URLDecArg}}) -> QsVals = parse_qs(RawQs, fun(Bin) -> URLDecFun(Bin, URLDecArg) end), qs_vals(Req#http_req{qs_vals=QsVals}); qs_vals(Req=#http_req{qs_vals=QsVals}) -> {QsVals, Req}. %% @doc Return the raw query string directly taken from the request. -spec raw_qs(#http_req{}) -> {binary(), #http_req{}}. raw_qs(Req) -> {Req#http_req.raw_qs, Req}. %% @equiv binding(Name, Req, undefined) -spec binding(atom(), #http_req{}) -> {binary() | undefined, #http_req{}}. binding(Name, Req) when is_atom(Name) -> binding(Name, Req, undefined). %% @doc Return the binding value for the given key obtained when matching %% the host and path against the dispatch list, or a default if missing. binding(Name, Req, Default) when is_atom(Name) -> case lists:keyfind(Name, 1, Req#http_req.bindings) of {Name, Value} -> {Value, Req}; false -> {Default, Req} end. %% @doc Return the full list of binding values. -spec bindings(#http_req{}) -> {list({atom(), binary()}), #http_req{}}. bindings(Req) -> {Req#http_req.bindings, Req}. %% @equiv header(Name, Req, undefined) -spec header(atom() | binary(), #http_req{}) -> {binary() | undefined, #http_req{}}. header(Name, Req) when is_atom(Name) orelse is_binary(Name) -> header(Name, Req, undefined). %% @doc Return the header value for the given key, or a default if missing. header(Name, Req, Default) when is_atom(Name) orelse is_binary(Name) -> case lists:keyfind(Name, 1, Req#http_req.headers) of {Name, Value} -> {Value, Req}; false -> {Default, Req} end. %% @doc Return the full list of headers. -spec headers(#http_req{}) -> {cowboy_http:headers(), #http_req{}}. headers(Req) -> {Req#http_req.headers, Req}. %% @doc Semantically parse headers. %% %% When the value isn't found, a proper default value for the type %% returned is used as a return value. %% @see parse_header/3 -spec parse_header(cowboy_http:header(), #http_req{}) -> {any(), #http_req{}} | {error, badarg}. parse_header(Name, Req=#http_req{p_headers=PHeaders}) -> case lists:keyfind(Name, 1, PHeaders) of false -> parse_header(Name, Req, parse_header_default(Name)); {Name, Value} -> {Value, Req} end. %% @doc Default values for semantic header parsing. -spec parse_header_default(cowboy_http:header()) -> any(). parse_header_default('Connection') -> []; parse_header_default(_Name) -> undefined. %% @doc Semantically parse headers. %% %% When the header is unknown, the value is returned directly without parsing. -spec parse_header(cowboy_http:header(), #http_req{}, any()) -> {any(), #http_req{}} | {error, badarg}. parse_header(Name, Req, Default) when Name =:= 'Accept' -> parse_header(Name, Req, Default, fun (Value) -> cowboy_http:list(Value, fun cowboy_http:media_range/2) end); parse_header(Name, Req, Default) when Name =:= 'Accept-Charset' -> parse_header(Name, Req, Default, fun (Value) -> cowboy_http:nonempty_list(Value, fun cowboy_http:conneg/2) end); parse_header(Name, Req, Default) when Name =:= 'Accept-Encoding' -> parse_header(Name, Req, Default, fun (Value) -> cowboy_http:list(Value, fun cowboy_http:conneg/2) end); parse_header(Name, Req, Default) when Name =:= 'Accept-Language' -> parse_header(Name, Req, Default, fun (Value) -> cowboy_http:nonempty_list(Value, fun cowboy_http:language_range/2) end); parse_header(Name, Req, Default) when Name =:= 'Connection' -> parse_header(Name, Req, Default, fun (Value) -> cowboy_http:nonempty_list(Value, fun cowboy_http:token_ci/2) end); parse_header(Name, Req, Default) when Name =:= 'Content-Length' -> parse_header(Name, Req, Default, fun (Value) -> cowboy_http:digits(Value) end); parse_header(Name, Req, Default) when Name =:= 'Content-Type' -> parse_header(Name, Req, Default, fun (Value) -> cowboy_http:content_type(Value) end); parse_header(Name, Req, Default) when Name =:= 'If-Match'; Name =:= 'If-None-Match' -> parse_header(Name, Req, Default, fun (Value) -> cowboy_http:entity_tag_match(Value) end); parse_header(Name, Req, Default) when Name =:= 'If-Modified-Since'; Name =:= 'If-Unmodified-Since' -> parse_header(Name, Req, Default, fun (Value) -> cowboy_http:http_date(Value) end); parse_header(Name, Req, Default) when Name =:= 'Upgrade' -> parse_header(Name, Req, Default, fun (Value) -> cowboy_http:nonempty_list(Value, fun cowboy_http:token_ci/2) end); parse_header(Name, Req, Default) when Name =:= <<"sec-websocket-protocol">> -> parse_header(Name, Req, Default, fun (Value) -> cowboy_http:nonempty_list(Value, fun cowboy_http:token/2) end); parse_header(Name, Req, Default) -> {Value, Req2} = header(Name, Req, Default), {undefined, Value, Req2}. parse_header(Name, Req=#http_req{p_headers=PHeaders}, Default, Fun) -> case header(Name, Req) of {undefined, Req2} -> {Default, Req2#http_req{p_headers=[{Name, Default}|PHeaders]}}; {Value, Req2} -> case Fun(Value) of {error, badarg} -> {error, badarg}; P -> {P, Req2#http_req{p_headers=[{Name, P}|PHeaders]}} end end. %% @equiv cookie(Name, Req, undefined) -spec cookie(binary(), #http_req{}) -> {binary() | true | undefined, #http_req{}}. cookie(Name, Req) when is_binary(Name) -> cookie(Name, Req, undefined). %% @doc Return the cookie value for the given key, or a default if %% missing. cookie(Name, Req=#http_req{cookies=undefined}, Default) when is_binary(Name) -> case header('Cookie', Req) of {undefined, Req2} -> {Default, Req2#http_req{cookies=[]}}; {RawCookie, Req2} -> Cookies = cowboy_cookies:parse_cookie(RawCookie), cookie(Name, Req2#http_req{cookies=Cookies}, Default) end; cookie(Name, Req, Default) -> case lists:keyfind(Name, 1, Req#http_req.cookies) of {Name, Value} -> {Value, Req}; false -> {Default, Req} end. %% @doc Return the full list of cookie values. -spec cookies(#http_req{}) -> {list({binary(), binary() | true}), #http_req{}}. cookies(Req=#http_req{cookies=undefined}) -> case header('Cookie', Req) of {undefined, Req2} -> {[], Req2#http_req{cookies=[]}}; {RawCookie, Req2} -> Cookies = cowboy_cookies:parse_cookie(RawCookie), cookies(Req2#http_req{cookies=Cookies}) end; cookies(Req=#http_req{cookies=Cookies}) -> {Cookies, Req}. %% @equiv meta(Name, Req, undefined) -spec meta(atom(), #http_req{}) -> {any() | undefined, #http_req{}}. meta(Name, Req) -> meta(Name, Req, undefined). %% @doc Return metadata information about the request. %% %% Metadata information varies from one protocol to another. Websockets %% would define the protocol version here, while REST would use it to %% indicate which media type, language and charset were retained. -spec meta(atom(), #http_req{}, any()) -> {any(), #http_req{}}. meta(Name, Req, Default) -> case lists:keyfind(Name, 1, Req#http_req.meta) of {Name, Value} -> {Value, Req}; false -> {Default, Req} end. %% Request Body API. %% @doc Return the full body sent with the request, or {error, badarg} %% if no Content-Length is available. %% @todo We probably want to allow a max length. %% @todo Add multipart support to this function. -spec body(#http_req{}) -> {ok, binary(), #http_req{}} | {error, atom()}. body(Req) -> {Length, Req2} = cowboy_http_req:parse_header('Content-Length', Req), case Length of undefined -> {error, badarg}; {error, badarg} -> {error, badarg}; _Any -> body(Length, Req2) end. %% @doc Return Length bytes of the request body. %% %% You probably shouldn't be calling this function directly, as it expects the %% Length argument to be the full size of the body, and will consider %% the body to be fully read from the socket. %% @todo We probably want to configure the timeout. -spec body(non_neg_integer(), #http_req{}) -> {ok, binary(), #http_req{}} | {error, atom()}. body(Length, Req=#http_req{body_state=waiting, buffer=Buffer}) when is_integer(Length) andalso Length =< byte_size(Buffer) -> << Body:Length/binary, Rest/bits >> = Buffer, {ok, Body, Req#http_req{body_state=done, buffer=Rest}}; body(Length, Req=#http_req{socket=Socket, transport=Transport, body_state=waiting, buffer=Buffer}) -> case Transport:recv(Socket, Length - byte_size(Buffer), 5000) of {ok, Body} -> {ok, << Buffer/binary, Body/binary >>, Req#http_req{body_state=done, buffer= <<>>}}; {error, Reason} -> {error, Reason} end. %% @doc Return the full body sent with the reqest, parsed as an %% application/x-www-form-urlencoded string. Essentially a POST query string. -spec body_qs(#http_req{}) -> {list({binary(), binary() | true}), #http_req{}}. body_qs(Req=#http_req{urldecode={URLDecFun, URLDecArg}}) -> {ok, Body, Req2} = body(Req), {parse_qs(Body, fun(Bin) -> URLDecFun(Bin, URLDecArg) end), Req2}. %% Multipart Request API. %% @doc Return data from the multipart parser. %% %% Use this function for multipart streaming. For each part in the request, %% this function returns {headers, Headers} followed by a sequence of %% {data, Data} tuples and finally end_of_part. When there %% is no part to parse anymore, eof is returned. %% %% If the request Content-Type is not a multipart one, {error, badarg} %% is returned. -spec multipart_data(#http_req{}) -> {{headers, cowboy_http:headers()} | {data, binary()} | end_of_part | eof, #http_req{}}. multipart_data(Req=#http_req{body_state=waiting}) -> {{<<"multipart">>, _SubType, Params}, Req2} = parse_header('Content-Type', Req), {_, Boundary} = lists:keyfind(<<"boundary">>, 1, Params), {Length, Req3=#http_req{buffer=Buffer}} = parse_header('Content-Length', Req2), multipart_data(Req3, Length, cowboy_multipart:parser(Boundary), Buffer); multipart_data(Req=#http_req{body_state={multipart, Length, Cont}}) -> multipart_data(Req, Length, Cont()); multipart_data(Req=#http_req{body_state=done}) -> {eof, Req}. multipart_data(Req, Length, Parser, Buffer) when byte_size(Buffer) >= Length -> << Data:Length/binary, Rest/binary >> = Buffer, multipart_data(Req#http_req{buffer=Rest}, 0, Parser(Data)); multipart_data(Req, Length, Parser, Buffer) -> NewLength = Length - byte_size(Buffer), multipart_data(Req#http_req{buffer= <<>>}, NewLength, Parser(Buffer)). multipart_data(Req, Length, {headers, Headers, Cont}) -> {{headers, Headers}, Req#http_req{body_state={multipart, Length, Cont}}}; multipart_data(Req, Length, {body, Data, Cont}) -> {{body, Data}, Req#http_req{body_state={multipart, Length, Cont}}}; multipart_data(Req, Length, {end_of_part, Cont}) -> {end_of_part, Req#http_req{body_state={multipart, Length, Cont}}}; multipart_data(Req, 0, eof) -> {eof, Req#http_req{body_state=done}}; multipart_data(Req=#http_req{socket=Socket, transport=Transport}, Length, eof) -> {ok, _Data} = Transport:recv(Socket, Length, 5000), {eof, Req#http_req{body_state=done}}; multipart_data(Req=#http_req{socket=Socket, transport=Transport}, Length, {more, Parser}) when Length > 0 -> case Transport:recv(Socket, 0, 5000) of {ok, << Data:Length/binary, Buffer/binary >>} -> multipart_data(Req#http_req{buffer=Buffer}, 0, Parser(Data)); {ok, Data} -> multipart_data(Req, Length - byte_size(Data), Parser(Data)) end. %% @doc Skip a part returned by the multipart parser. %% %% This function repeatedly calls multipart_data/1 until %% end_of_part or eof is parsed. multipart_skip(Req) -> case multipart_data(Req) of {end_of_part, Req2} -> {ok, Req2}; {eof, Req2} -> {ok, Req2}; {_Other, Req2} -> multipart_skip(Req2) end. %% Response API. %% @doc Add a cookie header to the response. -spec set_resp_cookie(binary(), binary(), [cowboy_cookies:cookie_option()], #http_req{}) -> {ok, #http_req{}}. set_resp_cookie(Name, Value, Options, Req) -> {HeaderName, HeaderValue} = cowboy_cookies:cookie(Name, Value, Options), set_resp_header(HeaderName, HeaderValue, Req). %% @doc Add a header to the response. set_resp_header(Name, Value, Req=#http_req{resp_headers=RespHeaders}) -> NameBin = header_to_binary(Name), {ok, Req#http_req{resp_headers=[{NameBin, Value}|RespHeaders]}}. %% @doc Add a body to the response. %% %% The body set here is ignored if the response is later sent using %% anything other than reply/2 or reply/3. The response body is expected %% to be a binary or an iolist. set_resp_body(Body, Req) -> {ok, Req#http_req{resp_body=Body}}. %% @doc Add a body function to the response. %% %% The response body may also be set to a content-length - stream-function pair. %% If the response body is of this type normal response headers will be sent. %% After the response headers has been sent the body function is applied. %% The body function is expected to write the response body directly to the %% socket using the transport module. %% %% If the body function crashes while writing the response body or writes fewer %% bytes than declared the behaviour is undefined. The body set here is ignored %% if the response is later sent using anything other than `reply/2' or %% `reply/3'. %% %% @see cowboy_http_req:transport/1. -spec set_resp_body_fun(non_neg_integer(), fun(() -> {sent, non_neg_integer()}), #http_req{}) -> {ok, #http_req{}}. set_resp_body_fun(StreamLen, StreamFun, Req) -> {ok, Req#http_req{resp_body={StreamLen, StreamFun}}}. %% @doc Return whether the given header has been set for the response. has_resp_header(Name, #http_req{resp_headers=RespHeaders}) -> NameBin = header_to_binary(Name), lists:keymember(NameBin, 1, RespHeaders). %% @doc Return whether a body has been set for the response. has_resp_body(#http_req{resp_body={Length, _}}) -> Length > 0; has_resp_body(#http_req{resp_body=RespBody}) -> iolist_size(RespBody) > 0. %% @equiv reply(Status, [], [], Req) -spec reply(cowboy_http:status(), #http_req{}) -> {ok, #http_req{}}. reply(Status, Req=#http_req{resp_body=Body}) -> reply(Status, [], Body, Req). %% @equiv reply(Status, Headers, [], Req) -spec reply(cowboy_http:status(), cowboy_http:headers(), #http_req{}) -> {ok, #http_req{}}. reply(Status, Headers, Req=#http_req{resp_body=Body}) -> reply(Status, Headers, Body, Req). %% @doc Send a reply to the client. reply(Status, Headers, Body, Req=#http_req{socket=Socket, transport=Transport, connection=Connection, pid=ReqPid, method=Method, resp_state=waiting, resp_headers=RespHeaders}) -> RespConn = response_connection(Headers, Connection), ContentLen = case Body of {CL, _} -> CL; _ -> iolist_size(Body) end, Head = response_head(Status, Headers, RespHeaders, [ {<<"Connection">>, atom_to_connection(Connection)}, {<<"Content-Length">>, integer_to_list(ContentLen)}, {<<"Date">>, cowboy_clock:rfc1123()}, {<<"Server">>, <<"Cowboy">>} ]), case {Method, Body} of {'HEAD', _} -> Transport:send(Socket, Head); {_, {_, StreamFun}} -> Transport:send(Socket, Head), StreamFun(); {_, _} -> Transport:send(Socket, [Head, Body]) end, ReqPid ! {?MODULE, resp_sent}, {ok, Req#http_req{connection=RespConn, resp_state=done, resp_headers=[], resp_body= <<>>}}. %% @equiv chunked_reply(Status, [], Req) -spec chunked_reply(cowboy_http:status(), #http_req{}) -> {ok, #http_req{}}. chunked_reply(Status, Req) -> chunked_reply(Status, [], Req). %% @doc Initiate the sending of a chunked reply to the client. %% @see cowboy_http_req:chunk/2 -spec chunked_reply(cowboy_http:status(), cowboy_http:headers(), #http_req{}) -> {ok, #http_req{}}. chunked_reply(Status, Headers, Req=#http_req{socket=Socket, transport=Transport, connection=Connection, pid=ReqPid, resp_state=waiting, resp_headers=RespHeaders}) -> RespConn = response_connection(Headers, Connection), Head = response_head(Status, Headers, RespHeaders, [ {<<"Connection">>, atom_to_connection(Connection)}, {<<"Transfer-Encoding">>, <<"chunked">>}, {<<"Date">>, cowboy_clock:rfc1123()}, {<<"Server">>, <<"Cowboy">>} ]), Transport:send(Socket, Head), ReqPid ! {?MODULE, resp_sent}, {ok, Req#http_req{connection=RespConn, resp_state=chunks, resp_headers=[], resp_body= <<>>}}. %% @doc Send a chunk of data. %% %% A chunked reply must have been initiated before calling this function. chunk(_Data, #http_req{socket=_Socket, transport=_Transport, method='HEAD'}) -> ok; chunk(Data, #http_req{socket=Socket, transport=Transport, resp_state=chunks}) -> Transport:send(Socket, [erlang:integer_to_list(iolist_size(Data), 16), <<"\r\n">>, Data, <<"\r\n">>]). %% @doc Send an upgrade reply. %% @private -spec upgrade_reply(cowboy_http:status(), cowboy_http:headers(), #http_req{}) -> {ok, #http_req{}}. upgrade_reply(Status, Headers, Req=#http_req{socket=Socket, transport=Transport, pid=ReqPid, resp_state=waiting, resp_headers=RespHeaders}) -> Head = response_head(Status, Headers, RespHeaders, [ {<<"Connection">>, <<"Upgrade">>} ]), Transport:send(Socket, Head), ReqPid ! {?MODULE, resp_sent}, {ok, Req#http_req{resp_state=done, resp_headers=[], resp_body= <<>>}}. %% Misc API. %% @doc Compact the request data by removing all non-system information. %% %% This essentially removes the host, path, query string, bindings and headers. %% Use it when you really need to save up memory, for example when having %% many concurrent long-running connections. -spec compact(#http_req{}) -> #http_req{}. compact(Req) -> Req#http_req{host=undefined, host_info=undefined, path=undefined, path_info=undefined, qs_vals=undefined, bindings=undefined, headers=[], p_headers=[], cookies=[]}. %% @doc Return the transport module and socket associated with a request. %% %% This exposes the same socket interface used internally by the HTTP protocol %% implementation to developers that needs low level access to the socket. %% %% It is preferred to use this in conjuction with the stream function support %% in `set_resp_body_fun/3' if this is used to write a response body directly %% to the socket. This ensures that the response headers are set correctly. -spec transport(#http_req{}) -> {ok, module(), inet:socket()}. transport(#http_req{transport=Transport, socket=Socket}) -> {ok, Transport, Socket}. %% Internal. -spec parse_qs(binary(), fun((binary()) -> binary())) -> list({binary(), binary() | true}). parse_qs(<<>>, _URLDecode) -> []; parse_qs(Qs, URLDecode) -> Tokens = binary:split(Qs, <<"&">>, [global, trim]), [case binary:split(Token, <<"=">>) of [Token] -> {URLDecode(Token), true}; [Name, Value] -> {URLDecode(Name), URLDecode(Value)} end || Token <- Tokens]. -spec response_connection(cowboy_http:headers(), keepalive | close) -> keepalive | close. response_connection([], Connection) -> Connection; response_connection([{Name, Value}|Tail], Connection) -> case Name of 'Connection' -> response_connection_parse(Value); Name when is_atom(Name) -> response_connection(Tail, Connection); Name -> Name2 = cowboy_bstr:to_lower(Name), case Name2 of <<"connection">> -> response_connection_parse(Value); _Any -> response_connection(Tail, Connection) end end. -spec response_connection_parse(binary()) -> keepalive | close. response_connection_parse(ReplyConn) -> Tokens = cowboy_http:nonempty_list(ReplyConn, fun cowboy_http:token/2), cowboy_http:connection_to_atom(Tokens). -spec response_head(cowboy_http:status(), cowboy_http:headers(), cowboy_http:headers(), cowboy_http:headers()) -> iolist(). response_head(Status, Headers, RespHeaders, DefaultHeaders) -> StatusLine = <<"HTTP/1.1 ", (status(Status))/binary, "\r\n">>, Headers2 = [{header_to_binary(Key), Value} || {Key, Value} <- Headers], Headers3 = merge_headers( merge_headers(Headers2, RespHeaders), DefaultHeaders), Headers4 = [[Key, <<": ">>, Value, <<"\r\n">>] || {Key, Value} <- Headers3], [StatusLine, Headers4, <<"\r\n">>]. -spec merge_headers(cowboy_http:headers(), cowboy_http:headers()) -> cowboy_http:headers(). merge_headers(Headers, []) -> Headers; merge_headers(Headers, [{Name, Value}|Tail]) -> Headers2 = case lists:keymember(Name, 1, Headers) of true -> Headers; false -> Headers ++ [{Name, Value}] end, merge_headers(Headers2, Tail). -spec atom_to_connection(keepalive) -> <<_:80>>; (close) -> <<_:40>>. atom_to_connection(keepalive) -> <<"keep-alive">>; atom_to_connection(close) -> <<"close">>. -spec status(cowboy_http:status()) -> binary(). status(100) -> <<"100 Continue">>; status(101) -> <<"101 Switching Protocols">>; status(102) -> <<"102 Processing">>; status(200) -> <<"200 OK">>; status(201) -> <<"201 Created">>; status(202) -> <<"202 Accepted">>; status(203) -> <<"203 Non-Authoritative Information">>; status(204) -> <<"204 No Content">>; status(205) -> <<"205 Reset Content">>; status(206) -> <<"206 Partial Content">>; status(207) -> <<"207 Multi-Status">>; status(226) -> <<"226 IM Used">>; status(300) -> <<"300 Multiple Choices">>; status(301) -> <<"301 Moved Permanently">>; status(302) -> <<"302 Found">>; status(303) -> <<"303 See Other">>; status(304) -> <<"304 Not Modified">>; status(305) -> <<"305 Use Proxy">>; status(306) -> <<"306 Switch Proxy">>; status(307) -> <<"307 Temporary Redirect">>; status(400) -> <<"400 Bad Request">>; status(401) -> <<"401 Unauthorized">>; status(402) -> <<"402 Payment Required">>; status(403) -> <<"403 Forbidden">>; status(404) -> <<"404 Not Found">>; status(405) -> <<"405 Method Not Allowed">>; status(406) -> <<"406 Not Acceptable">>; status(407) -> <<"407 Proxy Authentication Required">>; status(408) -> <<"408 Request Timeout">>; status(409) -> <<"409 Conflict">>; status(410) -> <<"410 Gone">>; status(411) -> <<"411 Length Required">>; status(412) -> <<"412 Precondition Failed">>; status(413) -> <<"413 Request Entity Too Large">>; status(414) -> <<"414 Request-URI Too Long">>; status(415) -> <<"415 Unsupported Media Type">>; status(416) -> <<"416 Requested Range Not Satisfiable">>; status(417) -> <<"417 Expectation Failed">>; status(418) -> <<"418 I'm a teapot">>; status(422) -> <<"422 Unprocessable Entity">>; status(423) -> <<"423 Locked">>; status(424) -> <<"424 Failed Dependency">>; status(425) -> <<"425 Unordered Collection">>; status(426) -> <<"426 Upgrade Required">>; status(500) -> <<"500 Internal Server Error">>; status(501) -> <<"501 Not Implemented">>; status(502) -> <<"502 Bad Gateway">>; status(503) -> <<"503 Service Unavailable">>; status(504) -> <<"504 Gateway Timeout">>; status(505) -> <<"505 HTTP Version Not Supported">>; status(506) -> <<"506 Variant Also Negotiates">>; status(507) -> <<"507 Insufficient Storage">>; status(510) -> <<"510 Not Extended">>; status(B) when is_binary(B) -> B. -spec header_to_binary(cowboy_http:header()) -> binary(). header_to_binary('Cache-Control') -> <<"Cache-Control">>; header_to_binary('Connection') -> <<"Connection">>; header_to_binary('Date') -> <<"Date">>; header_to_binary('Pragma') -> <<"Pragma">>; header_to_binary('Transfer-Encoding') -> <<"Transfer-Encoding">>; header_to_binary('Upgrade') -> <<"Upgrade">>; header_to_binary('Via') -> <<"Via">>; header_to_binary('Accept') -> <<"Accept">>; header_to_binary('Accept-Charset') -> <<"Accept-Charset">>; header_to_binary('Accept-Encoding') -> <<"Accept-Encoding">>; header_to_binary('Accept-Language') -> <<"Accept-Language">>; header_to_binary('Authorization') -> <<"Authorization">>; header_to_binary('From') -> <<"From">>; header_to_binary('Host') -> <<"Host">>; header_to_binary('If-Modified-Since') -> <<"If-Modified-Since">>; header_to_binary('If-Match') -> <<"If-Match">>; header_to_binary('If-None-Match') -> <<"If-None-Match">>; header_to_binary('If-Range') -> <<"If-Range">>; header_to_binary('If-Unmodified-Since') -> <<"If-Unmodified-Since">>; header_to_binary('Max-Forwards') -> <<"Max-Forwards">>; header_to_binary('Proxy-Authorization') -> <<"Proxy-Authorization">>; header_to_binary('Range') -> <<"Range">>; header_to_binary('Referer') -> <<"Referer">>; header_to_binary('User-Agent') -> <<"User-Agent">>; header_to_binary('Age') -> <<"Age">>; header_to_binary('Location') -> <<"Location">>; header_to_binary('Proxy-Authenticate') -> <<"Proxy-Authenticate">>; header_to_binary('Public') -> <<"Public">>; header_to_binary('Retry-After') -> <<"Retry-After">>; header_to_binary('Server') -> <<"Server">>; header_to_binary('Vary') -> <<"Vary">>; header_to_binary('Warning') -> <<"Warning">>; header_to_binary('Www-Authenticate') -> <<"Www-Authenticate">>; header_to_binary('Allow') -> <<"Allow">>; header_to_binary('Content-Base') -> <<"Content-Base">>; header_to_binary('Content-Encoding') -> <<"Content-Encoding">>; header_to_binary('Content-Language') -> <<"Content-Language">>; header_to_binary('Content-Length') -> <<"Content-Length">>; header_to_binary('Content-Location') -> <<"Content-Location">>; header_to_binary('Content-Md5') -> <<"Content-Md5">>; header_to_binary('Content-Range') -> <<"Content-Range">>; header_to_binary('Content-Type') -> <<"Content-Type">>; header_to_binary('Etag') -> <<"Etag">>; header_to_binary('Expires') -> <<"Expires">>; header_to_binary('Last-Modified') -> <<"Last-Modified">>; header_to_binary('Accept-Ranges') -> <<"Accept-Ranges">>; header_to_binary('Set-Cookie') -> <<"Set-Cookie">>; header_to_binary('Set-Cookie2') -> <<"Set-Cookie2">>; header_to_binary('X-Forwarded-For') -> <<"X-Forwarded-For">>; header_to_binary('Cookie') -> <<"Cookie">>; header_to_binary('Keep-Alive') -> <<"Keep-Alive">>; header_to_binary('Proxy-Connection') -> <<"Proxy-Connection">>; header_to_binary(B) when is_binary(B) -> B. %% Tests. -ifdef(TEST). parse_qs_test_() -> %% {Qs, Result} Tests = [ {<<"">>, []}, {<<"a=b">>, [{<<"a">>, <<"b">>}]}, {<<"aaa=bbb">>, [{<<"aaa">>, <<"bbb">>}]}, {<<"a&b">>, [{<<"a">>, true}, {<<"b">>, true}]}, {<<"a=b&c&d=e">>, [{<<"a">>, <<"b">>}, {<<"c">>, true}, {<<"d">>, <<"e">>}]}, {<<"a=b=c=d=e&f=g">>, [{<<"a">>, <<"b=c=d=e">>}, {<<"f">>, <<"g">>}]}, {<<"a+b=c+d">>, [{<<"a b">>, <<"c d">>}]} ], URLDecode = fun cowboy_http:urldecode/1, [{Qs, fun() -> R = parse_qs(Qs, URLDecode) end} || {Qs, R} <- Tests]. -endif. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_ssl_transport.erl0000644000177700017770000001325412633765070031564 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @doc SSL transport API. %% %% Wrapper around ssl implementing the Cowboy transport API. %% %% This transport requires the crypto, public_key %% and ssl applications to be started. If they aren't started, %% it will try to start them itself before opening a port to listen. %% Applications aren't stopped when the listening socket is closed, though. %% %% @see ssl -module(cowboy_ssl_transport). -export([name/0, messages/0, listen/1, accept/2, recv/3, send/2, setopts/2, controlling_process/2, peername/1, close/1]). %% @doc Name of this transport API, ssl. -spec name() -> ssl. name() -> ssl. %% @doc Atoms used in the process messages sent by this API. %% %% They identify incoming data, closed connection and errors when receiving %% data in active mode. -spec messages() -> {ssl, ssl_closed, ssl_error}. messages() -> {ssl, ssl_closed, ssl_error}. %% @doc Setup a socket to listen on the given port on the local host. %% %% The available options are: %%
    %%
    port
    Mandatory. TCP port number to open.
    %%
    backlog
    Maximum length of the pending connections queue. %% Defaults to 1024.
    %%
    ip
    Interface to listen on. Listen on all interfaces %% by default.
    %%
    certfile
    Mandatory. Path to a file containing the user's %% certificate.
    %%
    keyfile
    Mandatory. Path to the file containing the user's %% private PEM encoded key.
    %%
    cacertfile
    Optional. Path to file containing PEM encoded %% CA certificates (trusted certificates used for verifying a peer %% certificate).
    %%
    password
    Mandatory. String containing the user's password. %% All private keyfiles must be password protected currently.
    %%
    %% %% @see ssl:listen/2 %% @todo The password option shouldn't be mandatory. -spec listen([{port, inet:ip_port()} | {certfile, string()} | {keyfile, string()} | {password, string()} | {cacertfile, string()} | {ip, inet:ip_address()}]) -> {ok, ssl:sslsocket()} | {error, atom()}. listen(Opts) -> require([crypto, public_key, ssl]), {port, Port} = lists:keyfind(port, 1, Opts), Backlog = proplists:get_value(backlog, Opts, 1024), {certfile, CertFile} = lists:keyfind(certfile, 1, Opts), {keyfile, KeyFile} = lists:keyfind(keyfile, 1, Opts), {password, Password} = lists:keyfind(password, 1, Opts), ListenOpts0 = [binary, {active, false}, {backlog, Backlog}, {packet, raw}, {reuseaddr, true}, {certfile, CertFile}, {keyfile, KeyFile}, {password, Password}], ListenOpts1 = case lists:keyfind(ip, 1, Opts) of false -> ListenOpts0; Ip -> [Ip|ListenOpts0] end, ListenOpts = case lists:keyfind(cacertfile, 1, Opts) of false -> ListenOpts1; CACertFile -> [CACertFile|ListenOpts1] end, ssl:listen(Port, ListenOpts). %% @doc Accept an incoming connection on a listen socket. %% %% Note that this function does both the transport accept and %% the SSL handshake. %% %% @see ssl:transport_accept/2 %% @see ssl:ssl_accept/2 -spec accept(ssl:sslsocket(), timeout()) -> {ok, ssl:sslsocket()} | {error, closed | timeout | atom()}. accept(LSocket, Timeout) -> case ssl:transport_accept(LSocket, Timeout) of {ok, CSocket} -> ssl_accept(CSocket, Timeout); {error, Reason} -> {error, Reason} end. %% @doc Receive a packet from a socket in passive mode. %% @see ssl:recv/3 -spec recv(ssl:sslsocket(), non_neg_integer(), timeout()) -> {ok, any()} | {error, closed | atom()}. recv(Socket, Length, Timeout) -> ssl:recv(Socket, Length, Timeout). %% @doc Send a packet on a socket. %% @see ssl:send/2 -spec send(ssl:sslsocket(), iolist()) -> ok | {error, atom()}. send(Socket, Packet) -> ssl:send(Socket, Packet). %% @doc Set one or more options for a socket. %% @see ssl:setopts/2 -spec setopts(ssl:sslsocket(), list()) -> ok | {error, atom()}. setopts(Socket, Opts) -> ssl:setopts(Socket, Opts). %% @doc Assign a new controlling process Pid to Socket. %% @see ssl:controlling_process/2 -spec controlling_process(ssl:sslsocket(), pid()) -> ok | {error, closed | not_owner | atom()}. controlling_process(Socket, Pid) -> ssl:controlling_process(Socket, Pid). %% @doc Return the address and port for the other end of a connection. %% @see ssl:peername/1 -spec peername(ssl:sslsocket()) -> {ok, {inet:ip_address(), inet:ip_port()}} | {error, atom()}. peername(Socket) -> ssl:peername(Socket). %% @doc Close a TCP socket. %% @see ssl:close/1 -spec close(ssl:sslsocket()) -> ok. close(Socket) -> ssl:close(Socket). %% Internal. -spec require(list(module())) -> ok. require([]) -> ok; require([App|Tail]) -> case application:start(App) of ok -> ok; {error, {already_started, App}} -> ok end, require(Tail). -spec ssl_accept(ssl:sslsocket(), timeout()) -> {ok, ssl:sslsocket()} | {error, closed | timeout | atom()}. ssl_accept(Socket, Timeout) -> case ssl:ssl_accept(Socket, Timeout) of ok -> {ok, Socket}; {error, Reason} -> {error, Reason} end. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_http_rest.erl0000644000177700017770000010030512633765070030655 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @doc Experimental REST protocol implementation. %% %% Based on the Webmachine Diagram from Alan Dean and Justin Sheehy, which %% can be found in the Webmachine source tree, and on the Webmachine %% documentation available at http://wiki.basho.com/Webmachine.html %% at the time of writing. -module(cowboy_http_rest). -export([upgrade/4]). -record(state, { %% Handler. handler :: atom(), handler_state :: any(), %% Media type. content_types_p = [] :: [{{binary(), binary(), [{binary(), binary()}]}, atom()}], content_type_a :: undefined | {{binary(), binary(), [{binary(), binary()}]}, atom()}, %% Language. languages_p = [] :: [binary()], language_a :: undefined | binary(), %% Charset. charsets_p = [] :: [binary()], charset_a :: undefined | binary(), %% Cached resource calls. etag :: undefined | no_call | binary(), last_modified :: undefined | no_call | calendar:datetime(), expires :: undefined | no_call | calendar:datetime() }). -include("include/http.hrl"). %% @doc Upgrade a HTTP request to the REST protocol. %% %% You do not need to call this function manually. To upgrade to the REST %% protocol, you simply need to return {upgrade, protocol, {@module}} %% in your cowboy_http_handler:init/3 handler function. -spec upgrade(pid(), module(), any(), #http_req{}) -> {ok, #http_req{}} | close. upgrade(_ListenerPid, Handler, Opts, Req) -> try case erlang:function_exported(Handler, rest_init, 2) of true -> case Handler:rest_init(Req, Opts) of {ok, Req2, HandlerState} -> service_available(Req2, #state{handler=Handler, handler_state=HandlerState}) end; false -> service_available(Req, #state{handler=Handler}) end catch Class:Reason -> error_logger:error_msg( "** Handler ~p terminating in rest_init/3~n" " for the reason ~p:~p~n** Options were ~p~n" "** Request was ~p~n** Stacktrace: ~p~n~n", [Handler, Class, Reason, Opts, Req, erlang:get_stacktrace()]), {ok, _Req2} = cowboy_http_req:reply(500, Req), close end. service_available(Req, State) -> expect(Req, State, service_available, true, fun known_methods/2, 503). %% known_methods/2 should return a list of atoms or binary methods. known_methods(Req=#http_req{method=Method}, State) -> case call(Req, State, known_methods) of no_call when Method =:= 'HEAD'; Method =:= 'GET'; Method =:= 'POST'; Method =:= 'PUT'; Method =:= 'DELETE'; Method =:= 'TRACE'; Method =:= 'CONNECT'; Method =:= 'OPTIONS' -> next(Req, State, fun uri_too_long/2); no_call -> next(Req, State, 501); {halt, Req2, HandlerState} -> terminate(Req2, State#state{handler_state=HandlerState}); {List, Req2, HandlerState} -> State2 = State#state{handler_state=HandlerState}, case lists:member(Method, List) of true -> next(Req2, State2, fun uri_too_long/2); false -> next(Req2, State2, 501) end end. uri_too_long(Req, State) -> expect(Req, State, uri_too_long, false, fun allowed_methods/2, 414). %% allowed_methods/2 should return a list of atoms or binary methods. allowed_methods(Req=#http_req{method=Method}, State) -> case call(Req, State, allowed_methods) of no_call when Method =:= 'HEAD'; Method =:= 'GET' -> next(Req, State, fun malformed_request/2); no_call -> method_not_allowed(Req, State, ['GET', 'HEAD']); {halt, Req2, HandlerState} -> terminate(Req2, State#state{handler_state=HandlerState}); {List, Req2, HandlerState} -> State2 = State#state{handler_state=HandlerState}, case lists:member(Method, List) of true -> next(Req2, State2, fun malformed_request/2); false -> method_not_allowed(Req2, State2, List) end end. method_not_allowed(Req, State, Methods) -> {ok, Req2} = cowboy_http_req:set_resp_header( <<"Allow">>, method_not_allowed_build(Methods, []), Req), respond(Req2, State, 405). method_not_allowed_build([], []) -> <<>>; method_not_allowed_build([], [_Ignore|Acc]) -> lists:reverse(Acc); method_not_allowed_build([Method|Tail], Acc) when is_atom(Method) -> Method2 = list_to_binary(atom_to_list(Method)), method_not_allowed_build(Tail, [<<", ">>, Method2|Acc]); method_not_allowed_build([Method|Tail], Acc) -> method_not_allowed_build(Tail, [<<", ">>, Method|Acc]). malformed_request(Req, State) -> expect(Req, State, malformed_request, false, fun is_authorized/2, 400). %% is_authorized/2 should return true or {false, WwwAuthenticateHeader}. is_authorized(Req, State) -> case call(Req, State, is_authorized) of no_call -> forbidden(Req, State); {halt, Req2, HandlerState} -> terminate(Req2, State#state{handler_state=HandlerState}); {true, Req2, HandlerState} -> forbidden(Req2, State#state{handler_state=HandlerState}); {{false, AuthHead}, Req2, HandlerState} -> {ok, Req3} = cowboy_http_req:set_resp_header( <<"Www-Authenticate">>, AuthHead, Req2), respond(Req3, State#state{handler_state=HandlerState}, 401) end. forbidden(Req, State) -> expect(Req, State, forbidden, false, fun valid_content_headers/2, 403). valid_content_headers(Req, State) -> expect(Req, State, valid_content_headers, true, fun known_content_type/2, 501). known_content_type(Req, State) -> expect(Req, State, known_content_type, true, fun valid_entity_length/2, 413). valid_entity_length(Req, State) -> expect(Req, State, valid_entity_length, true, fun options/2, 413). %% If you need to add additional headers to the response at this point, %% you should do it directly in the options/2 call using set_resp_headers. options(Req=#http_req{method='OPTIONS'}, State) -> case call(Req, State, options) of {halt, Req2, HandlerState} -> terminate(Req2, State#state{handler_state=HandlerState}); {ok, Req2, HandlerState} -> respond(Req2, State#state{handler_state=HandlerState}, 200) end; options(Req, State) -> content_types_provided(Req, State). %% content_types_provided/2 should return a list of content types and their %% associated callback function as a tuple: {{Type, SubType, Params}, Fun}. %% Type and SubType are the media type as binary. Params is a list of %% Key/Value tuple, with Key and Value a binary. Fun is the name of the %% callback that will be used to return the content of the response. It is %% given as an atom. %% %% An example of such return value would be: %% {{<<"text">>, <<"html">>, []}, to_html} %% %% Note that it is also possible to return a binary content type that will %% then be parsed by Cowboy. However note that while this may make your %% resources a little more readable, this is a lot less efficient. An example %% of such a return value would be: %% {<<"text/html">>, to_html} content_types_provided(Req=#http_req{meta=Meta}, State) -> case call(Req, State, content_types_provided) of no_call -> not_acceptable(Req, State); {halt, Req2, HandlerState} -> terminate(Req2, State#state{handler_state=HandlerState}); {[], Req2, HandlerState} -> not_acceptable(Req2, State#state{handler_state=HandlerState}); {CTP, Req2, HandlerState} -> CTP2 = [normalize_content_types_provided(P) || P <- CTP], State2 = State#state{ handler_state=HandlerState, content_types_p=CTP2}, {Accept, Req3} = cowboy_http_req:parse_header('Accept', Req2), case Accept of undefined -> {PMT, _Fun} = HeadCTP = hd(CTP2), languages_provided( Req3#http_req{meta=[{media_type, PMT}|Meta]}, State2#state{content_type_a=HeadCTP}); Accept -> Accept2 = prioritize_accept(Accept), choose_media_type(Req3, State2, Accept2) end end. normalize_content_types_provided({ContentType, Handler}) when is_binary(ContentType) -> {cowboy_http:content_type(ContentType), Handler}; normalize_content_types_provided(Provided) -> Provided. prioritize_accept(Accept) -> lists:sort( fun ({MediaTypeA, Quality, _AcceptParamsA}, {MediaTypeB, Quality, _AcceptParamsB}) -> %% Same quality, check precedence in more details. prioritize_mediatype(MediaTypeA, MediaTypeB); ({_MediaTypeA, QualityA, _AcceptParamsA}, {_MediaTypeB, QualityB, _AcceptParamsB}) -> %% Just compare the quality. QualityA > QualityB end, Accept). %% Media ranges can be overridden by more specific media ranges or %% specific media types. If more than one media range applies to a given %% type, the most specific reference has precedence. %% %% We always choose B over A when we can't decide between the two. prioritize_mediatype({TypeA, SubTypeA, ParamsA}, {TypeB, SubTypeB, ParamsB}) -> case TypeB of TypeA -> case SubTypeB of SubTypeA -> length(ParamsA) > length(ParamsB); <<"*">> -> true; _Any -> false end; <<"*">> -> true; _Any -> false end. %% Ignoring the rare AcceptParams. Not sure what should be done about them. choose_media_type(Req, State, []) -> not_acceptable(Req, State); choose_media_type(Req, State=#state{content_types_p=CTP}, [MediaType|Tail]) -> match_media_type(Req, State, Tail, CTP, MediaType). match_media_type(Req, State, Accept, [], _MediaType) -> choose_media_type(Req, State, Accept); match_media_type(Req, State, Accept, CTP, MediaType = {{<<"*">>, <<"*">>, _Params_A}, _QA, _APA}) -> match_media_type_params(Req, State, Accept, CTP, MediaType); match_media_type(Req, State, Accept, CTP = [{{Type, SubType_P, _PP}, _Fun}|_Tail], MediaType = {{Type, SubType_A, _PA}, _QA, _APA}) when SubType_P =:= SubType_A; SubType_A =:= <<"*">> -> match_media_type_params(Req, State, Accept, CTP, MediaType); match_media_type(Req, State, Accept, [_Any|Tail], MediaType) -> match_media_type(Req, State, Accept, Tail, MediaType). match_media_type_params(Req=#http_req{meta=Meta}, State, Accept, [Provided = {PMT = {_TP, _STP, Params_P}, _Fun}|Tail], MediaType = {{_TA, _STA, Params_A}, _QA, _APA}) -> case lists:sort(Params_P) =:= lists:sort(Params_A) of true -> languages_provided(Req#http_req{meta=[{media_type, PMT}|Meta]}, State#state{content_type_a=Provided}); false -> match_media_type(Req, State, Accept, Tail, MediaType) end. %% languages_provided should return a list of binary values indicating %% which languages are accepted by the resource. %% %% @todo I suppose we should also ask the resource if it wants to %% set a language itself or if it wants it to be automatically chosen. languages_provided(Req, State) -> case call(Req, State, languages_provided) of no_call -> charsets_provided(Req, State); {halt, Req2, HandlerState} -> terminate(Req2, State#state{handler_state=HandlerState}); {[], Req2, HandlerState} -> not_acceptable(Req2, State#state{handler_state=HandlerState}); {LP, Req2, HandlerState} -> State2 = State#state{handler_state=HandlerState, languages_p=LP}, {AcceptLanguage, Req3} = cowboy_http_req:parse_header('Accept-Language', Req2), case AcceptLanguage of undefined -> set_language(Req3, State2#state{language_a=hd(LP)}); AcceptLanguage -> AcceptLanguage2 = prioritize_languages(AcceptLanguage), choose_language(Req3, State2, AcceptLanguage2) end end. %% A language-range matches a language-tag if it exactly equals the tag, %% or if it exactly equals a prefix of the tag such that the first tag %% character following the prefix is "-". The special range "*", if %% present in the Accept-Language field, matches every tag not matched %% by any other range present in the Accept-Language field. %% %% @todo The last sentence probably means we should always put '*' %% at the end of the list. prioritize_languages(AcceptLanguages) -> lists:sort( fun ({_TagA, QualityA}, {_TagB, QualityB}) -> QualityA > QualityB end, AcceptLanguages). choose_language(Req, State, []) -> not_acceptable(Req, State); choose_language(Req, State=#state{languages_p=LP}, [Language|Tail]) -> match_language(Req, State, Tail, LP, Language). match_language(Req, State, Accept, [], _Language) -> choose_language(Req, State, Accept); match_language(Req, State, _Accept, [Provided|_Tail], {'*', _Quality}) -> set_language(Req, State#state{language_a=Provided}); match_language(Req, State, _Accept, [Provided|_Tail], {Provided, _Quality}) -> set_language(Req, State#state{language_a=Provided}); match_language(Req, State, Accept, [Provided|Tail], Language = {Tag, _Quality}) -> Length = byte_size(Tag), case Provided of << Tag:Length/binary, $-, _Any/bits >> -> set_language(Req, State#state{language_a=Provided}); _Any -> match_language(Req, State, Accept, Tail, Language) end. set_language(Req=#http_req{meta=Meta}, State=#state{language_a=Language}) -> {ok, Req2} = cowboy_http_req:set_resp_header( <<"Content-Language">>, Language, Req), charsets_provided(Req2#http_req{meta=[{language, Language}|Meta]}, State). %% charsets_provided should return a list of binary values indicating %% which charsets are accepted by the resource. charsets_provided(Req, State) -> case call(Req, State, charsets_provided) of no_call -> set_content_type(Req, State); {halt, Req2, HandlerState} -> terminate(Req2, State#state{handler_state=HandlerState}); {[], Req2, HandlerState} -> not_acceptable(Req2, State#state{handler_state=HandlerState}); {CP, Req2, HandlerState} -> State2 = State#state{handler_state=HandlerState, charsets_p=CP}, {AcceptCharset, Req3} = cowboy_http_req:parse_header('Accept-Charset', Req2), case AcceptCharset of undefined -> set_content_type(Req3, State2#state{charset_a=hd(CP)}); AcceptCharset -> AcceptCharset2 = prioritize_charsets(AcceptCharset), choose_charset(Req3, State2, AcceptCharset2) end end. %% The special value "*", if present in the Accept-Charset field, %% matches every character set (including ISO-8859-1) which is not %% mentioned elsewhere in the Accept-Charset field. If no "*" is present %% in an Accept-Charset field, then all character sets not explicitly %% mentioned get a quality value of 0, except for ISO-8859-1, which gets %% a quality value of 1 if not explicitly mentioned. prioritize_charsets(AcceptCharsets) -> AcceptCharsets2 = lists:sort( fun ({_CharsetA, QualityA}, {_CharsetB, QualityB}) -> QualityA > QualityB end, AcceptCharsets), case lists:keymember(<<"*">>, 1, AcceptCharsets2) of true -> AcceptCharsets2; false -> [{<<"iso-8859-1">>, 1000}|AcceptCharsets2] end. choose_charset(Req, State, []) -> not_acceptable(Req, State); choose_charset(Req, State=#state{charsets_p=CP}, [Charset|Tail]) -> match_charset(Req, State, Tail, CP, Charset). match_charset(Req, State, Accept, [], _Charset) -> choose_charset(Req, State, Accept); match_charset(Req, State, _Accept, [Provided|_Tail], {Provided, _Quality}) -> set_content_type(Req, State#state{charset_a=Provided}); match_charset(Req, State, Accept, [_Provided|Tail], Charset) -> match_charset(Req, State, Accept, Tail, Charset). set_content_type(Req=#http_req{meta=Meta}, State=#state{ content_type_a={{Type, SubType, Params}, _Fun}, charset_a=Charset}) -> ParamsBin = set_content_type_build_params(Params, []), ContentType = [Type, <<"/">>, SubType, ParamsBin], ContentType2 = case Charset of undefined -> ContentType; Charset -> [ContentType, <<"; charset=">>, Charset] end, {ok, Req2} = cowboy_http_req:set_resp_header( <<"Content-Type">>, ContentType2, Req), encodings_provided(Req2#http_req{meta=[{charset, Charset}|Meta]}, State). set_content_type_build_params([], []) -> <<>>; set_content_type_build_params([], Acc) -> lists:reverse(Acc); set_content_type_build_params([{Attr, Value}|Tail], Acc) -> set_content_type_build_params(Tail, [[Attr, <<"=">>, Value], <<";">>|Acc]). %% @todo Match for identity as we provide nothing else for now. %% @todo Don't forget to set the Content-Encoding header when we reply a body %% and the found encoding is something other than identity. encodings_provided(Req, State) -> variances(Req, State). not_acceptable(Req, State) -> respond(Req, State, 406). %% variances/2 should return a list of headers that will be added %% to the Vary response header. The Accept, Accept-Language, %% Accept-Charset and Accept-Encoding headers do not need to be %% specified. %% %% @todo Do Accept-Encoding too when we handle it. %% @todo Does the order matter? variances(Req, State=#state{content_types_p=CTP, languages_p=LP, charsets_p=CP}) -> Variances = case CTP of [] -> []; [_] -> []; [_|_] -> [<<"Accept">>] end, Variances2 = case LP of [] -> Variances; [_] -> Variances; [_|_] -> [<<"Accept-Language">>|Variances] end, Variances3 = case CP of [] -> Variances2; [_] -> Variances2; [_|_] -> [<<"Accept-Charset">>|Variances2] end, {Variances4, Req3, State2} = case call(Req, State, variances) of no_call -> {Variances3, Req, State}; {HandlerVariances, Req2, HandlerState} -> {Variances3 ++ HandlerVariances, Req2, State#state{handler_state=HandlerState}} end, case [[<<", ">>, V] || V <- Variances4] of [] -> resource_exists(Req3, State2); [[<<", ">>, H]|Variances5] -> {ok, Req4} = cowboy_http_req:set_resp_header( <<"Variances">>, [H|Variances5], Req3), resource_exists(Req4, State2) end. resource_exists(Req, State) -> expect(Req, State, resource_exists, true, fun if_match_exists/2, fun if_match_musnt_exist/2). if_match_exists(Req, State) -> case cowboy_http_req:parse_header('If-Match', Req) of {undefined, Req2} -> if_unmodified_since_exists(Req2, State); {'*', Req2} -> if_unmodified_since_exists(Req2, State); {ETagsList, Req2} -> if_match(Req2, State, ETagsList) end. if_match(Req, State, EtagsList) -> {Etag, Req2, State2} = generate_etag(Req, State), case Etag of no_call -> precondition_failed(Req2, State2); Etag -> case lists:member(Etag, EtagsList) of true -> if_unmodified_since_exists(Req2, State2); false -> precondition_failed(Req2, State2) end end. if_match_musnt_exist(Req, State) -> case cowboy_http_req:header('If-Match', Req) of {undefined, Req2} -> is_put_to_missing_resource(Req2, State); {_Any, Req2} -> precondition_failed(Req2, State) end. if_unmodified_since_exists(Req, State) -> case cowboy_http_req:parse_header('If-Unmodified-Since', Req) of {undefined, Req2} -> if_none_match_exists(Req2, State); {{error, badarg}, Req2} -> if_none_match_exists(Req2, State); {IfUnmodifiedSince, Req2} -> if_unmodified_since(Req2, State, IfUnmodifiedSince) end. %% If LastModified is the atom 'no_call', we continue. if_unmodified_since(Req, State, IfUnmodifiedSince) -> {LastModified, Req2, State2} = last_modified(Req, State), case LastModified > IfUnmodifiedSince of true -> precondition_failed(Req2, State2); false -> if_none_match_exists(Req2, State2) end. if_none_match_exists(Req, State) -> case cowboy_http_req:parse_header('If-None-Match', Req) of {undefined, Req2} -> if_modified_since_exists(Req2, State); {'*', Req2} -> precondition_is_head_get(Req2, State); {EtagsList, Req2} -> if_none_match(Req2, State, EtagsList) end. if_none_match(Req, State, EtagsList) -> {Etag, Req2, State2} = generate_etag(Req, State), case Etag of no_call -> precondition_failed(Req2, State2); Etag -> case lists:member(Etag, EtagsList) of true -> precondition_is_head_get(Req2, State2); false -> if_modified_since_exists(Req2, State2) end end. precondition_is_head_get(Req=#http_req{method=Method}, State) when Method =:= 'HEAD'; Method =:= 'GET' -> not_modified(Req, State); precondition_is_head_get(Req, State) -> precondition_failed(Req, State). if_modified_since_exists(Req, State) -> case cowboy_http_req:parse_header('If-Modified-Since', Req) of {undefined, Req2} -> method(Req2, State); {{error, badarg}, Req2} -> method(Req2, State); {IfModifiedSince, Req2} -> if_modified_since_now(Req2, State, IfModifiedSince) end. if_modified_since_now(Req, State, IfModifiedSince) -> case IfModifiedSince > erlang:universaltime() of true -> method(Req, State); false -> if_modified_since(Req, State, IfModifiedSince) end. if_modified_since(Req, State, IfModifiedSince) -> {LastModified, Req2, State2} = last_modified(Req, State), case LastModified of no_call -> method(Req2, State2); LastModified -> case LastModified > IfModifiedSince of true -> method(Req2, State2); false -> not_modified(Req2, State2) end end. not_modified(Req=#http_req{resp_headers=RespHeaders}, State) -> RespHeaders2 = lists:keydelete(<<"Content-Type">>, 1, RespHeaders), Req2 = Req#http_req{resp_headers=RespHeaders2}, {Req3, State2} = set_resp_etag(Req2, State), {Req4, State3} = set_resp_expires(Req3, State2), respond(Req4, State3, 304). precondition_failed(Req, State) -> respond(Req, State, 412). is_put_to_missing_resource(Req=#http_req{method='PUT'}, State) -> moved_permanently(Req, State, fun is_conflict/2); is_put_to_missing_resource(Req, State) -> previously_existed(Req, State). %% moved_permanently/2 should return either false or {true, Location} %% with Location the full new URI of the resource. moved_permanently(Req, State, OnFalse) -> case call(Req, State, moved_permanently) of {{true, Location}, Req2, HandlerState} -> {ok, Req3} = cowboy_http_req:set_resp_header( <<"Location">>, Location, Req2), respond(Req3, State#state{handler_state=HandlerState}, 301); {false, Req2, HandlerState} -> OnFalse(Req2, State#state{handler_state=HandlerState}); {halt, Req2, HandlerState} -> terminate(Req2, State#state{handler_state=HandlerState}); no_call -> OnFalse(Req, State) end. previously_existed(Req, State) -> expect(Req, State, previously_existed, false, fun (R, S) -> is_post_to_missing_resource(R, S, 404) end, fun (R, S) -> moved_permanently(R, S, fun moved_temporarily/2) end). %% moved_temporarily/2 should return either false or {true, Location} %% with Location the full new URI of the resource. moved_temporarily(Req, State) -> case call(Req, State, moved_temporarily) of {{true, Location}, Req2, HandlerState} -> {ok, Req3} = cowboy_http_req:set_resp_header( <<"Location">>, Location, Req2), respond(Req3, State#state{handler_state=HandlerState}, 307); {false, Req2, HandlerState} -> is_post_to_missing_resource(Req2, State#state{handler_state=HandlerState}, 410); {halt, Req2, HandlerState} -> terminate(Req2, State#state{handler_state=HandlerState}); no_call -> is_post_to_missing_resource(Req, State, 410) end. is_post_to_missing_resource(Req=#http_req{method='POST'}, State, OnFalse) -> allow_missing_post(Req, State, OnFalse); is_post_to_missing_resource(Req, State, OnFalse) -> respond(Req, State, OnFalse). allow_missing_post(Req, State, OnFalse) -> expect(Req, State, allow_missing_post, true, fun post_is_create/2, OnFalse). method(Req=#http_req{method='DELETE'}, State) -> delete_resource(Req, State); method(Req=#http_req{method='POST'}, State) -> post_is_create(Req, State); method(Req=#http_req{method='PUT'}, State) -> is_conflict(Req, State); method(Req, State) -> set_resp_body(Req, State). %% delete_resource/2 should start deleting the resource and return. delete_resource(Req, State) -> expect(Req, State, delete_resource, true, fun delete_completed/2, 500). %% delete_completed/2 indicates whether the resource has been deleted yet. delete_completed(Req, State) -> expect(Req, State, delete_completed, true, fun has_resp_body/2, 202). %% post_is_create/2 indicates whether the POST method can create new resources. post_is_create(Req, State) -> expect(Req, State, post_is_create, false, fun process_post/2, fun create_path/2). %% When the POST method can create new resources, create_path/2 will be called %% and is expected to return the full path to the new resource %% (including the leading /). create_path(Req=#http_req{meta=Meta}, State) -> case call(Req, State, create_path) of {halt, Req2, HandlerState} -> terminate(Req2, State#state{handler_state=HandlerState}); {Path, Req2, HandlerState} -> Location = create_path_location(Req2, Path), State2 = State#state{handler_state=HandlerState}, {ok, Req3} = cowboy_http_req:set_resp_header( <<"Location">>, Location, Req2), put_resource(Req3#http_req{meta=[{put_path, Path}|Meta]}, State2, 303) end. create_path_location(#http_req{transport=Transport, raw_host=Host, port=Port}, Path) -> TransportName = Transport:name(), << (create_path_location_protocol(TransportName))/binary, "://", Host/binary, (create_path_location_port(TransportName, Port))/binary, Path/binary >>. create_path_location_protocol(ssl) -> <<"https">>; create_path_location_protocol(_) -> <<"http">>. create_path_location_port(ssl, 443) -> <<>>; create_path_location_port(tcp, 80) -> <<>>; create_path_location_port(_, Port) -> <<":", (list_to_binary(integer_to_list(Port)))/binary>>. %% process_post should return true when the POST body could be processed %% and false when it hasn't, in which case a 500 error is sent. process_post(Req, State) -> case call(Req, State, process_post) of {halt, Req2, HandlerState} -> terminate(Req2, State#state{handler_state=HandlerState}); {true, Req2, HandlerState} -> State2 = State#state{handler_state=HandlerState}, next(Req2, State2, 201); {false, Req2, HandlerState} -> State2 = State#state{handler_state=HandlerState}, respond(Req2, State2, 500) end. is_conflict(Req, State) -> expect(Req, State, is_conflict, false, fun put_resource/2, 409). put_resource(Req=#http_req{raw_path=RawPath, meta=Meta}, State) -> Req2 = Req#http_req{meta=[{put_path, RawPath}|Meta]}, put_resource(Req2, State, fun is_new_resource/2). %% content_types_accepted should return a list of media types and their %% associated callback functions in the same format as content_types_provided. %% %% The callback will then be called and is expected to process the content %% pushed to the resource in the request body. The path to the new resource %% may be different from the request path, and is stored as request metadata. %% It is always defined past this point. It can be retrieved as demonstrated: %% {PutPath, Req2} = cowboy_http_req:meta(put_path, Req) put_resource(Req, State, OnTrue) -> case call(Req, State, content_types_accepted) of no_call -> respond(Req, State, 415); {halt, Req2, HandlerState} -> terminate(Req2, State#state{handler_state=HandlerState}); {CTA, Req2, HandlerState} -> State2 = State#state{handler_state=HandlerState}, {ContentType, Req3} = cowboy_http_req:parse_header('Content-Type', Req2), choose_content_type(Req3, State2, OnTrue, ContentType, CTA) end. choose_content_type(Req, State, _OnTrue, _ContentType, []) -> respond(Req, State, 415); choose_content_type(Req, State, OnTrue, ContentType, [{Accepted, Fun}|_Tail]) when ContentType =:= Accepted -> case call(Req, State, Fun) of {halt, Req2, HandlerState} -> terminate(Req2, State#state{handler_state=HandlerState}); {true, Req2, HandlerState} -> State2 = State#state{handler_state=HandlerState}, next(Req2, State2, OnTrue); {false, Req2, HandlerState} -> State2 = State#state{handler_state=HandlerState}, respond(Req2, State2, 500) end; choose_content_type(Req, State, OnTrue, ContentType, [_Any|Tail]) -> choose_content_type(Req, State, OnTrue, ContentType, Tail). %% Whether we created a new resource, either through PUT or POST. %% This is easily testable because we would have set the Location %% header by this point if we did so. is_new_resource(Req, State) -> case cowboy_http_req:has_resp_header(<<"Location">>, Req) of true -> respond(Req, State, 201); false -> has_resp_body(Req, State) end. has_resp_body(Req, State) -> case cowboy_http_req:has_resp_body(Req) of true -> multiple_choices(Req, State); false -> respond(Req, State, 204) end. %% Set the response headers and call the callback found using %% content_types_provided/2 to obtain the request body and add %% it to the response. set_resp_body(Req=#http_req{method=Method}, State=#state{content_type_a={_Type, Fun}}) when Method =:= 'GET'; Method =:= 'HEAD' -> {Req2, State2} = set_resp_etag(Req, State), {LastModified, Req3, State3} = last_modified(Req2, State2), case LastModified of LastModified when is_atom(LastModified) -> Req4 = Req3; LastModified -> LastModifiedStr = httpd_util:rfc1123_date(LastModified), {ok, Req4} = cowboy_http_req:set_resp_header( <<"Last-Modified">>, LastModifiedStr, Req3) end, {Req5, State4} = set_resp_expires(Req4, State3), case call(Req5, State4, Fun) of {halt, Req6, HandlerState} -> terminate(Req6, State4#state{handler_state=HandlerState}); {Body, Req6, HandlerState} -> State5 = State4#state{handler_state=HandlerState}, {ok, Req7} = case Body of {stream, Len, Fun1} -> cowboy_http_req:set_resp_body_fun(Len, Fun1, Req6); _Contents -> cowboy_http_req:set_resp_body(Body, Req6) end, multiple_choices(Req7, State5) end; set_resp_body(Req, State) -> multiple_choices(Req, State). multiple_choices(Req, State) -> expect(Req, State, multiple_choices, false, 200, 300). %% Response utility functions. set_resp_etag(Req, State) -> {Etag, Req2, State2} = generate_etag(Req, State), case Etag of undefined -> {Req2, State2}; Etag -> {ok, Req3} = cowboy_http_req:set_resp_header( <<"Etag">>, Etag, Req2), {Req3, State2} end. set_resp_expires(Req, State) -> {Expires, Req2, State2} = expires(Req, State), case Expires of Expires when is_atom(Expires) -> {Req2, State2}; Expires -> ExpiresStr = httpd_util:rfc1123_date(Expires), {ok, Req3} = cowboy_http_req:set_resp_header( <<"Expires">>, ExpiresStr, Req2), {Req3, State2} end. %% Info retrieval. No logic. generate_etag(Req, State=#state{etag=no_call}) -> {undefined, Req, State}; generate_etag(Req, State=#state{etag=undefined}) -> case call(Req, State, generate_etag) of no_call -> {undefined, Req, State#state{etag=no_call}}; {Etag, Req2, HandlerState} -> {Etag, Req2, State#state{handler_state=HandlerState, etag=Etag}} end; generate_etag(Req, State=#state{etag=Etag}) -> {Etag, Req, State}. last_modified(Req, State=#state{last_modified=no_call}) -> {undefined, Req, State}; last_modified(Req, State=#state{last_modified=undefined}) -> case call(Req, State, last_modified) of no_call -> {undefined, Req, State#state{last_modified=no_call}}; {LastModified, Req2, HandlerState} -> {LastModified, Req2, State#state{handler_state=HandlerState, last_modified=LastModified}} end; last_modified(Req, State=#state{last_modified=LastModified}) -> {LastModified, Req, State}. expires(Req, State=#state{expires=no_call}) -> {undefined, Req, State}; expires(Req, State=#state{expires=undefined}) -> case call(Req, State, expires) of no_call -> {undefined, Req, State#state{expires=no_call}}; {Expires, Req2, HandlerState} -> {Expires, Req2, State#state{handler_state=HandlerState, expires=Expires}} end; expires(Req, State=#state{expires=Expires}) -> {Expires, Req, State}. %% REST primitives. expect(Req, State, Callback, Expected, OnTrue, OnFalse) -> case call(Req, State, Callback) of no_call -> next(Req, State, OnTrue); {halt, Req2, HandlerState} -> terminate(Req2, State#state{handler_state=HandlerState}); {Expected, Req2, HandlerState} -> next(Req2, State#state{handler_state=HandlerState}, OnTrue); {_Unexpected, Req2, HandlerState} -> next(Req2, State#state{handler_state=HandlerState}, OnFalse) end. call(Req, #state{handler=Handler, handler_state=HandlerState}, Fun) -> case erlang:function_exported(Handler, Fun, 2) of true -> Handler:Fun(Req, HandlerState); false -> no_call end. next(Req, State, Next) when is_function(Next) -> Next(Req, State); next(Req, State, StatusCode) when is_integer(StatusCode) -> respond(Req, State, StatusCode). %% @todo Allow some sort of callback for custom error pages. respond(Req, State, StatusCode) -> {ok, Req2} = cowboy_http_req:reply(StatusCode, Req), terminate(Req2, State). terminate(Req, #state{handler=Handler, handler_state=HandlerState}) -> case erlang:function_exported(Handler, rest_terminate, 2) of true -> ok = Handler:rest_terminate( Req#http_req{resp_state=locked}, HandlerState); false -> ok end, {ok, Req}. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_clock.erl0000644000177700017770000002076212633765070027744 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @doc Date and time related functions. %% %% While a gen_server process runs in the background to update %% the cache of formatted dates every second, all API calls are %% local and directly read from the ETS cache table, providing %% fast time and date computations. -module(cowboy_clock). -behaviour(gen_server). -export([start_link/0, stop/0, rfc1123/0, rfc2109/1]). %% API. -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). %% gen_server. -record(state, { universaltime = undefined :: undefined | calendar:datetime(), rfc1123 = <<>> :: binary(), tref = undefined :: undefined | timer:tref() }). -define(SERVER, ?MODULE). -define(TABLE, ?MODULE). -include_lib("eunit/include/eunit.hrl"). %% API. %% @private -spec start_link() -> {ok, pid()}. start_link() -> gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). %% @private -spec stop() -> stopped. stop() -> gen_server:call(?SERVER, stop). %% @doc Return the current date and time formatted according to RFC-1123. %% %% This format is used in the 'Date' header sent with HTTP responses. -spec rfc1123() -> binary(). rfc1123() -> ets:lookup_element(?TABLE, rfc1123, 2). %% @doc Return the current date and time formatted according to RFC-2109. %% %% This format is used in the 'Set-Cookie' header sent with %% HTTP responses. -spec rfc2109(calendar:datetime()) -> binary(). rfc2109(LocalTime) -> {{YYYY,MM,DD},{Hour,Min,Sec}} = case calendar:local_time_to_universal_time_dst(LocalTime) of [Gmt] -> Gmt; [_,Gmt] -> Gmt end, Wday = calendar:day_of_the_week({YYYY,MM,DD}), DayBin = pad_int(DD), YearBin = list_to_binary(integer_to_list(YYYY)), HourBin = pad_int(Hour), MinBin = pad_int(Min), SecBin = pad_int(Sec), WeekDay = weekday(Wday), Month = month(MM), <>. %% gen_server. %% @private -spec init([]) -> {ok, #state{}}. init([]) -> ?TABLE = ets:new(?TABLE, [set, protected, named_table, {read_concurrency, true}]), T = erlang:universaltime(), B = update_rfc1123(<<>>, undefined, T), {ok, TRef} = timer:send_interval(1000, update), ets:insert(?TABLE, {rfc1123, B}), {ok, #state{universaltime=T, rfc1123=B, tref=TRef}}. %% @private -spec handle_call(_, _, State) -> {reply, ignored, State} | {stop, normal, stopped, State}. handle_call(stop, _From, State=#state{tref=TRef}) -> {ok, cancel} = timer:cancel(TRef), {stop, normal, stopped, State}; handle_call(_Request, _From, State) -> {reply, ignored, State}. %% @private -spec handle_cast(_, State) -> {noreply, State}. handle_cast(_Msg, State) -> {noreply, State}. %% @private -spec handle_info(_, State) -> {noreply, State}. handle_info(update, #state{universaltime=Prev, rfc1123=B1, tref=TRef}) -> T = erlang:universaltime(), B2 = update_rfc1123(B1, Prev, T), ets:insert(?TABLE, {rfc1123, B2}), {noreply, #state{universaltime=T, rfc1123=B2, tref=TRef}}; handle_info(_Info, State) -> {noreply, State}. %% @private -spec terminate(_, _) -> ok. terminate(_Reason, _State) -> ok. %% @private -spec code_change(_, State, _) -> {ok, State}. code_change(_OldVsn, State, _Extra) -> {ok, State}. %% Internal. -spec update_rfc1123(binary(), undefined | calendar:datetime(), calendar:datetime()) -> binary(). update_rfc1123(Bin, Now, Now) -> Bin; update_rfc1123(<< Keep:23/binary, _/bits >>, {Date, {H, M, _}}, {Date, {H, M, S}}) -> << Keep/binary, (pad_int(S))/binary, " GMT" >>; update_rfc1123(<< Keep:20/binary, _/bits >>, {Date, {H, _, _}}, {Date, {H, M, S}}) -> << Keep/binary, (pad_int(M))/binary, $:, (pad_int(S))/binary, " GMT" >>; update_rfc1123(<< Keep:17/binary, _/bits >>, {Date, _}, {Date, {H, M, S}}) -> << Keep/binary, (pad_int(H))/binary, $:, (pad_int(M))/binary, $:, (pad_int(S))/binary, " GMT" >>; update_rfc1123(<< _:7/binary, Keep:10/binary, _/bits >>, {{Y, Mo, _}, _}, {Date = {Y, Mo, D}, {H, M, S}}) -> Wday = calendar:day_of_the_week(Date), << (weekday(Wday))/binary, ", ", (pad_int(D))/binary, Keep/binary, (pad_int(H))/binary, $:, (pad_int(M))/binary, $:, (pad_int(S))/binary, " GMT" >>; update_rfc1123(<< _:11/binary, Keep:6/binary, _/bits >>, {{Y, _, _}, _}, {Date = {Y, Mo, D}, {H, M, S}}) -> Wday = calendar:day_of_the_week(Date), << (weekday(Wday))/binary, ", ", (pad_int(D))/binary, " ", (month(Mo))/binary, Keep/binary, (pad_int(H))/binary, $:, (pad_int(M))/binary, $:, (pad_int(S))/binary, " GMT" >>; update_rfc1123(_, _, {Date = {Y, Mo, D}, {H, M, S}}) -> Wday = calendar:day_of_the_week(Date), << (weekday(Wday))/binary, ", ", (pad_int(D))/binary, " ", (month(Mo))/binary, " ", (list_to_binary(integer_to_list(Y)))/binary, " ", (pad_int(H))/binary, $:, (pad_int(M))/binary, $:, (pad_int(S))/binary, " GMT" >>. %% Following suggestion by MononcQc on #erlounge. -spec pad_int(0..59) -> binary(). pad_int(X) when X < 10 -> << $0, ($0 + X) >>; pad_int(X) -> list_to_binary(integer_to_list(X)). -spec weekday(1..7) -> <<_:24>>. weekday(1) -> <<"Mon">>; weekday(2) -> <<"Tue">>; weekday(3) -> <<"Wed">>; weekday(4) -> <<"Thu">>; weekday(5) -> <<"Fri">>; weekday(6) -> <<"Sat">>; weekday(7) -> <<"Sun">>. -spec month(1..12) -> <<_:24>>. month( 1) -> <<"Jan">>; month( 2) -> <<"Feb">>; month( 3) -> <<"Mar">>; month( 4) -> <<"Apr">>; month( 5) -> <<"May">>; month( 6) -> <<"Jun">>; month( 7) -> <<"Jul">>; month( 8) -> <<"Aug">>; month( 9) -> <<"Sep">>; month(10) -> <<"Oct">>; month(11) -> <<"Nov">>; month(12) -> <<"Dec">>. %% Tests. -ifdef(TEST). update_rfc1123_test_() -> Tests = [ {<<"Sat, 14 May 2011 14:25:33 GMT">>, undefined, {{2011, 5, 14}, {14, 25, 33}}, <<>>}, {<<"Sat, 14 May 2011 14:25:33 GMT">>, {{2011, 5, 14}, {14, 25, 33}}, {{2011, 5, 14}, {14, 25, 33}}, <<"Sat, 14 May 2011 14:25:33 GMT">>}, {<<"Sat, 14 May 2011 14:25:34 GMT">>, {{2011, 5, 14}, {14, 25, 33}}, {{2011, 5, 14}, {14, 25, 34}}, <<"Sat, 14 May 2011 14:25:33 GMT">>}, {<<"Sat, 14 May 2011 14:26:00 GMT">>, {{2011, 5, 14}, {14, 25, 59}}, {{2011, 5, 14}, {14, 26, 0}}, <<"Sat, 14 May 2011 14:25:59 GMT">>}, {<<"Sat, 14 May 2011 15:00:00 GMT">>, {{2011, 5, 14}, {14, 59, 59}}, {{2011, 5, 14}, {15, 0, 0}}, <<"Sat, 14 May 2011 14:59:59 GMT">>}, {<<"Sun, 15 May 2011 00:00:00 GMT">>, {{2011, 5, 14}, {23, 59, 59}}, {{2011, 5, 15}, { 0, 0, 0}}, <<"Sat, 14 May 2011 23:59:59 GMT">>}, {<<"Wed, 01 Jun 2011 00:00:00 GMT">>, {{2011, 5, 31}, {23, 59, 59}}, {{2011, 6, 1}, { 0, 0, 0}}, <<"Tue, 31 May 2011 23:59:59 GMT">>}, {<<"Sun, 01 Jan 2012 00:00:00 GMT">>, {{2011, 5, 31}, {23, 59, 59}}, {{2012, 1, 1}, { 0, 0, 0}}, <<"Sat, 31 Dec 2011 23:59:59 GMT">>} ], [{R, fun() -> R = update_rfc1123(B, P, N) end} || {R, P, N, B} <- Tests]. pad_int_test_() -> Tests = [ { 0, <<"00">>}, { 1, <<"01">>}, { 2, <<"02">>}, { 3, <<"03">>}, { 4, <<"04">>}, { 5, <<"05">>}, { 6, <<"06">>}, { 7, <<"07">>}, { 8, <<"08">>}, { 9, <<"09">>}, {10, <<"10">>}, {11, <<"11">>}, {12, <<"12">>}, {13, <<"13">>}, {14, <<"14">>}, {15, <<"15">>}, {16, <<"16">>}, {17, <<"17">>}, {18, <<"18">>}, {19, <<"19">>}, {20, <<"20">>}, {21, <<"21">>}, {22, <<"22">>}, {23, <<"23">>}, {24, <<"24">>}, {25, <<"25">>}, {26, <<"26">>}, {27, <<"27">>}, {28, <<"28">>}, {29, <<"29">>}, {30, <<"30">>}, {31, <<"31">>}, {32, <<"32">>}, {33, <<"33">>}, {34, <<"34">>}, {35, <<"35">>}, {36, <<"36">>}, {37, <<"37">>}, {38, <<"38">>}, {39, <<"39">>}, {40, <<"40">>}, {41, <<"41">>}, {42, <<"42">>}, {43, <<"43">>}, {44, <<"44">>}, {45, <<"45">>}, {46, <<"46">>}, {47, <<"47">>}, {48, <<"48">>}, {49, <<"49">>}, {50, <<"50">>}, {51, <<"51">>}, {52, <<"52">>}, {53, <<"53">>}, {54, <<"54">>}, {55, <<"55">>}, {56, <<"56">>}, {57, <<"57">>}, {58, <<"58">>}, {59, <<"59">>} ], [{I, fun() -> O = pad_int(I) end} || {I, O} <- Tests]. -endif. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_requests_sup.erl0000644000177700017770000000271712633765070031413 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @private -module(cowboy_requests_sup). -behaviour(supervisor). -export([start_link/0, start_request/5]). %% API. -export([init/1]). %% supervisor. %% API. -spec start_link() -> {ok, pid()}. start_link() -> supervisor:start_link(?MODULE, []). -spec start_request(pid(), inet:socket(), module(), module(), any()) -> {ok, pid()}. start_request(ListenerPid, Socket, Transport, Protocol, Opts) -> Protocol:start_link(ListenerPid, Socket, Transport, Opts). %% supervisor. -spec init([]) -> {ok, {{simple_one_for_one, 0, 1}, [{_, _, _, _, _, _}, ...]}}. init([]) -> {ok, {{simple_one_for_one, 0, 1}, [{?MODULE, {?MODULE, start_request, []}, temporary, brutal_kill, worker, [?MODULE]}]}}. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_acceptors_sup.erl0000644000177700017770000000340412633765070031515 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @private -module(cowboy_acceptors_sup). -behaviour(supervisor). -export([start_link/7]). %% API. -export([init/1]). %% supervisor. %% API. -spec start_link(non_neg_integer(), module(), any(), module(), any(), pid(), pid()) -> {ok, pid()}. start_link(NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts, ListenerPid, ReqsPid) -> supervisor:start_link(?MODULE, [NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts, ListenerPid, ReqsPid]). %% supervisor. -spec init(list()) -> {ok, {{one_for_one, 10, 10}, list()}}. init([NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts, ListenerPid, ReqsPid]) -> {ok, LSocket} = Transport:listen(TransOpts), MaxConns = proplists:get_value(max_connections, TransOpts, 1024), Procs = [{{acceptor, self(), N}, {cowboy_acceptor, start_link, [ LSocket, Transport, Protocol, ProtoOpts, MaxConns, ListenerPid, ReqsPid ]}, permanent, brutal_kill, worker, []} || N <- lists:seq(1, NbAcceptors)], {ok, {{one_for_one, 10, 10}, Procs}}. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_acceptor.erl0000644000177700017770000000443512633765070030450 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @private -module(cowboy_acceptor). -export([start_link/7]). %% API. -export([acceptor/7]). %% Internal. %% API. -spec start_link(inet:socket(), module(), module(), any(), non_neg_integer(), pid(), pid()) -> {ok, pid()}. start_link(LSocket, Transport, Protocol, Opts, MaxConns, ListenerPid, ReqsSup) -> Pid = spawn_link(?MODULE, acceptor, [LSocket, Transport, Protocol, Opts, MaxConns, ListenerPid, ReqsSup]), {ok, Pid}. %% Internal. -spec acceptor(inet:socket(), module(), module(), any(), non_neg_integer(), pid(), pid()) -> no_return(). acceptor(LSocket, Transport, Protocol, Opts, MaxConns, ListenerPid, ReqsSup) -> case Transport:accept(LSocket, 2000) of {ok, CSocket} -> {ok, Pid} = supervisor:start_child(ReqsSup, [ListenerPid, CSocket, Transport, Protocol, Opts]), Transport:controlling_process(CSocket, Pid), {ok, NbConns} = cowboy_listener:add_connection(ListenerPid, default, Pid), Pid ! {shoot, ListenerPid}, limit_reqs(ListenerPid, NbConns, MaxConns); {error, timeout} -> ignore; {error, _Reason} -> %% @todo Probably do something here. If the socket was closed, %% we may want to try and listen again on the port? ignore end, ?MODULE:acceptor(LSocket, Transport, Protocol, Opts, MaxConns, ListenerPid, ReqsSup). -spec limit_reqs(pid(), non_neg_integer(), non_neg_integer()) -> ok. limit_reqs(_ListenerPid, NbConns, MaxConns) when NbConns =< MaxConns -> ok; limit_reqs(ListenerPid, _NbConns, MaxConns) -> cowboy_listener:wait(ListenerPid, default, MaxConns). rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_listener_sup.erl0000644000177700017770000000350012633765070031354 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @private -module(cowboy_listener_sup). -behaviour(supervisor). -export([start_link/5]). %% API. -export([init/1]). %% supervisor. %% API. -spec start_link(non_neg_integer(), module(), any(), module(), any()) -> {ok, pid()}. start_link(NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts) -> {ok, SupPid} = supervisor:start_link(?MODULE, []), {ok, ListenerPid} = supervisor:start_child(SupPid, {cowboy_listener, {cowboy_listener, start_link, []}, permanent, 5000, worker, [cowboy_listener]}), {ok, ReqsPid} = supervisor:start_child(SupPid, {cowboy_requests_sup, {cowboy_requests_sup, start_link, []}, permanent, 5000, supervisor, [cowboy_requests_sup]}), {ok, _PoolPid} = supervisor:start_child(SupPid, {cowboy_acceptors_sup, {cowboy_acceptors_sup, start_link, [ NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts, ListenerPid, ReqsPid ]}, permanent, 5000, supervisor, [cowboy_acceptors_sup]}), {ok, SupPid}. %% supervisor. -spec init([]) -> {ok, {{one_for_all, 10, 10}, []}}. init([]) -> {ok, {{one_for_all, 10, 10}, []}}. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_http_static.erl0000644000177700017770000004231612633765070031176 0ustar michaelmichael%% Copyright (c) 2011, Magnus Klaar %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @doc Static resource handler. %% %% This built in HTTP handler provides a simple file serving capability for %% cowboy applications. It should be considered an experimental feature because %% of it's dependency on the experimental REST handler. It's recommended to be %% used for small or temporary environments where it is not preferrable to set %% up a second server just to serve files. %% %% If this handler is used the Erlang node running the cowboy application must %% be configured to use an async thread pool. This is configured by adding the %% `+A $POOL_SIZE' argument to the `erl' command used to start the node. See %% %% this reply from the OTP team to erlang-bugs %% %% == Base configuration == %% %% The handler must be configured with a request path prefix to serve files %% under and the path to a directory to read files from. The request path prefix %% is defined in the path pattern of the cowboy dispatch rule for the handler. %% The request path pattern must end with a ``'...''' token. %% The directory path can be set to either an absolute or relative path in the %% form of a list or binary string representation of a file system path. A list %% of binary path segments, as is used throughout cowboy, is also a valid %% directory path. %% %% The directory path can also be set to a relative path within the `priv/' %% directory of an application. This is configured by setting the value of the %% directory option to a tuple of the form `{priv_dir, Application, Relpath}'. %% %% ==== Examples ==== %% ``` %% %% Serve files from /var/www/ under http://example.com/static/ %% {[<<"static">>, '...'], cowboy_http_static, %% [{directory, "/var/www"}]} %% %% %% Serve files from the current working directory under http://example.com/static/ %% {[<<"static">>, '...'], cowboy_http_static, %% [{directory, <<"./">>}]} %% %% %% Serve files from cowboy/priv/www under http://example.com/ %% {['...'], cowboy_http_static, %% [{directory, {priv_dir, cowboy, [<<"www">>]}}]} %% ''' %% %% == Content type configuration == %% %% By default the content type of all static resources will be set to %% `application/octet-stream'. This can be overriden by supplying a list %% of filename extension to mimetypes pairs in the `mimetypes' option. %% The filename extension should be a binary string including the leading dot. %% The mimetypes must be of a type that the `cowboy_http_rest' protocol can %% handle. %% %% The spawngrid/mimetypes %% application, or an arbitrary function accepting the path to the file being %% served, can also be used to generate the list of content types for a static %% file resource. The function used must accept an additional argument after %% the file path argument. %% %% ==== Example ==== %% ``` %% %% Use a static list of content types. %% {[<<"static">>, '...'], cowboy_http_static, %% [{directory, {priv_dir, cowboy, []}}, %% {mimetypes, [ %% {<<".css">>, [<<"text/css">>]}, %% {<<".js">>, [<<"application/javascript">>]}]}]} %% %% %% Use the default database in the mimetypes application. %% {[<<"static">>, '...', cowboy_http_static, %% [{directory, {priv_dir, cowboy, []}}, %% {mimetypes, {fun mimetypes:path_to_mimes/2, default}}]]} %% ''' %% %% == ETag Header Function == %% %% The default behaviour of the static file handler is to not generate ETag %% headers. This is because generating ETag headers based on file metadata %% causes different servers in a cluster to generate different ETag values for %% the same file unless the metadata is also synced. Generating strong ETags %% based on the contents of a file is currently out of scope for this module. %% %% The default behaviour can be overridden to generate an ETag header based on %% a combination of the file path, file size, inode and mtime values. If the %% option value is a list of attribute names tagged with `attributes' a hex %% encoded CRC32 checksum of the attribute values are used as the ETag header %% value. %% %% If a strong ETag is required a user defined function for generating the %% header value can be supplied. The function must accept a proplist of the %% file attributes as the first argument and a second argument containing any %% additional data that the function requires. The function must return a %% `binary()' or `undefined'. %% %% ==== Examples ==== %% ``` %% %% A value of default is equal to not specifying the option. %% {[<<"static">>, '...', cowboy_http_static, %% [{directory, {priv_dir, cowboy, []}}, %% {etag, default}]]} %% %% %% Use all avaliable ETag function arguments to generate a header value. %% {[<<"static">>, '...', cowboy_http_static, %% [{directory, {priv_dir, cowboy, []}}, %% {etag, {attributes, [filepath, filesize, inode, mtime]}}]]} %% %% %% Use a user defined function to generate a strong ETag header value. %% {[<<"static">>, '...', cowboy_http_static, %% [{directory, {priv_dir, cowboy, []}}, %% {etag, {fun generate_strong_etag/2, strong_etag_extra}}]]} %% %% generate_strong_etag(Arguments, strong_etag_extra) -> %% {_, Filepath} = lists:keyfind(filepath, 1, Arguments), %% {_, _Filesize} = lists:keyfind(filesize, 1, Arguments), %% {_, _INode} = lists:keyfind(inode, 1, Arguments), %% {_, _Modified} = lists:keyfind(mtime, 1, Arguments), %% ChecksumCommand = lists:flatten(io_lib:format("sha1sum ~s", [Filepath])), %% [Checksum|_] = string:tokens(os:cmd(ChecksumCommand), " "), %% iolist_to_binary(Checksum). %% ''' -module(cowboy_http_static). %% include files -include("http.hrl"). -include_lib("kernel/include/file.hrl"). %% cowboy_http_protocol callbacks -export([init/3]). %% cowboy_http_rest callbacks -export([rest_init/2, allowed_methods/2, malformed_request/2, resource_exists/2, forbidden/2, last_modified/2, generate_etag/2, content_types_provided/2, file_contents/2]). %% internal -export([path_to_mimetypes/2]). %% types -type dirpath() :: string() | binary() | [binary()]. -type dirspec() :: dirpath() | {priv, atom(), dirpath()}. -type mimedef() :: {binary(), binary(), [{binary(), binary()}]}. -type etagarg() :: {filepath, binary()} | {mtime, calendar:datetime()} | {inode, non_neg_integer()} | {filesize, non_neg_integer()}. %% handler state -record(state, { filepath :: binary() | error, fileinfo :: {ok, #file_info{}} | {error, _} | error, mimetypes :: {fun((binary(), T) -> [mimedef()]), T} | undefined, etag_fun :: {fun(([etagarg()], T) -> undefined | binary()), T}}). %% @private Upgrade from HTTP handler to REST handler. init({_Transport, http}, _Req, _Opts) -> {upgrade, protocol, cowboy_http_rest}. %% @private Set up initial state of REST handler. -spec rest_init(#http_req{}, list()) -> {ok, #http_req{}, #state{}}. rest_init(Req, Opts) -> Directory = proplists:get_value(directory, Opts), Directory1 = directory_path(Directory), Mimetypes = proplists:get_value(mimetypes, Opts, []), Mimetypes1 = case Mimetypes of {_, _} -> Mimetypes; [] -> {fun path_to_mimetypes/2, []}; [_|_] -> {fun path_to_mimetypes/2, Mimetypes} end, ETagFunction = case proplists:get_value(etag, Opts) of default -> {fun no_etag_function/2, undefined}; undefined -> {fun no_etag_function/2, undefined}; {attributes, Attrs} -> {fun attr_etag_function/2, Attrs}; {_, _}=EtagFunction1 -> EtagFunction1 end, {Filepath, Req1} = cowboy_http_req:path_info(Req), State = case check_path(Filepath) of error -> #state{filepath=error, fileinfo=error, mimetypes=undefined, etag_fun=ETagFunction}; ok -> Filepath1 = join_paths(Directory1, Filepath), Fileinfo = file:read_file_info(Filepath1), #state{filepath=Filepath1, fileinfo=Fileinfo, mimetypes=Mimetypes1, etag_fun=ETagFunction} end, {ok, Req1, State}. %% @private Only allow GET and HEAD requests on files. -spec allowed_methods(#http_req{}, #state{}) -> {[atom()], #http_req{}, #state{}}. allowed_methods(Req, State) -> {['GET', 'HEAD'], Req, State}. %% @private malformed_request(Req, #state{filepath=error}=State) -> {true, Req, State}; malformed_request(Req, State) -> {false, Req, State}. %% @private Check if the resource exists under the document root. resource_exists(Req, #state{fileinfo={error, _}}=State) -> {false, Req, State}; resource_exists(Req, #state{fileinfo={ok, Fileinfo}}=State) -> {Fileinfo#file_info.type =:= regular, Req, State}. %% @private %% Access to a file resource is forbidden if it exists and the local node does %% not have permission to read it. Directory listings are always forbidden. forbidden(Req, #state{fileinfo={_, #file_info{type=directory}}}=State) -> {true, Req, State}; forbidden(Req, #state{fileinfo={error, eacces}}=State) -> {true, Req, State}; forbidden(Req, #state{fileinfo={error, _}}=State) -> {false, Req, State}; forbidden(Req, #state{fileinfo={ok, #file_info{access=Access}}}=State) -> {not (Access =:= read orelse Access =:= read_write), Req, State}. %% @private Read the time a file system system object was last modified. -spec last_modified(#http_req{}, #state{}) -> {calendar:datetime(), #http_req{}, #state{}}. last_modified(Req, #state{fileinfo={ok, #file_info{mtime=Modified}}}=State) -> {Modified, Req, State}. %% @private Generate the ETag header value for this file. %% The ETag header value is only generated if the resource is a file that %% exists in document root. -spec generate_etag(#http_req{}, #state{}) -> {undefined | binary(), #http_req{}, #state{}}. generate_etag(Req, #state{fileinfo={_, #file_info{type=regular, inode=INode, mtime=Modified, size=Filesize}}, filepath=Filepath, etag_fun={ETagFun, ETagData}}=State) -> ETagArgs = [ {filepath, Filepath}, {filesize, Filesize}, {inode, INode}, {mtime, Modified}], {ETagFun(ETagArgs, ETagData), Req, State}; generate_etag(Req, State) -> {undefined, Req, State}. %% @private Return the content type of a file. -spec content_types_provided(#http_req{}, #state{}) -> tuple(). content_types_provided(Req, #state{filepath=Filepath, mimetypes={MimetypesFun, MimetypesData}}=State) -> Mimetypes = [{T, file_contents} || T <- MimetypesFun(Filepath, MimetypesData)], {Mimetypes, Req, State}. %% @private Return a function that writes a file directly to the socket. -spec file_contents(#http_req{}, #state{}) -> tuple(). file_contents(Req, #state{filepath=Filepath, fileinfo={ok, #file_info{size=Filesize}}}=State) -> {ok, Transport, Socket} = cowboy_http_req:transport(Req), Writefile = content_function(Transport, Socket, Filepath), {{stream, Filesize, Writefile}, Req, State}. %% @private Return a function writing the contents of a file to a socket. %% The function returns the number of bytes written to the socket to enable %% the calling function to determine if the expected number of bytes were %% written to the socket. -spec content_function(module(), inet:socket(), binary()) -> fun(() -> {sent, non_neg_integer()}). content_function(Transport, Socket, Filepath) -> %% `file:sendfile/2' will only work with the `cowboy_tcp_transport' %% transport module. SSL or future SPDY transports that require the %% content to be encrypted or framed as the content is sent. case erlang:function_exported(file, sendfile, 2) of false -> fun() -> sfallback(Transport, Socket, Filepath) end; _ when Transport =/= cowboy_tcp_transport -> fun() -> sfallback(Transport, Socket, Filepath) end; true -> fun() -> sendfile(Socket, Filepath) end end. %% @private Sendfile fallback function. -spec sfallback(module(), inet:socket(), binary()) -> {sent, non_neg_integer()}. sfallback(Transport, Socket, Filepath) -> {ok, File} = file:open(Filepath, [read,binary,raw]), sfallback(Transport, Socket, File, 0). -spec sfallback(module(), inet:socket(), file:io_device(), non_neg_integer()) -> {sent, non_neg_integer()}. sfallback(Transport, Socket, File, Sent) -> case file:read(File, 16#1FFF) of eof -> ok = file:close(File), {sent, Sent}; {ok, Bin} -> ok = Transport:send(Socket, Bin), sfallback(Transport, Socket, File, Sent + byte_size(Bin)) end. %% @private Wrapper for sendfile function. -spec sendfile(inet:socket(), binary()) -> {sent, non_neg_integer()}. sendfile(Socket, Filepath) -> {ok, Sent} = file:sendfile(Filepath, Socket), {sent, Sent}. -spec directory_path(dirspec()) -> dirpath(). directory_path({priv_dir, App, []}) -> priv_dir_path(App); directory_path({priv_dir, App, [H|_]=Path}) when is_integer(H) -> filename:join(priv_dir_path(App), Path); directory_path({priv_dir, App, [H|_]=Path}) when is_binary(H) -> filename:join(filename:split(priv_dir_path(App)) ++ Path); directory_path({priv_dir, App, Path}) when is_binary(Path) -> filename:join(priv_dir_path(App), Path); directory_path(Path) -> Path. %% @private Validate a request path for unsafe characters. %% There is no way to escape special characters in a filesystem path. -spec check_path(Path::[binary()]) -> ok | error. check_path([]) -> ok; check_path([<<"">>|_T]) -> error; check_path([<<".">>|_T]) -> error; check_path([<<"..">>|_T]) -> error; check_path([H|T]) -> case binary:match(H, <<"/">>) of {_, _} -> error; nomatch -> check_path(T) end. %% @private Join the the directory and request paths. -spec join_paths(dirpath(), [binary()]) -> binary(). join_paths([H|_]=Dirpath, Filepath) when is_integer(H) -> filename:join(filename:split(Dirpath) ++ Filepath); join_paths([H|_]=Dirpath, Filepath) when is_binary(H) -> filename:join(Dirpath ++ Filepath); join_paths(Dirpath, Filepath) when is_binary(Dirpath) -> filename:join([Dirpath] ++ Filepath); join_paths([], Filepath) -> filename:join(Filepath). %% @private Return the path to the priv/ directory of an application. -spec priv_dir_path(atom()) -> string(). priv_dir_path(App) -> case code:priv_dir(App) of {error, bad_name} -> priv_dir_mod(App); Dir -> Dir end. -spec priv_dir_mod(atom()) -> string(). priv_dir_mod(Mod) -> case code:which(Mod) of File when not is_list(File) -> "../priv"; File -> filename:join([filename:dirname(File),"../priv"]) end. %% @private Use application/octet-stream as the default mimetype. %% If a list of extension - mimetype pairs are provided as the mimetypes %% an attempt to find the mimetype using the file extension. If no match %% is found the default mimetype is returned. -spec path_to_mimetypes(binary(), [{binary(), [mimedef()]}]) -> [mimedef()]. path_to_mimetypes(Filepath, Extensions) when is_binary(Filepath) -> Ext = filename:extension(Filepath), case Ext of <<>> -> default_mimetype(); _Ext -> path_to_mimetypes_(Ext, Extensions) end. -spec path_to_mimetypes_(binary(), [{binary(), [mimedef()]}]) -> [mimedef()]. path_to_mimetypes_(Ext, Extensions) -> case lists:keyfind(Ext, 1, Extensions) of {_, MTs} -> MTs; _Unknown -> default_mimetype() end. -spec default_mimetype() -> [mimedef()]. default_mimetype() -> [{<<"application">>, <<"octet-stream">>, []}]. %% @private Do not send ETag headers in the default configuration. -spec no_etag_function([etagarg()], undefined) -> undefined. no_etag_function(_Args, undefined) -> undefined. %% @private A simple alternative is to send an ETag based on file attributes. -type fileattr() :: filepath | filesize | mtime | inode. -spec attr_etag_function([etagarg()], [fileattr()]) -> binary(). attr_etag_function(Args, Attrs) -> attr_etag_function(Args, Attrs, []). -spec attr_etag_function([etagarg()], [fileattr()], [binary()]) -> binary(). attr_etag_function(_Args, [], Acc) -> list_to_binary(erlang:integer_to_list(erlang:crc32(Acc), 16)); attr_etag_function(Args, [H|T], Acc) -> {_, Value} = lists:keyfind(H, 1, Args), attr_etag_function(Args, T, [term_to_binary(Value)|Acc]). -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -define(_eq(E, I), ?_assertEqual(E, I)). check_path_test_() -> C = fun check_path/1, [?_eq(error, C([<<>>])), ?_eq(ok, C([<<"abc">>])), ?_eq(error, C([<<".">>])), ?_eq(error, C([<<"..">>])), ?_eq(error, C([<<"/">>])) ]. join_paths_test_() -> P = fun join_paths/2, [?_eq(<<"a">>, P([], [<<"a">>])), ?_eq(<<"a/b/c">>, P(<<"a/b">>, [<<"c">>])), ?_eq(<<"a/b/c">>, P("a/b", [<<"c">>])), ?_eq(<<"a/b/c">>, P([<<"a">>, <<"b">>], [<<"c">>])) ]. directory_path_test_() -> P = fun directory_path/1, PL = fun(I) -> length(filename:split(P(I))) end, Base = PL({priv_dir, cowboy, []}), [?_eq(Base + 1, PL({priv_dir, cowboy, "a"})), ?_eq(Base + 1, PL({priv_dir, cowboy, <<"a">>})), ?_eq(Base + 1, PL({priv_dir, cowboy, [<<"a">>]})), ?_eq(Base + 2, PL({priv_dir, cowboy, "a/b"})), ?_eq(Base + 2, PL({priv_dir, cowboy, <<"a/b">>})), ?_eq(Base + 2, PL({priv_dir, cowboy, [<<"a">>, <<"b">>]})), ?_eq("a/b", P("a/b")) ]. -endif. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_tcp_transport.erl0000644000177700017770000000732212633765070031550 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @doc TCP transport API. %% %% Wrapper around gen_tcp implementing the Cowboy transport API. %% %% @see gen_tcp -module(cowboy_tcp_transport). -export([name/0, messages/0, listen/1, accept/2, recv/3, send/2, setopts/2, controlling_process/2, peername/1, close/1]). %% @doc Name of this transport API, tcp. -spec name() -> tcp. name() -> tcp. %% @doc Atoms used in the process messages sent by this API. %% %% They identify incoming data, closed connection and errors when receiving %% data in active mode. -spec messages() -> {tcp, tcp_closed, tcp_error}. messages() -> {tcp, tcp_closed, tcp_error}. %% @doc Setup a socket to listen on the given port on the local host. %% %% The available options are: %%
    %%
    port
    Mandatory. TCP port number to open.
    %%
    backlog
    Maximum length of the pending connections queue. %% Defaults to 1024.
    %%
    ip
    Interface to listen on. Listen on all interfaces %% by default.
    %%
    %% %% @see gen_tcp:listen/2 -spec listen([{port, inet:ip_port()} | {ip, inet:ip_address()}]) -> {ok, inet:socket()} | {error, atom()}. listen(Opts) -> {port, Port} = lists:keyfind(port, 1, Opts), Backlog = proplists:get_value(backlog, Opts, 1024), ListenOpts0 = [binary, {active, false}, {backlog, Backlog}, {packet, raw}, {reuseaddr, true}], ListenOpts = case lists:keyfind(ip, 1, Opts) of false -> ListenOpts0; Ip -> [Ip|ListenOpts0] end, gen_tcp:listen(Port, ListenOpts). %% @doc Accept an incoming connection on a listen socket. %% @see gen_tcp:accept/2 -spec accept(inet:socket(), timeout()) -> {ok, inet:socket()} | {error, closed | timeout | atom()}. accept(LSocket, Timeout) -> gen_tcp:accept(LSocket, Timeout). %% @doc Receive a packet from a socket in passive mode. %% @see gen_tcp:recv/3 -spec recv(inet:socket(), non_neg_integer(), timeout()) -> {ok, any()} | {error, closed | atom()}. recv(Socket, Length, Timeout) -> gen_tcp:recv(Socket, Length, Timeout). %% @doc Send a packet on a socket. %% @see gen_tcp:send/2 -spec send(inet:socket(), iolist()) -> ok | {error, atom()}. send(Socket, Packet) -> gen_tcp:send(Socket, Packet). %% @doc Set one or more options for a socket. %% @see inet:setopts/2 -spec setopts(inet:socket(), list()) -> ok | {error, atom()}. setopts(Socket, Opts) -> inet:setopts(Socket, Opts). %% @doc Assign a new controlling process Pid to Socket. %% @see gen_tcp:controlling_process/2 -spec controlling_process(inet:socket(), pid()) -> ok | {error, closed | not_owner | atom()}. controlling_process(Socket, Pid) -> gen_tcp:controlling_process(Socket, Pid). %% @doc Return the address and port for the other end of a connection. %% @see inet:peername/1 -spec peername(inet:socket()) -> {ok, {inet:ip_address(), inet:ip_port()}} | {error, atom()}. peername(Socket) -> inet:peername(Socket). %% @doc Close a TCP socket. %% @see gen_tcp:close/1 -spec close(inet:socket()) -> ok. close(Socket) -> gen_tcp:close(Socket). rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_http_websocket_handler.erl0000644000177700017770000000557412633765070033377 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @doc Handler for HTTP WebSocket requests. %% %% WebSocket handlers must implement four callbacks: websocket_init/3, %% websocket_handle/3, websocket_info/3 and %% websocket_terminate/3. These callbacks will only be called if the %% connection is upgraded to WebSocket in the HTTP handler's init/3 %% callback. They are then called in that order, although %% websocket_handle/3 will be called for each packet received, %% and websocket_info for each message received. %% %% websocket_init/3 is meant for initialization. It receives %% information about the transport and protocol used, along with the handler %% options from the dispatch list. You can define a request-wide state here. %% If you are going to want to compact the request, you should probably do it %% here. %% %% websocket_handle/3 receives the data from the socket. It can reply %% something, do nothing or close the connection. %% %% websocket_info/3 receives messages sent to the process. It has %% the same reply format as websocket_handle/3 described above. Note %% that unlike in a gen_server, when websocket_info/3 %% replies something, it is always to the socket, not to the process that %% originated the message. %% %% websocket_terminate/3 is meant for cleaning up. It also receives %% the request and the state previously defined, along with a reason for %% termination. %% %% All of websocket_init/3, websocket_handle/3 and %% websocket_info/3 can decide to hibernate the process by adding %% an extra element to the returned tuple, containing the atom %% hibernate. Doing so helps save memory and improve CPU usage. -module(cowboy_http_websocket_handler). -export([behaviour_info/1]). %% @private -spec behaviour_info(_) -> undefined | [{websocket_handle, 3} | {websocket_info, 3} | {websocket_init, 3} | {websocket_terminate, 3}, ...]. behaviour_info(callbacks) -> [{websocket_init, 3}, {websocket_handle, 3}, {websocket_info, 3}, {websocket_terminate, 3}]; behaviour_info(_Other) -> undefined. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_multipart.erl0000644000177700017770000002151212633765070030664 0ustar michaelmichael%% Copyright (c) 2011, Anthony Ramine %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @doc Multipart parser. -module(cowboy_multipart). -type part_parser() :: any(). -type parser(T) :: fun((binary()) -> T). -type more(T) :: T | {more, parser(T)}. -type part_result() :: any(). -type headers() :: any(). -type http_headers() :: [{atom() | binary(), binary()}]. -type body_cont() :: any(). -type cont(T) :: fun(() -> T). -type body_result() :: any(). -type end_of_part() :: {end_of_part, cont(more(part_result()))}. -type disposition() :: {binary(), [{binary(), binary()}]}. -export([parser/1, content_disposition/1]). -include_lib("eunit/include/eunit.hrl"). %% API. %% @doc Return a multipart parser for the given boundary. -spec parser(binary()) -> part_parser(). parser(Boundary) when is_binary(Boundary) -> fun (Bin) when is_binary(Bin) -> parse(Bin, Boundary) end. %% @doc Parse a content disposition. %% @todo Parse the MIME header instead of the HTTP one. -spec content_disposition(binary()) -> disposition(). content_disposition(Data) -> cowboy_http:token_ci(Data, fun (_Rest, <<>>) -> {error, badarg}; (Rest, Disposition) -> cowboy_http:content_type_params(Rest, fun (Params) -> {Disposition, Params} end, []) end). %% Internal. %% @doc Entry point of the multipart parser, skips over the preamble if any. -spec parse(binary(), binary()) -> more(part_result()). parse(Bin, Boundary) when byte_size(Bin) >= byte_size(Boundary) + 2 -> BoundarySize = byte_size(Boundary), Pattern = pattern(Boundary), case Bin of <<"--", Boundary:BoundarySize/binary, Rest/binary>> -> % Data starts with initial boundary, skip preamble parsing. parse_boundary_tail(Rest, Pattern); _ -> % Parse preamble. skip(Bin, Pattern) end; parse(Bin, Boundary) -> % Not enough data to know if the data begins with a boundary. more(Bin, fun (NewBin) -> parse(NewBin, Boundary) end). -type pattern() :: {binary:cp(), non_neg_integer()}. %% @doc Return a compiled binary pattern with its size in bytes. %% The pattern is the boundary prepended with "\r\n--". -spec pattern(binary()) -> pattern(). pattern(Boundary) -> MatchPattern = <<"\r\n--", Boundary/binary>>, {binary:compile_pattern(MatchPattern), byte_size(MatchPattern)}. %% @doc Parse remaining characters of a line beginning with the boundary. %% If followed by "--", eof is returned and parsing is finished. -spec parse_boundary_tail(binary(), pattern()) -> more(part_result()). parse_boundary_tail(Bin, Pattern) when byte_size(Bin) >= 2 -> case Bin of <<"--", _Rest/binary>> -> % Boundary is followed by "--", end parsing. eof; _ -> % No dash after boundary, proceed with unknown chars and lwsp % removal. parse_boundary_eol(Bin, Pattern) end; parse_boundary_tail(Bin, Pattern) -> % Boundary may be followed by "--", need more data. more(Bin, fun (NewBin) -> parse_boundary_tail(NewBin, Pattern) end). %% @doc Skip whitespace and unknown chars until CRLF. -spec parse_boundary_eol(binary(), pattern()) -> more(part_result()). parse_boundary_eol(Bin, Pattern) -> case binary:match(Bin, <<"\r\n">>) of {CrlfStart, _Length} -> % End of line found, remove optional whitespace. <<_:CrlfStart/binary, Rest/binary>> = Bin, Fun = fun (Rest2) -> parse_boundary_crlf(Rest2, Pattern) end, cowboy_http:whitespace(Rest, Fun); nomatch -> % CRLF not found in the given binary. RestStart = lists:max([byte_size(Bin) - 1, 0]), <<_:RestStart/binary, Rest/binary>> = Bin, more(Rest, fun (NewBin) -> parse_boundary_eol(NewBin, Pattern) end) end. -spec parse_boundary_crlf(binary(), pattern()) -> more(part_result()). parse_boundary_crlf(<<"\r\n", Rest/binary>>, Pattern) -> % The binary is at least 2 bytes long as this function is only called by % parse_boundary_eol/3 when CRLF has been found so a more tuple will never % be returned from here. parse_headers(Rest, Pattern); parse_boundary_crlf(Bin, Pattern) -> % Unspecified behaviour here: RFC 2046 doesn't say what to do when LWSP is % not followed directly by a new line. In this implementation it is % considered part of the boundary so EOL needs to be searched again. parse_boundary_eol(Bin, Pattern). -spec parse_headers(binary(), pattern()) -> more(part_result()). parse_headers(Bin, Pattern) -> parse_headers(Bin, Pattern, []). -spec parse_headers(binary(), pattern(), http_headers()) -> more(part_result()). parse_headers(Bin, Pattern, Acc) -> case erlang:decode_packet(httph_bin, Bin, []) of {ok, {http_header, _, Name, _, Value}, Rest} -> parse_headers(Rest, Pattern, [{Name, Value} | Acc]); {ok, http_eoh, Rest} -> Headers = lists:reverse(Acc), {headers, Headers, fun () -> parse_body(Rest, Pattern) end}; {ok, {http_error, _}, _} -> % Skip malformed parts. skip(Bin, Pattern); {more, _} -> more(Bin, fun (NewBin) -> parse_headers(NewBin, Pattern, Acc) end) end. -spec parse_body(binary(), pattern()) -> more(body_result()). parse_body(Bin, Pattern = {P, PSize}) when byte_size(Bin) >= PSize -> case binary:match(Bin, P) of {0, _Length} -> <<_:PSize/binary, Rest/binary>> = Bin, end_of_part(Rest, Pattern); {BoundaryStart, _Length} -> % Boundary found, this is the latest partial body that will be % returned for this part. <> = Bin, FResult = end_of_part(Rest, Pattern), {body, PBody, fun () -> FResult end}; nomatch -> PartialLength = byte_size(Bin) - PSize + 1, <> = Bin, {body, PBody, fun () -> parse_body(Rest, Pattern) end} end; parse_body(Bin, Pattern) -> more(Bin, fun (NewBin) -> parse_body(NewBin, Pattern) end). -spec end_of_part(binary(), pattern()) -> end_of_part(). end_of_part(Bin, Pattern) -> {end_of_part, fun () -> parse_boundary_tail(Bin, Pattern) end}. -spec skip(binary(), pattern()) -> more(part_result()). skip(Bin, Pattern = {P, PSize}) -> case binary:match(Bin, P) of {BoundaryStart, _Length} -> % Boundary found, proceed with parsing of the next part. RestStart = BoundaryStart + PSize, <<_:RestStart/binary, Rest/binary>> = Bin, parse_boundary_tail(Rest, Pattern); nomatch -> % Boundary not found, need more data. RestStart = lists:max([byte_size(Bin) - PSize + 1, 0]), <<_:RestStart/binary, Rest/binary>> = Bin, more(Rest, fun (NewBin) -> skip(NewBin, Pattern) end) end. -spec more(binary(), parser(T)) -> {more, parser(T)}. more(<<>>, F) -> {more, F}; more(Bin, InnerF) -> F = fun (NewData) when is_binary(NewData) -> InnerF(<>) end, {more, F}. %% Tests. -ifdef(TEST). multipart_test_() -> %% {Body, Result} Tests = [ {<<"--boundary--">>, []}, {<<"preamble\r\n--boundary--">>, []}, {<<"--boundary--\r\nepilogue">>, []}, {<<"\r\n--boundary\r\nA:b\r\nC:d\r\n\r\n\r\n--boundary--">>, [{[{<<"A">>, <<"b">>}, {<<"C">>, <<"d">>}], <<>>}]}, { << "--boundary\r\nX-Name:answer\r\n\r\n42" "\r\n--boundary\r\nServer:Cowboy\r\n\r\nIt rocks!\r\n" "\r\n--boundary--" >>, [ {[{<<"X-Name">>, <<"answer">>}], <<"42">>}, {[{'Server', <<"Cowboy">>}], <<"It rocks!\r\n">>} ] } ], [{title(V), fun () -> R = acc_multipart(V) end} || {V, R} <- Tests]. acc_multipart(V) -> acc_multipart((parser(<<"boundary">>))(V), []). acc_multipart({headers, Headers, Cont}, Acc) -> acc_multipart(Cont(), [{Headers, []}|Acc]); acc_multipart({body, Body, Cont}, [{Headers, BodyAcc}|Acc]) -> acc_multipart(Cont(), [{Headers, [Body|BodyAcc]}|Acc]); acc_multipart({end_of_part, Cont}, [{Headers, BodyAcc}|Acc]) -> Body = list_to_binary(lists:reverse(BodyAcc)), acc_multipart(Cont(), [{Headers, Body}|Acc]); acc_multipart(eof, Acc) -> lists:reverse(Acc). content_disposition_test_() -> %% {Disposition, Result} Tests = [ {<<"form-data; name=id">>, {<<"form-data">>, [{<<"name">>, <<"id">>}]}}, {<<"inline">>, {<<"inline">>, []}}, {<<"attachment; \tfilename=brackets-slides.pdf">>, {<<"attachment">>, [{<<"filename">>, <<"brackets-slides.pdf">>}]}} ], [{title(V), fun () -> R = content_disposition(V) end} || {V, R} <- Tests]. title(Bin) -> Title = lists:foldl( fun ({T, R}, V) -> re:replace(V, T, R, [global]) end, Bin, [{"\t", "\\\\t"}, {"\r", "\\\\r"}, {"\n", "\\\\n"}] ), iolist_to_binary(Title). -endif. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_app.erl0000644000177700017770000000310712633765070027423 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @private -module(cowboy_app). -behaviour(application). -export([start/2, stop/1, profile_output/0]). %% API. -type application_start_type() :: normal | {takeover, node()} | {failover, node()}. %% API. -spec start(application_start_type(), any()) -> {ok, pid()}. start(_Type, _Args) -> consider_profiling(), cowboy_sup:start_link(). -spec stop(any()) -> ok. stop(_State) -> ok. -spec profile_output() -> ok. profile_output() -> eprof:stop_profiling(), eprof:log("procs.profile"), eprof:analyze(procs), eprof:log("total.profile"), eprof:analyze(total). %% Internal. -spec consider_profiling() -> profiling | not_profiling. consider_profiling() -> case application:get_env(profile) of {ok, true} -> {ok, _Pid} = eprof:start(), eprof:start_profiling([self()]); _ -> not_profiling end. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy_http.erl0000644000177700017770000007315512633765070027634 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% Copyright (c) 2011, Anthony Ramine %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @doc Core HTTP parsing API. -module(cowboy_http). %% Parsing. -export([list/2, nonempty_list/2, content_type/1, content_type_params/3, media_range/2, conneg/2, language_range/2, entity_tag_match/1, http_date/1, rfc1123_date/1, rfc850_date/1, asctime_date/1, whitespace/2, digits/1, token/2, token_ci/2, quoted_string/2]). %% Interpretation. -export([connection_to_atom/1, urldecode/1, urldecode/2, urlencode/1, urlencode/2]). -type method() :: 'OPTIONS' | 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'TRACE' | binary(). -type uri() :: '*' | {absoluteURI, http | https, Host::binary(), Port::integer() | undefined, Path::binary()} | {scheme, Scheme::binary(), binary()} | {abs_path, binary()} | binary(). -type version() :: {Major::non_neg_integer(), Minor::non_neg_integer()}. -type header() :: 'Cache-Control' | 'Connection' | 'Date' | 'Pragma' | 'Transfer-Encoding' | 'Upgrade' | 'Via' | 'Accept' | 'Accept-Charset' | 'Accept-Encoding' | 'Accept-Language' | 'Authorization' | 'From' | 'Host' | 'If-Modified-Since' | 'If-Match' | 'If-None-Match' | 'If-Range' | 'If-Unmodified-Since' | 'Max-Forwards' | 'Proxy-Authorization' | 'Range' | 'Referer' | 'User-Agent' | 'Age' | 'Location' | 'Proxy-Authenticate' | 'Public' | 'Retry-After' | 'Server' | 'Vary' | 'Warning' | 'Www-Authenticate' | 'Allow' | 'Content-Base' | 'Content-Encoding' | 'Content-Language' | 'Content-Length' | 'Content-Location' | 'Content-Md5' | 'Content-Range' | 'Content-Type' | 'Etag' | 'Expires' | 'Last-Modified' | 'Accept-Ranges' | 'Set-Cookie' | 'Set-Cookie2' | 'X-Forwarded-For' | 'Cookie' | 'Keep-Alive' | 'Proxy-Connection' | binary(). -type fake_iodata() :: iolist() | binary(). -type headers() :: [{header(), fake_iodata()}]. -type status() :: non_neg_integer() | binary(). -export_type([method/0, uri/0, version/0, header/0, headers/0, status/0]). -include("include/http.hrl"). -include_lib("eunit/include/eunit.hrl"). %% Parsing. %% @doc Parse a non-empty list of the given type. -spec nonempty_list(binary(), fun()) -> [any(), ...] | {error, badarg}. nonempty_list(Data, Fun) -> case list(Data, Fun, []) of {error, badarg} -> {error, badarg}; [] -> {error, badarg}; L -> lists:reverse(L) end. %% @doc Parse a list of the given type. -spec list(binary(), fun()) -> list() | {error, badarg}. list(Data, Fun) -> case list(Data, Fun, []) of {error, badarg} -> {error, badarg}; L -> lists:reverse(L) end. -spec list(binary(), fun(), [binary()]) -> [any()] | {error, badarg}. %% From the RFC: %%
    Wherever this construct is used, null elements are allowed, %% but do not contribute to the count of elements present. %% That is, "(element), , (element) " is permitted, but counts %% as only two elements. Therefore, where at least one element is required, %% at least one non-null element MUST be present.
    list(Data, Fun, Acc) -> whitespace(Data, fun (<<>>) -> Acc; (<< $,, Rest/binary >>) -> list(Rest, Fun, Acc); (Rest) -> Fun(Rest, fun (D, I) -> whitespace(D, fun (<<>>) -> [I|Acc]; (<< $,, R/binary >>) -> list(R, Fun, [I|Acc]); (_Any) -> {error, badarg} end) end) end). %% @doc Parse a content type. -spec content_type(binary()) -> any(). content_type(Data) -> media_type(Data, fun (Rest, Type, SubType) -> content_type_params(Rest, fun (Params) -> {Type, SubType, Params} end, []) end). -spec content_type_params(binary(), fun(), list({binary(), binary()})) -> any(). content_type_params(Data, Fun, Acc) -> whitespace(Data, fun (<< $;, Rest/binary >>) -> content_type_param(Rest, Fun, Acc); (<<>>) -> Fun(lists:reverse(Acc)); (_Rest) -> {error, badarg} end). -spec content_type_param(binary(), fun(), list({binary(), binary()})) -> any(). content_type_param(Data, Fun, Acc) -> whitespace(Data, fun (Rest) -> token_ci(Rest, fun (_Rest2, <<>>) -> {error, badarg}; (<< $=, Rest2/binary >>, Attr) -> word(Rest2, fun (Rest3, Value) -> content_type_params(Rest3, Fun, [{Attr, Value}|Acc]) end); (_Rest2, _Attr) -> {error, badarg} end) end). %% @doc Parse a media range. -spec media_range(binary(), fun()) -> any(). media_range(Data, Fun) -> media_type(Data, fun (Rest, Type, SubType) -> media_range_params(Rest, Fun, Type, SubType, []) end). -spec media_range_params(binary(), fun(), binary(), binary(), [{binary(), binary()}]) -> any(). media_range_params(Data, Fun, Type, SubType, Acc) -> whitespace(Data, fun (<< $;, Rest/binary >>) -> whitespace(Rest, fun (Rest2) -> media_range_param_attr(Rest2, Fun, Type, SubType, Acc) end); (Rest) -> Fun(Rest, {{Type, SubType, lists:reverse(Acc)}, 1000, []}) end). -spec media_range_param_attr(binary(), fun(), binary(), binary(), [{binary(), binary()}]) -> any(). media_range_param_attr(Data, Fun, Type, SubType, Acc) -> token_ci(Data, fun (_Rest, <<>>) -> {error, badarg}; (<< $=, Rest/binary >>, Attr) -> media_range_param_value(Rest, Fun, Type, SubType, Acc, Attr) end). -spec media_range_param_value(binary(), fun(), binary(), binary(), [{binary(), binary()}], binary()) -> any(). media_range_param_value(Data, Fun, Type, SubType, Acc, <<"q">>) -> qvalue(Data, fun (Rest, Quality) -> accept_ext(Rest, Fun, Type, SubType, Acc, Quality, []) end); media_range_param_value(Data, Fun, Type, SubType, Acc, Attr) -> word(Data, fun (Rest, Value) -> media_range_params(Rest, Fun, Type, SubType, [{Attr, Value}|Acc]) end). %% @doc Parse a media type. -spec media_type(binary(), fun()) -> any(). media_type(Data, Fun) -> token_ci(Data, fun (_Rest, <<>>) -> {error, badarg}; (<< $/, Rest/binary >>, Type) -> token_ci(Rest, fun (_Rest2, <<>>) -> {error, badarg}; (Rest2, SubType) -> Fun(Rest2, Type, SubType) end); (_Rest, _Type) -> {error, badarg} end). -spec accept_ext(binary(), fun(), binary(), binary(), [{binary(), binary()}], 0..1000, [{binary(), binary()} | binary()]) -> any(). accept_ext(Data, Fun, Type, SubType, Params, Quality, Acc) -> whitespace(Data, fun (<< $;, Rest/binary >>) -> whitespace(Rest, fun (Rest2) -> accept_ext_attr(Rest2, Fun, Type, SubType, Params, Quality, Acc) end); (Rest) -> Fun(Rest, {{Type, SubType, lists:reverse(Params)}, Quality, lists:reverse(Acc)}) end). -spec accept_ext_attr(binary(), fun(), binary(), binary(), [{binary(), binary()}], 0..1000, [{binary(), binary()} | binary()]) -> any(). accept_ext_attr(Data, Fun, Type, SubType, Params, Quality, Acc) -> token_ci(Data, fun (_Rest, <<>>) -> {error, badarg}; (<< $=, Rest/binary >>, Attr) -> accept_ext_value(Rest, Fun, Type, SubType, Params, Quality, Acc, Attr); (Rest, Attr) -> accept_ext(Rest, Fun, Type, SubType, Params, Quality, [Attr|Acc]) end). -spec accept_ext_value(binary(), fun(), binary(), binary(), [{binary(), binary()}], 0..1000, [{binary(), binary()} | binary()], binary()) -> any(). accept_ext_value(Data, Fun, Type, SubType, Params, Quality, Acc, Attr) -> word(Data, fun (Rest, Value) -> accept_ext(Rest, Fun, Type, SubType, Params, Quality, [{Attr, Value}|Acc]) end). %% @doc Parse a conneg header (Accept-Charset, Accept-Encoding), %% followed by an optional quality value. -spec conneg(binary(), fun()) -> any(). conneg(Data, Fun) -> token_ci(Data, fun (_Rest, <<>>) -> {error, badarg}; (Rest, Conneg) -> maybe_qparam(Rest, fun (Rest2, Quality) -> Fun(Rest2, {Conneg, Quality}) end) end). %% @doc Parse a language range, followed by an optional quality value. -spec language_range(binary(), fun()) -> any(). language_range(<< $*, Rest/binary >>, Fun) -> language_range_ret(Rest, Fun, '*'); language_range(Data, Fun) -> language_tag(Data, fun (Rest, LanguageTag) -> language_range_ret(Rest, Fun, LanguageTag) end). -spec language_range_ret(binary(), fun(), '*' | {binary(), [binary()]}) -> any(). language_range_ret(Data, Fun, LanguageTag) -> maybe_qparam(Data, fun (Rest, Quality) -> Fun(Rest, {LanguageTag, Quality}) end). -spec language_tag(binary(), fun()) -> any(). language_tag(Data, Fun) -> alpha(Data, fun (_Rest, Tag) when byte_size(Tag) =:= 0; byte_size(Tag) > 8 -> {error, badarg}; (<< $-, Rest/binary >>, Tag) -> language_subtag(Rest, Fun, Tag, []); (Rest, Tag) -> Fun(Rest, Tag) end). -spec language_subtag(binary(), fun(), binary(), [binary()]) -> any(). language_subtag(Data, Fun, Tag, Acc) -> alpha(Data, fun (_Rest, SubTag) when byte_size(SubTag) =:= 0; byte_size(SubTag) > 8 -> {error, badarg}; (<< $-, Rest/binary >>, SubTag) -> language_subtag(Rest, Fun, Tag, [SubTag|Acc]); (Rest, SubTag) -> %% Rebuild the full tag now that we know it's correct Sub = << << $-, S/binary >> || S <- lists:reverse([SubTag|Acc]) >>, Fun(Rest, << Tag/binary, Sub/binary >>) end). -spec maybe_qparam(binary(), fun()) -> any(). maybe_qparam(Data, Fun) -> whitespace(Data, fun (<< $;, Rest/binary >>) -> whitespace(Rest, fun (Rest2) -> qparam(Rest2, Fun) end); (Rest) -> Fun(Rest, 1000) end). %% @doc Parse a quality parameter string (for example q=0.500). -spec qparam(binary(), fun()) -> any(). qparam(<< Q, $=, Data/binary >>, Fun) when Q =:= $q; Q =:= $Q -> qvalue(Data, Fun). %% @doc Parse either a list of entity tags or a "*". -spec entity_tag_match(binary()) -> any(). entity_tag_match(<< $*, Rest/binary >>) -> whitespace(Rest, fun (<<>>) -> '*'; (_Any) -> {error, badarg} end); entity_tag_match(Data) -> nonempty_list(Data, fun entity_tag/2). %% @doc Parse an entity-tag. -spec entity_tag(binary(), fun()) -> any(). entity_tag(<< "W/", Rest/binary >>, Fun) -> opaque_tag(Rest, Fun, weak); entity_tag(Data, Fun) -> opaque_tag(Data, Fun, strong). -spec opaque_tag(binary(), fun(), weak | strong) -> any(). opaque_tag(Data, Fun, Strength) -> quoted_string(Data, fun (_Rest, <<>>) -> {error, badarg}; (Rest, OpaqueTag) -> Fun(Rest, {Strength, OpaqueTag}) end). %% @doc Parse an HTTP date (RFC1123, RFC850 or asctime date). %% @end %% %% While this may not be the most efficient date parsing we can do, %% it should work fine for our purposes because all HTTP dates should %% be sent as RFC1123 dates in HTTP/1.1. -spec http_date(binary()) -> any(). http_date(Data) -> case rfc1123_date(Data) of {error, badarg} -> case rfc850_date(Data) of {error, badarg} -> case asctime_date(Data) of {error, badarg} -> {error, badarg}; HTTPDate -> HTTPDate end; HTTPDate -> HTTPDate end; HTTPDate -> HTTPDate end. %% @doc Parse an RFC1123 date. -spec rfc1123_date(binary()) -> any(). rfc1123_date(Data) -> wkday(Data, fun (<< ", ", Rest/binary >>, _WkDay) -> date1(Rest, fun (<< " ", Rest2/binary >>, Date) -> time(Rest2, fun (<< " GMT", Rest3/binary >>, Time) -> http_date_ret(Rest3, {Date, Time}); (_Any, _Time) -> {error, badarg} end); (_Any, _Date) -> {error, badarg} end); (_Any, _WkDay) -> {error, badarg} end). %% @doc Parse an RFC850 date. -spec rfc850_date(binary()) -> any(). %% From the RFC: %% HTTP/1.1 clients and caches SHOULD assume that an RFC-850 date %% which appears to be more than 50 years in the future is in fact %% in the past (this helps solve the "year 2000" problem). rfc850_date(Data) -> weekday(Data, fun (<< ", ", Rest/binary >>, _WeekDay) -> date2(Rest, fun (<< " ", Rest2/binary >>, Date) -> time(Rest2, fun (<< " GMT", Rest3/binary >>, Time) -> http_date_ret(Rest3, {Date, Time}); (_Any, _Time) -> {error, badarg} end); (_Any, _Date) -> {error, badarg} end); (_Any, _WeekDay) -> {error, badarg} end). %% @doc Parse an asctime date. -spec asctime_date(binary()) -> any(). asctime_date(Data) -> wkday(Data, fun (<< " ", Rest/binary >>, _WkDay) -> date3(Rest, fun (<< " ", Rest2/binary >>, PartialDate) -> time(Rest2, fun (<< " ", Rest3/binary >>, Time) -> asctime_year(Rest3, PartialDate, Time); (_Any, _Time) -> {error, badarg} end); (_Any, _PartialDate) -> {error, badarg} end); (_Any, _WkDay) -> {error, badarg1} end). -spec asctime_year(binary(), tuple(), tuple()) -> any(). asctime_year(<< Y1, Y2, Y3, Y4, Rest/binary >>, {Month, Day}, Time) when Y1 >= $0, Y1 =< $9, Y2 >= $0, Y2 =< $9, Y3 >= $0, Y3 =< $9, Y4 >= $0, Y4 =< $9 -> Year = (Y1 - $0) * 1000 + (Y2 - $0) * 100 + (Y3 - $0) * 10 + (Y4 - $0), http_date_ret(Rest, {{Year, Month, Day}, Time}). -spec http_date_ret(binary(), tuple()) -> any(). http_date_ret(Data, DateTime = {Date, _Time}) -> whitespace(Data, fun (<<>>) -> case calendar:valid_date(Date) of true -> DateTime; false -> {error, badarg} end; (_Any) -> {error, badarg} end). %% We never use it, pretty much just checks the wkday is right. -spec wkday(binary(), fun()) -> any(). wkday(<< WkDay:3/binary, Rest/binary >>, Fun) when WkDay =:= <<"Mon">>; WkDay =:= <<"Tue">>; WkDay =:= <<"Wed">>; WkDay =:= <<"Thu">>; WkDay =:= <<"Fri">>; WkDay =:= <<"Sat">>; WkDay =:= <<"Sun">> -> Fun(Rest, WkDay); wkday(_Any, _Fun) -> {error, badarg}. %% We never use it, pretty much just checks the weekday is right. -spec weekday(binary(), fun()) -> any(). weekday(<< "Monday", Rest/binary >>, Fun) -> Fun(Rest, <<"Monday">>); weekday(<< "Tuesday", Rest/binary >>, Fun) -> Fun(Rest, <<"Tuesday">>); weekday(<< "Wednesday", Rest/binary >>, Fun) -> Fun(Rest, <<"Wednesday">>); weekday(<< "Thursday", Rest/binary >>, Fun) -> Fun(Rest, <<"Thursday">>); weekday(<< "Friday", Rest/binary >>, Fun) -> Fun(Rest, <<"Friday">>); weekday(<< "Saturday", Rest/binary >>, Fun) -> Fun(Rest, <<"Saturday">>); weekday(<< "Sunday", Rest/binary >>, Fun) -> Fun(Rest, <<"Sunday">>); weekday(_Any, _Fun) -> {error, badarg}. -spec date1(binary(), fun()) -> any(). date1(<< D1, D2, " ", M:3/binary, " ", Y1, Y2, Y3, Y4, Rest/binary >>, Fun) when D1 >= $0, D1 =< $9, D2 >= $0, D2 =< $9, Y1 >= $0, Y1 =< $9, Y2 >= $0, Y2 =< $9, Y3 >= $0, Y3 =< $9, Y4 >= $0, Y4 =< $9 -> case month(M) of {error, badarg} -> {error, badarg}; Month -> Fun(Rest, { (Y1 - $0) * 1000 + (Y2 - $0) * 100 + (Y3 - $0) * 10 + (Y4 - $0), Month, (D1 - $0) * 10 + (D2 - $0) }) end; date1(_Data, _Fun) -> {error, badarg}. -spec date2(binary(), fun()) -> any(). date2(<< D1, D2, "-", M:3/binary, "-", Y1, Y2, Rest/binary >>, Fun) when D1 >= $0, D1 =< $9, D2 >= $0, D2 =< $9, Y1 >= $0, Y1 =< $9, Y2 >= $0, Y2 =< $9 -> case month(M) of {error, badarg} -> {error, badarg}; Month -> Year = (Y1 - $0) * 10 + (Y2 - $0), Year2 = case Year > 50 of true -> Year + 1900; false -> Year + 2000 end, Fun(Rest, { Year2, Month, (D1 - $0) * 10 + (D2 - $0) }) end; date2(_Data, _Fun) -> {error, badarg}. -spec date3(binary(), fun()) -> any(). date3(<< M:3/binary, " ", D1, D2, Rest/binary >>, Fun) when (D1 >= $0 andalso D1 =< $3) orelse D1 =:= $\s, D2 >= $0, D2 =< $9 -> case month(M) of {error, badarg} -> {error, badarg}; Month -> Day = case D1 of $\s -> D2 - $0; D1 -> (D1 - $0) * 10 + (D2 - $0) end, Fun(Rest, {Month, Day}) end; date3(_Data, _Fun) -> {error, badarg}. -spec month(<< _:24 >>) -> 1..12 | {error, badarg}. month(<<"Jan">>) -> 1; month(<<"Feb">>) -> 2; month(<<"Mar">>) -> 3; month(<<"Apr">>) -> 4; month(<<"May">>) -> 5; month(<<"Jun">>) -> 6; month(<<"Jul">>) -> 7; month(<<"Aug">>) -> 8; month(<<"Sep">>) -> 9; month(<<"Oct">>) -> 10; month(<<"Nov">>) -> 11; month(<<"Dec">>) -> 12; month(_Any) -> {error, badarg}. -spec time(binary(), fun()) -> any(). time(<< H1, H2, ":", M1, M2, ":", S1, S2, Rest/binary >>, Fun) when H1 >= $0, H1 =< $2, H2 >= $0, H2 =< $9, M1 >= $0, M1 =< $5, M2 >= $0, M2 =< $9, S1 >= $0, S1 =< $5, S2 >= $0, S2 =< $9 -> Hour = (H1 - $0) * 10 + (H2 - $0), case Hour < 24 of true -> Time = { Hour, (M1 - $0) * 10 + (M2 - $0), (S1 - $0) * 10 + (S2 - $0) }, Fun(Rest, Time); false -> {error, badarg} end. %% @doc Skip whitespace. -spec whitespace(binary(), fun()) -> any(). whitespace(<< C, Rest/binary >>, Fun) when C =:= $\s; C =:= $\t -> whitespace(Rest, Fun); whitespace(Data, Fun) -> Fun(Data). %% @doc Parse a list of digits as a non negative integer. -spec digits(binary()) -> non_neg_integer() | {error, badarg}. digits(Data) -> digits(Data, fun (Rest, I) -> whitespace(Rest, fun (<<>>) -> I; (_Rest2) -> {error, badarg} end) end). -spec digits(binary(), fun()) -> any(). digits(<< C, Rest/binary >>, Fun) when C >= $0, C =< $9 -> digits(Rest, Fun, C - $0); digits(_Data, _Fun) -> {error, badarg}. -spec digits(binary(), fun(), non_neg_integer()) -> any(). digits(<< C, Rest/binary >>, Fun, Acc) when C >= $0, C =< $9 -> digits(Rest, Fun, Acc * 10 + (C - $0)); digits(Data, Fun, Acc) -> Fun(Data, Acc). %% @doc Parse a list of case-insensitive alpha characters. %% %% Changes all characters to lowercase. -spec alpha(binary(), fun()) -> any(). alpha(Data, Fun) -> alpha(Data, Fun, <<>>). -spec alpha(binary(), fun(), binary()) -> any(). alpha(<<>>, Fun, Acc) -> Fun(<<>>, Acc); alpha(<< C, Rest/binary >>, Fun, Acc) when C >= $a andalso C =< $z; C >= $A andalso C =< $Z -> C2 = cowboy_bstr:char_to_lower(C), alpha(Rest, Fun, << Acc/binary, C2 >>); alpha(Data, Fun, Acc) -> Fun(Data, Acc). %% @doc Parse either a token or a quoted string. -spec word(binary(), fun()) -> any(). word(Data = << $", _/binary >>, Fun) -> quoted_string(Data, Fun); word(Data, Fun) -> token(Data, fun (_Rest, <<>>) -> {error, badarg}; (Rest, Token) -> Fun(Rest, Token) end). %% @doc Parse a case-insensitive token. %% %% Changes all characters to lowercase. -spec token_ci(binary(), fun()) -> any(). token_ci(Data, Fun) -> token(Data, Fun, ci, <<>>). %% @doc Parse a token. -spec token(binary(), fun()) -> any(). token(Data, Fun) -> token(Data, Fun, cs, <<>>). -spec token(binary(), fun(), ci | cs, binary()) -> any(). token(<<>>, Fun, _Case, Acc) -> Fun(<<>>, Acc); token(Data = << C, _Rest/binary >>, Fun, _Case, Acc) when C =:= $(; C =:= $); C =:= $<; C =:= $>; C =:= $@; C =:= $,; C =:= $;; C =:= $:; C =:= $\\; C =:= $"; C =:= $/; C =:= $[; C =:= $]; C =:= $?; C =:= $=; C =:= ${; C =:= $}; C =:= $\s; C =:= $\t; C < 32; C =:= 127 -> Fun(Data, Acc); token(<< C, Rest/binary >>, Fun, Case = ci, Acc) -> C2 = cowboy_bstr:char_to_lower(C), token(Rest, Fun, Case, << Acc/binary, C2 >>); token(<< C, Rest/binary >>, Fun, Case, Acc) -> token(Rest, Fun, Case, << Acc/binary, C >>). %% @doc Parse a quoted string. -spec quoted_string(binary(), fun()) -> any(). quoted_string(<< $", Rest/binary >>, Fun) -> quoted_string(Rest, Fun, <<>>). -spec quoted_string(binary(), fun(), binary()) -> any(). quoted_string(<<>>, _Fun, _Acc) -> {error, badarg}; quoted_string(<< $", Rest/binary >>, Fun, Acc) -> Fun(Rest, Acc); quoted_string(<< $\\, C, Rest/binary >>, Fun, Acc) -> quoted_string(Rest, Fun, << Acc/binary, C >>); quoted_string(<< C, Rest/binary >>, Fun, Acc) -> quoted_string(Rest, Fun, << Acc/binary, C >>). %% @doc Parse a quality value. -spec qvalue(binary(), fun()) -> any(). qvalue(<< $0, $., Rest/binary >>, Fun) -> qvalue(Rest, Fun, 0, 100); qvalue(<< $0, Rest/binary >>, Fun) -> Fun(Rest, 0); qvalue(<< $1, $., $0, $0, $0, Rest/binary >>, Fun) -> Fun(Rest, 1000); qvalue(<< $1, $., $0, $0, Rest/binary >>, Fun) -> Fun(Rest, 1000); qvalue(<< $1, $., $0, Rest/binary >>, Fun) -> Fun(Rest, 1000); qvalue(<< $1, Rest/binary >>, Fun) -> Fun(Rest, 1000); qvalue(_Data, _Fun) -> {error, badarg}. -spec qvalue(binary(), fun(), integer(), 1 | 10 | 100) -> any(). qvalue(Data, Fun, Q, 0) -> Fun(Data, Q); qvalue(<< C, Rest/binary >>, Fun, Q, M) when C >= $0, C =< $9 -> qvalue(Rest, Fun, Q + (C - $0) * M, M div 10); qvalue(Data, Fun, Q, _M) -> Fun(Data, Q). %% Interpretation. %% @doc Walk through a tokens list and return whether %% the connection is keepalive or closed. %% %% The connection token is expected to be lower-case. -spec connection_to_atom([binary()]) -> keepalive | close. connection_to_atom([]) -> keepalive; connection_to_atom([<<"keep-alive">>|_Tail]) -> keepalive; connection_to_atom([<<"close">>|_Tail]) -> close; connection_to_atom([_Any|Tail]) -> connection_to_atom(Tail). %% @doc Decode a URL encoded binary. %% @equiv urldecode(Bin, crash) -spec urldecode(binary()) -> binary(). urldecode(Bin) when is_binary(Bin) -> urldecode(Bin, <<>>, crash). %% @doc Decode a URL encoded binary. %% The second argument specifies how to handle percent characters that are not %% followed by two valid hex characters. Use `skip' to ignore such errors, %% if `crash' is used the function will fail with the reason `badarg'. -spec urldecode(binary(), crash | skip) -> binary(). urldecode(Bin, OnError) when is_binary(Bin) -> urldecode(Bin, <<>>, OnError). -spec urldecode(binary(), binary(), crash | skip) -> binary(). urldecode(<<$%, H, L, Rest/binary>>, Acc, OnError) -> G = unhex(H), M = unhex(L), if G =:= error; M =:= error -> case OnError of skip -> ok; crash -> erlang:error(badarg) end, urldecode(<>, <>, OnError); true -> urldecode(Rest, <>, OnError) end; urldecode(<<$%, Rest/binary>>, Acc, OnError) -> case OnError of skip -> ok; crash -> erlang:error(badarg) end, urldecode(Rest, <>, OnError); urldecode(<<$+, Rest/binary>>, Acc, OnError) -> urldecode(Rest, <>, OnError); urldecode(<>, Acc, OnError) -> urldecode(Rest, <>, OnError); urldecode(<<>>, Acc, _OnError) -> Acc. -spec unhex(byte()) -> byte() | error. unhex(C) when C >= $0, C =< $9 -> C - $0; unhex(C) when C >= $A, C =< $F -> C - $A + 10; unhex(C) when C >= $a, C =< $f -> C - $a + 10; unhex(_) -> error. %% @doc URL encode a string binary. %% @equiv urlencode(Bin, []) -spec urlencode(binary()) -> binary(). urlencode(Bin) -> urlencode(Bin, []). %% @doc URL encode a string binary. %% The `noplus' option disables the default behaviour of quoting space %% characters, `\s', as `+'. The `upper' option overrides the default behaviour %% of writing hex numbers using lowecase letters to using uppercase letters %% instead. -spec urlencode(binary(), [noplus|upper]) -> binary(). urlencode(Bin, Opts) -> Plus = not proplists:get_value(noplus, Opts, false), Upper = proplists:get_value(upper, Opts, false), urlencode(Bin, <<>>, Plus, Upper). urlencode(<>, Acc, P=Plus, U=Upper) -> if C >= $0, C =< $9 -> urlencode(Rest, <>, P, U); C >= $A, C =< $Z -> urlencode(Rest, <>, P, U); C >= $a, C =< $z -> urlencode(Rest, <>, P, U); C =:= $.; C =:= $-; C =:= $~; C =:= $_ -> urlencode(Rest, <>, P, U); C =:= $ , Plus -> urlencode(Rest, <>, P, U); true -> H = C band 16#F0 bsr 4, L = C band 16#0F, H1 = if Upper -> tohexu(H); true -> tohexl(H) end, L1 = if Upper -> tohexu(L); true -> tohexl(L) end, urlencode(Rest, <>, P, U) end; urlencode(<<>>, Acc, _Plus, _Upper) -> Acc. -spec tohexu(byte()) -> byte(). tohexu(C) when C < 10 -> $0 + C; tohexu(C) when C < 17 -> $A + C - 10. -spec tohexl(byte()) -> byte(). tohexl(C) when C < 10 -> $0 + C; tohexl(C) when C < 17 -> $a + C - 10. %% Tests. -ifdef(TEST). nonempty_charset_list_test_() -> %% {Value, Result} Tests = [ {<<>>, {error, badarg}}, {<<"iso-8859-5, unicode-1-1;q=0.8">>, [ {<<"iso-8859-5">>, 1000}, {<<"unicode-1-1">>, 800} ]} ], [{V, fun() -> R = nonempty_list(V, fun conneg/2) end} || {V, R} <- Tests]. nonempty_language_range_list_test_() -> %% {Value, Result} Tests = [ {<<"da, en-gb;q=0.8, en;q=0.7">>, [ {<<"da">>, 1000}, {<<"en-gb">>, 800}, {<<"en">>, 700} ]}, {<<"en, en-US, en-cockney, i-cherokee, x-pig-latin">>, [ {<<"en">>, 1000}, {<<"en-us">>, 1000}, {<<"en-cockney">>, 1000}, {<<"i-cherokee">>, 1000}, {<<"x-pig-latin">>, 1000} ]} ], [{V, fun() -> R = nonempty_list(V, fun language_range/2) end} || {V, R} <- Tests]. nonempty_token_list_test_() -> %% {Value, Result} Tests = [ {<<>>, {error, badarg}}, {<<" ">>, {error, badarg}}, {<<" , ">>, {error, badarg}}, {<<",,,">>, {error, badarg}}, {<<"a b">>, {error, badarg}}, {<<"a , , , ">>, [<<"a">>]}, {<<" , , , a">>, [<<"a">>]}, {<<"a, , b">>, [<<"a">>, <<"b">>]}, {<<"close">>, [<<"close">>]}, {<<"keep-alive, upgrade">>, [<<"keep-alive">>, <<"upgrade">>]} ], [{V, fun() -> R = nonempty_list(V, fun token/2) end} || {V, R} <- Tests]. media_range_list_test_() -> %% {Tokens, Result} Tests = [ {<<"audio/*; q=0.2, audio/basic">>, [ {{<<"audio">>, <<"*">>, []}, 200, []}, {{<<"audio">>, <<"basic">>, []}, 1000, []} ]}, {<<"text/plain; q=0.5, text/html, " "text/x-dvi; q=0.8, text/x-c">>, [ {{<<"text">>, <<"plain">>, []}, 500, []}, {{<<"text">>, <<"html">>, []}, 1000, []}, {{<<"text">>, <<"x-dvi">>, []}, 800, []}, {{<<"text">>, <<"x-c">>, []}, 1000, []} ]}, {<<"text/*, text/html, text/html;level=1, */*">>, [ {{<<"text">>, <<"*">>, []}, 1000, []}, {{<<"text">>, <<"html">>, []}, 1000, []}, {{<<"text">>, <<"html">>, [{<<"level">>, <<"1">>}]}, 1000, []}, {{<<"*">>, <<"*">>, []}, 1000, []} ]}, {<<"text/*;q=0.3, text/html;q=0.7, text/html;level=1, " "text/html;level=2;q=0.4, */*;q=0.5">>, [ {{<<"text">>, <<"*">>, []}, 300, []}, {{<<"text">>, <<"html">>, []}, 700, []}, {{<<"text">>, <<"html">>, [{<<"level">>, <<"1">>}]}, 1000, []}, {{<<"text">>, <<"html">>, [{<<"level">>, <<"2">>}]}, 400, []}, {{<<"*">>, <<"*">>, []}, 500, []} ]}, {<<"text/html;level=1;quoted=\"hi hi hi\";" "q=0.123;standalone;complex=gits, text/plain">>, [ {{<<"text">>, <<"html">>, [{<<"level">>, <<"1">>}, {<<"quoted">>, <<"hi hi hi">>}]}, 123, [<<"standalone">>, {<<"complex">>, <<"gits">>}]}, {{<<"text">>, <<"plain">>, []}, 1000, []} ]} ], [{V, fun() -> R = list(V, fun media_range/2) end} || {V, R} <- Tests]. entity_tag_match_test_() -> %% {Tokens, Result} Tests = [ {<<"\"xyzzy\"">>, [{strong, <<"xyzzy">>}]}, {<<"\"xyzzy\", W/\"r2d2xxxx\", \"c3piozzzz\"">>, [{strong, <<"xyzzy">>}, {weak, <<"r2d2xxxx">>}, {strong, <<"c3piozzzz">>}]}, {<<"*">>, '*'} ], [{V, fun() -> R = entity_tag_match(V) end} || {V, R} <- Tests]. http_date_test_() -> %% {Tokens, Result} Tests = [ {<<"Sun, 06 Nov 1994 08:49:37 GMT">>, {{1994, 11, 6}, {8, 49, 37}}}, {<<"Sunday, 06-Nov-94 08:49:37 GMT">>, {{1994, 11, 6}, {8, 49, 37}}}, {<<"Sun Nov 6 08:49:37 1994">>, {{1994, 11, 6}, {8, 49, 37}}} ], [{V, fun() -> R = http_date(V) end} || {V, R} <- Tests]. rfc1123_date_test_() -> %% {Tokens, Result} Tests = [ {<<"Sun, 06 Nov 1994 08:49:37 GMT">>, {{1994, 11, 6}, {8, 49, 37}}} ], [{V, fun() -> R = rfc1123_date(V) end} || {V, R} <- Tests]. rfc850_date_test_() -> %% {Tokens, Result} Tests = [ {<<"Sunday, 06-Nov-94 08:49:37 GMT">>, {{1994, 11, 6}, {8, 49, 37}}} ], [{V, fun() -> R = rfc850_date(V) end} || {V, R} <- Tests]. asctime_date_test_() -> %% {Tokens, Result} Tests = [ {<<"Sun Nov 6 08:49:37 1994">>, {{1994, 11, 6}, {8, 49, 37}}} ], [{V, fun() -> R = asctime_date(V) end} || {V, R} <- Tests]. connection_to_atom_test_() -> %% {Tokens, Result} Tests = [ {[<<"close">>], close}, {[<<"keep-alive">>], keepalive}, {[<<"keep-alive">>, <<"upgrade">>], keepalive} ], [{lists:flatten(io_lib:format("~p", [T])), fun() -> R = connection_to_atom(T) end} || {T, R} <- Tests]. content_type_test_() -> %% {ContentType, Result} Tests = [ {<<"text/plain; charset=iso-8859-4">>, {<<"text">>, <<"plain">>, [{<<"charset">>, <<"iso-8859-4">>}]}}, {<<"multipart/form-data \t;Boundary=\"MultipartIsUgly\"">>, {<<"multipart">>, <<"form-data">>, [ {<<"boundary">>, <<"MultipartIsUgly">>} ]}}, {<<"foo/bar; one=FirstParam; two=SecondParam">>, {<<"foo">>, <<"bar">>, [ {<<"one">>, <<"FirstParam">>}, {<<"two">>, <<"SecondParam">>} ]}} ], [{V, fun () -> R = content_type(V) end} || {V, R} <- Tests]. digits_test_() -> %% {Digits, Result} Tests = [ {<<"42 ">>, 42}, {<<"69\t">>, 69}, {<<"1337">>, 1337} ], [{V, fun() -> R = digits(V) end} || {V, R} <- Tests]. urldecode_test_() -> U = fun urldecode/2, [?_assertEqual(<<" ">>, U(<<"%20">>, crash)), ?_assertEqual(<<" ">>, U(<<"+">>, crash)), ?_assertEqual(<<0>>, U(<<"%00">>, crash)), ?_assertEqual(<<255>>, U(<<"%fF">>, crash)), ?_assertEqual(<<"123">>, U(<<"123">>, crash)), ?_assertEqual(<<"%i5">>, U(<<"%i5">>, skip)), ?_assertEqual(<<"%5">>, U(<<"%5">>, skip)), ?_assertError(badarg, U(<<"%i5">>, crash)), ?_assertError(badarg, U(<<"%5">>, crash)) ]. urlencode_test_() -> U = fun urlencode/2, [?_assertEqual(<<"%ff%00">>, U(<<255,0>>, [])), ?_assertEqual(<<"%FF%00">>, U(<<255,0>>, [upper])), ?_assertEqual(<<"+">>, U(<<" ">>, [])), ?_assertEqual(<<"%20">>, U(<<" ">>, [noplus])), ?_assertEqual(<<"aBc">>, U(<<"aBc">>, [])), ?_assertEqual(<<".-~_">>, U(<<".-~_">>, [])), ?_assertEqual(<<"%ff+">>, urlencode(<<255, " ">>)) ]. -endif. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/src/cowboy.erl0000644000177700017770000000777712633765070026604 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. %% @doc Cowboy API to start and stop listeners. -module(cowboy). -export([start_listener/6, stop_listener/1, child_spec/6, accept_ack/1]). %% @doc Start a listener for the given transport and protocol. %% %% A listener is effectively a pool of NbAcceptors acceptors. %% Acceptors accept connections on the given Transport and forward %% requests to the given Protocol handler. Both transport and protocol %% modules can be given options through the TransOpts and the %% ProtoOpts arguments. Available options are documented in the %% listen transport function and in the protocol module of your choice. %% %% All acceptor and request processes are supervised by the listener. %% %% It is recommended to set a large enough number of acceptors to improve %% performance. The exact number depends of course on your hardware, on the %% protocol used and on the number of expected simultaneous connections. %% %% The Transport option max_connections allows you to define %% the maximum number of simultaneous connections for this listener. It defaults %% to 1024. See cowboy_listener for more details on limiting the number %% of connections. %% %% Although Cowboy includes a cowboy_http_protocol handler, other %% handlers can be created for different protocols like IRC, FTP and more. %% %% Ref can be used to stop the listener later on. -spec start_listener(any(), non_neg_integer(), module(), any(), module(), any()) -> {ok, pid()}. start_listener(Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts) when is_integer(NbAcceptors) andalso is_atom(Transport) andalso is_atom(Protocol) -> supervisor:start_child(cowboy_sup, child_spec(Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts)). %% @doc Stop a listener identified by Ref. %% @todo Currently request processes aren't terminated with the listener. -spec stop_listener(any()) -> ok | {error, not_found}. stop_listener(Ref) -> case supervisor:terminate_child(cowboy_sup, {cowboy_listener_sup, Ref}) of ok -> supervisor:delete_child(cowboy_sup, {cowboy_listener_sup, Ref}); {error, Reason} -> {error, Reason} end. %% @doc Return a child spec suitable for embedding. %% %% When you want to embed cowboy in another application, you can use this %% function to create a ChildSpec suitable for use in a supervisor. %% The parameters are the same as in start_listener/6 but rather %% than hooking the listener to the cowboy internal supervisor, it just returns %% the spec. -spec child_spec(any(), non_neg_integer(), module(), any(), module(), any()) -> supervisor:child_spec(). child_spec(Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts) when is_integer(NbAcceptors) andalso is_atom(Transport) andalso is_atom(Protocol) -> {{cowboy_listener_sup, Ref}, {cowboy_listener_sup, start_link, [ NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts ]}, permanent, 5000, supervisor, [cowboy_listener_sup]}. %% @doc Acknowledge the accepted connection. %% %% Effectively used to make sure the socket control has been given to %% the protocol process before starting to use it. -spec accept_ack(pid()) -> ok. accept_ack(ListenerPid) -> receive {shoot, ListenerPid} -> ok end. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/doc/0000755000177700017770000000000012633765070024532 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/doc/overview.edoc0000644000177700017770000000017512633765070027237 0ustar michaelmichael@author Loïc Hoguin @copyright 2011 Loïc Hoguin @version HEAD @title Small, fast, modular HTTP server. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/0000755000177700017770000000000012633765070024744 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/http_handler_long_polling.erl0000644000177700017770000000106612633765070032672 0ustar michaelmichael%% Feel free to use, reuse and abuse the code in this file. -module(http_handler_long_polling). -behaviour(cowboy_http_handler). -export([init/3, handle/2, info/3, terminate/2]). init({_Transport, http}, Req, _Opts) -> erlang:send_after(500, self(), timeout), {loop, Req, 9, 5000, hibernate}. handle(_Req, _State) -> exit(badarg). info(timeout, Req, 0) -> {ok, Req2} = cowboy_http_req:reply(102, Req), {ok, Req2, 0}; info(timeout, Req, State) -> erlang:send_after(500, self(), timeout), {loop, Req, State - 1, hibernate}. terminate(_Req, _State) -> ok. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/http_handler_set_resp.erl0000644000177700017770000000203412633765070032027 0ustar michaelmichael%% Feel free to use, reuse and abuse the code in this file. -module(http_handler_set_resp). -behaviour(cowboy_http_handler). -export([init/3, handle/2, terminate/2]). init({_Transport, http}, Req, Opts) -> Headers = proplists:get_value(headers, Opts, []), Body = proplists:get_value(body, Opts, <<"http_handler_set_resp">>), {ok, Req2} = lists:foldl(fun({Name, Value}, {ok, R}) -> cowboy_http_req:set_resp_header(Name, Value, R) end, {ok, Req}, Headers), {ok, Req3} = cowboy_http_req:set_resp_body(Body, Req2), {ok, Req4} = cowboy_http_req:set_resp_header( <<"X-Cowboy-Test">>, <<"ok">>, Req3), {ok, Req5} = cowboy_http_req:set_resp_cookie( <<"cake">>, <<"lie">>, [], Req4), {ok, Req5, undefined}. handle(Req, State) -> case cowboy_http_req:has_resp_header(<<"X-Cowboy-Test">>, Req) of false -> {ok, Req, State}; true -> case cowboy_http_req:has_resp_body(Req) of false -> {ok, Req, State}; true -> {ok, Req2} = cowboy_http_req:reply(200, Req), {ok, Req2, State} end end. terminate(_Req, _State) -> ok. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/proper_SUITE.erl0000644000177700017770000000243712633765070027736 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -module(proper_SUITE). -include_lib("common_test/include/ct.hrl"). -export([all/0, groups/0]). %% ct. -export([dispatcher_split_host/1]). %% cowboy_dispatcher. %% ct. all() -> [{group, dispatcher}]. groups() -> [{dispatcher, [], [dispatcher_split_host]}]. %% cowboy_dispatcher. dispatcher_split_host(_Config) -> true = proper:quickcheck(dispatcher_prop:prop_split_host_symmetric(), [{on_output, fun(Format, Data) -> io:format(user, Format, Data), %% Console. io:format(Format, Data) %% Logs. end}]). rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/ws_timeout_hibernate_handler.erl0000644000177700017770000000134712633765070033372 0ustar michaelmichael%% Feel free to use, reuse and abuse the code in this file. -module(ws_timeout_hibernate_handler). -behaviour(cowboy_http_handler). -behaviour(cowboy_http_websocket_handler). -export([init/3, handle/2, terminate/2]). -export([websocket_init/3, websocket_handle/3, websocket_info/3, websocket_terminate/3]). init(_Any, _Req, _Opts) -> {upgrade, protocol, cowboy_http_websocket}. handle(_Req, _State) -> exit(badarg). terminate(_Req, _State) -> exit(badarg). websocket_init(_TransportName, Req, _Opts) -> {ok, Req, undefined, 1000, hibernate}. websocket_handle(_Frame, Req, State) -> {ok, Req, State, hibernate}. websocket_info(_Info, Req, State) -> {ok, Req, State, hibernate}. websocket_terminate(_Reason, _Req, _State) -> ok. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/http_SUITE.erl0000644000177700017770000005342312633765070027407 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% Copyright (c) 2011, Anthony Ramine %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -module(http_SUITE). -include_lib("common_test/include/ct.hrl"). -export([all/0, groups/0, init_per_suite/1, end_per_suite/1, init_per_group/2, end_per_group/2]). %% ct. -export([chunked_response/1, headers_dupe/1, headers_huge/1, keepalive_nl/1, max_keepalive/1, nc_rand/1, nc_zero/1, pipeline/1, raw/1, set_resp_header/1, set_resp_overwrite/1, set_resp_body/1, stream_body_set_resp/1, response_as_req/1, static_mimetypes_function/1, static_attribute_etag/1, static_function_etag/1, multipart/1]). %% http. -export([http_200/1, http_404/1, handler_errors/1, file_200/1, file_403/1, dir_403/1, file_404/1, file_400/1]). %% http and https. -export([http_10_hostless/1]). %% misc. -export([rest_simple/1, rest_keepalive/1, rest_keepalive_post/1]). %% rest. %% ct. all() -> [{group, http}, {group, https}, {group, misc}, {group, rest}]. groups() -> BaseTests = [http_200, http_404, handler_errors, file_200, file_403, dir_403, file_404, file_400], [{http, [], [chunked_response, headers_dupe, headers_huge, keepalive_nl, max_keepalive, nc_rand, nc_zero, pipeline, raw, set_resp_header, set_resp_overwrite, set_resp_body, response_as_req, stream_body_set_resp, static_mimetypes_function, static_attribute_etag, static_function_etag, multipart] ++ BaseTests}, {https, [], BaseTests}, {misc, [], [http_10_hostless]}, {rest, [], [rest_simple, rest_keepalive, rest_keepalive_post]}]. init_per_suite(Config) -> application:start(inets), application:start(cowboy), Config. end_per_suite(_Config) -> application:stop(cowboy), application:stop(inets), ok. init_per_group(http, Config) -> Port = 33080, Config1 = init_static_dir(Config), cowboy:start_listener(http, 100, cowboy_tcp_transport, [{port, Port}], cowboy_http_protocol, [{max_keepalive, 50}, {dispatch, init_http_dispatch(Config1)}] ), [{scheme, "http"}, {port, Port}|Config1]; init_per_group(https, Config) -> Port = 33081, Config1 = init_static_dir(Config), application:start(crypto), application:start(public_key), application:start(ssl), DataDir = ?config(data_dir, Config), cowboy:start_listener(https, 100, cowboy_ssl_transport, [ {port, Port}, {certfile, DataDir ++ "cert.pem"}, {keyfile, DataDir ++ "key.pem"}, {password, "cowboy"}], cowboy_http_protocol, [{dispatch, init_https_dispatch(Config1)}] ), [{scheme, "https"}, {port, Port}|Config1]; init_per_group(misc, Config) -> Port = 33082, cowboy:start_listener(misc, 100, cowboy_tcp_transport, [{port, Port}], cowboy_http_protocol, [{dispatch, [{'_', [ {[], http_handler, []} ]}]}]), [{port, Port}|Config]; init_per_group(rest, Config) -> Port = 33083, cowboy:start_listener(reset, 100, cowboy_tcp_transport, [{port, Port}], cowboy_http_protocol, [{dispatch, [{'_', [ {[<<"simple">>], rest_simple_resource, []}, {[<<"forbidden_post">>], rest_forbidden_resource, [true]}, {[<<"simple_post">>], rest_forbidden_resource, [false]} ]}]}]), [{port, Port}|Config]. end_per_group(https, Config) -> cowboy:stop_listener(https), application:stop(ssl), application:stop(public_key), application:stop(crypto), end_static_dir(Config), ok; end_per_group(http, Config) -> cowboy:stop_listener(http), end_static_dir(Config); end_per_group(Listener, _Config) -> cowboy:stop_listener(Listener), ok. %% Dispatch configuration. init_http_dispatch(Config) -> [ {[<<"localhost">>], [ {[<<"chunked_response">>], chunked_handler, []}, {[<<"init_shutdown">>], http_handler_init_shutdown, []}, {[<<"long_polling">>], http_handler_long_polling, []}, {[<<"headers">>, <<"dupe">>], http_handler, [{headers, [{<<"Connection">>, <<"close">>}]}]}, {[<<"set_resp">>, <<"header">>], http_handler_set_resp, [{headers, [{<<"Vary">>, <<"Accept">>}]}]}, {[<<"set_resp">>, <<"overwrite">>], http_handler_set_resp, [{headers, [{<<"Server">>, <<"DesireDrive/1.0">>}]}]}, {[<<"set_resp">>, <<"body">>], http_handler_set_resp, [{body, <<"A flameless dance does not equal a cycle">>}]}, {[<<"stream_body">>, <<"set_resp">>], http_handler_stream_body, [{reply, set_resp}, {body, <<"stream_body_set_resp">>}]}, {[<<"static">>, '...'], cowboy_http_static, [{directory, ?config(static_dir, Config)}, {mimetypes, [{<<".css">>, [<<"text/css">>]}]}]}, {[<<"static_mimetypes_function">>, '...'], cowboy_http_static, [{directory, ?config(static_dir, Config)}, {mimetypes, {fun(Path, data) when is_binary(Path) -> [<<"text/html">>] end, data}}]}, {[<<"handler_errors">>], http_handler_errors, []}, {[<<"static_attribute_etag">>, '...'], cowboy_http_static, [{directory, ?config(static_dir, Config)}, {etag, {attributes, [filepath, filesize, inode, mtime]}}]}, {[<<"static_function_etag">>, '...'], cowboy_http_static, [{directory, ?config(static_dir, Config)}, {etag, {fun static_function_etag/2, etag_data}}]}, {[<<"multipart">>], http_handler_multipart, []}, {[], http_handler, []} ]} ]. init_https_dispatch(Config) -> init_http_dispatch(Config). init_static_dir(Config) -> Dir = filename:join(?config(priv_dir, Config), "static"), Level1 = fun(Name) -> filename:join(Dir, Name) end, ok = file:make_dir(Dir), ok = file:write_file(Level1("test_file"), "test_file\n"), ok = file:write_file(Level1("test_file.css"), "test_file.css\n"), ok = file:write_file(Level1("test_noread"), "test_noread\n"), ok = file:change_mode(Level1("test_noread"), 8#0333), ok = file:write_file(Level1("test.html"), "test.html\n"), ok = file:make_dir(Level1("test_dir")), [{static_dir, Dir}|Config]. end_static_dir(Config) -> Dir = ?config(static_dir, Config), Level1 = fun(Name) -> filename:join(Dir, Name) end, ok = file:delete(Level1("test_file")), ok = file:delete(Level1("test_file.css")), ok = file:delete(Level1("test_noread")), ok = file:delete(Level1("test.html")), ok = file:del_dir(Level1("test_dir")), ok = file:del_dir(Dir), Config. %% http. chunked_response(Config) -> {ok, {{"HTTP/1.1", 200, "OK"}, _Headers, "chunked_handler\r\nworks fine!"}} = httpc:request(build_url("/chunked_response", Config)). headers_dupe(Config) -> {port, Port} = lists:keyfind(port, 1, Config), {ok, Socket} = gen_tcp:connect("localhost", Port, [binary, {active, false}, {packet, raw}]), ok = gen_tcp:send(Socket, "GET /headers/dupe HTTP/1.1\r\n" "Host: localhost\r\nConnection: keep-alive\r\n\r\n"), {ok, Data} = gen_tcp:recv(Socket, 0, 6000), {_Start, _Length} = binary:match(Data, <<"Connection: close">>), nomatch = binary:match(Data, <<"Connection: keep-alive">>), {error, closed} = gen_tcp:recv(Socket, 0, 1000). headers_huge(Config) -> Cookie = lists:flatten(["whatever_man_biiiiiiiiiiiig_cookie_me_want_77=" "Wed Apr 06 2011 10:38:52 GMT-0500 (CDT)" || _N <- lists:seq(1, 40)]), {_Packet, 200} = raw_req(["GET / HTTP/1.0\r\nHost: localhost\r\n" "Set-Cookie: ", Cookie, "\r\n\r\n"], Config). keepalive_nl(Config) -> {port, Port} = lists:keyfind(port, 1, Config), {ok, Socket} = gen_tcp:connect("localhost", Port, [binary, {active, false}, {packet, raw}]), ok = keepalive_nl_loop(Socket, 10), ok = gen_tcp:close(Socket). keepalive_nl_loop(_Socket, 0) -> ok; keepalive_nl_loop(Socket, N) -> ok = gen_tcp:send(Socket, "GET / HTTP/1.1\r\n" "Host: localhost\r\nConnection: keep-alive\r\n\r\n"), {ok, Data} = gen_tcp:recv(Socket, 0, 6000), {0, 12} = binary:match(Data, <<"HTTP/1.1 200">>), nomatch = binary:match(Data, <<"Connection: close">>), ok = gen_tcp:send(Socket, "\r\n"), %% extra nl keepalive_nl_loop(Socket, N - 1). max_keepalive(Config) -> {port, Port} = lists:keyfind(port, 1, Config), {ok, Socket} = gen_tcp:connect("localhost", Port, [binary, {active, false}, {packet, raw}]), ok = max_keepalive_loop(Socket, 50), {error, closed} = gen_tcp:recv(Socket, 0, 1000). max_keepalive_loop(_Socket, 0) -> ok; max_keepalive_loop(Socket, N) -> ok = gen_tcp:send(Socket, "GET / HTTP/1.1\r\n" "Host: localhost\r\nConnection: keep-alive\r\n\r\n"), {ok, Data} = gen_tcp:recv(Socket, 0, 6000), {0, 12} = binary:match(Data, <<"HTTP/1.1 200">>), case N of 1 -> {_, _} = binary:match(Data, <<"Connection: close">>); N -> nomatch = binary:match(Data, <<"Connection: close">>) end, keepalive_nl_loop(Socket, N - 1). multipart(Config) -> Url = build_url("/multipart", Config), Body = << "This is a preamble." "\r\n--OHai\r\nX-Name:answer\r\n\r\n42" "\r\n--OHai\r\nServer:Cowboy\r\n\r\nIt rocks!\r\n" "\r\n--OHai--" "This is an epiloque." >>, Request = {Url, [], "multipart/x-makes-no-sense; boundary=OHai", Body}, {ok, {{"HTTP/1.1", 200, "OK"}, _Headers, Response}} = httpc:request(post, Request, [], [{body_format, binary}]), Parts = binary_to_term(Response), Parts = [ {[{<<"X-Name">>, <<"answer">>}], <<"42">>}, {[{'Server', <<"Cowboy">>}], <<"It rocks!\r\n">>} ]. nc_rand(Config) -> nc_reqs(Config, "/dev/urandom"). nc_zero(Config) -> nc_reqs(Config, "/dev/zero"). nc_reqs(Config, Input) -> Cat = os:find_executable("cat"), Nc = os:find_executable("nc"), case {Cat, Nc} of {false, _} -> {skip, {notfound, cat}}; {_, false} -> {skip, {notfound, nc}}; _Good -> %% Throw garbage at the server then check if it's still up. {port, Port} = lists:keyfind(port, 1, Config), [nc_run_req(Port, Input) || _N <- lists:seq(1, 100)], Packet = "GET / HTTP/1.0\r\nHost: localhost\r\n\r\n", {Packet, 200} = raw_req(Packet, Config) end. nc_run_req(Port, Input) -> os:cmd("cat " ++ Input ++ " | nc localhost " ++ integer_to_list(Port)). pipeline(Config) -> {port, Port} = lists:keyfind(port, 1, Config), {ok, Socket} = gen_tcp:connect("localhost", Port, [binary, {active, false}, {packet, raw}]), ok = gen_tcp:send(Socket, "GET / HTTP/1.1\r\nHost: localhost\r\nConnection: keep-alive\r\n\r\n" "GET / HTTP/1.1\r\nHost: localhost\r\nConnection: keep-alive\r\n\r\n" "GET / HTTP/1.1\r\nHost: localhost\r\nConnection: keep-alive\r\n\r\n" "GET / HTTP/1.1\r\nHost: localhost\r\nConnection: keep-alive\r\n\r\n" "GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"), Data = pipeline_recv(Socket, <<>>), Reqs = binary:split(Data, << "\r\n\r\nhttp_handler" >>, [global, trim]), 5 = length(Reqs), pipeline_check(Reqs). pipeline_check([]) -> ok; pipeline_check([Req|Tail]) -> << "HTTP/1.1 200", _Rest/bits >> = Req, pipeline_check(Tail). pipeline_recv(Socket, SoFar) -> case gen_tcp:recv(Socket, 0, 6000) of {ok, Data} -> pipeline_recv(Socket, << SoFar/binary, Data/binary >>); {error, closed} -> ok = gen_tcp:close(Socket), SoFar end. raw_req(Packet, Config) -> {port, Port} = lists:keyfind(port, 1, Config), {ok, Socket} = gen_tcp:connect("localhost", Port, [binary, {active, false}, {packet, raw}]), ok = gen_tcp:send(Socket, Packet), Res = case gen_tcp:recv(Socket, 0, 6000) of {ok, << "HTTP/1.1 ", Str:24/bits, _Rest/bits >>} -> list_to_integer(binary_to_list(Str)); {error, Reason} -> Reason end, gen_tcp:close(Socket), {Packet, Res}. %% Send a raw request. Return the response code and the full response. raw_resp(Request, Config) -> {port, Port} = lists:keyfind(port, 1, Config), Transport = case ?config(scheme, Config) of "http" -> gen_tcp; "https" -> ssl end, {ok, Socket} = Transport:connect("localhost", Port, [binary, {active, false}, {packet, raw}]), ok = Transport:send(Socket, Request), {StatusCode, Response} = case recv_loop(Transport, Socket, <<>>) of {ok, << "HTTP/1.1 ", Str:24/bits, _Rest/bits >> = Bin} -> {list_to_integer(binary_to_list(Str)), Bin}; {ok, Bin} -> {badresp, Bin}; {error, Reason} -> {Reason, <<>>} end, Transport:close(Socket), {Response, StatusCode}. recv_loop(Transport, Socket, Acc) -> case Transport:recv(Socket, 0, 6000) of {ok, Data} -> recv_loop(Transport, Socket, <>); {error, closed} -> ok = Transport:close(Socket), {ok, Acc}; {error, Reason} -> {error, Reason} end. raw(Config) -> Huge = [$0 || _N <- lists:seq(1, 5000)], Tests = [ {"\r\n\r\n\r\n\r\n\r\nGET / HTTP/1.1\r\nHost: localhost\r\n\r\n", 200}, {"\n", 400}, {"Garbage\r\n\r\n", 400}, {"\r\n\r\n\r\n\r\n\r\n\r\n", 400}, {"GET / HTTP/1.1\r\nHost: dev-extend.eu\r\n\r\n", 400}, {"", closed}, {"\r\n", closed}, {"\r\n\r\n", closed}, {"GET / HTTP/1.1", closed}, {"GET / HTTP/1.1\r\n", 408}, {"GET / HTTP/1.1\r\nHost: localhost", 408}, {"GET / HTTP/1.1\r\nHost: localhost\r\n", 408}, {"GET / HTTP/1.1\r\nHost: localhost\r\n\r", 408}, {"GET http://localhost/ HTTP/1.1\r\n\r\n", 501}, {"GET / HTTP/1.2\r\nHost: localhost\r\n\r\n", 505}, {"GET /init_shutdown HTTP/1.1\r\nHost: localhost\r\n\r\n", 666}, {"GET /long_polling HTTP/1.1\r\nHost: localhost\r\n\r\n", 102}, {Huge, 413}, {"GET / HTTP/1.1\r\n" ++ Huge, 413} ], [{Packet, StatusCode} = raw_req(Packet, Config) || {Packet, StatusCode} <- Tests]. set_resp_header(Config) -> {port, Port} = lists:keyfind(port, 1, Config), {ok, Socket} = gen_tcp:connect("localhost", Port, [binary, {active, false}, {packet, raw}]), ok = gen_tcp:send(Socket, "GET /set_resp/header HTTP/1.1\r\n" "Host: localhost\r\nConnection: close\r\n\r\n"), {ok, Data} = gen_tcp:recv(Socket, 0, 6000), {_, _} = binary:match(Data, <<"Vary: Accept">>), {_, _} = binary:match(Data, <<"Set-Cookie: ">>). set_resp_overwrite(Config) -> {port, Port} = lists:keyfind(port, 1, Config), {ok, Socket} = gen_tcp:connect("localhost", Port, [binary, {active, false}, {packet, raw}]), ok = gen_tcp:send(Socket, "GET /set_resp/overwrite HTTP/1.1\r\n" "Host: localhost\r\nConnection: close\r\n\r\n"), {ok, Data} = gen_tcp:recv(Socket, 0, 6000), {_Start, _Length} = binary:match(Data, <<"Server: DesireDrive/1.0">>). set_resp_body(Config) -> {port, Port} = lists:keyfind(port, 1, Config), {ok, Socket} = gen_tcp:connect("localhost", Port, [binary, {active, false}, {packet, raw}]), ok = gen_tcp:send(Socket, "GET /set_resp/body HTTP/1.1\r\n" "Host: localhost\r\nConnection: close\r\n\r\n"), {ok, Data} = gen_tcp:recv(Socket, 0, 6000), {_Start, _Length} = binary:match(Data, <<"\r\n\r\n" "A flameless dance does not equal a cycle">>). response_as_req(Config) -> Packet = "HTTP/1.0 302 Found Location: http://www.google.co.il/ Cache-Control: private Content-Type: text/html; charset=UTF-8 Set-Cookie: PREF=ID=568f67013d4a7afa:FF=0:TM=1323014101:LM=1323014101:S=XqctDWC65MzKT0zC; expires=Tue, 03-Dec-2013 15:55:01 GMT; path=/; domain=.google.com Date: Sun, 04 Dec 2011 15:55:01 GMT Server: gws Content-Length: 221 X-XSS-Protection: 1; mode=block X-Frame-Options: SAMEORIGIN 302 Moved

    302 Moved

    The document has moved here. ", {Packet, 400} = raw_req(Packet, Config). stream_body_set_resp(Config) -> {Packet, 200} = raw_resp( "GET /stream_body/set_resp HTTP/1.1\r\n" "Host: localhost\r\nConnection: close\r\n\r\n", Config), {_Start, _Length} = binary:match(Packet, <<"stream_body_set_resp">>). static_mimetypes_function(Config) -> TestURL = build_url("/static_mimetypes_function/test.html", Config), {ok, {{"HTTP/1.1", 200, "OK"}, Headers1, "test.html\n"}} = httpc:request(TestURL), "text/html" = ?config("content-type", Headers1). handler_errors(Config) -> Request = fun(Case) -> raw_resp(["GET /handler_errors?case=", Case, " HTTP/1.1\r\n", "Host: localhost\r\n\r\n"], Config) end, {_Packet1, 500} = Request("init_before_reply"), {Packet2, 200} = Request("init_after_reply"), nomatch = binary:match(Packet2, <<"HTTP/1.1 500">>), {Packet3, 200} = Request("init_reply_handle_error"), nomatch = binary:match(Packet3, <<"HTTP/1.1 500">>), {_Packet4, 500} = Request("handle_before_reply"), {Packet5, 200} = Request("handle_after_reply"), nomatch = binary:match(Packet5, <<"HTTP/1.1 500">>), {Packet6, 200} = raw_resp([ "GET / HTTP/1.1\r\n", "Host: localhost\r\n", "Connection: keep-alive\r\n\r\n", "GET /handler_errors?case=handle_after_reply\r\n", "Host: localhost\r\n\r\n"], Config), nomatch = binary:match(Packet6, <<"HTTP/1.1 500">>), {Packet7, 200} = raw_resp([ "GET / HTTP/1.1\r\n", "Host: localhost\r\n", "Connection: keep-alive\r\n\r\n", "GET /handler_errors?case=handle_before_reply HTTP/1.1\r\n", "Host: localhost\r\n\r\n"], Config), {{_, _}, _} = {binary:match(Packet7, <<"HTTP/1.1 500">>), Packet7}, done. static_attribute_etag(Config) -> TestURL = build_url("/static_attribute_etag/test.html", Config), {ok, {{"HTTP/1.1", 200, "OK"}, Headers1, "test.html\n"}} = httpc:request(TestURL), false = ?config("etag", Headers1) =:= undefined, {ok, {{"HTTP/1.1", 200, "OK"}, Headers2, "test.html\n"}} = httpc:request(TestURL), true = ?config("etag", Headers1) =:= ?config("etag", Headers2). static_function_etag(Config) -> TestURL = build_url("/static_function_etag/test.html", Config), {ok, {{"HTTP/1.1", 200, "OK"}, Headers1, "test.html\n"}} = httpc:request(TestURL), false = ?config("etag", Headers1) =:= undefined, {ok, {{"HTTP/1.1", 200, "OK"}, Headers2, "test.html\n"}} = httpc:request(TestURL), true = ?config("etag", Headers1) =:= ?config("etag", Headers2). static_function_etag(Arguments, etag_data) -> {_, Filepath} = lists:keyfind(filepath, 1, Arguments), {_, _Filesize} = lists:keyfind(filesize, 1, Arguments), {_, _INode} = lists:keyfind(inode, 1, Arguments), {_, _Modified} = lists:keyfind(mtime, 1, Arguments), ChecksumCommand = lists:flatten(io_lib:format("sha1sum ~s", [Filepath])), [Checksum|_] = string:tokens(os:cmd(ChecksumCommand), " "), iolist_to_binary(Checksum). %% http and https. build_url(Path, Config) -> {scheme, Scheme} = lists:keyfind(scheme, 1, Config), {port, Port} = lists:keyfind(port, 1, Config), Scheme ++ "://localhost:" ++ integer_to_list(Port) ++ Path. http_200(Config) -> {ok, {{"HTTP/1.1", 200, "OK"}, _Headers, "http_handler"}} = httpc:request(build_url("/", Config)). http_404(Config) -> {ok, {{"HTTP/1.1", 404, "Not Found"}, _Headers, _Body}} = httpc:request(build_url("/not/found", Config)). file_200(Config) -> {ok, {{"HTTP/1.1", 200, "OK"}, Headers, "test_file\n"}} = httpc:request(build_url("/static/test_file", Config)), "application/octet-stream" = ?config("content-type", Headers), {ok, {{"HTTP/1.1", 200, "OK"}, Headers1, "test_file.css\n"}} = httpc:request(build_url("/static/test_file.css", Config)), "text/css" = ?config("content-type", Headers1). file_403(Config) -> {ok, {{"HTTP/1.1", 403, "Forbidden"}, _Headers, _Body}} = httpc:request(build_url("/static/test_noread", Config)). dir_403(Config) -> {ok, {{"HTTP/1.1", 403, "Forbidden"}, _Headers, _Body}} = httpc:request(build_url("/static/test_dir", Config)), {ok, {{"HTTP/1.1", 403, "Forbidden"}, _Headers, _Body}} = httpc:request(build_url("/static/test_dir/", Config)). file_404(Config) -> {ok, {{"HTTP/1.1", 404, "Not Found"}, _Headers, _Body}} = httpc:request(build_url("/static/not_found", Config)). file_400(Config) -> {ok, {{"HTTP/1.1", 400, "Bad Request"}, _Headers, _Body}} = httpc:request(build_url("/static/%2f", Config)), {ok, {{"HTTP/1.1", 400, "Bad Request"}, _Headers1, _Body1}} = httpc:request(build_url("/static/%2e", Config)), {ok, {{"HTTP/1.1", 400, "Bad Request"}, _Headers2, _Body2}} = httpc:request(build_url("/static/%2e%2e", Config)). %% misc. http_10_hostless(Config) -> Packet = "GET / HTTP/1.0\r\n\r\n", {Packet, 200} = raw_req(Packet, Config). %% rest. rest_simple(Config) -> Packet = "GET /simple HTTP/1.1\r\nHost: localhost\r\n\r\n", {Packet, 200} = raw_req(Packet, Config). rest_keepalive(Config) -> {port, Port} = lists:keyfind(port, 1, Config), {ok, Socket} = gen_tcp:connect("localhost", Port, [binary, {active, false}, {packet, raw}]), ok = rest_keepalive_loop(Socket, 100), ok = gen_tcp:close(Socket). rest_keepalive_loop(_Socket, 0) -> ok; rest_keepalive_loop(Socket, N) -> ok = gen_tcp:send(Socket, "GET /simple HTTP/1.1\r\n" "Host: localhost\r\nConnection: keep-alive\r\n\r\n"), {ok, Data} = gen_tcp:recv(Socket, 0, 6000), {0, 12} = binary:match(Data, <<"HTTP/1.1 200">>), nomatch = binary:match(Data, <<"Connection: close">>), rest_keepalive_loop(Socket, N - 1). rest_keepalive_post(Config) -> {port, Port} = lists:keyfind(port, 1, Config), {ok, Socket} = gen_tcp:connect("localhost", Port, [binary, {active, false}, {packet, raw}]), ok = rest_keepalive_post_loop(Socket, 10, forbidden_post), ok = gen_tcp:close(Socket). rest_keepalive_post_loop(_Socket, 0, _) -> ok; rest_keepalive_post_loop(Socket, N, simple_post) -> ok = gen_tcp:send(Socket, "POST /simple_post HTTP/1.1\r\n" "Host: localhost\r\nConnection: keep-alive\r\n" "Content-Length: 5\r\nContent-Type: text/plain\r\n\r\n12345"), {ok, Data} = gen_tcp:recv(Socket, 0, 6000), {0, 12} = binary:match(Data, <<"HTTP/1.1 303">>), nomatch = binary:match(Data, <<"Connection: close">>), rest_keepalive_post_loop(Socket, N - 1, forbidden_post); rest_keepalive_post_loop(Socket, N, forbidden_post) -> ok = gen_tcp:send(Socket, "POST /forbidden_post HTTP/1.1\r\n" "Host: localhost\r\nConnection: keep-alive\r\n" "Content-Length: 5\r\nContent-Type: text/plain\r\n\r\n12345"), {ok, Data} = gen_tcp:recv(Socket, 0, 6000), {0, 12} = binary:match(Data, <<"HTTP/1.1 403">>), nomatch = binary:match(Data, <<"Connection: close">>), rest_keepalive_post_loop(Socket, N - 1, simple_post). rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/dispatcher_prop.erl0000644000177700017770000000434012633765070030637 0ustar michaelmichael%% Copyright (c) 2011, Magnus Klaar %% Copyright (c) 2011, Loïc Hoguin %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -module(dispatcher_prop). -include_lib("proper/include/proper.hrl"). %% Generators. hostname_head_char() -> oneof([choose($a, $z), choose($A, $Z), choose($0, $9)]). hostname_char() -> oneof([choose($a, $z), choose($A, $Z), choose($0, $9), $-]). hostname_label() -> ?SUCHTHAT(Label, [hostname_head_char()|list(hostname_char())], length(Label) < 64). hostname() -> ?SUCHTHAT(Hostname, ?LET(Labels, list(hostname_label()), string:join(Labels, ".")), length(Hostname) > 0 andalso length(Hostname) =< 255). port_number() -> choose(1, 16#ffff). port_str() -> oneof(["", ?LET(Port, port_number(), ":" ++ integer_to_list(Port))]). server() -> ?LET({Hostname, PortStr}, {hostname(), port_str()}, list_to_binary(Hostname ++ PortStr)). %% Properties. prop_split_host_symmetric() -> ?FORALL(Server, server(), begin case cowboy_dispatcher:split_host(Server) of {Tokens, RawHost, undefined} -> (Server == RawHost) and (Server == binary_join(Tokens, ".")); {Tokens, RawHost, Port} -> PortBin = (list_to_binary(":" ++ integer_to_list(Port))), (Server == << RawHost/binary, PortBin/binary >>) and (Server == << (binary_join(Tokens, "."))/binary, PortBin/binary >>) end end). %% Internal. %% Contributed by MononcQc on #erlounge. binary_join(Flowers, Leaf) -> case Flowers of [] -> <<>>; [Petal|Pot] -> iolist_to_binary( [Petal | [[Leaf | Pollen] || Pollen <- Pot]]) end. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/websocket_handler.erl0000644000177700017770000000211712633765070031134 0ustar michaelmichael%% Feel free to use, reuse and abuse the code in this file. -module(websocket_handler). -behaviour(cowboy_http_handler). -behaviour(cowboy_http_websocket_handler). -export([init/3, handle/2, terminate/2]). -export([websocket_init/3, websocket_handle/3, websocket_info/3, websocket_terminate/3]). init(_Any, _Req, _Opts) -> {upgrade, protocol, cowboy_http_websocket}. handle(_Req, _State) -> exit(badarg). terminate(_Req, _State) -> exit(badarg). websocket_init(_TransportName, Req, _Opts) -> erlang:start_timer(1000, self(), <<"websocket_init">>), Req2 = cowboy_http_req:compact(Req), {ok, Req2, undefined}. websocket_handle({text, Data}, Req, State) -> {reply, {text, Data}, Req, State}; websocket_handle({binary, Data}, Req, State) -> {reply, {binary, Data}, Req, State}; websocket_handle(_Frame, Req, State) -> {ok, Req, State}. websocket_info({timeout, _Ref, Msg}, Req, State) -> erlang:start_timer(1000, self(), <<"websocket_handle">>), {reply, {text, Msg}, Req, State}; websocket_info(_Info, Req, State) -> {ok, Req, State}. websocket_terminate(_Reason, _Req, _State) -> ok. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/rest_simple_resource.erl0000644000177700017770000000052512633765070031707 0ustar michaelmichael-module(rest_simple_resource). -export([init/3, content_types_provided/2, get_text_plain/2]). init(_Transport, _Req, _Opts) -> {upgrade, protocol, cowboy_http_rest}. content_types_provided(Req, State) -> {[{{<<"text">>, <<"plain">>, []}, get_text_plain}], Req, State}. get_text_plain(Req, State) -> {<<"This is REST!">>, Req, State}. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/rest_forbidden_resource.erl0000644000177700017770000000171612633765070032355 0ustar michaelmichael-module(rest_forbidden_resource). -export([init/3, rest_init/2, allowed_methods/2, forbidden/2, content_types_provided/2, content_types_accepted/2, post_is_create/2, create_path/2, to_text/2, from_text/2]). init(_Transport, _Req, _Opts) -> {upgrade, protocol, cowboy_http_rest}. rest_init(Req, [Forbidden]) -> {ok, Req, Forbidden}. allowed_methods(Req, State) -> {['GET', 'HEAD', 'POST'], Req, State}. forbidden(Req, State=true) -> {true, Req, State}; forbidden(Req, State=false) -> {false, Req, State}. content_types_provided(Req, State) -> {[{{<<"text">>, <<"plain">>, []}, to_text}], Req, State}. content_types_accepted(Req, State) -> {[{{<<"text">>, <<"plain">>, []}, from_text}], Req, State}. post_is_create(Req, State) -> {true, Req, State}. create_path(Req, State) -> {Path, Req2} = cowboy_http_req:raw_path(Req), {Path, Req2, State}. to_text(Req, State) -> {<<"This is REST!">>, Req, State}. from_text(Req, State) -> {true, Req, State}. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/http_handler_errors.erl0000644000177700017770000000221712633765070031522 0ustar michaelmichael%% Feel free to use, reuse and abuse the code in this file. -module(http_handler_errors). -behaviour(cowboy_http_handler). -export([init/3, handle/2, terminate/2]). init({_Transport, http}, Req, _Opts) -> {Case, Req1} = cowboy_http_req:qs_val(<<"case">>, Req), case_init(Case, Req1). case_init(<<"init_before_reply">> = Case, _Req) -> erlang:error(Case); case_init(<<"init_after_reply">> = Case, Req) -> {ok, _Req1} = cowboy_http_req:reply(200, [], "http_handler_crashes", Req), erlang:error(Case); case_init(<<"init_reply_handle_error">> = Case, Req) -> {ok, Req1} = cowboy_http_req:reply(200, [], "http_handler_crashes", Req), {ok, Req1, Case}; case_init(<<"handle_before_reply">> = Case, Req) -> {ok, Req, Case}; case_init(<<"handle_after_reply">> = Case, Req) -> {ok, Req, Case}. handle(_Req, <<"init_reply_handle_error">> = Case) -> erlang:error(Case); handle(_Req, <<"handle_before_reply">> = Case) -> erlang:error(Case); handle(Req, <<"handle_after_reply">> = Case) -> {ok, _Req1} = cowboy_http_req:reply(200, [], "http_handler_crashes", Req), erlang:error(Case). terminate(_Req, _State) -> ok. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/http_handler.erl0000644000177700017770000000106212633765070030123 0ustar michaelmichael%% Feel free to use, reuse and abuse the code in this file. -module(http_handler). -behaviour(cowboy_http_handler). -export([init/3, handle/2, terminate/2]). -record(state, {headers, body}). init({_Transport, http}, Req, Opts) -> Headers = proplists:get_value(headers, Opts, []), Body = proplists:get_value(body, Opts, "http_handler"), {ok, Req, #state{headers=Headers, body=Body}}. handle(Req, State=#state{headers=Headers, body=Body}) -> {ok, Req2} = cowboy_http_req:reply(200, Headers, Body, Req), {ok, Req2, State}. terminate(_Req, _State) -> ok. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/http_handler_init_shutdown.erl0000644000177700017770000000075712633765070033113 0ustar michaelmichael%% Feel free to use, reuse and abuse the code in this file. -module(http_handler_init_shutdown). -behaviour(cowboy_http_handler). -export([init/3, handle/2, terminate/2]). init({_Transport, http}, Req, _Opts) -> {ok, Req2} = cowboy_http_req:reply(<<"666 Init Shutdown Testing">>, [{'Connection', <<"close">>}], Req), {shutdown, Req2, undefined}. handle(Req, State) -> {ok, Req2} = cowboy_http_req:reply(200, [], "Hello world!", Req), {ok, Req2, State}. terminate(_Req, _State) -> ok. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/chunked_handler.erl0000644000177700017770000000070712633765070030572 0ustar michaelmichael%% Feel free to use, reuse and abuse the code in this file. -module(chunked_handler). -behaviour(cowboy_http_handler). -export([init/3, handle/2, terminate/2]). init({_Transport, http}, Req, _Opts) -> {ok, Req, undefined}. handle(Req, State) -> {ok, Req2} = cowboy_http_req:chunked_reply(200, Req), cowboy_http_req:chunk("chunked_handler\r\n", Req2), cowboy_http_req:chunk("works fine!", Req2), {ok, Req2, State}. terminate(_Req, _State) -> ok. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/ws_SUITE.erl0000644000177700017770000003057412633765070027063 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -module(ws_SUITE). -include_lib("common_test/include/ct.hrl"). -export([all/0, groups/0, init_per_suite/1, end_per_suite/1, init_per_group/2, end_per_group/2]). %% ct. -export([ws0/1, ws8/1, ws8_single_bytes/1, ws8_init_shutdown/1, ws13/1, ws_timeout_hibernate/1]). %% ws. %% ct. all() -> [{group, ws}]. groups() -> BaseTests = [ws0, ws8, ws8_single_bytes, ws8_init_shutdown, ws13, ws_timeout_hibernate], [{ws, [], BaseTests}]. init_per_suite(Config) -> application:start(inets), application:start(cowboy), Config. end_per_suite(_Config) -> application:stop(cowboy), application:stop(inets), ok. init_per_group(ws, Config) -> Port = 33080, cowboy:start_listener(ws, 100, cowboy_tcp_transport, [{port, Port}], cowboy_http_protocol, [{dispatch, init_dispatch()}] ), [{port, Port}|Config]. end_per_group(Listener, _Config) -> cowboy:stop_listener(Listener), ok. %% Dispatch configuration. init_dispatch() -> [ {[<<"localhost">>], [ {[<<"websocket">>], websocket_handler, []}, {[<<"ws_timeout_hibernate">>], ws_timeout_hibernate_handler, []}, {[<<"ws_init_shutdown">>], websocket_handler_init_shutdown, []} ]} ]. %% ws and wss. %% This test makes sure the code works even if we wait for a reply %% before sending the third challenge key in the GET body. %% %% This ensures that Cowboy will work fine with proxies on hixie. ws0(Config) -> {port, Port} = lists:keyfind(port, 1, Config), {ok, Socket} = gen_tcp:connect("localhost", Port, [binary, {active, false}, {packet, raw}]), ok = gen_tcp:send(Socket, "GET /websocket HTTP/1.1\r\n" "Host: localhost\r\n" "Connection: Upgrade\r\n" "Upgrade: WebSocket\r\n" "Origin: http://localhost\r\n" "Sec-Websocket-Key1: Y\" 4 1Lj!957b8@0H756!i\r\n" "Sec-Websocket-Key2: 1711 M;4\\74 80<6\r\n" "\r\n"), {ok, Handshake} = gen_tcp:recv(Socket, 0, 6000), {ok, {http_response, {1, 1}, 101, "WebSocket Protocol Handshake"}, Rest} = erlang:decode_packet(http, Handshake, []), [Headers, <<>>] = websocket_headers( erlang:decode_packet(httph, Rest, []), []), {'Connection', "Upgrade"} = lists:keyfind('Connection', 1, Headers), {'Upgrade', "WebSocket"} = lists:keyfind('Upgrade', 1, Headers), {"sec-websocket-location", "ws://localhost/websocket"} = lists:keyfind("sec-websocket-location", 1, Headers), {"sec-websocket-origin", "http://localhost"} = lists:keyfind("sec-websocket-origin", 1, Headers), ok = gen_tcp:send(Socket, <<15,245,8,18,2,204,133,33>>), {ok, Body} = gen_tcp:recv(Socket, 0, 6000), <<169,244,191,103,146,33,149,59,74,104,67,5,99,118,171,236>> = Body, ok = gen_tcp:send(Socket, << 0, "client_msg", 255 >>), {ok, << 0, "client_msg", 255 >>} = gen_tcp:recv(Socket, 0, 6000), {ok, << 0, "websocket_init", 255 >>} = gen_tcp:recv(Socket, 0, 6000), {ok, << 0, "websocket_handle", 255 >>} = gen_tcp:recv(Socket, 0, 6000), {ok, << 0, "websocket_handle", 255 >>} = gen_tcp:recv(Socket, 0, 6000), {ok, << 0, "websocket_handle", 255 >>} = gen_tcp:recv(Socket, 0, 6000), %% We try to send another HTTP request to make sure %% the server closed the request. ok = gen_tcp:send(Socket, [ << 255, 0 >>, %% Close websocket command. "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n" %% Server should ignore it. ]), {ok, << 255, 0 >>} = gen_tcp:recv(Socket, 0, 6000), {error, closed} = gen_tcp:recv(Socket, 0, 6000), ok. ws8(Config) -> {port, Port} = lists:keyfind(port, 1, Config), {ok, Socket} = gen_tcp:connect("localhost", Port, [binary, {active, false}, {packet, raw}]), ok = gen_tcp:send(Socket, [ "GET /websocket HTTP/1.1\r\n" "Host: localhost\r\n" "Connection: Upgrade\r\n" "Upgrade: websocket\r\n" "Sec-WebSocket-Origin: http://localhost\r\n" "Sec-WebSocket-Version: 8\r\n" "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" "\r\n"]), {ok, Handshake} = gen_tcp:recv(Socket, 0, 6000), {ok, {http_response, {1, 1}, 101, "Switching Protocols"}, Rest} = erlang:decode_packet(http, Handshake, []), [Headers, <<>>] = websocket_headers( erlang:decode_packet(httph, Rest, []), []), {'Connection', "Upgrade"} = lists:keyfind('Connection', 1, Headers), {'Upgrade', "websocket"} = lists:keyfind('Upgrade', 1, Headers), {"sec-websocket-accept", "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="} = lists:keyfind("sec-websocket-accept", 1, Headers), ok = gen_tcp:send(Socket, << 16#81, 16#85, 16#37, 16#fa, 16#21, 16#3d, 16#7f, 16#9f, 16#4d, 16#51, 16#58 >>), {ok, << 1:1, 0:3, 1:4, 0:1, 5:7, "Hello" >>} = gen_tcp:recv(Socket, 0, 6000), {ok, << 1:1, 0:3, 1:4, 0:1, 14:7, "websocket_init" >>} = gen_tcp:recv(Socket, 0, 6000), {ok, << 1:1, 0:3, 1:4, 0:1, 16:7, "websocket_handle" >>} = gen_tcp:recv(Socket, 0, 6000), {ok, << 1:1, 0:3, 1:4, 0:1, 16:7, "websocket_handle" >>} = gen_tcp:recv(Socket, 0, 6000), {ok, << 1:1, 0:3, 1:4, 0:1, 16:7, "websocket_handle" >>} = gen_tcp:recv(Socket, 0, 6000), ok = gen_tcp:send(Socket, << 1:1, 0:3, 9:4, 0:8 >>), %% ping {ok, << 1:1, 0:3, 10:4, 0:8 >>} = gen_tcp:recv(Socket, 0, 6000), %% pong ok = gen_tcp:send(Socket, << 1:1, 0:3, 8:4, 0:8 >>), %% close {ok, << 1:1, 0:3, 8:4, 0:8 >>} = gen_tcp:recv(Socket, 0, 6000), {error, closed} = gen_tcp:recv(Socket, 0, 6000), ok. ws8_single_bytes(Config) -> {port, Port} = lists:keyfind(port, 1, Config), {ok, Socket} = gen_tcp:connect("localhost", Port, [binary, {active, false}, {packet, raw}]), ok = gen_tcp:send(Socket, [ "GET /websocket HTTP/1.1\r\n" "Host: localhost\r\n" "Connection: Upgrade\r\n" "Upgrade: websocket\r\n" "Sec-WebSocket-Origin: http://localhost\r\n" "Sec-WebSocket-Version: 8\r\n" "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" "\r\n"]), {ok, Handshake} = gen_tcp:recv(Socket, 0, 6000), {ok, {http_response, {1, 1}, 101, "Switching Protocols"}, Rest} = erlang:decode_packet(http, Handshake, []), [Headers, <<>>] = websocket_headers( erlang:decode_packet(httph, Rest, []), []), {'Connection', "Upgrade"} = lists:keyfind('Connection', 1, Headers), {'Upgrade', "websocket"} = lists:keyfind('Upgrade', 1, Headers), {"sec-websocket-accept", "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="} = lists:keyfind("sec-websocket-accept", 1, Headers), ok = gen_tcp:send(Socket, << 16#81 >>), %% send one byte ok = timer:sleep(100), %% sleep for a period ok = gen_tcp:send(Socket, << 16#85 >>), %% send another and so on ok = timer:sleep(100), ok = gen_tcp:send(Socket, << 16#37 >>), ok = timer:sleep(100), ok = gen_tcp:send(Socket, << 16#fa >>), ok = timer:sleep(100), ok = gen_tcp:send(Socket, << 16#21 >>), ok = timer:sleep(100), ok = gen_tcp:send(Socket, << 16#3d >>), ok = timer:sleep(100), ok = gen_tcp:send(Socket, << 16#7f >>), ok = timer:sleep(100), ok = gen_tcp:send(Socket, << 16#9f >>), ok = timer:sleep(100), ok = gen_tcp:send(Socket, << 16#4d >>), ok = timer:sleep(100), ok = gen_tcp:send(Socket, << 16#51 >>), ok = timer:sleep(100), ok = gen_tcp:send(Socket, << 16#58 >>), {ok, << 1:1, 0:3, 1:4, 0:1, 14:7, "websocket_init" >>} = gen_tcp:recv(Socket, 0, 6000), {ok, << 1:1, 0:3, 1:4, 0:1, 5:7, "Hello" >>} = gen_tcp:recv(Socket, 0, 6000), {ok, << 1:1, 0:3, 1:4, 0:1, 16:7, "websocket_handle" >>} = gen_tcp:recv(Socket, 0, 6000), {ok, << 1:1, 0:3, 1:4, 0:1, 16:7, "websocket_handle" >>} = gen_tcp:recv(Socket, 0, 6000), {ok, << 1:1, 0:3, 1:4, 0:1, 16:7, "websocket_handle" >>} = gen_tcp:recv(Socket, 0, 6000), ok = gen_tcp:send(Socket, << 1:1, 0:3, 9:4, 0:8 >>), %% ping {ok, << 1:1, 0:3, 10:4, 0:8 >>} = gen_tcp:recv(Socket, 0, 6000), %% pong ok = gen_tcp:send(Socket, << 1:1, 0:3, 8:4, 0:8 >>), %% close {ok, << 1:1, 0:3, 8:4, 0:8 >>} = gen_tcp:recv(Socket, 0, 6000), {error, closed} = gen_tcp:recv(Socket, 0, 6000), ok. ws_timeout_hibernate(Config) -> {port, Port} = lists:keyfind(port, 1, Config), {ok, Socket} = gen_tcp:connect("localhost", Port, [binary, {active, false}, {packet, raw}]), ok = gen_tcp:send(Socket, [ "GET /ws_timeout_hibernate HTTP/1.1\r\n" "Host: localhost\r\n" "Connection: Upgrade\r\n" "Upgrade: websocket\r\n" "Sec-WebSocket-Origin: http://localhost\r\n" "Sec-WebSocket-Version: 8\r\n" "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" "\r\n"]), {ok, Handshake} = gen_tcp:recv(Socket, 0, 6000), {ok, {http_response, {1, 1}, 101, "Switching Protocols"}, Rest} = erlang:decode_packet(http, Handshake, []), [Headers, <<>>] = websocket_headers( erlang:decode_packet(httph, Rest, []), []), {'Connection', "Upgrade"} = lists:keyfind('Connection', 1, Headers), {'Upgrade', "websocket"} = lists:keyfind('Upgrade', 1, Headers), {"sec-websocket-accept", "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="} = lists:keyfind("sec-websocket-accept", 1, Headers), {ok, << 1:1, 0:3, 8:4, 0:8 >>} = gen_tcp:recv(Socket, 0, 6000), {error, closed} = gen_tcp:recv(Socket, 0, 6000), ok. ws8_init_shutdown(Config) -> {port, Port} = lists:keyfind(port, 1, Config), {ok, Socket} = gen_tcp:connect("localhost", Port, [binary, {active, false}, {packet, raw}]), ok = gen_tcp:send(Socket, [ "GET /ws_init_shutdown HTTP/1.1\r\n" "Host: localhost\r\n" "Connection: Upgrade\r\n" "Upgrade: websocket\r\n" "Sec-WebSocket-Origin: http://localhost\r\n" "Sec-WebSocket-Version: 8\r\n" "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" "\r\n"]), {ok, Handshake} = gen_tcp:recv(Socket, 0, 6000), {ok, {http_response, {1, 1}, 403, "Forbidden"}, _Rest} = erlang:decode_packet(http, Handshake, []), {error, closed} = gen_tcp:recv(Socket, 0, 6000), ok. ws13(Config) -> {port, Port} = lists:keyfind(port, 1, Config), {ok, Socket} = gen_tcp:connect("localhost", Port, [binary, {active, false}, {packet, raw}]), ok = gen_tcp:send(Socket, [ "GET /websocket HTTP/1.1\r\n" "Host: localhost\r\n" "Connection: Upgrade\r\n" "Origin: http://localhost\r\n" "Sec-WebSocket-Version: 13\r\n" "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" "Upgrade: websocket\r\n" "\r\n"]), {ok, Handshake} = gen_tcp:recv(Socket, 0, 6000), {ok, {http_response, {1, 1}, 101, "Switching Protocols"}, Rest} = erlang:decode_packet(http, Handshake, []), [Headers, <<>>] = websocket_headers( erlang:decode_packet(httph, Rest, []), []), {'Connection', "Upgrade"} = lists:keyfind('Connection', 1, Headers), {'Upgrade', "websocket"} = lists:keyfind('Upgrade', 1, Headers), {"sec-websocket-accept", "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="} = lists:keyfind("sec-websocket-accept", 1, Headers), %% text ok = gen_tcp:send(Socket, << 16#81, 16#85, 16#37, 16#fa, 16#21, 16#3d, 16#7f, 16#9f, 16#4d, 16#51, 16#58 >>), {ok, << 1:1, 0:3, 1:4, 0:1, 5:7, "Hello" >>} = gen_tcp:recv(Socket, 0, 6000), %% binary (empty) ok = gen_tcp:send(Socket, << 1:1, 0:3, 2:4, 0:8 >>), {ok, << 1:1, 0:3, 2:4, 0:8 >>} = gen_tcp:recv(Socket, 0, 6000), %% binary ok = gen_tcp:send(Socket, << 16#82, 16#85, 16#37, 16#fa, 16#21, 16#3d, 16#7f, 16#9f, 16#4d, 16#51, 16#58 >>), {ok, << 1:1, 0:3, 2:4, 0:1, 5:7, "Hello" >>} = gen_tcp:recv(Socket, 0, 6000), %% Receives. {ok, << 1:1, 0:3, 1:4, 0:1, 14:7, "websocket_init" >>} = gen_tcp:recv(Socket, 0, 6000), {ok, << 1:1, 0:3, 1:4, 0:1, 16:7, "websocket_handle" >>} = gen_tcp:recv(Socket, 0, 6000), {ok, << 1:1, 0:3, 1:4, 0:1, 16:7, "websocket_handle" >>} = gen_tcp:recv(Socket, 0, 6000), {ok, << 1:1, 0:3, 1:4, 0:1, 16:7, "websocket_handle" >>} = gen_tcp:recv(Socket, 0, 6000), ok = gen_tcp:send(Socket, << 1:1, 0:3, 9:4, 0:8 >>), %% ping {ok, << 1:1, 0:3, 10:4, 0:8 >>} = gen_tcp:recv(Socket, 0, 6000), %% pong ok = gen_tcp:send(Socket, << 1:1, 0:3, 8:4, 0:8 >>), %% close {ok, << 1:1, 0:3, 8:4, 0:8 >>} = gen_tcp:recv(Socket, 0, 6000), {error, closed} = gen_tcp:recv(Socket, 0, 6000), ok. websocket_headers({ok, http_eoh, Rest}, Acc) -> [Acc, Rest]; websocket_headers({ok, {http_header, _I, Key, _R, Value}, Rest}, Acc) -> F = fun(S) when is_atom(S) -> S; (S) -> string:to_lower(S) end, websocket_headers(erlang:decode_packet(httph, Rest, []), [{F(Key), Value}|Acc]). rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/http_handler_stream_body.erl0000644000177700017770000000153512633765070032520 0ustar michaelmichael%% Feel free to use, reuse and abuse the code in this file. -module(http_handler_stream_body). -behaviour(cowboy_http_handler). -export([init/3, handle/2, terminate/2]). -record(state, {headers, body, reply}). init({_Transport, http}, Req, Opts) -> Headers = proplists:get_value(headers, Opts, []), Body = proplists:get_value(body, Opts, "http_handler_stream_body"), Reply = proplists:get_value(reply, Opts), {ok, Req, #state{headers=Headers, body=Body, reply=Reply}}. handle(Req, State=#state{headers=_Headers, body=Body, reply=set_resp}) -> {ok, Transport, Socket} = cowboy_http_req:transport(Req), SFun = fun() -> Transport:send(Socket, Body), sent end, SLen = iolist_size(Body), {ok, Req2} = cowboy_http_req:set_resp_body_fun(SLen, SFun, Req), {ok, Req3} = cowboy_http_req:reply(200, Req2), {ok, Req3, State}. terminate(_Req, _State) -> ok. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/http_handler_multipart.erl0000644000177700017770000000165412633765070032233 0ustar michaelmichael%% Feel free to use, reuse and abuse the code in this file. -module(http_handler_multipart). -behaviour(cowboy_http_handler). -export([init/3, handle/2, terminate/2]). init({_Transport, http}, Req, []) -> {ok, Req, {}}. handle(Req, State) -> {Result, Req2} = acc_multipart(Req, []), {ok, Req3} = cowboy_http_req:reply(200, [], term_to_binary(Result), Req2), {ok, Req3, State}. terminate(_Req, _State) -> ok. acc_multipart(Req, Acc) -> {Result, Req2} = cowboy_http_req:multipart_data(Req), acc_multipart(Req2, Acc, Result). acc_multipart(Req, Acc, {headers, Headers}) -> acc_multipart(Req, [{Headers, []}|Acc]); acc_multipart(Req, [{Headers, BodyAcc}|Acc], {body, Data}) -> acc_multipart(Req, [{Headers, [Data|BodyAcc]}|Acc]); acc_multipart(Req, [{Headers, BodyAcc}|Acc], end_of_part) -> acc_multipart(Req, [{Headers, list_to_binary(lists:reverse(BodyAcc))}|Acc]); acc_multipart(Req, Acc, eof) -> {lists:reverse(Acc), Req}. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/websocket_handler_init_shutdown.erl0000644000177700017770000000136412633765070034115 0ustar michaelmichael%% Feel free to use, reuse and abuse the code in this file. -module(websocket_handler_init_shutdown). -behaviour(cowboy_http_handler). -behaviour(cowboy_http_websocket_handler). -export([init/3, handle/2, terminate/2]). -export([websocket_init/3, websocket_handle/3, websocket_info/3, websocket_terminate/3]). init(_Any, _Req, _Opts) -> {upgrade, protocol, cowboy_http_websocket}. handle(_Req, _State) -> exit(badarg). terminate(_Req, _State) -> exit(badarg). websocket_init(_TransportName, Req, _Opts) -> {ok, Req2} = cowboy_http_req:reply(403, Req), {shutdown, Req2}. websocket_handle(_Frame, _Req, _State) -> exit(badarg). websocket_info(_Info, _Req, _State) -> exit(badarg). websocket_terminate(_Reason, _Req, _State) -> exit(badarg). rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/http_SUITE_data/0000755000177700017770000000000012633765070027665 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/http_SUITE_data/cert.pem0000644000177700017770000000145212633765070031327 0ustar michaelmichael-----BEGIN CERTIFICATE----- MIICKTCCAZICCQCl9gdHk5NqUjANBgkqhkiG9w0BAQUFADBZMQswCQYDVQQGEwJB VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 cyBQdHkgTHRkMRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMTEwNDA4MTMxNTE3WhcN MTEwNTA4MTMxNTE3WjBZMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0 ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRIwEAYDVQQDDAls b2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOjgFPS0dP4d8F1e bNJPB+kAjM2FyTZGmkFCLUYONTPrdGOUIHL/UOGtU22BQzlskE+a6/j2Kg72tm8x 4X7yf+6s7CdRe086idNx9+GymZ64ZTnly33rD3AJffbBeWHwT2e9fuBeFk9WGC8v kqECFZyqf7+znS0o48oBNcx3ePB5AgMBAAEwDQYJKoZIhvcNAQEFBQADgYEASTkv oHuZyO8DgT8bIE6W3yM2fvlNshkhh7Thgpf32qQoVOxRU9EF0KpuJCCAHQHQNQlI nf9Zc4UzOrLhxZBGocNhkkn4WLw2ysto/7+/+9xHah0M0l4auHLQagVLCoOsHUn2 JX+A2NrbvuX5wnUrZGOdgY70tvMBeU/xLtp3af8= -----END CERTIFICATE----- rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/test/http_SUITE_data/key.pem0000644000177700017770000000170312633765070031161 0ustar michaelmichael-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,F11262DB77BB804C jOJ+ft/dihIxz7CTuuK47fCTGdX7xMLANmA7mRg8y9OYhNZQiCz5GjcWLqe0NNl5 qXPW0uvT/9B5O9o21Y2i/CKU1BqRLuXHXDsjHg7RGaSH6wIavWt+lR+I1sjieFbX VByK1KHXjEU704DEILKJIA9gVzoYAgMzo+FTw2e/2jusXntxk8HXyF5zKTzjHBtI NQGweJqTmfZjX3SgPP4Co/ShrA6fUG0uTp1HwbByJnwtAeT3xWJrAD4QSn7+qrlv 3qmEIqVXsvLrfZRY1WZ4uIsbLK8wkvxboSIoIK55VV9R2zRbwQULon6QJwKYujAr J2WUYkHHQOMpaAzUmalaT+8GUt8/A1oSK4BdiSZywsMMm46/hDadXBzFg+dPL5g2 Td+7/L0S6tUVWq4+YBp5EalZH6VQ4cqPYDJZUZ9xt6+yY7V5748lSdA7cHCROnbG bKbSW9WbF7MPDHCjvCAfq+s1dafHJgyIOlMg2bm7V8eHWAA0xKQ/o7i5EyEyaKYR UXGeAf+KfXcclEZ77v2RCXZvd6ceWkifm59qWv/3TCYaHiS2Aa3lVToMKTwYzzXQ p5X5os6wv3IAi2nGyAIOoSDisdHmFteZNXNQsw0n3XCAYfsNMk+r5/r5YqDffURH c8SMOCP4BIPoZ/abi/gnEntGqsx1YALg0aosHwHGDJ/l+QJC6u6PZk310YzRw4GL K9+wscFgEub2OO+R83Vkfesj4tYzgOjab7+92a/soHdW0zhGejlvehODOgNZ6NUG MPQlT+qpF9Jh5IThYXupXXFzJzQe3O/qVXy89m69JGa+AWRvbu+M/A== -----END RSA PRIVATE KEY----- rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/cover.spec0000644000177700017770000000003512633765070025755 0ustar michaelmichael{incl_app, cowboy, details}. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/Makefile0000644000177700017770000000114412633765070025425 0ustar michaelmichael# See LICENSE for licensing information. DIALYZER = dialyzer REBAR = rebar all: app app: deps @$(REBAR) compile deps: @$(REBAR) get-deps clean: @$(REBAR) clean rm -f test/*.beam rm -f erl_crash.dump tests: clean app eunit ct eunit: @$(REBAR) eunit skip_deps=true ct: @$(REBAR) ct skip_deps=true build-plt: @$(DIALYZER) --build_plt --output_plt .cowboy_dialyzer.plt \ --apps kernel stdlib sasl inets crypto public_key ssl dialyze: @$(DIALYZER) --src src --plt .cowboy_dialyzer.plt -Werror_handling \ -Wrace_conditions -Wunmatched_returns # -Wunderspecs docs: @$(REBAR) doc skip_deps=true rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/.travis.yml0000644000177700017770000000013512633765070026075 0ustar michaelmichaellanguage: erlang otp_release: - R15B - R14B04 - R14B03 - R14B02 script: "make tests" rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/include/0000755000177700017770000000000012633765070025410 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/include/http.hrl0000644000177700017770000000500512633765070027076 0ustar michaelmichael%% Copyright (c) 2011, Loïc Hoguin %% Copyright (c) 2011, Anthony Ramine %% %% Permission to use, copy, modify, and/or distribute this software for any %% purpose with or without fee is hereby granted, provided that the above %% copyright notice and this permission notice appear in all copies. %% %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -record(http_req, { %% Transport. socket = undefined :: undefined | inet:socket(), transport = undefined :: undefined | module(), connection = keepalive :: keepalive | close, %% Request. pid = undefined :: pid(), method = 'GET' :: cowboy_http:method(), version = {1, 1} :: cowboy_http:version(), peer = undefined :: undefined | {inet:ip_address(), inet:ip_port()}, host = undefined :: undefined | cowboy_dispatcher:tokens(), host_info = undefined :: undefined | cowboy_dispatcher:tokens(), raw_host = undefined :: undefined | binary(), port = undefined :: undefined | inet:ip_port(), path = undefined :: undefined | '*' | cowboy_dispatcher:tokens(), path_info = undefined :: undefined | cowboy_dispatcher:tokens(), raw_path = undefined :: undefined | binary(), qs_vals = undefined :: undefined | list({binary(), binary() | true}), raw_qs = undefined :: undefined | binary(), bindings = undefined :: undefined | cowboy_dispatcher:bindings(), headers = [] :: cowboy_http:headers(), p_headers = [] :: [any()], %% @todo Improve those specs. cookies = undefined :: undefined | [{binary(), binary()}], meta = [] :: [{atom(), any()}], %% Request body. body_state = waiting :: waiting | done | {multipart, non_neg_integer(), fun()}, buffer = <<>> :: binary(), %% Response. resp_state = waiting :: locked | waiting | chunks | done, resp_headers = [] :: cowboy_http:headers(), resp_body = <<>> :: cowboy_http:fake_iodata() | {non_neg_integer(), fun(() -> {sent, non_neg_integer()})}, %% Functions. urldecode :: {fun((binary(), T) -> binary()), T} }). rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/.done0000644000177700017770000000000012633765070024701 0ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/AUTHORS0000644000177700017770000000043212633765070025034 0ustar michaelmichaelCowboy is available thanks to the work of: Loïc Hoguin Anthony Ramine Magnus Klaar Paul Oliver Steven Gravell Tom Burdick Hunter Morris Yurii Rashkovskii Ali Sabil Hans Ulrich Niedermann Jesper Louis Andersen Mathieu Lecarme Max Lapshin Michiel Hakvoort Ori Bar Alisdair Sullivan rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/LICENSE0000644000177700017770000000136112633765070024773 0ustar michaelmichaelCopyright (c) 2011, Loïc Hoguin Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/cowboy-git/rebar.config0000644000177700017770000000042712633765070026252 0ustar michaelmichael{cover_enabled, true}. {deps, [ {proper, "1.0", {git, "git://github.com/manopapad/proper.git", {tag, "v1.0"}}} ]}. {eunit_opts, [verbose, {report, {eunit_surefire, [{dir, "."}]}}]}. {erl_opts, [ %% bin_opt_info, %% warn_missing_spec, warnings_as_errors, warn_export_all ]}. rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/.srcdist_done0000644000177700017770000000000012633765070024351 0ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/hash.mk0000644000177700017770000000003512633765070023154 0ustar michaelmichaelUPSTREAM_SHORT_HASH:=4b93c2d rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/Makefile0000644000177700017770000000002712633765070023341 0ustar michaelmichaelinclude ../umbrella.mk rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/0007-R12-type-definitions-must-be-ordered.patch0000644000177700017770000000240212633765070032135 0ustar michaelmichaelFrom 547731d5490b36f1239a99e6c4acc1964e724a6e Mon Sep 17 00:00:00 2001 From: Marek Majkowski Date: Thu, 26 Jan 2012 12:54:49 +0000 Subject: [PATCH 7/7] R12 - type definitions must be ordered --- src/cowboy_multipart.erl | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cowboy_multipart.erl b/src/cowboy_multipart.erl index c9b5b6c..0bd123a 100644 --- a/src/cowboy_multipart.erl +++ b/src/cowboy_multipart.erl @@ -15,15 +15,15 @@ %% @doc Multipart parser. -module(cowboy_multipart). --type part_parser() :: parser(more(part_result())). +-type part_parser() :: any(). -type parser(T) :: fun((binary()) -> T). -type more(T) :: T | {more, parser(T)}. --type part_result() :: headers() | eof. --type headers() :: {headers, http_headers(), body_cont()}. +-type part_result() :: any(). +-type headers() :: any(). -type http_headers() :: [{atom() | binary(), binary()}]. --type body_cont() :: cont(more(body_result())). +-type body_cont() :: any(). -type cont(T) :: fun(() -> T). --type body_result() :: {body, binary(), body_cont()} | end_of_part(). +-type body_result() :: any(). -type end_of_part() :: {end_of_part, cont(more(part_result()))}. -type disposition() :: {binary(), [{binary(), binary()}]}. -- 1.7.0.4 ././@LongLink0000644000000000000000000000016100000000000011601 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/0006-Use-erlang-integer_to_list-and-lists-max-instead-of-.patchrabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/0006-Use-erlang-integer_to_list-and-lists-max-inste0000644000177700017770000000474612633765070033214 0ustar michaelmichaelFrom 81106c53b80f5d0fa441b893048bbdc6c9e2c4f0 Mon Sep 17 00:00:00 2001 From: Marek Majkowski Date: Thu, 26 Jan 2012 12:54:31 +0000 Subject: [PATCH 6/7] Use erlang:integer_to_list and lists:max instead of bifs --- src/cowboy_http_req.erl | 2 +- src/cowboy_http_static.erl | 2 +- src/cowboy_multipart.erl | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cowboy_http_req.erl b/src/cowboy_http_req.erl index c884f5a..bf4ac7a 100644 --- a/src/cowboy_http_req.erl +++ b/src/cowboy_http_req.erl @@ -576,7 +576,7 @@ chunked_reply(Status, Headers, Req=#http_req{socket=Socket, chunk(_Data, #http_req{socket=_Socket, transport=_Transport, method='HEAD'}) -> ok; chunk(Data, #http_req{socket=Socket, transport=Transport, resp_state=chunks}) -> - Transport:send(Socket, [integer_to_list(iolist_size(Data), 16), + Transport:send(Socket, [erlang:integer_to_list(iolist_size(Data), 16), <<"\r\n">>, Data, <<"\r\n">>]). %% @doc Send an upgrade reply. diff --git a/src/cowboy_http_static.erl b/src/cowboy_http_static.erl index d370046..da3bd33 100644 --- a/src/cowboy_http_static.erl +++ b/src/cowboy_http_static.erl @@ -412,7 +412,7 @@ attr_etag_function(Args, Attrs) -> -spec attr_etag_function([etagarg()], [fileattr()], [binary()]) -> binary(). attr_etag_function(_Args, [], Acc) -> - list_to_binary(integer_to_list(erlang:crc32(Acc), 16)); + list_to_binary(erlang:integer_to_list(erlang:crc32(Acc), 16)); attr_etag_function(Args, [H|T], Acc) -> {_, Value} = lists:keyfind(H, 1, Args), attr_etag_function(Args, T, [term_to_binary(Value)|Acc]). diff --git a/src/cowboy_multipart.erl b/src/cowboy_multipart.erl index b7aeb54..c9b5b6c 100644 --- a/src/cowboy_multipart.erl +++ b/src/cowboy_multipart.erl @@ -105,7 +105,7 @@ parse_boundary_eol(Bin, Pattern) -> cowboy_http:whitespace(Rest, Fun); nomatch -> % CRLF not found in the given binary. - RestStart = max(byte_size(Bin) - 1, 0), + RestStart = lists:max([byte_size(Bin) - 1, 0]), <<_:RestStart/binary, Rest/binary>> = Bin, more(Rest, fun (NewBin) -> parse_boundary_eol(NewBin, Pattern) end) end. @@ -175,7 +175,7 @@ skip(Bin, Pattern = {P, PSize}) -> parse_boundary_tail(Rest, Pattern); nomatch -> % Boundary not found, need more data. - RestStart = max(byte_size(Bin) - PSize + 1, 0), + RestStart = lists:max([byte_size(Bin) - PSize + 1, 0]), <<_:RestStart/binary, Rest/binary>> = Bin, more(Rest, fun (NewBin) -> skip(NewBin, Pattern) end) end. -- 1.7.0.4 rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/0005-R12-drop-references-to-Default-any-type.patch0000644000177700017770000000433512633765070032505 0ustar michaelmichaelFrom c7aef1d044a1e83fcd6be7a83b2c763c0366d4f8 Mon Sep 17 00:00:00 2001 From: Marek Majkowski Date: Thu, 26 Jan 2012 12:53:36 +0000 Subject: [PATCH 5/7] R12: drop references to Default:any() type --- src/cowboy_http_req.erl | 8 -------- 1 files changed, 0 insertions(+), 8 deletions(-) diff --git a/src/cowboy_http_req.erl b/src/cowboy_http_req.erl index 64e757c..c884f5a 100644 --- a/src/cowboy_http_req.erl +++ b/src/cowboy_http_req.erl @@ -147,8 +147,6 @@ qs_val(Name, Req) when is_binary(Name) -> %% @doc Return the query string value for the given key, or a default if %% missing. --spec qs_val(binary(), #http_req{}, Default) - -> {binary() | true | Default, #http_req{}} when Default::any(). qs_val(Name, Req=#http_req{raw_qs=RawQs, qs_vals=undefined, urldecode={URLDecFun, URLDecArg}}, Default) when is_binary(Name) -> QsVals = parse_qs(RawQs, fun(Bin) -> URLDecFun(Bin, URLDecArg) end), @@ -180,8 +178,6 @@ binding(Name, Req) when is_atom(Name) -> %% @doc Return the binding value for the given key obtained when matching %% the host and path against the dispatch list, or a default if missing. --spec binding(atom(), #http_req{}, Default) - -> {binary() | Default, #http_req{}} when Default::any(). binding(Name, Req, Default) when is_atom(Name) -> case lists:keyfind(Name, 1, Req#http_req.bindings) of {Name, Value} -> {Value, Req}; @@ -200,8 +196,6 @@ header(Name, Req) when is_atom(Name) orelse is_binary(Name) -> header(Name, Req, undefined). %% @doc Return the header value for the given key, or a default if missing. --spec header(atom() | binary(), #http_req{}, Default) - -> {binary() | Default, #http_req{}} when Default::any(). header(Name, Req, Default) when is_atom(Name) orelse is_binary(Name) -> case lists:keyfind(Name, 1, Req#http_req.headers) of {Name, Value} -> {Value, Req}; @@ -313,8 +307,6 @@ cookie(Name, Req) when is_binary(Name) -> %% @doc Return the cookie value for the given key, or a default if %% missing. --spec cookie(binary(), #http_req{}, Default) - -> {binary() | true | Default, #http_req{}} when Default::any(). cookie(Name, Req=#http_req{cookies=undefined}, Default) when is_binary(Name) -> case header('Cookie', Req) of {undefined, Req2} -> -- 1.7.0.4 rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/package.mk0000644000177700017770000000146412633765070023633 0ustar michaelmichaelAPP_NAME:=cowboy UPSTREAM_GIT:=https://github.com/rabbitmq/cowboy.git UPSTREAM_REVISION:=4b93c2d19a10e5d9cee RETAIN_ORIGINAL_VERSION:=true WRAPPER_PATCHES:=\ 0001-R12-fake-iodata-type.patch \ 0002-R12-drop-all-references-to-boolean-type.patch \ 0003-R12-drop-all-references-to-reference-type.patch \ 0004-R12-drop-references-to-iodata-type.patch \ 0005-R12-drop-references-to-Default-any-type.patch \ 0006-Use-erlang-integer_to_list-and-lists-max-instead-of-.patch \ 0007-R12-type-definitions-must-be-ordered.patch \ 0008-sec-websocket-protocol.patch # Path include/http.hrl is needed during compilation INCLUDE_DIRS+=$(CLONE_DIR) ORIGINAL_APP_FILE:=$(CLONE_DIR)/src/$(APP_NAME).app.src DO_NOT_GENERATE_APP_FILE=true define construct_app_commands cp $(CLONE_DIR)/LICENSE $(APP_DIR)/LICENSE-ISC-Cowboy endef rabbitmq-server-3.5.7/plugins-src/cowboy-wrapper/0004-R12-drop-references-to-iodata-type.patch0000644000177700017770000000416412633765070031574 0ustar michaelmichaelFrom dfb750f491208a8e30cab0fa701dd866d60734b8 Mon Sep 17 00:00:00 2001 From: Marek Majkowski Date: Thu, 26 Jan 2012 12:53:08 +0000 Subject: [PATCH 4/7] R12: drop references to iodata() type --- src/cowboy_http_req.erl | 6 ------ 1 files changed, 0 insertions(+), 6 deletions(-) diff --git a/src/cowboy_http_req.erl b/src/cowboy_http_req.erl index d729d6c..64e757c 100644 --- a/src/cowboy_http_req.erl +++ b/src/cowboy_http_req.erl @@ -478,8 +478,6 @@ set_resp_cookie(Name, Value, Options, Req) -> set_resp_header(HeaderName, HeaderValue, Req). %% @doc Add a header to the response. --spec set_resp_header(cowboy_http:header(), iodata(), #http_req{}) - -> {ok, #http_req{}}. set_resp_header(Name, Value, Req=#http_req{resp_headers=RespHeaders}) -> NameBin = header_to_binary(Name), {ok, Req#http_req{resp_headers=[{NameBin, Value}|RespHeaders]}}. @@ -489,7 +487,6 @@ set_resp_header(Name, Value, Req=#http_req{resp_headers=RespHeaders}) -> %% The body set here is ignored if the response is later sent using %% anything other than reply/2 or reply/3. The response body is expected %% to be a binary or an iolist. --spec set_resp_body(iodata(), #http_req{}) -> {ok, #http_req{}}. set_resp_body(Body, Req) -> {ok, Req#http_req{resp_body=Body}}. @@ -537,8 +534,6 @@ reply(Status, Headers, Req=#http_req{resp_body=Body}) -> reply(Status, Headers, Body, Req). %% @doc Send a reply to the client. --spec reply(cowboy_http:status(), cowboy_http:headers(), iodata(), #http_req{}) - -> {ok, #http_req{}}. reply(Status, Headers, Body, Req=#http_req{socket=Socket, transport=Transport, connection=Connection, pid=ReqPid, method=Method, resp_state=waiting, resp_headers=RespHeaders}) -> @@ -586,7 +581,6 @@ chunked_reply(Status, Headers, Req=#http_req{socket=Socket, %% @doc Send a chunk of data. %% %% A chunked reply must have been initiated before calling this function. --spec chunk(iodata(), #http_req{}) -> ok | {error, atom()}. chunk(_Data, #http_req{socket=_Socket, transport=_Transport, method='HEAD'}) -> ok; chunk(Data, #http_req{socket=Socket, transport=Transport, resp_state=chunks}) -> -- 1.7.0.4 rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/0000755000177700017770000000000012633765070023245 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/README.in0000755000177700017770000000053112633765070024534 0ustar michaelmichaelREADME.in: Please see http://www.rabbitmq.com/build-erlang-client.html for build instructions. For your convenience, a text copy of these instructions is available below. Please be aware that the instructions here may not be as up to date as those at the above URL. =========================================================================== rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/0000755000177700017770000000000012633765070024034 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/amqp_rpc_server.erl0000644000177700017770000001166012633765070027734 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% %% @doc This is a utility module that is used to expose an arbitrary function %% via an asynchronous RPC over AMQP mechanism. It frees the implementor of %% a simple function from having to plumb this into AMQP. Note that the %% RPC server does not handle any data encoding, so it is up to the callback %% function to marshall and unmarshall message payloads accordingly. -module(amqp_rpc_server). -behaviour(gen_server). -include("amqp_client.hrl"). -export([init/1, terminate/2, code_change/3, handle_call/3, handle_cast/2, handle_info/2]). -export([start/3, start_link/3]). -export([stop/1]). -record(state, {channel, handler}). %%-------------------------------------------------------------------------- %% API %%-------------------------------------------------------------------------- %% @spec (Connection, Queue, RpcHandler) -> RpcServer %% where %% Connection = pid() %% Queue = binary() %% RpcHandler = function() %% RpcServer = pid() %% @doc Starts a new RPC server instance that receives requests via a %% specified queue and dispatches them to a specified handler function. This %% function returns the pid of the RPC server that can be used to stop the %% server. start(Connection, Queue, Fun) -> {ok, Pid} = gen_server:start(?MODULE, [Connection, Queue, Fun], []), Pid. %% @spec (Connection, Queue, RpcHandler) -> RpcServer %% where %% Connection = pid() %% Queue = binary() %% RpcHandler = function() %% RpcServer = pid() %% @doc Starts, and links to, a new RPC server instance that receives %% requests via a specified queue and dispatches them to a specified %% handler function. This function returns the pid of the RPC server that %% can be used to stop the server. start_link(Connection, Queue, Fun) -> {ok, Pid} = gen_server:start_link(?MODULE, [Connection, Queue, Fun], []), Pid. %% @spec (RpcServer) -> ok %% where %% RpcServer = pid() %% @doc Stops an exisiting RPC server. stop(Pid) -> gen_server:call(Pid, stop, infinity). %%-------------------------------------------------------------------------- %% gen_server callbacks %%-------------------------------------------------------------------------- %% @private init([Connection, Q, Fun]) -> {ok, Channel} = amqp_connection:open_channel( Connection, {amqp_direct_consumer, [self()]}), amqp_channel:call(Channel, #'queue.declare'{queue = Q}), amqp_channel:call(Channel, #'basic.consume'{queue = Q}), {ok, #state{channel = Channel, handler = Fun} }. %% @private handle_info(shutdown, State) -> {stop, normal, State}; %% @private handle_info({#'basic.consume'{}, _}, State) -> {noreply, State}; %% @private handle_info(#'basic.consume_ok'{}, State) -> {noreply, State}; %% @private handle_info(#'basic.cancel'{}, State) -> {noreply, State}; %% @private handle_info(#'basic.cancel_ok'{}, State) -> {stop, normal, State}; %% @private handle_info({#'basic.deliver'{delivery_tag = DeliveryTag}, #amqp_msg{props = Props, payload = Payload}}, State = #state{handler = Fun, channel = Channel}) -> #'P_basic'{correlation_id = CorrelationId, reply_to = Q} = Props, Response = Fun(Payload), Properties = #'P_basic'{correlation_id = CorrelationId}, Publish = #'basic.publish'{exchange = <<>>, routing_key = Q, mandatory = true}, amqp_channel:call(Channel, Publish, #amqp_msg{props = Properties, payload = Response}), amqp_channel:call(Channel, #'basic.ack'{delivery_tag = DeliveryTag}), {noreply, State}; %% @private handle_info({'DOWN', _MRef, process, _Pid, _Info}, State) -> {noreply, State}. %% @private handle_call(stop, _From, State) -> {stop, normal, ok, State}. %%-------------------------------------------------------------------------- %% Rest of the gen_server callbacks %%-------------------------------------------------------------------------- %% @private handle_cast(_Message, State) -> {noreply, State}. %% Closes the channel this gen_server instance started %% @private terminate(_Reason, #state{channel = Channel}) -> amqp_channel:close(Channel), ok. %% @private code_change(_OldVsn, State, _Extra) -> {ok, State}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/overview.edoc.in0000644000177700017770000000347012633765070027147 0ustar michaelmichael@title AMQP Client for Erlang @author GoPivotal Inc. @copyright 2007-2013 GoPivotal, Inc. @version %%VERSION%% @reference AMQP documentation on the RabbitMQ website. @doc == Overview == This application provides an Erlang library to interact with an AMQP 0-9-1 compliant message broker. The module documentation assumes that the programmer has some basic familiarity with the execution model defined in the AMQP specification. The main components are {@link amqp_connection} and {@link amqp_channel}. The {@link amqp_connection} module is used to open and close connections to an AMQP broker as well as creating channels. The {@link amqp_channel} module is used to send and receive commands and messages to and from a broker within the context of a channel. == AMQP Record Definitions == Many of the API functions take structured records as arguments. These records represent the commands defined in the AMQP execution model. The definitions for these records are automatically generated by the rabbitmq-codegen project. rabbitmq-codegen parses a machine readable view of the specification and generates a header file that includes the entire command set of AMQP. Each command in AMQP has an identically named record. The protocol documentation serves as a reference for the attributes of each command. == Programming Model == For more information, refer to the Erlang AMQP client developer's guide on the RabbitMQ website. == RPC Components == The {@link amqp_rpc_server} module provides a generic building block to expose Erlang functions via an RPC over AMQP mechanism. The {@link amqp_rpc_client} provides a simple client utility to submit RPC requests to a server via AMQP. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/amqp_rpc_client.erl0000644000177700017770000001513112633765070027701 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% %% @doc This module allows the simple execution of an asynchronous RPC over %% AMQP. It frees a client programmer of the necessary having to AMQP %% plumbing. Note that the this module does not handle any data encoding, %% so it is up to the caller to marshall and unmarshall message payloads %% accordingly. -module(amqp_rpc_client). -include("amqp_client.hrl"). -behaviour(gen_server). -export([start/2, start_link/2, stop/1]). -export([call/2]). -export([init/1, terminate/2, code_change/3, handle_call/3, handle_cast/2, handle_info/2]). -record(state, {channel, reply_queue, exchange, routing_key, continuations = dict:new(), correlation_id = 0}). %%-------------------------------------------------------------------------- %% API %%-------------------------------------------------------------------------- %% @spec (Connection, Queue) -> RpcClient %% where %% Connection = pid() %% Queue = binary() %% RpcClient = pid() %% @doc Starts a new RPC client instance that sends requests to a %% specified queue. This function returns the pid of the RPC client process %% that can be used to invoke RPCs and stop the client. start(Connection, Queue) -> {ok, Pid} = gen_server:start(?MODULE, [Connection, Queue], []), Pid. %% @spec (Connection, Queue) -> RpcClient %% where %% Connection = pid() %% Queue = binary() %% RpcClient = pid() %% @doc Starts, and links to, a new RPC client instance that sends requests %% to a specified queue. This function returns the pid of the RPC client %% process that can be used to invoke RPCs and stop the client. start_link(Connection, Queue) -> {ok, Pid} = gen_server:start_link(?MODULE, [Connection, Queue], []), Pid. %% @spec (RpcClient) -> ok %% where %% RpcClient = pid() %% @doc Stops an exisiting RPC client. stop(Pid) -> gen_server:call(Pid, stop, infinity). %% @spec (RpcClient, Payload) -> ok %% where %% RpcClient = pid() %% Payload = binary() %% @doc Invokes an RPC. Note the caller of this function is responsible for %% encoding the request and decoding the response. call(RpcClient, Payload) -> gen_server:call(RpcClient, {call, Payload}, infinity). %%-------------------------------------------------------------------------- %% Plumbing %%-------------------------------------------------------------------------- %% Sets up a reply queue for this client to listen on setup_reply_queue(State = #state{channel = Channel}) -> #'queue.declare_ok'{queue = Q} = amqp_channel:call(Channel, #'queue.declare'{exclusive = true, auto_delete = true}), State#state{reply_queue = Q}. %% Registers this RPC client instance as a consumer to handle rpc responses setup_consumer(#state{channel = Channel, reply_queue = Q}) -> amqp_channel:call(Channel, #'basic.consume'{queue = Q}). %% Publishes to the broker, stores the From address against %% the correlation id and increments the correlationid for %% the next request publish(Payload, From, State = #state{channel = Channel, reply_queue = Q, exchange = X, routing_key = RoutingKey, correlation_id = CorrelationId, continuations = Continuations}) -> EncodedCorrelationId = base64:encode(<>), Props = #'P_basic'{correlation_id = EncodedCorrelationId, content_type = <<"application/octet-stream">>, reply_to = Q}, Publish = #'basic.publish'{exchange = X, routing_key = RoutingKey, mandatory = true}, amqp_channel:call(Channel, Publish, #amqp_msg{props = Props, payload = Payload}), State#state{correlation_id = CorrelationId + 1, continuations = dict:store(EncodedCorrelationId, From, Continuations)}. %%-------------------------------------------------------------------------- %% gen_server callbacks %%-------------------------------------------------------------------------- %% Sets up a reply queue and consumer within an existing channel %% @private init([Connection, RoutingKey]) -> {ok, Channel} = amqp_connection:open_channel( Connection, {amqp_direct_consumer, [self()]}), InitialState = #state{channel = Channel, exchange = <<>>, routing_key = RoutingKey}, State = setup_reply_queue(InitialState), setup_consumer(State), {ok, State}. %% Closes the channel this gen_server instance started %% @private terminate(_Reason, #state{channel = Channel}) -> amqp_channel:close(Channel), ok. %% Handle the application initiated stop by just stopping this gen server %% @private handle_call(stop, _From, State) -> {stop, normal, ok, State}; %% @private handle_call({call, Payload}, From, State) -> NewState = publish(Payload, From, State), {noreply, NewState}. %% @private handle_cast(_Msg, State) -> {noreply, State}. %% @private handle_info({#'basic.consume'{}, _Pid}, State) -> {noreply, State}; %% @private handle_info(#'basic.consume_ok'{}, State) -> {noreply, State}; %% @private handle_info(#'basic.cancel'{}, State) -> {noreply, State}; %% @private handle_info(#'basic.cancel_ok'{}, State) -> {stop, normal, State}; %% @private handle_info({#'basic.deliver'{delivery_tag = DeliveryTag}, #amqp_msg{props = #'P_basic'{correlation_id = Id}, payload = Payload}}, State = #state{continuations = Conts, channel = Channel}) -> From = dict:fetch(Id, Conts), gen_server:reply(From, Payload), amqp_channel:call(Channel, #'basic.ack'{delivery_tag = DeliveryTag}), {noreply, State#state{continuations = dict:erase(Id, Conts) }}. %% @private code_change(_OldVsn, State, _Extra) -> {ok, State}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/uri_parser.erl0000644000177700017770000001162312633765070026716 0ustar michaelmichael%% This file is a copy of http_uri.erl from the R13B-1 Erlang/OTP %% distribution with several modifications. %% All modifications are Copyright (c) 2009-2014 GoPivotal, Ltd. %% ``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.'' %% See http://tools.ietf.org/html/rfc3986 -module(uri_parser). -export([parse/2]). %%%========================================================================= %%% API %%%========================================================================= %% Returns a key list of elements extracted from the URI. Note that %% only 'scheme' is guaranteed to exist. Key-Value pairs from the %% Defaults list will be used absence of a non-empty value extracted %% from the URI. The values extracted are strings, except for 'port' %% which is an integer, 'userinfo' which is a list of strings (split %% on $:), and 'query' which is a list of strings where no $= char %% found, or a {key,value} pair where a $= char is found (initial %% split on $& and subsequent optional split on $=). Possible keys %% are: 'scheme', 'userinfo', 'host', 'port', 'path', 'query', %% 'fragment'. parse(AbsURI, Defaults) -> case parse_scheme(AbsURI) of {error, Reason} -> {error, Reason}; {Scheme, Rest} -> case (catch parse_uri_rest(Rest, true)) of [_|_] = List -> merge_keylists([{scheme, Scheme} | List], Defaults); E -> {error, {malformed_uri, AbsURI, E}} end end. %%%======================================================================== %%% Internal functions %%%======================================================================== parse_scheme(AbsURI) -> split_uri(AbsURI, ":", {error, no_scheme}). parse_uri_rest("//" ++ URIPart, true) -> %% we have an authority {Authority, PathQueryFrag} = split_uri(URIPart, "/|\\?|#", {URIPart, ""}, 1, 0), AuthorityParts = parse_authority(Authority), parse_uri_rest(PathQueryFrag, false) ++ AuthorityParts; parse_uri_rest(PathQueryFrag, _Bool) -> %% no authority, just a path and maybe query {PathQuery, Frag} = split_uri(PathQueryFrag, "#", {PathQueryFrag, ""}), {Path, QueryString} = split_uri(PathQuery, "\\?", {PathQuery, ""}), QueryPropList = split_query(QueryString), [{path, Path}, {'query', QueryPropList}, {fragment, Frag}]. parse_authority(Authority) -> {UserInfo, HostPort} = split_uri(Authority, "@", {"", Authority}), UserInfoSplit = case re:split(UserInfo, ":", [{return, list}]) of [""] -> []; UIS -> UIS end, [{userinfo, UserInfoSplit} | parse_host_port(HostPort)]. parse_host_port("[" ++ HostPort) -> %ipv6 {Host, ColonPort} = split_uri(HostPort, "\\]", {HostPort, ""}), [{host, Host} | case split_uri(ColonPort, ":", not_found, 0, 1) of not_found -> case ColonPort of [] -> []; _ -> throw({invalid_port, ColonPort}) end; {_, Port} -> [{port, list_to_integer(Port)}] end]; parse_host_port(HostPort) -> {Host, Port} = split_uri(HostPort, ":", {HostPort, not_found}), [{host, Host} | case Port of not_found -> []; _ -> [{port, list_to_integer(Port)}] end]. split_query(Query) -> case re:split(Query, "&", [{return, list}]) of [""] -> []; QParams -> [split_uri(Param, "=", Param) || Param <- QParams] end. split_uri(UriPart, SplitChar, NoMatchResult) -> split_uri(UriPart, SplitChar, NoMatchResult, 1, 1). split_uri(UriPart, SplitChar, NoMatchResult, SkipLeft, SkipRight) -> case re:run(UriPart, SplitChar) of {match, [{Match, _}]} -> {string:substr(UriPart, 1, Match + 1 - SkipLeft), string:substr(UriPart, Match + 1 + SkipRight, length(UriPart))}; nomatch -> NoMatchResult end. merge_keylists(A, B) -> {AEmpty, ANonEmpty} = lists:partition(fun ({_Key, V}) -> V =:= [] end, A), [AEmptyS, ANonEmptyS, BS] = [lists:ukeysort(1, X) || X <- [AEmpty, ANonEmpty, B]], lists:ukeymerge(1, lists:ukeymerge(1, ANonEmptyS, BS), AEmptyS). rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/amqp_channel_sup.erl0000644000177700017770000000627312633765070030065 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% %% @private -module(amqp_channel_sup). -include("amqp_client_internal.hrl"). -behaviour(supervisor2). -export([start_link/6]). -export([init/1]). %%--------------------------------------------------------------------------- %% Interface %%--------------------------------------------------------------------------- start_link(Type, Connection, ConnName, InfraArgs, ChNumber, Consumer = {_, _}) -> Identity = {ConnName, ChNumber}, {ok, Sup} = supervisor2:start_link(?MODULE, [Consumer, Identity]), [{gen_consumer, ConsumerPid, _, _}] = supervisor2:which_children(Sup), {ok, ChPid} = supervisor2:start_child( Sup, {channel, {amqp_channel, start_link, [Type, Connection, ChNumber, ConsumerPid, Identity]}, intrinsic, ?MAX_WAIT, worker, [amqp_channel]}), Writer = start_writer(Sup, Type, InfraArgs, ConnName, ChNumber, ChPid), amqp_channel:set_writer(ChPid, Writer), {ok, AState} = init_command_assembler(Type), {ok, Sup, {ChPid, AState}}. %%--------------------------------------------------------------------------- %% Internal plumbing %%--------------------------------------------------------------------------- start_writer(_Sup, direct, [ConnPid, Node, User, VHost, Collector], ConnName, ChNumber, ChPid) -> {ok, RabbitCh} = rpc:call(Node, rabbit_direct, start_channel, [ChNumber, ChPid, ConnPid, ConnName, ?PROTOCOL, User, VHost, ?CLIENT_CAPABILITIES, Collector]), RabbitCh; start_writer(Sup, network, [Sock, FrameMax], ConnName, ChNumber, ChPid) -> {ok, Writer} = supervisor2:start_child( Sup, {writer, {rabbit_writer, start_link, [Sock, ChNumber, FrameMax, ?PROTOCOL, ChPid, {ConnName, ChNumber}]}, intrinsic, ?MAX_WAIT, worker, [rabbit_writer]}), Writer. init_command_assembler(direct) -> {ok, none}; init_command_assembler(network) -> rabbit_command_assembler:init(?PROTOCOL). %%--------------------------------------------------------------------------- %% supervisor2 callbacks %%--------------------------------------------------------------------------- init([{ConsumerModule, ConsumerArgs}, Identity]) -> {ok, {{one_for_all, 0, 1}, [{gen_consumer, {amqp_gen_consumer, start_link, [ConsumerModule, ConsumerArgs, Identity]}, intrinsic, ?MAX_WAIT, worker, [amqp_gen_consumer]}]}}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/amqp_channel_sup_sup.erl0000644000177700017770000000321212633765070030742 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% %% @private -module(amqp_channel_sup_sup). -include("amqp_client.hrl"). -behaviour(supervisor2). -export([start_link/3, start_channel_sup/4]). -export([init/1]). %%--------------------------------------------------------------------------- %% Interface %%--------------------------------------------------------------------------- start_link(Type, Connection, ConnName) -> supervisor2:start_link(?MODULE, [Type, Connection, ConnName]). start_channel_sup(Sup, InfraArgs, ChannelNumber, Consumer) -> supervisor2:start_child(Sup, [InfraArgs, ChannelNumber, Consumer]). %%--------------------------------------------------------------------------- %% supervisor2 callbacks %%--------------------------------------------------------------------------- init([Type, Connection, ConnName]) -> {ok, {{simple_one_for_one, 0, 1}, [{channel_sup, {amqp_channel_sup, start_link, [Type, Connection, ConnName]}, temporary, brutal_kill, supervisor, [amqp_channel_sup]}]}}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/amqp_gen_connection.erl0000644000177700017770000003610712633765070030555 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% %% @private -module(amqp_gen_connection). -include("amqp_client_internal.hrl"). -behaviour(gen_server). -export([start_link/2, connect/1, open_channel/3, hard_error_in_channel/3, channel_internal_error/3, server_misbehaved/2, channels_terminated/1, close/3, server_close/2, info/2, info_keys/0, info_keys/1, register_blocked_handler/2]). -export([behaviour_info/1]). -export([init/1, terminate/2, code_change/3, handle_call/3, handle_cast/2, handle_info/2]). -define(INFO_KEYS, [server_properties, is_closing, amqp_params, num_channels, channel_max]). -record(state, {module, module_state, channels_manager, amqp_params, channel_max, server_properties, %% connection.block, connection.unblock handler block_handler, closing = false %% #closing{} | false }). -record(closing, {reason, close, from = none}). %%--------------------------------------------------------------------------- %% Interface %%--------------------------------------------------------------------------- start_link(TypeSup, AMQPParams) -> gen_server:start_link(?MODULE, {TypeSup, AMQPParams}, []). connect(Pid) -> gen_server:call(Pid, connect, infinity). open_channel(Pid, ProposedNumber, Consumer) -> case gen_server:call(Pid, {command, {open_channel, ProposedNumber, Consumer}}, infinity) of {ok, ChannelPid} -> ok = amqp_channel:open(ChannelPid), {ok, ChannelPid}; Error -> Error end. hard_error_in_channel(Pid, ChannelPid, Reason) -> gen_server:cast(Pid, {hard_error_in_channel, ChannelPid, Reason}). channel_internal_error(Pid, ChannelPid, Reason) -> gen_server:cast(Pid, {channel_internal_error, ChannelPid, Reason}). server_misbehaved(Pid, AmqpError) -> gen_server:cast(Pid, {server_misbehaved, AmqpError}). channels_terminated(Pid) -> gen_server:cast(Pid, channels_terminated). close(Pid, Close, Timeout) -> gen_server:call(Pid, {command, {close, Close, Timeout}}, infinity). server_close(Pid, Close) -> gen_server:cast(Pid, {server_close, Close}). info(Pid, Items) -> gen_server:call(Pid, {info, Items}, infinity). info_keys() -> ?INFO_KEYS. info_keys(Pid) -> gen_server:call(Pid, info_keys, infinity). %%--------------------------------------------------------------------------- %% Behaviour %%--------------------------------------------------------------------------- behaviour_info(callbacks) -> [ %% init() -> {ok, InitialState} {init, 0}, %% terminate(Reason, FinalState) -> Ignored {terminate, 2}, %% connect(AmqpParams, SIF, TypeSup, State) -> %% {ok, ConnectParams} | {closing, ConnectParams, AmqpError, Reply} | %% {error, Error} %% where %% ConnectParams = {ServerProperties, ChannelMax, ChMgr, NewState} {connect, 4}, %% do(Method, State) -> Ignored {do, 2}, %% open_channel_args(State) -> OpenChannelArgs {open_channel_args, 1}, %% i(InfoItem, State) -> Info {i, 2}, %% info_keys() -> [InfoItem] {info_keys, 0}, %% CallbackReply = {ok, NewState} | {stop, Reason, FinalState} %% handle_message(Message, State) -> CallbackReply {handle_message, 2}, %% closing(flush|abrupt, Reason, State) -> CallbackReply {closing, 3}, %% channels_terminated(State) -> CallbackReply {channels_terminated, 1} ]; behaviour_info(_Other) -> undefined. callback(Function, Params, State = #state{module = Mod, module_state = MState}) -> case erlang:apply(Mod, Function, Params ++ [MState]) of {ok, NewMState} -> {noreply, State#state{module_state = NewMState}}; {stop, Reason, NewMState} -> {stop, Reason, State#state{module_state = NewMState}} end. %%--------------------------------------------------------------------------- %% gen_server callbacks %%--------------------------------------------------------------------------- init({TypeSup, AMQPParams}) -> %% Trapping exits since we need to make sure that the `terminate/2' is %% called in the case of direct connection (it does not matter for a network %% connection). See bug25116. process_flag(trap_exit, true), %% connect() has to be called first, so we can use a special state here {ok, {TypeSup, AMQPParams}}. handle_call(connect, _From, {TypeSup, AMQPParams}) -> {Type, Mod} = amqp_connection_type_sup:type_module(AMQPParams), {ok, MState} = Mod:init(), SIF = amqp_connection_type_sup:start_infrastructure_fun( TypeSup, self(), Type), State = #state{module = Mod, module_state = MState, amqp_params = AMQPParams, block_handler = none}, case Mod:connect(AMQPParams, SIF, TypeSup, MState) of {ok, Params} -> {reply, {ok, self()}, after_connect(Params, State)}; {closing, #amqp_error{name = access_refused} = AmqpError, Error} -> {stop, {shutdown, AmqpError}, Error, State}; {closing, Params, #amqp_error{} = AmqpError, Error} -> server_misbehaved(self(), AmqpError), {reply, Error, after_connect(Params, State)}; {error, _} = Error -> {stop, {shutdown, Error}, Error, State} end; handle_call({command, Command}, From, State = #state{closing = false}) -> handle_command(Command, From, State); handle_call({command, _Command}, _From, State) -> {reply, closing, State}; handle_call({info, Items}, _From, State) -> {reply, [{Item, i(Item, State)} || Item <- Items], State}; handle_call(info_keys, _From, State = #state{module = Mod}) -> {reply, ?INFO_KEYS ++ Mod:info_keys(), State}. after_connect({ServerProperties, ChannelMax, ChMgr, NewMState}, State) -> case ChannelMax of 0 -> ok; _ -> amqp_channels_manager:set_channel_max(ChMgr, ChannelMax) end, State1 = State#state{server_properties = ServerProperties, channel_max = ChannelMax, channels_manager = ChMgr, module_state = NewMState}, rabbit_misc:store_proc_name(?MODULE, i(name, State1)), State1. handle_cast({method, Method, none, noflow}, State) -> handle_method(Method, State); handle_cast(channels_terminated, State) -> handle_channels_terminated(State); handle_cast({hard_error_in_channel, _Pid, Reason}, State) -> server_initiated_close(Reason, State); handle_cast({channel_internal_error, Pid, Reason}, State) -> ?LOG_WARN("Connection (~p) closing: internal error in channel (~p): ~p~n", [self(), Pid, Reason]), internal_error(Pid, Reason, State); handle_cast({server_misbehaved, AmqpError}, State) -> server_misbehaved_close(AmqpError, State); handle_cast({server_close, #'connection.close'{} = Close}, State) -> server_initiated_close(Close, State); handle_cast({register_blocked_handler, HandlerPid}, State) -> Ref = erlang:monitor(process, HandlerPid), {noreply, State#state{block_handler = {HandlerPid, Ref}}}. %% @private handle_info({'DOWN', _, process, BlockHandler, Reason}, State = #state{block_handler = {BlockHandler, _Ref}}) -> ?LOG_WARN("Connection (~p): Unregistering block handler ~p because it died. " "Reason: ~p~n", [self(), BlockHandler, Reason]), {noreply, State#state{block_handler = none}}; handle_info(Info, State) -> callback(handle_message, [Info], State). terminate(Reason, #state{module = Mod, module_state = MState}) -> Mod:terminate(Reason, MState). code_change(_OldVsn, State, _Extra) -> {ok, State}. %%--------------------------------------------------------------------------- %% Infos %%--------------------------------------------------------------------------- i(server_properties, State) -> State#state.server_properties; i(is_closing, State) -> State#state.closing =/= false; i(amqp_params, State) -> State#state.amqp_params; i(channel_max, State) -> State#state.channel_max; i(num_channels, State) -> amqp_channels_manager:num_channels( State#state.channels_manager); i(Item, #state{module = Mod, module_state = MState}) -> Mod:i(Item, MState). %%--------------------------------------------------------------------------- %% connection.blocked, connection.unblocked %%--------------------------------------------------------------------------- register_blocked_handler(Pid, HandlerPid) -> gen_server:cast(Pid, {register_blocked_handler, HandlerPid}). %%--------------------------------------------------------------------------- %% Command handling %%--------------------------------------------------------------------------- handle_command({open_channel, ProposedNumber, Consumer}, _From, State = #state{channels_manager = ChMgr, module = Mod, module_state = MState}) -> {reply, amqp_channels_manager:open_channel(ChMgr, ProposedNumber, Consumer, Mod:open_channel_args(MState)), State}; handle_command({close, #'connection.close'{} = Close, Timeout}, From, State) -> app_initiated_close(Close, From, Timeout, State). %%--------------------------------------------------------------------------- %% Handling methods from broker %%--------------------------------------------------------------------------- handle_method(#'connection.close'{} = Close, State) -> server_initiated_close(Close, State); handle_method(#'connection.close_ok'{}, State = #state{closing = Closing}) -> case Closing of #closing{from = none} -> ok; #closing{from = From} -> gen_server:reply(From, ok) end, {stop, {shutdown, closing_to_reason(Closing)}, State}; handle_method(#'connection.blocked'{} = Blocked, State = #state{block_handler = BlockHandler}) -> case BlockHandler of none -> ok; {Pid, _Ref} -> Pid ! Blocked end, {noreply, State}; handle_method(#'connection.unblocked'{} = Unblocked, State = #state{block_handler = BlockHandler}) -> case BlockHandler of none -> ok; {Pid, _Ref} -> Pid ! Unblocked end, {noreply, State}; handle_method(Other, State) -> server_misbehaved_close(#amqp_error{name = command_invalid, explanation = "unexpected method on " "channel 0", method = element(1, Other)}, State). %%--------------------------------------------------------------------------- %% Closing %%--------------------------------------------------------------------------- app_initiated_close(Close, From, Timeout, State) -> case Timeout of infinity -> ok; _ -> erlang:send_after(Timeout, self(), closing_timeout) end, set_closing_state(flush, #closing{reason = app_initiated_close, close = Close, from = From}, State). internal_error(Pid, Reason, State) -> Str = list_to_binary(rabbit_misc:format("~p:~p", [Pid, Reason])), Close = #'connection.close'{reply_text = Str, reply_code = ?INTERNAL_ERROR, class_id = 0, method_id = 0}, set_closing_state(abrupt, #closing{reason = internal_error, close = Close}, State). server_initiated_close(Close, State) -> ?LOG_WARN("Connection (~p) closing: received hard error ~p " "from server~n", [self(), Close]), set_closing_state(abrupt, #closing{reason = server_initiated_close, close = Close}, State). server_misbehaved_close(AmqpError, State) -> ?LOG_WARN("Connection (~p) closing: server misbehaved: ~p~n", [self(), AmqpError]), {0, Close} = rabbit_binary_generator:map_exception(0, AmqpError, ?PROTOCOL), set_closing_state(abrupt, #closing{reason = server_misbehaved, close = Close}, State). set_closing_state(ChannelCloseType, NewClosing, State = #state{channels_manager = ChMgr, closing = CurClosing}) -> ResClosing = case closing_priority(NewClosing) =< closing_priority(CurClosing) of true -> NewClosing; false -> CurClosing end, ClosingReason = closing_to_reason(ResClosing), amqp_channels_manager:signal_connection_closing(ChMgr, ChannelCloseType, ClosingReason), callback(closing, [ChannelCloseType, ClosingReason], State#state{closing = ResClosing}). closing_priority(false) -> 99; closing_priority(#closing{reason = app_initiated_close}) -> 4; closing_priority(#closing{reason = internal_error}) -> 3; closing_priority(#closing{reason = server_misbehaved}) -> 2; closing_priority(#closing{reason = server_initiated_close}) -> 1. closing_to_reason(#closing{close = #'connection.close'{reply_code = 200}}) -> normal; closing_to_reason(#closing{reason = Reason, close = #'connection.close'{reply_code = Code, reply_text = Text}}) -> {Reason, Code, Text}; closing_to_reason(#closing{reason = Reason, close = {Reason, _Code, _Text} = Close}) -> Close. handle_channels_terminated(State = #state{closing = Closing, module = Mod, module_state = MState}) -> #closing{reason = Reason, close = Close, from = From} = Closing, case Reason of server_initiated_close -> Mod:do(#'connection.close_ok'{}, MState); _ -> Mod:do(Close, MState) end, case callback(channels_terminated, [], State) of {stop, _, _} = Stop -> case From of none -> ok; _ -> gen_server:reply(From, ok) end, Stop; Other -> Other end. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/amqp_connection.erl0000644000177700017770000003500212633765070027715 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% %% @type close_reason(Type) = {shutdown, amqp_reason(Type)}. %% @type amqp_reason(Type) = {Type, Code, Text} %% Code = non_neg_integer() %% Text = binary(). %% @doc This module is responsible for maintaining a connection to an AMQP %% broker and manages channels within the connection. This module is used to %% open and close connections to the broker as well as creating new channels %% within a connection.
    %% The connections and channels created by this module are supervised under %% amqp_client's supervision tree. Please note that connections and channels %% do not get restarted automatically by the supervision tree in the case of a %% failure. If you need robust connections and channels, we recommend you use %% Erlang monitors on the returned connection and channel PIDs.
    %%
    %% In case of a failure or an AMQP error, the connection process exits with a %% meaningful exit reason:
    %%
    %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %%
    CauseExit reason
    Any reason, where Code would have been 200 otherwise```normal'''
    User application calls amqp_connection:close/3```close_reason(app_initiated_close)'''
    Server closes connection (hard error)```close_reason(server_initiated_close)'''
    Server misbehaved (did not follow protocol)```close_reason(server_misbehaved)'''
    AMQP client internal error - usually caused by a channel exiting %% with an unusual reason. This is usually accompanied by a more %% detailed error log from the channel```close_reason(internal_error)'''
    Other error(various error reasons, causing more detailed logging)
    %%
    %% See type definitions below. -module(amqp_connection). -include("amqp_client_internal.hrl"). -export([open_channel/1, open_channel/2, open_channel/3, register_blocked_handler/2]). -export([start/1, close/1, close/2, close/3]). -export([error_atom/1]). -export([info/2, info_keys/1, info_keys/0]). -export([socket_adapter_info/2]). -define(DEFAULT_CONSUMER, {amqp_selective_consumer, []}). -define(PROTOCOL_SSL_PORT, (?PROTOCOL_PORT - 1)). %%--------------------------------------------------------------------------- %% Type Definitions %%--------------------------------------------------------------------------- %% @type amqp_adapter_info() = #amqp_adapter_info{}. %% @type amqp_params_direct() = #amqp_params_direct{}. %% As defined in amqp_client.hrl. It contains the following fields: %%
      %%
    • username :: binary() - The name of a user registered with the broker, %% defaults to <<guest">>
    • %%
    • password :: binary() - The password of user, defaults to 'none'
    • %%
    • virtual_host :: binary() - The name of a virtual host in the broker, %% defaults to <<"/">>
    • %%
    • node :: atom() - The node the broker runs on (direct only)
    • %%
    • adapter_info :: amqp_adapter_info() - Extra management information for if %% this connection represents a non-AMQP network connection.
    • %%
    • client_properties :: [{binary(), atom(), binary()}] - A list of extra %% client properties to be sent to the server, defaults to []
    • %%
    %% %% @type amqp_params_network() = #amqp_params_network{}. %% As defined in amqp_client.hrl. It contains the following fields: %%
      %%
    • username :: binary() - The name of a user registered with the broker, %% defaults to <<guest">>
    • %%
    • password :: binary() - The user's password, defaults to %% <<"guest">>
    • %%
    • virtual_host :: binary() - The name of a virtual host in the broker, %% defaults to <<"/">>
    • %%
    • host :: string() - The hostname of the broker, %% defaults to "localhost" (network only)
    • %%
    • port :: integer() - The port the broker is listening on, %% defaults to 5672 (network only)
    • %%
    • channel_max :: non_neg_integer() - The channel_max handshake parameter, %% defaults to 0
    • %%
    • frame_max :: non_neg_integer() - The frame_max handshake parameter, %% defaults to 0 (network only)
    • %%
    • heartbeat :: non_neg_integer() - The hearbeat interval in seconds, %% defaults to 0 (turned off) (network only)
    • %%
    • connection_timeout :: non_neg_integer() | 'infinity' %% - The connection timeout in milliseconds, %% defaults to 'infinity' (network only)
    • %%
    • ssl_options :: term() - The second parameter to be used with the %% ssl:connect/2 function, defaults to 'none' (network only)
    • %%
    • client_properties :: [{binary(), atom(), binary()}] - A list of extra %% client properties to be sent to the server, defaults to []
    • %%
    • socket_options :: [any()] - Extra socket options. These are %% appended to the default options. See %% inet:setopts/2 %% and %% gen_tcp:connect/4 for descriptions of the available options.
    • %%
    %%--------------------------------------------------------------------------- %% Starting a connection %%--------------------------------------------------------------------------- %% @spec (Params) -> {ok, Connection} | {error, Error} %% where %% Params = amqp_params_network() | amqp_params_direct() %% Connection = pid() %% @doc Starts a connection to an AMQP server. Use network params to %% connect to a remote AMQP server or direct params for a direct %% connection to a RabbitMQ server, assuming that the server is %% running in the same process space. If the port is set to 'undefined', %% the default ports will be selected depending on whether this is a %% normal or an SSL connection. start(AmqpParams) -> ensure_started(), AmqpParams1 = case AmqpParams of #amqp_params_network{port = undefined, ssl_options = none} -> AmqpParams#amqp_params_network{port = ?PROTOCOL_PORT}; #amqp_params_network{port = undefined, ssl_options = _} -> AmqpParams#amqp_params_network{port = ?PROTOCOL_SSL_PORT}; _ -> AmqpParams end, {ok, _Sup, Connection} = amqp_sup:start_connection_sup(AmqpParams1), amqp_gen_connection:connect(Connection). %% Usually the amqp_client application will already be running. We %% check whether that is the case by invoking an undocumented function %% which does not require a synchronous call to the application %% controller. That way we don't risk a dead-lock if, say, the %% application controller is in the process of shutting down the very %% application which is making this call. ensure_started() -> [ensure_started(App) || App <- [xmerl, amqp_client]]. ensure_started(App) -> case application_controller:get_master(App) of undefined -> case application:start(App) of ok -> ok; {error, {already_started, App}} -> ok; {error, _} = E -> throw(E) end; _ -> ok end. %%--------------------------------------------------------------------------- %% Commands %%--------------------------------------------------------------------------- %% @doc Invokes open_channel(ConnectionPid, none, %% {amqp_selective_consumer, []}). Opens a channel without having to %% specify a channel number. This uses the default consumer %% implementation. open_channel(ConnectionPid) -> open_channel(ConnectionPid, none, ?DEFAULT_CONSUMER). %% @doc Invokes open_channel(ConnectionPid, none, Consumer). %% Opens a channel without having to specify a channel number. open_channel(ConnectionPid, {_, _} = Consumer) -> open_channel(ConnectionPid, none, Consumer); %% @doc Invokes open_channel(ConnectionPid, ChannelNumber, %% {amqp_selective_consumer, []}). Opens a channel, using the default %% consumer implementation. open_channel(ConnectionPid, ChannelNumber) when is_number(ChannelNumber) orelse ChannelNumber =:= none -> open_channel(ConnectionPid, ChannelNumber, ?DEFAULT_CONSUMER). %% @spec (ConnectionPid, ChannelNumber, Consumer) -> Result %% where %% ConnectionPid = pid() %% ChannelNumber = pos_integer() | 'none' %% Consumer = {ConsumerModule, ConsumerArgs} %% ConsumerModule = atom() %% ConsumerArgs = [any()] %% Result = {ok, ChannelPid} | {error, Error} %% ChannelPid = pid() %% @doc Opens an AMQP channel.
    %% Opens a channel, using a proposed channel number and a specific consumer %% implementation.
    %% ConsumerModule must implement the amqp_gen_consumer behaviour. ConsumerArgs %% is passed as parameter to ConsumerModule:init/1.
    %% This function assumes that an AMQP connection (networked or direct) %% has already been successfully established.
    %% ChannelNumber must be less than or equal to the negotiated %% max_channel value, or less than or equal to ?MAX_CHANNEL_NUMBER %% (65535) if the negotiated max_channel value is 0.
    %% In the direct connection, max_channel is always 0. open_channel(ConnectionPid, ChannelNumber, {_ConsumerModule, _ConsumerArgs} = Consumer) -> amqp_gen_connection:open_channel(ConnectionPid, ChannelNumber, Consumer). %% @spec (ConnectionPid) -> ok | Error %% where %% ConnectionPid = pid() %% @doc Closes the channel, invokes %% close(Channel, 200, <<"Goodbye">>). close(ConnectionPid) -> close(ConnectionPid, 200, <<"Goodbye">>). %% @spec (ConnectionPid, Timeout) -> ok | Error %% where %% ConnectionPid = pid() %% Timeout = integer() %% @doc Closes the channel, using the supplied Timeout value. close(ConnectionPid, Timeout) -> close(ConnectionPid, 200, <<"Goodbye">>, Timeout). %% @spec (ConnectionPid, Code, Text) -> ok | closing %% where %% ConnectionPid = pid() %% Code = integer() %% Text = binary() %% @doc Closes the AMQP connection, allowing the caller to set the reply %% code and text. close(ConnectionPid, Code, Text) -> close(ConnectionPid, Code, Text, infinity). %% @spec (ConnectionPid, Code, Text, Timeout) -> ok | closing %% where %% ConnectionPid = pid() %% Code = integer() %% Text = binary() %% Timeout = integer() %% @doc Closes the AMQP connection, allowing the caller to set the reply %% code and text, as well as a timeout for the operation, after which the %% connection will be abruptly terminated. close(ConnectionPid, Code, Text, Timeout) -> Close = #'connection.close'{reply_text = Text, reply_code = Code, class_id = 0, method_id = 0}, amqp_gen_connection:close(ConnectionPid, Close, Timeout). register_blocked_handler(ConnectionPid, BlockHandler) -> amqp_gen_connection:register_blocked_handler(ConnectionPid, BlockHandler). %%--------------------------------------------------------------------------- %% Other functions %%--------------------------------------------------------------------------- %% @spec (Code) -> atom() %% where %% Code = integer() %% @doc Returns a descriptive atom corresponding to the given AMQP %% error code. error_atom(Code) -> ?PROTOCOL:amqp_exception(Code). %% @spec (ConnectionPid, Items) -> ResultList %% where %% ConnectionPid = pid() %% Items = [Item] %% ResultList = [{Item, Result}] %% Item = atom() %% Result = term() %% @doc Returns information about the connection, as specified by the Items %% list. Item may be any atom returned by info_keys/1: %%
      %%
    • type - returns the type of the connection (network or direct)
    • %%
    • server_properties - returns the server_properties fields sent by the %% server while establishing the connection
    • %%
    • is_closing - returns true if the connection is in the process of closing %% and false otherwise
    • %%
    • amqp_params - returns the #amqp_params{} structure used to start the %% connection
    • %%
    • num_channels - returns the number of channels currently open under the %% connection (excluding channel 0)
    • %%
    • channel_max - returns the channel_max value negotiated with the %% server
    • %%
    • heartbeat - returns the heartbeat value negotiated with the server %% (only for the network connection)
    • %%
    • frame_max - returns the frame_max value negotiated with the %% server (only for the network connection)
    • %%
    • sock - returns the socket for the network connection (for use with %% e.g. inet:sockname/1) (only for the network connection)
    • %%
    • any other value - throws an exception
    • %%
    info(ConnectionPid, Items) -> amqp_gen_connection:info(ConnectionPid, Items). %% @spec (ConnectionPid) -> Items %% where %% ConnectionPid = pid() %% Items = [Item] %% Item = atom() %% @doc Returns a list of atoms that can be used in conjunction with info/2. %% Note that the list differs from a type of connection to another (network vs. %% direct). Use info_keys/0 to get a list of info keys that can be used for %% any connection. info_keys(ConnectionPid) -> amqp_gen_connection:info_keys(ConnectionPid). %% @spec () -> Items %% where %% Items = [Item] %% Item = atom() %% @doc Returns a list of atoms that can be used in conjunction with info/2. %% These are general info keys, which can be used in any type of connection. %% Other info keys may exist for a specific type. To get the full list of %% atoms that can be used for a certain connection, use info_keys/1. info_keys() -> amqp_gen_connection:info_keys(). %% @doc Takes a socket and a protocol, returns an #amqp_adapter_info{} %% based on the socket for the protocol given. socket_adapter_info(Sock, Protocol) -> amqp_direct_connection:socket_adapter_info(Sock, Protocol). rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/amqp_direct_consumer.erl0000644000177700017770000000614612633765070030752 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2011-2015 Pivotal Software, Inc. All rights reserved. %% %% @doc This module is an implementation of the amqp_gen_consumer %% behaviour and can be used as part of the Consumer parameter when %% opening AMQP channels. %%
    %%
    %% The Consumer parameter for this implementation is {{@module}, %% [ConsumerPid]@}, where ConsumerPid is a process that will receive %% queue subscription-related messages.
    %%
    %% This consumer implementation causes the channel to send to the %% ConsumerPid all basic.consume, basic.consume_ok, basic.cancel, %% basic.cancel_ok and basic.deliver messages received from the %% server. %%
    %%
    %% In addition, this consumer implementation monitors the ConsumerPid %% and exits with the same shutdown reason when it dies. 'DOWN' %% messages from other sources are passed to ConsumerPid. %%
    %% Warning! It is not recommended to rely on a consumer on killing off the %% channel (through the exit signal). That may cause messages to get lost. %% Always use amqp_channel:close/{1,3} for a clean shut down.
    %%
    %% This module has no public functions. -module(amqp_direct_consumer). -include("amqp_gen_consumer_spec.hrl"). -behaviour(amqp_gen_consumer). -export([init/1, handle_consume_ok/3, handle_consume/3, handle_cancel_ok/3, handle_cancel/2, handle_server_cancel/2, handle_deliver/3, handle_deliver/4, handle_info/2, handle_call/3, terminate/2]). %%--------------------------------------------------------------------------- %% amqp_gen_consumer callbacks %%--------------------------------------------------------------------------- %% @private init([ConsumerPid]) -> erlang:monitor(process, ConsumerPid), {ok, ConsumerPid}. %% @private handle_consume(M, A, C) -> C ! {M, A}, {ok, C}. %% @private handle_consume_ok(M, _, C) -> C ! M, {ok, C}. %% @private handle_cancel(M, C) -> C ! M, {ok, C}. %% @private handle_cancel_ok(M, _, C) -> C ! M, {ok, C}. %% @private handle_server_cancel(M, C) -> C ! {server_cancel, M}, {ok, C}. %% @private handle_deliver(M, A, C) -> C ! {M, A}, {ok, C}. handle_deliver(M, A, DeliveryCtx, C) -> C ! {M, A, DeliveryCtx}, {ok, C}. %% @private handle_info({'DOWN', _MRef, process, C, Info}, C) -> {error, {consumer_died, Info}, C}; handle_info({'DOWN', MRef, process, Pid, Info}, C) -> C ! {'DOWN', MRef, process, Pid, Info}, {ok, C}. %% @private handle_call(M, A, C) -> C ! {M, A}, {reply, ok, C}. %% @private terminate(_Reason, C) -> C. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/amqp_selective_consumer.erl0000644000177700017770000002463512633765070031466 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public Licensbe %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2011-2015 Pivotal Software, Inc. All rights reserved. %% %% @doc This module is an implementation of the amqp_gen_consumer %% behaviour and can be used as part of the Consumer parameter when %% opening AMQP channels. This is the default implementation selected %% by channel.
    %%
    %% The Consumer parameter for this implementation is {{@module}, []@}
    %% This consumer implementation keeps track of consumer tags and sends %% the subscription-relevant messages to the registered consumers, according %% to an internal tag dictionary.
    %%
    %% Send a #basic.consume{} message to the channel to subscribe a %% consumer to a queue and send a #basic.cancel{} message to cancel a %% subscription.
    %%
    %% The channel will send to the relevant registered consumers the %% basic.consume_ok, basic.cancel_ok, basic.cancel and basic.deliver messages %% received from the server.
    %%
    %% If a consumer is not registered for a given consumer tag, the message %% is sent to the default consumer registered with %% {@module}:register_default_consumer. If there is no default consumer %% registered in this case, an exception occurs and the channel is abruptly %% terminated.
    -module(amqp_selective_consumer). -include("amqp_gen_consumer_spec.hrl"). -behaviour(amqp_gen_consumer). -export([register_default_consumer/2]). -export([init/1, handle_consume_ok/3, handle_consume/3, handle_cancel_ok/3, handle_cancel/2, handle_server_cancel/2, handle_deliver/3, handle_deliver/4, handle_info/2, handle_call/3, terminate/2]). -record(state, {consumers = dict:new(), %% Tag -> ConsumerPid unassigned = undefined, %% Pid monitors = dict:new(), %% Pid -> {Count, MRef} default_consumer = none}). %%--------------------------------------------------------------------------- %% Interface %%--------------------------------------------------------------------------- %% @spec (ChannelPid, ConsumerPid) -> ok %% where %% ChannelPid = pid() %% ConsumerPid = pid() %% @doc This function registers a default consumer with the channel. A %% default consumer is used when a subscription is made via %% amqp_channel:call(ChannelPid, #'basic.consume'{}) (rather than %% {@module}:subscribe/3) and hence there is no consumer pid %% registered with the consumer tag. In this case, the relevant %% deliveries will be sent to the default consumer. register_default_consumer(ChannelPid, ConsumerPid) -> amqp_channel:call_consumer(ChannelPid, {register_default_consumer, ConsumerPid}). %%--------------------------------------------------------------------------- %% amqp_gen_consumer callbacks %%--------------------------------------------------------------------------- %% @private init([]) -> {ok, #state{}}. %% @private handle_consume(#'basic.consume'{consumer_tag = Tag, nowait = NoWait}, Pid, State = #state{consumers = Consumers, monitors = Monitors}) -> Result = case NoWait of true when Tag =:= undefined orelse size(Tag) == 0 -> no_consumer_tag_specified; _ when is_binary(Tag) andalso size(Tag) >= 0 -> case resolve_consumer(Tag, State) of {consumer, _} -> consumer_tag_in_use; _ -> ok end; _ -> ok end, case {Result, NoWait} of {ok, true} -> {ok, State#state {consumers = dict:store(Tag, Pid, Consumers), monitors = add_to_monitor_dict(Pid, Monitors)}}; {ok, false} -> {ok, State#state{unassigned = Pid}}; {Err, true} -> {error, Err, State}; {_Err, false} -> %% Don't do anything (don't override existing %% consumers), the server will close the channel with an error. {ok, State} end. %% @private handle_consume_ok(BasicConsumeOk, _BasicConsume, State = #state{unassigned = Pid, consumers = Consumers, monitors = Monitors}) when is_pid(Pid) -> State1 = State#state{ consumers = dict:store(tag(BasicConsumeOk), Pid, Consumers), monitors = add_to_monitor_dict(Pid, Monitors), unassigned = undefined}, deliver(BasicConsumeOk, State1), {ok, State1}. %% @private %% We sent a basic.cancel. handle_cancel(#'basic.cancel'{nowait = true}, #state{default_consumer = none}) -> exit(cancel_nowait_requires_default_consumer); handle_cancel(Cancel = #'basic.cancel'{nowait = NoWait}, State) -> State1 = case NoWait of true -> do_cancel(Cancel, State); false -> State end, {ok, State1}. %% @private %% We sent a basic.cancel and now receive the ok. handle_cancel_ok(CancelOk, _Cancel, State) -> State1 = do_cancel(CancelOk, State), %% Use old state deliver(CancelOk, State), {ok, State1}. %% @private %% The server sent a basic.cancel. handle_server_cancel(Cancel = #'basic.cancel'{nowait = true}, State) -> State1 = do_cancel(Cancel, State), %% Use old state deliver(Cancel, State), {ok, State1}. %% @private handle_deliver(Method, Message, State) -> deliver(Method, Message, State), {ok, State}. %% @private handle_deliver(Method, Message, DeliveryCtx, State) -> deliver(Method, Message, DeliveryCtx, State), {ok, State}. %% @private handle_info({'DOWN', _MRef, process, Pid, _Info}, State = #state{monitors = Monitors, consumers = Consumers, default_consumer = DConsumer }) -> case dict:find(Pid, Monitors) of {ok, _CountMRef} -> {ok, State#state{monitors = dict:erase(Pid, Monitors), consumers = dict:filter( fun (_, Pid1) when Pid1 =:= Pid -> false; (_, _) -> true end, Consumers)}}; error -> case Pid of DConsumer -> {ok, State#state{ monitors = dict:erase(Pid, Monitors), default_consumer = none}}; _ -> {ok, State} %% unnamed consumer went down %% before receiving consume_ok end end. %% @private handle_call({register_default_consumer, Pid}, _From, State = #state{default_consumer = PrevPid, monitors = Monitors}) -> Monitors1 = case PrevPid of none -> Monitors; _ -> remove_from_monitor_dict(PrevPid, Monitors) end, {reply, ok, State#state{default_consumer = Pid, monitors = add_to_monitor_dict(Pid, Monitors1)}}. %% @private terminate(_Reason, State) -> State. %%--------------------------------------------------------------------------- %% Internal plumbing %%--------------------------------------------------------------------------- deliver_to_consumer_or_die(Method, Msg, State) -> case resolve_consumer(tag(Method), State) of {consumer, Pid} -> Pid ! Msg; {default, Pid} -> Pid ! Msg; error -> exit(unexpected_delivery_and_no_default_consumer) end. deliver(Method, State) -> deliver(Method, undefined, State). deliver(Method, Message, State) -> Combined = if Message =:= undefined -> Method; true -> {Method, Message} end, deliver_to_consumer_or_die(Method, Combined, State). deliver(Method, Message, DeliveryCtx, State) -> Combined = if Message =:= undefined -> Method; true -> {Method, Message, DeliveryCtx} end, deliver_to_consumer_or_die(Method, Combined, State). do_cancel(Cancel, State = #state{consumers = Consumers, monitors = Monitors}) -> Tag = tag(Cancel), case dict:find(Tag, Consumers) of {ok, Pid} -> State#state{ consumers = dict:erase(Tag, Consumers), monitors = remove_from_monitor_dict(Pid, Monitors)}; error -> %% Untracked consumer. Do nothing. State end. resolve_consumer(Tag, #state{consumers = Consumers, default_consumer = DefaultConsumer}) -> case dict:find(Tag, Consumers) of {ok, ConsumerPid} -> {consumer, ConsumerPid}; error -> case DefaultConsumer of none -> error; _ -> {default, DefaultConsumer} end end. tag(#'basic.consume'{consumer_tag = Tag}) -> Tag; tag(#'basic.consume_ok'{consumer_tag = Tag}) -> Tag; tag(#'basic.cancel'{consumer_tag = Tag}) -> Tag; tag(#'basic.cancel_ok'{consumer_tag = Tag}) -> Tag; tag(#'basic.deliver'{consumer_tag = Tag}) -> Tag. add_to_monitor_dict(Pid, Monitors) -> case dict:find(Pid, Monitors) of error -> dict:store(Pid, {1, erlang:monitor(process, Pid)}, Monitors); {ok, {Count, MRef}} -> dict:store(Pid, {Count + 1, MRef}, Monitors) end. remove_from_monitor_dict(Pid, Monitors) -> case dict:fetch(Pid, Monitors) of {1, MRef} -> erlang:demonitor(MRef), dict:erase(Pid, Monitors); {Count, MRef} -> dict:store(Pid, {Count - 1, MRef}, Monitors) end. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/amqp_connection_sup.erl0000644000177700017770000000361012633765070030604 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% %% @private -module(amqp_connection_sup). -include("amqp_client.hrl"). -behaviour(supervisor2). -export([start_link/1]). -export([init/1]). %%--------------------------------------------------------------------------- %% Interface %%--------------------------------------------------------------------------- start_link(AMQPParams) -> {ok, Sup} = supervisor2:start_link(?MODULE, []), {ok, TypeSup} = supervisor2:start_child( Sup, {connection_type_sup, {amqp_connection_type_sup, start_link, []}, transient, infinity, supervisor, [amqp_connection_type_sup]}), {ok, Connection} = supervisor2:start_child( Sup, {connection, {amqp_gen_connection, start_link, [TypeSup, AMQPParams]}, intrinsic, brutal_kill, worker, [amqp_gen_connection]}), {ok, Sup, Connection}. %%--------------------------------------------------------------------------- %% supervisor2 callbacks %%--------------------------------------------------------------------------- init([]) -> {ok, {{one_for_all, 0, 1}, []}}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/amqp_gen_consumer.erl0000644000177700017770000002463112633765070030250 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2011-2015 Pivotal Software, Inc. All rights reserved. %% %% @doc A behaviour module for implementing consumers for %% amqp_channel. To specify a consumer implementation for a channel, %% use amqp_connection:open_channel/{2,3}. %%
    %% All callbacks are called within the gen_consumer process.
    %%
    %% See comments in amqp_gen_consumer.erl source file for documentation %% on the callback functions. %%
    %% Note that making calls to the channel from the callback module will %% result in deadlock. -module(amqp_gen_consumer). -include("amqp_client.hrl"). -behaviour(gen_server2). -export([start_link/3, call_consumer/2, call_consumer/3, call_consumer/4]). -export([behaviour_info/1]). -export([init/1, terminate/2, code_change/3, handle_call/3, handle_cast/2, handle_info/2, prioritise_info/3]). -record(state, {module, module_state}). %%--------------------------------------------------------------------------- %% Interface %%--------------------------------------------------------------------------- %% @type ok_error() = {ok, state()} | {error, reason(), state()}. %% Denotes a successful or an error return from a consumer module call. start_link(ConsumerModule, ExtraParams, Identity) -> gen_server2:start_link( ?MODULE, [ConsumerModule, ExtraParams, Identity], []). %% @spec (Consumer, Msg) -> ok %% where %% Consumer = pid() %% Msg = any() %% %% @doc This function is used to perform arbitrary calls into the %% consumer module. call_consumer(Pid, Msg) -> gen_server2:call(Pid, {consumer_call, Msg}, infinity). %% @spec (Consumer, Method, Args) -> ok %% where %% Consumer = pid() %% Method = amqp_method() %% Args = any() %% %% @doc This function is used by amqp_channel to forward received %% methods and deliveries to the consumer module. call_consumer(Pid, Method, Args) -> gen_server2:call(Pid, {consumer_call, Method, Args}, infinity). call_consumer(Pid, Method, Args, DeliveryCtx) -> gen_server2:call(Pid, {consumer_call, Method, Args, DeliveryCtx}, infinity). %%--------------------------------------------------------------------------- %% Behaviour %%--------------------------------------------------------------------------- %% @private behaviour_info(callbacks) -> [ %% init(Args) -> {ok, InitialState} | {stop, Reason} | ignore %% where %% Args = [any()] %% InitialState = state() %% Reason = term() %% %% This callback is invoked by the channel, when it starts %% up. Use it to initialize the state of the consumer. In case of %% an error, return {stop, Reason} or ignore. {init, 1}, %% handle_consume(Consume, Sender, State) -> ok_error() %% where %% Consume = #'basic.consume'{} %% Sender = pid() %% State = state() %% %% This callback is invoked by the channel before a basic.consume %% is sent to the server. {handle_consume, 3}, %% handle_consume_ok(ConsumeOk, Consume, State) -> ok_error() %% where %% ConsumeOk = #'basic.consume_ok'{} %% Consume = #'basic.consume'{} %% State = state() %% %% This callback is invoked by the channel every time a %% basic.consume_ok is received from the server. Consume is the original %% method sent out to the server - it can be used to associate the %% call with the response. {handle_consume_ok, 3}, %% handle_cancel(Cancel, State) -> ok_error() %% where %% Cancel = #'basic.cancel'{} %% State = state() %% %% This callback is invoked by the channel every time a basic.cancel %% is sent to the server. {handle_cancel, 2}, %% handle_cancel_ok(CancelOk, Cancel, State) -> ok_error() %% where %% CancelOk = #'basic.cancel_ok'{} %% Cancel = #'basic.cancel'{} %% State = state() %% %% This callback is invoked by the channel every time a basic.cancel_ok %% is received from the server. {handle_cancel_ok, 3}, %% handle_server_cancel(Cancel, State) -> ok_error() %% where %% Cancel = #'basic.cancel'{} %% State = state() %% %% This callback is invoked by the channel every time a basic.cancel %% is received from the server. {handle_server_cancel, 2}, %% handle_deliver(Deliver, Message, State) -> ok_error() %% where %% Deliver = #'basic.deliver'{} %% Message = #amqp_msg{} %% State = state() %% %% This callback is invoked by the channel every time a basic.deliver %% is received from the server. {handle_deliver, 3}, %% handle_deliver(Deliver, Message, %% DeliveryCtx, State) -> ok_error() %% where %% Deliver = #'basic.deliver'{} %% Message = #amqp_msg{} %% DeliveryCtx = {pid(), pid(), pid()} %% State = state() %% %% This callback is invoked by the channel every time a basic.deliver %% is received from the server. Only relevant for channels that use %% direct client connection and manual flow control. {handle_deliver, 4}, %% handle_info(Info, State) -> ok_error() %% where %% Info = any() %% State = state() %% %% This callback is invoked the consumer process receives a %% message. {handle_info, 2}, %% handle_call(Msg, From, State) -> {reply, Reply, NewState} | %% {noreply, NewState} | %% {error, Reason, NewState} %% where %% Msg = any() %% From = any() %% Reply = any() %% State = state() %% NewState = state() %% %% This callback is invoked by the channel when calling %% amqp_channel:call_consumer/2. Reply is the term that %% amqp_channel:call_consumer/2 will return. If the callback %% returns {noreply, _}, then the caller to %% amqp_channel:call_consumer/2 and the channel remain blocked %% until gen_server2:reply/2 is used with the provided From as %% the first argument. {handle_call, 3}, %% terminate(Reason, State) -> any() %% where %% Reason = any() %% State = state() %% %% This callback is invoked by the channel after it has shut down and %% just before its process exits. {terminate, 2} ]; behaviour_info(_Other) -> undefined. %%--------------------------------------------------------------------------- %% gen_server2 callbacks %%--------------------------------------------------------------------------- init([ConsumerModule, ExtraParams, Identity]) -> ?store_proc_name(Identity), case ConsumerModule:init(ExtraParams) of {ok, MState} -> {ok, #state{module = ConsumerModule, module_state = MState}}; {stop, Reason} -> {stop, Reason}; ignore -> ignore end. prioritise_info({'DOWN', _MRef, process, _Pid, _Info}, _Len, _State) -> 1; prioritise_info(_, _Len, _State) -> 0. consumer_call_reply(Return, State) -> case Return of {ok, NewMState} -> {reply, ok, State#state{module_state = NewMState}}; {error, Reason, NewMState} -> {stop, {error, Reason}, {error, Reason}, State#state{module_state = NewMState}} end. handle_call({consumer_call, Msg}, From, State = #state{module = ConsumerModule, module_state = MState}) -> case ConsumerModule:handle_call(Msg, From, MState) of {noreply, NewMState} -> {noreply, State#state{module_state = NewMState}}; {reply, Reply, NewMState} -> {reply, Reply, State#state{module_state = NewMState}}; {error, Reason, NewMState} -> {stop, {error, Reason}, {error, Reason}, State#state{module_state = NewMState}} end; handle_call({consumer_call, Method, Args}, _From, State = #state{module = ConsumerModule, module_state = MState}) -> Return = case Method of #'basic.consume'{} -> ConsumerModule:handle_consume(Method, Args, MState); #'basic.consume_ok'{} -> ConsumerModule:handle_consume_ok(Method, Args, MState); #'basic.cancel'{} -> case Args of none -> %% server-sent ConsumerModule:handle_server_cancel(Method, MState); Pid when is_pid(Pid) -> %% client-sent ConsumerModule:handle_cancel(Method, MState) end; #'basic.cancel_ok'{} -> ConsumerModule:handle_cancel_ok(Method, Args, MState); #'basic.deliver'{} -> ConsumerModule:handle_deliver(Method, Args, MState) end, consumer_call_reply(Return, State); %% only supposed to be used with basic.deliver handle_call({consumer_call, Method = #'basic.deliver'{}, Args, DeliveryCtx}, _From, State = #state{module = ConsumerModule, module_state = MState}) -> Return = ConsumerModule:handle_deliver(Method, Args, DeliveryCtx, MState), consumer_call_reply(Return, State). handle_cast(_What, State) -> {noreply, State}. handle_info(Info, State = #state{module_state = MState, module = ConsumerModule}) -> case ConsumerModule:handle_info(Info, MState) of {ok, NewMState} -> {noreply, State#state{module_state = NewMState}}; {error, Reason, NewMState} -> {stop, {error, Reason}, State#state{module_state = NewMState}} end. terminate(Reason, #state{module = ConsumerModule, module_state = MState}) -> ConsumerModule:terminate(Reason, MState). code_change(_OldVsn, State, _Extra) -> {ok, State}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/amqp_connection_type_sup.erl0000644000177700017770000000667712633765070031665 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% %% @private -module(amqp_connection_type_sup). -include("amqp_client_internal.hrl"). -behaviour(supervisor2). -export([start_link/0, start_infrastructure_fun/3, type_module/1]). -export([init/1]). %%--------------------------------------------------------------------------- %% Interface %%--------------------------------------------------------------------------- start_link() -> supervisor2:start_link(?MODULE, []). type_module(#amqp_params_direct{}) -> {direct, amqp_direct_connection}; type_module(#amqp_params_network{}) -> {network, amqp_network_connection}. %%--------------------------------------------------------------------------- start_channels_manager(Sup, Conn, ConnName, Type) -> {ok, ChSupSup} = supervisor2:start_child( Sup, {channel_sup_sup, {amqp_channel_sup_sup, start_link, [Type, Conn, ConnName]}, intrinsic, infinity, supervisor, [amqp_channel_sup_sup]}), {ok, _} = supervisor2:start_child( Sup, {channels_manager, {amqp_channels_manager, start_link, [Conn, ConnName, ChSupSup]}, transient, ?MAX_WAIT, worker, [amqp_channels_manager]}). start_infrastructure_fun(Sup, Conn, network) -> fun (Sock, ConnName) -> {ok, ChMgr} = start_channels_manager(Sup, Conn, ConnName, network), {ok, AState} = rabbit_command_assembler:init(?PROTOCOL), {ok, Writer} = supervisor2:start_child( Sup, {writer, {rabbit_writer, start_link, [Sock, 0, ?FRAME_MIN_SIZE, ?PROTOCOL, Conn, ConnName]}, transient, ?MAX_WAIT, worker, [rabbit_writer]}), {ok, _Reader} = supervisor2:start_child( Sup, {main_reader, {amqp_main_reader, start_link, [Sock, Conn, ChMgr, AState, ConnName]}, transient, ?MAX_WAIT, worker, [amqp_main_reader]}), {ok, ChMgr, Writer} end; start_infrastructure_fun(Sup, Conn, direct) -> fun (ConnName) -> {ok, ChMgr} = start_channels_manager(Sup, Conn, ConnName, direct), {ok, Collector} = supervisor2:start_child( Sup, {collector, {rabbit_queue_collector, start_link, [ConnName]}, transient, ?MAX_WAIT, worker, [rabbit_queue_collector]}), {ok, ChMgr, Collector} end. %%--------------------------------------------------------------------------- %% supervisor2 callbacks %%--------------------------------------------------------------------------- init([]) -> {ok, {{one_for_all, 0, 1}, []}}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/amqp_direct_connection.erl0000644000177700017770000002034012633765070031246 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% %% @private -module(amqp_direct_connection). -include("amqp_client_internal.hrl"). -behaviour(amqp_gen_connection). -export([server_close/3]). -export([init/0, terminate/2, connect/4, do/2, open_channel_args/1, i/2, info_keys/0, handle_message/2, closing/3, channels_terminated/1]). -export([socket_adapter_info/2]). -record(state, {node, user, vhost, params, adapter_info, collector, closing_reason, %% undefined | Reason connected_at }). -define(INFO_KEYS, [type]). -define(CREATION_EVENT_KEYS, [pid, protocol, host, port, name, peer_host, peer_port, user, vhost, client_properties, type, connected_at]). %%--------------------------------------------------------------------------- %% amqp_connection:close() logically closes from the client end. We may %% want to close from the server end. server_close(ConnectionPid, Code, Text) -> Close = #'connection.close'{reply_text = Text, reply_code = Code, class_id = 0, method_id = 0}, amqp_gen_connection:server_close(ConnectionPid, Close). init() -> {ok, #state{}}. open_channel_args(#state{node = Node, user = User, vhost = VHost, collector = Collector}) -> [self(), Node, User, VHost, Collector]. do(_Method, _State) -> ok. handle_message({force_event_refresh, Ref}, State = #state{node = Node}) -> rpc:call(Node, rabbit_event, notify, [connection_created, connection_info(State), Ref]), {ok, State}; handle_message(closing_timeout, State = #state{closing_reason = Reason}) -> {stop, {closing_timeout, Reason}, State}; handle_message({'DOWN', _MRef, process, _ConnSup, shutdown}, State) -> {stop, {shutdown, node_down}, State}; handle_message({'DOWN', _MRef, process, _ConnSup, Reason}, State) -> {stop, {remote_node_down, Reason}, State}; handle_message(Msg, State) -> {stop, {unexpected_msg, Msg}, State}. closing(_ChannelCloseType, Reason, State) -> {ok, State#state{closing_reason = Reason}}. channels_terminated(State = #state{closing_reason = Reason, collector = Collector}) -> rabbit_queue_collector:delete_all(Collector), {stop, {shutdown, Reason}, State}. terminate(_Reason, #state{node = Node}) -> rpc:call(Node, rabbit_direct, disconnect, [self(), [{pid, self()}]]), ok. i(type, _State) -> direct; i(pid, _State) -> self(); %% AMQP Params i(user, #state{params = P}) -> P#amqp_params_direct.username; i(vhost, #state{params = P}) -> P#amqp_params_direct.virtual_host; i(client_properties, #state{params = P}) -> P#amqp_params_direct.client_properties; i(connected_at, #state{connected_at = T}) -> T; %% Optional adapter info i(protocol, #state{adapter_info = I}) -> I#amqp_adapter_info.protocol; i(host, #state{adapter_info = I}) -> I#amqp_adapter_info.host; i(port, #state{adapter_info = I}) -> I#amqp_adapter_info.port; i(peer_host, #state{adapter_info = I}) -> I#amqp_adapter_info.peer_host; i(peer_port, #state{adapter_info = I}) -> I#amqp_adapter_info.peer_port; i(name, #state{adapter_info = I}) -> I#amqp_adapter_info.name; i(Item, _State) -> throw({bad_argument, Item}). info_keys() -> ?INFO_KEYS. infos(Items, State) -> [{Item, i(Item, State)} || Item <- Items]. connection_info(State = #state{adapter_info = I}) -> infos(?CREATION_EVENT_KEYS, State) ++ I#amqp_adapter_info.additional_info. connect(Params = #amqp_params_direct{username = Username, password = Password, node = Node, adapter_info = Info, virtual_host = VHost}, SIF, _TypeSup, State) -> State1 = State#state{node = Node, vhost = VHost, params = Params, adapter_info = ensure_adapter_info(Info), connected_at = rabbit_misc:now_to_ms(os:timestamp())}, case rpc:call(Node, rabbit_direct, connect, [{Username, Password}, VHost, ?PROTOCOL, self(), connection_info(State1)]) of {ok, {User, ServerProperties}} -> {ok, ChMgr, Collector} = SIF(i(name, State1)), State2 = State1#state{user = User, collector = Collector}, %% There's no real connection-level process on the remote %% node for us to monitor or link to, but we want to %% detect connection death if the remote node goes down %% when there are no channels. So we monitor the %% supervisor; that way we find out if the node goes down %% or the rabbit app stops. erlang:monitor(process, {rabbit_direct_client_sup, Node}), {ok, {ServerProperties, 0, ChMgr, State2}}; {error, _} = E -> E; {badrpc, nodedown} -> {error, {nodedown, Node}} end. ensure_adapter_info(none) -> ensure_adapter_info(#amqp_adapter_info{}); ensure_adapter_info(A = #amqp_adapter_info{protocol = unknown}) -> ensure_adapter_info(A#amqp_adapter_info{ protocol = {'Direct', ?PROTOCOL:version()}}); ensure_adapter_info(A = #amqp_adapter_info{name = unknown}) -> Name = list_to_binary(rabbit_misc:pid_to_string(self())), ensure_adapter_info(A#amqp_adapter_info{name = Name}); ensure_adapter_info(Info) -> Info. socket_adapter_info(Sock, Protocol) -> {PeerHost, PeerPort, Host, Port} = case rabbit_net:socket_ends(Sock, inbound) of {ok, Res} -> Res; _ -> {unknown, unknown, unknown, unknown} end, Name = case rabbit_net:connection_string(Sock, inbound) of {ok, Res1} -> Res1; _Error -> "(unknown)" end, #amqp_adapter_info{protocol = Protocol, name = list_to_binary(Name), host = Host, port = Port, peer_host = PeerHost, peer_port = PeerPort, additional_info = maybe_ssl_info(Sock)}. maybe_ssl_info(Sock) -> case rabbit_net:is_ssl(Sock) of true -> [{ssl, true}] ++ ssl_info(Sock) ++ ssl_cert_info(Sock); false -> [{ssl, false}] end. ssl_info(Sock) -> {Protocol, KeyExchange, Cipher, Hash} = case rabbit_net:ssl_info(Sock) of {ok, {P, {K, C, H}}} -> {P, K, C, H}; {ok, {P, {K, C, H, _}}} -> {P, K, C, H}; _ -> {unknown, unknown, unknown, unknown} end, [{ssl_protocol, Protocol}, {ssl_key_exchange, KeyExchange}, {ssl_cipher, Cipher}, {ssl_hash, Hash}]. ssl_cert_info(Sock) -> case rabbit_net:peercert(Sock) of {ok, Cert} -> [{peer_cert_issuer, list_to_binary( rabbit_ssl:peer_cert_issuer(Cert))}, {peer_cert_subject, list_to_binary( rabbit_ssl:peer_cert_subject(Cert))}, {peer_cert_validity, list_to_binary( rabbit_ssl:peer_cert_validity(Cert))}]; _ -> [] end. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/amqp_uri.erl0000644000177700017770000002410012633765070026352 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(amqp_uri). -include("amqp_client.hrl"). -export([parse/1, parse/2, remove_credentials/1]). %%--------------------------------------------------------------------------- %% AMQP URI Parsing %%--------------------------------------------------------------------------- %% Reformat a URI to remove authentication secrets from it (before we %% log it or display it anywhere). remove_credentials(URI) -> Props = uri_parser:parse(URI, [{host, undefined}, {path, undefined}, {port, undefined}, {'query', []}]), PortPart = case proplists:get_value(port, Props) of undefined -> ""; Port -> rabbit_misc:format(":~B", [Port]) end, PGet = fun(K, P) -> case proplists:get_value(K, P) of undefined -> ""; R -> R end end, rabbit_misc:format( "~s://~s~s~s", [proplists:get_value(scheme, Props), PGet(host, Props), PortPart, PGet(path, Props)]). %% @spec (Uri) -> {ok, #amqp_params_network{} | #amqp_params_direct{}} | %% {error, {Info, Uri}} %% where %% Uri = string() %% Info = any() %% %% @doc Parses an AMQP URI. If any of the URI parts are missing, the %% default values are used. If the hostname is zero-length, an %% #amqp_params_direct{} record is returned; otherwise, an %% #amqp_params_network{} record is returned. Extra parameters may be %% specified via the query string %% (e.g. "?heartbeat=5&auth_mechanism=external"). In case of failure, %% an {error, {Info, Uri}} tuple is returned. %% %% The extra parameters that may be specified are channel_max, %% frame_max, heartbeat and auth_mechanism (the latter can appear more %% than once). The extra parameters that may be specified for an SSL %% connection are cacertfile, certfile, keyfile, verify, and %% fail_if_no_peer_cert. parse(Uri) -> parse(Uri, <<"/">>). parse(Uri, DefaultVHost) -> try return(parse1(Uri, DefaultVHost)) catch throw:Err -> {error, {Err, Uri}}; error:Err -> {error, {Err, Uri}} end. parse1(Uri, DefaultVHost) when is_list(Uri) -> case uri_parser:parse(Uri, [{host, undefined}, {path, undefined}, {port, undefined}, {'query', []}]) of {error, Err} -> throw({unable_to_parse_uri, Err}); Parsed -> Endpoint = case string:to_lower(proplists:get_value(scheme, Parsed)) of "amqp" -> build_broker(Parsed, DefaultVHost); "amqps" -> build_ssl_broker(Parsed, DefaultVHost); Scheme -> fail({unexpected_uri_scheme, Scheme}) end, return({ok, broker_add_query(Endpoint, Parsed)}) end; parse1(_, _DefaultVHost) -> fail(expected_string_uri). unescape_string(Atom) when is_atom(Atom) -> Atom; unescape_string([]) -> []; unescape_string([$%, N1, N2 | Rest]) -> try [erlang:list_to_integer([N1, N2], 16) | unescape_string(Rest)] catch error:badarg -> throw({invalid_entitiy, ['%', N1, N2]}) end; unescape_string([$% | Rest]) -> fail({unterminated_entity, ['%' | Rest]}); unescape_string([C | Rest]) -> [C | unescape_string(Rest)]. build_broker(ParsedUri, DefaultVHost) -> [Host, Port, Path] = [proplists:get_value(F, ParsedUri) || F <- [host, port, path]], case Port =:= undefined orelse (0 < Port andalso Port =< 65535) of true -> ok; false -> fail({port_out_of_range, Port}) end, VHost = case Path of undefined -> DefaultVHost; [$/|Rest] -> case string:chr(Rest, $/) of 0 -> list_to_binary(unescape_string(Rest)); _ -> fail({invalid_vhost, Rest}) end end, UserInfo = proplists:get_value(userinfo, ParsedUri), set_user_info(case unescape_string(Host) of undefined -> #amqp_params_direct{virtual_host = VHost}; Host1 -> Mech = mechanisms(ParsedUri), #amqp_params_network{host = Host1, port = Port, virtual_host = VHost, auth_mechanisms = Mech} end, UserInfo). set_user_info(Ps, UserInfo) -> case UserInfo of [U, P | _] -> set([{username, list_to_binary(unescape_string(U))}, {password, list_to_binary(unescape_string(P))}], Ps); [U] -> set([{username, list_to_binary(unescape_string(U))}], Ps); [] -> Ps end. set(KVs, Ps = #amqp_params_direct{}) -> set(KVs, Ps, record_info(fields, amqp_params_direct)); set(KVs, Ps = #amqp_params_network{}) -> set(KVs, Ps, record_info(fields, amqp_params_network)). set(KVs, Ps, Fields) -> {Ps1, _Ix} = lists:foldl(fun (Field, {PsN, Ix}) -> {case lists:keyfind(Field, 1, KVs) of false -> PsN; {_, V} -> setelement(Ix, PsN, V) end, Ix + 1} end, {Ps, 2}, Fields), Ps1. build_ssl_broker(ParsedUri, DefaultVHost) -> Params = build_broker(ParsedUri, DefaultVHost), Query = proplists:get_value('query', ParsedUri), SSLOptions = run_state_monad( [fun (L) -> KeyString = atom_to_list(Key), case lists:keysearch(KeyString, 1, Query) of {value, {_, Value}} -> try return([{Key, unescape_string(Fun(Value))} | L]) catch throw:Reason -> fail({invalid_ssl_parameter, Key, Value, Query, Reason}) end; false -> L end end || {Fun, Key} <- [{fun find_path_parameter/1, cacertfile}, {fun find_path_parameter/1, certfile}, {fun find_path_parameter/1, keyfile}, {fun find_atom_parameter/1, verify}, {fun find_boolean_parameter/1, fail_if_no_peer_cert}]], []), Params#amqp_params_network{ssl_options = SSLOptions}. broker_add_query(Params = #amqp_params_direct{}, Uri) -> broker_add_query(Params, Uri, record_info(fields, amqp_params_direct)); broker_add_query(Params = #amqp_params_network{}, Uri) -> broker_add_query(Params, Uri, record_info(fields, amqp_params_network)). broker_add_query(Params, ParsedUri, Fields) -> Query = proplists:get_value('query', ParsedUri), {Params1, _Pos} = run_state_monad( [fun ({ParamsN, Pos}) -> Pos1 = Pos + 1, KeyString = atom_to_list(Field), case proplists:get_value(KeyString, Query) of undefined -> return({ParamsN, Pos1}); true -> %% proplists short form, not permitted return({ParamsN, Pos1}); Value -> try ValueParsed = parse_amqp_param(Field, Value), return( {setelement(Pos, ParamsN, ValueParsed), Pos1}) catch throw:Reason -> fail({invalid_amqp_params_parameter, Field, Value, Query, Reason}) end end end || Field <- Fields], {Params, 2}), Params1. parse_amqp_param(Field, String) when Field =:= channel_max orelse Field =:= frame_max orelse Field =:= heartbeat orelse Field =:= connection_timeout -> try return(list_to_integer(String)) catch error:badarg -> fail({not_an_integer, String}) end; parse_amqp_param(Field, String) -> fail({parameter_unconfigurable_in_query, Field, String}). find_path_parameter(Value) -> return(Value). find_boolean_parameter(Value) -> Bool = list_to_atom(Value), case is_boolean(Bool) of true -> return(Bool); false -> fail({require_boolean, Bool}) end. find_atom_parameter(Value) -> return(list_to_atom(Value)). mechanisms(ParsedUri) -> Query = proplists:get_value('query', ParsedUri), Mechanisms = case proplists:get_all_values("auth_mechanism", Query) of [] -> ["plain", "amqplain"]; Mechs -> Mechs end, [case [list_to_atom(T) || T <- string:tokens(Mech, ":")] of [F] -> fun (R, P, S) -> amqp_auth_mechanisms:F(R, P, S) end; [M, F] -> fun (R, P, S) -> M:F(R, P, S) end; L -> throw({not_mechanism, L}) end || Mech <- Mechanisms]. %% --=: Plain state monad implementation start :=-- run_state_monad(FunList, State) -> lists:foldl(fun (Fun, StateN) -> Fun(StateN) end, State, FunList). return(V) -> V. fail(Reason) -> throw(Reason). %% --=: end :=-- rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/rabbit_routing_util.erl0000644000177700017770000002242112633765070030610 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2013-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_routing_util). -export([init_state/0, dest_prefixes/0, all_dest_prefixes/0]). -export([ensure_endpoint/4, ensure_endpoint/5, ensure_binding/3]). -export([parse_endpoint/1, parse_endpoint/2]). -export([parse_routing/1, dest_temp_queue/1]). -include("amqp_client.hrl"). -include("rabbit_routing_prefixes.hrl"). %%---------------------------------------------------------------------------- init_state() -> sets:new(). dest_prefixes() -> [?EXCHANGE_PREFIX, ?TOPIC_PREFIX, ?QUEUE_PREFIX, ?AMQQUEUE_PREFIX, ?REPLY_QUEUE_PREFIX]. all_dest_prefixes() -> [?TEMP_QUEUE_PREFIX | dest_prefixes()]. %% -------------------------------------------------------------------------- parse_endpoint(Destination) -> parse_endpoint(Destination, false). parse_endpoint(undefined, AllowAnonymousQueue) -> parse_endpoint("/queue", AllowAnonymousQueue); parse_endpoint(Destination, AllowAnonymousQueue) when is_binary(Destination) -> parse_endpoint(unicode:characters_to_list(Destination), AllowAnonymousQueue); parse_endpoint(Destination, AllowAnonymousQueue) when is_list(Destination) -> case re:split(Destination, "/", [{return, list}]) of [Name] -> {ok, {queue, unescape(Name)}}; ["", Type | Rest] when Type =:= "exchange" orelse Type =:= "queue" orelse Type =:= "topic" orelse Type =:= "temp-queue" -> parse_endpoint0(atomise(Type), Rest, AllowAnonymousQueue); ["", "amq", "queue" | Rest] -> parse_endpoint0(amqqueue, Rest, AllowAnonymousQueue); ["", "reply-queue" = Prefix | [_|_]] -> parse_endpoint0(reply_queue, [lists:nthtail(2 + length(Prefix), Destination)], AllowAnonymousQueue); _ -> {error, {unknown_destination, Destination}} end. parse_endpoint0(exchange, ["" | _] = Rest, _) -> {error, {invalid_destination, exchange, to_url(Rest)}}; parse_endpoint0(exchange, [Name], _) -> {ok, {exchange, {unescape(Name), undefined}}}; parse_endpoint0(exchange, [Name, Pattern], _) -> {ok, {exchange, {unescape(Name), unescape(Pattern)}}}; parse_endpoint0(queue, [], false) -> {error, {invalid_destination, queue, []}}; parse_endpoint0(queue, [], true) -> {ok, {queue, undefined}}; parse_endpoint0(Type, [[_|_]] = [Name], _) -> {ok, {Type, unescape(Name)}}; parse_endpoint0(Type, Rest, _) -> {error, {invalid_destination, Type, to_url(Rest)}}. %% -------------------------------------------------------------------------- ensure_endpoint(Dir, Channel, Endpoint, State) -> ensure_endpoint(Dir, Channel, Endpoint, [], State). ensure_endpoint(source, Channel, {exchange, {Name, _}}, Params, State) -> check_exchange(Name, Channel, proplists:get_value(check_exchange, Params, false)), Method = queue_declare_method(#'queue.declare'{}, exchange, Params), #'queue.declare_ok'{queue = Queue} = amqp_channel:call(Channel, Method), {ok, Queue, State}; ensure_endpoint(source, Channel, {topic, _}, Params, State) -> Method = queue_declare_method(#'queue.declare'{}, topic, Params), #'queue.declare_ok'{queue = Queue} = amqp_channel:call(Channel, Method), {ok, Queue, State}; ensure_endpoint(_Dir, _Channel, {queue, undefined}, _Params, State) -> {ok, undefined, State}; ensure_endpoint(_, Channel, {queue, Name}, Params, State) -> Params1 = rabbit_misc:pset(durable, true, Params), Queue = list_to_binary(Name), State1 = case sets:is_element(Queue, State) of true -> State; _ -> Method = queue_declare_method( #'queue.declare'{queue = Queue, nowait = true}, queue, Params1), case Method#'queue.declare'.nowait of true -> amqp_channel:cast(Channel, Method); false -> amqp_channel:call(Channel, Method) end, sets:add_element(Queue, State) end, {ok, Queue, State1}; ensure_endpoint(dest, Channel, {exchange, {Name, _}}, Params, State) -> check_exchange(Name, Channel, proplists:get_value(check_exchange, Params, false)), {ok, undefined, State}; ensure_endpoint(dest, _Ch, {topic, _}, _Params, State) -> {ok, undefined, State}; ensure_endpoint(_, _Ch, {amqqueue, Name}, _Params, State) -> {ok, list_to_binary(Name), State}; ensure_endpoint(_, _Ch, {reply_queue, Name}, _Params, State) -> {ok, list_to_binary(Name), State}; ensure_endpoint(_Direction, _Ch, _Endpoint, _Params, _State) -> {error, invalid_endpoint}. %% -------------------------------------------------------------------------- ensure_binding(QueueBin, {"", Queue}, _Channel) -> %% i.e., we should only be asked to bind to the default exchange a %% queue with its own name QueueBin = list_to_binary(Queue), ok; ensure_binding(Queue, {Exchange, RoutingKey}, Channel) -> #'queue.bind_ok'{} = amqp_channel:call(Channel, #'queue.bind'{ queue = Queue, exchange = list_to_binary(Exchange), routing_key = list_to_binary(RoutingKey)}), ok. %% -------------------------------------------------------------------------- parse_routing({exchange, {Name, undefined}}) -> {Name, ""}; parse_routing({exchange, {Name, Pattern}}) -> {Name, Pattern}; parse_routing({topic, Name}) -> {"amq.topic", Name}; parse_routing({Type, Name}) when Type =:= queue orelse Type =:= reply_queue orelse Type =:= amqqueue -> {"", Name}. dest_temp_queue({temp_queue, Name}) -> Name; dest_temp_queue(_) -> none. %% -------------------------------------------------------------------------- check_exchange(_, _, false) -> ok; check_exchange(ExchangeName, Channel, true) -> XDecl = #'exchange.declare'{ exchange = list_to_binary(ExchangeName), passive = true }, #'exchange.declare_ok'{} = amqp_channel:call(Channel, XDecl), ok. update_queue_declare_arguments(Method, Params) -> Method#'queue.declare'{arguments = proplists:get_value(arguments, Params, [])}. update_queue_declare_exclusive(Method, Params) -> case proplists:get_value(exclusive, Params) of undefined -> Method; Val -> Method#'queue.declare'{exclusive = Val} end. update_queue_declare_auto_delete(Method, Params) -> case proplists:get_value(auto_delete, Params) of undefined -> Method; Val -> Method#'queue.declare'{auto_delete = Val} end. update_queue_declare_nowait(Method, Params) -> case proplists:get_value(nowait, Params) of undefined -> Method; Val -> Method#'queue.declare'{nowait = Val} end. queue_declare_method(#'queue.declare'{} = Method, Type, Params) -> %% defaults Method1 = case proplists:get_value(durable, Params, false) of true -> Method#'queue.declare'{durable = true}; false -> Method#'queue.declare'{auto_delete = true, exclusive = true} end, %% set the rest of queue.declare fields from Params Method2 = lists:foldl(fun (F, Acc) -> F(Acc, Params) end, Method1, [fun update_queue_declare_arguments/2, fun update_queue_declare_exclusive/2, fun update_queue_declare_auto_delete/2, fun update_queue_declare_nowait/2]), case {Type, proplists:get_value(subscription_queue_name_gen, Params)} of {topic, SQNG} when is_function(SQNG) -> Method2#'queue.declare'{queue = SQNG()}; {exchange, SQNG} when is_function(SQNG) -> Method2#'queue.declare'{queue = SQNG()}; {'reply-queue', SQNG} when is_function(SQNG) -> Method2#'queue.declare'{queue = SQNG()}; _ -> Method2 end. %% -------------------------------------------------------------------------- to_url([]) -> []; to_url(Lol) -> "/" ++ string:join(Lol, "/"). atomise(Name) when is_list(Name) -> list_to_atom(re:replace(Name, "-", "_", [{return,list}, global])). unescape(Str) -> unescape(Str, []). unescape("%2F" ++ Str, Acc) -> unescape(Str, [$/ | Acc]); unescape([C | Str], Acc) -> unescape(Str, [C | Acc]); unescape([], Acc) -> lists:reverse(Acc). rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/amqp_auth_mechanisms.erl0000644000177700017770000000346512633765070030736 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% %% @private -module(amqp_auth_mechanisms). -include("amqp_client.hrl"). -export([plain/3, amqplain/3, external/3, crdemo/3]). %%--------------------------------------------------------------------------- plain(none, _, init) -> {<<"PLAIN">>, []}; plain(none, #amqp_params_network{username = Username, password = Password}, _State) -> {<<0, Username/binary, 0, Password/binary>>, _State}. amqplain(none, _, init) -> {<<"AMQPLAIN">>, []}; amqplain(none, #amqp_params_network{username = Username, password = Password}, _State) -> LoginTable = [{<<"LOGIN">>, longstr, Username}, {<<"PASSWORD">>, longstr, Password}], {rabbit_binary_generator:generate_table(LoginTable), _State}. external(none, _, init) -> {<<"EXTERNAL">>, []}; external(none, _, _State) -> {<<"">>, _State}. crdemo(none, _, init) -> {<<"RABBIT-CR-DEMO">>, 0}; crdemo(none, #amqp_params_network{username = Username}, 0) -> {Username, 1}; crdemo(<<"Please tell me your password">>, #amqp_params_network{password = Password}, 1) -> {<<"My password is ", Password/binary>>, 2}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/amqp_sup.erl0000644000177700017770000000277012633765070026373 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% %% @private -module(amqp_sup). -include("amqp_client.hrl"). -behaviour(supervisor2). -export([start_link/0, start_connection_sup/1]). -export([init/1]). %%--------------------------------------------------------------------------- %% Interface %%--------------------------------------------------------------------------- start_link() -> supervisor2:start_link({local, amqp_sup}, ?MODULE, []). start_connection_sup(AmqpParams) -> supervisor2:start_child(amqp_sup, [AmqpParams]). %%--------------------------------------------------------------------------- %% supervisor2 callbacks %%--------------------------------------------------------------------------- init([]) -> {ok, {{simple_one_for_one, 0, 1}, [{connection_sup, {amqp_connection_sup, start_link, []}, temporary, infinity, supervisor, [amqp_connection_sup]}]}}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/amqp_channels_manager.erl0000644000177700017770000002426612633765070031055 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% %% @private -module(amqp_channels_manager). -include("amqp_client_internal.hrl"). -behaviour(gen_server). -export([start_link/3, open_channel/4, set_channel_max/2, is_empty/1, num_channels/1, pass_frame/3, signal_connection_closing/3, process_channel_frame/4]). -export([init/1, terminate/2, code_change/3, handle_call/3, handle_cast/2, handle_info/2]). -record(state, {connection, channel_sup_sup, map_num_pa = gb_trees:empty(), %% Number -> {Pid, AState} map_pid_num = dict:new(), %% Pid -> Number channel_max = ?MAX_CHANNEL_NUMBER, closing = false}). %%--------------------------------------------------------------------------- %% Interface %%--------------------------------------------------------------------------- start_link(Connection, ConnName, ChSupSup) -> gen_server:start_link(?MODULE, [Connection, ConnName, ChSupSup], []). open_channel(ChMgr, ProposedNumber, Consumer, InfraArgs) -> gen_server:call(ChMgr, {open_channel, ProposedNumber, Consumer, InfraArgs}, infinity). set_channel_max(ChMgr, ChannelMax) -> gen_server:cast(ChMgr, {set_channel_max, ChannelMax}). is_empty(ChMgr) -> gen_server:call(ChMgr, is_empty, infinity). num_channels(ChMgr) -> gen_server:call(ChMgr, num_channels, infinity). pass_frame(ChMgr, ChNumber, Frame) -> gen_server:cast(ChMgr, {pass_frame, ChNumber, Frame}). signal_connection_closing(ChMgr, ChannelCloseType, Reason) -> gen_server:cast(ChMgr, {connection_closing, ChannelCloseType, Reason}). process_channel_frame(Frame, Channel, ChPid, AState) -> case rabbit_command_assembler:process(Frame, AState) of {ok, NewAState} -> NewAState; {ok, Method, NewAState} -> rabbit_channel:do(ChPid, Method), NewAState; {ok, Method, Content, NewAState} -> rabbit_channel:do(ChPid, Method, Content), NewAState; {error, Reason} -> ChPid ! {channel_exit, Channel, Reason}, AState end. %%--------------------------------------------------------------------------- %% gen_server callbacks %%--------------------------------------------------------------------------- init([Connection, ConnName, ChSupSup]) -> ?store_proc_name(ConnName), {ok, #state{connection = Connection, channel_sup_sup = ChSupSup}}. terminate(_Reason, _State) -> ok. code_change(_OldVsn, State, _Extra) -> {ok, State}. handle_call({open_channel, ProposedNumber, Consumer, InfraArgs}, _, State = #state{closing = false}) -> handle_open_channel(ProposedNumber, Consumer, InfraArgs, State); handle_call(is_empty, _, State) -> {reply, internal_is_empty(State), State}; handle_call(num_channels, _, State) -> {reply, internal_num_channels(State), State}. handle_cast({set_channel_max, ChannelMax}, State) -> {noreply, State#state{channel_max = ChannelMax}}; handle_cast({pass_frame, ChNumber, Frame}, State) -> {noreply, internal_pass_frame(ChNumber, Frame, State)}; handle_cast({connection_closing, ChannelCloseType, Reason}, State) -> handle_connection_closing(ChannelCloseType, Reason, State). handle_info({'DOWN', _, process, Pid, Reason}, State) -> handle_down(Pid, Reason, State). %%--------------------------------------------------------------------------- %% Internal plumbing %%--------------------------------------------------------------------------- handle_open_channel(ProposedNumber, Consumer, InfraArgs, State = #state{channel_sup_sup = ChSupSup}) -> case new_number(ProposedNumber, State) of {ok, Number} -> {ok, _ChSup, {Ch, AState}} = amqp_channel_sup_sup:start_channel_sup(ChSupSup, InfraArgs, Number, Consumer), NewState = internal_register(Number, Ch, AState, State), erlang:monitor(process, Ch), {reply, {ok, Ch}, NewState}; {error, _} = Error -> {reply, Error, State} end. new_number(none, #state{channel_max = ChannelMax, map_num_pa = MapNPA}) -> case gb_trees:is_empty(MapNPA) of true -> {ok, 1}; false -> {Smallest, _} = gb_trees:smallest(MapNPA), if Smallest > 1 -> {ok, Smallest - 1}; true -> {Largest, _} = gb_trees:largest(MapNPA), if Largest < ChannelMax -> {ok, Largest + 1}; true -> find_free(MapNPA) end end end; new_number(Proposed, State = #state{channel_max = ChannelMax, map_num_pa = MapNPA}) -> IsValid = Proposed > 0 andalso Proposed =< ChannelMax andalso not gb_trees:is_defined(Proposed, MapNPA), case IsValid of true -> {ok, Proposed}; false -> new_number(none, State) end. find_free(MapNPA) -> find_free(gb_trees:iterator(MapNPA), 1). find_free(It, Candidate) -> case gb_trees:next(It) of {Number, _, It1} -> if Number > Candidate -> {ok, Number - 1}; Number =:= Candidate -> find_free(It1, Candidate + 1) end; none -> {error, out_of_channel_numbers} end. handle_down(Pid, Reason, State) -> case internal_lookup_pn(Pid, State) of undefined -> {stop, {error, unexpected_down}, State}; Number -> handle_channel_down(Pid, Number, Reason, State) end. handle_channel_down(Pid, Number, Reason, State) -> maybe_report_down(Pid, case Reason of {shutdown, R} -> R; _ -> Reason end, State), NewState = internal_unregister(Number, Pid, State), check_all_channels_terminated(NewState), {noreply, NewState}. maybe_report_down(_Pid, normal, _State) -> ok; maybe_report_down(_Pid, shutdown, _State) -> ok; maybe_report_down(_Pid, {app_initiated_close, _, _}, _State) -> ok; maybe_report_down(_Pid, {server_initiated_close, _, _}, _State) -> ok; maybe_report_down(_Pid, {connection_closing, _}, _State) -> ok; maybe_report_down(_Pid, {server_misbehaved, AmqpError}, #state{connection = Connection}) -> amqp_gen_connection:server_misbehaved(Connection, AmqpError); maybe_report_down(Pid, Other, #state{connection = Connection}) -> amqp_gen_connection:channel_internal_error(Connection, Pid, Other). check_all_channels_terminated(#state{closing = false}) -> ok; check_all_channels_terminated(State = #state{closing = true, connection = Connection}) -> case internal_is_empty(State) of true -> amqp_gen_connection:channels_terminated(Connection); false -> ok end. handle_connection_closing(ChannelCloseType, Reason, State = #state{connection = Connection}) -> case internal_is_empty(State) of true -> amqp_gen_connection:channels_terminated(Connection); false -> signal_channels_connection_closing(ChannelCloseType, Reason, State) end, {noreply, State#state{closing = true}}. %%--------------------------------------------------------------------------- internal_pass_frame(Number, Frame, State) -> case internal_lookup_npa(Number, State) of undefined -> ?LOG_INFO("Dropping frame ~p for invalid or closed " "channel number ~p~n", [Frame, Number]), State; {ChPid, AState} -> NewAState = process_channel_frame(Frame, Number, ChPid, AState), internal_update_npa(Number, ChPid, NewAState, State) end. internal_register(Number, Pid, AState, State = #state{map_num_pa = MapNPA, map_pid_num = MapPN}) -> MapNPA1 = gb_trees:enter(Number, {Pid, AState}, MapNPA), MapPN1 = dict:store(Pid, Number, MapPN), State#state{map_num_pa = MapNPA1, map_pid_num = MapPN1}. internal_unregister(Number, Pid, State = #state{map_num_pa = MapNPA, map_pid_num = MapPN}) -> MapNPA1 = gb_trees:delete(Number, MapNPA), MapPN1 = dict:erase(Pid, MapPN), State#state{map_num_pa = MapNPA1, map_pid_num = MapPN1}. internal_is_empty(#state{map_num_pa = MapNPA}) -> gb_trees:is_empty(MapNPA). internal_num_channels(#state{map_num_pa = MapNPA}) -> gb_trees:size(MapNPA). internal_lookup_npa(Number, #state{map_num_pa = MapNPA}) -> case gb_trees:lookup(Number, MapNPA) of {value, PA} -> PA; none -> undefined end. internal_lookup_pn(Pid, #state{map_pid_num = MapPN}) -> case dict:find(Pid, MapPN) of {ok, Number} -> Number; error -> undefined end. internal_update_npa(Number, Pid, AState, State = #state{map_num_pa = MapNPA}) -> State#state{map_num_pa = gb_trees:update(Number, {Pid, AState}, MapNPA)}. signal_channels_connection_closing(ChannelCloseType, Reason, #state{map_pid_num = MapPN}) -> [amqp_channel:connection_closing(Pid, ChannelCloseType, Reason) || Pid <- dict:fetch_keys(MapPN)]. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/amqp_main_reader.erl0000644000177700017770000001437312633765070030034 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% %% @private -module(amqp_main_reader). -include("amqp_client_internal.hrl"). -behaviour(gen_server). -export([start_link/5]). -export([init/1, terminate/2, code_change/3, handle_call/3, handle_cast/2, handle_info/2]). -record(state, {sock, connection, channels_manager, astate, message = none %% none | {Type, Channel, Length} }). %%--------------------------------------------------------------------------- %% Interface %%--------------------------------------------------------------------------- start_link(Sock, Connection, ChMgr, AState, ConnName) -> gen_server:start_link( ?MODULE, [Sock, Connection, ConnName, ChMgr, AState], []). %%--------------------------------------------------------------------------- %% gen_server callbacks %%--------------------------------------------------------------------------- init([Sock, Connection, ConnName, ChMgr, AState]) -> ?store_proc_name(ConnName), State = #state{sock = Sock, connection = Connection, channels_manager = ChMgr, astate = AState, message = none}, case rabbit_net:async_recv(Sock, 0, infinity) of {ok, _} -> {ok, State}; {error, Reason} -> {stop, Reason, _} = handle_error(Reason, State), {stop, Reason} end. terminate(_Reason, _State) -> ok. code_change(_OldVsn, State, _Extra) -> {ok, State}. handle_call(Call, From, State) -> {stop, {unexpected_call, Call, From}, State}. handle_cast(Cast, State) -> {stop, {unexpected_cast, Cast}, State}. handle_info({inet_async, Sock, _, {ok, Data}}, State = #state {sock = Sock}) -> %% Latency hiding: Request next packet first, then process data case rabbit_net:async_recv(Sock, 0, infinity) of {ok, _} -> handle_data(Data, State); {error, Reason} -> handle_error(Reason, State) end; handle_info({inet_async, Sock, _, {error, Reason}}, State = #state{sock = Sock}) -> handle_error(Reason, State). handle_data(<>, #state{message = none} = State) when Type =:= ?FRAME_METHOD; Type =:= ?FRAME_HEADER; Type =:= ?FRAME_BODY; Type =:= ?FRAME_HEARTBEAT -> %% Optimisation for the direct match handle_data( More, process_frame(Type, Channel, Payload, State#state{message = none})); handle_data(<>, #state{message = none} = State) when Type =:= ?FRAME_METHOD; Type =:= ?FRAME_HEADER; Type =:= ?FRAME_BODY; Type =:= ?FRAME_HEARTBEAT -> {noreply, State#state{message = {Type, Channel, Length, Data}}}; handle_data(<<"AMQP", A, B, C>>, #state{sock = Sock, message = none} = State) -> {ok, <>} = rabbit_net:sync_recv(Sock, 1), handle_error({refused, {A, B, C, D}}, State); handle_data(<>, #state{message = none} = State) -> handle_error({malformed_header, Malformed}, State); handle_data(<>, #state{message = none} = State) -> {noreply, State#state{message = {expecting_header, Data}}}; handle_data(Data, #state{message = {Type, Channel, L, OldData}} = State) -> case <> of <> -> handle_data(More, process_frame(Type, Channel, Payload, State#state{message = none})); NotEnough -> %% Read in more data from the socket {noreply, State#state{message = {Type, Channel, L, NotEnough}}} end; handle_data(Data, #state{message = {expecting_header, Old}} = State) -> handle_data(<>, State#state{message = none}); handle_data(<<>>, State) -> {noreply, State}. %%--------------------------------------------------------------------------- %% Internal plumbing %%--------------------------------------------------------------------------- process_frame(Type, ChNumber, Payload, State = #state{connection = Connection, channels_manager = ChMgr, astate = AState}) -> case rabbit_command_assembler:analyze_frame(Type, Payload, ?PROTOCOL) of heartbeat when ChNumber /= 0 -> amqp_gen_connection:server_misbehaved( Connection, #amqp_error{name = command_invalid, explanation = "heartbeat on non-zero channel"}), State; %% Match heartbeats but don't do anything with them heartbeat -> State; AnalyzedFrame when ChNumber /= 0 -> amqp_channels_manager:pass_frame(ChMgr, ChNumber, AnalyzedFrame), State; AnalyzedFrame -> State#state{astate = amqp_channels_manager:process_channel_frame( AnalyzedFrame, 0, Connection, AState)} end. handle_error(closed, State = #state{connection = Conn}) -> Conn ! socket_closed, {noreply, State}; handle_error({refused, Version}, State = #state{connection = Conn}) -> Conn ! {refused, Version}, {noreply, State}; handle_error({malformed_header, Version}, State = #state{connection = Conn}) -> Conn ! {malformed_header, Version}, {noreply, State}; handle_error(Reason, State = #state{connection = Conn}) -> Conn ! {socket_error, Reason}, {stop, {socket_error, Reason}, State}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/amqp_network_connection.erl0000644000177700017770000003704012633765070031472 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% %% @private -module(amqp_network_connection). -include("amqp_client_internal.hrl"). -behaviour(amqp_gen_connection). -export([init/0, terminate/2, connect/4, do/2, open_channel_args/1, i/2, info_keys/0, handle_message/2, closing/3, channels_terminated/1]). -define(RABBIT_TCP_OPTS, [binary, {packet, 0}, {active,false}, {nodelay, true}]). -define(SOCKET_CLOSING_TIMEOUT, 1000). -define(HANDSHAKE_RECEIVE_TIMEOUT, 60000). -define(TCP_MAX_PACKET_SIZE, (16#4000000 + ?EMPTY_FRAME_SIZE - 1)). -record(state, {sock, name, heartbeat, writer0, frame_max, type_sup, closing_reason, %% undefined | Reason waiting_socket_close = false}). -define(INFO_KEYS, [type, heartbeat, frame_max, sock, name]). %%--------------------------------------------------------------------------- init() -> {ok, #state{}}. open_channel_args(#state{sock = Sock, frame_max = FrameMax}) -> [Sock, FrameMax]. do(#'connection.close_ok'{} = CloseOk, State) -> erlang:send_after(?SOCKET_CLOSING_TIMEOUT, self(), socket_closing_timeout), do2(CloseOk, State); do(Method, State) -> do2(Method, State). do2(Method, #state{writer0 = Writer}) -> %% Catching because it expects the {channel_exit, _, _} message on error catch rabbit_writer:send_command_sync(Writer, Method). handle_message(socket_closing_timeout, State = #state{closing_reason = Reason}) -> {stop, {socket_closing_timeout, Reason}, State}; handle_message(socket_closed, State = #state{waiting_socket_close = true, closing_reason = Reason}) -> {stop, {shutdown, Reason}, State}; handle_message(socket_closed, State = #state{waiting_socket_close = false}) -> {stop, socket_closed_unexpectedly, State}; handle_message({socket_error, _} = SocketError, State) -> {stop, SocketError, State}; handle_message({channel_exit, 0, Reason}, State) -> {stop, {channel0_died, Reason}, State}; handle_message(heartbeat_timeout, State) -> {stop, heartbeat_timeout, State}; handle_message(closing_timeout, State = #state{closing_reason = Reason}) -> {stop, Reason, State}; %% see http://erlang.org/pipermail/erlang-bugs/2012-June/002933.html handle_message({Ref, {error, Reason}}, State = #state{waiting_socket_close = Waiting, closing_reason = CloseReason}) when is_reference(Ref) -> {stop, case {Reason, Waiting} of {closed, true} -> {shutdown, CloseReason}; {closed, false} -> socket_closed_unexpectedly; {_, _} -> {socket_error, Reason} end, State}. closing(_ChannelCloseType, Reason, State) -> {ok, State#state{closing_reason = Reason}}. channels_terminated(State = #state{closing_reason = {server_initiated_close, _, _}}) -> {ok, State#state{waiting_socket_close = true}}; channels_terminated(State) -> {ok, State}. terminate(_Reason, _State) -> ok. i(type, _State) -> network; i(heartbeat, State) -> State#state.heartbeat; i(frame_max, State) -> State#state.frame_max; i(sock, State) -> State#state.sock; i(name, State) -> State#state.name; i(Item, _State) -> throw({bad_argument, Item}). info_keys() -> ?INFO_KEYS. %%--------------------------------------------------------------------------- %% Handshake %%--------------------------------------------------------------------------- connect(AmqpParams = #amqp_params_network{host = Host}, SIF, TypeSup, State) -> case gethostaddr(Host) of [] -> {error, unknown_host}; [AF|_] -> do_connect( AF, AmqpParams, SIF, State#state{type_sup = TypeSup}) end. do_connect({Addr, Family}, AmqpParams = #amqp_params_network{ssl_options = none, port = Port, connection_timeout = Timeout, socket_options = ExtraOpts}, SIF, State) -> obtain(), case gen_tcp:connect(Addr, Port, [Family | ?RABBIT_TCP_OPTS] ++ ExtraOpts, Timeout) of {ok, Sock} -> try_handshake(AmqpParams, SIF, State#state{sock = Sock}); {error, _} = E -> E end; do_connect({Addr, Family}, AmqpParams = #amqp_params_network{ssl_options = SslOpts0, port = Port, connection_timeout = Timeout, socket_options = ExtraOpts}, SIF, State) -> {ok, GlobalSslOpts} = application:get_env(amqp_client, ssl_options), app_utils:start_applications([asn1, crypto, public_key, ssl]), obtain(), case gen_tcp:connect(Addr, Port, [Family | ?RABBIT_TCP_OPTS] ++ ExtraOpts, Timeout) of {ok, Sock} -> SslOpts = rabbit_networking:fix_ssl_options( orddict:to_list( orddict:merge(fun (_, _A, B) -> B end, orddict:from_list(GlobalSslOpts), orddict:from_list(SslOpts0)))), case ssl:connect(Sock, SslOpts) of {ok, SslSock} -> RabbitSslSock = #ssl_socket{ssl = SslSock, tcp = Sock}, try_handshake(AmqpParams, SIF, State#state{sock = RabbitSslSock}); {error, _} = E -> E end; {error, _} = E -> E end. inet_address_preference() -> case application:get_env(amqp_client, prefer_ipv6) of {ok, true} -> [inet6, inet]; {ok, false} -> [inet, inet6] end. gethostaddr(Host) -> Lookups = [{Family, inet:getaddr(Host, Family)} || Family <- inet_address_preference()], [{IP, Family} || {Family, {ok, IP}} <- Lookups]. try_handshake(AmqpParams, SIF, State = #state{sock = Sock}) -> Name = case rabbit_net:connection_string(Sock, outbound) of {ok, Str} -> list_to_binary(Str); {error, _} -> <<"unknown">> end, try handshake(AmqpParams, SIF, State#state{name = <<"client ", Name/binary>>}) of Return -> Return catch exit:Reason -> {error, Reason} end. handshake(AmqpParams, SIF, State0 = #state{sock = Sock}) -> ok = rabbit_net:send(Sock, ?PROTOCOL_HEADER), network_handshake(AmqpParams, start_infrastructure(SIF, State0)). start_infrastructure(SIF, State = #state{sock = Sock, name = Name}) -> {ok, ChMgr, Writer} = SIF(Sock, Name), {ChMgr, State#state{writer0 = Writer}}. network_handshake(AmqpParams = #amqp_params_network{virtual_host = VHost}, {ChMgr, State0}) -> Start = #'connection.start'{server_properties = ServerProperties, mechanisms = Mechanisms} = handshake_recv('connection.start'), ok = check_version(Start), case login(AmqpParams, Mechanisms, State0) of {closing, #amqp_error{}, _Error} = Err -> do(#'connection.close_ok'{}, State0), Err; Tune -> {TuneOk, ChannelMax, State1} = tune(Tune, AmqpParams, State0), do2(TuneOk, State1), do2(#'connection.open'{virtual_host = VHost}, State1), Params = {ServerProperties, ChannelMax, ChMgr, State1}, case handshake_recv('connection.open_ok') of #'connection.open_ok'{} -> {ok, Params}; {closing, #amqp_error{} = AmqpError, Error} -> {closing, Params, AmqpError, Error} end end. check_version(#'connection.start'{version_major = ?PROTOCOL_VERSION_MAJOR, version_minor = ?PROTOCOL_VERSION_MINOR}) -> ok; check_version(#'connection.start'{version_major = 8, version_minor = 0}) -> exit({protocol_version_mismatch, 0, 8}); check_version(#'connection.start'{version_major = Major, version_minor = Minor}) -> exit({protocol_version_mismatch, Major, Minor}). tune(#'connection.tune'{channel_max = ServerChannelMax, frame_max = ServerFrameMax, heartbeat = ServerHeartbeat}, #amqp_params_network{channel_max = ClientChannelMax, frame_max = ClientFrameMax, heartbeat = ClientHeartbeat}, State) -> [ChannelMax, Heartbeat, FrameMax] = lists:zipwith(fun (Client, Server) when Client =:= 0; Server =:= 0 -> lists:max([Client, Server]); (Client, Server) -> lists:min([Client, Server]) end, [ClientChannelMax, ClientHeartbeat, ClientFrameMax], [ServerChannelMax, ServerHeartbeat, ServerFrameMax]), %% If we attempt to recv > 64Mb, inet_drv will return enomem, so %% we cap the max negotiated frame size accordingly. Note that %% since we receive the frame header separately, we can actually %% cope with frame sizes of 64M + ?EMPTY_FRAME_SIZE - 1. CappedFrameMax = case FrameMax of 0 -> ?TCP_MAX_PACKET_SIZE; _ -> lists:min([FrameMax, ?TCP_MAX_PACKET_SIZE]) end, NewState = State#state{heartbeat = Heartbeat, frame_max = CappedFrameMax}, start_heartbeat(NewState), {#'connection.tune_ok'{channel_max = ChannelMax, frame_max = CappedFrameMax, heartbeat = Heartbeat}, ChannelMax, NewState}. start_heartbeat(#state{sock = Sock, name = Name, heartbeat = Heartbeat, type_sup = Sup}) -> Frame = rabbit_binary_generator:build_heartbeat_frame(), SendFun = fun () -> catch rabbit_net:send(Sock, Frame) end, Connection = self(), ReceiveFun = fun () -> Connection ! heartbeat_timeout end, rabbit_heartbeat:start( Sup, Sock, Name, Heartbeat, SendFun, Heartbeat, ReceiveFun). login(Params = #amqp_params_network{auth_mechanisms = ClientMechanisms, client_properties = UserProps}, ServerMechanismsStr, State) -> ServerMechanisms = string:tokens(binary_to_list(ServerMechanismsStr), " "), case [{N, S, F} || F <- ClientMechanisms, {N, S} <- [F(none, Params, init)], lists:member(binary_to_list(N), ServerMechanisms)] of [{Name, MState0, Mech}|_] -> {Resp, MState1} = Mech(none, Params, MState0), StartOk = #'connection.start_ok'{ client_properties = client_properties(UserProps), mechanism = Name, response = Resp}, do2(StartOk, State), login_loop(Mech, MState1, Params, State); [] -> exit({no_suitable_auth_mechanism, ServerMechanisms}) end. login_loop(Mech, MState0, Params, State) -> case handshake_recv('connection.tune') of Tune = #'connection.tune'{} -> Tune; #'connection.secure'{challenge = Challenge} -> {Resp, MState1} = Mech(Challenge, Params, MState0), do2(#'connection.secure_ok'{response = Resp}, State), login_loop(Mech, MState1, Params, State); #'connection.close'{reply_code = ?ACCESS_REFUSED, reply_text = ExplanationBin} -> Explanation = binary_to_list(ExplanationBin), {closing, #amqp_error{name = access_refused, explanation = Explanation}, {error, {auth_failure, Explanation}}} end. client_properties(UserProperties) -> {ok, Vsn} = application:get_key(amqp_client, vsn), Default = [{<<"product">>, longstr, <<"RabbitMQ">>}, {<<"version">>, longstr, list_to_binary(Vsn)}, {<<"platform">>, longstr, <<"Erlang">>}, {<<"copyright">>, longstr, <<"Copyright (c) 2007-2015 Pivotal Software, Inc.">>}, {<<"information">>, longstr, <<"Licensed under the MPL. " "See http://www.rabbitmq.com/">>}, {<<"capabilities">>, table, ?CLIENT_CAPABILITIES}], lists:foldl(fun({K, _, _} = Tuple, Acc) -> lists:keystore(K, 1, Acc, Tuple) end, Default, UserProperties). handshake_recv(Expecting) -> receive {'$gen_cast', {method, Method, none, noflow}} -> case {Expecting, element(1, Method)} of {E, M} when E =:= M -> Method; {'connection.tune', 'connection.secure'} -> Method; {'connection.tune', 'connection.close'} -> Method; {'connection.open_ok', _} -> {closing, #amqp_error{name = command_invalid, explanation = "was expecting " "connection.open_ok"}, {error, {unexpected_method, Method, {expecting, Expecting}}}}; _ -> throw({unexpected_method, Method, {expecting, Expecting}}) end; socket_closed -> case Expecting of 'connection.tune' -> exit({auth_failure, "Disconnected"}); 'connection.open_ok' -> exit(access_refused); _ -> exit({socket_closed_unexpectedly, Expecting}) end; {socket_error, _} = SocketError -> exit({SocketError, {expecting, Expecting}}); {refused, Version} -> exit({server_refused_connection, Version}); {malformed_header, All} -> exit({server_sent_malformed_header, All}); heartbeat_timeout -> exit(heartbeat_timeout); Other -> throw({handshake_recv_unexpected_message, Other}) after ?HANDSHAKE_RECEIVE_TIMEOUT -> case Expecting of 'connection.open_ok' -> {closing, #amqp_error{name = internal_error, explanation = "handshake timed out waiting " "connection.open_ok"}, {error, handshake_receive_timed_out}}; _ -> exit(handshake_receive_timed_out) end end. obtain() -> case code:is_loaded(file_handle_cache) of false -> ok; _ -> file_handle_cache:obtain() end. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/amqp_channel.erl0000644000177700017770000011761012633765070027174 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% %% @type close_reason(Type) = {shutdown, amqp_reason(Type)}. %% @type amqp_reason(Type) = {Type, Code, Text} %% Code = non_neg_integer() %% Text = binary(). %% @doc This module encapsulates the client's view of an AMQP %% channel. Each server side channel is represented by an amqp_channel %% process on the client side. Channel processes are created using the %% {@link amqp_connection} module. Channel processes are supervised %% under amqp_client's supervision tree.
    %%
    %% In case of a failure or an AMQP error, the channel process exits with a %% meaningful exit reason:
    %%
    %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %% %%
    CauseExit reason
    Any reason, where Code would have been 200 otherwise```normal'''
    User application calls amqp_channel:close/3```close_reason(app_initiated_close)'''
    Server closes channel (soft error)```close_reason(server_initiated_close)'''
    Server misbehaved (did not follow protocol)```close_reason(server_misbehaved)'''
    Connection is closing (causing all channels to cleanup and %% close)```{shutdown, {connection_closing, amqp_reason(atom())}}'''
    Other error(various error reasons, causing more detailed logging)
    %%
    %% See type definitions below. -module(amqp_channel). -include("amqp_client_internal.hrl"). -behaviour(gen_server). -export([call/2, call/3, cast/2, cast/3, cast_flow/3]). -export([close/1, close/3]). -export([register_return_handler/2, unregister_return_handler/1, register_flow_handler/2, unregister_flow_handler/1, register_confirm_handler/2, unregister_confirm_handler/1]). -export([call_consumer/2, subscribe/3]). -export([next_publish_seqno/1, wait_for_confirms/1, wait_for_confirms/2, wait_for_confirms_or_die/1, wait_for_confirms_or_die/2]). -export([start_link/5, set_writer/2, connection_closing/3, open/1, enable_delivery_flow_control/1, notify_received/1]). -export([init/1, terminate/2, code_change/3, handle_call/3, handle_cast/2, handle_info/2]). -define(TIMEOUT_FLUSH, 60000). -record(state, {number, connection, consumer, driver, rpc_requests = queue:new(), closing = false, %% false | %% {just_channel, Reason} | %% {connection, Reason} writer, return_handler = none, confirm_handler = none, next_pub_seqno = 0, flow_active = true, flow_handler = none, unconfirmed_set = gb_sets:new(), waiting_set = gb_trees:empty(), only_acks_received = true, %% true | false, only relevant in the direct %% client case. %% when true, consumers will manually notify %% queue pids using rabbit_amqqueue:notify_sent/2 %% to prevent the queue from overwhelming slow %% consumers that use automatic acknowledgement %% mode. delivery_flow_control = false }). %%--------------------------------------------------------------------------- %% Type Definitions %%--------------------------------------------------------------------------- %% @type amqp_method(). %% This abstract datatype represents the set of methods that comprise %% the AMQP execution model. As indicated in the overview, the %% attributes of each method in the execution model are described in %% the protocol documentation. The Erlang record definitions are %% autogenerated from a parseable version of the specification. Most %% fields in the generated records have sensible default values that %% you need not worry in the case of a simple usage of the client %% library. %% @type amqp_msg() = #amqp_msg{}. %% This is the content encapsulated in content-bearing AMQP methods. It %% contains the following fields: %%
      %%
    • props :: class_property() - A class property record, defaults to %% #'P_basic'{}
    • %%
    • payload :: binary() - The arbitrary data payload
    • %%
    %%--------------------------------------------------------------------------- %% AMQP Channel API methods %%--------------------------------------------------------------------------- %% @spec (Channel, Method) -> Result %% @doc This is equivalent to amqp_channel:call(Channel, Method, none). call(Channel, Method) -> gen_server:call(Channel, {call, Method, none, self()}, infinity). %% @spec (Channel, Method, Content) -> Result %% where %% Channel = pid() %% Method = amqp_method() %% Content = amqp_msg() | none %% Result = amqp_method() | ok | blocked | closing %% @doc This sends an AMQP method on the channel. %% For content bearing methods, Content has to be an amqp_msg(), whereas %% for non-content bearing methods, it needs to be the atom 'none'.
    %% In the case of synchronous methods, this function blocks until the %% corresponding reply comes back from the server and returns it. %% In the case of asynchronous methods, the function blocks until the method %% gets sent on the wire and returns the atom 'ok' on success.
    %% This will return the atom 'blocked' if the server has %% throttled the client for flow control reasons. This will return the %% atom 'closing' if the channel is in the process of shutting down.
    %% Note that for asynchronous methods, the synchronicity implied by %% 'call' only means that the client has transmitted the method to %% the broker. It does not necessarily imply that the broker has %% accepted responsibility for the message. call(Channel, Method, Content) -> gen_server:call(Channel, {call, Method, Content, self()}, infinity). %% @spec (Channel, Method) -> ok %% @doc This is equivalent to amqp_channel:cast(Channel, Method, none). cast(Channel, Method) -> gen_server:cast(Channel, {cast, Method, none, self(), noflow}). %% @spec (Channel, Method, Content) -> ok %% where %% Channel = pid() %% Method = amqp_method() %% Content = amqp_msg() | none %% @doc This function is the same as {@link call/3}, except that it returns %% immediately with the atom 'ok', without blocking the caller process. %% This function is not recommended with synchronous methods, since there is no %% way to verify that the server has received the method. cast(Channel, Method, Content) -> gen_server:cast(Channel, {cast, Method, Content, self(), noflow}). %% @spec (Channel, Method, Content) -> ok %% where %% Channel = pid() %% Method = amqp_method() %% Content = amqp_msg() | none %% @doc Like cast/3, with flow control. cast_flow(Channel, Method, Content) -> credit_flow:send(Channel), gen_server:cast(Channel, {cast, Method, Content, self(), flow}). %% @spec (Channel) -> ok | closing %% where %% Channel = pid() %% @doc Closes the channel, invokes %% close(Channel, 200, <<"Goodbye">>). close(Channel) -> close(Channel, 200, <<"Goodbye">>). %% @spec (Channel, Code, Text) -> ok | closing %% where %% Channel = pid() %% Code = integer() %% Text = binary() %% @doc Closes the channel, allowing the caller to supply a reply code and %% text. If the channel is already closing, the atom 'closing' is returned. close(Channel, Code, Text) -> gen_server:call(Channel, {close, Code, Text}, infinity). %% @spec (Channel) -> integer() %% where %% Channel = pid() %% @doc When in confirm mode, returns the sequence number of the next %% message to be published. next_publish_seqno(Channel) -> gen_server:call(Channel, next_publish_seqno, infinity). %% @spec (Channel) -> boolean() | 'timeout' %% where %% Channel = pid() %% @doc Wait until all messages published since the last call have %% been either ack'd or nack'd by the broker. Note, when called on a %% non-Confirm channel, waitForConfirms returns an error. wait_for_confirms(Channel) -> wait_for_confirms(Channel, infinity). %% @spec (Channel, Timeout) -> boolean() | 'timeout' %% where %% Channel = pid() %% Timeout = non_neg_integer() | 'infinity' %% @doc Wait until all messages published since the last call have %% been either ack'd or nack'd by the broker or the timeout expires. %% Note, when called on a non-Confirm channel, waitForConfirms throws %% an exception. wait_for_confirms(Channel, Timeout) -> case gen_server:call(Channel, {wait_for_confirms, Timeout}, infinity) of {error, Reason} -> throw(Reason); Other -> Other end. %% @spec (Channel) -> true %% where %% Channel = pid() %% @doc Behaves the same as wait_for_confirms/1, but if a nack is %% received, the calling process is immediately sent an %% exit(nack_received). wait_for_confirms_or_die(Channel) -> wait_for_confirms_or_die(Channel, infinity). %% @spec (Channel, Timeout) -> true %% where %% Channel = pid() %% Timeout = non_neg_integer() | 'infinity' %% @doc Behaves the same as wait_for_confirms/1, but if a nack is %% received, the calling process is immediately sent an %% exit(nack_received). If the timeout expires, the calling process is %% sent an exit(timeout). wait_for_confirms_or_die(Channel, Timeout) -> case wait_for_confirms(Channel, Timeout) of timeout -> close(Channel, 200, <<"Confirm Timeout">>), exit(timeout); false -> close(Channel, 200, <<"Nacks Received">>), exit(nacks_received); true -> true end. %% @spec (Channel, ReturnHandler) -> ok %% where %% Channel = pid() %% ReturnHandler = pid() %% @doc This registers a handler to deal with returned messages. The %% registered process will receive #basic.return{} records. register_return_handler(Channel, ReturnHandler) -> gen_server:cast(Channel, {register_return_handler, ReturnHandler} ). %% @spec (Channel) -> ok %% where %% Channel = pid() %% @doc Removes the return handler, if it exists. Does nothing if there is no %% such handler. unregister_return_handler(Channel) -> gen_server:cast(Channel, unregister_return_handler). %% @spec (Channel, ConfirmHandler) -> ok %% where %% Channel = pid() %% ConfirmHandler = pid() %% @doc This registers a handler to deal with confirm-related %% messages. The registered process will receive #basic.ack{} and %% #basic.nack{} commands. register_confirm_handler(Channel, ConfirmHandler) -> gen_server:cast(Channel, {register_confirm_handler, ConfirmHandler} ). %% @spec (Channel) -> ok %% where %% Channel = pid() %% @doc Removes the confirm handler, if it exists. Does nothing if there is no %% such handler. unregister_confirm_handler(Channel) -> gen_server:cast(Channel, unregister_confirm_handler). %% @spec (Channel, FlowHandler) -> ok %% where %% Channel = pid() %% FlowHandler = pid() %% @doc This registers a handler to deal with channel flow notifications. %% The registered process will receive #channel.flow{} records. register_flow_handler(Channel, FlowHandler) -> gen_server:cast(Channel, {register_flow_handler, FlowHandler} ). %% @spec (Channel) -> ok %% where %% Channel = pid() %% @doc Removes the flow handler, if it exists. Does nothing if there is no %% such handler. unregister_flow_handler(Channel) -> gen_server:cast(Channel, unregister_flow_handler). %% @spec (Channel, Msg) -> ok %% where %% Channel = pid() %% Msg = any() %% @doc This causes the channel to invoke Consumer:handle_call/2, %% where Consumer is the amqp_gen_consumer implementation registered with %% the channel. call_consumer(Channel, Msg) -> gen_server:call(Channel, {call_consumer, Msg}, infinity). %% @spec (Channel, BasicConsume, Subscriber) -> ok %% where %% Channel = pid() %% BasicConsume = amqp_method() %% Subscriber = pid() %% @doc Subscribe the given pid to a queue using the specified %% basic.consume method. subscribe(Channel, BasicConsume = #'basic.consume'{}, Subscriber) -> gen_server:call(Channel, {subscribe, BasicConsume, Subscriber}, infinity). %%--------------------------------------------------------------------------- %% Internal interface %%--------------------------------------------------------------------------- %% @private start_link(Driver, Connection, ChannelNumber, Consumer, Identity) -> gen_server:start_link( ?MODULE, [Driver, Connection, ChannelNumber, Consumer, Identity], []). set_writer(Pid, Writer) -> gen_server:cast(Pid, {set_writer, Writer}). enable_delivery_flow_control(Pid) -> gen_server:cast(Pid, enable_delivery_flow_control). notify_received({Pid, QPid, ServerChPid}) -> gen_server:cast(Pid, {send_notify, {QPid, ServerChPid}}). %% @private connection_closing(Pid, ChannelCloseType, Reason) -> gen_server:cast(Pid, {connection_closing, ChannelCloseType, Reason}). %% @private open(Pid) -> gen_server:call(Pid, open, infinity). %%--------------------------------------------------------------------------- %% gen_server callbacks %%--------------------------------------------------------------------------- %% @private init([Driver, Connection, ChannelNumber, Consumer, Identity]) -> ?store_proc_name(Identity), {ok, #state{connection = Connection, driver = Driver, number = ChannelNumber, consumer = Consumer}}. %% @private handle_call(open, From, State) -> {noreply, rpc_top_half(#'channel.open'{}, none, From, none, noflow, State)}; %% @private handle_call({close, Code, Text}, From, State) -> handle_close(Code, Text, From, State); %% @private handle_call({call, Method, AmqpMsg, Sender}, From, State) -> handle_method_to_server(Method, AmqpMsg, From, Sender, noflow, State); %% Handles the delivery of messages from a direct channel %% @private handle_call({send_command_sync, Method, Content}, From, State) -> Ret = handle_method_from_server(Method, Content, State), gen_server:reply(From, ok), Ret; %% Handles the delivery of messages from a direct channel %% @private handle_call({send_command_sync, Method}, From, State) -> Ret = handle_method_from_server(Method, none, State), gen_server:reply(From, ok), Ret; %% @private handle_call(next_publish_seqno, _From, State = #state{next_pub_seqno = SeqNo}) -> {reply, SeqNo, State}; handle_call({wait_for_confirms, Timeout}, From, State) -> handle_wait_for_confirms(From, Timeout, State); %% @private handle_call({call_consumer, Msg}, _From, State = #state{consumer = Consumer}) -> {reply, amqp_gen_consumer:call_consumer(Consumer, Msg), State}; %% @private handle_call({subscribe, BasicConsume, Subscriber}, From, State) -> handle_method_to_server(BasicConsume, none, From, Subscriber, noflow, State). %% @private handle_cast({set_writer, Writer}, State = #state{driver = direct}) -> link(Writer), {noreply, State#state{writer = Writer}}; handle_cast({set_writer, Writer}, State) -> {noreply, State#state{writer = Writer}}; %% @private handle_cast(enable_delivery_flow_control, State) -> {noreply, State#state{delivery_flow_control = true}}; %% @private handle_cast({send_notify, {QPid, ChPid}}, State) -> rabbit_amqqueue:notify_sent(QPid, ChPid), {noreply, State}; %% @private handle_cast({cast, Method, AmqpMsg, Sender, noflow}, State) -> handle_method_to_server(Method, AmqpMsg, none, Sender, noflow, State); handle_cast({cast, Method, AmqpMsg, Sender, flow}, State) -> credit_flow:ack(Sender), handle_method_to_server(Method, AmqpMsg, none, Sender, flow, State); %% @private handle_cast({register_return_handler, ReturnHandler}, State) -> Ref = erlang:monitor(process, ReturnHandler), {noreply, State#state{return_handler = {ReturnHandler, Ref}}}; %% @private handle_cast(unregister_return_handler, State = #state{return_handler = {_ReturnHandler, Ref}}) -> erlang:demonitor(Ref), {noreply, State#state{return_handler = none}}; %% @private handle_cast({register_confirm_handler, ConfirmHandler}, State) -> Ref = erlang:monitor(process, ConfirmHandler), {noreply, State#state{confirm_handler = {ConfirmHandler, Ref}}}; %% @private handle_cast(unregister_confirm_handler, State = #state{confirm_handler = {_ConfirmHandler, Ref}}) -> erlang:demonitor(Ref), {noreply, State#state{confirm_handler = none}}; %% @private handle_cast({register_flow_handler, FlowHandler}, State) -> Ref = erlang:monitor(process, FlowHandler), {noreply, State#state{flow_handler = {FlowHandler, Ref}}}; %% @private handle_cast(unregister_flow_handler, State = #state{flow_handler = {_FlowHandler, Ref}}) -> erlang:demonitor(Ref), {noreply, State#state{flow_handler = none}}; %% Received from channels manager %% @private handle_cast({method, Method, Content, noflow}, State) -> handle_method_from_server(Method, Content, State); %% Handles the situation when the connection closes without closing the channel %% beforehand. The channel must block all further RPCs, %% flush the RPC queue (optional), and terminate %% @private handle_cast({connection_closing, CloseType, Reason}, State) -> handle_connection_closing(CloseType, Reason, State); %% @private handle_cast({shutdown, Shutdown}, State) -> handle_shutdown(Shutdown, State). %% Received from rabbit_channel in the direct case %% @private handle_info({send_command, Method}, State) -> handle_method_from_server(Method, none, State); %% Received from rabbit_channel in the direct case %% @private handle_info({send_command, Method, Content}, State) -> handle_method_from_server(Method, Content, State); %% Received from rabbit_channel in the direct case %% @private handle_info({send_command_and_notify, QPid, ChPid, Method = #'basic.deliver'{}, Content}, State = #state{delivery_flow_control = MFC}) -> case MFC of false -> handle_method_from_server(Method, Content, State), rabbit_amqqueue:notify_sent(QPid, ChPid); true -> handle_method_from_server(Method, Content, {self(), QPid, ChPid}, State) end, {noreply, State}; %% This comes from the writer or rabbit_channel %% @private handle_info({channel_exit, _ChNumber, Reason}, State) -> handle_channel_exit(Reason, State); %% This comes from rabbit_channel in the direct case handle_info({channel_closing, ChPid}, State) -> ok = rabbit_channel:ready_for_close(ChPid), {noreply, State}; %% @private handle_info({bump_credit, Msg}, State) -> credit_flow:handle_bump_msg(Msg), {noreply, State}; %% @private handle_info(timed_out_flushing_channel, State) -> ?LOG_WARN("Channel (~p) closing: timed out flushing while " "connection closing~n", [self()]), {stop, timed_out_flushing_channel, State}; %% @private handle_info({'DOWN', _, process, ReturnHandler, Reason}, State = #state{return_handler = {ReturnHandler, _Ref}}) -> ?LOG_WARN("Channel (~p): Unregistering return handler ~p because it died. " "Reason: ~p~n", [self(), ReturnHandler, Reason]), {noreply, State#state{return_handler = none}}; %% @private handle_info({'DOWN', _, process, ConfirmHandler, Reason}, State = #state{confirm_handler = {ConfirmHandler, _Ref}}) -> ?LOG_WARN("Channel (~p): Unregistering confirm handler ~p because it died. " "Reason: ~p~n", [self(), ConfirmHandler, Reason]), {noreply, State#state{confirm_handler = none}}; %% @private handle_info({'DOWN', _, process, FlowHandler, Reason}, State = #state{flow_handler = {FlowHandler, _Ref}}) -> ?LOG_WARN("Channel (~p): Unregistering flow handler ~p because it died. " "Reason: ~p~n", [self(), FlowHandler, Reason]), {noreply, State#state{flow_handler = none}}; handle_info({'DOWN', _, process, QPid, _Reason}, State) -> rabbit_amqqueue:notify_sent_queue_down(QPid), {noreply, State}; handle_info({confirm_timeout, From}, State = #state{waiting_set = WSet}) -> case gb_trees:lookup(From, WSet) of none -> {noreply, State}; {value, _} -> gen_server:reply(From, timeout), {noreply, State#state{waiting_set = gb_trees:delete(From, WSet)}} end. %% @private terminate(_Reason, State) -> flush_writer(State), State. %% @private code_change(_OldVsn, State, _Extra) -> {ok, State}. %%--------------------------------------------------------------------------- %% RPC mechanism %%--------------------------------------------------------------------------- handle_method_to_server(Method, AmqpMsg, From, Sender, Flow, State = #state{unconfirmed_set = USet}) -> case {check_invalid_method(Method), From, check_block(Method, AmqpMsg, State)} of {ok, _, ok} -> State1 = case {Method, State#state.next_pub_seqno} of {#'confirm.select'{}, _} -> State#state{next_pub_seqno = 1}; {#'basic.publish'{}, 0} -> State; {#'basic.publish'{}, SeqNo} -> State#state{unconfirmed_set = gb_sets:add(SeqNo, USet), next_pub_seqno = SeqNo + 1}; _ -> State end, {noreply, rpc_top_half(Method, build_content(AmqpMsg), From, Sender, Flow, State1)}; {ok, none, BlockReply} -> ?LOG_WARN("Channel (~p): discarding method ~p in cast.~n" "Reason: ~p~n", [self(), Method, BlockReply]), {noreply, State}; {ok, _, BlockReply} -> {reply, BlockReply, State}; {{_, InvalidMethodMessage}, none, _} -> ?LOG_WARN("Channel (~p): ignoring cast of ~p method. " ++ InvalidMethodMessage ++ "~n", [self(), Method]), {noreply, State}; {{InvalidMethodReply, _}, _, _} -> {reply, {error, InvalidMethodReply}, State} end. handle_close(Code, Text, From, State) -> Close = #'channel.close'{reply_code = Code, reply_text = Text, class_id = 0, method_id = 0}, case check_block(Close, none, State) of ok -> {noreply, rpc_top_half(Close, none, From, none, noflow, State)}; BlockReply -> {reply, BlockReply, State} end. rpc_top_half(Method, Content, From, Sender, Flow, State0 = #state{rpc_requests = RequestQueue}) -> State1 = State0#state{ rpc_requests = queue:in({From, Sender, Method, Content, Flow}, RequestQueue)}, IsFirstElement = queue:is_empty(RequestQueue), if IsFirstElement -> do_rpc(State1); true -> State1 end. rpc_bottom_half(Reply, State = #state{rpc_requests = RequestQueue}) -> {{value, {From, _Sender, _Method, _Content, _Flow}}, RequestQueue1} = queue:out(RequestQueue), case From of none -> ok; _ -> gen_server:reply(From, Reply) end, do_rpc(State#state{rpc_requests = RequestQueue1}). do_rpc(State = #state{rpc_requests = Q, closing = Closing}) -> case queue:out(Q) of {{value, {From, Sender, Method, Content, Flow}}, NewQ} -> State1 = pre_do(Method, Content, Sender, State), DoRet = do(Method, Content, Flow, State1), case ?PROTOCOL:is_method_synchronous(Method) of true -> State1; false -> case {From, DoRet} of {none, _} -> ok; {_, ok} -> gen_server:reply(From, ok); _ -> ok %% Do not reply if error in do. Expecting %% {channel_exit, _, _} end, do_rpc(State1#state{rpc_requests = NewQ}) end; {empty, NewQ} -> case Closing of {connection, Reason} -> gen_server:cast(self(), {shutdown, {connection_closing, Reason}}); _ -> ok end, State#state{rpc_requests = NewQ} end. pending_rpc_method(#state{rpc_requests = Q}) -> {value, {_From, _Sender, Method, _Content, _Flow}} = queue:peek(Q), Method. pre_do(#'channel.close'{reply_code = Code, reply_text = Text}, none, _Sender, State) -> State#state{closing = {just_channel, {app_initiated_close, Code, Text}}}; pre_do(#'basic.consume'{} = Method, none, Sender, State) -> ok = call_to_consumer(Method, Sender, State), State; pre_do(#'basic.cancel'{} = Method, none, Sender, State) -> ok = call_to_consumer(Method, Sender, State), State; pre_do(_, _, _, State) -> State. %%--------------------------------------------------------------------------- %% Handling of methods from the server %%--------------------------------------------------------------------------- safely_handle_method_from_server(Method, Content, Continuation, State = #state{closing = Closing}) -> case is_connection_method(Method) of true -> server_misbehaved( #amqp_error{name = command_invalid, explanation = "connection method on " "non-zero channel", method = element(1, Method)}, State); false -> Drop = case {Closing, Method} of {{just_channel, _}, #'channel.close'{}} -> false; {{just_channel, _}, #'channel.close_ok'{}} -> false; {{just_channel, _}, _} -> true; _ -> false end, if Drop -> ?LOG_INFO("Channel (~p): dropping method ~p from " "server because channel is closing~n", [self(), {Method, Content}]), {noreply, State}; true -> Continuation() end end. handle_method_from_server(Method, Content, State) -> Fun = fun () -> handle_method_from_server1(Method, amqp_msg(Content), State) end, safely_handle_method_from_server(Method, Content, Fun, State). handle_method_from_server(Method = #'basic.deliver'{}, Content, DeliveryCtx, State) -> Fun = fun () -> handle_method_from_server1(Method, amqp_msg(Content), DeliveryCtx, State) end, safely_handle_method_from_server(Method, Content, Fun, State). handle_method_from_server1(#'channel.open_ok'{}, none, State) -> {noreply, rpc_bottom_half(ok, State)}; handle_method_from_server1(#'channel.close'{reply_code = Code, reply_text = Text}, none, State = #state{closing = {just_channel, _}}) -> %% Both client and server sent close at the same time. Don't shutdown yet, %% wait for close_ok. do(#'channel.close_ok'{}, none, noflow, State), {noreply, State#state{ closing = {just_channel, {server_initiated_close, Code, Text}}}}; handle_method_from_server1(#'channel.close'{reply_code = Code, reply_text = Text}, none, State) -> do(#'channel.close_ok'{}, none, noflow, State), handle_shutdown({server_initiated_close, Code, Text}, State); handle_method_from_server1(#'channel.close_ok'{}, none, State = #state{closing = Closing}) -> case Closing of {just_channel, {app_initiated_close, _, _} = Reason} -> handle_shutdown(Reason, rpc_bottom_half(ok, State)); {just_channel, {server_initiated_close, _, _} = Reason} -> handle_shutdown(Reason, rpc_bottom_half(closing, State)); {connection, Reason} -> handle_shutdown({connection_closing, Reason}, State) end; handle_method_from_server1(#'basic.consume_ok'{} = ConsumeOk, none, State) -> Consume = #'basic.consume'{} = pending_rpc_method(State), ok = call_to_consumer(ConsumeOk, Consume, State), {noreply, rpc_bottom_half(ConsumeOk, State)}; handle_method_from_server1(#'basic.cancel_ok'{} = CancelOk, none, State) -> Cancel = #'basic.cancel'{} = pending_rpc_method(State), ok = call_to_consumer(CancelOk, Cancel, State), {noreply, rpc_bottom_half(CancelOk, State)}; handle_method_from_server1(#'basic.cancel'{} = Cancel, none, State) -> ok = call_to_consumer(Cancel, none, State), {noreply, State}; handle_method_from_server1(#'basic.deliver'{} = Deliver, AmqpMsg, State) -> ok = call_to_consumer(Deliver, AmqpMsg, State), {noreply, State}; handle_method_from_server1(#'channel.flow'{active = Active} = Flow, none, State = #state{flow_handler = FlowHandler}) -> case FlowHandler of none -> ok; {Pid, _Ref} -> Pid ! Flow end, %% Putting the flow_ok in the queue so that the RPC queue can be %% flushed beforehand. Methods that made it to the queue are not %% blocked in any circumstance. {noreply, rpc_top_half(#'channel.flow_ok'{active = Active}, none, none, none, noflow, State#state{flow_active = Active})}; handle_method_from_server1( #'basic.return'{} = BasicReturn, AmqpMsg, State = #state{return_handler = ReturnHandler}) -> case ReturnHandler of none -> ?LOG_WARN("Channel (~p): received {~p, ~p} but there is " "no return handler registered~n", [self(), BasicReturn, AmqpMsg]); {Pid, _Ref} -> Pid ! {BasicReturn, AmqpMsg} end, {noreply, State}; handle_method_from_server1(#'basic.ack'{} = BasicAck, none, #state{confirm_handler = none} = State) -> {noreply, update_confirm_set(BasicAck, State)}; handle_method_from_server1(#'basic.ack'{} = BasicAck, none, #state{confirm_handler = {CH, _Ref}} = State) -> CH ! BasicAck, {noreply, update_confirm_set(BasicAck, State)}; handle_method_from_server1(#'basic.nack'{} = BasicNack, none, #state{confirm_handler = none} = State) -> ?LOG_WARN("Channel (~p): received ~p but there is no " "confirm handler registered~n", [self(), BasicNack]), {noreply, update_confirm_set(BasicNack, State)}; handle_method_from_server1(#'basic.nack'{} = BasicNack, none, #state{confirm_handler = {CH, _Ref}} = State) -> CH ! BasicNack, {noreply, update_confirm_set(BasicNack, State)}; handle_method_from_server1(Method, none, State) -> {noreply, rpc_bottom_half(Method, State)}; handle_method_from_server1(Method, Content, State) -> {noreply, rpc_bottom_half({Method, Content}, State)}. %% only used with manual consumer-to-queue flow control handle_method_from_server1(#'basic.deliver'{} = Deliver, AmqpMsg, DeliveryCtx, State) -> ok = call_to_consumer(Deliver, AmqpMsg, DeliveryCtx, State), {noreply, State}. %%--------------------------------------------------------------------------- %% Other handle_* functions %%--------------------------------------------------------------------------- handle_connection_closing(CloseType, Reason, State = #state{rpc_requests = RpcQueue, closing = Closing}) -> NewState = State#state{closing = {connection, Reason}}, case {CloseType, Closing, queue:is_empty(RpcQueue)} of {flush, false, false} -> erlang:send_after(?TIMEOUT_FLUSH, self(), timed_out_flushing_channel), {noreply, NewState}; {flush, {just_channel, _}, false} -> {noreply, NewState}; _ -> handle_shutdown({connection_closing, Reason}, NewState) end. handle_channel_exit(Reason = #amqp_error{name = ErrorName, explanation = Expl}, State = #state{connection = Connection, number = Number}) -> %% Sent by rabbit_channel for hard errors in the direct case ?LOG_ERR("connection ~p, channel ~p - error:~n~p~n", [Connection, Number, Reason]), {true, Code, _} = ?PROTOCOL:lookup_amqp_exception(ErrorName), ReportedReason = {server_initiated_close, Code, Expl}, amqp_gen_connection:hard_error_in_channel( Connection, self(), ReportedReason), handle_shutdown({connection_closing, ReportedReason}, State); handle_channel_exit(Reason, State) -> %% Unexpected death of a channel infrastructure process {stop, {infrastructure_died, Reason}, State}. handle_shutdown({_, 200, _}, State) -> {stop, normal, State}; handle_shutdown({connection_closing, {_, 200, _}}, State) -> {stop, normal, State}; handle_shutdown({connection_closing, normal}, State) -> {stop, normal, State}; handle_shutdown(Reason, State) -> {stop, {shutdown, Reason}, State}. %%--------------------------------------------------------------------------- %% Internal plumbing %%--------------------------------------------------------------------------- do(Method, Content, Flow, #state{driver = network, writer = W}) -> %% Catching because it expects the {channel_exit, _, _} message on error catch case {Content, Flow} of {none, _} -> rabbit_writer:send_command(W, Method); {_, flow} -> rabbit_writer:send_command_flow(W, Method, Content); {_, noflow} -> rabbit_writer:send_command(W, Method, Content) end; do(Method, Content, Flow, #state{driver = direct, writer = W}) -> %% ditto catching because... catch case {Content, Flow} of {none, _} -> rabbit_channel:do(W, Method); {_, flow} -> rabbit_channel:do_flow(W, Method, Content); {_, noflow} -> rabbit_channel:do(W, Method, Content) end. flush_writer(#state{driver = network, writer = Writer}) -> try rabbit_writer:flush(Writer) catch exit:noproc -> ok end; flush_writer(#state{driver = direct}) -> ok. amqp_msg(none) -> none; amqp_msg(Content) -> {Props, Payload} = rabbit_basic:from_content(Content), #amqp_msg{props = Props, payload = Payload}. build_content(none) -> none; build_content(#amqp_msg{props = Props, payload = Payload}) -> rabbit_basic:build_content(Props, Payload). check_block(_Method, _AmqpMsg, #state{closing = {just_channel, _}}) -> closing; check_block(_Method, _AmqpMsg, #state{closing = {connection, _}}) -> closing; check_block(_Method, none, #state{}) -> ok; check_block(_Method, #amqp_msg{}, #state{flow_active = false}) -> blocked; check_block(_Method, _AmqpMsg, #state{}) -> ok. check_invalid_method(#'channel.open'{}) -> {use_amqp_connection_module, "Use amqp_connection:open_channel/{1,2} instead"}; check_invalid_method(#'channel.close'{}) -> {use_close_function, "Use close/{1,3} instead"}; check_invalid_method(Method) -> case is_connection_method(Method) of true -> {connection_methods_not_allowed, "Sending connection methods is not allowed"}; false -> ok end. is_connection_method(Method) -> {ClassId, _} = ?PROTOCOL:method_id(element(1, Method)), ?PROTOCOL:lookup_class_name(ClassId) == connection. server_misbehaved(#amqp_error{} = AmqpError, State = #state{number = Number}) -> case rabbit_binary_generator:map_exception(Number, AmqpError, ?PROTOCOL) of {0, _} -> handle_shutdown({server_misbehaved, AmqpError}, State); {_, Close} -> ?LOG_WARN("Channel (~p) flushing and closing due to soft " "error caused by the server ~p~n", [self(), AmqpError]), Self = self(), spawn(fun () -> call(Self, Close) end), {noreply, State} end. update_confirm_set(#'basic.ack'{delivery_tag = SeqNo, multiple = Multiple}, State = #state{unconfirmed_set = USet}) -> maybe_notify_waiters( State#state{unconfirmed_set = update_unconfirmed(SeqNo, Multiple, USet)}); update_confirm_set(#'basic.nack'{delivery_tag = SeqNo, multiple = Multiple}, State = #state{unconfirmed_set = USet}) -> maybe_notify_waiters( State#state{unconfirmed_set = update_unconfirmed(SeqNo, Multiple, USet), only_acks_received = false}). update_unconfirmed(SeqNo, false, USet) -> gb_sets:del_element(SeqNo, USet); update_unconfirmed(SeqNo, true, USet) -> case gb_sets:is_empty(USet) of true -> USet; false -> {S, USet1} = gb_sets:take_smallest(USet), case S > SeqNo of true -> USet; false -> update_unconfirmed(SeqNo, true, USet1) end end. maybe_notify_waiters(State = #state{unconfirmed_set = USet}) -> case gb_sets:is_empty(USet) of false -> State; true -> notify_confirm_waiters(State) end. notify_confirm_waiters(State = #state{waiting_set = WSet, only_acks_received = OAR}) -> [begin safe_cancel_timer(TRef), gen_server:reply(From, OAR) end || {From, TRef} <- gb_trees:to_list(WSet)], State#state{waiting_set = gb_trees:empty(), only_acks_received = true}. handle_wait_for_confirms(_From, _Timeout, State = #state{next_pub_seqno = 0}) -> {reply, {error, not_in_confirm_mode}, State}; handle_wait_for_confirms(From, Timeout, State = #state{unconfirmed_set = USet, waiting_set = WSet}) -> case gb_sets:is_empty(USet) of true -> {reply, true, State}; false -> TRef = case Timeout of infinity -> undefined; _ -> erlang:send_after( Timeout * 1000, self(), {confirm_timeout, From}) end, {noreply, State#state{waiting_set = gb_trees:insert(From, TRef, WSet)}} end. call_to_consumer(Method, Args, #state{consumer = Consumer}) -> amqp_gen_consumer:call_consumer(Consumer, Method, Args). call_to_consumer(Method, Args, DeliveryCtx, #state{consumer = Consumer}) -> amqp_gen_consumer:call_consumer(Consumer, Method, Args, DeliveryCtx). safe_cancel_timer(undefined) -> ok; safe_cancel_timer(TRef) -> erlang:cancel_timer(TRef). rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/src/amqp_client.erl0000644000177700017770000000235312633765070027037 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% %% @private -module(amqp_client). -behaviour(application). -export([start/0]). -export([start/2, stop/1]). %%--------------------------------------------------------------------------- %% Interface %%--------------------------------------------------------------------------- start() -> application:start(amqp_client). %%--------------------------------------------------------------------------- %% application callbacks %%--------------------------------------------------------------------------- start(_StartType, _StartArgs) -> amqp_sup:start_link(). stop(_State) -> ok. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/CONTRIBUTING.md0000644000177700017770000000424512633765070025503 0ustar michaelmichael## Overview RabbitMQ projects use pull requests to discuss, collaborate on and accept code contributions. Pull requests is the primary place of discussing code changes. ## How to Contribute The process is fairly standard: * Fork the repository or repositories you plan on contributing to * Clone [RabbitMQ umbrella repository](https://github.com/rabbitmq/rabbitmq-public-umbrella) * `cd umbrella`, `make co` * Create a branch with a descriptive name in the relevant repositories * Make your changes, run tests, commit with a [descriptive message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), push to your fork * Submit pull requests with an explanation what has been changed and **why** * Submit a filled out and signed [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) if needed (see below) * Be patient. We will get to your pull request eventually If what you are going to work on is a substantial change, please first ask the core team of their opinion on [RabbitMQ mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). ## (Brief) Code of Conduct In one line: don't be a dick. Be respectful to the maintainers and other contributors. Open source contributors put long hours into developing projects and doing user support. Those projects and user support are available for free. We believe this deserves some respect. Be respectful to people of all races, genders, religious beliefs and political views. Regardless of how brilliant a pull request is technically, we will not tolerate disrespectful or aggressive behaviour. Contributors who violate this straightforward Code of Conduct will see their pull requests closed and locked. ## Contributor Agreement If you want to contribute a non-trivial change, please submit a signed copy of our [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) around the time you submit your pull request. This will make it much easier (in some cases, possible) for the RabbitMQ team at Pivotal to merge your contribution. ## Where to Ask Questions If something isn't clear, feel free to ask on our [mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/test/0000755000177700017770000000000012633765070024224 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/test/negative_test_util.erl0000644000177700017770000002213212633765070030626 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(negative_test_util). -include("amqp_client_internal.hrl"). -include_lib("eunit/include/eunit.hrl"). -compile(export_all). non_existent_exchange_test() -> {ok, Connection} = test_util:new_connection(), X = <<"test">>, RoutingKey = <<"a">>, Payload = <<"foobar">>, {ok, Channel} = amqp_connection:open_channel(Connection), {ok, OtherChannel} = amqp_connection:open_channel(Connection), amqp_channel:call(Channel, #'exchange.declare'{exchange = X}), %% Deliberately mix up the routingkey and exchange arguments Publish = #'basic.publish'{exchange = RoutingKey, routing_key = X}, amqp_channel:call(Channel, Publish, #amqp_msg{payload = Payload}), test_util:wait_for_death(Channel), %% Make sure Connection and OtherChannel still serve us and are not dead {ok, _} = amqp_connection:open_channel(Connection), amqp_channel:call(OtherChannel, #'exchange.delete'{exchange = X}), amqp_connection:close(Connection). bogus_rpc_test() -> {ok, Connection} = test_util:new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), %% Deliberately bind to a non-existent queue Bind = #'queue.bind'{exchange = <<"amq.topic">>, queue = <<"does-not-exist">>, routing_key = <<>>}, try amqp_channel:call(Channel, Bind) of _ -> exit(expected_to_exit) catch exit:{{shutdown, {server_initiated_close, Code, _}},_} -> ?assertMatch(?NOT_FOUND, Code) end, test_util:wait_for_death(Channel), ?assertMatch(true, is_process_alive(Connection)), amqp_connection:close(Connection). hard_error_test() -> {ok, Connection} = test_util:new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), {ok, OtherChannel} = amqp_connection:open_channel(Connection), OtherChannelMonitor = erlang:monitor(process, OtherChannel), Qos = #'basic.qos'{prefetch_size = 10000000}, try amqp_channel:call(Channel, Qos) of _ -> exit(expected_to_exit) catch exit:{{shutdown, {connection_closing, {server_initiated_close, ?NOT_IMPLEMENTED, _}}}, _} -> ok end, receive {'DOWN', OtherChannelMonitor, process, OtherChannel, OtherExit} -> ?assertMatch({shutdown, {connection_closing, {server_initiated_close, ?NOT_IMPLEMENTED, _}}}, OtherExit) end, test_util:wait_for_death(Channel), test_util:wait_for_death(Connection). %% The connection should die if the underlying connection is prematurely %% closed. For a network connection, this means that the TCP socket is %% closed. For a direct connection (remotely only, of course), this means that %% the RabbitMQ node appears as down. connection_failure_test() -> {ok, Connection} = test_util:new_connection(), case amqp_connection:info(Connection, [type, amqp_params]) of [{type, direct}, {amqp_params, Params}] -> case Params#amqp_params_direct.node of N when N == node() -> amqp_connection:close(Connection); N -> true = erlang:disconnect_node(N), net_adm:ping(N) end; [{type, network}, {amqp_params, _}] -> [{sock, Sock}] = amqp_connection:info(Connection, [sock]), ok = gen_tcp:close(Sock) end, test_util:wait_for_death(Connection), ok. %% An error in a channel should result in the death of the entire connection. %% The death of the channel is caused by an error in generating the frames %% (writer dies) channel_writer_death_test() -> {ok, Connection} = test_util:new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), Publish = #'basic.publish'{routing_key = <<>>, exchange = <<>>}, QoS = #'basic.qos'{prefetch_count = 0}, Message = #amqp_msg{props = <<>>, payload = <<>>}, amqp_channel:cast(Channel, Publish, Message), ?assertExit(_, amqp_channel:call(Channel, QoS)), test_util:wait_for_death(Channel), test_util:wait_for_death(Connection), ok. %% An error in the channel process should result in the death of the entire %% connection. The death of the channel is caused by making a call with an %% invalid message to the channel process channel_death_test() -> {ok, Connection} = test_util:new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), ?assertExit(_, amqp_channel:call(Channel, bogus_message)), test_util:wait_for_death(Channel), test_util:wait_for_death(Connection), ok. %% Attempting to send a shortstr longer than 255 bytes in a property field %% should fail - this only applies to the network case shortstr_overflow_property_test() -> {ok, Connection} = test_util:new_connection(just_network), {ok, Channel} = amqp_connection:open_channel(Connection), SentString = << <<"k">> || _ <- lists:seq(1, 340)>>, #'queue.declare_ok'{queue = Q} = amqp_channel:call(Channel, #'queue.declare'{exclusive = true}), Publish = #'basic.publish'{exchange = <<>>, routing_key = Q}, PBasic = #'P_basic'{content_type = SentString}, AmqpMsg = #amqp_msg{payload = <<"foobar">>, props = PBasic}, QoS = #'basic.qos'{prefetch_count = 0}, amqp_channel:cast(Channel, Publish, AmqpMsg), ?assertExit(_, amqp_channel:call(Channel, QoS)), test_util:wait_for_death(Channel), test_util:wait_for_death(Connection), ok. %% Attempting to send a shortstr longer than 255 bytes in a method's field %% should fail - this only applies to the network case shortstr_overflow_field_test() -> {ok, Connection} = test_util:new_connection(just_network), {ok, Channel} = amqp_connection:open_channel(Connection), SentString = << <<"k">> || _ <- lists:seq(1, 340)>>, #'queue.declare_ok'{queue = Q} = amqp_channel:call(Channel, #'queue.declare'{exclusive = true}), ?assertExit(_, amqp_channel:call( Channel, #'basic.consume'{queue = Q, no_ack = true, consumer_tag = SentString})), test_util:wait_for_death(Channel), test_util:wait_for_death(Connection), ok. %% Simulates a #'connection.open'{} method received on non-zero channel. The %% connection is expected to send a '#connection.close{}' to the server with %% reply code command_invalid command_invalid_over_channel_test() -> {ok, Connection} = test_util:new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), MonitorRef = erlang:monitor(process, Connection), case amqp_connection:info(Connection, [type]) of [{type, direct}] -> Channel ! {send_command, #'connection.open'{}}; [{type, network}] -> gen_server:cast(Channel, {method, #'connection.open'{}, none, noflow}) end, assert_down_with_error(MonitorRef, command_invalid), ?assertNot(is_process_alive(Channel)), ok. %% Simulates a #'basic.ack'{} method received on channel zero. The connection %% is expected to send a '#connection.close{}' to the server with reply code %% command_invalid - this only applies to the network case command_invalid_over_channel0_test() -> {ok, Connection} = test_util:new_connection(just_network), gen_server:cast(Connection, {method, #'basic.ack'{}, none, noflow}), MonitorRef = erlang:monitor(process, Connection), assert_down_with_error(MonitorRef, command_invalid), ok. assert_down_with_error(MonitorRef, CodeAtom) -> receive {'DOWN', MonitorRef, process, _, Reason} -> {shutdown, {server_misbehaved, Code, _}} = Reason, ?assertMatch(CodeAtom, ?PROTOCOL:amqp_exception(Code)) after 2000 -> exit(did_not_die) end. non_existent_user_test() -> Params = [{username, <<"no-user">>}, {password, <<"no-user">>}], ?assertMatch({error, {auth_failure, _}}, test_util:new_connection(Params)). invalid_password_test() -> Params = [{username, <<"guest">>}, {password, <<"bad">>}], ?assertMatch({error, {auth_failure, _}}, test_util:new_connection(Params)). non_existent_vhost_test() -> Params = [{virtual_host, <<"oops">>}], ?assertMatch({error, access_refused}, test_util:new_connection(Params)). no_permission_test() -> Params = [{username, <<"test_user_no_perm">>}, {password, <<"test_user_no_perm">>}], ?assertMatch({error, access_refused}, test_util:new_connection(Params)). rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/test/Makefile0000644000177700017770000000202612633765070025664 0ustar michaelmichael# The contents of this file are subject to the Mozilla Public License # Version 1.1 (the "License"); you may not use this file except in # compliance with the License. You may obtain a copy of the License at # http://www.mozilla.org/MPL/ # # 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 Original Code is RabbitMQ. # # The Initial Developer of the Original Code is GoPivotal, Inc. # Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. # TEST_SOURCES=$(wildcard *.erl) TEST_TARGETS=$(patsubst %.erl, %.beam, $(TEST_SOURCES)) INCLUDES=$(wildcard ../$(INCLUDE_DIR)/*.hrl) DEPS_DIR=../deps ERLC_OPTS=-I ../$(INCLUDE_DIR) -o ./ -Wall -v +debug_info LIBS_PATH=ERL_LIBS=$(DEPS_DIR) all: compile compile: $(TEST_TARGETS) %.beam: %.erl $(DEPS_DIR)/$(COMMON_PACKAGE_DIR) $(INCLUDES) $(LIBS_PATH) erlc $(ERLC_OPTS) $< clean: rm -f *.beam rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/test/test_util.erl0000644000177700017770000013651612633765070026760 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2011-2015 Pivotal Software, Inc. All rights reserved. %% -module(test_util). -include_lib("eunit/include/eunit.hrl"). -include("amqp_client_internal.hrl"). -compile([export_all]). -define(TEST_REPEATS, 100). %% The latch constant defines how many processes are spawned in order %% to run certain functionality in parallel. It follows the standard %% countdown latch pattern. -define(Latch, 100). %% The wait constant defines how long a consumer waits before it %% unsubscribes -define(Wait, 200). %% How to long wait for a process to die after an expected failure -define(DeathWait, 5000). %% AMQP URI parsing test amqp_uri_parse_test() -> %% From the spec (adapted) ?assertMatch({ok, #amqp_params_network{username = <<"user">>, password = <<"pass">>, host = "host", port = 10000, virtual_host = <<"vhost">>, heartbeat = 5}}, amqp_uri:parse( "amqp://user:pass@host:10000/vhost?heartbeat=5")), ?assertMatch({ok, #amqp_params_network{username = <<"usera">>, password = <<"apass">>, host = "hoast", port = 10000, virtual_host = <<"v/host">>}}, amqp_uri:parse( "aMQp://user%61:%61pass@ho%61st:10000/v%2fhost")), ?assertMatch({ok, #amqp_params_direct{}}, amqp_uri:parse("amqp://")), ?assertMatch({ok, #amqp_params_direct{username = <<"">>, virtual_host = <<"">>}}, amqp_uri:parse("amqp://:@/")), ?assertMatch({ok, #amqp_params_network{username = <<"">>, password = <<"">>, virtual_host = <<"">>, host = "host"}}, amqp_uri:parse("amqp://:@host/")), ?assertMatch({ok, #amqp_params_direct{username = <<"user">>}}, amqp_uri:parse("amqp://user@")), ?assertMatch({ok, #amqp_params_network{username = <<"user">>, password = <<"pass">>, host = "localhost"}}, amqp_uri:parse("amqp://user:pass@localhost")), ?assertMatch({ok, #amqp_params_network{host = "host", virtual_host = <<"/">>}}, amqp_uri:parse("amqp://host")), ?assertMatch({ok, #amqp_params_network{port = 10000, host = "localhost"}}, amqp_uri:parse("amqp://localhost:10000")), ?assertMatch({ok, #amqp_params_direct{virtual_host = <<"vhost">>}}, amqp_uri:parse("amqp:///vhost")), ?assertMatch({ok, #amqp_params_network{host = "host", virtual_host = <<"">>}}, amqp_uri:parse("amqp://host/")), ?assertMatch({ok, #amqp_params_network{host = "host", virtual_host = <<"/">>}}, amqp_uri:parse("amqp://host/%2f")), ?assertMatch({ok, #amqp_params_network{host = "::1"}}, amqp_uri:parse("amqp://[::1]")), %% Varous other cases ?assertMatch({ok, #amqp_params_network{host = "host", port = 100}}, amqp_uri:parse("amqp://host:100")), ?assertMatch({ok, #amqp_params_network{host = "::1", port = 100}}, amqp_uri:parse("amqp://[::1]:100")), ?assertMatch({ok, #amqp_params_network{host = "host", virtual_host = <<"blah">>}}, amqp_uri:parse("amqp://host/blah")), ?assertMatch({ok, #amqp_params_network{host = "host", port = 100, virtual_host = <<"blah">>}}, amqp_uri:parse("amqp://host:100/blah")), ?assertMatch({ok, #amqp_params_network{host = "::1", virtual_host = <<"blah">>}}, amqp_uri:parse("amqp://[::1]/blah")), ?assertMatch({ok, #amqp_params_network{host = "::1", port = 100, virtual_host = <<"blah">>}}, amqp_uri:parse("amqp://[::1]:100/blah")), ?assertMatch({ok, #amqp_params_network{username = <<"user">>, password = <<"pass">>, host = "host"}}, amqp_uri:parse("amqp://user:pass@host")), ?assertMatch({ok, #amqp_params_network{username = <<"user">>, password = <<"pass">>, port = 100}}, amqp_uri:parse("amqp://user:pass@host:100")), ?assertMatch({ok, #amqp_params_network{username = <<"user">>, password = <<"pass">>, host = "::1"}}, amqp_uri:parse("amqp://user:pass@[::1]")), ?assertMatch({ok, #amqp_params_network{username = <<"user">>, password = <<"pass">>, host = "::1", port = 100}}, amqp_uri:parse("amqp://user:pass@[::1]:100")), %% Various failure cases ?assertMatch({error, _}, amqp_uri:parse("http://www.rabbitmq.com")), ?assertMatch({error, _}, amqp_uri:parse("amqp://foo:bar:baz")), ?assertMatch({error, _}, amqp_uri:parse("amqp://foo[::1]")), ?assertMatch({error, _}, amqp_uri:parse("amqp://foo:[::1]")), ?assertMatch({error, _}, amqp_uri:parse("amqp://[::1]foo")), ?assertMatch({error, _}, amqp_uri:parse("amqp://foo:1000xyz")), ?assertMatch({error, _}, amqp_uri:parse("amqp://foo:1000000")), ?assertMatch({error, _}, amqp_uri:parse("amqp://foo/bar/baz")), ?assertMatch({error, _}, amqp_uri:parse("amqp://foo%1")), ?assertMatch({error, _}, amqp_uri:parse("amqp://foo%1x")), ?assertMatch({error, _}, amqp_uri:parse("amqp://foo%xy")), ok. %%-------------------------------------------------------------------- %% Destination Parsing Tests %%-------------------------------------------------------------------- route_destination_test() -> %% valid queue ?assertMatch({ok, {queue, "test"}}, parse_dest("/queue/test")), %% valid topic ?assertMatch({ok, {topic, "test"}}, parse_dest("/topic/test")), %% valid exchange ?assertMatch({ok, {exchange, {"test", undefined}}}, parse_dest("/exchange/test")), %% valid temp queue ?assertMatch({ok, {temp_queue, "test"}}, parse_dest("/temp-queue/test")), %% valid reply queue ?assertMatch({ok, {reply_queue, "test"}}, parse_dest("/reply-queue/test")), ?assertMatch({ok, {reply_queue, "test/2"}}, parse_dest("/reply-queue/test/2")), %% valid exchange with pattern ?assertMatch({ok, {exchange, {"test", "pattern"}}}, parse_dest("/exchange/test/pattern")), %% valid pre-declared queue ?assertMatch({ok, {amqqueue, "test"}}, parse_dest("/amq/queue/test")), %% queue without name ?assertMatch({error, {invalid_destination, queue, ""}}, parse_dest("/queue")), ?assertMatch({ok, {queue, undefined}}, parse_dest("/queue", true)), %% topic without name ?assertMatch({error, {invalid_destination, topic, ""}}, parse_dest("/topic")), %% exchange without name ?assertMatch({error, {invalid_destination, exchange, ""}}, parse_dest("/exchange")), %% exchange default name ?assertMatch({error, {invalid_destination, exchange, "//foo"}}, parse_dest("/exchange//foo")), %% amqqueue without name ?assertMatch({error, {invalid_destination, amqqueue, ""}}, parse_dest("/amq/queue")), %% queue without name with trailing slash ?assertMatch({error, {invalid_destination, queue, "/"}}, parse_dest("/queue/")), %% topic without name with trailing slash ?assertMatch({error, {invalid_destination, topic, "/"}}, parse_dest("/topic/")), %% exchange without name with trailing slash ?assertMatch({error, {invalid_destination, exchange, "/"}}, parse_dest("/exchange/")), %% queue with invalid name ?assertMatch({error, {invalid_destination, queue, "/foo/bar"}}, parse_dest("/queue/foo/bar")), %% topic with invalid name ?assertMatch({error, {invalid_destination, topic, "/foo/bar"}}, parse_dest("/topic/foo/bar")), %% exchange with invalid name ?assertMatch({error, {invalid_destination, exchange, "/foo/bar/baz"}}, parse_dest("/exchange/foo/bar/baz")), %% unknown destination ?assertMatch({error, {unknown_destination, "/blah/boo"}}, parse_dest("/blah/boo")), %% queue with escaped name ?assertMatch({ok, {queue, "te/st"}}, parse_dest("/queue/te%2Fst")), %% valid exchange with escaped name and pattern ?assertMatch({ok, {exchange, {"te/st", "pa/tt/ern"}}}, parse_dest("/exchange/te%2Fst/pa%2Ftt%2Fern")), ok. parse_dest(Destination, Params) -> rabbit_routing_util:parse_endpoint(Destination, Params). parse_dest(Destination) -> rabbit_routing_util:parse_endpoint(Destination). %%%% %% %% This is an example of how the client interaction should work %% %% {ok, Connection} = amqp_connection:start(network), %% {ok, Channel} = amqp_connection:open_channel(Connection), %% %%...do something useful %% amqp_channel:close(Channel), %% amqp_connection:close(Connection). %% lifecycle_test() -> {ok, Connection} = new_connection(), X = <<"x">>, {ok, Channel} = amqp_connection:open_channel(Connection), amqp_channel:call(Channel, #'exchange.declare'{exchange = X, type = <<"topic">>}), Parent = self(), [spawn(fun () -> queue_exchange_binding(Channel, X, Parent, Tag) end) || Tag <- lists:seq(1, ?Latch)], latch_loop(), amqp_channel:call(Channel, #'exchange.delete'{exchange = X}), teardown(Connection, Channel), ok. direct_no_user_test() -> {ok, Connection} = new_connection(just_direct, [{username, none}, {password, none}]), amqp_connection:close(Connection), wait_for_death(Connection). direct_no_password_test() -> {ok, Connection} = new_connection(just_direct, [{username, <<"guest">>}, {password, none}]), amqp_connection:close(Connection), wait_for_death(Connection). queue_exchange_binding(Channel, X, Parent, Tag) -> receive nothing -> ok after (?Latch - Tag rem 7) * 10 -> ok end, Q = <<"a.b.c", Tag:32>>, Binding = <<"a.b.c.*">>, #'queue.declare_ok'{queue = Q1} = amqp_channel:call(Channel, #'queue.declare'{queue = Q}), ?assertMatch(Q, Q1), Route = #'queue.bind'{queue = Q, exchange = X, routing_key = Binding}, amqp_channel:call(Channel, Route), amqp_channel:call(Channel, #'queue.delete'{queue = Q}), Parent ! finished. nowait_exchange_declare_test() -> {ok, Connection} = new_connection(), X = <<"x">>, {ok, Channel} = amqp_connection:open_channel(Connection), ?assertEqual( ok, amqp_channel:call(Channel, #'exchange.declare'{exchange = X, type = <<"topic">>, nowait = true})), teardown(Connection, Channel). channel_lifecycle_test() -> {ok, Connection} = new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), amqp_channel:close(Channel), {ok, Channel2} = amqp_connection:open_channel(Connection), teardown(Connection, Channel2), ok. abstract_method_serialization_test(BeforeFun, MultiOpFun, AfterFun) -> {ok, Connection} = new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), X = <<"test">>, Payload = list_to_binary(["x" || _ <- lists:seq(1, 1000)]), OpsPerProcess = 20, #'exchange.declare_ok'{} = amqp_channel:call(Channel, #'exchange.declare'{exchange = X, type = <<"topic">>}), BeforeRet = BeforeFun(Channel, X), Parent = self(), [spawn(fun () -> Ret = [MultiOpFun(Channel, X, Payload, BeforeRet, I) || _ <- lists:seq(1, OpsPerProcess)], Parent ! {finished, Ret} end) || I <- lists:seq(1, ?Latch)], MultiOpRet = latch_loop(), AfterFun(Channel, X, Payload, BeforeRet, MultiOpRet), amqp_channel:call(Channel, #'exchange.delete'{exchange = X}), teardown(Connection, Channel). %% This is designed to exercize the internal queuing mechanism %% to ensure that sync methods are properly serialized sync_method_serialization_test() -> abstract_method_serialization_test( fun (_, _) -> ok end, fun (Channel, _, _, _, Count) -> Q = fmt("test-~p", [Count]), #'queue.declare_ok'{queue = Q1} = amqp_channel:call(Channel, #'queue.declare'{queue = Q, exclusive = true}), ?assertMatch(Q, Q1) end, fun (_, _, _, _, _) -> ok end). %% This is designed to exercize the internal queuing mechanism %% to ensure that sending async methods and then a sync method is serialized %% properly async_sync_method_serialization_test() -> abstract_method_serialization_test( fun (Channel, _X) -> #'queue.declare_ok'{queue = Q} = amqp_channel:call(Channel, #'queue.declare'{}), Q end, fun (Channel, X, Payload, _, _) -> %% The async methods ok = amqp_channel:call(Channel, #'basic.publish'{exchange = X, routing_key = <<"a">>}, #amqp_msg{payload = Payload}) end, fun (Channel, X, _, Q, _) -> %% The sync method #'queue.bind_ok'{} = amqp_channel:call(Channel, #'queue.bind'{exchange = X, queue = Q, routing_key = <<"a">>}), %% No message should have been routed #'queue.declare_ok'{message_count = 0} = amqp_channel:call(Channel, #'queue.declare'{queue = Q, passive = true}) end). %% This is designed to exercize the internal queuing mechanism %% to ensure that sending sync methods and then an async method is serialized %% properly sync_async_method_serialization_test() -> abstract_method_serialization_test( fun (_, _) -> ok end, fun (Channel, X, _Payload, _, _) -> %% The sync methods (called with cast to resume immediately; %% the order should still be preserved) #'queue.declare_ok'{queue = Q} = amqp_channel:call(Channel, #'queue.declare'{exclusive = true}), amqp_channel:cast(Channel, #'queue.bind'{exchange = X, queue = Q, routing_key= <<"a">>}), Q end, fun (Channel, X, Payload, _, MultiOpRet) -> #'confirm.select_ok'{} = amqp_channel:call( Channel, #'confirm.select'{}), ok = amqp_channel:call(Channel, #'basic.publish'{exchange = X, routing_key = <<"a">>}, #amqp_msg{payload = Payload}), %% All queues must have gotten this message true = amqp_channel:wait_for_confirms(Channel), lists:foreach( fun (Q) -> #'queue.declare_ok'{message_count = 1} = amqp_channel:call( Channel, #'queue.declare'{queue = Q, passive = true}) end, lists:flatten(MultiOpRet)) end). queue_unbind_test() -> {ok, Connection} = new_connection(), X = <<"eggs">>, Q = <<"foobar">>, Key = <<"quay">>, Payload = <<"foobar">>, {ok, Channel} = amqp_connection:open_channel(Connection), amqp_channel:call(Channel, #'exchange.declare'{exchange = X}), amqp_channel:call(Channel, #'queue.declare'{queue = Q}), Bind = #'queue.bind'{queue = Q, exchange = X, routing_key = Key}, amqp_channel:call(Channel, Bind), Publish = #'basic.publish'{exchange = X, routing_key = Key}, amqp_channel:call(Channel, Publish, Msg = #amqp_msg{payload = Payload}), get_and_assert_equals(Channel, Q, Payload), Unbind = #'queue.unbind'{queue = Q, exchange = X, routing_key = Key}, amqp_channel:call(Channel, Unbind), amqp_channel:call(Channel, Publish, Msg), get_and_assert_empty(Channel, Q), teardown(Connection, Channel). get_and_assert_empty(Channel, Q) -> #'basic.get_empty'{} = amqp_channel:call(Channel, #'basic.get'{queue = Q, no_ack = true}). get_and_assert_equals(Channel, Q, Payload) -> get_and_assert_equals(Channel, Q, Payload, true). get_and_assert_equals(Channel, Q, Payload, NoAck) -> {GetOk = #'basic.get_ok'{}, Content} = amqp_channel:call(Channel, #'basic.get'{queue = Q, no_ack = NoAck}), #amqp_msg{payload = Payload2} = Content, ?assertMatch(Payload, Payload2), GetOk. basic_get_test() -> basic_get_test1(new_connection()). basic_get_ipv6_test() -> basic_get_test1(new_connection(just_network, [{host, "::1"}])). basic_get_test1({ok, Connection}) -> {ok, Channel} = amqp_connection:open_channel(Connection), {ok, Q} = setup_publish(Channel), get_and_assert_equals(Channel, Q, <<"foobar">>), get_and_assert_empty(Channel, Q), teardown(Connection, Channel). basic_return_test() -> {ok, Connection} = new_connection(), X = <<"test">>, Q = <<"test">>, Key = <<"test">>, Payload = <<"qwerty">>, {ok, Channel} = amqp_connection:open_channel(Connection), amqp_channel:register_return_handler(Channel, self()), amqp_channel:call(Channel, #'exchange.declare'{exchange = X}), amqp_channel:call(Channel, #'queue.declare'{queue = Q, exclusive = true}), Publish = #'basic.publish'{exchange = X, routing_key = Key, mandatory = true}, amqp_channel:call(Channel, Publish, #amqp_msg{payload = Payload}), receive {BasicReturn = #'basic.return'{}, Content} -> #'basic.return'{reply_code = ReplyCode, exchange = X} = BasicReturn, ?assertMatch(?NO_ROUTE, ReplyCode), #amqp_msg{payload = Payload2} = Content, ?assertMatch(Payload, Payload2); WhatsThis1 -> exit({bad_message, WhatsThis1}) after 2000 -> exit(no_return_received) end, amqp_channel:unregister_return_handler(Channel), Publish = #'basic.publish'{exchange = X, routing_key = Key, mandatory = true}, amqp_channel:call(Channel, Publish, #amqp_msg{payload = Payload}), ok = receive {_BasicReturn = #'basic.return'{}, _Content} -> unexpected_return; WhatsThis2 -> exit({bad_message, WhatsThis2}) after 2000 -> ok end, amqp_channel:call(Channel, #'exchange.delete'{exchange = X}), teardown(Connection, Channel). channel_repeat_open_close_test() -> {ok, Connection} = new_connection(), lists:foreach( fun(_) -> {ok, Ch} = amqp_connection:open_channel(Connection), ok = amqp_channel:close(Ch) end, lists:seq(1, 50)), amqp_connection:close(Connection), wait_for_death(Connection). channel_multi_open_close_test() -> {ok, Connection} = new_connection(), [spawn_link( fun() -> try amqp_connection:open_channel(Connection) of {ok, Ch} -> try amqp_channel:close(Ch) of ok -> ok; closing -> ok catch exit:{noproc, _} -> ok; exit:{normal, _} -> ok end; closing -> ok catch exit:{noproc, _} -> ok; exit:{normal, _} -> ok end end) || _ <- lists:seq(1, 50)], erlang:yield(), amqp_connection:close(Connection), wait_for_death(Connection). basic_ack_test() -> {ok, Connection} = new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), {ok, Q} = setup_publish(Channel), {#'basic.get_ok'{delivery_tag = Tag}, _} = amqp_channel:call(Channel, #'basic.get'{queue = Q, no_ack = false}), amqp_channel:cast(Channel, #'basic.ack'{delivery_tag = Tag}), teardown(Connection, Channel). basic_ack_call_test() -> {ok, Connection} = new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), {ok, Q} = setup_publish(Channel), {#'basic.get_ok'{delivery_tag = Tag}, _} = amqp_channel:call(Channel, #'basic.get'{queue = Q, no_ack = false}), amqp_channel:call(Channel, #'basic.ack'{delivery_tag = Tag}), teardown(Connection, Channel). basic_consume_test() -> {ok, Connection} = new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), X = <<"test">>, amqp_channel:call(Channel, #'exchange.declare'{exchange = X}), RoutingKey = <<"key">>, Parent = self(), [spawn_link(fun () -> consume_loop(Channel, X, RoutingKey, Parent, <>) end) || Tag <- lists:seq(1, ?Latch)], timer:sleep(?Latch * 20), Publish = #'basic.publish'{exchange = X, routing_key = RoutingKey}, amqp_channel:call(Channel, Publish, #amqp_msg{payload = <<"foobar">>}), latch_loop(), amqp_channel:call(Channel, #'exchange.delete'{exchange = X}), teardown(Connection, Channel). consume_loop(Channel, X, RoutingKey, Parent, Tag) -> #'queue.declare_ok'{queue = Q} = amqp_channel:call(Channel, #'queue.declare'{}), #'queue.bind_ok'{} = amqp_channel:call(Channel, #'queue.bind'{queue = Q, exchange = X, routing_key = RoutingKey}), #'basic.consume_ok'{} = amqp_channel:call(Channel, #'basic.consume'{queue = Q, consumer_tag = Tag}), receive #'basic.consume_ok'{consumer_tag = Tag} -> ok end, receive {#'basic.deliver'{}, _} -> ok end, #'basic.cancel_ok'{} = amqp_channel:call(Channel, #'basic.cancel'{consumer_tag = Tag}), receive #'basic.cancel_ok'{consumer_tag = Tag} -> ok end, Parent ! finished. consume_notification_test() -> {ok, Connection} = new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), #'queue.declare_ok'{queue = Q} = amqp_channel:call(Channel, #'queue.declare'{}), #'basic.consume_ok'{consumer_tag = CTag} = ConsumeOk = amqp_channel:call(Channel, #'basic.consume'{queue = Q}), receive ConsumeOk -> ok end, #'queue.delete_ok'{} = amqp_channel:call(Channel, #'queue.delete'{queue = Q}), receive #'basic.cancel'{consumer_tag = CTag} -> ok end, amqp_channel:close(Channel), ok. basic_recover_test() -> {ok, Connection} = new_connection(), {ok, Channel} = amqp_connection:open_channel( Connection, {amqp_direct_consumer, [self()]}), #'queue.declare_ok'{queue = Q} = amqp_channel:call(Channel, #'queue.declare'{}), #'basic.consume_ok'{consumer_tag = Tag} = amqp_channel:call(Channel, #'basic.consume'{queue = Q}), receive #'basic.consume_ok'{consumer_tag = Tag} -> ok end, Publish = #'basic.publish'{exchange = <<>>, routing_key = Q}, amqp_channel:call(Channel, Publish, #amqp_msg{payload = <<"foobar">>}), receive {#'basic.deliver'{consumer_tag = Tag}, _} -> %% no_ack set to false, but don't send ack ok end, BasicRecover = #'basic.recover'{requeue = true}, amqp_channel:cast(Channel, BasicRecover), receive {#'basic.deliver'{consumer_tag = Tag, delivery_tag = DeliveryTag2}, _} -> amqp_channel:cast(Channel, #'basic.ack'{delivery_tag = DeliveryTag2}) end, teardown(Connection, Channel). simultaneous_close_test() -> {ok, Connection} = new_connection(), ChannelNumber = 5, {ok, Channel1} = amqp_connection:open_channel(Connection, ChannelNumber), %% Publish to non-existent exchange and immediately close channel amqp_channel:cast(Channel1, #'basic.publish'{exchange = <<"does-not-exist">>, routing_key = <<"a">>}, #amqp_msg{payload = <<"foobar">>}), try amqp_channel:close(Channel1) of ok -> wait_for_death(Channel1); closing -> wait_for_death(Channel1) catch exit:{noproc, _} -> ok; exit:{{shutdown, {server_initiated_close, ?NOT_FOUND, _}}, _} -> ok end, %% Channel2 (opened with the exact same number as Channel1) %% should not receive a close_ok (which is intended for Channel1) {ok, Channel2} = amqp_connection:open_channel(Connection, ChannelNumber), %% Make sure Channel2 functions normally #'exchange.declare_ok'{} = amqp_channel:call(Channel2, #'exchange.declare'{exchange = <<"test">>}), #'exchange.delete_ok'{} = amqp_channel:call(Channel2, #'exchange.delete'{exchange = <<"test">>}), teardown(Connection, Channel2). channel_tune_negotiation_test() -> {ok, Connection} = new_connection([{channel_max, 10}]), amqp_connection:close(Connection). basic_qos_test() -> [NoQos, Qos] = [basic_qos_test(Prefetch) || Prefetch <- [0,1]], ExpectedRatio = (1+1) / (1+50/5), FudgeFactor = 2, %% account for timing variations ?assertMatch(true, Qos / NoQos < ExpectedRatio * FudgeFactor). basic_qos_test(Prefetch) -> {ok, Connection} = new_connection(), Messages = 100, Workers = [5, 50], Parent = self(), {ok, Chan} = amqp_connection:open_channel(Connection), #'queue.declare_ok'{queue = Q} = amqp_channel:call(Chan, #'queue.declare'{}), Kids = [spawn( fun() -> {ok, Channel} = amqp_connection:open_channel(Connection), amqp_channel:call(Channel, #'basic.qos'{prefetch_count = Prefetch}), amqp_channel:call(Channel, #'basic.consume'{queue = Q}), Parent ! finished, sleeping_consumer(Channel, Sleep, Parent) end) || Sleep <- Workers], latch_loop(length(Kids)), spawn(fun() -> {ok, Channel} = amqp_connection:open_channel(Connection), producer_loop(Channel, Q, Messages) end), {Res, _} = timer:tc(erlang, apply, [fun latch_loop/1, [Messages]]), [Kid ! stop || Kid <- Kids], latch_loop(length(Kids)), teardown(Connection, Chan), Res. sleeping_consumer(Channel, Sleep, Parent) -> receive stop -> do_stop(Channel, Parent); #'basic.consume_ok'{} -> sleeping_consumer(Channel, Sleep, Parent); #'basic.cancel_ok'{} -> exit(unexpected_cancel_ok); {#'basic.deliver'{delivery_tag = DeliveryTag}, _Content} -> Parent ! finished, receive stop -> do_stop(Channel, Parent) after Sleep -> ok end, amqp_channel:cast(Channel, #'basic.ack'{delivery_tag = DeliveryTag}), sleeping_consumer(Channel, Sleep, Parent) end. do_stop(Channel, Parent) -> Parent ! finished, amqp_channel:close(Channel), wait_for_death(Channel), exit(normal). producer_loop(Channel, _RoutingKey, 0) -> amqp_channel:close(Channel), wait_for_death(Channel), ok; producer_loop(Channel, RoutingKey, N) -> Publish = #'basic.publish'{exchange = <<>>, routing_key = RoutingKey}, amqp_channel:call(Channel, Publish, #amqp_msg{payload = <<>>}), producer_loop(Channel, RoutingKey, N - 1). confirm_test() -> {ok, Connection} = new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), #'confirm.select_ok'{} = amqp_channel:call(Channel, #'confirm.select'{}), amqp_channel:register_confirm_handler(Channel, self()), {ok, Q} = setup_publish(Channel), {#'basic.get_ok'{}, _} = amqp_channel:call(Channel, #'basic.get'{queue = Q, no_ack = false}), ok = receive #'basic.ack'{} -> ok; #'basic.nack'{} -> fail after 2000 -> exit(did_not_receive_pub_ack) end, teardown(Connection, Channel). confirm_barrier_test() -> {ok, Connection} = new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), #'confirm.select_ok'{} = amqp_channel:call(Channel, #'confirm.select'{}), [amqp_channel:call(Channel, #'basic.publish'{routing_key = <<"whoosh">>}, #amqp_msg{payload = <<"foo">>}) || _ <- lists:seq(1, 1000)], %% Hopefully enough to get a multi-ack true = amqp_channel:wait_for_confirms(Channel), teardown(Connection, Channel). confirm_select_before_wait_test() -> {ok, Connection} = new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), try amqp_channel:wait_for_confirms(Channel) of _ -> exit(success_despite_lack_of_confirm_mode) catch not_in_confirm_mode -> ok end, teardown(Connection, Channel). confirm_barrier_timeout_test() -> {ok, Connection} = new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), #'confirm.select_ok'{} = amqp_channel:call(Channel, #'confirm.select'{}), [amqp_channel:call(Channel, #'basic.publish'{routing_key = <<"whoosh">>}, #amqp_msg{payload = <<"foo">>}) || _ <- lists:seq(1, 1000)], case amqp_channel:wait_for_confirms(Channel, 0) of true -> ok; timeout -> ok end, teardown(Connection, Channel). confirm_barrier_die_timeout_test() -> {ok, Connection} = new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), #'confirm.select_ok'{} = amqp_channel:call(Channel, #'confirm.select'{}), [amqp_channel:call(Channel, #'basic.publish'{routing_key = <<"whoosh">>}, #amqp_msg{payload = <<"foo">>}) || _ <- lists:seq(1, 1000)], try amqp_channel:wait_for_confirms_or_die(Channel, 0) of true -> ok catch exit:timeout -> ok end, amqp_connection:close(Connection), wait_for_death(Connection). default_consumer_test() -> {ok, Connection} = new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), amqp_selective_consumer:register_default_consumer(Channel, self()), #'queue.declare_ok'{queue = Q} = amqp_channel:call(Channel, #'queue.declare'{}), Pid = spawn(fun () -> receive after 10000 -> ok end end), #'basic.consume_ok'{} = amqp_channel:subscribe(Channel, #'basic.consume'{queue = Q}, Pid), erlang:monitor(process, Pid), exit(Pid, shutdown), receive {'DOWN', _, process, _, _} -> io:format("little consumer died out~n") end, Payload = <<"for the default consumer">>, amqp_channel:call(Channel, #'basic.publish'{exchange = <<>>, routing_key = Q}, #amqp_msg{payload = Payload}), receive {#'basic.deliver'{}, #'amqp_msg'{payload = Payload}} -> ok after 1000 -> exit('default_consumer_didnt_work') end, teardown(Connection, Channel). subscribe_nowait_test() -> {ok, Conn} = new_connection(), {ok, Ch} = amqp_connection:open_channel(Conn), {ok, Q} = setup_publish(Ch), CTag = <<"ctag">>, amqp_selective_consumer:register_default_consumer(Ch, self()), ok = amqp_channel:call(Ch, #'basic.consume'{queue = Q, consumer_tag = CTag, nowait = true}), ok = amqp_channel:call(Ch, #'basic.cancel' {consumer_tag = CTag, nowait = true}), ok = amqp_channel:call(Ch, #'basic.consume'{queue = Q, consumer_tag = CTag, nowait = true}), receive #'basic.consume_ok'{} -> exit(unexpected_consume_ok); {#'basic.deliver'{delivery_tag = DTag}, _Content} -> amqp_channel:cast(Ch, #'basic.ack'{delivery_tag = DTag}) end, teardown(Conn, Ch). basic_nack_test() -> {ok, Connection} = new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), #'queue.declare_ok'{queue = Q} = amqp_channel:call(Channel, #'queue.declare'{}), Payload = <<"m1">>, amqp_channel:call(Channel, #'basic.publish'{exchange = <<>>, routing_key = Q}, #amqp_msg{payload = Payload}), #'basic.get_ok'{delivery_tag = Tag} = get_and_assert_equals(Channel, Q, Payload, false), amqp_channel:call(Channel, #'basic.nack'{delivery_tag = Tag, multiple = false, requeue = false}), get_and_assert_empty(Channel, Q), teardown(Connection, Channel). large_content_test() -> {ok, Connection} = new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), #'queue.declare_ok'{queue = Q} = amqp_channel:call(Channel, #'queue.declare'{}), {A1,A2,A3} = now(), random:seed(A1, A2, A3), F = list_to_binary([random:uniform(256)-1 || _ <- lists:seq(1, 1000)]), Payload = list_to_binary([[F || _ <- lists:seq(1, 1000)]]), Publish = #'basic.publish'{exchange = <<>>, routing_key = Q}, amqp_channel:call(Channel, Publish, #amqp_msg{payload = Payload}), get_and_assert_equals(Channel, Q, Payload), teardown(Connection, Channel). %% ---------------------------------------------------------------------------- %% Test for the network client %% Sends a bunch of messages and immediatly closes the connection without %% closing the channel. Then gets the messages back from the queue and expects %% all of them to have been sent. pub_and_close_test() -> {ok, Connection1} = new_connection(just_network), Payload = <<"eggs">>, NMessages = 50000, {ok, Channel1} = amqp_connection:open_channel(Connection1), #'queue.declare_ok'{queue = Q} = amqp_channel:call(Channel1, #'queue.declare'{}), %% Send messages pc_producer_loop(Channel1, <<>>, Q, Payload, NMessages), %% Close connection without closing channels amqp_connection:close(Connection1), %% Get sent messages back and count them {ok, Connection2} = new_connection(just_network), {ok, Channel2} = amqp_connection:open_channel( Connection2, {amqp_direct_consumer, [self()]}), amqp_channel:call(Channel2, #'basic.consume'{queue = Q, no_ack = true}), receive #'basic.consume_ok'{} -> ok end, ?assert(pc_consumer_loop(Channel2, Payload, 0) == NMessages), %% Make sure queue is empty #'queue.declare_ok'{queue = Q, message_count = NRemaining} = amqp_channel:call(Channel2, #'queue.declare'{queue = Q, passive = true}), ?assert(NRemaining == 0), amqp_channel:call(Channel2, #'queue.delete'{queue = Q}), teardown(Connection2, Channel2), ok. pc_producer_loop(_, _, _, _, 0) -> ok; pc_producer_loop(Channel, X, Key, Payload, NRemaining) -> Publish = #'basic.publish'{exchange = X, routing_key = Key}, ok = amqp_channel:call(Channel, Publish, #amqp_msg{payload = Payload}), pc_producer_loop(Channel, X, Key, Payload, NRemaining - 1). pc_consumer_loop(Channel, Payload, NReceived) -> receive {#'basic.deliver'{}, #amqp_msg{payload = DeliveredPayload}} -> case DeliveredPayload of Payload -> pc_consumer_loop(Channel, Payload, NReceived + 1); _ -> exit(received_unexpected_content) end after 1000 -> NReceived end. %%--------------------------------------------------------------------------- %% This tests whether RPC over AMQP produces the same result as invoking the %% same argument against the same underlying gen_server instance. rpc_test() -> {ok, Connection} = new_connection(), Fun = fun(X) -> X + 1 end, RPCHandler = fun(X) -> term_to_binary(Fun(binary_to_term(X))) end, Q = <<"rpc-test">>, Server = amqp_rpc_server:start(Connection, Q, RPCHandler), Client = amqp_rpc_client:start(Connection, Q), Input = 1, Reply = amqp_rpc_client:call(Client, term_to_binary(Input)), Expected = Fun(Input), DecodedReply = binary_to_term(Reply), ?assertMatch(Expected, DecodedReply), amqp_rpc_client:stop(Client), amqp_rpc_server:stop(Server), {ok, Channel} = amqp_connection:open_channel(Connection), amqp_channel:call(Channel, #'queue.delete'{queue = Q}), amqp_connection:close(Connection), wait_for_death(Connection), ok. %% This tests if the RPC continues to generate valid correlation ids %% over a series of requests. rpc_client_test() -> {ok, Connection} = new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), Q = <<"rpc-test">>, Latch = 255, % enough requests to tickle bad correlation ids %% Start a server to return correlation ids to the client. Server = spawn_link(fun() -> rpc_correlation_server(Channel, Q) end), %% Generate a series of RPC requests on the same client. Client = amqp_rpc_client:start(Connection, Q), Parent = self(), [spawn(fun() -> Reply = amqp_rpc_client:call(Client, <<>>), Parent ! {finished, Reply} end) || _ <- lists:seq(1, Latch)], %% Verify that the correlation ids are valid UTF-8 strings. CorrelationIds = latch_loop(Latch), [?assertMatch(<<_/binary>>, DecodedId) || DecodedId <- [unicode:characters_to_binary(Id, utf8) || Id <- CorrelationIds]], %% Cleanup. Server ! stop, amqp_rpc_client:stop(Client), amqp_channel:call(Channel, #'queue.delete'{queue = Q}), teardown(Connection, Channel), ok. %% Consumer of RPC requests that replies with the CorrelationId. rpc_correlation_server(Channel, Q) -> amqp_channel:register_return_handler(Channel, self()), amqp_channel:call(Channel, #'queue.declare'{queue = Q}), amqp_channel:call(Channel, #'basic.consume'{queue = Q, consumer_tag = <<"server">>}), rpc_client_consume_loop(Channel), amqp_channel:call(Channel, #'basic.cancel'{consumer_tag = <<"server">>}), amqp_channel:unregister_return_handler(Channel). rpc_client_consume_loop(Channel) -> receive stop -> ok; {#'basic.deliver'{delivery_tag = DeliveryTag}, #amqp_msg{props = Props}} -> #'P_basic'{correlation_id = CorrelationId, reply_to = Q} = Props, Properties = #'P_basic'{correlation_id = CorrelationId}, Publish = #'basic.publish'{exchange = <<>>, routing_key = Q, mandatory = true}, amqp_channel:call( Channel, Publish, #amqp_msg{props = Properties, payload = CorrelationId}), amqp_channel:call( Channel, #'basic.ack'{delivery_tag = DeliveryTag}), rpc_client_consume_loop(Channel); _ -> rpc_client_consume_loop(Channel) after 3000 -> exit(no_request_received) end. %%--------------------------------------------------------------------------- %% connection.blocked, connection.unblocked connection_blocked_network_test() -> {ok, Connection} = new_connection(just_network), X = <<"amq.direct">>, K = Payload = <<"x">>, clear_resource_alarm(memory), timer:sleep(1000), {ok, Channel} = amqp_connection:open_channel(Connection), Parent = self(), Child = spawn_link( fun() -> receive #'connection.blocked'{} -> ok end, clear_resource_alarm(memory), receive #'connection.unblocked'{} -> ok end, Parent ! ok end), amqp_connection:register_blocked_handler(Connection, Child), set_resource_alarm(memory), Publish = #'basic.publish'{exchange = X, routing_key = K}, amqp_channel:call(Channel, Publish, #amqp_msg{payload = Payload}), timer:sleep(1000), receive ok -> clear_resource_alarm(memory), clear_resource_alarm(disk), ok after 10000 -> clear_resource_alarm(memory), clear_resource_alarm(disk), exit(did_not_receive_connection_blocked) end. %%--------------------------------------------------------------------------- setup_publish(Channel) -> #'queue.declare_ok'{queue = Q} = amqp_channel:call(Channel, #'queue.declare'{exclusive = true}), ok = amqp_channel:call(Channel, #'basic.publish'{exchange = <<>>, routing_key = Q}, #amqp_msg{payload = <<"foobar">>}), {ok, Q}. teardown(Connection, Channel) -> amqp_channel:close(Channel), wait_for_death(Channel), amqp_connection:close(Connection), wait_for_death(Connection). teardown_test() -> {ok, Connection} = new_connection(), {ok, Channel} = amqp_connection:open_channel(Connection), ?assertMatch(true, is_process_alive(Channel)), ?assertMatch(true, is_process_alive(Connection)), teardown(Connection, Channel), ?assertMatch(false, is_process_alive(Channel)), ?assertMatch(false, is_process_alive(Connection)). wait_for_death(Pid) -> Ref = erlang:monitor(process, Pid), receive {'DOWN', Ref, process, Pid, _Reason} -> ok after ?DeathWait -> exit({timed_out_waiting_for_process_death, Pid}) end. latch_loop() -> latch_loop(?Latch, []). latch_loop(Latch) -> latch_loop(Latch, []). latch_loop(0, Acc) -> Acc; latch_loop(Latch, Acc) -> receive finished -> latch_loop(Latch - 1, Acc); {finished, Ret} -> latch_loop(Latch - 1, [Ret | Acc]) after ?Latch * ?Wait -> exit(waited_too_long) end. new_connection() -> new_connection(both, []). new_connection(AllowedConnectionTypes) when is_atom(AllowedConnectionTypes) -> new_connection(AllowedConnectionTypes, []); new_connection(Params) when is_list(Params) -> new_connection(both, Params). new_connection(AllowedConnectionTypes, Params) -> Params1 = case {AllowedConnectionTypes, os:getenv("AMQP_CLIENT_TEST_CONNECTION_TYPE")} of {just_direct, "network"} -> exit(normal); {just_direct, "network_ssl"} -> exit(normal); {just_network, "direct"} -> exit(normal); {_, "network"} -> make_network_params(Params); {_, "network_ssl"} -> {ok, [[CertsDir]]} = init:get_argument(erlang_client_ssl_dir), make_network_params( [{ssl_options, [{cacertfile, CertsDir ++ "/testca/cacert.pem"}, {certfile, CertsDir ++ "/client/cert.pem"}, {keyfile, CertsDir ++ "/client/key.pem"}, {verify, verify_peer}, {fail_if_no_peer_cert, true}]}] ++ Params); {_, "direct"} -> make_direct_params([{node, rabbit_nodes:make(rabbit)}] ++ Params) end, amqp_connection:start(Params1). %% Note: not all amqp_params_network fields supported. make_network_params(Props) -> Pgv = fun (Key, Default) -> proplists:get_value(Key, Props, Default) end, #amqp_params_network{username = Pgv(username, <<"guest">>), password = Pgv(password, <<"guest">>), virtual_host = Pgv(virtual_host, <<"/">>), channel_max = Pgv(channel_max, 0), ssl_options = Pgv(ssl_options, none), host = Pgv(host, "localhost")}. %% Note: not all amqp_params_direct fields supported. make_direct_params(Props) -> Pgv = fun (Key, Default) -> proplists:get_value(Key, Props, Default) end, #amqp_params_direct{username = Pgv(username, <<"guest">>), password = Pgv(password, <<"guest">>), virtual_host = Pgv(virtual_host, <<"/">>), node = Pgv(node, node())}. set_resource_alarm(memory) -> os:cmd("cd ../rabbitmq-test; make set-resource-alarm SOURCE=memory"); set_resource_alarm(disk) -> os:cmd("cd ../rabbitmq-test; make set-resource-alarm SOURCE=disk"). clear_resource_alarm(memory) -> os:cmd("cd ../rabbitmq-test; make clear-resource-alarm SOURCE=memory"); clear_resource_alarm(disk) -> os:cmd("cd ../rabbitmq-test; make clear-resource-alarm SOURCE=disk"). fmt(Fmt, Args) -> list_to_binary(rabbit_misc:format(Fmt, Args)). rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/test/amqp_dbg.erl0000644000177700017770000000700212633765070026501 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(amqp_dbg). -include_lib("stdlib/include/ms_transform.hrl"). -export([tracer/0, all/0, c_all/0]). -export([supervision/0, c_supervision/0, connection_lifecycle/0, c_connection_lifecycle/0, channels_manager_lifecycle/0, c_channels_manager_lifecycle/0, channel_lifecycle/0, c_channel_lifecycle/0, methods/0, c_methods/0]). tracer() -> Ret = dbg:tracer(), {ok, _} = dbg:p(all, c), Ret. all() -> tpl_list(all_args()). c_all() -> ctpl_list(all_args()). supervision() -> tpl_list(sup_args()). c_supervision() -> ctpl_list(sup_args()). connection_lifecycle() -> tpl_list(cl_args()). c_connection_lifecycle() -> ctpl_list(cl_args()). channels_manager_lifecycle() -> tpl_list(cml_args()). c_channels_manager_lifecycle() -> ctpl_list(cml_args()). channel_lifecycle() -> tpl_list(cl_args()). c_channel_lifecycle() -> ctpl_list(cl_args()). methods() -> tpl_list(m_args()). c_methods() -> ctpl_list(m_args()). %%--------------------------------------------------------------------------- %% Internal plumbing %%--------------------------------------------------------------------------- all_args() -> sup_args() ++ ncl_args() ++ cml_args() ++ cl_args() ++ m_args(). sup_args() -> [{amqp_connection_sup, start_link, return_ms()}, {amqp_connection_type_sup, start_link, return_ms()}, {amqp_channel_sup_sup, start_link, return_ms()}, {amqp_channel_sup_sup, start_channel_sup, return_ms()}, {amqp_channel_sup, start_link, return_ms()}, {amqp_network_connection, start_infrastructure, return_ms()}, {amqp_network_connection, start_heartbeat, return_ms()}, {amqp_channel, start_writer, return_ms()}]. ncl_args() -> [{amqp_main_reader, start_link, return_ms()}, {amqp_gen_connection, set_closing_state, []}, {amqp_gen_connection, handle_channels_terminated, []}, {amqp_network_connection, connect, []}, {amqp_direct_connection, connect, []}, {amqp_gen_connection, terminate, []}]. cml_args() -> [{amqp_channels_manager, handle_open_channel, return_ms()}, {amqp_channels_manager, handle_channel_down, []}, {amqp_channels_manager, signal_channels_connection_closing, []}]. cl_args() -> [{amqp_channel, init, []}, {amqp_channel_util, open_channel, []}, {amqp_channel, terminate, []}]. m_args() -> [{amqp_channel, do, return_ms()}, {amqp_channel, handle_method, []}, {amqp_gen_connection, handle_method, []}, {amqp_network_connection, do, return_ms()}, {amqp_network_connection, handshake_recv, return_ms()}]. tpl_list(ArgsList) -> [{ok, _} = dbg:tpl(Module, Func, Ms) || {Module, Func, Ms} <- ArgsList], ok. ctpl_list(ArgsList) -> [{ok, _} = dbg:ctpl(Module, Func) || {Module, Func, _} <- ArgsList], ok. return_ms() -> dbg:fun2ms(fun(_) -> return_trace() end). rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/test/amqp_client_SUITE.erl0000644000177700017770000001256012633765070030201 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(amqp_client_SUITE). -export([test_coverage/0]). -include_lib("eunit/include/eunit.hrl"). -define(FUNCTION, begin catch throw(x), Fun = case erlang:get_stacktrace() of [{_, F, _} | _] -> F; %% < R15 [{_, F, _, _} | _] -> F %% >= R15 end, list_to_atom(string:strip(atom_to_list(Fun), right, $_)) end). -define(RUN(Props), run(?FUNCTION, Props)). %%--------------------------------------------------------------------------- %% Tests %%--------------------------------------------------------------------------- amqp_uri_parse_test_() -> ?RUN([]). route_destination_test_() -> ?RUN([]). basic_get_test_() -> ?RUN([]). basic_get_ipv6_test_() -> ?RUN([]). basic_return_test_() -> ?RUN([]). simultaneous_close_test_() -> ?RUN([repeat]). basic_qos_test_() -> ?RUN([]). basic_recover_test_() -> ?RUN([]). basic_consume_test_() -> ?RUN([]). consume_notification_test_() -> ?RUN([]). basic_nack_test_() -> ?RUN([]). large_content_test_() -> ?RUN([]). lifecycle_test_() -> ?RUN([]). direct_no_user_test_() -> ?RUN([]). direct_no_password_test_() -> ?RUN([]). nowait_exchange_declare_test_() -> ?RUN([]). channel_repeat_open_close_test_() -> ?RUN([]). channel_multi_open_close_test_() -> ?RUN([]). basic_ack_test_() -> ?RUN([]). basic_ack_call_test_() -> ?RUN([]). channel_lifecycle_test_() -> ?RUN([]). queue_unbind_test_() -> ?RUN([]). sync_method_serialization_test_() -> ?RUN([]). async_sync_method_serialization_test_() -> ?RUN([]). sync_async_method_serialization_test_() -> ?RUN([]). teardown_test_() -> ?RUN([repeat]). rpc_test_() -> ?RUN([]). rpc_client_test_() -> ?RUN([]). pub_and_close_test_() -> ?RUN([]). channel_tune_negotiation_test_() -> ?RUN([]). confirm_test_() -> ?RUN([]). confirm_barrier_test_() -> ?RUN([]). confirm_select_before_wait_test_() -> ?RUN([]). confirm_barrier_timeout_test_() -> ?RUN([]). confirm_barrier_die_timeout_test_() -> ?RUN([]). default_consumer_test_() -> ?RUN([]). subscribe_nowait_test_() -> ?RUN([]). connection_blocked_network_test_() -> ?RUN([]). non_existent_exchange_test_() -> ?RUN([negative]). bogus_rpc_test_() -> ?RUN([negative, repeat]). hard_error_test_() -> ?RUN([negative, repeat]). non_existent_user_test_() -> ?RUN([negative]). invalid_password_test_() -> ?RUN([negative]). non_existent_vhost_test_() -> ?RUN([negative]). no_permission_test_() -> ?RUN([negative]). channel_writer_death_test_() -> ?RUN([negative]). connection_failure_test_() -> ?RUN([negative]). channel_death_test_() -> ?RUN([negative]). shortstr_overflow_property_test_() -> ?RUN([negative]). shortstr_overflow_field_test_() -> ?RUN([negative]). command_invalid_over_channel_test_() -> ?RUN([negative]). command_invalid_over_channel0_test_() -> ?RUN([negative]). %%--------------------------------------------------------------------------- %% Internal %%--------------------------------------------------------------------------- run(TestName, Props) -> RepeatCount = case proplists:get_value(repeat, Props, false) of true -> 100; Number when is_number(Number) -> Number; false -> 1 end, Module = case proplists:get_bool(negative, Props) of true -> negative_test_util; false -> test_util end, {timeout, proplists:get_value(timeout, Props, 60), fun () -> lists:foreach( fun (_) -> try erlang:apply(Module, TestName, []) of Ret -> Ret catch exit:normal -> ok end end, lists:seq(1, RepeatCount)) end}. %%--------------------------------------------------------------------------- %% Coverage %%--------------------------------------------------------------------------- test_coverage() -> rabbit_misc:enable_cover(), test(), rabbit_misc:report_cover(). rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/.srcdist_done0000644000177700017770000000000012633765070025714 0ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/Makefile0000644000177700017770000001154712633765070024715 0ustar michaelmichael# The contents of this file are subject to the Mozilla Public License # Version 1.1 (the "License"); you may not use this file except in # compliance with the License. You may obtain a copy of the License at # http://www.mozilla.org/MPL/ # # 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 Original Code is RabbitMQ. # # The Initial Developer of the Original Code is GoPivotal, Inc. # Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. # VERSION=0.0.0 SOURCE_PACKAGE_DIR=$(PACKAGE)-$(VERSION)-src SOURCE_PACKAGE_TAR_GZ=$(SOURCE_PACKAGE_DIR).tar.gz BROKER_HEADERS=$(wildcard $(BROKER_DIR)/$(INCLUDE_DIR)/*.hrl) BROKER_SOURCES=$(wildcard $(BROKER_DIR)/$(SOURCE_DIR)/*.erl) BROKER_DEPS=$(BROKER_HEADERS) $(BROKER_SOURCES) INFILES=$(shell find . -name '*.app.in') INTARGETS=$(patsubst %.in, %, $(INFILES)) WEB_URL=http://www.rabbitmq.com/ include common.mk run_in_broker: compile $(BROKER_DEPS) $(EBIN_DIR)/$(PACKAGE).app $(MAKE) RABBITMQ_SERVER_START_ARGS='$(PA_LOAD_PATH)' -C $(BROKER_DIR) run clean: common_clean rm -f $(INTARGETS) rm -rf $(DIST_DIR) distribution: documentation source_tarball package %.app: %.app.in $(SOURCES) $(BROKER_DIR)/generate_app escript $(BROKER_DIR)/generate_app $< $@ $(SOURCE_DIR) sed 's/%%VSN%%/$(VERSION)/' $@ > $@.tmp && mv $@.tmp $@ ############################################################################### ## Dialyzer ############################################################################### RABBIT_PLT=$(BROKER_DIR)/rabbit.plt dialyze: $(RABBIT_PLT) $(TARGETS) dialyzer --plt $(RABBIT_PLT) --no_native -Wrace_conditions $(TARGETS) .PHONY: $(RABBIT_PLT) $(RABBIT_PLT): $(MAKE) -C $(BROKER_DIR) create-plt ############################################################################### ## Documentation ############################################################################### documentation: $(DOC_DIR)/index.html $(DOC_DIR)/overview.edoc: $(SOURCE_DIR)/overview.edoc.in mkdir -p $(DOC_DIR) sed -e 's:%%VERSION%%:$(VERSION):g' < $< > $@ $(DOC_DIR)/index.html: $(DEPS_DIR)/$(COMMON_PACKAGE_DIR) $(DOC_DIR)/overview.edoc $(SOURCES) $(LIBS_PATH) erl -noshell -eval 'edoc:application(amqp_client, ".", [{preprocess, true}, {macros, [{edoc, true}]}])' -run init stop ############################################################################### ## Testing ############################################################################### include test.mk compile_tests: $(TEST_TARGETS) $(EBIN_DIR)/$(PACKAGE).app $(TEST_TARGETS): $(TEST_DIR) .PHONY: $(TEST_DIR) $(TEST_DIR): $(DEPS_DIR)/$(COMMON_PACKAGE_DIR) $(MAKE) -C $(TEST_DIR) ############################################################################### ## Packaging ############################################################################### COPY=cp -pR $(DIST_DIR)/$(COMMON_PACKAGE_EZ): $(BROKER_DEPS) $(COMMON_PACKAGE).app | $(DIST_DIR) rm -f $@ $(MAKE) -C $(BROKER_DIR) rm -rf $(DIST_DIR)/$(COMMON_PACKAGE_DIR) mkdir -p $(DIST_DIR)/$(COMMON_PACKAGE_DIR)/$(INCLUDE_DIR) mkdir -p $(DIST_DIR)/$(COMMON_PACKAGE_DIR)/$(EBIN_DIR) cp $(COMMON_PACKAGE).app $(DIST_DIR)/$(COMMON_PACKAGE_DIR)/$(EBIN_DIR)/ $(foreach DEP, $(DEPS), \ ( cp $(BROKER_DIR)/ebin/$(DEP).beam $(DIST_DIR)/$(COMMON_PACKAGE_DIR)/$(EBIN_DIR)/ \ );) cp $(BROKER_DIR)/include/*.hrl $(DIST_DIR)/$(COMMON_PACKAGE_DIR)/$(INCLUDE_DIR)/ (cd $(DIST_DIR); zip -q -r $(COMMON_PACKAGE_EZ) $(COMMON_PACKAGE_DIR)) source_tarball: $(DIST_DIR)/$(COMMON_PACKAGE_EZ) $(EBIN_DIR)/$(PACKAGE).app | $(DIST_DIR) mkdir -p $(DIST_DIR)/$(SOURCE_PACKAGE_DIR)/$(DIST_DIR) $(COPY) $(DIST_DIR)/$(COMMON_PACKAGE_EZ) $(DIST_DIR)/$(SOURCE_PACKAGE_DIR)/$(DIST_DIR)/ $(COPY) README.in $(DIST_DIR)/$(SOURCE_PACKAGE_DIR)/README elinks -dump -no-references -no-numbering $(WEB_URL)build-erlang-client.html >> $(DIST_DIR)/$(SOURCE_PACKAGE_DIR)/README $(COPY) common.mk $(DIST_DIR)/$(SOURCE_PACKAGE_DIR)/ $(COPY) test.mk $(DIST_DIR)/$(SOURCE_PACKAGE_DIR)/ sed 's/%%VSN%%/$(VERSION)/' Makefile.in > $(DIST_DIR)/$(SOURCE_PACKAGE_DIR)/Makefile mkdir -p $(DIST_DIR)/$(SOURCE_PACKAGE_DIR)/$(SOURCE_DIR) $(COPY) $(SOURCE_DIR)/*.erl $(DIST_DIR)/$(SOURCE_PACKAGE_DIR)/$(SOURCE_DIR)/ mkdir -p $(DIST_DIR)/$(SOURCE_PACKAGE_DIR)/$(EBIN_DIR) $(COPY) $(EBIN_DIR)/*.app $(DIST_DIR)/$(SOURCE_PACKAGE_DIR)/$(EBIN_DIR)/ mkdir -p $(DIST_DIR)/$(SOURCE_PACKAGE_DIR)/$(INCLUDE_DIR) $(COPY) $(INCLUDE_DIR)/*.hrl $(DIST_DIR)/$(SOURCE_PACKAGE_DIR)/$(INCLUDE_DIR)/ mkdir -p $(DIST_DIR)/$(SOURCE_PACKAGE_DIR)/$(TEST_DIR) $(COPY) $(TEST_DIR)/*.erl $(DIST_DIR)/$(SOURCE_PACKAGE_DIR)/$(TEST_DIR)/ $(COPY) $(TEST_DIR)/Makefile $(DIST_DIR)/$(SOURCE_PACKAGE_DIR)/$(TEST_DIR)/ cd $(DIST_DIR) ; tar czf $(SOURCE_PACKAGE_TAR_GZ) $(SOURCE_PACKAGE_DIR) $(DIST_DIR): mkdir -p $@ rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/common.mk0000644000177700017770000001615712633765070025100 0ustar michaelmichael# The contents of this file are subject to the Mozilla Public License # Version 1.1 (the "License"); you may not use this file except in # compliance with the License. You may obtain a copy of the License at # http://www.mozilla.org/MPL/ # # 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 Original Code is RabbitMQ. # # The Initial Developer of the Original Code is GoPivotal, Inc. # Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. # # The client library can either be built from source control or by downloading # a source tarball from the RabbitMQ site. The intention behind the source tarball is # to be able to unpack this anywhere and just run a simple a test, under the # assumption that you have a running broker. This provides the simplest # possible way of building and running the client. # # The source control version, on the other hand, contains far more infrastructure # to start and stop brokers, package modules from the server, run embedded tests # and so forth. # # This means that the Makefile of the source control version contains a lot of # functionality that just wouldn't work with the source tarball version. # # The purpose of this common Makefile is to define as many commonalities # between the build requirements of the source control version and the source # tarball version. This avoids duplicating make definitions and rules and # helps keep the Makefile maintenence well factored. ifndef TMPDIR TMPDIR := /tmp endif EBIN_DIR=ebin BROKER_DIR=../rabbitmq-server export INCLUDE_DIR=include TEST_DIR=test SOURCE_DIR=src DIST_DIR=dist DEPS_DIR=deps DOC_DIR=doc DEPS_FILE=deps.mk ifeq ("$(ERL_LIBS)", "") ERL_LIBS := else ERL_LIBS := :$(ERL_LIBS) endif ERL_PATH ?= PACKAGE=amqp_client PACKAGE_DIR=$(PACKAGE)-$(VERSION) PACKAGE_NAME_EZ=$(PACKAGE_DIR).ez COMMON_PACKAGE=rabbit_common export COMMON_PACKAGE_DIR=$(COMMON_PACKAGE)-$(VERSION) COMMON_PACKAGE_EZ=$(COMMON_PACKAGE_DIR).ez NODE_NAME=amqp_client DEPS=$(shell erl -noshell -eval '{ok,[{_,_,[_,_,{modules, Mods},_,_,_]}]} = \ file:consult("$(COMMON_PACKAGE).app.in"), \ [io:format("~p ",[M]) || M <- Mods], halt().') INCLUDES=$(wildcard $(INCLUDE_DIR)/*.hrl) SOURCES=$(wildcard $(SOURCE_DIR)/*.erl) TARGETS=$(patsubst $(SOURCE_DIR)/%.erl, $(EBIN_DIR)/%.beam, $(SOURCES)) TEST_SOURCES=$(wildcard $(TEST_DIR)/*.erl) TEST_TARGETS=$(patsubst $(TEST_DIR)/%.erl, $(TEST_DIR)/%.beam, $(TEST_SOURCES)) LIBS_PATH_UNIX=$(DEPS_DIR):$(DIST_DIR)$(ERL_LIBS) IS_CYGWIN=$(shell if [ $(shell expr "$(shell uname -s)" : 'CYGWIN_NT') -gt 0 ]; then echo "true"; else echo "false"; fi) ifeq ($(IS_CYGWIN),true) LIBS_PATH=ERL_LIBS="$(shell cygpath -wp $(LIBS_PATH_UNIX))" else LIBS_PATH=ERL_LIBS=$(LIBS_PATH_UNIX) endif LOAD_PATH=$(EBIN_DIR) $(TEST_DIR) $(ERL_PATH) RUN:=$(LIBS_PATH) erl -pa $(LOAD_PATH) -sname $(NODE_NAME) MKTEMP=$$(mktemp $(TMPDIR)/tmp.XXXXXXXXXX) ifndef USE_SPECS # our type specs rely on features / bug fixes in dialyzer that are # only available in R13B01 upwards (R13B is eshell 5.7.2) # # NB: do not mark this variable for export, otherwise it will # override the test in rabbitmq-server's Makefile when it does the # make -C, which causes problems whenever the test here and the test # there compare system_info(version) against *different* eshell # version numbers. USE_SPECS:=$(shell erl -noshell -eval 'io:format([list_to_integer(X) || X <- string:tokens(erlang:system_info(version), ".")] >= [5,7,2]), halt().') endif ERLC_OPTS=-I $(INCLUDE_DIR) -pa $(EBIN_DIR) -o $(EBIN_DIR) -Wall -v +debug_info $(if $(filter true,$(USE_SPECS)),-Duse_specs) RABBITMQ_NODENAME=rabbit PA_LOAD_PATH=-pa $(realpath $(LOAD_PATH)) RABBITMQCTL=$(BROKER_DIR)/scripts/rabbitmqctl ifdef SSL_CERTS_DIR SSL := true ALL_SSL := { $(MAKE) test_ssl || OK=false; } ALL_SSL_COVERAGE := { $(MAKE) test_ssl_coverage || OK=false; } SSL_BROKER_ARGS := -rabbit ssl_listeners [{\\\"0.0.0.0\\\",5671},{\\\"::1\\\",5671}] \ -rabbit ssl_options [{cacertfile,\\\"$(SSL_CERTS_DIR)/testca/cacert.pem\\\"},{certfile,\\\"$(SSL_CERTS_DIR)/server/cert.pem\\\"},{keyfile,\\\"$(SSL_CERTS_DIR)/server/key.pem\\\"},{verify,verify_peer},{fail_if_no_peer_cert,true}] SSL_CLIENT_ARGS := -erlang_client_ssl_dir $(SSL_CERTS_DIR) else SSL := @echo No SSL_CERTS_DIR defined. && false ALL_SSL := true ALL_SSL_COVERAGE := true SSL_BROKER_ARGS := SSL_CLIENT_ARGS := endif # Versions prior to this are not supported NEED_MAKE := 3.80 ifneq "$(NEED_MAKE)" "$(firstword $(sort $(NEED_MAKE) $(MAKE_VERSION)))" $(error Versions of make prior to $(NEED_MAKE) are not supported) endif # .DEFAULT_GOAL introduced in 3.81 DEFAULT_GOAL_MAKE := 3.81 ifneq "$(DEFAULT_GOAL_MAKE)" "$(firstword $(sort $(DEFAULT_GOAL_MAKE) $(MAKE_VERSION)))" .DEFAULT_GOAL=all endif all: package common_clean: rm -f $(EBIN_DIR)/*.beam rm -f erl_crash.dump rm -rf $(DEPS_DIR) rm -rf $(DOC_DIR) rm -f $(DEPS_FILE) $(MAKE) -C $(TEST_DIR) clean compile: $(TARGETS) $(EBIN_DIR)/$(PACKAGE).app run: compile $(RUN) ############################################################################### ## Packaging ############################################################################### $(DIST_DIR)/$(PACKAGE_NAME_EZ): $(TARGETS) $(EBIN_DIR)/$(PACKAGE).app | $(DIST_DIR) rm -f $@ rm -rf $(DIST_DIR)/$(PACKAGE_DIR) mkdir -p $(DIST_DIR)/$(PACKAGE_DIR)/$(EBIN_DIR) mkdir -p $(DIST_DIR)/$(PACKAGE_DIR)/$(INCLUDE_DIR) cp -r $(EBIN_DIR)/*.beam $(DIST_DIR)/$(PACKAGE_DIR)/$(EBIN_DIR) cp -r $(EBIN_DIR)/*.app $(DIST_DIR)/$(PACKAGE_DIR)/$(EBIN_DIR) mkdir -p $(DIST_DIR)/$(PACKAGE_DIR)/$(INCLUDE_DIR) cp -r $(INCLUDE_DIR)/* $(DIST_DIR)/$(PACKAGE_DIR)/$(INCLUDE_DIR) (cd $(DIST_DIR); zip -q -r $(PACKAGE_NAME_EZ) $(PACKAGE_DIR)) package: $(DIST_DIR)/$(PACKAGE_NAME_EZ) ############################################################################### ## Internal targets ############################################################################### $(DEPS_DIR)/$(COMMON_PACKAGE_DIR): $(DIST_DIR)/$(COMMON_PACKAGE_EZ) | $(DEPS_DIR) rm -rf $(DEPS_DIR)/$(COMMON_PACKAGE_DIR) mkdir -p $(DEPS_DIR)/$(COMMON_PACKAGE_DIR) unzip -q -o $< -d $(DEPS_DIR) $(DEPS_FILE): $(SOURCES) $(INCLUDES) rm -f $@ echo $(subst : ,:,$(foreach FILE,$^,$(FILE):)) | escript $(BROKER_DIR)/generate_deps $@ $(EBIN_DIR) $(EBIN_DIR)/%.beam: $(SOURCE_DIR)/%.erl $(INCLUDES) $(DEPS_DIR)/$(COMMON_PACKAGE_DIR) | $(DEPS_FILE) $(LIBS_PATH) erlc $(ERLC_OPTS) $< $(DEPS_DIR): mkdir -p $@ # Note that all targets which depend on clean must have clean in their # name. Also any target that doesn't depend on clean should not have # clean in its name, unless you know that you don't need any of the # automatic dependency generation for that target. # We want to load the dep file if *any* target *doesn't* contain # "clean" - i.e. if removing all clean-like targets leaves something ifeq "$(MAKECMDGOALS)" "" TESTABLEGOALS:=$(.DEFAULT_GOAL) else TESTABLEGOALS:=$(MAKECMDGOALS) endif ifneq "$(strip $(patsubst clean%,,$(patsubst %clean,,$(TESTABLEGOALS))))" "" -include $(DEPS_FILE) endif rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/test.mk0000644000177700017770000001155212633765070024561 0ustar michaelmichael# The contents of this file are subject to the Mozilla Public License # Version 1.1 (the "License"); you may not use this file except in # compliance with the License. You may obtain a copy of the License at # http://www.mozilla.org/MPL/ # # 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 Original Code is RabbitMQ. # # The Initial Developer of the Original Code is GoPivotal, Inc. # Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. # IS_SUCCESS:=egrep "(All .+ tests (successful|passed).|Test passed.)" TESTING_MESSAGE:=-eval "error_logger:tty(false), error_logger:logfile({open, \"$(TMPDIR)/erlang-client-tests.log\"}), io:format(\"~nTesting in progress. Please wait...~n~n\")." prepare_tests: compile compile_tests all_tests: prepare_tests OK=true && \ { $(MAKE) test_suites || OK=false; } && \ { $(MAKE) test_common_package || OK=false; } && \ { $(MAKE) test_direct || OK=false; } && \ $$OK test_suites: prepare_tests OK=true && \ { $(MAKE) test_network || OK=false; } && \ { $(MAKE) test_remote_direct || OK=false; } && \ $(ALL_SSL) && \ $$OK test_suites_coverage: prepare_tests OK=true && \ { $(MAKE) test_network_coverage || OK=false; } && \ { $(MAKE) test_direct_coverage || OK=false; } && \ $(ALL_SSL_COVERAGE) && \ $$OK ## Starts a broker, configures users and runs the tests on the same node run_test_in_broker: $(MAKE) start_test_broker_node $(MAKE) unboot_broker OK=true && \ TMPFILE=$(MKTEMP) && echo "Redirecting output to $$TMPFILE" && \ { $(MAKE) -C $(BROKER_DIR) run-node \ RABBITMQ_SERVER_START_ARGS="$(PA_LOAD_PATH) $(SSL_BROKER_ARGS) \ -noshell -s rabbit $(RUN_TEST_ARGS) -s init stop" 2>&1 | \ tee $$TMPFILE || OK=false; } && \ { $(IS_SUCCESS) $$TMPFILE || OK=false; } && \ rm $$TMPFILE && \ $(MAKE) boot_broker && \ $(MAKE) stop_test_broker_node && \ $$OK ## Starts a broker, configures users and runs the tests from a different node run_test_detached: start_test_broker_node OK=true && \ TMPFILE=$(MKTEMP) && echo "Redirecting output to $$TMPFILE" && \ { $(RUN) -noinput $(TESTING_MESSAGE) \ $(SSL_CLIENT_ARGS) $(RUN_TEST_ARGS) \ -s init stop 2>&1 | tee $$TMPFILE || OK=false; } && \ { $(IS_SUCCESS) $$TMPFILE || OK=false; } && \ rm $$TMPFILE && \ $(MAKE) stop_test_broker_node && \ $$OK ## Starts a broker, configures users and runs the tests from a different node run_test_foreground: start_test_broker_node OK=true && \ { $(RUN) -noinput $(TESTING_MESSAGE) \ $(SSL_CLIENT_ARGS) $(RUN_TEST_ARGS) \ -s init stop || OK=false; } && \ $(MAKE) stop_test_broker_node && \ $$OK start_test_broker_node: boot_broker sleep 1 - $(RABBITMQCTL) delete_user test_user_no_perm $(RABBITMQCTL) add_user test_user_no_perm test_user_no_perm sleep 1 stop_test_broker_node: sleep 1 $(RABBITMQCTL) delete_user test_user_no_perm $(MAKE) unboot_broker boot_broker: $(MAKE) -C $(BROKER_DIR) start-background-node RABBITMQ_SERVER_START_ARGS="$(RABBITMQ_SERVER_START_ARGS) $(SSL_BROKER_ARGS)" $(MAKE) -C $(BROKER_DIR) start-rabbit-on-node unboot_broker: $(MAKE) -C $(BROKER_DIR) stop-rabbit-on-node $(MAKE) -C $(BROKER_DIR) stop-node ssl: $(SSL) test_ssl: prepare_tests ssl $(MAKE) run_test_detached AMQP_CLIENT_TEST_CONNECTION_TYPE="network_ssl" RUN_TEST_ARGS="-s amqp_client_SUITE test" test_network: prepare_tests $(MAKE) run_test_detached AMQP_CLIENT_TEST_CONNECTION_TYPE="network" RUN_TEST_ARGS="-s amqp_client_SUITE test" test_direct: prepare_tests $(MAKE) run_test_in_broker AMQP_CLIENT_TEST_CONNECTION_TYPE="direct" RUN_TEST_ARGS="-s amqp_client_SUITE test" test_remote_direct: prepare_tests $(MAKE) run_test_detached AMQP_CLIENT_TEST_CONNECTION_TYPE="direct" RUN_TEST_ARGS="-s amqp_client_SUITE test" test_common_package: $(DIST_DIR)/$(COMMON_PACKAGE_EZ) package prepare_tests $(MAKE) run_test_detached RUN="$(LIBS_PATH) erl -pa $(TEST_DIR)" \ AMQP_CLIENT_TEST_CONNECTION_TYPE="network" RUN_TEST_ARGS="-s amqp_client_SUITE test" $(MAKE) run_test_detached RUN="$(LIBS_PATH) erl -pa $(TEST_DIR) -sname amqp_client" \ AMQP_CLIENT_TEST_CONNECTION_TYPE="direct" RUN_TEST_ARGS="-s amqp_client_SUITE test" test_ssl_coverage: prepare_tests ssl $(MAKE) run_test_detached AMQP_CLIENT_TEST_CONNECTION_TYPE="network_ssl" RUN_TEST_ARGS="-s amqp_client_SUITE test_coverage" test_network_coverage: prepare_tests $(MAKE) run_test_detached AMQP_CLIENT_TEST_CONNECTION_TYPE="network" RUN_TEST_ARGS="-s amqp_client_SUITE test_coverage" test_remote_direct_coverage: prepare_tests $(MAKE) run_test_detached AMQP_CLIENT_TEST_CONNECTION_TYPE="direct" RUN_TEST_ARGS="-s amqp_client_SUITE test_coverage" test_direct_coverage: prepare_tests $(MAKE) run_test_in_broker AMQP_CLIENT_TEST_CONNECTION_TYPE="direct" RUN_TEST_ARGS="-s amqp_client_SUITE test_coverage" rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/rabbit_common.app.in0000644000177700017770000000255612633765070027177 0ustar michaelmichael{application, rabbit_common, [{description, "RabbitMQ Common Libraries"}, {vsn, "%%VSN%%"}, {modules, [ app_utils, credit_flow, pmon, gen_server2, mirrored_supervisor, mochijson2, priority_queue, rabbit_backing_queue, rabbit_basic, rabbit_binary_generator, rabbit_binary_parser, rabbit_channel, rabbit_channel_interceptor, rabbit_runtime_parameter, rabbit_command_assembler, rabbit_exchange_type, rabbit_exchange_decorator, rabbit_authn_backend, rabbit_authz_backend, rabbit_auth_mechanism, rabbit_framing_amqp_0_8, rabbit_framing_amqp_0_9_1, rabbit_heartbeat, rabbit_misc, rabbit_msg_store_index, rabbit_net, rabbit_networking, rabbit_nodes, rabbit_policy_validator, rabbit_reader, rabbit_writer, rabbit_event, rabbit_queue_collector, rabbit_queue_decorator, rabbit_amqqueue, ssl_compat, supervisor2, time_compat ]}, {registered, []}, {env, []}, {applications, [kernel, stdlib]}]}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/ebin/0000755000177700017770000000000012633765070024162 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/ebin/amqp_client.app.in0000644000177700017770000000041312633765070027563 0ustar michaelmichael{application, amqp_client, [{description, "RabbitMQ AMQP Client"}, {vsn, "%%VSN%%"}, {modules, []}, {registered, [amqp_sup]}, {env, [{prefer_ipv6, false}, {ssl_options, []}]}, {mod, {amqp_client, []}}, {applications, [kernel, stdlib, xmerl]}]}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/include/0000755000177700017770000000000012633765070024670 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/include/amqp_client_internal.hrl0000644000177700017770000000300412633765070031564 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -include("amqp_client.hrl"). -define(PROTOCOL_VERSION_MAJOR, 0). -define(PROTOCOL_VERSION_MINOR, 9). -define(PROTOCOL_HEADER, <<"AMQP", 0, 0, 9, 1>>). -define(PROTOCOL, rabbit_framing_amqp_0_9_1). -define(MAX_CHANNEL_NUMBER, 65535). -define(LOG_DEBUG(Format), error_logger:info_msg(Format)). -define(LOG_INFO(Format, Args), error_logger:info_msg(Format, Args)). -define(LOG_WARN(Format, Args), error_logger:warning_msg(Format, Args)). -define(LOG_ERR(Format, Args), error_logger:error_msg(Format, Args)). -define(CLIENT_CAPABILITIES, [{<<"publisher_confirms">>, bool, true}, {<<"exchange_exchange_bindings">>, bool, true}, {<<"basic.nack">>, bool, true}, {<<"consumer_cancel_notify">>, bool, true}, {<<"connection.blocked">>, bool, true}, {<<"authentication_failure_close">>, bool, true}]). rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/include/amqp_gen_consumer_spec.hrl0000644000177700017770000000351212633765070032114 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2011-2015 Pivotal Software, Inc. All rights reserved. %% -include("amqp_client.hrl"). -ifndef(edoc). -type(state() :: any()). -type(consume() :: #'basic.consume'{}). -type(consume_ok() :: #'basic.consume_ok'{}). -type(cancel() :: #'basic.cancel'{}). -type(cancel_ok() :: #'basic.cancel_ok'{}). -type(deliver() :: #'basic.deliver'{}). -type(from() :: any()). -type(reason() :: any()). -type(ok_error() :: {ok, state()} | {error, reason(), state()}). -spec(init/1 :: ([any()]) -> {ok, state()}). -spec(handle_consume/3 :: (consume(), pid(), state()) -> ok_error()). -spec(handle_consume_ok/3 :: (consume_ok(), consume(), state()) -> ok_error()). -spec(handle_cancel/2 :: (cancel(), state()) -> ok_error()). -spec(handle_server_cancel/2 :: (cancel(), state()) -> ok_error()). -spec(handle_cancel_ok/3 :: (cancel_ok(), cancel(), state()) -> ok_error()). -spec(handle_deliver/3 :: (deliver(), #amqp_msg{}, state()) -> ok_error()). -spec(handle_info/2 :: (any(), state()) -> ok_error()). -spec(handle_call/3 :: (any(), from(), state()) -> {reply, any(), state()} | {noreply, state()} | {error, reason(), state()}). -spec(terminate/2 :: (any(), state()) -> state()). -endif. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/include/amqp_client.hrl0000644000177700017770000000473012633765070027677 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -ifndef(AMQP_CLIENT_HRL). -define(AMQP_CLIENT_HRL, true). -include_lib("rabbit_common/include/rabbit.hrl"). -include_lib("rabbit_common/include/rabbit_framing.hrl"). -record(amqp_msg, {props = #'P_basic'{}, payload = <<>>}). -record(amqp_params_network, {username = <<"guest">>, password = <<"guest">>, virtual_host = <<"/">>, host = "localhost", port = undefined, channel_max = 0, frame_max = 0, heartbeat = 10, connection_timeout = infinity, ssl_options = none, auth_mechanisms = [fun amqp_auth_mechanisms:plain/3, fun amqp_auth_mechanisms:amqplain/3], client_properties = [], socket_options = []}). -record(amqp_params_direct, {username = none, password = none, virtual_host = <<"/">>, node = node(), adapter_info = none, client_properties = []}). -record(amqp_adapter_info, {host = unknown, port = unknown, peer_host = unknown, peer_port = unknown, name = unknown, protocol = unknown, additional_info = []}). -endif. rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/include/rabbit_routing_prefixes.hrl0000644000177700017770000000173212633765070032321 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2011-2015 Pivotal Software, Inc. All rights reserved. %% -define(QUEUE_PREFIX, "/queue"). -define(TOPIC_PREFIX, "/topic"). -define(EXCHANGE_PREFIX, "/exchange"). -define(AMQQUEUE_PREFIX, "/amq/queue"). -define(TEMP_QUEUE_PREFIX, "/temp-queue"). %% reply queues names can have slashes in the content so no further %% parsing happens. -define(REPLY_QUEUE_PREFIX, "/reply-queue/"). rabbitmq-server-3.5.7/plugins-src/rabbitmq-erlang-client/Makefile.in0000644000177700017770000000140612633765070025313 0ustar michaelmichael# The contents of this file are subject to the Mozilla Public License # Version 1.1 (the "License"); you may not use this file except in # compliance with the License. You may obtain a copy of the License at # http://www.mozilla.org/MPL/ # # 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 Original Code is RabbitMQ. # # The Initial Developer of the Original Code is GoPivotal, Inc. # Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. # VERSION=%%VSN%% include common.mk include test.mk clean: common_clean compile_tests: $(MAKE) -C test VERSION=$(VERSION) rabbitmq-server-3.5.7/plugins-src/Makefile0000644000177700017770000001526112633765070020367 0ustar michaelmichael.PHONY: default default: @echo No default target && false REPOS:= \ rabbitmq-server \ rabbitmq-codegen \ rabbitmq-java-client \ rabbitmq-dotnet-client \ rabbitmq-test \ cowboy-wrapper \ eldap-wrapper \ mochiweb-wrapper \ rabbitmq-amqp1.0 \ rabbitmq-auth-backend-ldap \ rabbitmq-auth-mechanism-ssl \ rabbitmq-consistent-hash-exchange \ rabbitmq-erlang-client \ rabbitmq-federation \ rabbitmq-federation-management \ rabbitmq-management \ rabbitmq-management-agent \ rabbitmq-management-visualiser \ rabbitmq-metronome \ rabbitmq-web-dispatch \ rabbitmq-mqtt \ rabbitmq-shovel \ rabbitmq-shovel-management \ rabbitmq-stomp \ rabbitmq-toke \ rabbitmq-tracing \ rabbitmq-web-stomp \ rabbitmq-web-stomp-examples \ sockjs-erlang-wrapper \ toke \ webmachine-wrapper BRANCH:=master UMBRELLA_REPO_FETCH:=$(shell git remote -v 2>/dev/null | awk '/^origin\t.+ \(fetch\)$$/ { print $$2; }') ifdef UMBRELLA_REPO_FETCH GIT_CORE_REPOBASE_FETCH:=$(shell dirname $(UMBRELLA_REPO_FETCH)) GIT_CORE_SUFFIX_FETCH:=$(suffix $(UMBRELLA_REPO_FETCH)) else GIT_CORE_REPOBASE_FETCH:=https://github.com/rabbitmq GIT_CORE_SUFFIX_FETCH:=.git endif UMBRELLA_REPO_PUSH:=$(shell git remote -v 2>/dev/null | awk '/^origin\t.+ \(push\)$$/ { print $$2; }') ifdef UMBRELLA_REPO_PUSH GIT_CORE_REPOBASE_PUSH:=$(shell dirname $(UMBRELLA_REPO_PUSH)) GIT_CORE_SUFFIX_PUSH:=$(suffix $(UMBRELLA_REPO_PUSH)) else GIT_CORE_REPOBASE_PUSH:=git@github.com:rabbitmq GIT_CORE_SUFFIX_PUSH:=.git endif VERSION:=0.0.0 ifndef VERBOSE QUIET:=@ endif #---------------------------------- all: $(MAKE) -f all-packages.mk all-packages VERSION=$(VERSION) test: $(MAKE) -f all-packages.mk test-all-packages VERSION=$(VERSION) release: $(MAKE) -f all-packages.mk all-releasable VERSION=$(VERSION) clean: $(MAKE) -f all-packages.mk clean-all-packages check-xref: $(MAKE) -f all-packages.mk check-xref-packages plugins-dist: release rm -rf $(PLUGINS_DIST_DIR) mkdir -p $(PLUGINS_DIST_DIR) $(MAKE) -f all-packages.mk copy-releasable VERSION=$(VERSION) PLUGINS_DIST_DIR=$(PLUGINS_DIST_DIR) plugins-srcdist: rm -rf $(PLUGINS_SRC_DIST_DIR) mkdir -p $(PLUGINS_SRC_DIST_DIR)/licensing rsync -a --exclude '.git*' rabbitmq-erlang-client $(PLUGINS_SRC_DIST_DIR)/ touch $(PLUGINS_SRC_DIST_DIR)/rabbitmq-erlang-client/.srcdist_done rsync -a --exclude '.git*' rabbitmq-server $(PLUGINS_SRC_DIST_DIR)/ touch $(PLUGINS_SRC_DIST_DIR)/rabbitmq-server/.srcdist_done $(MAKE) -f all-packages.mk copy-srcdist VERSION=$(VERSION) PLUGINS_SRC_DIST_DIR=$(PLUGINS_SRC_DIST_DIR) cp Makefile *.mk generate* $(PLUGINS_SRC_DIST_DIR)/ echo "This is the released version of rabbitmq-public-umbrella. \ You can clone the full version with: git clone https://github.com/rabbitmq/rabbitmq-public-umbrella.git" > $(PLUGINS_SRC_DIST_DIR)/README PRESERVE_CLONE_DIR=1 $(MAKE) -C $(PLUGINS_SRC_DIST_DIR) clean rm -rf $(PLUGINS_SRC_DIST_DIR)/rabbitmq-server #---------------------------------- # Convenience aliases .PHONY: co co: checkout .PHONY: ci ci: checkin .PHONY: up up: update .PHONY: st st: status .PHONY: up_c up_c: named_update #---------------------------------- $(REPOS): $(QUIET)retries=5; \ umbrella_branch="$$(git branch | awk '/^\* / { print $$2; }')"; \ if test "$$umbrella_branch" = "stable"; then \ branch_arg="-b $$umbrella_branch"; \ fi; \ while ! git clone $$branch_arg $(GIT_CORE_REPOBASE_FETCH)/$@$(GIT_CORE_SUFFIX_FETCH); do \ retries=$$((retries - 1)); \ if test "$$retries" = 0; then break; fi; \ sleep 1; \ done $(QUIET)test -d $@ $(QUIET)global_user_name="$$(git config --global user.name)"; \ global_user_email="$$(git config --global user.email)"; \ user_name="$$(git config user.name)"; \ user_email="$$(git config user.email)"; \ cd $@ && \ git remote set-url --push origin $(GIT_CORE_REPOBASE_PUSH)/$@$(GIT_CORE_SUFFIX_PUSH) && \ if test "$$global_user_name" != "$$user_name"; then git config user.name "$$user_name"; fi && \ if test "$$global_user_email" != "$$user_email"; then git config user.email "$$user_email"; fi .PHONY: checkout checkout: $(REPOS) .PHONY: list-repos list-repos: @for repo in $(REPOS); do echo $$repo; done .PHONY: sync-gituser sync-gituser: @global_user_name="$$(git config --global user.name)"; \ global_user_email="$$(git config --global user.email)"; \ user_name="$$(git config user.name)"; \ user_email="$$(git config user.email)"; \ for repo in $(REPOS); do \ cd $$repo && \ git config --unset user.name && \ git config --unset user.email && \ if test "$$global_user_name" != "$$user_name"; then git config user.name "$$user_name"; fi && \ if test "$$global_user_email" != "$$user_email"; then git config user.email "$$user_email"; fi && \ cd ..; done .PHONY: sync-gitremote sync-gitremote: @for repo in $(REPOS); do \ cd $$repo && \ git remote set-url origin $(GIT_CORE_REPOBASE_FETCH)/$$repo$(GIT_CORE_SUFFIX_FETCH) && \ git remote set-url --push origin $(GIT_CORE_REPOBASE_PUSH)/$$repo$(GIT_CORE_SUFFIX_PUSH) && \ cd ..; done #---------------------------------- # Subrepository management # $(1) is the target # $(2) is the target dependency. Can use % to get current REPO # $(3) is the target body. Can use % to get current REPO define repo_target .PHONY: $(1) $(1): $(2) $(3) endef # $(1) is the list of repos # $(2) is the suffix # $(3) is the target dependency. Can use % to get current REPO # $(4) is the target body. Can use % to get current REPO define repo_targets $(foreach REPO,$(1),$(call repo_target,$(REPO)+$(2),\ $(patsubst %,$(3),$(REPO)),$(patsubst %,$(4),$(REPO)))) endef # Do not allow status to fork with -j otherwise output will be garbled .PHONY: status status: checkout @for repo in . $(REPOS); do \ echo "$$repo:"; \ cd "$$repo" && git status -s && cd - >/dev/null; \ done .PHONY: pull pull: $(foreach DIR,. $(REPOS),$(DIR)+pull) $(eval $(call repo_targets,. $(REPOS),pull,| %,\ (cd % && git fetch -p && \ (! git symbolic-ref -q HEAD || git pull --ff-only)))) .PHONY: update update: pull .PHONY: named_update named_update: $(foreach DIR,. $(REPOS),$(DIR)+named_update) $(eval $(call repo_targets,. $(REPOS),named_update,| %,\ (cd % && git fetch -p && git checkout $(BRANCH) && \ (! git symbolic-ref -q HEAD || git pull --ff-only)))) .PHONY: tag tag: $(foreach DIR,. $(REPOS),$(DIR)+tag) $(eval $(call repo_targets,. $(REPOS),tag,| %,\ (cd % && git tag $(TAG)))) .PHONY: push push: $(foreach DIR,. $(REPOS),$(DIR)+push) $(eval $(call repo_targets,. $(REPOS),push,| %,\ (cd % && git push && git push --tags))) .PHONY: checkin checkin: $(foreach DIR,. $(REPOS),$(DIR)+checkin) $(eval $(call repo_targets,. $(REPOS),checkin,| %,\ (cd % && (test -z "$$$$(git status -s -uno)" || git commit -a)))) rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-agent/0000755000177700017770000000000012633765070023731 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management-agent/src/0000755000177700017770000000000012633765070024520 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management-agent/src/rabbit_mgmt_external_stats.erl0000644000177700017770000003323712633765070032643 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ Management Console. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_mgmt_external_stats). -behaviour(gen_server). -export([start_link/0]). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -export([list_registry_plugins/1]). -import(rabbit_misc, [pget/2]). -include_lib("rabbit_common/include/rabbit.hrl"). -define(REFRESH_RATIO, 5000). -define(KEYS, [name, partitions, os_pid, fd_used, fd_total, sockets_used, sockets_total, mem_used, mem_limit, mem_alarm, disk_free_limit, disk_free, disk_free_alarm, proc_used, proc_total, rates_mode, uptime, run_queue, processors, exchange_types, auth_mechanisms, applications, contexts, log_file, sasl_log_file, db_dir, config_files, net_ticktime, enabled_plugins, persister_stats]). %%-------------------------------------------------------------------- -record(state, {fd_total, fhc_stats, fhc_stats_derived, node_owners}). %%-------------------------------------------------------------------- start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). %%-------------------------------------------------------------------- get_used_fd() -> get_used_fd(os:type()). get_used_fd({unix, linux}) -> case file:list_dir("/proc/" ++ os:getpid() ++ "/fd") of {ok, Files} -> length(Files); {error, _} -> get_used_fd({unix, generic}) end; get_used_fd({unix, BSD}) when BSD == openbsd; BSD == freebsd; BSD == netbsd -> Digit = fun (D) -> lists:member(D, "0123456789*") end, Output = os:cmd("fstat -p " ++ os:getpid()), try length( lists:filter( fun (Line) -> lists:all(Digit, (lists:nth(4, string:tokens(Line, " ")))) end, string:tokens(Output, "\n"))) catch _:Error -> case get(logged_used_fd_error) of undefined -> rabbit_log:warning( "Could not parse fstat output:~n~s~n~p~n", [Output, {Error, erlang:get_stacktrace()}]), put(logged_used_fd_error, true); _ -> ok end, unknown end; get_used_fd({unix, _}) -> Cmd = rabbit_misc:format( "lsof -d \"0-9999999\" -lna -p ~s || echo failed", [os:getpid()]), Res = os:cmd(Cmd), case string:right(Res, 7) of "failed\n" -> unknown; _ -> string:words(Res, $\n) - 1 end; %% handle.exe can be obtained from %% http://technet.microsoft.com/en-us/sysinternals/bb896655.aspx %% Output looks like: %% Handle v3.42 %% Copyright (C) 1997-2008 Mark Russinovich %% Sysinternals - www.sysinternals.com %% %% Handle type summary: %% ALPC Port : 2 %% Desktop : 1 %% Directory : 1 %% Event : 108 %% File : 25 %% IoCompletion : 3 %% Key : 7 %% KeyedEvent : 1 %% Mutant : 1 %% Process : 3 %% Process : 38 %% Thread : 41 %% Timer : 3 %% TpWorkerFactory : 2 %% WindowStation : 2 %% Total handles: 238 %% Note that the "File" number appears to include network sockets too; I assume %% that's the number we care about. Note also that if you omit "-s" you will %% see a list of file handles *without* network sockets. If you then add "-a" %% you will see a list of handles of various types, including network sockets %% shown as file handles to \Device\Afd. get_used_fd({win32, _}) -> Handle = rabbit_misc:os_cmd( "handle.exe /accepteula -s -p " ++ os:getpid() ++ " 2> nul"), case Handle of [] -> install_handle_from_sysinternals; _ -> find_files_line(string:tokens(Handle, "\r\n")) end; get_used_fd(_) -> unknown. find_files_line([]) -> unknown; find_files_line([" File " ++ Rest | _T]) -> [Files] = string:tokens(Rest, ": "), list_to_integer(Files); find_files_line([_H | T]) -> find_files_line(T). -define(SAFE_CALL(Fun, NoProcFailResult), try Fun catch exit:{noproc, _} -> NoProcFailResult end). get_disk_free_limit() -> ?SAFE_CALL(rabbit_disk_monitor:get_disk_free_limit(), disk_free_monitoring_disabled). get_disk_free() -> ?SAFE_CALL(rabbit_disk_monitor:get_disk_free(), disk_free_monitoring_disabled). %%-------------------------------------------------------------------- infos(Items, State) -> [{Item, i(Item, State)} || Item <- Items]. i(name, _State) -> node(); i(partitions, _State) -> rabbit_node_monitor:partitions(); i(fd_used, _State) -> get_used_fd(); i(fd_total, #state{fd_total = FdTotal}) -> FdTotal; i(sockets_used, _State) -> proplists:get_value(sockets_used, file_handle_cache:info([sockets_used])); i(sockets_total, _State) -> proplists:get_value(sockets_limit, file_handle_cache:info([sockets_limit])); i(os_pid, _State) -> list_to_binary(os:getpid()); i(mem_used, _State) -> erlang:memory(total); i(mem_limit, _State) -> vm_memory_monitor:get_memory_limit(); i(mem_alarm, _State) -> resource_alarm_set(memory); i(proc_used, _State) -> erlang:system_info(process_count); i(proc_total, _State) -> erlang:system_info(process_limit); i(run_queue, _State) -> erlang:statistics(run_queue); i(processors, _State) -> erlang:system_info(logical_processors); i(disk_free_limit, _State) -> get_disk_free_limit(); i(disk_free, _State) -> get_disk_free(); i(disk_free_alarm, _State) -> resource_alarm_set(disk); i(contexts, _State) -> rabbit_web_dispatch_contexts(); i(uptime, _State) -> {Total, _} = erlang:statistics(wall_clock), Total; i(rates_mode, _State) -> rabbit_mgmt_db_handler:rates_mode(); i(exchange_types, _State) -> list_registry_plugins(exchange); i(log_file, _State) -> log_location(kernel); i(sasl_log_file, _State) -> log_location(sasl); i(db_dir, _State) -> list_to_binary(rabbit_mnesia:dir()); i(config_files, _State) -> [list_to_binary(F) || F <- rabbit:config_files()]; i(net_ticktime, _State) -> net_kernel:get_net_ticktime(); i(persister_stats, State) -> persister_stats(State); i(enabled_plugins, _State) -> {ok, Dir} = application:get_env( rabbit, enabled_plugins_file), rabbit_plugins:read_enabled(Dir); i(auth_mechanisms, _State) -> {ok, Mechanisms} = application:get_env(rabbit, auth_mechanisms), list_registry_plugins( auth_mechanism, fun (N) -> lists:member(list_to_atom(binary_to_list(N)), Mechanisms) end); i(applications, _State) -> [format_application(A) || A <- lists:keysort(1, rabbit_misc:which_applications())]. log_location(Type) -> case rabbit:log_location(Type) of tty -> <<"tty">>; File -> list_to_binary(File) end. resource_alarm_set(Source) -> lists:member({{resource_limit, Source, node()},[]}, rabbit_alarm:get_alarms()). list_registry_plugins(Type) -> list_registry_plugins(Type, fun(_) -> true end). list_registry_plugins(Type, Fun) -> [registry_plugin_enabled(set_plugin_name(Name, Module), Fun) || {Name, Module} <- rabbit_registry:lookup_all(Type)]. registry_plugin_enabled(Desc, Fun) -> Desc ++ [{enabled, Fun(proplists:get_value(name, Desc))}]. format_application({Application, Description, Version}) -> [{name, Application}, {description, list_to_binary(Description)}, {version, list_to_binary(Version)}]. set_plugin_name(Name, Module) -> [{name, list_to_binary(atom_to_list(Name))} | proplists:delete(name, Module:description())]. persister_stats(#state{fhc_stats = FHC, fhc_stats_derived = FHCD}) -> [{flatten_key(K), V} || {{_Op, Type} = K, V} <- FHC, Type =/= time] ++ [{flatten_key(K), V} || {K, V} <- FHCD]. flatten_key({A, B}) -> list_to_atom(atom_to_list(A) ++ "_" ++ atom_to_list(B)). cluster_links() -> {ok, Items} = net_kernel:nodes_info(), [Link || Item <- Items, Link <- [format_nodes_info(Item)], Link =/= undefined]. format_nodes_info({Node, Info}) -> Owner = proplists:get_value(owner, Info), case catch process_info(Owner, links) of {links, Links} -> case [Link || Link <- Links, is_port(Link)] of [Port] -> {Node, Owner, format_nodes_info1(Port)}; _ -> undefined end; _ -> undefined end. format_nodes_info1(Port) -> case {rabbit_net:socket_ends(Port, inbound), rabbit_net:getstat(Port, [recv_oct, send_oct])} of {{ok, {PeerAddr, PeerPort, SockAddr, SockPort}}, {ok, Stats}} -> [{peer_addr, maybe_ntoab(PeerAddr)}, {peer_port, PeerPort}, {sock_addr, maybe_ntoab(SockAddr)}, {sock_port, SockPort}, {recv_bytes, pget(recv_oct, Stats)}, {send_bytes, pget(send_oct, Stats)}]; _ -> [] end. maybe_ntoab(A) when is_tuple(A) -> list_to_binary(rabbit_misc:ntoab(A)); maybe_ntoab(H) -> H. %%-------------------------------------------------------------------- %% This is slightly icky in that we introduce knowledge of %% rabbit_web_dispatch, which is not a dependency. But the last thing I %% want to do is create a rabbitmq_mochiweb_management_agent plugin. rabbit_web_dispatch_contexts() -> [format_context(C) || C <- rabbit_web_dispatch_registry_list_all()]. %% For similar reasons we don't declare a dependency on %% rabbitmq_mochiweb - so at startup there's no guarantee it will be %% running. So we have to catch this noproc. rabbit_web_dispatch_registry_list_all() -> case code:is_loaded(rabbit_web_dispatch_registry) of false -> []; _ -> try M = rabbit_web_dispatch_registry, %% Fool xref M:list_all() catch exit:{noproc, _} -> [] end end. format_context({Path, Description, Rest}) -> [{description, list_to_binary(Description)}, {path, list_to_binary("/" ++ Path)} | format_mochiweb_option_list(Rest)]. format_mochiweb_option_list(C) -> [{K, format_mochiweb_option(K, V)} || {K, V} <- C]. format_mochiweb_option(ssl_opts, V) -> format_mochiweb_option_list(V); format_mochiweb_option(_K, V) -> case io_lib:printable_list(V) of true -> list_to_binary(V); false -> list_to_binary(rabbit_misc:format("~w", [V])) end. %%-------------------------------------------------------------------- init([]) -> State = #state{fd_total = file_handle_cache:ulimit(), fhc_stats = file_handle_cache_stats:get(), node_owners = sets:new()}, %% If we emit an update straight away we will do so just before %% the mgmt db starts up - and then have to wait ?REFRESH_RATIO %% until we send another. So let's have a shorter wait in the hope %% that the db will have started by the time we emit an update, %% and thus shorten that little gap at startup where mgmt knows %% nothing about any nodes. erlang:send_after(1000, self(), emit_update), {ok, State}. handle_call(_Req, _From, State) -> {reply, unknown_request, State}. handle_cast(_C, State) -> {noreply, State}. handle_info(emit_update, State) -> {noreply, emit_update(State)}; handle_info(_I, State) -> {noreply, State}. terminate(_, _) -> ok. code_change(_, State, _) -> {ok, State}. %%-------------------------------------------------------------------- emit_update(State0) -> State = update_state(State0), rabbit_event:notify(node_stats, infos(?KEYS, State)), erlang:send_after(?REFRESH_RATIO, self(), emit_update), emit_node_node_stats(State). emit_node_node_stats(State = #state{node_owners = Owners}) -> Links = cluster_links(), NewOwners = sets:from_list([{Node, Owner} || {Node, Owner, _} <- Links]), Dead = sets:to_list(sets:subtract(Owners, NewOwners)), [rabbit_event:notify( node_node_deleted, [{route, Route}]) || {Node, _Owner} <- Dead, Route <- [{node(), Node}, {Node, node()}]], [rabbit_event:notify( node_node_stats, [{route, {node(), Node}} | Stats]) || {Node, _Owner, Stats} <- Links], State#state{node_owners = NewOwners}. update_state(State0 = #state{fhc_stats = FHC0}) -> FHC = file_handle_cache_stats:get(), Avgs = [{{Op, avg_time}, avg_op_time(Op, V, FHC, FHC0)} || {{Op, time}, V} <- FHC], State0#state{fhc_stats = FHC, fhc_stats_derived = Avgs}. -define(MICRO_TO_MILLI, 1000). avg_op_time(Op, Time, FHC, FHC0) -> Time0 = pget({Op, time}, FHC0), TimeDelta = Time - Time0, OpDelta = pget({Op, count}, FHC) - pget({Op, count}, FHC0), case OpDelta of 0 -> 0; _ -> (TimeDelta / OpDelta) / ?MICRO_TO_MILLI end. rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-agent/src/rabbit_mgmt_db_handler.erl0000644000177700017770000000674712633765070031673 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ Management Console. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_mgmt_db_handler). %% Make sure our database is hooked in *before* listening on the network or %% recovering queues (i.e. so there can't be any events fired before it starts). -rabbit_boot_step({rabbit_mgmt_db_handler, [{description, "management agent"}, {mfa, {?MODULE, add_handler, []}}, {cleanup, {gen_event, delete_handler, [rabbit_event, ?MODULE, []]}}, {requires, rabbit_event}, {enables, recovery}]}). -behaviour(gen_event). -export([add_handler/0, gc/0, rates_mode/0]). -export([init/1, handle_call/2, handle_event/2, handle_info/2, terminate/2, code_change/3]). %%---------------------------------------------------------------------------- add_handler() -> ensure_statistics_enabled(), gen_event:add_handler(rabbit_event, ?MODULE, []). gc() -> erlang:garbage_collect(whereis(rabbit_event)). %% some people have reasons to only run with the agent enabled: %% make it possible for them to configure key management app %% settings such as rates_mode. get_management_env(Key) -> rabbit_misc:get_env( rabbitmq_management, Key, rabbit_misc:get_env(rabbitmq_management_agent, Key, undefined)). rates_mode() -> case get_management_env(rates_mode) of undefined -> basic; Mode -> Mode end. handle_force_fine_statistics() -> case get_management_env(force_fine_statistics) of undefined -> ok; X -> rabbit_log:warning( "force_fine_statistics set to ~p; ignored.~n" "Replaced by {rates_mode, none} in the rabbitmq_management " "application.~n", [X]) end. %%---------------------------------------------------------------------------- ensure_statistics_enabled() -> ForceStats = rates_mode() =/= none, handle_force_fine_statistics(), {ok, StatsLevel} = application:get_env(rabbit, collect_statistics), rabbit_log:info("Management plugin: using rates mode '~p'~n", [rates_mode()]), case {ForceStats, StatsLevel} of {true, fine} -> ok; {true, _} -> application:set_env(rabbit, collect_statistics, fine); {false, none} -> application:set_env(rabbit, collect_statistics, coarse); {_, _} -> ok end. %%---------------------------------------------------------------------------- init([]) -> {ok, []}. handle_call(_Request, State) -> {ok, not_understood, State}. handle_event(Event, State) -> gen_server:cast({global, rabbit_mgmt_db}, {event, Event}), {ok, State}. handle_info(_Info, State) -> {ok, State}. terminate(_Arg, _State) -> ok. code_change(_OldVsn, State, _Extra) -> {ok, State}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-agent/src/rabbit_mgmt_agent_app.erl0000644000177700017770000000156512633765070031540 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ Management Console. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_mgmt_agent_app). -behaviour(application). -export([start/2, stop/1]). start(_Type, _StartArgs) -> rabbit_mgmt_agent_sup:start_link(). stop(_State) -> ok. rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-agent/src/rabbit_mgmt_agent_sup.erl0000644000177700017770000000216412633765070031563 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License at %% http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ Management Console. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_mgmt_agent_sup). -behaviour(supervisor). -export([init/1]). -export([start_link/0]). init([]) -> ExternalStats = {rabbit_mgmt_external_stats, {rabbit_mgmt_external_stats, start_link, []}, permanent, 5000, worker, [rabbit_mgmt_external_stats]}, {ok, {{one_for_one, 10, 10}, [ExternalStats]}}. start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-agent/src/rabbitmq_management_agent.app.src0000644000177700017770000000036112633765070033163 0ustar michaelmichael{application, rabbitmq_management_agent, [{description, "RabbitMQ Management Agent"}, {vsn, "%%VSN%%"}, {modules, []}, {registered, []}, {mod, {rabbit_mgmt_agent_app, []}}, {env, []}, {applications, [kernel, stdlib, rabbit]}]}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-agent/CONTRIBUTING.md0000644000177700017770000000424512633765070026167 0ustar michaelmichael## Overview RabbitMQ projects use pull requests to discuss, collaborate on and accept code contributions. Pull requests is the primary place of discussing code changes. ## How to Contribute The process is fairly standard: * Fork the repository or repositories you plan on contributing to * Clone [RabbitMQ umbrella repository](https://github.com/rabbitmq/rabbitmq-public-umbrella) * `cd umbrella`, `make co` * Create a branch with a descriptive name in the relevant repositories * Make your changes, run tests, commit with a [descriptive message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), push to your fork * Submit pull requests with an explanation what has been changed and **why** * Submit a filled out and signed [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) if needed (see below) * Be patient. We will get to your pull request eventually If what you are going to work on is a substantial change, please first ask the core team of their opinion on [RabbitMQ mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). ## (Brief) Code of Conduct In one line: don't be a dick. Be respectful to the maintainers and other contributors. Open source contributors put long hours into developing projects and doing user support. Those projects and user support are available for free. We believe this deserves some respect. Be respectful to people of all races, genders, religious beliefs and political views. Regardless of how brilliant a pull request is technically, we will not tolerate disrespectful or aggressive behaviour. Contributors who violate this straightforward Code of Conduct will see their pull requests closed and locked. ## Contributor Agreement If you want to contribute a non-trivial change, please submit a signed copy of our [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) around the time you submit your pull request. This will make it much easier (in some cases, possible) for the RabbitMQ team at Pivotal to merge your contribution. ## Where to Ask Questions If something isn't clear, feel free to ask on our [mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-agent/.srcdist_done0000644000177700017770000000000012633765070026400 0ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management-agent/Makefile0000644000177700017770000000002712633765070025370 0ustar michaelmichaelinclude ../umbrella.mk rabbitmq-server-3.5.7/plugins-src/rabbitmq-management-agent/ebin/0000755000177700017770000000000012633765070024646 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-management-agent/package.mk0000644000177700017770000000003512633765070025653 0ustar michaelmichaelDEPS:=rabbitmq-erlang-client rabbitmq-server-3.5.7/plugins-src/common.mk0000644000177700017770000001055512633765070020551 0ustar michaelmichael# Various global definitions # UMBRELLA_BASE_DIR should be set to the path of the # rabbitmq-public-umbrella directory before this file is included. # Make version check REQUIRED_MAKE_VERSION:=3.81 ifneq ($(shell ( echo "$(MAKE_VERSION)" ; echo "$(REQUIRED_MAKE_VERSION)" ) | sort -t. -n | head -1),$(REQUIRED_MAKE_VERSION)) $(error GNU make version $(REQUIRED_MAKE_VERSION) required) endif # This is the standard trick for making pattern substitution work # (amongst others) when the replacement needs to include a comma. COMMA:=, # Global settings that can be overridden on the command line # These ones are expected to be passed down to the sub-makes invoked # for non-integrated packages VERSION ?= 0.0.0 ERL ?= erl ERL_OPTS ?= ERLC ?= erlc ERLC_OPTS ?= -Wall +debug_info TMPDIR ?= /tmp NODENAME ?= rabbit-test ERL_CALL ?= erl_call ERL_CALL_OPTS ?= -sname $(NODENAME) -e # Where we put all the files produced when running tests. TEST_TMPDIR=$(TMPDIR)/rabbitmq-test # Callable functions # Convert a package name to the corresponding erlang app name define package_to_app_name $(subst -,_,$(1)) endef # If the variable named $(1) holds a non-empty value, return it. # Otherwise, set the variable to $(2) and return that value. define memoize $(if $($(1)),$($(1)),$(eval $(1):=$(2))$(2)) endef # Return a canonical form for the path in $(1) # # Absolute path names can be a bit verbose. This provides a way to # canonicalize path names with more concise results. define canonical_path $(call memoize,SHORT_$(realpath $(1)),$(1)) endef # Convert a package name to a path name define package_to_path $(call canonical_path,$(UMBRELLA_BASE_DIR)/$(1)) endef # Produce a cp command to copy from $(1) to $(2), unless $(1) is # empty, in which case do nothing. # # The optional $(3) gives a suffix to append to the command, if a # command is produced. define copy $(if $(1),cp -r $(1) $(2)$(if $(3), $(3))) endef # Produce the makefile fragment for the package with path in $(1), if # it hasn't already been visited. The path should have been # canonicalized via canonical_path. define do_package # Have we already visited this package? If so, skip it ifndef DONE_$(1) PACKAGE_DIR:=$(1) include $(UMBRELLA_BASE_DIR)/do-package.mk endif endef # This is used to chain test rules, so that test-all-packages works in # the presence of 'make -j' define chain_test $(if $(CHAIN_TESTS),$(CHAINED_TESTS)$(eval CHAINED_TESTS+=$(1))) endef # Mark the non-integrated repos NON_INTEGRATED_$(call package_to_path,rabbitmq-server):=true NON_INTEGRATED_$(call package_to_path,rabbitmq-erlang-client):=true NON_INTEGRATED_$(call package_to_path,rabbitmq-java-client):=true NON_INTEGRATED_$(call package_to_path,rabbitmq-dotnet-client):=true NON_INTEGRATED_DEPS_$(call package_to_path,rabbitmq-erlang-client):=rabbitmq-server # Where the coverage package lives COVERAGE_PATH:=$(call package_to_path,coverage) # Where the rabbitmq-server package lives RABBITMQ_SERVER_PATH=$(call package_to_path,rabbitmq-server) # Cleaning support ifndef MAKECMDGOALS TESTABLEGOALS:=$(.DEFAULT_GOAL) else TESTABLEGOALS:=$(MAKECMDGOALS) endif # The CLEANING variable can be used to determine whether the top-level # goal is cleaning related. In particular, it can be used to prevent # including generated files when cleaning, which might otherwise # trigger undesirable activity. ifeq "$(strip $(patsubst clean%,,$(patsubst %clean,,$(TESTABLEGOALS))))" "" CLEANING:=true endif # Include a generated makefile fragment # # Note that this includes using "-include", and thus make will proceed # even if an error occurs while the fragment is being re-made (we # don't use "include" becuase it will produce a superfluous error # message when the fragment is re-made because it doesn't exist). # Thus you should also list the fragment as a dependency of any rules # that will refer to the contents of the fragment. define safe_include ifndef CLEANING -include $(1) # If we fail to make the fragment, make will just loop trying to # create it. So we have to explicitly catch that case. $$(if $$(MAKE_RESTARTS),$$(if $$(wildcard $(1)),,$$(error Failed to produce $(1)))) endif endef # This is not the make default, but it is a good idea .DELETE_ON_ERROR: # Declarations for global targets .PHONY: all-releasable copy-releasable copy-srcdist all-packages clean-all-packages all-releasable:: copy-releasable:: copy-srcdist:: all-packages:: clean-all-packages:: check-xref-packages:: rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/0000755000177700017770000000000012633765070021465 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/0000755000177700017770000000000012633765070023333 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/src/0000755000177700017770000000000012633765070024122 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/src/Makefile0000644000177700017770000000100312633765070025554 0ustar michaelmichael ERLC = erlc EBIN_DIR = ../ebin ERLC_FLAGS += -I ./src -I ../include +debug_info ERL_OBJECTS := ${EBIN_DIR}/eldap.beam ${EBIN_DIR}/ELDAPv3.beam ${EBIN_DIR}/eldap_fsm.beam .SUFFIXES: .asn .erl .beam $(EBIN_DIR)/%.beam: %.erl $(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< .PHONY: all all: asn $(ERL_OBJECTS) .PHONY: asn asn: ELDAPv3.erl ../ebin/ELDAPv3.beam ELDAPv3.erl: ELDAPv3.asn ${ERLC} ELDAPv3.asn mv ELDAPv3.beam ${EBIN_DIR} .PHONY: clean clean: -rm $(ERL_OBJECTS) ELDAPv3.erl ELDAPv3.asn1db ELDAPv3.hrl rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/src/ELDAPv3.asn0000644000177700017770000002415512633765070025732 0ustar michaelmichael-- 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 } END rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/src/eldap.erl0000644000177700017770000010672312633765070025724 0ustar michaelmichael-module(eldap). %%% -------------------------------------------------------------------- %%% Created: 12 Oct 2000 by Tobbe %%% Function: Erlang client LDAP implementation according RFC 2251,2253 %%% and 2255. The interface is based on RFC 1823, and %%% draft-ietf-asid-ldap-c-api-00.txt %%% %%% Copyright (c) 2010 Torbjorn Tornkvist %%% See MIT-LICENSE at the top dir for licensing information. %%% -------------------------------------------------------------------- -vc('$Id$ '). -export([open/1,open/2,simple_bind/3,controlling_process/2, baseObject/0,singleLevel/0,wholeSubtree/0,close/1, equalityMatch/2,greaterOrEqual/2,lessOrEqual/2, approxMatch/2,search/2,substrings/2,present/1, 'and'/1,'or'/1,'not'/1,modify/3, mod_add/2, mod_delete/2, mod_replace/2, add/3, delete/2, modify_dn/5,parse_dn/1, parse_ldap_url/1]). -import(lists,[concat/1]). -include("ELDAPv3.hrl"). -include("eldap.hrl"). -define(LDAP_VERSION, 3). -define(LDAP_PORT, 389). -define(LDAPS_PORT, 636). -record(eldap, {version = ?LDAP_VERSION, host, % Host running LDAP server port = ?LDAP_PORT, % The LDAP server port fd, % Socket filedescriptor. binddn = "", % Name of the entry to bind as passwd, % Password for (above) entry id = 0, % LDAP Request ID log, % User provided log function timeout = infinity, % Request timeout anon_auth = false, % Allow anonymous authentication use_tls = false % LDAP/LDAPS }). %%% For debug purposes %%-define(PRINT(S, A), io:fwrite("~w(~w): " ++ S, [?MODULE,?LINE|A])). -define(PRINT(S, A), true). -define(elog(S, A), error_logger:info_msg("~w(~w): "++S,[?MODULE,?LINE|A])). %%% ==================================================================== %%% Exported interface %%% ==================================================================== %%% -------------------------------------------------------------------- %%% open(Hosts [,Opts] ) %%% -------------------- %%% Setup a connection to on of the Hosts in the argument %%% list. Stop at the first successful connection attempt. %%% Valid Opts are: Where: %%% %%% {port, Port} - Port is the port number %%% {log, F} - F(LogLevel, FormatString, ListOfArgs) %%% {timeout, milliSec} - request timeout %%% %%% -------------------------------------------------------------------- open(Hosts) -> open(Hosts, []). open(Hosts, Opts) when list(Hosts), list(Opts) -> Self = self(), Pid = spawn_link(fun() -> init(Hosts, Opts, Self) end), recv(Pid). %%% -------------------------------------------------------------------- %%% Shutdown connection (and process) asynchronous. %%% -------------------------------------------------------------------- close(Handle) when pid(Handle) -> send(Handle, close). %%% -------------------------------------------------------------------- %%% Set who we should link ourselves to %%% -------------------------------------------------------------------- controlling_process(Handle, Pid) when pid(Handle),pid(Pid) -> link(Pid), send(Handle, {cnt_proc, Pid}), recv(Handle). %%% -------------------------------------------------------------------- %%% Authenticate ourselves to the Directory %%% using simple authentication. %%% %%% Dn - The name of the entry to bind as %%% Passwd - The password to be used %%% %%% Returns: ok | {error, Error} %%% -------------------------------------------------------------------- simple_bind(Handle, Dn, Passwd) when pid(Handle) -> send(Handle, {simple_bind, Dn, Passwd}), recv(Handle). %%% -------------------------------------------------------------------- %%% 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 pid(Handle),list(Entry),list(Attributes) -> send(Handle, {add, Entry, add_attrs(Attributes)}), recv(Handle). %%% Do sanity check ! add_attrs(Attrs) -> F = fun({Type,Vals}) when list(Type),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 pid(Handle), list(Entry) -> send(Handle, {delete, Entry}), recv(Handle). %%% -------------------------------------------------------------------- %%% 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 pid(Handle), list(Object), list(Mods) -> send(Handle, {modify, Object, Mods}), recv(Handle). %%% %%% Modification operations. %%% Example: %%% replace("telephoneNumber", ["555 555 00"]) %%% mod_add(Type, Values) when list(Type), list(Values) -> m(add, Type, Values). mod_delete(Type, Values) when list(Type), list(Values) -> m(delete, Type, Values). mod_replace(Type, Values) when list(Type), 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 pid(Handle),list(Entry),list(NewRDN),atom(DelOldRDN),list(NewSup) -> send(Handle, {modify_dn, Entry, NewRDN, bool_p(DelOldRDN), optional(NewSup)}), recv(Handle). %%% 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 pid(Handle), record(A, eldap_search) -> call_search(Handle, A); search(Handle, L) when pid(Handle), list(L) -> case catch parse_search_args(L) of {error, Emsg} -> {error, Emsg}; A when record(A, eldap_search) -> call_search(Handle, A) end. call_search(Handle, A) -> send(Handle, {search, A}), recv(Handle). 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 integer(Timeout) -> parse_search_args(T,A#eldap_search{timeout = Timeout}); 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 list(ListOfFilters) -> {'and',ListOfFilters}. 'or'(ListOfFilters) when list(ListOfFilters) -> {'or', ListOfFilters}. 'not'(Filter) when 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 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 list(Type), list(SubStr) -> Ss = {'SubstringFilter_substrings',v_substr(SubStr)}, {substrings,#'SubstringFilter'{type = Type, substrings = Ss}}. %%% -------------------------------------------------------------------- %%% Worker process. We keep track of a controlling process to %%% be able to terminate together with it. %%% -------------------------------------------------------------------- init(Hosts, Opts, Cpid) -> Data = parse_args(Opts, Cpid, #eldap{}), case try_connect(Hosts, Data) of {ok,Data2} -> send(Cpid, {ok,self()}), put(req_timeout, Data#eldap.timeout), % kludge... loop(Cpid, Data2); Else -> send(Cpid, Else), unlink(Cpid), exit(Else) end. parse_args([{port, Port}|T], Cpid, Data) when integer(Port) -> parse_args(T, Cpid, Data#eldap{port = Port}); parse_args([{timeout, Timeout}|T], Cpid, Data) when integer(Timeout),Timeout>0 -> parse_args(T, Cpid, Data#eldap{timeout = Timeout}); parse_args([{anon_auth, true}|T], Cpid, Data) -> parse_args(T, Cpid, Data#eldap{anon_auth = false}); parse_args([{anon_auth, _}|T], Cpid, Data) -> parse_args(T, Cpid, Data); parse_args([{ssl, true}|T], Cpid, Data) -> parse_args(T, Cpid, Data#eldap{use_tls = true}); parse_args([{ssl, _}|T], Cpid, Data) -> parse_args(T, Cpid, Data); parse_args([{log, F}|T], Cpid, Data) when function(F) -> parse_args(T, Cpid, Data#eldap{log = F}); parse_args([{log, _}|T], Cpid, Data) -> parse_args(T, Cpid, Data); parse_args([H|_], Cpid, _) -> send(Cpid, {error,{wrong_option,H}}), exit(wrong_option); parse_args([], _, Data) -> Data. %%% Try to connect to the hosts in the listed order, %%% and stop with the first one to which a successful %%% connection is made. try_connect([Host|Hosts], Data) -> TcpOpts = [{packet, asn1}, {active,false}], case do_connect(Host, Data, TcpOpts) of {ok,Fd} -> {ok,Data#eldap{host = Host, fd = Fd}}; _ -> try_connect(Hosts, Data) end; try_connect([],_) -> {error,"connect failed"}. do_connect(Host, Data, Opts) when Data#eldap.use_tls == false -> gen_tcp:connect(Host, Data#eldap.port, Opts, Data#eldap.timeout); do_connect(Host, Data, Opts) when Data#eldap.use_tls == true -> ssl:connect(Host, Data#eldap.port, [{verify,0}|Opts]). loop(Cpid, Data) -> receive {From, {search, A}} -> {Res,NewData} = do_search(Data, A), send(From,Res), loop(Cpid, NewData); {From, {modify, Obj, Mod}} -> {Res,NewData} = do_modify(Data, Obj, Mod), send(From,Res), loop(Cpid, NewData); {From, {modify_dn, Obj, NewRDN, DelOldRDN, NewSup}} -> {Res,NewData} = do_modify_dn(Data, Obj, NewRDN, DelOldRDN, NewSup), send(From,Res), loop(Cpid, NewData); {From, {add, Entry, Attrs}} -> {Res,NewData} = do_add(Data, Entry, Attrs), send(From,Res), loop(Cpid, NewData); {From, {delete, Entry}} -> {Res,NewData} = do_delete(Data, Entry), send(From,Res), loop(Cpid, NewData); {From, {simple_bind, Dn, Passwd}} -> {Res,NewData} = do_simple_bind(Data, Dn, Passwd), send(From,Res), loop(Cpid, NewData); {From, {cnt_proc, NewCpid}} -> unlink(Cpid), send(From,ok), ?PRINT("New Cpid is: ~p~n",[NewCpid]), loop(NewCpid, Data); {From, close} -> unlink(Cpid), exit(closed); {Cpid, 'EXIT', Reason} -> ?PRINT("Got EXIT from Cpid, reason=~p~n",[Reason]), exit(Reason); _XX -> ?PRINT("loop got: ~p~n",[_XX]), loop(Cpid, Data) end. %%% -------------------------------------------------------------------- %%% bindRequest %%% -------------------------------------------------------------------- %%% Authenticate ourselves to the directory using %%% simple authentication. do_simple_bind(Data, anon, anon) -> %% For testing do_the_simple_bind(Data, "", ""); do_simple_bind(Data, Dn, _Passwd) when Dn=="",Data#eldap.anon_auth==false -> {{error,anonymous_auth},Data}; do_simple_bind(Data, _Dn, Passwd) when Passwd=="",Data#eldap.anon_auth==false -> {{error,anonymous_auth},Data}; do_simple_bind(Data, Dn, Passwd) -> do_the_simple_bind(Data, Dn, Passwd). do_the_simple_bind(Data, Dn, Passwd) -> case catch exec_simple_bind(Data#eldap{binddn = Dn, passwd = Passwd, id = bump_id(Data)}) of {ok,NewData} -> {ok,NewData}; {error,Emsg} -> {{error,Emsg},Data}; Else -> {{error,Else},Data} end. exec_simple_bind(Data) -> Req = #'BindRequest'{version = Data#eldap.version, name = Data#eldap.binddn, authentication = {simple, Data#eldap.passwd}}, log2(Data, "bind request = ~p~n", [Req]), Reply = request(Data#eldap.fd, Data, Data#eldap.id, {bindRequest, Req}), log2(Data, "bind reply = ~p~n", [Reply]), exec_simple_bind_reply(Data, Reply). exec_simple_bind_reply(Data, {ok,Msg}) when Msg#'LDAPMessage'.messageID == Data#eldap.id -> case Msg#'LDAPMessage'.protocolOp of {bindResponse, Result} -> case Result#'BindResponse'.resultCode of success -> {ok,Data}; Error -> {error, Error} end; Other -> {error, Other} end; exec_simple_bind_reply(_, Error) -> {error, Error}. %%% -------------------------------------------------------------------- %%% searchRequest %%% -------------------------------------------------------------------- do_search(Data, A) -> case catch do_search_0(Data, A) of {error,Emsg} -> {ldap_closed_p(Data, Emsg),Data}; {'EXIT',Error} -> {ldap_closed_p(Data, Error),Data}; {ok,Res,Ref,NewData} -> {{ok,polish(Res, Ref)},NewData}; Else -> {ldap_closed_p(Data, Else),Data} end. %%% %%% Polish the returned search result %%% polish(Res, Ref) -> R = polish_result(Res), %%% No special treatment of referrals at the moment. #eldap_search_result{entries = R, referrals = Ref}. polish_result([H|T]) when record(H, 'SearchResultEntry') -> ObjectName = H#'SearchResultEntry'.objectName, F = fun({_,A,V}) -> {A,V} end, Attrs = lists:map(F, H#'SearchResultEntry'.attributes), [#eldap_entry{object_name = ObjectName, attributes = Attrs}| polish_result(T)]; polish_result([]) -> []. do_search_0(Data, A) -> Req = #'SearchRequest'{baseObject = A#eldap_search.base, scope = v_scope(A#eldap_search.scope), derefAliases = neverDerefAliases, sizeLimit = 0, % no size 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) }, Id = bump_id(Data), collect_search_responses(Data#eldap{id=Id}, Req, Id). %%% The returned answers cames in one packet per entry %%% mixed with possible referals collect_search_responses(Data, Req, ID) -> S = Data#eldap.fd, log2(Data, "search request = ~p~n", [Req]), send_request(S, Data, ID, {searchRequest, Req}), Resp = recv_response(S, Data), log2(Data, "search reply = ~p~n", [Resp]), collect_search_responses(Data, S, ID, Resp, [], []). collect_search_responses(Data, S, ID, {ok,Msg}, Acc, Ref) when record(Msg,'LDAPMessage') -> case Msg#'LDAPMessage'.protocolOp of {'searchResDone',R} when R#'LDAPResult'.resultCode == success -> log2(Data, "search reply = searchResDone ~n", []), {ok,Acc,Ref,Data}; {'searchResEntry',R} when record(R,'SearchResultEntry') -> Resp = recv_response(S, Data), log2(Data, "search reply = ~p~n", [Resp]), collect_search_responses(Data, S, ID, Resp, [R|Acc], Ref); {'searchResRef',R} -> %% At the moment we don't do anyting sensible here since %% I haven't been able to trigger the server to generate %% a response like this. Resp = recv_response(S, Data), log2(Data, "search reply = ~p~n", [Resp]), collect_search_responses(Data, S, ID, Resp, Acc, [R|Ref]); Else -> throw({error,Else}) end; collect_search_responses(_, _, _, Else, _, _) -> throw({error,Else}). %%% -------------------------------------------------------------------- %%% addRequest %%% -------------------------------------------------------------------- do_add(Data, Entry, Attrs) -> case catch do_add_0(Data, Entry, Attrs) of {error,Emsg} -> {ldap_closed_p(Data, Emsg),Data}; {'EXIT',Error} -> {ldap_closed_p(Data, Error),Data}; {ok,NewData} -> {ok,NewData}; Else -> {ldap_closed_p(Data, Else),Data} end. do_add_0(Data, Entry, Attrs) -> Req = #'AddRequest'{entry = Entry, attributes = Attrs}, S = Data#eldap.fd, Id = bump_id(Data), log2(Data, "add request = ~p~n", [Req]), Resp = request(S, Data, Id, {addRequest, Req}), log2(Data, "add reply = ~p~n", [Resp]), check_reply(Data#eldap{id = Id}, Resp, addResponse). %%% -------------------------------------------------------------------- %%% deleteRequest %%% -------------------------------------------------------------------- do_delete(Data, Entry) -> case catch do_delete_0(Data, Entry) of {error,Emsg} -> {ldap_closed_p(Data, Emsg),Data}; {'EXIT',Error} -> {ldap_closed_p(Data, Error),Data}; {ok,NewData} -> {ok,NewData}; Else -> {ldap_closed_p(Data, Else),Data} end. do_delete_0(Data, Entry) -> S = Data#eldap.fd, Id = bump_id(Data), log2(Data, "del request = ~p~n", [Entry]), Resp = request(S, Data, Id, {delRequest, Entry}), log2(Data, "del reply = ~p~n", [Resp]), check_reply(Data#eldap{id = Id}, Resp, delResponse). %%% -------------------------------------------------------------------- %%% modifyRequest %%% -------------------------------------------------------------------- do_modify(Data, Obj, Mod) -> case catch do_modify_0(Data, Obj, Mod) of {error,Emsg} -> {ldap_closed_p(Data, Emsg),Data}; {'EXIT',Error} -> {ldap_closed_p(Data, Error),Data}; {ok,NewData} -> {ok,NewData}; Else -> {ldap_closed_p(Data, Else),Data} end. do_modify_0(Data, Obj, Mod) -> v_modifications(Mod), Req = #'ModifyRequest'{object = Obj, modification = Mod}, S = Data#eldap.fd, Id = bump_id(Data), log2(Data, "modify request = ~p~n", [Req]), Resp = request(S, Data, Id, {modifyRequest, Req}), log2(Data, "modify reply = ~p~n", [Resp]), check_reply(Data#eldap{id = Id}, Resp, modifyResponse). %%% -------------------------------------------------------------------- %%% modifyDNRequest %%% -------------------------------------------------------------------- do_modify_dn(Data, Entry, NewRDN, DelOldRDN, NewSup) -> case catch do_modify_dn_0(Data, Entry, NewRDN, DelOldRDN, NewSup) of {error,Emsg} -> {ldap_closed_p(Data, Emsg),Data}; {'EXIT',Error} -> {ldap_closed_p(Data, Error),Data}; {ok,NewData} -> {ok,NewData}; Else -> {ldap_closed_p(Data, Else),Data} end. do_modify_dn_0(Data, Entry, NewRDN, DelOldRDN, NewSup) -> Req = #'ModifyDNRequest'{entry = Entry, newrdn = NewRDN, deleteoldrdn = DelOldRDN, newSuperior = NewSup}, S = Data#eldap.fd, Id = bump_id(Data), log2(Data, "modify DN request = ~p~n", [Req]), Resp = request(S, Data, Id, {modDNRequest, Req}), log2(Data, "modify DN reply = ~p~n", [Resp]), check_reply(Data#eldap{id = Id}, Resp, modDNResponse). %%% -------------------------------------------------------------------- %%% Send an LDAP request and receive the answer %%% -------------------------------------------------------------------- request(S, Data, ID, Request) -> send_request(S, Data, ID, Request), recv_response(S, Data). send_request(S, Data, ID, Request) -> Message = #'LDAPMessage'{messageID = ID, protocolOp = Request}, {ok,Bytes} = asn1rt:encode('ELDAPv3', 'LDAPMessage', Message), case do_send(S, Data, Bytes) of {error,Reason} -> throw({gen_tcp_error,Reason}); Else -> Else end. do_send(S, Data, Bytes) when Data#eldap.use_tls == false -> gen_tcp:send(S, Bytes); do_send(S, Data, Bytes) when Data#eldap.use_tls == true -> ssl:send(S, Bytes). do_recv(S, Data, Len, Timeout) when Data#eldap.use_tls == false -> gen_tcp:recv(S, Len, Timeout); do_recv(S, Data, Len, Timeout) when Data#eldap.use_tls == true -> ssl:recv(S, Len, Timeout). recv_response(S, Data) -> Timeout = get(req_timeout), % kludge... case do_recv(S, Data, 0, Timeout) of {ok, Packet} -> check_tag(Packet), case asn1rt:decode('ELDAPv3', 'LDAPMessage', Packet) of {ok,Resp} -> {ok,Resp}; Error -> throw(Error) end; {error,Reason} -> throw({gen_tcp_error, Reason}); Error -> throw(Error) end. %%% Sanity check of received packet check_tag(Data) -> case asn1rt_ber_bin:decode_tag(b2l(Data)) of {_Tag, Data1, _Rb} -> case asn1rt_ber_bin:decode_length(b2l(Data1)) of {{_Len, _Data2}, _Rb2} -> ok; _ -> throw({error,decoded_tag_length}) end; _ -> throw({error,decoded_tag}) end. %%% Check for expected kind of reply check_reply(Data, {ok,Msg}, Op) when Msg#'LDAPMessage'.messageID == Data#eldap.id -> case Msg#'LDAPMessage'.protocolOp of {Op, Result} -> case Result#'LDAPResult'.resultCode of success -> {ok,Data}; Error -> {error, Error} end; Other -> {error, Other} end; check_reply(_, Error, _) -> {error, Error}. %%% -------------------------------------------------------------------- %%% 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 record(S,'SubstringFilter') -> {substrings,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 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 integer(I), I>=0 -> I; v_timeout(_I) -> throw({error,concat(["timeout not positive integer: ",_I])}). v_attributes(Attrs) -> F = fun(A) when list(A) -> A; (A) -> throw({error,concat(["attribute not String: ",A])}) end, lists:map(F,Attrs). %%% -------------------------------------------------------------------- %%% Log routines. Call a user provided log routine F. %%% -------------------------------------------------------------------- log1(Data, Str, Args) -> log(Data, Str, Args, 1). log2(Data, Str, Args) -> log(Data, Str, Args, 2). log(Data, Str, Args, Level) when function(Data#eldap.log) -> catch (Data#eldap.log)(Level, Str, Args); log(_, _, _, _) -> ok. %%% -------------------------------------------------------------------- %%% Misc. routines %%% -------------------------------------------------------------------- send(To,Msg) -> To ! {self(),Msg}. recv(From) -> receive {From,Msg} -> Msg end. ldap_closed_p(Data, Emsg) when Data#eldap.use_tls == true -> %% Check if the SSL socket seems to be alive or not case catch ssl:sockname(Data#eldap.fd) of {error, _} -> ssl:close(Data#eldap.fd), {error, ldap_closed}; {ok, _} -> {error, Emsg}; _ -> %% sockname crashes if the socket pid is not alive {error, ldap_closed} end; ldap_closed_p(Data, Emsg) -> %% non-SSL socket case inet:port(Data#eldap.fd) of {error,_} -> {error, ldap_closed}; _ -> {error,Emsg} end. bump_id(Data) -> Data#eldap.id + 1. %%% -------------------------------------------------------------------- %%% parse_dn/1 - Implementation of RFC 2253: %%% %%% "UTF-8 String Representation of Distinguished Names" %%% %%% Test cases: %%% %%% The simplest case: %%% %%% 1> eldap:parse_dn("CN=Steve Kille,O=Isode Limited,C=GB"). %%% {ok,[[{attribute_type_and_value,"CN","Steve Kille"}], %%% [{attribute_type_and_value,"O","Isode Limited"}], %%% [{attribute_type_and_value,"C","GB"}]]} %%% %%% The first RDN is multi-valued: %%% %%% 2> eldap:parse_dn("OU=Sales+CN=J. Smith,O=Widget Inc.,C=US"). %%% {ok,[[{attribute_type_and_value,"OU","Sales"}, %%% {attribute_type_and_value,"CN","J. Smith"}], %%% [{attribute_type_and_value,"O","Widget Inc."}], %%% [{attribute_type_and_value,"C","US"}]]} %%% %%% Quoting a comma: %%% %%% 3> eldap:parse_dn("CN=L. Eagle,O=Sue\\, Grabbit and Runn,C=GB"). %%% {ok,[[{attribute_type_and_value,"CN","L. Eagle"}], %%% [{attribute_type_and_value,"O","Sue\\, Grabbit and Runn"}], %%% [{attribute_type_and_value,"C","GB"}]]} %%% %%% A value contains a carriage return: %%% %%% 4> eldap:parse_dn("CN=Before %%% 4> After,O=Test,C=GB"). %%% {ok,[[{attribute_type_and_value,"CN","Before\nAfter"}], %%% [{attribute_type_and_value,"O","Test"}], %%% [{attribute_type_and_value,"C","GB"}]]} %%% %%% 5> eldap:parse_dn("CN=Before\\0DAfter,O=Test,C=GB"). %%% {ok,[[{attribute_type_and_value,"CN","Before\\0DAfter"}], %%% [{attribute_type_and_value,"O","Test"}], %%% [{attribute_type_and_value,"C","GB"}]]} %%% %%% An RDN in OID form: %%% %%% 6> eldap:parse_dn("1.3.6.1.4.1.1466.0=#04024869,O=Test,C=GB"). %%% {ok,[[{attribute_type_and_value,"1.3.6.1.4.1.1466.0","#04024869"}], %%% [{attribute_type_and_value,"O","Test"}], %%% [{attribute_type_and_value,"C","GB"}]]} %%% %%% %%% -------------------------------------------------------------------- parse_dn("") -> % empty DN string {ok,[]}; parse_dn([H|_] = Str) when H=/=$, -> % 1:st name-component ! case catch parse_name(Str,[]) of {'EXIT',Reason} -> {parse_error,internal_error,Reason}; Else -> Else end. parse_name("",Acc) -> {ok,lists:reverse(Acc)}; parse_name([$,|T],Acc) -> % N:th name-component ! parse_name(T,Acc); parse_name(Str,Acc) -> {Rest,NameComponent} = parse_name_component(Str), parse_name(Rest,[NameComponent|Acc]). parse_name_component(Str) -> parse_name_component(Str,[]). parse_name_component(Str,Acc) -> case parse_attribute_type_and_value(Str) of {[$+|Rest], ATV} -> parse_name_component(Rest,[ATV|Acc]); {Rest,ATV} -> {Rest,lists:reverse([ATV|Acc])} end. parse_attribute_type_and_value(Str) -> case parse_attribute_type(Str) of {Rest,[]} -> error(expecting_attribute_type,Str); {Rest,Type} -> Rest2 = parse_equal_sign(Rest), {Rest3,Value} = parse_attribute_value(Rest2), {Rest3,{attribute_type_and_value,Type,Value}} end. -define(IS_ALPHA(X) , X>=$a,X=<$z;X>=$A,X=<$Z ). -define(IS_DIGIT(X) , X>=$0,X=<$9 ). -define(IS_SPECIAL(X) , X==$,;X==$=;X==$+;X==$<;X==$>;X==$#;X==$; ). -define(IS_QUOTECHAR(X) , X=/=$\\,X=/=$" ). -define(IS_STRINGCHAR(X) , X=/=$,,X=/=$=,X=/=$+,X=/=$<,X=/=$>,X=/=$#,X=/=$;,?IS_QUOTECHAR(X) ). -define(IS_HEXCHAR(X) , ?IS_DIGIT(X);X>=$a,X=<$f;X>=$A,X=<$F ). parse_attribute_type([H|T]) when ?IS_ALPHA(H) -> %% NB: It must be an error in the RFC in the definition %% of 'attributeType', should be: (ALPHA *keychar) {Rest,KeyChars} = parse_keychars(T), {Rest,[H|KeyChars]}; parse_attribute_type([H|_] = Str) when ?IS_DIGIT(H) -> parse_oid(Str); parse_attribute_type(Str) -> error(invalid_attribute_type,Str). %%% Is a hexstring ! parse_attribute_value([$#,X,Y|T]) when ?IS_HEXCHAR(X),?IS_HEXCHAR(Y) -> {Rest,HexString} = parse_hexstring(T), {Rest,[$#,X,Y|HexString]}; %%% Is a "quotation-sequence" ! parse_attribute_value([$"|T]) -> {Rest,Quotation} = parse_quotation(T), {Rest,[$"|Quotation]}; %%% Is a stringchar , pair or Empty ! parse_attribute_value(Str) -> parse_string(Str). parse_hexstring(Str) -> parse_hexstring(Str,[]). parse_hexstring([X,Y|T],Acc) when ?IS_HEXCHAR(X),?IS_HEXCHAR(Y) -> parse_hexstring(T,[Y,X|Acc]); parse_hexstring(T,Acc) -> {T,lists:reverse(Acc)}. parse_quotation([$"|T]) -> % an empty: "" is ok ! {T,[$"]}; parse_quotation(Str) -> parse_quotation(Str,[]). %%% Parse to end of quotation parse_quotation([$"|T],Acc) -> {T,lists:reverse([$"|Acc])}; parse_quotation([X|T],Acc) when ?IS_QUOTECHAR(X) -> parse_quotation(T,[X|Acc]); parse_quotation([$\\,X|T],Acc) when ?IS_SPECIAL(X) -> parse_quotation(T,[X,$\\|Acc]); parse_quotation([$\\,$\\|T],Acc) -> parse_quotation(T,[$\\,$\\|Acc]); parse_quotation([$\\,$"|T],Acc) -> parse_quotation(T,[$",$\\|Acc]); parse_quotation([$\\,X,Y|T],Acc) when ?IS_HEXCHAR(X),?IS_HEXCHAR(Y) -> parse_quotation(T,[Y,X,$\\|Acc]); parse_quotation(T,_) -> error(expecting_double_quote_mark,T). parse_string(Str) -> parse_string(Str,[]). parse_string("",Acc) -> {"",lists:reverse(Acc)}; parse_string([H|T],Acc) when ?IS_STRINGCHAR(H) -> parse_string(T,[H|Acc]); parse_string([$\\,X|T],Acc) when ?IS_SPECIAL(X) -> % is a pair ! parse_string(T,[X,$\\|Acc]); parse_string([$\\,$\\|T],Acc) -> % is a pair ! parse_string(T,[$\\,$\\|Acc]); parse_string([$\\,$" |T],Acc) -> % is a pair ! parse_string(T,[$" ,$\\|Acc]); parse_string([$\\,X,Y|T],Acc) when ?IS_HEXCHAR(X),?IS_HEXCHAR(Y) -> % is a pair! parse_string(T,[Y,X,$\\|Acc]); parse_string(T,Acc) -> {T,lists:reverse(Acc)}. parse_equal_sign([$=|T]) -> T; parse_equal_sign(T) -> error(expecting_equal_sign,T). parse_keychars(Str) -> parse_keychars(Str,[]). parse_keychars([H|T],Acc) when ?IS_ALPHA(H) -> parse_keychars(T,[H|Acc]); parse_keychars([H|T],Acc) when ?IS_DIGIT(H) -> parse_keychars(T,[H|Acc]); parse_keychars([$-|T],Acc) -> parse_keychars(T,[$-|Acc]); parse_keychars(T,Acc) -> {T,lists:reverse(Acc)}. parse_oid(Str) -> parse_oid(Str,[]). parse_oid([H,$.|T], Acc) when ?IS_DIGIT(H) -> parse_oid(T,[$.,H|Acc]); parse_oid([H|T], Acc) when ?IS_DIGIT(H) -> parse_oid(T,[H|Acc]); parse_oid(T, Acc) -> {T,lists:reverse(Acc)}. error(Emsg,Rest) -> throw({parse_error,Emsg,Rest}). %%% -------------------------------------------------------------------- %%% Parse LDAP url according to RFC 2255 %%% %%% Test case: %%% %%% 2> eldap:parse_ldap_url("ldap://10.42.126.33:389/cn=Administrative%20CA,o=Post%20Danmark,c=DK?certificateRevokationList;binary"). %%% {ok,{{10,42,126,33},389}, %%% [[{attribute_type_and_value,"cn","Administrative%20CA"}], %%% [{attribute_type_and_value,"o","Post%20Danmark"}], %%% [{attribute_type_and_value,"c","DK"}]], %%% {attributes,["certificateRevokationList;binary"]}} %%% %%% -------------------------------------------------------------------- parse_ldap_url("ldap://" ++ Rest1 = Str) -> {Rest2,HostPort} = parse_hostport(Rest1), %% Split the string into DN and Attributes+etc {Sdn,Rest3} = split_string(rm_leading_slash(Rest2),$?), case parse_dn(Sdn) of {parse_error,internal_error,_Reason} -> {parse_error,internal_error,{Str,[]}}; {parse_error,Emsg,Tail} -> Head = get_head(Str,Tail), {parse_error,Emsg,{Head,Tail}}; {ok,DN} -> %% We stop parsing here for now and leave %% 'scope', 'filter' and 'extensions' to %% be implemented later if needed. {_Rest4,Attributes} = parse_attributes(Rest3), {ok,HostPort,DN,Attributes} end. rm_leading_slash([$/|Tail]) -> Tail; rm_leading_slash(Tail) -> Tail. parse_attributes([$?|Tail]) -> case split_string(Tail,$?) of {[],Attributes} -> {[],{attributes,string:tokens(Attributes,",")}}; {Attributes,Rest} -> {Rest,{attributes,string:tokens(Attributes,",")}} end. parse_hostport(Str) -> {HostPort,Rest} = split_string(Str,$/), case split_string(HostPort,$:) of {Shost,[]} -> {Rest,{parse_host(Rest,Shost),?LDAP_PORT}}; {Shost,[$:|Sport]} -> {Rest,{parse_host(Rest,Shost), parse_port(Rest,Sport)}} end. parse_port(Rest,Sport) -> case list_to_integer(Sport) of Port when integer(Port) -> Port; _ -> error(parsing_port,Rest) end. parse_host(Rest,Shost) -> case catch validate_host(Shost) of {parse_error,Emsg,_} -> error(Emsg,Rest); Host -> Host end. validate_host(Shost) -> case inet_parse:address(Shost) of {ok,Host} -> Host; _ -> case inet_parse:domain(Shost) of true -> Shost; _ -> error(parsing_host,Shost) end end. split_string(Str,Key) -> Pred = fun(X) when X==Key -> false; (_) -> true end, lists:splitwith(Pred, Str). get_head(Str,Tail) -> get_head(Str,Tail,[]). %%% Should always succeed ! get_head([H|Tail],Tail,Rhead) -> lists:reverse([H|Rhead]); get_head([H|Rest],Tail,Rhead) -> get_head(Rest,Tail,[H|Rhead]). b2l(B) when binary(B) -> B; b2l(L) when list(L) -> list_to_binary(L). rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/README0000644000177700017770000000227212633765070024216 0ustar michaelmichaelHi, This is 'eldap', the Erlang LDAP library. It exports an API that can do all possible operations you may want to do against an LDAP server. The code has been tested to work at some point, but only the bind and search operations are running daily in our products, so there may be bugs lurking in some parts of the code. To just use eldap for doing authentication, do like in: {ok,X} = eldap:open(["ldap.mycorp.com"], []). eldap:simple_bind(X, "uid=tobbe,ou=People,dc=mycorp,dc=com", "passwd"). In the doc/README.example you'll find a trace from a Erlang shell session as an example on how to setup a connection, authenticate (bind) and perform a search. Note that by using the option {ssl, true}, you should be able to setup an SSL tunnel (LDAPS) if your Erlang system has been configured with SSL. In the test directory there are some hints and examples on how to test the code and how to setup and populate an OpenLDAP server. The 'eldap' code has been tested agains OpenLDAP, IPlanet and ActiveDirectory servers. If you plan to incorporate this code into your system I suggest that you build a server/supervisor harnesk that uses 'eldap' (as we have done in our products). Good luck ! /Tobbe rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/doc/0000755000177700017770000000000012633765070024100 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/doc/short-desc0000644000177700017770000000005312633765070026074 0ustar michaelmichaelThis is 'eldap', the Erlang LDAP library. rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/doc/README.example0000644000177700017770000000455712633765070026425 0ustar michaelmichael1> {_,S} = eldap:open(["192.168.128.47"], []). {ok,<0.30.0>} 2> eldap:simple_bind(S,"cn=Torbjorn Tornkvist,cn=Users,dc=bluetail,dc=com","qwe123"). ok 3> Base = {base, "dc=bluetail,dc=com"}. {base,"dc=bluetail,dc=com"} 4> Scope = {scope, eldap:wholeSubtree()}. {scope,wholeSubtree} 5> Filter = {filter, eldap:equalityMatch("sAMAccountName", "tobbe")}. {filter,{equalityMatch,{'AttributeValueAssertion',"sAMAccountName","tobbe"}}} 6> Search = [Base, Scope, Filter]. [{base,"dc=bluetail,dc=com"}, {scope,wholeSubtree}, {filter,{equalityMatch,{'AttributeValueAssertion',"sAMAccountName","tobbe"}}}] 7> eldap:search(S, Search). {ok,{eldap_search_result,[{eldap_entry, "CN=Torbjorn Tornkvist,CN=Users,DC=bluetail,DC=com", [{"manager", ["CN=Tord Larsson,CN=Users,DC=bluetail,DC=com"]}, {"memberOf", ["CN=TestGroup2,CN=Users,DC=bluetail,DC=com", "CN=TestGroup,CN=Users,DC=bluetail,DC=com", "CN=Pre-Windows 2000 Compatible Access,CN=Builtin,DC=bluetail,DC=com", "CN=Server Operators,CN=Builtin,DC=bluetail,DC=com"]}, {"accountExpires",["0"]}, {"adminCount",["1"]}, {"badPasswordTime",["127119104851642448"]}, {"badPwdCount",["0"]}, {"codePage",["0"]}, {"cn",["Torbjorn Tornkvist"]}, {"company",["Alteon Web Systems"]}, {"countryCode",["0"]}, {"department",["Bluetail"]}, {"displayName",["Torbjorn Tornkvist"]}, {"mail",["tobbe@bluetail.com"]}, {"givenName",["Torbjorn"]}, {"instanceType",["4"]}, {"lastLogoff",["0"]}, {"lastLogon",["127119109376267104"]}, {"logonCount",[...]}, {"msNPAllowDialin"|...}, {...}|...]}], [["ldap://bluetail.com/CN=Configuration,DC=bluetail,DC=com"]]}} 8> rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/test/0000755000177700017770000000000012633765070024312 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/test/bluetail.ldif0000644000177700017770000000050212633765070026750 0ustar michaelmichaeldn: dc=bluetail, dc=com objectclass: dcObject dc: bluetail dn: o=Bluetail AB, dc=bluetail, dc=com objectclass: organization o: Bluetail AB street: St.Eriksgatan 44 postalCode: 112 34 dn: ou=people, o=Bluetail AB, dc=bluetail, dc=com objectclass: organizationalUnit ou: people description: People working at Bluetail rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/test/README.test0000644000177700017770000000523212633765070026152 0ustar michaelmichael%%% $Id$ %%% -------------------------------------------------------------------- %%% Init setup %%% -------------------------------------------------------------------- I set up the OpenLDAP (2.0.6) server using the following /usr/local/etc/openldap/slapd.conf file: include /usr/local/etc/openldap/schema/core.schema pidfile /var/run/slapd.pid argsfile /var/run/slapd.args database ldbm suffix "dc=bluetail, dc=com" rootdn "dc=bluetail, dc=com" rootpw hejsan directory /usr/local/var/openldap-ldbm index objectClass eq %%% I started it on the console with some debug output: /usr/local/libexec/slapd -d 255 -f /usr/local/etc/openldap/slapd.conf %%% Then I defined the following data in: bluetail.ldif dn: dc=bluetail, dc=com objectclass: organization objectclass: dcObject dc: bluetail o: Bluetail AB %%% and in: tobbe.ldif dn: cn=Torbjorn Tornkvist, dc=bluetail, dc=com objectclass: person cn: Torbjorn Tornkvist sn: Tornkvist %%% I load the data with: ldapadd -D "dc=bluetail, dc=com" -w hejsan < bluetail.ldif ldapadd -D "dc=bluetail, dc=com" -w hejsan < people.ldif %%%% To search from a Unix shell: ldapsearch -L -b "dc=bluetail, dc=com" -w hejsan "(objectclass=*)" ldapsearch -L -b "dc=bluetail, dc=com" -w hejsan "cn=Torbjorn Tornkvist" ldapsearch -L -b "dc=bluetail, dc=com" -w hejsan "cn=Torb*kvist" %%% -------------------------------------------------------------------- %%% Example with certificateRevocationList %%% -------------------------------------------------------------------- %%% Using two ldif files: %%% post_danmark.ldif dn: o=Post Danmark, c=DK objectclass: country objectclass: organization c: DK o: Post Danmark %%% crl.ldif dn: cn=Administrative CA, o=Post Danmark, c=DK objectclass: cRLDistributionPoint cn: Administrative CA certificateRevocationList;binary:< file:/home/tobbe/erlang/eldap/server1.crl %%% Note the definition of the CRL file !! %%% To add the difinitions ldapadd -D "o=Post Danmark, c=DK" -w hejsan < post_danmark.ldif ldapadd -D "o=Post Danmark, c=DK" -w hejsan < crl.ldif %%% And to retreive the CRL ldapsearch -L -b "o=Post Danmark, c=DK" -w hejsan "(objectclass=*)" ldapsearch -L -b "o=Post Danmark, c=DK" -w hejsan "(cn=Administrative CA)" \ certificateRevocationList ### Put the retrieved binary in a file (tmp) with ### the following header and footer -----BEGIN X509 CRL----- <...binary....> -----END X509 CRL----- ### To verify it with openssl openssl crl -inform PEM -in tmp -text ldapsearch -L -D "cn=Torbjorn Tornkvist,o=Post Danmark,c=DK" -b "o=Post Danmark, c=DK" -w qwe123 "(cn=Torbjorn Tornkvist)" cn rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/test/post_danmark.ldif0000644000177700017770000000013512633765070027633 0ustar michaelmichaeldn: o=Post Danmark,c=DK objectclass: country objectclass: organization c: DK o: Post Danmark rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/test/ldap.rc0000644000177700017770000000406212633765070025562 0ustar michaelmichael#!/bin/sh # # ldap This shell script takes care of starting and stopping # ldap servers (slapd and slurpd). # # chkconfig: - 39 61 # description: LDAP stands for Lightweight Directory Access Protocol, used \ # for implementing the industry standard directory services. # processname: slapd # config: /etc/openldap/slapd.conf # pidfile: /var/run/slapd.pid # Source function library. . /etc/init.d/functions # Source networking configuration and check that networking is up. if [ -r /etc/sysconfig/network ] ; then . /etc/sysconfig/network [ ${NETWORKING} = "no" ] && exit 0 fi slapd=/usr/sbin/slapd slurpd=/usr/sbin/slurpd [ -x ${slapd} ] || exit 0 [ -x ${slurpd} ] || exit 0 RETVAL=0 function start() { # Start daemons. echo -n "Starting slapd:" daemon ${slapd} RETVAL=$? echo if [ $RETVAL -eq 0 ]; then if grep -q "^replogfile" /etc/openldap/slapd.conf; then echo -n "Starting slurpd:" daemon ${slurpd} RETVAL=$? echo fi fi [ $RETVAL -eq 0 ] && touch /var/lock/subsys/ldap return $RETVAL } function stop() { # Stop daemons. echo -n "Shutting down ldap: " killproc ${slapd} RETVAL=$? if [ $RETVAL -eq 0 ]; then if grep -q "^replogfile" /etc/openldap/slapd.conf; then killproc ${slurpd} RETVAL=$? fi fi echo [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/ldap /var/run/slapd.args return $RETVAL } # See how we were called. case "$1" in start) start ;; stop) stop ;; status) status ${slapd} if grep -q "^replogfile" /etc/openldap/slapd.conf ; then status ${slurpd} fi ;; restart) stop start ;; reload) killall -HUP ${slapd} RETVAL=$? if [ $RETVAL -eq 0 ]; then if grep -q "^replogfile" /etc/openldap/slapd.conf; then killall -HUP ${slurpd} RETVAL=$? fi fi ;; condrestart) if [ -f /var/lock/subsys/ldap ] ; then stop start fi ;; *) echo "Usage: $0 start|stop|restart|status|condrestart}" RETVAL=1 esac exit $RETVAL rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/test/tobbe.ldif0000644000177700017770000000017512633765070026250 0ustar michaelmichaeldn: cn=Torbjorn Tornkvist,o=Post Danmark,c=DK objectclass: person cn: Torbjorn Tornkvist sn: Tornkvist userPassword: qwe123 rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/test/slapd.conf0000644000177700017770000000257012633765070026270 0ustar michaelmichael# $OpenLDAP: pkg/ldap/servers/slapd/slapd.conf,v 1.8.8.4 2000/08/26 17:06:18 kurt Exp $ # # See slapd.conf(5) for details on configuration options. # This file should NOT be world readable. # include /usr/etc/openldap/schema/core.schema # Define global ACLs to disable default read access. # Do not enable referrals until AFTER you have a working directory # service AND an understanding of referrals. #referral ldap://root.openldap.org pidfile /var/run/slapd.pid argsfile /var/run/slapd.args # Load dynamic backend modules: # modulepath /usr/libexec/openldap # moduleload back_ldap.la # moduleload back_ldbm.la # moduleload back_passwd.la # moduleload back_shell.la ####################################################################### # ldbm database definitions ####################################################################### database ldbm suffix "dc=bluetail, dc=com" #suffix "o=My Organization Name, c=US" rootdn "dc=bluetail, dc=com" #rootdn "cn=Manager, o=My Organization Name, c=US" # Cleartext passwords, especially for the rootdn, should # be avoid. See slappasswd(8) and slapd.conf(5) for details. # Use of strong authentication encouraged. rootpw hejsan # The database directory MUST exist prior to running slapd AND # should only be accessable by the slapd/tools. Mode 700 recommended. directory /usr/var/openldap-ldbm # Indices to maintain index objectClass eq rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/test/server1.crl0000644000177700017770000013374312633765070026416 0ustar michaelmichael0‚·ß0‚·H0  *†H†÷ 0Ã1 0 UUS10U  Entrust.net1;09U 2www.entrust.net/CPS incorp. by ref. (limits liab.)1%0#U (c) 1999 Entrust.net Limited1:08U1Entrust.net Secure Server Certification Authority 011114143859Z 011115143859Z0‚¶0#7JÒM 990525175538Z0 0 U 0#7JÒO 990525175716Z0 0 U 0#7JÒL 990525175812Z0 0 U 0#7JÓ« 990820202820Z0 0 U 0#7JÓª 990820202856Z0 0 U 0#7JÚ¡ 000131164211Z0 0 U 0#7JÚÙ 000131165325Z0 0 U 0#7JÚÜ 000131165447Z0 0 U 0#7JÝ 000203154145Z0 0 U 0#7JÚÍ 000210135059Z0 0 U 0#7JÚ› 000210135129Z0 0 U 0#7JÛQ 000302183659Z0 0 U 0#7Jݧ 000302183721Z0 0 U 0#7Jà! 000302183811Z0 0 U 0#7Jâ! 000309165548Z0 0 U 0#7Jä} 000403203708Z0 0 U 0#7Jຠ000413144803Z0 0 U 0#7Jå[ 000516175008Z0 0 U 0#7Jå^ 000516175034Z0 0 U 0#7JåX 000516175057Z0 0 U 0#7JäW 000516175130Z0 0 U 0#7Jä” 000516175201Z0 0 U 0#7JäT 000516175229Z0 0 U 0#7Jä€ 000516175300Z0 0 U 0#7JêE 000605185104Z0 0 U 0#7Jèa 000606152333Z0 0 U 0#7Jå‘ 000621195324Z0 0 U 0#7Jëi 000628184236Z0 0 U 0#7Jî™ 000714143308Z0 0 U 0#7Jî9 000804144912Z0 0 U 0#7Jêˆ 000817201522Z0 0 U 0#7Jï¸ 000821194130Z0 0 U 0#7Jñ¾ 000823200341Z0 0 U 0#7Jóu 000828204916Z0 0 U 0#7Jò² 000829142007Z0 0 U 0#7Jó· 000908175148Z0 0 U 0#7Jò© 000911194727Z0 0 U 0#7Jì 000913165543Z0 0 U 0#7Jî 000914204008Z0 0 U 0#7Jìk 000919140611Z0 0 U 0#7Jã‹ 000919140710Z0 0 U 0#7Jõ¸ 000919140825Z0 0 U 0#7Jõû 000919141005Z0 0 U 0#7JöJ 000922210539Z0 0 U 0#7Jó´ 000925163347Z0 0 U 0#7JõA 000926145959Z0 0 U 0#7JÓ¢ 001002175014Z0 0 U 0#7JÒ[ 001002175053Z0 0 U 0#7Jê‹ 001003134606Z0 0 U 0#7JÓ` 001003171558Z0 0 U 0#7JÒf 001003171650Z0 0 U 0#7JÒW 001003171742Z0 0 U 0#7JÒV 001003171819Z0 0 U 0#7Jïû 001003171931Z0 0 U 0#7Jïú 001003172018Z0 0 U 0#7Jùf 001011154910Z0 0 U 0#7Jùc 001011155023Z0 0 U 0#7Jú 001017125243Z0 0 U 0#7Jø 001017131240Z0 0 U 0#7JúG 001019165221Z0 0 U 0#7JûC 001019174947Z0 0 U 0#7Jû  001019204503Z0 0 U 0#7Jû 001019204529Z0 0 U 0#7Jû  001019204712Z0 0 U 0#7JûÖ 001020153727Z0 0 U 0#7Júî 001020234322Z0 0 U 0#7Júñ 001020234409Z0 0 U 0#7Júë 001020234505Z0 0 U 0#7Júè 001020234602Z0 0 U 0#7JëÊ 001023190656Z0 0 U 0#7JëR 001023191001Z0 0 U 0#7Jìn 001023191510Z0 0 U 0#7Jì6 001025123200Z0 0 U 0#7Jì  001025123251Z0 0 U 0#7Jìz 001025123343Z0 0 U 0#7Jì} 001025123429Z0 0 U 0#7JôÊ 001025123521Z0 0 U 0#7JôÍ 001025123610Z0 0 U 0#7Jü 001025182238Z0 0 U 0#7Jù¡ 001026180638Z0 0 U 0#7Jùž 001026180702Z0 0 U 0#7Jüª 001026204259Z0 0 U 0#7Jü§ 001026204339Z0 0 U 0#7Jüc 001027144520Z0 0 U 0#7Jüß 001030181704Z0 0 U 0#7Jý¬ 001102150821Z0 0 U 0#7Jþ 001103170909Z0 0 U 0#7Jþz 001107190213Z0 0 U 0#7Jþ4 001107190323Z0 0 U 0#7Jý[ 001108215744Z0 0 U 0#7JýX 001108215825Z0 0 U 0#7JýU 001108215908Z0 0 U 0#7JýR 001108215941Z0 0 U 0#7JýO 001108220024Z0 0 U 0#7JýL 001108220111Z0 0 U 0#7Jÿ  001109182918Z0 0 U 0#7Jýõ 001110182414Z0 0 U 0#7Jÿˆ 001113165037Z0 0 U 0#7Jÿ… 001113165052Z0 0 U 0#7Jÿ‚ 001113165201Z0 0 U 0#7Jþ˜ 001113185600Z0 0 U 0#7Jÿ 001114181854Z0 0 U 0#7Jÿk 001114181943Z0 0 U 0#7Jþƒ 001115151312Z0 0 U 0#7Jÿ 001115151353Z0 0 U 0#7Jþ¼ 001115151539Z0 0 U 0#7JþÖ 001116212153Z0 0 U 0#7JÿM 001117190830Z0 0 U 0#7JýÕ 001120145654Z0 0 U 0#7Jÿ, 001120145709Z0 0 U 0#7KÒ 001120173733Z0 0 U 0#7KØ 001120175358Z0 0 U 0#7Jÿ· 001120180522Z0 0 U 0#7Kj 001120184830Z0 0 U 0#7Jÿ´ 001120184928Z0 0 U 0#7K 001121212919Z0 0 U 0#7K 001121212958Z0 0 U 0#7K 001122142151Z0 0 U 0#7K 001122142228Z0 0 U 0#7K~ 001127204930Z0 0 U 0#7K* 001129143719Z0 0 U 0#7Jÿ£ 001129180550Z0 0 U 0#7Jÿ¦ 001129180614Z0 0 U 0#7K¿ 001130182111Z0 0 U 0#7Km 001204172750Z0 0 U 0#7K 001204200728Z0 0 U 0#7K„ 001205215948Z0 0 U 0#7K„ 001206212945Z0 0 U 0#7K 001207195836Z0 0 U 0#7K¿ 001211221342Z0 0 U 0#7K– 001212210045Z0 0 U 0#7JøS 001213155452Z0 0 U 0#7JøY 001213155532Z0 0 U 0#7JøV 001213155602Z0 0 U 0#7Ka 001213192537Z0 0 U 0#7K^ 001214175644Z0 0 U 0#7KS 001215200242Z0 0 U 0#7K} 001218174840Z0 0 U 0#7Ks 001218182420Z0 0 U 0#7Kš 001218221842Z0 0 U 0#7Kõ 001218222114Z0 0 U 0#7K— 001219143811Z0 0 U 0#7KY 001219154900Z0 0 U 0#7K6 001219185239Z0 0 U 0#7Kø 001219211710Z0 0 U 0#7K  001221174122Z0 0 U 0#7K¢ 001221191428Z0 0 U 0#7Kœ 001221195025Z0 0 U 0#7K™ 001221195038Z0 0 U 0#7K– 001221195049Z0 0 U 0#7K 001221211110Z0 0 U 0#7KŸ 001222145818Z0 0 U 0#7K_ 001222205456Z0 0 U 0#7K 010102142224Z0 0 U 0#7K‚ 010102175728Z0 0 U 0#7Kè 010102175906Z0 0 U 0#7KH 010103143850Z0 0 U 0#7K« 010103163513Z0 0 U 0#7KQ 010104191220Z0 0 U 0#7K¥ 010104222152Z0 0 U 0#7K‡ 010105185403Z0 0 U 0#7K€ 010105185646Z0 0 U 0#7Jÿ½ 010108134620Z0 0 U 0#7K» 010108163445Z0 0 U 0#7K< 010108194952Z0 0 U 0#7Ke 010108195407Z0 0 U 0#7K• 010108195633Z0 0 U 0#7K # 010108221600Z0 0 U 0#7Kw 010109144246Z0 0 U 0#7Kt 010109144420Z0 0 U 0#7K - 010109170529Z0 0 U 0#7K 0 010110184321Z0 0 U 0#7K ‚ 010110215800Z0 0 U 0#7KÇ 010110220200Z0 0 U 0#7Kß 010112164030Z0 0 U 0#7K  010112205539Z0 0 U 0#7K * 010113003258Z0 0 U 0#7K … 010115215616Z0 0 U 0#7K Ý 010115235140Z0 0 U 0#7K - 010116230321Z0 0 U 0#7K  010116230544Z0 0 U 0#7K 4 010116230604Z0 0 U 0#7K  010117150349Z0 0 U 0#7K ì 010117171904Z0 0 U 0#7K õ 010117203646Z0 0 U 0#7K  010118182156Z0 0 U 0#7K " 010118222646Z0 0 U 0#7Kd 010119154300Z0 0 U 0#7K ‰ 010119155929Z0 0 U 0#7K À 010119160606Z0 0 U 0#7K < 010119162936Z0 0 U 0#7K ½ 010119193506Z0 0 U 0#7K º 010119193629Z0 0 U 0#7K · 010119193800Z0 0 U 0#7K ´ 010119232357Z0 0 U 0#7K ¬ 010122194405Z0 0 U 0#7K ? 010122210816Z0 0 U 0#7K å 010123183746Z0 0 U 0#7Jõþ 010124000609Z0 0 U 0#7K ö 010124150400Z0 0 U 0#7K Ú 010124163613Z0 0 U 0#7K0 010124175955Z0 0 U 0#7K ` 010124221245Z0 0 U 0#7Kv 010125151717Z0 0 U 0#7Jþ 010125151806Z0 0 U 0#7K › 010125183826Z0 0 U 0#7K › 010125225116Z0 0 U 0#7K : 010126151123Z0 0 U 0#7K 4 010129204047Z0 0 U 0#7K E 010130204936Z0 0 U 0#7K H 010130205121Z0 0 U 0#7K\ 010131185121Z0 0 U 0#7K o 010131212700Z0 0 U 0#7K Œ 010201210454Z0 0 U 0#7K ˜ 010201220520Z0 0 U 0#7K ( 010202002205Z0 0 U 0#7K á 010202151733Z0 0 U 0#7K › 010202181547Z0 0 U 0#7K x 010202211248Z0 0 U 0#7K: 010202231940Z0 0 U 0#7K7 010202232131Z0 0 U 0#7K  010205165918Z0 0 U 0#7K 010205170243Z0 0 U 0#7K" 010205191001Z0 0 U 0#7K< 010205210210Z0 0 U 0#7Jþ 010207161029Z0 0 U 0#7JþÅ 010207161152Z0 0 U 0#7JþÈ 010207164707Z0 0 U 0#7JþÑ 010207181925Z0 0 U 0#7K l 010208125710Z0 0 U 0#7K ¦ 010208125812Z0 0 U 0#7K9 010208202144Z0 0 U 0#7Kû 010209005120Z0 0 U 0#7K 010209174816Z0 0 U 0#7K 010209192902Z0 0 U 0#7K] 010209233452Z0 0 U 0#7Kƒ 010210180910Z0 0 U 0#7K3 010212171542Z0 0 U 0#7K T 010212184042Z0 0 U 0#7K­ 010212184320Z0 0 U 0#7Jÿ  010212200425Z0 0 U 0#7Kÿ 010213174207Z0 0 U 0#7K ¼ 010213234039Z0 0 U 0#7K ¹ 010213234143Z0 0 U 0#7K ¶ 010213234227Z0 0 U 0#7K ³ 010213234331Z0 0 U 0#7KT 010214145003Z0 0 U 0#7K H 010214154218Z0 0 U 0#7K Ë 010214185710Z0 0 U 0#7K" 010214205834Z0 0 U 0#7K0 010214215921Z0 0 U 0#7Jÿ_ 010214220009Z0 0 U 0#7Jö· 010214220251Z0 0 U 0#7Kc 010215135255Z0 0 U 0#7K1 010215174952Z0 0 U 0#7KÈ 010216165139Z0 0 U 0#7KH 010216165228Z0 0 U 0#7K| 010216215115Z0 0 U 0#7KE 010216224324Z0 0 U 0#7KB 010216224446Z0 0 U 0#7KK 010216224603Z0 0 U 0#7KQ 010216224654Z0 0 U 0#7KN 010216224748Z0 0 U 0#7K \ 010219171329Z0 0 U 0#7K© 010221153039Z0 0 U 0#7K' 010221205736Z0 0 U 0#7K{ 010221210223Z0 0 U 0#7K 010221210310Z0 0 U 0#7Kw 010222180610Z0 0 U 0#7Kç 010223145845Z0 0 U 0#7Kœ 010223183226Z0 0 U 0#7K$ 010226172425Z0 0 U 0#7K ¯ 010226172822Z0 0 U 0#7K œ 010226172854Z0 0 U 0#7JùŒ 010226172959Z0 0 U 0#7K– 010227131412Z0 0 U 0#7K÷ 010228130544Z0 0 U 0#7Kv 010228181420Z0 0 U 0#7K0 010301150144Z0 0 U 0#7Kô 010302143812Z0 0 U 0#7Kñ 010302143928Z0 0 U 0#7Kî 010302144055Z0 0 U 0#7Kë 010302144145Z0 0 U 0#7Kè 010302144233Z0 0 U 0#7KÎ 010302150350Z0 0 U 0#7K× 010302150504Z0 0 U 0#7K + 010302153526Z0 0 U 0#7K ¡ 010302173905Z0 0 U 0#7K× 010302191808Z0 0 U 0#7K û 010302192240Z0 0 U 0#7K: 010302192354Z0 0 U 0#7K­ 010302200834Z0 0 U 0#7K † 010305183746Z0 0 U 0#7K ƒ 010305183831Z0 0 U 0#7Ko 010305184247Z0 0 U 0#7K 1 010305184419Z0 0 U 0#7K[ 010305202137Z0 0 U 0#7KX 010305202240Z0 0 U 0#7Kß 010305232715Z0 0 U 0#7KÌ 010306213746Z0 0 U 0#7Kå 010307185616Z0 0 U 0#7K 010308020003Z0 0 U 0#7Km 010308182243Z0 0 U 0#7Kj 010308182333Z0 0 U 0#7KÕ 010308214910Z0 0 U 0#7Ké 010309130635Z0 0 U 0#7Kõ 010309130652Z0 0 U 0#7KL 010309172620Z0 0 U 0#7K¶ 010309173204Z0 0 U 0#7KZ 010309203234Z0 0 U 0#7Kk 010310001657Z0 0 U 0#7K¨ 010312190022Z0 0 U 0#7Kï 010312234807Z0 0 U 0#7K ¾ 010313181851Z0 0 U 0#7K© 010314193613Z0 0 U 0#7KË 010314205700Z0 0 U 0#7K * 010315003948Z0 0 U 0#7Kf 010315161055Z0 0 U 0#7Kq 010315181200Z0 0 U 0#7K† 010315220244Z0 0 U 0#7Ke 010315231343Z0 0 U 0#7K£ 010316163521Z0 0 U 0#7Kt 010316195249Z0 0 U 0#7K› 010316195417Z0 0 U 0#7K 010316233543Z0 0 U 0#7K 010316233559Z0 0 U 0#7K  010316233742Z0 0 U 0#7K 010316233843Z0 0 U 0#7K 010316233954Z0 0 U 0#7K ý 010320135055Z0 0 U 0#7K  010320135200Z0 0 U 0#7K3 010320160955Z0 0 U 0#7Kß 010320211935Z0 0 U 0#7K© 010320215716Z0 0 U 0#7K­ 010321141538Z0 0 U 0#7K£ 010321154330Z0 0 U 0#7KÒ 010321181655Z0 0 U 0#7KÖ 010322002838Z0 0 U 0#7Kó 010322145246Z0 0 U 0#7K‰ 010322202519Z0 0 U 0#7KÜ 010323010657Z0 0 U 0#7Kß 010323010722Z0 0 U 0#7Ka 010323131943Z0 0 U 0#7Kï 010323182011Z0 0 U 0#7Kó 010323182100Z0 0 U 0#7K> 010323190045Z0 0 U 0#7K; 010323190157Z0 0 U 0#7Kä 010323220414Z0 0 U 0#7K† 010323220521Z0 0 U 0#7K 010326155439Z0 0 U 0#7Kç 010326175648Z0 0 U 0#7K˜ 010326192155Z0 0 U 0#7KK 010326212156Z0 0 U 0#7Kq 010326212355Z0 0 U 0#7Km 010327131619Z0 0 U 0#7K€ 010327201604Z0 0 U 0#7KÇ 010328203741Z0 0 U 0#7K“ 010328222245Z0 0 U 0#7KR 010329213247Z0 0 U 0#7K# 010330131120Z0 0 U 0#7Ké 010330182308Z0 0 U 0#7KÊ 010330205006Z0 0 U 0#7K² 010402121341Z0 0 U 0#7K  010402121746Z0 0 U 0#7K Á 010402142809Z0 0 U 0#7K Ä 010402142830Z0 0 U 0#7K a 010402160457Z0 0 U 0#7K ô 010402160758Z0 0 U 0#7K  010403200510Z0 0 U 0#7Jýä 010403204746Z0 0 U 0#7KB 010403221950Z0 0 U 0#7K!ž 010404122511Z0 0 U 0#7K” 010404151014Z0 0 U 0#7Kƒ 010404164735Z0 0 U 0#7K¸ 010404164956Z0 0 U 0#7K‘ 010404165245Z0 0 U 0#7K!â 010404184522Z0 0 U 0#7K!+ 010404234348Z0 0 U 0#7K!² 010405183558Z0 0 U 0#7K' 010405183721Z0 0 U 0#7K Ê 010405212209Z0 0 U 0#7K" 010406140528Z0 0 U 0#7KQ 010406150840Z0 0 U 0#7K"À 010406151005Z0 0 U 0#7K P 010406173336Z0 0 U 0#7K#I 010406194144Z0 0 U 0#7K"Æ 010406233938Z0 0 U 0#7K"É 010406234205Z0 0 U 0#7K#À 010409205446Z0 0 U 0#7K#Æ 010409205550Z0 0 U 0#7Kf 010409205710Z0 0 U 0#7Kc 010409205746Z0 0 U 0#7K"M 010409213919Z0 0 U 0#7K#õ 010410120938Z0 0 U 0#7K#ø 010410121014Z0 0 U 0#7K$l 010410175907Z0 0 U 0#7K$i 010410180025Z0 0 U 0#7KŠ 010410205937Z0 0 U 0#7Kê 010410210004Z0 0 U 0#7K$„ 010410221911Z0 0 U 0#7K j 010410222032Z0 0 U 0#7K$® 010410233423Z0 0 U 0#7K#+ 010411131754Z0 0 U 0#7K"_ 010411174525Z0 0 U 0#7K"\ 010411204043Z0 0 U 0#7K"Y 010411204213Z0 0 U 0#7K#| 010412120844Z0 0 U 0#7K ‚ 010412145750Z0 0 U 0#7K  010412174404Z0 0 U 0#7K$ó 010412180422Z0 0 U 0#7K#Û 010412180816Z0 0 U 0#7K#á 010412180834Z0 0 U 0#7K  010412202242Z0 0 U 0#7K$  010412202419Z0 0 U 0#7K$¢ 010416172608Z0 0 U 0#7Kœ 010416184300Z0 0 U 0#7K&" 010416234849Z0 0 U 0#7K!¡ 010417195237Z0 0 U 0#7K" 010417234149Z0 0 U 0#7Kí 010418144627Z0 0 U 0#7K# 010419121421Z0 0 U 0#7K¯ 010419151127Z0 0 U 0#7K!å 010419191117Z0 0 U 0#7K&6 010420121431Z0 0 U 0#7K( 010423123708Z0 0 U 0#7K'  010423173654Z0 0 U 0#7Kô 010423173912Z0 0 U 0#7K'‹ 010423185744Z0 0 U 0#7K d 010423190008Z0 0 U 0#7K$Æ 010423190111Z0 0 U 0#7K( 010423192054Z0 0 U 0#7K› 010423220548Z0 0 U 0#7K# 010423220709Z0 0 U 0#7K% 010423220756Z0 0 U 0#7K$$ 010424193722Z0 0 U 0#7K'é 010424194103Z0 0 U 0#7K} 010424194541Z0 0 U 0#7K€ 010424194616Z0 0 U 0#7K# 010424224443Z0 0 U 0#7K$¨ 010424224659Z0 0 U 0#7K" 010424224839Z0 0 U 0#7K( 010425195817Z0 0 U 0#7K(Ý 010425205049Z0 0 U 0#7K#= 010425224243Z0 0 U 0#7K$Ø 010426113348Z0 0 U 0#7K) 010426165610Z0 0 U 0#7K) 010426185924Z0 0 U 0#7K\ 010426213507Z0 0 U 0#7Ké 010427143635Z0 0 U 0#7K å 010427154208Z0 0 U 0#7K(X 010427173431Z0 0 U 0#7K%‚ 010427181921Z0 0 U 0#7K è 010427183240Z0 0 U 0#7K)Ð 010427200830Z0 0 U 0#7K) 010430142506Z0 0 U 0#7K 010430142705Z0 0 U 0#7K#1 010430170121Z0 0 U 0#7K Ž 010430194844Z0 0 U 0#7K O 010501225622Z0 0 U 0#7K*: 010502171144Z0 0 U 0#7K*Ý 010502171746Z0 0 U 0#7K+5 010502180002Z0 0 U 0#7K+ï 010503123518Z0 0 U 0#7K+Ä 010503200731Z0 0 U 0#7K+w 010503231253Z0 0 U 0#7K%% 010504124246Z0 0 U 0#7K] 010504152402Z0 0 U 0#7K+à 010504152640Z0 0 U 0#7K,I 010504160044Z0 0 U 0#7K* 010504193150Z0 0 U 0#7K,Û 010507173959Z0 0 U 0#7K+¾ 010507174119Z0 0 U 0#7K,f 010507230008Z0 0 U 0#7K,Ï 010509162653Z0 0 U 0#7K. 010509204622Z0 0 U 0#7K)… 010510205854Z0 0 U 0#7K.Ñ 010510235431Z0 0 U 0#7K)ö 010511121927Z0 0 U 0#7K.È 010511160910Z0 0 U 0#7K/9 010511161037Z0 0 U 0#7K/< 010511161052Z0 0 U 0#7K/? 010511165603Z0 0 U 0#7K˜ 010511182418Z0 0 U 0#7K(L 010511212123Z0 0 U 0#7K*@ 010514233946Z0 0 U 0#7K+  010515125127Z0 0 U 0#7K/i 010515144435Z0 0 U 0#7K.¿ 010515144713Z0 0 U 0#7K. 010515144732Z0 0 U 0#7Jêã 010515145000Z0 0 U 0#7K-g 010515190701Z0 0 U 0#7K0_ 010515204230Z0 0 U 0#7K0, 010515204426Z0 0 U 0#7K0A 010515234818Z0 0 U 0#7K Ú 010515234933Z0 0 U 0#7K ­ 010516144425Z0 0 U 0#7K. 010516201034Z0 0 U 0#7K+ø 010516225431Z0 0 U 0#7K. 010516233903Z0 0 U 0#7K#X 010516234006Z0 0 U 0#7JðG 010516235558Z0 0 U 0#7K0‰ 010517114944Z0 0 U 0#7K' 010517115245Z0 0 U 0#7K,ö 010517131045Z0 0 U 0#7K,ù 010517131134Z0 0 U 0#7K0P 010517152646Z0 0 U 0#7K+ 010517153136Z0 0 U 0#7K+ì 010517153259Z0 0 U 0#7K-d 010517153412Z0 0 U 0#7K! 010517184834Z0 0 U 0#7K1m 010517200849Z0 0 U 0#7K 010517201135Z0 0 U 0#7K( 010517234200Z0 0 U 0#7K% 010517234234Z0 0 U 0#7K  010517234308Z0 0 U 0#7K æ 010517234359Z0 0 U 0#7K ã 010517234429Z0 0 U 0#7K1; 010518134308Z0 0 U 0#7K.  010518134530Z0 0 U 0#7K1s 010518142046Z0 0 U 0#7K) 010518164414Z0 0 U 0#7K0Í 010518165017Z0 0 U 0#7K1û 010518225042Z0 0 U 0#7K1® 010522121913Z0 0 U 0#7K(I 010522122615Z0 0 U 0#7K+— 010522122943Z0 0 U 0#7K+Õ 010522123216Z0 0 U 0#7K1ê 010522151010Z0 0 U 0#7K-m 010522165110Z0 0 U 0#7K/0 010522165209Z0 0 U 0#7K/3 010522165317Z0 0 U 0#7K,½ 010522165531Z0 0 U 0#7K,À 010522165654Z0 0 U 0#7K,à 010522165838Z0 0 U 0#7K2ó 010522213313Z0 0 U 0#7K2 010523115147Z0 0 U 0#7K1¢ 010523115309Z0 0 U 0#7K2´ 010523140723Z0 0 U 0#7K1ˆ 010523140851Z0 0 U 0#7K$™ 010523152737Z0 0 U 0#7K0» 010523171822Z0 0 U 0#7K2Õ 010523171923Z0 0 U 0#7K$ 010523203647Z0 0 U 0#7K$ 010523203818Z0 0 U 0#7K2 010524153036Z0 0 U 0#7K-‡ 010524195909Z0 0 U 0#7K/Œ 010524215135Z0 0 U 0#7K0¬ 010525120534Z0 0 U 0#7K1) 010525153932Z0 0 U 0#7K*´ 010528115226Z0 0 U 0#7K3† 010528171347Z0 0 U 0#7K* 010528204329Z0 0 U 0#7K0  010528220237Z0 0 U 0#7K1F 010528220756Z0 0 U 0#7K2™ 010529160904Z0 0 U 0#7K4G 010529200228Z0 0 U 0#7K4‚ 010529200623Z0 0 U 0#7K4… 010529200652Z0 0 U 0#7K4õ 010529214529Z0 0 U 0#7K3î 010529214730Z0 0 U 0#7K4¡ 010530121027Z0 0 U 0#7K0# 010530130342Z0 0 U 0#7K5s 010530145703Z0 0 U 0#7K'” 010530145926Z0 0 U 0#7K&­ 010530145949Z0 0 U 0#7K&° 010530150025Z0 0 U 0#7K'‘ 010530150050Z0 0 U 0#7K @ 010530172628Z0 0 U 0#7K5W 010530185949Z0 0 U 0#7K5f 010530190710Z0 0 U 0#7K-r 010531113954Z0 0 U 0#7K4ª 010531125815Z0 0 U 0#7K6q 010531144535Z0 0 U 0#7K+õ 010531162013Z0 0 U 0#7K0Ä 010531194552Z0 0 U 0#7K6à 010601114309Z0 0 U 0#7K+t 010601121431Z0 0 U 0#7K75 010601184539Z0 0 U 0#7K-ø 010601184927Z0 0 U 0#7K6› 010604142919Z0 0 U 0#7K,Õ 010604143043Z0 0 U 0#7K3ô 010604143158Z0 0 U 0#7K0¡ 010604180916Z0 0 U 0#7K5 010604181306Z0 0 U 0#7K7b 010604201435Z0 0 U 0#7K6 010604201611Z0 0 U 0#7K6° 010604201806Z0 0 U 0#7K7’ 010604233026Z0 0 U 0#7K7¦ 010604233226Z0 0 U 0#7Kâ 010605184233Z0 0 U 0#7K8 010606185244Z0 0 U 0#7K5› 010607161118Z0 0 U 0#7K3ú 010607161436Z0 0 U 0#7K5x 010607183420Z0 0 U 0#7K+ò 010607183658Z0 0 U 0#7K3w 010607220701Z0 0 U 0#7K8Ï 010607235259Z0 0 U 0#7K8Ì 010607235328Z0 0 U 0#7K8É 010607235407Z0 0 U 0#7K8¥ 010608124000Z0 0 U 0#7K9 010608124127Z0 0 U 0#7K87 010608170528Z0 0 U 0#7K8: 010608170542Z0 0 U 0#7K81 010608170604Z0 0 U 0#7K8 010608170645Z0 0 U 0#7K84 010608170701Z0 0 U 0#7K"˜ 010608193419Z0 0 U 0#7K9 010608193659Z0 0 U 0#7KŒ 010608234151Z0 0 U 0#7K2i 010611171629Z0 0 U 0#7K6¹ 010611192107Z0 0 U 0#7K6¼ 010611192226Z0 0 U 0#7K4[ 010611210317Z0 0 U 0#7K/¶ 010611224119Z0 0 U 0#7K/­ 010611224141Z0 0 U 0#7K9= 010611224330Z0 0 U 0#7K:2 010612143058Z0 0 U 0#7K:5 010612143330Z0 0 U 0#7K:P 010612201543Z0 0 U 0#7K72 010612201714Z0 0 U 0#7K6Ý 010613152642Z0 0 U 0#7K ˆ 010613183150Z0 0 U 0#7K2ÿ 010613183551Z0 0 U 0#7K9É 010613184114Z0 0 U 0#7K7} 010613191308Z0 0 U 0#7K` 010613233450Z0 0 U 0#7K,  010613233514Z0 0 U 0#7K7ã 010614131952Z0 0 U 0#7K:Á 010614132551Z0 0 U 0#7K&` 010614161452Z0 0 U 0#7K&] 010614161553Z0 0 U 0#7K:ë 010614161747Z0 0 U 0#7K8g 010614211116Z0 0 U 0#7K6- 010614233939Z0 0 U 0#7K6* 010614234000Z0 0 U 0#7K± 010615132811Z0 0 U 0#7K;_ 010615133509Z0 0 U 0#7K:å 010615165755Z0 0 U 0#7K9“ 010615214108Z0 0 U 0#7K6å 010618132105Z0 0 U 0#7K;Í 010618132301Z0 0 U 0#7K<9 010618132538Z0 0 U 0#7K;Á 010618133152Z0 0 U 0#7K2Ÿ 010618173319Z0 0 U 0#7Kn 010625190415Z0 0 U 0#7K9¢ 010625195608Z0 0 U 0#7K7 010625210601Z0 0 U 0#7K0> 010626155726Z0 0 U 0#7K/• 010626155815Z0 0 U 0#7K.ã 010626155859Z0 0 U 0#7K>Ë 010626160040Z0 0 U 0#7K 010628153454Z0 0 U 0#7K:¡ 010628191256Z0 0 U 0#7K@ 010628221803Z0 0 U 0#7K9d 010628230741Z0 0 U 0#7K@ 010629154151Z0 0 U 0#7K@k 010629154916Z0 0 U 0#7K1 010629192841Z0 0 U 0#7K@t 010629203212Z0 0 U 0#7K8¨ 010629203347Z0 0 U 0#7K;¼ 010629203620Z0 0 U 0#7K@­ 010629224114Z0 0 U 0#7K@H 010703114950Z0 0 U 0#7K=ó 010703115249Z0 0 U 0#7K94 010703115350Z0 0 U 0#7K9, 010703115420Z0 0 U 0#7K=á 010703161227Z0 0 U 0#7K@  010703161346Z0 0 U 0#7K;› 010704125730Z0 0 U 0#7KA\ 010704130950Z0 0 U 0#7K>8 010704222411Z0 0 U 0#7KAd 010705172010Z0 0 U 0#7K?A 010705180831Z0 0 U 0#7KA_ 010705231349Z0 0 U 0#7KB 010705231854Z0 0 U 0#7K>­ 010705232032Z0 0 U 0#7K@W 010705232300Z0 0 U 0#7K@° 010706135718Z0 0 U 0#7K5¶ 010706194816Z0 0 U 0#7KB# 010709120525Z0 0 U 0#7KB 010709120626Z0 0 U 0#7KB 010709120708Z0 0 U 0#7KBv 010709150502Z0 0 U 0#7KBÖ 010709171534Z0 0 U 0#7K=Õ 010709171701Z0 0 U 0#7K8ð 010709221141Z0 0 U 0#7K:Í 010710142011Z0 0 U 0#7KBñ 010710142418Z0 0 U 0#7K?# 010710162942Z0 0 U 0#7K;z 010710202146Z0 0 U 0#7K;} 010710202216Z0 0 U 0#7K;w 010710202308Z0 0 U 0#7KB¬ 010710214305Z0 0 U 0#7KB© 010710214334Z0 0 U 0#7KB¦ 010710214356Z0 0 U 0#7KA 010711174336Z0 0 U 0#7K0Ö 010711174608Z0 0 U 0#7K0Ù 010711175950Z0 0 U 0#7KCœ 010711192513Z0 0 U 0#7KCŸ 010711192550Z0 0 U 0#7KC™ 010711192615Z0 0 U 0#7K?Ì 010712131202Z0 0 U 0#7KAº 010712160546Z0 0 U 0#7KA 010712160855Z0 0 U 0#7KBš 010712184813Z0 0 U 0#7K=2 010712184927Z0 0 U 0#7K ÿ 010712210059Z0 0 U 0#7K?r 010712210335Z0 0 U 0#7K$ 010713120812Z0 0 U 0#7KDÌ 010713180006Z0 0 U 0#7KDR 010713185937Z0 0 U 0#7KDs 010713190000Z0 0 U 0#7K:è 010716172147Z0 0 U 0#7KC9 010716172343Z0 0 U 0#7KC“ 010716221020Z0 0 U 0#7K(Î 010716233549Z0 0 U 0#7KP 010717185913Z0 0 U 0#7K8ä 010718131325Z0 0 U 0#7KF 010718171652Z0 0 U 0#7KF  010718174818Z0 0 U 0#7K0M 010718182355Z0 0 U 0#7KC  010718182637Z0 0 U 0#7KC/ 010718192621Z0 0 U 0#7KE[ 010719130442Z0 0 U 0#7KC 010719130853Z0 0 U 0#7K@ª 010719131145Z0 0 U 0#7KF¹ 010719170551Z0 0 U 0#7KF¼ 010719170653Z0 0 U 0#7K<¢ 010719171033Z0 0 U 0#7K:â 010719222043Z0 0 U 0#7K 010719231050Z0 0 U 0#7KC 010719231304Z0 0 U 0#7KG  010720143242Z0 0 U 0#7KGm 010720144259Z0 0 U 0#7KE% 010720221550Z0 0 U 0#7KF° 010723134211Z0 0 U 0#7KG" 010723160257Z0 0 U 0#7K=¾ 010723160446Z0 0 U 0#7K6­ 010723191330Z0 0 U 0#7K@â 010724122409Z0 0 U 0#7KEo 010724151803Z0 0 U 0#7KH– 010724153912Z0 0 U 0#7J⟠010724190519Z0 0 U 0#7KH² 010725181003Z0 0 U 0#7KH 010725181114Z0 0 U 0#7Kn 010725192352Z0 0 U 0#7KEƒ 010725192645Z0 0 U 0#7KI& 010725202817Z0 0 U 0#7KI  010726182034Z0 0 U 0#7KHð 010726182625Z0 0 U 0#7KI˜ 010727142911Z0 0 U 0#7KH 010727143604Z0 0 U 0#7KG 010727181014Z0 0 U 0#7KI› 010727181114Z0 0 U 0#7KHö 010730165817Z0 0 U 0#7K@• 010730170925Z0 0 U 0#7KIä 010730172750Z0 0 U 0#7KIð 010730172857Z0 0 U 0#7KJ 010730224935Z0 0 U 0#7KJ" 010730224959Z0 0 U 0#7KJ% 010730225020Z0 0 U 0#7KJ( 010730225038Z0 0 U 0#7KJ+ 010730225054Z0 0 U 0#7KIû 010730225335Z0 0 U 0#7KH¦ 010801115202Z0 0 U 0#7K+; 010801130604Z0 0 U 0#7KJñ 010801131004Z0 0 U 0#7KJî 010801131137Z0 0 U 0#7KJF 010801172548Z0 0 U 0#7K?d 010801184058Z0 0 U 0#7KIà 010801195011Z0 0 U 0#7KK² 010802152145Z0 0 U 0#7K?À 010802174929Z0 0 U 0#7KKH 010803114823Z0 0 U 0#7KL  010803152059Z0 0 U 0#7KI) 010803162446Z0 0 U 0#7KI‡ 010803180710Z0 0 U 0#7KJ” 010803180832Z0 0 U 0#7KI 010803181020Z0 0 U 0#7KKç 010803193540Z0 0 U 0#7KJä 010803193655Z0 0 U 0#7KJ7 010807120752Z0 0 U 0#7KH 010807122130Z0 0 U 0#7KLT 010807144953Z0 0 U 0#7KLQ 010807164749Z0 0 U 0#7KLf 010807170503Z0 0 U 0#7KL{ 010807192406Z0 0 U 0#7KKö 010807192515Z0 0 U 0#7KD™ 010807192621Z0 0 U 0#7KLõ 010807200441Z0 0 U 0#7KLè 010807234138Z0 0 U 0#7KJÉ 010807234259Z0 0 U 0#7K#U 010808121141Z0 0 U 0#7K3¯ 010808141323Z0 0 U 0#7KB— 010808141450Z0 0 U 0#7KBa 010808141621Z0 0 U 0#7KL 010808142003Z0 0 U 0#7KG 010808224144Z0 0 U 0#7KL] 010808224310Z0 0 U 0#7KL‡ 010808224409Z0 0 U 0#7KM 010808224458Z0 0 U 0#7KL¼ 010808224641Z0 0 U 0#7KK 010809141933Z0 0 U 0#7Kr 010809142206Z0 0 U 0#7K%= 010809155250Z0 0 U 0#7KM 010809184050Z0 0 U 0#7KMQ 010809184500Z0 0 U 0#7KBâ 010809203018Z0 0 U 0#7KN6 010809203334Z0 0 U 0#7KCÝ 010809221534Z0 0 U 0#7KD| 010810001710Z0 0 U 0#7KGÒ 010810002008Z0 0 U 0#7KGØ 010810002109Z0 0 U 0#7KGá 010810002249Z0 0 U 0#7K:G 010810002347Z0 0 U 0#7KL1 010810002447Z0 0 U 0#7KIµ 010810121405Z0 0 U 0#7KM‡ 010810160956Z0 0 U 0#7KL„ 010810161232Z0 0 U 0#7KN: 010810161527Z0 0 U 0#7KN² 010810212540Z0 0 U 0#7KN€ 010813133545Z0 0 U 0#7K 010813191529Z0 0 U 0#7KO} 010813223050Z0 0 U 0#7KOt 010813223141Z0 0 U 0#7KI@ 010814192844Z0 0 U 0#7KNC 010814211626Z0 0 U 0#7KN£ 010814235023Z0 0 U 0#7KOü 010815181247Z0 0 U 0#7KO¹ 010815183020Z0 0 U 0#7KPO 010815195102Z0 0 U 0#7KPL 010815195224Z0 0 U 0#7KPI 010815195322Z0 0 U 0#7KGÞ 010815195706Z0 0 U 0#7KGÕ 010815200135Z0 0 U 0#7K"€ 010815225735Z0 0 U 0#7KOª 010815225946Z0 0 U 0#7KPˆ 010816123616Z0 0 U 0#7KD 010816153838Z0 0 U 0#7KPa 010816154001Z0 0 U 0#7KP‚ 010816234048Z0 0 U 0#7KHó 010817124434Z0 0 U 0#7KQ 010820122620Z0 0 U 0#7KL¹ 010820185502Z0 0 U 0#7K!Á 010820185651Z0 0 U 0#7KPd 010820185917Z0 0 U 0#7KQ 010820190537Z0 0 U 0#7KQ— 010820190651Z0 0 U 0#7KDy 010820190934Z0 0 U 0#7KL% 010820230953Z0 0 U 0#7KP@ 010820231111Z0 0 U 0#7KOw 010820231159Z0 0 U 0#7KPí 010820231249Z0 0 U 0#7KM 010821155552Z0 0 U 0#7KLH 010821180919Z0 0 U 0#7KO* 010821181149Z0 0 U 0#7KP7 010821195124Z0 0 U 0#7KLZ 010821225046Z0 0 U 0#7K:X 010821232417Z0 0 U 0#7KNt 010822143254Z0 0 U 0#7KGç 010822173455Z0 0 U 0#7KR” 010822225734Z0 0 U 0#7KR^ 010822225821Z0 0 U 0#7KR1 010823161305Z0 0 U 0#7KFí 010823180054Z0 0 U 0#7KFl 010823180112Z0 0 U 0#7KRˆ 010823180216Z0 0 U 0#7KQÀ 010823232501Z0 0 U 0#7KL+ 010824133115Z0 0 U 0#7KÏ 010824160608Z0 0 U 0#7KQm 010827185131Z0 0 U 0#7K(‡ 010827205829Z0 0 U 0#7KRÞ 010828161701Z0 0 U 0#7KQ1 010828161831Z0 0 U 0#7Jãí 010828183938Z0 0 U 0#7Jáb 010828184021Z0 0 U 0#7Já_ 010828184104Z0 0 U 0#7Já\ 010828184320Z0 0 U 0#7JáY 010828184357Z0 0 U 0#7Já5 010828184458Z0 0 U 0#7Kö 010828185317Z0 0 U 0#7K.* 010828185355Z0 0 U 0#7KT˜ 010828233424Z0 0 U 0#7KT­ 010828233935Z0 0 U 0#7KKE 010829125810Z0 0 U 0#7KT+ 010829182257Z0 0 U 0#7K,Ò 010829182611Z0 0 U 0#7K7P 010829211033Z0 0 U 0#7KLª 010830161648Z0 0 U 0#7KU/ 010830174553Z0 0 U 0#7KU• 010830230357Z0 0 U 0#7KFÈ 010831130644Z0 0 U 0#7KP¦ 010831195329Z0 0 U 0#7KT3 010904120644Z0 0 U 0#7KTÎ 010904121120Z0 0 U 0#7KT¹ 010904121523Z0 0 U 0#7KT¶ 010904121709Z0 0 U 0#7KU× 010904121923Z0 0 U 0#7KS 010904171419Z0 0 U 0#7KT› 010904171639Z0 0 U 0#7KR 010904172006Z0 0 U 0#7KIž 010904211155Z0 0 U 0#7KPö 010904211239Z0 0 U 0#7KTä 010904211327Z0 0 U 0#7KV 010905121343Z0 0 U 0#7KUÔ 010905121803Z0 0 U 0#7KV¬ 010905132657Z0 0 U 0#7KCþ 010905150111Z0 0 U 0#7KFË 010905154453Z0 0 U 0#7KS3 010905180923Z0 0 U 0#7KV_ 010905194522Z0 0 U 0#7KVb 010905194552Z0 0 U 0#7KV¯ 010905194611Z0 0 U 0#7KVú 010905194640Z0 0 U 0#7KUÀ 010905211033Z0 0 U 0#7KV‰ 010905211402Z0 0 U 0#7KVÜ 010906154541Z0 0 U 0#7KVß 010906154703Z0 0 U 0#7KVè 010906154832Z0 0 U 0#7KVî 010906155014Z0 0 U 0#7KVë 010906155142Z0 0 U 0#7KW 010906221634Z0 0 U 0#7KOV 010906221741Z0 0 U 0#7KWq 010907121123Z0 0 U 0#7KUG 010907121239Z0 0 U 0#7KVe 010907142716Z0 0 U 0#7KNÖ 010907142842Z0 0 U 0#7KT 010907165257Z0 0 U 0#7Jý¡ 010907165415Z0 0 U 0#7K  010907165506Z0 0 U 0#7K  010907165551Z0 0 U 0#7KW× 010907165707Z0 0 U 0#7KFB 010907181822Z0 0 U 0#7KÑ 010907215205Z0 0 U 0#7KË 010907215243Z0 0 U 0#7KÈ 010907215319Z0 0 U 0#7KÅ 010907215359Z0 0 U 0#7K 010907215441Z0 0 U 0#7K! 010907215629Z0 0 U 0#7KWÚ 010910150242Z0 0 U 0#7Kë 010910172328Z0 0 U 0#7Kì 010910172422Z0 0 U 0#7KI 010910172512Z0 0 U 0#7JôE 010910172633Z0 0 U 0#7JôF 010910172709Z0 0 U 0#7JÛß 010910172748Z0 0 U 0#7JÛà 010910172821Z0 0 U 0#7KV§ 010910182536Z0 0 U 0#7KU› 010910220035Z0 0 U 0#7KWì 010910220338Z0 0 U 0#7KOò 010910220533Z0 0 U 0#7KT6 010911130930Z0 0 U 0#7KW 010912152238Z0 0 U 0#7KXÙ 010912193045Z0 0 U 0#7KDd 010913152727Z0 0 U 0#7KDa 010913152834Z0 0 U 0#7KYG 010913153020Z0 0 U 0#7K.c 010913153703Z0 0 U 0#7K@ 010913171810Z0 0 U 0#7KY 010913171930Z0 0 U 0#7KX’ 010913172100Z0 0 U 0#7KX. 010913192358Z0 0 U 0#7KY| 010913202229Z0 0 U 0#7KXÜ 010914122436Z0 0 U 0#7KJ÷ 010914195316Z0 0 U 0#7KQé 010914200558Z0 0 U 0#7KR‹ 010914200820Z0 0 U 0#7KZ> 010914201130Z0 0 U 0#7KXz 010917192846Z0 0 U 0#7K2x 010918150431Z0 0 U 0#7K2 010918150539Z0 0 U 0#7KR| 010918150704Z0 0 U 0#7KR 010918150812Z0 0 U 0#7KVÓ 010918172326Z0 0 U 0#7KZi 010918172631Z0 0 U 0#7KX˜ 010918172724Z0 0 U 0#7KZu 010918191452Z0 0 U 0#7KZl 010918191625Z0 0 U 0#7KF– 010918191734Z0 0 U 0#7KJÀ 010918191926Z0 0 U 0#7K[  010918205149Z0 0 U 0#7K5Q 010919123042Z0 0 U 0#7K5È 010919152619Z0 0 U 0#7K?ì 010919165902Z0 0 U 0#7K[³ 010920133555Z0 0 U 0#7K[ª 010920170308Z0 0 U 0#7K[¼ 010921135254Z0 0 U 0#7KZÆ 010921151559Z0 0 U 0#7KWû 010921184800Z0 0 U 0#7KYp 010921202753Z0 0 U 0#7K x 010921202941Z0 0 U 0#7K\³ 010921210630Z0 0 U 0#7KQï 010924200820Z0 0 U 0#7KX 010924214138Z0 0 U 0#7K3L 010925135206Z0 0 U 0#7K\Ë 010925141005Z0 0 U 0#7K« 010925141226Z0 0 U 0#7KYˆ 010925141349Z0 0 U 0#7K] 010925190123Z0 0 U 0#7K]“ 010925190318Z0 0 U 0#7K]R 010925192201Z0 0 U 0#7KLi 010925220530Z0 0 U 0#7KLc 010925220607Z0 0 U 0#7K]á 010925220732Z0 0 U 0#7KL4 010926121003Z0 0 U 0#7KVn 010926143926Z0 0 U 0#7KZP 010926193026Z0 0 U 0#7KZ 010926193137Z0 0 U 0#7K]¥ 010926193336Z0 0 U 0#7K\K 010926212242Z0 0 U 0#7KX¦ 010927121628Z0 0 U 0#7K^E 010927145511Z0 0 U 0#7K\ 010927145718Z0 0 U 0#7K\ 010927145905Z0 0 U 0#7K]¢ 010927174103Z0 0 U 0#7KTÅ 010927175903Z0 0 U 0#7K]= 010927213313Z0 0 U 0#7KYj 010927214149Z0 0 U 0#7K^Œ 010928150127Z0 0 U 0#7K^ 010928190415Z0 0 U 0#7K^Ñ 011001171557Z0 0 U 0#7K[Î 011001172300Z0 0 U 0#7KX› 011001172536Z0 0 U 0#7K_Ò 011001220127Z0 0 U 0#7K:S 011002120356Z0 0 U 0#7K/° 011002120425Z0 0 U 0#7K^" 011002120946Z0 0 U 0#7K.ú 011002180621Z0 0 U 0#7K?& 011002180746Z0 0 U 0#7K] 011002180937Z0 0 U 0#7K^† 011002213647Z0 0 U 0#7K^¹ 011003120702Z0 0 U 0#7K_` 011003121517Z0 0 U 0#7K]ü 011003121600Z0 0 U 0#7K_u 011003121853Z0 0 U 0#7KJ. 011003170912Z0 0 U 0#7K#Ÿ 011003190428Z0 0 U 0#7KX‰ 011004163807Z0 0 U 0#7K[Œ 011004195124Z0 0 U 0#7K^Q 011004221702Z0 0 U 0#7K`Ú 011005125959Z0 0 U 0#7K`× 011005130113Z0 0 U 0#7K_Q 011005130349Z0 0 U 0#7K[< 011005160358Z0 0 U 0#7K] 011005212305Z0 0 U 0#7K] 011005212401Z0 0 U 0#7KO“ 011009120400Z0 0 U 0#7Kbu 011009224319Z0 0 U 0#7K^ª 011009224416Z0 0 U 0#7K_Ú 011010161559Z0 0 U 0#7KTx 011010202051Z0 0 U 0#7KcŒ 011010220632Z0 0 U 0#7Ka  011011153032Z0 0 U 0#7Kd 011011183451Z0 0 U 0#7KcÊ 011011203403Z0 0 U 0#7K\¼ 011011215942Z0 0 U 0#7K:Ü 011011220020Z0 0 U 0#7KdA 011012190230Z0 0 U 0#7K^ 011015182752Z0 0 U 0#7Jæh 011015182936Z0 0 U 0#7Jæ( 011015183114Z0 0 U 0#7Jä— 011015183226Z0 0 U 0#7Kbï 011016192144Z0 0 U 0#7Kc 011016204430Z0 0 U 0#7Kc 011017140727Z0 0 U 0#7KdÁ 011017141008Z0 0 U 0#7Kc’ 011017174306Z0 0 U 0#7Kd  011017174703Z0 0 U 0#7Kbœ 011017194940Z0 0 U 0#7Keµ 011017195134Z0 0 U 0#7KcÓ 011017195242Z0 0 U 0#7K>Î 011017195403Z0 0 U 0#7KQ¦ 011017195510Z0 0 U 0#7K\{ 011018161238Z0 0 U 0#7K;’ 011018161719Z0 0 U 0#7Ke: 011019140524Z0 0 U 0#7K^¤ 011019140917Z0 0 U 0#7Kcg 011019174836Z0 0 U 0#7KfÈ 011019210853Z0 0 U 0#7Ka) 011022120103Z0 0 U 0#7K`T 011022190118Z0 0 U 0#7JÛÄ 011022190317Z0 0 U 0#7JÛÇ 011022190414Z0 0 U 0#7J݃ 011022190536Z0 0 U 0#7Kf{ 011023120250Z0 0 U 0#7Kfx 011023120356Z0 0 U 0#7Keþ 011023172433Z0 0 U 0#7Keû 011023172549Z0 0 U 0#7Ke‚ 011023172835Z0 0 U 0#7K^ô 011024120355Z0 0 U 0#7KbÈ 011025120015Z0 0 U 0#7K%( 011025120901Z0 0 U 0#7Kh: 011025180127Z0 0 U 0#7Kf– 011025195301Z0 0 U 0#7K2 011026120204Z0 0 U 0#7K= 011026120331Z0 0 U 0#7K= 011026120421Z0 0 U 0#7K=v 011026120527Z0 0 U 0#7K=G 011026120612Z0 0 U 0#7K=' 011026120658Z0 0 U 0#7KZ  011026165836Z0 0 U 0#7Kgq 011026165950Z0 0 U 0#7Keï 011026170123Z0 0 U 0#7Kg 011026170232Z0 0 U 0#7Kg 011026170306Z0 0 U 0#7KWà 011026170646Z0 0 U 0#7KhÇ 011026170754Z0 0 U 0#7Kb 011026203357Z0 0 U 0#7Kb 011026203415Z0 0 U 0#7Ke© 011029145636Z0 0 U 0#7Ki5 011029145859Z0 0 U 0#7KSg 011029150155Z0 0 U 0#7KbŠ 011029150340Z0 0 U 0#7Ke¦ 011029180247Z0 0 U 0#7Ki 011029180443Z0 0 U 0#7Kep 011029223549Z0 0 U 0#7KC¨ 011029225032Z0 0 U 0#7Kik 011030180954Z0 0 U 0#7Khu 011030181126Z0 0 U 0#7Kh= 011030181256Z0 0 U 0#7Ki© 011030181458Z0 0 U 0#7Kc© 011031175606Z0 0 U 0#7KfO 011031180041Z0 0 U 0#7Kc¦ 011031180120Z0 0 U 0#7KdÄ 011031180202Z0 0 U 0#7K`Z 011031201914Z0 0 U 0#7KiÍ 011031202243Z0 0 U 0#7Kõ 011031202428Z0 0 U 0#7K  011031202533Z0 0 U 0#7K É 011031202641Z0 0 U 0#7KGX 011031202725Z0 0 U 0#7K 011031202810Z0 0 U 0#7KG^ 011031202856Z0 0 U 0#7K 011031202940Z0 0 U 0#7KG[ 011031203024Z0 0 U 0#7K 011031203140Z0 0 U 0#7KGa 011031203237Z0 0 U 0#7K 011031203318Z0 0 U 0#7K_Ì 011031203911Z0 0 U 0#7Kav 011031204003Z0 0 U 0#7K_É 011031204210Z0 0 U 0#7Kh. 011101125941Z0 0 U 0#7Kj  011101130045Z0 0 U 0#7Kj) 011101130129Z0 0 U 0#7Kiß 011101184657Z0 0 U 0#7KTá 011101204219Z0 0 U 0#7K± 011101211340Z0 0 U 0#7JþË 011101211448Z0 0 U 0#7Kh 011102125854Z0 0 U 0#7Ki) 011102181832Z0 0 U 0#7K]™ 011102182015Z0 0 U 0#7Kk 011102210017Z0 0 U 0#7K¬ 011105125729Z0 0 U 0#7Ke7 011105150821Z0 0 U 0#7K© 011105150958Z0 0 U 0#7Kî 011105151153Z0 0 U 0#7KZ 011105151241Z0 0 U 0#7KÞ 011105151407Z0 0 U 0#7Kj 011105195953Z0 0 U 0#7Kjƒ 011105200116Z0 0 U 0#7K0Á 011105210130Z0 0 U 0#7Kj/ 011106125747Z0 0 U 0#7KkG 011106173500Z0 0 U 0#7Ki‰ 011106173632Z0 0 U 0#7Kfa 011106173744Z0 0 U 0#7KF 011106173916Z0 0 U 0#7KS\ 011106194220Z0 0 U 0#7Kg' 011106194338Z0 0 U 0#7Kj& 011106194731Z0 0 U 0#7Kjq 011106205745Z0 0 U 0#7Kap 011107125825Z0 0 U 0#7KgW 011107125914Z0 0 U 0#7Kcž 011107125956Z0 0 U 0#7Kb[ 011107130255Z0 0 U 0#7Kbº 011107130442Z0 0 U 0#7Kk 011107130603Z0 0 U 0#7Kk¬ 011107161935Z0 0 U 0#7K* 011107162028Z0 0 U 0#7Kkÿ 011107183044Z0 0 U 0#7Kú 011107183214Z0 0 U 0#7K# 011107183310Z0 0 U 0#7K  011107205149Z0 0 U 0#7Kl 011107205348Z0 0 U 0#7Kk‘ 011108130245Z0 0 U 0#7Kl¿ 011108205123Z0 0 U 0#7Km` 011108214519Z0 0 U 0#7Kj# 011108220042Z0 0 U 0#7KÆ 011108222136Z0 0 U 0#7KdU 011109163039Z0 0 U 0#7KdO 011109163237Z0 0 U 0#7KdR 011109163359Z0 0 U 0#7Klz 011109163508Z0 0 U 0#7K^• 011109163727Z0 0 U 0#7Kl, 011109164006Z0 0 U 0#7KÄ 011109210735Z0 0 U 0#7KmM 011109211253Z0 0 U 0#7K+‘ 011109211833Z0 0 U 0#7K\¿ 011109212112Z0 0 U 0#7K ” 011109212244Z0 0 U 0#7KNk 011109212428Z0 0 U 0#7K 011112150140Z0 0 U 0#7KiS 011112190815Z0 0 U 0#7Kk' 011112190927Z0 0 U 0#7KkÇ 011112191106Z0 0 U 0#7Kµ 011112191209Z0 0 U 0#7KkÒ 011112202048Z0 0 U 0#7Kb´ 011112202142Z0 0 U 0#7Km“ 011112215010Z0 0 U 0#7Kx 011113180723Z0 0 U 0#7KnÅ 011113180818Z0 0 U 0#7Ko 011113192702Z0 0 U 0#7Km® 011113220623Z0 0 U  00.0 U ¡0U#0€ðbU=³ÿ kûP„—óíbÐ0  *†H†÷ \8r>•]AªU >{ô8ûøÊ‰’œ¦’e‰HÜû— îû³GàØ,œ %%% See MIT-LICENSE at the top dir for licensing information. %%% %%% -------------------------------------------------------------------- -vc('$Id$ '). -export([topen_bind/1,topen_bind/2,all/0,t10/0,t20/0,t21/0,t22/0, t23/0,t24/0,t25/0,t26/0,t27/0,debug/1,t30/0,t31/0, t40/0,t41/0,t50/0,t51/0]). -export([crl1/0]). -export([switch/1]). -export([junk/0]). -include("ELDAPv3.hrl"). -include("eldap.hrl"). junk() -> DN = "cn=Torbjorn Tornkvist, ou=people, o=Bluetail AB, dc=bluetail, dc=com", Msg = #'LDAPMessage'{messageID = 1, protocolOp = {delRequest,DN}}, asn1rt:encode('ELDAPv3', 'LDAPMessage', Msg). %%% -------------------------------------------------------------------- %%% TEST STUFF %%% ---------- %%% When adding a new test case it can be useful to %%% switch on debugging, i.e debug(t) in the call to %%% topen_bind/2. %%% -------------------------------------------------------------------- all() -> Check = "=== Check the result of the previous test case !~n", t10(), t20(),t21(),t22(),t23(),t24(),t25(),t26(),t27(), t30(),t26(Check),t31(),t26(Check), t40(),t26(Check),t41(),t26(Check), t50(),t26(Check),t51(),t26(Check), ok. %%% %%% Setup a connection and bind using simple authentication %%% t10() -> F = fun() -> sleep(), line(), io:format("=== TEST 10 (connection setup + simple auth)~n"), line(), X = topen_bind("localhost", debug(f)), io:format("~p~n",[X]), X end, go(F). %%% %%% Do an equality match: sn = Tornkvist %%% t20() -> F = fun() -> sleep(), line(), io:format("=== TEST 20 (equality match)~n"), line(), {ok,S} = topen_bind("localhost", debug(f)), Filter = eldap:equalityMatch("sn","Tornkvist"), X=(catch eldap:search(S, [{base, "dc=bluetail, dc=com"}, {filter, Filter}])), io:format("~p~n",[X]), X end, go(F). %%% %%% Do a substring match: sn = To*kv*st %%% t21() -> F = fun() -> sleep(), line(), io:format("=== TEST 21 (substring match)~n"), line(), {ok,S} = topen_bind("localhost", debug(f)), Filter = eldap:substrings("sn", [{initial,"To"}, {any,"kv"}, {final,"st"}]), X=(catch eldap:search(S, [{base, "dc=bluetail, dc=com"}, {filter, Filter}])), io:format("~p~n",[X]), X end, go(F). %%% %%% Do a substring match: sn = *o* %%% and do only retrieve the cn attribute %%% t22() -> F = fun() -> sleep(), line(), io:format("=== TEST 22 (substring match + return 'cn' only)~n"), line(), {ok,S} = topen_bind("localhost", debug(f)), Filter = eldap:substrings("sn", [{any,"o"}]), X=(catch eldap:search(S, [{base, "dc=bluetail, dc=com"}, {filter, Filter}, {attributes,["cn"]}])), io:format("~p~n",[X]), X end, go(F). %%% %%% Do a present search for the attribute 'objectclass' %%% on the base level. %%% t23() -> F = fun() -> sleep(), line(), io:format("=== TEST 23 (objectclass=* , base level)~n"), line(), {ok,S} = topen_bind("localhost", debug(f)), X=(catch eldap:search(S, [{base, "dc=bluetail, dc=com"}, {filter, eldap:present("objectclass")}, {scope,eldap:baseObject()}])), io:format("~p~n",[X]), X end, go(F). %%% %%% Do a present search for the attribute 'objectclass' %%% on a single level. %%% t24() -> F = fun() -> sleep(), line(), io:format("=== TEST 24 (objectclass=* , single level)~n"), line(), {ok,S} = topen_bind("localhost", debug(f)), X=(catch eldap:search(S, [{base, "dc=bluetail, dc=com"}, {filter, eldap:present("objectclass")}, {scope,eldap:singleLevel()}])), io:format("~p~n",[X]), X end, go(F). %%% %%% Do a present search for the attribute 'objectclass' %%% on the whole subtree. %%% t25() -> F = fun() -> sleep(), line(), io:format("=== TEST 25 (objectclass=* , whole subtree)~n"), line(), {ok,S} = topen_bind("localhost", debug(f)), X=(catch eldap:search(S, [{base, "dc=bluetail, dc=com"}, {filter, eldap:present("objectclass")}, {scope,eldap:wholeSubtree()}])), io:format("~p~n",[X]), X end, go(F). %%% %%% Do a present search for the attributes %%% 'objectclass' and 'sn' on the whole subtree. %%% t26() -> t26([]). t26(Heading) -> F = fun() -> sleep(), line(), heading(Heading, "=== TEST 26 (objectclass=* and sn=*)~n"), line(), {ok,S} = topen_bind("localhost", debug(f)), Filter = eldap:'and'([eldap:present("objectclass"), eldap:present("sn")]), X=(catch eldap:search(S, [{base, "dc=bluetail, dc=com"}, {filter, Filter}, {scope,eldap:wholeSubtree()}])), io:format("~p~n",[X]), X end, go(F). %%% %%% Do a present search for the attributes %%% 'objectclass' and (not 'sn') on the whole subtree. %%% t27() -> F = fun() -> sleep(), line(), io:format("=== TEST 27 (objectclass=* and (not sn))~n"), line(), {ok,S} = topen_bind("localhost", debug(f)), Filter = eldap:'and'([eldap:present("objectclass"), eldap:'not'(eldap:present("sn"))]), X=(catch eldap:search(S, [{base, "dc=bluetail, dc=com"}, {filter, Filter}, {scope,eldap:wholeSubtree()}])), io:format("~p~n",[X]), X end, go(F). %%% %%% Replace the 'telephoneNumber' attribute and %%% add a new attribute 'description' %%% t30() -> t30([]). t30(Heading) -> F = fun() -> sleep(), {_,_,Tno} = erlang:now(), Stno = integer_to_list(Tno), Desc = "LDAP hacker " ++ Stno, line(), heading(Heading, "=== TEST 30 (replace telephoneNumber/" ++ Stno ++ " add description/" ++ Desc ++ ")~n"), line(), {ok,S} = topen_bind("localhost", debug(f)), Obj = "cn=Torbjorn Tornkvist, ou=people, o=Bluetail AB, dc=bluetail, dc=com", Mod = [eldap:mod_replace("telephoneNumber", [Stno]), eldap:mod_add("description", [Desc])], X=(catch eldap:modify(S, Obj, Mod)), io:format("~p~n",[X]), X end, go(F). %%% %%% Delete attribute 'description' %%% t31() -> t31([]). t31(Heading) -> F = fun() -> sleep(), {_,_,Tno} = erlang:now(), line(), heading(Heading, "=== TEST 31 (delete 'description' attribute)~n"), line(), {ok,S} = topen_bind("localhost", debug(f)), Obj = "cn=Torbjorn Tornkvist, ou=people, o=Bluetail AB, dc=bluetail, dc=com", Mod = [eldap:mod_delete("description", [])], X=(catch eldap:modify(S, Obj, Mod)), io:format("~p~n",[X]), X end, go(F). %%% %%% Add an entry %%% t40() -> t40([]). t40(Heading) -> F = fun() -> sleep(), {_,_,Tno} = erlang:now(), line(), heading(Heading, "=== TEST 40 (add entry 'Bill Valentine')~n"), line(), {ok,S} = topen_bind("localhost", debug(f)), Entry = "cn=Bill Valentine, ou=people, o=Bluetail AB, dc=bluetail, dc=com", X=(catch eldap:add(S, Entry, [{"objectclass", ["person"]}, {"cn", ["Bill Valentine"]}, {"sn", ["Valentine"]}, {"telephoneNumber", ["545 555 00"]}])), io:format("~p~n",[X]), X end, go(F). %%% %%% Delete an entry %%% t41() -> t41([]). t41(Heading) -> F = fun() -> sleep(), {_,_,Tno} = erlang:now(), line(), heading(Heading, "=== TEST 41 (delete entry 'Bill Valentine')~n"), line(), {ok,S} = topen_bind("localhost", debug(f)), Entry = "cn=Bill Valentine, ou=people, o=Bluetail AB, dc=bluetail, dc=com", X=(catch eldap:delete(S, Entry)), io:format("~p~n",[X]), X end, go(F). %%% %%% Modify the DN of an entry %%% t50() -> t50([]). t50(Heading) -> F = fun() -> sleep(), {_,_,Tno} = erlang:now(), line(), heading(Heading, "=== TEST 50 (modify DN to: 'Torbjorn M.Tornkvist')~n"), line(), {ok,S} = topen_bind("localhost", debug(f)), Entry = "cn=Torbjorn Tornkvist, ou=people, o=Bluetail AB, dc=bluetail, dc=com", X=(catch eldap:modify_dn(S, Entry, "cn=Torbjorn M.Tornkvist", false, [])), io:format("~p~n",[X]), X end, go(F). %%% %%% Modify the DN of an entry and remove the RDN attribute. %%% NB: Must be run after: 't50' ! %%% t51() -> t51([]). t51(Heading) -> F = fun() -> sleep(), {_,_,Tno} = erlang:now(), line(), heading(Heading, "=== TEST 51 (modify DN, remove the RDN attribute)~n"), line(), {ok,S} = topen_bind("localhost", debug(f)), Entry = "cn=Torbjorn M.Tornkvist, ou=people, o=Bluetail AB, dc=bluetail, dc=com", X=(catch eldap:modify_dn(S, Entry, "cn=Torbjorn Tornkvist", true, [])), io:format("~p~n",[X]), X end, go(F). %%% -------------------------------------------------------------------- %%% Test cases for certificate revocation lists %%% -------------------------------------------------------------------- crl1() -> F = fun() -> sleep(), line(), io:format("=== CRL-TEST 1 ~n"), line(), {ok,S} = crl_open_bind("localhost", debug(f)), Filter = eldap:equalityMatch("cn","Administrative CA"), X=(catch eldap:search(S, [{base, "o=Post Danmark, c=DK"}, {filter, Filter}, {attributes,["certificateRevocationList"]}])), dump_to_file("test-crl1.result",X), ok end, go(F). dump_to_file(Fname,{ok,Res}) -> case Res#eldap_search_result.entries of [Entry|_] -> case Entry#eldap_entry.attributes of [{Attribute,Value}|_] -> file:write_file(Fname,list_to_binary(Value)), io:format("Value of '~s' dumped to file: ~s~n", [Attribute,Fname]); Else -> io:format("ERROR(dump_to_file): no attributes found~n",[]) end; Else -> io:format("ERROR(dump_to_file): no entries found~n",[]) end. switch(1) -> %% %% SEARCH %% F = fun() -> sleep(), line(), io:format("=== SWITCH-TEST 1 (short-search)~n"), line(), {ok,S} = sw_open_bind("korp", debug(t)), Filter = eldap:equalityMatch("cn","Administrative CA"), X=(catch eldap:search(S, [{base, "o=Post Danmark, c=DK"}, {filter, Filter}, {attributes,["cn"]}])), io:format("RESULT: ~p~n", [X]), %%dump_to_file("test-switch-1.result",X), eldap:close(S), ok end, go(F); switch(2) -> %% %% ADD AN ENTRY %% F = fun() -> sleep(), line(), io:format("=== SWITCH-TEST 2 (add-entry)~n"), line(), {ok,S} = sw_open_bind("korp", debug(t)), Entry = "cn=Bill Valentine, o=Post Danmark, c=DK", X=(catch eldap:add(S, Entry, [{"objectclass", ["person"]}, {"cn", ["Bill Valentine"]}, {"sn", ["Valentine"]} ])), io:format("~p~n",[X]), eldap:close(S), X end, go(F); switch(3) -> %% %% SEARCH FOR THE NEWLEY ADDED ENTRY %% F = fun() -> sleep(), line(), io:format("=== SWITCH-TEST 3 (search-added)~n"), line(), {ok,S} = sw_open_bind("korp", debug(t)), Filter = eldap:equalityMatch("cn","Bill Valentine"), X=(catch eldap:search(S, [{base, "o=Post Danmark, c=DK"}, {filter, Filter}, {attributes,["cn"]}])), io:format("RESULT: ~p~n", [X]), %%dump_to_file("test-switch-1.result",X), eldap:close(S), ok end, go(F); switch(4) -> %% %% DELETE THE NEWLEY ADDED ENTRY %% F = fun() -> sleep(), line(), io:format("=== SWITCH-TEST 4 (delete-added)~n"), line(), {ok,S} = sw_open_bind("korp", debug(t)), Entry = "cn=Bill Valentine, o=Post Danmark, c=DK", X=(catch eldap:delete(S, Entry)), io:format("RESULT: ~p~n", [X]), %%dump_to_file("test-switch-1.result",X), eldap:close(S), ok end, go(F). %%% --------------- %%% Misc. functions %%% --------------- sw_open_bind(Host) -> sw_open_bind(Host, debug(t)). sw_open_bind(Host, Dbg) -> sw_open_bind(Host, Dbg, "cn=Torbjorn Tornkvist,o=Post Danmark,c=DK", "qwe123"). sw_open_bind(Host, LogFun, RootDN, Passwd) -> Opts = [{log,LogFun},{port,9779}], {ok,Handle} = eldap:open([Host], Opts), {eldap:simple_bind(Handle, RootDN, Passwd), Handle}. crl_open_bind(Host) -> crl_open_bind(Host, debug(t)). crl_open_bind(Host, Dbg) -> do_open_bind(Host, Dbg, "o=Post Danmark, c=DK", "hejsan"). topen_bind(Host) -> topen_bind(Host, debug(t)). topen_bind(Host, Dbg) -> do_open_bind(Host, Dbg, "dc=bluetail, dc=com", "hejsan"). do_open_bind(Host, LogFun, RootDN, Passwd) -> Opts = [{log,LogFun}], {ok,Handle} = eldap:open([Host], Opts), {eldap:simple_bind(Handle, RootDN, Passwd), Handle}. debug(t) -> fun(L,S,A) -> io:format("--- " ++ S, A) end; debug(1) -> fun(L,S,A) when L =< 1 -> io:format("--- " ++ S, A) end; debug(2) -> fun(L,S,A) when L =< 2 -> io:format("--- " ++ S, A) end; debug(f) -> false. sleep() -> msleep(400). %sleep(Sec) -> msleep(Sec*1000). msleep(T) -> receive after T -> true end. line() -> S = "==============================================================\n", io:format(S). heading([], Heading) -> io:format(Heading); heading(Heading, _ ) -> io:format(Heading). %%% %%% Process to run the test case %%% go(F) -> Self = self(), Pid = spawn(fun() -> run(F,Self) end), receive {Pid, X} -> ok end. run(F, Pid) -> Pid ! {self(),catch F()}. rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/Makefile0000644000177700017770000000007112633765070024771 0ustar michaelmichael all: (cd src;$(MAKE)) clean: (cd src;$(MAKE) clean) rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/ebin/0000755000177700017770000000000012633765070024250 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/ebin/eldap.app0000644000177700017770000000026712633765070026044 0ustar michaelmichael{application, eldap, [{description, "LDAP Client Library"}, {vsn, "0.01"}, {modules, [ eldap, 'ELDAPv3' ]}, {registered, []}, {applications, [kernel, stdlib]} ]}. rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/include/0000755000177700017770000000000012633765070024756 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/include/eldap.hrl0000644000177700017770000000136212633765070026554 0ustar michaelmichael-ifndef( _ELDAP_HRL ). -define( _ELDAP_HRL , 1 ). %%% %%% Search input parameters %%% -record(eldap_search, { base = [], % Baseobject filter = [], % Search conditions scope, % Search scope attributes = [], % Attributes to be returned types_only = false, % Return types+values or types timeout = 0 % Timelimit for search }). %%% %%% Returned search result %%% -record(eldap_search_result, { entries = [], % List of #eldap_entry{} records referrals = [] % List of referrals }). %%% %%% LDAP entry %%% -record(eldap_entry, { object_name = "", % The DN for the entry attributes = [] % List of {Attribute, Value} pairs }). -endif. rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/.done0000644000177700017770000000000012633765070024247 0ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-git/LICENSE0000644000177700017770000000205212633765070024337 0ustar michaelmichael Copyright (c) 2010, Torbjorn Tornkvist 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. rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/remove-eldap-fsm.patch0000644000177700017770000010425212633765070025655 0ustar michaelmichaeldiff --git a/src/eldap_fsm.erl b/src/eldap_fsm.erl deleted file mode 100644 index 381ce69..0000000 --- a/src/eldap_fsm.erl +++ /dev/null @@ -1,946 +0,0 @@ --module(eldap_fsm). -%%% -------------------------------------------------------------------- -%%% 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 Torbjörn Törnkvist -%%% Copyright (c) 2010 Torbjorn Tornkvist -%%% See MIT-LICENSE at the top dir for licensing information. -%%% -%%% 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. -%%% -------------------------------------------------------------------- - - -%%%---------------------------------------------------------------------- -%%% 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 -%%%---------------------------------------------------------------------- - -%%-compile(export_all). -%%-export([Function/Arity, ...]). - --behaviour(gen_fsm). - -%% External exports --export([start_link/1, start_link/5, 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, - 'and'/1,'or'/1,'not'/1,modify/3, mod_add/2, mod_delete/2, - mod_replace/2, add/3, delete/2, modify_dn/5]). --export([debug_level/2, get_status/1]). - -%% gen_fsm callbacks --export([init/1, connecting/2, - connecting/3, wait_bind_response/3, active/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, 5000). --define(BIND_TIMEOUT, 10000). --define(CMD_TIMEOUT, 5000). --define(MAX_TRANSACTION_ID, 65535). --define(MIN_TRANSACTION_ID, 0). - --record(eldap, {version = ?LDAP_VERSION, - hosts, % Possible hosts running LDAP servers - host = null, % Connected Host LDAP server - port = 389 , % The LDAP server port - fd = null, % Socket filedescriptor. - rootdn = "", % Name of the entry to bind as - passwd, % Password for (above) entry - id = 0, % LDAP Request ID - log, % User provided log function - bind_timer, % Ref to bind timeout - dict, % dict holding operation params and results - debug_level % Integer debug/logging level - }). - -%%%---------------------------------------------------------------------- -%%% 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) -> - Log = fun(N, Fmt, Args) -> io:format("---- " ++ Fmt, [Args]) end, - Reg_name = list_to_atom("eldap_" ++ Name), - gen_fsm:start_link({local, Reg_name}, ?MODULE, {Hosts, Port, Rootdn, Passwd, Log}, []). - -start_link(Name, Hosts, Port, Rootdn, Passwd, Log) -> - Reg_name = list_to_atom("eldap_" ++ Name), - gen_fsm:start_link({local, Reg_name}, ?MODULE, {Hosts, Port, Rootdn, Passwd, Log}, []). - -%%% -------------------------------------------------------------------- -%%% Set Debug Level. 0 - none, 1 - errors, 2 - ldap events -%%% -------------------------------------------------------------------- -debug_level(Handle, N) when integer(N) -> - Handle1 = get_handle(Handle), - gen_fsm:sync_send_all_state_event(Handle1, {debug_level,N}). - -%%% -------------------------------------------------------------------- -%%% 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 list(Entry),list(Attributes) -> - Handle1 = get_handle(Handle), - gen_fsm:sync_send_event(Handle1, {add, Entry, add_attrs(Attributes)}). - -%%% Do sanity check ! -add_attrs(Attrs) -> - F = fun({Type,Vals}) when list(Type),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 list(Entry) -> - Handle1 = get_handle(Handle), - gen_fsm:sync_send_event(Handle1, {delete, Entry}). - -%%% -------------------------------------------------------------------- -%%% 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 list(Object), list(Mods) -> - Handle1 = get_handle(Handle), - gen_fsm:sync_send_event(Handle1, {modify, Object, Mods}). - -%%% -%%% Modification operations. -%%% Example: -%%% replace("telephoneNumber", ["555 555 00"]) -%%% -mod_add(Type, Values) when list(Type), list(Values) -> m(add, Type, Values). -mod_delete(Type, Values) when list(Type), list(Values) -> m(delete, Type, Values). -mod_replace(Type, Values) when list(Type), 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 list(Entry),list(NewRDN),atom(DelOldRDN),list(NewSup) -> - Handle1 = get_handle(Handle), - gen_fsm:sync_send_event(Handle1, {modify_dn, Entry, NewRDN, bool_p(DelOldRDN), optional(NewSup)}). - -%%% 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 record(A, eldap_search) -> - call_search(Handle, A); -search(Handle, L) when list(Handle), list(L) -> - case catch parse_search_args(L) of - {error, Emsg} -> {error, Emsg}; - {'EXIT', Emsg} -> {error, Emsg}; - A when 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}). - -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 integer(Timeout) -> - parse_search_args(T,A#eldap_search{timeout = Timeout}); -parse_search_args([H|T],A) -> - 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 list(ListOfFilters) -> {'and',ListOfFilters}. -'or'(ListOfFilters) when list(ListOfFilters) -> {'or', ListOfFilters}. -'not'(Filter) when 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 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 list(Type), list(SubStr) -> - Ss = {'SubstringFilter_substrings',v_substr(SubStr)}, - {substrings,#'SubstringFilter'{type = Type, - substrings = Ss}}. - - -get_handle(Pid) when pid(Pid) -> Pid; -get_handle(Atom) when atom(Atom) -> Atom; -get_handle(Name) when 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, Rootdn, Passwd, Log} -> - init({Hosts, Rootdn, Passwd, Log}); - {error, Reason} -> - {stop, Reason} - end; -init({Hosts, Port, Rootdn, Passwd, Log}) -> - {ok, connecting, #eldap{hosts = Hosts, - port = Port, - rootdn = Rootdn, - passwd = Passwd, - id = 0, - log = Log, - dict = dict:new(), - debug_level = 0}, 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) -> - Reply = {error, connecting}, - {reply, Reply, connecting, S}. - -wait_bind_response(Event, From, S) -> - Reply = {error, wait_bind_response}, - {reply, Reply, wait_bind_response, S}. - -active(Event, From, S) -> - case catch send_command(Event, From, S) of - {ok, NewS} -> - {next_state, active, NewS}; - {error, Reason} -> - {reply, {error, Reason}, active, S}; - {'EXIT', Reason} -> - {reply, {error, Reason}, active, S} - end. - -%%---------------------------------------------------------------------- -%% 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) -> - gen_tcp:close(S#eldap.fd), - {stop, closed, 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({debug_level, N}, From, StateName, S) -> - {reply, ok, StateName, S#eldap{debug_level = N}}; - -handle_sync_event(Event, From, StateName, S) -> - {reply, {StateName, S}, StateName, S}; - -handle_sync_event(Event, From, StateName, S) -> - Reply = ok, - {reply, Reply, 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({tcp, Socket, Data}, connecting, S) -> - log1("eldap. tcp packet received when disconnected!~n~p~n", [Data], S), - {next_state, connecting, S}; - -handle_info({tcp, Socket, Data}, wait_bind_response, S) -> - cancel_timer(S#eldap.bind_timer), - case catch recvd_wait_bind_response(Data, S) of - bound -> {next_state, active, S}; - {fail_bind, Reason} -> close_and_retry(S), - {next_state, connecting, S#eldap{fd = null}}; - {'EXIT', Reason} -> close_and_retry(S), - {next_state, connecting, S#eldap{fd = null}}; - {error, Reason} -> close_and_retry(S), - {next_state, connecting, S#eldap{fd = null}} - end; - -handle_info({tcp, Socket, Data}, active, S) -> - case catch recvd_packet(Data, S) of - {reply, Reply, To, NewS} -> gen_fsm:reply(To, Reply), - {next_state, active, NewS}; - {ok, NewS} -> {next_state, active, NewS}; - {'EXIT', Reason} -> {next_state, active, S}; - {error, Reason} -> {next_state, active, S} - end; - -handle_info({tcp_closed, Socket}, All_fsm_states, S) -> - F = fun(Id, [{Timer, From, Name}|Res]) -> - gen_fsm:reply(From, {error, tcp_closed}), - cancel_timer(Timer) - end, - dict:map(F, S#eldap.dict), - retry_connect(), - {next_state, connecting, S#eldap{fd = null, - dict = dict:new()}}; - -handle_info({tcp_error, Socket, Reason}, Fsm_state, S) -> - log1("eldap received tcp_error: ~p~nIn State: ~p~n", [Reason, Fsm_state], S), - {next_state, Fsm_state, S}; -%% -%% Timers -%% -handle_info({timeout, Timer, {cmd_timeout, Id}}, active, S) -> - case cmd_timeout(Timer, Id, S) of - {reply, To, Reason, NewS} -> gen_fsm:reply(To, Reason), - {next_state, active, NewS}; - {error, Reason} -> {next_state, active, 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) -> - close_and_retry(S), - {next_state, connecting, S#eldap{fd = null}}; - -%% -%% Make sure we don't fill the message queue with rubbish -%% -handle_info(Info, StateName, S) -> - log1("eldap. Unexpected Info: ~p~nIn state: ~p~n when StateData is: ~p~n", - [Info, StateName, S], 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 -%%%---------------------------------------------------------------------- -send_command(Command, From, S) -> - Id = bump_id(S), - {Name, Request} = gen_req(Command), - Message = #'LDAPMessage'{messageID = Id, - protocolOp = {Name, Request}}, - log2("~p~n",[{Name, Request}], S), - {ok, Bytes} = asn1rt:encode('ELDAPv3', 'LDAPMessage', Message), - ok = gen_tcp:send(S#eldap.fd, Bytes), - Timer = erlang:start_timer(?CMD_TIMEOUT, self(), {cmd_timeout, Id}), - New_dict = dict:store(Id, [{Timer, From, Name}], S#eldap.dict), - {ok, S#eldap{id = Id, - dict = New_dict}}. - -gen_req({search, A}) -> - {searchRequest, - #'SearchRequest'{baseObject = A#eldap_search.base, - scope = v_scope(A#eldap_search.scope), - derefAliases = neverDerefAliases, - sizeLimit = 0, % no size 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}}. - -%%----------------------------------------------------------------------- -%% 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, - log2("~p~n",[Op], S), - Dict = S#eldap.dict, - Id = Msg#'LDAPMessage'.messageID, - {Timer, From, Name, Result_so_far} = get_op_rec(Id, Dict), - case {Name, Op} of - {searchRequest, {searchResEntry, R}} when - record(R,'SearchResultEntry') -> - New_dict = dict:append(Id, R, Dict), - {ok, S#eldap{dict = New_dict}}; - {searchRequest, {searchResDone, Result}} -> - case Result#'LDAPResult'.resultCode of - success -> - {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}}; - Reason -> - 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}}; - {OtherName, OtherResult} -> - New_dict = dict:erase(Id, Dict), - cancel_timer(Timer), - {reply, {error, {invalid_result, OtherName, OtherResult}}, - From, S#eldap{dict = New_dict}} - end; - Error -> Error - end. - -check_reply(#'LDAPResult'{resultCode = success}, From) -> - ok; -check_reply(#'LDAPResult'{resultCode = Reason}, From) -> - {error, Reason}; -check_reply(Other, From) -> - {error, Other}. - -get_op_rec(Id, Dict) -> - case dict:find(Id, Dict) of - {ok, [{Timer, 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} -> - log2("~p", [Msg], S), - check_id(S#eldap.id, Msg#'LDAPMessage'.messageID), - case Msg#'LDAPMessage'.protocolOp of - {bindResponse, Result} -> - case Result#'LDAPResult'.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) -> - case asn1rt_ber:decode_tag(Data) of - {Tag, Data1, Rb} -> - case asn1rt_ber:decode_length(Data1) of - {{Len,Data2}, Rb2} -> ok; - _ -> throw({error,decoded_tag_length}) - end; - _ -> throw({error,decoded_tag}) - end. - -close_and_retry(S) -> - gen_tcp:close(S#eldap.fd), - retry_connect(). - -retry_connect() -> - erlang:send_after(?RETRY_TIMEOUT, self(), - {timeout, retry_connect}). - - -%%----------------------------------------------------------------------- -%% Sort out timed out commands -%%----------------------------------------------------------------------- -cmd_timeout(Timer, Id, S) -> - Dict = S#eldap.dict, - case dict:find(Id, Dict) of - {ok, [{Id, Timer, 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}}; - Others -> - 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 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), - TcpOpts = [{packet, asn1}, {active, true}], - case gen_tcp:connect(Host, S#eldap.port, TcpOpts) of - {ok, Socket} -> - case bind_request(Socket, S) of - {ok, NewS} -> - Timer = erlang:start_timer(?BIND_TIMEOUT, self(), - {timeout, bind_timeout}), - {ok, wait_bind_response, NewS#eldap{fd = Socket, - host = Host, - bind_timer = Timer}}; - {error, Reason} -> - gen_tcp:close(Socket), - erlang:send_after(?RETRY_TIMEOUT, self(), - {timeout, retry_connect}), - {ok, connecting, S#eldap{host = Host}} - end; - {error, Reason} -> - erlang:send_after(?RETRY_TIMEOUT, self(), - {timeout, retry_connect}), - {ok, connecting, S#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}}, - log2("Message:~p~n",[Message], S), - {ok, Bytes} = asn1rt:encode('ELDAPv3', 'LDAPMessage', Message), - ok = gen_tcp:send(Socket, Bytes), - {ok, S#eldap{id = Id}}. - -%% 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, [H|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 record(S,'SubstringFilter') -> {substrings,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 list(Str),Key==initial;Key==any;Key==final -> - [{Key,Str}|v_substr(T)]; -v_substr([H|T]) -> - 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 integer(I), I>=0 -> I; -v_timeout(_I) -> throw({error,concat(["timeout not positive integer: ",_I])}). - -v_attributes(Attrs) -> - F = fun(A) when 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, Log} -> - {ok, Hosts, Port, Rootdn, Passwd, Log}; - {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_log(log, Entries)}. - -get_integer(Key, List) -> - case lists:keysearch(Key, 1, List) of - {value, {Key, Value}} when 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 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_log(Key, List) -> - case lists:keysearch(Key, 1, List) of - {value, {Key, Value}} when function(Value) -> - Value; - {value, {Key, Else}} -> - false; - false -> - fun(Level, Format, Args) -> io:format("--- " ++ Format, Args) end - end. - -get_hosts(Key, List) -> - lists:map(fun({Key1, {A,B,C,D}}) when integer(A), - integer(B), - integer(C), - integer(D), - Key == Key1-> - {A,B,C,D}; - ({Key1, Value}) when 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. - -%%% -------------------------------------------------------------------- -%%% Log routines. Call a user provided log routine Fun. -%%% -------------------------------------------------------------------- - -log1(Str, Args, #eldap{log = Fun, debug_level = N}) -> log(Fun, Str, Args, 1, N). -log2(Str, Args, #eldap{log = Fun, debug_level = N}) -> log(Fun, Str, Args, 2, N). - -log(Fun, Str, Args, This_level, Status) when function(Fun), This_level =< Status -> - catch Fun(This_level, Str, Args); -log(_, _, _, _, _) -> - ok. rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/remove-ietf-doc.patch0000644000177700017770000034266212633765070025510 0ustar michaelmichaeldiff --git a/doc/draft-ietf-asid-ldap-c-api-00.txt b/doc/draft-ietf-asid-ldap-c-api-00.txt deleted file mode 100755 index 5f2e856..0000000 --- a/doc/draft-ietf-asid-ldap-c-api-00.txt +++ /dev/null @@ -1,3030 +0,0 @@ - - - - - - -Network Working Group T. Howes -INTERNET-DRAFT Netscape Communications Corp. -Intended Category: Standards Track M. Smith -Obsoletes: RFC 1823 Netscape Communications Corp. -Expires: January 1998 A. Herron - Microsoft Corp. - C. Weider - Microsoft Corp. - M. Wahl - Critical Angle, Inc. - - 29 July 1997 - - - The C LDAP Application Program Interface - - - - -1. Status of this Memo - -This draft document will be submitted to the RFC Editor as a Standards -Track document. Distribution of this memo is unlimited. Please send com- -ments to the authors. - -This document is an Internet-Draft. Internet-Drafts are working docu- -ments of the Internet Engineering Task Force (IETF), its areas, and its -working groups. Note that other groups may also distribute working -documents as Internet-Drafts. - -Internet-Drafts are draft documents valid for a maximum of six months -and may be updated, replaced, or obsoleted by other documents at any -time. It is inappropriate to use Internet-Drafts as reference material -or to cite them other than as ``work in progress.'' - -To learn the current status of any Internet-Draft, please check the -``1id-abstracts.txt'' listing contained in the Internet-Drafts Shadow -Directories on ds.internic.net (US East Coast), nic.nordu.net (Europe), -ftp.isi.edu (US West Coast), or munnari.oz.au (Pacific Rim). - -2. Introduction - -This document defines a C language application program interface to the -lightweight directory access protocol (LDAP). This document replaces the -previous definition of this API, defined in RFC 1823, updating it to -include support for features found in version 3 of the LDAP protocol. -New extended operation functions were added to support LDAPv3 features -such as controls. In addition, other LDAP API changes were made to - - - -Expires: January 1998 [Page 1] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -support information hiding and thread safety. - -The C LDAP API is designed to be powerful, yet simple to use. It defines -compatible synchronous and asynchronous interfaces to LDAP to suit a -wide variety of applications. This document gives a brief overview of -the LDAP model, then an overview of how the API is used by an applica- -tion program to obtain LDAP information. The API calls are described in -detail, followed by an appendix that provides some example code demon- -strating the use of the API. This document provides information to the -Internet community. It does not specify any standard. - -3. Overview of the LDAP Model - -LDAP is the lightweight directory access protocol, described in [2] and -[6]. It can provide a lightweight frontend to the X.500 directory [1], -or a stand-alone service. In either mode, LDAP is based on a client- -server model in which a client makes a TCP connection to an LDAP server, -over which it sends requests and receives responses. - -The LDAP information model is based on the entry, which contains infor- -mation about some object (e.g., a person). Entries are composed of -attributes, which have a type and one or more values. Each attribute has -a syntax that determines what kinds of values are allowed in the attri- -bute (e.g., ASCII characters, a jpeg photograph, etc.) and how those -values behave during directory operations (e.g., is case significant -during comparisons). - -Entries may be organized in a tree structure, usually based on politi- -cal, geographical, and organizational boundaries. Each entry is uniquely -named relative to its sibling entries by its relative distinguished name -(RDN) consisting of one or more distinguished attribute values from the -entry. At most one value from each attribute may be used in the RDN. -For example, the entry for the person Babs Jensen might be named with -the "Barbara Jensen" value from the commonName attribute. - -A globally unique name for an entry, called a distinguished name or DN, -is constructed by concatenating the sequence of RDNs from the entry up -to the root of the tree. For example, if Babs worked for the University -of Michigan, the DN of her U-M entry might be "cn=Barbara Jensen, -o=University of Michigan, c=US". The DN format used by LDAP is defined -in [4]. - -Operations are provided to authenticate, search for and retrieve infor- -mation, modify information, and add and delete entries from the tree. -The next sections give an overview of how the API is used and detailed -descriptions of the LDAP API calls that implement all of these func- -tions. - - - - -Expires: January 1998 [Page 2] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -4. Overview of LDAP API Use - -An application generally uses the C LDAP API in four simple steps. - -- Initialize an LDAP session with a default LDAP server. The - ldap_init() function returns a handle to the session, allowing mul- - tiple connections to be open at once. - -- Authenticate to the LDAP server. The ldap_bind() function and - friends support a variety of authentication methods. - -- Perform some LDAP operations and obtain some results. ldap_search() - and friends return results which can be parsed by - ldap_result2error(), ldap_first_entry(), ldap_next_entry(), etc. - -- Close the session. The ldap_unbind() function closes the connec- - tion. - -Operations can be performed either synchronously or asynchronously. The -names of the synchronous functions end in _s. For example, a synchronous -search can be completed by calling ldap_search_s(). An asynchronous -search can be initiated by calling ldap_search(). All synchronous rou- -tines return an indication of the outcome of the operation (e.g, the -constant LDAP_SUCCESS or some other error code). The asynchronous rou- -tines return the message id of the operation initiated. This id can be -used in subsequent calls to ldap_result() to obtain the result(s) of the -operation. An asynchronous operation can be abandoned by calling -ldap_abandon(). - -Results and errors are returned in an opaque structure called LDAPMes- -sage. Routines are provided to parse this structure, step through -entries and attributes returned, etc. Routines are also provided to -interpret errors. Later sections of this document describe these rou- -tines in more detail. - -LDAP version 3 servers may return referrals to other servers. By -default, implementations of this API will attempt to follow referrals -automatically for the application. This behavior can be disabled glo- -bally (using the ldap_set_option() call) or on a per-request basis -through the use of a client control. - -As in the LDAPv3 protocol itself, all DNs and string values that are -passed into or produced by the C LDAP API are represented as UTF-8[10] -characters. - -For compatibility with existing applications, implementations of this -API will by default use version 2 of the LDAP protocol. Applications -that intend to take advantage of LDAP version 3 features will need to - - - -Expires: January 1998 [Page 3] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -use the ldap_set_option() call with a LDAP_OPT_PROTOCOL_VERSION to -switch to version 3. - - -5. Common Data Structures - -Some data structures that are common to several LDAP API functions are -defined here: - - typedef struct ldap LDAP; - - typedef struct ldapmsg LDAPMessage; - - struct berval { - unsigned long bv_len; - char *bv_val; - }; - - struct timeval { - long tv_sec; - long tv_usec; - }; - -The LDAP structure is an opaque data type that represents an LDAP ses- -sion Typically this corresponds to a connection to a single server, but -it may encompass several server connections in the face of LDAPv3 refer- -rals. - -The LDAPMessage structure is an opaque data type that is used to return -results and error information. - -The berval structure is used to represent arbitrary binary data and its -fields have the following meanings: - -bv_len Length of data in bytes. - -bv_val A pointer to the data itself. - - -The timeval structure is used to represent an interval of time and its -fields have the following meanings: - -tv_sec Seconds component of time interval. - -tv_usec Microseconds component of time interval. - - - - - - -Expires: January 1998 [Page 4] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -6. LDAP Error Codes - -Many of the LDAP API routines return LDAP error codes, some of which -indicate local errors and some of which may be returned by servers. -Supported error codes are (hexadecimal values are given in parentheses -after the constant): - - LDAP_SUCCESS (0x00) - LDAP_OPERATIONS_ERROR( 0x01) - LDAP_PROTOCOL_ERROR (0x02) - LDAP_TIMELIMIT_EXCEEDED (0x03) - LDAP_SIZELIMIT_EXCEEDED (0x04) - LDAP_COMPARE_FALSE (0x05) - LDAP_COMPARE_TRUE (0x06) - LDAP_STRONG_AUTH_NOT_SUPPORTED (0x07) - LDAP_STRONG_AUTH_REQUIRED (0x08) - LDAP_REFERRAL (0x0a) -- new in LDAPv3 - LDAP_ADMINLIMIT_EXCEEDED (0x0b) -- new in LDAPv3 - LDAP_UNAVAILABLE_CRITICAL_EXTENSION (0x0c) -- new in LDAPv3 - LDAP_CONFIDENTIALITY_REQUIRED (0x0d) -- new in LDAPv3 - LDAP_NO_SUCH_ATTRIBUTE (0x10) - LDAP_UNDEFINED_TYPE (0x11) - LDAP_INAPPROPRIATE_MATCHING (0x12) - LDAP_CONSTRAINT_VIOLATION (0x13) - LDAP_TYPE_OR_VALUE_EXISTS (0x14) - LDAP_INVALID_SYNTAX (0x15) - LDAP_NO_SUCH_OBJECT (0x20) - LDAP_ALIAS_PROBLEM (0x21) - LDAP_INVALID_DN_SYNTAX (0x22) - LDAP_IS_LEAF (0x23) -- not used in LDAPv3 - LDAP_ALIAS_DEREF_PROBLEM (0x24) - LDAP_INAPPROPRIATE_AUTH (0x30) - LDAP_INVALID_CREDENTIALS (0x31) - LDAP_INSUFFICIENT_ACCESS (0x32) - LDAP_BUSY (0x33) - LDAP_UNAVAILABLE (0x34) - LDAP_UNWILLING_TO_PERFORM (0x35) - LDAP_LOOP_DETECT (0x36) - LDAP_NAMING_VIOLATION (0x40) - LDAP_OBJECT_CLASS_VIOLATION (0x41) - LDAP_NOT_ALLOWED_ON_NONLEAF (0x42) - LDAP_NOT_ALLOWED_ON_RDN (0x43) - LDAP_ALREADY_EXISTS (0x44) - LDAP_NO_OBJECT_CLASS_MODS (0x45) - LDAP_RESULTS_TOO_LARGE (0x46) - LDAP_AFFECTS_MULTIPLE_DSAS (0x47) -- new in LDAPv3 - LDAP_OTHER (0x50) - LDAP_SERVER_DOWN (0x51) - - - -Expires: January 1998 [Page 5] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - LDAP_LOCAL_ERROR (0x52) - LDAP_ENCODING_ERROR (0x53) - LDAP_DECODING_ERROR (0x54) - LDAP_TIMEOUT (0x55) - LDAP_AUTH_UNKNOWN (0x56) - LDAP_FILTER_ERROR (0x57) - LDAP_USER_CANCELLED (0x58) - LDAP_PARAM_ERROR (0x59) - LDAP_NO_MEMORY (0x5a) - LDAP_CONNECT_ERROR (0x5b) - LDAP_NOT_SUPPORTED (0x5c) - LDAP_CONTROL_NOT_FOUND (0x5d) - LDAP_NO_RESULTS_RETURNED (0x5e) - LDAP_MORE_RESULTS_TO_RETURN (0x5f) - LDAP_CLIENT_LOOP (0x60) - LDAP_REFERRAL_LIMIT_EXCEEDED (0x61) - - -7. Performing LDAP Operations - -This section describes each LDAP operation API call in detail. All func- -tions take a "session handle," a pointer to an LDAP structure containing -per-connection information. Many routines return results in an LDAPMes- -sage structure. These structures and others are described as needed -below. - - -7.1. Initializing an LDAP Session - -ldap_init() initializes a session with an LDAP server. The server is not -actually contacted until an operation is performed that requires it, -allowing various options to be set after initialization. - - LDAP *ldap_init( - char *hostname, - int portno - ); - -Use of the following routine is deprecated. - - LDAP *ldap_open( - char *hostname, - int portno - ); - -Parameters are: - -hostname Contains a space-separated list of hostnames or dotted strings - - - -Expires: January 1998 [Page 6] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - representing the IP address of hosts running an LDAP server to - connect to. Each hostname in the list can include an optional - port number which is separated from the host itself with a - colon (:) character. The hosts are tried in the order listed, - stopping with the first one to which a successful connection is - made. Note that only ldap_open() attempts to make the connec- - tion before returning to the caller. ldap_init() does not con- - nect to the LDAP server. - -portno Contains the TCP port number to connect to. The default LDAP - port of 389 can be obtained by supplying the constant - LDAP_PORT. If a host includes a port number then this parame- - ter is ignored. - -ldap_init() and ldap_open() both return a "session handle," a pointer to -an opaque structure that should be passed to subsequent calls pertaining -to the session. These routines return NULL if the session cannot be ini- -tialized in which case the operating system error reporting mechanism -can be checked to see why the call failed. - -Note that if you connect to an LDAPv2 server, one of the ldap_bind() -calls described below must be completed before other operations can be -performed on the session. LDAPv3 does not require that a bind operation -be completed before other operations can be performed. - -The calling program can set various attributes of the session by calling -the routines described in the next section. - - -7.2. LDAP Session Handle Options - -The LDAP session handle returned by ldap_init() is a pointer to an -opaque data type representing an LDAP session. Formerly, this data type -was a structure exposed to the caller, and various fields in the struc- -ture could be set to control aspects of the session, such as size and -time limits on searches. - -In the interest of insulating callers from inevitable changes to this -structure, these aspects of the session are now accessed through a pair -of accessor functions, described below. - -ldap_get_option() is used to access the current value of various -session-wide parameters. ldap_set_option() is used to set the value of -these parameters. - - int ldap_get_option( - LDAP *ld, - int option, - - - -Expires: January 1998 [Page 7] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - void *outvalue - ); - - int ldap_set_option( - LDAP *ld, - int option, - void *invalue - ); - -Parameters are: - -ld The session handle. - -option The name of the option being accessed or set. This parameter - should be one of the following constants, which have the indi- - cated meanings. After the constant the actual value of the con- - stant is listed in hexadecimal in parentheses followed by the - type of the corresponding outvalue or invalue parameter. - - LDAP_OPT_DESC (0x01) int * - The underlying socket descriptor corresponding to the default - LDAP connection. - - LDAP_OPT_DEREF (0x02) int * - Controls how aliases are handled during search. It can have - one of the following values: LDAP_DEREF_NEVER (0x00), - LDAP_DEREF_SEARCHING (0x01), LDAP_DEREF_FINDING (0x02), or - LDAP_DEREF_ALWAYS (0x03). The LDAP_DEREF_SEARCHING value - means aliases should be dereferenced during the search but not - when locating the base object of the search. The - LDAP_DEREF_FINDING value means aliases should be dereferenced - when locating the base object but not during the search. - - LDAP_OPT_SIZELIMIT (0x03) int * - A limit on the number of entries to return from a search. A - value of zero means no limit. - - LDAP_OPT_TIMELIMIT (0x04) int * - A limit on the number of seconds to spend on a search. A value - of zero means no limit - - LDAP_OPT_REBIND_FN (0x06) function pointer - See the discussion of ldap_bind() and friends below. - - LDAP_OPT_REBIND_ARG (0x07) void * - See the discussion of ldap_bind() and friends below. - - LDAP_OPT_REFERRALS (0x08) void * - - - -Expires: January 1998 [Page 8] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - This option controls whether the LDAP library automatically - follows referrals returned by LDAP servers or not. It can be - set to one of the constants LDAP_OPT_ON or LDAP_OPT_OFF. - - LDAP_OPT_RESTART (0x09) void * - This option controls whether LDAP I/O operations should - automatically be restarted if they abort prematurely. It - should be set to one of the constants LDAP_OPT_ON or - LDAP_OPT_OFF. This option is useful if an LDAP I/O operation - may be interrupted prematurely, for example by a timer going - off, or other interrrupt. - - LDAP_OPT_PROTOCOL_VERSION (0x11) int * - This option indicates the version of the default LDAP server. - It can be one of the constants LDAP_VERSION2 or LDAP_VERSION3. - If no version is set the default is LDAP_VERSION2. - - LDAP_OPT_SERVER_CONTROLS (0x12) LDAPControl ** - A default list of LDAP server controls to be sent with each - request. See the Using Controls section below. - - LDAP_OPT_CLIENT_CONTROLS (0x13) LDAPControl ** - A default list of client controls that affect the LDAP ses- - sion. See the Using Controls section below. - - LDAP_OPT_HOST_NAME (0x30) char ** - The host name of the default LDAP server. - - LDAP_OPT_ERROR_NUMBER (0x31) int * - The code of the most recent LDAP error that occurred for this - session. - - LDAP_OPT_ERROR_STRING (0x32) char ** - The message returned with the most recent LDAP error that - occurred for this session. - - -outvalue The address of a place to put the value of the option. The - actual type of this parameter depends on the setting of the - option parameter. - -invalue A pointer to the value the option is to be given. The actual - type of this parameter depends on the setting of the option - parameter. The constants LDAP_OPT_ON and LDAP_OPT_OFF can be - given for options that have on or off settings. - - - - - - -Expires: January 1998 [Page 9] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -7.3. Working with controls - -LDAPv3 operations can be extended through the use of controls. Controls -may be sent to a server or returned to the client with any LDAP message. -These controls are referred to as server controls. - -The LDAP API also supports a client-side extension mechanism through the -use of client controls. These controls affect the behavior of the LDAP -API only and are never sent to a server. A common data structure is -used to represent both types of controls: - - typedef struct ldapcontrol { - char *ldctl_oid; - struct berval ldctl_value; - char ldctl_iscritical; - } LDAPControl, *PLDAPControl; - -The fields in the ldapcontrol structure have the following meanings: - -ldctl_oid The control type, represented as a string. - -ldctl_value The data associated with the control (if any). - -ldctl_iscritical Indicates whether the control is critical of not. If - this field is non-zero, the operation will only be car- - ried out if the control is recognized by the server - and/or client. - -Some LDAP API calls allocate an ldapcontrol structure or a NULL- -terminated array of ldapcontrol structures. The following routines can -be used to dispose of a single control or an array of controls: - - void ldap_control_free( LDAPControl *ctrl ); - void ldap_controls_free( LDAPControl **ctrls ); - -A set of controls that affect the entire session can be set using the -ldap_set_option() function (see above). A list of controls can also be -passed directly to some LDAP API calls such as ldap_search_ext(), in -which case any controls set for the session through the use of -ldap_set_option() are ignored. Control lists are represented as a NULL- -terminated array of pointers to ldapcontrol structures. - -Server controls are defined by LDAPv3 protocol extension documents; for -example, a control has been proposed to support server-side sorting of -search results [7]. - -No client controls are defined by this document but they may be defined -in future revisions or in any document that extends this API. - - - -Expires: January 1998 [Page 10] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -7.4. Authenticating to the directory - -The following functions are used to authenticate an LDAP client to an -LDAP directory server. - -The ldap_sasl_bind() and ldap_sasl_bind_s() functions can be used to do -general and extensible authentication over LDAP through the use of the -Simple Authentication Security Layer [8]. The routines both take the dn -to bind as, the method to use, as a dotted-string representation of an -OID identifying the method, and a struct berval holding the credentials. -The special constant value LDAP_SASL_SIMPLE ("") can be passed to -request simple authentication, or the simplified routines -ldap_simple_bind() or ldap_simple_bind_s() can be used. - - int ldap_sasl_bind( - LDAP *ld, - char *dn, - char *mechanism, - struct berval *cred, - LDAPControl **serverctrls, - LDAPControl **clientctrls, - int *msgidp - ); - - int ldap_sasl_bind_s( - LDAP *ld, - char *dn, - char *mechanism, - struct berval *cred, - LDAPControl **serverctrls, - LDAPControl **clientctrls, - struct berval **servercredp - ); - - int ldap_simple_bind( - LDAP *ld, - char *dn, - char *passwd - ); - - int ldap_simple_bind_s( - LDAP *ld, - char *dn, - char *passwd - ); - - The use of the following routines is deprecated: - - - - -Expires: January 1998 [Page 11] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - int ldap_bind( LDAP *ld, char *dn, char *cred, int method ); - - int ldap_bind_s( LDAP *ld, char *dn, char *cred, int method ); - - int ldap_kerberos_bind( LDAP *ld, char *dn ); - - int ldap_kerberos_bind_s( LDAP *ld, char *dn ); - -Parameters are: - -ld The session handle. - -dn The name of the entry to bind as. - -mechanism Either LDAP_AUTH_SIMPLE_OID to get simple authentication, - or a dotted text string representing an OID identifying the - SASL method. - -cred The credentials with which to authenticate. Arbitrary - credentials can be passed using this parameter. The format - and content of the credentials depends on the setting of - the mechanism parameter. - -passwd For ldap_simple_bind(), the password to compare to the - entry's userPassword attribute. - -serverctrls List of LDAP server controls. - -clientctrls List of client controls. - -msgidp This result parameter will be set to the message id of the - request if the ldap_sasl_bind() call succeeds. - -servercredp This result parameter will be set to the credentials - returned by the server. This should be freed by calling - ldap_If no credentials are returned it will be set to NULL. - -Additional parameters for the deprecated routines are not described. -Interested readers are referred to RFC 1823. - -The ldap_sasl_bind() function initiates an asynchronous bind operation -and returns the constant LDAP_SUCCESS if the request was successfully -sent, or another LDAP error code if not. See the section below on error -handling for more information about possible errors and how to interpret -them. If successful, ldap_sasl_bind() places the message id of the -request in *msgidp. A subsequent call to ldap_result(), described below, -can be used to obtain the result of the bind. - - - - -Expires: January 1998 [Page 12] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -The ldap_simple_bind() function initiates a simple asynchronous bind -operation and returns the message id of the operation initiated. A sub- -sequent call to ldap_result(), described below, can be used to obtain -the result of the bind. In case of error, ldap_simple_bind() will return --1, setting the session error parameters in the LDAP structure appropri- -ately. - -The synchronous ldap_sasl_bind_s() and ldap_simple_bind_s() functions -both return the result of the operation, either the constant -LDAP_SUCCESS if the operation was successful, or another LDAP error code -if it was not. See the section below on error handling for more informa- -tion about possible errors and how to interpret them. - -Note that if an LDAPv2 server is contacted, no other operations over the -connection should be attempted before a bind call has successfully com- -pleted. - -Subsequent bind calls can be used to re-authenticate over the same con- -nection, and multistep SASL sequences can be accomplished through a -sequence of calls to ldap_sasl_bind() or ldap_sasl_bind_s(). - - -7.5. Closing the session - -The following functions are used to unbind from the directory, close the -connection, and dispose of the session handle. - - int ldap_unbind( LDAP *ld ); - - int ldap_unbind_s( LDAP *ld ); - -Parameters are: - -ld The session handle. - -ldap_unbind() and ldap_unbind_s() both work synchronously, unbinding -from the directory, closing the connection, and freeing up the ld struc- -ture before returning. There is no server response to an unbind opera- -tion. ldap_unbind() returns LDAP_SUCCESS (or another LDAP error code if -the request cannot be sent to the LDAP server). After a call to -ldap_unbind() or ldap_unbind_s(), the session handle ld is invalid. - - -7.6. Searching - -The following functions are used to search the LDAP directory, returning -a requested set of attributes for each entry matched. There are five -variations. - - - -Expires: January 1998 [Page 13] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - int ldap_search_ext( - LDAP *ld, - char *base, - int scope, - char *filter, - char **attrs, - int attrsonly, - LDAPControl **serverctrls, - LDAPControl **clientctrls, - struct timeval *timeoutp, - int sizelimit, - int *msgidp - ); - - int ldap_search_ext_s( - LDAP *ld, - char *base, - int scope, - char *filter, - char **attrs, - int attrsonly, - LDAPControl **serverctrls, - LDAPControl **clientctrls, - struct timeval *timeoutp, - int sizelimit, - LDAPMessage **res - ); - - int ldap_search( - LDAP *ld, - char *base, - int scope, - char *filter, - char **attrs, - int attrsonly - ); - - int ldap_search_s( - LDAP *ld, - char *base, - int scope, - char *filter, - char **attrs, - int attrsonly, - LDAPMessage **res - ); - - int ldap_search_st( - - - -Expires: January 1998 [Page 14] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - LDAP *ld, - char *base, - int scope, - char *filter, - char **attrs, - int attrsonly, - struct timeval *timeout, - LDAPMessage **res - ); - -Parameters are: - -ld The session handle. - -base The dn of the entry at which to start the search. - -scope One of LDAP_SCOPE_BASE (0x00), LDAP_SCOPE_ONELEVEL (0x01), - or LDAP_SCOPE_SUBTREE (0x02), indicating the scope of the - search. - -filter A character string as described in [3], representing the - search filter. - -attrs A NULL-terminated array of strings indicating which attri- - butes to return for each matching entry. Passing NULL for - this parameter causes all available attributes to be - retrieved. - -attrsonly A boolean value that should be zero if both attribute types - and values are to be returned, non-zero if only types are - wanted. - -timeout For the ldap_search_st() function, this specifies the local - search timeout value. For the ldap_search_ext() and - ldap_search_ext_s() functions, this specifies both the - local search timeout value and the operation time limit - that is sent to the server within the search request. - -res For the synchronous calls, this is a result parameter which - will contain the results of the search upon completion of - the call. - -serverctrls List of LDAP server controls. - -clientctrls List of client controls. - -msgidp This result parameter will be set to the message id of the - request if the ldap_search_ext() call succeeds. - - - -Expires: January 1998 [Page 15] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -There are three options in the session handle ld which potentially -affect how the search is performed. They are: - -LDAP_OPT_SIZELIMIT - A limit on the number of entries to return from the search. - A value of zero means no limit. Note that the value from - the session handle is ignored when using the - ldap_search_ext() or ldap_search_ext_s() functions. - -LDAP_OPT_TIMELIMIT - A limit on the number of seconds to spend on the search. A - value of zero means no limit. Note that the value from the - session handle is ignored when using the ldap_search_ext() - or ldap_search_ext_s() functions. - -LDAP_OPT_DEREF - One of LDAP_DEREF_NEVER (0x00), LDAP_DEREF_SEARCHING - (0x01), LDAP_DEREF_FINDING (0x02), or LDAP_DEREF_ALWAYS - (0x03), specifying how aliases should be handled during the - search. The LDAP_DEREF_SEARCHING value means aliases should - be dereferenced during the search but not when locating the - base object of the search. The LDAP_DEREF_FINDING value - means aliases should be dereferenced when locating the base - object but not during the search. - -The ldap_search_ext() function initiates an asynchronous search opera- -tion and returns the constant LDAP_SUCCESS if the request was success- -fully sent, or another LDAP error code if not. See the section below on -error handling for more information about possible errors and how to -interpret them. If successful, ldap_search_ext() places the message id -of the request in *msgidp. A subsequent call to ldap_result(), described -below, can be used to obtain the results from the search. These results -can be parsed using the result parsing routines described in detail -later. - -Similar to ldap_search_ext(), the ldap_search() function initiates an -asynchronous search operation and returns the message id of the opera- -tion initiated. As for ldap_search_ext(), a subsequent call to -ldap_result(), described below, can be used to obtain the result of the -bind. In case of error, ldap_search() will return -1, setting the ses- -sion error parameters in the LDAP structure appropriately. - -The synchronous ldap_search_ext_s(), ldap_search_s(), and -ldap_search_st() functions all return the result of the operation, -either the constant LDAP_SUCCESS if the operation was successful, or -another LDAP error code if it was not. See the section below on error -handling for more information about possible errors and how to interpret -them. Entries returned from the search (if any) are contained in the - - - -Expires: January 1998 [Page 16] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -res parameter. This parameter is opaque to the caller. Entries, attri- -butes, values, etc., should be extracted by calling the parsing routines -described below. The results contained in res should be freed when no -longer in use by calling ldap_msgfree(), described later. - -The ldap_search_ext() and ldap_search_ext_s() functions support LDAPv3 -server controls, client controls, and allow varying size and time limits -to be easily specified for each search operation. The ldap_search_st() -function is identical to ldap_search_s() except that it takes an addi- -tional parameter specifying a local timeout for the search. - -7.7. Reading an Entry - -LDAP does not support a read operation directly. Instead, this operation -is emulated by a search with base set to the DN of the entry to read, -scope set to LDAP_SCOPE_BASE, and filter set to "(objectclass=*)". attrs -contains the list of attributes to return. - - -7.8. Listing the Children of an Entry - -LDAP does not support a list operation directly. Instead, this operation -is emulated by a search with base set to the DN of the entry to list, -scope set to LDAP_SCOPE_ONELEVEL, and filter set to "(objectclass=*)". -attrs contains the list of attributes to return for each child entry. - -7.9. Comparing a Value Against an Entry - -The following routines are used to compare a given attribute value -assertion against an LDAP entry. There are four variations: - - int ldap_compare_ext( - LDAP *ld, - char *dn, - char *attr, - struct berval *bvalue - LDAPControl **serverctrls, - LDAPControl **clientctrls, - int *msgidp - ); - - int ldap_compare_ext_s( - LDAP *ld, - char *dn, - char *attr, - struct berval *bvalue, - LDAPControl **serverctrls, - LDAPControl **clientctrls - - - -Expires: January 1998 [Page 17] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - ); - - int ldap_compare( - LDAP *ld, - char *dn, - char *attr, - char *value - ); - - int ldap_compare_s( - LDAP *ld, - char *dn, - char *attr, - char *value - ); - -Parameters are: - -ld The session handle. - -dn The name of the entry to compare against. - -attr The attribute to compare against. - -bvalue The attribute value to compare against those found in the - given entry. This parameter is used in the extended rou- - tines and is a pointer to a struct berval so it is possible - to compare binary values. - -value A string attribute value to compare against, used by the - ldap_compare() and ldap_compare_s() functions. Use - ldap_compare_ext() or ldap_compare_ext_s() if you need to - compare binary values. - -serverctrls List of LDAP server controls. - -clientctrls List of client controls. - -msgidp This result parameter will be set to the message id of the - request if the ldap_compare_ext() call succeeds. - -The ldap_compare_ext() function initiates an asynchronous compare opera- -tion and returns the constant LDAP_SUCCESS if the request was success- -fully sent, or another LDAP error code if not. See the section below on -error handling for more information about possible errors and how to -interpret them. If successful, ldap_compare_ext() places the message id -of the request in *msgidp. A subsequent call to ldap_result(), described -below, can be used to obtain the result of the compare. - - - -Expires: January 1998 [Page 18] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -Similar to ldap_compare_ext(), the ldap_compare() function initiates an -asynchronous compare operation and returns the message id of the opera- -tion initiated. As for ldap_compare_ext(), a subsequent call to -ldap_result(), described below, can be used to obtain the result of the -bind. In case of error, ldap_compare() will return -1, setting the ses- -sion error parameters in the LDAP structure appropriately. - -The synchronous ldap_compare_ext_s() and ldap_compare_s() functions both -return the result of the operation, either the constant LDAP_SUCCESS if -the operation was successful, or another LDAP error code if it was not. -See the section below on error handling for more information about pos- -sible errors and how to interpret them. - -The ldap_compare_ext() and ldap_compare_ext_s() functions support LDAPv3 -server controls and client controls. - - -7.10. Modifying an entry - -The following routines are used to modify an existing LDAP entry. There -are four variations: - - typedef struct ldapmod { - int mod_op; - char *mod_type; - union { - char **modv_strvals; - struct berval **modv_bvals; - } mod_vals; - } LDAPMod; - #define mod_values mod_vals.modv_strvals - #define mod_bvalues mod_vals.modv_bvals - - int ldap_modify_ext( - LDAP *ld, - char *dn, - LDAPMod **mods, - LDAPControl **serverctrls, - LDAPControl **clientctrls, - int *msgidp - ); - - int ldap_modify_ext_s( - LDAP *ld, - char *dn, - LDAPMod **mods, - LDAPControl **serverctrls, - LDAPControl **clientctrls - - - -Expires: January 1998 [Page 19] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - ); - - int ldap_modify( - LDAP *ld, - char *dn, - LDAPMod **mods - ); - - int ldap_modify_s( - LDAP *ld, - char *dn, - LDAPMod **mods - ); - -Parameters are: - -ld The session handle. - -dn The name of the entry to modify. - -mods A NULL-terminated array of modifications to make to the - entry. - -serverctrls List of LDAP server controls. - -clientctrls List of client controls. - -msgidp This result parameter will be set to the message id of the - request if the ldap_modify_ext() call succeeds. - -The fields in the LDAPMod structure have the following meanings: - -mod_op The modification operation to perform. It should be one of - LDAP_MOD_ADD (0x00), LDAP_MOD_DELETE (0x01), or - LDAP_MOD_REPLACE (0x02). This field also indicates the - type of values included in the mod_vals union. It is logi- - cally ORed with LDAP_MOD_BVALUES (0x80) to select the - mod_bvalues form. Otherwise, the mod_values form is used. - -mod_type The type of the attribute to modify. - -mod_vals The values (if any) to add, delete, or replace. Only one of - the mod_values or mod_bvalues variants should be used, - selected by ORing the mod_op field with the constant - LDAP_MOD_BVALUES. mod_values is a NULL-terminated array of - zero-terminated strings and mod_bvalues is a NULL- - terminated array of berval structures that can be used to - pass binary values such as images. - - - -Expires: January 1998 [Page 20] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -For LDAP_MOD_ADD modifications, the given values are added to the -entry, creating the attribute if necessary. - -For LDAP_MOD_DELETE modifications, the given values are deleted from the -entry, removing the attribute if no values remain. If the entire attri- -bute is to be deleted, the mod_vals field should be set to NULL. - -For LDAP_MOD_REPLACE modifications, the attribute will have the listed -values after the modification, having been created if necessary, or -removed if the mod_vals field is NULL. All modifications are performed -in the order in which they are listed. - -The ldap_modify_ext() function initiates an asynchronous modify opera- -tion and returns the constant LDAP_SUCCESS if the request was success- -fully sent, or another LDAP error code if not. See the section below on -error handling for more information about possible errors and how to -interpret them. If successful, ldap_modify_ext() places the message id -of the request in *msgidp. A subsequent call to ldap_result(), described -below, can be used to obtain the result of the modify. - -Similar to ldap_modify_ext(), the ldap_modify() function initiates an -asynchronous modify operation and returns the message id of the opera- -tion initiated. As for ldap_modify_ext(), a subsequent call to -ldap_result(), described below, can be used to obtain the result of the -modify. In case of error, ldap_modify() will return -1, setting the ses- -sion error parameters in the LDAP structure appropriately. - -The synchronous ldap_modify_ext_s() and ldap_modify_s() functions both -return the result of the operation, either the constant LDAP_SUCCESS if -the operation was successful, or another LDAP error code if it was not. -See the section below on error handling for more information about pos- -sible errors and how to interpret them. - -The ldap_modify_ext() and ldap_modify_ext_s() functions support LDAPv3 -server controls and client controls. - - -7.11. Modifying the Name of an Entry - -In LDAPv2, the ldap_modrdn() and ldap_modrdn_s() routines were used to -change the name of an LDAP entry. They could only be used to change the -least significant component of a name (the RDN or relative distinguished -name). LDAPv3 provides the Modify DN protocol operation that allows more -general name change access. The ldap_rename() and ldap_rename_s() rou- -tines are used to change the name of an entry, and the use of the -ldap_modrdn() and ldap_modrdn_s() routines is deprecated. - - int ldap_rename( - - - -Expires: January 1998 [Page 21] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - LDAP *ld, - char *dn, - char *newrdn, - char *newparent, - int deleteoldrdn, - LDAPControl **serverctrls, - LDAPControl **clientctrls, - int *msgidp - - ); - int ldap_rename_s( - LDAP *ld, - char *dn, - char *newrdn, - char *newparent, - int deleteoldrdn, - LDAPControl **serverctrls, - LDAPControl **clientctrls - ); - - Use of the following routines is deprecated. - - int ldap_modrdn( - LDAP *ld, - char *dn, - char *newrdn, - int deleteoldrdn - ); - int ldap_modrdn_s( - LDAP *ld, - char *dn, - char *newrdn, - int deleteoldrdn - ); - -Parameters are: - -ld The session handle. - -dn The name of the entry whose DN is to be changed. - -newrdn The new RDN to give the entry. - -newparent The new parent, or superior entry. If this parameter is - NULL, only the RDN of the entry is changed. The root DN - may be specified by passing a zero length string, "". The - newparent parameter should always be NULL when using ver- - sion 2 of the LDAP protocol; otherwise the server's - - - -Expires: January 1998 [Page 22] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - behavior is undefined. - -deleteoldrdn This parameter only has meaning on the rename routines if - newrdn is different than the old RDN. It is a boolean - value, if non-zero indicating that the old RDN value(s) - should be removed, if zero indicating that the old RDN - value(s) should be retained as non-distinguished values of - the entry. - -serverctrls List of LDAP server controls. - -clientctrls List of client controls. - -msgidp This result parameter will be set to the message id of the - request if the ldap_rename() call succeeds. - -The ldap_rename() function initiates an asynchronous modify DN operation -and returns the constant LDAP_SUCCESS if the request was successfully -sent, or another LDAP error code if not. See the section below on error -handling for more information about possible errors and how to interpret -them. If successful, ldap_rename() places the DN message id of the -request in *msgidp. A subsequent call to ldap_result(), described below, -can be used to obtain the result of the rename. - -The synchronous ldap_rename_s() returns the result of the operation, -either the constant LDAP_SUCCESS if the operation was successful, or -another LDAP error code if it was not. See the section below on error -handling for more information about possible errors and how to interpret -them. - -The ldap_rename() and ldap_rename_s() functions both support LDAPv3 -server controls and client controls. - - -7.12. Adding an entry - -The following functions are used to add entries to the LDAP directory. -There are four variations: - - int ldap_add_ext( - LDAP *ld, - char *dn, - LDAPMod **attrs, - LDAPControl **serverctrls, - LDAPControl **clientctrls, - int *msgidp - ); - - - - -Expires: January 1998 [Page 23] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - int ldap_add_ext_s( - LDAP *ld, - char *dn, - LDAPMod **attrs, - LDAPControl **serverctrls, - LDAPControl **clientctrls - ); - - int ldap_add( - LDAP *ld, - char *dn, - LDAPMod **attrs - ); - - int ldap_add_s( - LDAP *ld, - char *dn, - LDAPMod **attrs - ); - -Parameters are: - -ld The session handle. - -dn The name of the entry to add. - -attrs The entry's attributes, specified using the LDAPMod struc- - ture defined for ldap_modify(). The mod_type and mod_vals - fields should be filled in. The mod_op field is ignored - unless ORed with the constant LDAP_MOD_BVALUES, used to - select the mod_bvalues case of the mod_vals union. - -serverctrls List of LDAP server controls. - -clientctrls List of client controls. - -msgidp This result parameter will be set to the message id of the - request if the ldap_add_ext() call succeeds. - -Note that the parent of the entry being added must already exist or the -parent must be empty (i.e., equal to the root DN) for an add to succeed. - -The ldap_add_ext() function initiates an asynchronous add operation and -returns the constant LDAP_SUCCESS if the request was successfully sent, -or another LDAP error code if not. See the section below on error han- -dling for more information about possible errors and how to interpret -them. If successful, ldap_add_ext() places the message id of the -request in *msgidp. A subsequent call to ldap_result(), described below, - - - -Expires: January 1998 [Page 24] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -can be used to obtain the result of the add. - -Similar to ldap_add_ext(), the ldap_add() function initiates an asyn- -chronous add operation and returns the message id of the operation ini- -tiated. As for ldap_add_ext(), a subsequent call to ldap_result(), -described below, can be used to obtain the result of the add. In case of -error, ldap_add() will return -1, setting the session error parameters -in the LDAP structure appropriately. - -The synchronous ldap_add_ext_s() and ldap_add_s() functions both return -the result of the operation, either the constant LDAP_SUCCESS if the -operation was successful, or another LDAP error code if it was not. See -the section below on error handling for more information about possible -errors and how to interpret them. - -The ldap_add_ext() and ldap_add_ext_s() functions support LDAPv3 server -controls and client controls. - - - -7.13. Deleting an entry - -The following functions are used to delete a leaf entry from the LDAP -directory. There are four variations: - - int ldap_delete_ext( - LDAP *ld, - char *dn, - LDAPControl **serverctrls, - LDAPControl **clientctrls, - int *msgidp - ); - - int ldap_delete_ext_s( - LDAP *ld, - char *dn, - LDAPControl **serverctrls, - LDAPControl **clientctrls - ); - - int ldap_delete( - LDAP *ld, - char *dn - ); - - int ldap_delete_s( - LDAP *ld, - char *dn - - - -Expires: January 1998 [Page 25] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - ); - -Parameters are: - -ld The session handle. - -dn The name of the entry to delete. - -serverctrls List of LDAP server controls. - -clientctrls List of client controls. - -msgidp This result parameter will be set to the message id of the - request if the ldap_delete_ext() call succeeds. - -Note that the entry to delete must be a leaf entry (i.e., it must have -no children). Deletion of entire subtrees in a single operation is not -supported by LDAP. - -The ldap_delete_ext() function initiates an asynchronous delete opera- -tion and returns the constant LDAP_SUCCESS if the request was success- -fully sent, or another LDAP error code if not. See the section below on -error handling for more information about possible errors and how to -interpret them. If successful, ldap_delete_ext() places the message id -of the request in *msgidp. A subsequent call to ldap_result(), described -below, can be used to obtain the result of the delete. - -Similar to ldap_delete_ext(), the ldap_delete() function initiates an -asynchronous delete operation and returns the message id of the opera- -tion initiated. As for ldap_delete_ext(), a subsequent call to -ldap_result(), described below, can be used to obtain the result of the -delete. In case of error, ldap_delete() will return -1, setting the ses- -sion error parameters in the LDAP structure appropriately. - -The synchronous ldap_delete_ext_s() and ldap_delete_s() functions both -return the result of the operation, either the constant LDAP_SUCCESS if -the operation was successful, or another LDAP error code if it was not. -See the section below on error handling for more information about pos- -sible errors and how to interpret them. - -The ldap_delete_ext() and ldap_delete_ext_s() functions support LDAPv3 -server controls and client controls. - - -7.14. Extended Operations - -The ldap_extended_operation() and ldap_extended_operation_s() routines -allow extended LDAP operations to be passed to the server, providing a - - - -Expires: January 1998 [Page 26] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -general protocol extensibility mechanism. - - int ldap_extended_operation( - LDAP *ld, - char *exoid, - struct berval *exdata, - LDAPControl **serverctrls, - LDAPControl **clientctrls, - int *msgidp - ); - - int ldap_extended_operation_s( - LDAP *ld, - char *exoid, - struct berval *exdata, - LDAPControl **serverctrls, - LDAPControl **clientctrls, - char **retoidp, - struct berval **retdatap - ); - -Parameters are: - -ld The session handle. - -requestoid The dotted-OID text string naming the request. - -requestdata The arbitrary data required by the operation (if NULL, no - data is sent to the server). - -serverctrls List of LDAP server controls. - -clientctrls List of client controls. - -msgidp This result parameter will be set to the message id of the - request if the ldap_extended_operation() call succeeds. - -retoidp Pointer to a character string that will be set to an allo- - cated, dotted-OID text string returned by the server. This - string should be disposed of using the ldap_memfree() func- - tion. If no OID was returned, *retoidp is set to NULL. - -retdatap Pointer to a berval structure pointer that will be set an - allocated copy of the data returned by the server. This - struct berval should be disposed of using ber_bvfree(). If - no data is returned, *retdatap is set to NULL. - -The ldap_extended_operation() function initiates an asynchronous - - - -Expires: January 1998 [Page 27] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -extended operation and returns the constant LDAP_SUCCESS if the request -was successfully sent, or another LDAP error code if not. See the sec- -tion below on error handling for more information about possible errors -and how to interpret them. If successful, ldap_extended_operation() -places the message id of the request in *msgidp. A subsequent call to -ldap_result(), described below, can be used to obtain the result of the -extended operation which can be passed to ldap_parse_extended_result() -to obtain the OID and data contained in the response. - -The synchronous ldap_extended_operation_s() function returns the result -of the operation, either the constant LDAP_SUCCESS if the operation was -successful, or another LDAP error code if it was not. See the section -below on error handling for more information about possible errors and -how to interpret them. The retoid and retdata parameters are filled in -with the OID and data from the response. If no OID or data was -returned, these parameters are set to NULL. - -The ldap_extended_operation() and ldap_extended_operation_s() functions -both support LDAPv3 server controls and client controls. - - -8. Abandoning An Operation - -The following calls are used to abandon an operation in progress: - - int ldap_abandon_ext( - LDAP *ld, - int msgid, - LDAPControl **serverctrls, - LDAPControl **clientctrls - ); - - int ldap_abandon( - LDAP *ld, - int msgid - ); - - -ld The session handle. - -msgid The message id of the request to be abandoned. - -serverctrls List of LDAP server controls. - -clientctrls List of client controls. - -ldap_abandon_ext() abandons the operation with message id msgid and -returns the constant LDAP_SUCCESS if the abandon was successful or - - - -Expires: January 1998 [Page 28] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -another LDAP error code if not. See the section below on error handling -for more information about possible errors and how to interpret them. - -ldap_abandon() is identical to ldap_abandon_ext() except that it returns -zero if the abandon was successful, -1 otherwise and does not support -LDAPv3 server controls or client controls. - -After a successful call to ldap_abandon() or ldap_abandon_ext(), results -with the given message id are never returned from a subsequent call to -ldap_result(). There is no server response to LDAP abandon operations. - - -9. Obtaining Results and Peeking Inside LDAP Messages - -ldap_result() is used to obtain the result of a previous asynchronously -initiated operation. Note that depending on how it is called, -ldap_result() may actually return a list or "chain" of messages. - -ldap_msgfree() frees the results obtained from a previous call to -ldap_result(), or a synchronous search routine. - -ldap_msgtype() returns the type of an LDAP message. ldap_msgid() -returns the message ID of an LDAP message. - - int ldap_result( - LDAP *ld, - int msgid, - int all, - struct timeval *timeout, - LDAPMessage **res - ); - - int ldap_msgfree( LDAPMessage *res ); - - int ldap_msgtype( LDAPMessage *res ); - - int ldap_msgid( LDAPMessage *res ); - -Parameters are: - -ld The session handle. - -msgid The message id of the operation whose results are to be - returned, or the constant LDAP_RES_ANY (-1) if any result is - desired. - -all Specifies how many messages will be retrieved in a single call - to ldap_result(). This parameter only has meaning for search - - - -Expires: January 1998 [Page 29] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - results. Pass the constant LDAP_MSG_ONE (0x00) to retrieve one - message at a time. Pass LDAP_MSG_ALL (0x01) to request that - all results of a search be received before returning all - results in a single chain. Pass LDAP_MSG_RECEIVED (0x02) to - indicate that all results retrieved so far should be returned - in the result chain. - -timeout A timeout specifying how long to wait for results to be - returned. A NULL value causes ldap_result() to block until - results are available. A timeout value of zero seconds speci- - fies a polling behavior. - -res For ldap_result(), a result parameter that will contain the - result(s) of the operation. For ldap_msgfree(), the result - chain to be freed, obtained from a previous call to - ldap_result(), ldap_search_s(), or ldap_search_st(). - -Upon successful completion, ldap_result() returns the type of the first -result returned in the res parameter. This will be one of the following -constants. - - LDAP_RES_BIND (0x61) - LDAP_RES_SEARCH_ENTRY (0x64) - LDAP_RES_SEARCH_REFERENCE (0x73) -- new in LDAPv3 - LDAP_RES_SEARCH_RESULT (0x65) - LDAP_RES_MODIFY (0x67) - LDAP_RES_ADD (0x69) - LDAP_RES_DELETE (0x6B) - LDAP_RES_MODDN (0x6D) - LDAP_RES_COMPARE (0x6F) - LDAP_RES_EXTENDED (0x78) -- new in LDAPv3 - -ldap_result() returns 0 if the timeout expired and -1 if an error -occurs, in which case the error parameters of the LDAP session handle -will be set accordingly. - -ldap_msgfree() frees the result structure pointed to by res and returns -the type of the message it freed. - -ldap_msgtype() returns the type of the LDAP message it is passed as a -parameter. The type will be one of the types listed above, or -1 on -error. - -ldap_msgid() returns the message ID associated with the LDAP message -passed as a parameter. - - - - - - -Expires: January 1998 [Page 30] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -10. Handling Errors and Parsing Results - -The following calls are used to extract information from results and -handle errors returned by other LDAP API routines. - - int ldap_parse_result( - LDAP *ld, - LDAPMessage *res, - int *errcodep, - char **matcheddnp, - char **errmsgp, - char ***referralsp, - LDAPControl ***serverctrlsp, - int freeit - ); - - int ldap_parse_sasl_bind_result( - LDAP *ld, - LDAPMessage *res, - struct berval **servercredp, - int freeit - ); - - int ldap_parse_extended_result( - LDAP *ld, - LDAPMessage *res, - char **resultoidp, - struct berval **resultdata, - int freeit - ); - - char *ldap_err2string( int err ); - - The use of the following routines is deprecated. - - int ldap_result2error( - LDAP *ld, - LDAPMessage *res, - int freeit - ); - - void ldap_perror( LDAP *ld, char *msg ); - -Parameters are: - -ld The session handle. - -res The result of an LDAP operation as returned by - - - -Expires: January 1998 [Page 31] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - ldap_result() or one of the synchronous API operation - calls. - -errcodep This result parameter will be filled in with the LDAP error - code field from the LDAPResult message. This is the indi- - cation from the server of the outcome of the operation. - NULL may be passed to ignore this field. - -matcheddnp In the case of a return of LDAP_NO_SUCH_OBJECT, this result - parameter will be filled in with a DN indicating how much - of the name in the request was recognized. NULL may be - passed to ignore this field. The matched DN string should - be freed by calling ldap_memfree() which is described later - in this document. - -errmsgp This result parameter will be filled in with the contents - of the error message field from the LDAPResult message. - The error message string should be freed by calling - ldap_memfree() which is described later in this document. - NULL may be passed to ignore this field. - -referralsp This result parameter will be filled in with the contents - of the referrals field from the LDAPResult message, indi- - cating zero or more alternate LDAP servers where the - request should be retried. The referrals array should be - freed by calling ldap_value_free() which is described later - in this document. NULL may be passed to ignore this field. - -serverctrlsp This result parameter will be filled in with an allocated - array of controls copied out of the LDAPResult message. - The control array should be freed by calling - ldap_controls_free() which was described earlier. - -freeit A boolean that determines whether the res parameter is - disposed of or not. Pass any non-zero value to have these - routines free res after extracting the requested informa- - tion. This is provided as a convenience; you can also use - ldap_msgfree() to free the result later. - -servercredp For SASL bind results, this result parameter will be filled - in with the credentials passed back by the server for - mutual authentication, if given. An allocated berval struc- - ture is returned that should be disposed of by calling - ldap_ber_free(). NULL may be passed to ignore this field. - -resultoidp For extended results, this result parameter will be filled - in with the dotted-OID text representation of the name of - the extended operation response. This string should be - - - -Expires: January 1998 [Page 32] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - disposed of by calling ldap_memfree(). NULL may be passed - to ignore this field. - -resultdatap For extended results, this result parameter will be filled - in with a pointer to a struct berval containing the data in - the extended operation response. It should be disposed of - by calling ldap_ber_free(). NULL may be passed to ignore - this field. - -err For ldap_err2string(), an LDAP error code, as returned by - ldap_result2error() or another LDAP API call. - -Additional parameters for the deprecated routines are not described. -Interested readers are referred to RFC 1823. - -All of the ldap_parse_*_result() routines skip over messages of type -LDAP_RES_SEARCH_ENTRY and LDAP_RES_SEARCH_REFERENCE when looking for a -result message to parse. They return the constant LDAP_SUCCESS if the -result was successfully parsed and another LDAP error code if not. Note -that the LDAP error code that indicates the outcome of the operation -performed by the server is placed in the errcodep ldap_parse_result() -parameter. - -ldap_err2string() is used to convert a numeric LDAP error code, as -returned by one of the ldap_parse_*_result() routines, or one of the -synchronous API operation calls, into an informative NULL-terminated -character string message describing the error. It returns a pointer to -static data. - - -11. Stepping Through a List of Results - -The ldap_first_message() and ldap_next_message() routines are used to -step through the list of messages in a result chain returned by -ldap_result(). For search operations, the result chain may actually -include referral messages, entry messages, and result messages. -ldap_count_messages() is used to count the number of messages returned. -The ldap_msgtype() function, described above, can be used to distinguish -between the different message types. - - LDAPMessage *ldap_first_message( LDAP *ld, LDAPMessage *res ); - - LDAPMessage *ldap_next_message( LDAP *ld, LDAPMessage *msg ); - - int ldap_count_messages( LDAP *ld, LDAPMessage *res ); - -Parameters are: - - - - -Expires: January 1998 [Page 33] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -ld The session handle. - -res The result chain, as obtained by a call to one of the synchronous - search routines or ldap_result(). - -msg The message returned by a previous call to ldap_first_message() - or ldap_next_message(). - -ldap_first_message() and ldap_next_message() will return NULL when no -more messages exist in the result set to be returned. NULL is also -returned if an error occurs while stepping through the entries, in which -case the error parameters in the session handle ld will be set to indi- -cate the error. - -ldap_count_messages() returns the number of messages contained in a -chain of results. It can also be used to count the number of messages -that remain in a chain if called with a message, entry, or reference -returned by ldap_first_message(), ldap_next_message(), -ldap_first_entry(), ldap_next_entry(), ldap_first_reference(), -ldap_next_reference(). - - -12. Parsing Search Results - -The following calls are used to parse the entries and references -returned by ldap_search() and friends. These results are returned in an -opaque structure that should only be accessed by calling the routines -described below. Routines are provided to step through the entries and -references returned, step through the attributes of an entry, retrieve -the name of an entry, and retrieve the values associated with a given -attribute in an entry. - - -12.1. Stepping Through a List of Entries - -The ldap_first_entry() and ldap_next_entry() routines are used to step -through and retrieve the list of entries from a search result chain. -The ldap_first_reference() and ldap_next_reference() routines are used -to step through and retrieve the list of continuation references from a -search result chain. ldap_count_entries() is used to count the number -of entries returned. ldap_count_references() is used to count the number -of references returned. - - LDAPMessage *ldap_first_entry( LDAP *ld, LDAPMessage *res ); - - LDAPMessage *ldap_next_entry( LDAP *ld, LDAPMessage *entry ); - - LDAPMessage *ldap_first_reference( LDAP *ld, LDAPMessage *res ); - - - -Expires: January 1998 [Page 34] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - LDAPMessage *ldap_next_reference( LDAP *ld, LDAPMessage *ref ); - - int ldap_count_entries( LDAP *ld, LDAPMessage *res ); - - int ldap_count_references( LDAP *ld, LDAPMessage *res ); - -Parameters are: - -ld The session handle. - -res The search result, as obtained by a call to one of the synchro- - nous search routines or ldap_result(). - -entry The entry returned by a previous call to ldap_first_entry() or - ldap_next_entry(). - -ldap_first_entry() and ldap_next_entry() will return NULL when no more -entries or references exist in the result set to be returned. NULL is -also returned if an error occurs while stepping through the entries, in -which case the error parameters in the session handle ld will be set to -indicate the error. - -ldap_count_entries() returns the number of entries contained in a chain -of entries. It can also be used to count the number of entries that -remain in a chain if called with a message, entry or reference returned -by ldap_first_message(), ldap_next_message(), ldap_first_entry(), -ldap_next_entry(), ldap_first_reference(), ldap_next_reference(). - -ldap_count_references() returns the number of references contained in a -chain of search results. It can also be used to count the number of -references that remain in a chain. - - -12.2. Stepping Through the Attributes of an Entry - -The ldap_first_attribute() and ldap_next_attribute() calls are used to -step through the list of attribute types returned with an entry. - - char *ldap_first_attribute( - LDAP *ld, - LDAPMessage *entry, - BerElement **ptr - ); - - char *ldap_next_attribute( - LDAP *ld, - LDAPMessage *entry, - BerElement *ptr - - - -Expires: January 1998 [Page 35] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - ); - - void ldap_memfree( char *mem ); - -Parameters are: - -ld The session handle. - -entry The entry whose attributes are to be stepped through, as returned - by ldap_first_entry() or ldap_next_entry(). - -ptr In ldap_first_attribute(), the address of a pointer used inter- - nally to keep track of the current position in the entry. In - ldap_next_attribute(), the pointer returned by a previous call to - ldap_first_attribute(). - -mem A pointer to memory allocated by the LDAP library, such as the - attribute names returned by ldap_first_attribute() and - ldap_next_attribute, or the DN returned by ldap_get_dn(). - -ldap_first_attribute() and ldap_next_attribute() will return NULL when -the end of the attributes is reached, or if there is an error, in which -case the error parameters in the session handle ld will be set to indi- -cate the error. - -Both routines return a pointer to an allocated buffer containing the -current attribute name. This should be freed when no longer in use by -calling ldap_memfree(). - -ldap_first_attribute() will allocate and return in ptr a pointer to a -BerElement used to keep track of the current position. This pointer -should be passed in subsequent calls to ldap_next_attribute() to step -through the entry's attributes. After a set of calls to -ldap_first_attribute() and ldap_next_attibute(), if ptr is non-NULL, it -should be freed by calling ldap_ber_free( ptr, 0 ). Note that it is very -important to pass the second parameter as 0 (zero) in this call. - -The attribute names returned are suitable for passing in a call to -ldap_get_values() and friends to retrieve the associated values. - - -12.3. Retrieving the Values of an Attribute - -ldap_get_values() and ldap_get_values_len() are used to retrieve the -values of a given attribute from an entry. ldap_count_values() and -ldap_count_values_len() are used to count the returned values. -ldap_value_free() and ldap_value_free_len() are used to free the values. - - - - -Expires: January 1998 [Page 36] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - char **ldap_get_values( - LDAP *ld, - LDAPMessage *entry, - char *attr - ); - - struct berval **ldap_get_values_len( - LDAP *ld, - LDAPMessage *entry, - char *attr - ); - - int ldap_count_values( char **vals ); - - int ldap_count_values_len( struct berval **vals ); - - int ldap_value_free( char **vals ); - - int ldap_value_free_len( struct berval **vals ); - -Parameters are: - -ld The session handle. - -entry The entry from which to retrieve values, as returned by - ldap_first_entry() or ldap_next_entry(). - -attr The attribute whose values are to be retrieved, as returned by - ldap_first_attribute() or ldap_next_attribute(), or a caller- - supplied string (e.g., "mail"). - -vals The values returned by a previous call to ldap_get_values() or - ldap_get_values_len(). - -Two forms of the various calls are provided. The first form is only -suitable for use with non-binary character string data. The second _len -form is used with any kind of data. - -Note that the values returned are dynamically allocated and should be -freed by calling either ldap_value_free() or ldap_value_free_len() when -no longer in use. - - -12.4. Retrieving the name of an entry - -ldap_get_dn() is used to retrieve the name of an entry. -ldap_explode_dn() and ldap_explode_rdn() are used to break up a name -into its component parts. ldap_dn2ufn() is used to convert the name into - - - -Expires: January 1998 [Page 37] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -a more "user friendly" format. - - char *ldap_get_dn( LDAP *ld, LDAPMessage *entry ); - - char **ldap_explode_dn( char *dn, int notypes ); - - char **ldap_explode_rdn( char *rdn, int notypes ); - - char *ldap_dn2ufn( char *dn ); - -Parameters are: - -ld The session handle. - -entry The entry whose name is to be retrieved, as returned by - ldap_first_entry() or ldap_next_entry(). - -dn The dn to explode, such as returned by ldap_get_dn(). - -rdn The rdn to explode, such as returned in the components of the - array returned by ldap_explode_dn(). - -notypes A boolean parameter, if non-zero indicating that the dn or rdn - components should have their type information stripped off - (i.e., "cn=Babs" would become "Babs"). - -ldap_get_dn() will return NULL if there is some error parsing the dn, -setting error parameters in the session handle ld to indicate the error. -It returns a pointer to malloc'ed space that the caller should free by -calling ldap_memfree() when it is no longer in use. Note the format of -the DNs returned is given by [4]. - -ldap_explode_dn() returns a NULL-terminated char * array containing the -RDN components of the DN supplied, with or without types as indicated by -the notypes parameter. The array returned should be freed when it is no -longer in use by calling ldap_value_free(). - -ldap_explode_rdn() returns a NULL-terminated char * array containing the -components of the RDN supplied, with or without types as indicated by -the notypes parameter. The array returned should be freed when it is no -longer in use by calling ldap_value_free(). - -ldap_dn2ufn() converts the DN into the user friendly format described in -[5]. The UFN returned is malloc'ed space that should be freed by a call -to ldap_memfree() when no longer in use. - - - - - - -Expires: January 1998 [Page 38] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -13. Encoded ASN.1 Value Manipulation - -This section describes routines which may be used to encode and decode -BER-encoded ASN.1 values, which are often used inside of control and -extension values. - -With the exceptions of two new functions ber_flatten() and ber_init(), -these functions are compatible with the University of Michigan LDAP 3.3 -implementation of BER. - - -13.1. General - - struct berval { - unsigned long bv_len; - char *bv_val; - }; - -A struct berval contains a sequence of bytes and an indication of its -length. The bv_val is not null terminated. bv_len must always be a -nonnegative number. Applications may allocate their own berval struc- -tures. - - typedef struct berelement { - /* opaque */ - } BerElement; - -The BerElement structure contains not only a copy of the encoded value, -but also state information used in encoding or decoding. Applications -cannot allocate their own BerElement structures. The internal state is -neither thread-specific nor locked, so two threads should not manipulate -the same BerElement value simultaneously. - -A single BerElement value cannot be used for both encoding and decoding. - - void ber_bvfree ( struct berval *bv); - -ber_bvfree() frees a berval returned from this API. Both the bv->bv_val -string and the berval itself are freed. Applications should not use -ber_bvfree() with bervals which the application has allocated. - - void ber_bvecfree ( struct berval **bv ); - -ber_bvecfree() frees an array of bervals returned from this API. Each -of the bervals in the array are freed using ber_bvfree(), then the array -itself is freed. - - struct berval *ber_bvdup (struct berval *bv ); - - - -Expires: January 1998 [Page 39] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -ber_bvdup() returns a copy of a berval. The bv_val field in the -returned berval points to a different area of memory as the bv_val field -in the argument berval. The null pointer is returned on error (e.g. out -of memory). - - void ber_free ( BerElement *ber, int fbuf ); - -ber_free() frees a BerElement which is returned from the API calls -ber_alloc_t() or ber_init(). Each BerElement must be freed by the -caller. The second argument fbuf should always be set to 1. - - -13.2. Encoding - - BerElement *ber_alloc_t(int options); - -ber_alloc_t() constructs and returns BerElement. The null pointer is -returned on error. The options field contains a bitwise-or of options -which are to be used when generating the encoding of this BerElement. -One option is defined and must always be supplied: - - #define LBER_USE_DER 0x01 - -When this option is present, lengths will always be encoded in the -minimum number of octets. Note that this option does not cause values -of sets and sequences to be rearranged in tag and byte order, so these -functions are not suitable for generating DER output as defined in X.509 -and X.680. - -Unrecognized option bits are ignored. - -The BerElement returned by ber_alloc_t() is initially empty. Calls to -ber_printf() will append bytes to the end of the ber_alloc_t(). - - int ber_printf(BerElement *ber, char *fmt, ... ) - -The ber_printf() routine is used to encode a BER element in much the -same way that sprintf() works. One important difference, though, is -that state information is kept in the ber argument so that multiple -calls can be made to ber_printf() to append to the end of the BER ele- -ment. ber must be a pointer to a BerElement returned by ber_alloc_t(). -ber_printf() interprets and formats its arguments according to the for- -mat string fmt. ber_printf() returns -1 if there is an error during -encoding. As with sprintf(), each character in fmt refers to an argu- -ment to ber_printf(). - -The format string can contain the following format characters: - - - - -Expires: January 1998 [Page 40] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -'t' Tag. The next argument is an int specifying the tag to override - the next element to be written to the ber. This works across - calls. The int value must contain the tag class, constructed - bit, and tag value. The tag value must fit in a single octet - (tag value is less than 32). For example, a tag of "[3]" for a - constructed type is 0xA3. - -'b' Boolean. The next argument is an int, containing either 0 for - FALSE or 0xff for TRUE. A boolean element is output. If this - format character is not preceded by the 't' format modifier, the - tag 0x01 is used for the element. - -'i' Integer. The next argument is an int, containing the integer in - the host's byte order. An integer element is output. If this - format character is not preceded by the 't' format modifier, the - tag 0x02 is used for the element. - -'X' Bitstring. The next two arguments are a char * pointer to the - start of the bitstring, followed by an int containing the number - of bits in the bitstring. A bitstring element is output, in - primitive form. If this format character is not preceded by the - 't' format modifier, the tag 0x03 is used for the element. - -'n' Null. No argument is required. An ASN.1 NULL element is out- - put. If this format character is not preceded by the 't' format - modifier, the tag 0x05 is used for the element. - -'o' Octet string. The next two arguments are a char *, followed by - an int with the length of the string. The string may contain - null bytes and need not by null-terminated. An octet string - element is output, in primitive form. If this format character - is not preceded by the 't' format modifier, the tag 0x04 is used - for the element. - -'s' Octet string. The next argument is a char * pointing to a - null-terminated string. An octet string element in primitive - form is output, which does not include the trailing ' ' byte. If - this format character is not preceded by the 't' format modif- - ier, the tag 0x04 is used for the element. - -'v' Several octet strings. The next argument is a char **, an array - of char * pointers to null-terminated strings. The last element - in the array must be a null pointer. The octet strings do not - include the trailing SEQUENCE OF octet strings. The 't' format - modifier cannot be used with this format character. - -'V' Several octet strings. A null-terminated array of berval *'s is - supplied. Note that a construct like '{V}' is required to get an - - - -Expires: January 1998 [Page 41] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - actual SEQUENCE OF octet strings. The 't' format modifier cannot - be used with this format character. - -'{' Begin sequence. No argument is required. If this format char- - acter is not preceded by the 't' format modifier, the tag 0x30 - is used. - -'}' End sequence. No argument is required. The 't' format modifier - cannot be used with this format character. - -'[' Begin set. No argument is required. If this format character - is not preceded by the 't' format modifier, the tag 0x31 is - used. - -']' End set. No argument is required. The 't' format modifier can- - not be used with this format character. - -Each use of a '{' format character must be matched by a '}' character, -either later in the format string, or in the format string of a subse- -quent call to ber_printf() for that BerElement. The same applies to the -'[' and - -Sequences and sets nest, and implementations of this API must maintain -internal state to be able to properly calculate the lengths. - - int ber_flatten (BerElement *ber, struct berval **bvPtr); - -The ber_flatten routine allocates a struct berval whose contents are a -BER encoding taken from the ber argument. The bvPtr pointer points to -the returned berval, which must be freed using ber_bvfree(). This rou- -tine returns 0 on success and -1 on error. - -The ber_flatten API call is not present in U-M LDAP 3.3. - -The use of ber_flatten on a BerElement in which all '{' and '}' format -modifiers have not been properly matched can result in a berval whose -contents are not a valid BER encoding. - - -13.3. Encoding Example - -The following is an example of encoding the following ASN.1 data type: - - Example1Request ::= SEQUENCE { - s OCTET STRING, -- must be printable - val1 INTEGER, - val2 [0] INTEGER DEFAULT 0 - } - - - -Expires: January 1998 [Page 42] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - int encode_example1(char *s,int val1,int val2,struct berval **bvPtr) - { - BerElement *ber; - int rc; - - ber = ber_alloc_t(LBER_USE_DER); - - if (ber == NULL) return -1; - - if (ber_printf(ber,"{si",s,val1) == -1) { - ber_free(ber,1); - return -1; - } - - if (val2 != 0) { - if (ber_printf(ber,"ti",0x80,val2) == -1) { - ber_free(ber,1); - return -1; - } - } - - if (ber_printf(ber,"}") == -1) { - ber_free(ber,1); - return -1; - } - - rc = ber_flatten(ber,bvPtr); - ber_free(ber,1); - return -1; - } - - -13.4. Decoding - -The following two symbols are available to applications. - - #define LBER_ERROR 0xffffffffL - #define LBER_DEFAULT 0xffffffffL - - BerElement *ber_init (struct berval *bv); - -The ber_init functions construct BerElement and returns a new BerElement -containing a copy of the data in the bv argument. ber_init returns the -null pointer on error. - - unsigned long ber_scanf (BerElement *ber, char *fmt, ... ); - -The ber_scanf() routine is used to decode a BER element in much the same - - - -Expires: January 1998 [Page 43] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -way that sscanf() works. One important difference, though, is that some -state information is kept with the ber argument so that multiple calls -can be made to ber_scanf() to sequentially read from the BER element. -The ber argument must be a pointer to a BerElement returned by -ber_init(). ber_scanf interprets the bytes according to the format -string fmt, and stores the results in its additional arguments. -ber_scanf() returns LBER_ERROR on error, and a nonnegative number on -success. - -The format string contains conversion specifications which are used to -direct the interpretation of the BER element. The format string can -contain the following characters: - -'a' Octet string. A char ** argument should be supplied. Memory is - allocated, filled with the contents of the octet string, null- - terminated, and the pointer to the string is stored in the argu- - ment. The returned value must be freed using ldap_memfree. The - tag of the element must indicate the primitive form (constructed - strings are not supported) but is otherwise ignored and dis- - carded during the decoding. This format cannot be used with - octet strings which could contain null bytes. - -'O' Octet string. A struct berval ** argument should be supplied, - which upon return points to a allocated struct berval containing - the octet string and its length. ber_bvfree() must be called to - free the allocated memory. The tag of the element must indicate - the primitive form (constructed strings are not supported) but - is otherwise ignored during the decoding. - -'b' Boolean. A pointer to an int should be supplied. The int value - stored will be 0 for FALSE or nonzero for TRUE. The tag of the - element must indicate the primitive form but is otherwise - ignored during the decoding. - -'i' Integer. A pointer to an int should be supplied. The int value - stored will be in host byte order. The tag of the element must - indicate the primitive form but is otherwise ignored during the - decoding. ber_scanf() will return an error if the integer can- - not be stored in an int. - -'B' Bitstring. A char ** argument should be supplied which will - point to the allocated bits, followed by an unsigned long * - argument, which will point to the length (in bits) of the bit- - string returned. ldap_memfree must be called to free the bit- - string. The tag of the element must indicate the primitive form - (constructed bitstrings are not supported) but is otherwise - ignored during the decoding. - - - - -Expires: January 1998 [Page 44] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -'n' Null. No argument is required. The element is simply skipped - if it is recognized as a zero-length element. The tag is - ignored. - -'v' Several octet strings. A char *** argument should be supplied, - which upon return points to a allocated null-terminated array of - char *'s containing the octet strings. NULL is stored if the - sequence is empty. ldap_memfree must be called to free each - element of the array and the array itself. The tag of the - sequence and of the octet strings are ignored. - -'V' Several octet strings (which could contain null bytes). A - struct berval *** should be supplied, which upon return points - to a allocated null-terminated array of struct berval *'s con- - taining the octet strings and their lengths. NULL is stored if - the sequence is empty. ber_bvecfree() can be called to free the - allocated memory. The tag of the sequence and of the octet - strings are ignored. - -'x' Skip element. The next element is skipped. No argument is - required. - -'{' Begin sequence. No argument is required. The initial sequence - tag and length are skipped. - -'}' End sequence. No argument is required. - -'[' Begin set. No argument is required. The initial set tag and - length are skipped. - -']' End set. No argument is required. - - unsigned long ber_peek_tag (BerElement *ber, unsigned long *lenPtr); - -ber_peek_tag() returns the tag of the next element to be parsed in the -BerElement argument. The length of this element is stored in the -*lenPtr argument. LBER_DEFAULT is returned if there is no further data -to be read. The ber argument is not modified. - - unsigned long ber_skip_tag (BerElement *ber, unsigned long *lenPtr); - -ber_skip_tag() is similar to ber_peek_tag(), except that the state -pointer in the BerElement argument is advanced past the first tag and -length, and is pointed to the value part of the next element. This rou- -tine should only be used with constructed types and situations when a -BER encoding is used as the value of an OCTET STRING. The length of the -value is stored in *lenPtr. - - - - -Expires: January 1998 [Page 45] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - unsigned long ber_first_element(BerElement *ber, - unsigned long *lenPtr, char **opaquePtr); - - unsigned long ber_next_element (BerElement *ber, - unsigned long *lenPtr, char *opaque); - -ber_first_element() and ber_next_element() are used to traverse a SET, -SET OF, SEQUENCE or SEQUENCE OF data value. ber_first_element() calls -ber_skip_tag(), stores internal information in *lenPtr and *opaquePtr, -and calls ber_peek_tag() for the first element inside the constructed -value. LBER_DEFAULT is returned if the constructed value is empty. -ber_next_element() positions the state at the start of the next element -in the constructed type. LBER_DEFAULT is returned if there are no -further values. - -The len and opaque values should not be used by applications other than -as arguments to ber_next_element(), as shown in the example below. - - -13.5. Decoding Example - -The following is an example of decoding an ASN.1 data type: - - Example2Request ::= SEQUENCE { - dn OCTET STRING, -- must be printable - scope ENUMERATED { b (0), s (1), w (2) }, - ali ENUMERATED { n (0), s (1), f (2), a (3) }, - size INTEGER, - time INTEGER, - tonly BOOLEAN, - attrs SEQUENCE OF OCTET STRING, -- must be printable - [0] SEQUENCE OF SEQUENCE { - type OCTET STRING -- must be printable, - crit BOOLEAN DEFAULT FALSE, - value OCTET STRING - } OPTIONAL } - - #define LDAP_TAG_CONTROL_LIST 0xA0L /* context specific cons 0 */ - - int decode_example2(struct berval *bv) - { - BerElement *ber; - unsigned long len; - int scope, ali, size, time, tonly; - char *dn = NULL, **attrs = NULL; - int res,i,rc = 0; - - ber = ber_init(bv); - - - -Expires: January 1998 [Page 46] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - if (ber == NULL) { - printf("ERROR ber_init failed0); - return -1; - } - - res = ber_scanf(ber,"{aiiiiib{v}",&dn,&scope,&ali, - &size,&time,&tonly,&attrs); - - if (res == -1) { - printf("ERROR ber_scanf failed0); - ber_free(ber,1); - return -1; - } - - /* *** use dn */ - ldap_memfree(dn); - - for (i = 0; attrs != NULL && attrs[i] != NULL; i++) { - /* *** use attrs[i] */ - ldap_memfree(attrs[i]); - } - ldap_memfree(attrs); - - if (ber_peek_tag(ber,&len) == LDAP_TAG_CONTROL_LIST) { - char *opaque; - unsigned long tag; - - for (tag = ber_first_element(ber,&len,&opaque); - tag != LBER_DEFAULT; - tag = ber_next_element (ber,&len,opaque)) { - - unsigned long ttag, tlen; - char *type; - int crit; - struct berval *value; - - if (ber_scanf(ber,"{a",&type) == LBER_ERROR) { - printf("ERROR cannot parse type0); - break; - } - /* *** use type */ - ldap_memfree(type); - - ttag = ber_peek_tag(ber,&tlen); - if (ttag == 0x01) { /* boolean */ - if (ber_scanf(ber,"b", - &crit) == LBER_ERROR) { - printf("ERROR cannot parse crit0); - - - -Expires: January 1998 [Page 47] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - rc = -1; - break; - } - } else if (ttag == 0x04) { /* octet string */ - crit = 0; - } else { - printf("ERROR extra field in controls0); - break; - } - - if (ber_scanf(ber,"O}",&value) == LBER_ERROR) { - printf("ERROR cannot parse value0); - rc = -1; - break; - } - /* *** use value */ - ldap_bvfree(value); - } - } - - ber_scanf(ber,"}"); - - ber_free(ber,1); - - return rc; - } - - - -14. Security Considerations - -LDAPv2 supports security through protocol-level authentication using -clear-text passwords. LDAPv3 adds support for SASL [8] (Simple Authen- -tication Security Layer) methods. LDAPv3 also supports operation over a -secure transport layer using Transport Layer Security TLS [8]. Readers -are referred to the protocol documents for discussion of related secu- -rity considerations. - -Implementations of this API should be cautious when handling authentica- -tion credentials. In particular, keeping long-lived copies of creden- -tials without the application's knowledge is discouraged. - - -15. Acknowledgements - -Many members of the IETF ASID working group as well as members of the -Internet at large have provided useful comments and suggestions that -have been incorporated into this revision. - - - -Expires: January 1998 [Page 48] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -This original material upon which this revision is based was based upon -work supported by the National Science Foundation under Grant No. NCR- -9416667. - - -16. Bibliography - -[1] The Directory: Selected Attribute Syntaxes. CCITT, Recommendation - X.520. - -[2] M. Wahl, A. Coulbeck, T. Howes, S. Kille, W. Yeong, C. Robbins, - "Lightweight Directory Access Protocol Attribute Syntax Defini- - tions", INTERNET-DRAFT , - 11 July 1997. - -[3] T. Howes, "A String Representation of LDAP Search Filters," - INTERNET-DRAFT , May 1997. - -[4] S. Kille, M. Wahl, "A UTF-8 String Representation of Distinguished - Names", INTERNET-DRAFT , 29 April - 1997. - -[5] S. Kille, "Using the OSI Directory to Achieve User Friendly Nam- - ing," RFC 1781, March 1995. - -[6] M. Wahl, T. Howes, S. Kille, "Lightweight Directory Access Protocol - (v3)", INTERNET-DRAFT , 11 - July 1997. - -[7] A. Herron, T. Howes, M. Wahl, "LDAP Control Extension for Server - Side Sorting of Search Result," INTERNET-DRAFT , 16 April 1997. - -[8] J. Meyers, "Simple Authentication and Security Layer", INTERNET- - DRAFT , April 1997. - -[9] "Lightweight Directory Access Protocol (v3) Extension for Transport - Layer Security", INTERNET-DRAFT , June 1997. - -[10] "UTF-8, a transformation format of Unicode and ISO 10646", RFC - 2044, October 1996. - -[11] "IP Version 6 Addressing Architecture,", RFC 1884, December 1995. - - - - - - - -Expires: January 1998 [Page 49] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -17. Author's Addresses - - Tim Howes - Netscape Communications Corp. - 501 E. Middlefield Rd., Mailstop MV068 - Mountain View, CA 94043 - USA - +1 415 937-3419 - howes@netscape.com - - - Mark Smith - Netscape Communications Corp. - 501 E. Middlefield Rd., Mailstop MV068 - Mountain View, CA 94043 - USA - +1 415 937-3477 - mcs@netscape.com - - Andy Herron - Microsoft Corp. - 1 Microsoft Way - Redmond, WA 98052 - USA - +1 425 882-8080 - andyhe@microsoft.com - - Chris Weider - Microsoft Corp. - 1 Microsoft Way - Redmond, WA 98052 - USA - +1 425 882-8080 - cweider@microsoft.com - - Mark Wahl - Critical Angle Inc. - 4815 W Braker Lane #502-385 - Austin, TX 78759 - USA - M.Wahl@critical-angle.com - - -18. Appendix A - Sample LDAP API Code - - #include - - main() - - - -Expires: January 1998 [Page 50] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - { - LDAP *ld; - LDAPMessage *res, *e; - int i; - char *a, *dn; - BerElement *ptr; - char **vals; - - /* open an LDAP session */ - if ( (ld = ldap_init( "dotted.host.name", LDAP_PORT )) == NULL ) - exit( 1 ); - - /* authenticate as nobody */ - if ( ldap_simple_bind_s( ld, NULL, NULL ) != LDAP_SUCCESS ) { - ldap_perror( ld, "ldap_simple_bind_s" ); - exit( 1 ); - } - - /* search for entries with cn of "Babs Jensen", return all attrs */ - if ( ldap_search_s( ld, "o=University of Michigan, c=US", - LDAP_SCOPE_SUBTREE, "(cn=Babs Jensen)", NULL, 0, &res ) - != LDAP_SUCCESS ) { - ldap_perror( ld, "ldap_search_s" ); - exit( 1 ); - } - - /* step through each entry returned */ - for ( e = ldap_first_entry( ld, res ); e != NULL; - e = ldap_next_entry( ld, e ) ) { - /* print its name */ - dn = ldap_get_dn( ld, e ); - printf( "dn: %s\n", dn ); - ldap_memfree( dn ); - - /* print each attribute */ - for ( a = ldap_first_attribute( ld, e, &ptr ); a != NULL; - a = ldap_next_attribute( ld, e, ptr ) ) { - printf( "attribute: %s\n", a ); - - /* print each value */ - vals = ldap_get_values( ld, e, a ); - for ( i = 0; vals[i] != NULL; i++ ) { - printf( "value: %s\n", vals[i] ); - } - ldap_value_free( vals ); - } - if ( ptr != NULL ) { - ldap_ber_free( ptr, 0 ); - - - -Expires: January 1998 [Page 51] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - - } - } - /* free the search results */ - ldap_msgfree( res ); - - /* close and free connection resources */ - ldap_unbind( ld ); - } - - - -19. Appendix B - Outstanding Issues - - -19.1. Support for multithreaded applications - -In order to support multithreaded applications in a platform-independent -way, some additions to the LDAP API are needed. Different implementors -have taken different paths to solve this problem in the past. A common -set of thread-related API calls must be defined so that application -developers are not unduly burdened. These will be added to a future -revision of this specification. - - -19.2. Using Transport Layer Security (TLS) - -The API calls used to support TLS must be specified. They will be added -to a future revision of this specification. - - -19.3. Client control for chasing referrals - -A client control has been defined that can be used to specify on a per- -operation basis whether references and external referrals are automati- -cally chased by the client library. This will be added to a future -revision of this specification. - - -19.4. Potential confusion between hostname:port and IPv6 addresses - -String representations of IPv6 network addresses [11] can contain colon -characters. The ldap_init() call is specified to take strings of the -form "hostname:port" or "ipaddress:port". If IPv6 addresses are used, -the latter could be ambiguous. A future revision of this specification -will resolve this issue. - - - - - - -Expires: January 1998 [Page 52] - -C LDAP API The C LDAP Application Program Interface 29 July 1997 - - -19.5. Need to track SASL API standardization efforts - -If a standard Simple Authentication and Security Layer API is defined, -it may be necessary to modify the LDAP API to accommodate it. - - -19.6. Support for character sets other than UTF-8? - -Some application developers would prefer to pass string data using a -character set other than UTF-8. This could be accommodated by adding a -new option to ldap_set_option() that supports choosing a character set. -If this feature is added, the number of different character sets sup- -ported should definitely be minimized. - - -19.7. Use of UTF-8 with LDAPv2 servers - -Strings are always passed as UTF-8 in this API but LDAP version 2 -servers do not support the full range of UTF-8 characters. The expected -behavior of this API when using LDAP version 2 with unsupported charac- -ters should be specified. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Expires: January 1998 [Page 53] - - - -1. Status of this Memo............................................1 -2. Introduction...................................................1 -3. Overview of the LDAP Model.....................................2 -4. Overview of LDAP API Use.......................................3 -5. Common Data Structures.........................................4 -6. LDAP Error Codes...............................................5 -7. Performing LDAP Operations.....................................6 -7.1. Initializing an LDAP Session................................6 -7.2. LDAP Session Handle Options.................................7 -7.3. Working with controls.......................................10 -7.4. Authenticating to the directory.............................11 -7.5. Closing the session.........................................13 -7.6. Searching...................................................13 -7.7. Reading an Entry............................................17 -7.8. Listing the Children of an Entry............................17 -7.9. Comparing a Value Against an Entry..........................17 -7.10. Modifying an entry..........................................19 -7.11. Modifying the Name of an Entry..............................21 -7.12. Adding an entry.............................................23 -7.13. Deleting an entry...........................................25 -7.14. Extended Operations.........................................26 -8. Abandoning An Operation........................................28 -9. Obtaining Results and Peeking Inside LDAP Messages.............29 -10. Handling Errors and Parsing Results............................31 -11. Stepping Through a List of Results.............................33 -12. Parsing Search Results.........................................34 -12.1. Stepping Through a List of Entries..........................34 -12.2. Stepping Through the Attributes of an Entry.................35 -12.3. Retrieving the Values of an Attribute.......................36 -12.4. Retrieving the name of an entry.............................37 -13. Encoded ASN.1 Value Manipulation...............................39 -13.1. General.....................................................39 -13.2. Encoding....................................................40 -13.3. Encoding Example............................................42 -13.4. Decoding....................................................43 -13.5. Decoding Example............................................46 -14. Security Considerations........................................48 -15. Acknowledgements...............................................48 -16. Bibliography...................................................49 -17. Author's Addresses.............................................50 -18. Appendix A - Sample LDAP API Code..............................50 -19. Appendix B - Outstanding Issues................................52 -19.1. Support for multithreaded applications......................52 -19.2. Using Transport Layer Security (TLS)........................52 -19.3. Client control for chasing referrals........................52 -19.4. Potential confusion between hostname:port and IPv6 addresses52 -19.5. Need to track SASL API standardization efforts..............53 -19.6. Support for character sets other than UTF-8?................53 -19.7. Use of UTF-8 with LDAPv2 servers............................53 - - - - - - - - rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/LICENSE-MIT-eldap0000644000177700017770000000205212633765070024203 0ustar michaelmichael Copyright (c) 2010, Torbjorn Tornkvist 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. rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/CONTRIBUTING.md0000644000177700017770000000424512633765070023723 0ustar michaelmichael## Overview RabbitMQ projects use pull requests to discuss, collaborate on and accept code contributions. Pull requests is the primary place of discussing code changes. ## How to Contribute The process is fairly standard: * Fork the repository or repositories you plan on contributing to * Clone [RabbitMQ umbrella repository](https://github.com/rabbitmq/rabbitmq-public-umbrella) * `cd umbrella`, `make co` * Create a branch with a descriptive name in the relevant repositories * Make your changes, run tests, commit with a [descriptive message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), push to your fork * Submit pull requests with an explanation what has been changed and **why** * Submit a filled out and signed [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) if needed (see below) * Be patient. We will get to your pull request eventually If what you are going to work on is a substantial change, please first ask the core team of their opinion on [RabbitMQ mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). ## (Brief) Code of Conduct In one line: don't be a dick. Be respectful to the maintainers and other contributors. Open source contributors put long hours into developing projects and doing user support. Those projects and user support are available for free. We believe this deserves some respect. Be respectful to people of all races, genders, religious beliefs and political views. Regardless of how brilliant a pull request is technically, we will not tolerate disrespectful or aggressive behaviour. Contributors who violate this straightforward Code of Conduct will see their pull requests closed and locked. ## Contributor Agreement If you want to contribute a non-trivial change, please submit a signed copy of our [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) around the time you submit your pull request. This will make it much easier (in some cases, possible) for the RabbitMQ team at Pivotal to merge your contribution. ## Where to Ask Questions If something isn't clear, feel free to ask on our [mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/.srcdist_done0000644000177700017770000000000012633765070024134 0ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/eldap-wrapper/license_info0000644000177700017770000000021412633765070024042 0ustar michaelmichaelEldap is "Copyright (c) 2010, Torbjorn Tornkvist" and is covered by the MIT license. It was downloaded from https://github.com/etnt/eldap rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/hash.mk0000644000177700017770000000003512633765070022737 0ustar michaelmichaelUPSTREAM_SHORT_HASH:=e309de4 rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/Makefile0000644000177700017770000000002712633765070023124 0ustar michaelmichaelinclude ../umbrella.mk rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-appify.patch0000644000177700017770000000061312633765070025061 0ustar michaelmichaeldiff -Naur eldap.orig/ebin/eldap.app eldap/ebin/eldap.app --- eldap.orig/ebin/eldap.app 1970-01-01 01:00:00.000000000 +0100 +++ eldap/ebin/eldap.app 2011-01-20 12:47:04.377399296 +0000 @@ -0,0 +1,10 @@ +{application, eldap, + [{description, "LDAP Client Library"}, + {vsn, "0.01"}, + {modules, [ + eldap, + 'ELDAPv3' + ]}, + {registered, []}, + {applications, [kernel, stdlib]} + ]}. rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/package.mk0000644000177700017770000000165412633765070023417 0ustar michaelmichaelAPP_NAME:=eldap UPSTREAM_GIT:=https://github.com/rabbitmq/eldap.git UPSTREAM_REVISION:=e309de4db4b78d67d623 WRAPPER_PATCHES:=eldap-appify.patch remove-eldap-fsm.patch eldap-no-ssl-seed.patch remove-ietf-doc.patch ORIGINAL_APP_FILE:=$(CLONE_DIR)/ebin/$(APP_NAME).app DO_NOT_GENERATE_APP_FILE=true GENERATED_DIR:=$(CLONE_DIR)/generated PACKAGE_ERLC_OPTS+=-I $(GENERATED_DIR) INCLUDE_HRLS+=$(GENERATED_DIR)/ELDAPv3.hrl EBIN_BEAMS+=$(GENERATED_DIR)/ELDAPv3.beam define package_rules $(CLONE_DIR)/src/ELDAPv3.asn: $(CLONE_DIR)/.done $(GENERATED_DIR)/ELDAPv3.hrl $(GENERATED_DIR)/ELDAPv3.beam: $(CLONE_DIR)/src/ELDAPv3.asn @mkdir -p $(GENERATED_DIR) $(ERLC) $(PACKAGE_ERLC_OPTS) -o $(GENERATED_DIR) $$< $(PACKAGE_DIR)+clean:: rm -rf $(GENERATED_DIR) $(EBIN_DIR) # This rule is run *before* the one in do_package.mk $(PLUGINS_SRC_DIST_DIR)/$(PACKAGE_DIR)/.srcdist_done:: cp $(CLONE_DIR)/LICENSE $(PACKAGE_DIR)/LICENSE-MIT-eldap endef rabbitmq-server-3.5.7/plugins-src/eldap-wrapper/eldap-no-ssl-seed.patch0000644000177700017770000000114112633765070025717 0ustar michaelmichaeldiff --git a/src/eldap.erl b/src/eldap.erl index 9a78270..b0cdb2e 100644 --- a/src/eldap.erl +++ b/src/eldap.erl @@ -363,12 +363,5 @@ do_connect(Host, Data, Opts) when Data#eldap.use_tls == false -> gen_tcp:connect(Host, Data#eldap.port, Opts, Data#eldap.timeout); do_connect(Host, Data, Opts) when Data#eldap.use_tls == true -> - Vsn = erlang:system_info(version), - if Vsn >= "5.3" -> - %% In R9C, but not in R9B - {_,_,X} = erlang:now(), - ssl:seed("bkrlnateqqo" ++ integer_to_list(X)); - true -> true - end, ssl:connect(Host, Data#eldap.port, [{verify,0}|Opts]). rabbitmq-server-3.5.7/plugins-src/generate_app0000644000177700017770000000115612633765070021302 0ustar michaelmichael#!/usr/bin/env escript %% -*- erlang -*- main([InFile, OutFile | SrcDirs]) -> Modules = [list_to_atom(filename:basename(F, ".erl")) || SrcDir <- SrcDirs, F <- filelib:wildcard("*.erl", SrcDir)], {ok, [{application, Application, Properties}]} = file:consult(InFile), NewProperties = case proplists:get_value(modules, Properties) of [] -> lists:keyreplace(modules, 1, Properties, {modules, Modules}); _ -> Properties end, file:write_file( OutFile, io_lib:format("~p.~n", [{application, Application, NewProperties}])). rabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/0000755000177700017770000000000012633765070024753 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/priv/0000755000177700017770000000000012633765070025733 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/priv/www/0000755000177700017770000000000012633765070026557 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/priv/www/js/0000755000177700017770000000000012633765070027173 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/priv/www/js/tmpl/0000755000177700017770000000000012633765070030147 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/priv/www/js/tmpl/federation.ejs0000644000177700017770000000417012633765070032774 0ustar michaelmichael

    Federation Status

    Running Links

    <% if (links.length > 0) { %> <% if (vhosts_interesting) { %> <% } %> <% if (nodes_interesting) { %> <% } %> <% for (var i = 0; i < links.length; i++) { var link = links[i]; %> > <% if (vhosts_interesting) { %> <% } %> <% if (nodes_interesting) { %> <% } %> <% if (link.error) { %> <% if (vhosts_interesting) { %> <% } else { %> <% } %> <% } %>
    Upstream URIVirtual HostExchange / QueueNodeState Inbound message rate Last changed
    <%= fmt_string(link.upstream) %> <% if (link.type == 'exchange' && link.exchange != link.upstream_exchange) { %> <%= fmt_string(link.upstream_exchange) %> <% } else if (link.type == 'queue' && link.queue != link.upstream_queue) { %> <%= fmt_string(link.upstream_queue) %> <% } %> <%= fmt_string(link.uri) %><%= fmt_string(link.vhost) %> <% if (link.type == 'exchange') { %> <%= link_exchange(link.vhost, link.exchange) %> <% } else { %> <%= link_queue(link.vhost, link.queue) %> <% } %> <%= fmt_string(link.type) %> <%= fmt_node(link.node) %> <%= fmt_state('red', link.status) %> <%= link.timestamp %>
    <% } else { %> <% } %> Error detail:
    <%= fmt_escape_html(link.error) %>
    <%= fmt_state(link.status == 'starting' ? 'yellow' : 'green', link.status) %> <% if (link.local_channel) { %> <%= fmt_detail_rate(link.local_channel.message_stats, 'confirm') %> <% } %> <%= link.timestamp %>
    <% } else { %>

    ... no links ...

    <% } %>
    ././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/priv/www/js/tmpl/federation-upstream.ejsrabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/priv/www/js/tmpl/federation-upstrea0000644000177700017770000000314712633765070033700 0ustar michaelmichael

    Federation Upstream: <%= fmt_string(upstream.name) %><%= fmt_maybe_vhost(upstream.vhost) %>

    Overview

    URI <%= fmt_string(upstream.value.uri) %>
    Expires <%= fmt_time(upstream.value.expires, 'ms') %>
    Message TTL <%= fmt_time(upstream.value['message-ttl'], 'ms') %>
    Max Hops <%= fmt_string(upstream.value['max-hops']) %>
    Prefetch Count <%= fmt_string(upstream.value['prefetch-count']) %>
    Reconnect Delay <%= fmt_time(upstream.value['reconnect-delay'], 's') %>
    Ack Mode <%= fmt_string(upstream.value['ack-mode']) %>
    Trust User-ID <%= fmt_boolean(upstream.value['trust-user-id']) %>

    Delete this upstream

    ././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/priv/www/js/tmpl/federation-upstreams.ejsrabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/priv/www/js/tmpl/federation-upstrea0000644000177700017770000001311512633765070033674 0ustar michaelmichael

    Federation Upstreams

    Upstreams

    <% if (upstreams.length > 0) { %> <% if (vhosts_interesting) { %> <% } %> <% for (var i = 0; i < upstreams.length; i++) { var upstream = upstreams[i]; %> > <% if (vhosts_interesting) { %> <% } %> <% } %>
    Virtual HostName URI Expiry Message TTL Max Hops Prefetch Count Reconnect Delay Ack mode Trust User-ID
    <%= fmt_string(upstream.vhost) %><%= link_fed_conn(upstream.vhost, upstream.name) %> <%= fmt_shortened_uri(upstream.value.uri) %> <%= fmt_time(upstream.value.expires, 'ms') %> <%= fmt_time(upstream.value['message-ttl'], 'ms') %> <%= upstream.value['max-hops'] %> <%= upstream.value['prefetch-count'] %> <%= fmt_time(upstream.value['reconnect-delay'], 's') %> <%= fmt_string(upstream.value['ack-mode']) %> <%= fmt_boolean(upstream.value['trust-user-id']) %>
    <% } else { %>

    ... no upstreams ...

    <% } %>

    Add a new upstream

    <% if (vhosts_interesting) { %> <% } else { %> <% } %>
    *
    *
    ms
    ms
    s

    URI examples

    • amqp://server-name
      connect to server-name, without SSL and default credentials
    • amqp://user:password@server-name/my-vhost
      connect to server-name, with credentials and overridden virtual host
    • amqps://user:password@server-name?cacertfile=/path/to/cacert.pem&certfile=/path/to/cert.pem&keyfile=/path/to/key.pem&verify=verify_peer
      connect to server-name, with credentials and SSL
    • amqps://server-name?cacertfile=/path/to/cacert.pem&certfile=/path/to/cert.pem&keyfile=/path/to/key.pem&verify=verify_peer&fail_if_no_peer_cert=true&auth_mechanism=external
      connect to server-name, with SSL and EXTERNAL authentication
    rabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/priv/www/js/federation.js0000644000177700017770000000746212633765070031662 0ustar michaelmichaeldispatcher_add(function(sammy) { sammy.get('#/federation', function() { render({'links': {path: '/federation-links', options:{vhost:true}}, 'vhosts': '/vhosts'}, 'federation', '#/federation'); }); sammy.get('#/federation-upstreams', function() { render({'upstreams': {path: '/parameters/federation-upstream', options:{vhost:true}}, 'vhosts': '/vhosts', 'globals': '/parameters/federation'}, 'federation-upstreams', '#/federation-upstreams'); }); sammy.get('#/federation-upstreams/:vhost/:id', function() { render({'upstream': '/parameters/federation-upstream/' + esc(this.params['vhost']) + '/' + esc(this.params['id'])}, 'federation-upstream', '#/federation'); }); sammy.put('#/fed-parameters', function() { var num_keys = ['expires', 'message-ttl', 'max-hops', 'prefetch-count', 'reconnect-delay']; var bool_keys = ['trust-user-id']; var arrayable_keys = ['uri']; put_parameter(this, [], num_keys, bool_keys, arrayable_keys); return false; }); sammy.del('#/fed-parameters', function() { if (sync_delete(this, '/parameters/:component/:vhost/:name')) go_to('#/federation-upstreams'); return false; }); }); NAVIGATION['Admin'][0]['Federation Status'] = ['#/federation', "monitoring"]; NAVIGATION['Admin'][0]['Federation Upstreams'] = ['#/federation-upstreams', "policymaker"]; HELP['federation-uri'] = 'URI to connect to. If upstream is a cluster and can have several URIs, you can enter them here separated by spaces.'; HELP['federation-expires'] = 'Time in milliseconds that the upstream should remember about this node for. After this time all upstream state will be removed. Leave this blank to mean "forever".'; HELP['federation-ttl'] = 'Time in milliseconds that undelivered messages should be held upstream when there is a network outage or backlog. Leave this blank to mean "forever".'; HELP['federation-max-hops'] = 'Maximum number of federation links that messages can traverse before being dropped. Defaults to 1 if not set.'; HELP['federation-prefetch'] = 'Maximum number of unacknowledged messages that may be in flight over a federation link at one time. Defaults to 1000 if not set.'; HELP['federation-reconnect'] = 'Time in seconds to wait after a network link goes down before attempting reconnection. Defaults to 5 if not set.'; HELP['federation-ack-mode'] = '
    \
    on-confirm
    \
    Messages are acknowledged to the upstream broker after they have been confirmed downstream. Handles network errors and broker failures without losing messages. The slowest option, and the default.
    \
    on-publish
    \
    Messages are acknowledged to the upstream broker after they have been published downstream. Handles network errors without losing messages, but may lose messages in the event of broker failures.
    \
    no-ack
    \
    Message acknowledgements are not used. The fastest option, but may lose messages in the event of network or broker failures.
    \
    '; HELP['federation-trust-user-id'] = 'Set "Yes" to preserve the "user-id" field across a federation link, even if the user-id does not match that used to republish the message. Set to "No" to clear the "user-id" field when messages are federated. Only set this to "Yes" if you trust the upstream broker not to forge user-ids.'; function link_fed_conn(vhost, name) { return _link_to(name, '#/federation-upstreams/' + esc(vhost) + '/' + esc(name)); } rabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/src/0000755000177700017770000000000012633765070025542 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/src/rabbit_federation_mgmt.erl0000644000177700017770000000647112633765070032745 0ustar michaelmichael%% The contents of this file are subject to the Mozilla Public License %% Version 1.1 (the "License"); you may not use this file except in %% compliance with the License. You may obtain a copy of the License %% at http://www.mozilla.org/MPL/ %% %% 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 Original Code is RabbitMQ. %% %% The Initial Developer of the Original Code is GoPivotal, Inc. %% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved. %% -module(rabbit_federation_mgmt). -behaviour(rabbit_mgmt_extension). -export([dispatcher/0, web_ui/0]). -export([init/1, to_json/2, resource_exists/2, content_types_provided/2, is_authorized/2]). -import(rabbit_misc, [pget/2]). -include_lib("rabbitmq_management/include/rabbit_mgmt.hrl"). -include_lib("webmachine/include/webmachine.hrl"). dispatcher() -> [{["federation-links"], ?MODULE, []}, {["federation-links", vhost], ?MODULE, []}]. web_ui() -> [{javascript, <<"federation.js">>}]. %%-------------------------------------------------------------------- init(_Config) -> {ok, #context{}}. content_types_provided(ReqData, Context) -> {[{"application/json", to_json}], ReqData, Context}. resource_exists(ReqData, Context) -> {case rabbit_mgmt_util:vhost(ReqData) of not_found -> false; _ -> true end, ReqData, Context}. to_json(ReqData, Context) -> Chs = rabbit_mgmt_db:get_all_channels( rabbit_mgmt_util:range(ReqData)), rabbit_mgmt_util:reply_list( filter_vhost(status(Chs, ReqData, Context), ReqData), ReqData, Context). is_authorized(ReqData, Context) -> rabbit_mgmt_util:is_authorized_monitor(ReqData, Context). %%-------------------------------------------------------------------- filter_vhost(List, ReqData) -> rabbit_mgmt_util:all_or_one_vhost( ReqData, fun(V) -> lists:filter(fun(I) -> pget(vhost, I) =:= V end, List) end). status(Chs, ReqData, Context) -> rabbit_mgmt_util:filter_vhost( lists:append([status(Node, Chs) || Node <- [node() | nodes()]]), ReqData, Context). status(Node, Chs) -> case rpc:call(Node, rabbit_federation_status, status, [], infinity) of {badrpc, {'EXIT', {undef, _}}} -> []; {badrpc, {'EXIT', {noproc, _}}} -> []; Status -> [format(Node, I, Chs) || I <- Status] end. format(Node, Info, Chs) -> LocalCh = case rabbit_mgmt_format:strip_pids( [Ch || Ch <- Chs, pget(name, pget(connection_details, Ch)) =:= pget(local_connection, Info)]) of [Ch] -> [{local_channel, Ch}]; [] -> [] end, [{node, Node} | format_info(Info)] ++ LocalCh. format_info(Items) -> [format_item(I) || I <- Items]. format_item({timestamp, {{Y, M, D}, {H, Min, S}}}) -> {timestamp, print("~w-~2.2.0w-~2.2.0w ~w:~2.2.0w:~2.2.0w", [Y, M, D, H, Min, S])}; format_item({error, E}) -> {error, rabbit_mgmt_format:print("~p", [E])}; format_item(I) -> I. print(Fmt, Val) -> list_to_binary(io_lib:format(Fmt, Val)). ././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/src/rabbitmq_federation_management.app.srcrabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/src/rabbitmq_federation_management.0000644000177700017770000000034412633765070033741 0ustar michaelmichael{application, rabbitmq_federation_management, [{description, "RabbitMQ Federation Management"}, {vsn, "%%VSN%%"}, {modules, []}, {registered, []}, {env, []}, {applications, [kernel, stdlib, rabbitmq_management]} ]}. rabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/README0000644000177700017770000000047312633765070025637 0ustar michaelmichaelAdds information on federation link status to the management plugin. Build it like any other plugin. If you have a heterogenous cluster (where the nodes have different plugins installed), this should be installed on the same nodes as the management plugin. The HTTP API is very simple: GET /api/federation-links. rabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/CONTRIBUTING.md0000644000177700017770000000424512633765070027211 0ustar michaelmichael## Overview RabbitMQ projects use pull requests to discuss, collaborate on and accept code contributions. Pull requests is the primary place of discussing code changes. ## How to Contribute The process is fairly standard: * Fork the repository or repositories you plan on contributing to * Clone [RabbitMQ umbrella repository](https://github.com/rabbitmq/rabbitmq-public-umbrella) * `cd umbrella`, `make co` * Create a branch with a descriptive name in the relevant repositories * Make your changes, run tests, commit with a [descriptive message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), push to your fork * Submit pull requests with an explanation what has been changed and **why** * Submit a filled out and signed [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) if needed (see below) * Be patient. We will get to your pull request eventually If what you are going to work on is a substantial change, please first ask the core team of their opinion on [RabbitMQ mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). ## (Brief) Code of Conduct In one line: don't be a dick. Be respectful to the maintainers and other contributors. Open source contributors put long hours into developing projects and doing user support. Those projects and user support are available for free. We believe this deserves some respect. Be respectful to people of all races, genders, religious beliefs and political views. Regardless of how brilliant a pull request is technically, we will not tolerate disrespectful or aggressive behaviour. Contributors who violate this straightforward Code of Conduct will see their pull requests closed and locked. ## Contributor Agreement If you want to contribute a non-trivial change, please submit a signed copy of our [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) around the time you submit your pull request. This will make it much easier (in some cases, possible) for the RabbitMQ team at Pivotal to merge your contribution. ## Where to Ask Questions If something isn't clear, feel free to ask on our [mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). rabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/.srcdist_done0000644000177700017770000000000012633765070027422 0ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/Makefile0000644000177700017770000000002712633765070026412 0ustar michaelmichaelinclude ../umbrella.mk rabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/ebin/0000755000177700017770000000000012633765070025670 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/rabbitmq-federation-management/package.mk0000644000177700017770000000026712633765070026704 0ustar michaelmichaelRELEASABLE:=true DEPS:=rabbitmq-management CONSTRUCT_APP_PREREQS:=$(shell find $(PACKAGE_DIR)/priv -type f) define construct_app_commands cp -r $(PACKAGE_DIR)/priv $(APP_DIR) endef rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/0000755000177700017770000000000012633765070022175 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/CONTRIBUTING.md0000644000177700017770000000424512633765070024433 0ustar michaelmichael## Overview RabbitMQ projects use pull requests to discuss, collaborate on and accept code contributions. Pull requests is the primary place of discussing code changes. ## How to Contribute The process is fairly standard: * Fork the repository or repositories you plan on contributing to * Clone [RabbitMQ umbrella repository](https://github.com/rabbitmq/rabbitmq-public-umbrella) * `cd umbrella`, `make co` * Create a branch with a descriptive name in the relevant repositories * Make your changes, run tests, commit with a [descriptive message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), push to your fork * Submit pull requests with an explanation what has been changed and **why** * Submit a filled out and signed [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) if needed (see below) * Be patient. We will get to your pull request eventually If what you are going to work on is a substantial change, please first ask the core team of their opinion on [RabbitMQ mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). ## (Brief) Code of Conduct In one line: don't be a dick. Be respectful to the maintainers and other contributors. Open source contributors put long hours into developing projects and doing user support. Those projects and user support are available for free. We believe this deserves some respect. Be respectful to people of all races, genders, religious beliefs and political views. Regardless of how brilliant a pull request is technically, we will not tolerate disrespectful or aggressive behaviour. Contributors who violate this straightforward Code of Conduct will see their pull requests closed and locked. ## Contributor Agreement If you want to contribute a non-trivial change, please submit a signed copy of our [Contributor Agreement](https://github.com/rabbitmq/ca#how-to-submit) around the time you submit your pull request. This will make it much easier (in some cases, possible) for the RabbitMQ team at Pivotal to merge your contribution. ## Where to Ask Questions If something isn't clear, feel free to ask on our [mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users). rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/20-MAX_RECV_BODY.patch0000644000177700017770000000064712633765070025525 0ustar michaelmichaeldiff --git a/src/mochiweb_request.erl b/src/mochiweb_request.erl index 5d89662..6765ab0 100644 --- a/src/mochiweb_request.erl +++ b/src/mochiweb_request.erl @@ -42,7 +42,7 @@ -define(IDLE_TIMEOUT, 300000). % Maximum recv_body() length of 1MB --define(MAX_RECV_BODY, (1024*1024)). +-define(MAX_RECV_BODY, 104857600). %% @spec get_header_value(K) -> undefined | Value %% @doc Get the value of a given request header. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/LICENSE-MIT-Mochi0000644000177700017770000000207712633765070024674 0ustar michaelmichaelThis is the MIT license. Copyright (c) 2007 Mochi Media, Inc. 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. ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootrabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/40-remove-compiler-syntax_tools-dependencies.patchrabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/40-remove-compiler-syntax_tools-dependencies.patc0000644000177700017770000000663612633765070033577 0ustar michaelmichaeldiff --git a/src/mochiglobal.erl b/src/mochiglobal.erl deleted file mode 100644 index 6b20e41..0000000 --- a/src/mochiglobal.erl +++ /dev/null @@ -1,107 +0,0 @@ -%% @author Bob Ippolito -%% @copyright 2010 Mochi Media, Inc. -%% @doc Abuse module constant pools as a "read-only shared heap" (since erts 5.6) -%% [1]. --module(mochiglobal). --author("Bob Ippolito "). --export([get/1, get/2, put/2, delete/1]). - -%% -spec get(atom()) -> any() | undefined. -%% @equiv get(K, undefined) -get(K) -> - get(K, undefined). - -%% -spec get(atom(), T) -> any() | T. -%% @doc Get the term for K or return Default. -get(K, Default) -> - get(K, Default, key_to_module(K)). - -get(_K, Default, Mod) -> - try Mod:term() - catch error:undef -> - Default - end. - -%% -spec put(atom(), any()) -> ok. -%% @doc Store term V at K, replaces an existing term if present. -put(K, V) -> - put(K, V, key_to_module(K)). - -put(_K, V, Mod) -> - Bin = compile(Mod, V), - code:purge(Mod), - {module, Mod} = code:load_binary(Mod, atom_to_list(Mod) ++ ".erl", Bin), - ok. - -%% -spec delete(atom()) -> boolean(). -%% @doc Delete term stored at K, no-op if non-existent. -delete(K) -> - delete(K, key_to_module(K)). - -delete(_K, Mod) -> - code:purge(Mod), - code:delete(Mod). - -%% -spec key_to_module(atom()) -> atom(). -key_to_module(K) -> - list_to_atom("mochiglobal:" ++ atom_to_list(K)). - -%% -spec compile(atom(), any()) -> binary(). -compile(Module, T) -> - {ok, Module, Bin} = compile:forms(forms(Module, T), - [verbose, report_errors]), - Bin. - -%% -spec forms(atom(), any()) -> [erl_syntax:syntaxTree()]. -forms(Module, T) -> - [erl_syntax:revert(X) || X <- term_to_abstract(Module, term, T)]. - -%% -spec term_to_abstract(atom(), atom(), any()) -> [erl_syntax:syntaxTree()]. -term_to_abstract(Module, Getter, T) -> - [%% -module(Module). - erl_syntax:attribute( - erl_syntax:atom(module), - [erl_syntax:atom(Module)]), - %% -export([Getter/0]). - erl_syntax:attribute( - erl_syntax:atom(export), - [erl_syntax:list( - [erl_syntax:arity_qualifier( - erl_syntax:atom(Getter), - erl_syntax:integer(0))])]), - %% Getter() -> T. - erl_syntax:function( - erl_syntax:atom(Getter), - [erl_syntax:clause([], none, [erl_syntax:abstract(T)])])]. - -%% -%% Tests -%% --ifdef(TEST). --include_lib("eunit/include/eunit.hrl"). -get_put_delete_test() -> - K = '$$test$$mochiglobal', - delete(K), - ?assertEqual( - bar, - get(K, bar)), - try - ?MODULE:put(K, baz), - ?assertEqual( - baz, - get(K, bar)), - ?MODULE:put(K, wibble), - ?assertEqual( - wibble, - ?MODULE:get(K)) - after - delete(K) - end, - ?assertEqual( - bar, - get(K, bar)), - ?assertEqual( - undefined, - ?MODULE:get(K)), - ok. --endif. diff --git a/src/mochiweb.app.src b/src/mochiweb.app.src index c98d8a0..4a6808e 100644 --- a/src/mochiweb.app.src +++ b/src/mochiweb.app.src @@ -5,5 +5,4 @@ {modules, []}, {registered, []}, {env, []}, - {applications, [kernel, stdlib, inets, xmerl, - compiler, syntax_tools]}]}. + {applications, [kernel, stdlib, inets, xmerl]}]}. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/.srcdist_done0000644000177700017770000000000012633765070024644 0ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/license_info0000644000177700017770000000022112633765070024550 0ustar michaelmichaelMochiweb is "Copyright (c) 2007 Mochi Media, Inc." and is covered by the MIT license. It was downloaded from http://github.com/mochi/mochiweb/ rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/hash.mk0000644000177700017770000000003512633765070023447 0ustar michaelmichaelUPSTREAM_SHORT_HASH:=680dba8 rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/Makefile0000644000177700017770000000002712633765070023634 0ustar michaelmichaelinclude ../umbrella.mk rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/0000755000177700017770000000000012633765070024553 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/scripts/0000755000177700017770000000000012633765070026242 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/scripts/entities.erl0000755000177700017770000000262112633765070030576 0ustar michaelmichael#!/usr/bin/env escript %% -*- mode: erlang -*- -export([main/1]). %% @doc Script used to generate mochiweb_charref.erl table. main(_) -> application:start(inets), code:add_patha("ebin"), {ok, {_, _, HTML}} = httpc:request("http://www.w3.org/TR/html5/named-character-references.html"), print(lists:sort(search(mochiweb_html:parse(HTML)))). print([F | T]) -> io:put_chars([clause(F), ";\n"]), print(T); print([]) -> io:put_chars(["entity(_) -> undefined.\n"]), ok. clause({Title, [Codepoint]}) -> ["entity(\"", Title, "\") -> 16#", Codepoint]; clause({Title, [First | Rest]}) -> ["entity(\"", Title, "\") -> [16#", First, [[", 16#", Codepoint] || Codepoint <- Rest], "]"]. search(Elem) -> search(Elem, []). search({<<"tr">>, [{<<"id">>, <<"entity-", _/binary>>} | _], Children}, Acc) -> %% HTML5 charrefs can have more than one code point(!) [{<<"td">>, _, [{<<"code">>, _, [TitleSemi]}]}, {<<"td">>, [], [RawCPs]} | _] = Children, L = byte_size(TitleSemi) - 1, <> = TitleSemi, {match, Matches} = re:run(RawCPs, "(?:\\s*U\\+)([a-fA-F0-9]+)", [{capture, all, binary}, global]), [{Title, [CP || [_, CP] <- Matches]} | Acc]; search({Tag, Attrs, [H | T]}, Acc) -> search({Tag, Attrs, T}, search(H, Acc)); search({_Tag, _Attrs, []}, Acc) -> Acc; search(<<_/binary>>, Acc) -> Acc. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/scripts/new_mochiweb.erl0000755000177700017770000000101012633765070031407 0ustar michaelmichael#!/usr/bin/env escript %% -*- mode: erlang -*- -export([main/1]). %% External API main(_) -> usage(). %% Internal API usage() -> io:format( "new_mochiweb.erl has been replaced by a rebar template!\n" "\n" "To create a new mochiweb using project:\n" " make app PROJECT=project_name\n" "\n" "To create a new mochiweb using project in a specific directory:\n" " make app PROJECT=project_name PREFIX=$HOME/projects/\n" "\n" ), halt(1). rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/CHANGES.md0000644000177700017770000000651212633765070026151 0ustar michaelmichaelVersion 2.7.0 released XXXX-XX-XX * `mochiweb_socket_server:stop/1` is now a synchronous call instead of an asynchronous cast * `mochiweb_html:parse_tokens/1` (and `parse/1`) will now create a html element to wrap documents that have a HTML5 doctype (``) but no html element https://github.com/mochi/mochiweb/issues/110 Version 2.6.0 released 2013-04-15 * Enable R15B gen_tcp workaround only on R15B https://github.com/mochi/mochiweb/pull/107 Version 2.5.0 released 2013-03-04 * Replace now() with os:timestamp() in acceptor (optimization) https://github.com/mochi/mochiweb/pull/102 * New mochiweb_session module for managing session cookies. NOTE: this module is only supported on R15B02 and later! https://github.com/mochi/mochiweb/pull/94 * New mochiweb_base64url module for base64url encoding (URL and Filename safe alphabet, see RFC 4648). * Fix rebar.config in mochiwebapp_skel to use {branch, "master"} https://github.com/mochi/mochiweb/issues/105 Version 2.4.2 released 2013-02-05 * Fixed issue in mochiweb_response introduced in v2.4.0 https://github.com/mochi/mochiweb/pull/100 Version 2.4.1 released 2013-01-30 * Fixed issue in mochiweb_request introduced in v2.4.0 https://github.com/mochi/mochiweb/issues/97 * Fixed issue in mochifmt_records introduced in v2.4.0 https://github.com/mochi/mochiweb/issues/96 Version 2.4.0 released 2013-01-23 * Switch from parameterized modules to explicit tuple module calls for R16 compatibility (#95) * Fix for mochiweb_acceptor crash with extra-long HTTP headers under R15B02 (#91) * Fix case in handling range headers (#85) * Handle combined Content-Length header (#88) * Windows security fix for `safe_relative_path`, any path with a backslash on any platform is now considered unsafe (#92) Version 2.3.2 released 2012-07-27 * Case insensitive match for "Connection: close" (#81) Version 2.3.1 released 2012-03-31 * Fix edoc warnings (#63) * Fix mochiweb_html handling of invalid charref sequences (unescaped &) (#69). * Add a manual garbage collection between requests to avoid worst case behavior on keep-alive sockets. * Fix dst cookie bug (#73) * Removed unnecessary template_dir option, see https://github.com/basho/rebar/issues/203 Version 2.3.0 released 2011-10-14 * Handle ssl_closed message in mochiweb_http (#59) * Added support for new MIME types (otf, eot, m4v, svg, svgz, ttc, ttf, vcf, webm, webp, woff) (#61) * Updated mochiweb_charref to support all HTML5 entities. Note that if you are using this module directly, the spec has changed to return `[integer()]` for some entities. (#64) Version 2.2.1 released 2011-08-31 * Removed `mochiweb_skel` module from the pre-rebar era Version 2.2.0 released 2011-08-29 * Added new `mochiweb_http:start_link/1` and `mochiweb_socket_server:start_link/1` APIs to explicitly start linked servers. Also added `{link, false}` option to the `start/1` variants to explicitly start unlinked. This is in expectation that we will eventually change the default behavior of `start/1` to be unlinked as you would expect it to. See https://github.com/mochi/mochiweb/issues/58 for discussion. Version 2.1.0 released 2011-08-29 * Added new `mochijson2:decode/2` with `{format, struct | proplist | eep18}` options for easy decoding to various proplist formats. Also added encoding support for eep18 style objects. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/0000755000177700017770000000000012633765070025342 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb_base64url.erl0000644000177700017770000000614712633765070031542 0ustar michaelmichael-module(mochiweb_base64url). -export([encode/1, decode/1]). %% @doc URL and filename safe base64 variant with no padding, %% also known as "base64url" per RFC 4648. %% %% This differs from base64 in the following ways: %% '-' is used in place of '+' (62), %% '_' is used in place of '/' (63), %% padding is implicit rather than explicit ('='). -spec encode(iolist()) -> binary(). encode(B) when is_binary(B) -> encode_binary(B); encode(L) when is_list(L) -> encode_binary(iolist_to_binary(L)). -spec decode(iolist()) -> binary(). decode(B) when is_binary(B) -> decode_binary(B); decode(L) when is_list(L) -> decode_binary(iolist_to_binary(L)). %% Implementation, derived from stdlib base64.erl %% One-based decode map. -define(DECODE_MAP, {bad,bad,bad,bad,bad,bad,bad,bad,ws,ws,bad,bad,ws,bad,bad, %1-15 bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad, %16-31 ws,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,62,bad,bad, %32-47 52,53,54,55,56,57,58,59,60,61,bad,bad,bad,bad,bad,bad, %48-63 bad,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14, %64-79 15,16,17,18,19,20,21,22,23,24,25,bad,bad,bad,bad,63, %80-95 bad,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, %96-111 41,42,43,44,45,46,47,48,49,50,51,bad,bad,bad,bad,bad, %112-127 bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad, bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad, bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad, bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad, bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad, bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad, bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad, bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad,bad}). encode_binary(Bin) -> Split = 3*(byte_size(Bin) div 3), <> = Bin, Main = << <<(b64e(C)):8>> || <> <= Main0 >>, case Rest of <> -> <
    >; <> -> <
    >; <<>> -> Main end. decode_binary(Bin) -> Main = << <<(b64d(C)):6>> || <> <= Bin, (C =/= $\t andalso C =/= $\s andalso C =/= $\r andalso C =/= $\n) >>, case bit_size(Main) rem 8 of 0 -> Main; N -> Split = byte_size(Main) - 1, <> = Main, Result end. %% accessors b64e(X) -> element(X+1, {$A, $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L, $M, $N, $O, $P, $Q, $R, $S, $T, $U, $V, $W, $X, $Y, $Z, $a, $b, $c, $d, $e, $f, $g, $h, $i, $j, $k, $l, $m, $n, $o, $p, $q, $r, $s, $t, $u, $v, $w, $x, $y, $z, $0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $-, $_}). b64d(X) -> b64d_ok(element(X, ?DECODE_MAP)). b64d_ok(I) when is_integer(I) -> I. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb_acceptor.erl0000644000177700017770000000244012633765070031523 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2010 Mochi Media, Inc. %% @doc MochiWeb acceptor. -module(mochiweb_acceptor). -author('bob@mochimedia.com'). -include("internal.hrl"). -export([start_link/3, init/3]). start_link(Server, Listen, Loop) -> proc_lib:spawn_link(?MODULE, init, [Server, Listen, Loop]). init(Server, Listen, Loop) -> T1 = os:timestamp(), case catch mochiweb_socket:accept(Listen) of {ok, Socket} -> gen_server:cast(Server, {accepted, self(), timer:now_diff(os:timestamp(), T1)}), call_loop(Loop, Socket); {error, closed} -> exit(normal); {error, timeout} -> init(Server, Listen, Loop); {error, esslaccept} -> exit(normal); Other -> error_logger:error_report( [{application, mochiweb}, "Accept failed error", lists:flatten(io_lib:format("~p", [Other]))]), exit({error, accept_failed}) end. call_loop({M, F}, Socket) -> M:F(Socket); call_loop({M, F, [A1]}, Socket) -> M:F(Socket, A1); call_loop({M, F, A}, Socket) -> erlang:apply(M, F, [Socket | A]); call_loop(Loop, Socket) -> Loop(Socket). %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb_multipart.erl0000644000177700017770000010666312633765070031760 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2007 Mochi Media, Inc. %% @doc Utilities for parsing multipart/form-data. -module(mochiweb_multipart). -author('bob@mochimedia.com'). -export([parse_form/1, parse_form/2]). -export([parse_multipart_request/2]). -export([parts_to_body/3, parts_to_multipart_body/4]). -export([default_file_handler/2]). -define(CHUNKSIZE, 4096). -record(mp, {state, boundary, length, buffer, callback, req}). %% TODO: DOCUMENT THIS MODULE. %% @type key() = atom() | string() | binary(). %% @type value() = atom() | iolist() | integer(). %% @type header() = {key(), value()}. %% @type bodypart() = {Start::integer(), End::integer(), Body::iolist()}. %% @type formfile() = {Name::string(), ContentType::string(), Content::binary()}. %% @type request(). %% @type file_handler() = (Filename::string(), ContentType::string()) -> file_handler_callback(). %% @type file_handler_callback() = (binary() | eof) -> file_handler_callback() | term(). %% @spec parts_to_body([bodypart()], ContentType::string(), %% Size::integer()) -> {[header()], iolist()} %% @doc Return {[header()], iolist()} representing the body for the given %% parts, may be a single part or multipart. parts_to_body([{Start, End, Body}], ContentType, Size) -> HeaderList = [{"Content-Type", ContentType}, {"Content-Range", ["bytes ", mochiweb_util:make_io(Start), "-", mochiweb_util:make_io(End), "/", mochiweb_util:make_io(Size)]}], {HeaderList, Body}; parts_to_body(BodyList, ContentType, Size) when is_list(BodyList) -> parts_to_multipart_body(BodyList, ContentType, Size, mochihex:to_hex(mochiweb_util:rand_bytes(8))). %% @spec parts_to_multipart_body([bodypart()], ContentType::string(), %% Size::integer(), Boundary::string()) -> %% {[header()], iolist()} %% @doc Return {[header()], iolist()} representing the body for the given %% parts, always a multipart response. parts_to_multipart_body(BodyList, ContentType, Size, Boundary) -> HeaderList = [{"Content-Type", ["multipart/byteranges; ", "boundary=", Boundary]}], MultiPartBody = multipart_body(BodyList, ContentType, Boundary, Size), {HeaderList, MultiPartBody}. %% @spec multipart_body([bodypart()], ContentType::string(), %% Boundary::string(), Size::integer()) -> iolist() %% @doc Return the representation of a multipart body for the given [bodypart()]. multipart_body([], _ContentType, Boundary, _Size) -> ["--", Boundary, "--\r\n"]; multipart_body([{Start, End, Body} | BodyList], ContentType, Boundary, Size) -> ["--", Boundary, "\r\n", "Content-Type: ", ContentType, "\r\n", "Content-Range: ", "bytes ", mochiweb_util:make_io(Start), "-", mochiweb_util:make_io(End), "/", mochiweb_util:make_io(Size), "\r\n\r\n", Body, "\r\n" | multipart_body(BodyList, ContentType, Boundary, Size)]. %% @spec parse_form(request()) -> [{string(), string() | formfile()}] %% @doc Parse a multipart form from the given request using the in-memory %% default_file_handler/2. parse_form(Req) -> parse_form(Req, fun default_file_handler/2). %% @spec parse_form(request(), F::file_handler()) -> [{string(), string() | term()}] %% @doc Parse a multipart form from the given request using the given file_handler(). parse_form(Req, FileHandler) -> Callback = fun (Next) -> parse_form_outer(Next, FileHandler, []) end, {_, _, Res} = parse_multipart_request(Req, Callback), Res. parse_form_outer(eof, _, Acc) -> lists:reverse(Acc); parse_form_outer({headers, H}, FileHandler, State) -> {"form-data", H1} = proplists:get_value("content-disposition", H), Name = proplists:get_value("name", H1), Filename = proplists:get_value("filename", H1), case Filename of undefined -> fun (Next) -> parse_form_value(Next, {Name, []}, FileHandler, State) end; _ -> ContentType = proplists:get_value("content-type", H), Handler = FileHandler(Filename, ContentType), fun (Next) -> parse_form_file(Next, {Name, Handler}, FileHandler, State) end end. parse_form_value(body_end, {Name, Acc}, FileHandler, State) -> Value = binary_to_list(iolist_to_binary(lists:reverse(Acc))), State1 = [{Name, Value} | State], fun (Next) -> parse_form_outer(Next, FileHandler, State1) end; parse_form_value({body, Data}, {Name, Acc}, FileHandler, State) -> Acc1 = [Data | Acc], fun (Next) -> parse_form_value(Next, {Name, Acc1}, FileHandler, State) end. parse_form_file(body_end, {Name, Handler}, FileHandler, State) -> Value = Handler(eof), State1 = [{Name, Value} | State], fun (Next) -> parse_form_outer(Next, FileHandler, State1) end; parse_form_file({body, Data}, {Name, Handler}, FileHandler, State) -> H1 = Handler(Data), fun (Next) -> parse_form_file(Next, {Name, H1}, FileHandler, State) end. default_file_handler(Filename, ContentType) -> default_file_handler_1(Filename, ContentType, []). default_file_handler_1(Filename, ContentType, Acc) -> fun(eof) -> Value = iolist_to_binary(lists:reverse(Acc)), {Filename, ContentType, Value}; (Next) -> default_file_handler_1(Filename, ContentType, [Next | Acc]) end. parse_multipart_request(Req, Callback) -> %% TODO: Support chunked? Length = list_to_integer(Req:get_combined_header_value("content-length")), Boundary = iolist_to_binary( get_boundary(Req:get_header_value("content-type"))), Prefix = <<"\r\n--", Boundary/binary>>, BS = byte_size(Boundary), Chunk = read_chunk(Req, Length), Length1 = Length - byte_size(Chunk), <<"--", Boundary:BS/binary, "\r\n", Rest/binary>> = Chunk, feed_mp(headers, flash_multipart_hack(#mp{boundary=Prefix, length=Length1, buffer=Rest, callback=Callback, req=Req})). parse_headers(<<>>) -> []; parse_headers(Binary) -> parse_headers(Binary, []). parse_headers(Binary, Acc) -> case find_in_binary(<<"\r\n">>, Binary) of {exact, N} -> <> = Binary, parse_headers(Rest, [split_header(Line) | Acc]); not_found -> lists:reverse([split_header(Binary) | Acc]) end. split_header(Line) -> {Name, [$: | Value]} = lists:splitwith(fun (C) -> C =/= $: end, binary_to_list(Line)), {string:to_lower(string:strip(Name)), mochiweb_util:parse_header(Value)}. read_chunk(Req, Length) when Length > 0 -> case Length of Length when Length < ?CHUNKSIZE -> Req:recv(Length); _ -> Req:recv(?CHUNKSIZE) end. read_more(State=#mp{length=Length, buffer=Buffer, req=Req}) -> Data = read_chunk(Req, Length), Buffer1 = <>, flash_multipart_hack(State#mp{length=Length - byte_size(Data), buffer=Buffer1}). flash_multipart_hack(State=#mp{length=0, buffer=Buffer, boundary=Prefix}) -> %% http://code.google.com/p/mochiweb/issues/detail?id=22 %% Flash doesn't terminate multipart with \r\n properly so we fix it up here PrefixSize = size(Prefix), case size(Buffer) - (2 + PrefixSize) of Seek when Seek >= 0 -> case Buffer of <<_:Seek/binary, Prefix:PrefixSize/binary, "--">> -> Buffer1 = <>, State#mp{buffer=Buffer1}; _ -> State end; _ -> State end; flash_multipart_hack(State) -> State. feed_mp(headers, State=#mp{buffer=Buffer, callback=Callback}) -> {State1, P} = case find_in_binary(<<"\r\n\r\n">>, Buffer) of {exact, N} -> {State, N}; _ -> S1 = read_more(State), %% Assume headers must be less than ?CHUNKSIZE {exact, N} = find_in_binary(<<"\r\n\r\n">>, S1#mp.buffer), {S1, N} end, <> = State1#mp.buffer, NextCallback = Callback({headers, parse_headers(Headers)}), feed_mp(body, State1#mp{buffer=Rest, callback=NextCallback}); feed_mp(body, State=#mp{boundary=Prefix, buffer=Buffer, callback=Callback}) -> Boundary = find_boundary(Prefix, Buffer), case Boundary of {end_boundary, Start, Skip} -> <> = Buffer, C1 = Callback({body, Data}), C2 = C1(body_end), {State#mp.length, Rest, C2(eof)}; {next_boundary, Start, Skip} -> <> = Buffer, C1 = Callback({body, Data}), feed_mp(headers, State#mp{callback=C1(body_end), buffer=Rest}); {maybe, Start} -> <> = Buffer, feed_mp(body, read_more(State#mp{callback=Callback({body, Data}), buffer=Rest})); not_found -> {Data, Rest} = {Buffer, <<>>}, feed_mp(body, read_more(State#mp{callback=Callback({body, Data}), buffer=Rest})) end. get_boundary(ContentType) -> {"multipart/form-data", Opts} = mochiweb_util:parse_header(ContentType), case proplists:get_value("boundary", Opts) of S when is_list(S) -> S end. %% @spec find_in_binary(Pattern::binary(), Data::binary()) -> %% {exact, N} | {partial, N, K} | not_found %% @doc Searches for the given pattern in the given binary. find_in_binary(P, Data) when size(P) > 0 -> PS = size(P), DS = size(Data), case DS - PS of Last when Last < 0 -> partial_find(P, Data, 0, DS); Last -> case binary:match(Data, P) of {Pos, _} -> {exact, Pos}; nomatch -> partial_find(P, Data, Last+1, PS-1) end end. partial_find(_B, _D, _N, 0) -> not_found; partial_find(B, D, N, K) -> <> = B, case D of <<_Skip:N/binary, B1:K/binary>> -> {partial, N, K}; _ -> partial_find(B, D, 1 + N, K - 1) end. find_boundary(Prefix, Data) -> case find_in_binary(Prefix, Data) of {exact, Skip} -> PrefixSkip = Skip + size(Prefix), case Data of <<_:PrefixSkip/binary, "\r\n", _/binary>> -> {next_boundary, Skip, size(Prefix) + 2}; <<_:PrefixSkip/binary, "--\r\n", _/binary>> -> {end_boundary, Skip, size(Prefix) + 4}; _ when size(Data) < PrefixSkip + 4 -> %% Underflow {maybe, Skip}; _ -> %% False positive not_found end; {partial, Skip, Length} when (Skip + Length) =:= size(Data) -> %% Underflow {maybe, Skip}; _ -> not_found end. %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). ssl_cert_opts() -> EbinDir = filename:dirname(code:which(?MODULE)), CertDir = filename:join([EbinDir, "..", "support", "test-materials"]), CertFile = filename:join(CertDir, "test_ssl_cert.pem"), KeyFile = filename:join(CertDir, "test_ssl_key.pem"), [{certfile, CertFile}, {keyfile, KeyFile}]. with_socket_server(Transport, ServerFun, ClientFun) -> ServerOpts0 = [{ip, "127.0.0.1"}, {port, 0}, {loop, ServerFun}], ServerOpts = case Transport of plain -> ServerOpts0; ssl -> ServerOpts0 ++ [{ssl, true}, {ssl_opts, ssl_cert_opts()}] end, {ok, Server} = mochiweb_socket_server:start_link(ServerOpts), Port = mochiweb_socket_server:get(Server, port), ClientOpts = [binary, {active, false}], {ok, Client} = case Transport of plain -> gen_tcp:connect("127.0.0.1", Port, ClientOpts); ssl -> ClientOpts1 = [{ssl_imp, new} | ClientOpts], {ok, SslSocket} = ssl:connect("127.0.0.1", Port, ClientOpts1), {ok, {ssl, SslSocket}} end, Res = (catch ClientFun(Client)), mochiweb_socket_server:stop(Server), Res. fake_request(Socket, ContentType, Length) -> mochiweb_request:new(Socket, 'POST', "/multipart", {1,1}, mochiweb_headers:make( [{"content-type", ContentType}, {"content-length", Length}])). test_callback({body, <<>>}, Rest=[body_end | _]) -> %% When expecting the body_end we might get an empty binary fun (Next) -> test_callback(Next, Rest) end; test_callback({body, Got}, [{body, Expect} | Rest]) when Got =/= Expect -> %% Partial response GotSize = size(Got), <> = Expect, fun (Next) -> test_callback(Next, [{body, Expect1} | Rest]) end; test_callback(Got, [Expect | Rest]) -> ?assertEqual(Got, Expect), case Rest of [] -> ok; _ -> fun (Next) -> test_callback(Next, Rest) end end. parse3_http_test() -> parse3(plain). parse3_https_test() -> parse3(ssl). parse3(Transport) -> ContentType = "multipart/form-data; boundary=---------------------------7386909285754635891697677882", BinContent = <<"-----------------------------7386909285754635891697677882\r\nContent-Disposition: form-data; name=\"hidden\"\r\n\r\nmultipart message\r\n-----------------------------7386909285754635891697677882\r\nContent-Disposition: form-data; name=\"file\"; filename=\"test_file.txt\"\r\nContent-Type: text/plain\r\n\r\nWoo multiline text file\n\nLa la la\r\n-----------------------------7386909285754635891697677882--\r\n">>, Expect = [{headers, [{"content-disposition", {"form-data", [{"name", "hidden"}]}}]}, {body, <<"multipart message">>}, body_end, {headers, [{"content-disposition", {"form-data", [{"name", "file"}, {"filename", "test_file.txt"}]}}, {"content-type", {"text/plain", []}}]}, {body, <<"Woo multiline text file\n\nLa la la">>}, body_end, eof], TestCallback = fun (Next) -> test_callback(Next, Expect) end, ServerFun = fun (Socket) -> ok = mochiweb_socket:send(Socket, BinContent), exit(normal) end, ClientFun = fun (Socket) -> Req = fake_request(Socket, ContentType, byte_size(BinContent)), Res = parse_multipart_request(Req, TestCallback), {0, <<>>, ok} = Res, ok end, ok = with_socket_server(Transport, ServerFun, ClientFun), ok. parse2_http_test() -> parse2(plain). parse2_https_test() -> parse2(ssl). parse2(Transport) -> ContentType = "multipart/form-data; boundary=---------------------------6072231407570234361599764024", BinContent = <<"-----------------------------6072231407570234361599764024\r\nContent-Disposition: form-data; name=\"hidden\"\r\n\r\nmultipart message\r\n-----------------------------6072231407570234361599764024\r\nContent-Disposition: form-data; name=\"file\"; filename=\"\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----------------------------6072231407570234361599764024--\r\n">>, Expect = [{headers, [{"content-disposition", {"form-data", [{"name", "hidden"}]}}]}, {body, <<"multipart message">>}, body_end, {headers, [{"content-disposition", {"form-data", [{"name", "file"}, {"filename", ""}]}}, {"content-type", {"application/octet-stream", []}}]}, {body, <<>>}, body_end, eof], TestCallback = fun (Next) -> test_callback(Next, Expect) end, ServerFun = fun (Socket) -> ok = mochiweb_socket:send(Socket, BinContent), exit(normal) end, ClientFun = fun (Socket) -> Req = fake_request(Socket, ContentType, byte_size(BinContent)), Res = parse_multipart_request(Req, TestCallback), {0, <<>>, ok} = Res, ok end, ok = with_socket_server(Transport, ServerFun, ClientFun), ok. parse_form_http_test() -> do_parse_form(plain). parse_form_https_test() -> do_parse_form(ssl). do_parse_form(Transport) -> ContentType = "multipart/form-data; boundary=AaB03x", "AaB03x" = get_boundary(ContentType), Content = mochiweb_util:join( ["--AaB03x", "Content-Disposition: form-data; name=\"submit-name\"", "", "Larry", "--AaB03x", "Content-Disposition: form-data; name=\"files\";" ++ "filename=\"file1.txt\"", "Content-Type: text/plain", "", "... contents of file1.txt ...", "--AaB03x--", ""], "\r\n"), BinContent = iolist_to_binary(Content), ServerFun = fun (Socket) -> ok = mochiweb_socket:send(Socket, BinContent), exit(normal) end, ClientFun = fun (Socket) -> Req = fake_request(Socket, ContentType, byte_size(BinContent)), Res = parse_form(Req), [{"submit-name", "Larry"}, {"files", {"file1.txt", {"text/plain",[]}, <<"... contents of file1.txt ...">>} }] = Res, ok end, ok = with_socket_server(Transport, ServerFun, ClientFun), ok. parse_http_test() -> do_parse(plain). parse_https_test() -> do_parse(ssl). do_parse(Transport) -> ContentType = "multipart/form-data; boundary=AaB03x", "AaB03x" = get_boundary(ContentType), Content = mochiweb_util:join( ["--AaB03x", "Content-Disposition: form-data; name=\"submit-name\"", "", "Larry", "--AaB03x", "Content-Disposition: form-data; name=\"files\";" ++ "filename=\"file1.txt\"", "Content-Type: text/plain", "", "... contents of file1.txt ...", "--AaB03x--", ""], "\r\n"), BinContent = iolist_to_binary(Content), Expect = [{headers, [{"content-disposition", {"form-data", [{"name", "submit-name"}]}}]}, {body, <<"Larry">>}, body_end, {headers, [{"content-disposition", {"form-data", [{"name", "files"}, {"filename", "file1.txt"}]}}, {"content-type", {"text/plain", []}}]}, {body, <<"... contents of file1.txt ...">>}, body_end, eof], TestCallback = fun (Next) -> test_callback(Next, Expect) end, ServerFun = fun (Socket) -> ok = mochiweb_socket:send(Socket, BinContent), exit(normal) end, ClientFun = fun (Socket) -> Req = fake_request(Socket, ContentType, byte_size(BinContent)), Res = parse_multipart_request(Req, TestCallback), {0, <<>>, ok} = Res, ok end, ok = with_socket_server(Transport, ServerFun, ClientFun), ok. parse_partial_body_boundary_http_test() -> parse_partial_body_boundary(plain). parse_partial_body_boundary_https_test() -> parse_partial_body_boundary(ssl). parse_partial_body_boundary(Transport) -> Boundary = string:copies("$", 2048), ContentType = "multipart/form-data; boundary=" ++ Boundary, ?assertEqual(Boundary, get_boundary(ContentType)), Content = mochiweb_util:join( ["--" ++ Boundary, "Content-Disposition: form-data; name=\"submit-name\"", "", "Larry", "--" ++ Boundary, "Content-Disposition: form-data; name=\"files\";" ++ "filename=\"file1.txt\"", "Content-Type: text/plain", "", "... contents of file1.txt ...", "--" ++ Boundary ++ "--", ""], "\r\n"), BinContent = iolist_to_binary(Content), Expect = [{headers, [{"content-disposition", {"form-data", [{"name", "submit-name"}]}}]}, {body, <<"Larry">>}, body_end, {headers, [{"content-disposition", {"form-data", [{"name", "files"}, {"filename", "file1.txt"}]}}, {"content-type", {"text/plain", []}} ]}, {body, <<"... contents of file1.txt ...">>}, body_end, eof], TestCallback = fun (Next) -> test_callback(Next, Expect) end, ServerFun = fun (Socket) -> ok = mochiweb_socket:send(Socket, BinContent), exit(normal) end, ClientFun = fun (Socket) -> Req = fake_request(Socket, ContentType, byte_size(BinContent)), Res = parse_multipart_request(Req, TestCallback), {0, <<>>, ok} = Res, ok end, ok = with_socket_server(Transport, ServerFun, ClientFun), ok. parse_large_header_http_test() -> parse_large_header(plain). parse_large_header_https_test() -> parse_large_header(ssl). parse_large_header(Transport) -> ContentType = "multipart/form-data; boundary=AaB03x", "AaB03x" = get_boundary(ContentType), Content = mochiweb_util:join( ["--AaB03x", "Content-Disposition: form-data; name=\"submit-name\"", "", "Larry", "--AaB03x", "Content-Disposition: form-data; name=\"files\";" ++ "filename=\"file1.txt\"", "Content-Type: text/plain", "x-large-header: " ++ string:copies("%", 4096), "", "... contents of file1.txt ...", "--AaB03x--", ""], "\r\n"), BinContent = iolist_to_binary(Content), Expect = [{headers, [{"content-disposition", {"form-data", [{"name", "submit-name"}]}}]}, {body, <<"Larry">>}, body_end, {headers, [{"content-disposition", {"form-data", [{"name", "files"}, {"filename", "file1.txt"}]}}, {"content-type", {"text/plain", []}}, {"x-large-header", {string:copies("%", 4096), []}} ]}, {body, <<"... contents of file1.txt ...">>}, body_end, eof], TestCallback = fun (Next) -> test_callback(Next, Expect) end, ServerFun = fun (Socket) -> ok = mochiweb_socket:send(Socket, BinContent), exit(normal) end, ClientFun = fun (Socket) -> Req = fake_request(Socket, ContentType, byte_size(BinContent)), Res = parse_multipart_request(Req, TestCallback), {0, <<>>, ok} = Res, ok end, ok = with_socket_server(Transport, ServerFun, ClientFun), ok. find_boundary_test() -> B = <<"\r\n--X">>, {next_boundary, 0, 7} = find_boundary(B, <<"\r\n--X\r\nRest">>), {next_boundary, 1, 7} = find_boundary(B, <<"!\r\n--X\r\nRest">>), {end_boundary, 0, 9} = find_boundary(B, <<"\r\n--X--\r\nRest">>), {end_boundary, 1, 9} = find_boundary(B, <<"!\r\n--X--\r\nRest">>), not_found = find_boundary(B, <<"--X\r\nRest">>), {maybe, 0} = find_boundary(B, <<"\r\n--X\r">>), {maybe, 1} = find_boundary(B, <<"!\r\n--X\r">>), P = <<"\r\n-----------------------------16037454351082272548568224146">>, B0 = <<55,212,131,77,206,23,216,198,35,87,252,118,252,8,25,211,132,229, 182,42,29,188,62,175,247,243,4,4,0,59, 13,10,45,45,45,45,45,45,45, 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45, 49,54,48,51,55,52,53,52,51,53,49>>, {maybe, 30} = find_boundary(P, B0), not_found = find_boundary(B, <<"\r\n--XJOPKE">>), ok. find_in_binary_test() -> {exact, 0} = find_in_binary(<<"foo">>, <<"foobarbaz">>), {exact, 1} = find_in_binary(<<"oo">>, <<"foobarbaz">>), {exact, 8} = find_in_binary(<<"z">>, <<"foobarbaz">>), not_found = find_in_binary(<<"q">>, <<"foobarbaz">>), {partial, 7, 2} = find_in_binary(<<"azul">>, <<"foobarbaz">>), {exact, 0} = find_in_binary(<<"foobarbaz">>, <<"foobarbaz">>), {partial, 0, 3} = find_in_binary(<<"foobar">>, <<"foo">>), {partial, 1, 3} = find_in_binary(<<"foobar">>, <<"afoo">>), ok. flash_parse_http_test() -> flash_parse(plain). flash_parse_https_test() -> flash_parse(ssl). flash_parse(Transport) -> ContentType = "multipart/form-data; boundary=----------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5", "----------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5" = get_boundary(ContentType), BinContent = <<"------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"Filename\"\r\n\r\nhello.txt\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"success_action_status\"\r\n\r\n201\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"file\"; filename=\"hello.txt\"\r\nContent-Type: application/octet-stream\r\n\r\nhello\n\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"Upload\"\r\n\r\nSubmit Query\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5--">>, Expect = [{headers, [{"content-disposition", {"form-data", [{"name", "Filename"}]}}]}, {body, <<"hello.txt">>}, body_end, {headers, [{"content-disposition", {"form-data", [{"name", "success_action_status"}]}}]}, {body, <<"201">>}, body_end, {headers, [{"content-disposition", {"form-data", [{"name", "file"}, {"filename", "hello.txt"}]}}, {"content-type", {"application/octet-stream", []}}]}, {body, <<"hello\n">>}, body_end, {headers, [{"content-disposition", {"form-data", [{"name", "Upload"}]}}]}, {body, <<"Submit Query">>}, body_end, eof], TestCallback = fun (Next) -> test_callback(Next, Expect) end, ServerFun = fun (Socket) -> ok = mochiweb_socket:send(Socket, BinContent), exit(normal) end, ClientFun = fun (Socket) -> Req = fake_request(Socket, ContentType, byte_size(BinContent)), Res = parse_multipart_request(Req, TestCallback), {0, <<>>, ok} = Res, ok end, ok = with_socket_server(Transport, ServerFun, ClientFun), ok. flash_parse2_http_test() -> flash_parse2(plain). flash_parse2_https_test() -> flash_parse2(ssl). flash_parse2(Transport) -> ContentType = "multipart/form-data; boundary=----------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5", "----------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5" = get_boundary(ContentType), Chunk = iolist_to_binary(string:copies("%", 4096)), BinContent = <<"------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"Filename\"\r\n\r\nhello.txt\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"success_action_status\"\r\n\r\n201\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"file\"; filename=\"hello.txt\"\r\nContent-Type: application/octet-stream\r\n\r\n", Chunk/binary, "\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"Upload\"\r\n\r\nSubmit Query\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5--">>, Expect = [{headers, [{"content-disposition", {"form-data", [{"name", "Filename"}]}}]}, {body, <<"hello.txt">>}, body_end, {headers, [{"content-disposition", {"form-data", [{"name", "success_action_status"}]}}]}, {body, <<"201">>}, body_end, {headers, [{"content-disposition", {"form-data", [{"name", "file"}, {"filename", "hello.txt"}]}}, {"content-type", {"application/octet-stream", []}}]}, {body, Chunk}, body_end, {headers, [{"content-disposition", {"form-data", [{"name", "Upload"}]}}]}, {body, <<"Submit Query">>}, body_end, eof], TestCallback = fun (Next) -> test_callback(Next, Expect) end, ServerFun = fun (Socket) -> ok = mochiweb_socket:send(Socket, BinContent), exit(normal) end, ClientFun = fun (Socket) -> Req = fake_request(Socket, ContentType, byte_size(BinContent)), Res = parse_multipart_request(Req, TestCallback), {0, <<>>, ok} = Res, ok end, ok = with_socket_server(Transport, ServerFun, ClientFun), ok. parse_headers_test() -> ?assertEqual([], parse_headers(<<>>)). flash_multipart_hack_test() -> Buffer = <<"prefix-">>, Prefix = <<"prefix">>, State = #mp{length=0, buffer=Buffer, boundary=Prefix}, ?assertEqual(State, flash_multipart_hack(State)). parts_to_body_single_test() -> {HL, B} = parts_to_body([{0, 5, <<"01234">>}], "text/plain", 10), [{"Content-Range", Range}, {"Content-Type", Type}] = lists:sort(HL), ?assertEqual( <<"bytes 0-5/10">>, iolist_to_binary(Range)), ?assertEqual( <<"text/plain">>, iolist_to_binary(Type)), ?assertEqual( <<"01234">>, iolist_to_binary(B)), ok. parts_to_body_multi_test() -> {[{"Content-Type", Type}], _B} = parts_to_body([{0, 5, <<"01234">>}, {5, 10, <<"56789">>}], "text/plain", 10), ?assertMatch( <<"multipart/byteranges; boundary=", _/binary>>, iolist_to_binary(Type)), ok. parts_to_multipart_body_test() -> {[{"Content-Type", V}], B} = parts_to_multipart_body( [{0, 5, <<"01234">>}, {5, 10, <<"56789">>}], "text/plain", 10, "BOUNDARY"), MB = multipart_body( [{0, 5, <<"01234">>}, {5, 10, <<"56789">>}], "text/plain", "BOUNDARY", 10), ?assertEqual( <<"multipart/byteranges; boundary=BOUNDARY">>, iolist_to_binary(V)), ?assertEqual( iolist_to_binary(MB), iolist_to_binary(B)), ok. multipart_body_test() -> ?assertEqual( <<"--BOUNDARY--\r\n">>, iolist_to_binary(multipart_body([], "text/plain", "BOUNDARY", 0))), ?assertEqual( <<"--BOUNDARY\r\n" "Content-Type: text/plain\r\n" "Content-Range: bytes 0-5/10\r\n\r\n" "01234\r\n" "--BOUNDARY\r\n" "Content-Type: text/plain\r\n" "Content-Range: bytes 5-10/10\r\n\r\n" "56789\r\n" "--BOUNDARY--\r\n">>, iolist_to_binary(multipart_body([{0, 5, <<"01234">>}, {5, 10, <<"56789">>}], "text/plain", "BOUNDARY", 10))), ok. %% @todo Move somewhere more appropriate than in the test suite multipart_parsing_benchmark_test() -> run_multipart_parsing_benchmark(1). run_multipart_parsing_benchmark(0) -> ok; run_multipart_parsing_benchmark(N) -> multipart_parsing_benchmark(), run_multipart_parsing_benchmark(N-1). multipart_parsing_benchmark() -> ContentType = "multipart/form-data; boundary=----------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5", Chunk = binary:copy(<<"This Is_%Some=Quite0Long4String2Used9For7BenchmarKing.5">>, 102400), BinContent = <<"------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"Filename\"\r\n\r\nhello.txt\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"success_action_status\"\r\n\r\n201\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"file\"; filename=\"hello.txt\"\r\nContent-Type: application/octet-stream\r\n\r\n", Chunk/binary, "\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5\r\nContent-Disposition: form-data; name=\"Upload\"\r\n\r\nSubmit Query\r\n------------ei4GI3GI3Ij5Ef1ae0KM7Ij5ei4Ij5--">>, Expect = [{headers, [{"content-disposition", {"form-data", [{"name", "Filename"}]}}]}, {body, <<"hello.txt">>}, body_end, {headers, [{"content-disposition", {"form-data", [{"name", "success_action_status"}]}}]}, {body, <<"201">>}, body_end, {headers, [{"content-disposition", {"form-data", [{"name", "file"}, {"filename", "hello.txt"}]}}, {"content-type", {"application/octet-stream", []}}]}, {body, Chunk}, body_end, {headers, [{"content-disposition", {"form-data", [{"name", "Upload"}]}}]}, {body, <<"Submit Query">>}, body_end, eof], TestCallback = fun (Next) -> test_callback(Next, Expect) end, ServerFun = fun (Socket) -> ok = mochiweb_socket:send(Socket, BinContent), exit(normal) end, ClientFun = fun (Socket) -> Req = fake_request(Socket, ContentType, byte_size(BinContent)), Res = parse_multipart_request(Req, TestCallback), {0, <<>>, ok} = Res, ok end, ok = with_socket_server(plain, ServerFun, ClientFun), ok. -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb.app.src0000644000177700017770000000035112633765070030426 0ustar michaelmichael%% This is generated from src/mochiweb.app.src {application, mochiweb, [{description, "MochiMedia Web Server"}, {vsn, "2.7.0"}, {modules, []}, {registered, []}, {env, []}, {applications, [kernel, stdlib, inets, xmerl]}]}. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb.erl0000644000177700017770000000473512633765070027654 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2007 Mochi Media, Inc. %% @doc Start and stop the MochiWeb server. -module(mochiweb). -author('bob@mochimedia.com'). -export([new_request/1, new_response/1]). -export([all_loaded/0, all_loaded/1, reload/0]). -export([ensure_started/1]). reload() -> [c:l(Module) || Module <- all_loaded()]. all_loaded() -> all_loaded(filename:dirname(code:which(?MODULE))). all_loaded(Base) when is_atom(Base) -> []; all_loaded(Base) -> FullBase = Base ++ "/", F = fun ({_Module, Loaded}, Acc) when is_atom(Loaded) -> Acc; ({Module, Loaded}, Acc) -> case lists:prefix(FullBase, Loaded) of true -> [Module | Acc]; false -> Acc end end, lists:foldl(F, [], code:all_loaded()). %% @spec new_request({Socket, Request, Headers}) -> MochiWebRequest %% @doc Return a mochiweb_request data structure. new_request({Socket, {Method, {abs_path, Uri}, Version}, Headers}) -> mochiweb_request:new(Socket, Method, Uri, Version, mochiweb_headers:make(Headers)); % this case probably doesn't "exist". new_request({Socket, {Method, {absoluteURI, _Protocol, _Host, _Port, Uri}, Version}, Headers}) -> mochiweb_request:new(Socket, Method, Uri, Version, mochiweb_headers:make(Headers)); %% Request-URI is "*" %% From http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2 new_request({Socket, {Method, '*'=Uri, Version}, Headers}) -> mochiweb_request:new(Socket, Method, Uri, Version, mochiweb_headers:make(Headers)). %% @spec new_response({Request, integer(), Headers}) -> MochiWebResponse %% @doc Return a mochiweb_response data structure. new_response({Request, Code, Headers}) -> mochiweb_response:new(Request, Code, mochiweb_headers:make(Headers)). %% @spec ensure_started(App::atom()) -> ok %% @doc Start the given App if it has not been started already. ensure_started(App) -> case application:start(App) of ok -> ok; {error, {already_started, App}} -> ok end. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochilogfile2.erl0000644000177700017770000000732712633765070030602 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2010 Mochi Media, Inc. %% @doc Write newline delimited log files, ensuring that if a truncated %% entry is found on log open then it is fixed before writing. Uses %% delayed writes and raw files for performance. -module(mochilogfile2). -author('bob@mochimedia.com'). -export([open/1, write/2, close/1, name/1]). %% @spec open(Name) -> Handle %% @doc Open the log file Name, creating or appending as necessary. All data %% at the end of the file will be truncated until a newline is found, to %% ensure that all records are complete. open(Name) -> {ok, FD} = file:open(Name, [raw, read, write, delayed_write, binary]), fix_log(FD), {?MODULE, Name, FD}. %% @spec name(Handle) -> string() %% @doc Return the path of the log file. name({?MODULE, Name, _FD}) -> Name. %% @spec write(Handle, IoData) -> ok %% @doc Write IoData to the log file referenced by Handle. write({?MODULE, _Name, FD}, IoData) -> ok = file:write(FD, [IoData, $\n]), ok. %% @spec close(Handle) -> ok %% @doc Close the log file referenced by Handle. close({?MODULE, _Name, FD}) -> ok = file:sync(FD), ok = file:close(FD), ok. fix_log(FD) -> {ok, Location} = file:position(FD, eof), Seek = find_last_newline(FD, Location), {ok, Seek} = file:position(FD, Seek), ok = file:truncate(FD), ok. %% Seek backwards to the last valid log entry find_last_newline(_FD, N) when N =< 1 -> 0; find_last_newline(FD, Location) -> case file:pread(FD, Location - 1, 1) of {ok, <<$\n>>} -> Location; {ok, _} -> find_last_newline(FD, Location - 1) end. %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). name_test() -> D = mochitemp:mkdtemp(), FileName = filename:join(D, "open_close_test.log"), H = open(FileName), ?assertEqual( FileName, name(H)), close(H), file:delete(FileName), file:del_dir(D), ok. open_close_test() -> D = mochitemp:mkdtemp(), FileName = filename:join(D, "open_close_test.log"), OpenClose = fun () -> H = open(FileName), ?assertEqual( true, filelib:is_file(FileName)), ok = close(H), ?assertEqual( {ok, <<>>}, file:read_file(FileName)), ok end, OpenClose(), OpenClose(), file:delete(FileName), file:del_dir(D), ok. write_test() -> D = mochitemp:mkdtemp(), FileName = filename:join(D, "write_test.log"), F = fun () -> H = open(FileName), write(H, "test line"), close(H), ok end, F(), ?assertEqual( {ok, <<"test line\n">>}, file:read_file(FileName)), F(), ?assertEqual( {ok, <<"test line\ntest line\n">>}, file:read_file(FileName)), file:delete(FileName), file:del_dir(D), ok. fix_log_test() -> D = mochitemp:mkdtemp(), FileName = filename:join(D, "write_test.log"), file:write_file(FileName, <<"first line good\nsecond line bad">>), F = fun () -> H = open(FileName), write(H, "test line"), close(H), ok end, F(), ?assertEqual( {ok, <<"first line good\ntest line\n">>}, file:read_file(FileName)), file:write_file(FileName, <<"first line bad">>), F(), ?assertEqual( {ok, <<"test line\n">>}, file:read_file(FileName)), F(), ?assertEqual( {ok, <<"test line\ntest line\n">>}, file:read_file(FileName)), ok. -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb_request_tests.erl0000644000177700017770000001761512633765070032647 0ustar michaelmichael-module(mochiweb_request_tests). -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). accepts_content_type_test() -> Req1 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "multipart/related"}])), ?assertEqual(true, Req1:accepts_content_type("multipart/related")), ?assertEqual(true, Req1:accepts_content_type(<<"multipart/related">>)), Req2 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "text/html"}])), ?assertEqual(false, Req2:accepts_content_type("multipart/related")), Req3 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "text/html, multipart/*"}])), ?assertEqual(true, Req3:accepts_content_type("multipart/related")), Req4 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "text/html, multipart/*; q=0.0"}])), ?assertEqual(false, Req4:accepts_content_type("multipart/related")), Req5 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "text/html, multipart/*; q=0"}])), ?assertEqual(false, Req5:accepts_content_type("multipart/related")), Req6 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "text/html, */*; q=0.0"}])), ?assertEqual(false, Req6:accepts_content_type("multipart/related")), Req7 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "multipart/*; q=0.0, */*"}])), ?assertEqual(false, Req7:accepts_content_type("multipart/related")), Req8 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "*/*; q=0.0, multipart/*"}])), ?assertEqual(true, Req8:accepts_content_type("multipart/related")), Req9 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "*/*; q=0.0, multipart/related"}])), ?assertEqual(true, Req9:accepts_content_type("multipart/related")), Req10 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "text/html; level=1"}])), ?assertEqual(true, Req10:accepts_content_type("text/html;level=1")), Req11 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "text/html; level=1, text/html"}])), ?assertEqual(true, Req11:accepts_content_type("text/html")), Req12 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "text/html; level=1; q=0.0, text/html"}])), ?assertEqual(false, Req12:accepts_content_type("text/html;level=1")), Req13 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "text/html; level=1; q=0.0, text/html"}])), ?assertEqual(false, Req13:accepts_content_type("text/html; level=1")), Req14 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "text/html;level=1;q=0.1, text/html"}])), ?assertEqual(true, Req14:accepts_content_type("text/html; level=1")). accepted_encodings_test() -> Req1 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([])), ?assertEqual(["identity"], Req1:accepted_encodings(["gzip", "identity"])), Req2 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept-Encoding", "gzip, deflate"}])), ?assertEqual(["gzip", "identity"], Req2:accepted_encodings(["gzip", "identity"])), Req3 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept-Encoding", "gzip;q=0.5, deflate"}])), ?assertEqual(["deflate", "gzip", "identity"], Req3:accepted_encodings(["gzip", "deflate", "identity"])), Req4 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept-Encoding", "identity, *;q=0"}])), ?assertEqual(["identity"], Req4:accepted_encodings(["gzip", "deflate", "identity"])), Req5 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept-Encoding", "gzip; q=0.1, *;q=0"}])), ?assertEqual(["gzip"], Req5:accepted_encodings(["gzip", "deflate", "identity"])), Req6 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept-Encoding", "gzip; q=, *;q=0"}])), ?assertEqual(bad_accept_encoding_value, Req6:accepted_encodings(["gzip", "deflate", "identity"])), Req7 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept-Encoding", "gzip;q=2.0, *;q=0"}])), ?assertEqual(bad_accept_encoding_value, Req7:accepted_encodings(["gzip", "identity"])), Req8 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept-Encoding", "deflate, *;q=0.0"}])), ?assertEqual([], Req8:accepted_encodings(["gzip", "identity"])). accepted_content_types_test() -> Req1 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "text/html"}])), ?assertEqual(["text/html"], Req1:accepted_content_types(["text/html", "application/json"])), Req2 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "text/html, */*;q=0"}])), ?assertEqual(["text/html"], Req2:accepted_content_types(["text/html", "application/json"])), Req3 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "text/*, */*;q=0"}])), ?assertEqual(["text/html"], Req3:accepted_content_types(["text/html", "application/json"])), Req4 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "text/*;q=0.8, */*;q=0.5"}])), ?assertEqual(["text/html", "application/json"], Req4:accepted_content_types(["application/json", "text/html"])), Req5 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "text/*;q=0.8, */*;q=0.5"}])), ?assertEqual(["text/html", "application/json"], Req5:accepted_content_types(["text/html", "application/json"])), Req6 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "text/*;q=0.5, */*;q=0.5"}])), ?assertEqual(["application/json", "text/html"], Req6:accepted_content_types(["application/json", "text/html"])), Req7 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make( [{"Accept", "text/html;q=0.5, application/json;q=0.5"}])), ?assertEqual(["application/json", "text/html"], Req7:accepted_content_types(["application/json", "text/html"])), Req8 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "text/html"}])), ?assertEqual([], Req8:accepted_content_types(["application/json"])), Req9 = mochiweb_request:new(nil, 'GET', "/foo", {1, 1}, mochiweb_headers:make([{"Accept", "text/*;q=0.9, text/html;q=0.5, */*;q=0.7"}])), ?assertEqual(["application/json", "text/html"], Req9:accepted_content_types(["text/html", "application/json"])). should_close_test() -> F = fun (V, H) -> (mochiweb_request:new( nil, 'GET', "/", V, mochiweb_headers:make(H) )):should_close() end, ?assertEqual( true, F({1, 1}, [{"Connection", "close"}])), ?assertEqual( true, F({1, 0}, [{"Connection", "close"}])), ?assertEqual( true, F({1, 1}, [{"Connection", "ClOSe"}])), ?assertEqual( false, F({1, 1}, [{"Connection", "closer"}])), ?assertEqual( false, F({1, 1}, [])), ?assertEqual( true, F({1, 0}, [])), ?assertEqual( false, F({1, 0}, [{"Connection", "Keep-Alive"}])), ok. -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb_cover.erl0000644000177700017770000000366412633765070031052 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2010 Mochi Media, Inc. %% @doc Workarounds for various cover deficiencies. -module(mochiweb_cover). -export([get_beam/1, get_abstract_code/1, get_clauses/2, clause_lookup_table/1]). -export([clause_lookup_table/2]). %% Internal get_beam(Module) -> {Module, Beam, _Path} = code:get_object_code(Module), Beam. get_abstract_code(Beam) -> {ok, {_Module, [{abstract_code, {raw_abstract_v1, L}}]}} = beam_lib:chunks(Beam, [abstract_code]), L. get_clauses(Function, Code) -> [L] = [Clauses || {function, _, FName, _, Clauses} <- Code, FName =:= Function], L. clause_lookup_table(Module, Function) -> clause_lookup_table( get_clauses(Function, get_abstract_code(get_beam(Module)))). clause_lookup_table(Clauses) -> lists:foldr(fun clause_fold/2, [], Clauses). clause_fold({clause, _, [InTerm], _Guards=[], [OutTerm]}, Acc) -> try [{erl_parse:normalise(InTerm), erl_parse:normalise(OutTerm)} | Acc] catch error:_ -> Acc end; clause_fold(_, Acc) -> Acc. %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). foo_table(a) -> b; foo_table("a") -> <<"b">>; foo_table(123) -> {4, 3, 2}; foo_table([list]) -> []; foo_table([list1, list2]) -> [list1, list2, list3]; foo_table(ignored) -> some, code, ignored; foo_table(Var) -> Var. foo_table_test() -> T = clause_lookup_table(?MODULE, foo_table), [?assertEqual(V, foo_table(K)) || {K, V} <- T]. clause_lookup_table_test() -> ?assertEqual(b, foo_table(a)), ?assertEqual(ignored, foo_table(ignored)), ?assertEqual('Var', foo_table('Var')), ?assertEqual( [{a, b}, {"a", <<"b">>}, {123, {4, 3, 2}}, {[list], []}, {[list1, list2], [list1, list2, list3]}], clause_lookup_table(?MODULE, foo_table)). -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb_cookies.erl0000644000177700017770000002434112633765070031363 0ustar michaelmichael%% @author Emad El-Haraty %% @copyright 2007 Mochi Media, Inc. %% @doc HTTP Cookie parsing and generating (RFC 2109, RFC 2965). -module(mochiweb_cookies). -export([parse_cookie/1, cookie/3, cookie/2]). -define(QUOTE, $\"). -define(IS_WHITESPACE(C), (C =:= $\s orelse C =:= $\t orelse C =:= $\r orelse C =:= $\n)). %% RFC 2616 separators (called tspecials in RFC 2068) -define(IS_SEPARATOR(C), (C < 32 orelse C =:= $\s orelse C =:= $\t orelse C =:= $( orelse C =:= $) orelse C =:= $< orelse C =:= $> orelse C =:= $@ orelse C =:= $, orelse C =:= $; orelse C =:= $: orelse C =:= $\\ orelse C =:= $\" orelse C =:= $/ orelse C =:= $[ orelse C =:= $] orelse C =:= $? orelse C =:= $= orelse C =:= ${ orelse C =:= $})). %% @type proplist() = [{Key::string(), Value::string()}]. %% @type header() = {Name::string(), Value::string()}. %% @type int_seconds() = integer(). %% @spec cookie(Key::string(), Value::string()) -> header() %% @doc Short-hand for cookie(Key, Value, []). cookie(Key, Value) -> cookie(Key, Value, []). %% @spec cookie(Key::string(), Value::string(), Options::[Option]) -> header() %% where Option = {max_age, int_seconds()} | {local_time, {date(), time()}} %% | {domain, string()} | {path, string()} %% | {secure, true | false} | {http_only, true | false} %% %% @doc Generate a Set-Cookie header field tuple. cookie(Key, Value, Options) -> Cookie = [any_to_list(Key), "=", quote(Value), "; Version=1"], %% Set-Cookie: %% Comment, Domain, Max-Age, Path, Secure, Version %% Set-Cookie2: %% Comment, CommentURL, Discard, Domain, Max-Age, Path, Port, Secure, %% Version ExpiresPart = case proplists:get_value(max_age, Options) of undefined -> ""; RawAge -> When = case proplists:get_value(local_time, Options) of undefined -> calendar:local_time(); LocalTime -> LocalTime end, Age = case RawAge < 0 of true -> 0; false -> RawAge end, ["; Expires=", age_to_cookie_date(Age, When), "; Max-Age=", quote(Age)] end, SecurePart = case proplists:get_value(secure, Options) of true -> "; Secure"; _ -> "" end, DomainPart = case proplists:get_value(domain, Options) of undefined -> ""; Domain -> ["; Domain=", quote(Domain)] end, PathPart = case proplists:get_value(path, Options) of undefined -> ""; Path -> ["; Path=", quote(Path)] end, HttpOnlyPart = case proplists:get_value(http_only, Options) of true -> "; HttpOnly"; _ -> "" end, CookieParts = [Cookie, ExpiresPart, SecurePart, DomainPart, PathPart, HttpOnlyPart], {"Set-Cookie", lists:flatten(CookieParts)}. %% Every major browser incorrectly handles quoted strings in a %% different and (worse) incompatible manner. Instead of wasting time %% writing redundant code for each browser, we restrict cookies to %% only contain characters that browsers handle compatibly. %% %% By replacing the definition of quote with this, we generate %% RFC-compliant cookies: %% %% quote(V) -> %% Fun = fun(?QUOTE, Acc) -> [$\\, ?QUOTE | Acc]; %% (Ch, Acc) -> [Ch | Acc] %% end, %% [?QUOTE | lists:foldr(Fun, [?QUOTE], V)]. %% Convert to a string and raise an error if quoting is required. quote(V0) -> V = any_to_list(V0), lists:all(fun(Ch) -> Ch =:= $/ orelse not ?IS_SEPARATOR(Ch) end, V) orelse erlang:error({cookie_quoting_required, V}), V. %% Return a date in the form of: Wdy, DD-Mon-YYYY HH:MM:SS GMT %% See also: rfc2109: 10.1.2 rfc2109_cookie_expires_date(LocalTime) -> {{YYYY,MM,DD},{Hour,Min,Sec}} = case calendar:local_time_to_universal_time_dst(LocalTime) of [] -> {Date, {Hour1, Min1, Sec1}} = LocalTime, LocalTime2 = {Date, {Hour1 + 1, Min1, Sec1}}, case calendar:local_time_to_universal_time_dst(LocalTime2) of [Gmt] -> Gmt; [_,Gmt] -> Gmt end; [Gmt] -> Gmt; [_,Gmt] -> Gmt end, DayNumber = calendar:day_of_the_week({YYYY,MM,DD}), lists:flatten( io_lib:format("~s, ~2.2.0w-~3.s-~4.4.0w ~2.2.0w:~2.2.0w:~2.2.0w GMT", [httpd_util:day(DayNumber),DD,httpd_util:month(MM),YYYY,Hour,Min,Sec])). add_seconds(Secs, LocalTime) -> Greg = calendar:datetime_to_gregorian_seconds(LocalTime), calendar:gregorian_seconds_to_datetime(Greg + Secs). age_to_cookie_date(Age, LocalTime) -> rfc2109_cookie_expires_date(add_seconds(Age, LocalTime)). %% @spec parse_cookie(string()) -> [{K::string(), V::string()}] %% @doc Parse the contents of a Cookie header field, ignoring cookie %% attributes, and return a simple property list. parse_cookie("") -> []; parse_cookie(Cookie) -> parse_cookie(Cookie, []). %% Internal API parse_cookie([], Acc) -> lists:reverse(Acc); parse_cookie(String, Acc) -> {{Token, Value}, Rest} = read_pair(String), Acc1 = case Token of "" -> Acc; "$" ++ _ -> Acc; _ -> [{Token, Value} | Acc] end, parse_cookie(Rest, Acc1). read_pair(String) -> {Token, Rest} = read_token(skip_whitespace(String)), {Value, Rest1} = read_value(skip_whitespace(Rest)), {{Token, Value}, skip_past_separator(Rest1)}. read_value([$= | Value]) -> Value1 = skip_whitespace(Value), case Value1 of [?QUOTE | _] -> read_quoted(Value1); _ -> read_token(Value1) end; read_value(String) -> {"", String}. read_quoted([?QUOTE | String]) -> read_quoted(String, []). read_quoted([], Acc) -> {lists:reverse(Acc), []}; read_quoted([?QUOTE | Rest], Acc) -> {lists:reverse(Acc), Rest}; read_quoted([$\\, Any | Rest], Acc) -> read_quoted(Rest, [Any | Acc]); read_quoted([C | Rest], Acc) -> read_quoted(Rest, [C | Acc]). skip_whitespace(String) -> F = fun (C) -> ?IS_WHITESPACE(C) end, lists:dropwhile(F, String). read_token(String) -> F = fun (C) -> not ?IS_SEPARATOR(C) end, lists:splitwith(F, String). skip_past_separator([]) -> []; skip_past_separator([$; | Rest]) -> Rest; skip_past_separator([$, | Rest]) -> Rest; skip_past_separator([_ | Rest]) -> skip_past_separator(Rest). any_to_list(V) when is_list(V) -> V; any_to_list(V) when is_atom(V) -> atom_to_list(V); any_to_list(V) when is_binary(V) -> binary_to_list(V); any_to_list(V) when is_integer(V) -> integer_to_list(V). %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). quote_test() -> %% ?assertError eunit macro is not compatible with coverage module try quote(":wq") catch error:{cookie_quoting_required, ":wq"} -> ok end, ?assertEqual( "foo", quote(foo)), ok. parse_cookie_test() -> %% RFC example C1 = "$Version=\"1\"; Customer=\"WILE_E_COYOTE\"; $Path=\"/acme\"; Part_Number=\"Rocket_Launcher_0001\"; $Path=\"/acme\"; Shipping=\"FedEx\"; $Path=\"/acme\"", ?assertEqual( [{"Customer","WILE_E_COYOTE"}, {"Part_Number","Rocket_Launcher_0001"}, {"Shipping","FedEx"}], parse_cookie(C1)), %% Potential edge cases ?assertEqual( [{"foo", "x"}], parse_cookie("foo=\"\\x\"")), ?assertEqual( [], parse_cookie("=")), ?assertEqual( [{"foo", ""}, {"bar", ""}], parse_cookie(" foo ; bar ")), ?assertEqual( [{"foo", ""}, {"bar", ""}], parse_cookie("foo=;bar=")), ?assertEqual( [{"foo", "\";"}, {"bar", ""}], parse_cookie("foo = \"\\\";\";bar ")), ?assertEqual( [{"foo", "\";bar"}], parse_cookie("foo=\"\\\";bar")), ?assertEqual( [], parse_cookie([])), ?assertEqual( [{"foo", "bar"}, {"baz", "wibble"}], parse_cookie("foo=bar , baz=wibble ")), ok. domain_test() -> ?assertEqual( {"Set-Cookie", "Customer=WILE_E_COYOTE; " "Version=1; " "Domain=acme.com; " "HttpOnly"}, cookie("Customer", "WILE_E_COYOTE", [{http_only, true}, {domain, "acme.com"}])), ok. local_time_test() -> {"Set-Cookie", S} = cookie("Customer", "WILE_E_COYOTE", [{max_age, 111}, {secure, true}]), ?assertMatch( ["Customer=WILE_E_COYOTE", " Version=1", " Expires=" ++ _, " Max-Age=111", " Secure"], string:tokens(S, ";")), ok. cookie_test() -> C1 = {"Set-Cookie", "Customer=WILE_E_COYOTE; " "Version=1; " "Path=/acme"}, C1 = cookie("Customer", "WILE_E_COYOTE", [{path, "/acme"}]), C1 = cookie("Customer", "WILE_E_COYOTE", [{path, "/acme"}, {badoption, "negatory"}]), C1 = cookie('Customer', 'WILE_E_COYOTE', [{path, '/acme'}]), C1 = cookie(<<"Customer">>, <<"WILE_E_COYOTE">>, [{path, <<"/acme">>}]), {"Set-Cookie","=NoKey; Version=1"} = cookie("", "NoKey", []), {"Set-Cookie","=NoKey; Version=1"} = cookie("", "NoKey"), LocalTime = calendar:universal_time_to_local_time({{2007, 5, 15}, {13, 45, 33}}), C2 = {"Set-Cookie", "Customer=WILE_E_COYOTE; " "Version=1; " "Expires=Tue, 15-May-2007 13:45:33 GMT; " "Max-Age=0"}, C2 = cookie("Customer", "WILE_E_COYOTE", [{max_age, -111}, {local_time, LocalTime}]), C3 = {"Set-Cookie", "Customer=WILE_E_COYOTE; " "Version=1; " "Expires=Wed, 16-May-2007 13:45:50 GMT; " "Max-Age=86417"}, C3 = cookie("Customer", "WILE_E_COYOTE", [{max_age, 86417}, {local_time, LocalTime}]), ok. -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/reloader.erl0000644000177700017770000001133512633765070027646 0ustar michaelmichael%% @copyright 2007 Mochi Media, Inc. %% @author Matthew Dempsky %% %% @doc Erlang module for automatically reloading modified modules %% during development. -module(reloader). -author("Matthew Dempsky "). -include_lib("kernel/include/file.hrl"). -behaviour(gen_server). -export([start/0, start_link/0]). -export([stop/0]). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -export([all_changed/0]). -export([is_changed/1]). -export([reload_modules/1]). -record(state, {last, tref}). %% External API %% @spec start() -> ServerRet %% @doc Start the reloader. start() -> gen_server:start({local, ?MODULE}, ?MODULE, [], []). %% @spec start_link() -> ServerRet %% @doc Start the reloader. start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). %% @spec stop() -> ok %% @doc Stop the reloader. stop() -> gen_server:call(?MODULE, stop). %% gen_server callbacks %% @spec init([]) -> {ok, State} %% @doc gen_server init, opens the server in an initial state. init([]) -> {ok, TRef} = timer:send_interval(timer:seconds(1), doit), {ok, #state{last = stamp(), tref = TRef}}. %% @spec handle_call(Args, From, State) -> tuple() %% @doc gen_server callback. handle_call(stop, _From, State) -> {stop, shutdown, stopped, State}; handle_call(_Req, _From, State) -> {reply, {error, badrequest}, State}. %% @spec handle_cast(Cast, State) -> tuple() %% @doc gen_server callback. handle_cast(_Req, State) -> {noreply, State}. %% @spec handle_info(Info, State) -> tuple() %% @doc gen_server callback. handle_info(doit, State) -> Now = stamp(), _ = doit(State#state.last, Now), {noreply, State#state{last = Now}}; handle_info(_Info, State) -> {noreply, State}. %% @spec terminate(Reason, State) -> ok %% @doc gen_server termination callback. terminate(_Reason, State) -> {ok, cancel} = timer:cancel(State#state.tref), ok. %% @spec code_change(_OldVsn, State, _Extra) -> State %% @doc gen_server code_change callback (trivial). code_change(_Vsn, State, _Extra) -> {ok, State}. %% @spec reload_modules([atom()]) -> [{module, atom()} | {error, term()}] %% @doc code:purge/1 and code:load_file/1 the given list of modules in order, %% return the results of code:load_file/1. reload_modules(Modules) -> [begin code:purge(M), code:load_file(M) end || M <- Modules]. %% @spec all_changed() -> [atom()] %% @doc Return a list of beam modules that have changed. all_changed() -> [M || {M, Fn} <- code:all_loaded(), is_list(Fn), is_changed(M)]. %% @spec is_changed(atom()) -> boolean() %% @doc true if the loaded module is a beam with a vsn attribute %% and does not match the on-disk beam file, returns false otherwise. is_changed(M) -> try module_vsn(M:module_info()) =/= module_vsn(code:get_object_code(M)) catch _:_ -> false end. %% Internal API module_vsn({M, Beam, _Fn}) -> {ok, {M, Vsn}} = beam_lib:version(Beam), Vsn; module_vsn(L) when is_list(L) -> {_, Attrs} = lists:keyfind(attributes, 1, L), {_, Vsn} = lists:keyfind(vsn, 1, Attrs), Vsn. doit(From, To) -> [case file:read_file_info(Filename) of {ok, #file_info{mtime = Mtime}} when Mtime >= From, Mtime < To -> reload(Module); {ok, _} -> unmodified; {error, enoent} -> %% The Erlang compiler deletes existing .beam files if %% recompiling fails. Maybe it's worth spitting out a %% warning here, but I'd want to limit it to just once. gone; {error, Reason} -> io:format("Error reading ~s's file info: ~p~n", [Filename, Reason]), error end || {Module, Filename} <- code:all_loaded(), is_list(Filename)]. reload(Module) -> io:format("Reloading ~p ...", [Module]), code:purge(Module), case code:load_file(Module) of {module, Module} -> io:format(" ok.~n"), case erlang:function_exported(Module, test, 0) of true -> io:format(" - Calling ~p:test() ...", [Module]), case catch Module:test() of ok -> io:format(" ok.~n"), reload; Reason -> io:format(" fail: ~p.~n", [Reason]), reload_but_test_failed end; false -> reload end; {error, Reason} -> io:format(" fail: ~p.~n", [Reason]), error end. stamp() -> erlang:localtime(). %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochilists.erl0000644000177700017770000000532712633765070030233 0ustar michaelmichael%% @copyright Copyright (c) 2010 Mochi Media, Inc. %% @author David Reid %% @doc Utility functions for dealing with proplists. -module(mochilists). -author("David Reid "). -export([get_value/2, get_value/3, is_defined/2, set_default/2, set_defaults/2]). %% @spec set_default({Key::term(), Value::term()}, Proplist::list()) -> list() %% %% @doc Return new Proplist with {Key, Value} set if not is_defined(Key, Proplist). set_default({Key, Value}, Proplist) -> case is_defined(Key, Proplist) of true -> Proplist; false -> [{Key, Value} | Proplist] end. %% @spec set_defaults([{Key::term(), Value::term()}], Proplist::list()) -> list() %% %% @doc Return new Proplist with {Key, Value} set if not is_defined(Key, Proplist). set_defaults(DefaultProps, Proplist) -> lists:foldl(fun set_default/2, Proplist, DefaultProps). %% @spec is_defined(Key::term(), Proplist::list()) -> bool() %% %% @doc Returns true if Propist contains at least one entry associated %% with Key, otherwise false is returned. is_defined(Key, Proplist) -> lists:keyfind(Key, 1, Proplist) =/= false. %% @spec get_value(Key::term(), Proplist::list()) -> term() | undefined %% %% @doc Return the value of Key or undefined get_value(Key, Proplist) -> get_value(Key, Proplist, undefined). %% @spec get_value(Key::term(), Proplist::list(), Default::term()) -> term() %% %% @doc Return the value of Key or Default get_value(_Key, [], Default) -> Default; get_value(Key, Proplist, Default) -> case lists:keyfind(Key, 1, Proplist) of false -> Default; {Key, Value} -> Value end. %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). set_defaults_test() -> ?assertEqual( [{k, v}], set_defaults([{k, v}], [])), ?assertEqual( [{k, v}], set_defaults([{k, vee}], [{k, v}])), ?assertEqual( lists:sort([{kay, vee}, {k, v}]), lists:sort(set_defaults([{k, vee}, {kay, vee}], [{k, v}]))), ok. set_default_test() -> ?assertEqual( [{k, v}], set_default({k, v}, [])), ?assertEqual( [{k, v}], set_default({k, vee}, [{k, v}])), ok. get_value_test() -> ?assertEqual( undefined, get_value(foo, [])), ?assertEqual( undefined, get_value(foo, [{bar, baz}])), ?assertEqual( bar, get_value(foo, [{foo, bar}])), ?assertEqual( default, get_value(foo, [], default)), ?assertEqual( default, get_value(foo, [{bar, baz}], default)), ?assertEqual( bar, get_value(foo, [{foo, bar}], default)), ok. -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb_util.erl0000644000177700017770000010111412633765070030676 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2007 Mochi Media, Inc. %% @doc Utilities for parsing and quoting. -module(mochiweb_util). -author('bob@mochimedia.com'). -export([join/2, quote_plus/1, urlencode/1, parse_qs/1, unquote/1]). -export([path_split/1]). -export([urlsplit/1, urlsplit_path/1, urlunsplit/1, urlunsplit_path/1]). -export([guess_mime/1, parse_header/1]). -export([shell_quote/1, cmd/1, cmd_string/1, cmd_port/2, cmd_status/1, cmd_status/2]). -export([record_to_proplist/2, record_to_proplist/3]). -export([safe_relative_path/1, partition/2]). -export([parse_qvalues/1, pick_accepted_encodings/3]). -export([make_io/1, rand_bytes/1, rand_uniform/2]). -define(PERCENT, 37). % $\% -define(FULLSTOP, 46). % $\. -define(IS_HEX(C), ((C >= $0 andalso C =< $9) orelse (C >= $a andalso C =< $f) orelse (C >= $A andalso C =< $F))). -define(QS_SAFE(C), ((C >= $a andalso C =< $z) orelse (C >= $A andalso C =< $Z) orelse (C >= $0 andalso C =< $9) orelse (C =:= ?FULLSTOP orelse C =:= $- orelse C =:= $~ orelse C =:= $_))). hexdigit(C) when C < 10 -> $0 + C; hexdigit(C) when C < 16 -> $A + (C - 10). unhexdigit(C) when C >= $0, C =< $9 -> C - $0; unhexdigit(C) when C >= $a, C =< $f -> C - $a + 10; unhexdigit(C) when C >= $A, C =< $F -> C - $A + 10. %% @spec partition(String, Sep) -> {String, [], []} | {Prefix, Sep, Postfix} %% @doc Inspired by Python 2.5's str.partition: %% partition("foo/bar", "/") = {"foo", "/", "bar"}, %% partition("foo", "/") = {"foo", "", ""}. partition(String, Sep) -> case partition(String, Sep, []) of undefined -> {String, "", ""}; Result -> Result end. partition("", _Sep, _Acc) -> undefined; partition(S, Sep, Acc) -> case partition2(S, Sep) of undefined -> [C | Rest] = S, partition(Rest, Sep, [C | Acc]); Rest -> {lists:reverse(Acc), Sep, Rest} end. partition2(Rest, "") -> Rest; partition2([C | R1], [C | R2]) -> partition2(R1, R2); partition2(_S, _Sep) -> undefined. %% @spec safe_relative_path(string()) -> string() | undefined %% @doc Return the reduced version of a relative path or undefined if it %% is not safe. safe relative paths can be joined with an absolute path %% and will result in a subdirectory of the absolute path. Safe paths %% never contain a backslash character. safe_relative_path("/" ++ _) -> undefined; safe_relative_path(P) -> case string:chr(P, $\\) of 0 -> safe_relative_path(P, []); _ -> undefined end. safe_relative_path("", Acc) -> case Acc of [] -> ""; _ -> string:join(lists:reverse(Acc), "/") end; safe_relative_path(P, Acc) -> case partition(P, "/") of {"", "/", _} -> %% /foo or foo//bar undefined; {"..", _, _} when Acc =:= [] -> undefined; {"..", _, Rest} -> safe_relative_path(Rest, tl(Acc)); {Part, "/", ""} -> safe_relative_path("", ["", Part | Acc]); {Part, _, Rest} -> safe_relative_path(Rest, [Part | Acc]) end. %% @spec shell_quote(string()) -> string() %% @doc Quote a string according to UNIX shell quoting rules, returns a string %% surrounded by double quotes. shell_quote(L) -> shell_quote(L, [$\"]). %% @spec cmd_port([string()], Options) -> port() %% @doc open_port({spawn, mochiweb_util:cmd_string(Argv)}, Options). cmd_port(Argv, Options) -> open_port({spawn, cmd_string(Argv)}, Options). %% @spec cmd([string()]) -> string() %% @doc os:cmd(cmd_string(Argv)). cmd(Argv) -> os:cmd(cmd_string(Argv)). %% @spec cmd_string([string()]) -> string() %% @doc Create a shell quoted command string from a list of arguments. cmd_string(Argv) -> string:join([shell_quote(X) || X <- Argv], " "). %% @spec cmd_status([string()]) -> {ExitStatus::integer(), Stdout::binary()} %% @doc Accumulate the output and exit status from the given application, %% will be spawned with cmd_port/2. cmd_status(Argv) -> cmd_status(Argv, []). %% @spec cmd_status([string()], [atom()]) -> {ExitStatus::integer(), Stdout::binary()} %% @doc Accumulate the output and exit status from the given application, %% will be spawned with cmd_port/2. cmd_status(Argv, Options) -> Port = cmd_port(Argv, [exit_status, stderr_to_stdout, use_stdio, binary | Options]), try cmd_loop(Port, []) after catch port_close(Port) end. %% @spec cmd_loop(port(), list()) -> {ExitStatus::integer(), Stdout::binary()} %% @doc Accumulate the output and exit status from a port. cmd_loop(Port, Acc) -> receive {Port, {exit_status, Status}} -> {Status, iolist_to_binary(lists:reverse(Acc))}; {Port, {data, Data}} -> cmd_loop(Port, [Data | Acc]) end. %% @spec join([iolist()], iolist()) -> iolist() %% @doc Join a list of strings or binaries together with the given separator %% string or char or binary. The output is flattened, but may be an %% iolist() instead of a string() if any of the inputs are binary(). join([], _Separator) -> []; join([S], _Separator) -> lists:flatten(S); join(Strings, Separator) -> lists:flatten(revjoin(lists:reverse(Strings), Separator, [])). revjoin([], _Separator, Acc) -> Acc; revjoin([S | Rest], Separator, []) -> revjoin(Rest, Separator, [S]); revjoin([S | Rest], Separator, Acc) -> revjoin(Rest, Separator, [S, Separator | Acc]). %% @spec quote_plus(atom() | integer() | float() | string() | binary()) -> string() %% @doc URL safe encoding of the given term. quote_plus(Atom) when is_atom(Atom) -> quote_plus(atom_to_list(Atom)); quote_plus(Int) when is_integer(Int) -> quote_plus(integer_to_list(Int)); quote_plus(Binary) when is_binary(Binary) -> quote_plus(binary_to_list(Binary)); quote_plus(Float) when is_float(Float) -> quote_plus(mochinum:digits(Float)); quote_plus(String) -> quote_plus(String, []). quote_plus([], Acc) -> lists:reverse(Acc); quote_plus([C | Rest], Acc) when ?QS_SAFE(C) -> quote_plus(Rest, [C | Acc]); quote_plus([$\s | Rest], Acc) -> quote_plus(Rest, [$+ | Acc]); quote_plus([C | Rest], Acc) -> <> = <>, quote_plus(Rest, [hexdigit(Lo), hexdigit(Hi), ?PERCENT | Acc]). %% @spec urlencode([{Key, Value}]) -> string() %% @doc URL encode the property list. urlencode(Props) -> Pairs = lists:foldr( fun ({K, V}, Acc) -> [quote_plus(K) ++ "=" ++ quote_plus(V) | Acc] end, [], Props), string:join(Pairs, "&"). %% @spec parse_qs(string() | binary()) -> [{Key, Value}] %% @doc Parse a query string or application/x-www-form-urlencoded. parse_qs(Binary) when is_binary(Binary) -> parse_qs(binary_to_list(Binary)); parse_qs(String) -> parse_qs(String, []). parse_qs([], Acc) -> lists:reverse(Acc); parse_qs(String, Acc) -> {Key, Rest} = parse_qs_key(String), {Value, Rest1} = parse_qs_value(Rest), parse_qs(Rest1, [{Key, Value} | Acc]). parse_qs_key(String) -> parse_qs_key(String, []). parse_qs_key([], Acc) -> {qs_revdecode(Acc), ""}; parse_qs_key([$= | Rest], Acc) -> {qs_revdecode(Acc), Rest}; parse_qs_key(Rest=[$; | _], Acc) -> {qs_revdecode(Acc), Rest}; parse_qs_key(Rest=[$& | _], Acc) -> {qs_revdecode(Acc), Rest}; parse_qs_key([C | Rest], Acc) -> parse_qs_key(Rest, [C | Acc]). parse_qs_value(String) -> parse_qs_value(String, []). parse_qs_value([], Acc) -> {qs_revdecode(Acc), ""}; parse_qs_value([$; | Rest], Acc) -> {qs_revdecode(Acc), Rest}; parse_qs_value([$& | Rest], Acc) -> {qs_revdecode(Acc), Rest}; parse_qs_value([C | Rest], Acc) -> parse_qs_value(Rest, [C | Acc]). %% @spec unquote(string() | binary()) -> string() %% @doc Unquote a URL encoded string. unquote(Binary) when is_binary(Binary) -> unquote(binary_to_list(Binary)); unquote(String) -> qs_revdecode(lists:reverse(String)). qs_revdecode(S) -> qs_revdecode(S, []). qs_revdecode([], Acc) -> Acc; qs_revdecode([$+ | Rest], Acc) -> qs_revdecode(Rest, [$\s | Acc]); qs_revdecode([Lo, Hi, ?PERCENT | Rest], Acc) when ?IS_HEX(Lo), ?IS_HEX(Hi) -> qs_revdecode(Rest, [(unhexdigit(Lo) bor (unhexdigit(Hi) bsl 4)) | Acc]); qs_revdecode([C | Rest], Acc) -> qs_revdecode(Rest, [C | Acc]). %% @spec urlsplit(Url) -> {Scheme, Netloc, Path, Query, Fragment} %% @doc Return a 5-tuple, does not expand % escapes. Only supports HTTP style %% URLs. urlsplit(Url) -> {Scheme, Url1} = urlsplit_scheme(Url), {Netloc, Url2} = urlsplit_netloc(Url1), {Path, Query, Fragment} = urlsplit_path(Url2), {Scheme, Netloc, Path, Query, Fragment}. urlsplit_scheme(Url) -> case urlsplit_scheme(Url, []) of no_scheme -> {"", Url}; Res -> Res end. urlsplit_scheme([C | Rest], Acc) when ((C >= $a andalso C =< $z) orelse (C >= $A andalso C =< $Z) orelse (C >= $0 andalso C =< $9) orelse C =:= $+ orelse C =:= $- orelse C =:= $.) -> urlsplit_scheme(Rest, [C | Acc]); urlsplit_scheme([$: | Rest], Acc=[_ | _]) -> {string:to_lower(lists:reverse(Acc)), Rest}; urlsplit_scheme(_Rest, _Acc) -> no_scheme. urlsplit_netloc("//" ++ Rest) -> urlsplit_netloc(Rest, []); urlsplit_netloc(Path) -> {"", Path}. urlsplit_netloc("", Acc) -> {lists:reverse(Acc), ""}; urlsplit_netloc(Rest=[C | _], Acc) when C =:= $/; C =:= $?; C =:= $# -> {lists:reverse(Acc), Rest}; urlsplit_netloc([C | Rest], Acc) -> urlsplit_netloc(Rest, [C | Acc]). %% @spec path_split(string()) -> {Part, Rest} %% @doc Split a path starting from the left, as in URL traversal. %% path_split("foo/bar") = {"foo", "bar"}, %% path_split("/foo/bar") = {"", "foo/bar"}. path_split(S) -> path_split(S, []). path_split("", Acc) -> {lists:reverse(Acc), ""}; path_split("/" ++ Rest, Acc) -> {lists:reverse(Acc), Rest}; path_split([C | Rest], Acc) -> path_split(Rest, [C | Acc]). %% @spec urlunsplit({Scheme, Netloc, Path, Query, Fragment}) -> string() %% @doc Assemble a URL from the 5-tuple. Path must be absolute. urlunsplit({Scheme, Netloc, Path, Query, Fragment}) -> lists:flatten([case Scheme of "" -> ""; _ -> [Scheme, "://"] end, Netloc, urlunsplit_path({Path, Query, Fragment})]). %% @spec urlunsplit_path({Path, Query, Fragment}) -> string() %% @doc Assemble a URL path from the 3-tuple. urlunsplit_path({Path, Query, Fragment}) -> lists:flatten([Path, case Query of "" -> ""; _ -> [$? | Query] end, case Fragment of "" -> ""; _ -> [$# | Fragment] end]). %% @spec urlsplit_path(Url) -> {Path, Query, Fragment} %% @doc Return a 3-tuple, does not expand % escapes. Only supports HTTP style %% paths. urlsplit_path(Path) -> urlsplit_path(Path, []). urlsplit_path("", Acc) -> {lists:reverse(Acc), "", ""}; urlsplit_path("?" ++ Rest, Acc) -> {Query, Fragment} = urlsplit_query(Rest), {lists:reverse(Acc), Query, Fragment}; urlsplit_path("#" ++ Rest, Acc) -> {lists:reverse(Acc), "", Rest}; urlsplit_path([C | Rest], Acc) -> urlsplit_path(Rest, [C | Acc]). urlsplit_query(Query) -> urlsplit_query(Query, []). urlsplit_query("", Acc) -> {lists:reverse(Acc), ""}; urlsplit_query("#" ++ Rest, Acc) -> {lists:reverse(Acc), Rest}; urlsplit_query([C | Rest], Acc) -> urlsplit_query(Rest, [C | Acc]). %% @spec guess_mime(string()) -> string() %% @doc Guess the mime type of a file by the extension of its filename. guess_mime(File) -> case mochiweb_mime:from_extension(filename:extension(File)) of undefined -> "text/plain"; Mime -> Mime end. %% @spec parse_header(string()) -> {Type, [{K, V}]} %% @doc Parse a Content-Type like header, return the main Content-Type %% and a property list of options. parse_header(String) -> %% TODO: This is exactly as broken as Python's cgi module. %% Should parse properly like mochiweb_cookies. [Type | Parts] = [string:strip(S) || S <- string:tokens(String, ";")], F = fun (S, Acc) -> case lists:splitwith(fun (C) -> C =/= $= end, S) of {"", _} -> %% Skip anything with no name Acc; {_, ""} -> %% Skip anything with no value Acc; {Name, [$\= | Value]} -> [{string:to_lower(string:strip(Name)), unquote_header(string:strip(Value))} | Acc] end end, {string:to_lower(Type), lists:foldr(F, [], Parts)}. unquote_header("\"" ++ Rest) -> unquote_header(Rest, []); unquote_header(S) -> S. unquote_header("", Acc) -> lists:reverse(Acc); unquote_header("\"", Acc) -> lists:reverse(Acc); unquote_header([$\\, C | Rest], Acc) -> unquote_header(Rest, [C | Acc]); unquote_header([C | Rest], Acc) -> unquote_header(Rest, [C | Acc]). %% @spec record_to_proplist(Record, Fields) -> proplist() %% @doc calls record_to_proplist/3 with a default TypeKey of '__record' record_to_proplist(Record, Fields) -> record_to_proplist(Record, Fields, '__record'). %% @spec record_to_proplist(Record, Fields, TypeKey) -> proplist() %% @doc Return a proplist of the given Record with each field in the %% Fields list set as a key with the corresponding value in the Record. %% TypeKey is the key that is used to store the record type %% Fields should be obtained by calling record_info(fields, record_type) %% where record_type is the record type of Record record_to_proplist(Record, Fields, TypeKey) when tuple_size(Record) - 1 =:= length(Fields) -> lists:zip([TypeKey | Fields], tuple_to_list(Record)). shell_quote([], Acc) -> lists:reverse([$\" | Acc]); shell_quote([C | Rest], Acc) when C =:= $\" orelse C =:= $\` orelse C =:= $\\ orelse C =:= $\$ -> shell_quote(Rest, [C, $\\ | Acc]); shell_quote([C | Rest], Acc) -> shell_quote(Rest, [C | Acc]). %% @spec parse_qvalues(string()) -> [qvalue()] | invalid_qvalue_string %% @type qvalue() = {media_type() | encoding() , float()}. %% @type media_type() = string(). %% @type encoding() = string(). %% %% @doc Parses a list (given as a string) of elements with Q values associated %% to them. Elements are separated by commas and each element is separated %% from its Q value by a semicolon. Q values are optional but when missing %% the value of an element is considered as 1.0. A Q value is always in the %% range [0.0, 1.0]. A Q value list is used for example as the value of the %% HTTP "Accept" and "Accept-Encoding" headers. %% %% Q values are described in section 2.9 of the RFC 2616 (HTTP 1.1). %% %% Example: %% %% parse_qvalues("gzip; q=0.5, deflate, identity;q=0.0") -> %% [{"gzip", 0.5}, {"deflate", 1.0}, {"identity", 0.0}] %% parse_qvalues(QValuesStr) -> try lists:map( fun(Pair) -> [Type | Params] = string:tokens(Pair, ";"), NormParams = normalize_media_params(Params), {Q, NonQParams} = extract_q(NormParams), {string:join([string:strip(Type) | NonQParams], ";"), Q} end, string:tokens(string:to_lower(QValuesStr), ",") ) catch _Type:_Error -> invalid_qvalue_string end. normalize_media_params(Params) -> {ok, Re} = re:compile("\\s"), normalize_media_params(Re, Params, []). normalize_media_params(_Re, [], Acc) -> lists:reverse(Acc); normalize_media_params(Re, [Param | Rest], Acc) -> NormParam = re:replace(Param, Re, "", [global, {return, list}]), normalize_media_params(Re, Rest, [NormParam | Acc]). extract_q(NormParams) -> {ok, KVRe} = re:compile("^([^=]+)=([^=]+)$"), {ok, QRe} = re:compile("^((?:0|1)(?:\\.\\d{1,3})?)$"), extract_q(KVRe, QRe, NormParams, []). extract_q(_KVRe, _QRe, [], Acc) -> {1.0, lists:reverse(Acc)}; extract_q(KVRe, QRe, [Param | Rest], Acc) -> case re:run(Param, KVRe, [{capture, [1, 2], list}]) of {match, [Name, Value]} -> case Name of "q" -> {match, [Q]} = re:run(Value, QRe, [{capture, [1], list}]), QVal = case Q of "0" -> 0.0; "1" -> 1.0; Else -> list_to_float(Else) end, case QVal < 0.0 orelse QVal > 1.0 of false -> {QVal, lists:reverse(Acc) ++ Rest} end; _ -> extract_q(KVRe, QRe, Rest, [Param | Acc]) end end. %% @spec pick_accepted_encodings([qvalue()], [encoding()], encoding()) -> %% [encoding()] %% %% @doc Determines which encodings specified in the given Q values list are %% valid according to a list of supported encodings and a default encoding. %% %% The returned list of encodings is sorted, descendingly, according to the %% Q values of the given list. The last element of this list is the given %% default encoding unless this encoding is explicitily or implicitily %% marked with a Q value of 0.0 in the given Q values list. %% Note: encodings with the same Q value are kept in the same order as %% found in the input Q values list. %% %% This encoding picking process is described in section 14.3 of the %% RFC 2616 (HTTP 1.1). %% %% Example: %% %% pick_accepted_encodings( %% [{"gzip", 0.5}, {"deflate", 1.0}], %% ["gzip", "identity"], %% "identity" %% ) -> %% ["gzip", "identity"] %% pick_accepted_encodings(AcceptedEncs, SupportedEncs, DefaultEnc) -> SortedQList = lists:reverse( lists:sort(fun({_, Q1}, {_, Q2}) -> Q1 < Q2 end, AcceptedEncs) ), {Accepted, Refused} = lists:foldr( fun({E, Q}, {A, R}) -> case Q > 0.0 of true -> {[E | A], R}; false -> {A, [E | R]} end end, {[], []}, SortedQList ), Refused1 = lists:foldr( fun(Enc, Acc) -> case Enc of "*" -> lists:subtract(SupportedEncs, Accepted) ++ Acc; _ -> [Enc | Acc] end end, [], Refused ), Accepted1 = lists:foldr( fun(Enc, Acc) -> case Enc of "*" -> lists:subtract(SupportedEncs, Accepted ++ Refused1) ++ Acc; _ -> [Enc | Acc] end end, [], Accepted ), Accepted2 = case lists:member(DefaultEnc, Accepted1) of true -> Accepted1; false -> Accepted1 ++ [DefaultEnc] end, [E || E <- Accepted2, lists:member(E, SupportedEncs), not lists:member(E, Refused1)]. make_io(Atom) when is_atom(Atom) -> atom_to_list(Atom); make_io(Integer) when is_integer(Integer) -> integer_to_list(Integer); make_io(Io) when is_list(Io); is_binary(Io) -> Io. rand_bytes(Count) -> list_to_binary([rand_uniform(0, 16#FF + 1) || _ <- lists:seq(1, Count)]). rand_uniform(Lo, Hi) -> random:uniform(Hi - Lo) + Lo - 1. %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). make_io_test() -> ?assertEqual( <<"atom">>, iolist_to_binary(make_io(atom))), ?assertEqual( <<"20">>, iolist_to_binary(make_io(20))), ?assertEqual( <<"list">>, iolist_to_binary(make_io("list"))), ?assertEqual( <<"binary">>, iolist_to_binary(make_io(<<"binary">>))), ok. -record(test_record, {field1=f1, field2=f2}). record_to_proplist_test() -> ?assertEqual( [{'__record', test_record}, {field1, f1}, {field2, f2}], record_to_proplist(#test_record{}, record_info(fields, test_record))), ?assertEqual( [{'typekey', test_record}, {field1, f1}, {field2, f2}], record_to_proplist(#test_record{}, record_info(fields, test_record), typekey)), ok. shell_quote_test() -> ?assertEqual( "\"foo \\$bar\\\"\\`' baz\"", shell_quote("foo $bar\"`' baz")), ok. cmd_port_test_spool(Port, Acc) -> receive {Port, eof} -> Acc; {Port, {data, {eol, Data}}} -> cmd_port_test_spool(Port, ["\n", Data | Acc]); {Port, Unknown} -> throw({unknown, Unknown}) after 1000 -> throw(timeout) end. cmd_port_test() -> Port = cmd_port(["echo", "$bling$ `word`!"], [eof, stream, {line, 4096}]), Res = try lists:append(lists:reverse(cmd_port_test_spool(Port, []))) after catch port_close(Port) end, self() ! {Port, wtf}, try cmd_port_test_spool(Port, []) catch throw:{unknown, wtf} -> ok end, try cmd_port_test_spool(Port, []) catch throw:timeout -> ok end, ?assertEqual( "$bling$ `word`!\n", Res). cmd_test() -> ?assertEqual( "$bling$ `word`!\n", cmd(["echo", "$bling$ `word`!"])), ok. cmd_string_test() -> ?assertEqual( "\"echo\" \"\\$bling\\$ \\`word\\`!\"", cmd_string(["echo", "$bling$ `word`!"])), ok. cmd_status_test() -> ?assertEqual( {0, <<"$bling$ `word`!\n">>}, cmd_status(["echo", "$bling$ `word`!"])), ok. parse_header_test() -> ?assertEqual( {"multipart/form-data", [{"boundary", "AaB03x"}]}, parse_header("multipart/form-data; boundary=AaB03x")), %% This tests (currently) intentionally broken behavior ?assertEqual( {"multipart/form-data", [{"b", ""}, {"cgi", "is"}, {"broken", "true\"e"}]}, parse_header("multipart/form-data;b=;cgi=\"i\\s;broken=true\"e;=z;z")), ok. guess_mime_test() -> "text/plain" = guess_mime(""), "text/plain" = guess_mime(".text"), "application/zip" = guess_mime(".zip"), "application/zip" = guess_mime("x.zip"), "text/html" = guess_mime("x.html"), "application/xhtml+xml" = guess_mime("x.xhtml"), ok. path_split_test() -> {"", "foo/bar"} = path_split("/foo/bar"), {"foo", "bar"} = path_split("foo/bar"), {"bar", ""} = path_split("bar"), ok. urlsplit_test() -> {"", "", "/foo", "", "bar?baz"} = urlsplit("/foo#bar?baz"), {"http", "host:port", "/foo", "", "bar?baz"} = urlsplit("http://host:port/foo#bar?baz"), {"http", "host", "", "", ""} = urlsplit("http://host"), {"", "", "/wiki/Category:Fruit", "", ""} = urlsplit("/wiki/Category:Fruit"), ok. urlsplit_path_test() -> {"/foo/bar", "", ""} = urlsplit_path("/foo/bar"), {"/foo", "baz", ""} = urlsplit_path("/foo?baz"), {"/foo", "", "bar?baz"} = urlsplit_path("/foo#bar?baz"), {"/foo", "", "bar?baz#wibble"} = urlsplit_path("/foo#bar?baz#wibble"), {"/foo", "bar", "baz"} = urlsplit_path("/foo?bar#baz"), {"/foo", "bar?baz", "baz"} = urlsplit_path("/foo?bar?baz#baz"), ok. urlunsplit_test() -> "/foo#bar?baz" = urlunsplit({"", "", "/foo", "", "bar?baz"}), "http://host:port/foo#bar?baz" = urlunsplit({"http", "host:port", "/foo", "", "bar?baz"}), ok. urlunsplit_path_test() -> "/foo/bar" = urlunsplit_path({"/foo/bar", "", ""}), "/foo?baz" = urlunsplit_path({"/foo", "baz", ""}), "/foo#bar?baz" = urlunsplit_path({"/foo", "", "bar?baz"}), "/foo#bar?baz#wibble" = urlunsplit_path({"/foo", "", "bar?baz#wibble"}), "/foo?bar#baz" = urlunsplit_path({"/foo", "bar", "baz"}), "/foo?bar?baz#baz" = urlunsplit_path({"/foo", "bar?baz", "baz"}), ok. join_test() -> ?assertEqual("foo,bar,baz", join(["foo", "bar", "baz"], $,)), ?assertEqual("foo,bar,baz", join(["foo", "bar", "baz"], ",")), ?assertEqual("foo bar", join([["foo", " bar"]], ",")), ?assertEqual("foo bar,baz", join([["foo", " bar"], "baz"], ",")), ?assertEqual("foo", join(["foo"], ",")), ?assertEqual("foobarbaz", join(["foo", "bar", "baz"], "")), ?assertEqual("foo" ++ [<<>>] ++ "bar" ++ [<<>>] ++ "baz", join(["foo", "bar", "baz"], <<>>)), ?assertEqual("foobar" ++ [<<"baz">>], join(["foo", "bar", <<"baz">>], "")), ?assertEqual("", join([], "any")), ok. quote_plus_test() -> "foo" = quote_plus(foo), "1" = quote_plus(1), "1.1" = quote_plus(1.1), "foo" = quote_plus("foo"), "foo+bar" = quote_plus("foo bar"), "foo%0A" = quote_plus("foo\n"), "foo%0A" = quote_plus("foo\n"), "foo%3B%26%3D" = quote_plus("foo;&="), "foo%3B%26%3D" = quote_plus(<<"foo;&=">>), ok. unquote_test() -> ?assertEqual("foo bar", unquote("foo+bar")), ?assertEqual("foo bar", unquote("foo%20bar")), ?assertEqual("foo\r\n", unquote("foo%0D%0A")), ?assertEqual("foo\r\n", unquote(<<"foo%0D%0A">>)), ok. urlencode_test() -> "foo=bar&baz=wibble+%0D%0A&z=1" = urlencode([{foo, "bar"}, {"baz", "wibble \r\n"}, {z, 1}]), ok. parse_qs_test() -> ?assertEqual( [{"foo", "bar"}, {"baz", "wibble \r\n"}, {"z", "1"}], parse_qs("foo=bar&baz=wibble+%0D%0a&z=1")), ?assertEqual( [{"", "bar"}, {"baz", "wibble \r\n"}, {"z", ""}], parse_qs("=bar&baz=wibble+%0D%0a&z=")), ?assertEqual( [{"foo", "bar"}, {"baz", "wibble \r\n"}, {"z", "1"}], parse_qs(<<"foo=bar&baz=wibble+%0D%0a&z=1">>)), ?assertEqual( [], parse_qs("")), ?assertEqual( [{"foo", ""}, {"bar", ""}, {"baz", ""}], parse_qs("foo;bar&baz")), ok. partition_test() -> {"foo", "", ""} = partition("foo", "/"), {"foo", "/", "bar"} = partition("foo/bar", "/"), {"foo", "/", ""} = partition("foo/", "/"), {"", "/", "bar"} = partition("/bar", "/"), {"f", "oo/ba", "r"} = partition("foo/bar", "oo/ba"), ok. safe_relative_path_test() -> "foo" = safe_relative_path("foo"), "foo/" = safe_relative_path("foo/"), "foo" = safe_relative_path("foo/bar/.."), "bar" = safe_relative_path("foo/../bar"), "bar/" = safe_relative_path("foo/../bar/"), "" = safe_relative_path("foo/.."), "" = safe_relative_path("foo/../"), undefined = safe_relative_path("/foo"), undefined = safe_relative_path("../foo"), undefined = safe_relative_path("foo/../.."), undefined = safe_relative_path("foo//"), undefined = safe_relative_path("foo\\bar"), ok. parse_qvalues_test() -> [] = parse_qvalues(""), [{"identity", 0.0}] = parse_qvalues("identity;q=0"), [{"identity", 0.0}] = parse_qvalues("identity ;q=0"), [{"identity", 0.0}] = parse_qvalues(" identity; q =0 "), [{"identity", 0.0}] = parse_qvalues("identity ; q = 0"), [{"identity", 0.0}] = parse_qvalues("identity ; q= 0.0"), [{"gzip", 1.0}, {"deflate", 1.0}, {"identity", 0.0}] = parse_qvalues( "gzip,deflate,identity;q=0.0" ), [{"deflate", 1.0}, {"gzip", 1.0}, {"identity", 0.0}] = parse_qvalues( "deflate,gzip,identity;q=0.0" ), [{"gzip", 1.0}, {"deflate", 1.0}, {"gzip", 1.0}, {"identity", 0.0}] = parse_qvalues("gzip,deflate,gzip,identity;q=0"), [{"gzip", 1.0}, {"deflate", 1.0}, {"identity", 0.0}] = parse_qvalues( "gzip, deflate , identity; q=0.0" ), [{"gzip", 1.0}, {"deflate", 1.0}, {"identity", 0.0}] = parse_qvalues( "gzip; q=1, deflate;q=1.0, identity;q=0.0" ), [{"gzip", 0.5}, {"deflate", 1.0}, {"identity", 0.0}] = parse_qvalues( "gzip; q=0.5, deflate;q=1.0, identity;q=0" ), [{"gzip", 0.5}, {"deflate", 1.0}, {"identity", 0.0}] = parse_qvalues( "gzip; q=0.5, deflate , identity;q=0.0" ), [{"gzip", 0.5}, {"deflate", 0.8}, {"identity", 0.0}] = parse_qvalues( "gzip; q=0.5, deflate;q=0.8, identity;q=0.0" ), [{"gzip", 0.5}, {"deflate", 1.0}, {"identity", 1.0}] = parse_qvalues( "gzip; q=0.5,deflate,identity" ), [{"gzip", 0.5}, {"deflate", 1.0}, {"identity", 1.0}, {"identity", 1.0}] = parse_qvalues("gzip; q=0.5,deflate,identity, identity "), [{"text/html;level=1", 1.0}, {"text/plain", 0.5}] = parse_qvalues("text/html;level=1, text/plain;q=0.5"), [{"text/html;level=1", 0.3}, {"text/plain", 1.0}] = parse_qvalues("text/html;level=1;q=0.3, text/plain"), [{"text/html;level=1", 0.3}, {"text/plain", 1.0}] = parse_qvalues("text/html; level = 1; q = 0.3, text/plain"), [{"text/html;level=1", 0.3}, {"text/plain", 1.0}] = parse_qvalues("text/html;q=0.3;level=1, text/plain"), invalid_qvalue_string = parse_qvalues("gzip; q=1.1, deflate"), invalid_qvalue_string = parse_qvalues("gzip; q=0.5, deflate;q=2"), invalid_qvalue_string = parse_qvalues("gzip, deflate;q=AB"), invalid_qvalue_string = parse_qvalues("gzip; q=2.1, deflate"), invalid_qvalue_string = parse_qvalues("gzip; q=0.1234, deflate"), invalid_qvalue_string = parse_qvalues("text/html;level=1;q=0.3, text/html;level"), ok. pick_accepted_encodings_test() -> ["identity"] = pick_accepted_encodings( [], ["gzip", "identity"], "identity" ), ["gzip", "identity"] = pick_accepted_encodings( [{"gzip", 1.0}], ["gzip", "identity"], "identity" ), ["identity"] = pick_accepted_encodings( [{"gzip", 0.0}], ["gzip", "identity"], "identity" ), ["gzip", "identity"] = pick_accepted_encodings( [{"gzip", 1.0}, {"deflate", 1.0}], ["gzip", "identity"], "identity" ), ["gzip", "identity"] = pick_accepted_encodings( [{"gzip", 0.5}, {"deflate", 1.0}], ["gzip", "identity"], "identity" ), ["identity"] = pick_accepted_encodings( [{"gzip", 0.0}, {"deflate", 0.0}], ["gzip", "identity"], "identity" ), ["gzip"] = pick_accepted_encodings( [{"gzip", 1.0}, {"deflate", 1.0}, {"identity", 0.0}], ["gzip", "identity"], "identity" ), ["gzip", "deflate", "identity"] = pick_accepted_encodings( [{"gzip", 1.0}, {"deflate", 1.0}], ["gzip", "deflate", "identity"], "identity" ), ["gzip", "deflate"] = pick_accepted_encodings( [{"gzip", 1.0}, {"deflate", 1.0}, {"identity", 0.0}], ["gzip", "deflate", "identity"], "identity" ), ["deflate", "gzip", "identity"] = pick_accepted_encodings( [{"gzip", 0.2}, {"deflate", 1.0}], ["gzip", "deflate", "identity"], "identity" ), ["deflate", "deflate", "gzip", "identity"] = pick_accepted_encodings( [{"gzip", 0.2}, {"deflate", 1.0}, {"deflate", 1.0}], ["gzip", "deflate", "identity"], "identity" ), ["deflate", "gzip", "gzip", "identity"] = pick_accepted_encodings( [{"gzip", 0.2}, {"deflate", 1.0}, {"gzip", 1.0}], ["gzip", "deflate", "identity"], "identity" ), ["gzip", "deflate", "gzip", "identity"] = pick_accepted_encodings( [{"gzip", 0.2}, {"deflate", 0.9}, {"gzip", 1.0}], ["gzip", "deflate", "identity"], "identity" ), [] = pick_accepted_encodings( [{"*", 0.0}], ["gzip", "deflate", "identity"], "identity" ), ["gzip", "deflate", "identity"] = pick_accepted_encodings( [{"*", 1.0}], ["gzip", "deflate", "identity"], "identity" ), ["gzip", "deflate", "identity"] = pick_accepted_encodings( [{"*", 0.6}], ["gzip", "deflate", "identity"], "identity" ), ["gzip"] = pick_accepted_encodings( [{"gzip", 1.0}, {"*", 0.0}], ["gzip", "deflate", "identity"], "identity" ), ["gzip", "deflate"] = pick_accepted_encodings( [{"gzip", 1.0}, {"deflate", 0.6}, {"*", 0.0}], ["gzip", "deflate", "identity"], "identity" ), ["deflate", "gzip"] = pick_accepted_encodings( [{"gzip", 0.5}, {"deflate", 1.0}, {"*", 0.0}], ["gzip", "deflate", "identity"], "identity" ), ["gzip", "identity"] = pick_accepted_encodings( [{"deflate", 0.0}, {"*", 1.0}], ["gzip", "deflate", "identity"], "identity" ), ["gzip", "identity"] = pick_accepted_encodings( [{"*", 1.0}, {"deflate", 0.0}], ["gzip", "deflate", "identity"], "identity" ), ok. -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiutf8.erl0000644000177700017770000002650312633765070027762 0ustar michaelmichael%% @copyright 2010 Mochi Media, Inc. %% @author Bob Ippolito %% @doc Algorithm to convert any binary to a valid UTF-8 sequence by ignoring %% invalid bytes. -module(mochiutf8). -export([valid_utf8_bytes/1, codepoint_to_bytes/1, codepoints_to_bytes/1]). -export([bytes_to_codepoints/1, bytes_foldl/3, codepoint_foldl/3]). -export([read_codepoint/1, len/1]). %% External API %% -type unichar_low() :: 0..16#d7ff. %% -type unichar_high() :: 16#e000..16#10ffff. %% -type unichar() :: unichar_low() | unichar_high(). %% -spec codepoint_to_bytes(unichar()) -> binary(). %% @doc Convert a unicode codepoint to UTF-8 bytes. codepoint_to_bytes(C) when (C >= 16#00 andalso C =< 16#7f) -> %% U+0000 - U+007F - 7 bits <>; codepoint_to_bytes(C) when (C >= 16#080 andalso C =< 16#07FF) -> %% U+0080 - U+07FF - 11 bits <<0:5, B1:5, B0:6>> = <>, <<2#110:3, B1:5, 2#10:2, B0:6>>; codepoint_to_bytes(C) when (C >= 16#0800 andalso C =< 16#FFFF) andalso (C < 16#D800 orelse C > 16#DFFF) -> %% U+0800 - U+FFFF - 16 bits (excluding UTC-16 surrogate code points) <> = <>, <<2#1110:4, B2:4, 2#10:2, B1:6, 2#10:2, B0:6>>; codepoint_to_bytes(C) when (C >= 16#010000 andalso C =< 16#10FFFF) -> %% U+10000 - U+10FFFF - 21 bits <<0:3, B3:3, B2:6, B1:6, B0:6>> = <>, <<2#11110:5, B3:3, 2#10:2, B2:6, 2#10:2, B1:6, 2#10:2, B0:6>>. %% -spec codepoints_to_bytes([unichar()]) -> binary(). %% @doc Convert a list of codepoints to a UTF-8 binary. codepoints_to_bytes(L) -> <<<<(codepoint_to_bytes(C))/binary>> || C <- L>>. %% -spec read_codepoint(binary()) -> {unichar(), binary(), binary()}. read_codepoint(Bin = <<2#0:1, C:7, Rest/binary>>) -> %% U+0000 - U+007F - 7 bits <> = Bin, {C, B, Rest}; read_codepoint(Bin = <<2#110:3, B1:5, 2#10:2, B0:6, Rest/binary>>) -> %% U+0080 - U+07FF - 11 bits case <> of <> when C >= 16#80 -> <> = Bin, {C, B, Rest} end; read_codepoint(Bin = <<2#1110:4, B2:4, 2#10:2, B1:6, 2#10:2, B0:6, Rest/binary>>) -> %% U+0800 - U+FFFF - 16 bits (excluding UTC-16 surrogate code points) case <> of <> when (C >= 16#0800 andalso C =< 16#FFFF) andalso (C < 16#D800 orelse C > 16#DFFF) -> <> = Bin, {C, B, Rest} end; read_codepoint(Bin = <<2#11110:5, B3:3, 2#10:2, B2:6, 2#10:2, B1:6, 2#10:2, B0:6, Rest/binary>>) -> %% U+10000 - U+10FFFF - 21 bits case <> of <> when (C >= 16#010000 andalso C =< 16#10FFFF) -> <> = Bin, {C, B, Rest} end. %% -spec codepoint_foldl(fun((unichar(), _) -> _), _, binary()) -> _. codepoint_foldl(F, Acc, <<>>) when is_function(F, 2) -> Acc; codepoint_foldl(F, Acc, Bin) -> {C, _, Rest} = read_codepoint(Bin), codepoint_foldl(F, F(C, Acc), Rest). %% -spec bytes_foldl(fun((binary(), _) -> _), _, binary()) -> _. bytes_foldl(F, Acc, <<>>) when is_function(F, 2) -> Acc; bytes_foldl(F, Acc, Bin) -> {_, B, Rest} = read_codepoint(Bin), bytes_foldl(F, F(B, Acc), Rest). %% -spec bytes_to_codepoints(binary()) -> [unichar()]. bytes_to_codepoints(B) -> lists:reverse(codepoint_foldl(fun (C, Acc) -> [C | Acc] end, [], B)). %% -spec len(binary()) -> non_neg_integer(). len(<<>>) -> 0; len(B) -> {_, _, Rest} = read_codepoint(B), 1 + len(Rest). %% -spec valid_utf8_bytes(B::binary()) -> binary(). %% @doc Return only the bytes in B that represent valid UTF-8. Uses %% the following recursive algorithm: skip one byte if B does not %% follow UTF-8 syntax (a 1-4 byte encoding of some number), %% skip sequence of 2-4 bytes if it represents an overlong encoding %% or bad code point (surrogate U+D800 - U+DFFF or > U+10FFFF). valid_utf8_bytes(B) when is_binary(B) -> binary_skip_bytes(B, invalid_utf8_indexes(B)). %% Internal API %% -spec binary_skip_bytes(binary(), [non_neg_integer()]) -> binary(). %% @doc Return B, but skipping the 0-based indexes in L. binary_skip_bytes(B, []) -> B; binary_skip_bytes(B, L) -> binary_skip_bytes(B, L, 0, []). %% @private %% -spec binary_skip_bytes(binary(), [non_neg_integer()], non_neg_integer(), iolist()) -> binary(). binary_skip_bytes(B, [], _N, Acc) -> iolist_to_binary(lists:reverse([B | Acc])); binary_skip_bytes(<<_, RestB/binary>>, [N | RestL], N, Acc) -> binary_skip_bytes(RestB, RestL, 1 + N, Acc); binary_skip_bytes(<>, L, N, Acc) -> binary_skip_bytes(RestB, L, 1 + N, [C | Acc]). %% -spec invalid_utf8_indexes(binary()) -> [non_neg_integer()]. %% @doc Return the 0-based indexes in B that are not valid UTF-8. invalid_utf8_indexes(B) -> invalid_utf8_indexes(B, 0, []). %% @private. %% -spec invalid_utf8_indexes(binary(), non_neg_integer(), [non_neg_integer()]) -> [non_neg_integer()]. invalid_utf8_indexes(<>, N, Acc) when C < 16#80 -> %% U+0000 - U+007F - 7 bits invalid_utf8_indexes(Rest, 1 + N, Acc); invalid_utf8_indexes(<>, N, Acc) when C1 band 16#E0 =:= 16#C0, C2 band 16#C0 =:= 16#80 -> %% U+0080 - U+07FF - 11 bits case ((C1 band 16#1F) bsl 6) bor (C2 band 16#3F) of C when C < 16#80 -> %% Overlong encoding. invalid_utf8_indexes(Rest, 2 + N, [1 + N, N | Acc]); _ -> %% Upper bound U+07FF does not need to be checked invalid_utf8_indexes(Rest, 2 + N, Acc) end; invalid_utf8_indexes(<>, N, Acc) when C1 band 16#F0 =:= 16#E0, C2 band 16#C0 =:= 16#80, C3 band 16#C0 =:= 16#80 -> %% U+0800 - U+FFFF - 16 bits case ((((C1 band 16#0F) bsl 6) bor (C2 band 16#3F)) bsl 6) bor (C3 band 16#3F) of C when (C < 16#800) orelse (C >= 16#D800 andalso C =< 16#DFFF) -> %% Overlong encoding or surrogate. invalid_utf8_indexes(Rest, 3 + N, [2 + N, 1 + N, N | Acc]); _ -> %% Upper bound U+FFFF does not need to be checked invalid_utf8_indexes(Rest, 3 + N, Acc) end; invalid_utf8_indexes(<>, N, Acc) when C1 band 16#F8 =:= 16#F0, C2 band 16#C0 =:= 16#80, C3 band 16#C0 =:= 16#80, C4 band 16#C0 =:= 16#80 -> %% U+10000 - U+10FFFF - 21 bits case ((((((C1 band 16#0F) bsl 6) bor (C2 band 16#3F)) bsl 6) bor (C3 band 16#3F)) bsl 6) bor (C4 band 16#3F) of C when (C < 16#10000) orelse (C > 16#10FFFF) -> %% Overlong encoding or invalid code point. invalid_utf8_indexes(Rest, 4 + N, [3 + N, 2 + N, 1 + N, N | Acc]); _ -> invalid_utf8_indexes(Rest, 4 + N, Acc) end; invalid_utf8_indexes(<<_, Rest/binary>>, N, Acc) -> %% Invalid char invalid_utf8_indexes(Rest, 1 + N, [N | Acc]); invalid_utf8_indexes(<<>>, _N, Acc) -> lists:reverse(Acc). %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). binary_skip_bytes_test() -> ?assertEqual(<<"foo">>, binary_skip_bytes(<<"foo">>, [])), ?assertEqual(<<"foobar">>, binary_skip_bytes(<<"foo bar">>, [3])), ?assertEqual(<<"foo">>, binary_skip_bytes(<<"foo bar">>, [3, 4, 5, 6])), ?assertEqual(<<"oo bar">>, binary_skip_bytes(<<"foo bar">>, [0])), ok. invalid_utf8_indexes_test() -> ?assertEqual( [], invalid_utf8_indexes(<<"unicode snowman for you: ", 226, 152, 131>>)), ?assertEqual( [0], invalid_utf8_indexes(<<128>>)), ?assertEqual( [57,59,60,64,66,67], invalid_utf8_indexes(<<"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; (", 167, 65, 170, 186, 73, 83, 80, 166, 87, 186, 217, 41, 41>>)), ok. codepoint_to_bytes_test() -> %% U+0000 - U+007F - 7 bits %% U+0080 - U+07FF - 11 bits %% U+0800 - U+FFFF - 16 bits (excluding UTC-16 surrogate code points) %% U+10000 - U+10FFFF - 21 bits ?assertEqual( <<"a">>, codepoint_to_bytes($a)), ?assertEqual( <<16#c2, 16#80>>, codepoint_to_bytes(16#80)), ?assertEqual( <<16#df, 16#bf>>, codepoint_to_bytes(16#07ff)), ?assertEqual( <<16#ef, 16#bf, 16#bf>>, codepoint_to_bytes(16#ffff)), ?assertEqual( <<16#f4, 16#8f, 16#bf, 16#bf>>, codepoint_to_bytes(16#10ffff)), ok. bytes_foldl_test() -> ?assertEqual( <<"abc">>, bytes_foldl(fun (B, Acc) -> <> end, <<>>, <<"abc">>)), ?assertEqual( <<"abc", 226, 152, 131, 228, 184, 173, 194, 133, 244,143,191,191>>, bytes_foldl(fun (B, Acc) -> <> end, <<>>, <<"abc", 226, 152, 131, 228, 184, 173, 194, 133, 244,143,191,191>>)), ok. bytes_to_codepoints_test() -> ?assertEqual( "abc" ++ [16#2603, 16#4e2d, 16#85, 16#10ffff], bytes_to_codepoints(<<"abc", 226, 152, 131, 228, 184, 173, 194, 133, 244,143,191,191>>)), ok. codepoint_foldl_test() -> ?assertEqual( "cba", codepoint_foldl(fun (C, Acc) -> [C | Acc] end, [], <<"abc">>)), ?assertEqual( [16#10ffff, 16#85, 16#4e2d, 16#2603 | "cba"], codepoint_foldl(fun (C, Acc) -> [C | Acc] end, [], <<"abc", 226, 152, 131, 228, 184, 173, 194, 133, 244,143,191,191>>)), ok. len_test() -> ?assertEqual( 29, len(<<"unicode snowman for you: ", 226, 152, 131, 228, 184, 173, 194, 133, 244, 143, 191, 191>>)), ok. codepoints_to_bytes_test() -> ?assertEqual( iolist_to_binary(lists:map(fun codepoint_to_bytes/1, lists:seq(1, 1000))), codepoints_to_bytes(lists:seq(1, 1000))), ok. valid_utf8_bytes_test() -> ?assertEqual( <<"invalid U+11ffff: ">>, valid_utf8_bytes(<<"invalid U+11ffff: ", 244, 159, 191, 191>>)), ?assertEqual( <<"U+10ffff: ", 244, 143, 191, 191>>, valid_utf8_bytes(<<"U+10ffff: ", 244, 143, 191, 191>>)), ?assertEqual( <<"overlong 2-byte encoding (a): ">>, valid_utf8_bytes(<<"overlong 2-byte encoding (a): ", 2#11000001, 2#10100001>>)), ?assertEqual( <<"overlong 2-byte encoding (!): ">>, valid_utf8_bytes(<<"overlong 2-byte encoding (!): ", 2#11000000, 2#10100001>>)), ?assertEqual( <<"mu: ", 194, 181>>, valid_utf8_bytes(<<"mu: ", 194, 181>>)), ?assertEqual( <<"bad coding bytes: ">>, valid_utf8_bytes(<<"bad coding bytes: ", 2#10011111, 2#10111111, 2#11111111>>)), ?assertEqual( <<"low surrogate (unpaired): ">>, valid_utf8_bytes(<<"low surrogate (unpaired): ", 237, 176, 128>>)), ?assertEqual( <<"high surrogate (unpaired): ">>, valid_utf8_bytes(<<"high surrogate (unpaired): ", 237, 191, 191>>)), ?assertEqual( <<"unicode snowman for you: ", 226, 152, 131>>, valid_utf8_bytes(<<"unicode snowman for you: ", 226, 152, 131>>)), ?assertEqual( <<"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; (AISPW))">>, valid_utf8_bytes(<<"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; (", 167, 65, 170, 186, 73, 83, 80, 166, 87, 186, 217, 41, 41>>)), ok. -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb_http.erl0000644000177700017770000002264512633765070030713 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2007 Mochi Media, Inc. %% @doc HTTP server. -module(mochiweb_http). -author('bob@mochimedia.com'). -export([start/1, start_link/1, stop/0, stop/1]). -export([loop/2]). -export([after_response/2, reentry/1]). -export([parse_range_request/1, range_skip_length/2]). -define(REQUEST_RECV_TIMEOUT, 300000). %% timeout waiting for request line -define(HEADERS_RECV_TIMEOUT, 30000). %% timeout waiting for headers -define(MAX_HEADERS, 1000). -define(DEFAULTS, [{name, ?MODULE}, {port, 8888}]). parse_options(Options) -> {loop, HttpLoop} = proplists:lookup(loop, Options), Loop = {?MODULE, loop, [HttpLoop]}, Options1 = [{loop, Loop} | proplists:delete(loop, Options)], mochilists:set_defaults(?DEFAULTS, Options1). stop() -> mochiweb_socket_server:stop(?MODULE). stop(Name) -> mochiweb_socket_server:stop(Name). %% @spec start(Options) -> ServerRet %% Options = [option()] %% Option = {name, atom()} | {ip, string() | tuple()} | {backlog, integer()} %% | {nodelay, boolean()} | {acceptor_pool_size, integer()} %% | {ssl, boolean()} | {profile_fun, undefined | (Props) -> ok} %% | {link, false} %% @doc Start a mochiweb server. %% profile_fun is used to profile accept timing. %% After each accept, if defined, profile_fun is called with a proplist of a subset of the mochiweb_socket_server state and timing information. %% The proplist is as follows: [{name, Name}, {port, Port}, {active_sockets, ActiveSockets}, {timing, Timing}]. %% @end start(Options) -> mochiweb_socket_server:start(parse_options(Options)). start_link(Options) -> mochiweb_socket_server:start_link(parse_options(Options)). loop(Socket, Body) -> ok = mochiweb_socket:setopts(Socket, [{packet, http}]), request(Socket, Body). -ifdef(gen_tcp_r15b_workaround). -define(R15B_GEN_TCP_FIX, {tcp_error,_,emsgsize} -> % R15B02 returns this then closes the socket, so close and exit mochiweb_socket:close(Socket), exit(normal); ). -else. -define(R15B_GEN_TCP_FIX,). -endif. request(Socket, Body) -> ok = mochiweb_socket:setopts(Socket, [{active, once}]), receive {Protocol, _, {http_request, Method, Path, Version}} when Protocol == http orelse Protocol == ssl -> ok = mochiweb_socket:setopts(Socket, [{packet, httph}]), headers(Socket, {Method, Path, Version}, [], Body, 0); {Protocol, _, {http_error, "\r\n"}} when Protocol == http orelse Protocol == ssl -> request(Socket, Body); {Protocol, _, {http_error, "\n"}} when Protocol == http orelse Protocol == ssl -> request(Socket, Body); {tcp_closed, _} -> mochiweb_socket:close(Socket), exit(normal); {ssl_closed, _} -> mochiweb_socket:close(Socket), exit(normal); ?R15B_GEN_TCP_FIX _Other -> handle_invalid_request(Socket) after ?REQUEST_RECV_TIMEOUT -> mochiweb_socket:close(Socket), exit(normal) end. reentry(Body) -> fun (Req) -> ?MODULE:after_response(Body, Req) end. headers(Socket, Request, Headers, _Body, ?MAX_HEADERS) -> %% Too many headers sent, bad request. ok = mochiweb_socket:setopts(Socket, [{packet, raw}]), handle_invalid_request(Socket, Request, Headers); headers(Socket, Request, Headers, Body, HeaderCount) -> ok = mochiweb_socket:setopts(Socket, [{active, once}]), receive {Protocol, _, http_eoh} when Protocol == http orelse Protocol == ssl -> Req = new_request(Socket, Request, Headers), call_body(Body, Req), ?MODULE:after_response(Body, Req); {Protocol, _, {http_header, _, Name, _, Value}} when Protocol == http orelse Protocol == ssl -> headers(Socket, Request, [{Name, Value} | Headers], Body, 1 + HeaderCount); {tcp_closed, _} -> mochiweb_socket:close(Socket), exit(normal); ?R15B_GEN_TCP_FIX _Other -> handle_invalid_request(Socket, Request, Headers) after ?HEADERS_RECV_TIMEOUT -> mochiweb_socket:close(Socket), exit(normal) end. call_body({M, F, A}, Req) -> erlang:apply(M, F, [Req | A]); call_body({M, F}, Req) -> M:F(Req); call_body(Body, Req) -> Body(Req). %% -spec handle_invalid_request(term()) -> no_return(). handle_invalid_request(Socket) -> handle_invalid_request(Socket, {'GET', {abs_path, "/"}, {0,9}}, []), exit(normal). %% -spec handle_invalid_request(term(), term(), term()) -> no_return(). handle_invalid_request(Socket, Request, RevHeaders) -> Req = new_request(Socket, Request, RevHeaders), Req:respond({400, [], []}), mochiweb_socket:close(Socket), exit(normal). new_request(Socket, Request, RevHeaders) -> ok = mochiweb_socket:setopts(Socket, [{packet, raw}]), mochiweb:new_request({Socket, Request, lists:reverse(RevHeaders)}). after_response(Body, Req) -> Socket = Req:get(socket), case Req:should_close() of true -> mochiweb_socket:close(Socket), exit(normal); false -> Req:cleanup(), erlang:garbage_collect(), ?MODULE:loop(Socket, Body) end. parse_range_request("bytes=0-") -> undefined; parse_range_request(RawRange) when is_list(RawRange) -> try "bytes=" ++ RangeString = RawRange, Ranges = string:tokens(RangeString, ","), lists:map(fun ("-" ++ V) -> {none, list_to_integer(V)}; (R) -> case string:tokens(R, "-") of [S1, S2] -> {list_to_integer(S1), list_to_integer(S2)}; [S] -> {list_to_integer(S), none} end end, Ranges) catch _:_ -> fail end. range_skip_length(Spec, Size) -> case Spec of {none, R} when R =< Size, R >= 0 -> {Size - R, R}; {none, _OutOfRange} -> {0, Size}; {R, none} when R >= 0, R < Size -> {R, Size - R}; {_OutOfRange, none} -> invalid_range; {Start, End} when 0 =< Start, Start =< End, End < Size -> {Start, End - Start + 1}; {Start, End} when 0 =< Start, Start =< End, End >= Size -> {Start, Size - Start}; {_OutOfRange, _End} -> invalid_range end. %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). range_test() -> %% valid, single ranges ?assertEqual([{20, 30}], parse_range_request("bytes=20-30")), ?assertEqual([{20, none}], parse_range_request("bytes=20-")), ?assertEqual([{none, 20}], parse_range_request("bytes=-20")), %% trivial single range ?assertEqual(undefined, parse_range_request("bytes=0-")), %% invalid, single ranges ?assertEqual(fail, parse_range_request("")), ?assertEqual(fail, parse_range_request("garbage")), ?assertEqual(fail, parse_range_request("bytes=-20-30")), %% valid, multiple range ?assertEqual( [{20, 30}, {50, 100}, {110, 200}], parse_range_request("bytes=20-30,50-100,110-200")), ?assertEqual( [{20, none}, {50, 100}, {none, 200}], parse_range_request("bytes=20-,50-100,-200")), %% no ranges ?assertEqual([], parse_range_request("bytes=")), ok. range_skip_length_test() -> Body = <<"012345678901234567890123456789012345678901234567890123456789">>, BodySize = byte_size(Body), %% 60 BodySize = 60, %% these values assume BodySize =:= 60 ?assertEqual({1,9}, range_skip_length({1,9}, BodySize)), %% 1-9 ?assertEqual({10,10}, range_skip_length({10,19}, BodySize)), %% 10-19 ?assertEqual({40, 20}, range_skip_length({none, 20}, BodySize)), %% -20 ?assertEqual({30, 30}, range_skip_length({30, none}, BodySize)), %% 30- %% valid edge cases for range_skip_length ?assertEqual({BodySize, 0}, range_skip_length({none, 0}, BodySize)), ?assertEqual({0, BodySize}, range_skip_length({none, BodySize}, BodySize)), ?assertEqual({0, BodySize}, range_skip_length({0, none}, BodySize)), BodySizeLess1 = BodySize - 1, ?assertEqual({BodySizeLess1, 1}, range_skip_length({BodySize - 1, none}, BodySize)), ?assertEqual({BodySizeLess1, 1}, range_skip_length({BodySize - 1, BodySize+5}, BodySize)), ?assertEqual({BodySizeLess1, 1}, range_skip_length({BodySize - 1, BodySize}, BodySize)), %% out of range, return whole thing ?assertEqual({0, BodySize}, range_skip_length({none, BodySize + 1}, BodySize)), ?assertEqual({0, BodySize}, range_skip_length({none, -1}, BodySize)), ?assertEqual({0, BodySize}, range_skip_length({0, BodySize + 1}, BodySize)), %% invalid ranges ?assertEqual(invalid_range, range_skip_length({-1, 30}, BodySize)), ?assertEqual(invalid_range, range_skip_length({-1, BodySize + 1}, BodySize)), ?assertEqual(invalid_range, range_skip_length({BodySize, 40}, BodySize)), ?assertEqual(invalid_range, range_skip_length({-1, none}, BodySize)), ?assertEqual(invalid_range, range_skip_length({BodySize, none}, BodySize)), ok. -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochifmt.erl0000644000177700017770000003541412633765070027663 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2008 Mochi Media, Inc. %% @doc String Formatting for Erlang, inspired by Python 2.6 %% (PEP 3101). %% -module(mochifmt). -author('bob@mochimedia.com'). -export([format/2, format_field/2, convert_field/2, get_value/2, get_field/2]). -export([tokenize/1, format/3, get_field/3, format_field/3]). -export([bformat/2, bformat/3]). -export([f/2, f/3]). -record(conversion, {length, precision, ctype, align, fill_char, sign}). %% @spec tokenize(S::string()) -> tokens() %% @doc Tokenize a format string into mochifmt's internal format. tokenize(S) -> {?MODULE, tokenize(S, "", [])}. %% @spec convert_field(Arg, Conversion::conversion()) -> term() %% @doc Process Arg according to the given explicit conversion specifier. convert_field(Arg, "") -> Arg; convert_field(Arg, "r") -> repr(Arg); convert_field(Arg, "s") -> str(Arg). %% @spec get_value(Key::string(), Args::args()) -> term() %% @doc Get the Key from Args. If Args is a tuple then convert Key to %% an integer and get element(1 + Key, Args). If Args is a list and Key %% can be parsed as an integer then use lists:nth(1 + Key, Args), %% otherwise try and look for Key in Args as a proplist, converting %% Key to an atom or binary if necessary. get_value(Key, Args) when is_tuple(Args) -> element(1 + list_to_integer(Key), Args); get_value(Key, Args) when is_list(Args) -> try lists:nth(1 + list_to_integer(Key), Args) catch error:_ -> {_K, V} = proplist_lookup(Key, Args), V end. %% @spec get_field(Key::string(), Args) -> term() %% @doc Consecutively call get_value/2 on parts of Key delimited by ".", %% replacing Args with the result of the previous get_value. This %% is used to implement formats such as {0.0}. get_field(Key, Args) -> get_field(Key, Args, ?MODULE). %% @spec get_field(Key::string(), Args, Module) -> term() %% @doc Consecutively call Module:get_value/2 on parts of Key delimited by ".", %% replacing Args with the result of the previous get_value. This %% is used to implement formats such as {0.0}. get_field(Key, Args, Module) -> {Name, Next} = lists:splitwith(fun (C) -> C =/= $. end, Key), Res = try Module:get_value(Name, Args) catch error:undef -> get_value(Name, Args) end, case Next of "" -> Res; "." ++ S1 -> get_field(S1, Res, Module) end. %% @spec format(Format::string(), Args) -> iolist() %% @doc Format Args with Format. format(Format, Args) -> format(Format, Args, ?MODULE). %% @spec format(Format::string(), Args, Module) -> iolist() %% @doc Format Args with Format using Module. format({?MODULE, Parts}, Args, Module) -> format2(Parts, Args, Module, []); format(S, Args, Module) -> format(tokenize(S), Args, Module). %% @spec format_field(Arg, Format) -> iolist() %% @doc Format Arg with Format. format_field(Arg, Format) -> format_field(Arg, Format, ?MODULE). %% @spec format_field(Arg, Format, _Module) -> iolist() %% @doc Format Arg with Format. format_field(Arg, Format, _Module) -> F = default_ctype(Arg, parse_std_conversion(Format)), fix_padding(fix_sign(convert2(Arg, F), F), F). %% @spec f(Format::string(), Args) -> string() %% @doc Format Args with Format and return a string(). f(Format, Args) -> f(Format, Args, ?MODULE). %% @spec f(Format::string(), Args, Module) -> string() %% @doc Format Args with Format using Module and return a string(). f(Format, Args, Module) -> case lists:member(${, Format) of true -> binary_to_list(bformat(Format, Args, Module)); false -> Format end. %% @spec bformat(Format::string(), Args) -> binary() %% @doc Format Args with Format and return a binary(). bformat(Format, Args) -> iolist_to_binary(format(Format, Args)). %% @spec bformat(Format::string(), Args, Module) -> binary() %% @doc Format Args with Format using Module and return a binary(). bformat(Format, Args, Module) -> iolist_to_binary(format(Format, Args, Module)). %% Internal API add_raw("", Acc) -> Acc; add_raw(S, Acc) -> [{raw, lists:reverse(S)} | Acc]. tokenize([], S, Acc) -> lists:reverse(add_raw(S, Acc)); tokenize("{{" ++ Rest, S, Acc) -> tokenize(Rest, "{" ++ S, Acc); tokenize("{" ++ Rest, S, Acc) -> {Format, Rest1} = tokenize_format(Rest), tokenize(Rest1, "", [{format, make_format(Format)} | add_raw(S, Acc)]); tokenize("}}" ++ Rest, S, Acc) -> tokenize(Rest, "}" ++ S, Acc); tokenize([C | Rest], S, Acc) -> tokenize(Rest, [C | S], Acc). tokenize_format(S) -> tokenize_format(S, 1, []). tokenize_format("}" ++ Rest, 1, Acc) -> {lists:reverse(Acc), Rest}; tokenize_format("}" ++ Rest, N, Acc) -> tokenize_format(Rest, N - 1, "}" ++ Acc); tokenize_format("{" ++ Rest, N, Acc) -> tokenize_format(Rest, 1 + N, "{" ++ Acc); tokenize_format([C | Rest], N, Acc) -> tokenize_format(Rest, N, [C | Acc]). make_format(S) -> {Name0, Spec} = case lists:splitwith(fun (C) -> C =/= $: end, S) of {_, ""} -> {S, ""}; {SN, ":" ++ SS} -> {SN, SS} end, {Name, Transform} = case lists:splitwith(fun (C) -> C =/= $! end, Name0) of {_, ""} -> {Name0, ""}; {TN, "!" ++ TT} -> {TN, TT} end, {Name, Transform, Spec}. proplist_lookup(S, P) -> A = try list_to_existing_atom(S) catch error:_ -> make_ref() end, B = try list_to_binary(S) catch error:_ -> make_ref() end, proplist_lookup2({S, A, B}, P). proplist_lookup2({KS, KA, KB}, [{K, V} | _]) when KS =:= K orelse KA =:= K orelse KB =:= K -> {K, V}; proplist_lookup2(Keys, [_ | Rest]) -> proplist_lookup2(Keys, Rest). format2([], _Args, _Module, Acc) -> lists:reverse(Acc); format2([{raw, S} | Rest], Args, Module, Acc) -> format2(Rest, Args, Module, [S | Acc]); format2([{format, {Key, Convert, Format0}} | Rest], Args, Module, Acc) -> Format = f(Format0, Args, Module), V = case Module of ?MODULE -> V0 = get_field(Key, Args), V1 = convert_field(V0, Convert), format_field(V1, Format); _ -> V0 = try Module:get_field(Key, Args) catch error:undef -> get_field(Key, Args, Module) end, V1 = try Module:convert_field(V0, Convert) catch error:undef -> convert_field(V0, Convert) end, try Module:format_field(V1, Format) catch error:undef -> format_field(V1, Format, Module) end end, format2(Rest, Args, Module, [V | Acc]). default_ctype(_Arg, C=#conversion{ctype=N}) when N =/= undefined -> C; default_ctype(Arg, C) when is_integer(Arg) -> C#conversion{ctype=decimal}; default_ctype(Arg, C) when is_float(Arg) -> C#conversion{ctype=general}; default_ctype(_Arg, C) -> C#conversion{ctype=string}. fix_padding(Arg, #conversion{length=undefined}) -> Arg; fix_padding(Arg, F=#conversion{length=Length, fill_char=Fill0, align=Align0, ctype=Type}) -> Padding = Length - iolist_size(Arg), Fill = case Fill0 of undefined -> $\s; _ -> Fill0 end, Align = case Align0 of undefined -> case Type of string -> left; _ -> right end; _ -> Align0 end, case Padding > 0 of true -> do_padding(Arg, Padding, Fill, Align, F); false -> Arg end. do_padding(Arg, Padding, Fill, right, _F) -> [lists:duplicate(Padding, Fill), Arg]; do_padding(Arg, Padding, Fill, center, _F) -> LPadding = lists:duplicate(Padding div 2, Fill), RPadding = case Padding band 1 of 1 -> [Fill | LPadding]; _ -> LPadding end, [LPadding, Arg, RPadding]; do_padding([$- | Arg], Padding, Fill, sign_right, _F) -> [[$- | lists:duplicate(Padding, Fill)], Arg]; do_padding(Arg, Padding, Fill, sign_right, #conversion{sign=$-}) -> [lists:duplicate(Padding, Fill), Arg]; do_padding([S | Arg], Padding, Fill, sign_right, #conversion{sign=S}) -> [[S | lists:duplicate(Padding, Fill)], Arg]; do_padding(Arg, Padding, Fill, sign_right, #conversion{sign=undefined}) -> [lists:duplicate(Padding, Fill), Arg]; do_padding(Arg, Padding, Fill, left, _F) -> [Arg | lists:duplicate(Padding, Fill)]. fix_sign(Arg, #conversion{sign=$+}) when Arg >= 0 -> [$+, Arg]; fix_sign(Arg, #conversion{sign=$\s}) when Arg >= 0 -> [$\s, Arg]; fix_sign(Arg, _F) -> Arg. ctype($\%) -> percent; ctype($s) -> string; ctype($b) -> bin; ctype($o) -> oct; ctype($X) -> upper_hex; ctype($x) -> hex; ctype($c) -> char; ctype($d) -> decimal; ctype($g) -> general; ctype($f) -> fixed; ctype($e) -> exp. align($<) -> left; align($>) -> right; align($^) -> center; align($=) -> sign_right. convert2(Arg, F=#conversion{ctype=percent}) -> [convert2(100.0 * Arg, F#conversion{ctype=fixed}), $\%]; convert2(Arg, #conversion{ctype=string}) -> str(Arg); convert2(Arg, #conversion{ctype=bin}) -> erlang:integer_to_list(Arg, 2); convert2(Arg, #conversion{ctype=oct}) -> erlang:integer_to_list(Arg, 8); convert2(Arg, #conversion{ctype=upper_hex}) -> erlang:integer_to_list(Arg, 16); convert2(Arg, #conversion{ctype=hex}) -> string:to_lower(erlang:integer_to_list(Arg, 16)); convert2(Arg, #conversion{ctype=char}) when Arg < 16#80 -> [Arg]; convert2(Arg, #conversion{ctype=char}) -> xmerl_ucs:to_utf8(Arg); convert2(Arg, #conversion{ctype=decimal}) -> integer_to_list(Arg); convert2(Arg, #conversion{ctype=general, precision=undefined}) -> try mochinum:digits(Arg) catch error:undef -> io_lib:format("~g", [Arg]) end; convert2(Arg, #conversion{ctype=fixed, precision=undefined}) -> io_lib:format("~f", [Arg]); convert2(Arg, #conversion{ctype=exp, precision=undefined}) -> io_lib:format("~e", [Arg]); convert2(Arg, #conversion{ctype=general, precision=P}) -> io_lib:format("~." ++ integer_to_list(P) ++ "g", [Arg]); convert2(Arg, #conversion{ctype=fixed, precision=P}) -> io_lib:format("~." ++ integer_to_list(P) ++ "f", [Arg]); convert2(Arg, #conversion{ctype=exp, precision=P}) -> io_lib:format("~." ++ integer_to_list(P) ++ "e", [Arg]). str(A) when is_atom(A) -> atom_to_list(A); str(I) when is_integer(I) -> integer_to_list(I); str(F) when is_float(F) -> try mochinum:digits(F) catch error:undef -> io_lib:format("~g", [F]) end; str(L) when is_list(L) -> L; str(B) when is_binary(B) -> B; str(P) -> repr(P). repr(P) when is_float(P) -> try mochinum:digits(P) catch error:undef -> float_to_list(P) end; repr(P) -> io_lib:format("~p", [P]). parse_std_conversion(S) -> parse_std_conversion(S, #conversion{}). parse_std_conversion("", Acc) -> Acc; parse_std_conversion([Fill, Align | Spec], Acc) when Align =:= $< orelse Align =:= $> orelse Align =:= $= orelse Align =:= $^ -> parse_std_conversion(Spec, Acc#conversion{fill_char=Fill, align=align(Align)}); parse_std_conversion([Align | Spec], Acc) when Align =:= $< orelse Align =:= $> orelse Align =:= $= orelse Align =:= $^ -> parse_std_conversion(Spec, Acc#conversion{align=align(Align)}); parse_std_conversion([Sign | Spec], Acc) when Sign =:= $+ orelse Sign =:= $- orelse Sign =:= $\s -> parse_std_conversion(Spec, Acc#conversion{sign=Sign}); parse_std_conversion("0" ++ Spec, Acc) -> Align = case Acc#conversion.align of undefined -> sign_right; A -> A end, parse_std_conversion(Spec, Acc#conversion{fill_char=$0, align=Align}); parse_std_conversion(Spec=[D|_], Acc) when D >= $0 andalso D =< $9 -> {W, Spec1} = lists:splitwith(fun (C) -> C >= $0 andalso C =< $9 end, Spec), parse_std_conversion(Spec1, Acc#conversion{length=list_to_integer(W)}); parse_std_conversion([$. | Spec], Acc) -> case lists:splitwith(fun (C) -> C >= $0 andalso C =< $9 end, Spec) of {"", Spec1} -> parse_std_conversion(Spec1, Acc); {P, Spec1} -> parse_std_conversion(Spec1, Acc#conversion{precision=list_to_integer(P)}) end; parse_std_conversion([Type], Acc) -> parse_std_conversion("", Acc#conversion{ctype=ctype(Type)}). %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). tokenize_test() -> {?MODULE, [{raw, "ABC"}]} = tokenize("ABC"), {?MODULE, [{format, {"0", "", ""}}]} = tokenize("{0}"), {?MODULE, [{raw, "ABC"}, {format, {"1", "", ""}}, {raw, "DEF"}]} = tokenize("ABC{1}DEF"), ok. format_test() -> <<" -4">> = bformat("{0:4}", [-4]), <<" 4">> = bformat("{0:4}", [4]), <<" 4">> = bformat("{0:{0}}", [4]), <<"4 ">> = bformat("{0:4}", ["4"]), <<"4 ">> = bformat("{0:{0}}", ["4"]), <<"1.2yoDEF">> = bformat("{2}{0}{1}{3}", {yo, "DE", 1.2, <<"F">>}), <<"cafebabe">> = bformat("{0:x}", {16#cafebabe}), <<"CAFEBABE">> = bformat("{0:X}", {16#cafebabe}), <<"CAFEBABE">> = bformat("{0:X}", {16#cafebabe}), <<"755">> = bformat("{0:o}", {8#755}), <<"a">> = bformat("{0:c}", {97}), %% Horizontal ellipsis <<226, 128, 166>> = bformat("{0:c}", {16#2026}), <<"11">> = bformat("{0:b}", {3}), <<"11">> = bformat("{0:b}", [3]), <<"11">> = bformat("{three:b}", [{three, 3}]), <<"11">> = bformat("{three:b}", [{"three", 3}]), <<"11">> = bformat("{three:b}", [{<<"three">>, 3}]), <<"\"foo\"">> = bformat("{0!r}", {"foo"}), <<"2008-5-4">> = bformat("{0.0}-{0.1}-{0.2}", {{2008,5,4}}), <<"2008-05-04">> = bformat("{0.0:04}-{0.1:02}-{0.2:02}", {{2008,5,4}}), <<"foo6bar-6">> = bformat("foo{1}{0}-{1}", {bar, 6}), <<"-'atom test'-">> = bformat("-{arg!r}-", [{arg, 'atom test'}]), <<"2008-05-04">> = bformat("{0.0:0{1.0}}-{0.1:0{1.1}}-{0.2:0{1.2}}", {{2008,5,4}, {4, 2, 2}}), ok. std_test() -> M = mochifmt_std:new(), <<"01">> = bformat("{0}{1}", [0, 1], M), ok. records_test() -> M = mochifmt_records:new([{conversion, record_info(fields, conversion)}]), R = #conversion{length=long, precision=hard, sign=peace}, long = M:get_value("length", R), hard = M:get_value("precision", R), peace = M:get_value("sign", R), <<"long hard">> = bformat("{length} {precision}", R, M), <<"long hard">> = bformat("{0.length} {0.precision}", [R], M), ok. -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochifmt_records.erl0000644000177700017770000000206612633765070031401 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2008 Mochi Media, Inc. %% @doc Formatter that understands records. %% %% Usage: %% %% 1> M = mochifmt_records:new([{rec, record_info(fields, rec)}]), %% M:format("{0.bar}", [#rec{bar=foo}]). %% foo -module(mochifmt_records). -author('bob@mochimedia.com'). -export([new/1, get_value/3]). new([{_Rec, RecFields}]=Recs) when is_list(RecFields) -> {?MODULE, Recs}. get_value(Key, Rec, {?MODULE, Recs}) when is_tuple(Rec) and is_atom(element(1, Rec)) -> try begin Atom = list_to_existing_atom(Key), {_, Fields} = proplists:lookup(element(1, Rec), Recs), element(get_rec_index(Atom, Fields, 2), Rec) end catch error:_ -> mochifmt:get_value(Key, Rec) end; get_value(Key, Args, {?MODULE, _Recs}) -> mochifmt:get_value(Key, Args). get_rec_index(Atom, [Atom | _], Index) -> Index; get_rec_index(Atom, [_ | Rest], Index) -> get_rec_index(Atom, Rest, 1 + Index). %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb_response.erl0000644000177700017770000000442512633765070031566 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2007 Mochi Media, Inc. %% @doc Response abstraction. -module(mochiweb_response). -author('bob@mochimedia.com'). -define(QUIP, "Any of you quaids got a smint?"). -export([new/3, get_header_value/2, get/2, dump/1]). -export([send/2, write_chunk/2]). %% @type response(). A mochiweb_response parameterized module instance. %% @spec new(Request, Code, Headers) -> response() %% @doc Create a new mochiweb_response instance. new(Request, Code, Headers) -> {?MODULE, [Request, Code, Headers]}. %% @spec get_header_value(string() | atom() | binary(), response()) -> %% string() | undefined %% @doc Get the value of the given response header. get_header_value(K, {?MODULE, [_Request, _Code, Headers]}) -> mochiweb_headers:get_value(K, Headers). %% @spec get(request | code | headers, response()) -> term() %% @doc Return the internal representation of the given field. get(request, {?MODULE, [Request, _Code, _Headers]}) -> Request; get(code, {?MODULE, [_Request, Code, _Headers]}) -> Code; get(headers, {?MODULE, [_Request, _Code, Headers]}) -> Headers. %% @spec dump(response()) -> {mochiweb_request, [{atom(), term()}]} %% @doc Dump the internal representation to a "human readable" set of terms %% for debugging/inspection purposes. dump({?MODULE, [Request, Code, Headers]}) -> [{request, Request:dump()}, {code, Code}, {headers, mochiweb_headers:to_list(Headers)}]. %% @spec send(iodata(), response()) -> ok %% @doc Send data over the socket if the method is not HEAD. send(Data, {?MODULE, [Request, _Code, _Headers]}) -> case Request:get(method) of 'HEAD' -> ok; _ -> Request:send(Data) end. %% @spec write_chunk(iodata(), response()) -> ok %% @doc Write a chunk of a HTTP chunked response. If Data is zero length, %% then the chunked response will be finished. write_chunk(Data, {?MODULE, [Request, _Code, _Headers]}=THIS) -> case Request:get(version) of Version when Version >= {1, 1} -> Length = iolist_size(Data), send([io_lib:format("~.16b\r\n", [Length]), Data, <<"\r\n">>], THIS); _ -> send(Data, THIS) end. %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb_io.erl0000644000177700017770000000212712633765070030334 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2007 Mochi Media, Inc. %% @doc Utilities for dealing with IO devices (open files). -module(mochiweb_io). -author('bob@mochimedia.com'). -export([iodevice_stream/3, iodevice_stream/2]). -export([iodevice_foldl/4, iodevice_foldl/3]). -export([iodevice_size/1]). -define(READ_SIZE, 8192). iodevice_foldl(F, Acc, IoDevice) -> iodevice_foldl(F, Acc, IoDevice, ?READ_SIZE). iodevice_foldl(F, Acc, IoDevice, BufferSize) -> case file:read(IoDevice, BufferSize) of eof -> Acc; {ok, Data} -> iodevice_foldl(F, F(Data, Acc), IoDevice, BufferSize) end. iodevice_stream(Callback, IoDevice) -> iodevice_stream(Callback, IoDevice, ?READ_SIZE). iodevice_stream(Callback, IoDevice, BufferSize) -> F = fun (Data, ok) -> Callback(Data) end, ok = iodevice_foldl(F, ok, IoDevice, BufferSize). iodevice_size(IoDevice) -> {ok, Size} = file:position(IoDevice, eof), {ok, 0} = file:position(IoDevice, bof), Size. %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb_session.erl0000644000177700017770000001603312633765070031411 0ustar michaelmichael%% @author Asier Azkuenaga Batiz %% @doc HTTP Cookie session. Note that the expiration time travels unencrypted %% as far as this module is concerned. In order to achieve more security, %% it is advised to use https. %% Based on the paper %% %% "A Secure Cookie Protocol". %% This module is only supported on R15B02 and later, the AES CFB mode is not %% available in earlier releases of crypto. -module(mochiweb_session). -export([generate_session_data/4, generate_session_cookie/4, check_session_cookie/4]). -export_types([expiration_time/0]). -type expiration_time() :: integer(). -type key_fun() :: fun((string()) -> iolist()). %% TODO: Import this from elsewhere after attribute types refactor. -type header() :: {string(), string()}. %% @doc Generates a secure encrypted binary convining all the parameters. The %% expiration time must be a 32-bit integer. %% -spec generate_session_data( %% ExpirationTime :: expiration_time(), %% Data :: iolist(), %% FSessionKey :: key_fun(), %% ServerKey :: iolist()) -> binary(). generate_session_data(ExpirationTime, Data, FSessionKey, ServerKey) when is_integer(ExpirationTime), is_function(FSessionKey)-> BData = ensure_binary(Data), ExpTime = integer_to_list(ExpirationTime), Key = gen_key(ExpTime, ServerKey), Hmac = gen_hmac(ExpTime, BData, FSessionKey(ExpTime), Key), EData = encrypt_data(BData, Key), mochiweb_base64url:encode( <>). %% @doc Convenience wrapper for generate_session_data that returns a %% mochiweb cookie with "id" as the key, a max_age of 20000 seconds, %% and the current local time as local time. %% -spec generate_session_cookie( %% ExpirationTime :: expiration_time(), %% Data :: iolist(), %% FSessionKey :: key_fun(), %% ServerKey :: iolist()) -> header(). generate_session_cookie(ExpirationTime, Data, FSessionKey, ServerKey) when is_integer(ExpirationTime), is_function(FSessionKey)-> CookieData = generate_session_data(ExpirationTime, Data, FSessionKey, ServerKey), mochiweb_cookies:cookie("id", CookieData, [{max_age, 20000}, {local_time, calendar:universal_time_to_local_time( calendar:universal_time())}]). %% TODO: This return type is messy to express in the type system. %% -spec check_session_cookie( %% ECookie :: binary(), %% ExpirationTime :: string(), %% FSessionKey :: key_fun(), %% ServerKey :: iolist()) -> %% {Success :: boolean(), %% ExpTimeAndData :: [integer() | binary()]}. check_session_cookie(ECookie, ExpirationTime, FSessionKey, ServerKey) when is_binary(ECookie), is_integer(ExpirationTime), is_function(FSessionKey) -> case mochiweb_base64url:decode(ECookie) of <> -> ETString = integer_to_list(ExpirationTime1), Key = gen_key(ETString, ServerKey), Data = decrypt_data(EData, Key), Hmac2 = gen_hmac(ETString, Data, FSessionKey(ETString), Key), {ExpirationTime1 >= ExpirationTime andalso eq(Hmac2, BHmac), [ExpirationTime1, binary_to_list(Data)]}; _ -> {false, []} end; check_session_cookie(_ECookie, _ExpirationTime, _FSessionKey, _ServerKey) -> {false, []}. %% 'Constant' time =:= operator for binary, to mitigate timing attacks. %% -spec eq(binary(), binary()) -> boolean(). eq(A, B) when is_binary(A) andalso is_binary(B) -> eq(A, B, 0). eq(<>, <>, Acc) -> eq(As, Bs, Acc bor (A bxor B)); eq(<<>>, <<>>, 0) -> true; eq(_As, _Bs, _Acc) -> false. %% -spec ensure_binary(iolist()) -> binary(). ensure_binary(B) when is_binary(B) -> B; ensure_binary(L) when is_list(L) -> iolist_to_binary(L). %% -spec encrypt_data(binary(), binary()) -> binary(). encrypt_data(Data, Key) -> IV = crypto:rand_bytes(16), Crypt = crypto:aes_cfb_128_encrypt(Key, IV, Data), <>. %% -spec decrypt_data(binary(), binary()) -> binary(). decrypt_data(<>, Key) -> crypto:aes_cfb_128_decrypt(Key, IV, Crypt). %% -spec gen_key(iolist(), iolist()) -> binary(). gen_key(ExpirationTime, ServerKey)-> crypto:md5_mac(ServerKey, [ExpirationTime]). %% -spec gen_hmac(iolist(), binary(), iolist(), binary()) -> binary(). gen_hmac(ExpirationTime, Data, SessionKey, Key) -> crypto:sha_mac(Key, [ExpirationTime, Data, SessionKey]). -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). generate_check_session_cookie_test_() -> {setup, fun setup_server_key/0, fun generate_check_session_cookie/1}. setup_server_key() -> crypto:start(), ["adfasdfasfs",30000]. generate_check_session_cookie([ServerKey, TS]) -> Id = fun (A) -> A end, TSFuture = TS + 1000, TSPast = TS - 1, [?_assertEqual( {true, [TSFuture, "alice"]}, check_session_cookie( generate_session_data(TSFuture, "alice", Id, ServerKey), TS, Id, ServerKey)), ?_assertEqual( {true, [TSFuture, "alice and"]}, check_session_cookie( generate_session_data(TSFuture, "alice and", Id, ServerKey), TS, Id, ServerKey)), ?_assertEqual( {true, [TSFuture, "alice and"]}, check_session_cookie( generate_session_data(TSFuture, "alice and", Id, ServerKey), TS, Id,ServerKey)), ?_assertEqual( {true, [TSFuture, "alice and bob"]}, check_session_cookie( generate_session_data(TSFuture, "alice and bob", Id, ServerKey), TS, Id, ServerKey)), ?_assertEqual( {true, [TSFuture, "alice jlkjfkjsdfg sdkfjgldsjgl"]}, check_session_cookie( generate_session_data(TSFuture, "alice jlkjfkjsdfg sdkfjgldsjgl", Id, ServerKey), TS, Id, ServerKey)), ?_assertEqual( {true, [TSFuture, "alice .'¡'ç+-$%/(&\""]}, check_session_cookie( generate_session_data(TSFuture, "alice .'¡'ç+-$%/(&\"" ,Id, ServerKey), TS, Id, ServerKey)), ?_assertEqual( {true,[TSFuture,"alice456689875"]}, check_session_cookie( generate_session_data(TSFuture, ["alice","456689875"], Id, ServerKey), TS, Id, ServerKey)), ?_assertError( function_clause, check_session_cookie( generate_session_data(TSFuture, {tuple,one}, Id, ServerKey), TS, Id,ServerKey)), ?_assertEqual( {false, [TSPast, "bob"]}, check_session_cookie( generate_session_data(TSPast, "bob", Id,ServerKey), TS, Id, ServerKey)) ]. -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb_html.erl0000644000177700017770000006711012633765070030674 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2007 Mochi Media, Inc. %% @doc Loosely tokenizes and generates parse trees for HTML 4. -module(mochiweb_html). -export([tokens/1, parse/1, parse_tokens/1, to_tokens/1, escape/1, escape_attr/1, to_html/1]). -compile([export_all]). -ifdef(TEST). -export([destack/1, destack/2, is_singleton/1]). -endif. %% This is a macro to placate syntax highlighters.. -define(QUOTE, $\"). %% $\" -define(SQUOTE, $\'). %% $\' -define(ADV_COL(S, N), S#decoder{column=N+S#decoder.column, offset=N+S#decoder.offset}). -define(INC_COL(S), S#decoder{column=1+S#decoder.column, offset=1+S#decoder.offset}). -define(INC_LINE(S), S#decoder{column=1, line=1+S#decoder.line, offset=1+S#decoder.offset}). -define(INC_CHAR(S, C), case C of $\n -> S#decoder{column=1, line=1+S#decoder.line, offset=1+S#decoder.offset}; _ -> S#decoder{column=1+S#decoder.column, offset=1+S#decoder.offset} end). -define(IS_WHITESPACE(C), (C =:= $\s orelse C =:= $\t orelse C =:= $\r orelse C =:= $\n)). -define(IS_LITERAL_SAFE(C), ((C >= $A andalso C =< $Z) orelse (C >= $a andalso C =< $z) orelse (C >= $0 andalso C =< $9))). -define(PROBABLE_CLOSE(C), (C =:= $> orelse ?IS_WHITESPACE(C))). -record(decoder, {line=1, column=1, offset=0}). %% @type html_node() = {string(), [html_attr()], [html_node() | string()]} %% @type html_attr() = {string(), string()} %% @type html_token() = html_data() | start_tag() | end_tag() | inline_html() | html_comment() | html_doctype() %% @type html_data() = {data, string(), Whitespace::boolean()} %% @type start_tag() = {start_tag, Name, [html_attr()], Singleton::boolean()} %% @type end_tag() = {end_tag, Name} %% @type html_comment() = {comment, Comment} %% @type html_doctype() = {doctype, [Doctype]} %% @type inline_html() = {'=', iolist()} %% External API. %% @spec parse(string() | binary()) -> html_node() %% @doc tokenize and then transform the token stream into a HTML tree. parse(Input) -> parse_tokens(tokens(Input)). %% @spec parse_tokens([html_token()]) -> html_node() %% @doc Transform the output of tokens(Doc) into a HTML tree. parse_tokens(Tokens) when is_list(Tokens) -> %% Skip over doctype, processing instructions [{start_tag, Tag, Attrs, false} | Rest] = find_document(Tokens, normal), {Tree, _} = tree(Rest, [norm({Tag, Attrs})]), Tree. find_document(Tokens=[{start_tag, _Tag, _Attrs, false} | _Rest], Mode) -> maybe_add_html_tag(Tokens, Mode); find_document([{doctype, [<<"html">>]} | Rest], _Mode) -> find_document(Rest, html5); find_document([_T | Rest], Mode) -> find_document(Rest, Mode); find_document([], _Mode) -> []. maybe_add_html_tag(Tokens=[{start_tag, Tag, _Attrs, false} | _], html5) when Tag =/= <<"html">> -> [{start_tag, <<"html">>, [], false} | Tokens]; maybe_add_html_tag(Tokens, _Mode) -> Tokens. %% @spec tokens(StringOrBinary) -> [html_token()] %% @doc Transform the input UTF-8 HTML into a token stream. tokens(Input) -> tokens(iolist_to_binary(Input), #decoder{}, []). %% @spec to_tokens(html_node()) -> [html_token()] %% @doc Convert a html_node() tree to a list of tokens. to_tokens({Tag0}) -> to_tokens({Tag0, [], []}); to_tokens(T={'=', _}) -> [T]; to_tokens(T={doctype, _}) -> [T]; to_tokens(T={comment, _}) -> [T]; to_tokens({Tag0, Acc}) -> %% This is only allowed in sub-tags: {p, [{"class", "foo"}]} to_tokens({Tag0, [], Acc}); to_tokens({Tag0, Attrs, Acc}) -> Tag = to_tag(Tag0), case is_singleton(Tag) of true -> to_tokens([], [{start_tag, Tag, Attrs, true}]); false -> to_tokens([{Tag, Acc}], [{start_tag, Tag, Attrs, false}]) end. %% @spec to_html([html_token()] | html_node()) -> iolist() %% @doc Convert a list of html_token() to a HTML document. to_html(Node) when is_tuple(Node) -> to_html(to_tokens(Node)); to_html(Tokens) when is_list(Tokens) -> to_html(Tokens, []). %% @spec escape(string() | atom() | binary()) -> binary() %% @doc Escape a string such that it's safe for HTML (amp; lt; gt;). escape(B) when is_binary(B) -> escape(binary_to_list(B), []); escape(A) when is_atom(A) -> escape(atom_to_list(A), []); escape(S) when is_list(S) -> escape(S, []). %% @spec escape_attr(string() | binary() | atom() | integer() | float()) -> binary() %% @doc Escape a string such that it's safe for HTML attrs %% (amp; lt; gt; quot;). escape_attr(B) when is_binary(B) -> escape_attr(binary_to_list(B), []); escape_attr(A) when is_atom(A) -> escape_attr(atom_to_list(A), []); escape_attr(S) when is_list(S) -> escape_attr(S, []); escape_attr(I) when is_integer(I) -> escape_attr(integer_to_list(I), []); escape_attr(F) when is_float(F) -> escape_attr(mochinum:digits(F), []). to_html([], Acc) -> lists:reverse(Acc); to_html([{'=', Content} | Rest], Acc) -> to_html(Rest, [Content | Acc]); to_html([{pi, Bin} | Rest], Acc) -> Open = [<<">, Bin, <<"?>">>], to_html(Rest, [Open | Acc]); to_html([{pi, Tag, Attrs} | Rest], Acc) -> Open = [<<">, Tag, attrs_to_html(Attrs, []), <<"?>">>], to_html(Rest, [Open | Acc]); to_html([{comment, Comment} | Rest], Acc) -> to_html(Rest, [[<<"">>] | Acc]); to_html([{doctype, Parts} | Rest], Acc) -> Inside = doctype_to_html(Parts, Acc), to_html(Rest, [[<<">, Inside, <<">">>] | Acc]); to_html([{data, Data, _Whitespace} | Rest], Acc) -> to_html(Rest, [escape(Data) | Acc]); to_html([{start_tag, Tag, Attrs, Singleton} | Rest], Acc) -> Open = [<<"<">>, Tag, attrs_to_html(Attrs, []), case Singleton of true -> <<" />">>; false -> <<">">> end], to_html(Rest, [Open | Acc]); to_html([{end_tag, Tag} | Rest], Acc) -> to_html(Rest, [[<<">, Tag, <<">">>] | Acc]). doctype_to_html([], Acc) -> lists:reverse(Acc); doctype_to_html([Word | Rest], Acc) -> case lists:all(fun (C) -> ?IS_LITERAL_SAFE(C) end, binary_to_list(iolist_to_binary(Word))) of true -> doctype_to_html(Rest, [[<<" ">>, Word] | Acc]); false -> doctype_to_html(Rest, [[<<" \"">>, escape_attr(Word), ?QUOTE] | Acc]) end. attrs_to_html([], Acc) -> lists:reverse(Acc); attrs_to_html([{K, V} | Rest], Acc) -> attrs_to_html(Rest, [[<<" ">>, escape(K), <<"=\"">>, escape_attr(V), <<"\"">>] | Acc]). escape([], Acc) -> list_to_binary(lists:reverse(Acc)); escape("<" ++ Rest, Acc) -> escape(Rest, lists:reverse("<", Acc)); escape(">" ++ Rest, Acc) -> escape(Rest, lists:reverse(">", Acc)); escape("&" ++ Rest, Acc) -> escape(Rest, lists:reverse("&", Acc)); escape([C | Rest], Acc) -> escape(Rest, [C | Acc]). escape_attr([], Acc) -> list_to_binary(lists:reverse(Acc)); escape_attr("<" ++ Rest, Acc) -> escape_attr(Rest, lists:reverse("<", Acc)); escape_attr(">" ++ Rest, Acc) -> escape_attr(Rest, lists:reverse(">", Acc)); escape_attr("&" ++ Rest, Acc) -> escape_attr(Rest, lists:reverse("&", Acc)); escape_attr([?QUOTE | Rest], Acc) -> escape_attr(Rest, lists:reverse(""", Acc)); escape_attr([C | Rest], Acc) -> escape_attr(Rest, [C | Acc]). to_tag(A) when is_atom(A) -> norm(atom_to_list(A)); to_tag(L) -> norm(L). to_tokens([], Acc) -> lists:reverse(Acc); to_tokens([{Tag, []} | Rest], Acc) -> to_tokens(Rest, [{end_tag, to_tag(Tag)} | Acc]); to_tokens([{Tag0, [{T0} | R1]} | Rest], Acc) -> %% Allow {br} to_tokens([{Tag0, [{T0, [], []} | R1]} | Rest], Acc); to_tokens([{Tag0, [T0={'=', _C0} | R1]} | Rest], Acc) -> %% Allow {'=', iolist()} to_tokens([{Tag0, R1} | Rest], [T0 | Acc]); to_tokens([{Tag0, [T0={comment, _C0} | R1]} | Rest], Acc) -> %% Allow {comment, iolist()} to_tokens([{Tag0, R1} | Rest], [T0 | Acc]); to_tokens([{Tag0, [T0={pi, _S0} | R1]} | Rest], Acc) -> %% Allow {pi, binary()} to_tokens([{Tag0, R1} | Rest], [T0 | Acc]); to_tokens([{Tag0, [T0={pi, _S0, _A0} | R1]} | Rest], Acc) -> %% Allow {pi, binary(), list()} to_tokens([{Tag0, R1} | Rest], [T0 | Acc]); to_tokens([{Tag0, [{T0, A0=[{_, _} | _]} | R1]} | Rest], Acc) -> %% Allow {p, [{"class", "foo"}]} to_tokens([{Tag0, [{T0, A0, []} | R1]} | Rest], Acc); to_tokens([{Tag0, [{T0, C0} | R1]} | Rest], Acc) -> %% Allow {p, "content"} and {p, <<"content">>} to_tokens([{Tag0, [{T0, [], C0} | R1]} | Rest], Acc); to_tokens([{Tag0, [{T0, A1, C0} | R1]} | Rest], Acc) when is_binary(C0) -> %% Allow {"p", [{"class", "foo"}], <<"content">>} to_tokens([{Tag0, [{T0, A1, binary_to_list(C0)} | R1]} | Rest], Acc); to_tokens([{Tag0, [{T0, A1, C0=[C | _]} | R1]} | Rest], Acc) when is_integer(C) -> %% Allow {"p", [{"class", "foo"}], "content"} to_tokens([{Tag0, [{T0, A1, [C0]} | R1]} | Rest], Acc); to_tokens([{Tag0, [{T0, A1, C1} | R1]} | Rest], Acc) -> %% Native {"p", [{"class", "foo"}], ["content"]} Tag = to_tag(Tag0), T1 = to_tag(T0), case is_singleton(norm(T1)) of true -> to_tokens([{Tag, R1} | Rest], [{start_tag, T1, A1, true} | Acc]); false -> to_tokens([{T1, C1}, {Tag, R1} | Rest], [{start_tag, T1, A1, false} | Acc]) end; to_tokens([{Tag0, [L | R1]} | Rest], Acc) when is_list(L) -> %% List text Tag = to_tag(Tag0), to_tokens([{Tag, R1} | Rest], [{data, iolist_to_binary(L), false} | Acc]); to_tokens([{Tag0, [B | R1]} | Rest], Acc) when is_binary(B) -> %% Binary text Tag = to_tag(Tag0), to_tokens([{Tag, R1} | Rest], [{data, B, false} | Acc]). tokens(B, S=#decoder{offset=O}, Acc) -> case B of <<_:O/binary>> -> lists:reverse(Acc); _ -> {Tag, S1} = tokenize(B, S), case parse_flag(Tag) of script -> {Tag2, S2} = tokenize_script(B, S1), tokens(B, S2, [Tag2, Tag | Acc]); textarea -> {Tag2, S2} = tokenize_textarea(B, S1), tokens(B, S2, [Tag2, Tag | Acc]); none -> tokens(B, S1, [Tag | Acc]) end end. parse_flag({start_tag, B, _, false}) -> case string:to_lower(binary_to_list(B)) of "script" -> script; "textarea" -> textarea; _ -> none end; parse_flag(_) -> none. tokenize(B, S=#decoder{offset=O}) -> case B of <<_:O/binary, "", _/binary>> -> Len = O - Start, <<_:Start/binary, Raw:Len/binary, _/binary>> = Bin, {{comment, Raw}, ?ADV_COL(S, 3)}; <<_:O/binary, C, _/binary>> -> tokenize_comment(Bin, ?INC_CHAR(S, C), Start); <<_:Start/binary, Raw/binary>> -> {{comment, Raw}, S} end. tokenize_script(Bin, S=#decoder{offset=O}) -> tokenize_script(Bin, S, O). tokenize_script(Bin, S=#decoder{offset=O}, Start) -> case Bin of %% Just a look-ahead, we want the end_tag separately <<_:O/binary, $<, $/, SS, CC, RR, II, PP, TT, ZZ, _/binary>> when (SS =:= $s orelse SS =:= $S) andalso (CC =:= $c orelse CC =:= $C) andalso (RR =:= $r orelse RR =:= $R) andalso (II =:= $i orelse II =:= $I) andalso (PP =:= $p orelse PP =:= $P) andalso (TT=:= $t orelse TT =:= $T) andalso ?PROBABLE_CLOSE(ZZ) -> Len = O - Start, <<_:Start/binary, Raw:Len/binary, _/binary>> = Bin, {{data, Raw, false}, S}; <<_:O/binary, C, _/binary>> -> tokenize_script(Bin, ?INC_CHAR(S, C), Start); <<_:Start/binary, Raw/binary>> -> {{data, Raw, false}, S} end. tokenize_textarea(Bin, S=#decoder{offset=O}) -> tokenize_textarea(Bin, S, O). tokenize_textarea(Bin, S=#decoder{offset=O}, Start) -> case Bin of %% Just a look-ahead, we want the end_tag separately <<_:O/binary, $<, $/, TT, EE, XX, TT2, AA, RR, EE2, AA2, ZZ, _/binary>> when (TT =:= $t orelse TT =:= $T) andalso (EE =:= $e orelse EE =:= $E) andalso (XX =:= $x orelse XX =:= $X) andalso (TT2 =:= $t orelse TT2 =:= $T) andalso (AA =:= $a orelse AA =:= $A) andalso (RR =:= $r orelse RR =:= $R) andalso (EE2 =:= $e orelse EE2 =:= $E) andalso (AA2 =:= $a orelse AA2 =:= $A) andalso ?PROBABLE_CLOSE(ZZ) -> Len = O - Start, <<_:Start/binary, Raw:Len/binary, _/binary>> = Bin, {{data, Raw, false}, S}; <<_:O/binary, C, _/binary>> -> tokenize_textarea(Bin, ?INC_CHAR(S, C), Start); <<_:Start/binary, Raw/binary>> -> {{data, Raw, false}, S} end. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb_socket.erl0000644000177700017770000000404412633765070031215 0ustar michaelmichael%% @copyright 2010 Mochi Media, Inc. %% @doc MochiWeb socket - wrapper for plain and ssl sockets. -module(mochiweb_socket). -export([listen/4, accept/1, recv/3, send/2, close/1, port/1, peername/1, setopts/2, type/1]). -define(ACCEPT_TIMEOUT, 2000). listen(Ssl, Port, Opts, SslOpts) -> case Ssl of true -> case ssl:listen(Port, Opts ++ SslOpts) of {ok, ListenSocket} -> {ok, {ssl, ListenSocket}}; {error, _} = Err -> Err end; false -> gen_tcp:listen(Port, Opts) end. accept({ssl, ListenSocket}) -> % There's a bug in ssl:transport_accept/2 at the moment, which is the % reason for the try...catch block. Should be fixed in OTP R14. try ssl:transport_accept(ListenSocket) of {ok, Socket} -> case ssl:ssl_accept(Socket) of ok -> {ok, {ssl, Socket}}; {error, _} = Err -> Err end; {error, _} = Err -> Err catch error:{badmatch, {error, Reason}} -> {error, Reason} end; accept(ListenSocket) -> gen_tcp:accept(ListenSocket, ?ACCEPT_TIMEOUT). recv({ssl, Socket}, Length, Timeout) -> ssl:recv(Socket, Length, Timeout); recv(Socket, Length, Timeout) -> gen_tcp:recv(Socket, Length, Timeout). send({ssl, Socket}, Data) -> ssl:send(Socket, Data); send(Socket, Data) -> gen_tcp:send(Socket, Data). close({ssl, Socket}) -> ssl:close(Socket); close(Socket) -> gen_tcp:close(Socket). port({ssl, Socket}) -> case ssl:sockname(Socket) of {ok, {_, Port}} -> {ok, Port}; {error, _} = Err -> Err end; port(Socket) -> inet:port(Socket). peername({ssl, Socket}) -> ssl:peername(Socket); peername(Socket) -> inet:peername(Socket). setopts({ssl, Socket}, Opts) -> ssl:setopts(Socket, Opts); setopts(Socket, Opts) -> inet:setopts(Socket, Opts). type({ssl, _}) -> ssl; type(_) -> plain. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb_echo.erl0000644000177700017770000000160512633765070030643 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2007 Mochi Media, Inc. %% @doc Simple and stupid echo server to demo mochiweb_socket_server. -module(mochiweb_echo). -author('bob@mochimedia.com'). -export([start/0, stop/0, loop/1]). stop() -> mochiweb_socket_server:stop(?MODULE). start() -> mochiweb_socket_server:start([{link, false} | options()]). options() -> [{name, ?MODULE}, {port, 6789}, {ip, "127.0.0.1"}, {max, 1}, {loop, {?MODULE, loop}}]. loop(Socket) -> case mochiweb_socket:recv(Socket, 0, 30000) of {ok, Data} -> case mochiweb_socket:send(Socket, Data) of ok -> loop(Socket); _ -> exit(normal) end; _Other -> exit(normal) end. %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochitemp.erl0000644000177700017770000001664612633765070030050 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2010 Mochi Media, Inc. %% @doc Create temporary files and directories. -module(mochitemp). -export([gettempdir/0]). -export([mkdtemp/0, mkdtemp/3]). -export([rmtempdir/1]). %% -export([mkstemp/4]). -define(SAFE_CHARS, {$a, $b, $c, $d, $e, $f, $g, $h, $i, $j, $k, $l, $m, $n, $o, $p, $q, $r, $s, $t, $u, $v, $w, $x, $y, $z, $A, $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L, $M, $N, $O, $P, $Q, $R, $S, $T, $U, $V, $W, $X, $Y, $Z, $0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $_}). -define(TMP_MAX, 10000). -include_lib("kernel/include/file.hrl"). %% TODO: An ugly wrapper over the mktemp tool with open_port and sadness? %% We can't implement this race-free in Erlang without the ability %% to issue O_CREAT|O_EXCL. I suppose we could hack something with %% mkdtemp, del_dir, open. %% mkstemp(Suffix, Prefix, Dir, Options) -> %% ok. rmtempdir(Dir) -> case file:del_dir(Dir) of {error, eexist} -> ok = rmtempdirfiles(Dir), ok = file:del_dir(Dir); ok -> ok end. rmtempdirfiles(Dir) -> {ok, Files} = file:list_dir(Dir), ok = rmtempdirfiles(Dir, Files). rmtempdirfiles(_Dir, []) -> ok; rmtempdirfiles(Dir, [Basename | Rest]) -> Path = filename:join([Dir, Basename]), case filelib:is_dir(Path) of true -> ok = rmtempdir(Path); false -> ok = file:delete(Path) end, rmtempdirfiles(Dir, Rest). mkdtemp() -> mkdtemp("", "tmp", gettempdir()). mkdtemp(Suffix, Prefix, Dir) -> mkdtemp_n(rngpath_fun(Suffix, Prefix, Dir), ?TMP_MAX). mkdtemp_n(RngPath, 1) -> make_dir(RngPath()); mkdtemp_n(RngPath, N) -> try make_dir(RngPath()) catch throw:{error, eexist} -> mkdtemp_n(RngPath, N - 1) end. make_dir(Path) -> case file:make_dir(Path) of ok -> ok; E={error, eexist} -> throw(E) end, %% Small window for a race condition here because dir is created 777 ok = file:write_file_info(Path, #file_info{mode=8#0700}), Path. rngpath_fun(Prefix, Suffix, Dir) -> fun () -> filename:join([Dir, Prefix ++ rngchars(6) ++ Suffix]) end. rngchars(0) -> ""; rngchars(N) -> [rngchar() | rngchars(N - 1)]. rngchar() -> rngchar(mochiweb_util:rand_uniform(0, tuple_size(?SAFE_CHARS))). rngchar(C) -> element(1 + C, ?SAFE_CHARS). %% @spec gettempdir() -> string() %% @doc Get a usable temporary directory using the first of these that is a directory: %% $TMPDIR, $TMP, $TEMP, "/tmp", "/var/tmp", "/usr/tmp", ".". gettempdir() -> gettempdir(gettempdir_checks(), fun normalize_dir/1). gettempdir_checks() -> [{fun os:getenv/1, ["TMPDIR", "TMP", "TEMP"]}, {fun gettempdir_identity/1, ["/tmp", "/var/tmp", "/usr/tmp"]}, {fun gettempdir_cwd/1, [cwd]}]. gettempdir_identity(L) -> L. gettempdir_cwd(cwd) -> {ok, L} = file:get_cwd(), L. gettempdir([{_F, []} | RestF], Normalize) -> gettempdir(RestF, Normalize); gettempdir([{F, [L | RestL]} | RestF], Normalize) -> case Normalize(F(L)) of false -> gettempdir([{F, RestL} | RestF], Normalize); Dir -> Dir end. normalize_dir(False) when False =:= false orelse False =:= "" -> %% Erlang doesn't have an unsetenv, wtf. false; normalize_dir(L) -> Dir = filename:absname(L), case filelib:is_dir(Dir) of false -> false; true -> Dir end. %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). pushenv(L) -> [{K, os:getenv(K)} || K <- L]. popenv(L) -> F = fun ({K, false}) -> %% Erlang doesn't have an unsetenv, wtf. os:putenv(K, ""); ({K, V}) -> os:putenv(K, V) end, lists:foreach(F, L). gettempdir_fallback_test() -> ?assertEqual( "/", gettempdir([{fun gettempdir_identity/1, ["/--not-here--/"]}, {fun gettempdir_identity/1, ["/"]}], fun normalize_dir/1)), ?assertEqual( "/", %% simulate a true os:getenv unset env gettempdir([{fun gettempdir_identity/1, [false]}, {fun gettempdir_identity/1, ["/"]}], fun normalize_dir/1)), ok. gettempdir_identity_test() -> ?assertEqual( "/", gettempdir([{fun gettempdir_identity/1, ["/"]}], fun normalize_dir/1)), ok. gettempdir_cwd_test() -> {ok, Cwd} = file:get_cwd(), ?assertEqual( normalize_dir(Cwd), gettempdir([{fun gettempdir_cwd/1, [cwd]}], fun normalize_dir/1)), ok. rngchars_test() -> ?assertEqual( "", rngchars(0)), ?assertEqual( 10, length(rngchars(10))), ok. rngchar_test() -> ?assertEqual( $a, rngchar(0)), ?assertEqual( $A, rngchar(26)), ?assertEqual( $_, rngchar(62)), ok. mkdtemp_n_failonce_test() -> D = mkdtemp(), Path = filename:join([D, "testdir"]), %% Toggle the existence of a dir so that it fails %% the first time and succeeds the second. F = fun () -> case filelib:is_dir(Path) of true -> file:del_dir(Path); false -> file:make_dir(Path) end, Path end, try %% Fails the first time ?assertThrow( {error, eexist}, mkdtemp_n(F, 1)), %% Reset state file:del_dir(Path), %% Succeeds the second time ?assertEqual( Path, mkdtemp_n(F, 2)) after rmtempdir(D) end, ok. mkdtemp_n_fail_test() -> {ok, Cwd} = file:get_cwd(), ?assertThrow( {error, eexist}, mkdtemp_n(fun () -> Cwd end, 1)), ?assertThrow( {error, eexist}, mkdtemp_n(fun () -> Cwd end, 2)), ok. make_dir_fail_test() -> {ok, Cwd} = file:get_cwd(), ?assertThrow( {error, eexist}, make_dir(Cwd)), ok. mkdtemp_test() -> D = mkdtemp(), ?assertEqual( true, filelib:is_dir(D)), ?assertEqual( ok, file:del_dir(D)), ok. rmtempdir_test() -> D1 = mkdtemp(), ?assertEqual( true, filelib:is_dir(D1)), ?assertEqual( ok, rmtempdir(D1)), D2 = mkdtemp(), ?assertEqual( true, filelib:is_dir(D2)), ok = file:write_file(filename:join([D2, "foo"]), <<"bytes">>), D3 = mkdtemp("suffix", "prefix", D2), ?assertEqual( true, filelib:is_dir(D3)), ok = file:write_file(filename:join([D3, "foo"]), <<"bytes">>), ?assertEqual( ok, rmtempdir(D2)), ?assertEqual( {error, enoent}, file:consult(D3)), ?assertEqual( {error, enoent}, file:consult(D2)), ok. gettempdir_env_test() -> Env = pushenv(["TMPDIR", "TEMP", "TMP"]), FalseEnv = [{"TMPDIR", false}, {"TEMP", false}, {"TMP", false}], try popenv(FalseEnv), popenv([{"TMPDIR", "/"}]), ?assertEqual( "/", os:getenv("TMPDIR")), ?assertEqual( "/", gettempdir()), {ok, Cwd} = file:get_cwd(), popenv(FalseEnv), popenv([{"TMP", Cwd}]), ?assertEqual( normalize_dir(Cwd), gettempdir()) after popenv(Env) end, ok. -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb_mime.erl0000644000177700017770000002441512633765070030660 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2007 Mochi Media, Inc. %% @doc Gives a good MIME type guess based on file extension. -module(mochiweb_mime). -author('bob@mochimedia.com'). -export([from_extension/1]). %% @spec from_extension(S::string()) -> string() | undefined %% @doc Given a filename extension (e.g. ".html") return a guess for the MIME %% type such as "text/html". Will return the atom undefined if no good %% guess is available. from_extension(".stl") -> "application/SLA"; from_extension(".stp") -> "application/STEP"; from_extension(".step") -> "application/STEP"; from_extension(".dwg") -> "application/acad"; from_extension(".ez") -> "application/andrew-inset"; from_extension(".ccad") -> "application/clariscad"; from_extension(".drw") -> "application/drafting"; from_extension(".tsp") -> "application/dsptype"; from_extension(".dxf") -> "application/dxf"; from_extension(".xls") -> "application/excel"; from_extension(".unv") -> "application/i-deas"; from_extension(".jar") -> "application/java-archive"; from_extension(".hqx") -> "application/mac-binhex40"; from_extension(".cpt") -> "application/mac-compactpro"; from_extension(".pot") -> "application/vnd.ms-powerpoint"; from_extension(".ppt") -> "application/vnd.ms-powerpoint"; from_extension(".dms") -> "application/octet-stream"; from_extension(".lha") -> "application/octet-stream"; from_extension(".lzh") -> "application/octet-stream"; from_extension(".oda") -> "application/oda"; from_extension(".ogg") -> "application/ogg"; from_extension(".ogm") -> "application/ogg"; from_extension(".pdf") -> "application/pdf"; from_extension(".pgp") -> "application/pgp"; from_extension(".ai") -> "application/postscript"; from_extension(".eps") -> "application/postscript"; from_extension(".ps") -> "application/postscript"; from_extension(".prt") -> "application/pro_eng"; from_extension(".rtf") -> "application/rtf"; from_extension(".smi") -> "application/smil"; from_extension(".smil") -> "application/smil"; from_extension(".sol") -> "application/solids"; from_extension(".vda") -> "application/vda"; from_extension(".xlm") -> "application/vnd.ms-excel"; from_extension(".cod") -> "application/vnd.rim.cod"; from_extension(".pgn") -> "application/x-chess-pgn"; from_extension(".cpio") -> "application/x-cpio"; from_extension(".csh") -> "application/x-csh"; from_extension(".deb") -> "application/x-debian-package"; from_extension(".dcr") -> "application/x-director"; from_extension(".dir") -> "application/x-director"; from_extension(".dxr") -> "application/x-director"; from_extension(".gz") -> "application/x-gzip"; from_extension(".hdf") -> "application/x-hdf"; from_extension(".ipx") -> "application/x-ipix"; from_extension(".ips") -> "application/x-ipscript"; from_extension(".js") -> "application/x-javascript"; from_extension(".skd") -> "application/x-koan"; from_extension(".skm") -> "application/x-koan"; from_extension(".skp") -> "application/x-koan"; from_extension(".skt") -> "application/x-koan"; from_extension(".latex") -> "application/x-latex"; from_extension(".lsp") -> "application/x-lisp"; from_extension(".scm") -> "application/x-lotusscreencam"; from_extension(".mif") -> "application/x-mif"; from_extension(".com") -> "application/x-msdos-program"; from_extension(".exe") -> "application/octet-stream"; from_extension(".cdf") -> "application/x-netcdf"; from_extension(".nc") -> "application/x-netcdf"; from_extension(".pl") -> "application/x-perl"; from_extension(".pm") -> "application/x-perl"; from_extension(".rar") -> "application/x-rar-compressed"; from_extension(".sh") -> "application/x-sh"; from_extension(".shar") -> "application/x-shar"; from_extension(".swf") -> "application/x-shockwave-flash"; from_extension(".sit") -> "application/x-stuffit"; from_extension(".sv4cpio") -> "application/x-sv4cpio"; from_extension(".sv4crc") -> "application/x-sv4crc"; from_extension(".tar.gz") -> "application/x-tar-gz"; from_extension(".tgz") -> "application/x-tar-gz"; from_extension(".tar") -> "application/x-tar"; from_extension(".tcl") -> "application/x-tcl"; from_extension(".texi") -> "application/x-texinfo"; from_extension(".texinfo") -> "application/x-texinfo"; from_extension(".man") -> "application/x-troff-man"; from_extension(".me") -> "application/x-troff-me"; from_extension(".ms") -> "application/x-troff-ms"; from_extension(".roff") -> "application/x-troff"; from_extension(".t") -> "application/x-troff"; from_extension(".tr") -> "application/x-troff"; from_extension(".ustar") -> "application/x-ustar"; from_extension(".src") -> "application/x-wais-source"; from_extension(".zip") -> "application/zip"; from_extension(".tsi") -> "audio/TSP-audio"; from_extension(".au") -> "audio/basic"; from_extension(".snd") -> "audio/basic"; from_extension(".kar") -> "audio/midi"; from_extension(".mid") -> "audio/midi"; from_extension(".midi") -> "audio/midi"; from_extension(".mp2") -> "audio/mpeg"; from_extension(".mp3") -> "audio/mpeg"; from_extension(".mpga") -> "audio/mpeg"; from_extension(".aif") -> "audio/x-aiff"; from_extension(".aifc") -> "audio/x-aiff"; from_extension(".aiff") -> "audio/x-aiff"; from_extension(".m3u") -> "audio/x-mpegurl"; from_extension(".wax") -> "audio/x-ms-wax"; from_extension(".wma") -> "audio/x-ms-wma"; from_extension(".rpm") -> "audio/x-pn-realaudio-plugin"; from_extension(".ram") -> "audio/x-pn-realaudio"; from_extension(".rm") -> "audio/x-pn-realaudio"; from_extension(".ra") -> "audio/x-realaudio"; from_extension(".wav") -> "audio/x-wav"; from_extension(".pdb") -> "chemical/x-pdb"; from_extension(".ras") -> "image/cmu-raster"; from_extension(".gif") -> "image/gif"; from_extension(".ief") -> "image/ief"; from_extension(".jpe") -> "image/jpeg"; from_extension(".jpeg") -> "image/jpeg"; from_extension(".jpg") -> "image/jpeg"; from_extension(".jp2") -> "image/jp2"; from_extension(".png") -> "image/png"; from_extension(".tif") -> "image/tiff"; from_extension(".tiff") -> "image/tiff"; from_extension(".pnm") -> "image/x-portable-anymap"; from_extension(".pbm") -> "image/x-portable-bitmap"; from_extension(".pgm") -> "image/x-portable-graymap"; from_extension(".ppm") -> "image/x-portable-pixmap"; from_extension(".rgb") -> "image/x-rgb"; from_extension(".xbm") -> "image/x-xbitmap"; from_extension(".xwd") -> "image/x-xwindowdump"; from_extension(".iges") -> "model/iges"; from_extension(".igs") -> "model/iges"; from_extension(".mesh") -> "model/mesh"; from_extension(".") -> ""; from_extension(".msh") -> "model/mesh"; from_extension(".silo") -> "model/mesh"; from_extension(".vrml") -> "model/vrml"; from_extension(".wrl") -> "model/vrml"; from_extension(".css") -> "text/css"; from_extension(".htm") -> "text/html"; from_extension(".html") -> "text/html"; from_extension(".asc") -> "text/plain"; from_extension(".c") -> "text/plain"; from_extension(".cc") -> "text/plain"; from_extension(".f90") -> "text/plain"; from_extension(".f") -> "text/plain"; from_extension(".hh") -> "text/plain"; from_extension(".m") -> "text/plain"; from_extension(".txt") -> "text/plain"; from_extension(".rtx") -> "text/richtext"; from_extension(".sgm") -> "text/sgml"; from_extension(".sgml") -> "text/sgml"; from_extension(".tsv") -> "text/tab-separated-values"; from_extension(".jad") -> "text/vnd.sun.j2me.app-descriptor"; from_extension(".etx") -> "text/x-setext"; from_extension(".xml") -> "application/xml"; from_extension(".dl") -> "video/dl"; from_extension(".fli") -> "video/fli"; from_extension(".flv") -> "video/x-flv"; from_extension(".gl") -> "video/gl"; from_extension(".mp4") -> "video/mp4"; from_extension(".mpe") -> "video/mpeg"; from_extension(".mpeg") -> "video/mpeg"; from_extension(".mpg") -> "video/mpeg"; from_extension(".mov") -> "video/quicktime"; from_extension(".qt") -> "video/quicktime"; from_extension(".viv") -> "video/vnd.vivo"; from_extension(".vivo") -> "video/vnd.vivo"; from_extension(".asf") -> "video/x-ms-asf"; from_extension(".asx") -> "video/x-ms-asx"; from_extension(".wmv") -> "video/x-ms-wmv"; from_extension(".wmx") -> "video/x-ms-wmx"; from_extension(".wvx") -> "video/x-ms-wvx"; from_extension(".avi") -> "video/x-msvideo"; from_extension(".movie") -> "video/x-sgi-movie"; from_extension(".mime") -> "www/mime"; from_extension(".ice") -> "x-conference/x-cooltalk"; from_extension(".vrm") -> "x-world/x-vrml"; from_extension(".spx") -> "audio/ogg"; from_extension(".xhtml") -> "application/xhtml+xml"; from_extension(".bz2") -> "application/x-bzip2"; from_extension(".doc") -> "application/msword"; from_extension(".z") -> "application/x-compress"; from_extension(".ico") -> "image/x-icon"; from_extension(".bmp") -> "image/bmp"; from_extension(".m4a") -> "audio/mpeg"; from_extension(".csv") -> "text/csv"; from_extension(".eot") -> "application/vnd.ms-fontobject"; from_extension(".m4v") -> "video/mp4"; from_extension(".svg") -> "image/svg+xml"; from_extension(".svgz") -> "image/svg+xml"; from_extension(".ttc") -> "application/x-font-ttf"; from_extension(".ttf") -> "application/x-font-ttf"; from_extension(".vcf") -> "text/x-vcard"; from_extension(".webm") -> "video/web"; from_extension(".webp") -> "image/web"; from_extension(".woff") -> "application/x-font-woff"; from_extension(".otf") -> "font/opentype"; from_extension(_) -> undefined. %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). exhaustive_from_extension_test() -> T = mochiweb_cover:clause_lookup_table(?MODULE, from_extension), [?assertEqual(V, from_extension(K)) || {K, V} <- T]. from_extension_test() -> ?assertEqual("text/html", from_extension(".html")), ?assertEqual(undefined, from_extension("")), ?assertEqual(undefined, from_extension(".wtf")), ok. -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochifmt_std.erl0000644000177700017770000000142112633765070030524 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2008 Mochi Media, Inc. %% @doc Template module for a mochifmt formatter. -module(mochifmt_std). -author('bob@mochimedia.com'). -export([new/0, format/3, get_value/3, format_field/3, get_field/3, convert_field/3]). new() -> {?MODULE}. format(Format, Args, {?MODULE}=THIS) -> mochifmt:format(Format, Args, THIS). get_field(Key, Args, {?MODULE}=THIS) -> mochifmt:get_field(Key, Args, THIS). convert_field(Key, Args, {?MODULE}) -> mochifmt:convert_field(Key, Args). get_value(Key, Args, {?MODULE}) -> mochifmt:get_value(Key, Args). format_field(Arg, Format, {?MODULE}=THIS) -> mochifmt:format_field(Arg, Format, THIS). %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb_request.erl0000644000177700017770000010723012633765070031416 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2007 Mochi Media, Inc. %% @doc MochiWeb HTTP Request abstraction. -module(mochiweb_request). -author('bob@mochimedia.com'). -include_lib("kernel/include/file.hrl"). -include("internal.hrl"). -define(QUIP, "Any of you quaids got a smint?"). -export([new/5]). -export([get_header_value/2, get_primary_header_value/2, get_combined_header_value/2, get/2, dump/1]). -export([send/2, recv/2, recv/3, recv_body/1, recv_body/2, stream_body/4]). -export([start_response/2, start_response_length/2, start_raw_response/2]). -export([respond/2, ok/2]). -export([not_found/1, not_found/2]). -export([parse_post/1, parse_qs/1]). -export([should_close/1, cleanup/1]). -export([parse_cookie/1, get_cookie_value/2]). -export([serve_file/3, serve_file/4]). -export([accepted_encodings/2]). -export([accepts_content_type/2, accepted_content_types/2]). -define(SAVE_QS, mochiweb_request_qs). -define(SAVE_PATH, mochiweb_request_path). -define(SAVE_RECV, mochiweb_request_recv). -define(SAVE_BODY, mochiweb_request_body). -define(SAVE_BODY_LENGTH, mochiweb_request_body_length). -define(SAVE_POST, mochiweb_request_post). -define(SAVE_COOKIE, mochiweb_request_cookie). -define(SAVE_FORCE_CLOSE, mochiweb_request_force_close). %% @type key() = atom() | string() | binary() %% @type value() = atom() | string() | binary() | integer() %% @type headers(). A mochiweb_headers structure. %% @type request(). A mochiweb_request parameterized module instance. %% @type response(). A mochiweb_response parameterized module instance. %% @type ioheaders() = headers() | [{key(), value()}]. % 5 minute default idle timeout -define(IDLE_TIMEOUT, 300000). % Maximum recv_body() length of 1MB -define(MAX_RECV_BODY, 104857600). %% @spec new(Socket, Method, RawPath, Version, headers()) -> request() %% @doc Create a new request instance. new(Socket, Method, RawPath, Version, Headers) -> {?MODULE, [Socket, Method, RawPath, Version, Headers]}. %% @spec get_header_value(K, request()) -> undefined | Value %% @doc Get the value of a given request header. get_header_value(K, {?MODULE, [_Socket, _Method, _RawPath, _Version, Headers]}) -> mochiweb_headers:get_value(K, Headers). get_primary_header_value(K, {?MODULE, [_Socket, _Method, _RawPath, _Version, Headers]}) -> mochiweb_headers:get_primary_value(K, Headers). get_combined_header_value(K, {?MODULE, [_Socket, _Method, _RawPath, _Version, Headers]}) -> mochiweb_headers:get_combined_value(K, Headers). %% @type field() = socket | scheme | method | raw_path | version | headers | peer | path | body_length | range %% @spec get(field(), request()) -> term() %% @doc Return the internal representation of the given field. If %% socket is requested on a HTTPS connection, then %% an ssl socket will be returned as {ssl, SslSocket}. %% You can use SslSocket with the ssl %% application, eg: ssl:peercert(SslSocket). get(socket, {?MODULE, [Socket, _Method, _RawPath, _Version, _Headers]}) -> Socket; get(scheme, {?MODULE, [Socket, _Method, _RawPath, _Version, _Headers]}) -> case mochiweb_socket:type(Socket) of plain -> http; ssl -> https end; get(method, {?MODULE, [_Socket, Method, _RawPath, _Version, _Headers]}) -> Method; get(raw_path, {?MODULE, [_Socket, _Method, RawPath, _Version, _Headers]}) -> RawPath; get(version, {?MODULE, [_Socket, _Method, _RawPath, Version, _Headers]}) -> Version; get(headers, {?MODULE, [_Socket, _Method, _RawPath, _Version, Headers]}) -> Headers; get(peer, {?MODULE, [Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> case mochiweb_socket:peername(Socket) of {ok, {Addr={10, _, _, _}, _Port}} -> case get_header_value("x-forwarded-for", THIS) of undefined -> inet_parse:ntoa(Addr); Hosts -> string:strip(lists:last(string:tokens(Hosts, ","))) end; {ok, {{127, 0, 0, 1}, _Port}} -> case get_header_value("x-forwarded-for", THIS) of undefined -> "127.0.0.1"; Hosts -> string:strip(lists:last(string:tokens(Hosts, ","))) end; {ok, {Addr, _Port}} -> inet_parse:ntoa(Addr); {error, enotconn} -> exit(normal) end; get(path, {?MODULE, [_Socket, _Method, RawPath, _Version, _Headers]}) -> case erlang:get(?SAVE_PATH) of undefined -> {Path0, _, _} = mochiweb_util:urlsplit_path(RawPath), Path = mochiweb_util:unquote(Path0), put(?SAVE_PATH, Path), Path; Cached -> Cached end; get(body_length, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> case erlang:get(?SAVE_BODY_LENGTH) of undefined -> BodyLength = body_length(THIS), put(?SAVE_BODY_LENGTH, {cached, BodyLength}), BodyLength; {cached, Cached} -> Cached end; get(range, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> case get_header_value(range, THIS) of undefined -> undefined; RawRange -> mochiweb_http:parse_range_request(RawRange) end. %% @spec dump(request()) -> {mochiweb_request, [{atom(), term()}]} %% @doc Dump the internal representation to a "human readable" set of terms %% for debugging/inspection purposes. dump({?MODULE, [_Socket, Method, RawPath, Version, Headers]}) -> {?MODULE, [{method, Method}, {version, Version}, {raw_path, RawPath}, {headers, mochiweb_headers:to_list(Headers)}]}. %% @spec send(iodata(), request()) -> ok %% @doc Send data over the socket. send(Data, {?MODULE, [Socket, _Method, _RawPath, _Version, _Headers]}) -> case mochiweb_socket:send(Socket, Data) of ok -> ok; _ -> exit(normal) end. %% @spec recv(integer(), request()) -> binary() %% @doc Receive Length bytes from the client as a binary, with the default %% idle timeout. recv(Length, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> recv(Length, ?IDLE_TIMEOUT, THIS). %% @spec recv(integer(), integer(), request()) -> binary() %% @doc Receive Length bytes from the client as a binary, with the given %% Timeout in msec. recv(Length, Timeout, {?MODULE, [Socket, _Method, _RawPath, _Version, _Headers]}) -> case mochiweb_socket:recv(Socket, Length, Timeout) of {ok, Data} -> put(?SAVE_RECV, true), Data; _ -> exit(normal) end. %% @spec body_length(request()) -> undefined | chunked | unknown_transfer_encoding | integer() %% @doc Infer body length from transfer-encoding and content-length headers. body_length({?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> case get_header_value("transfer-encoding", THIS) of undefined -> case get_combined_header_value("content-length", THIS) of undefined -> undefined; Length -> list_to_integer(Length) end; "chunked" -> chunked; Unknown -> {unknown_transfer_encoding, Unknown} end. %% @spec recv_body(request()) -> binary() %% @doc Receive the body of the HTTP request (defined by Content-Length). %% Will only receive up to the default max-body length of 1MB. recv_body({?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> recv_body(?MAX_RECV_BODY, THIS). %% @spec recv_body(integer(), request()) -> binary() %% @doc Receive the body of the HTTP request (defined by Content-Length). %% Will receive up to MaxBody bytes. recv_body(MaxBody, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> case erlang:get(?SAVE_BODY) of undefined -> % we could use a sane constant for max chunk size Body = stream_body(?MAX_RECV_BODY, fun ({0, _ChunkedFooter}, {_LengthAcc, BinAcc}) -> iolist_to_binary(lists:reverse(BinAcc)); ({Length, Bin}, {LengthAcc, BinAcc}) -> NewLength = Length + LengthAcc, if NewLength > MaxBody -> exit({body_too_large, chunked}); true -> {NewLength, [Bin | BinAcc]} end end, {0, []}, MaxBody, THIS), put(?SAVE_BODY, Body), Body; Cached -> Cached end. stream_body(MaxChunkSize, ChunkFun, FunState, {?MODULE,[_Socket,_Method,_RawPath,_Version,_Headers]}=THIS) -> stream_body(MaxChunkSize, ChunkFun, FunState, undefined, THIS). stream_body(MaxChunkSize, ChunkFun, FunState, MaxBodyLength, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> Expect = case get_header_value("expect", THIS) of undefined -> undefined; Value when is_list(Value) -> string:to_lower(Value) end, case Expect of "100-continue" -> _ = start_raw_response({100, gb_trees:empty()}, THIS), ok; _Else -> ok end, case body_length(THIS) of undefined -> undefined; {unknown_transfer_encoding, Unknown} -> exit({unknown_transfer_encoding, Unknown}); chunked -> % In this case the MaxBody is actually used to % determine the maximum allowed size of a single % chunk. stream_chunked_body(MaxChunkSize, ChunkFun, FunState, THIS); 0 -> <<>>; Length when is_integer(Length) -> case MaxBodyLength of MaxBodyLength when is_integer(MaxBodyLength), MaxBodyLength < Length -> exit({body_too_large, content_length}); _ -> stream_unchunked_body(Length, ChunkFun, FunState, THIS) end end. %% @spec start_response({integer(), ioheaders()}, request()) -> response() %% @doc Start the HTTP response by sending the Code HTTP response and %% ResponseHeaders. The server will set header defaults such as Server %% and Date if not present in ResponseHeaders. start_response({Code, ResponseHeaders}, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> HResponse = mochiweb_headers:make(ResponseHeaders), HResponse1 = mochiweb_headers:default_from_list(server_headers(), HResponse), start_raw_response({Code, HResponse1}, THIS). %% @spec start_raw_response({integer(), headers()}, request()) -> response() %% @doc Start the HTTP response by sending the Code HTTP response and %% ResponseHeaders. start_raw_response({Code, ResponseHeaders}, {?MODULE, [_Socket, _Method, _RawPath, Version, _Headers]}=THIS) -> F = fun ({K, V}, Acc) -> [mochiweb_util:make_io(K), <<": ">>, V, <<"\r\n">> | Acc] end, End = lists:foldl(F, [<<"\r\n">>], mochiweb_headers:to_list(ResponseHeaders)), send([make_version(Version), make_code(Code), <<"\r\n">> | End], THIS), mochiweb:new_response({THIS, Code, ResponseHeaders}). %% @spec start_response_length({integer(), ioheaders(), integer()}, request()) -> response() %% @doc Start the HTTP response by sending the Code HTTP response and %% ResponseHeaders including a Content-Length of Length. The server %% will set header defaults such as Server %% and Date if not present in ResponseHeaders. start_response_length({Code, ResponseHeaders, Length}, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> HResponse = mochiweb_headers:make(ResponseHeaders), HResponse1 = mochiweb_headers:enter("Content-Length", Length, HResponse), start_response({Code, HResponse1}, THIS). %% @spec respond({integer(), ioheaders(), iodata() | chunked | {file, IoDevice}}, request()) -> response() %% @doc Start the HTTP response with start_response, and send Body to the %% client (if the get(method) /= 'HEAD'). The Content-Length header %% will be set by the Body length, and the server will insert header %% defaults. respond({Code, ResponseHeaders, {file, IoDevice}}, {?MODULE, [_Socket, Method, _RawPath, _Version, _Headers]}=THIS) -> Length = mochiweb_io:iodevice_size(IoDevice), Response = start_response_length({Code, ResponseHeaders, Length}, THIS), case Method of 'HEAD' -> ok; _ -> mochiweb_io:iodevice_stream( fun (Body) -> send(Body, THIS) end, IoDevice) end, Response; respond({Code, ResponseHeaders, chunked}, {?MODULE, [_Socket, Method, _RawPath, Version, _Headers]}=THIS) -> HResponse = mochiweb_headers:make(ResponseHeaders), HResponse1 = case Method of 'HEAD' -> %% This is what Google does, http://www.google.com/ %% is chunked but HEAD gets Content-Length: 0. %% The RFC is ambiguous so emulating Google is smart. mochiweb_headers:enter("Content-Length", "0", HResponse); _ when Version >= {1, 1} -> %% Only use chunked encoding for HTTP/1.1 mochiweb_headers:enter("Transfer-Encoding", "chunked", HResponse); _ -> %% For pre-1.1 clients we send the data as-is %% without a Content-Length header and without %% chunk delimiters. Since the end of the document %% is now ambiguous we must force a close. put(?SAVE_FORCE_CLOSE, true), HResponse end, start_response({Code, HResponse1}, THIS); respond({Code, ResponseHeaders, Body}, {?MODULE, [_Socket, Method, _RawPath, _Version, _Headers]}=THIS) -> Response = start_response_length({Code, ResponseHeaders, iolist_size(Body)}, THIS), case Method of 'HEAD' -> ok; _ -> send(Body, THIS) end, Response. %% @spec not_found(request()) -> response() %% @doc Alias for not_found([]). not_found({?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> not_found([], THIS). %% @spec not_found(ExtraHeaders, request()) -> response() %% @doc Alias for respond({404, [{"Content-Type", "text/plain"} %% | ExtraHeaders], <<"Not found.">>}). not_found(ExtraHeaders, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> respond({404, [{"Content-Type", "text/plain"} | ExtraHeaders], <<"Not found.">>}, THIS). %% @spec ok({value(), iodata()} | {value(), ioheaders(), iodata() | {file, IoDevice}}, request()) -> %% response() %% @doc respond({200, [{"Content-Type", ContentType} | Headers], Body}). ok({ContentType, Body}, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> ok({ContentType, [], Body}, THIS); ok({ContentType, ResponseHeaders, Body}, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> HResponse = mochiweb_headers:make(ResponseHeaders), case THIS:get(range) of X when (X =:= undefined orelse X =:= fail) orelse Body =:= chunked -> %% http://code.google.com/p/mochiweb/issues/detail?id=54 %% Range header not supported when chunked, return 200 and provide %% full response. HResponse1 = mochiweb_headers:enter("Content-Type", ContentType, HResponse), respond({200, HResponse1, Body}, THIS); Ranges -> {PartList, Size} = range_parts(Body, Ranges), case PartList of [] -> %% no valid ranges HResponse1 = mochiweb_headers:enter("Content-Type", ContentType, HResponse), %% could be 416, for now we'll just return 200 respond({200, HResponse1, Body}, THIS); PartList -> {RangeHeaders, RangeBody} = mochiweb_multipart:parts_to_body(PartList, ContentType, Size), HResponse1 = mochiweb_headers:enter_from_list( [{"Accept-Ranges", "bytes"} | RangeHeaders], HResponse), respond({206, HResponse1, RangeBody}, THIS) end end. %% @spec should_close(request()) -> bool() %% @doc Return true if the connection must be closed. If false, using %% Keep-Alive should be safe. should_close({?MODULE, [_Socket, _Method, _RawPath, Version, _Headers]}=THIS) -> ForceClose = erlang:get(?SAVE_FORCE_CLOSE) =/= undefined, DidNotRecv = erlang:get(?SAVE_RECV) =:= undefined, ForceClose orelse Version < {1, 0} %% Connection: close orelse is_close(get_header_value("connection", THIS)) %% HTTP 1.0 requires Connection: Keep-Alive orelse (Version =:= {1, 0} andalso get_header_value("connection", THIS) =/= "Keep-Alive") %% unread data left on the socket, can't safely continue orelse (DidNotRecv andalso get_combined_header_value("content-length", THIS) =/= undefined andalso list_to_integer(get_combined_header_value("content-length", THIS)) > 0) orelse (DidNotRecv andalso get_header_value("transfer-encoding", THIS) =:= "chunked"). is_close("close") -> true; is_close(S=[_C, _L, _O, _S, _E]) -> string:to_lower(S) =:= "close"; is_close(_) -> false. %% @spec cleanup(request()) -> ok %% @doc Clean up any junk in the process dictionary, required before continuing %% a Keep-Alive request. cleanup({?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}) -> L = [?SAVE_QS, ?SAVE_PATH, ?SAVE_RECV, ?SAVE_BODY, ?SAVE_BODY_LENGTH, ?SAVE_POST, ?SAVE_COOKIE, ?SAVE_FORCE_CLOSE], lists:foreach(fun(K) -> erase(K) end, L), ok. %% @spec parse_qs(request()) -> [{Key::string(), Value::string()}] %% @doc Parse the query string of the URL. parse_qs({?MODULE, [_Socket, _Method, RawPath, _Version, _Headers]}) -> case erlang:get(?SAVE_QS) of undefined -> {_, QueryString, _} = mochiweb_util:urlsplit_path(RawPath), Parsed = mochiweb_util:parse_qs(QueryString), put(?SAVE_QS, Parsed), Parsed; Cached -> Cached end. %% @spec get_cookie_value(Key::string, request()) -> string() | undefined %% @doc Get the value of the given cookie. get_cookie_value(Key, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> proplists:get_value(Key, parse_cookie(THIS)). %% @spec parse_cookie(request()) -> [{Key::string(), Value::string()}] %% @doc Parse the cookie header. parse_cookie({?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> case erlang:get(?SAVE_COOKIE) of undefined -> Cookies = case get_header_value("cookie", THIS) of undefined -> []; Value -> mochiweb_cookies:parse_cookie(Value) end, put(?SAVE_COOKIE, Cookies), Cookies; Cached -> Cached end. %% @spec parse_post(request()) -> [{Key::string(), Value::string()}] %% @doc Parse an application/x-www-form-urlencoded form POST. This %% has the side-effect of calling recv_body(). parse_post({?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> case erlang:get(?SAVE_POST) of undefined -> Parsed = case recv_body(THIS) of undefined -> []; Binary -> case get_primary_header_value("content-type",THIS) of "application/x-www-form-urlencoded" ++ _ -> mochiweb_util:parse_qs(Binary); _ -> [] end end, put(?SAVE_POST, Parsed), Parsed; Cached -> Cached end. %% @spec stream_chunked_body(integer(), fun(), term(), request()) -> term() %% @doc The function is called for each chunk. %% Used internally by read_chunked_body. stream_chunked_body(MaxChunkSize, Fun, FunState, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> case read_chunk_length(THIS) of 0 -> Fun({0, read_chunk(0, THIS)}, FunState); Length when Length > MaxChunkSize -> NewState = read_sub_chunks(Length, MaxChunkSize, Fun, FunState, THIS), stream_chunked_body(MaxChunkSize, Fun, NewState, THIS); Length -> NewState = Fun({Length, read_chunk(Length, THIS)}, FunState), stream_chunked_body(MaxChunkSize, Fun, NewState, THIS) end. stream_unchunked_body(0, Fun, FunState, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}) -> Fun({0, <<>>}, FunState); stream_unchunked_body(Length, Fun, FunState, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) when Length > 0 -> PktSize = case Length > ?RECBUF_SIZE of true -> ?RECBUF_SIZE; false -> Length end, Bin = recv(PktSize, THIS), NewState = Fun({PktSize, Bin}, FunState), stream_unchunked_body(Length - PktSize, Fun, NewState, THIS). %% @spec read_chunk_length(request()) -> integer() %% @doc Read the length of the next HTTP chunk. read_chunk_length({?MODULE, [Socket, _Method, _RawPath, _Version, _Headers]}) -> ok = mochiweb_socket:setopts(Socket, [{packet, line}]), case mochiweb_socket:recv(Socket, 0, ?IDLE_TIMEOUT) of {ok, Header} -> ok = mochiweb_socket:setopts(Socket, [{packet, raw}]), Splitter = fun (C) -> C =/= $\r andalso C =/= $\n andalso C =/= $ end, {Hex, _Rest} = lists:splitwith(Splitter, binary_to_list(Header)), mochihex:to_int(Hex); _ -> exit(normal) end. %% @spec read_chunk(integer(), request()) -> Chunk::binary() | [Footer::binary()] %% @doc Read in a HTTP chunk of the given length. If Length is 0, then read the %% HTTP footers (as a list of binaries, since they're nominal). read_chunk(0, {?MODULE, [Socket, _Method, _RawPath, _Version, _Headers]}) -> ok = mochiweb_socket:setopts(Socket, [{packet, line}]), F = fun (F1, Acc) -> case mochiweb_socket:recv(Socket, 0, ?IDLE_TIMEOUT) of {ok, <<"\r\n">>} -> Acc; {ok, Footer} -> F1(F1, [Footer | Acc]); _ -> exit(normal) end end, Footers = F(F, []), ok = mochiweb_socket:setopts(Socket, [{packet, raw}]), put(?SAVE_RECV, true), Footers; read_chunk(Length, {?MODULE, [Socket, _Method, _RawPath, _Version, _Headers]}) -> case mochiweb_socket:recv(Socket, 2 + Length, ?IDLE_TIMEOUT) of {ok, <>} -> Chunk; _ -> exit(normal) end. read_sub_chunks(Length, MaxChunkSize, Fun, FunState, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) when Length > MaxChunkSize -> Bin = recv(MaxChunkSize, THIS), NewState = Fun({size(Bin), Bin}, FunState), read_sub_chunks(Length - MaxChunkSize, MaxChunkSize, Fun, NewState, THIS); read_sub_chunks(Length, _MaxChunkSize, Fun, FunState, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> Fun({Length, read_chunk(Length, THIS)}, FunState). %% @spec serve_file(Path, DocRoot, request()) -> Response %% @doc Serve a file relative to DocRoot. serve_file(Path, DocRoot, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> serve_file(Path, DocRoot, [], THIS). %% @spec serve_file(Path, DocRoot, ExtraHeaders, request()) -> Response %% @doc Serve a file relative to DocRoot. serve_file(Path, DocRoot, ExtraHeaders, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> case mochiweb_util:safe_relative_path(Path) of undefined -> not_found(ExtraHeaders, THIS); RelPath -> FullPath = filename:join([DocRoot, RelPath]), case filelib:is_dir(FullPath) of true -> maybe_redirect(RelPath, FullPath, ExtraHeaders, THIS); false -> maybe_serve_file(FullPath, ExtraHeaders, THIS) end end. %% Internal API %% This has the same effect as the DirectoryIndex directive in httpd directory_index(FullPath) -> filename:join([FullPath, "index.html"]). maybe_redirect([], FullPath, ExtraHeaders, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> maybe_serve_file(directory_index(FullPath), ExtraHeaders, THIS); maybe_redirect(RelPath, FullPath, ExtraHeaders, {?MODULE, [_Socket, _Method, _RawPath, _Version, Headers]}=THIS) -> case string:right(RelPath, 1) of "/" -> maybe_serve_file(directory_index(FullPath), ExtraHeaders, THIS); _ -> Host = mochiweb_headers:get_value("host", Headers), Location = "http://" ++ Host ++ "/" ++ RelPath ++ "/", LocationBin = list_to_binary(Location), MoreHeaders = [{"Location", Location}, {"Content-Type", "text/html"} | ExtraHeaders], Top = <<"" "" "301 Moved Permanently" "" "

    Moved Permanently

    " "

    The document has moved >, Bottom = <<">here.

    \n">>, Body = <>, respond({301, MoreHeaders, Body}, THIS) end. maybe_serve_file(File, ExtraHeaders, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> case file:read_file_info(File) of {ok, FileInfo} -> LastModified = httpd_util:rfc1123_date(FileInfo#file_info.mtime), case get_header_value("if-modified-since", THIS) of LastModified -> respond({304, ExtraHeaders, ""}, THIS); _ -> case file:open(File, [raw, binary]) of {ok, IoDevice} -> ContentType = mochiweb_util:guess_mime(File), Res = ok({ContentType, [{"last-modified", LastModified} | ExtraHeaders], {file, IoDevice}}, THIS), ok = file:close(IoDevice), Res; _ -> not_found(ExtraHeaders, THIS) end end; {error, _} -> not_found(ExtraHeaders, THIS) end. server_headers() -> [{"Server", "MochiWeb/1.0 (" ++ ?QUIP ++ ")"}, {"Date", httpd_util:rfc1123_date()}]. make_code(X) when is_integer(X) -> [integer_to_list(X), [" " | httpd_util:reason_phrase(X)]]; make_code(Io) when is_list(Io); is_binary(Io) -> Io. make_version({1, 0}) -> <<"HTTP/1.0 ">>; make_version(_) -> <<"HTTP/1.1 ">>. range_parts({file, IoDevice}, Ranges) -> Size = mochiweb_io:iodevice_size(IoDevice), F = fun (Spec, Acc) -> case mochiweb_http:range_skip_length(Spec, Size) of invalid_range -> Acc; V -> [V | Acc] end end, LocNums = lists:foldr(F, [], Ranges), {ok, Data} = file:pread(IoDevice, LocNums), Bodies = lists:zipwith(fun ({Skip, Length}, PartialBody) -> {Skip, Skip + Length - 1, PartialBody} end, LocNums, Data), {Bodies, Size}; range_parts(Body0, Ranges) -> Body = iolist_to_binary(Body0), Size = size(Body), F = fun(Spec, Acc) -> case mochiweb_http:range_skip_length(Spec, Size) of invalid_range -> Acc; {Skip, Length} -> <<_:Skip/binary, PartialBody:Length/binary, _/binary>> = Body, [{Skip, Skip + Length - 1, PartialBody} | Acc] end end, {lists:foldr(F, [], Ranges), Size}. %% @spec accepted_encodings([encoding()], request()) -> [encoding()] | bad_accept_encoding_value %% @type encoding() = string(). %% %% @doc Returns a list of encodings accepted by a request. Encodings that are %% not supported by the server will not be included in the return list. %% This list is computed from the "Accept-Encoding" header and %% its elements are ordered, descendingly, according to their Q values. %% %% Section 14.3 of the RFC 2616 (HTTP 1.1) describes the "Accept-Encoding" %% header and the process of determining which server supported encodings %% can be used for encoding the body for the request's response. %% %% Examples %% %% 1) For a missing "Accept-Encoding" header: %% accepted_encodings(["gzip", "identity"]) -> ["identity"] %% %% 2) For an "Accept-Encoding" header with value "gzip, deflate": %% accepted_encodings(["gzip", "identity"]) -> ["gzip", "identity"] %% %% 3) For an "Accept-Encoding" header with value "gzip;q=0.5, deflate": %% accepted_encodings(["gzip", "deflate", "identity"]) -> %% ["deflate", "gzip", "identity"] %% accepted_encodings(SupportedEncodings, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> AcceptEncodingHeader = case get_header_value("Accept-Encoding", THIS) of undefined -> ""; Value -> Value end, case mochiweb_util:parse_qvalues(AcceptEncodingHeader) of invalid_qvalue_string -> bad_accept_encoding_value; QList -> mochiweb_util:pick_accepted_encodings( QList, SupportedEncodings, "identity" ) end. %% @spec accepts_content_type(string() | binary(), request()) -> boolean() | bad_accept_header %% %% @doc Determines whether a request accepts a given media type by analyzing its %% "Accept" header. %% %% Examples %% %% 1) For a missing "Accept" header: %% accepts_content_type("application/json") -> true %% %% 2) For an "Accept" header with value "text/plain, application/*": %% accepts_content_type("application/json") -> true %% %% 3) For an "Accept" header with value "text/plain, */*; q=0.0": %% accepts_content_type("application/json") -> false %% %% 4) For an "Accept" header with value "text/plain; q=0.5, */*; q=0.1": %% accepts_content_type("application/json") -> true %% %% 5) For an "Accept" header with value "text/*; q=0.0, */*": %% accepts_content_type("text/plain") -> false %% accepts_content_type(ContentType1, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> ContentType = re:replace(ContentType1, "\\s", "", [global, {return, list}]), AcceptHeader = accept_header(THIS), case mochiweb_util:parse_qvalues(AcceptHeader) of invalid_qvalue_string -> bad_accept_header; QList -> [MainType, _SubType] = string:tokens(ContentType, "/"), SuperType = MainType ++ "/*", lists:any( fun({"*/*", Q}) when Q > 0.0 -> true; ({Type, Q}) when Q > 0.0 -> Type =:= ContentType orelse Type =:= SuperType; (_) -> false end, QList ) andalso (not lists:member({ContentType, 0.0}, QList)) andalso (not lists:member({SuperType, 0.0}, QList)) end. %% @spec accepted_content_types([string() | binary()], request()) -> [string()] | bad_accept_header %% %% @doc Filters which of the given media types this request accepts. This filtering %% is performed by analyzing the "Accept" header. The returned list is sorted %% according to the preferences specified in the "Accept" header (higher Q values %% first). If two or more types have the same preference (Q value), they're order %% in the returned list is the same as they're order in the input list. %% %% Examples %% %% 1) For a missing "Accept" header: %% accepted_content_types(["text/html", "application/json"]) -> %% ["text/html", "application/json"] %% %% 2) For an "Accept" header with value "text/html, application/*": %% accepted_content_types(["application/json", "text/html"]) -> %% ["application/json", "text/html"] %% %% 3) For an "Accept" header with value "text/html, */*; q=0.0": %% accepted_content_types(["text/html", "application/json"]) -> %% ["text/html"] %% %% 4) For an "Accept" header with value "text/html; q=0.5, */*; q=0.1": %% accepts_content_types(["application/json", "text/html"]) -> %% ["text/html", "application/json"] %% accepted_content_types(Types1, {?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> Types = lists:map( fun(T) -> re:replace(T, "\\s", "", [global, {return, list}]) end, Types1), AcceptHeader = accept_header(THIS), case mochiweb_util:parse_qvalues(AcceptHeader) of invalid_qvalue_string -> bad_accept_header; QList -> TypesQ = lists:foldr( fun(T, Acc) -> case proplists:get_value(T, QList) of undefined -> [MainType, _SubType] = string:tokens(T, "/"), case proplists:get_value(MainType ++ "/*", QList) of undefined -> case proplists:get_value("*/*", QList) of Q when is_float(Q), Q > 0.0 -> [{Q, T} | Acc]; _ -> Acc end; Q when Q > 0.0 -> [{Q, T} | Acc]; _ -> Acc end; Q when Q > 0.0 -> [{Q, T} | Acc]; _ -> Acc end end, [], Types), % Note: Stable sort. If 2 types have the same Q value we leave them in the % same order as in the input list. SortFun = fun({Q1, _}, {Q2, _}) -> Q1 >= Q2 end, [Type || {_Q, Type} <- lists:sort(SortFun, TypesQ)] end. accept_header({?MODULE, [_Socket, _Method, _RawPath, _Version, _Headers]}=THIS) -> case get_header_value("Accept", THIS) of undefined -> "*/*"; Value -> Value end. %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb_charref.erl0000644000177700017770000020415412633765070031343 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2007 Mochi Media, Inc. %% @doc Converts HTML 5 charrefs and entities to codepoints (or lists of code points). -module(mochiweb_charref). -export([charref/1]). %% External API. %% @doc Convert a decimal charref, hex charref, or html entity to a unicode %% codepoint, or return undefined on failure. %% The input should not include an ampersand or semicolon. %% charref("#38") = 38, charref("#x26") = 38, charref("amp") = 38. %% -spec charref(binary() | string()) -> integer() | [integer()] | undefined. charref(B) when is_binary(B) -> charref(binary_to_list(B)); charref([$#, C | L]) when C =:= $x orelse C =:= $X -> try erlang:list_to_integer(L, 16) catch error:badarg -> undefined end; charref([$# | L]) -> try list_to_integer(L) catch error:badarg -> undefined end; charref(L) -> entity(L). %% Internal API. %% [2011-10-14] Generated from: %% http://www.w3.org/TR/html5/named-character-references.html entity("AElig") -> 16#000C6; entity("AMP") -> 16#00026; entity("Aacute") -> 16#000C1; entity("Abreve") -> 16#00102; entity("Acirc") -> 16#000C2; entity("Acy") -> 16#00410; entity("Afr") -> 16#1D504; entity("Agrave") -> 16#000C0; entity("Alpha") -> 16#00391; entity("Amacr") -> 16#00100; entity("And") -> 16#02A53; entity("Aogon") -> 16#00104; entity("Aopf") -> 16#1D538; entity("ApplyFunction") -> 16#02061; entity("Aring") -> 16#000C5; entity("Ascr") -> 16#1D49C; entity("Assign") -> 16#02254; entity("Atilde") -> 16#000C3; entity("Auml") -> 16#000C4; entity("Backslash") -> 16#02216; entity("Barv") -> 16#02AE7; entity("Barwed") -> 16#02306; entity("Bcy") -> 16#00411; entity("Because") -> 16#02235; entity("Bernoullis") -> 16#0212C; entity("Beta") -> 16#00392; entity("Bfr") -> 16#1D505; entity("Bopf") -> 16#1D539; entity("Breve") -> 16#002D8; entity("Bscr") -> 16#0212C; entity("Bumpeq") -> 16#0224E; entity("CHcy") -> 16#00427; entity("COPY") -> 16#000A9; entity("Cacute") -> 16#00106; entity("Cap") -> 16#022D2; entity("CapitalDifferentialD") -> 16#02145; entity("Cayleys") -> 16#0212D; entity("Ccaron") -> 16#0010C; entity("Ccedil") -> 16#000C7; entity("Ccirc") -> 16#00108; entity("Cconint") -> 16#02230; entity("Cdot") -> 16#0010A; entity("Cedilla") -> 16#000B8; entity("CenterDot") -> 16#000B7; entity("Cfr") -> 16#0212D; entity("Chi") -> 16#003A7; entity("CircleDot") -> 16#02299; entity("CircleMinus") -> 16#02296; entity("CirclePlus") -> 16#02295; entity("CircleTimes") -> 16#02297; entity("ClockwiseContourIntegral") -> 16#02232; entity("CloseCurlyDoubleQuote") -> 16#0201D; entity("CloseCurlyQuote") -> 16#02019; entity("Colon") -> 16#02237; entity("Colone") -> 16#02A74; entity("Congruent") -> 16#02261; entity("Conint") -> 16#0222F; entity("ContourIntegral") -> 16#0222E; entity("Copf") -> 16#02102; entity("Coproduct") -> 16#02210; entity("CounterClockwiseContourIntegral") -> 16#02233; entity("Cross") -> 16#02A2F; entity("Cscr") -> 16#1D49E; entity("Cup") -> 16#022D3; entity("CupCap") -> 16#0224D; entity("DD") -> 16#02145; entity("DDotrahd") -> 16#02911; entity("DJcy") -> 16#00402; entity("DScy") -> 16#00405; entity("DZcy") -> 16#0040F; entity("Dagger") -> 16#02021; entity("Darr") -> 16#021A1; entity("Dashv") -> 16#02AE4; entity("Dcaron") -> 16#0010E; entity("Dcy") -> 16#00414; entity("Del") -> 16#02207; entity("Delta") -> 16#00394; entity("Dfr") -> 16#1D507; entity("DiacriticalAcute") -> 16#000B4; entity("DiacriticalDot") -> 16#002D9; entity("DiacriticalDoubleAcute") -> 16#002DD; entity("DiacriticalGrave") -> 16#00060; entity("DiacriticalTilde") -> 16#002DC; entity("Diamond") -> 16#022C4; entity("DifferentialD") -> 16#02146; entity("Dopf") -> 16#1D53B; entity("Dot") -> 16#000A8; entity("DotDot") -> 16#020DC; entity("DotEqual") -> 16#02250; entity("DoubleContourIntegral") -> 16#0222F; entity("DoubleDot") -> 16#000A8; entity("DoubleDownArrow") -> 16#021D3; entity("DoubleLeftArrow") -> 16#021D0; entity("DoubleLeftRightArrow") -> 16#021D4; entity("DoubleLeftTee") -> 16#02AE4; entity("DoubleLongLeftArrow") -> 16#027F8; entity("DoubleLongLeftRightArrow") -> 16#027FA; entity("DoubleLongRightArrow") -> 16#027F9; entity("DoubleRightArrow") -> 16#021D2; entity("DoubleRightTee") -> 16#022A8; entity("DoubleUpArrow") -> 16#021D1; entity("DoubleUpDownArrow") -> 16#021D5; entity("DoubleVerticalBar") -> 16#02225; entity("DownArrow") -> 16#02193; entity("DownArrowBar") -> 16#02913; entity("DownArrowUpArrow") -> 16#021F5; entity("DownBreve") -> 16#00311; entity("DownLeftRightVector") -> 16#02950; entity("DownLeftTeeVector") -> 16#0295E; entity("DownLeftVector") -> 16#021BD; entity("DownLeftVectorBar") -> 16#02956; entity("DownRightTeeVector") -> 16#0295F; entity("DownRightVector") -> 16#021C1; entity("DownRightVectorBar") -> 16#02957; entity("DownTee") -> 16#022A4; entity("DownTeeArrow") -> 16#021A7; entity("Downarrow") -> 16#021D3; entity("Dscr") -> 16#1D49F; entity("Dstrok") -> 16#00110; entity("ENG") -> 16#0014A; entity("ETH") -> 16#000D0; entity("Eacute") -> 16#000C9; entity("Ecaron") -> 16#0011A; entity("Ecirc") -> 16#000CA; entity("Ecy") -> 16#0042D; entity("Edot") -> 16#00116; entity("Efr") -> 16#1D508; entity("Egrave") -> 16#000C8; entity("Element") -> 16#02208; entity("Emacr") -> 16#00112; entity("EmptySmallSquare") -> 16#025FB; entity("EmptyVerySmallSquare") -> 16#025AB; entity("Eogon") -> 16#00118; entity("Eopf") -> 16#1D53C; entity("Epsilon") -> 16#00395; entity("Equal") -> 16#02A75; entity("EqualTilde") -> 16#02242; entity("Equilibrium") -> 16#021CC; entity("Escr") -> 16#02130; entity("Esim") -> 16#02A73; entity("Eta") -> 16#00397; entity("Euml") -> 16#000CB; entity("Exists") -> 16#02203; entity("ExponentialE") -> 16#02147; entity("Fcy") -> 16#00424; entity("Ffr") -> 16#1D509; entity("FilledSmallSquare") -> 16#025FC; entity("FilledVerySmallSquare") -> 16#025AA; entity("Fopf") -> 16#1D53D; entity("ForAll") -> 16#02200; entity("Fouriertrf") -> 16#02131; entity("Fscr") -> 16#02131; entity("GJcy") -> 16#00403; entity("GT") -> 16#0003E; entity("Gamma") -> 16#00393; entity("Gammad") -> 16#003DC; entity("Gbreve") -> 16#0011E; entity("Gcedil") -> 16#00122; entity("Gcirc") -> 16#0011C; entity("Gcy") -> 16#00413; entity("Gdot") -> 16#00120; entity("Gfr") -> 16#1D50A; entity("Gg") -> 16#022D9; entity("Gopf") -> 16#1D53E; entity("GreaterEqual") -> 16#02265; entity("GreaterEqualLess") -> 16#022DB; entity("GreaterFullEqual") -> 16#02267; entity("GreaterGreater") -> 16#02AA2; entity("GreaterLess") -> 16#02277; entity("GreaterSlantEqual") -> 16#02A7E; entity("GreaterTilde") -> 16#02273; entity("Gscr") -> 16#1D4A2; entity("Gt") -> 16#0226B; entity("HARDcy") -> 16#0042A; entity("Hacek") -> 16#002C7; entity("Hat") -> 16#0005E; entity("Hcirc") -> 16#00124; entity("Hfr") -> 16#0210C; entity("HilbertSpace") -> 16#0210B; entity("Hopf") -> 16#0210D; entity("HorizontalLine") -> 16#02500; entity("Hscr") -> 16#0210B; entity("Hstrok") -> 16#00126; entity("HumpDownHump") -> 16#0224E; entity("HumpEqual") -> 16#0224F; entity("IEcy") -> 16#00415; entity("IJlig") -> 16#00132; entity("IOcy") -> 16#00401; entity("Iacute") -> 16#000CD; entity("Icirc") -> 16#000CE; entity("Icy") -> 16#00418; entity("Idot") -> 16#00130; entity("Ifr") -> 16#02111; entity("Igrave") -> 16#000CC; entity("Im") -> 16#02111; entity("Imacr") -> 16#0012A; entity("ImaginaryI") -> 16#02148; entity("Implies") -> 16#021D2; entity("Int") -> 16#0222C; entity("Integral") -> 16#0222B; entity("Intersection") -> 16#022C2; entity("InvisibleComma") -> 16#02063; entity("InvisibleTimes") -> 16#02062; entity("Iogon") -> 16#0012E; entity("Iopf") -> 16#1D540; entity("Iota") -> 16#00399; entity("Iscr") -> 16#02110; entity("Itilde") -> 16#00128; entity("Iukcy") -> 16#00406; entity("Iuml") -> 16#000CF; entity("Jcirc") -> 16#00134; entity("Jcy") -> 16#00419; entity("Jfr") -> 16#1D50D; entity("Jopf") -> 16#1D541; entity("Jscr") -> 16#1D4A5; entity("Jsercy") -> 16#00408; entity("Jukcy") -> 16#00404; entity("KHcy") -> 16#00425; entity("KJcy") -> 16#0040C; entity("Kappa") -> 16#0039A; entity("Kcedil") -> 16#00136; entity("Kcy") -> 16#0041A; entity("Kfr") -> 16#1D50E; entity("Kopf") -> 16#1D542; entity("Kscr") -> 16#1D4A6; entity("LJcy") -> 16#00409; entity("LT") -> 16#0003C; entity("Lacute") -> 16#00139; entity("Lambda") -> 16#0039B; entity("Lang") -> 16#027EA; entity("Laplacetrf") -> 16#02112; entity("Larr") -> 16#0219E; entity("Lcaron") -> 16#0013D; entity("Lcedil") -> 16#0013B; entity("Lcy") -> 16#0041B; entity("LeftAngleBracket") -> 16#027E8; entity("LeftArrow") -> 16#02190; entity("LeftArrowBar") -> 16#021E4; entity("LeftArrowRightArrow") -> 16#021C6; entity("LeftCeiling") -> 16#02308; entity("LeftDoubleBracket") -> 16#027E6; entity("LeftDownTeeVector") -> 16#02961; entity("LeftDownVector") -> 16#021C3; entity("LeftDownVectorBar") -> 16#02959; entity("LeftFloor") -> 16#0230A; entity("LeftRightArrow") -> 16#02194; entity("LeftRightVector") -> 16#0294E; entity("LeftTee") -> 16#022A3; entity("LeftTeeArrow") -> 16#021A4; entity("LeftTeeVector") -> 16#0295A; entity("LeftTriangle") -> 16#022B2; entity("LeftTriangleBar") -> 16#029CF; entity("LeftTriangleEqual") -> 16#022B4; entity("LeftUpDownVector") -> 16#02951; entity("LeftUpTeeVector") -> 16#02960; entity("LeftUpVector") -> 16#021BF; entity("LeftUpVectorBar") -> 16#02958; entity("LeftVector") -> 16#021BC; entity("LeftVectorBar") -> 16#02952; entity("Leftarrow") -> 16#021D0; entity("Leftrightarrow") -> 16#021D4; entity("LessEqualGreater") -> 16#022DA; entity("LessFullEqual") -> 16#02266; entity("LessGreater") -> 16#02276; entity("LessLess") -> 16#02AA1; entity("LessSlantEqual") -> 16#02A7D; entity("LessTilde") -> 16#02272; entity("Lfr") -> 16#1D50F; entity("Ll") -> 16#022D8; entity("Lleftarrow") -> 16#021DA; entity("Lmidot") -> 16#0013F; entity("LongLeftArrow") -> 16#027F5; entity("LongLeftRightArrow") -> 16#027F7; entity("LongRightArrow") -> 16#027F6; entity("Longleftarrow") -> 16#027F8; entity("Longleftrightarrow") -> 16#027FA; entity("Longrightarrow") -> 16#027F9; entity("Lopf") -> 16#1D543; entity("LowerLeftArrow") -> 16#02199; entity("LowerRightArrow") -> 16#02198; entity("Lscr") -> 16#02112; entity("Lsh") -> 16#021B0; entity("Lstrok") -> 16#00141; entity("Lt") -> 16#0226A; entity("Map") -> 16#02905; entity("Mcy") -> 16#0041C; entity("MediumSpace") -> 16#0205F; entity("Mellintrf") -> 16#02133; entity("Mfr") -> 16#1D510; entity("MinusPlus") -> 16#02213; entity("Mopf") -> 16#1D544; entity("Mscr") -> 16#02133; entity("Mu") -> 16#0039C; entity("NJcy") -> 16#0040A; entity("Nacute") -> 16#00143; entity("Ncaron") -> 16#00147; entity("Ncedil") -> 16#00145; entity("Ncy") -> 16#0041D; entity("NegativeMediumSpace") -> 16#0200B; entity("NegativeThickSpace") -> 16#0200B; entity("NegativeThinSpace") -> 16#0200B; entity("NegativeVeryThinSpace") -> 16#0200B; entity("NestedGreaterGreater") -> 16#0226B; entity("NestedLessLess") -> 16#0226A; entity("NewLine") -> 16#0000A; entity("Nfr") -> 16#1D511; entity("NoBreak") -> 16#02060; entity("NonBreakingSpace") -> 16#000A0; entity("Nopf") -> 16#02115; entity("Not") -> 16#02AEC; entity("NotCongruent") -> 16#02262; entity("NotCupCap") -> 16#0226D; entity("NotDoubleVerticalBar") -> 16#02226; entity("NotElement") -> 16#02209; entity("NotEqual") -> 16#02260; entity("NotEqualTilde") -> [16#02242, 16#00338]; entity("NotExists") -> 16#02204; entity("NotGreater") -> 16#0226F; entity("NotGreaterEqual") -> 16#02271; entity("NotGreaterFullEqual") -> [16#02267, 16#00338]; entity("NotGreaterGreater") -> [16#0226B, 16#00338]; entity("NotGreaterLess") -> 16#02279; entity("NotGreaterSlantEqual") -> [16#02A7E, 16#00338]; entity("NotGreaterTilde") -> 16#02275; entity("NotHumpDownHump") -> [16#0224E, 16#00338]; entity("NotHumpEqual") -> [16#0224F, 16#00338]; entity("NotLeftTriangle") -> 16#022EA; entity("NotLeftTriangleBar") -> [16#029CF, 16#00338]; entity("NotLeftTriangleEqual") -> 16#022EC; entity("NotLess") -> 16#0226E; entity("NotLessEqual") -> 16#02270; entity("NotLessGreater") -> 16#02278; entity("NotLessLess") -> [16#0226A, 16#00338]; entity("NotLessSlantEqual") -> [16#02A7D, 16#00338]; entity("NotLessTilde") -> 16#02274; entity("NotNestedGreaterGreater") -> [16#02AA2, 16#00338]; entity("NotNestedLessLess") -> [16#02AA1, 16#00338]; entity("NotPrecedes") -> 16#02280; entity("NotPrecedesEqual") -> [16#02AAF, 16#00338]; entity("NotPrecedesSlantEqual") -> 16#022E0; entity("NotReverseElement") -> 16#0220C; entity("NotRightTriangle") -> 16#022EB; entity("NotRightTriangleBar") -> [16#029D0, 16#00338]; entity("NotRightTriangleEqual") -> 16#022ED; entity("NotSquareSubset") -> [16#0228F, 16#00338]; entity("NotSquareSubsetEqual") -> 16#022E2; entity("NotSquareSuperset") -> [16#02290, 16#00338]; entity("NotSquareSupersetEqual") -> 16#022E3; entity("NotSubset") -> [16#02282, 16#020D2]; entity("NotSubsetEqual") -> 16#02288; entity("NotSucceeds") -> 16#02281; entity("NotSucceedsEqual") -> [16#02AB0, 16#00338]; entity("NotSucceedsSlantEqual") -> 16#022E1; entity("NotSucceedsTilde") -> [16#0227F, 16#00338]; entity("NotSuperset") -> [16#02283, 16#020D2]; entity("NotSupersetEqual") -> 16#02289; entity("NotTilde") -> 16#02241; entity("NotTildeEqual") -> 16#02244; entity("NotTildeFullEqual") -> 16#02247; entity("NotTildeTilde") -> 16#02249; entity("NotVerticalBar") -> 16#02224; entity("Nscr") -> 16#1D4A9; entity("Ntilde") -> 16#000D1; entity("Nu") -> 16#0039D; entity("OElig") -> 16#00152; entity("Oacute") -> 16#000D3; entity("Ocirc") -> 16#000D4; entity("Ocy") -> 16#0041E; entity("Odblac") -> 16#00150; entity("Ofr") -> 16#1D512; entity("Ograve") -> 16#000D2; entity("Omacr") -> 16#0014C; entity("Omega") -> 16#003A9; entity("Omicron") -> 16#0039F; entity("Oopf") -> 16#1D546; entity("OpenCurlyDoubleQuote") -> 16#0201C; entity("OpenCurlyQuote") -> 16#02018; entity("Or") -> 16#02A54; entity("Oscr") -> 16#1D4AA; entity("Oslash") -> 16#000D8; entity("Otilde") -> 16#000D5; entity("Otimes") -> 16#02A37; entity("Ouml") -> 16#000D6; entity("OverBar") -> 16#0203E; entity("OverBrace") -> 16#023DE; entity("OverBracket") -> 16#023B4; entity("OverParenthesis") -> 16#023DC; entity("PartialD") -> 16#02202; entity("Pcy") -> 16#0041F; entity("Pfr") -> 16#1D513; entity("Phi") -> 16#003A6; entity("Pi") -> 16#003A0; entity("PlusMinus") -> 16#000B1; entity("Poincareplane") -> 16#0210C; entity("Popf") -> 16#02119; entity("Pr") -> 16#02ABB; entity("Precedes") -> 16#0227A; entity("PrecedesEqual") -> 16#02AAF; entity("PrecedesSlantEqual") -> 16#0227C; entity("PrecedesTilde") -> 16#0227E; entity("Prime") -> 16#02033; entity("Product") -> 16#0220F; entity("Proportion") -> 16#02237; entity("Proportional") -> 16#0221D; entity("Pscr") -> 16#1D4AB; entity("Psi") -> 16#003A8; entity("QUOT") -> 16#00022; entity("Qfr") -> 16#1D514; entity("Qopf") -> 16#0211A; entity("Qscr") -> 16#1D4AC; entity("RBarr") -> 16#02910; entity("REG") -> 16#000AE; entity("Racute") -> 16#00154; entity("Rang") -> 16#027EB; entity("Rarr") -> 16#021A0; entity("Rarrtl") -> 16#02916; entity("Rcaron") -> 16#00158; entity("Rcedil") -> 16#00156; entity("Rcy") -> 16#00420; entity("Re") -> 16#0211C; entity("ReverseElement") -> 16#0220B; entity("ReverseEquilibrium") -> 16#021CB; entity("ReverseUpEquilibrium") -> 16#0296F; entity("Rfr") -> 16#0211C; entity("Rho") -> 16#003A1; entity("RightAngleBracket") -> 16#027E9; entity("RightArrow") -> 16#02192; entity("RightArrowBar") -> 16#021E5; entity("RightArrowLeftArrow") -> 16#021C4; entity("RightCeiling") -> 16#02309; entity("RightDoubleBracket") -> 16#027E7; entity("RightDownTeeVector") -> 16#0295D; entity("RightDownVector") -> 16#021C2; entity("RightDownVectorBar") -> 16#02955; entity("RightFloor") -> 16#0230B; entity("RightTee") -> 16#022A2; entity("RightTeeArrow") -> 16#021A6; entity("RightTeeVector") -> 16#0295B; entity("RightTriangle") -> 16#022B3; entity("RightTriangleBar") -> 16#029D0; entity("RightTriangleEqual") -> 16#022B5; entity("RightUpDownVector") -> 16#0294F; entity("RightUpTeeVector") -> 16#0295C; entity("RightUpVector") -> 16#021BE; entity("RightUpVectorBar") -> 16#02954; entity("RightVector") -> 16#021C0; entity("RightVectorBar") -> 16#02953; entity("Rightarrow") -> 16#021D2; entity("Ropf") -> 16#0211D; entity("RoundImplies") -> 16#02970; entity("Rrightarrow") -> 16#021DB; entity("Rscr") -> 16#0211B; entity("Rsh") -> 16#021B1; entity("RuleDelayed") -> 16#029F4; entity("SHCHcy") -> 16#00429; entity("SHcy") -> 16#00428; entity("SOFTcy") -> 16#0042C; entity("Sacute") -> 16#0015A; entity("Sc") -> 16#02ABC; entity("Scaron") -> 16#00160; entity("Scedil") -> 16#0015E; entity("Scirc") -> 16#0015C; entity("Scy") -> 16#00421; entity("Sfr") -> 16#1D516; entity("ShortDownArrow") -> 16#02193; entity("ShortLeftArrow") -> 16#02190; entity("ShortRightArrow") -> 16#02192; entity("ShortUpArrow") -> 16#02191; entity("Sigma") -> 16#003A3; entity("SmallCircle") -> 16#02218; entity("Sopf") -> 16#1D54A; entity("Sqrt") -> 16#0221A; entity("Square") -> 16#025A1; entity("SquareIntersection") -> 16#02293; entity("SquareSubset") -> 16#0228F; entity("SquareSubsetEqual") -> 16#02291; entity("SquareSuperset") -> 16#02290; entity("SquareSupersetEqual") -> 16#02292; entity("SquareUnion") -> 16#02294; entity("Sscr") -> 16#1D4AE; entity("Star") -> 16#022C6; entity("Sub") -> 16#022D0; entity("Subset") -> 16#022D0; entity("SubsetEqual") -> 16#02286; entity("Succeeds") -> 16#0227B; entity("SucceedsEqual") -> 16#02AB0; entity("SucceedsSlantEqual") -> 16#0227D; entity("SucceedsTilde") -> 16#0227F; entity("SuchThat") -> 16#0220B; entity("Sum") -> 16#02211; entity("Sup") -> 16#022D1; entity("Superset") -> 16#02283; entity("SupersetEqual") -> 16#02287; entity("Supset") -> 16#022D1; entity("THORN") -> 16#000DE; entity("TRADE") -> 16#02122; entity("TSHcy") -> 16#0040B; entity("TScy") -> 16#00426; entity("Tab") -> 16#00009; entity("Tau") -> 16#003A4; entity("Tcaron") -> 16#00164; entity("Tcedil") -> 16#00162; entity("Tcy") -> 16#00422; entity("Tfr") -> 16#1D517; entity("Therefore") -> 16#02234; entity("Theta") -> 16#00398; entity("ThickSpace") -> [16#0205F, 16#0200A]; entity("ThinSpace") -> 16#02009; entity("Tilde") -> 16#0223C; entity("TildeEqual") -> 16#02243; entity("TildeFullEqual") -> 16#02245; entity("TildeTilde") -> 16#02248; entity("Topf") -> 16#1D54B; entity("TripleDot") -> 16#020DB; entity("Tscr") -> 16#1D4AF; entity("Tstrok") -> 16#00166; entity("Uacute") -> 16#000DA; entity("Uarr") -> 16#0219F; entity("Uarrocir") -> 16#02949; entity("Ubrcy") -> 16#0040E; entity("Ubreve") -> 16#0016C; entity("Ucirc") -> 16#000DB; entity("Ucy") -> 16#00423; entity("Udblac") -> 16#00170; entity("Ufr") -> 16#1D518; entity("Ugrave") -> 16#000D9; entity("Umacr") -> 16#0016A; entity("UnderBar") -> 16#0005F; entity("UnderBrace") -> 16#023DF; entity("UnderBracket") -> 16#023B5; entity("UnderParenthesis") -> 16#023DD; entity("Union") -> 16#022C3; entity("UnionPlus") -> 16#0228E; entity("Uogon") -> 16#00172; entity("Uopf") -> 16#1D54C; entity("UpArrow") -> 16#02191; entity("UpArrowBar") -> 16#02912; entity("UpArrowDownArrow") -> 16#021C5; entity("UpDownArrow") -> 16#02195; entity("UpEquilibrium") -> 16#0296E; entity("UpTee") -> 16#022A5; entity("UpTeeArrow") -> 16#021A5; entity("Uparrow") -> 16#021D1; entity("Updownarrow") -> 16#021D5; entity("UpperLeftArrow") -> 16#02196; entity("UpperRightArrow") -> 16#02197; entity("Upsi") -> 16#003D2; entity("Upsilon") -> 16#003A5; entity("Uring") -> 16#0016E; entity("Uscr") -> 16#1D4B0; entity("Utilde") -> 16#00168; entity("Uuml") -> 16#000DC; entity("VDash") -> 16#022AB; entity("Vbar") -> 16#02AEB; entity("Vcy") -> 16#00412; entity("Vdash") -> 16#022A9; entity("Vdashl") -> 16#02AE6; entity("Vee") -> 16#022C1; entity("Verbar") -> 16#02016; entity("Vert") -> 16#02016; entity("VerticalBar") -> 16#02223; entity("VerticalLine") -> 16#0007C; entity("VerticalSeparator") -> 16#02758; entity("VerticalTilde") -> 16#02240; entity("VeryThinSpace") -> 16#0200A; entity("Vfr") -> 16#1D519; entity("Vopf") -> 16#1D54D; entity("Vscr") -> 16#1D4B1; entity("Vvdash") -> 16#022AA; entity("Wcirc") -> 16#00174; entity("Wedge") -> 16#022C0; entity("Wfr") -> 16#1D51A; entity("Wopf") -> 16#1D54E; entity("Wscr") -> 16#1D4B2; entity("Xfr") -> 16#1D51B; entity("Xi") -> 16#0039E; entity("Xopf") -> 16#1D54F; entity("Xscr") -> 16#1D4B3; entity("YAcy") -> 16#0042F; entity("YIcy") -> 16#00407; entity("YUcy") -> 16#0042E; entity("Yacute") -> 16#000DD; entity("Ycirc") -> 16#00176; entity("Ycy") -> 16#0042B; entity("Yfr") -> 16#1D51C; entity("Yopf") -> 16#1D550; entity("Yscr") -> 16#1D4B4; entity("Yuml") -> 16#00178; entity("ZHcy") -> 16#00416; entity("Zacute") -> 16#00179; entity("Zcaron") -> 16#0017D; entity("Zcy") -> 16#00417; entity("Zdot") -> 16#0017B; entity("ZeroWidthSpace") -> 16#0200B; entity("Zeta") -> 16#00396; entity("Zfr") -> 16#02128; entity("Zopf") -> 16#02124; entity("Zscr") -> 16#1D4B5; entity("aacute") -> 16#000E1; entity("abreve") -> 16#00103; entity("ac") -> 16#0223E; entity("acE") -> [16#0223E, 16#00333]; entity("acd") -> 16#0223F; entity("acirc") -> 16#000E2; entity("acute") -> 16#000B4; entity("acy") -> 16#00430; entity("aelig") -> 16#000E6; entity("af") -> 16#02061; entity("afr") -> 16#1D51E; entity("agrave") -> 16#000E0; entity("alefsym") -> 16#02135; entity("aleph") -> 16#02135; entity("alpha") -> 16#003B1; entity("amacr") -> 16#00101; entity("amalg") -> 16#02A3F; entity("amp") -> 16#00026; entity("and") -> 16#02227; entity("andand") -> 16#02A55; entity("andd") -> 16#02A5C; entity("andslope") -> 16#02A58; entity("andv") -> 16#02A5A; entity("ang") -> 16#02220; entity("ange") -> 16#029A4; entity("angle") -> 16#02220; entity("angmsd") -> 16#02221; entity("angmsdaa") -> 16#029A8; entity("angmsdab") -> 16#029A9; entity("angmsdac") -> 16#029AA; entity("angmsdad") -> 16#029AB; entity("angmsdae") -> 16#029AC; entity("angmsdaf") -> 16#029AD; entity("angmsdag") -> 16#029AE; entity("angmsdah") -> 16#029AF; entity("angrt") -> 16#0221F; entity("angrtvb") -> 16#022BE; entity("angrtvbd") -> 16#0299D; entity("angsph") -> 16#02222; entity("angst") -> 16#000C5; entity("angzarr") -> 16#0237C; entity("aogon") -> 16#00105; entity("aopf") -> 16#1D552; entity("ap") -> 16#02248; entity("apE") -> 16#02A70; entity("apacir") -> 16#02A6F; entity("ape") -> 16#0224A; entity("apid") -> 16#0224B; entity("apos") -> 16#00027; entity("approx") -> 16#02248; entity("approxeq") -> 16#0224A; entity("aring") -> 16#000E5; entity("ascr") -> 16#1D4B6; entity("ast") -> 16#0002A; entity("asymp") -> 16#02248; entity("asympeq") -> 16#0224D; entity("atilde") -> 16#000E3; entity("auml") -> 16#000E4; entity("awconint") -> 16#02233; entity("awint") -> 16#02A11; entity("bNot") -> 16#02AED; entity("backcong") -> 16#0224C; entity("backepsilon") -> 16#003F6; entity("backprime") -> 16#02035; entity("backsim") -> 16#0223D; entity("backsimeq") -> 16#022CD; entity("barvee") -> 16#022BD; entity("barwed") -> 16#02305; entity("barwedge") -> 16#02305; entity("bbrk") -> 16#023B5; entity("bbrktbrk") -> 16#023B6; entity("bcong") -> 16#0224C; entity("bcy") -> 16#00431; entity("bdquo") -> 16#0201E; entity("becaus") -> 16#02235; entity("because") -> 16#02235; entity("bemptyv") -> 16#029B0; entity("bepsi") -> 16#003F6; entity("bernou") -> 16#0212C; entity("beta") -> 16#003B2; entity("beth") -> 16#02136; entity("between") -> 16#0226C; entity("bfr") -> 16#1D51F; entity("bigcap") -> 16#022C2; entity("bigcirc") -> 16#025EF; entity("bigcup") -> 16#022C3; entity("bigodot") -> 16#02A00; entity("bigoplus") -> 16#02A01; entity("bigotimes") -> 16#02A02; entity("bigsqcup") -> 16#02A06; entity("bigstar") -> 16#02605; entity("bigtriangledown") -> 16#025BD; entity("bigtriangleup") -> 16#025B3; entity("biguplus") -> 16#02A04; entity("bigvee") -> 16#022C1; entity("bigwedge") -> 16#022C0; entity("bkarow") -> 16#0290D; entity("blacklozenge") -> 16#029EB; entity("blacksquare") -> 16#025AA; entity("blacktriangle") -> 16#025B4; entity("blacktriangledown") -> 16#025BE; entity("blacktriangleleft") -> 16#025C2; entity("blacktriangleright") -> 16#025B8; entity("blank") -> 16#02423; entity("blk12") -> 16#02592; entity("blk14") -> 16#02591; entity("blk34") -> 16#02593; entity("block") -> 16#02588; entity("bne") -> [16#0003D, 16#020E5]; entity("bnequiv") -> [16#02261, 16#020E5]; entity("bnot") -> 16#02310; entity("bopf") -> 16#1D553; entity("bot") -> 16#022A5; entity("bottom") -> 16#022A5; entity("bowtie") -> 16#022C8; entity("boxDL") -> 16#02557; entity("boxDR") -> 16#02554; entity("boxDl") -> 16#02556; entity("boxDr") -> 16#02553; entity("boxH") -> 16#02550; entity("boxHD") -> 16#02566; entity("boxHU") -> 16#02569; entity("boxHd") -> 16#02564; entity("boxHu") -> 16#02567; entity("boxUL") -> 16#0255D; entity("boxUR") -> 16#0255A; entity("boxUl") -> 16#0255C; entity("boxUr") -> 16#02559; entity("boxV") -> 16#02551; entity("boxVH") -> 16#0256C; entity("boxVL") -> 16#02563; entity("boxVR") -> 16#02560; entity("boxVh") -> 16#0256B; entity("boxVl") -> 16#02562; entity("boxVr") -> 16#0255F; entity("boxbox") -> 16#029C9; entity("boxdL") -> 16#02555; entity("boxdR") -> 16#02552; entity("boxdl") -> 16#02510; entity("boxdr") -> 16#0250C; entity("boxh") -> 16#02500; entity("boxhD") -> 16#02565; entity("boxhU") -> 16#02568; entity("boxhd") -> 16#0252C; entity("boxhu") -> 16#02534; entity("boxminus") -> 16#0229F; entity("boxplus") -> 16#0229E; entity("boxtimes") -> 16#022A0; entity("boxuL") -> 16#0255B; entity("boxuR") -> 16#02558; entity("boxul") -> 16#02518; entity("boxur") -> 16#02514; entity("boxv") -> 16#02502; entity("boxvH") -> 16#0256A; entity("boxvL") -> 16#02561; entity("boxvR") -> 16#0255E; entity("boxvh") -> 16#0253C; entity("boxvl") -> 16#02524; entity("boxvr") -> 16#0251C; entity("bprime") -> 16#02035; entity("breve") -> 16#002D8; entity("brvbar") -> 16#000A6; entity("bscr") -> 16#1D4B7; entity("bsemi") -> 16#0204F; entity("bsim") -> 16#0223D; entity("bsime") -> 16#022CD; entity("bsol") -> 16#0005C; entity("bsolb") -> 16#029C5; entity("bsolhsub") -> 16#027C8; entity("bull") -> 16#02022; entity("bullet") -> 16#02022; entity("bump") -> 16#0224E; entity("bumpE") -> 16#02AAE; entity("bumpe") -> 16#0224F; entity("bumpeq") -> 16#0224F; entity("cacute") -> 16#00107; entity("cap") -> 16#02229; entity("capand") -> 16#02A44; entity("capbrcup") -> 16#02A49; entity("capcap") -> 16#02A4B; entity("capcup") -> 16#02A47; entity("capdot") -> 16#02A40; entity("caps") -> [16#02229, 16#0FE00]; entity("caret") -> 16#02041; entity("caron") -> 16#002C7; entity("ccaps") -> 16#02A4D; entity("ccaron") -> 16#0010D; entity("ccedil") -> 16#000E7; entity("ccirc") -> 16#00109; entity("ccups") -> 16#02A4C; entity("ccupssm") -> 16#02A50; entity("cdot") -> 16#0010B; entity("cedil") -> 16#000B8; entity("cemptyv") -> 16#029B2; entity("cent") -> 16#000A2; entity("centerdot") -> 16#000B7; entity("cfr") -> 16#1D520; entity("chcy") -> 16#00447; entity("check") -> 16#02713; entity("checkmark") -> 16#02713; entity("chi") -> 16#003C7; entity("cir") -> 16#025CB; entity("cirE") -> 16#029C3; entity("circ") -> 16#002C6; entity("circeq") -> 16#02257; entity("circlearrowleft") -> 16#021BA; entity("circlearrowright") -> 16#021BB; entity("circledR") -> 16#000AE; entity("circledS") -> 16#024C8; entity("circledast") -> 16#0229B; entity("circledcirc") -> 16#0229A; entity("circleddash") -> 16#0229D; entity("cire") -> 16#02257; entity("cirfnint") -> 16#02A10; entity("cirmid") -> 16#02AEF; entity("cirscir") -> 16#029C2; entity("clubs") -> 16#02663; entity("clubsuit") -> 16#02663; entity("colon") -> 16#0003A; entity("colone") -> 16#02254; entity("coloneq") -> 16#02254; entity("comma") -> 16#0002C; entity("commat") -> 16#00040; entity("comp") -> 16#02201; entity("compfn") -> 16#02218; entity("complement") -> 16#02201; entity("complexes") -> 16#02102; entity("cong") -> 16#02245; entity("congdot") -> 16#02A6D; entity("conint") -> 16#0222E; entity("copf") -> 16#1D554; entity("coprod") -> 16#02210; entity("copy") -> 16#000A9; entity("copysr") -> 16#02117; entity("crarr") -> 16#021B5; entity("cross") -> 16#02717; entity("cscr") -> 16#1D4B8; entity("csub") -> 16#02ACF; entity("csube") -> 16#02AD1; entity("csup") -> 16#02AD0; entity("csupe") -> 16#02AD2; entity("ctdot") -> 16#022EF; entity("cudarrl") -> 16#02938; entity("cudarrr") -> 16#02935; entity("cuepr") -> 16#022DE; entity("cuesc") -> 16#022DF; entity("cularr") -> 16#021B6; entity("cularrp") -> 16#0293D; entity("cup") -> 16#0222A; entity("cupbrcap") -> 16#02A48; entity("cupcap") -> 16#02A46; entity("cupcup") -> 16#02A4A; entity("cupdot") -> 16#0228D; entity("cupor") -> 16#02A45; entity("cups") -> [16#0222A, 16#0FE00]; entity("curarr") -> 16#021B7; entity("curarrm") -> 16#0293C; entity("curlyeqprec") -> 16#022DE; entity("curlyeqsucc") -> 16#022DF; entity("curlyvee") -> 16#022CE; entity("curlywedge") -> 16#022CF; entity("curren") -> 16#000A4; entity("curvearrowleft") -> 16#021B6; entity("curvearrowright") -> 16#021B7; entity("cuvee") -> 16#022CE; entity("cuwed") -> 16#022CF; entity("cwconint") -> 16#02232; entity("cwint") -> 16#02231; entity("cylcty") -> 16#0232D; entity("dArr") -> 16#021D3; entity("dHar") -> 16#02965; entity("dagger") -> 16#02020; entity("daleth") -> 16#02138; entity("darr") -> 16#02193; entity("dash") -> 16#02010; entity("dashv") -> 16#022A3; entity("dbkarow") -> 16#0290F; entity("dblac") -> 16#002DD; entity("dcaron") -> 16#0010F; entity("dcy") -> 16#00434; entity("dd") -> 16#02146; entity("ddagger") -> 16#02021; entity("ddarr") -> 16#021CA; entity("ddotseq") -> 16#02A77; entity("deg") -> 16#000B0; entity("delta") -> 16#003B4; entity("demptyv") -> 16#029B1; entity("dfisht") -> 16#0297F; entity("dfr") -> 16#1D521; entity("dharl") -> 16#021C3; entity("dharr") -> 16#021C2; entity("diam") -> 16#022C4; entity("diamond") -> 16#022C4; entity("diamondsuit") -> 16#02666; entity("diams") -> 16#02666; entity("die") -> 16#000A8; entity("digamma") -> 16#003DD; entity("disin") -> 16#022F2; entity("div") -> 16#000F7; entity("divide") -> 16#000F7; entity("divideontimes") -> 16#022C7; entity("divonx") -> 16#022C7; entity("djcy") -> 16#00452; entity("dlcorn") -> 16#0231E; entity("dlcrop") -> 16#0230D; entity("dollar") -> 16#00024; entity("dopf") -> 16#1D555; entity("dot") -> 16#002D9; entity("doteq") -> 16#02250; entity("doteqdot") -> 16#02251; entity("dotminus") -> 16#02238; entity("dotplus") -> 16#02214; entity("dotsquare") -> 16#022A1; entity("doublebarwedge") -> 16#02306; entity("downarrow") -> 16#02193; entity("downdownarrows") -> 16#021CA; entity("downharpoonleft") -> 16#021C3; entity("downharpoonright") -> 16#021C2; entity("drbkarow") -> 16#02910; entity("drcorn") -> 16#0231F; entity("drcrop") -> 16#0230C; entity("dscr") -> 16#1D4B9; entity("dscy") -> 16#00455; entity("dsol") -> 16#029F6; entity("dstrok") -> 16#00111; entity("dtdot") -> 16#022F1; entity("dtri") -> 16#025BF; entity("dtrif") -> 16#025BE; entity("duarr") -> 16#021F5; entity("duhar") -> 16#0296F; entity("dwangle") -> 16#029A6; entity("dzcy") -> 16#0045F; entity("dzigrarr") -> 16#027FF; entity("eDDot") -> 16#02A77; entity("eDot") -> 16#02251; entity("eacute") -> 16#000E9; entity("easter") -> 16#02A6E; entity("ecaron") -> 16#0011B; entity("ecir") -> 16#02256; entity("ecirc") -> 16#000EA; entity("ecolon") -> 16#02255; entity("ecy") -> 16#0044D; entity("edot") -> 16#00117; entity("ee") -> 16#02147; entity("efDot") -> 16#02252; entity("efr") -> 16#1D522; entity("eg") -> 16#02A9A; entity("egrave") -> 16#000E8; entity("egs") -> 16#02A96; entity("egsdot") -> 16#02A98; entity("el") -> 16#02A99; entity("elinters") -> 16#023E7; entity("ell") -> 16#02113; entity("els") -> 16#02A95; entity("elsdot") -> 16#02A97; entity("emacr") -> 16#00113; entity("empty") -> 16#02205; entity("emptyset") -> 16#02205; entity("emptyv") -> 16#02205; entity("emsp") -> 16#02003; entity("emsp13") -> 16#02004; entity("emsp14") -> 16#02005; entity("eng") -> 16#0014B; entity("ensp") -> 16#02002; entity("eogon") -> 16#00119; entity("eopf") -> 16#1D556; entity("epar") -> 16#022D5; entity("eparsl") -> 16#029E3; entity("eplus") -> 16#02A71; entity("epsi") -> 16#003B5; entity("epsilon") -> 16#003B5; entity("epsiv") -> 16#003F5; entity("eqcirc") -> 16#02256; entity("eqcolon") -> 16#02255; entity("eqsim") -> 16#02242; entity("eqslantgtr") -> 16#02A96; entity("eqslantless") -> 16#02A95; entity("equals") -> 16#0003D; entity("equest") -> 16#0225F; entity("equiv") -> 16#02261; entity("equivDD") -> 16#02A78; entity("eqvparsl") -> 16#029E5; entity("erDot") -> 16#02253; entity("erarr") -> 16#02971; entity("escr") -> 16#0212F; entity("esdot") -> 16#02250; entity("esim") -> 16#02242; entity("eta") -> 16#003B7; entity("eth") -> 16#000F0; entity("euml") -> 16#000EB; entity("euro") -> 16#020AC; entity("excl") -> 16#00021; entity("exist") -> 16#02203; entity("expectation") -> 16#02130; entity("exponentiale") -> 16#02147; entity("fallingdotseq") -> 16#02252; entity("fcy") -> 16#00444; entity("female") -> 16#02640; entity("ffilig") -> 16#0FB03; entity("fflig") -> 16#0FB00; entity("ffllig") -> 16#0FB04; entity("ffr") -> 16#1D523; entity("filig") -> 16#0FB01; entity("fjlig") -> [16#00066, 16#0006A]; entity("flat") -> 16#0266D; entity("fllig") -> 16#0FB02; entity("fltns") -> 16#025B1; entity("fnof") -> 16#00192; entity("fopf") -> 16#1D557; entity("forall") -> 16#02200; entity("fork") -> 16#022D4; entity("forkv") -> 16#02AD9; entity("fpartint") -> 16#02A0D; entity("frac12") -> 16#000BD; entity("frac13") -> 16#02153; entity("frac14") -> 16#000BC; entity("frac15") -> 16#02155; entity("frac16") -> 16#02159; entity("frac18") -> 16#0215B; entity("frac23") -> 16#02154; entity("frac25") -> 16#02156; entity("frac34") -> 16#000BE; entity("frac35") -> 16#02157; entity("frac38") -> 16#0215C; entity("frac45") -> 16#02158; entity("frac56") -> 16#0215A; entity("frac58") -> 16#0215D; entity("frac78") -> 16#0215E; entity("frasl") -> 16#02044; entity("frown") -> 16#02322; entity("fscr") -> 16#1D4BB; entity("gE") -> 16#02267; entity("gEl") -> 16#02A8C; entity("gacute") -> 16#001F5; entity("gamma") -> 16#003B3; entity("gammad") -> 16#003DD; entity("gap") -> 16#02A86; entity("gbreve") -> 16#0011F; entity("gcirc") -> 16#0011D; entity("gcy") -> 16#00433; entity("gdot") -> 16#00121; entity("ge") -> 16#02265; entity("gel") -> 16#022DB; entity("geq") -> 16#02265; entity("geqq") -> 16#02267; entity("geqslant") -> 16#02A7E; entity("ges") -> 16#02A7E; entity("gescc") -> 16#02AA9; entity("gesdot") -> 16#02A80; entity("gesdoto") -> 16#02A82; entity("gesdotol") -> 16#02A84; entity("gesl") -> [16#022DB, 16#0FE00]; entity("gesles") -> 16#02A94; entity("gfr") -> 16#1D524; entity("gg") -> 16#0226B; entity("ggg") -> 16#022D9; entity("gimel") -> 16#02137; entity("gjcy") -> 16#00453; entity("gl") -> 16#02277; entity("glE") -> 16#02A92; entity("gla") -> 16#02AA5; entity("glj") -> 16#02AA4; entity("gnE") -> 16#02269; entity("gnap") -> 16#02A8A; entity("gnapprox") -> 16#02A8A; entity("gne") -> 16#02A88; entity("gneq") -> 16#02A88; entity("gneqq") -> 16#02269; entity("gnsim") -> 16#022E7; entity("gopf") -> 16#1D558; entity("grave") -> 16#00060; entity("gscr") -> 16#0210A; entity("gsim") -> 16#02273; entity("gsime") -> 16#02A8E; entity("gsiml") -> 16#02A90; entity("gt") -> 16#0003E; entity("gtcc") -> 16#02AA7; entity("gtcir") -> 16#02A7A; entity("gtdot") -> 16#022D7; entity("gtlPar") -> 16#02995; entity("gtquest") -> 16#02A7C; entity("gtrapprox") -> 16#02A86; entity("gtrarr") -> 16#02978; entity("gtrdot") -> 16#022D7; entity("gtreqless") -> 16#022DB; entity("gtreqqless") -> 16#02A8C; entity("gtrless") -> 16#02277; entity("gtrsim") -> 16#02273; entity("gvertneqq") -> [16#02269, 16#0FE00]; entity("gvnE") -> [16#02269, 16#0FE00]; entity("hArr") -> 16#021D4; entity("hairsp") -> 16#0200A; entity("half") -> 16#000BD; entity("hamilt") -> 16#0210B; entity("hardcy") -> 16#0044A; entity("harr") -> 16#02194; entity("harrcir") -> 16#02948; entity("harrw") -> 16#021AD; entity("hbar") -> 16#0210F; entity("hcirc") -> 16#00125; entity("hearts") -> 16#02665; entity("heartsuit") -> 16#02665; entity("hellip") -> 16#02026; entity("hercon") -> 16#022B9; entity("hfr") -> 16#1D525; entity("hksearow") -> 16#02925; entity("hkswarow") -> 16#02926; entity("hoarr") -> 16#021FF; entity("homtht") -> 16#0223B; entity("hookleftarrow") -> 16#021A9; entity("hookrightarrow") -> 16#021AA; entity("hopf") -> 16#1D559; entity("horbar") -> 16#02015; entity("hscr") -> 16#1D4BD; entity("hslash") -> 16#0210F; entity("hstrok") -> 16#00127; entity("hybull") -> 16#02043; entity("hyphen") -> 16#02010; entity("iacute") -> 16#000ED; entity("ic") -> 16#02063; entity("icirc") -> 16#000EE; entity("icy") -> 16#00438; entity("iecy") -> 16#00435; entity("iexcl") -> 16#000A1; entity("iff") -> 16#021D4; entity("ifr") -> 16#1D526; entity("igrave") -> 16#000EC; entity("ii") -> 16#02148; entity("iiiint") -> 16#02A0C; entity("iiint") -> 16#0222D; entity("iinfin") -> 16#029DC; entity("iiota") -> 16#02129; entity("ijlig") -> 16#00133; entity("imacr") -> 16#0012B; entity("image") -> 16#02111; entity("imagline") -> 16#02110; entity("imagpart") -> 16#02111; entity("imath") -> 16#00131; entity("imof") -> 16#022B7; entity("imped") -> 16#001B5; entity("in") -> 16#02208; entity("incare") -> 16#02105; entity("infin") -> 16#0221E; entity("infintie") -> 16#029DD; entity("inodot") -> 16#00131; entity("int") -> 16#0222B; entity("intcal") -> 16#022BA; entity("integers") -> 16#02124; entity("intercal") -> 16#022BA; entity("intlarhk") -> 16#02A17; entity("intprod") -> 16#02A3C; entity("iocy") -> 16#00451; entity("iogon") -> 16#0012F; entity("iopf") -> 16#1D55A; entity("iota") -> 16#003B9; entity("iprod") -> 16#02A3C; entity("iquest") -> 16#000BF; entity("iscr") -> 16#1D4BE; entity("isin") -> 16#02208; entity("isinE") -> 16#022F9; entity("isindot") -> 16#022F5; entity("isins") -> 16#022F4; entity("isinsv") -> 16#022F3; entity("isinv") -> 16#02208; entity("it") -> 16#02062; entity("itilde") -> 16#00129; entity("iukcy") -> 16#00456; entity("iuml") -> 16#000EF; entity("jcirc") -> 16#00135; entity("jcy") -> 16#00439; entity("jfr") -> 16#1D527; entity("jmath") -> 16#00237; entity("jopf") -> 16#1D55B; entity("jscr") -> 16#1D4BF; entity("jsercy") -> 16#00458; entity("jukcy") -> 16#00454; entity("kappa") -> 16#003BA; entity("kappav") -> 16#003F0; entity("kcedil") -> 16#00137; entity("kcy") -> 16#0043A; entity("kfr") -> 16#1D528; entity("kgreen") -> 16#00138; entity("khcy") -> 16#00445; entity("kjcy") -> 16#0045C; entity("kopf") -> 16#1D55C; entity("kscr") -> 16#1D4C0; entity("lAarr") -> 16#021DA; entity("lArr") -> 16#021D0; entity("lAtail") -> 16#0291B; entity("lBarr") -> 16#0290E; entity("lE") -> 16#02266; entity("lEg") -> 16#02A8B; entity("lHar") -> 16#02962; entity("lacute") -> 16#0013A; entity("laemptyv") -> 16#029B4; entity("lagran") -> 16#02112; entity("lambda") -> 16#003BB; entity("lang") -> 16#027E8; entity("langd") -> 16#02991; entity("langle") -> 16#027E8; entity("lap") -> 16#02A85; entity("laquo") -> 16#000AB; entity("larr") -> 16#02190; entity("larrb") -> 16#021E4; entity("larrbfs") -> 16#0291F; entity("larrfs") -> 16#0291D; entity("larrhk") -> 16#021A9; entity("larrlp") -> 16#021AB; entity("larrpl") -> 16#02939; entity("larrsim") -> 16#02973; entity("larrtl") -> 16#021A2; entity("lat") -> 16#02AAB; entity("latail") -> 16#02919; entity("late") -> 16#02AAD; entity("lates") -> [16#02AAD, 16#0FE00]; entity("lbarr") -> 16#0290C; entity("lbbrk") -> 16#02772; entity("lbrace") -> 16#0007B; entity("lbrack") -> 16#0005B; entity("lbrke") -> 16#0298B; entity("lbrksld") -> 16#0298F; entity("lbrkslu") -> 16#0298D; entity("lcaron") -> 16#0013E; entity("lcedil") -> 16#0013C; entity("lceil") -> 16#02308; entity("lcub") -> 16#0007B; entity("lcy") -> 16#0043B; entity("ldca") -> 16#02936; entity("ldquo") -> 16#0201C; entity("ldquor") -> 16#0201E; entity("ldrdhar") -> 16#02967; entity("ldrushar") -> 16#0294B; entity("ldsh") -> 16#021B2; entity("le") -> 16#02264; entity("leftarrow") -> 16#02190; entity("leftarrowtail") -> 16#021A2; entity("leftharpoondown") -> 16#021BD; entity("leftharpoonup") -> 16#021BC; entity("leftleftarrows") -> 16#021C7; entity("leftrightarrow") -> 16#02194; entity("leftrightarrows") -> 16#021C6; entity("leftrightharpoons") -> 16#021CB; entity("leftrightsquigarrow") -> 16#021AD; entity("leftthreetimes") -> 16#022CB; entity("leg") -> 16#022DA; entity("leq") -> 16#02264; entity("leqq") -> 16#02266; entity("leqslant") -> 16#02A7D; entity("les") -> 16#02A7D; entity("lescc") -> 16#02AA8; entity("lesdot") -> 16#02A7F; entity("lesdoto") -> 16#02A81; entity("lesdotor") -> 16#02A83; entity("lesg") -> [16#022DA, 16#0FE00]; entity("lesges") -> 16#02A93; entity("lessapprox") -> 16#02A85; entity("lessdot") -> 16#022D6; entity("lesseqgtr") -> 16#022DA; entity("lesseqqgtr") -> 16#02A8B; entity("lessgtr") -> 16#02276; entity("lesssim") -> 16#02272; entity("lfisht") -> 16#0297C; entity("lfloor") -> 16#0230A; entity("lfr") -> 16#1D529; entity("lg") -> 16#02276; entity("lgE") -> 16#02A91; entity("lhard") -> 16#021BD; entity("lharu") -> 16#021BC; entity("lharul") -> 16#0296A; entity("lhblk") -> 16#02584; entity("ljcy") -> 16#00459; entity("ll") -> 16#0226A; entity("llarr") -> 16#021C7; entity("llcorner") -> 16#0231E; entity("llhard") -> 16#0296B; entity("lltri") -> 16#025FA; entity("lmidot") -> 16#00140; entity("lmoust") -> 16#023B0; entity("lmoustache") -> 16#023B0; entity("lnE") -> 16#02268; entity("lnap") -> 16#02A89; entity("lnapprox") -> 16#02A89; entity("lne") -> 16#02A87; entity("lneq") -> 16#02A87; entity("lneqq") -> 16#02268; entity("lnsim") -> 16#022E6; entity("loang") -> 16#027EC; entity("loarr") -> 16#021FD; entity("lobrk") -> 16#027E6; entity("longleftarrow") -> 16#027F5; entity("longleftrightarrow") -> 16#027F7; entity("longmapsto") -> 16#027FC; entity("longrightarrow") -> 16#027F6; entity("looparrowleft") -> 16#021AB; entity("looparrowright") -> 16#021AC; entity("lopar") -> 16#02985; entity("lopf") -> 16#1D55D; entity("loplus") -> 16#02A2D; entity("lotimes") -> 16#02A34; entity("lowast") -> 16#02217; entity("lowbar") -> 16#0005F; entity("loz") -> 16#025CA; entity("lozenge") -> 16#025CA; entity("lozf") -> 16#029EB; entity("lpar") -> 16#00028; entity("lparlt") -> 16#02993; entity("lrarr") -> 16#021C6; entity("lrcorner") -> 16#0231F; entity("lrhar") -> 16#021CB; entity("lrhard") -> 16#0296D; entity("lrm") -> 16#0200E; entity("lrtri") -> 16#022BF; entity("lsaquo") -> 16#02039; entity("lscr") -> 16#1D4C1; entity("lsh") -> 16#021B0; entity("lsim") -> 16#02272; entity("lsime") -> 16#02A8D; entity("lsimg") -> 16#02A8F; entity("lsqb") -> 16#0005B; entity("lsquo") -> 16#02018; entity("lsquor") -> 16#0201A; entity("lstrok") -> 16#00142; entity("lt") -> 16#0003C; entity("ltcc") -> 16#02AA6; entity("ltcir") -> 16#02A79; entity("ltdot") -> 16#022D6; entity("lthree") -> 16#022CB; entity("ltimes") -> 16#022C9; entity("ltlarr") -> 16#02976; entity("ltquest") -> 16#02A7B; entity("ltrPar") -> 16#02996; entity("ltri") -> 16#025C3; entity("ltrie") -> 16#022B4; entity("ltrif") -> 16#025C2; entity("lurdshar") -> 16#0294A; entity("luruhar") -> 16#02966; entity("lvertneqq") -> [16#02268, 16#0FE00]; entity("lvnE") -> [16#02268, 16#0FE00]; entity("mDDot") -> 16#0223A; entity("macr") -> 16#000AF; entity("male") -> 16#02642; entity("malt") -> 16#02720; entity("maltese") -> 16#02720; entity("map") -> 16#021A6; entity("mapsto") -> 16#021A6; entity("mapstodown") -> 16#021A7; entity("mapstoleft") -> 16#021A4; entity("mapstoup") -> 16#021A5; entity("marker") -> 16#025AE; entity("mcomma") -> 16#02A29; entity("mcy") -> 16#0043C; entity("mdash") -> 16#02014; entity("measuredangle") -> 16#02221; entity("mfr") -> 16#1D52A; entity("mho") -> 16#02127; entity("micro") -> 16#000B5; entity("mid") -> 16#02223; entity("midast") -> 16#0002A; entity("midcir") -> 16#02AF0; entity("middot") -> 16#000B7; entity("minus") -> 16#02212; entity("minusb") -> 16#0229F; entity("minusd") -> 16#02238; entity("minusdu") -> 16#02A2A; entity("mlcp") -> 16#02ADB; entity("mldr") -> 16#02026; entity("mnplus") -> 16#02213; entity("models") -> 16#022A7; entity("mopf") -> 16#1D55E; entity("mp") -> 16#02213; entity("mscr") -> 16#1D4C2; entity("mstpos") -> 16#0223E; entity("mu") -> 16#003BC; entity("multimap") -> 16#022B8; entity("mumap") -> 16#022B8; entity("nGg") -> [16#022D9, 16#00338]; entity("nGt") -> [16#0226B, 16#020D2]; entity("nGtv") -> [16#0226B, 16#00338]; entity("nLeftarrow") -> 16#021CD; entity("nLeftrightarrow") -> 16#021CE; entity("nLl") -> [16#022D8, 16#00338]; entity("nLt") -> [16#0226A, 16#020D2]; entity("nLtv") -> [16#0226A, 16#00338]; entity("nRightarrow") -> 16#021CF; entity("nVDash") -> 16#022AF; entity("nVdash") -> 16#022AE; entity("nabla") -> 16#02207; entity("nacute") -> 16#00144; entity("nang") -> [16#02220, 16#020D2]; entity("nap") -> 16#02249; entity("napE") -> [16#02A70, 16#00338]; entity("napid") -> [16#0224B, 16#00338]; entity("napos") -> 16#00149; entity("napprox") -> 16#02249; entity("natur") -> 16#0266E; entity("natural") -> 16#0266E; entity("naturals") -> 16#02115; entity("nbsp") -> 16#000A0; entity("nbump") -> [16#0224E, 16#00338]; entity("nbumpe") -> [16#0224F, 16#00338]; entity("ncap") -> 16#02A43; entity("ncaron") -> 16#00148; entity("ncedil") -> 16#00146; entity("ncong") -> 16#02247; entity("ncongdot") -> [16#02A6D, 16#00338]; entity("ncup") -> 16#02A42; entity("ncy") -> 16#0043D; entity("ndash") -> 16#02013; entity("ne") -> 16#02260; entity("neArr") -> 16#021D7; entity("nearhk") -> 16#02924; entity("nearr") -> 16#02197; entity("nearrow") -> 16#02197; entity("nedot") -> [16#02250, 16#00338]; entity("nequiv") -> 16#02262; entity("nesear") -> 16#02928; entity("nesim") -> [16#02242, 16#00338]; entity("nexist") -> 16#02204; entity("nexists") -> 16#02204; entity("nfr") -> 16#1D52B; entity("ngE") -> [16#02267, 16#00338]; entity("nge") -> 16#02271; entity("ngeq") -> 16#02271; entity("ngeqq") -> [16#02267, 16#00338]; entity("ngeqslant") -> [16#02A7E, 16#00338]; entity("nges") -> [16#02A7E, 16#00338]; entity("ngsim") -> 16#02275; entity("ngt") -> 16#0226F; entity("ngtr") -> 16#0226F; entity("nhArr") -> 16#021CE; entity("nharr") -> 16#021AE; entity("nhpar") -> 16#02AF2; entity("ni") -> 16#0220B; entity("nis") -> 16#022FC; entity("nisd") -> 16#022FA; entity("niv") -> 16#0220B; entity("njcy") -> 16#0045A; entity("nlArr") -> 16#021CD; entity("nlE") -> [16#02266, 16#00338]; entity("nlarr") -> 16#0219A; entity("nldr") -> 16#02025; entity("nle") -> 16#02270; entity("nleftarrow") -> 16#0219A; entity("nleftrightarrow") -> 16#021AE; entity("nleq") -> 16#02270; entity("nleqq") -> [16#02266, 16#00338]; entity("nleqslant") -> [16#02A7D, 16#00338]; entity("nles") -> [16#02A7D, 16#00338]; entity("nless") -> 16#0226E; entity("nlsim") -> 16#02274; entity("nlt") -> 16#0226E; entity("nltri") -> 16#022EA; entity("nltrie") -> 16#022EC; entity("nmid") -> 16#02224; entity("nopf") -> 16#1D55F; entity("not") -> 16#000AC; entity("notin") -> 16#02209; entity("notinE") -> [16#022F9, 16#00338]; entity("notindot") -> [16#022F5, 16#00338]; entity("notinva") -> 16#02209; entity("notinvb") -> 16#022F7; entity("notinvc") -> 16#022F6; entity("notni") -> 16#0220C; entity("notniva") -> 16#0220C; entity("notnivb") -> 16#022FE; entity("notnivc") -> 16#022FD; entity("npar") -> 16#02226; entity("nparallel") -> 16#02226; entity("nparsl") -> [16#02AFD, 16#020E5]; entity("npart") -> [16#02202, 16#00338]; entity("npolint") -> 16#02A14; entity("npr") -> 16#02280; entity("nprcue") -> 16#022E0; entity("npre") -> [16#02AAF, 16#00338]; entity("nprec") -> 16#02280; entity("npreceq") -> [16#02AAF, 16#00338]; entity("nrArr") -> 16#021CF; entity("nrarr") -> 16#0219B; entity("nrarrc") -> [16#02933, 16#00338]; entity("nrarrw") -> [16#0219D, 16#00338]; entity("nrightarrow") -> 16#0219B; entity("nrtri") -> 16#022EB; entity("nrtrie") -> 16#022ED; entity("nsc") -> 16#02281; entity("nsccue") -> 16#022E1; entity("nsce") -> [16#02AB0, 16#00338]; entity("nscr") -> 16#1D4C3; entity("nshortmid") -> 16#02224; entity("nshortparallel") -> 16#02226; entity("nsim") -> 16#02241; entity("nsime") -> 16#02244; entity("nsimeq") -> 16#02244; entity("nsmid") -> 16#02224; entity("nspar") -> 16#02226; entity("nsqsube") -> 16#022E2; entity("nsqsupe") -> 16#022E3; entity("nsub") -> 16#02284; entity("nsubE") -> [16#02AC5, 16#00338]; entity("nsube") -> 16#02288; entity("nsubset") -> [16#02282, 16#020D2]; entity("nsubseteq") -> 16#02288; entity("nsubseteqq") -> [16#02AC5, 16#00338]; entity("nsucc") -> 16#02281; entity("nsucceq") -> [16#02AB0, 16#00338]; entity("nsup") -> 16#02285; entity("nsupE") -> [16#02AC6, 16#00338]; entity("nsupe") -> 16#02289; entity("nsupset") -> [16#02283, 16#020D2]; entity("nsupseteq") -> 16#02289; entity("nsupseteqq") -> [16#02AC6, 16#00338]; entity("ntgl") -> 16#02279; entity("ntilde") -> 16#000F1; entity("ntlg") -> 16#02278; entity("ntriangleleft") -> 16#022EA; entity("ntrianglelefteq") -> 16#022EC; entity("ntriangleright") -> 16#022EB; entity("ntrianglerighteq") -> 16#022ED; entity("nu") -> 16#003BD; entity("num") -> 16#00023; entity("numero") -> 16#02116; entity("numsp") -> 16#02007; entity("nvDash") -> 16#022AD; entity("nvHarr") -> 16#02904; entity("nvap") -> [16#0224D, 16#020D2]; entity("nvdash") -> 16#022AC; entity("nvge") -> [16#02265, 16#020D2]; entity("nvgt") -> [16#0003E, 16#020D2]; entity("nvinfin") -> 16#029DE; entity("nvlArr") -> 16#02902; entity("nvle") -> [16#02264, 16#020D2]; entity("nvlt") -> [16#0003C, 16#020D2]; entity("nvltrie") -> [16#022B4, 16#020D2]; entity("nvrArr") -> 16#02903; entity("nvrtrie") -> [16#022B5, 16#020D2]; entity("nvsim") -> [16#0223C, 16#020D2]; entity("nwArr") -> 16#021D6; entity("nwarhk") -> 16#02923; entity("nwarr") -> 16#02196; entity("nwarrow") -> 16#02196; entity("nwnear") -> 16#02927; entity("oS") -> 16#024C8; entity("oacute") -> 16#000F3; entity("oast") -> 16#0229B; entity("ocir") -> 16#0229A; entity("ocirc") -> 16#000F4; entity("ocy") -> 16#0043E; entity("odash") -> 16#0229D; entity("odblac") -> 16#00151; entity("odiv") -> 16#02A38; entity("odot") -> 16#02299; entity("odsold") -> 16#029BC; entity("oelig") -> 16#00153; entity("ofcir") -> 16#029BF; entity("ofr") -> 16#1D52C; entity("ogon") -> 16#002DB; entity("ograve") -> 16#000F2; entity("ogt") -> 16#029C1; entity("ohbar") -> 16#029B5; entity("ohm") -> 16#003A9; entity("oint") -> 16#0222E; entity("olarr") -> 16#021BA; entity("olcir") -> 16#029BE; entity("olcross") -> 16#029BB; entity("oline") -> 16#0203E; entity("olt") -> 16#029C0; entity("omacr") -> 16#0014D; entity("omega") -> 16#003C9; entity("omicron") -> 16#003BF; entity("omid") -> 16#029B6; entity("ominus") -> 16#02296; entity("oopf") -> 16#1D560; entity("opar") -> 16#029B7; entity("operp") -> 16#029B9; entity("oplus") -> 16#02295; entity("or") -> 16#02228; entity("orarr") -> 16#021BB; entity("ord") -> 16#02A5D; entity("order") -> 16#02134; entity("orderof") -> 16#02134; entity("ordf") -> 16#000AA; entity("ordm") -> 16#000BA; entity("origof") -> 16#022B6; entity("oror") -> 16#02A56; entity("orslope") -> 16#02A57; entity("orv") -> 16#02A5B; entity("oscr") -> 16#02134; entity("oslash") -> 16#000F8; entity("osol") -> 16#02298; entity("otilde") -> 16#000F5; entity("otimes") -> 16#02297; entity("otimesas") -> 16#02A36; entity("ouml") -> 16#000F6; entity("ovbar") -> 16#0233D; entity("par") -> 16#02225; entity("para") -> 16#000B6; entity("parallel") -> 16#02225; entity("parsim") -> 16#02AF3; entity("parsl") -> 16#02AFD; entity("part") -> 16#02202; entity("pcy") -> 16#0043F; entity("percnt") -> 16#00025; entity("period") -> 16#0002E; entity("permil") -> 16#02030; entity("perp") -> 16#022A5; entity("pertenk") -> 16#02031; entity("pfr") -> 16#1D52D; entity("phi") -> 16#003C6; entity("phiv") -> 16#003D5; entity("phmmat") -> 16#02133; entity("phone") -> 16#0260E; entity("pi") -> 16#003C0; entity("pitchfork") -> 16#022D4; entity("piv") -> 16#003D6; entity("planck") -> 16#0210F; entity("planckh") -> 16#0210E; entity("plankv") -> 16#0210F; entity("plus") -> 16#0002B; entity("plusacir") -> 16#02A23; entity("plusb") -> 16#0229E; entity("pluscir") -> 16#02A22; entity("plusdo") -> 16#02214; entity("plusdu") -> 16#02A25; entity("pluse") -> 16#02A72; entity("plusmn") -> 16#000B1; entity("plussim") -> 16#02A26; entity("plustwo") -> 16#02A27; entity("pm") -> 16#000B1; entity("pointint") -> 16#02A15; entity("popf") -> 16#1D561; entity("pound") -> 16#000A3; entity("pr") -> 16#0227A; entity("prE") -> 16#02AB3; entity("prap") -> 16#02AB7; entity("prcue") -> 16#0227C; entity("pre") -> 16#02AAF; entity("prec") -> 16#0227A; entity("precapprox") -> 16#02AB7; entity("preccurlyeq") -> 16#0227C; entity("preceq") -> 16#02AAF; entity("precnapprox") -> 16#02AB9; entity("precneqq") -> 16#02AB5; entity("precnsim") -> 16#022E8; entity("precsim") -> 16#0227E; entity("prime") -> 16#02032; entity("primes") -> 16#02119; entity("prnE") -> 16#02AB5; entity("prnap") -> 16#02AB9; entity("prnsim") -> 16#022E8; entity("prod") -> 16#0220F; entity("profalar") -> 16#0232E; entity("profline") -> 16#02312; entity("profsurf") -> 16#02313; entity("prop") -> 16#0221D; entity("propto") -> 16#0221D; entity("prsim") -> 16#0227E; entity("prurel") -> 16#022B0; entity("pscr") -> 16#1D4C5; entity("psi") -> 16#003C8; entity("puncsp") -> 16#02008; entity("qfr") -> 16#1D52E; entity("qint") -> 16#02A0C; entity("qopf") -> 16#1D562; entity("qprime") -> 16#02057; entity("qscr") -> 16#1D4C6; entity("quaternions") -> 16#0210D; entity("quatint") -> 16#02A16; entity("quest") -> 16#0003F; entity("questeq") -> 16#0225F; entity("quot") -> 16#00022; entity("rAarr") -> 16#021DB; entity("rArr") -> 16#021D2; entity("rAtail") -> 16#0291C; entity("rBarr") -> 16#0290F; entity("rHar") -> 16#02964; entity("race") -> [16#0223D, 16#00331]; entity("racute") -> 16#00155; entity("radic") -> 16#0221A; entity("raemptyv") -> 16#029B3; entity("rang") -> 16#027E9; entity("rangd") -> 16#02992; entity("range") -> 16#029A5; entity("rangle") -> 16#027E9; entity("raquo") -> 16#000BB; entity("rarr") -> 16#02192; entity("rarrap") -> 16#02975; entity("rarrb") -> 16#021E5; entity("rarrbfs") -> 16#02920; entity("rarrc") -> 16#02933; entity("rarrfs") -> 16#0291E; entity("rarrhk") -> 16#021AA; entity("rarrlp") -> 16#021AC; entity("rarrpl") -> 16#02945; entity("rarrsim") -> 16#02974; entity("rarrtl") -> 16#021A3; entity("rarrw") -> 16#0219D; entity("ratail") -> 16#0291A; entity("ratio") -> 16#02236; entity("rationals") -> 16#0211A; entity("rbarr") -> 16#0290D; entity("rbbrk") -> 16#02773; entity("rbrace") -> 16#0007D; entity("rbrack") -> 16#0005D; entity("rbrke") -> 16#0298C; entity("rbrksld") -> 16#0298E; entity("rbrkslu") -> 16#02990; entity("rcaron") -> 16#00159; entity("rcedil") -> 16#00157; entity("rceil") -> 16#02309; entity("rcub") -> 16#0007D; entity("rcy") -> 16#00440; entity("rdca") -> 16#02937; entity("rdldhar") -> 16#02969; entity("rdquo") -> 16#0201D; entity("rdquor") -> 16#0201D; entity("rdsh") -> 16#021B3; entity("real") -> 16#0211C; entity("realine") -> 16#0211B; entity("realpart") -> 16#0211C; entity("reals") -> 16#0211D; entity("rect") -> 16#025AD; entity("reg") -> 16#000AE; entity("rfisht") -> 16#0297D; entity("rfloor") -> 16#0230B; entity("rfr") -> 16#1D52F; entity("rhard") -> 16#021C1; entity("rharu") -> 16#021C0; entity("rharul") -> 16#0296C; entity("rho") -> 16#003C1; entity("rhov") -> 16#003F1; entity("rightarrow") -> 16#02192; entity("rightarrowtail") -> 16#021A3; entity("rightharpoondown") -> 16#021C1; entity("rightharpoonup") -> 16#021C0; entity("rightleftarrows") -> 16#021C4; entity("rightleftharpoons") -> 16#021CC; entity("rightrightarrows") -> 16#021C9; entity("rightsquigarrow") -> 16#0219D; entity("rightthreetimes") -> 16#022CC; entity("ring") -> 16#002DA; entity("risingdotseq") -> 16#02253; entity("rlarr") -> 16#021C4; entity("rlhar") -> 16#021CC; entity("rlm") -> 16#0200F; entity("rmoust") -> 16#023B1; entity("rmoustache") -> 16#023B1; entity("rnmid") -> 16#02AEE; entity("roang") -> 16#027ED; entity("roarr") -> 16#021FE; entity("robrk") -> 16#027E7; entity("ropar") -> 16#02986; entity("ropf") -> 16#1D563; entity("roplus") -> 16#02A2E; entity("rotimes") -> 16#02A35; entity("rpar") -> 16#00029; entity("rpargt") -> 16#02994; entity("rppolint") -> 16#02A12; entity("rrarr") -> 16#021C9; entity("rsaquo") -> 16#0203A; entity("rscr") -> 16#1D4C7; entity("rsh") -> 16#021B1; entity("rsqb") -> 16#0005D; entity("rsquo") -> 16#02019; entity("rsquor") -> 16#02019; entity("rthree") -> 16#022CC; entity("rtimes") -> 16#022CA; entity("rtri") -> 16#025B9; entity("rtrie") -> 16#022B5; entity("rtrif") -> 16#025B8; entity("rtriltri") -> 16#029CE; entity("ruluhar") -> 16#02968; entity("rx") -> 16#0211E; entity("sacute") -> 16#0015B; entity("sbquo") -> 16#0201A; entity("sc") -> 16#0227B; entity("scE") -> 16#02AB4; entity("scap") -> 16#02AB8; entity("scaron") -> 16#00161; entity("sccue") -> 16#0227D; entity("sce") -> 16#02AB0; entity("scedil") -> 16#0015F; entity("scirc") -> 16#0015D; entity("scnE") -> 16#02AB6; entity("scnap") -> 16#02ABA; entity("scnsim") -> 16#022E9; entity("scpolint") -> 16#02A13; entity("scsim") -> 16#0227F; entity("scy") -> 16#00441; entity("sdot") -> 16#022C5; entity("sdotb") -> 16#022A1; entity("sdote") -> 16#02A66; entity("seArr") -> 16#021D8; entity("searhk") -> 16#02925; entity("searr") -> 16#02198; entity("searrow") -> 16#02198; entity("sect") -> 16#000A7; entity("semi") -> 16#0003B; entity("seswar") -> 16#02929; entity("setminus") -> 16#02216; entity("setmn") -> 16#02216; entity("sext") -> 16#02736; entity("sfr") -> 16#1D530; entity("sfrown") -> 16#02322; entity("sharp") -> 16#0266F; entity("shchcy") -> 16#00449; entity("shcy") -> 16#00448; entity("shortmid") -> 16#02223; entity("shortparallel") -> 16#02225; entity("shy") -> 16#000AD; entity("sigma") -> 16#003C3; entity("sigmaf") -> 16#003C2; entity("sigmav") -> 16#003C2; entity("sim") -> 16#0223C; entity("simdot") -> 16#02A6A; entity("sime") -> 16#02243; entity("simeq") -> 16#02243; entity("simg") -> 16#02A9E; entity("simgE") -> 16#02AA0; entity("siml") -> 16#02A9D; entity("simlE") -> 16#02A9F; entity("simne") -> 16#02246; entity("simplus") -> 16#02A24; entity("simrarr") -> 16#02972; entity("slarr") -> 16#02190; entity("smallsetminus") -> 16#02216; entity("smashp") -> 16#02A33; entity("smeparsl") -> 16#029E4; entity("smid") -> 16#02223; entity("smile") -> 16#02323; entity("smt") -> 16#02AAA; entity("smte") -> 16#02AAC; entity("smtes") -> [16#02AAC, 16#0FE00]; entity("softcy") -> 16#0044C; entity("sol") -> 16#0002F; entity("solb") -> 16#029C4; entity("solbar") -> 16#0233F; entity("sopf") -> 16#1D564; entity("spades") -> 16#02660; entity("spadesuit") -> 16#02660; entity("spar") -> 16#02225; entity("sqcap") -> 16#02293; entity("sqcaps") -> [16#02293, 16#0FE00]; entity("sqcup") -> 16#02294; entity("sqcups") -> [16#02294, 16#0FE00]; entity("sqsub") -> 16#0228F; entity("sqsube") -> 16#02291; entity("sqsubset") -> 16#0228F; entity("sqsubseteq") -> 16#02291; entity("sqsup") -> 16#02290; entity("sqsupe") -> 16#02292; entity("sqsupset") -> 16#02290; entity("sqsupseteq") -> 16#02292; entity("squ") -> 16#025A1; entity("square") -> 16#025A1; entity("squarf") -> 16#025AA; entity("squf") -> 16#025AA; entity("srarr") -> 16#02192; entity("sscr") -> 16#1D4C8; entity("ssetmn") -> 16#02216; entity("ssmile") -> 16#02323; entity("sstarf") -> 16#022C6; entity("star") -> 16#02606; entity("starf") -> 16#02605; entity("straightepsilon") -> 16#003F5; entity("straightphi") -> 16#003D5; entity("strns") -> 16#000AF; entity("sub") -> 16#02282; entity("subE") -> 16#02AC5; entity("subdot") -> 16#02ABD; entity("sube") -> 16#02286; entity("subedot") -> 16#02AC3; entity("submult") -> 16#02AC1; entity("subnE") -> 16#02ACB; entity("subne") -> 16#0228A; entity("subplus") -> 16#02ABF; entity("subrarr") -> 16#02979; entity("subset") -> 16#02282; entity("subseteq") -> 16#02286; entity("subseteqq") -> 16#02AC5; entity("subsetneq") -> 16#0228A; entity("subsetneqq") -> 16#02ACB; entity("subsim") -> 16#02AC7; entity("subsub") -> 16#02AD5; entity("subsup") -> 16#02AD3; entity("succ") -> 16#0227B; entity("succapprox") -> 16#02AB8; entity("succcurlyeq") -> 16#0227D; entity("succeq") -> 16#02AB0; entity("succnapprox") -> 16#02ABA; entity("succneqq") -> 16#02AB6; entity("succnsim") -> 16#022E9; entity("succsim") -> 16#0227F; entity("sum") -> 16#02211; entity("sung") -> 16#0266A; entity("sup") -> 16#02283; entity("sup1") -> 16#000B9; entity("sup2") -> 16#000B2; entity("sup3") -> 16#000B3; entity("supE") -> 16#02AC6; entity("supdot") -> 16#02ABE; entity("supdsub") -> 16#02AD8; entity("supe") -> 16#02287; entity("supedot") -> 16#02AC4; entity("suphsol") -> 16#027C9; entity("suphsub") -> 16#02AD7; entity("suplarr") -> 16#0297B; entity("supmult") -> 16#02AC2; entity("supnE") -> 16#02ACC; entity("supne") -> 16#0228B; entity("supplus") -> 16#02AC0; entity("supset") -> 16#02283; entity("supseteq") -> 16#02287; entity("supseteqq") -> 16#02AC6; entity("supsetneq") -> 16#0228B; entity("supsetneqq") -> 16#02ACC; entity("supsim") -> 16#02AC8; entity("supsub") -> 16#02AD4; entity("supsup") -> 16#02AD6; entity("swArr") -> 16#021D9; entity("swarhk") -> 16#02926; entity("swarr") -> 16#02199; entity("swarrow") -> 16#02199; entity("swnwar") -> 16#0292A; entity("szlig") -> 16#000DF; entity("target") -> 16#02316; entity("tau") -> 16#003C4; entity("tbrk") -> 16#023B4; entity("tcaron") -> 16#00165; entity("tcedil") -> 16#00163; entity("tcy") -> 16#00442; entity("tdot") -> 16#020DB; entity("telrec") -> 16#02315; entity("tfr") -> 16#1D531; entity("there4") -> 16#02234; entity("therefore") -> 16#02234; entity("theta") -> 16#003B8; entity("thetasym") -> 16#003D1; entity("thetav") -> 16#003D1; entity("thickapprox") -> 16#02248; entity("thicksim") -> 16#0223C; entity("thinsp") -> 16#02009; entity("thkap") -> 16#02248; entity("thksim") -> 16#0223C; entity("thorn") -> 16#000FE; entity("tilde") -> 16#002DC; entity("times") -> 16#000D7; entity("timesb") -> 16#022A0; entity("timesbar") -> 16#02A31; entity("timesd") -> 16#02A30; entity("tint") -> 16#0222D; entity("toea") -> 16#02928; entity("top") -> 16#022A4; entity("topbot") -> 16#02336; entity("topcir") -> 16#02AF1; entity("topf") -> 16#1D565; entity("topfork") -> 16#02ADA; entity("tosa") -> 16#02929; entity("tprime") -> 16#02034; entity("trade") -> 16#02122; entity("triangle") -> 16#025B5; entity("triangledown") -> 16#025BF; entity("triangleleft") -> 16#025C3; entity("trianglelefteq") -> 16#022B4; entity("triangleq") -> 16#0225C; entity("triangleright") -> 16#025B9; entity("trianglerighteq") -> 16#022B5; entity("tridot") -> 16#025EC; entity("trie") -> 16#0225C; entity("triminus") -> 16#02A3A; entity("triplus") -> 16#02A39; entity("trisb") -> 16#029CD; entity("tritime") -> 16#02A3B; entity("trpezium") -> 16#023E2; entity("tscr") -> 16#1D4C9; entity("tscy") -> 16#00446; entity("tshcy") -> 16#0045B; entity("tstrok") -> 16#00167; entity("twixt") -> 16#0226C; entity("twoheadleftarrow") -> 16#0219E; entity("twoheadrightarrow") -> 16#021A0; entity("uArr") -> 16#021D1; entity("uHar") -> 16#02963; entity("uacute") -> 16#000FA; entity("uarr") -> 16#02191; entity("ubrcy") -> 16#0045E; entity("ubreve") -> 16#0016D; entity("ucirc") -> 16#000FB; entity("ucy") -> 16#00443; entity("udarr") -> 16#021C5; entity("udblac") -> 16#00171; entity("udhar") -> 16#0296E; entity("ufisht") -> 16#0297E; entity("ufr") -> 16#1D532; entity("ugrave") -> 16#000F9; entity("uharl") -> 16#021BF; entity("uharr") -> 16#021BE; entity("uhblk") -> 16#02580; entity("ulcorn") -> 16#0231C; entity("ulcorner") -> 16#0231C; entity("ulcrop") -> 16#0230F; entity("ultri") -> 16#025F8; entity("umacr") -> 16#0016B; entity("uml") -> 16#000A8; entity("uogon") -> 16#00173; entity("uopf") -> 16#1D566; entity("uparrow") -> 16#02191; entity("updownarrow") -> 16#02195; entity("upharpoonleft") -> 16#021BF; entity("upharpoonright") -> 16#021BE; entity("uplus") -> 16#0228E; entity("upsi") -> 16#003C5; entity("upsih") -> 16#003D2; entity("upsilon") -> 16#003C5; entity("upuparrows") -> 16#021C8; entity("urcorn") -> 16#0231D; entity("urcorner") -> 16#0231D; entity("urcrop") -> 16#0230E; entity("uring") -> 16#0016F; entity("urtri") -> 16#025F9; entity("uscr") -> 16#1D4CA; entity("utdot") -> 16#022F0; entity("utilde") -> 16#00169; entity("utri") -> 16#025B5; entity("utrif") -> 16#025B4; entity("uuarr") -> 16#021C8; entity("uuml") -> 16#000FC; entity("uwangle") -> 16#029A7; entity("vArr") -> 16#021D5; entity("vBar") -> 16#02AE8; entity("vBarv") -> 16#02AE9; entity("vDash") -> 16#022A8; entity("vangrt") -> 16#0299C; entity("varepsilon") -> 16#003F5; entity("varkappa") -> 16#003F0; entity("varnothing") -> 16#02205; entity("varphi") -> 16#003D5; entity("varpi") -> 16#003D6; entity("varpropto") -> 16#0221D; entity("varr") -> 16#02195; entity("varrho") -> 16#003F1; entity("varsigma") -> 16#003C2; entity("varsubsetneq") -> [16#0228A, 16#0FE00]; entity("varsubsetneqq") -> [16#02ACB, 16#0FE00]; entity("varsupsetneq") -> [16#0228B, 16#0FE00]; entity("varsupsetneqq") -> [16#02ACC, 16#0FE00]; entity("vartheta") -> 16#003D1; entity("vartriangleleft") -> 16#022B2; entity("vartriangleright") -> 16#022B3; entity("vcy") -> 16#00432; entity("vdash") -> 16#022A2; entity("vee") -> 16#02228; entity("veebar") -> 16#022BB; entity("veeeq") -> 16#0225A; entity("vellip") -> 16#022EE; entity("verbar") -> 16#0007C; entity("vert") -> 16#0007C; entity("vfr") -> 16#1D533; entity("vltri") -> 16#022B2; entity("vnsub") -> [16#02282, 16#020D2]; entity("vnsup") -> [16#02283, 16#020D2]; entity("vopf") -> 16#1D567; entity("vprop") -> 16#0221D; entity("vrtri") -> 16#022B3; entity("vscr") -> 16#1D4CB; entity("vsubnE") -> [16#02ACB, 16#0FE00]; entity("vsubne") -> [16#0228A, 16#0FE00]; entity("vsupnE") -> [16#02ACC, 16#0FE00]; entity("vsupne") -> [16#0228B, 16#0FE00]; entity("vzigzag") -> 16#0299A; entity("wcirc") -> 16#00175; entity("wedbar") -> 16#02A5F; entity("wedge") -> 16#02227; entity("wedgeq") -> 16#02259; entity("weierp") -> 16#02118; entity("wfr") -> 16#1D534; entity("wopf") -> 16#1D568; entity("wp") -> 16#02118; entity("wr") -> 16#02240; entity("wreath") -> 16#02240; entity("wscr") -> 16#1D4CC; entity("xcap") -> 16#022C2; entity("xcirc") -> 16#025EF; entity("xcup") -> 16#022C3; entity("xdtri") -> 16#025BD; entity("xfr") -> 16#1D535; entity("xhArr") -> 16#027FA; entity("xharr") -> 16#027F7; entity("xi") -> 16#003BE; entity("xlArr") -> 16#027F8; entity("xlarr") -> 16#027F5; entity("xmap") -> 16#027FC; entity("xnis") -> 16#022FB; entity("xodot") -> 16#02A00; entity("xopf") -> 16#1D569; entity("xoplus") -> 16#02A01; entity("xotime") -> 16#02A02; entity("xrArr") -> 16#027F9; entity("xrarr") -> 16#027F6; entity("xscr") -> 16#1D4CD; entity("xsqcup") -> 16#02A06; entity("xuplus") -> 16#02A04; entity("xutri") -> 16#025B3; entity("xvee") -> 16#022C1; entity("xwedge") -> 16#022C0; entity("yacute") -> 16#000FD; entity("yacy") -> 16#0044F; entity("ycirc") -> 16#00177; entity("ycy") -> 16#0044B; entity("yen") -> 16#000A5; entity("yfr") -> 16#1D536; entity("yicy") -> 16#00457; entity("yopf") -> 16#1D56A; entity("yscr") -> 16#1D4CE; entity("yucy") -> 16#0044E; entity("yuml") -> 16#000FF; entity("zacute") -> 16#0017A; entity("zcaron") -> 16#0017E; entity("zcy") -> 16#00437; entity("zdot") -> 16#0017C; entity("zeetrf") -> 16#02128; entity("zeta") -> 16#003B6; entity("zfr") -> 16#1D537; entity("zhcy") -> 16#00436; entity("zigrarr") -> 16#021DD; entity("zopf") -> 16#1D56B; entity("zscr") -> 16#1D4CF; entity("zwj") -> 16#0200D; entity("zwnj") -> 16#0200C; entity(_) -> undefined. %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). exhaustive_entity_test() -> T = mochiweb_cover:clause_lookup_table(?MODULE, entity), [?assertEqual(V, entity(K)) || {K, V} <- T]. charref_test() -> 1234 = charref("#1234"), 255 = charref("#xfF"), 255 = charref(<<"#XFf">>), 38 = charref("amp"), 38 = charref(<<"amp">>), undefined = charref("not_an_entity"), undefined = charref("#not_an_entity"), undefined = charref("#xnot_an_entity"), ok. -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochijson.erl0000644000177700017770000004524012633765070030044 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2006 Mochi Media, Inc. %% @doc Yet another JSON (RFC 4627) library for Erlang. -module(mochijson). -author('bob@mochimedia.com'). -export([encoder/1, encode/1]). -export([decoder/1, decode/1]). -export([binary_encoder/1, binary_encode/1]). -export([binary_decoder/1, binary_decode/1]). % This is a macro to placate syntax highlighters.. -define(Q, $\"). -define(ADV_COL(S, N), S#decoder{column=N+S#decoder.column}). -define(INC_COL(S), S#decoder{column=1+S#decoder.column}). -define(INC_LINE(S), S#decoder{column=1, line=1+S#decoder.line}). %% @type json_string() = atom | string() | binary() %% @type json_number() = integer() | float() %% @type json_array() = {array, [json_term()]} %% @type json_object() = {struct, [{json_string(), json_term()}]} %% @type json_term() = json_string() | json_number() | json_array() | %% json_object() %% @type encoding() = utf8 | unicode %% @type encoder_option() = {input_encoding, encoding()} | %% {handler, function()} %% @type decoder_option() = {input_encoding, encoding()} | %% {object_hook, function()} %% @type bjson_string() = binary() %% @type bjson_number() = integer() | float() %% @type bjson_array() = [bjson_term()] %% @type bjson_object() = {struct, [{bjson_string(), bjson_term()}]} %% @type bjson_term() = bjson_string() | bjson_number() | bjson_array() | %% bjson_object() %% @type binary_encoder_option() = {handler, function()} %% @type binary_decoder_option() = {object_hook, function()} -record(encoder, {input_encoding=unicode, handler=null}). -record(decoder, {input_encoding=utf8, object_hook=null, line=1, column=1, state=null}). %% @spec encoder([encoder_option()]) -> function() %% @doc Create an encoder/1 with the given options. encoder(Options) -> State = parse_encoder_options(Options, #encoder{}), fun (O) -> json_encode(O, State) end. %% @spec encode(json_term()) -> iolist() %% @doc Encode the given as JSON to an iolist. encode(Any) -> json_encode(Any, #encoder{}). %% @spec decoder([decoder_option()]) -> function() %% @doc Create a decoder/1 with the given options. decoder(Options) -> State = parse_decoder_options(Options, #decoder{}), fun (O) -> json_decode(O, State) end. %% @spec decode(iolist()) -> json_term() %% @doc Decode the given iolist to Erlang terms. decode(S) -> json_decode(S, #decoder{}). %% @spec binary_decoder([binary_decoder_option()]) -> function() %% @doc Create a binary_decoder/1 with the given options. binary_decoder(Options) -> mochijson2:decoder(Options). %% @spec binary_encoder([binary_encoder_option()]) -> function() %% @doc Create a binary_encoder/1 with the given options. binary_encoder(Options) -> mochijson2:encoder(Options). %% @spec binary_encode(bjson_term()) -> iolist() %% @doc Encode the given as JSON to an iolist, using lists for arrays and %% binaries for strings. binary_encode(Any) -> mochijson2:encode(Any). %% @spec binary_decode(iolist()) -> bjson_term() %% @doc Decode the given iolist to Erlang terms, using lists for arrays and %% binaries for strings. binary_decode(S) -> mochijson2:decode(S). %% Internal API parse_encoder_options([], State) -> State; parse_encoder_options([{input_encoding, Encoding} | Rest], State) -> parse_encoder_options(Rest, State#encoder{input_encoding=Encoding}); parse_encoder_options([{handler, Handler} | Rest], State) -> parse_encoder_options(Rest, State#encoder{handler=Handler}). parse_decoder_options([], State) -> State; parse_decoder_options([{input_encoding, Encoding} | Rest], State) -> parse_decoder_options(Rest, State#decoder{input_encoding=Encoding}); parse_decoder_options([{object_hook, Hook} | Rest], State) -> parse_decoder_options(Rest, State#decoder{object_hook=Hook}). json_encode(true, _State) -> "true"; json_encode(false, _State) -> "false"; json_encode(null, _State) -> "null"; json_encode(I, _State) when is_integer(I) -> integer_to_list(I); json_encode(F, _State) when is_float(F) -> mochinum:digits(F); json_encode(L, State) when is_list(L); is_binary(L); is_atom(L) -> json_encode_string(L, State); json_encode({array, Props}, State) when is_list(Props) -> json_encode_array(Props, State); json_encode({struct, Props}, State) when is_list(Props) -> json_encode_proplist(Props, State); json_encode(Bad, #encoder{handler=null}) -> exit({json_encode, {bad_term, Bad}}); json_encode(Bad, State=#encoder{handler=Handler}) -> json_encode(Handler(Bad), State). json_encode_array([], _State) -> "[]"; json_encode_array(L, State) -> F = fun (O, Acc) -> [$,, json_encode(O, State) | Acc] end, [$, | Acc1] = lists:foldl(F, "[", L), lists:reverse([$\] | Acc1]). json_encode_proplist([], _State) -> "{}"; json_encode_proplist(Props, State) -> F = fun ({K, V}, Acc) -> KS = case K of K when is_atom(K) -> json_encode_string_utf8(atom_to_list(K)); K when is_integer(K) -> json_encode_string(integer_to_list(K), State); K when is_list(K); is_binary(K) -> json_encode_string(K, State) end, VS = json_encode(V, State), [$,, VS, $:, KS | Acc] end, [$, | Acc1] = lists:foldl(F, "{", Props), lists:reverse([$\} | Acc1]). json_encode_string(A, _State) when is_atom(A) -> json_encode_string_unicode(xmerl_ucs:from_utf8(atom_to_list(A))); json_encode_string(B, _State) when is_binary(B) -> json_encode_string_unicode(xmerl_ucs:from_utf8(B)); json_encode_string(S, #encoder{input_encoding=utf8}) -> json_encode_string_utf8(S); json_encode_string(S, #encoder{input_encoding=unicode}) -> json_encode_string_unicode(S). json_encode_string_utf8(S) -> [?Q | json_encode_string_utf8_1(S)]. json_encode_string_utf8_1([C | Cs]) when C >= 0, C =< 16#7f -> NewC = case C of $\\ -> "\\\\"; ?Q -> "\\\""; _ when C >= $\s, C < 16#7f -> C; $\t -> "\\t"; $\n -> "\\n"; $\r -> "\\r"; $\f -> "\\f"; $\b -> "\\b"; _ when C >= 0, C =< 16#7f -> unihex(C); _ -> exit({json_encode, {bad_char, C}}) end, [NewC | json_encode_string_utf8_1(Cs)]; json_encode_string_utf8_1(All=[C | _]) when C >= 16#80, C =< 16#10FFFF -> [?Q | Rest] = json_encode_string_unicode(xmerl_ucs:from_utf8(All)), Rest; json_encode_string_utf8_1([]) -> "\"". json_encode_string_unicode(S) -> [?Q | json_encode_string_unicode_1(S)]. json_encode_string_unicode_1([C | Cs]) -> NewC = case C of $\\ -> "\\\\"; ?Q -> "\\\""; _ when C >= $\s, C < 16#7f -> C; $\t -> "\\t"; $\n -> "\\n"; $\r -> "\\r"; $\f -> "\\f"; $\b -> "\\b"; _ when C >= 0, C =< 16#10FFFF -> unihex(C); _ -> exit({json_encode, {bad_char, C}}) end, [NewC | json_encode_string_unicode_1(Cs)]; json_encode_string_unicode_1([]) -> "\"". dehex(C) when C >= $0, C =< $9 -> C - $0; dehex(C) when C >= $a, C =< $f -> C - $a + 10; dehex(C) when C >= $A, C =< $F -> C - $A + 10. hexdigit(C) when C >= 0, C =< 9 -> C + $0; hexdigit(C) when C =< 15 -> C + $a - 10. unihex(C) when C < 16#10000 -> <> = <>, Digits = [hexdigit(D) || D <- [D3, D2, D1, D0]], [$\\, $u | Digits]; unihex(C) when C =< 16#10FFFF -> N = C - 16#10000, S1 = 16#d800 bor ((N bsr 10) band 16#3ff), S2 = 16#dc00 bor (N band 16#3ff), [unihex(S1), unihex(S2)]. json_decode(B, S) when is_binary(B) -> json_decode(binary_to_list(B), S); json_decode(L, S) -> {Res, L1, S1} = decode1(L, S), {eof, [], _} = tokenize(L1, S1#decoder{state=trim}), Res. decode1(L, S=#decoder{state=null}) -> case tokenize(L, S#decoder{state=any}) of {{const, C}, L1, S1} -> {C, L1, S1}; {start_array, L1, S1} -> decode_array(L1, S1#decoder{state=any}, []); {start_object, L1, S1} -> decode_object(L1, S1#decoder{state=key}, []) end. make_object(V, #decoder{object_hook=null}) -> V; make_object(V, #decoder{object_hook=Hook}) -> Hook(V). decode_object(L, S=#decoder{state=key}, Acc) -> case tokenize(L, S) of {end_object, Rest, S1} -> V = make_object({struct, lists:reverse(Acc)}, S1), {V, Rest, S1#decoder{state=null}}; {{const, K}, Rest, S1} when is_list(K) -> {colon, L2, S2} = tokenize(Rest, S1), {V, L3, S3} = decode1(L2, S2#decoder{state=null}), decode_object(L3, S3#decoder{state=comma}, [{K, V} | Acc]) end; decode_object(L, S=#decoder{state=comma}, Acc) -> case tokenize(L, S) of {end_object, Rest, S1} -> V = make_object({struct, lists:reverse(Acc)}, S1), {V, Rest, S1#decoder{state=null}}; {comma, Rest, S1} -> decode_object(Rest, S1#decoder{state=key}, Acc) end. decode_array(L, S=#decoder{state=any}, Acc) -> case tokenize(L, S) of {end_array, Rest, S1} -> {{array, lists:reverse(Acc)}, Rest, S1#decoder{state=null}}; {start_array, Rest, S1} -> {Array, Rest1, S2} = decode_array(Rest, S1#decoder{state=any}, []), decode_array(Rest1, S2#decoder{state=comma}, [Array | Acc]); {start_object, Rest, S1} -> {Array, Rest1, S2} = decode_object(Rest, S1#decoder{state=key}, []), decode_array(Rest1, S2#decoder{state=comma}, [Array | Acc]); {{const, Const}, Rest, S1} -> decode_array(Rest, S1#decoder{state=comma}, [Const | Acc]) end; decode_array(L, S=#decoder{state=comma}, Acc) -> case tokenize(L, S) of {end_array, Rest, S1} -> {{array, lists:reverse(Acc)}, Rest, S1#decoder{state=null}}; {comma, Rest, S1} -> decode_array(Rest, S1#decoder{state=any}, Acc) end. tokenize_string(IoList=[C | _], S=#decoder{input_encoding=utf8}, Acc) when is_list(C); is_binary(C); C >= 16#7f -> List = xmerl_ucs:from_utf8(iolist_to_binary(IoList)), tokenize_string(List, S#decoder{input_encoding=unicode}, Acc); tokenize_string("\"" ++ Rest, S, Acc) -> {lists:reverse(Acc), Rest, ?INC_COL(S)}; tokenize_string("\\\"" ++ Rest, S, Acc) -> tokenize_string(Rest, ?ADV_COL(S, 2), [$\" | Acc]); tokenize_string("\\\\" ++ Rest, S, Acc) -> tokenize_string(Rest, ?ADV_COL(S, 2), [$\\ | Acc]); tokenize_string("\\/" ++ Rest, S, Acc) -> tokenize_string(Rest, ?ADV_COL(S, 2), [$/ | Acc]); tokenize_string("\\b" ++ Rest, S, Acc) -> tokenize_string(Rest, ?ADV_COL(S, 2), [$\b | Acc]); tokenize_string("\\f" ++ Rest, S, Acc) -> tokenize_string(Rest, ?ADV_COL(S, 2), [$\f | Acc]); tokenize_string("\\n" ++ Rest, S, Acc) -> tokenize_string(Rest, ?ADV_COL(S, 2), [$\n | Acc]); tokenize_string("\\r" ++ Rest, S, Acc) -> tokenize_string(Rest, ?ADV_COL(S, 2), [$\r | Acc]); tokenize_string("\\t" ++ Rest, S, Acc) -> tokenize_string(Rest, ?ADV_COL(S, 2), [$\t | Acc]); tokenize_string([$\\, $u, C3, C2, C1, C0 | Rest], S, Acc) -> % coalesce UTF-16 surrogate pair? C = dehex(C0) bor (dehex(C1) bsl 4) bor (dehex(C2) bsl 8) bor (dehex(C3) bsl 12), tokenize_string(Rest, ?ADV_COL(S, 6), [C | Acc]); tokenize_string([C | Rest], S, Acc) when C >= $\s; C < 16#10FFFF -> tokenize_string(Rest, ?ADV_COL(S, 1), [C | Acc]). tokenize_number(IoList=[C | _], Mode, S=#decoder{input_encoding=utf8}, Acc) when is_list(C); is_binary(C); C >= 16#7f -> List = xmerl_ucs:from_utf8(iolist_to_binary(IoList)), tokenize_number(List, Mode, S#decoder{input_encoding=unicode}, Acc); tokenize_number([$- | Rest], sign, S, []) -> tokenize_number(Rest, int, ?INC_COL(S), [$-]); tokenize_number(Rest, sign, S, []) -> tokenize_number(Rest, int, S, []); tokenize_number([$0 | Rest], int, S, Acc) -> tokenize_number(Rest, frac, ?INC_COL(S), [$0 | Acc]); tokenize_number([C | Rest], int, S, Acc) when C >= $1, C =< $9 -> tokenize_number(Rest, int1, ?INC_COL(S), [C | Acc]); tokenize_number([C | Rest], int1, S, Acc) when C >= $0, C =< $9 -> tokenize_number(Rest, int1, ?INC_COL(S), [C | Acc]); tokenize_number(Rest, int1, S, Acc) -> tokenize_number(Rest, frac, S, Acc); tokenize_number([$., C | Rest], frac, S, Acc) when C >= $0, C =< $9 -> tokenize_number(Rest, frac1, ?ADV_COL(S, 2), [C, $. | Acc]); tokenize_number([E | Rest], frac, S, Acc) when E == $e; E == $E -> tokenize_number(Rest, esign, ?INC_COL(S), [$e, $0, $. | Acc]); tokenize_number(Rest, frac, S, Acc) -> {{int, lists:reverse(Acc)}, Rest, S}; tokenize_number([C | Rest], frac1, S, Acc) when C >= $0, C =< $9 -> tokenize_number(Rest, frac1, ?INC_COL(S), [C | Acc]); tokenize_number([E | Rest], frac1, S, Acc) when E == $e; E == $E -> tokenize_number(Rest, esign, ?INC_COL(S), [$e | Acc]); tokenize_number(Rest, frac1, S, Acc) -> {{float, lists:reverse(Acc)}, Rest, S}; tokenize_number([C | Rest], esign, S, Acc) when C == $-; C == $+ -> tokenize_number(Rest, eint, ?INC_COL(S), [C | Acc]); tokenize_number(Rest, esign, S, Acc) -> tokenize_number(Rest, eint, S, Acc); tokenize_number([C | Rest], eint, S, Acc) when C >= $0, C =< $9 -> tokenize_number(Rest, eint1, ?INC_COL(S), [C | Acc]); tokenize_number([C | Rest], eint1, S, Acc) when C >= $0, C =< $9 -> tokenize_number(Rest, eint1, ?INC_COL(S), [C | Acc]); tokenize_number(Rest, eint1, S, Acc) -> {{float, lists:reverse(Acc)}, Rest, S}. tokenize([], S=#decoder{state=trim}) -> {eof, [], S}; tokenize([L | Rest], S) when is_list(L) -> tokenize(L ++ Rest, S); tokenize([B | Rest], S) when is_binary(B) -> tokenize(xmerl_ucs:from_utf8(B) ++ Rest, S); tokenize("\r\n" ++ Rest, S) -> tokenize(Rest, ?INC_LINE(S)); tokenize("\n" ++ Rest, S) -> tokenize(Rest, ?INC_LINE(S)); tokenize([C | Rest], S) when C == $\s; C == $\t -> tokenize(Rest, ?INC_COL(S)); tokenize("{" ++ Rest, S) -> {start_object, Rest, ?INC_COL(S)}; tokenize("}" ++ Rest, S) -> {end_object, Rest, ?INC_COL(S)}; tokenize("[" ++ Rest, S) -> {start_array, Rest, ?INC_COL(S)}; tokenize("]" ++ Rest, S) -> {end_array, Rest, ?INC_COL(S)}; tokenize("," ++ Rest, S) -> {comma, Rest, ?INC_COL(S)}; tokenize(":" ++ Rest, S) -> {colon, Rest, ?INC_COL(S)}; tokenize("null" ++ Rest, S) -> {{const, null}, Rest, ?ADV_COL(S, 4)}; tokenize("true" ++ Rest, S) -> {{const, true}, Rest, ?ADV_COL(S, 4)}; tokenize("false" ++ Rest, S) -> {{const, false}, Rest, ?ADV_COL(S, 5)}; tokenize("\"" ++ Rest, S) -> {String, Rest1, S1} = tokenize_string(Rest, ?INC_COL(S), []), {{const, String}, Rest1, S1}; tokenize(L=[C | _], S) when C >= $0, C =< $9; C == $- -> case tokenize_number(L, sign, S, []) of {{int, Int}, Rest, S1} -> {{const, list_to_integer(Int)}, Rest, S1}; {{float, Float}, Rest, S1} -> {{const, list_to_float(Float)}, Rest, S1} end. %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). %% testing constructs borrowed from the Yaws JSON implementation. %% Create an object from a list of Key/Value pairs. obj_new() -> {struct, []}. is_obj({struct, Props}) -> F = fun ({K, _}) when is_list(K) -> true; (_) -> false end, lists:all(F, Props). obj_from_list(Props) -> Obj = {struct, Props}, case is_obj(Obj) of true -> Obj; false -> exit(json_bad_object) end. %% Test for equivalence of Erlang terms. %% Due to arbitrary order of construction, equivalent objects might %% compare unequal as erlang terms, so we need to carefully recurse %% through aggregates (tuples and objects). equiv({struct, Props1}, {struct, Props2}) -> equiv_object(Props1, Props2); equiv({array, L1}, {array, L2}) -> equiv_list(L1, L2); equiv(N1, N2) when is_number(N1), is_number(N2) -> N1 == N2; equiv(S1, S2) when is_list(S1), is_list(S2) -> S1 == S2; equiv(true, true) -> true; equiv(false, false) -> true; equiv(null, null) -> true. %% Object representation and traversal order is unknown. %% Use the sledgehammer and sort property lists. equiv_object(Props1, Props2) -> L1 = lists:keysort(1, Props1), L2 = lists:keysort(1, Props2), Pairs = lists:zip(L1, L2), true = lists:all(fun({{K1, V1}, {K2, V2}}) -> equiv(K1, K2) and equiv(V1, V2) end, Pairs). %% Recursively compare tuple elements for equivalence. equiv_list([], []) -> true; equiv_list([V1 | L1], [V2 | L2]) -> equiv(V1, V2) andalso equiv_list(L1, L2). e2j_vec_test() -> test_one(e2j_test_vec(utf8), 1). issue33_test() -> %% http://code.google.com/p/mochiweb/issues/detail?id=33 Js = {struct, [{"key", [194, 163]}]}, Encoder = encoder([{input_encoding, utf8}]), "{\"key\":\"\\u00a3\"}" = lists:flatten(Encoder(Js)). test_one([], _N) -> %% io:format("~p tests passed~n", [N-1]), ok; test_one([{E, J} | Rest], N) -> %% io:format("[~p] ~p ~p~n", [N, E, J]), true = equiv(E, decode(J)), true = equiv(E, decode(encode(E))), test_one(Rest, 1+N). e2j_test_vec(utf8) -> [ {1, "1"}, {3.1416, "3.14160"}, % text representation may truncate, trail zeroes {-1, "-1"}, {-3.1416, "-3.14160"}, {12.0e10, "1.20000e+11"}, {1.234E+10, "1.23400e+10"}, {-1.234E-10, "-1.23400e-10"}, {10.0, "1.0e+01"}, {123.456, "1.23456E+2"}, {10.0, "1e1"}, {"foo", "\"foo\""}, {"foo" ++ [5] ++ "bar", "\"foo\\u0005bar\""}, {"", "\"\""}, {"\"", "\"\\\"\""}, {"\n\n\n", "\"\\n\\n\\n\""}, {"\\", "\"\\\\\""}, {"\" \b\f\r\n\t\"", "\"\\\" \\b\\f\\r\\n\\t\\\"\""}, {obj_new(), "{}"}, {obj_from_list([{"foo", "bar"}]), "{\"foo\":\"bar\"}"}, {obj_from_list([{"foo", "bar"}, {"baz", 123}]), "{\"foo\":\"bar\",\"baz\":123}"}, {{array, []}, "[]"}, {{array, [{array, []}]}, "[[]]"}, {{array, [1, "foo"]}, "[1,\"foo\"]"}, % json array in a json object {obj_from_list([{"foo", {array, [123]}}]), "{\"foo\":[123]}"}, % json object in a json object {obj_from_list([{"foo", obj_from_list([{"bar", true}])}]), "{\"foo\":{\"bar\":true}}"}, % fold evaluation order {obj_from_list([{"foo", {array, []}}, {"bar", obj_from_list([{"baz", true}])}, {"alice", "bob"}]), "{\"foo\":[],\"bar\":{\"baz\":true},\"alice\":\"bob\"}"}, % json object in a json array {{array, [-123, "foo", obj_from_list([{"bar", {array, []}}]), null]}, "[-123,\"foo\",{\"bar\":[]},null]"} ]. -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb_headers.erl0000644000177700017770000003516512633765070031350 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2007 Mochi Media, Inc. %% @doc Case preserving (but case insensitive) HTTP Header dictionary. -module(mochiweb_headers). -author('bob@mochimedia.com'). -export([empty/0, from_list/1, insert/3, enter/3, get_value/2, lookup/2]). -export([delete_any/2, get_primary_value/2, get_combined_value/2]). -export([default/3, enter_from_list/2, default_from_list/2]). -export([to_list/1, make/1]). -export([from_binary/1]). %% @type headers(). %% @type key() = atom() | binary() | string(). %% @type value() = atom() | binary() | string() | integer(). %% @spec empty() -> headers() %% @doc Create an empty headers structure. empty() -> gb_trees:empty(). %% @spec make(headers() | [{key(), value()}]) -> headers() %% @doc Construct a headers() from the given list. make(L) when is_list(L) -> from_list(L); %% assume a non-list is already mochiweb_headers. make(T) -> T. %% @spec from_binary(iolist()) -> headers() %% @doc Transforms a raw HTTP header into a mochiweb headers structure. %% %% The given raw HTTP header can be one of the following: %% %% 1) A string or a binary representing a full HTTP header ending with %% double CRLF. %% Examples: %% ``` %% "Content-Length: 47\r\nContent-Type: text/plain\r\n\r\n" %% <<"Content-Length: 47\r\nContent-Type: text/plain\r\n\r\n">>''' %% %% 2) A list of binaries or strings where each element represents a raw %% HTTP header line ending with a single CRLF. %% Examples: %% ``` %% [<<"Content-Length: 47\r\n">>, <<"Content-Type: text/plain\r\n">>] %% ["Content-Length: 47\r\n", "Content-Type: text/plain\r\n"] %% ["Content-Length: 47\r\n", <<"Content-Type: text/plain\r\n">>]''' %% from_binary(RawHttpHeader) when is_binary(RawHttpHeader) -> from_binary(RawHttpHeader, []); from_binary(RawHttpHeaderList) -> from_binary(list_to_binary([RawHttpHeaderList, "\r\n"])). from_binary(RawHttpHeader, Acc) -> case erlang:decode_packet(httph, RawHttpHeader, []) of {ok, {http_header, _, H, _, V}, Rest} -> from_binary(Rest, [{H, V} | Acc]); _ -> make(Acc) end. %% @spec from_list([{key(), value()}]) -> headers() %% @doc Construct a headers() from the given list. from_list(List) -> lists:foldl(fun ({K, V}, T) -> insert(K, V, T) end, empty(), List). %% @spec enter_from_list([{key(), value()}], headers()) -> headers() %% @doc Insert pairs into the headers, replace any values for existing keys. enter_from_list(List, T) -> lists:foldl(fun ({K, V}, T1) -> enter(K, V, T1) end, T, List). %% @spec default_from_list([{key(), value()}], headers()) -> headers() %% @doc Insert pairs into the headers for keys that do not already exist. default_from_list(List, T) -> lists:foldl(fun ({K, V}, T1) -> default(K, V, T1) end, T, List). %% @spec to_list(headers()) -> [{key(), string()}] %% @doc Return the contents of the headers. The keys will be the exact key %% that was first inserted (e.g. may be an atom or binary, case is %% preserved). to_list(T) -> F = fun ({K, {array, L}}, Acc) -> L1 = lists:reverse(L), lists:foldl(fun (V, Acc1) -> [{K, V} | Acc1] end, Acc, L1); (Pair, Acc) -> [Pair | Acc] end, lists:reverse(lists:foldl(F, [], gb_trees:values(T))). %% @spec get_value(key(), headers()) -> string() | undefined %% @doc Return the value of the given header using a case insensitive search. %% undefined will be returned for keys that are not present. get_value(K, T) -> case lookup(K, T) of {value, {_, V}} -> expand(V); none -> undefined end. %% @spec get_primary_value(key(), headers()) -> string() | undefined %% @doc Return the value of the given header up to the first semicolon using %% a case insensitive search. undefined will be returned for keys %% that are not present. get_primary_value(K, T) -> case get_value(K, T) of undefined -> undefined; V -> lists:takewhile(fun (C) -> C =/= $; end, V) end. %% @spec get_combined_value(key(), headers()) -> string() | undefined %% @doc Return the value from the given header using a case insensitive search. %% If the value of the header is a comma-separated list where holds values %% are all identical, the identical value will be returned. %% undefined will be returned for keys that are not present or the %% values in the list are not the same. %% %% NOTE: The process isn't designed for a general purpose. If you need %% to access all values in the combined header, please refer to %% '''tokenize_header_value/1'''. %% %% Section 4.2 of the RFC 2616 (HTTP 1.1) describes multiple message-header %% fields with the same field-name may be present in a message if and only %% if the entire field-value for that header field is defined as a %% comma-separated list [i.e., #(values)]. get_combined_value(K, T) -> case get_value(K, T) of undefined -> undefined; V -> case sets:to_list(sets:from_list(tokenize_header_value(V))) of [Val] -> Val; _ -> undefined end end. %% @spec lookup(key(), headers()) -> {value, {key(), string()}} | none %% @doc Return the case preserved key and value for the given header using %% a case insensitive search. none will be returned for keys that are %% not present. lookup(K, T) -> case gb_trees:lookup(normalize(K), T) of {value, {K0, V}} -> {value, {K0, expand(V)}}; none -> none end. %% @spec default(key(), value(), headers()) -> headers() %% @doc Insert the pair into the headers if it does not already exist. default(K, V, T) -> K1 = normalize(K), V1 = any_to_list(V), try gb_trees:insert(K1, {K, V1}, T) catch error:{key_exists, _} -> T end. %% @spec enter(key(), value(), headers()) -> headers() %% @doc Insert the pair into the headers, replacing any pre-existing key. enter(K, V, T) -> K1 = normalize(K), V1 = any_to_list(V), gb_trees:enter(K1, {K, V1}, T). %% @spec insert(key(), value(), headers()) -> headers() %% @doc Insert the pair into the headers, merging with any pre-existing key. %% A merge is done with Value = V0 ++ ", " ++ V1. insert(K, V, T) -> K1 = normalize(K), V1 = any_to_list(V), try gb_trees:insert(K1, {K, V1}, T) catch error:{key_exists, _} -> {K0, V0} = gb_trees:get(K1, T), V2 = merge(K1, V1, V0), gb_trees:update(K1, {K0, V2}, T) end. %% @spec delete_any(key(), headers()) -> headers() %% @doc Delete the header corresponding to key if it is present. delete_any(K, T) -> K1 = normalize(K), gb_trees:delete_any(K1, T). %% Internal API tokenize_header_value(undefined) -> undefined; tokenize_header_value(V) -> reversed_tokens(trim_and_reverse(V, false), [], []). trim_and_reverse([S | Rest], Reversed) when S=:=$ ; S=:=$\n; S=:=$\t -> trim_and_reverse(Rest, Reversed); trim_and_reverse(V, false) -> trim_and_reverse(lists:reverse(V), true); trim_and_reverse(V, true) -> V. reversed_tokens([], [], Acc) -> Acc; reversed_tokens([], Token, Acc) -> [Token | Acc]; reversed_tokens("\"" ++ Rest, [], Acc) -> case extract_quoted_string(Rest, []) of {String, NewRest} -> reversed_tokens(NewRest, [], [String | Acc]); undefined -> undefined end; reversed_tokens("\"" ++ _Rest, _Token, _Acc) -> undefined; reversed_tokens([C | Rest], [], Acc) when C=:=$ ;C=:=$\n;C=:=$\t;C=:=$, -> reversed_tokens(Rest, [], Acc); reversed_tokens([C | Rest], Token, Acc) when C=:=$ ;C=:=$\n;C=:=$\t;C=:=$, -> reversed_tokens(Rest, [], [Token | Acc]); reversed_tokens([C | Rest], Token, Acc) -> reversed_tokens(Rest, [C | Token], Acc); reversed_tokens(_, _, _) -> undefeined. extract_quoted_string([], _Acc) -> undefined; extract_quoted_string("\"\\" ++ Rest, Acc) -> extract_quoted_string(Rest, "\"" ++ Acc); extract_quoted_string("\"" ++ Rest, Acc) -> {Acc, Rest}; extract_quoted_string([C | Rest], Acc) -> extract_quoted_string(Rest, [C | Acc]). expand({array, L}) -> mochiweb_util:join(lists:reverse(L), ", "); expand(V) -> V. merge("set-cookie", V1, {array, L}) -> {array, [V1 | L]}; merge("set-cookie", V1, V0) -> {array, [V1, V0]}; merge(_, V1, V0) -> V0 ++ ", " ++ V1. normalize(K) when is_list(K) -> string:to_lower(K); normalize(K) when is_atom(K) -> normalize(atom_to_list(K)); normalize(K) when is_binary(K) -> normalize(binary_to_list(K)). any_to_list(V) when is_list(V) -> V; any_to_list(V) when is_atom(V) -> atom_to_list(V); any_to_list(V) when is_binary(V) -> binary_to_list(V); any_to_list(V) when is_integer(V) -> integer_to_list(V). %% %% Tests. %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). make_test() -> Identity = make([{hdr, foo}]), ?assertEqual( Identity, make(Identity)). enter_from_list_test() -> H = make([{hdr, foo}]), ?assertEqual( [{baz, "wibble"}, {hdr, "foo"}], to_list(enter_from_list([{baz, wibble}], H))), ?assertEqual( [{hdr, "bar"}], to_list(enter_from_list([{hdr, bar}], H))), ok. default_from_list_test() -> H = make([{hdr, foo}]), ?assertEqual( [{baz, "wibble"}, {hdr, "foo"}], to_list(default_from_list([{baz, wibble}], H))), ?assertEqual( [{hdr, "foo"}], to_list(default_from_list([{hdr, bar}], H))), ok. get_primary_value_test() -> H = make([{hdr, foo}, {baz, <<"wibble;taco">>}]), ?assertEqual( "foo", get_primary_value(hdr, H)), ?assertEqual( undefined, get_primary_value(bar, H)), ?assertEqual( "wibble", get_primary_value(<<"baz">>, H)), ok. get_combined_value_test() -> H = make([{hdr, foo}, {baz, <<"wibble,taco">>}, {content_length, "123, 123"}, {test, " 123, 123, 123 , 123,123 "}, {test2, "456, 123, 123 , 123"}, {test3, "123"}, {test4, " 123, "}]), ?assertEqual( "foo", get_combined_value(hdr, H)), ?assertEqual( undefined, get_combined_value(bar, H)), ?assertEqual( undefined, get_combined_value(<<"baz">>, H)), ?assertEqual( "123", get_combined_value(<<"content_length">>, H)), ?assertEqual( "123", get_combined_value(<<"test">>, H)), ?assertEqual( undefined, get_combined_value(<<"test2">>, H)), ?assertEqual( "123", get_combined_value(<<"test3">>, H)), ?assertEqual( "123", get_combined_value(<<"test4">>, H)), ok. set_cookie_test() -> H = make([{"set-cookie", foo}, {"set-cookie", bar}, {"set-cookie", baz}]), ?assertEqual( [{"set-cookie", "foo"}, {"set-cookie", "bar"}, {"set-cookie", "baz"}], to_list(H)), ok. headers_test() -> H = ?MODULE:make([{hdr, foo}, {"Hdr", "bar"}, {'Hdr', 2}]), [{hdr, "foo, bar, 2"}] = ?MODULE:to_list(H), H1 = ?MODULE:insert(taco, grande, H), [{hdr, "foo, bar, 2"}, {taco, "grande"}] = ?MODULE:to_list(H1), H2 = ?MODULE:make([{"Set-Cookie", "foo"}]), [{"Set-Cookie", "foo"}] = ?MODULE:to_list(H2), H3 = ?MODULE:insert("Set-Cookie", "bar", H2), [{"Set-Cookie", "foo"}, {"Set-Cookie", "bar"}] = ?MODULE:to_list(H3), "foo, bar" = ?MODULE:get_value("set-cookie", H3), {value, {"Set-Cookie", "foo, bar"}} = ?MODULE:lookup("set-cookie", H3), undefined = ?MODULE:get_value("shibby", H3), none = ?MODULE:lookup("shibby", H3), H4 = ?MODULE:insert("content-type", "application/x-www-form-urlencoded; charset=utf8", H3), "application/x-www-form-urlencoded" = ?MODULE:get_primary_value( "content-type", H4), H4 = ?MODULE:delete_any("nonexistent-header", H4), H3 = ?MODULE:delete_any("content-type", H4), HB = <<"Content-Length: 47\r\nContent-Type: text/plain\r\n\r\n">>, H_HB = ?MODULE:from_binary(HB), H_HB = ?MODULE:from_binary(binary_to_list(HB)), "47" = ?MODULE:get_value("Content-Length", H_HB), "text/plain" = ?MODULE:get_value("Content-Type", H_HB), L_H_HB = ?MODULE:to_list(H_HB), 2 = length(L_H_HB), true = lists:member({'Content-Length', "47"}, L_H_HB), true = lists:member({'Content-Type', "text/plain"}, L_H_HB), HL = [ <<"Content-Length: 47\r\n">>, <<"Content-Type: text/plain\r\n">> ], HL2 = [ "Content-Length: 47\r\n", <<"Content-Type: text/plain\r\n">> ], HL3 = [ <<"Content-Length: 47\r\n">>, "Content-Type: text/plain\r\n" ], H_HL = ?MODULE:from_binary(HL), H_HL = ?MODULE:from_binary(HL2), H_HL = ?MODULE:from_binary(HL3), "47" = ?MODULE:get_value("Content-Length", H_HL), "text/plain" = ?MODULE:get_value("Content-Type", H_HL), L_H_HL = ?MODULE:to_list(H_HL), 2 = length(L_H_HL), true = lists:member({'Content-Length', "47"}, L_H_HL), true = lists:member({'Content-Type', "text/plain"}, L_H_HL), [] = ?MODULE:to_list(?MODULE:from_binary(<<>>)), [] = ?MODULE:to_list(?MODULE:from_binary(<<"">>)), [] = ?MODULE:to_list(?MODULE:from_binary(<<"\r\n">>)), [] = ?MODULE:to_list(?MODULE:from_binary(<<"\r\n\r\n">>)), [] = ?MODULE:to_list(?MODULE:from_binary("")), [] = ?MODULE:to_list(?MODULE:from_binary([<<>>])), [] = ?MODULE:to_list(?MODULE:from_binary([<<"">>])), [] = ?MODULE:to_list(?MODULE:from_binary([<<"\r\n">>])), [] = ?MODULE:to_list(?MODULE:from_binary([<<"\r\n\r\n">>])), ok. tokenize_header_value_test() -> ?assertEqual(["a quote in a \"quote\"."], tokenize_header_value("\"a quote in a \\\"quote\\\".\"")), ?assertEqual(["abc"], tokenize_header_value("abc")), ?assertEqual(["abc", "def"], tokenize_header_value("abc def")), ?assertEqual(["abc", "def"], tokenize_header_value("abc , def")), ?assertEqual(["abc", "def"], tokenize_header_value(",abc ,, def,,")), ?assertEqual(["abc def"], tokenize_header_value("\"abc def\" ")), ?assertEqual(["abc, def"], tokenize_header_value("\"abc, def\"")), ?assertEqual(["\\a\\$"], tokenize_header_value("\"\\a\\$\"")), ?assertEqual(["abc def", "foo, bar", "12345", ""], tokenize_header_value("\"abc def\" \"foo, bar\" , 12345, \"\"")), ?assertEqual(undefined, tokenize_header_value(undefined)), ?assertEqual(undefined, tokenize_header_value("umatched quote\"")), ?assertEqual(undefined, tokenize_header_value("\"unmatched quote")). -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochiweb_socket_server.erl0000644000177700017770000003141512633765070032605 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2007 Mochi Media, Inc. %% @doc MochiWeb socket server. -module(mochiweb_socket_server). -author('bob@mochimedia.com'). -behaviour(gen_server). -include("internal.hrl"). -export([start/1, start_link/1, stop/1]). -export([init/1, handle_call/3, handle_cast/2, terminate/2, code_change/3, handle_info/2]). -export([get/2, set/3]). -record(mochiweb_socket_server, {port, loop, name=undefined, %% NOTE: This is currently ignored. max=2048, ip=any, listen=null, nodelay=false, backlog=128, active_sockets=0, acceptor_pool_size=16, ssl=false, ssl_opts=[{ssl_imp, new}], acceptor_pool=sets:new(), profile_fun=undefined}). -define(is_old_state(State), not is_record(State, mochiweb_socket_server)). start_link(Options) -> start_server(start_link, parse_options(Options)). start(Options) -> case lists:keytake(link, 1, Options) of {value, {_Key, false}, Options1} -> start_server(start, parse_options(Options1)); _ -> %% TODO: https://github.com/mochi/mochiweb/issues/58 %% [X] Phase 1: Add new APIs (Sep 2011) %% [_] Phase 2: Add deprecation warning %% [_] Phase 3: Change default to {link, false} and ignore link %% [_] Phase 4: Add deprecation warning for {link, _} option %% [_] Phase 5: Remove support for {link, _} option start_link(Options) end. get(Name, Property) -> gen_server:call(Name, {get, Property}). set(Name, profile_fun, Fun) -> gen_server:cast(Name, {set, profile_fun, Fun}); set(Name, Property, _Value) -> error_logger:info_msg("?MODULE:set for ~p with ~p not implemented~n", [Name, Property]). stop(Name) when is_atom(Name) orelse is_pid(Name) -> gen_server:call(Name, stop); stop({Scope, Name}) when Scope =:= local orelse Scope =:= global -> stop(Name); stop(Options) -> State = parse_options(Options), stop(State#mochiweb_socket_server.name). %% Internal API parse_options(State=#mochiweb_socket_server{}) -> State; parse_options(Options) -> parse_options(Options, #mochiweb_socket_server{}). parse_options([], State) -> State; parse_options([{name, L} | Rest], State) when is_list(L) -> Name = {local, list_to_atom(L)}, parse_options(Rest, State#mochiweb_socket_server{name=Name}); parse_options([{name, A} | Rest], State) when A =:= undefined -> parse_options(Rest, State#mochiweb_socket_server{name=A}); parse_options([{name, A} | Rest], State) when is_atom(A) -> Name = {local, A}, parse_options(Rest, State#mochiweb_socket_server{name=Name}); parse_options([{name, Name} | Rest], State) -> parse_options(Rest, State#mochiweb_socket_server{name=Name}); parse_options([{port, L} | Rest], State) when is_list(L) -> Port = list_to_integer(L), parse_options(Rest, State#mochiweb_socket_server{port=Port}); parse_options([{port, Port} | Rest], State) -> parse_options(Rest, State#mochiweb_socket_server{port=Port}); parse_options([{ip, Ip} | Rest], State) -> ParsedIp = case Ip of any -> any; Ip when is_tuple(Ip) -> Ip; Ip when is_list(Ip) -> {ok, IpTuple} = inet_parse:address(Ip), IpTuple end, parse_options(Rest, State#mochiweb_socket_server{ip=ParsedIp}); parse_options([{loop, Loop} | Rest], State) -> parse_options(Rest, State#mochiweb_socket_server{loop=Loop}); parse_options([{backlog, Backlog} | Rest], State) -> parse_options(Rest, State#mochiweb_socket_server{backlog=Backlog}); parse_options([{nodelay, NoDelay} | Rest], State) -> parse_options(Rest, State#mochiweb_socket_server{nodelay=NoDelay}); parse_options([{acceptor_pool_size, Max} | Rest], State) -> MaxInt = ensure_int(Max), parse_options(Rest, State#mochiweb_socket_server{acceptor_pool_size=MaxInt}); parse_options([{max, Max} | Rest], State) -> error_logger:info_report([{warning, "TODO: max is currently unsupported"}, {max, Max}]), MaxInt = ensure_int(Max), parse_options(Rest, State#mochiweb_socket_server{max=MaxInt}); parse_options([{ssl, Ssl} | Rest], State) when is_boolean(Ssl) -> parse_options(Rest, State#mochiweb_socket_server{ssl=Ssl}); parse_options([{ssl_opts, SslOpts} | Rest], State) when is_list(SslOpts) -> SslOpts1 = [{ssl_imp, new} | proplists:delete(ssl_imp, SslOpts)], parse_options(Rest, State#mochiweb_socket_server{ssl_opts=SslOpts1}); parse_options([{profile_fun, ProfileFun} | Rest], State) when is_function(ProfileFun) -> parse_options(Rest, State#mochiweb_socket_server{profile_fun=ProfileFun}). start_server(F, State=#mochiweb_socket_server{ssl=Ssl, name=Name}) -> ok = prep_ssl(Ssl), case Name of undefined -> gen_server:F(?MODULE, State, []); _ -> gen_server:F(Name, ?MODULE, State, []) end. prep_ssl(true) -> ok = mochiweb:ensure_started(crypto), ok = mochiweb:ensure_started(asn1), ok = mochiweb:ensure_started(public_key), ok = mochiweb:ensure_started(ssl); prep_ssl(false) -> ok. ensure_int(N) when is_integer(N) -> N; ensure_int(S) when is_list(S) -> list_to_integer(S). ipv6_supported() -> case (catch inet:getaddr("localhost", inet6)) of {ok, _Addr} -> true; {error, _} -> false end. init(State=#mochiweb_socket_server{ip=Ip, port=Port, backlog=Backlog, nodelay=NoDelay}) -> process_flag(trap_exit, true), BaseOpts = [binary, {reuseaddr, true}, {packet, 0}, {backlog, Backlog}, {recbuf, ?RECBUF_SIZE}, {exit_on_close, false}, {active, false}, {nodelay, NoDelay}], Opts = case Ip of any -> case ipv6_supported() of % IPv4, and IPv6 if supported true -> [inet, inet6 | BaseOpts]; _ -> BaseOpts end; {_, _, _, _} -> % IPv4 [inet, {ip, Ip} | BaseOpts]; {_, _, _, _, _, _, _, _} -> % IPv6 [inet6, {ip, Ip} | BaseOpts] end, listen(Port, Opts, State). new_acceptor_pool(Listen, State=#mochiweb_socket_server{acceptor_pool=Pool, acceptor_pool_size=Size, loop=Loop}) -> F = fun (_, S) -> Pid = mochiweb_acceptor:start_link(self(), Listen, Loop), sets:add_element(Pid, S) end, Pool1 = lists:foldl(F, Pool, lists:seq(1, Size)), State#mochiweb_socket_server{acceptor_pool=Pool1}. listen(Port, Opts, State=#mochiweb_socket_server{ssl=Ssl, ssl_opts=SslOpts}) -> case mochiweb_socket:listen(Ssl, Port, Opts, SslOpts) of {ok, Listen} -> {ok, ListenPort} = mochiweb_socket:port(Listen), {ok, new_acceptor_pool( Listen, State#mochiweb_socket_server{listen=Listen, port=ListenPort})}; {error, Reason} -> {stop, Reason} end. do_get(port, #mochiweb_socket_server{port=Port}) -> Port; do_get(active_sockets, #mochiweb_socket_server{active_sockets=ActiveSockets}) -> ActiveSockets. state_to_proplist(#mochiweb_socket_server{name=Name, port=Port, active_sockets=ActiveSockets}) -> [{name, Name}, {port, Port}, {active_sockets, ActiveSockets}]. upgrade_state(State = #mochiweb_socket_server{}) -> State; upgrade_state({mochiweb_socket_server, Port, Loop, Name, Max, IP, Listen, NoDelay, Backlog, ActiveSockets, AcceptorPoolSize, SSL, SSL_opts, AcceptorPool}) -> #mochiweb_socket_server{port=Port, loop=Loop, name=Name, max=Max, ip=IP, listen=Listen, nodelay=NoDelay, backlog=Backlog, active_sockets=ActiveSockets, acceptor_pool_size=AcceptorPoolSize, ssl=SSL, ssl_opts=SSL_opts, acceptor_pool=AcceptorPool}. handle_call(Req, From, State) when ?is_old_state(State) -> handle_call(Req, From, upgrade_state(State)); handle_call({get, Property}, _From, State) -> Res = do_get(Property, State), {reply, Res, State}; handle_call(stop, _From, State) -> {stop, normal, ok, State}; handle_call(_Message, _From, State) -> Res = error, {reply, Res, State}. handle_cast(Req, State) when ?is_old_state(State) -> handle_cast(Req, upgrade_state(State)); handle_cast({accepted, Pid, Timing}, State=#mochiweb_socket_server{active_sockets=ActiveSockets}) -> State1 = State#mochiweb_socket_server{active_sockets=1 + ActiveSockets}, case State#mochiweb_socket_server.profile_fun of undefined -> undefined; F when is_function(F) -> catch F([{timing, Timing} | state_to_proplist(State1)]) end, {noreply, recycle_acceptor(Pid, State1)}; handle_cast({set, profile_fun, ProfileFun}, State) -> State1 = case ProfileFun of ProfileFun when is_function(ProfileFun); ProfileFun =:= undefined -> State#mochiweb_socket_server{profile_fun=ProfileFun}; _ -> State end, {noreply, State1}. terminate(Reason, State) when ?is_old_state(State) -> terminate(Reason, upgrade_state(State)); terminate(_Reason, #mochiweb_socket_server{listen=Listen}) -> mochiweb_socket:close(Listen). code_change(_OldVsn, State, _Extra) -> State. recycle_acceptor(Pid, State=#mochiweb_socket_server{ acceptor_pool=Pool, listen=Listen, loop=Loop, active_sockets=ActiveSockets}) -> case sets:is_element(Pid, Pool) of true -> Acceptor = mochiweb_acceptor:start_link(self(), Listen, Loop), Pool1 = sets:add_element(Acceptor, sets:del_element(Pid, Pool)), State#mochiweb_socket_server{acceptor_pool=Pool1}; false -> State#mochiweb_socket_server{active_sockets=ActiveSockets - 1} end. handle_info(Msg, State) when ?is_old_state(State) -> handle_info(Msg, upgrade_state(State)); handle_info({'EXIT', Pid, normal}, State) -> {noreply, recycle_acceptor(Pid, State)}; handle_info({'EXIT', Pid, Reason}, State=#mochiweb_socket_server{acceptor_pool=Pool}) -> case sets:is_element(Pid, Pool) of true -> %% If there was an unexpected error accepting, log and sleep. error_logger:error_report({?MODULE, ?LINE, {acceptor_error, Reason}}), timer:sleep(100); false -> ok end, {noreply, recycle_acceptor(Pid, State)}; % this is what release_handler needs to get a list of modules, % since our supervisor modules list is set to 'dynamic' % see sasl-2.1.9.2/src/release_handler_1.erl get_dynamic_mods handle_info({From, Tag, get_modules}, State = #mochiweb_socket_server{name={local,Mod}}) -> From ! {element(2,Tag), [Mod]}, {noreply, State}; % If for some reason we can't get the module name, send empty list to avoid release_handler timeout: handle_info({From, Tag, get_modules}, State) -> error_logger:info_msg("mochiweb_socket_server replying to dynamic modules request as '[]'~n",[]), From ! {element(2,Tag), []}, {noreply, State}; handle_info(Info, State) -> error_logger:info_report([{'INFO', Info}, {'State', State}]), {noreply, State}. %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). upgrade_state_test() -> OldState = {mochiweb_socket_server, port, loop, name, max, ip, listen, nodelay, backlog, active_sockets, acceptor_pool_size, ssl, ssl_opts, acceptor_pool}, State = upgrade_state(OldState), CmpState = #mochiweb_socket_server{port=port, loop=loop, name=name, max=max, ip=ip, listen=listen, nodelay=nodelay, backlog=backlog, active_sockets=active_sockets, acceptor_pool_size=acceptor_pool_size, ssl=ssl, ssl_opts=ssl_opts, acceptor_pool=acceptor_pool, profile_fun=undefined}, ?assertEqual(CmpState, State). -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/src/mochihex.erl0000644000177700017770000000400312633765070027647 0ustar michaelmichael%% @author Bob Ippolito %% @copyright 2006 Mochi Media, Inc. %% @doc Utilities for working with hexadecimal strings. -module(mochihex). -author('bob@mochimedia.com'). -export([to_hex/1, to_bin/1, to_int/1, dehex/1, hexdigit/1]). %% @spec to_hex(integer | iolist()) -> string() %% @doc Convert an iolist to a hexadecimal string. to_hex(0) -> "0"; to_hex(I) when is_integer(I), I > 0 -> to_hex_int(I, []); to_hex(B) -> to_hex(iolist_to_binary(B), []). %% @spec to_bin(string()) -> binary() %% @doc Convert a hexadecimal string to a binary. to_bin(L) -> to_bin(L, []). %% @spec to_int(string()) -> integer() %% @doc Convert a hexadecimal string to an integer. to_int(L) -> erlang:list_to_integer(L, 16). %% @spec dehex(char()) -> integer() %% @doc Convert a hex digit to its integer value. dehex(C) when C >= $0, C =< $9 -> C - $0; dehex(C) when C >= $a, C =< $f -> C - $a + 10; dehex(C) when C >= $A, C =< $F -> C - $A + 10. %% @spec hexdigit(integer()) -> char() %% @doc Convert an integer less than 16 to a hex digit. hexdigit(C) when C >= 0, C =< 9 -> C + $0; hexdigit(C) when C =< 15 -> C + $a - 10. %% Internal API to_hex(<<>>, Acc) -> lists:reverse(Acc); to_hex(<>, Acc) -> to_hex(Rest, [hexdigit(C2), hexdigit(C1) | Acc]). to_hex_int(0, Acc) -> Acc; to_hex_int(I, Acc) -> to_hex_int(I bsr 4, [hexdigit(I band 15) | Acc]). to_bin([], Acc) -> iolist_to_binary(lists:reverse(Acc)); to_bin([C1, C2 | Rest], Acc) -> to_bin(Rest, [(dehex(C1) bsl 4) bor dehex(C2) | Acc]). %% %% Tests %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). to_hex_test() -> "ff000ff1" = to_hex([255, 0, 15, 241]), "ff000ff1" = to_hex(16#ff000ff1), "0" = to_hex(16#0), ok. to_bin_test() -> <<255, 0, 15, 241>> = to_bin("ff000ff1"), <<255, 0, 10, 161>> = to_bin("Ff000aA1"), ok. to_int_test() -> 16#ff000ff1 = to_int("ff000ff1"), 16#ff000aa1 = to_int("FF000Aa1"), 16#0 = to_int("0"), ok. -endif. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/README0000644000177700017770000000127012633765070025433 0ustar michaelmichaelMochiWeb is an Erlang library for building lightweight HTTP servers. The latest version of MochiWeb is available at http://github.com/mochi/mochiweb The mailing list for MochiWeb is at http://groups.google.com/group/mochiweb/ R12B compatibility: The master of MochiWeb is tested with R14A and later. A branch compatible with R12B is maintained separately at http://github.com/lemenkov/mochiweb The R12B branch of that repository is mirrored in the official repository occasionally for convenience. To create a new mochiweb using project: make app PROJECT=project_name To create a new mochiweb using project in a specific directory: make app PROJECT=project_name PREFIX=$HOME/projects/ rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/rebar0000755000177700017770000027203312633765070025603 0ustar michaelmichael#!/usr/bin/env escript %%! -noshell -noinput PK-qM>÷d getopt.beam…X}lçy¿ãË#ÍW>êhËvçì£#;ÔÇI¤,Q±œW¢hÖŽc3%´s’"O%ŠdÈ£mµq«Xv*×ñ¬ÔI¶af (P ûÈš¦-º?æfÿ Ã: Ú% þ«4X XW`¿÷î(QÍÖ xŽÏû¼Ïçïy?NwêüçF¡ï¥™ÔôsÓf}E\ÿ-BÊ»`˜õ†éi›-Ãk4«ÅÚ‚k±ìm™ÍJmÁkÖ—ZËc.6ë—=F³Yozª•–Ùò5K,\õeÏ¥bµmˆQÏ|±Ú2B–£<\Vêµ|µ^[ð-«ó•ZÙß®• 0F¹§RƒM¥ìhíßaRlµ* PÊ› ½;-Q«Q­˜;µvØ·ëMÓm6ÛÆžòšqÅäÚ¾¹z½jk¤V7{W*ðS[èò¯ðTó5 ¶eâàÞb£a@ŽŠíªé̵ü(mÅX™3š{Jõ1·¢Õ­Ì~M å[ £”7W†Ï¬Û¿•ši,MÏ|µ^4½s•Z±¹ê.¢O»9Üy¨9´3¶4{:#Û"ØrK ¿Õúe£é+–uW¥ÅÈshÈÔäTÐ[mãjˆz0pPê è|ÈU­à|ài·Š †«R÷Î×›+EÓ3_¯–«¾ùjÑ4Z5›/­”óU4>ÈÓâéñ4©=ç ¹gÇ(אַÝÅòVïjÃ[5j æ¢¿ÜÆ"(MÃW2*ð¼àAQµÒ®•z¹]5ì|}7Öu¾{ÈNg[ëÑZþÁ‰Ö§×ï¾ýæ]ÿ`üíwƒjƒinV »U:æ“UF4Vœiá Yö©º\O©JÚ&§T’þvZé•q“•’ìÝ’·Aeñç×9X|/Xh0%Âb SÜpÁHœ•fY6÷zâoÉä#¢ÎA™!²}¤|˜x¤M>Ò2,§„rL#ÐbW=2s‡YUS$’eacY…Í&Yœx27 âýè#òPV…T“î‹tOþ(ÞNeEmUd•£¸Áÿ¯µ<8CÄO\½ÿÞ%9Øh„ÜŒ”Y‰°l˜%QIœi³LɹeúX‚†È$ˆ—PB -I²p–Åc(€Íj¬Là²ÌK—^kz[’å³Å´‚iQxMÞt˜u-­Hr³a”%íqõ”5QÚ\[cJ™i9++××B¡a–°dœÅf™fZ©ö!ÕI(ÎZíÌYí„J‘XYa1¾ .Féèãc“„Ê!sCnüßУš#\ÏÄ*}ÚRù ©<‰Tx“ŽŠRœ*y37DéèvWÜ;ºrŒwå)@¶¯ JÑ :ˆ¥ÔJЧ²“ Lpsm&+\ŸÉêwɱ»ÝÐÅ9ªÀ¶ÄÓšÒØ,1˜ x„X’>9ƒÀÙôõt /•EÚ[ðäxe›¢4ÀL%dò=¹¾¡¶PÀ1•C}‹£P{óKƒqúTr;¹BÉå\‹‘YÞפ›ÅÂL‹0%nç4„œœ rVŸÂ^‡:à|&ÛÃÀå1U”ô #ÓD‹%è¨6 ÊÌhrrFS³Q:šäKd4ËŸ#Š(ë:wñaZÃR¹êakJˆ÷Ü‹R”F·¸Xœö@+Ž(el‚&œ(ˆ2Á£ˆ¢g!@ÅY5ÈP±Œò4¯IÂÏvlòXܧoFéqœ«lÊ”â&St\”ŽZQçç$ÎPšL”&ì<ÆD)§qœž “Ø “Í k z ÔT$„¶ž¨StJ”N€×8 ¦d]åeÃ>x:)0Ô8 Š ¨vNžÏ Â!TÊôDx†dzt~ØZ»m1B§‘–}±ðîá@ÂbH;[?œæiV"½:L/Eè ¹Æ¯C>ž‘7(ÌW·u(‘íFí$Fi³ šBà”uÄóšS:MòßSPÐYZ§çÉÓ„žï»ˆÐÏŽÐÓ'é™@?}6°Ÿž¥Ï"‰sò=Q:m1ï‰Ò‹¹/JÏZÌDélÌ/lŸü*Á*y;Á:¶ž³/~™¾¨Óçy¤çûX ž{Hq¾žÃ‚°´ÎÛɰÀ ‘äOùó|Ÿ~Ya 9’–­§j=uëɬg&J/4àÎÁ3wsa—G’IºÁùàB‡‹èçIzÍznZÏ{Öó=ëy?J¿@Ò(åóŽ‹/Ø.pþ·àbX]LЗfÁËé¢(½¤cŒª }`÷E`ø2pË‹ÒQ‘W¦Ë¢ô²Í-ˆRÞææD©à„)Âõ(²›ëÁ»É|:5¸O£=¤%€U¥`ôDè–-Ä g™­ubƒ6w1ü.LÐ v–¢¥‹Š_ÇÓŸPp·Øi,ÚÛ°§óÄÉc †q.OкcX…a?]¡(U£´¦ø‡DiÅv‚ªj¶“zœ.uœà%-0œ^ ªxKÁÅÅWõå­÷ ®á…%E\$å&$ÆDú"©RFMnŒ•Û ê:7Æ»–ù´ýšm&¶÷Fq'06¹l÷v0ÃBÖÑHœs{AàNñ&á·Ñul‘ U÷éRowËÝoX>YRþŸ —tØ]†{,ŠUQºÂ%¨iu‚®9Üœ'W´LPG^ö)'gqž–pÚµî—(}µ Ð/ád•× ©lZ ‘”ý‰–ò«η¯ŠÒ—è—Kй×H•ºt>­øeæ²™WèUxåçgEIaù*JK½°8ÁÍT§²Ž"Ŷ½:@¿R²mK¶­$ÿ&ãO{ø l-Âe§Xvö¼(}µsõEøQ½ 8×âô ö¢JÀ_¥×€è `|-(È€™·p{r“S€ûú½éÀ½¸×-¸w‚ÍZü¸mÙx¿^âwØ +CfgˆäNðä7Dé†ÌÖRYPÔlÉëQú5Þ"Èýƒ¥®‰¯É÷-QŽ‹,±µDiƒ_ïaeC•Ý:½e¯3”}•ÝŒÓuç^ú:ê9 $nÓÛÊÈ…=r¶_¯zdiQ®zÔ5ÿ^Eé§oˆŠ<®â¿5Y-*ýBñµ~ùeÃÓ/ôËýBÞƒ•_èø{Êö&þA“öÊ÷åT$-…•Qœæ©öCI)ab]1oÈRoGëMÅ&€¶˜óÐ0ârE³mnãxÀÏo£€iÔt‡'Úg'Š@ýtS$à™âZ›vµoB9‰.~ƒõâ6‘ö‰Ò].ù[ U 7îÛ¦ÐäwômÂoç•cüï1þZ|‹dÍfŽÿÃzz¥_ñØ rƒDä¹@~PÀ‘wx—£O»tdGÆÉçèÇw‡¼Kÿ‰.ý£]:Ǻø§ºøhWn]r©‹vüwÅšpæ9ŸèÒº‹¦«FÖUãL—Îì¯ñ®ÔŽ¡pÖÁ+éÌ¿åðüï 1Û¶Ãsû–Ãó8¯8¿j׸ÏÇ_)GþŽãOð|øÑþ³3go=WþàÂ?L>d²çÁ?íûÅ»ø­Í¥;÷þ4U+þÞÜ‘÷{ƒï?ø›Ã·o÷ýç±7öyß¹³ú—õ›‹ÏÎþäg§nFÏè¾¾¿þÕôþ}ú…nßïýÝôk/dþîáðÔ÷.ý›f^ýó¿ú³ÂÏ#ÿzæON¾~þÞ_|÷ŸOÿDü1ùý÷ÿ+úGgG®ýðæ·f¾óË[G~u<þ¯üôÇ|ü­úÏBãG…³õR÷Úê®aÚ©ë褃Å-Д£stÂѹštä«Ïå—Aq‡_Å~4êðs Çö"Hwä/‚†> Ò4è°#ç½=äÈùZP9_/ù˜Ó#—ã{Ÿ³ø:Ý+Ø{€ûÛãÔxÐáEÇNìµËuw;ú²ã¯qiÚ4›øýx½Ê=,ºÊ¹ÔªñX“…ô©ŸWzèïýE=ýͯÿÈWðÛæb½ié”e©]¬-ÕY©¾bT«ÅÖP½¹`©í2®4êMÓúvÈu}\(Y_÷ ) |èçCëÛ¬=–:_í!mUVÕÎ'7[¶õv­¼Cêíìê|fµ--%O׿‘À/­Ý\Ãç|Äã/âX_ó­öÊJ±¹jûk›åJsYps•—ˆ•eÁW©•ªí²Ä·>/Ì•ËB`æÂé³³ùÜéçRËÂîQ}dD‰åõ1=ë(I/$³ùÓçN_v-TLu||D/Îé^>þ9I- žøÐøÐ(—¹ÍÊŠ±èÅ*ó}TtiÑSôƒV‚­z»Y2–…Èð"^6jK•áV³4Ü4æŠM‹³?›Íê’0=×2ù¾þPK-qM>ûp² T mustache.beamX påÞ½ï~ö.·dïöBágÃ&’l²’K¿Ü%9ÂOˆÑêår·IŽ$wçÞž`ÁB‡ªŒ(2“Q´Ò"L¥S D:;E©uœi©ŒÅê@U1#¢U«öýöö’«`m†w÷½÷ï{žý¾eÛW¬¬¥(~™¿­ey‹–¦(úSŠ¢1Ã锎 (¶Hb8RE ¥"á¸5¥©±x¿)1h'¢dXM)yú5¤¬Oª)ÝP¹;<äŒ+ëB½±x¬Sf¢³€4­˜#‰¨bI¦Õ~Å>”GC}Þ:œˆ¦‡3áíªbHMªbS•äP8¦ØÓñ¨Ò‹+Q«ª«š£±ˆ†`)[(1B!KJK¨Še(–ÒR¶¾¡°¦)ñ¼¤ª„ŒB¬_ò¯¬´(ªšPC®"5· ‡µÈ€5•î…*éJ[<¡ ò ›PJ‰h±D܆V…´Dˆ¬âÌ*µpŠKhŠ6Çq%/GÅjÊ0T¢)Ð2mÀ²n @ýŠ%Ç£Nˆ$]}鸾 ihBÕ”¨YSÓŠ¥/<”RÌ`”ÊÅ5¥_Q³)XcäÞkíK¨¯U9%IçîV`,аª™b‰¼LC±x_"VåüÀL(*o%Ìž£2[:<4grÏâh¡¡Mâ8¤x³ÀºmåkCMmHò#Š÷#N¬lãWbÙ8.£rmb‹(¼m,›m”€Íh+GÙéú8‡!Ž›âiÉ "³™cçe,‚ÂÑx1¢» 'îq æÍylÆX»Ë—FMéÌÚ•iþ}ÎÆõäÈõEÒlãqPa1”DNr]\;æƒOÐtÀ?—9[«î.ý—{¦Öëã6¦3µ¦oTëuq²µ&¡ªÍ&·c2G︾ì#½‡(ú`à ääHÙf®LW‹ØQ€,Ò5Ž>Öp†Ÿh µ›yŒDh húä÷«Þ!±%z¬å €„Ebe#¾aÅpNNÒ#ðØ1Ù¤êZÊ1ÜŠf\e:˜¹’à«RÌ{pC“»M8èc=¨ h¢Y¬‡Lô Xó{m|,ïiÂ~…üޝdyäðp]R;–ɸx˜ˆe—¢­3›ŒƒIÞ&#©7£,·1Â1ÈØ=ˆáNJ4ã¾3y d>ÙÇNᛀ°Ÿ§D?/È•ìÑá™´c>J@šMxÇÇB–E¹Yñ±‘-Ò'ïc‹dPË‚_¦Vùe.Š@K µ)P¤Šñ§¸½ ØÒ²eô8(FA1*øG©ÓþQî¼—-:Ž]<^%b ላvšØ„ý"%ûE.PÉN“§Ôe`råqÀ£ç ð €¥cÜðˆáà1‚™,ƒÆ™Ð‚Æ 3•‡‚¶&ol&€–Œa ¡† úØY0„Y¼C(§|û-Üd;*ø–ÞkÁ 'BÙ²Ø)ÑLxÏx—7²sQ ’Ul™Ü,³e…Ø^Âζo`çÐÌl/[€´ŠIˆ9äÇ$Nò±ðƒÇ@5F^uo2ê™lÈó ÞdÄŸløÚsúj5îDnZÓ ø¢ôú'Ó+ÿ±â-‰›ßå8‡§žþÙüáÓÛ¥’bÃgÞ#û ö|Kl’/ü©s¤þ¦¯¸w|yjÓÆþüuîÞüíW®|uôêºBÞ?§äÂÕŠ!û©NljG=ϬÚï·Þ\qâÛÞ7†~û^ôøKÇ~tâ_çZ¿ž÷—ý &¥w-½å½g…ß4V¼‘xeÝŽ£õ¼”'¾‰wþÙóH„E/|àÒ®í›êßž;8µqß¹Qׯ¬É{ªä}¤¾½º`ás5îýqWþ‡>ìTk×>!?£í8ÌÖÜñú‹_ܹ?ioyüTeásSžÌw‰|»´ú½èŠHÃ¥·ñmþxŠ×öß~áÔ_ÕCw>ôÔËWvÜZ½q[ÞÅC÷_Üùe×ýor‡~î¸zyûê%åÛŠÎT·žž¶|CËÎÙ·ßüþyc£Ý¯m°Ü¶åŸ¿|àÕ»ÂMÿìàñç®|ݳvó·žµ½TV÷tÇþÔ»ý¾¶Ï«?p½q-@[ßC}|íÈ7Ôµ¯ÎGž°Ä&ýý¾ºû~õû3›¶]zpßeq?¶©ý¡ÚG›ßPÜ¿ÃÒtÏö×¶ßÕû» [/.}zïü¹wmùÉœ ò³¼Põ¡ϟ?t0öÙÚ©M]»ëw>vàòÙ^½¼ì‘æâ§Ç\íÿíà¼Gw|Ú!Þ±æÄË»_|äêÅà¿g?ºÒýɱﻎì©Go ? rebar.app•VMÜ ½ï¯@+í-ªÔö¶ÇªýUo«QDÀ¤´P>Fö¿v¢NvC›Sb?óbžY¹s¨Úšy˜¸îØÓ*!¯ÝÙ|ÿµØÙÜÌìSÒ(Ù7kñþ%ƒÙz ôaûZ¬La`Oó½y^#ŸŒ£°‹Óƹ1E¡îžx€NaÒ3åó@x¸!Sƺ]‚#ꔚãé™Üd0ï;»iáñØ#qû‘¤;MìHå¤-þQõèÏådÄ -ñ‡lt¥êNg}ì$vÞF;%¥Bh ÞK÷+ÚÇ3áTIÐô{ÀåÙ󹣜¿’ÎùËq¬Bš¤öDê‹CNöIr³ç’80Š{Pמ¢½%`I!rñØá¬#fr= ³”l¶Zù ÞÀ å Q¢žªpË易\0ì3(ž0²Ü“ áxñ®Ù6¾ÚÞ[Ÿ“Tc÷ý°SØÅ—Ï}¼ãæ”%³ܭBÐYa7 ÝÅn ñ"®•­]sßhˆ¼¦`5ÑF5(ÙT5ð&»-äá†óL\p ´Ò¢Í`‡¹ÒZ…ᳬ’‰€öÄ#WéJÙÓ4ªÊÖ8"bšSˆˆi z™æ4!š²MÄ“‡@ß^ ¨Ô†-¥n TjjÌSøÊ‚€Ö$œ€îæ_'àíIÞ=kÿs‰™H ·9Ö­®ØYóëáåÝÝPK-qM>ï”×Öä rebar.beam…X \WºŸÉ$dŒ ™ˆ‚ADy@ex„‚¢¼´Uã$ WgѪ-Ý֊תh×ZëÖÖG‹Zo}õ^ÝV[mu«^|kÝvµÞV«n[ÛÕj÷;“AÙ½÷öòû}9ßùÎw¾ïÿ=Î9ü¦|âä, Ó],±W| #ö`Ö¨x;'(=œË«âÁ'„5q.7ï ã7çmV¶pî€Âצpùš|‚‡ BÐÁùýn—ƒ ¸|^¥ÛÇ9Õ ´qÁÙaaŽ?àS‰N„K¦mn_³ÒåuÔ¼è\þ@Dh°y9O6/Ĩ9»ˆÆÈЇÏÛäjÖˆ|ÀÖìöÙ9wxÐëä›\^Þ©i~$T9y{°™¡mÁ€Ë-ª‘‚£ÝIÚ9‘·9]‚Æçç «HøƒM¯ §ý‚ÏÁ‹"L<Îë•-¼Û|þ€*(rͼÆÏ `†šE•Īgñ‚Ý'ò*H‡ƒ'‘³VŸ]T¢Ÿp°‰b8’ÏâÜA>, Ú&b–è•¶ñs¢ÇgkrsÍ’1»ÏçV„ 8àÜ"¯[|í6—·Égópsì¼ „ìÅñØ-€KpyxA%ºyÞOzpeý¼Ã†à„¹|0ÚÕ.o€oæ…HÈz€$Ÿb˜\Þæ°€¯÷Š‘HÝðÙ8蕊Zàvž’J…ãƒ^În‡%àmÿ´©€fâì>!0PªEŸE›8—öˆaÞcç….ñÿÐó PòÙavÎ éú¯zbÐnk÷ Îǯ!ÿäÿ_uk„Çç ºy)»QiŸùˆô_ž™•îv$Í0ÂhL’þ¿•(3;½)èMÏþõå¬__6¦÷O—OÖ?¹„ƒ[êsò¦¾,…þ:8 8­Ð¥q}$MUæ*é n,Ræ[ˆ‚zB_B`L ARë™ìÔzC M4Fãlj=!hi¯¡õ´…P0¬#Ôzºw}¦B»Æý`’%”¬–PÓúÔ„À*‰NSÒ”VEÿÃ;Æx—B{’Æ×›{ˆb‚1˜{˜bÆTšÞc*4õIJá³v…·»S{J­tN!ÔÏ „cðH¬$¦eñg!¯j̘z•Ô ^£•àÔ&IkÔôL–`X  ÒûYMœÌv„"1°V#Hâ µ±K­ïU")ãÀ%× &Iú_n+´†“tFkeÁH‰µÎdHö3X‰d'µýŒ€,IRJb¢“Ôú+ùTQô(ÓF*Ž)d¨¸X6›bJ‡“ è@Çé5–0S‰.µ”*‹‰G~†ÍF`¥ Hé7â¤îÑØ@À†etȵž2¤R±P M Ã&0ÌjFô²jì6cÁ¬&•` Jµ‘¤Ó¨þPB‚‰V"!d'û#ôÊè$V“2:Š!4qRž2B1,´„Žè4b`Ö¨¢©ZYLI¨õ¬d öcÍTvè SY†bƒ©4‡Ê.e‚5)f«d:i=:iJÔ>*è°–JZ¯·0:Ô¨H )Ê~„œŒ•®ž¾‹¦*“»hrNæ¬29tãÀ9 ¨zž™* "õ4 DÕ†;b´™2Ks¨|d°wÒ4,ä!wJ‚òl†UBªÁÿXÊ ¢§Y‘€E3zn r¨QF!ÀóÑý>¸Ç¨\ˆNL-jM8G0ÈH¡(’:` tÀXœCë1‹Nj±EbŠPýY°Z i+~ÔÅ`d°‘*CFÊÀH.U†Jq²äQšËA¿T2QFér=4@•%šf¬YÀf5ŒåÒaSB0áê!1pC$°„IâCR¥TLIŒŽG!ZÁ@ g¦ÆC~ &3UÅDêÙbšÃ m‘@V#ÕR¤´'+PaCv`¥r|UEÁ…“ƒYA¡±Å?\M‚jO„[ê›j@LB@¨'qr2ka±ÖL5 ^P:Ô‰=Y º*‹T#ÂÓ(%­0ÕãdÝ£¤ÕB£Õ‡fpªAзr¨ÉS#Â4œÕ¦©að|áä0­‡é“0MÃÉi0m€ét˜Ì0m„Ñf¦fð˜¡î”N‡”PH?zËúºš™CÍ óÚ€P‡÷ F| °CT@a@8 ¤ŠŠ”åý€¢äÿ ÐÿÑ2¯bd^Ô_ÖŠ•í ~€Ì£½œA@ƒå½ƒ^ÖI”q!;I@Ã0ôt†øá}lŽ”÷¦¥Ë6{ù^üY2ä&™G1šeûù@2?ºOìE@¬Ì#lŲN úwIæ‘N¹¬ƒb±Ê<Ò©èÃïc‡÷Nš(Ï‘|²,ïå–Ù¨FX•\›Iòú$™0y¦ÌÇ%Ë:¨&YN˾‘\QôöÚD~déòˆ)ƒNT×zyú¤¼#Æö †:Y>U¶‰aÖôT¹ W¾ŽašE³×,i˜>ñb¹.˜qpùùJÏÊïoþ±¾lùÌsÕ/lXá½€%nÖY&­úžßUâ˜{c°ûÏSLwµ÷º3¾üpáºÏh80+aû qé;·..»3úÖö¯æL̨õ}÷zäÔ•Uã¿x"µºdÅ5üÔ¦×NþÜqmAÔú¨+ñgÊSõ4¼zgkÇßék·Ò×e÷ß¡íxeç"ë²LoXM¯ÔÏÛôù­‰×Ws5ÿååÓhºvêŸþ‡·7^.WW¿?ü¸ª2»÷K·Ùný—/>óŃ·ŸLL ÞKo{?úÃ}K[WZö® b–E,¿sÓ´¿‰òÚì›ãÎÕÔûGüg|µgÍ…e6©|?s]¿?8xê/;O|x嫿ûoý¨6æÙ±ƒºgú¯­ëGÇÍÿÞÚoéËÿ6åÈÚ¬ˆ%Þ;xÚw6žˆ+:ðÓ·Û6øO´ÕÞ®ùð7ÖÕ§W_^üÉ 3ó‹´iû~Z}jíþnGØÚÅBåG¹¥÷‹‡íhyïã£ûÞ\ó_O]¿´:êóUnïKíÎâÅ£‹>5¿Ü>W³Aõ÷cߦ=7JÿúÈûFäX;¿Y8ìÏ‹#·Dï©[¼r3³dikWÅœrÜ4zè°Âœs„/~Ûô]™cš%çhæí¢©·×ŸÐÎ|>bëJϞɖ5‡ï~ýñéß_<œb=þˆö'Ÿý4ýÕ‡az»)9{õ/kïwoüŸ˜üô±agîÞ|'pØY² aQSþsÓ®N{åíš6f\¼öâƒÁÏ·ÛÎŽ¦Ì‡ö+S‡ví~iw¤jMåì=U ®˜;§žßþÃëÄ¥Ÿ¿èlž÷ÖíÄ¥4ìÌêqÉ[ºy¿y×sü ê?=)¾àãM{v§¬<ú¶rÖEâádÃÙyÉuü„zs¦>ghJWÌ”n#þãü'b.œ­ST, ¬K{æÐÜï;ãÍåC~;—]óÄßï9žüת¢ý ;—œ|áðkAûŽõÎÕËVLètüìÃÏ?ß™7ï——¯ÝY;÷Ü‘>Ò-.é8ÿuI‘QñÔZ{UÚÊŸÄÍÇßZ󷌢zŽ9õSuツ1#’^,ñU–™—æt\ÞhŸ÷vd*•0¾ ±@µpÊ™1©Ÿ°H»sdꉽQ‰O%h·44vÛöžóûÎ/ÞŸÛrh(guµ}±nÄ®®Š¯ÇlnŸÿªýÂþšQô{µŽû'ÿ6×Û¹ÝìÙúñ…7»–nï´sk»ýþó>â¼W?zXY8wùíëÿžÂ~ÜòÁ¹´›7,KnEåçFuª6—t½±5©.·iÕŠ‹ª•—|%M]{[¶/<þÚ–Ó=ô•²Ok·ë‰yóQNôûlRáü_ÆmÜ‘ukVÖ󊬵»žbyøÔý»Ôñ¸Kƪ÷ÛÙàÝr†ü /ÌzáŽXoûÁèÓÃD£uÏñ%…•ó/üöMeéw;NŽ;_?½ùæØoF`«t=X•Ïî°ëXèÍj”ï7Û¿Ü…}￾w^­|FæÇUË:Y ;rebar_abnfc_compiler.beam]UlUwïÚ^oívíöCp'íœBFoÝ Lß~tµ:¶†ñGÈqm¯ë­í]½»p&"þÂÄ¢FQ !ú‡‰d@1‘80ÄH"„(üaHŒdš 4þÀ÷ÚC'M>½Ï}Þç}ß÷û½—÷†7´àá{ã=ë{l£õ$ 5dª)Å”•”žMËi£XÒ ªéq›1Ò²i6ge3­Êê6Ûc”m9£™\ÑÈ” É­šE£W¬ªÑRŠ¥þ še«Æ7J¶å«ZÒ†žÕÆà˜j»±ªº·d¥‚fÙ–‹ò„R(«žŒšUÊ›¯N×,¹dª–ªÛ®ŠÀ¤ŒêÚšÓÒ9Øíö醎ÓÁ!4}Ìï,_­Œ±Í²êÊ*Ke³XÕ•¢Ê’, ¸Êp醑gÈ(mäiÍpg ³¨Ø.;g[kœj5=kÔ‘ü¼Úœµ¢±¶lYo“ÚpcûpjÐ<¦ä· £ ÃKñtp™H‰µ#<‚ý GP@1ˆ„NFTŒ Nõ ¾¡Êħ Wl xD€ 3P¨uö¡H1- ˜Fý-ñ#”DòBt†$‘¡ƒWEj‹O‘Ààð ÿ2b;Y Jt ðÔ© ×ÂrýŽ Ó±éÞ÷SÇ©=(ÁC:ˆ"~Ì ÿÏbsPç} N€Õ¸F Wƒ@ ¾Çƒ õ‹O’ ‡pa ¸(ùØ/Ô#®ÑÏsMþ Åòxñ@ÈéC/îC¨R/ƒB jÇYFpíŒGÜRI·ÚŠªS¨Àíàgù1œà–&`g­g¼ÞáÀY›¾²>ê¬K|­Î¼FÇ þð‘óù‹o%Ÿš>±üÄ¢UW´#—®þÚU{¨nÿÒN)è…7ö5Ÿ½›ƒSGfž½¾÷ï¹wÚ^ë?’ݺªáØö'vïûcnøùÉ5¿u Íö/6™¯ïO³3æñü¡îžÀºOŸûäV©ÅòL´6ÐuA`¾œŠe¦²þ×\ÿùä’Ù߯ õyÝù×}зùÀäô¹ÃÛ'vϳæ†xYflZ~jI+ÕÝ<¯ì4ÕýÓÍ·ýéÿâÕɧÁ ‘&ub¸ïèMÂïtZE¾uÀé#ÙµNÉÜGgzlÛ$ßçÅQrtÀ K¯¼è<M&w^¿$ŸËöRîÚäøx_RÏâ1oÅÏ¿§zæZDpg€_5MÔ­r±¨˜Û‰ÁOy|È磦4(”–MOÊ5¼eŸÍš®fre2€ëÝ”ì—G“ëãyP“ÚÛ¥X{‡,uIvtÝ6±÷m”“CÃyP3¦ÙâêÕí’’’Æ+9M¨¦…“ÊWçÊÕ+cDcl­¨æÜ)¼‡.+´âW\ŠWñU¬ÞHy‹æŒ¢Í«ú¸µÌt´r¿üÇî¸ÚVâ»jWÝ“²lÒðPK-qM>ܧ=prebar_app_utils.beam]U]lU¾wïlw:»CowÚÒŸ:F:í¥qºËb[ãCãvvgJ§û3›™Ù!$Fä¥CHD$ ‰Æhš0Áê‹ÔLTâ_CPbx#b|ÐxïtjW6ùöž{ιßwæÌ½s3ÇŸé€e“éÁcƒ®UNv4ØFN³³Z¥’­ºfÑáLÇ›è¦^ yîÐIÃÍæçtvÊ,e­d03–YÑYṈ̃sfQÏk¶Î¸vÕNiEÇX'rì¼D@H",u?8A‘<Þ»µÎVä´@i†²ž ¬ó><Š KÚÁmÁm¬áæc„œv>*òd£k\¢ÔÍÇ<Aa$…kBA™'­c…ÿ´hüÿb“kblŒªm&jÍd²¥V­…ªµPµ&‘o†lÓ†ZKZ˺Zó†ZËãj_­…ªm%j[ɤµA”qFT®UE\pAø6é /J"Yœ”@")áTFF*'¨ 5É3·u“8×®±¾2ÀÇÑAq]ZæãÂSoR8oçb|dÛðqiPJ¤Hv‚d'ädŒ&8ŸLˆN7åĽ|<…åyÅah=yÕQbHÉÇBâ"V€_ALe¼ :¼ÿ8ž\«½SEtsq1²»h@<*AvyDI†lgD”‰Q¡ºÙÍKˆk'„i†ô%Fû2Oû"BVò–n'«ºd»”(Á·!»ƒ:H§vÒ]G|â]D˨kÑÃ3TªÐñ‚büs$¨#ï<–Öø×툟Ãlòí >×ý¾Mù7×øÛ|ž‚¸oSÿ6?g;T“¿£&‡Úô)¯þ—8‚.?¾Ó·?nõý­;½Åôë‹úvÄïô9þÍúu@¿GŸ?0lº´†wI¨ñÔ%ã«AnYÆÁÛß\ †"\fì‡OC;z3g_øâÞî7Ÿÿé½ô³Â?ëqpÞ\ú`²ñÆ®?ƒs^9²2þþƒ·ÆVÎõý}çÌ~gùû·W¦/ÏþÑ?w©ïÚçúýÍ×Ò½vùÜ«¯Ü‰Z«ß]\®?¿rö‘†üÑþ£‡v–—®ßzqÂ|¹å–ôåÏÇWïÿ&ïŸxºké×粓O,ê«§ïŒ|4låÇü÷ýþÒ÷Ò9èº6ý–ž)ÒÈt@ô£ïMÊT~y§ø@ÿzÿ½‰ Ÿ·Ý¸vzf&5Tž"1ÆËgh~Ȫx—uÔé€÷n™¬S-•4ûšPgU]rcäÌ2õ@³Bf9_¬ê†6®‘iDbº¸äøÐð‘ìØÐ±t4ôɽ½r_o"+ï“ûÖ“ØgS£Ù¡‘ÌñŸ4]±¿¿WÖròŒWÓ¬a;¤¨îÝÓ¿§ú×,Óu9²±Ô¯µz-âèXU;oÀ“=ÓVÉè)峇\¨=Þ­½am\í{Èí;3˜s\ºþPK-qM>ª…ß[Prebar_asn1_compiler.beammUßkEŸÙÙ»Ýä.ÍäöšÄ¦±E¸^²—k …Iâ哦1‰‚rÙÛ»Ûû±{ì¤Ä@),–€–"!àƒÒ‡R|3h}‘RŠ«øÔ?@ÄßœÙlê .|v¿óý~¾ßù|gvgç.­æˆÏϧ/NûNø`LqiEw˺gçˆÓîX-êJ‘!UÙ­eUä-«eºkFäŠîÑ'dävÌhQÝÆGQžT|«å%LÚ¢>-Sݨ N3¥„“%ŽÈ!¯—Ú^àÒ²i¹=¡§ã{É#‚áØU«†jÔÙŽSiÄ9ÁðcÔu7NÝ–n×b~Ýu¶)רM]ݧf(ÓùÝÖÛTl8–kYžïŪNËl%ÚŽ0-–]uúYõr×x4÷?¥&&sÕÀÎi9™·ÏkÊ®ãøÜ²Ù\ÔÜ[ÜYǤl·˜‰ÁѵÃp’A†XH=£Bõ„Š J“@‰5@J¸@Jê,)iR"kDT2HɬBMH¹*$IÀxªÂ8HT¿“°JöQ (pEHÝÕàFRÕxU‘Œ(a-û)Ú'¿*DÈ ˆ’F0ÁÅÞ”)–V2 «=–Ô• zq©3(Ù]¥WyùìdwÑ~JUà6)m o¨ðú«îÍ#xGHõªð É&G"›«†±Š‹b©£%Üá= lÈ畵m ²¤I -ãëð>ÄPfk p—ºåæÕ œâMdX¡´„ïHø€”¶I}È•#A)Š ÚÁ8šCTd²ÂrÇXn:®QÖ|w/úB»ÃŸ·N0 ‘2Äâ ߆žÈÏÖôEv´Îåã±.-áß4Ùc´«'^Joo=¿dù<×e¸qù–±±qh28ª‡Ëg=þ½FÆ–÷pöýoOü® =‹>>MžK¬ßÿq1÷=¼{ífá£ÕáŸþ\\\|ïðóâÁþíÏŠÅ¿‹äç/îÝ¿õ(½÷)Ì÷/ ‘{ßœU?諟ºñÉ øúñ™i–£»çnÝÝZ£¾ø%"|Ú÷¹æå«-­ &@›žÍÐÆàä»Î—/ýUùíÃÅ•›ÆÕwœ×¿î¸!Ç)7ðØaB*zE¿B7ÇÙ÷Üh°oxÁ®²¸ÖyšÄN'˱= /<‰Ê^Ðnëî•°®øì(k‘V,›{ Õ’e­À¤&è l“V-›šuÄb¦ zg^_Xz¥¼¾p±Øý“Z>¯Mæ eí¼v¡pþ˜$¿1»V^Xž»Ô‰šå«SSyM¯ha+Ò&u=&ª bçÆ§Æ'¹Oô­6­Ç+ì%ùEô>=¦÷èÉP ç®A› ?QwÚt¢Ií†5á¹ÆDxæþký÷·0ÎNÛÆtÅóù;ôPK-qM>jQ¤ô rebar_base_compiler.beamuWklǾãÉÓ‰kŸ¸ÔÓ¶|ÒÑ’mZÒQ¤,YŠã•(Š‘ã©-j¸¥Iñ(ø8úî芠‚# )àÖ@ÜN_@ Ð(ÐHŒôoàºý$à¸.‚õES è,¹Jè¦0w³3³óøvvt\:ûL\B]HÏŸž÷ìª øb‚ ÌÇ,ä\!ïš¹5»Z·*¦ƒœFÍg—¦SÉ×Ö%׬”B-³5»V²ÖåuÓËmÚ×_4 õŽ–®b¯# År=¹æE_,ÖÙR5<«â*%«VÌ• €»kmÃ\+ç*y×ËUíbGݱëÍmMÏÛ®ô¸Vµ^ù<¥Üe'_¯›Žä9 Ó_ÊW\3ÈfB¯¡ ¡Á¶ªÑ.Ô !]IÃiú5¬i"…u1K3ªØjˆ`¹%ÖC[[y”iF#4¨+ѵ]‰ÒT’¢Eª¯5ª^PÓ瑞î8¬Ãc\'t‚di‘@ˆ±Ü¨¢²ìƒÚšLÐÅËxuòXW©¤ƒ)E ê!?=°%nù Ɋ¯×Ss©ë½T‰üDéþ½x;”¥] KMD¨¥(TëP)]DÀŒ¾)!Ñi’Ð(Ä@Oá,ß JbÌ[!ÒDŠê šÒA'ñ.DêÏŠ†h<Ö©(M$!k_PÝb¹G·zd[5‚Ú+MäxÑȇÒ"é(A²zÛ·AM”ÕàL`ÿìÔ`sh‡UQîS@]Ï`‚摞€7™'©•&)®0°`*ÊäŒz[”#`?dˆrwH0žÖ Ü‹æîhúpÏ$îåVŽÜ{‰r؃mÿ Þ‡BÔ˜G(É0‚òš½ÓmàA¶}°¹}`ïåUZíb@BÑYÇÇ{EyOKä Çú–(ï¥QÒÄù¡©(ïKâ>í ² öC#P–ÄCˆ´tC»(àÂNM”‡{ñt ÇÐÇz©†õ,>$ÊúÈRuÇÈÕ–2Š£ÊA<¹Ž*‡ðAQŽvÏàQÕ0æ£(º¤‘Œ2”B–W’A¬AR’x,J•ÃäKš‘nU3Ò:«6K¶©ÀïGæã]A”G¿Ð„cñ˜ƒƒÜ€pHSÚ)a‰DS1(E9ÇSÊX7;…LPp~ ºXת!,i(#e"ÍÎMnjPûßLè•Ã-›N±t¶þWº±><,ÊGúÙsìdT”Çþ h€‰ÝY¦C‚êpe ZXfQ6zñ4à?…fñQ¤í¤ÃG‰2ÔýdÇY.:¢‹:´kQŽŸˆ8É:'ÙìœÉIœåÉfúà·/#mÃd‘l¸2l ±ö`y$vLý_“¤zW]ÒôŒbd$†ü’–È(ñ J't½¹õ`F§Q´šcõú$‹”ÃÝl ·[>Ú‡ÁÑt?{ΓÍ1FgÔG¢<ˀ廅 ÓdX<Âä–(Ñ-Ö—l¦À|ƒë— . ¤¤”}Àú† »»)vÆÙïÁ? § ¿OÌà24¸ap·`4EƒšÜeà)ŦJ7žeÊF`„µÈ Ho¾µÚÖT6 aXÃAaŠXHâ'ÙUIQeŽWƒõ"D›h鼄BDc75'”Løx´Fs˜nw¸”Ä‹ÌaœÌ‚³§Øø#:M „ÏYeÿ|–«uöþPHòóÿK  ç;€ Ô òq{Ìù]@»9ßæ|P/4´§ßËm¿¯M¾ŸóQ m±b\Îro“'¸|‡÷q›£m6ñ6›cŒO_iÖNyÍ“\?ÇyÛ±ý2ÇÂÇßþ6¿¾¥FùIrÙ,Çé)~‘뙟ã»=üÌ;óÏÍþ%6ó±îÕ ½pt¤º0½yäÙ‹vÕ³þ¯wå„ ‚ð›so|ò§«ßø`y†””Ø›ÚÙû7êÏÜwòõ±òKö;ù;ÎÛ«?µüòΣཾî? ¾|hðG«Ëeÿèkï äÎ=x¹úÝŸÿ"÷ì?÷|rïÆGK·î½ ½÷«žÆ÷Õ·/Þ¿k§>Š}ÿÜoœûãµïúþëáS¿ùéà ƒ·RûOÙk,ÿ¼'ÚkŸáx¤¦8â¿p˜àöì=Âm4 a.ïâ|7×ùxo r^åv~Þƒ„óóžçÀûàs†ø†¯( Kn­¹¨©Â­×ĹW×Ïûgß½û•þ}s3µ\+NnÚKÌ>h×=Ë®¹L( ¸ùí˜sÕjÞ¹Ê vïᲠ™«Æ$¢U‚Vm­Ò(šE¡£Q+šðÁn7èŠEAYøêò©ÅÜêòétYØ=iÄãÆd<‘3¦Œc‰©#ùk©•Üò™¥³e¡sÝò´é鸑/›Íœ.™Ž I•r|z|’É$Ϫš4ç{y_çýùŽ|¨™`ë«·,Ä'6ìª9Q6k›Ö„ë¬M4R|Á=þÓe~³lÎ\5ðPK-qM>'f]­ rebar_cleaner.beamURÝŽÒ@>ý ÜzÑè‰ ë†xW!!Ùe W&µ´Ó2´!ÓvÕ Ñë}BÁ ŸÀ;_ÂGp¦[âÚäë9óÍ×žÅÕ‹€¦ŸÏ§—Óœ¥p#Ðns¼õ¸ë'Ø£˜el–o7$ ÎZÕ=£!‰´çFB²<«…ŒcÏß5S v ™‰yâѨ#DîºÓ/í†ã~XоÝG·ŽÒÝ-r’dO]Šff,À"¸nŸH ! +Hí>°ëBŽúÐ÷j68š£÷êBŠ­v?ƒâ8]m…,å¹8!å£õ$aÙÊAí~Gʧr4Xç|#Í—éAFGÀ5ª¨ ˜5µª" ÜÉ%ß’ó“üü]éó¨ú¶^iÍ*‡Ê[=bQP©¿_éšUèɷ׿n¾Æo?’ý~¶¤b´ŠZêu©¯±CNÍ$aÐÆœ3îfEšzü½˜¬ÈÂcÐñ–PÉ($†¡~R8€FAŠƒ&î‚NÎ_./ž¹›åå<†ÎØìñèÔµÏì§§gGQýÕlí.W‹«šÉ­Édd{[{_öty&šŠÁx2˜ Æ’Ós’â¹?â·§zmÏð^«l0c÷q ‡;–âaŒéž 3îËÕú—×z 6s0Ýf¹œï_PK-qM> }ÓûP rebar_config.beammVMlEžñlì“m67mhÓnºn×I¼ŽSZUÚ$¸nÚ4Ò†œµ=I6YïZ»ëRn••¨8ô’[+õ$ªJ•8"„(U'ª •P¹ nˆ oÖ“& ,=íûùÞ7ß›íúÜååBÝçgË3—fB¯‰þ!”ïõYÍò«uÏ]³×‰ËÞîé$Ú¡í‰uVëo7âr’‡ëŽW³yÍv˜k5™´éٮ쀂¶v1ß÷ü˜·g®ÇܰËñê–g¾c¹ë±\®Ëªy~H€«»å{-Ç ›3_³œ6“¹ÇsQ*jTX޳O<;À€,Œ7˜ÃB–œ&¬Æ]¡¤Õ‚>ÎU ½ªí†lù¤i]3wP=V 4Ô­ÐöÜofîµhExv·Ý[³]ÖHÚAõók^ÀâIÎNŸÔòe’‘Òª× ƒ®h¢„ϰž¦×h; –_óú8zOÜ?û/Œ;õÌ[xã{3< ãs^ƒ!$Q8+u~‹`¯ò«±Ô1„µ^„šê9ƒV–+¤3)I!Š ¨«ØÜg¨&É”VÈô 1f ¢³DÓs+tyjE7+ˆšË$¡©g^‚ˆàU“¤;|åtŒBPNS’P5“H Õ(m“ém¢uhTÝØ¦¯ÑíæƒöïáVn[Rz˜™~˜1f3ˆÌf4š{H–û¥þ H’T%¯jjù!g?Â7L]ú?¬@;HjJ¤_Jh&tÜæ’HŒ”%B#ÊŠ —𽗣§+„nP|߬h zK%S~\zN¦ŸGãaü¹Üóâ2@Í9ºh´ðSŽ^ô€Þo`Y?`¹¢ˆR%…’i°Ýv…—{µ%“¦MØ£9ÃHš2brÁº™&²ÑÒ°Lwxå4P€Ìþ’2T•TÅœ2 GRŠtQ»å—= g–?XR¡gpïòƒ°¼±ÇÚ–秦ÝV—ÔsZ6B*‰nf¨Y-÷€eð%ï+À{´Ê)C$9tZ9L{£ã5ù9ßf ]šrHÅòáqeh§Ú»ý¹)Á•Ðͤ´0dRw@bÑxŒå#±T ¸ò*‰JB{ZR4˜ax÷æä”aú…©“”J±¬AD’X7 ‡/,™Ç–u¸ßfÅ¢öøhOפbF\Îf0ÇÍÔ‡HêX>Ù,ˆ9£dÉ ÑaGõg0Ý¢*ƒäQVÖ)5‹?‚åì”r‚¼,Ÿ„î1àÌ™)žéÇòÏ@eœIMNay’ÌŸQ °Õǃ>ëU ˜ &ß¹ìéŒÄÓqÈa¹0¥LÈLAŠg”S‚`êߎS‚"–OM)“„t%ô¯òÂ|³ÅŸ¿ñ÷“Ä»ƒÅÁb(zG YäºÁ’Âïï–˜èí>Ï÷ çM‹:÷ ÷_Ùƒ?$0Ü?²‡ÿ¨À ƒîë{zG„,·§wü?~¬|=š÷˜6&êãÂG¢TøÇ…!±ÞÎ~pM‡…Ïu ]|¶"¿l@äS"&b¿RÂW‹}‰µb vÈu¾Ö¸~§¾ººÊVWÕGkO³.]{rñÑw¿YHÜšÇ_}ùSª,_I_øs¿ÿ'½’~qëÓô‹äg7¤¾\ÈöÞ™?[þøë¿ÊÙl¯Óºû‰y÷ƒ¸qsýú÷Á[-xõ«b^®'/´Á&„ÏsY¡md& }Ž×áÕX‘k®Š.nþüË÷«UTúýÍó››sóîÔp„—8>:ø^<o %úäWƒv³iùïp@Ük‡ ÛßB«Ù.Ï`{ %l·î´¬v¿¬jJήÌ/¼^½:©¼…ú&BÁ˜,«Æ)£T<µ’ߘ»R_¨žm»B rebar_core.beam…X}lבßå[ŠkJÏ^ri+þŠ×Z:vBÓZ‰´%Ù±õ$’¢-Ë2-ÑŽ;¦–äJZ‰_æ.cûŠNŠâ|iï.×"¸¦î‡{E€Ëý‘:Fs` \ \q)R·Ú¤(\÷ É%W7@ýãtfù$3éNÀˆÃyóf~ï÷ff‰8>3 ëåñÌØ±1·^rK3Ø´Šf³Pª7-ÙY¶…²Ý첚³¶@,wM«V¶æíšU–ÜfËò—­bkaM{O¥¾@P-×W_î¶ÂJÿ¼Yq¬5+_¥Ñ¬—,Ç4ÕªY+;þŠí¸N`²š¥Å`½a5M׮לîvè–kWœä/”.”{V ÖæíR³.HŽå:>»Þû«¦ëw›õ Ý+9 a`Þ®X»Øe{_¥ f³&¡-à´Cªõr«b9~/t·ÙhTì’‡ÀKjÕžXgÖ.áÞ÷ôÅbÁFÓâI$»6_ï6Ëå‚U±ªVÍínÔ—/ö¬ ñθO¨´X¯;X(Ým|÷Rà 4­Š‡Ààçºö©Ñ걸 _BÇÕ%¾+`]´J-×’ñ´5³jÉEÓñ1æ·šÍz³kÞ„¥r—]/CþFÓ®¹~³XoºJ«Q6] ˆ.[…†é.ÊààÝß$¥R/™•5µz¡´ÅaIè&㺑 T“Ô+åPÓr\¸ÜŽX÷\g]l@ VbKKu»&_°+å’Ù,¯u€¬’»Âz7ç 醣5¥ÓUµªE« |=a5«»Ùª­º›¥Òо¶Qi-Ø«K´ÍYÛØ.-³R ÌWL×µjþ¤/_‡ I·Ä?¦0^)EÏýq#î¿°h—{jõZÁºûíÚÂÖø§Ž×Ÿèذ-þg¼€ýÞz./nSüÓ Ëó­æ„Nq¬Þøjoõ!¡{z[ÚW@\Í¢â ÷)¢¶N1” MÍöeIÐ/¨ºqR? Ÿìe3{‹ÑP4©R†øt–TÖ$CaE•IDÖ4Edì +ª˜›ÔÅ9_øuEl|21^$È‹½¬ø¹™çÅ˪ø»ETñÚ$¯ûÂwñµA†_¡çñ-_øCE¼=L²6§Œ‘dzA`$* o0¢²( Eƒ°Áp4 䉄9F¤€Ð`II*# !!)‘U=Gû‰*šIúÔP4”dY…´Ëâ]–&~å×9QV’?&m×Ý4DD8‘*Ê!–ÕÈ´òœ(‡}áàf&ÊêÚËŒ%ÒLÏ3µÌˆP®tŽnêe·h¤H׋r3¹H–¡²àý„¥Ý+ 9“<žäõ«l…M—”ë1º‘Ü`e*”×)K M2’dÁí§¿5ûA´q"¨ãDÑa‹zƒ¹*Ó‰¤Ñ¾Îõ(¬GXpÇÿ³7 ŒÀî€v›•uI°àNéftRÑ 6#!ÒÜ Ò¶S^eéœhNK9º…‘tç\")­{Ìé†[´W”7( N2y!çÙ.ŒyÞ'ʽpp8pîÿ€©ãÕsPÆÝ¢|K«!/»va€Cð!ÏkeõÑLÏÑøßÎ%,Y¾2§µO{ S#«‡‘ÈEhÃ+÷·ñ0åMP½òf¨‹”Ï–aºôÌåÆP“,¥BðD„éQFòMV ª!’±õ½_”·bäÓe5”稢ª$ôV kð̉òýXØQ°á¡Cù+J+›Et´€¤XÒó$Û’t3a),_ n„qM”û†i”Œ=1B·ëûA´ƒëוh,ÐΪû;:Ùß¡ØÐH6šÕÃF#¹…­!~¨:C”£Iº°ìs˜wæ}òî¼; úü¡^ì§»‚}P”w1úJ‰òƒm-,Êy3AŽÁ¾½Ði»×Î1¦§ð£ÎâÌ–H25/t4IãäJNöW˜s‰d$,¨k^»É†¢ˆrnœEVÑ ¨Î(£ìuìýv³?éWd˜°/ FíD÷°´ŽU‘l—O( õÍhF”÷ŒJ#Ôr:ÉéWƒ#»é Ü/Êý#t¨Ð5à5£‰àSÓ Âoüøã4[“Ó úÿrušL„`;¬×`šÊຠØJn„ç€ÜÑÞR½sí«»ÞZÙ5ˆÃJVž5’k¡ðÀà¨0äÞ$ÝKXpŒ„5ˆ¼×œÐ<89sH08à÷a lcŒî#7CÀ‹f²’·kVþ„Ÿ€ðÃ#tøêäcH fzÇ‘Bmˆ³)F÷“">!Ø?$8Ö¯û1Øv èáazPC3ÆHB¶Q#™Dö6Œy3ÈQ¡>çï=nƒ…Á­KĈ!ÂÁ$=@ 1D>A‚it˜Ž“†11 Ó¡Ìá®§€’cÐâɆâ=¨ôl$»#ã”·4…›ÂV…¡>&ÊÌ{vH:¦Œb¾Q¨Ð1ü¶UÃx’BPÏÐÞ)ì‚4ÉÁRf˜fIOŽ‘Ôp Q”¼‚HéØ{$ žnh#t(=ܦ4FCyñgi: ˆI8Ç›€˜K‘•¡Í% ÍŸMÒ4i“{Óô' ý$ô:Ó#xÅ@®ÅÂÁÓO…Ù1tEw35LZ˜f³0ÍDëxhgu–’H…fD´Ó€vº³¦Û³g&ó.éÓCj ðKÒ£|HMc‡Ä3PQ¹EaÁY‹R“·Á½kPF3x5NšÇÀçøž‚ÏæS»4šåY´À¨ÉÓGH¡ÁŽx¬FÛ·yoó4>ŸOé)Q>‰·]™^y8ø)Öùí‘$%í¹÷x‰|BŠÇ’ô 4Ý]D~f-þ,"py€±wÓ³ðàð¡¤ÞÏö&Yñ& xQ>Ë{êo©Ç!ô” ÊçX3ö‰r-à9‡±À¨Éº(›`|ŒÅaZ&=ü."R{¸EwÓ žY}L1­DÚª6À^NRq[é,|Ÿ¦ ð@bÀ—Ž—šÑa@ªº×qØXXÝPÎŒ ×u!I- µ¡Pö0­|ÔƒV‘ö*Ò¾T¤Ë¢¼Ô†bCêåU°vgØJ’.bØ*R^ƒØˆ]¿÷[²}'ˆrÖLX;?Lx¨©úmªûA´qUHŒ«J 0$´ñ„0;žPJ1ڜ탩bÒÀZ.Iþ|gú&˜»À&ÊN’6ˆJaÖmæñó‘j>ÅŸ€ºV D‘AÖpJÄ×á#ðßÝ!nWA"ܾd×{;ôû@6vÄÙÄsmÙÊõm ×Wâ ®ƒD;ö>ÀuŒÿ`‡¾›ë ƒ|o$Éõ} C\Ç8ÃÜÿÈÃülx–ƒÜŽ÷Iñ³ žæqPÏvÄ?Òq®I®#WÓ<&êÇ;ΘﰟìÀöHÇyOwØOs;æ}¬#×¹Ÿ9Ô3ñ~…).þ)òµ)~ܳŽÛ×rÁ¿.hð|¨û&Zµ<Ï‡ß ü³Î÷ ]7ײַ²]¬«ýà.^üê“'þu’ (ýùàzÿ™g/Þ5ž=½þóÏ ½øÌ•ì7o÷VØWÿkŸ:ø¨Ûÿ™wÿöÀO?X:~.üáoÞ¼z©ò¥—gÞs¿öÒG±xŹýÃì—߸v‡¼ôô¾ÿóÅW'ã¯_k’ë‘k×ÿñ` ï _ýè/þîÚÛ?üù—²¯Ž=öò‰»±woþ12Öû|ü§ßühß–ïÐ×Þ(ÿdêü‰_œþò_þnßâ¶Þüզ͟‰'k—v>ó‡§ÖǺJCᅵÿ›ïþ›yõ©µÊ¾±ý͛ӯH¿µÿé…½_úÖ†ŸÜùöW6žéÿX»yáÕ_¼û݃_üÍÛO¾wöÜøµ/éë]þú¿¿÷­ýÙûÿrçꕃÁ' #‹3Oûsg?øã¨{}üî³ïüì?ßÿ¨ºüÂÍÖž…/¾ôµw¦>xï¯^9zéÂ{£Gvùçmÿc~eúï{ÒÕ/<%Œ©Ïß ª—òmj½19Ïç?Åùã\·AÎò{šy”Û‹ 3ÜŽµrŠëy®‹|}†ë9 ~^#'xOLò5Ô3 Gy‚æ:öσ}uˆëØ{{ù^ìÏ=Μ8×û@bw}¶‚Ñ}e<áÔ¼/5Eøñ/3wuðï=ýý©w~ùþ.-¥ŽÔðü{þúê ÊõÞœVµj6/¡CW½å–íæ² YE»†Ñ^v­Ti•­²pïÝà"µrYŽŸ<2•.äË, ëcp Q0ö#‰½+Nò©ÔláÈôÄñe¡{Ávµ¡¡Ã,K&|¥ –rÏОA´I®]µ»àÆï˜>“š~sÙãtê­fÉZvõ/Ö«Vÿ²U[²ûf©ß{ÙsOó^o•%a¬èà»áOPK-qM>&À—YZ À rebar_ct.beammW tåžÙvw²dÂìÎæ!»„À’dò $„ ÉfHx‚Ú\ö1ÙL²»“ÎÎ‚Š ­ç`´bA=°(âÁŠJ£r°P›ªœžZÛC}+¨P¬ïÖ¦V ÇGíýg†²¢9çfïÿÏ}|ÿ½ßýw§gÕšz‚`- v®èÔÕ$AØî'¢ÖäHX Eu[Tç´L*¤Ëi=¤ †F59-§tç ’JÄ¡¤C1E³†i™ÒµŒLm k©Ó=¡ÆˆM¡/Æpn”µˆš–s­jjP‰»â²Š'ÔH8áµD8·HNmœfZet%‘¶¥‡r¢ Ù ë’SéŒ&¹eMS5»>¤©›œ)uS(­k†çÚ¤)ºÂjNtHŽŽ`G*K˜c «@<$kóTò$/r>q¢D ‡$›§A Å\A}”ÈyEäw²„A Q¦PŒ¬Ódr5ËA¿Í'J,7&âO‘S`Åqä!8rƒèåDÊ'ú‘]¸[ Gû¹ÕæyV wä <Ä¢x¦¬õ$j;‰ø%ˆ – ‰ÈK±ïˆω/!'Ï"‰%½°Ø­l0‡G(˜ÓaþóÁÒ^\ûSä~œN±lGD ±<öÚÏöð>IZ-yƒ>›¯‡o”\Él´qn¯“ÁÐÎ2ON,Eä)›Ç•Ï’çrYVD”(m@Nvuëg¨q09€é 0nÎUÈòŽ'J£ÜKˆ®BãìÒVD³rŒÐ¸“¥œ‰I”ö[è l„“ß`X4Ž‹E³œvCh@(cIšËƒpØë9?v”& ’ØÊœ‚l8ܸ(âD\ 8ÒŽiöýˆôçÌÂÁú"Q€ñR´E±L‘(Mr"à¿ 8í 0ùè[v4û½†ù¸ù^ ¤Ýˆæ'’.À§(„øàEV à˜Èê,SŒ[kÖ=ÕÊ”À™J²ÏT›ÆÞŽ)‹1·X(W NT ‰fñ$]–7 ÔíQÌIœk êvò“"j‚U>'vCÊI'K?ìX;¸X@h†F3|¡¨1åfI—ƒM!.æ‡Ù9ºÈj];SAÒ3àL$]3á$h7œ><"Ź) u˳A?Bn?TO×bèÍáé!h/.HÌÊÌ " 6›)/ˆ+Ýþ1vx–€À Dä›°›èëv7A–J|¸~)já¦Öˆ¡ö[úaÑ™(‚é¸H·ÕÖQº‘»;‹…¢¥gÖÐ W¯Ô0X W€Aâ$J‚ fxÌיЅèBe. ] Ä0¥‘s t¡ÀÌÆ•+ë‹0U$í‹¢wL#D.RuApçjº¨…ñ£NÄùš˜Y>–Ça‚-ºœ]Íí(Ü…À¨åC„égZU˜hڌۇž…Û€ öðàEƒ[~ˆÏÆÀ«x Ÿ“kd4Ø@—€”š-Ÿ‰«_&0óð!æÁÇÌÕ˜IÏ5xO!‘¢¥ÌÃ!k ä"HT›Ô—èJÎ`1˦ǩÇŨ‹00,uæ™|Ö™L^=ŽÕ±:`¿ÑŒåÿV¬f«ÇjŠ0óIºÉŒ5ËŠ5ÿR¬fkÄZ û-y<‹éâ¡®æ ¶"—hÜtö†‚´‚>›Ã¹²¹aŽ N¾'_„ Ò¦1 IºíR'ª¹1þ;w!½ÐŒ?ÇŠ¿CjHKàYG.A˜xºL<‹1«‰‹ÍNÌÅŽ`+‚O7|vŠ´’¥aT—à8X6„Mž†ñì†ÍÈtðÌ’î¥6R ³1@ `ä jŒ 3‡8€'ó¦Ñ(ÞÒ&¦¾Lè^±"öµ0+P®Àw"Ÿ†@ôá*·3dV⺬ÄMYa–“ô2Ü/²Ãí^n®Æxöâ%q1ËŠ&¦gY)ºú bôLÄZ]ëÇ_Ò½ÉQø$÷‚Z BØAHXy ÓAlÖ÷»ÛÒ9¯¥cßËÛY:¶)¶~”€”Zöå 3²bVd鼥ϴpÙ,_VÌ*+æljËës,›¹ Ëëó,½<˾¤ÖÚ¯ËÊ%€Ô[qðÙ›¬:à3ηj„1,ÈÊÛjÙc½ÍÒqœ…YõiϪOð2ýbÞÞ¬:b›àµ¸GfŒ¡Ûòë²tü×iùÒ“Iaû2Ë®ÇÚZ¶„ãêG—+:ØØà÷šºvoríÙU\'Û1¬æ‹¾r/÷ïÚF׿‘SõÌ… ·¯æXt¾ëù/·xàɆ©Óÿõl/ìë¿o¶ë¥{×l?}îèÄú¶ž#Ûö?û›–Îñ›cÿ§{NÜu—Ëv"ïÂM¿=óÑ/öm¹õpßÏßxdMþ'Róç/»F“o=üØ#•{÷\=ç„ò*ö5·â«÷7žð×( Ž7xåY?{úަñ{Ç·ßûűâ×´óŠyg&wí¼{Ûš^ç᱕×vlùðóãNò‹üwg¬8Ù7xà›²Ñ·ßª œ?pæ©]è½ië7¿_tÛ ø×¡ö“ïïûæÉŸ?w—¿<ðF~UÇ+òº‰•‘/ß\¿óÕÅRfª¯÷¥Ý~a ½‡?¼oýúÃeè Ñ|}ôÆçÞ>W Lì.-ÜôâM¿¿ê¦ÀºeòËÚØ€¿Óš©|¡`ˆâ”ÀýÊ‚Ý낻ىЇÕS¨ùô;G›f8r>*î¹eë¡_Ú1·~ß›ï¶O‰õèËÇò^¼òµç§ŸÛNU»ž<_…¸ºÜóúBËö´úþsãÖãDÅ–Wžš[í¢ï9ô´ra[iõckÚÝñºÏÊwI§v\}ö|Þýá êׇ¡’å?<õÆÞ¸­î¯W-}nwjæ5ï-“Ÿ¾â9Í;õ“ô×?¸Áþì½öÀá¯ûJ'\}‰¢OŸ¹oêxñÀíêá+ï¹Ps®âçºÍ?^[xÛ_Ú^,¨}°³îø…kŽMÿ˜X®F1÷Žæ}±Ôâ^ˆdñQºŒ“K,Zv€,¶lZ¬5ÖAYz­õÌfÍyƒ¥ã¹eé˜÷>˾(kð¼ægÍt®5O9Ö§1ߺ®áY»9-‡l1mL§ŒEŠ%†o-ø÷2ÏŸWÿÎ~KÍä× wõ¦áá׆=…íꨮ¨©4ÞpÄÆx†·d2¬]‡ jF‡×Á‚’#J ïÊáTRÑD&&LjK¯wCžÅb„kɺÞåÝ¡þÞÁbzƒP_/4Ô7†„ùBkãü‹Fô]kC½+{VÓâŠÎ/XP/„#° ^øÒj„°7Õ.¨mÀ{”®$å!GÞÚ΄ma&lç„s €i5£E墪nHMÊu#rjX©KkÑ:ãíÿ’/¯µ²–ÆP$­ã&þPK-qM>Î¥Hxàü"rebar_deps.beam¼X{|U¾ÏôLÛ!í)“N ”ç”I Z†&…¦<œ&Mƒò m}…6M¦%6MB’P^¾ÑUìâ\QT_ àúèÝeå®úñâ⪻º>®Ëòq? >ÖÇ^õþ~3“6EV¯ÿÜ~>§sæœßãû{ž3©_Ø0Õdÿ¹Û[;¿6ë2™ØC&“)eN¨mDKH'Íñ„OÄ‚j2Éá{K(œÈ×·ƒ±h{¸ÃÜ¡¦Z:"±¶@„E‚!ø‰áµ= e‡Ô¶îŽ!:G$ÖA`d·"IuH²3×tdGÂÉT2·=–PÁY±Î¼x,™2´æ¨‰H ÚA@ìîhH¡j([M’jn0ÖGTsp…ì,×D¥V$b«8 Ö^I¼;•×Rªö΂†P^H¨Æ‚ìGß’6Ï<°–Ƥ׹6ЩMÚAi4Ð¥²—ÅÂÑaº|, ©-ñ@jW6•èVs‘8n3«ÑdwBãg‘jH Ò(`L"–‚ÞÒ„ä&Ô5‘T³=p$·+œL†£yº »SáH2aW…²m±DŠ ƒz¬8˜Ö¥FSfÝF\Î kèÙp´=ÆëB’.);ÑÕ’h–PWv‡\2Öª-j´¼Ìc oÑ`Ú"j.˜¢†êRpOb6Ñ5øD×äâ¤'ÍJ¨$ÑÍÆº©àŠlí?»*ˆrêê¸L©!²"äÑâp,ÚÖj$…ô¿ñ†45ˆÞÜL£Í Çr u€Ž)Š­ŠFb±G:Â)’ì‰f­è m—'rÚhpI:´`¢Žœp¬ìÊmR)5š FàrV0”•\AØêÒr ç ƒÜ¤û§ ìj F°­™m·SÌê–T¬%Õ¨E†‹٠¡ZØÕÕj°;…>Îg´ôµå´BDG^W,Ô ÃÅÈg¼.,nŠ£<´-—§L-—ˇ¦„£)µCM—gdþ”Ê Ê¨òöðêâòŒZ1¦ÁÔòsíè¬ÃËÓÅ6ˆáË:µµ| Va£½; ‹#ÊšÌYÔƒ6tjsºû$TNo!á4-Ô”É4l Ly“þ· Æ30Ê>«p¼Èˆ"¯«’%(•$W4)DP¬„i‘Ò&(Y¼X¬¹2ëWáºÍå%5^"ò"ï&&ÖMx«—:ŸIP¶\6L^+.ð‚Ū/),ay:Zé”ã¨Ä^E|b‡Ia…\QfdØÞ$š€âI^æëEÁgæ}DH¡I`”9„ñgš-"ÓZÀ›ÌÙJ!±w³Uñɤ˜¸BXXËåý¼lª 2³¸±¸†‹LoŽxˆÙ ó"‘ÙWÀóhS›0Ø¢¤æÁÁù;A1óšàçíàã&Þ0ŸB8¾Õļz!aÞyÅ"s:ßtNy”'50P"þ8ŒGq`ŠqM>XÆñ`gI£D†+<[”y´& X÷Àxà‡ìpŽNk>EXÖDG*ÄaD%Šƒ= Ô05 A™ˆn,ïè7 Ñ ™cAf‘“Ž‘Ï/)•iH•„7šn2K1P‹ð>ƒ d.Ñ3ˆ¶Œtb­—g¸Q@nƒçèj:Ž@ÚÕArÑñB ¿[0·À;Ü‚èq r£Ž'æRE²*‚âQ$–•é\-;J4;™–3ZR¤˜Ëè˜>:–áÆ(¾VÔiasÅ^ÅÌrùv*3¯oñû´·2† ž É VsÒQİMDw”@¨¹ñŠo#Dþy À‚Éð´ÉT"3•Š”«h©y49¥Š¯WÊ‘éD†+ƒè³ È 3ÜD™Ú‘ÁŽ çÃ$†;ÏIí‚‹Ú¥b>/»%pĸWu·AÂܨ V/ HLnr*YÀ¿Êpöj:A¨™Nvð­þz¹ÑçðùvúÌVo£GÐqLvQ‡c¦ƒ:Š‘–Ë´‚áÊÝS£ÛÁeêhä[ãõ²Ã×è "›#ÍVA[[ýi:·CL*R“BêS Ú”Fk½Ÿõ™KEãL*AAiÄd›ã¢U¤*=HP’L«0PUZ ¦ôQðÉEr(¬¤˜+¥É£ÔÅÙ´IY?®X!j˜ÄÙü-cr»¨“­áw³ “%;u ˜"Ú¦qX!Kl«ž'?aj­d¸©vZ%Ù„ÍñÁQ™&ò“¤Ž|^Á4½Ë+¼—d/ 1õíƒZ8 5à4’ª•áª0ɦA¢8ü 7]¦Ó0Q¦a¢TC¢Ì`¸jXCä°f® .óZÃp.æ© Üïö@ˆ<|ÐEgB6Í”ü˜Jv:S« ­|JˆÒÈ*AèäÒKX{¥à³ŠQ5?[Z…øŸ%Íê4i3 x¿‹ÎæYiæYƒ˜=¬Æ)"§žÒ3Šl–1/ͯTÁó|õ@0=ÄŸ¦z öP4PXà]—âéªmáéºkÆJ [ÁýKúkk)O3FcÙ@\aXahqÑåpX.ÈpÒ·™.—fHtyÑF³Ÿ¶šѹªæFÚÎp­.„¾ôˆé¦%Ó`ãŒF„o¢óE´áù²vKtX!Ôý"Ñ™nÏV‚9éãŠÐï£`g4P£=®^”|æ%>¢¥‚v'¹±˜„¶,È?àÑÏ7@Í"5„Pómÿ ŠDûµå&Ÿ§^†:ñÃ]A‚bha¸P¾ìG€HÛlÕb k 5u#3`Ú´[<.¤xœ §þ¨ %­B·eÔYÂÏ%ÙF,¶´¬YºïFÿ„Ú¾c~¦˜å+ «›á%\ @têW˜.g ¿Û …ç%·SqØi—`ŽÚI öæesã,V /6¨ô›eÁ¦ÑN·Ëúh'Ã]†MÚᱱz˰j-[ •yàŽ)Æ1Û‰Žrjmsœ{F×LoG°0»ŒÂT.Š&@aÆ\4 …=»0£X˜Q­0ãP˜)(Ìn(̆‹»h 3™Y˜I,̤V˜+¡0 ·’Šþ8ÜJy¦ÉÙa¨/8UÑÏ€+ñoùK~À_|þä¿+‡Ã¥(/bžx=ZïÿcYQîL.ýyÏ`rÛO¯‚@,‡çj]­{‘±uCË^Îo k k kÀùknM¾,âõÒ ®ø y=&¼v”\9‘^_æ2R(CÄ/ßÄ‹zÂ\‰©w%¯U’¼DBT¥ØôÁMW€ö¨œµvºŽô×:íâŸUœdeúÚE7² ™·— Ö•–Ä>n‚dÁ[_‘‹®ºõ™tësˆ»ànVv®WúôŒÜ€•„_òm°z¥L7bl£éU`ðÕ`ø5à€kî*Ð1¿Ü®†Éy8¹&“pr-Lì8¹ A×Ëô:tZD7€@Ð ô ·)ßd†ÉØàÛ+Çj©à ·¾uoÐw§¤wåA»7ê»SÓ»•ƒv¡ï:Ò»ÎA»7¸xJý6w›n3€û%€Ûàne¸Íù/ýYÕÿa‹7ŠÛ‘ãv<¿oþÐËp·É4­à¯½àW èèÕœúË|“!dº0°·¥µ:cõÖþUWÆêm˜@ éöô6ªöuªßÚïCÚh«R‡>'1Ü6\;õ_1ˆœá~‹+`ñ®jz7ÉçùZ¢ÝrKû¿}1ð%z.Üí¤¿B¥Ûñ2pÔŽjz/)ÅZ"9\t|nìÒ?7à#Úc§»ð“{ãØ•ð¨(“é}è«ûÐW÷€¯v2Ü=˜¤pIéÈòÚ©ÊÏ´|¯“nGí÷aÜeôHX¿ÐDÀŒªéƒ¤€7~ÕØ ír÷À¯vº[ûÂ_eðלL³tÒûQðîïž_ƒÌ.x]àC ð!M`ç÷vúPç÷æR7œ“éC³ËQÐ~ ái8Ó{2=ús`ávÒ_£ÊG@Oôöòîî7;Ïtv¸Ï¿ebý…£góª§&ïÏ{广†—]þŸÍ£üôäŸx¢M¯ï¸¦3öÆì=§— lXtäèÆèü°÷µ i[Qß§ÅÅ£>øëÉë6Ü¿¹rŽðÍ+Ï1·¬}{þØ}B½ùÆÕ¾o6/Yýܾܷþ_Ÿìy%±ûëmOùßÙÚqüôö&û„û?=öÕw3ÿ2ßDÇž^ùÁSÇÿrO[û Öfõùöz®ŸµuÎ-#Û–¾½í¶ÕÑÏïÝûÜ‹cŠ¿Û6C:V¶;ùÅã{&m:yÉÜ¡¿Éùüý÷Ý5{RÝÈßÿ}Þæ{Ï,úŸ²eW¾Å=|âæ—?²õ]RvüÌA÷º¯_]ȬW¢äéâÞ«Ž7H‡Þ³ü©~Ao\¾ô©ŠbÖvSïö=¥¿­{gSŒùþÀ¶Ôªõ®ì òQ¥öwýý±›7Œ˜=ÍýÀï6Mß]æoÏ]|ê¼}î™»øOc;]ÿñù‰+ž]ØÒ²þŸ·{vrýí¾¥ùvßÎÒ#ÿ¸õÇÞ;¾múçj7¬»w\Áömod.<}çôîüƒ»Ü UKŽ]ÿòâß,|äæG^;ÿêïNM™'´d*†Ö|üþµw[G ßþä‹Gmßr¨ë­ï¯ùâÔ×_,.­ê\5$vìÈÉqïÜùðÃ?z¾=züÅÃùoŸêéÙSúÖÞŠOÞñ.ºHÊÿrâÖœŠÈ£[^_óQòÕÿ%<"\òÛ£îæ–MöÚÉoNºð€sÜП½åzñã¡[Ng¯²zÜ¡ÿÿÿE‘MhA†'ÿVÍ­ Uƒˆ “MÒj%ÖjC«E›Æƒâº›™6»›³›øƒREÑz¡x+BA‚¤âÕƒ jª"^Dë¥P¿‰Ÿ¸ðÀ³ï¼ß2|k¿þ^ܵ³]Y]ÞýáârréÛlòð¹¹Óqþ<6|yáq ýâSß—›ú2?ã7ï÷ŽÎÇÊýטïŽ<önr±­¿Z]¸2û»õõ×½µmÛ{Þ< dÜ©– ñ$„làž§Ð—€úSÀApôG€þ¨£/&àî5Ìïó€Šù5@G¿„y8œÀü pgt™Àærn ½Œ.;G€AüæºìŒ{°3äч€ @gèrv"û½@œü}6[±ÓSô<¹ÛÄåÎfj~J-—w^xŒ\ý¼2·’›ŒÞz»0!nWLs¸Ä§áp­ÓÊ~Äix†Ã]„)‰2!¡ºMÛÖÄYY;MÂ"A¦\&>Ã"ƒWëMÊ(éjrʦ Îh-g”’õ{§JãûÔréàˆEº³J&£d39UÉ+¹ü¿ÒºÊð¤Z:´Â"f /^(dMWÌÎZL¸p)‹„úS…TVfAϰY- 1ò^ókQ-¤ui;t¦¨2‹$Ò5Çfi‹qÓH»¢šL×ÄS)k¸)&ê&)ê®'—ùPK-qM>HRòƒˆ rebar_dialyzer.beamuWl׿ó;ÇgÇ—\òB ¤NÁ8±c‡ü#í%Áñè(ÑŠ¶š³}±/±ï¼ó9:Z@Û” ÚnS» ¡õÏTm¢í:­ÛЀ©í˜ºŠ?¢ ºª…I[›QQ:´±}ï|Im–>Ý÷~ï{ß÷ûþÜéy`íú E¹wôEzè5´,EÙ2EÝW¦ËqI%)3ñ°¬;,…Ø\ƈ)êˆf—u]ÓmÚ˜K—¥dÌ\9U͈K%éVµX¾HÇF”Œ\ZôY0”LÞ.Å5ÝàfÜÅ´œ‘w÷š:¢¤PJ6P^O8sº–Ë(y#Ï‹kZ†1ô‚l‘2y™UTňv‹¤«ŠšÊÛ“r¼r]e´"¢T»‘Öµ-e³‹Dã%“ôÃùòâ)—+ò㉒Q’¡hjÞ¥Œ\ÁŒå$Éäcºœ`Hœ‰´œ#NlŠV2¢éYÉ`Éñ¤¢çË­c³ôÌT`%K‰´[•·±œd¤Í3ª”•‰A’…dgAMÊ#Š*'mZ¾`Y/‘õŒ¤¦Üt,fh1âÔæó±„ñÀŒjŠZ!o‚ÎFpýŒw)„}ª‘ôÒ¬–,dd³•å$æmëÿ]ä[‚þ‘‚êøËŠYÎlÌñϤ ™DýCAxýLBKʈG¶þË&Ï€¿L(ÊÞ 3ÇSÅ™¿NŽæm•‹Z(yóŠˆqðT'Ç£.¡Q¸ñÞÇãnÌñÕâú¶xÀÚÛí…õf=òØÆ2-òal¸‚©ðˆQ 9¾ç:=xÊ[èæ;PÁBsâ ,Ú¼¢9À‹×`ƒB݈vUîvá'é|ŽPÔå‰2 àHTĨçYzòŽ àƒчˆ'±§‚axÎ~Á²çuú?È8ꪊ¢ö ú/ðP„ˆ8D7cÑ5ˆˆiæØWxü BÔÓS£Œï rÍ뼂»®`¡S¡>Ì÷û®„\óya0ÒoÃb4g¥5•ñbzZŒ£JÓ,?¢Ù [¥«V ÙJRvLÊ.̲tð›yx0P ñ à²c†‹È 3‰ZþX‘ú=QOÛð€àºHË!ëIŒ€l˜Ãˆ”ÙÌæ†B»=œ‡faIR¡YÏ ¯* ƒÀÎJd Òn.Ÿ#<î,éÓ¹â sÕÈê¢=©æz¸y4[=‹šÅæŽz|\ )Wƒ»@Ì‚dVË2çgÍkH½Øy3Äæ±žfkÝœCvž[NÑ쀮só„dŠÌ ;¹vš ÁÍCU‘žQÈš.‰!Æ0—¢òq ‘Ë/F§ÀðÁÃKpLŒNc‡p Æ"âl6qV˜‚ +y ¶â´Aoñݹ;43ä1ã0³®!ºTô2·ƒ«G½{}Üì|¤ƒ[âíõ†úar¶ˆýV8P!XœÂÿÁÊ!L?àšÈ»ÒDޮх¹šm£,ÍÉãÿ×r1Í6B³ä‹EÒ¶âó‰ 6‘Á] 9WA|Ð ’ä lUtWb,½YVðô‹•h ÏVÐl3Aà\ ±P`+i6`€ApæàYL2BfäJˆœ­`±,B\A£{ù8ÁÐÎ4‰ 9Æ dö$æZ<Ûàà}ppy×aÖ¸kÇn>M÷› ˜ºÝÍòÛÝ´‹^TÍv„¹6„5dèȇsU6Oš¨U „¡Š€ ¤ÄF¾« eÖ>ùæVXx5È\ 'Rc]Rgé^zË~1ÈK'6K-âs™…7ƒ´Xx$x›ÞjÙ„@–¾¤ý.?Ȳï¼íl§eOöº-¼ä^¢G¶’:P"ˆ¤ÃÚo±tòóƒ,²|Ì©µôJëiÊ@AÝ`í‘ó]Ö3hù P´áýÕŠAj¾Ì_ÝúÌöõÇïGAÏÞM+Ë«–>txÝŠ —.$ÖMúÙ×~èÌåsoŒœL¾xýHõ¿ïŒ]ýüÅ=/luîÿî…‰ƒ'[ßødn"ª OoþôsÞ•¥u¯í:þ7~thþáµ_¿·vMîQû ½w_àƒM'Õám“—þõtߦ/¦§#»ÿ°ûÑ:¾öæK×V®|é³ò›aO<ÕÐÞšýɾ‡‡m¯¬¬©ª:ò§¥=Ì­·¶Ç·þpgß®}°îAÔðƒþËC»v„N„ŸøÝ†Šß,zïôÓÏå³/7?˜øk¶éÂðôa~øÒÐsø•žáyýZ—üûÙÉÆÓo~õ,WÛtðÓí¿øÊÕ=úÛ±Ó7¾äþöà/µå›ßXpm[ïÇ-ïýãň×hxrb×Kç.Þûü7º«›týõÏOäοV¶Ôóå' ¦"êþúTòݺæ«{/lÊ!oýÙ=]Kž¢o1öœýõû¯éßKwˆ¾Õ˜]ÿÌ?oáG^¸vT»¹å|ø£3\vùåï?öÎ}X~$2õöÑ߿ӹ퓋õÆÑ2ßù 7wŒŸ¹ ½Y­%Hï’ ,¹ÏZ½#óµÂÒCwõ´ÊÒ} mÖ yo²t¤Ñ²!ïCƒ¥×ö†NÞ‡äæB§mI çUs¡–SôoðÝúóÏÛ¦²òo}4:Jõ¯RG`™ö ±wÀõ—\2 P’¤8ór çlVÒ'ˆA ÜÄàî4F1r\Q B+c”CQ™BRNRŸ]Óö’IÊÕ·qÕꕱ «ˆŒQå­`0Ð ÅmÎPÛŒ;Ü?[µf`íUšR ¡½=âQ“Ó¸¬çÔe7·7·Œ1”¬œ.‰S”ã]É&q’]rJn“`^+è yŒZÖ’Ö²r˘¬Ž*-po1/ÖŸi³)šá;JõÆóy—þPK-qM> Ãf4rebar_edoc.beamM’MOÛ0ÇŸÄ¡¥´QsÚ­; !Ñ”R!8¹íʨÆËl§Ii;­›WŽƒØiâ¾ëû h_b;ìÄmf³C«駦Â1l¨rebar_erlc_compiler.beamY pÕ}ß½]éÖ+=kïöü-Áš=°|ÖJwF’?`ugù¿ÍÙöyµ·º;ë¾¼wg[| Æ0æÃahë†É„Ìd¨3Œ;$aRЧm !¡I›Nè¤i'¥¦L¦LoïI^›Ò©fÞíÿýßÿëýÿ¿÷{ºÍ;oê縞³ÉÑ‘í#j™ãÚ»9Ž{TuqËÍ:nÉÎÚÕr­XrÜ #ºŽ¹¥ìDÑ­7ðYrê-Y»Z™(æçåF¶Tµ­31nÕ9‚Û¬tM]ªÞU.Žûçmvɱ*m¥b½QNT]Dz -[ÍF±T—'Š•\KTi±)ÝZëÈ9%§ád©N :9?Wm` ³î»œK=K^¬ð#Ñ…j­QÀ‘sÎx3Ÿ-V&ª2È—ªãV©ÍãÎk9,Uó†TwílöæÕÜjÍ ˜XµšƒðŽX¥¦So‡]«’ôö¶MTK¹’DÝV¬²#ª+A:+Çe§Roºµ$ÚÕœã…U³ÉÊå•YÝš[¬ºÅÆ”Œ dsÕ\Þq[~.DòÓȹFMb¶n„ÆmxŽÍÇ‚"]3L¶!ƒÛüÛF¶Íë¨[€²­¼´ØÍ?‘?K+ P%ã,lé] Ò6šží0œE(;†È͸*õø0Ù«oÐÉÞE¦Avšä&^Ú‰~Œ^¬ kèÅ{SòÁN£ffè]eÚ3NÏÛ ƒÜB+t‹W¡]¨Ðn^Ú¥ìâ¼ó>NÏ»H¯YdwJ³ÛôÏnò{@ǯ3/æ4óRGošñÄeàh/e”ƒÜfÃse®žquéŸíÅÅ;ªã%.´ƒÃK7'ÈvZg”a%/ÝBsòä$‡TíkWHŽ—nÅÔÁô¶VÅÃ*ƒ 1@ Ir;âØÏK·Ó÷1€—©H®…Ê~TÐËõj7 C”ÿ ¦îzyÉ¢ÈSü€©I«yÉó˜¹!âð ÄŠÀØms/˜äh›…–q'Al É (N"ùaR: ‚ tÄŽTR02½¤—KøLɃÈ@ c$3œÌ(õdFÃåU°½¥:–êf²ÎNÖ•“uã,öt_”Ëø|E® ‘ÂÌÈÌ…w!~âÌäîWÉ Ê§É F‡™_yòŸÊUHt(ë臑ìP¸Ž>•Ž0>µ"!¹Jª\K»´u„õÆ9^*´Î_û: Œ&eì«ìíKǾ°7#ÕKÊ:õUŽË.RHÉ—I¦;™Ò¦rÆ[Â]]¶MÜÕ3¸«O'mãE,Íxº§å²AÊ/®‘”QÓ:™”¤ÄK“ÐB6Ê^6^A6. ïBþOë‚ÜÄç»Ë¡Aã,ý¿¤q‰¡ÒåÖæ*ØÜQT»ÚB×ÅWov3øô%ûž‡‡HýËC}ÓS¤˜Aš…M….PXç%—j¢Ë ]õVcƒÅÃ~´4¤F7)$Àú=J_H½WÏ¥mÒšYÙcX¾ Χ†È³PdoNsPœò¿#AŽQãwBñn(Þ5Dîþ2Å»üŠw'ÈTñ(Þƒszo»I–óÒ4¦÷"¾û†È´:¢êq<ã#ñTÏÌHÆ®'Èt½Ó¬ÑNœòš„ž€é1ƒ<@SóRs„Ü‚ÎðÒýÊ47Å;®QG‘ûÑ„Úz˜™]ˆ€)&tô‡ÖÂtAŒ £[œÕxaM#¬ãCäa¡Ó˜»Tðšä]V'©ó“^‡zµ9ÁKµÞÉQÔã8¡'Z³šB¿µøóðp‚ƒç©!òøl²ñ…€¾{õà›…„ïvR?Æ€?û§ü^OǨ×'`é,=ÙÉÑk&ÞKžÂ[ýò"=E_CNcý$"zºÝ h_Ï`ú¦Ïbšà¥ç0}Ó3˜\¦áî¡_ ÇÊ5< £ CÀhDzÑщÀ óÝž‹óL7Ât)½ÐG/fòK1–1~ÆŒ%†Æhêk9“¹ Cgü(ÆÕÌ×5+Øÿ(½’ñgcÿZƧvV3šú]ÃlR¾Áè~Œ½–ÉÓØ†½Î•ÙÀø4¶ëMã¿ÉPùŸ/ÉÐùzß~G}¼Í>¿72šøö¾•ÉÎæä+ŒOuoeôíû}º–/6Ûó„O&ï«EÑCÑçkÊÇ¿Ó'gü0dµ£üã>ù‡M1ó0¥GQìqÛXÝ l}œÑôï F˜Ù“`ò2£E_>››Øä;Ù^eºg˜=®ýä3€Ç#Œÿ,óɉ š?Àã$ã?Íìqü/^z›kýŸ‰Ê=ÉÖ¹À9ƒÇýŒÿ(‹ƒkûå9šß{™þ}\ëüèŸö¯ø½öã‘ã§¢ËûËÆŸ×÷?þä Ÿ¾±ôû½Gþ¦¯ñßÏo}íÖØ›‰¿>ßyùÍ…c«¢oô¿ñ“ÒËáU¯þè;on[¾èÙØÑyá»·‰ï ?[óø÷ßÚ™:gö¶ ûþño×ÜúÑï¾ûòK/Çο½6œ}yÙg»ýÛÜ‚þðô¦Á5?ÿë­½O~ôÃÞ?ú´GœÜ·ÿ§kògÎ¥Ÿ{êóÆ…Co»÷µÆ÷>~ø`òzþå¯â3{¿3°aï_¾ô¯ÿùðíoq‘÷møüW.|þÔN ÚªMsú×:×~œù±åÇ“C3Œ>u†¦Y]_†!?nîfòw±Aé©Ë0tŒñ_†!?nüX9Ädr£ocsJïÃÈ2ÝlòÇØåÓ¾u ãoÂèf4í73Ú#÷²½\‡±›Å@ïžíŒ`v)Ý‹a2yz'lä.ö–ÙûŠÞ9}ÜÅû¨—Ñd¤Ñpñ\9S¢‘9N8R¯x“ŠÂ]}⇷žÎÍû³ÆÂÅÛÇ®€CÔ ˜ rebar_erlydtl_compiler.beamuW}pÓæ—üʶâXD¶ á#!*6Ÿ‰Ùq |”¾ qL„,PºöÖÅ’%¶äI2_ƒ^î k¸•Ž­£ÝzlMáVv£¬£ô8Ö·•­t[JÙ:nWÊØÝhïÆÊnÝí¶îëye\zMî‰=ïóüÞßóñ*RïæÁEq‡»Ó]›ºl£HQž)Š¢ÖÏ2Õ!Ù̪fa·b²9£XÒ ªéwV1rYÓ0ì€e”ÍœšUwÙ~£lgÍ  ¥\pL>ˆ—õaOs³PÁ’-õ2Ëzpz£d[ÁŠSÎÐóÚ0VmX5C¯)™F© Y¶UÆì¹PVýŠš—Ë».W¶€wÖ–‡-²{­‹žP¿ Îä EõîÑr#AÝÐ`iÀK3|yÃ,ʶ×1Œm–Uo^.XªßÓJ%U (Æ4_1V릦ËE•̓ÍQHRDñÁý°=BÇ}–m¼Ï*ÆéªªXÓ(~VІ¸‚lÙYÀÓòšªxì¬ï®3Õ¼jªzNUH c©° «;keEɪµ¨êv­¢¦u¿mdI4G`Âcª~S-äœê“!]©É›P)âÌ5Û”s6ci{ToY‡*O'§éy£ŽÔ¹ê~~üNô¶öx!ûR²-OÆš•5ÕárA6?Ó3ž‰83jhúgúHà#Åýù‚lÛª^[‡²­,5âUMÓ0}¶1¦êV}üU…ø|Y‡XzM(>mKº¶uÐ}Šò¶Ã\óTågd%Hˆæ=á"-Îà1êaø4FN",¤QÅ(†SîFŽ!ú`E}á¨ã–¡¿HaÄ S8µGÚ1³Ç¢å°GÀÞÂ=ˆçhÉ~‰§1öDñKB¿$Òžð5‘ÞE,0°Ã?ŒàG+CÉ„xz\*£Õ¨\?™<2øý¡—»/¿¡㌈zg$¸œÂàNŸÇ™¸Laü½ Ñ‚Dß JÉ%Æ "~7s< Ô¿ ‰Â™íÈ/àL ±üvŠfy0Å1ÄHÜ\‰`sN¨Çy\(ÐÀ…i6tËÃ+q3%š ã@# KÍ ÍF`çù`ž9c¶îÁQ§¤•ò‚sK#Õvt†è0¹áoò½¢ „3(-dÆ…^1šIf˜tTpÔÁLTh 1!åfc”"ÑŠ„b¤)RÃP êî—JÍÜ,h ·Y<æÓȃÒ=H˜€Ä2ñz -ò4;;Hñ~~|¯—?Œ„}^qRø|‡V:NsÀi1ä6ÊbHa¨+õ¼“e17AP®JEæa óNWXÇÑØ„È3"×HªÁ Vœ‚-µE¤ÙÆ[Ãà§®‡P¼É‹|:âi¯ ÇÏãvÒš¦ ÀOùE–‡ßЛ@I ×ĽˆC/5rëß õgœ¹ŒâÌ©vœ9/ø1tUJÌÚü<+PF·C·V[ æ‹Àƒ´6žI¸òì¬fND4äƳHx!’µÓ'kÜëIÀÊÑi‚Œï«€øFý<;›f£Ä5‰‘MÁ(²shv!×€qQ'·E¾ !¦²3Lè22¡Ë`B¸Å0¥Khv1ÙxÂKœñ„5©#ƒP˜ŠKSÜB8$ì22°Í€¾|[:¹8âD,v!稤£žhZˆ’\æ¹dH· T¢/žâš ^+@a€jëäÚj¼ ¥3S†EÓ™«hÎÜ$El\É¥Ð*±QB7⣗V \ ’jâ¤@— Y gX^€Óóïæ’4›€ƒN³ÉOSk«¦ÖžâZ µIµøõ¿åAžLŒk­—mšv]«ëa|:}ÒßµÅ6·’f_±Wú¨"ˆ„ñ€Ô€Üû ‚@êÜç-Ñg‚Ì¡AfƒÌqc Î\×qmÄÿ.®øD«ô˜ë·d‘ë¿d©ë³ ¤Ùõ‰ƒ´ºÏ|¢·UÙ¥*=áÆ’ÿ)ÆÅépíÄgy•¾¢*¶³Ê¾²*¯ÕUœW»vÂón×Nr¼§Šs—«wƒ¬«Ê1]…™!zzé…ƒEr_åÆÅ\rkç™–Þ²¾Õ͋ܯwã:]_Êÿí3$®×]ŸÎ“¦Þzdj£f“¾ë°tp×Ñïþ¨ÿg_=OÕðß8€=±ðŸ6l´¥+²àÄk‹ž}¬ñrý3­÷ÿëG¼Ø¨ŸúÞÓû~ýá_Zt Ý ú¶¡£G–Ì»òÅbðÅã{6|<}èk÷ÊÊä±/o8ø×Á§Æ³{zsé#6Åäíׯîky¹±ôÌÁÎÏí²ÏÝè…¯|üÑ+ïÇrvFË19Yµà䊱']úiÇóËÙ¿Sÿ»Ý×Nçã3?ïë? ÷á‹O&Þ=Þ5‡âJÇ€öÃsßlï=¶ã©ëµ'¤“GOóÏ=ýÊ??Ü¿2ûø¶{G†ÞXôÛþöÖ·NÏœýàžÞ™<ý¿ÌÙ}þÃ…EýÛ½²úÅו¥gñ…«sëš6­9ó«-žK»ç0ñË×v÷¿;UȽïýˆ>ãyû ¹÷ž­¿xézÃåþå›þsßæƒûŽ£ôåÄ{ *¢|׃ýËvPu3®Üsý¾¦¼¹V5ýã­ÛCëÏ>öUãøël;[:³¾|ãô×¢Þ=û_ŠÚhäHÏž™qGϪû„]ÌõZWoYãöœ¤Û䮟FÅ®œ?‘º}6çS·Ï¬@Ý>Ë!ׇu9H­kgºlÛ$s¹¿@,#…B;,ݹÑyêÑWØýZà\â'SGØ…?]×§ça­Öñgˆ¿¿ò¾oƒO¡8ç/k•‹EÙÜM|ð/ùc£i:±ÐÚå×ô\¡¬¨ USÖá»@ÓUeÁš¢Pî{û6öd·ömJQuI)‘’‰ö¬Ô!­lï˜vb·­Û’íëïÝõiÕ †Qª ¾È™ü?PK-qM>ƒhmJ8 rebar_escripter.beameVol[W¿Ï÷9~vìæÚÏmÒ&ioû¼•Ì8~‰]Ú&Ý$sMPÖEÍŠ€M8ÏöMòbû=÷ýi×ie%#‚TÚ'¤mÙZ?À`Ú„C0!&MHûТMbBª´/bÚεïÚ"ç¼sçœßùÝ÷Þ}g9?…PÜœ¯Ì=<¸„”Û¡É!×-¯Æý†gwî%¤g?Éå’ÕíÖÂÀnûšð«Ã“ӿ裮³f¯Ç×yPk» «[³Û¼m×ÜñCך¶q[éÏ3m§Ñ•ýîµ-g=’Ïã'íî@ÃãVÀ£Üó\/^¿ðšL°Õn«¢`â²gCL¸ñ~ß¶»ŽÁ¢Á†ç^>ÙÍÞ*4Xsãw=\w½ÁÆ4ⵎÛäÑF›[é—è¡z6y›C}n56Rb1q[_åuÛQƒ¡Ä4ƒýä^^Ô‚úvÙn7–×L´]IÃße¤‰!˜ºéÚNª×D ¸øƒÀ)”T‡Dß=×#…{ÕŠÓ…v#÷m³8U0 £…} ÷­!´TÂÛ°Çõÿ„OÁ ‰dNP…0)Ã9¦ãAì¼Î°Ár˜Ù˜IVc„æ·ðû•Î"b!ñˆ®Ò·EVé¬J°JS„åtX¤&⫚8f²™φ˜Îc¤Ïcb˜¡þe=f;§ä‚b΄ÆlhÐy•æ ²KU“)ø©èòò‚îF±N0üƇ îD1ZFøqm}+šÈ\E ¢Šctu¦²¯E>Ô„0³bDp% ÓT™žÎ²:]V]†9¯*,â¹²¼¸úÿÀUˆ@r}f Ïníé²¥ïÌl³[ÆnŸ}w!¿UJ~:ºüÂBœ jÛ&ŠÑW…z¤+ݯaåêW±r=’IŒQå…$ÙÕ}²C A /¡¤‚#X#o!åU€£Ê[g>ÂIFÓê{,)¤”cô½üû¸Ú%UÊÐý*Öè.SÞëmÁLWcôc¦¬¬§ËÛÄTÍÔQ¦êÛ„ÊRq”¾M•ÝòëÆºò1ô»Ÿ*üd¶¥©Q¢hiX; k™Þš!Ò~ ¨$•%&9KõªZ¥2DW42€Ìl‘ÑÒ3©ƒx잌©ƒúT iAí¤ä‘¢ ³ >G´Œ¢ˆ9,Bj€=Áp=“ÃIJA—,P1Ó“RgYqo¢ ò ¨ŠûœÆÊ©#0¨6&ME;z&u §Øª9‡KP¢ÌŒ+©•Ü ŠW*ú l‘–•UÅ£qw`†K ,Ë¢Y©œÎ¦sB`²,u(WthÊ Ù±rjëx%ð…goØ8^ }¯o“"w.Qù>L ÅNÖñœÃ`*êÀb2¦Åe< –‹€’OKŒ–•Q÷ÐÌðÌÈžšG$^ÄG¥?vTbŽƒq,'}Áí>élbO“{êñü½x¥ò„Еåüy‰=,}$yɼ„üß³%;¹¯}úÄ ?zpè–|ö‡?ØyîÚÅòðøÒXPþË¿›Ûýù?'º/ߘšœüìbíñë?½òé'/ß·3‘®¼{íìÛ™±g®¯~øíï¾xñ÷[Ïý{ü–úîñó»G~ý›Ü—Ö_úíJñ—?yÿgç_?ôØôTüÑ‘Ä7ÿ_ºåý¤ðÆéÞ¸Äï|ôÊÓ­Ý7ë·V²ëŸžy¾”ûÓ9ÿâöÉï|úsñµwn|6Ñxì__9wóæ‡ßQî U¿‡–܆à¾$÷{Rî“м ç{ñ€Ô#+5ñ ØýÒïúcÒOÎ'´½ÖY‘&—|§wá”;ñÔóoþõæà¦÷ýnÿù›› ‹Î¬©=¼*ð1¾\Ç&JõÎåšv:–wEÜ0€Ã°…z¤ˆ(v ÅÄñ6yÅC§É×l‡770¬5›(1aqé¡Ú£‹WZhhÚœš2§§J5ó”9S:õ9HûúÂJmñÜÙGZhpÝèéÓS¦U77{œ.qÏR--Ožžœ15°;|c Ê߬ˆ•²¢VÜJöúnè5x Šn‡[ÜÙ´‹¾×(öÎï{Þ½O Iø$Ùœ«û¸Ùþ PK-qM>æõ—z¦!rebar_eunit.beamŒX tUš®Ju§+M.T§áMA„"Ý@BTBCx‚¼$étW: È[#APPgv|>F=g\ÖÙÝÙ=gÇarÜñ1ºëÁÙwVG|ÌàÊì¸ß_}C Ew8ç¦ný÷ÿ¿ÿýßjæ-½yª ŒUêj×f‚û´ ‡¤Ì¶`ªÅìŠG3Nëo^W{æ%[R*÷? ÁÉÎ$NSÉ }ïÎ63Ø™vÛ©ŒœæŠ¡˜Œ;S-©ö<+ndœ‹ì m ˤ…üwlHDã²ÙÓ1Kš©öd²áNwE3¦ƒX]鬜#c¦3ù³–L¢%ˆ< $Ä,~"™I»£é–Ífª-‘6ÝýT+$•Ÿ¥e³%“t\ÐGµÜÉâXño‰ÆÛt«€ÝÔ m u˜¡-ÁÍÁhL¨+ź¦dn ¹r‚LH™‘®X0%%»2×| %`³þ¶À÷¶˜æoÁx0vÛ6Ó‘F]à5ƒ¡Žœh"—Ä‚5Ë”D9eúÝYZ”¢dm)f:È^§™J%Ržë [:á\¬®˜)[ÁˆéâgÎ-ÑPG>¬¶ÂÝf†sÛ‚á`*RÐäÄŠ{K{W|@$˜šò7±t˜Á0ª"«‘G1œ—L™±ÂùñD¼ÅÜŠð£!@O‹L…ƒ¼´å†:ºâÓ,؆® †(asH0Ä[≌l†AíŠgÄ2îÚ–ª†„Í­ŽDÒŒ;-B^2˜ÊÀ‹Dˆ*ö-æ–´²ÎÛ±p,7š \í±`&cÆ íÁî‹”8‰Ç›J1ŸªŽªêÉä†Ìx†˜JhÜxh$͘9Ë ª=[ÔF—ÝHEùÔ2D·¬¢ì{§–å¢m"™ŽïåÒ˼eßéu¹#ýÿ&kâe+Wņê§\¹Ë(Yײ_ŠàŸ%(9²NË…¥L±¢&¸)y =Å?Ü( œ;¤]±q9¤EeFËR©‹rA)+ôVä+ÚlS ÕKú¼P,euŽÃ(Ì×ôÙ…l0éõ’Ú!œÇ‘e<§°@ÓV(¢\”¯(”7A.ÒÙTQd\bC{Ù0QjŽH5l¸(3r`ÅpJ‚Ö£¸1ŸÃ¥ƒÇJŸ¬µm‚,ôt¼Œ¨+V1¯ÎÆôX‚ÝËÆˆòh#pК(± 5ª&÷ ºXÊâ: w¥PH„³öh öŠ¡4¸«$_Cà¬ÏkÉÃ]õcÉ–q°¥Zeï@Ep;åáîj©”Ý„†r× e³)r#JY±¸`ôª5l¼(‹¨_YEàFB•(7 …òqµ–ƒZë}•7ÏÒMÖߨ«Cš&ä뺡^‡Ñ ³ê­6Õá4Ê×áCÛ: 6 |‰ßåI:›HšH*íe“E¹ÔPѪáóæêlŠ(O¦B†Š2ˆÌ…è?+W9­œÔQ%:Ð T‰h£•z+Xzé0jò åZAÌ)– -‹(x¦Q¥*šÒ .SÍŒµö@ È Eiœá^ ’3Å’ÇrEgdqY¬÷²©¢¬[LZÇ8v ¢>Õj>VP2|0½÷묒d+1°Ø´Klº(OãžLGiS¨Ù{Í ·ì_‹yÀ=4)öÁ<îð³Î ¨PzÁp/±¸²*ÉÊ21ƒÌRðîê›reV OŽ•‡êĸAÝTÁÊ¥xΤòu/Çrž¾â*V#ÍÄÒê$A­“ÔuZ­²š" ³j÷6K”«Áå—W«ó ¾:¯RB=õZ]½ÐTW¯„JY¯˜æD“ÃÑ œc†JíU,¡6!Á³ˆyTäñJ+…Aj(”¤†b‰ÂQ¨"Òý¾κUCQž ûWÀþ9ÙÎú\ÕQ¼ë(Wy­(“Ъ 8=̵VùÖ)º2OSîæ ñ“oÂY=Wâ97_@@nQ“ËÍœr l²ô6€c5;/_Ó¨mUËj- ­ ŠZÝkXÀ½–Íw¯cóE9`¥ªX#âÙØÏRÖ¨º§`jÕ°¢<Œ¢¼¦©= Ú]žxc‰òF ¹â«d¾Z_}ˆ{£öžoÈÝ rä´V—Vºý¬± §ÂéÆ-Ã6ÙÝj¤É»¾Ñ¢‹t¶ÐWíc )ˆ‹{ÙQ^¼Ó©Ë“¼¯bèót_@ ¨¯á£:^òmÒR…¤eùºæqP»¢Ó²¡ ‡R–V±åðo¹Ý¿åðçÃhÐ[7¬<Dº ¥ˆ‚YB·¨evY/d¡@N9ÆÓ„ýºuðAp0’mx}í;%ûnÅ`9Åàf˜Þ’lò³^Þ©+hæx)×p%¢*ËÁÔKåU¬†4÷;‘eï:jèBLútG‘r §f¯Í¬)ÍPMclâý\8ó J±Ñ)Ÿt9àN Èššmÿ~Ë­frk%ÜŠ¡°oÉ^Tƒnå~'VÁ‰U7rÖG–¯hqît*r…4ì믭éÇfç¥CŠ´Rv(7šÒJI yzØ!Ÿ—¦<a]EƬ†1q³]g}`(Vù ‡9Ü€Ïjȱ˜hkÁšD%­+e·J"þ¨"¸ÇSVnÍ´NMöKªªÌÐð¡©hA©Dª%ÊzÓY"”(xÉ —hazÑJ„gk‰ í€Ì4‰ÿt@Ý„V(ZE4Ç[ŒúVš!Ê­D•Aʈš\)Êm vÁžPkCÌÚ$sas l¾:I«§"Á蓬àÃÌ!Ñ@£@”X@@›ñ4«X@a)dݾˆÉDºJ’JX;¿uÛû®ß$·B²£ŠE ‘tJtû@PAPµ:U¨¯S•¦ÎVÙ_g“OUôÖyš—: ¨( nÔ†*Tô¯÷iŘ‚C®+Y[ýmì«¿”ò4mƒ¦Î*ƒ¦˜Ý茎ýõFǵP‰*Tœ ¤Õ•ÄÑmªd©Vò¦ëÝ;ñ·Éƒ?!÷pbT¦iT Ý—Ç@>æÉ×`XÒõé+´~~È3'³”$ZŸçô]Fs”1±’“ÊžàªÙ{Òˆ\.¶¢œñ³$ß w£¨6W²­°PõV±-p‹å¾î×—²->÷úª'Ùm¢¼~çâå­~ÖE(·åvø¹­’íà~n‡ŸÛ­{Øò³”moB»l¯w£®–Á £ž¾‹¶ÙmÝžµvøÙmt fµìú°qW%ÛÃmÜ w÷Û®›Ýö[~w> #‰9ÙB‘ø¬rŸØ7ð•´ »³®ìå=~¶“\¹ʺqrG%»“+놲nR¦À¯n^|Z~ùȯîzwA¾ÒJ7D“õUdw©;‹‡(ßég·þ^àß ü}•ì.)_Sj%\ÚÝDÕöcû”eÖç@aÀÑ Œ~7Üåg{ ¢û±¿Šõ àz¨U«U­OŽ5†åê$/¯~]žUÅ€ñ@v –²*o…Ô w®p+Ù=È"ÀÌ´›sÐîÔ=~v7Ùq‚û‘õÕì^+ë“Ù¯š¯”^¯õÙk;’MïaQ¾×ÏÀQ€æc•ì¾>ÍDÍu¿Jí÷ùÙQ<ÁƒŽ¿ŸË âŠQ‡ðØÎùûò-:fO¢±ÓûjBpÔ<ÿ ·ñ÷ ÜFÑùØ9ÂØÊéÜoÁUóÊxlætªQ§¥÷ãgàÑÅ锇\KïØõcE34ë€åX¹õTsÓ„:UÙ<&ÚûEÃÚ39á¹Ožqwµ?~cÊöýÛæ6/øû¼¿ùì™’[ÝZ½õ§? –ÿï?~épýO&Úgÿr‡o¡ü?‹äè{Kÿùè´{ôÓvÿàçNy³pÃÄüæ£çßþè¾éÏMiÏè¡æ,w¼øùê_}ú‰œÙ4´-wR÷æoŒtlþÕº»GÛøpçKGŒãO<Þ{vë?œhμ6Wœµ!ÜÚ½bÕö+¯^øzü’wfœijþ»1™+5”§&ϧvU=ùO;•?ÿÝ£SÇ=;ª7çéãÿùرŠ]ãWç }ûÂŒw.ϸ;Õùò„Wåï]üÜÈóÍo ZØ0ö_fÉ—_ÿé+Ö{ïËìým²è?ž˜üÑU×üósV¼5Á<:øóÆ«Öv=|WEóëGŠšÿôHbèW—ê×;6¼1.ïHäКO_ÙóûƒçWD»÷®üþ_¶¯ýü…ž+G>ùàØ”¿Ô¾úÌå{~ó»¶N¿Yíâ¸gÏn¸åŸžúQÕïm`|-çÅUk†ý¢"}|â~}V­{zmÙÁî%GÚ•µµG+]ÿxì-¹É¸ôUðM#еº¢æðÕч¯NyrÄ!ó± §k_ºýÜßþ¨æùŸ|°ëÇ_¾;dÕgÉsç\Ÿ?» ©&õèUmÛ©AGÏU|ãéŽQÞ²+•3Ë/¾ §×-ÿÍ…oÕÆ¼Ã×ÿyæ×ÿȭǘޭ]9â'7_9>zïŸ?»ÐtjlæRÀxaØ/¦-zõʃ¿ÏÛX~:gKô×ÓÖÿqéª]_~¡Ÿô|ùÞ¿W”}¼öC¯¾:äêzVôÉW/§Z’÷å”~-=áúæ¢DˆzæC!;»óž8uˆïObäûXøþï­.×Ãé¿Ñ{wò=Ѻùþ¾hO3òvŽC=¸›Ó©vpú¦oô­½WíýiïI{^ë½ÚL†æù„nkJvä„is:n½ÄÁ˜µ6ºíÞèGYýâÃïì>»aCý‚8îq¸Åï ~WâÿÿÿUËNÃ0E‡Ò6-Pñ lÙ$NJ±äQ¤H<<¶–ÄqbWcÁ·ò3$H±»:3š9º» õ,àÇÎQà¢ë¬È÷±ï}6sƒÒd`ŠRÛ‘ìi‰¶u*XF«ðU[TÍþ0SÃÁËçêöš?Uw[ÇËsVäkÎ6ì|½ù]Z¼\=òêþæÁÀá›'e™3!Ù?vü–¼#ùA×Àì,-ÓbdÓ {læ ù±3±G?¶ÞEªÑÀiÖ¸3ƒ¶Õ™§:#”‚þÇhuH‘ºàBú0”ßPK-qM>M(|ò}” rebar_file_utils.beamuV}låÏïÙ¾8>zñ¹qÒz‰Ý´©kû’8N´í’àxéúEmíœí‹í;ïîœ&hTŠ*‚iË`huRWQ`lE›†@Tªº? L]&¤¡-Z6m AWD·2i =ïùBL&"=òó>ïóü~¿÷y?rSÇNô!Ôú½‰äø‘qS«"Dý!ãt9›ÑÓ¥"§ë¦R1œz5­šA›‹5™®«Ê‚ó´¢ô»-]Q²®‚¦W3¦³¢¦á.T2¦)«­  Àa”ZÙM!9­Tò¹ŒžwÉz%£‘«¥u7ÀÈ™\Ée˜º¢é9MQÕy†”©™ªìQ3¦2o¹NY×5½5/WdSN“"šd¹—¬j²j¶4T´"sš%];½½©$Wô´µŽÖ…œV[lø. +š%QԈЦ^—…LÅ™lư0ÕLY&4©t)ñ[«Z¾MSÔ‚¶­(›é¦±?² ëêjDŒÜe?ò«Ñ±¾H%ú¶¿b6dRËË9_—C¿e°10/Å9|Ý%x9N´¡„ŒGe,L`Ä‹2?ÆËéÄ`6I‰œ€’´ƒ_æ”BØ-pnNRïÄðý8%H«Ø‡xJ’hÜF»9 àhŽ’0‰§ÝÂqo‡ÜU Œv’©:þuLÍÂTÍáóøjÉ+P"a?Qt ^³]E×Röé—¨€)"ÉÏ/ È-ÌÚü¤”ÈK~Üæw 5Nâ@s0‰ƒ$IJI[t¿º©û2(¸ n€‚vZ÷ŠB-ñ~ ‡ˆ–Ç£` ,2X:ó¯,ËQ·8 %ýœ a~Yšã[hXß&ÃI!ìæ– = ¢C1y LÍ~±6µ£`ñæ‚Æ¯ÆÙ¶ Á¯m+{ÍFàDnJàSžÎ´¿ÁíƒE2<¬’ñÃ2wp³}„íÀ^ÇØj7·’`Û±³™±“÷tdAÏnN“Aàòã ”Z²šêéÄnº¾‚î2¢˜vÈÇ«€íq† Ógýô‚‚NB¾È»€|ç» ÃÉ#ä¤é/¥.líßnÒ? n'”튳;l¸ÝdAw\7ÐìiÞ³/ïðå­î‚õv5¯·‹_ý®S¼ÄûX¶6úÊ—7º‹èê]!ÐL°½@ÑkQb@d{ƒcA¶7 yö²!OÛC1!Èâ!‹&x49Ás3a¶wÒ³×+΂ê,Í4ÖuƒÜ(ãF­»¹[Ù½8u#Ì Mß+Ñdrt ë«GnšÀî±,m=ÿGr&Ç&m9û@Î~ŠÙç…+…ý1m³0¼±àX0ìŠÀaWö{Ѭ4ÃC[`¸ЂY]n~uãü÷’» À<&ç·†S°u¸Èm,ÏO¸È3b/bóŠ3HwÃÐÝ0œ·ƒ’åÅDH”DI rcŒÀ&ˆ-9Ÿs-Nëý‚š[ßg7©PôCmj¼HhLÇíé8™„éð °‰/Ü!¦MdGñfG¡£=ì0tu„b†'xG­$ï#9ô4Æ>PqvœêÑCÃã÷iä°b’ÚÿÂðÜÂùSßçÐUÉÿØ/Y®¾ûè²péö‹ë?¿çÔkµ÷ñ'ŽŸæoÎV{øbÏ¥µüS;¾}Í{çÏ¿óàÅot¿VŠëç~|Ôøð•…9ýõߟ+\œ~øø¯~öÃÞÛåtÝDoÿ`éÉ“^žr}t½žp™k¿ýÉ+gÖþúÇ¿¬ü®°~ëŒÑÿÂW.þfϳ§ o}ð‰mg_]:¹ËùЃcåÏúl†{ïå‡?¡~é+¿~XË5ïIÌîÏЖ^6÷/dûäœtÛ>9K]gbÜ4urFÎVH¤äÈ#±¿o -ЉÁ$æÉ™ôôÑ©ceÔZTLax¸OÌdÅ9KÓ¼¬ ªŒœñèp´ŸÄhS©Ê%W.ïŸ2Ž ›qfZ2^K ¡Õõœ\FÑXI«Ê±²¬Î)1CÏŬÑM¯éÓ: ŸÀs°âñ¬a’Ãû?PK-qM>ø¯ÆDrebar_lfe_compiler.beam]TmhW}ó±ÙlÌìNÔ H\+•t“Ù²5h$Ý,Õ“è´ÝÌμÝý˜Ù¼™MR”Tj[LhÅZˆ?’h l+bcl­µ¥iCTZÁ‚E¨è€-…R*ÅbK+}o3AÛ3sß¹çÝ{ç0ó:ºö†pìh‹µînµŒ"àWŒ€Á”Œ’…4L*F±¤ rÙA-!Ó2-|/@Ó»"U =­eÜh% šiñ+lJ6W`PY¯¶¤´{µ<«*t g5%ëÕ = GpMÏКáL¨([Nˆ ²žqXYd Wö%Ët"h•‘Ž%Y,‡6òÕEC-ãšž6jÉ«ÏÞ|î¾rð'nzbؽõsïæþܸñôëË tO?3OI'~ÿyᇮ÷z÷7›N^¼piæArBÛ2ôË«K3gN›S¢3ì•ûÁâµú×v}<=Áß½~çhÝØòõ³ƒ—f÷ÿ3ôýðà·¹GîOö5žŽXnyë©]@þàüâ CYõˆþŸGn;f[- ߈“YZÌ©W:®z"›Gÿ˜NŒ¶L6;?WÖçrízç\=Kô.üj†n©‚ˆ’f¹X”Ñ+Dà4Ê–ª¡<`aJÓ CiyàÒt¥PV¡ ªÊº ÓšÕ,ƒsª (‡@èÏLrebar_log.beamMTÍoãDŸñäÃq3Ô±Ó¦ŸÔ»­RV­ÓݪÚ]MÛÝ ]µÝj·]Á)±ãIêÆ±#Û)åVØ!q@BâK½"n.À¸ð¡JœÊ­Ä$„=pA¼I¼jGúé½ù½7¿÷‹&ž{VJßY»»ºµ„Ѐé\Èm+¬yA+åúnœ=ä¡Dý"“þ7ûêןϲýáŸtö;ÝSAc7ñ!´'“Y〱„ÓVã8„øâOT÷%‘ÃÈïo|í¤÷?3Þ]þ¸ýýÖÌ—g߬oøM(þ×ïO‰þlÐßv$ˆŒƒhÿ=¨E½NÇ _ ™ ;nØF)n»¾`°ÛFY×ox=‡;èâÃß'Ps¤¬ímlÞ©ínlÝm£áE³R1+×kæ’yóúÒ³&ùñú£ÚÆö½m4Ôrccy¹bZ¶yÐ÷OW¦Ú(}c~y~Qp©ØíðýŒ „3K²¨•¶rV¾o0 zaƒ·Ñ ûA‡/´¹à.Dac¡ÿ‚]dâ¹™‡×è¡U;ŠÅeýPK-qM>í£ø rebar_neotoma_compiler.beamuWlç¿ów¶/Žœ}&„À'Û  ý’àx¡ü¤!¨¹Øgçbûλ;ó§Ö¨SÛ uŒµEEÕÒ–®šÚ"ÆèVU[•ò§t-«è¦"M•¶jk5itel]+í}ç3u©éÅïÞ÷ÞïýÞŸ³>oÞÚKQþ«ƒÉ–^¢(×9Š¢R͆2&iMÑÁ(§3z©¬Ãë(lVϤ ]·¼zÅJgUÃWÒ³•¢’Vö[Å(ÊZÞÕÕ%TAÆdS¹‰€ŒŠæ¯ÁêeËôW2º–Só(¯X°ªºÖP6ôrQ5-³Œé½r±¢x³JN®-Ÿ©WŒŒ­Ñ&T½.“ѳŠ{߸š÷kºn£%U÷ät£$[nkÜÐ÷1–QQÜ9¹h*^³ –ËJÖ—ÕkTÙüÓä’Â’ˆâ'tÒ–ž–!‹§Z±P®X qvéNS”¬YƒðkQãŠ2B€šS•¬Û® ÉÚ&CÉ)†¢e”lº¬äMÆTà@Sö5ÊÙlZ)*%E³³J±¦{!9‰æo ìuŠ×PÊE9£xd(DË6ä ½d;³feÌ2äŒÅ˜ê]Š»¢Awy©ZNo"ý­{ž½½'-f"wÆzz£±¨O5Ó†’¯eãk={Á³7ÊLèªöµ>øHQo®([–¢5V× b©EÓeŽ»ÃÐ i07¥Íl‰~©¹“«hA¯ Dk¶˜c‚  (æ2ì2OUÿ¦@Vgšw;DZœ…yŒ ŸÄHÀ1„…#*…pDÀƒÈÖÃDߊpØ>JQ‚W¤0bòŽ áÇÌ(…1Ê`—€S¢‰ˆä1-¹‚Oñ4Æ®0~JØ$‰ôWð"½Ç/ŠX` Ã?€$!V‡²+èãyzRª Õ¨Ò29x$vÄxfë‹ôaœ’@OC>ø8‰]ð¼ƒ}É/IE°OŠ B^w]A¾f 3%Q8…‘WÜ‚S[Ëï¡è÷pHÀ Ô„‰k–¸¤â-Ø×zÝׯñôÕ›çn‰$šå±o JÍÖ#š BÖv0 ³0¤Mà0rš7X×¼/@¼búTíž}À(À@û¼ü$?Í‹á”oa %îð°Où:R¡d<Œ " Dì6Wqwq!ä‹1°ñ˜O"J&0…¡¾=_ª ÁfèK€!!®LÛd(K¸AÅÕ²Z€Už·Ç À9ÌyJä‘›[%ÌŠ'yš¨ËDš{sz^j†8„ û%^ä“!W¼:Í)žÇqÒݶ*ÀOyÅ÷Xþ*k ȵù±M.d“‹|±‚¾´‘±­Æ©É8N¼¦`ç „€X——g$–#Vë­sÚÉð\x¡^‘Už uqó åÙ=œGhóWÝUkÁ{6éX2ý6¨·¯âóqmâÙfš]@,Бä£È¶ÐìB0öƒ±c·ùE~!¦šxŽÄ-&+¶V¬ ûZ¹ÍÚ €&$ˆØâ iÒE¡  %¸…°ãìb²sK} øv®â–"NÄâ²7,NRC)ì\g~ ™5ÁƒFÔã-MpKÞ2€º  ºVq=5Y…’©i„’ 'S'mÐVœš!=lëã$Ô""JD|Xâ$aµÀIPT„[îä¢4»§. ð>@À¼µ\7ÍFá5¥Ùî¯2ëªgÖ“à–f©´è%^ÌÏ“5ƒ]mt³í5×8œ¦`{éDQ£–±|©”ÊðIAâñ‚¸@Xç³Ä‘Ô,&GÌ¡AZ@æ8±g®c'¸ êì¢c@ÂŽ}1ÈÇÞ ²Ô±w,w¾‰­³w×é=N,ÜE¨ãàÄ;ñIÔé+êb¿Qg_Ydzϱ×ôÏÕuu­­ã|»£cÇd]æ0Ñ“ûIÏíÒÃUNœè蔃íªÉpEÛæð'Ï)'.áøRîC×I|Ò99x´ëåþÇ7¨™ïN8ºcÿ±'¾µvóY‰¯<¹ôÒ“ßœzàÛ>¸>rñÈQê§:|?ÒÂè…CoÚòøòÿ¾¿këÎÜK¯Þµï•ÝÁö ƒÇ*mósß8øÄèÞ×¾ó÷ûòÿi?’Zñãà¿6NoR¯<|{gëúÙ}gÎlîËw¿üûöâû~yùÌs…™Žeì¬Ó×ZϾÒxâ‘{;÷m;óæã¡ÈsëÉ_~ú§^Éa‡=ŸÐ÷>/´>6_ÞxâþÁ‡Nýîè«;ÜÒóh¶åà·û®u–6õ¿yÏǣƟÙþÐ&kÏë¥âî¡Éìñè̇GJê§f^¸r~÷ÞÏsáˆqü\6z`Ýùk…;;×øÃ…ç~=yùìGwÿ©éíËè¾—Þ=Í}ð÷;„3—o+žnúüûoÍ;7åïžsÑw¦UkÿͽÏÿ퟇þÌu¤~ûúékG?Þ%üûÂŽ¿Þóì±þŸÌÚ½àô³ù쓟§¨ z†Ìg„»e>õ3¹­nçÖ8:Ù~g^ ’Û²Ìñ!ïÑ"ÇÞ Òîèäý ::ÉË;8¬ó\Û9Ÿcg,Ë 9¿GÞvzÜ•¥Ð^S³4žêïKÿêÞYRº}ÅÀwŸÞõ㉉¡-g¶?Cü½Õ«µI ž,ÅÙ—¬´Y)•dãq ·Y¸Í(FS5b¡ÕåUµL±’U²TCEƒ+¸ª)ÙqgÙ,åÜ>²a]zÛÈÆdjŠI½½R¬7ž–VH}ñ5'vÇÐhzdÓðæÕ˜W-qåÊ^I“&lN{ÃRÊè^Ù#6ÆRKʸg ¾ÌÞ•]2'»åÙo¬Þü T¢g\/)=p/œP{L#Óc߿оòÓ¥~–LPc¦EÞ¹ÿPK-qM>Xù0"T rebar_otp_app.beam…W}lç¿óëØÇ¯}GI Gl>‚I|Ž/é%©ãd|6ª«Ö™³}I.>û¬»sÒˆµb°MQ«‰l* vü´ee“Ú!婨Úè¶±ŽÒI“Z4Æ4µSË*­Ò:íyÏ—Ä+šéáž{Þßó{Ÿç÷¼>½ŒQ”ßPrpÿ ¥(ʵHQÔk(ÙHëV)-—JÞ¬^(©š²¶…Hºl©šéSMûÅ4²nË(+5“²f*¬¦Ë9;> 95ŠaèF]%ÓΪ‘3ºa¹ô…À@à¢YÖ,Òƒ6¿ÂPc7Êä•yÓÒ …]Ñ‹lÍddÓ®ÉOPv×0ÀkÚÐçð Ò‘Í«9SÑ& ½& ŒYÎX†œµ¼“šlYJѯdÔâ2¾&£ÈÓm ê*¡4©z-Ѽ꽱½:)*¶kÙðWÅh¬]l¯# ¤*XÜÔþÅz¢64ÐXûÿ\®0 ƒÄU³Î%¦* `Ý`,]ÁVü¢pK(,qHB¼SâêGK ÒxW&I‹Ïx)ŒÜÜs„–$чl î[B» PPÄ2}tQÜ¡ÈwKb2äBIqRŠBŒ ˆti0„„8€.³BR6ç½Eú%'‡`«@Ø+Š+U|3sš>.¹¹,H÷‘W$ u£…ê¥K((rôù/!ú¢+è ôU?I/nÒ ‹†ÅÀónæSú$ ~È‹öÝE»î"a¥ì»Ü‰Ÿ†|õôí æè{„ž f&Ô Í×H‚„6}˜(ÀÖƒl=hÀr"ËÓ ·ÂÇÖ¯ê&:`¢ƒD3ü °KRdà¥PÂÙõP¸›b·ãCxD¥î§0†°èJ!@®f|ˆ¡”¯1ÅW00¦”=m<†FO”#ì:t Â^|Þ‹/zñU‡€ÝåºQ貞´Ú­†0ͬ_ƒ±ä ‡$߯a7 _XJ‰œä‚ØVäoH®Jò,`Ø$醕”Ä-¯’(/¾ÝÇ6¢]`«R³Ðs)Hn$;7Á¦;@ßæ^v#D¡xÛÚ&°X”†BÔðPOÀQâ©áÔ„Ä…¤' #¯toå84CÕl‚ññ&àlÎ?¨ŠÀÌR‡*b0  hcØ@CT’‡Q¹4q”[(é„ÝFª„Ì)šÙ Œ1`l°!Îf)'éù8÷6TùYq<2NØ#•òPo¿ðN-|‚ £=ìš Ãø°¶K„˜ _¬"‡Å Íl!Cåá øJþVäü ˜­@{€â<· >ØÎ6h§žÛý%¥.òzHï€å·Ár~¥¼ô˜çÔµtiü…__þÎçŸÜÿ~ÛÙ·gÿâ›·Äë=ÿò°={rŸž%º—œY 8º“9ìq|¸·RýŽßáÜ(çLÅœ³Öîø-ά\Ι UͽÁ‰-Ë '5²:íÊQhÖ,Ú/EL½©d߉}÷ÇFàÀüñ÷ž-ÌÌ 'aÍeãÝïÕKä*i’€'G±öõ7m– Ù˜'^¶à™§ÜäîD"´š§¼j1«•sJŽZ½6N#XËå(ßБ±}§íO橵b,&vÆâi±Kì‹w-ƒ˜G‡'ÒcF橺)Õzzb¢œgìšfÄ¢òTM¢£§£“ÄÜ–ZP¦=ø(üIvɬ\#×Ê~»@S/Y%OE¢ÓzA‰æ•⌅›uÔ¾³®zËÿ=è€Ëô E fL‹ à?PK-qM>–ú$m—ørebar_port_compiler.beamu9 tÕ•3š±õ$ë9#b'qH&%q¢(G²ãOLÆ–eåo‡ücG–ƶlYÒÈù9ÄäG§¥{ í² åÓÐ-ì'Kt»ËvOYà´å„B( [ =–J~…nwïyNDz6ç<ë¾ûîÿ÷ž¢îž- Wûag´cS‡™ç8ñYŽãŠrÞŒçrÙ¼9ÈŽçRi#ïd€Ç²Å|Â(xlÂD63”&Æ9NLGvÌeQ™‰B¹‘OÇ3ÃŽ@@Le†².›#`•!yÁ9”ÍñÄHY"mÄ3’M1ºŠf*]¨HiÃ4¤Ò8‹g’Óú+lZ‹Ì™* Äó e(ž.¢™/N’N ’ý©t2Ï'§Ù³ƒ£FÂ,Èùbf —7˜k#Y°¼˜IC©Œ‘œaùÇ…D>•3ðÏ JòÆp1Ï;RÙr0|M§2cŽöva<~ ,i ‡×·“éDVŽùa[ÿÀD<ïÌæ“ÉTÂÁçd™‘Ïgóe"±X HÌfseñAð§l(›N¦]Cù츕l>XQB(3"‚ûT|0m8òXŸKÇF8ly«0ˆ‘7 ÉT^Ld“†å7îœè&¢¢p°`ãX4åP`‰¸Yž- §#[(‡Tä3ÚÅ52/¦­’s¦2‰t1iP¨<`}C Ú Á´´fSÁ* ð¼:dðËf Õ0Øef-Ÿ¬JÆZ¢v!~0•!…ì@!g$ ¢y0gH…ý)bH8N¦Ót<>f LÓ8À<ΰK4žËÙeJƒ H[ œ KöÕÁi1õ¡`:áï×ê‚Zд#P¯• Ë ¹tʤh7bsicf°$' b¨˜Ê9ÁkSZ¿’Í ^­@^•>7øõ–äÕC'Ä]!ƒñ‚UÇrЪv&¡ˆ‚3®àlU_§±yƒ¬:UCP,fÁce¯z¡ œ,9å3ŸÊ _Ë¢ÝÐAEèV0 †XŠŠã*ÃJœýï4¬[aùyÉQµPá•Ê^E—ÃzŒSõ•².t95NwÈ¢r2Ü(èƒBU¯Ìkºà9ÚgáiL|z^ÖªÞ%LS#VštAÖEá´¤;Ɇ½"‚Ñ*Q¢íˆ º,ˆ ƒº¨êŽ‘Ý'x}b/½®%*´F¥SàäNARuYÐU0χ²ü¨ Ãë÷†En—PU8‹b’¬?V)Ãt*šîC†%ØØñúZïuT}¬ðû<šâuÙwÅwÿßщqJú°b{öJŸ¢4Aõút¿€ŠuQ>­HàÇ ¢2‰Î–øœ£Ê]¥ðSÍÏ ‚jyRm}RU<šÞ©rB§*ùA–ò9¥^í¢Ð&\¬ÑÝ3ïqWŸåïy€2夯?*¼~§´uHÊ•h¡Ÿó(º® Órl©”F⟠@ù ëþ-0 ,û°\¢Ež@æÝsžx+5Ƚ_wתº{®ìÔr-Ô'´Ò+î>ˆ»pJS ÚZ–VÓ*÷L*ó¤JÒ¹¨Ï!DEÈELÁ°MÑx"K ÈÛ˜&8•»¤^®[Qcî1TuÈVŠÁ5åZ Úªí,hµ<ØNgòÄuîZžÌÄúÓ@W5$Ô€d˜®J<™])I¶Ý~´{9VˆQtØš!™¬AW-èªÖU+òdÊ—@~-ÊŸ ¢õòäºfª ž©^¯èõuBRøõPXW»ty«.˜NéFÙ„àB1>£Çt™ÞdE½X£~ —KçAÈæódFÅÄ í•Á}Ó®RDŠþˆÞ¥ê[¡+BzR(ƒâŸâÉ|›<Ùgybõ…D—7ƒìAVÔ/»ü°S;ÔPv!Wv‘ŽH_"Hý}m}¨ß¡Šk]À%Lý L™)3,ˆå@ò§ô–Ô+±ua‚ Zít!O€ÔDlꦻþ_&ž,´ü7lÀ±+þ¨a:WðH½zHÐ#PS^i+€% dÉ11†keÄÉ^YuºØ#AB« N‰H%ŒDª(#^Q°y–y=×…éRÙÃIì¼Jà…*ΗV* Î.Y€@æáTF¡>Kh€.x»p!E@[sº{%¦JÞf_&é ÛwµæÏÉŒ”øDŸP¥UŒCB¢Y¢e× ØY‰ ÒÆP[ˆ6Z© º´ž'ÁfºÂÊö¹záo"öL; ódE˜6FôØèbR"Xv1»5S®Õ@Dƒë]é ÐO´fÚèHŽƒ‚+ìÇ{À ¯´T¼e©Yð‡< ³ÃF=F$šÀ“FçªfÚj2Ú¤¶ÂR<úô(³Æ§€ýáTÈÌÚ =Övujh›<ˆã›fr×N[xÒ '‚» Þ%§)ê:,D€,öDdt?F@‡(ÌgºAj>cÍt#KD·ºZ¥Ý5ºF×*tOÖ^MI¸SUJnº GÑ&kr¯ƒq´ž'ëØ@ãÖ©»ï 7t3RÏBšÙÖd™ÃÁ½Õ²÷H™Dü·/ÂáÈbô§TŒÌ‰ Q9Fj{;7&Feµ^gýgý/°c%æÃc{ƒw M»Ð²N•ín+ø¸âq£G’¬‚<7ýâØ%C b° èvB…m¯”4h™½¶mKtøâ·Ÿ C g€ÖPÜ »±«…î„æÜ)ÀCDbý鳇*>|¤sºD,‚h.’­·‡õêÕd1^plD 1ä°&ÝnT¶ï{À¦½MÃöREûfÞi?©rº.gݽW¶ðÖ»±ýˆÅ{ ‚\w7¦c K6næIm§<é ¼º¦q<°®Ëž¨ì°íØgýƒ5û Rƒz”&YÊ“b I[…Ó`O @r¨™ý$ÁMO¾]%¯=$5}» ‡©“gÀ˜j¦£ÓŒ`ØRìÚeØäð`y©˜T©˜Ñ0A1c fº,ÝBÇ /cE‡¼D /}pCB t<Ò¡bû„všáɸBøÊ¤ÌH½ 6¦“£*»~² vf¼ä² 6kÍbd†¬÷¢ "Ê5áÉM@8nä›iaگݮxG–^Ó›P« Œ)`,6Ó Á£ £Ï¡ÁÒ›y{Ymæ°ZŸ¨©/ÕP,Õ0¦&jØÒàÃfz4(–YÜ áT°&ŒV†ïîRþƒaºùÿ8Xx¸…‚²b€“pƒ#Íôæ’œßXjÑ‘R‰7‡é$2Æ,TøT = B²t „†­'²Ê.pN+ Vâ» °VÚ_Àö:ÇÙ|Üz&ÞóùOnÁ7ˆõE†äÓ:g?ñŠOc€^nw'´AåmTPe/\ß$øgO3>͈òÚqœÐ'À"p²…žGN€#Nìºp€ž-=§Ö BŸ™ßŠ_×çàÓ1`#,V,å‚å€UËÃðV%Ãã÷N/,– ËÇàX³Œ2¯c¼ˆŸÇðóa)Lò.dðbXK Âu ¿´„mXÆh”è 2í_ÁèÖJxJhB ßkU ÜÂlFÛÚJxW3<Ò´—ȹžÑtÀêd4Ó0Æ «›}OGúµ%ö¯cðX â719È{CI|¶”øuc ¼­$Û™”¹‹Áý°JlŽ_OÛŸä®Ö€Q’‹Ñx¬ÞÂà\IL¾©Î3¸Pb?櫈øè¬C.ÌbµÑ&ŒÿaÍ`|åìÓZÝÅ òNrv회÷$ããÊ}YæÓ;w”=½c:Îö‡™<Îñðòûác˜ísŒãÞ®@{‡˜iöépüöw³6¦Lì£'À„£þúέ{{ÞÐ|4øDï>}äÎ[ñ†ã ÝuÇC·¥·Ìl=õÊu¾WÏ?¿aÏ_4mZØf™]ÿÇî›üî–ëyzÇsÏý÷ͯýêóe·=¸íãß¿þ\ëÅíï¦7äî;x鯷ûÅ5{$oÃî»ûÇ—3ß{2ÐñÚóò?~ÑyL[<9K¶wÕ7猿öÙ–šBÆ;¼ð“¥ŸŸø×^ül«ÿî§µ77µ=ñóî‡/]ÓKåO>}ë;?z|õÿŽõfæ½ûåïjÏDþ­ÿb²þdlæù‡®t¶s×…ºó{W¾þ;å_ö´]ض‰°mÿü-Ë'w„*w¼à8tñvõLlé?ö“Ô¤³8qß:c^îÞÉj/ùàWZnòî½ÿòkî÷¦ÎÔëG^ýÔ1ÙÒpÇÂO(ËænèkþSîƒêK_î~éĆ–;.<¹u÷ìó3»Mt<ñ½W>÷~õÎkÏ/÷¤”úüÏž“{ïi{è§cÞ§.¾¹þõ‘†³îS·<ûÔË}Ëü©çRÿ¯‹wwJ?[óØí½Mg/}qó—G/ÿ¦ÿ©¹7Ÿ¹|¿¯ë¿þYìï);ùUðÛ§N×½~{õ¡Ç—Îà^åîÿ§þEíï¿ôÿþÝzwŠNá½?wÃåÚáÈÚÌ/½ŸÔüàÍ]úÆlj—?ÁÙóµ´J{&ÃðG®é™4ë“°R ==Âàü5½TÚ? F“býͳó=Lï^X»gØN†ÇÙ¶ƒáqþmf­Þk=ƒ±·»Ü+ÂlˆÁÒ¹«su ƒñ¼•Ѭa0ÊÇyÖÈðx?„~9¬z†¯cûéù¼ˆ³gÞ{*£Ÿ k£ñ²=âq¦U1<é0MŒWÝqŒ?âHrÂD!cm27zì¾ËúøG‹Ž>Øÿ½Ëß½}bt4².ñ‚ûßšFHïÌæðÿ’ ˆ(OrÔú½c Pç"Ay¶h&Sù1N4SÄð©1nú'…$wõç¡Î’IÎÝyãº][×mŠŽq3Vj ÚʆЀ֨µ„§‰È¶HßÀºÍÝ=c\ÅpÊTV­jÐâƒÚ¨eûÅcŒ+ ¯Xµb%âD35nŒ”CÖoÄq/‹»âË@û'‰1®¡~$;nÔ™ÑT}!Ÿ¨·~h¸ }ýç»F>=Ú1XÀúåþPK-qM>ºAÐ48rebar_post_script.beamU’AoÓ0ÇŸ“6]×–v͈à‚ZÓnS5NiË&*mÚ .!MÜÖMbWŽ3m„„Ɖ;BBˆ+$Ž ‰OÀ• 7¾v–i]¤_Þóÿým?Yoÿè¸  Ûý½ÞaO°¾IêO<î.Y"ÜÄçd)J>‹—$ÂfWkE?ÂÝÈþ«º‰Ï°ŸŠ[ÞrJ<%Õ«;|F§dVžaáFÌ÷¢Ê•œ %Z2×XX‰YÊ 2óÈ£³º²¯È`Ù÷[I®¾‘¤&)¢†Ö¼k!Ë阆…‘­5ûrœãlõTkN,ô² –Ãï•lx˜êÜÑÌ’ÕØ½Ð]èV_óÁ…y‰–Î¥Þ½~¢£wZó7 NS5,ôU®è§£›J°làDð±jb/UÜ–$k’²D:`]R‘h’;êÍ%h%×öÎní­åõjžC~F!?ã:f0œ¿…ÚcäºÑ‚ËxÿM¤*s-ý4¡Ù‚6àÃ÷î«þ¯/‡|þ÷âý§óÅb0¤SY32AùKl)£‰Œj˜sÆÝ$cŸ+ƒÁRBOU "!”õ£4ÀÜ À\—µ €õþ³áÁcw<<Ü ¡Þ±Ûm»ÓÞrí{wkçÚ´ö|pâGûG!TfDXÝnÛö&ö"ëéóD6Bq{³»ÙQZAÏ @é§y5¯è•½jÖ`ÂRîãZ­9‹q+ÄtAZ ÷[ÙäÝd«c»)çnЛ$B=üPK-qM>p´÷–{iÀÉRT–,IŒ­"®•ÊAŒ}jæï5ÙÂ×8Èĺ³šÑO Åaýîü€Ñ)™UgXx1 ü¸v'g‚Ä©–Î5Õfòs„N™yìÓYSÙ×ä! ±ìù³Ä„»çTÒ”‘©YOld»½–acähÖÀF®{ž¯ÞhÖÄFïê`»üiÅ­Lç®ÖªØæþJ?Xéö@‡Ö‹Uë-Ý[Ý‚úøZG_5ë o®¥Ÿš6º‘+ýtõ–lG¸üR51J–*îHJ’ IU"°)©I4É#uß´–k‡×ÿímõz‘CqF©8ã>æ³à²¸ µÇ(t£/—ñÙ§XUæZúUJó5î¾ü5þ~Éžÿ~<ø¾X Gt*kåÜ_Rþ [ Âhª#„æœq/Í’Äçï•Á`™  „'„*‘*„qâ`®ËZÂæ`<:~å]ŽN#höœn×éu·=g×ÙßÞ½7m¼^x£Ó£³j3"ì½½®ãOœEÞÓæ©l*‚òN{¯ÝSZIÏ @寯ù ¿ìWýzÞ`Ê2àÚ9Kp'ÂtA:):ùä=dkSÛ–c·ÜŸ¤B]ü?PK-qM>rFçŸÔ rebar_protobuffs_compiler.beammV}lgÏï9w‰}íkŸ“6iÒ\b÷3q|Î\’nÎ ®—µk«.eh‚:gßëø’ówwn; b­6Uê†öÇåCˆMb*hSAh'>Ä4U¥bÿ ”•IPøc¬P:&˜Ïk_:°ô;?÷{¾Ÿç=û9–E¨ûõÙBþÁ¼ïÔâ®"„&ú]ZÖÝRÃu|§Ü¬V½RÅ©7L‹ºB U¸XfYKO¤L˜H[wT+Y %ÔÇ‚J´¢‚E¢ nñÌ5Bñë ·úat’Hã–!PŒçiOî™õ„ç ä0á.„âo#îb!íoà£FÂî‘qÉÜåP¼'A¸kQyTYP ½&‹Ê"ân€j+ánuªŽ¶U"4ÙÓO81¶ÑOP‰F 8$Š‹2TÝÛ8Øn[yc NÛÆºmlNì:Ód(wµ3¤@9×îV“y#á ù^€ÕÔYáY™ÌÍÊ ¯ÍÉšœÐpJKæ`b½ª4+‘†`'ÒVWàÄ­0ðB*$kÅU,(µd¾<&õãcZñœKiÅEà¯ äÆ˜4ÈÈEYKàXBPnµ \Mí­›Ì°<ýíæp!…“Zñ‚ãc ˆ~wñi h9̇ƉÛrRÛ.t;x?æÄ!8âvè{'ô=<-â¨BòCs0‘ì—|¯”ÄÊ,Fò,&É1))?>.${öM-$!5ÏR_„Ôí´3Ò'*`‡qâtÅT1š“¶©“,k ²î…íÐâø0cœ¸“1PÇ.¶ 1Ή»÷=ÓÒ^(Ni'³CÓ 1Ïæ¦%g ag—(¤°¾Î½9i7,™%ƒ iˆ<>-¥q”°YùîA`Ï@§o:'1Ç pœÇÌ´¤â¨Jb|{8)ž¼ÁX óä‹EÈ ö’Er@•‹©"_Ld§B5'M`Ãþï.°~¾Þ`ßȦâ Ðp@4àÙoE,„½€¾@fü–~ °_·á‚¸Cq¶ö `$7F;|žù&>Øð»»;bŽý—*œnõ› úÜèw2 bIA<1ønáé3ß7À¥ÿôs3OÍÄyò„Í~¿2Zør,’WGê\yó Ê¥KÞÚÛk™¼ôð·æÏüùSÉoîùÇ–þ¸ãáØw¯þ4÷î+k?®ŸÿÅà×ß;ún)üúµÜÌg—^¾ž<óìþþŸüÑåæË¯¾ðÚ;·£Ü|ïêõû¾ùÈÀÔ3·Ë¿_šþÈO¾zbuç[¿²ž\:½éó»÷¢pxõåO¿?üãÿºÒs+öƒÎ~Æ]ûÒðÇîüáÏ ×8óÒ}¡\æÒ›ßyøû¯~/ÿì¿ÿ9øþÓ¯­uýúÎÍã>eýü`ßÏ^º±n~ ;äT‚ÿ6¯‰`6@:ǰyìì øá\°÷ÁŽÝo xv¾ú™Ÿ­Ìvœd6÷MÁ"yßwÙ>¿h1m-d |Ò³[76AàÆ‰OùMê—矻é}ÅxgyynÞ®‚nSËžgö‚ÓðMÇöÑe ©õîQòšõºî>Æ ºœ¦Ì+ˆ§eÓf g® Á´+VÓ ênÚ­š65jt†zfÏúDiaþÁ Ú<©f³êdöž’ºOÝϾu#ñ“s•æ8²‚"K¦¯LMeU½¬.·j:I]ŠZAáÜÄÔÄ$ãx߬ÓZW!á·zH—ô°Þ­G[zNÓ­Ð4•©9ušY¡ö²™ñÜJ¦õ.ñ¡ôÿ^É&à½j¡|ÙóÙ@ÿPK-qM>ÒET4rebar_rel_utils.beam]RMkA~'³É¶MC†ôàIXDAD›M?¥—MkZ"m*ýÓF!tÅ<Þ½h$ž#´X$,ßw¼ˆý&³yÐ LxN0(«1ÿÈë!eÒÇ+ §-1+¡!’«ÜdH¢äI)‚¬21HoÖ ±°¦ÃLð*N®Y“ƒ =$&lxs²©UÈê¨Ïጞç*_ZÜ&&z/AŸ-<§ÃÂ{±ØWZþ¡º-‰¼V^2oŠ$¤ž`*‹•ßÒq®9Nç,eýÅ,_̠δªËt-‹ÕÉmñXõÞ‘0Æo{N‡v:§ÃohòúûìÓæÙÊ­ó󕓯çÇüÍÏǰ‹ô ÀVØÛ¿ôÚˆc!¯Û/=5}˜£€¢ %?gÏ–“ñ¯wŸ~\?ßÖ[A_æ´´^Sõzxó0ˆ”P PbB„ÂŽßwı*(„I,×Äuy Ä]ÐyÐóÊ(L'e}0:Ä2G)̬´¶îÛû­í¦ å³V3j‹¶¹l®,._M=Zß³[íŠõzÍtºæ(õtÄD$M¹_š¯Ï/(M‹¹Ï†…®ü!?œœSròδ3›ŒÂDô˜ ÷ªÃÐgU—#^D¯šnöUtµþórOGn«7ü PK-qM>äé ãÚ Àrebar_reltool.beam…X pW¹ÞÕ‘¬ãµÖYye;±{Ùy)¶eKŽ"'vŽ%ËŠót,;¤I‹žk[Ñ3«UgZðs¹.̽ 7÷Ò6!}·Í-i‡@™Hi`  mJ§LÚR eèƒKdÊ´L{ÿ³Z; …â™_ûï9ÿùÿïîz‡wu3Lí£¾ÀàŽA5—aff?¯È±¨V䴚˥ñ”œ••¨*›õKA*j¸ +‡dÅK™dEÉ)“ÑdZNT–ΦsS¨BVÒÑì”IVr7›âi9šJ“ .ªÉtÁ¤dÂÊdUBN˪–£ñéÊø´O…²Æx.!›ÓÉX8‘TªJ'K‡¢±œ¢bª%ÍÈ8-hLU:M„ã¹ìdrÊHwÍÀŠiµ²0S«Å|ZFÀ™ÒÉ‚Z0§ä™Éd6ašŒ¦ 2^MÉ*µTYÌ&dØ‘–’Í’BŽnO¥s±hA,ÌÑXÚ´äQ7g‡¢JÁz(šN& Z4|áh>_0)\X>L­VëaÔh¦Jaר*EÙ AÈÈYµJ)fâ¿„ èØ y9Ž•\NC)È`«|Ç ê É\¶ Á­ž1ÞÅâP Z÷YÖ6|«„´¸ˆ]¤za™š§ÚYì&ÈE‹À EàAÄåÖ¶i-ô‚­õå®9‡_o‡ AHjiÀ³¹@§‰ðCÂ^ÒÊ "éÅy†ÑÅâõZc«j-Ð ¶>(ïÂ`Áu^~#(7:Ѱs›àx ´J©UúPC£ :ëhÓÓ¾õó›XÜ'HLÀHÇ'¶‰ósÝ…A²TÒ¬lÒj´Ÿ6ç…´ $¢7gÉä@Éä f²ò°†kÙG¹À0è6\Ö—j‰Åµ4³0|0Çi±.4‚ñƒ~?ø?´GƒÈòò!ÿ&?ªŸ•ø€“ßBøÑQ~7‹>?÷ù…‚“Å7ÆA€pCü0àƒ,"³ÃN ‚†€?„* ü,ò£d:Õ5]@Ÿc![ Äuþ€ËOk¯´‰ÐÃ{KÁntð{ИæÛ¦Å'®Ÿ·j£/( ꩞á- À|~in\„ÛÆpÛùmr‹G,ùãPF6"‘mmâ¢U's ˆÏr2¤±åf/é*Ëúèü„¨=V¯?P†|H$ dM”ÖµZ€È{ù­ «üéÊÃ㵬)À¿¥´ ó,Þ {4¢ö„=û4Å×jg™8/.Ä‚v?XqA›ÒXŒ²x›%nÑMt!ð:ƒ„†Èܸ†ÙýqÌã¢u|éöŠ´"°x»†ô°F(êO¶C¶ý9Ûb® ¦–]íÕåúC<r‹ŒnDüÔ^3¿“sð»X¼Së9ÝlAœ—h‘þÔÌhyÍøüΨnT˜==< U< U<LC‹^Éâ,î[Ñ |YœÒ ‚tdx£†·ƒi¯_´ýæ%¾]ÐdD¥+í˜`ž£q7A"‚—õªŒÓ—÷‘L®ì À®¢[F UêkP•¾ÎU—ñKtÞJÿÐyÈdªªÓ×—-Óù& åºþV eòme2«t~ ÐZ]†âY§óô|g†.ýÿºî,ÃߣËPÞ¥ŸíZ_†yƒ~–âܨ¯o"z\èÙÁ2_|e˜‡õõ Чë#eü°.OÏî(“ßYÏ]ºÌШnwh¼ìì§Ê0ì-‹É¾2)o¦ùeܺžôý°ÎÓ¿›€,ºŽJýªÑö¤ g 8zÏỊ¡9±[x©®áô¬ážÿÝ:qwò"{›úA+½x·/ð:[=¯´~ãÉ“Ï=—êú¶'VÛ{Ç_žò¼‘½<û­GÎ|ù½—/}oyp÷Ÿ7}þž¯ÿâÝé«Cooöþiã©Ïðè+WžÚòÐögê~1ý?Ÿ¿wê±+k~› ÝVøÍ¦#‘GÕ}O½pôß¼Q~qÇÞ#ìýñ½¾»Ÿø¦kïVÝ4òô™{Sßzïk×ÝúÑö UŽçޝ|þöóèá;¾ú@ôV4æúKåõT¯àoXz’m¾ëHÕ“~®GX{ÿÙ;>sñà_ß=zã·mÞ2Ýz굋¯tÎ]V.Y¾[µõßf²ý‡-ê§óƒu¯ž·oÝØðÃû#Ë.úês^ڼǾ2ð~W6ôòóWщ /nÚ½nðÄ>û“ZÏ¥ƒï|tõô·ï¯ºô…Éo»tæê—í½ßÿù÷Ì›Ö?þ«?’,7~êu«ç?ÿûëöÉ7wøß›ýõ‡÷$oœëü÷»~6»oÕ­Ìk/5Í9¦žœ©Më —´…{cí¿´ãuo~î©æÎÇUÞ»÷«O„ÖMü:9¿S‰ý<ÿ¥/íæ_èøæ;ÓG~'KÏWïš\ÓñÈ™?ç^­ŒüñöÈçŽNfÞuó4ܹüåµÌ©+ßùºé–—\þâPþüÝW/9î[ÿÎ{þs7LŸ;r¦ã‰›¢¶ÎÛF/ý×–4óØóÓo?êØúÆOjjýý¿¾õÄ›Oß÷þ-ÿW­|çÈùæ‡Nˆ…#«‹?¼rnßwοúò±:ü…ÚïíÐÑNþাØÚí¹8­Ñ3Li®ì×ë/ ´Gç÷•Õ?­w¿^ÏC@zMÓíÓy/P‡ÞûtN¬ÖÏÒëJ·µëòÍ@-:OgUƒÎÓyV¯ótÎ-|ó¨TU…ê›KÓÝiC‚A‡ Yí&+0óø¬:å+„6d.³·ð;søG²“°gÐäTÞœËÓ9ºP‘`xí+d¸PÌd¢Ê ¨ÈÕDRI1F9–ÌÒ6™bÌÉl<]LÈ æÚW¾i{‰Ãù&F¶…ÇGvRÌ’gw·³§Ûvö:½®Þ!¼Ç ìÞ•bª¦’ªäñt;£1ç “þ.ŘܞκfT“yº"Æ0æËQC”š¢•Q‹°+*q9Å8º¦s¹+%g$» J¼Kûêx[øØ)+é0@c•ñÿPK-qM>£™GŒÜrebar_require_vsn.beamUTMlEžÙYï:vš¬H$$¤-F-B"^Û)QA‘ÆI\×Mê†$T-—õzwl¯íÝu÷'j‡‚§(*BHETA¥ªP„Ê…S{°¸p@7¤  'Ä 3ë5¤#}zoÞûf¾7³³ïÌ…ü÷K•òù²ïX€Ÿ(fS.ij®ê’+éuÛ³EݱfŸÄH`›þ”Þ!zOÝ&®g:¶'‰Äõ=Æž­×»e¶Q›øbDˆÛ×ìvÒÛñ|b©¦Ýr8— 7°c–æëÑvB3H3hOŒ¶é;mD‘Íßì{1­é¸þôX×ñL6ɬKúDóHÒrŒ OB‰iZzd–ƒçéY%0uŠE J\úYÊ‚D Â¥‹2ÄÌ]çÒKlLÉ®‚ÞÈ`”€ßF¢D£RóQ‘•!z gñÃàð]8e%,Ux®TA¥®Ê™ÿ@¢¢,~¯%ä*(Ç’U‰2†»8‘Í„rY”âS#½,N<õŸ`ö Áýïà'Qšm˜+â Õ‹+Š žH‡z¸ºŽâ2–áýs~Ç¥3þˆÓ¨.­ÃßÙT‚q £ É ´é»[ìÂjÖ€ÙK"…YD1A‘ €IŠÉ(.EwÌü4E†‚‹ø³ìs•«áþìñ3Q^Š|6¦¢½¸ˆÃ±fúlí Š¿®~¬7 þÒN,¾(¯Þ9-ž-¶”}åàäÉ™ë×gö?S~~üë~ ƒk¿Í¿™YÝ+mlfßßH®–Þz˜ø¢|üA‚|^Þøsçb"&¾ÞÆ{ÉÛ²·I—Ÿ~›¯ßÝýPýt7YŒkk¯vßèÆ¶n½´~ëå÷*‡¸^ï6¯¼pgñ~,œýrå2õØê=ZØš£oEçQýÌ eßw©}þ>‹t8 ú´Ã‰-ê7ß>siøÏ9¯ps°rf»ÝåšÝ¢9!äóŒ/:Ÿý–, àq]ÇU½À²4w‡'ð Óíž4M›E Ù¢iëýÀ ˜lƒ´L›Ds†K¯ÕÖVÔ­ÚùJL•BA)JªrJ9]:5&Å/.oªµú™ =l›¾¼°PP´¦Ò kŠ@ÄæçæŠ,Æû¦E:B“>œ4N;¦Å´ m2,ÐsW'=Ïw‹ä{ÄîšyÏÕóaøß;Ú¢æhoéPnz>{ÿPK-qM>l(»çRHrebar_subdirs.beamMSËnÓ@½ö8¯&¡£¸ –e„’8I«–ݤ%­"õÚ”%®cO’ñc&ò£Àº[¾oà#Ê‚™ÔUkéÈwÎ9¾÷ÎøÎÁéY‘½Ñðx˜‰~J4i’5zéLÆÇ£Öûv¯g÷{ÇÞ¶_ ¶ïLÕ×ûçÎøäà4„úœeÖÎNÏv§v°êéŠ&©l*„ÒVg§ÓWœ‘±˜.ÊSyÈ]Ýmº%·æ6V ¦"O<ÂóîBÄ´R°nšxÝÕHßGwW¢#‡8NÓLôPK-qM>'ðênÊ8rebar_templater.beamX}tוŸÑKÃXÆa¾ ŒãFöØ’±elx¶, ó 6Á„Yc[¶,93#bNNRI6›Å[Ê!!! ‡¤MÛs I›¶Û¼´Ý$Kóµ›²{J’Íöìîa—´›´%g“½o4¶¥ûÇúœ+Ýyï÷îýÝûî»ó¬ŽM[kf–ÚnÝÐjf‡ý3Ã0{fèZ<¦GMmx$35]Hè|ûb##üÄ ;Id3}©~ÁÐÌh:¥‹ml&›Ô¦§S†é›Xa85=Ëô;ªª©¬³/«ÇLGvÈ™_Q”Ôâ¹þiy³él?™¶7¦§bñ´fQS†kHÛ×—Ê$¹d*a¢ŒvW‘¦ëY½8¿(g¦ÒFQ,žÕÍi¹LR¤–,ê‹¥ »+¦g„>ÍL DÁ†á2³Qj±X$4¡’¾”ˆ%´¨f$ôÔˆíKo—ý„'G³éd߀A#9³x"Òh*YJiNš™LO’5•LCS㎬á„)-³—§æ2±a̦€2ÅZ¼–š5´©1Ü“.“)}†¡¥µÄ”7>3,SÓÒÙXÞ G? Çö£0Ó - Y6Š 3«kŹ‘$µfXé*Õ5#›Þ«Eu-‘ÓÔÞü¤µµQÈb<•‰éû\PF.mNÏ?Fíôò°ãQ#Ë8Íì–1¸að´l—Ìf4—®íÕÀÿ4в˜Ø| ä†º[¨;t ƒp?œ3Lº;Â]z 8Ò\ô#Š )öçÒ1]?9ÝJgê9MÔF¹©M¦ÁLQb`8›,N @=jQP5ŒÒ\9µQ«Òú ûQ s¹4ìh¦/;ƒ–IÁóßͦkVøÒ‰Š=jM­Oõ9S4 ñrß-ö»F-Vøn],7€žËÁI Ì÷Ý¢FÛ—Ë®Ìwã¡«©+0‡;±2Œ{5¨"“ÿ{äN¹¬èð,’YÙ-Ëy‰Ä‘#‘:ä’ÂIÄ‹ŠädVuxâ2K @⟂6;<ºÌöNŽùŒcð,‚8øšID8T¹dFˆC"–Ê0ø`Eœ!ãÈÃHìˆÃó¶ÌîŸN¦ & PI ˆÔF p($¢Jä#äRU€xò"8—ßCMï!¹ 1R"!¢HDòTÓ2x¬%%A JÀ >‹š.Ná«.JB Q8³y‚:,[<ŠšŽ ŽJB©HÔ°â@áà"‚ê%©å%ö0¬„¯§«."a®(3yÆ›%"Ì£”ó¦Ù3”â\â¤Ñò²ÌzÜ/1Œ,»°ª×Ž˜À çË3ƒ­¸=2öJ¤Ñxó+VÓ°óH8àW $²9 Ô@‡ ç'^˜ ‘ ‰8º «E½x-aÏ­Eì¥5ˆ½âð2Ã^ƒmîgè~BÀD(·–:¬¤ZÛêRŸb5L¥ ‹Ò8Ý AA¼|†ay ò%`q1(ª²½…’G†0›hÉÁ^‹üì ^ u´²°ŽVJ㢠]z Ôx>Fð°’ÖTóZ…å[ Ñð« ä0 ¯v‹²ubøèm¼Ç’ä"üXÍËü\H'l'¤§ÕMÔŽ&Hª€îþçAÙ/ÇmÞï­ÂЉY¾ Ì”Uá¯Â¡ü\ˆ6ä»4´áhüLú†jÁí,ºq¢”N°|;´Ç’ jLæçqÂ\Sæš›ßü,ÚÅà4‡a[Ǽ†g#KÐø×ÐÐ;!œp¾×6âP— #ˆ{Í ÜC÷hŠ7±üº¶s°-!QqÏÁ•é”P‚× ›ð–_O ä„–ÍòÜ#O©œ@ï:‚H—]ÄD £› $ôEš‹ ÞôwÒßY@?iÑŸKé°üF˜Dã¤ÂOPü!ÒUßEº­·Loš Ö–OMÒë6ãÍux+4§n–ßìÃ=GÜûÏPnG$rê̈dBbñ–[2ë`†Â¦Åne·Ÿå·üì`z+õ GâGº¼$TAü‚Ú‰ÔMŒ$9eB2Zobú»Ýù÷g`ò¼W(ÄDœŠáÜtÝŠ|*BW ÞÆò]Ëñv4Þ‚w²|÷ÿËëînÿóîX~-QÓÛEÚð“nX"ɉ o·rÂòÛé `€žDôà^y?éê&¡vÊM© —%ƒ '襅/›¸µÐõ@©=DïÝ]´ÛÁz(ÕÜ Í«7€ïè²ïrüÐ6!²YpíˆÁ· 7·0Šðó©Å`±ñª Ím'­ù]PóÛàa7ñ "_Îò{èî(Í Ê<¼Õzap; Æqa°ØŠ$Î~+.¤'Q™¼Q·Ô%‡ò/·x÷Òœ;ÀD²kÈ-‚Þ¾8)nοmü0h¯Ñ8A×ôÁš;`M#„))Aœ’š@àÖ¬¶I \/í[/+ôu¤òUx »ò· °ß?a¿¼ÀþÍ ÌA;I‘‰›Ì`÷Q§Càt7´‹´[&ôÖõã÷®cl;\…%/²úí0 ÷½L#±ée^è©”×&ÁµƒÞ9àR¤Xw±2ãPÂ^E #E‚7p/·/å@)æ²yJ– àa$!¦ËÔ»é?Ã#ðÍžu1RâáA¦ÙºRlë3ìÿ=ˆD²u/ÈLû’Y ³m</am}¾­S_ m Å/²íP¿n³ñKA–ÙzÈò‚µ>[§ãµ¶î ø]QÀ³±À~“¡z³­·€¬*ˆ±Í´ÛzHÄŽc Hض¹d¡úz[§|: ¸m)à¼ÕÆP_Ý|n¿I§øž‚½ vRžáQº–/'È6{]ÔÖéßn\·ËÖ¶8ìXÒ‘ËtìÝn{>mÛc|öß×§LÀ8`Œ;9úäÑî-ÙwTñ­ÞÄ‹êì8?›œï»çö4”?v¡rt§z}r~ìôßID~ðÎóÇßw]ýO~¾Àé©ùô“W~òŪ_ïö„Ùá W½«×½éýtùÁKË®¾}rL]0nd³žýèžð’úŸ?¿ú"»Êù‡+u‡7œÝÿ•sU ³þÀئ‘3o¿ÿÉ#×{ùhù›ß¿¯>uâл¸\?àܺ®flïò7Oô£Sߘóñ™¥~ôùLJî>’ÉäÉÜùÔW‡>xòë_¬½x÷s£¿ÿ`—l~ãþãKŽ æ•5¯üÝoÛ4ß;î9Õrâú˯\Ý"í¸oæß_Ùôêaÿ ÷å׸U­W®ß÷î®ú //½´,>­¤øt¬ùÀ õǶ,r=Ú^þoMW.Îø‹o~;}~Ϙï³ݳm“ãË•×N_8±gWð›Û¹;_rÔw×®øhþ;¯[6û½úÙøçé7¼Omo7¯ö<¾jûmç_üã{áŸ{æw¯.ûÖØ/þñÁO=¯ý¯ÒDø‰Ö3™ª|átå‡~ö×ëz‡¾[òã‡/=±aàê·úüÁFã•¿ß1ýDìõã+žóÀ·¿ð~ÏÀ©®Á—:yáÑŸ½c8öÃÑþçò£ïßsìWûž86dT>sµí­}Ï~Ýs÷WÛuŽ‘±{wûå‡ÚNœ=®•ûÿ!4üÚõ·œ›=îx~$9ÞÿÈ¥‹Õ{óEÝÒ“ —ÝÿôåýgIýâû_¬|ørlãÂÖŸ~í¹G2;—Ïü©y¨jÝ®õ=¿üÉaß3ó^8ÜTÉ=ðIcå†Òß^x«;Ñqò|ÃæôÞûÎó/íyØý·=GÄåé‡Vwün7÷ëéç?|õ¾Üc};¯®þößdúÖg´.ÿÛ>Ë{ìúÌÜT£wØãý ;l= ²ÝÖc íÚ_kŸMzÞ[ Î2ýe¥=°uÖî1AC{Oƒ­ÓþToë´ŸÖÙº ¢Ú:=OÕöš²ÄÖi«´õ™özÆî ²­Ïh5M®9H#dIí52ÖCFdžºðƒw¯JÌ»÷¯^ø…³ÿº~p0Ô™éƒ9ÎÂsïÊŽ˜©lÆ Î$ƒ­Ÿ`£Fnx8¦ï£g6g&SúÃiñT†Ž°©!Æ•Ê$Ò¹¤–d¦~œ@0—L2BÛ¶ÎõíÑîÎ á!fFZ[«ÖÕú£j½ô×O€øÛC]ÑΛ†˜âþ”)74Ôª±¸:hq¢?$©!¦(PÝP]GÇ835¬ 8ãШ.Ç1+ŠM‹¹-‚F6§'´!ÆW3Öj†´Ì`ªÆÐ5ÖÉSÚÔOàÕšžl&MâÿPK-qM>G%È”1 ¨rebar_upgrade.beam}Xpåß»ï.·9²ÉwÙ ùG’ {DàÙäÉ‚›»G…Jtlµ^6w›pÉåöÜÛ‹¤ØBEhG@ÅŠÅŽ)m´ŠŽø'8£¥8ý㨌ʤÕ­-&eJUK§V§ïÛýBNez™—{ßûÞ{ßû½?ßf³zà í ãĺ®ë2´†±?Ã0ÌZNWû=QÈ êJJŃjVÕCm¥瀒ɫ8§«£i­OèjFUòj™e•Ô²éA÷ j$3Z¿’™C½éLÞ©ôkºQ¢ê%;h÷ûI-¥²D7§›íÚ0›§¼ÃÐ ª[/dÉÍjr8ïHgÔLº¿$O¤Ò:K–YeDu ié¬}åJ´²m%&Žh4 s“h¹ ¢|!c üXÁniN×r™tÞÈ—d4m¸ã‹ÍFU=ŸÖ²ìéL*©è)»®ºt5—Q’jy:«èc CKs5qV”Nˆ¾P¹1§u‚’˩ٔ[I¥LTy¥Œ@‚H MËäÙÆ=¢ «$†BΩ꺦;Sja°ÔJ]FD@sL¥|ROç Öä Ew÷kš‘ 8ó– ’Sf)ŽdÒÙa$›(ºÔ-†®$’„m¨ C—3™Ñòª=­• húˆb¸’€*[ȹ`©*Éͺ:¢š~†®ª˜®•LÆ:vΈ–*dÔD:; UT­ëZ¿¬ÝÖÑ:PȶJ­åà=eÊLÍÒYNR“†¦±$‡ä`ÄL¾=­4¸¶õÂD¡†}ú3ÖgÐ2²¶a{å|Á&”Ë‚Ìå^Ž —Àø—¡ÙÎËq±–m’äetj(†Â1$`Gã ,Ê¢/VšyÙ –‚Œ.F’QTö‰²——9ˆähÐ!s^ M™2ä¸jÂù×@}‚CÞã§È>æs_„Å. ;$N4­a…–aqQžB• o“× ÛF{¥ ¶¾ò& ÔíÂ!ÄX·]”ã˜sì/€Ey‚ü`¨€Â!<€ʼ/ÆÛ±¸@.Ü'#/õàý’/ïñša¿C€‡xðÊÝŽèþÂqî˜ãÌuóH&ž¤Ëž@èë¶„2ïñÍŠ·{–x#¿ ËÅêTÞW¤Ž%fµ€âÁ¸£Ræm9HÅvHE5¶í+ØÔï M ðÄå`Dÿ?Õ9!v‰hh"ž‘ð&ÿDÔ]'o‚SÙ]ÅM¢ð$’gL#Hø'yw=–drªŒc‰9H·äH·`Ûã£Q°,ƒ–àr|;Or*x;Ž!;ŠÅ÷!ø5Žø˜ƒGˆ³Ï…tN£.Ä‹ÁiÑ´9r¹§xœÔ»¤WL-$ºðI‰¦gHŒè ÎeâÜti¶I?ÂÓEð§þ´:žÈÀOú§7¹ÅÐt2<"I&IâÁé(–ö¬ùø‚õ4@»Ð|’ÅÒ%´]ª–;8ÏE®ÒÆzd¨²È_/`[ÉÛXÈ6ÖËÉð aRdÞ UV‹B«E­V³0xÁ´8A¾™üx!?¾"E'1X6.ð–Þlo—p:ÄU¡05Q\?eV(þ ²Ò } à ‚“—3oŠ|1/ˆŠœF/ÑȈDÇÇ‚e²|Á…Y Ç )’!¶ RÄÎè‹[ÍaóNÄÐ2/ºdÖâj Â$YeÄ%\ïnµ±5rœÅfµÝK‘Kb+ÁˆÔ×%°|ˆ«£Ú¯Õ‚‘ç FN`½!®ÌêgÍü\½iV‡)&’¸ØJ«qÙzr§`1â@ü e’àq@j@ ŠË[©`«ü\#šÂ}LÌg§e¢e¸¼ ^«.ÐÉlmå¯T·¨z¤¿ˆx®å|;Ùgçšz$é–®Y0ø±ŠC·é–wÖ‘À˜}ÐÈgú ‘· ÔH Ô;±P…޳Õt<­áɽ!°Õ~®Ù¼qRÅÇÙÚËy­ ( 4;Z\3OtêxY4o*p#±uÔtœÎð¬ÈšgÌÖ›ËË—[Å`çAlÍ$Ðùè*˜6±L–H%‚d„DRy_,¹•cÏgÈL5D>:DWš ¯ååÊ›0}lÃÿ?RæFÂâñÙ9 yÍy 2ð%#° òŒkñs>3­u³+³D>‚| —! -ä9„HjT"p mìU°Óݹ° “Ûu<䬔ÁV„±±‹åJt=fm¬ŸH`g i  l“ma7xXZeœ‹1^¤0 "Bˆk‡Ú¶×¶Ÿ q’:è) ¹Wû¹6Þ·¥ùÊ–p+ZOý…ðÅbv>ÄÓf±5ÀJ‚&²aÑN°w@|ka(c°ÕAššà„f“¡÷’?dzFrðm{X¨Èäb)_ ä¦ü 2úwáËl@ JÊó@^ÊÛª"?s)_TKuæ5P9ñÓDåP3¢¶ó©œØ¶Pý«€R9‰gåý@K€@m@õCäíÔ–ðEñ‹ü/£ò«–étR"é„©¯ :×­,ŠóÚ¢{â‰ÎÃóÞž|ú³“·¿>õé©?=ŸX³Uÿïóïî©r®Û™¬=pnèßö?™j0™-ûá#ã¯>qÓ:÷]óo¾#úÆsËŸAŸ´}„–¿sð×ïøà¾³ûÂçþ¶5u±£½û•U…Æ×^«Ýú!‰ÞL-léùQ÷ª§Z¸°­ûq|ìÛÒGZÖŒ,\àš»ƒƒg'—õ\,¿ÿŒ+~õÚÕó¶ßÖ\8uÛáûËGë=ÒÚ·÷'ß™ü¬ô®ÇÙ£á?7þûꋟïÝséÎÚmMO·:~s÷k¯öfö‡÷Æ^øë­w}ÔòÔ‹‡ÊßëÝ}UãÑõ»&W®»gòÜ“ÿ_úc|,wcç7w®¸ôÐÏšnûà_[œ:^,g[w>öØÚý·>–yóãÂÐ{§N}ÒõÒ¾éw[*Ò¿Ýß<öì|®2}³¬eŸxy<;À<÷Éùã þaчeϼ»õ¦ûF÷­‡ŽçêÊÏŸ9x⟷±¥ùÚ™óÇϬ¸e›ý쯼ýá­ÛïÍ]³áž¯+—î+ìÿýK½žÝÿýãé[}ë@öØèÿø~|ï@ùC|çoMü²é7á{j†Ïmcæ´•ÂT¬×’¤_Ƹ/õKqtQžô¡LuÈl®¢})Ò›™çÕo(êÏj tVɽ᣶ä}«‘êpTof0•—t†NÎß‘!»›í)æ³æ"‹™UKüAfm£ýo??:úÙ¡uCCÑÈ%c³›ú¢ïÒr¼‘牠$Åpæûq"_—q¢P¢ x9f*¼¡‰-≠ÒÙd¦RSLi!›RÒY5µÁ^*Ÿ#7ö¬ïNôö\f*:¤öv©£=–I¡À²%ö¦è¦DÏõ«7 3sÓ†°|y»¤ôKCfLôßÃŒ3¸tùÒ"séusI?\Îï+v…SœJ©Rf˜× zRfüm›µµmXÍ¥Ûòz²Í|¿Ÿåfþå²ÞÙ‡ xýyƒÌþÿPK-qM> 2¦T ¸rebar_utils.beamXpÜv•—VZ¯V²byµþ'NdïÆIì8–½vlÇN¢ÝÍz›ÄN8nÚ¤ÍZޕ׊×Òž¤S˜ÌB˜&´P†)Má\†”£ÜÍ”æÚ¡@ å Sàf:0¹^‡×ûñžöëf¹\gžôÞçû¾ïû¾ï½ïû*;q÷á~Šjº’Ê$§’ž½LQì)Š2ǘ×\Å3Kn¨hx¹üJ]0KFÀ^ ™nNwò‹Ç`œŠ\Ö½übȲý7ë9#¸ —\ƒÃy¨È­ØNÁ5ßcÔNI·Š‚û ëË9ÓZ°éîÓòŒ¢áä<;W2]O°½rÎ1J†î2ÑD+¦g佊czzî"‹“ÃU/Kv‘ —»ŒÜPÞ^.ëyO4Çvr‹ºU(Ný9¥—*Æ»â•+Þê€X¶/çžgZEwïv©TUuƒnY_±ÂvÙ°r¨ômJeÜlζr+¦U°WÜ€í²Þƒeƒ_9‡‘rCø,™óü‚]Z…,{%çz—×K†Uоd›óÌe£ÎÄýÏ×-ØD2XÝÈBI÷<Ãâ Ë…­ç ¦Sg§a(¨Ïƒ3ì¢^‚]ºyÇ,{9\§Ä¼Ç,³y»`ˆdNÉÖ F!è6.T¬¼g‚ÛÆiÜŒQ‘É ¾ßÆi#_ñôù’Á¡¿–¾lð–î™§|v L‚ˆåÜÅøUä+®›)@0Ã:ÈÖøNaTü 58$ÌzW!I94à«…ÀLɶËlA÷t6)ðt¯âò~:ò%Û50 X¤F‚–mØ%H˜7ôeY¶ ¢’éÕA\!ìIÛ´¸y(t¹~Õ€ÅÍCù‘)œcÛ*ÑŽÛd,W ÒFîOB2N{”QÈ/¿S‹ºu®]qò†F*%ïᬘycïÿk®/Ñ áïíïýóãjïÇЫóW˜Küs½ ½þûú‰ùÖÞ?Í#è¿ÓÀàî4pÇ5½ÓŽöÞ:#}d‚Ôë.‚PÊÇO¨ ¬öRTŠ˜¢xú‘DUÿ.-)´ˆtR´ROQ!Šbv1JŠ¡ä#Åz†ä”c"”L«w1´ˆ–èézIÒ–¥>«e©˜ÆÊlH•ÔóÌs¾E{¿ñp…žÓžd"’L—µ«þûì~†¾ˆ¼@ÑO¬Q(í{LHRÎ%õ} pšÆD5>‚˜Õx9ø— ÷FåÆhH™® Œ¬± §L+ô•@„oRèçEUSYMŽƒ…L<Àd¢LLËJ²Æ73!uNË*²gã`"$•YI450¯c`JH9‹«ÅAng|AÖ¢0µF ìàÈF‹æE-«Êè‡*M(±,¯d㨃yOh˜†n²ª80ú6³óí[ÑSß–Çä·[4¾óû©_Ð×µlì2”ˆ*Ó7ðqÃAø˜DsÕÀ†¨+=b„ÉjZvšoâÛ@ºŠ.eç0ZŒ_Ðl™!œ0ÎÉ`³K¡¹h½¢h2 *RÚ“1I@´@öÊM? M ¸•¢¹f¿®Š-ÌN w7€ €¬¦d*‘’¥tJVfŒS¥ççR1*ŸŠIn*¦œËœƒ$¸ “ÉÍ¥èéYðô'Ý„•Z ’¸VXV‡×ÖSRHâ¤Q± Öm«)=±Mæ;áãûµ”_‚\›ÿ\SÀóõõl-æ§´ÓÏw#ÃI\#,Ñ*ƒ*Ím¨WU‰küF ’ KEzÄN&{QãGd­?†C!•“U±êWìhÑž7^ÁüFHk5_AUœcÊ»§rQ:0y¸›¬7»‰WwÓÔ#nb®úÎn±YË>!¯–q'SÝKLÙ S6Š=°ó®š²» nÄ®–³üq ¯‰[ù$PJ즹-=bWìjQò+QÎòíY(YÌm]E6¬"ÝPŸEe^· ÷€yÜiW˘ßƧÅ^0½æ¶ÕÛ¬öµÛ l/N߆õÁföBÌTIS2r –a Ö³W˜ƒ ×Bsý0šx `6ü4@Nh.Ñ"îbFÅqØýxm½CiǨ«ÔUZÇc qÎÑ„8ÈgÅ47ZiÐJ+©45“JKùq8ŸÌ»çzÄa7œé\òÜ#—@z$\éRòÒ³×@z6lƒt-yí•7@z%ì€ôFò· ķˆ‚”$¡Q€:}[B$)DYˆ"$‡q1!š¢B“ÐŒPSx¡æ¤Ð,´­µ„ µ&…Va­Ð†ÐÚª­¶¤Ð&¬Ö#´.ì"´>)¬Ú… µWØ6¡a!%)(B‡Ð‰PGU«3)t 1!ŽP,\A(žâÂ&¡ ¡MUó]I¡KØ,lAhsÕ‰-Ia‹°UèFhkW‘ãM»£âT·&tÇ¡j[inhO´Ú?%nm¸.–¹ R!é&©€”_~=ïX-ŠÎ*͆ÜÍŒÍø¹Û/ŽðÄQšéÇa1lCÑØèùyhˆ(Aƒ‹âYó=J”²ÏË0ŽM.Š7 ¨ß®»³GKÓ«VïèàXUCR§'ÝLû>Ž·Š šÛµŸ»¡P'ÁâžúêU„7×6"jL’‘¡#a#Í^/(¿÷së´ì 8ØÜzh;íÐv4ìI0·$—ªö‚ @Éx†ŽÀÐÞj£/Î‘Žœ½é·d[2 g@mÎËé^p^²œ„÷ Þ §ŒŠSph¦j[ƶŒ©-%ÂÖÄ4—§bÉX" ït2˜÷Lr&Å;'%áŠSî¨8™Ø ¤¤“JHÐ'±9LBs8*ÞÅß+îãï÷ÓÜ]’ªàÕÇfeì‚~ ì÷á}$³ÅrõBö¬Ÿÿš‰§!1æ€v{>öý‹·¦>ñWN=àgnr?¤l {ðAØ1ˆïÝZ„9(q47„ò`ŠÑÜaïp&þàgAzÑ= æ@< C÷?ü}Õ¡c êPÇ%EÉ0~»» yØýZ³Rír'̃^õdõæ*¤×)"¨Ïƒh€˜÷ƒé×  Z€6DïjhŽl†ÃY®‹l“¤P™(\ë è.€î"èo9³ îš#âI +ÉÀ·™$n~7¬øÝƒWËT? NŠ‹0>þf<ç~ î[.Û~Ø.  ïÄ:Êÿ.ô±5@ @4á%¢‡|c %x P+™»¨è ¿žè ¿±ÆNáã@›ˆ›¶ºz¾ ¨—èoê#öQ_­ñ'Aø@Ã5ø(ñm'ÐáqÝ1¢3´‹ðH5~ÞUcg_þáÝMôŸ®™{¨Fº†Ÿ!<úsѪñ ç¯Y÷8ÑÁ±/®Æ$ssJ}™äì?DxŠøw„à{>4Il爫Æf¬·¡&ëkâùÜJì7SÕzB¬‰&Â×Â?žªæ•&ïÕº LT,¬IÔ€ÉX‘ŒSô™÷jðÊÔñÐ¥’Ò¾3ÒgÍ<ô/+¿}ç7?þç.<º×{Åɾyïõ#ŸøÒçŸRž¹~þÔ™Ÿœ™™ûÞ®¥©ëÒÝ+m85½î¥4ýã—ÞÿËCO÷|³ò5cöÍËö•÷æ@ùPóË/þëç6¾a\¾Øÿݱðcí™7QÛ;üÜã¿úìþ/ïj~àßÞ¾|ú'á¶–æ¿ßzê­Ÿ½øÔ‹öÇž9ñ©ÉÃß:ýÃgþùÏFyö[¯?ö¾Aæ¥bCø8S¢óú'ÿ…Ÿÿé+Ò:~ý?Á+Ÿ´þ;þÚ“ß¾ñ>ÓýŸßHæ_ýðß]¼ÿ¹ž™à_{úÐãÛ\ëk,óÖÇ?pm@ßviýÈ\›Õþ#*×¾;ø•®}Ÿyé#ŸÿÛ¾¯Ÿ^ùÑc{?ö7P“vký:UíU&‰¯ùj«¶>jk¢¶jk®¶Îjk¢¶js_›ïÚÏ;@ÂãùÚKlâùÚMÝêo1Â7&=Ï÷–s%DŠ9åZ¾`ITæØÍÃÝ©o>þ?ÿ»þ‡/=y2½ÏZÀ©¾>‹ú!»Œ?d¹Ô(òSŸ[Y^ÖQ¡Î®xÓY¢XcÞ´¡Í%*dZùR¥`¨pÅ* ¦e+(>5»oroîȾ©ÌÕ0 ö÷«ý‰œ:¤Ž&†V•¸{Ò3¹}'î^¢„¢é)ÃÃýª>¯žô}:e8.8µD·o@ŒÅßöë â¡×õ€.êA=¬×ûVIZ¢¶ö-ÚËFß’a4û\'ßçÿ¬y‹«þ »ÝpJ'“ó®‡çöPK-qM>IA¤\ Lrebar_xref.beam…X}l#Gßõ¬íÍÆs™d}Iî#×MÖ¹\›K²ŽÆÎ]îÆvÇwÉ]¸´UR}k{8ñGº»¾"ÐÑÓA ´* R‘8Q JU©Hˆ"ÚòñGÿ*Ðò´ªEˆö@üAEycOsj“fgæÍ{¿÷æ÷ÞL<·xþBXz’éÄJ­W}(ªb[yÓÎ]±­’Ä>^Ç5m×Sß"Žåæ*å¼mÚWsÛ¦»Ùrî²i×ʵuÇ[2+ŽhYêµRy­[®Rvr—,;_w,?ïå]“n†X´Jf£âb³XÌ˶UpëöU©P/Z2˜7u·@n¹âø™°p¹(—Ê«fV-i³^®ÉÌš©J®Ý°º›6¬Â–C¬+ÛuÛurµº›k8VÑ[);®ã«ZÕ¼e6jà¿\³Š¹R£VpËõZ®`V*ŽìpßýM˜Üí(~³fV®>bi-Œ¿T·-³°ÑÅöÓÄS!nײsæeój®¼^ƒõ¢·á8ªšÛþRÅt]«æÙ*ù·¬«Y ËÎv”«%Óñ”ë>€¬š®Òê˜ÔW®³¼tqIÉ 8fÉÊY«jÕ\ŸeWÌÚºŸO¥ôƒÙû|y³hÚë]í°{˜'†•sê »`õ0–ëùMÈF®™Š¼eV™_a£QÛr°™w\Ûä«=¶y9×–\ wÁìr¾áZË’¼ËIwµ^lT¬\¹Vª7=ṫ&n a*‚6®>2áµl»nßIoú鉡рÁÒŽÜén­5BWÞÚ0/•!.Ïøø|„¡ß1ÚÖ~öµ››ïbÅ’7¡\&Ú•2etø‘Œ8NpJŽMܹîÚ:þÿ÷œ)ð-òÜDhýÛvZ¿H<}#š¨í3E!:‚üDˆß@s7–D‚:~CMJ†5•­idüJÒ¼Jm†ßÐ( úƒÜ$‹šžy>ƒÒº±á+™`ZGjo°iFiFh¬Þî.6!¶™†_»æ'O‚ ¥Ÿ**Ͷ•*ƒˆª’_»i4Ð Ô JÿŒ ÐÈ3"¥’Ú+Qåú•ûmK\•ÞDÞ/Ò Ú1?y®å$‰úUÜ>ƒÄkKH|ÒÓ§ ñf@À[+Þ—â/ ¹Zñ&ÑÇ_P“T¸f4UÒð Gy^„»ˆøÚ>‡vÞAsït ¼³‹°L‘´.@Ü;Dðk¯qœ·çà ¢LhPgtIªWà D”{Akú¾}$(¸ 6ȳ~ò6ãLB;„øµ[~"“ÖLÃ`¢‚éQM”ƒ¢QU§½*7äÞ8ÞæpG¸¸_• Þ>¢Šò~˜!›zZ³~àM¤c€4ÃPé‘8Ðç J“:‰&u-ö; Bl¡8>." ªf×KZò t¡tšM…Ú õFiÆ å>Ø4ìÌËØåQ<€€-á %‚ÆaS‡ãø B.¶¡“H‹¤#ž6,ÍP©ÊÀ P<Æ`|$އÀxˆS0&`¬é¬œ[F«FwÑ$lZúNIx¸Û+‘ ¡ Ÿ–âxpF:Q•0ˆ–]KêBDeš*‘‘#ͯ QˆÒAGFÀØÝE‚‘¨ŠàŒB.÷ÇñhŒ!cÏǘ¢™‹*0 qöï*h IB c­ 7©K%RkXXƒ…5-¹&8É5rÔ%ÅcE ¢£×ç iÉëJ^'ê8>Š”x ª éq< ÞFYNà›D ÚTkãxTWæàé…OJ9šàh´é(Dƒ:Û«M2ðD¤ܘ Ѩ«IÂTI*©jk,å$DͲ&cuQC™`&Õ§w£Kð9ºt]”ÇXE*ç!OwÓ>tŽÈ¢|“¹ãì€P“Eù8O¢ ž§P€  5ëT¥½ˆêAªFá€kãx)'iT¥aÄæwÃ<Ȧ‰öTj(»­v ÂöB4’–P+½“íE/¬@OEñqV½ø§PFᎢ€¡%à‚H2Üax.1<Ãn1Íï’SP°§t-`À]"¡fC4ÂáçÉE²h¨ ª ‡õá)X÷Á¢(ŸŽâ“,f ¨Y@OÄpÍÃ߉3:U΢m C„Ø:7ŸŒbÊÌS`¾ A-Äpæ¶$ù—X––¨Ó¨EQN·³´¼/vfi¡ÓA&ŠSˆhZZõ0?Kì6Í‚³óë™8ΑÊîpvR–U5rBÊà\µöÕ¶-ÅnªmVÝ}¢|°Vk9†ÏñŒ¯€ùŠ l²Œ#0²?zˆ]ËDa“ LXƳI&Lmù#I_iʲ(Ÿ‹â³p k®}û¡‘­nC/²ñahhšÈÇ^ÞËкø+üw [ügmï{:~ËôBëãcZ°Cg?÷uÚÁùᎎðžéhc½Ã6Ô!íñ˜ï†v×9Þ1ž‚ftøá¶÷B›íÐ9Åå»ã]y¢Cžáòhç˜<}…q+ã1ÌsÝq>x\»Üy5¦åóó\ÿŒ°KöÏ_u¡Kqù Þ þ÷¿K–Ë.³}‘‰®|ëþ'Nw¿b_>}ìõï¼ýÀË£±Iåѳ?Û© ¯\xì_úSOãÕßL½÷Ì…_gÞzóý·æ“K‹·=ÓŸøºïƒoÿÄ÷׿úÌ#óÿó‰Ïýýxltô“Þ'¿ÿ»›¡ ù‡Øxù©_½ù°õøÑ—¢ôÑ¿¬?õÞ³¼ñéÃõ‡_|ìÙ/W³SxôóŸÊú¾þуNèÏK¥Ç–ç_¼þÛDð3/~%ÔýP¼þã[˃߻pMµ¿ða÷»Kÿ¾ö§>øWé?¾G6W~º\/°=¼Ëëd•ïoù6.–9? в\Îò°Äåó·q”äc–OÊuà .œæy™àœ‹¼Ž&¹ŽÆ×D^ƒã||˜ç”é B;ÊǬ®G¸«÷až6vîârvV†øXIÀ«‡a]¯0Ɇ§( KN­9©᛿XÿÛ7¾øGþ5ïgŸ<½¹™ÊÖJ°øaS_búþú6{T8Là+ ¸ùË9jÕ´¯2_½áÂÃeK¬|¹Æ$byKð—k…J£h…½·è‚µbQP’÷g—r÷eWÒ[BÏ´ÓáHΘ1â‘™]%ùÔZ.{nñü–н^vµÙÙ°aæÍfL—,Û ¶otrvršÉ$·\µ6|y¨Õß››^³Ë 4l=;·„cSõª5µeÕ6ËSŽ]˜jþïÃÞ¨ù"œ„Wõ¦€7/#ö¿PK-qM>:&priv/templates/basicnif.c­TÑn›0}ç+®¨T%ÈZ³½V}¨:*EË҉ѽT•eY­“‰eüû.4ÒXya_Ÿ{α ¡"YÄ\n$U"ùðâ:Nn™øFnEð\&âa™qöûTÇ…äUEÿûÃcpç_;ŽÅ¹˜'[SDÖÙ;U¿ð…©Xr,»º‚oF[]—çŽlèv}OC?øÚ/Wü×â°µ¯vpµ# ”f~F"­r ƒµ8±{z^^¿‰˜–I¡"+´š ƒ®s¡ªÈF<ê^½a·žäÏ(›åÀT q©X*"LN M|˜å1¤<Õ¦Ä;Aüj½ê\&Ǿ{K$Òo§VI+*5‹§™{±£1³Œ 5¬×P¡=q<ºÔvaÒWG©ê;¬•wBIwNÔ/ÏX2¯ë4é]à߆>üé…·_ü‡~0z5<«ÆŽ{½]‡=ÛÈñ®$pÙE`û¸Ùô߈øPK-qM>ûV5‡4Øpriv/templates/basicnif.erl­’MOÃ0 †ïýV¥I™Ôq'†Äe6NUiã€Y–Li LUÿ;IÊ>O“À§Øzý&~âtcD«uÝpèûqE)~om؋Ư|’D°ÍN¶ºjÈèüæ5(.”á‚‘¦&Ÿ„I’­æË•KSÒ•jŠJcëe¿¥€ãe¹Ý6 ø±Ó?€=¡¼¦c4‚ÙßÃÛÌŸÝÏ@ƒuSÿ—ëù®D%¯©*ü GY'àfíî@i iÖ.¿ 6wØ¢PK-qM>ý+¡R‡ priv/templates/basicnif.template«.K,ÊLLÊI-ÖQˆ®ÎÍO)ÍIÕQPÊ­„0•jckõ¸ªKRs rK@2I‰Å™Éy™iz©E9J@~qQ²~5Tcm-X—Ždúäx4É õPK-qM>ôävÞ priv/templates/simpleapp.app.srcmŽÁ „0 DïýŠà9,ì÷Ȳ¸6HØn-Mñüwk[P\s 3/ÌD‡CâÙ#¨fÉv]Ñ@oÔ’Œ‘C¥]·û ‹ìâÙT¤‰%Q$‹Ð¿ªw ,I×ùRôäð†H²Ž?ÿ EÿæÜ£Ç§ï¼KqÅä—¢L¾˜ PK-qM>üÁ™\Î!priv/templates/simpleapp.template«.K,ÊLLÊI-ÖQˆ®N,(ÈLÑQPÊ­²”jckõ¸ªKRs rKRÂÅ™@f*PJ„‹‹’•@‚EÉúÕµµp \:ãA R‹r0tÂ%pê,.Å¡&Q«PK-qM>À­À‰œk priv/templates/simpleapp_app.erlÓÍÍO)ÍIÕ¨®N,(ÈL©­Òšz\\ºI©‰e™ù¥E@‘œÌäÄ’Ìü<Œªª‚#BD!91'')19»˜K7µ¢ ¿¨D#º¸$±¨DßHG¡¸$¿@ß0ªË–r€Ûr*™Ïv»F|0ˆ ©,HÕQ€°‹Ò‹5tí¸€ZÅ¥V`-ñ9™yÙ Ÿ‚< 6 $®!?[ PK-qM>‡O³Ì priv/templates/simpleapp_sup.erl­RQKÃ0~ϯ¸—A ©ë|TÄ +LÔ§QJ–¦.,MJš¥ä¿{uÝêÃÞìA¸»/Ü÷}GâÊ­–´ëx]«"„¼iëèŠx+wü lë(¾HwPu}a6ƒ‡×”Äò«¶ÎÓMã¹ó¹Vf?O²¡áíŒÁµÞr±oF„2ÊÏ§Þ•ÔØ ÎB‰ˆB Í2Ÿ vJN°%ŒC¸¥2’>®Òõ’¦ Þ¿k1èÒã'b°ÉDVÜHã\'Ir`-ÍÂ0ÄíÿcÊÖ¯¬i¦ú—Œ|hñŒQŽ›?åN[Ô›ÁýóËòcýη^ˆi©^´x*Æý†PœøÄ¶³he‡ÉÈW$ÇŒV2X$á×bÈíPK-qM>@*‡«priv/templates/simplefsm.erlµS]kÂ0}÷Wäe¡Õ}ø´‡ Á Â6‡2_DBÖ^5˜ÞHE)þ÷%Z5ºn[[hiî=99÷æ\?VÑJͲi‹h·«7jþ'ÌùZ¨UBg€Ì$l0‚©@ Ã`0 y~íw>^“©ÝÜÿßei¿÷Hw…¡ I°YªD§%±×|ØóÑqªy¢™¸hÞNJ•Ÿ7«ú ݼóˆ)ECCóþbõà‘9ÇHƒ5 vÖéÃ<Ø:N•ÅhHb†Å.B bÍV¹º¸çŽõ•°¿¥5ê|Å´Nü§9^Í£“ɤ ¹4F>8zw²´GÆûVë ʶ|”µ“YšW©…Gö§pÉÎö¸ŠíûŽåIÊë mèH„°Ñ´ë³ôë&*¾âI`)·±º i\×^*y;‹D]c²³å ¥;*áµSCYÏ|ÿ.ñ4q” €§ 6Ç\2µ0œ©¤¬/£QŠß™ÍÆ`£îÚ èôÒÜÝCSrY©½¿PK-qM>¥DŒrFS!priv/templates/simplefsm.template«.K,ÊLLÊI-ÖQˆ®N+ÎÍLÑQPÊ­²”jckõ¸ªKRs rKRÂÅ™@f*PJ/µ(G $P”¬_ ÑU[ êPK-qM>>Ò8ì[lpriv/templates/simplemod.erlÓÍÍO)ÍIÕ¨®22Sjk5õ¸¸tS+ ò‹J4¢s+ãÓJó’õ bÁ™i)©i!®Á!@®nr~nA&P+Dq|bNH45/%3 ¨ªUCSA׎KA!?[ PK-qM>þ6ÛöV’!priv/templates/simplemod.template«.K,ÊLLÊI-ÖQˆ®ÎÍOÉLÑQPÊ­²”jckõ¸ªKRs rKRÂÅ™@f*PJ/µ(G $P”¬_ ÑU[ Ä¥#¾$µ¸¤¦ÄAhD’jPK-qM>+]çI;D"priv/templates/simplemod_tests.erlÓÍÍO)ÍIÕ¨®22SjkãKR‹KŠ5õ¸t3ó’sJSRãs2“4”RKó2Kô¡Bú`ž^FQŽP!PK-qM>Õv¬N$priv/templates/simplenode.app.config}޽‚0…÷>Å I·ª˜ˆºêŒ#! b!$`MË ’¾»—…8p·ó÷å¦ œ#9%1 }/ëŠa°¹mR†ïyG*c´‘®*e†²n”@@z3Æ+¯IΉٖ|2e×?¨îKÿñ*ÛRÞj3£N|z±®@¡*:mú@›?¯}§¬À6Ü£Ã>ô N—3(Æø:lýR˘±F˜Èa:ŽÈÏíšæ™cÙš±7PK-qM>K"’V`$priv/templates/simplenode.erl.scriptmR{kÛ0ÿߟ▸mš5v÷Ë–0 ̓$ ‰lgS[2’œ4týî»ócËBÁéìû½îúÂ(Sa$lêyý>lÓÌ‚MV:0Xæ"F .E˜ˆ*wÐC“÷ S€ÆÙÑÍ‚ûƒ¦…Ô`…91˜°€-–Ä•´ ¹1¡$c¸Ê¨»ºpö=‡Lý38 ‚±"­]‹5°Npå6€…vH …£×?ítZ.ÉA?£d)l&q„I‚±cH€©”b²NæhT›Å"B)©Mi‰Ja-åÐ)¯Ú ¾` 23„—׆D“9°©®rIÚ¨Æå÷%â¹Í–Ы¢t™oÿBƒl$³Õ]œ£Pµa†K²œz"ËED'ÊÑ_/—ÛéÃ:4HZ i.ͦèЙ†'²¥p)?Ö‰±ŸÊq‰ÑEàÍÖÛÍîËÃbGÐcKð_ï¯Âá\_Cy”·L±ÐGšÞ9!m,ÚœšL϶ªR¶ÆÿoƒîÉj8" ©(ó-ÅOÃ·ŽºHqm®ÇD³ /|<—JPl3ðÚTÆþëùg2@XúJ‹ +^õ:·zº,‹BM´·ÙNÖÛÝlý8ÞÇ4–Ë”mØL‡6!‰}9"Æ¿½W@d“Õê²Þ‰ MµÂºÎÄïp8o6ÿ>ŽPÞj½ü¶˜Ìgã=Æ©ÿ~ƒ¥”nl ŸžÂ0¼Ù{_çÓqÏo`ÃvG{¾”Ú8 ¨îØvצ¡»uLžW¯¸O 0âõ{'¿õž­*íɧ=ÿsïíPK-qM>ì,?¯ˆÓ"priv/templates/simplenode.nodetoolÍWÝoÛ6Ï_qTZ宊=(Ȱ.ëÚ>t’ìÉ3F¢bÎ2)t“ÀIÿöÝ‘”õa9Ú«üAÝýîwwäÝñøf?Ì`­Jž×5“×'þk&dÉ¥Õü#¯3xyþ[vef^^Šš´ŽßfPÙS¯ Öœ¾sƒÜÒÛÙ×?CH [¥Ð[^7\ÃE¡Ec¡R„´\³Â dp#ìjñ‘; ´¿£52~¥¯M³Ÿµ‚S0–i›óf]ÆIê–Ñàë[KŒÀ.90TqëÛsn,¤p‰‹Üþ¢ÑªàÆä${ù"… ¾’—ˆÛ_p¢r¸ä ÅFkLP}z#%ý%!aŸ”²)Üð'u WLÔ§`†ÃVr›¯¸–˜å¥(1Çy¡¤ä…Í 9î(&),+×Yƒðý7 *éü³zÃSh”¼~hCÔ>juÒÉå(Ä&„„Ê0ŸkfãˆÐáSCôAsƒ˜%yfóìoa:&‹ûöY²ÚÆ/·Æeèo³Ð§>6ZŒaÄßU>¸V”LŒvÅtÚ…ŸÕš³ò.P4¼$†ÌqLÁ(øgc,”›u3FeQœ¢CþÓKô19éQ4V5û{JŸÝYÁ꺗©O‰À@~wýôŸd1°€nÐnþZ#æ1;WJ}3„òˆ•¦@„÷ªÜÔ¨óûFb‰Pîá¼)hì™wÛcÒ`-ŒÍ­Ê™UëØ#&£Õ´‡Ï¼5Ý2îoÂöÁ²2"Ö½9Ù[ß^±9§¸¯™QrïPMÄöüÏ3Ú§x¼*, ¼Ì vßg7>XíØ>Ÿüþ‘l<š£Œa)_›‰´¥@q{e.¬ÆÃõ?¤‹£Ù }ÉciüÞó«–þ$Z“N~ñH¾&{@î}çBÀK‰ÿeØ5 ¡ÓÖªè=¬ûPPîý‰ ÂØUvúÑëe¤'ÏŽŽ]•jÄ«¢èwÞ]ßÒf0™ÆG£X2èÐ'#¨hf¸-”Z Ž~¹TUä#Vüˆ”¡jîuc×fÇ{ÑÃ%!LÃd`Ÿdk"dðψ\¾ãt‰ÍuÚS`MƒÑt­?7›ª·qB”Óøcó(ÛªÑð2=&)ž·¨èv1bcŸñ‡Ì’`Ïf2á™ù~\3K¥í·ó «ÊÈ•í&Í ì ‚²‹ Œ{þ¨?¶Êóú¢LVà"½Éf—øúéSˆ`V2¾V²u^­¥/0^kk~ò7¡«ÂÚDe¥ÐÎ3nÜ4žù¯Ü­µ[Øeé"Òn CB8Ü–9¿åÅ/5}>:Sƒ²Z±µ¦Êþ¤É¢<‰2QŒÎÔ¦.ÝôIÐ@äŸ}ÚEiü¬¹ojuÅêר}Èf'q¸ÐNéï4P’¿ÛeÞõ íâc\¯Ê¬ZqiB£_¢A|æ¹ßÖù[…[pllP¡œ^×vã÷XcŽ3¾‡:Ù' Â"ÌPÏ'=lÓWhlÁ&gî©¢J°‘$½HLœvïò…ûó¡ñæ>˜)’ÞhJ{Ï~#è’8`þ¹@~‰…a@Âø ^Š%Þ;¼Ë€÷æ+!™¾£»¶=¼-ÒEšn/dnKñŽÃ܉ÏÂôãsBlÇ!„¸Y"´0>§n¥ r¢ö‹ë4«£Çí*žòN׳qkÊþínß”CÿZ±3%m°B-|gl¾¹)˜l3Ý“oÛRI7b$}SowÕö*‰b“Ã5‘KgÌ5“§ß‹aœ©ÝI—‹Ì}æÿØc¨;ýí¨Ò´ˆš¡7L¥-W’róØAfû3ÑÖ CøNVêQ/{r‡ËÜv­4§JÚûñîeùE ÎbÕmôPK-qM>¯oLÎ)0(priv/templates/simplenode.reltool.config•Rmoƒ þî¯ |Ú¢Ùï™­Q¹R h3Çøï»³Ñ²Ù5Ÿäîy¹{0úÉ ö^°Û‰ZuTŽjû$Ö²-ÑX J¦ÄñöÆ×þ]€±8ƒè{Á‰ªy¡õz½m]|h]hz ­!›¹<”í¬ Ífƒ 0:{TƒsR‚ÌzðÑëCj`†:eªr—Möàð¸àË]Eà©Z=}‚û Óî•çóµã(æPP;*ƒ~½5R0ú¼HHûT,K•E1ž½Ò¯…¨i¯àt;‰<+´8Ÿnpm‡Šœ²íç~oGäpJÁW¨@Áױ޴Bsõ¦Nuš¡Þ3.M¬ý[`8ÈLgð priv/templates/simplenode.runner½W[SÛ8~÷¯8o)lC§O0Ùi )Í,¹LÊt(“8¶’h±-¯$XÂß#ùçÒ.íÃúÁéèÜôOÇû{΄ÆÎÄscì#¤7±4óÓg4H,mvÄrÓP ¡(y<)ê@,ðF¤a ®»ÝÖ`ä^ Úýá¨ÙÔ­·~ÖóñoÎÑ ¼yÉ"8,åÎn+“zÞZ©r­áE&¶±Î!Ò/d®z—»eB63úí~fÈ‘Qâl‰:®ÝÖ n`dH99§„Ïi"ßxÇ4ž'p†€—$œ%œz’@*7ènaìÀ´*JM¸SÁßÂx1g^DǰWß’8S*cð"ÄGû;…ªØ¬c°>SºîèÅMS9(ˆÉ´Ÿ„î)€rCmÂFÔëË1KJø’ñ'´O…FtC`'åÚ<ÉjiëQrÏ—: Òã3´#< ö"SÎ"ýYÃatÖ¨1¸¬gœ$`8°oÅÝ‘’=(•ç»ì VF~ì{[U)>içs¼ªˆ¬¢êcëx¬ô=ŽØ`©NB¢pâÅ.ÐxÊ wØ G­ÁU}ì{r =N¾J8S%G„‡µÀ“ÞØh †îè‹ÛÅ¢.uüXÌ~s|ÿ^”3 µˆ UXÊ1d9ÏöÃÏ;êݵ­Â¢¢1¥Í%2Mpë¢H…„ª|KÎB…J£Ûk¶†½ÞUÝ´JíÉÓVRÂ’áÊPÝGeìbNü{­yJ¹€»˜F¸0EÔÑXHžú’²X¾J²i˜8¬7PgîP¿ªkvÞ±žc†*CN¼à Ñ +,ç rÝ åÖÇV$87.'5þiZ® H9 ‹gëð+® †]eÍ&s[{æºl†¼âX¼~n©½èu:n³nnm˜:h¬ ’Yø+Åä1a\®k('WLTPy%m]&IV´Ü£¡¢gâa,^‰;¥|e{1:\°DkÒ›Œ¦¦äƃ(,$&¼ÿãÍ*9ggF¾Ù,©îõG3Œ Ì€%!–xø¤åkµZ¹B£gœê¶Å¸ÀPq]Ñ8}\6=¾ ñò'äÜm.›Ü›±øSø´ì©z ‰ñy¸¶4ó§ßnÂfÖ‹ çêãQñ6C€uõÌ ¬¾ü¶µ@]š'·P;rn'wċ̥·¸‡ƒg<>±Z¬“—ƒñ–L^õÓMãžû«ÎÛdZõ^±íÿèúÅ×Ë›v÷h—ó×è¼  ¯nÃáWp‡íNë5ñÜ,ÒÓ÷ÿá)ž¿*”’RËáÅœ†ˆÄ{b᫚i"â€<8q†ã•¶€­Ù!AgO*Ó1Ù*N6YqÙ˜®”/XàÑ®Î-ÅBªØÕ0¶a>b‡ï¹Â†&ŒýÐN¥ßbs'`Nô,+t­¬¯ZTš· *^^3ç¢è9·¦I—> “*Ûê<)=¾ûôÈжûëgÅÞOêŒzíAQ¾‹9®’T!eÉ4'o}yγËü9ò±‰«‰¨©ü£1„©|J¨ï…¸…¥x8Tý–’wE¯Û¤êò9[ÂßivÈ$Í0²w v_4B d-¶›ÙÂ$ B¦ixºÎ×ÕÓ¾œÈÜ>,¾Ï{½á§öU«^8·ÁëaVä+^|·†‹fh‚\`sòwŠ-~Øû­ úvý8•çín6Ÿ îjº ÑV纮L•ýAïRµNõ±† þº,ñ%€õí›ã8Bºè¨–!3‡VB}äÚ:Áßo?­¼­t¬"1Ȍфš±1yS:ÛjÏqÛkù”­‚‘Ëwšx°müƒ=ùÝ´>š/[ý †¼9”'js8 ls´ÈQÙ³f%@âÊY¬{IÕ‘k8âoš#$)O†¿Ò¦+²…;ŵÓ47f˜EœÉ]3«Ö®XÆ¡OéŠè•-õ %Æ4o-ëÎÓU‚Ê‹4YSäVس¦ê›Ð£­:®†™×›‘Ó²HŸµCKuø,sÆ]fܺT¼UÔÿ2cµYc´§kÂÐãÇÆ¿PK-qM>M•Þ¥¹"priv/templates/simplenode.templateuÍ Â0„ï>E©×/}ñÛm äM,HÈ»›õ/5¡—e™Ùù&,¿Jp]sÚŒ Æ®iÕƒÖ6^"ÛÊJî!éN¤ÈcÒ#Ù`ô$æ6™…BÑIÈ"(™PXOòÝ!i¯ëá¦Lú~Úû¾2k z˜A?e“öwQ#ñ®5`†O%1n#‹›Ê­]µô­´íŠÅ8Î.§¾BŠ<PK-qM>Z·{6«!priv/templates/simplenode.vm.argsEMO1†ïýc¸hÌ"?b¼HpQ#(ü¸‘nwšÝ’v !„ÿîìz ½´3ïû¼ÓQ|èÁÀkr9ª„šÊáÐõ¯ï»=9}¥D?t®´…óÛÀÞf‘1ô•¦•J²ùWœ­ïµç 5C­I¯°FâGБ]â1°4|OÀ`YÈ@24®–k$Ñl»ÅvþlƒÎ*ÉÍöc¡cÅÝn ;Ëk0‚µŽÎ.D›¬›àv„””è +ظªM9h(p:ìÉÈ<ê<¨Ëw`Q]à¶õ¾‘‘ŽP¬3ôÍÆŒ#½—KÆ¿ ΔÈA%H[Hgãådð»œ~Îs¸é=ܵœÅu /C`>ÔÎ7ëg¤“mô5ÏÒtºŒé ú=¥þPK-qM>‘£0¤Vpriv/templates/simplesrv.erlµRQkÂ0~ï¯È‹!]·ù¶‡ Á Âġ̑ٳcâ’T¥ÿ}‰s5ÆÖRr¹û>îîûâÊ ¸,>𬪺7QüvàªÐ8I èhÿžÁšKÀ³t:O§='ƒ×çÔe¢NÅÿþZƒ`óJV!priv/templates/simplesrv.template«.K,ÊLLÊI-ÖQˆ®..*ËLÑQPÊ­,N-*K-Rª­Õãª.IÍ-ÈI,IÊg™©@uz©E9J ¢dýjˆÆÚZ° PPK-qM>÷d getopt.beamPK-qM>ûp² T Dmustache.beamPK-qM>©Go ? }rebar.appPK-qM>ï”×Öä Ãrebar.beamPK-qM>:Y ;Á+rebar_abnfc_compiler.beamPK-qM>ܧ=p31rebar_app_utils.beamPK-qM>ª…ß[PÕ6rebar_asn1_compiler.beamPK-qM>jQ¤ô f;rebar_base_compiler.beamPK-qM>'f]­ @Drebar_cleaner.beamPK-qM> }ÓûP „Frebar_config.beamPK-qM>¨žm»B ®Lrebar_core.beamPK-qM>&À—YZ À Zrebar_ct.beamPK-qM>Î¥Hxàü"¢erebar_deps.beamPK-qM>HRòƒˆ ¯zrebar_dialyzer.beamPK-qM> Ãf4cƒrebar_edoc.beamPK-qM>¦Â1l¨Ä…rebar_erlc_compiler.beamPK-qM>€CÔ ˜ f—rebar_erlydtl_compiler.beamPK-qM>ƒhmJ8 ° rebar_escripter.beamPK-qM>æõ—z¦!,§rebar_eunit.beamPK-qM>M(|ò}” »rebar_file_utils.beamPK-qM>ø¯ÆD°Ârebar_lfe_compiler.beamPK-qM>(‡@èÏLÇrebar_log.beamPK-qM>í£ø þÊrebar_neotoma_compiler.beamPK-qM>Xù0"T ÚÓrebar_otp_app.beamPK-qM>–ú$m—ø(Ürebar_port_compiler.beamPK-qM>ºAÐ48õírebar_post_script.beamPK-qM>p´rFçŸÔ ¿òrebar_protobuffs_compiler.beamPK-qM>ÒET4šùrebar_rel_utils.beamPK-qM>äé ãÚ À ürebar_reltool.beamPK-qM>£™GŒÜ* rebar_require_vsn.beamPK-qM>l(»çRHê rebar_subdirs.beamPK-qM>'ðênÊ8lrebar_templater.beamPK-qM>G%È”1 ¨hrebar_upgrade.beamPK-qM> 2¦T ¸É*rebar_utils.beamPK-qM>IA¤\ LK8rebar_xref.beamPK-qM>:&ÔBpriv/templates/basicnif.cPK-qM>ûV5‡4ØEpriv/templates/basicnif.erlPK-qM>ý+¡R‡ ~Fpriv/templates/basicnif.templatePK-qM>ôävÞ Gpriv/templates/simpleapp.app.srcPK-qM>üÁ™\Î!ÂGpriv/templates/simpleapp.templatePK-qM>À­À‰œk ]Hpriv/templates/simpleapp_app.erlPK-qM>‡O³Ì 7Ipriv/templates/simpleapp_sup.erlPK-qM>@*‡«Jpriv/templates/simplefsm.erlPK-qM>¥DŒrFS!NLpriv/templates/simplefsm.templatePK-qM>>Ò8ì[lÓLpriv/templates/simplemod.erlPK-qM>þ6ÛöV’!hMpriv/templates/simplemod.templatePK-qM>+]çI;D"ýMpriv/templates/simplemod_tests.erlPK-qM>Õv¬N$xNpriv/templates/simplenode.app.configPK-qM>K"’V`$fOpriv/templates/simplenode.erl.scriptPK-qM>ì,?¯ˆÓ"þQpriv/templates/simplenode.nodetoolPK-qM>¯oLÎ)0(ÆWpriv/templates/simplenode.reltool.configPK-qM>8ÈLgð 5Ypriv/templates/simplenode.runnerPK-qM>M•Þ¥¹"Ú_priv/templates/simplenode.templatePK-qM>Z·{6«!¿`priv/templates/simplenode.vm.argsPK-qM>‘£0¤V4bpriv/templates/simplesrv.erlPK-qM>Zƒ`óJV!Äcpriv/templates/simplesrv.templatePK99‹Mdrabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/test/0000755000177700017770000000000012633765070025532 5ustar michaelmichaelrabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/test/mochiweb_http_tests.erl0000644000177700017770000000252212633765070032315 0ustar michaelmichael-module(mochiweb_http_tests). -include_lib("eunit/include/eunit.hrl"). -ifdef(gen_tcp_r15b_workaround). -define(SHOULD_HAVE_BUG, true). -else. -define(SHOULD_HAVE_BUG, false). -endif. has_acceptor_bug_test_() -> {setup, fun start_server/0, fun mochiweb_http:stop/1, fun has_acceptor_bug_tests/1}. start_server() -> application:start(inets), {ok, Pid} = mochiweb_http:start_link([{port, 0}, {loop, fun responder/1}]), Pid. has_acceptor_bug_tests(Server) -> Port = mochiweb_socket_server:get(Server, port), [{"1000 should be fine even with the bug", ?_assertEqual(false, has_bug(Port, 1000))}, {"10000 should trigger the bug if present", ?_assertEqual(?SHOULD_HAVE_BUG, has_bug(Port, 10000))}]. responder(Req) -> Req:respond({200, [{"Content-Type", "text/html"}], ["Hello"]}). has_bug(Port, Len) -> case httpc:request(get, {"http://127.0.0.1:" ++ integer_to_list(Port) ++ "/", [{"X-Random", lists:duplicate(Len, $a)}]}, [], []) of {error, socket_closed_remotely} -> true; {ok, {{"HTTP/1.1", 200, "OK"}, _, "Hello"}} -> false; {ok, {{"HTTP/1.1", 400, "Bad Request"}, _, []}} -> false end. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/test/mochiweb_base64url_tests.erl0000644000177700017770000000125712633765070033151 0ustar michaelmichael-module(mochiweb_base64url_tests). -include_lib("eunit/include/eunit.hrl"). id(X) -> ?assertEqual( X, mochiweb_base64url:decode(mochiweb_base64url:encode(X))), ?assertEqual( X, mochiweb_base64url:decode( binary_to_list(mochiweb_base64url:encode(binary_to_list(X))))). random_binary(Short,Long) -> << <<(random:uniform(256) - 1)>> || _ <- lists:seq(1, Short + random:uniform(1 + Long - Short) - 1) >>. empty_test() -> id(<<>>). onechar_test() -> [id(<>) || C <- lists:seq(0,255)], ok. nchar_test() -> %% 1000 tests of 2-6 char strings [id(B) || _ <- lists:seq(1,1000), B <- [random_binary(2, 6)]], ok. rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/test/mochiweb_tests.erl0000644000177700017770000001477412633765070031272 0ustar michaelmichael-module(mochiweb_tests). -include_lib("eunit/include/eunit.hrl"). -record(treq, {path, body= <<>>, xreply= <<>>}). ssl_cert_opts() -> EbinDir = filename:dirname(code:which(?MODULE)), CertDir = filename:join([EbinDir, "..", "support", "test-materials"]), CertFile = filename:join(CertDir, "test_ssl_cert.pem"), KeyFile = filename:join(CertDir, "test_ssl_key.pem"), [{certfile, CertFile}, {keyfile, KeyFile}]. with_server(Transport, ServerFun, ClientFun) -> ServerOpts0 = [{ip, "127.0.0.1"}, {port, 0}, {loop, ServerFun}], ServerOpts = case Transport of plain -> ServerOpts0; ssl -> ServerOpts0 ++ [{ssl, true}, {ssl_opts, ssl_cert_opts()}] end, {ok, Server} = mochiweb_http:start_link(ServerOpts), Port = mochiweb_socket_server:get(Server, port), Res = (catch ClientFun(Transport, Port)), mochiweb_http:stop(Server), Res. request_test() -> R = mochiweb_request:new(z, z, "/foo/bar/baz%20wibble+quux?qs=2", z, []), "/foo/bar/baz wibble quux" = R:get(path), ok. -define(LARGE_TIMEOUT, 60). single_http_GET_test() -> do_GET(plain, 1). single_https_GET_test() -> do_GET(ssl, 1). multiple_http_GET_test() -> do_GET(plain, 3). multiple_https_GET_test() -> do_GET(ssl, 3). hundred_http_GET_test_() -> % note the underscore {timeout, ?LARGE_TIMEOUT, fun() -> ?assertEqual(ok, do_GET(plain,100)) end}. hundred_https_GET_test_() -> % note the underscore {timeout, ?LARGE_TIMEOUT, fun() -> ?assertEqual(ok, do_GET(ssl,100)) end}. single_128_http_POST_test() -> do_POST(plain, 128, 1). single_128_https_POST_test() -> do_POST(ssl, 128, 1). single_2k_http_POST_test() -> do_POST(plain, 2048, 1). single_2k_https_POST_test() -> do_POST(ssl, 2048, 1). single_100k_http_POST_test() -> do_POST(plain, 102400, 1). single_100k_https_POST_test() -> do_POST(ssl, 102400, 1). multiple_100k_http_POST_test() -> do_POST(plain, 102400, 3). multiple_100K_https_POST_test() -> do_POST(ssl, 102400, 3). hundred_128_http_POST_test_() -> % note the underscore {timeout, ?LARGE_TIMEOUT, fun() -> ?assertEqual(ok, do_POST(plain, 128, 100)) end}. hundred_128_https_POST_test_() -> % note the underscore {timeout, ?LARGE_TIMEOUT, fun() -> ?assertEqual(ok, do_POST(ssl, 128, 100)) end}. do_GET(Transport, Times) -> PathPrefix = "/whatever/", ReplyPrefix = "You requested: ", ServerFun = fun (Req) -> Reply = ReplyPrefix ++ Req:get(path), Req:ok({"text/plain", Reply}) end, TestReqs = [begin Path = PathPrefix ++ integer_to_list(N), ExpectedReply = list_to_binary(ReplyPrefix ++ Path), #treq{path=Path, xreply=ExpectedReply} end || N <- lists:seq(1, Times)], ClientFun = new_client_fun('GET', TestReqs), ok = with_server(Transport, ServerFun, ClientFun), ok. do_POST(Transport, Size, Times) -> ServerFun = fun (Req) -> Body = Req:recv_body(), Headers = [{"Content-Type", "application/octet-stream"}], Req:respond({201, Headers, Body}) end, TestReqs = [begin Path = "/stuff/" ++ integer_to_list(N), Body = crypto:rand_bytes(Size), #treq{path=Path, body=Body, xreply=Body} end || N <- lists:seq(1, Times)], ClientFun = new_client_fun('POST', TestReqs), ok = with_server(Transport, ServerFun, ClientFun), ok. new_client_fun(Method, TestReqs) -> fun (Transport, Port) -> client_request(Transport, Port, Method, TestReqs) end. client_request(Transport, Port, Method, TestReqs) -> Opts = [binary, {active, false}, {packet, http}], SockFun = case Transport of plain -> {ok, Socket} = gen_tcp:connect("127.0.0.1", Port, Opts), fun (recv) -> gen_tcp:recv(Socket, 0); ({recv, Length}) -> gen_tcp:recv(Socket, Length); ({send, Data}) -> gen_tcp:send(Socket, Data); ({setopts, L}) -> inet:setopts(Socket, L) end; ssl -> {ok, Socket} = ssl:connect("127.0.0.1", Port, [{ssl_imp, new} | Opts]), fun (recv) -> ssl:recv(Socket, 0); ({recv, Length}) -> ssl:recv(Socket, Length); ({send, Data}) -> ssl:send(Socket, Data); ({setopts, L}) -> ssl:setopts(Socket, L) end end, client_request(SockFun, Method, TestReqs). client_request(SockFun, _Method, []) -> {the_end, {error, closed}} = {the_end, SockFun(recv)}, ok; client_request(SockFun, Method, [#treq{path=Path, body=Body, xreply=ExReply} | Rest]) -> Request = [atom_to_list(Method), " ", Path, " HTTP/1.1\r\n", client_headers(Body, Rest =:= []), "\r\n", Body], ok = SockFun({send, Request}), case Method of 'GET' -> {ok, {http_response, {1,1}, 200, "OK"}} = SockFun(recv); 'POST' -> {ok, {http_response, {1,1}, 201, "Created"}} = SockFun(recv) end, ok = SockFun({setopts, [{packet, httph}]}), {ok, {http_header, _, 'Server', _, "MochiWeb" ++ _}} = SockFun(recv), {ok, {http_header, _, 'Date', _, _}} = SockFun(recv), {ok, {http_header, _, 'Content-Type', _, _}} = SockFun(recv), {ok, {http_header, _, 'Content-Length', _, ConLenStr}} = SockFun(recv), ContentLength = list_to_integer(ConLenStr), {ok, http_eoh} = SockFun(recv), ok = SockFun({setopts, [{packet, raw}]}), {payload, ExReply} = {payload, drain_reply(SockFun, ContentLength, <<>>)}, ok = SockFun({setopts, [{packet, http}]}), client_request(SockFun, Method, Rest). client_headers(Body, IsLastRequest) -> ["Host: localhost\r\n", case Body of <<>> -> ""; _ -> ["Content-Type: application/octet-stream\r\n", "Content-Length: ", integer_to_list(byte_size(Body)), "\r\n"] end, case IsLastRequest of true -> "Connection: close\r\n"; false -> "" end]. drain_reply(_SockFun, 0, Acc) -> Acc; drain_reply(SockFun, Length, Acc) -> Sz = erlang:min(Length, 1024), {ok, B} = SockFun({recv, Sz}), drain_reply(SockFun, Length - Sz, <>). rabbitmq-server-3.5.7/plugins-src/mochiweb-wrapper/mochiweb-git/test/mochiweb_html_tests.erl0000644000177700017770000005567412633765070032322 0ustar michaelmichael-module(mochiweb_html_tests). -include_lib("eunit/include/eunit.hrl"). to_html_test() -> ?assertEqual( <<"hey!

    what's up

    sucka
    RAW!">>, iolist_to_binary( mochiweb_html:to_html({html, [], [{<<"head">>, [], [{title, <<"hey!">>}]}, {body, [], [{p, [{class, foo}], [<<"what's">>, <<" up">>, {br}]}, {'div', <<"sucka">>}, {'=', <<"RAW!">>}, {comment, <<" comment! ">>}]}]}))), ?assertEqual( <<"">>, iolist_to_binary( mochiweb_html:to_html({doctype, [<<"html">>, <<"PUBLIC">>, <<"-//W3C//DTD XHTML 1.0 Transitional//EN">>, <<"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">>]}))), ?assertEqual( <<"">>, iolist_to_binary( mochiweb_html:to_html({<<"html">>,[], [{pi, <<"xml:namespace">>, [{<<"prefix">>,<<"o">>}, {<<"ns">>,<<"urn:schemas-microsoft-com:office:office">>}]}]}))), ok. escape_test() -> ?assertEqual( <<"&quot;\"word ><<up!&quot;">>, mochiweb_html:escape(<<""\"word ><>)), ?assertEqual( <<"&quot;\"word ><<up!&quot;">>, mochiweb_html:escape(""\"word ><>, mochiweb_html:escape('"\"word >< ?assertEqual( <<"&quot;"word ><<up!&quot;">>, mochiweb_html:escape_attr(<<""\"word ><>)), ?assertEqual( <<"&quot;"word ><<up!&quot;">>, mochiweb_html:escape_attr(""\"word ><>, mochiweb_html:escape_attr('"\"word ><>, mochiweb_html:escape_attr(12345)), ?assertEqual( <<"1.5">>, mochiweb_html:escape_attr(1.5)), ok. tokens_test() -> ?assertEqual( [{start_tag, <<"foo">>, [{<<"bar">>, <<"baz">>}, {<<"wibble">>, <<"wibble">>}, {<<"alice">>, <<"bob">>}], true}], mochiweb_html:tokens(<<"">>)), ?assertEqual( [{start_tag, <<"foo">>, [{<<"bar">>, <<"baz">>}, {<<"wibble">>, <<"wibble">>}, {<<"alice">>, <<"bob">>}], true}], mochiweb_html:tokens(<<"">>)), ?assertEqual( [{comment, <<"[if lt IE 7]>\n\n>}], mochiweb_html:tokens(<<"">>)), ?assertEqual( [{start_tag, <<"script">>, [{<<"type">>, <<"text/javascript">>}], false}, {data, <<" A= B <= C ">>, false}, {end_tag, <<"script">>}], mochiweb_html:tokens(<<"">>)), ?assertEqual( [{start_tag, <<"script">>, [{<<"type">>, <<"text/javascript">>}], false}, {data, <<" A= B <= C ">>, false}, {end_tag, <<"script">>}], mochiweb_html:tokens(<<"">>)), ?assertEqual( [{start_tag, <<"script">>, [{<<"type">>, <<"text/javascript">>}], false}, {data, <<" A= B <= C ">>, false}, {end_tag, <<"script">>}], mochiweb_html:tokens(<<"">>)), ?assertEqual( [{start_tag, <<"script">>, [{<<"type">>, <<"text/javascript">>}], false}, {data, <<" A= B <= C ">>, false}, {end_tag, <<"script">>}], mochiweb_html:tokens(<<"">>)), ?assertEqual( [{start_tag, <<"textarea">>, [], false}, {data, <<"">>, false}, {end_tag, <<"textarea">>}], mochiweb_html:tokens(<<"">>)), ?assertEqual( [{start_tag, <<"textarea">>, [], false}, {data, <<"">>, false}], mochiweb_html:tokens(<<"