pax_global_header00006660000000000000000000000064135412625740014523gustar00rootroot0000000000000052 comment=9ca94765fd79aafd3eac231e4ebb7fd2a76be6c9 uTox-0.17.1/000077500000000000000000000000001354126257400125505ustar00rootroot00000000000000uTox-0.17.1/.editorconfig000066400000000000000000000004071354126257400152260ustar00rootroot00000000000000root = true [*] end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true [*.{c,h,m,sh,xml}] indent_style = space indent_size = 4 [*.yml] indent_style = space indent_size = 2 [{Makefile,CMakeLists.txt}] indent_style = space indent_size = 4 uTox-0.17.1/.gitattributes000066400000000000000000000000301354126257400154340ustar00rootroot00000000000000*.h linguist-language=C uTox-0.17.1/.github/000077500000000000000000000000001354126257400141105ustar00rootroot00000000000000uTox-0.17.1/.github/ISSUE_TEMPLATE.md000066400000000000000000000002171354126257400166150ustar00rootroot00000000000000### Overview 1. uTox version: 2. Operating system: 3. Desktop Environment/Window Manager (Linux/BSD only): ### Issue Write your issue here. uTox-0.17.1/.gitignore000066400000000000000000000006461354126257400145460ustar00rootroot00000000000000# objects **/*.o **/*.a **/*.tar.gz # executables utox utox.exe *.apk # store dirs lib/* libs/* build*/* toolchain/* Tox/ libtoxcore.log toolchain/ build/* tox/* dist/* cache/* # editor files *.swp *~ *.orig GPATH GRTAGS GTAGS .dir-locals.el # CMake CMakeFiles cmake_install.cmake CMakeCache.txt Makefile install_manifest.txt # CI common dirs toxcore/tox* sys/** # generated by CMake src/cocoa/Info.plist src/utox.1 uTox-0.17.1/.gitlab-ci.yml000066400000000000000000000100561354126257400152060ustar00rootroot00000000000000stages: - build - dev_tool - test - deploy # # build # android: stage: build tags: - android variables: TOXCORE_REPO: "TokTok/c-toxcore" GL_BUILD: "android" script: - ./tools/build-android.sh --auto-CI artifacts: expire_in: 1 week paths: - ./uTox.ready.apk build:linux:64: stage: build tags: - linux cache: # keep cache across stages key: "$CI_BUILD_REF_NAME/linux" paths: - cache/ variables: TOXCORE_REPO: "TokTok/c-toxcore" GL_BUILD: "lin64" before_script: - ./extra/gitlab/linux-before.sh script: - pkg-config --list-all | sort - ./extra/gitlab/linux-script.sh - cp build/utox uTox-linux-x64 artifacts: # keep compiled files as artifacts to pass to the test stage # remove them after one hour expire_in: 1h untracked: true build:linux:muslc: stage: build image: alpine-tox-xvfb tags: - alpine-tox-xvfb cache: # keep cache across stages key: "$CI_BUILD_REF_NAME/linux" paths: - cache/ variables: TOXCORE_REPO: "TokTok/c-toxcore" GL_BUILD: "linMUSL" before_script: - apk add freetype-dev - apk add openal-soft-dev - ./extra/common/filter_audio.sh - ./extra/gitlab/linux-muslc-before.sh script: - ./extra/gitlab/linux-muslc-script.sh - cp build/utox uTox-muslc-64 # TODO static build here artifacts: paths: - uTox-muslc-64 expire_in: 1h build:windows:64: stage: build tags: - mingw64 cache: paths: - cache/ variables: TOXCORE_REPO: "TokTok/c-toxcore" GL_BUILD: "win64" before_script: - ./extra/gitlab/windows-before.sh script: - ./extra/gitlab/windows-script.sh - cp build_win/utox.exe uTox-Win64.exe artifacts: paths: - uTox-Win64.exe expire_in: 6h build:windows:legacy: stage: build tags: - mingw64 cache: paths: - cache/ variables: TOXCORE_REPO: "TokTok/c-toxcore" GL_BUILD: "winLEGACY" before_script: - ./extra/gitlab/windows_legacy-before.sh script: - ./extra/gitlab/windows_legacy-script.sh - cp build_win/utox.exe uTox-Win32-LEGACY.exe artifacts: paths: - uTox-Win32-LEGACY.exe expire_in: 6h build:macos: stage: build tags: - osx cache: paths: - cache/ script: - pwd - docker run --rm -u $(id -u):$(id -g) -v $(pwd):/workdir -e CROSS_TRIPLE=x86_64-apple-darwin arch-build ./extra/gitlab/osx-docker.sh - ls -la ./* artifacts: paths: - utox.app/ expire_in: 6h # ## Create development zip # dev_tool:windows: stage: dev_tool tags: - mingw64 script: - echo "Creating development files for windows" - echo "Pulling headers" - echo "Pulling libs from build:windows" - echo "zipping folder" - echo "archving stuff :D" only: - master - tags - triggers # # test # .test: &test stage: test cache: # keep cache across stages key: "$CI_BUILD_REF_NAME/linux" paths: - cache/ dependencies: - build:linux:64 test:chatlog: <<: *test script: - cd build/tests/ - ctest -VV -R test_chatlog test:updater: <<: *test script: - cd build/tests/ - ctest -VV -R test_updater test:XVFB: stage: test image: alpine-tox-xvfb tags: - alpine-tox-xvfb cache: key: "$CI_BUILD_REF_NAME/linux" paths: - cache/ dependencies: - build:linux:muslc script: - Xvfb :99 & - export DISPLAY=:99 - apk add openal-soft-dev - ls -la - (sleep 2m && killall uTox-muslc-64) & - ./uTox-muslc-64 -vvvvv || true # ## Deploy # deploy:main: stage: deploy tags: - utox.io script: - echo "Deploying to live server" environment: name: utox.io url: https://utox.io/ when: manual only: - master deploy:nightly: stage: deploy tags: - utox.io script: - echo "Deploying to live server" - pwd - ls -la - ls -la ../ - whoami - ls -la /srv/http/utox.io/* environment: name: utox.io url: https://utox.io/nightly when: manual only: - master - develop - deploy uTox-0.17.1/.gitmodules000066400000000000000000000005061354126257400147260ustar00rootroot00000000000000[submodule "third-party/stb"] path = third-party/stb url = https://github.com/nothings/stb.git [submodule "third-party/minini"] path = third-party/minini url = https://github.com/compuphase/minIni.git [submodule "third-party/qrcodegen"] path = third-party/qrcodegen url = https://github.com/nayuki/QR-Code-generator.git uTox-0.17.1/.travis.yml000066400000000000000000000035151354126257400146650ustar00rootroot00000000000000sudo: false language: c addons: apt: packages: - cmake - cmake-data - yasm - check - libdbus-1-dev - libopenal-dev - libopenal-data - libopenal1 - libv4l-dev cache: directories: - $HOME/cache matrix: fast_finish: true include: - name: "Linux Clang" os: linux env: BUILD=linux compiler: clang - name: "Windows x64" sudo: required os: linux env: BUILD=windows compiler: x86_64-w64-mingw32-gcc dist: trusty addons: apt: sources: - ubuntu-toolchain-r-test packages: - gcc - mingw-w64 - gcc-mingw-w64 - mingw-w64-common - binutils-mingw-w64 - yasm - libopenal-dev - libopenal-data - libopenal1 - name: "Windows x32 (XP)" sudo: required os: linux env: BUILD=windows_legacy compiler: i686-w64-mingw32-gcc dist: trusty addons: apt: sources: - ubuntu-toolchain-r-test packages: - gcc - mingw-w64 - gcc-mingw-w64 - mingw-w64-common - binutils-mingw-w64 - yasm - libopenal-dev - libopenal-data - libopenal1 - os: osx compiler: clang env: BUILD=osx git: depth: 5 before_script: - ./extra/travis/env.sh - ./extra/travis/${BUILD}-before.sh - ./extra/travis/filter_audio.sh script: - ./extra/travis/${BUILD}-script.sh after_failure: - ./extra/travis/debug_failure.sh notifications: email: false irc: channels: - "chat.freenode.net#utox" use_notice: true skip_join: true template: - "TRAVIS Build %{result} %{branch} %{message} %{build_url}" uTox-0.17.1/CHANGELOG.md000066400000000000000000003141051354126257400143650ustar00rootroot00000000000000# Change Log ## [Unreleased](https://github.com/uTox/uTox/tree/HEAD) [Full Changelog](https://github.com/uTox/uTox/compare/v0.17.0...HEAD) **Closed issues:** - uTox 0.17.0 fails to build [\#1205](https://github.com/uTox/uTox/issues/1205) ## [v0.17.0](https://github.com/uTox/uTox/tree/v0.17.0) (2018-04-15) [Full Changelog](https://github.com/uTox/uTox/compare/v0.16.1...v0.17.0) **Closed issues:** - CMake can not determine linker language [\#1199](https://github.com/uTox/uTox/issues/1199) - Segv when toggling UDP while in video call [\#1198](https://github.com/uTox/uTox/issues/1198) - uTox doesn't build with toxcore-0.2.1 [\#1196](https://github.com/uTox/uTox/issues/1196) - Build fails \(using toxcore-0.2.0\) [\#1189](https://github.com/uTox/uTox/issues/1189) - Force utox to always use proxy is not saving after close and open utox [\#1184](https://github.com/uTox/uTox/issues/1184) - uTox don't save settings if the Windows user account contains diacritics [\#1178](https://github.com/uTox/uTox/issues/1178) - Implement correcting the last message [\#1168](https://github.com/uTox/uTox/issues/1168) - Announcing Fedora package [\#1160](https://github.com/uTox/uTox/issues/1160) - uTox \(0.16.1\) doesn't automatically create .config/tox [\#1156](https://github.com/uTox/uTox/issues/1156) - FPS setting always gives different actual FPS [\#1149](https://github.com/uTox/uTox/issues/1149) - Crash on video preview \[Linux\] [\#1145](https://github.com/uTox/uTox/issues/1145) - File keeps on being resent [\#1137](https://github.com/uTox/uTox/issues/1137) - Aliases should be locally controlled [\#1136](https://github.com/uTox/uTox/issues/1136) - Inconsistent behavior when sending messages to offline contact [\#1125](https://github.com/uTox/uTox/issues/1125) - website not reachable [\#1124](https://github.com/uTox/uTox/issues/1124) - Add a "poll" feature to group chat [\#1121](https://github.com/uTox/uTox/issues/1121) - contact goes invisible when offline [\#1114](https://github.com/uTox/uTox/issues/1114) - Garbage at the end of the text in the notification balloon [\#1108](https://github.com/uTox/uTox/issues/1108) - Switch for "Force uTox to use a proxy" is missing [\#1100](https://github.com/uTox/uTox/issues/1100) - show used toxcore version on "Advanced" Tab in settings [\#1085](https://github.com/uTox/uTox/issues/1085) - Filter audio always disabled in CMake [\#1081](https://github.com/uTox/uTox/issues/1081) - Suggestion [\#1078](https://github.com/uTox/uTox/issues/1078) - Message arrival timestamp state should be saved [\#1058](https://github.com/uTox/uTox/issues/1058) - Chat messages can overlap the arrival timestamps. [\#1057](https://github.com/uTox/uTox/issues/1057) - qr code of own ToxID [\#1055](https://github.com/uTox/uTox/issues/1055) - `SIGTRAP` in message\_free when closing uTox. [\#1049](https://github.com/uTox/uTox/issues/1049) - 0.16.1 crash when desktop share [\#1038](https://github.com/uTox/uTox/issues/1038) - Human-readable settings file format \(INI\) [\#1037](https://github.com/uTox/uTox/issues/1037) - Crash while exporting chat history at macOS [\#1030](https://github.com/uTox/uTox/issues/1030) - Tray icon shows up only when running the 2nd instance of uTox in OpenBox/Tint2 [\#1029](https://github.com/uTox/uTox/issues/1029) - Don't build release builds with ASAN [\#1026](https://github.com/uTox/uTox/issues/1026) - CMake ignores user instructions again... [\#1017](https://github.com/uTox/uTox/issues/1017) - Crash when trying to open downloaded file [\#1013](https://github.com/uTox/uTox/issues/1013) - Reload tray icon after Windows Explorer crash [\#1004](https://github.com/uTox/uTox/issues/1004) - File picker doesn't open [\#1002](https://github.com/uTox/uTox/issues/1002) - Crash when trying to use file picker to save an inline image [\#1001](https://github.com/uTox/uTox/issues/1001) - Click to open doesn't work with inline images [\#1000](https://github.com/uTox/uTox/issues/1000) - Zenburn theme text blends in [\#997](https://github.com/uTox/uTox/issues/997) - Disabled button doesn't look disabled [\#996](https://github.com/uTox/uTox/issues/996) - Crash when trying to send a screenshot after sending an empty screenshot [\#982](https://github.com/uTox/uTox/issues/982) - Simple PubKeys can't be added [\#967](https://github.com/uTox/uTox/issues/967) - Instructions for Trisquel 8 installation. [\#964](https://github.com/uTox/uTox/issues/964) - Implicit fallthrough warnings using gcc version 7 [\#941](https://github.com/uTox/uTox/issues/941) - Group notifications setting dropdown isn't updated on start [\#935](https://github.com/uTox/uTox/issues/935) - Wrong cursor type above the scrollbar [\#925](https://github.com/uTox/uTox/issues/925) - Settings are not saved [\#901](https://github.com/uTox/uTox/issues/901) - Allow multiple portable instances of uTox to run concurrently [\#898](https://github.com/uTox/uTox/issues/898) - utox static 64bit for Linux won't start [\#875](https://github.com/uTox/uTox/issues/875) - Preview call never ends uTox 0.15.0 [\#874](https://github.com/uTox/uTox/issues/874) - Add warning about password length minimum [\#825](https://github.com/uTox/uTox/issues/825) - alignment of buttons in advanced settings should be language depentent [\#639](https://github.com/uTox/uTox/issues/639) - Window not displayed after startups [\#584](https://github.com/uTox/uTox/issues/584) - Tool tips can be drawn off screen [\#571](https://github.com/uTox/uTox/issues/571) - \[GUI\] Drop-down menu close itself; hard to select the option [\#545](https://github.com/uTox/uTox/issues/545) - Tool tip for Decline Call still appears when the button is missing/hidden [\#445](https://github.com/uTox/uTox/issues/445) - system tray icon not showing in xfce on arch linux [\#396](https://github.com/uTox/uTox/issues/396) - Preview URL \[ New feature\] [\#384](https://github.com/uTox/uTox/issues/384) - uTox needs to handle/support tox://URIs [\#326](https://github.com/uTox/uTox/issues/326) - Unicode file names broken in windows [\#324](https://github.com/uTox/uTox/issues/324) - message log should contain information on calls [\#322](https://github.com/uTox/uTox/issues/322) - Messages will draw the name too high [\#300](https://github.com/uTox/uTox/issues/300) - Inconsistent behavior of the dropdown menu and the context menu [\#232](https://github.com/uTox/uTox/issues/232) - No emojis in Windows Client [\#211](https://github.com/uTox/uTox/issues/211) - Friend request improvements [\#143](https://github.com/uTox/uTox/issues/143) - close to tray does not work on Gnome3 [\#55](https://github.com/uTox/uTox/issues/55) - Garbage in clipboard when copy non ASCII characters [\#1107](https://github.com/uTox/uTox/issues/1107) - User Interface Issues [\#893](https://github.com/uTox/uTox/issues/893) - Delete file\_raw\(\) [\#798](https://github.com/uTox/uTox/issues/798) - Click to open doesn't work with auto accept enabled [\#794](https://github.com/uTox/uTox/issues/794) - Video framerate [\#793](https://github.com/uTox/uTox/issues/793) - Dropdown menus not working properly [\#789](https://github.com/uTox/uTox/issues/789) - Chat history not saved [\#779](https://github.com/uTox/uTox/issues/779) - uTox doesn't save proxy\_force setting [\#712](https://github.com/uTox/uTox/issues/712) **Merged pull requests:** - fix \#1156 [\#1182](https://github.com/uTox/uTox/pull/1182) ([publicarray](https://github.com/publicarray)) - Fix Travis build [\#1180](https://github.com/uTox/uTox/pull/1180) ([redmanmale](https://github.com/redmanmale)) - Draw tooltip within window [\#1173](https://github.com/uTox/uTox/pull/1173) ([redmanmale](https://github.com/redmanmale)) - Add error checks to messages.c [\#1171](https://github.com/uTox/uTox/pull/1171) ([endoffile78](https://github.com/endoffile78)) - Add error checks to windows and osx video.c [\#1170](https://github.com/uTox/uTox/pull/1170) ([endoffile78](https://github.com/endoffile78)) - Update bg.h [\#1166](https://github.com/uTox/uTox/pull/1166) ([Reckku](https://github.com/Reckku)) - Add issue template [\#1163](https://github.com/uTox/uTox/pull/1163) ([endoffile78](https://github.com/endoffile78)) - Use $TOXCORE\_REPO\_BRANCH in linux-before.sh [\#1161](https://github.com/uTox/uTox/pull/1161) ([endoffile78](https://github.com/endoffile78)) - Support Toxcore 0.2.0 [\#1157](https://github.com/uTox/uTox/pull/1157) ([robinlinden](https://github.com/robinlinden)) - Fix Travis [\#1154](https://github.com/uTox/uTox/pull/1154) ([robinlinden](https://github.com/robinlinden)) - Fix struct size [\#1151](https://github.com/uTox/uTox/pull/1151) ([redmanmale](https://github.com/redmanmale)) - Add Estonian language support [\#1141](https://github.com/uTox/uTox/pull/1141) ([robinlinden](https://github.com/robinlinden)) - Fix send offline ui [\#1139](https://github.com/uTox/uTox/pull/1139) ([redmanmale](https://github.com/redmanmale)) - Password too short warning [\#1138](https://github.com/uTox/uTox/pull/1138) ([redmanmale](https://github.com/redmanmale)) - Update qr library [\#1134](https://github.com/uTox/uTox/pull/1134) ([redmanmale](https://github.com/redmanmale)) - Get rid of redundant flags, OpenBSD [\#1120](https://github.com/uTox/uTox/pull/1120) ([mazocomp](https://github.com/mazocomp)) - Update Opus download link. [\#1109](https://github.com/uTox/uTox/pull/1109) ([robinlinden](https://github.com/robinlinden)) - Don't build release builds with ASAN [\#1096](https://github.com/uTox/uTox/pull/1096) ([endoffile78](https://github.com/endoffile78)) - Remove references to removed member variables. [\#1095](https://github.com/uTox/uTox/pull/1095) ([robinlinden](https://github.com/robinlinden)) - Fix macOS Travis. [\#1094](https://github.com/uTox/uTox/pull/1094) ([robinlinden](https://github.com/robinlinden)) - Fix no output for --help and --version [\#1084](https://github.com/uTox/uTox/pull/1084) ([endoffile78](https://github.com/endoffile78)) - Fix filter audio option in CMake [\#1082](https://github.com/uTox/uTox/pull/1082) ([redmanmale](https://github.com/redmanmale)) - Update team [\#1076](https://github.com/uTox/uTox/pull/1076) ([redmanmale](https://github.com/redmanmale)) - Language fixes [\#1070](https://github.com/uTox/uTox/pull/1070) ([redmanmale](https://github.com/redmanmale)) - tray icon fix in d505cb8f was not correct, cleanup [\#1066](https://github.com/uTox/uTox/pull/1066) ([termac](https://github.com/termac)) - Fix travis's IRC noise [\#1060](https://github.com/uTox/uTox/pull/1060) ([GrayHatter](https://github.com/GrayHatter)) - Don't look for all Toxcore libs by default. [\#1056](https://github.com/uTox/uTox/pull/1056) ([robinlinden](https://github.com/robinlinden)) - fix tray icon not showing in Linux [\#1050](https://github.com/uTox/uTox/pull/1050) ([termac](https://github.com/termac)) - Fix offline message [\#1046](https://github.com/uTox/uTox/pull/1046) ([endoffile78](https://github.com/endoffile78)) - Use git submodule for stb [\#1041](https://github.com/uTox/uTox/pull/1041) ([redmanmale](https://github.com/redmanmale)) - Fix README [\#1036](https://github.com/uTox/uTox/pull/1036) ([redmanmale](https://github.com/redmanmale)) - Fix file sending for macOS [\#1034](https://github.com/uTox/uTox/pull/1034) ([publicarray](https://github.com/publicarray)) - Fix chat export crash on macOS. Fixes \#1030 [\#1031](https://github.com/uTox/uTox/pull/1031) ([publicarray](https://github.com/publicarray)) - Use CMAKE\_PREFIX\_PATH to find dependencies. [\#1020](https://github.com/uTox/uTox/pull/1020) ([robinlinden](https://github.com/robinlinden)) - Revert check [\#1018](https://github.com/uTox/uTox/pull/1018) ([robinlinden](https://github.com/robinlinden)) - Fix uTox not linking against all required Tox libs. [\#1015](https://github.com/uTox/uTox/pull/1015) ([robinlinden](https://github.com/robinlinden)) - Don't require Check. [\#1012](https://github.com/uTox/uTox/pull/1012) ([robinlinden](https://github.com/robinlinden)) - Fix GTK loading [\#1009](https://github.com/uTox/uTox/pull/1009) ([endoffile78](https://github.com/endoffile78)) - Update group notifications setting on start [\#1007](https://github.com/uTox/uTox/pull/1007) ([redmanmale](https://github.com/redmanmale)) - Update changelog [\#1006](https://github.com/uTox/uTox/pull/1006) ([endoffile78](https://github.com/endoffile78)) - update macOS release link [\#999](https://github.com/uTox/uTox/pull/999) ([publicarray](https://github.com/publicarray)) - Release 0.17.0 [\#1200](https://github.com/uTox/uTox/pull/1200) ([robinlinden](https://github.com/robinlinden)) - Don't allocate too much memory for group peers [\#1143](https://github.com/uTox/uTox/pull/1143) ([robinlinden](https://github.com/robinlinden)) - Fix chat layout for different DPI [\#1140](https://github.com/uTox/uTox/pull/1140) ([redmanmale](https://github.com/redmanmale)) - \[Windows\] Fix garbage at the end of notification [\#1135](https://github.com/uTox/uTox/pull/1135) ([redmanmale](https://github.com/redmanmale)) - \[Windows\] Fix copy to clipboard [\#1132](https://github.com/uTox/uTox/pull/1132) ([redmanmale](https://github.com/redmanmale)) - Better error checking for xlib/video.c [\#1130](https://github.com/uTox/uTox/pull/1130) ([endoffile78](https://github.com/endoffile78)) - Drop file\_raw [\#1118](https://github.com/uTox/uTox/pull/1118) ([redmanmale](https://github.com/redmanmale)) - Save datetime format settings [\#1116](https://github.com/uTox/uTox/pull/1116) ([redmanmale](https://github.com/redmanmale)) - Fix bug that would put uToxGTK in a bad state [\#1113](https://github.com/uTox/uTox/pull/1113) ([robinlinden](https://github.com/robinlinden)) - Allow to override saved theme from cmd args even when it's default [\#1101](https://github.com/uTox/uTox/pull/1101) ([redmanmale](https://github.com/redmanmale)) - Move the stb submodule to third-party directory [\#1099](https://github.com/uTox/uTox/pull/1099) ([endoffile78](https://github.com/endoffile78)) - Tox ID as QR code [\#1097](https://github.com/uTox/uTox/pull/1097) ([redmanmale](https://github.com/redmanmale)) - Fix dropdown [\#1093](https://github.com/uTox/uTox/pull/1093) ([redmanmale](https://github.com/redmanmale)) - Remove deprecated cid field from friend [\#1092](https://github.com/uTox/uTox/pull/1092) ([redmanmale](https://github.com/redmanmale)) - More UI fixes [\#1091](https://github.com/uTox/uTox/pull/1091) ([redmanmale](https://github.com/redmanmale)) - Update INSTALL.md [\#1090](https://github.com/uTox/uTox/pull/1090) ([eclipseo](https://github.com/eclipseo)) - Minor UI fixes [\#1083](https://github.com/uTox/uTox/pull/1083) ([redmanmale](https://github.com/redmanmale)) - Friend request improvements [\#1073](https://github.com/uTox/uTox/pull/1073) ([redmanmale](https://github.com/redmanmale)) - Graceful shutdown [\#1069](https://github.com/uTox/uTox/pull/1069) ([redmanmale](https://github.com/redmanmale)) - Don't allow loading a 0 fps setting from save. [\#1068](https://github.com/uTox/uTox/pull/1068) ([robinlinden](https://github.com/robinlinden)) - Minor UI fixes [\#1063](https://github.com/uTox/uTox/pull/1063) ([redmanmale](https://github.com/redmanmale)) - \[Windows\] Allow multiple portable instances of uTox to run concurrently [\#1061](https://github.com/uTox/uTox/pull/1061) ([redmanmale](https://github.com/redmanmale)) - INI config [\#1053](https://github.com/uTox/uTox/pull/1053) ([redmanmale](https://github.com/redmanmale)) - fix video preview [\#1042](https://github.com/uTox/uTox/pull/1042) ([termac](https://github.com/termac)) - Save force proxy settings [\#1035](https://github.com/uTox/uTox/pull/1035) ([redmanmale](https://github.com/redmanmale)) - Support Tox URI [\#1028](https://github.com/uTox/uTox/pull/1028) ([redmanmale](https://github.com/redmanmale)) - Fix a potential overflow write [\#1011](https://github.com/uTox/uTox/pull/1011) ([GrayHatter](https://github.com/GrayHatter)) - Reload tray icon after Windows Explorer crash [\#1010](https://github.com/uTox/uTox/pull/1010) ([redmanmale](https://github.com/redmanmale)) - Fix save inline image dialog [\#1008](https://github.com/uTox/uTox/pull/1008) ([redmanmale](https://github.com/redmanmale)) - Add friend by public key [\#968](https://github.com/uTox/uTox/pull/968) ([dkmoz](https://github.com/dkmoz)) - Log call info to disk [\#963](https://github.com/uTox/uTox/pull/963) ([dkmoz](https://github.com/dkmoz)) - Fix fallthrough warnings [\#942](https://github.com/uTox/uTox/pull/942) ([endoffile78](https://github.com/endoffile78)) ## [v0.16.1](https://github.com/uTox/uTox/tree/v0.16.1) (2017-08-22) [Full Changelog](https://github.com/uTox/uTox/compare/v0.16.0...v0.16.1) **Closed issues:** - There are no recent uTox OS X .dmg releases even though OS X is a supported platform. [\#998](https://github.com/uTox/uTox/issues/998) - IO device dropdowns broken after Tox thread restart [\#992](https://github.com/uTox/uTox/issues/992) **Merged pull requests:** - Merge develop into master [\#1005](https://github.com/uTox/uTox/pull/1005) ([endoffile78](https://github.com/endoffile78)) - Fix zenburn theme chat text color [\#1003](https://github.com/uTox/uTox/pull/1003) ([redmanmale](https://github.com/redmanmale)) - Release 0.16.1. [\#995](https://github.com/uTox/uTox/pull/995) ([robinlinden](https://github.com/robinlinden)) - Fix cmake so linux can cross compile all versions [\#993](https://github.com/uTox/uTox/pull/993) ([GrayHatter](https://github.com/GrayHatter)) - Fix AV IO dropdowns breaking after Tox-thread restart. [\#994](https://github.com/uTox/uTox/pull/994) ([robinlinden](https://github.com/robinlinden)) ## [v0.16.0](https://github.com/uTox/uTox/tree/v0.16.0) (2017-08-20) [Full Changelog](https://github.com/uTox/uTox/compare/v0.15.0...v0.16.0) **Closed issues:** - how can I change my tox ID ? [\#985](https://github.com/uTox/uTox/issues/985) - CMake needs some TLC [\#978](https://github.com/uTox/uTox/issues/978) - Default asan to off on static Windows [\#972](https://github.com/uTox/uTox/issues/972) - Segfault in video\_begin [\#951](https://github.com/uTox/uTox/issues/951) - Custom bootstrap node [\#939](https://github.com/uTox/uTox/issues/939) - Set up regular static analysis [\#927](https://github.com/uTox/uTox/issues/927) - Video with = 0 can't preview when doing desktop sharing [\#915](https://github.com/uTox/uTox/issues/915) - Friend settings are not saved unless you change the alias too [\#905](https://github.com/uTox/uTox/issues/905) - Chrono test fails randomly [\#881](https://github.com/uTox/uTox/issues/881) - Remember auto-accept option [\#879](https://github.com/uTox/uTox/issues/879) - Clicking on webcam makes uTox crash 0.15.0 [\#873](https://github.com/uTox/uTox/issues/873) - uTox assembly info \(on Windows\) [\#869](https://github.com/uTox/uTox/issues/869) - video window has title "TEMP TILTE CHANGE ME" [\#862](https://github.com/uTox/uTox/issues/862) - Minor UI glitch [\#855](https://github.com/uTox/uTox/issues/855) - make Xcode project [\#851](https://github.com/uTox/uTox/issues/851) - Status and name overlaps with the status change button. [\#850](https://github.com/uTox/uTox/issues/850) - OS X: crash on start [\#841](https://github.com/uTox/uTox/issues/841) - Profile password field in the wrong place [\#821](https://github.com/uTox/uTox/issues/821) - Links does not work if contain non-ASCII characters [\#815](https://github.com/uTox/uTox/issues/815) - Some warnings. [\#781](https://github.com/uTox/uTox/issues/781) - Incorrect button labels on Advanced settings tab [\#667](https://github.com/uTox/uTox/issues/667) - filetransfer rejected if illegal characters in filename on windows [\#611](https://github.com/uTox/uTox/issues/611) - Unencrypted debug info is wrong [\#586](https://github.com/uTox/uTox/issues/586) - Maximum distance for switches [\#580](https://github.com/uTox/uTox/issues/580) - No A/V in develop branch [\#460](https://github.com/uTox/uTox/issues/460) - Messages received from the wrong user. [\#449](https://github.com/uTox/uTox/issues/449) - Displayed version numbers are not up to date [\#422](https://github.com/uTox/uTox/issues/422) - Porable mode: Yes/No combobox in the Profile tab in Settings \(origin by @darkman088\) [\#398](https://github.com/uTox/uTox/issues/398) - Double click to select text \(X11\) is broken [\#353](https://github.com/uTox/uTox/issues/353) - DPI Broken - Windows 10 [\#351](https://github.com/uTox/uTox/issues/351) - Group calls not working [\#348](https://github.com/uTox/uTox/issues/348) - Scrollbar bottom cap is garbled at certain DPI settings [\#265](https://github.com/uTox/uTox/issues/265) - Version 0.4.2 broke Group Call [\#34](https://github.com/uTox/uTox/issues/34) - uTox hang on restarting Tox thread [\#989](https://github.com/uTox/uTox/issues/989) - crash on macOS [\#957](https://github.com/uTox/uTox/issues/957) - message icon not refresh [\#812](https://github.com/uTox/uTox/issues/812) - X11: middle click to paste text stopped working [\#784](https://github.com/uTox/uTox/issues/784) - Doesn't launch at all with OS X Sierra [\#780](https://github.com/uTox/uTox/issues/780) - Language settings don't save after changing [\#96](https://github.com/uTox/uTox/issues/96) **Merged pull requests:** - Fix video thread lock on restart [\#990](https://github.com/uTox/uTox/pull/990) ([GrayHatter](https://github.com/GrayHatter)) - Let cmake update the man file version. [\#987](https://github.com/uTox/uTox/pull/987) ([robinlinden](https://github.com/robinlinden)) - Opus 1.1.4 -\> 1.2.1 [\#984](https://github.com/uTox/uTox/pull/984) ([robinlinden](https://github.com/robinlinden)) - Clean up CMakeLists.txt. [\#983](https://github.com/uTox/uTox/pull/983) ([robinlinden](https://github.com/robinlinden)) - Fix Ukrainian language code. [\#977](https://github.com/uTox/uTox/pull/977) ([robinlinden](https://github.com/robinlinden)) - Disable asan on static Windows builds [\#974](https://github.com/uTox/uTox/pull/974) ([publicarray](https://github.com/publicarray)) - Default OS X ASAN to off [\#971](https://github.com/uTox/uTox/pull/971) ([publicarray](https://github.com/publicarray)) - Fix false positive [\#969](https://github.com/uTox/uTox/pull/969) ([endoffile78](https://github.com/endoffile78)) - Add info to readme [\#966](https://github.com/uTox/uTox/pull/966) ([dkmoz](https://github.com/dkmoz)) - Fix type mismatch warning [\#954](https://github.com/uTox/uTox/pull/954) ([endoffile78](https://github.com/endoffile78)) - Fix typing notification not using the contact's alias [\#950](https://github.com/uTox/uTox/pull/950) ([dkmoz](https://github.com/dkmoz)) - Fix x11 double click text copying [\#948](https://github.com/uTox/uTox/pull/948) ([dkmoz](https://github.com/dkmoz)) - Fix memory leaks in xlib/window.c [\#945](https://github.com/uTox/uTox/pull/945) ([dkmoz](https://github.com/dkmoz)) - Fix decryption error messages [\#944](https://github.com/uTox/uTox/pull/944) ([dkmoz](https://github.com/dkmoz)) - Check resumeable file pointer with fstat. [\#933](https://github.com/uTox/uTox/pull/933) ([robinlinden](https://github.com/robinlinden)) - Remove incorrect debug info & fix X11 middle click to paste [\#932](https://github.com/uTox/uTox/pull/932) ([dkmoz](https://github.com/dkmoz)) - fix potential crash on macOS when video input == nil [\#930](https://github.com/uTox/uTox/pull/930) ([publicarray](https://github.com/publicarray)) - Fix issues detected by clang-scan. [\#926](https://github.com/uTox/uTox/pull/926) ([robinlinden](https://github.com/robinlinden)) - Fix \*BSD file picker. [\#924](https://github.com/uTox/uTox/pull/924) ([robinlinden](https://github.com/robinlinden)) - Fix groupchat problems. [\#922](https://github.com/uTox/uTox/pull/922) ([robinlinden](https://github.com/robinlinden)) - Fix opening url with unicode on Windows [\#921](https://github.com/uTox/uTox/pull/921) ([redmanmale](https://github.com/redmanmale)) - Fix null dereference in edit.c [\#920](https://github.com/uTox/uTox/pull/920) ([robinlinden](https://github.com/robinlinden)) - Replace forbidden characters in the incoming filename on Windows... [\#919](https://github.com/uTox/uTox/pull/919) ([redmanmale](https://github.com/redmanmale)) - Warning fix [\#918](https://github.com/uTox/uTox/pull/918) ([redmanmale](https://github.com/redmanmale)) - Correctly include mingw stuff as system includes. [\#910](https://github.com/uTox/uTox/pull/910) ([robinlinden](https://github.com/robinlinden)) - Reduce scope for tox pointer [\#906](https://github.com/uTox/uTox/pull/906) ([GrayHatter](https://github.com/GrayHatter)) - Disable missing field initialiser warning for Clang. [\#900](https://github.com/uTox/uTox/pull/900) ([robinlinden](https://github.com/robinlinden)) - Fix notifications. [\#899](https://github.com/uTox/uTox/pull/899) ([robinlinden](https://github.com/robinlinden)) - Revert "Remove files generated by cmake from git." [\#895](https://github.com/uTox/uTox/pull/895) ([endoffile78](https://github.com/endoffile78)) - Only error asan+static compilation on Windows. [\#892](https://github.com/uTox/uTox/pull/892) ([robinlinden](https://github.com/robinlinden)) - Fix autoaccept setting not triggering metadata save. [\#891](https://github.com/uTox/uTox/pull/891) ([robinlinden](https://github.com/robinlinden)) - Make uTox save the language you set. [\#890](https://github.com/uTox/uTox/pull/890) ([robinlinden](https://github.com/robinlinden)) - Fix Linux static jenkins builds. [\#889](https://github.com/uTox/uTox/pull/889) ([robinlinden](https://github.com/robinlinden)) - Remove log spam when video is running. [\#888](https://github.com/uTox/uTox/pull/888) ([robinlinden](https://github.com/robinlinden)) - update macOS instructions [\#887](https://github.com/uTox/uTox/pull/887) ([publicarray](https://github.com/publicarray)) - Reduce size of MinSizeRel builds. [\#886](https://github.com/uTox/uTox/pull/886) ([robinlinden](https://github.com/robinlinden)) - Remove files generated by cmake from git. [\#885](https://github.com/uTox/uTox/pull/885) ([robinlinden](https://github.com/robinlinden)) - Move copyright info to cmake. [\#884](https://github.com/uTox/uTox/pull/884) ([robinlinden](https://github.com/robinlinden)) - Update deprecated debug calls. [\#883](https://github.com/uTox/uTox/pull/883) ([robinlinden](https://github.com/robinlinden)) - Fix video window title for Windows [\#882](https://github.com/uTox/uTox/pull/882) ([thorpelawrence](https://github.com/thorpelawrence)) - Add assembly info on Windows [\#880](https://github.com/uTox/uTox/pull/880) ([redmanmale](https://github.com/redmanmale)) - Add badge for irc channel to README [\#878](https://github.com/uTox/uTox/pull/878) ([endoffile78](https://github.com/endoffile78)) - Delete cygwin-compile.sh [\#877](https://github.com/uTox/uTox/pull/877) ([endoffile78](https://github.com/endoffile78)) - fix \#841 [\#866](https://github.com/uTox/uTox/pull/866) ([publicarray](https://github.com/publicarray)) - Enable tests on OSX [\#859](https://github.com/uTox/uTox/pull/859) ([endoffile78](https://github.com/endoffile78)) - Remove \#include \ from tests [\#858](https://github.com/uTox/uTox/pull/858) ([xsleonard](https://github.com/xsleonard)) - Update changelog [\#856](https://github.com/uTox/uTox/pull/856) ([endoffile78](https://github.com/endoffile78)) - Improve macOS Builds [\#854](https://github.com/uTox/uTox/pull/854) ([publicarray](https://github.com/publicarray)) - Fix double sending of outgoing files [\#988](https://github.com/uTox/uTox/pull/988) ([GrayHatter](https://github.com/GrayHatter)) - Update German translation [\#976](https://github.com/uTox/uTox/pull/976) ([sfan5](https://github.com/sfan5)) - Update Swedish translation for 0.16.0 [\#975](https://github.com/uTox/uTox/pull/975) ([robinlinden](https://github.com/robinlinden)) - Add video fps control to av settings [\#965](https://github.com/uTox/uTox/pull/965) ([dkmoz](https://github.com/dkmoz)) - Set typing state to 0 when message is sent [\#961](https://github.com/uTox/uTox/pull/961) ([dkmoz](https://github.com/dkmoz)) - Move av components [\#960](https://github.com/uTox/uTox/pull/960) ([dkmoz](https://github.com/dkmoz)) - Add timestamps to messages in chatlog [\#953](https://github.com/uTox/uTox/pull/953) ([dkmoz](https://github.com/dkmoz)) - Fix autostart switch being a no-op. [\#949](https://github.com/uTox/uTox/pull/949) ([robinlinden](https://github.com/robinlinden)) - Remove Tox DNS. [\#947](https://github.com/uTox/uTox/pull/947) ([robinlinden](https://github.com/robinlinden)) - Release 0.16.0. [\#937](https://github.com/uTox/uTox/pull/937) ([robinlinden](https://github.com/robinlinden)) - Create filter\_audio.c [\#936](https://github.com/uTox/uTox/pull/936) ([endoffile78](https://github.com/endoffile78)) - fix mac font issues once and for all [\#931](https://github.com/uTox/uTox/pull/931) ([publicarray](https://github.com/publicarray)) - Group av [\#928](https://github.com/uTox/uTox/pull/928) ([endoffile78](https://github.com/endoffile78)) - File transfer refactoring [\#923](https://github.com/uTox/uTox/pull/923) ([redmanmale](https://github.com/redmanmale)) - Fix webcam issues on XLIB [\#909](https://github.com/uTox/uTox/pull/909) ([GrayHatter](https://github.com/GrayHatter)) - Clean up header files. [\#896](https://github.com/uTox/uTox/pull/896) ([robinlinden](https://github.com/robinlinden)) - Remove more things from main.h [\#894](https://github.com/uTox/uTox/pull/894) ([robinlinden](https://github.com/robinlinden)) - update cmake - use find modules and pkg-config - enable static build for macOS and dmg [\#872](https://github.com/uTox/uTox/pull/872) ([publicarray](https://github.com/publicarray)) - Fixes UI glitches [\#870](https://github.com/uTox/uTox/pull/870) ([redmanmale](https://github.com/redmanmale)) - Improve chrono test [\#864](https://github.com/uTox/uTox/pull/864) ([endoffile78](https://github.com/endoffile78)) - Merge in android fixes [\#860](https://github.com/uTox/uTox/pull/860) ([GrayHatter](https://github.com/GrayHatter)) - Fix problems detected by coverity [\#857](https://github.com/uTox/uTox/pull/857) ([endoffile78](https://github.com/endoffile78)) - Initial version of chrono [\#846](https://github.com/uTox/uTox/pull/846) ([endoffile78](https://github.com/endoffile78)) - Create native/window.h [\#831](https://github.com/uTox/uTox/pull/831) ([robinlinden](https://github.com/robinlinden)) - Dynamic groups [\#802](https://github.com/uTox/uTox/pull/802) ([endoffile78](https://github.com/endoffile78)) ## [v0.15.0](https://github.com/uTox/uTox/tree/v0.15.0) (2017-04-22) [Full Changelog](https://github.com/uTox/uTox/compare/v0.14.0...v0.15.0) **Closed issues:** - Add a configure-time switch to disable LTO [\#844](https://github.com/uTox/uTox/issues/844) - Fix updater test [\#829](https://github.com/uTox/uTox/issues/829) - Could not set password on Ubuntu [\#824](https://github.com/uTox/uTox/issues/824) - Some redesign proposal [\#823](https://github.com/uTox/uTox/issues/823) - no tray icon in LXDE [\#822](https://github.com/uTox/uTox/issues/822) - Missing a lot of translations [\#818](https://github.com/uTox/uTox/issues/818) - Group notifications settings use old style switch [\#816](https://github.com/uTox/uTox/issues/816) - Crash when receiving file with auto accept enabled [\#811](https://github.com/uTox/uTox/issues/811) - Interface glitches after changing DPI [\#810](https://github.com/uTox/uTox/issues/810) - make with -DENABLE\_FILTERAUDIO=0 fails [\#809](https://github.com/uTox/uTox/issues/809) - Video window doesn't open on Windows [\#804](https://github.com/uTox/uTox/issues/804) - Updates \(no new version on site\) [\#795](https://github.com/uTox/uTox/issues/795) - Segfault upon hitting the "preview video" button [\#790](https://github.com/uTox/uTox/issues/790) - official sources [\#787](https://github.com/uTox/uTox/issues/787) - Update notes display at every startup, bottom of text is cut off with no scrollbar [\#783](https://github.com/uTox/uTox/issues/783) - The screenshot status is not updated [\#771](https://github.com/uTox/uTox/issues/771) - Desktop notifications on X11 stopped working [\#728](https://github.com/uTox/uTox/issues/728) - Clicks apply to multiple layers [\#718](https://github.com/uTox/uTox/issues/718) - Deleting messages functionality\(Unsend messages\) [\#711](https://github.com/uTox/uTox/issues/711) - File transfers sometimes miss updates [\#655](https://github.com/uTox/uTox/issues/655) - Publish GPG key [\#653](https://github.com/uTox/uTox/issues/653) - Can't connect from restricted network \(port 443\) [\#625](https://github.com/uTox/uTox/issues/625) - Build uTox with muslc [\#555](https://github.com/uTox/uTox/issues/555) - Sending files or photos stops in the middle of transference or 'file transfer broken' Error [\#509](https://github.com/uTox/uTox/issues/509) **Merged pull requests:** - v0.15.0 [\#853](https://github.com/uTox/uTox/pull/853) ([GrayHatter](https://github.com/GrayHatter)) - Release v0.15.0 [\#852](https://github.com/uTox/uTox/pull/852) ([robinlinden](https://github.com/robinlinden)) - Enable updater test only when updater is enabled [\#849](https://github.com/uTox/uTox/pull/849) ([nurupo](https://github.com/nurupo)) - Fix dbus includes [\#848](https://github.com/uTox/uTox/pull/848) ([nurupo](https://github.com/nurupo)) - Add OpenBSD and FreeBSD instructions to BUILD.md and INSTALL.md [\#847](https://github.com/uTox/uTox/pull/847) ([endoffile78](https://github.com/endoffile78)) - Ukrainian translation update for v.0.14.0 [\#843](https://github.com/uTox/uTox/pull/843) ([v2e](https://github.com/v2e)) - UI refactor to make things cool and stuff [\#842](https://github.com/uTox/uTox/pull/842) ([GrayHatter](https://github.com/GrayHatter)) - Fix xlib [\#840](https://github.com/uTox/uTox/pull/840) ([endoffile78](https://github.com/endoffile78)) - Fix some coverity warnings [\#839](https://github.com/uTox/uTox/pull/839) ([endoffile78](https://github.com/endoffile78)) - Remove unneeded includes from xlib/main.h [\#837](https://github.com/uTox/uTox/pull/837) ([endoffile78](https://github.com/endoffile78)) - Move somethings out of main.h [\#836](https://github.com/uTox/uTox/pull/836) ([endoffile78](https://github.com/endoffile78)) - UI redesign [\#835](https://github.com/uTox/uTox/pull/835) ([redmanmale](https://github.com/redmanmale)) - Fix the updater tests [\#834](https://github.com/uTox/uTox/pull/834) ([GrayHatter](https://github.com/GrayHatter)) - Remove unneeded includes from main.h [\#833](https://github.com/uTox/uTox/pull/833) ([endoffile78](https://github.com/endoffile78)) - Improve cmake ASAN behaviour. [\#828](https://github.com/uTox/uTox/pull/828) ([robinlinden](https://github.com/robinlinden)) - Python script to find missing translations [\#820](https://github.com/uTox/uTox/pull/820) ([redmanmale](https://github.com/redmanmale)) - Fix langs [\#819](https://github.com/uTox/uTox/pull/819) ([redmanmale](https://github.com/redmanmale)) - Fix markdown formatting [\#817](https://github.com/uTox/uTox/pull/817) ([nurupo](https://github.com/nurupo)) - Fix for bad redraw size on windows [\#813](https://github.com/uTox/uTox/pull/813) ([GrayHatter](https://github.com/GrayHatter)) - Fix double free in edit\_do on friend\_free\(\) [\#807](https://github.com/uTox/uTox/pull/807) ([GrayHatter](https://github.com/GrayHatter)) - Fix autoaccepting file transfers on Windows [\#806](https://github.com/uTox/uTox/pull/806) ([robinlinden](https://github.com/robinlinden)) - Fixes for video not showing up on windows [\#805](https://github.com/uTox/uTox/pull/805) ([GrayHatter](https://github.com/GrayHatter)) - Support for OpenBSD, NetBSD and FreeBSD. [\#801](https://github.com/uTox/uTox/pull/801) ([robinlinden](https://github.com/robinlinden)) - Drop deprecated function `file\_raw` from Windows. [\#800](https://github.com/uTox/uTox/pull/800) ([robinlinden](https://github.com/robinlinden)) - Fix travis [\#799](https://github.com/uTox/uTox/pull/799) ([endoffile78](https://github.com/endoffile78)) - Fix a lot of the issues found on coverity. [\#797](https://github.com/uTox/uTox/pull/797) ([robinlinden](https://github.com/robinlinden)) ## [v0.14.0](https://github.com/uTox/uTox/tree/v0.14.0) (2017-04-07) [Full Changelog](https://github.com/uTox/uTox/compare/v0.13.1...v0.14.0) **Closed issues:** - make fails - tox/toxav.h: No such file or directory [\#788](https://github.com/uTox/uTox/issues/788) - Error 2 compiling on ubuntu 16.04 [\#782](https://github.com/uTox/uTox/issues/782) - GitLab? [\#778](https://github.com/uTox/uTox/issues/778) - Can't send or receive more than one inline image still. [\#775](https://github.com/uTox/uTox/issues/775) - uTox lost chat history [\#770](https://github.com/uTox/uTox/issues/770) - Notification icon is red forever [\#769](https://github.com/uTox/uTox/issues/769) - enable -Werror in CI environment [\#765](https://github.com/uTox/uTox/issues/765) - CMake: when using clang, also use safestack [\#741](https://github.com/uTox/uTox/issues/741) - notifications works wrong [\#726](https://github.com/uTox/uTox/issues/726) - No notifications when window is minimised [\#717](https://github.com/uTox/uTox/issues/717) - Can't remove avatar [\#697](https://github.com/uTox/uTox/issues/697) - Debug builds should make use of the GIT\_VERSION macro [\#668](https://github.com/uTox/uTox/issues/668) - All randomised nospams start with 0000. [\#665](https://github.com/uTox/uTox/issues/665) - Close to tray option setting will not be remembered. [\#614](https://github.com/uTox/uTox/issues/614) - update\_tray\(\) on windows needs some TLC [\#602](https://github.com/uTox/uTox/issues/602) - Tray icon only visible as white vertical bar [\#185](https://github.com/uTox/uTox/issues/185) **Merged pull requests:** - Update develop with develop from gitlab \(We're back\) [\#792](https://github.com/uTox/uTox/pull/792) ([GrayHatter](https://github.com/GrayHatter)) - Mirror @cebe's build fixes for gcc from GitLab to GitHub [\#786](https://github.com/uTox/uTox/pull/786) ([robinlinden](https://github.com/robinlinden)) - Mirror changes done on GitLab to GitHub. [\#785](https://github.com/uTox/uTox/pull/785) ([robinlinden](https://github.com/robinlinden)) ## [v0.13.1](https://github.com/uTox/uTox/tree/v0.13.1) (2017-02-21) [Full Changelog](https://github.com/uTox/uTox/compare/v0.13.0...v0.13.1) **Closed issues:** - inline filetransfers stop working after the first one being successful [\#755](https://github.com/uTox/uTox/issues/755) - Linux packagers need a way to disable auto-updates [\#683](https://github.com/uTox/uTox/issues/683) **Merged pull requests:** - v0.13.1 to master [\#774](https://github.com/uTox/uTox/pull/774) ([GrayHatter](https://github.com/GrayHatter)) - Gitlab [\#773](https://github.com/uTox/uTox/pull/773) ([GrayHatter](https://github.com/GrayHatter)) ## [v0.13.0](https://github.com/uTox/uTox/tree/v0.13.0) (2017-02-21) [Full Changelog](https://github.com/uTox/uTox/compare/v0.12.2...v0.13.0) **Closed issues:** - Video issues uTox 0.9.7 -\> 0.12.2 [\#752](https://github.com/uTox/uTox/issues/752) - LOG\_FATAL\_ERR should never be a no-op [\#748](https://github.com/uTox/uTox/issues/748) - The XLIB crash bug on Debian [\#742](https://github.com/uTox/uTox/issues/742) - All contacts are lost on Advanced parameter change [\#732](https://github.com/uTox/uTox/issues/732) - Non-ASCII characters past issue [\#729](https://github.com/uTox/uTox/issues/729) - Replace flist\_get\_selected with flist\_get\_selected\_friend/group/type [\#722](https://github.com/uTox/uTox/issues/722) - v0.12.1: Windows7/Windows10: Send File issue [\#721](https://github.com/uTox/uTox/issues/721) - Avatars not loading since 0.11.x [\#713](https://github.com/uTox/uTox/issues/713) - Manual change nospam [\#708](https://github.com/uTox/uTox/issues/708) - uTox doesn't save chat history even though the option is on [\#682](https://github.com/uTox/uTox/issues/682) - Chat window doesn't redraw when scrolling using pgup/pgdn [\#661](https://github.com/uTox/uTox/issues/661) - Delete contacts confirmation [\#615](https://github.com/uTox/uTox/issues/615) - Could not paste non-ASCII characters into chat [\#583](https://github.com/uTox/uTox/issues/583) - Create additional debug levels [\#572](https://github.com/uTox/uTox/issues/572) **Merged pull requests:** - v0.13.0 [\#767](https://github.com/uTox/uTox/pull/767) ([GrayHatter](https://github.com/GrayHatter)) - Release v0.13.0 [\#766](https://github.com/uTox/uTox/pull/766) ([robinlinden](https://github.com/robinlinden)) - FT make file counting more roubust [\#763](https://github.com/uTox/uTox/pull/763) ([GrayHatter](https://github.com/GrayHatter)) - Fix outgoing images [\#762](https://github.com/uTox/uTox/pull/762) ([GrayHatter](https://github.com/GrayHatter)) - Add an option to allow disable the updater [\#761](https://github.com/uTox/uTox/pull/761) ([endoffile78](https://github.com/endoffile78)) - Stop uTox from segfaulting when a peer is missing from gc. [\#759](https://github.com/uTox/uTox/pull/759) ([robinlinden](https://github.com/robinlinden)) - Move finding freetype to xlib's CMakeLists.txt [\#758](https://github.com/uTox/uTox/pull/758) ([endoffile78](https://github.com/endoffile78)) - Update documentation [\#756](https://github.com/uTox/uTox/pull/756) ([romantic668](https://github.com/romantic668)) - Cleanup and bugfixes [\#754](https://github.com/uTox/uTox/pull/754) ([robinlinden](https://github.com/robinlinden)) - Update travis script for win\* [\#753](https://github.com/uTox/uTox/pull/753) ([GrayHatter](https://github.com/GrayHatter)) - Always exit on LOG\_FATAL\_ERR, and convert exiting LOG\_ERRs [\#751](https://github.com/uTox/uTox/pull/751) ([cebe](https://github.com/cebe)) - Remove old debug macros [\#750](https://github.com/uTox/uTox/pull/750) ([endoffile78](https://github.com/endoffile78)) - removed superflous newlines in log messages [\#749](https://github.com/uTox/uTox/pull/749) ([cebe](https://github.com/cebe)) - Fix FT threading issues [\#747](https://github.com/uTox/uTox/pull/747) ([GrayHatter](https://github.com/GrayHatter)) - Don't leak memory if realloc fails. [\#746](https://github.com/uTox/uTox/pull/746) ([robinlinden](https://github.com/robinlinden)) - Fix logic in pausing file always being true. [\#745](https://github.com/uTox/uTox/pull/745) ([robinlinden](https://github.com/robinlinden)) - Need to start travis [\#744](https://github.com/uTox/uTox/pull/744) ([GrayHatter](https://github.com/GrayHatter)) - Fix Windows warnings and exporting chatlogs as plaintext on Windows. [\#739](https://github.com/uTox/uTox/pull/739) ([robinlinden](https://github.com/robinlinden)) - Fix warnings related to message types. [\#738](https://github.com/uTox/uTox/pull/738) ([robinlinden](https://github.com/robinlinden)) - Allow users to log errors to a file [\#737](https://github.com/uTox/uTox/pull/737) ([endoffile78](https://github.com/endoffile78)) - Louder errors and more checks for saving things. [\#735](https://github.com/uTox/uTox/pull/735) ([robinlinden](https://github.com/robinlinden)) - Update CMakeLists.txt [\#731](https://github.com/uTox/uTox/pull/731) ([Axaprj](https://github.com/Axaprj)) - Fix utf8 copy-paste everywhere. [\#727](https://github.com/uTox/uTox/pull/727) ([robinlinden](https://github.com/robinlinden)) - Make fread more samey across uTox. [\#725](https://github.com/uTox/uTox/pull/725) ([robinlinden](https://github.com/robinlinden)) - Add flist\_get\_friend, flist\_get\_groupchat, and flist\_get\_type [\#724](https://github.com/uTox/uTox/pull/724) ([endoffile78](https://github.com/endoffile78)) - Allow changing nospam manually [\#723](https://github.com/uTox/uTox/pull/723) ([endoffile78](https://github.com/endoffile78)) - Refactor themes a bit. [\#716](https://github.com/uTox/uTox/pull/716) ([robinlinden](https://github.com/robinlinden)) - Add confirmation to deleting friends [\#715](https://github.com/uTox/uTox/pull/715) ([endoffile78](https://github.com/endoffile78)) - Fix loading of avatars. \(Patch courtesy of @flussence.\) [\#714](https://github.com/uTox/uTox/pull/714) ([robinlinden](https://github.com/robinlinden)) - Update OSX build instructions [\#710](https://github.com/uTox/uTox/pull/710) ([endoffile78](https://github.com/endoffile78)) - Fix pgup/pgdown not redrawing chat screen. [\#707](https://github.com/uTox/uTox/pull/707) ([robinlinden](https://github.com/robinlinden)) - Fix a few memory leaks in messages.c [\#706](https://github.com/uTox/uTox/pull/706) ([robinlinden](https://github.com/robinlinden)) - Fix SIGTRAP on clearing chat backlog. [\#705](https://github.com/uTox/uTox/pull/705) ([robinlinden](https://github.com/robinlinden)) - Fix chatlogs being set to read-only on Windows. [\#704](https://github.com/uTox/uTox/pull/704) ([robinlinden](https://github.com/robinlinden)) - button.c gen fixups [\#702](https://github.com/uTox/uTox/pull/702) ([GrayHatter](https://github.com/GrayHatter)) - Use GNUInstallDirs in cmake [\#698](https://github.com/uTox/uTox/pull/698) ([GrayHatter](https://github.com/GrayHatter)) - Improve logging macros [\#656](https://github.com/uTox/uTox/pull/656) ([GrayHatter](https://github.com/GrayHatter)) - Custom Windows and Notifications popups [\#550](https://github.com/uTox/uTox/pull/550) ([GrayHatter](https://github.com/GrayHatter)) ## [v0.12.2](https://github.com/uTox/uTox/tree/v0.12.2) (2017-01-28) [Full Changelog](https://github.com/uTox/uTox/compare/v0.12.1...v0.12.2) **Closed issues:** - Buffer overflow in group\_peer\_add [\#689](https://github.com/uTox/uTox/issues/689) - 'i18nal' field is not getting initialized in edits.c [\#687](https://github.com/uTox/uTox/issues/687) - Segfault on network disconnect. [\#684](https://github.com/uTox/uTox/issues/684) - ELF file has executable stack markings [\#676](https://github.com/uTox/uTox/issues/676) - Segfault in groupchat [\#675](https://github.com/uTox/uTox/issues/675) - Segfault with \*\*\* buffer overflow detected \*\*\*: utox terminated; [\#673](https://github.com/uTox/uTox/issues/673) - Min window size limit [\#663](https://github.com/uTox/uTox/issues/663) - Updater must update [\#641](https://github.com/uTox/uTox/issues/641) - Refactor messages.c [\#638](https://github.com/uTox/uTox/issues/638) - Add checkums to releases. [\#588](https://github.com/uTox/uTox/issues/588) - DPI setting stuck in "BUG. PLEASE REPORT". So I'm reporting. [\#495](https://github.com/uTox/uTox/issues/495) - The Tox save logic needs to be removed from the toxcore thread [\#474](https://github.com/uTox/uTox/issues/474) - Tox ID cannot be retrieved after transferring from q to u [\#424](https://github.com/uTox/uTox/issues/424) - Switch UI element visually broken [\#421](https://github.com/uTox/uTox/issues/421) - Program crashes using video with windows 10 [\#395](https://github.com/uTox/uTox/issues/395) - Unchecking ipv6 crashes client [\#388](https://github.com/uTox/uTox/issues/388) - At low DPI "Audio/Video" tab is unclickable [\#377](https://github.com/uTox/uTox/issues/377) - Message queueing causes duplicate messages to be delivered [\#368](https://github.com/uTox/uTox/issues/368) - Add ability to toggle/mute sounds [\#352](https://github.com/uTox/uTox/issues/352) - UTOX close to call [\#350](https://github.com/uTox/uTox/issues/350) - BSOD on Surface Book running Windows 10 [\#344](https://github.com/uTox/uTox/issues/344) - call button color update is wrong [\#281](https://github.com/uTox/uTox/issues/281) - 0.7.0 \(very small\) bugs [\#275](https://github.com/uTox/uTox/issues/275) **Merged pull requests:** - Push Develop to master [\#693](https://github.com/uTox/uTox/pull/693) ([GrayHatter](https://github.com/GrayHatter)) - Version Tick v0.12.1 to v0.12.2 [\#692](https://github.com/uTox/uTox/pull/692) ([GrayHatter](https://github.com/GrayHatter)) - Small improvements to groups [\#691](https://github.com/uTox/uTox/pull/691) ([endoffile78](https://github.com/endoffile78)) - Fix missing initializer for field ‘i18nal’ [\#688](https://github.com/uTox/uTox/pull/688) ([fling-](https://github.com/fling-)) - Fix memory leaks in chatlog code and minor cleanup in messages [\#681](https://github.com/uTox/uTox/pull/681) ([robinlinden](https://github.com/robinlinden)) - Fix executable stack [\#677](https://github.com/uTox/uTox/pull/677) ([fling-](https://github.com/fling-)) - Fix uTox group chat regressions [\#674](https://github.com/uTox/uTox/pull/674) ([robinlinden](https://github.com/robinlinden)) - Fix a typo in CMakeLists.txt [\#672](https://github.com/uTox/uTox/pull/672) ([fling-](https://github.com/fling-)) - Cleanup utoxav [\#671](https://github.com/uTox/uTox/pull/671) ([robinlinden](https://github.com/robinlinden)) - Windows FT fixes [\#669](https://github.com/uTox/uTox/pull/669) ([GrayHatter](https://github.com/GrayHatter)) - Decrease minimum width. [\#666](https://github.com/uTox/uTox/pull/666) ([robinlinden](https://github.com/robinlinden)) - Plug 2 memory leaks related to file transfers. [\#662](https://github.com/uTox/uTox/pull/662) ([robinlinden](https://github.com/robinlinden)) - Fix Windows cmake toolchains and strip symbols from Release build types. [\#660](https://github.com/uTox/uTox/pull/660) ([robinlinden](https://github.com/robinlinden)) - Add self.c and self.h [\#659](https://github.com/uTox/uTox/pull/659) ([endoffile78](https://github.com/endoffile78)) - Move things from main.h to main\_native.h [\#658](https://github.com/uTox/uTox/pull/658) ([robinlinden](https://github.com/robinlinden)) - Fix warnings part 2 [\#657](https://github.com/uTox/uTox/pull/657) ([GrayHatter](https://github.com/GrayHatter)) - Fix man install directory [\#654](https://github.com/uTox/uTox/pull/654) ([NicoHood](https://github.com/NicoHood)) - Update manpage with new domain [\#652](https://github.com/uTox/uTox/pull/652) ([GrayHatter](https://github.com/GrayHatter)) - Fix warnings through out uTox [\#651](https://github.com/uTox/uTox/pull/651) ([GrayHatter](https://github.com/GrayHatter)) - Add macros.h [\#649](https://github.com/uTox/uTox/pull/649) ([endoffile78](https://github.com/endoffile78)) - Add settings.c and settings.h [\#647](https://github.com/uTox/uTox/pull/647) ([endoffile78](https://github.com/endoffile78)) - Cleanup includes [\#646](https://github.com/uTox/uTox/pull/646) ([endoffile78](https://github.com/endoffile78)) ## [v0.12.1](https://github.com/uTox/uTox/tree/v0.12.1) (2017-01-23) [Full Changelog](https://github.com/uTox/uTox/compare/v0.12.0...v0.12.1) **Closed issues:** - Could you please fix the Windows XP build? [\#609](https://github.com/uTox/uTox/issues/609) - Drag and drop for files do not work, 0.11.1 [\#600](https://github.com/uTox/uTox/issues/600) - refactor tox.h/c =\> core.h/c && tox.h/c [\#528](https://github.com/uTox/uTox/issues/528) **Merged pull requests:** - NEW VERSION v012.0 -\> v0.12.1 [\#645](https://github.com/uTox/uTox/pull/645) ([GrayHatter](https://github.com/GrayHatter)) - Fix a segv with inline transfers [\#644](https://github.com/uTox/uTox/pull/644) ([GrayHatter](https://github.com/GrayHatter)) - Fix segv on saving inline images on Windows [\#642](https://github.com/uTox/uTox/pull/642) ([robinlinden](https://github.com/robinlinden)) - added missing German translations [\#640](https://github.com/uTox/uTox/pull/640) ([cebe](https://github.com/cebe)) ## [v0.12.0](https://github.com/uTox/uTox/tree/v0.12.0) (2017-01-22) [Full Changelog](https://github.com/uTox/uTox/compare/v0.11.1...v0.12.0) **Closed issues:** - segfault on exporting changelog [\#630](https://github.com/uTox/uTox/issues/630) - Linker warning, related to forward declares? [\#628](https://github.com/uTox/uTox/issues/628) - uTox is prevented from starting on windows with some McAffee thingy installed [\#621](https://github.com/uTox/uTox/issues/621) - filetransfer resume has UI errors [\#620](https://github.com/uTox/uTox/issues/620) - Segfault on any contact going offline \(current nightly, Linux\) [\#616](https://github.com/uTox/uTox/issues/616) - File transfers crash, 0.11.1 [\#601](https://github.com/uTox/uTox/issues/601) - uTox making random noises [\#585](https://github.com/uTox/uTox/issues/585) - chat history is lost after changing network settings [\#582](https://github.com/uTox/uTox/issues/582) - time display is missing the last digit [\#581](https://github.com/uTox/uTox/issues/581) - Wrong text when hovering on buttons [\#576](https://github.com/uTox/uTox/issues/576) - UI glitch with password field [\#570](https://github.com/uTox/uTox/issues/570) - \[binaries\] Linux static x32 binary is not static and not x32 [\#567](https://github.com/uTox/uTox/issues/567) - Language selector shows multiple options for english [\#563](https://github.com/uTox/uTox/issues/563) - GUI freeze when I try to change network settings 0.9.7 [\#544](https://github.com/uTox/uTox/issues/544) - DPI and Can't Connect [\#459](https://github.com/uTox/uTox/issues/459) - \[feature request\] Ability to change «nospam» part of ToxID from µTox UI. [\#406](https://github.com/uTox/uTox/issues/406) - Problems in the Video Preview [\#251](https://github.com/uTox/uTox/issues/251) **Merged pull requests:** - Delete util files. [\#643](https://github.com/uTox/uTox/pull/643) ([robinlinden](https://github.com/robinlinden)) - NEW VERSION [\#636](https://github.com/uTox/uTox/pull/636) ([GrayHatter](https://github.com/GrayHatter)) - Merge nospam into develop. \(Merge conflict with changes\) [\#635](https://github.com/uTox/uTox/pull/635) ([GrayHatter](https://github.com/GrayHatter)) - Update changelog [\#634](https://github.com/uTox/uTox/pull/634) ([endoffile78](https://github.com/endoffile78)) - Version tick [\#633](https://github.com/uTox/uTox/pull/633) ([endoffile78](https://github.com/endoffile78)) - Don't segv when exporting chat history [\#631](https://github.com/uTox/uTox/pull/631) ([GrayHatter](https://github.com/GrayHatter)) - Change some variables over to being declared rather than defined in .h files. [\#629](https://github.com/uTox/uTox/pull/629) ([robinlinden](https://github.com/robinlinden)) - Allow uTox to check for updates [\#627](https://github.com/uTox/uTox/pull/627) ([GrayHatter](https://github.com/GrayHatter)) - Reduce and make includes explicit. [\#626](https://github.com/uTox/uTox/pull/626) ([robinlinden](https://github.com/robinlinden)) - Build fixes for windows [\#624](https://github.com/uTox/uTox/pull/624) ([GrayHatter](https://github.com/GrayHatter)) - WIP commit for fixing file sending on windows [\#622](https://github.com/uTox/uTox/pull/622) ([GrayHatter](https://github.com/GrayHatter)) - Add .gitattribute file [\#619](https://github.com/uTox/uTox/pull/619) ([GrayHatter](https://github.com/GrayHatter)) - WinXP support [\#618](https://github.com/uTox/uTox/pull/618) ([GrayHatter](https://github.com/GrayHatter)) - separated out logging from main.h [\#617](https://github.com/uTox/uTox/pull/617) ([cebe](https://github.com/cebe)) - Make UI less dependent on the rest of uTox. [\#610](https://github.com/uTox/uTox/pull/610) ([robinlinden](https://github.com/robinlinden)) - Friend request improvements [\#608](https://github.com/uTox/uTox/pull/608) ([endoffile78](https://github.com/endoffile78)) - Add sign-release.sh and checksum.sh [\#607](https://github.com/uTox/uTox/pull/607) ([endoffile78](https://github.com/endoffile78)) - enable address sanitizer in cmake debug builds [\#606](https://github.com/uTox/uTox/pull/606) ([cebe](https://github.com/cebe)) - port the add\_cflags makefile function from toxcore [\#605](https://github.com/uTox/uTox/pull/605) ([cebe](https://github.com/cebe)) - Fix avatars, and mkdir for posix [\#604](https://github.com/uTox/uTox/pull/604) ([GrayHatter](https://github.com/GrayHatter)) - Use find\_package to find X11 and Xrender [\#599](https://github.com/uTox/uTox/pull/599) ([endoffile78](https://github.com/endoffile78)) - Fix defects detected by coverity [\#596](https://github.com/uTox/uTox/pull/596) ([endoffile78](https://github.com/endoffile78)) - fix utox clobbering chatlogs [\#595](https://github.com/uTox/uTox/pull/595) ([GrayHatter](https://github.com/GrayHatter)) - Delete .clang-format [\#594](https://github.com/uTox/uTox/pull/594) ([GrayHatter](https://github.com/GrayHatter)) - configure version in one place [\#593](https://github.com/uTox/uTox/pull/593) ([cebe](https://github.com/cebe)) - fixes build for linux [\#591](https://github.com/uTox/uTox/pull/591) ([cebe](https://github.com/cebe)) - Refactor postmessages\(\) [\#590](https://github.com/uTox/uTox/pull/590) ([GrayHatter](https://github.com/GrayHatter)) - Fix uTox not using the MAIN\_HEIGHT & WIDTH defines. [\#579](https://github.com/uTox/uTox/pull/579) ([robinlinden](https://github.com/robinlinden)) - Apply irungentoo's fixes for the XP build and AUDIO\_FILTERING [\#578](https://github.com/uTox/uTox/pull/578) ([robinlinden](https://github.com/robinlinden)) - Fix switches [\#577](https://github.com/uTox/uTox/pull/577) ([cebe](https://github.com/cebe)) - Split CMakeLists.txt into multiple files [\#575](https://github.com/uTox/uTox/pull/575) ([endoffile78](https://github.com/endoffile78)) - Fix friend notification sounds [\#573](https://github.com/uTox/uTox/pull/573) ([GrayHatter](https://github.com/GrayHatter)) - Fixed Hanging GUI when changing network settings [\#569](https://github.com/uTox/uTox/pull/569) ([cebe](https://github.com/cebe)) - Fix names of links to Linux/Posix builds. [\#568](https://github.com/uTox/uTox/pull/568) ([robinlinden](https://github.com/robinlinden)) - Fix when and where we fflush. [\#566](https://github.com/uTox/uTox/pull/566) ([robinlinden](https://github.com/robinlinden)) - Update BUILD.md [\#565](https://github.com/uTox/uTox/pull/565) ([cebe](https://github.com/cebe)) - Fix language-selection dropdown having multiple English languages and none of others. [\#564](https://github.com/uTox/uTox/pull/564) ([robinlinden](https://github.com/robinlinden)) ## [v0.11.1](https://github.com/uTox/uTox/tree/v0.11.1) (2016-12-21) [Full Changelog](https://github.com/uTox/uTox/compare/v0.11.0...v0.11.1) **Closed issues:** - passing a null pointer for dereference, presumably not intentional [\#556](https://github.com/uTox/uTox/issues/556) - GPG signatures for source validation [\#502](https://github.com/uTox/uTox/issues/502) **Merged pull requests:** - Rename onpress to on\_mup [\#589](https://github.com/uTox/uTox/pull/589) ([GrayHatter](https://github.com/GrayHatter)) - Hotfix: drop a bad attempt at secure erase [\#562](https://github.com/uTox/uTox/pull/562) ([GrayHatter](https://github.com/GrayHatter)) - Hotfix: drop a bad attempt at secure erase [\#561](https://github.com/uTox/uTox/pull/561) ([GrayHatter](https://github.com/GrayHatter)) - v0.11.1 to master [\#560](https://github.com/uTox/uTox/pull/560) ([GrayHatter](https://github.com/GrayHatter)) - Write '\0' instead of 0 in ft\_decon\_resumeable [\#559](https://github.com/uTox/uTox/pull/559) ([robinlinden](https://github.com/robinlinden)) - Updated changelog for 0.11.1 [\#557](https://github.com/uTox/uTox/pull/557) ([robinlinden](https://github.com/robinlinden)) - Fix Windows native\_get\_file folder creation. [\#552](https://github.com/uTox/uTox/pull/552) ([robinlinden](https://github.com/robinlinden)) - Move chatlog-related functions to their own file. [\#551](https://github.com/uTox/uTox/pull/551) ([robinlinden](https://github.com/robinlinden)) - Update OS X plist to use the correct version number. [\#548](https://github.com/uTox/uTox/pull/548) ([robinlinden](https://github.com/robinlinden)) - Update tools [\#547](https://github.com/uTox/uTox/pull/547) ([endoffile78](https://github.com/endoffile78)) - Fix segv in ft\_find\_resumeable in file\_transfer.c on Windows [\#546](https://github.com/uTox/uTox/pull/546) ([robinlinden](https://github.com/robinlinden)) - Force toxcore \>= v0.1 [\#542](https://github.com/uTox/uTox/pull/542) ([GrayHatter](https://github.com/GrayHatter)) - Version tick [\#541](https://github.com/uTox/uTox/pull/541) ([endoffile78](https://github.com/endoffile78)) - Add skel checklist for new versions [\#523](https://github.com/uTox/uTox/pull/523) ([GrayHatter](https://github.com/GrayHatter)) ## [v0.11.0](https://github.com/uTox/uTox/tree/v0.11.0) (2016-12-13) [Full Changelog](https://github.com/uTox/uTox/compare/v0.9.8...v0.11.0) **Closed issues:** - compiler error on \(Arch\)linux [\#525](https://github.com/uTox/uTox/issues/525) - Utox it's not autoupdating ? [\#520](https://github.com/uTox/uTox/issues/520) - utox won't start - Trace/breakpoint trap / Illegal instruction / Segmentation fault [\#498](https://github.com/uTox/uTox/issues/498) - Themes are not being saved [\#471](https://github.com/uTox/uTox/issues/471) - Get Tox ID from already added friend [\#458](https://github.com/uTox/uTox/issues/458) - friend\_meta\_data\_read is missing a null check after calloc [\#453](https://github.com/uTox/uTox/issues/453) - Reason to have pulse audio DONT\_MOVE flag [\#448](https://github.com/uTox/uTox/issues/448) - "Audio/Video" tab button is too fat [\#441](https://github.com/uTox/uTox/issues/441) - "Show" button remains even when it has performed its function [\#440](https://github.com/uTox/uTox/issues/440) - The "Show" button is on the title it meant to be next to [\#439](https://github.com/uTox/uTox/issues/439) - Manpage gives different Git repository [\#438](https://github.com/uTox/uTox/issues/438) - FIX headers, and includes. [\#436](https://github.com/uTox/uTox/issues/436) - dpi bug [\#427](https://github.com/uTox/uTox/issues/427) - uTow not starting ? \(Unable to get saved avatar from disk for friend ?\) [\#418](https://github.com/uTox/uTox/issues/418) - uTox segfaults if the "end" key is pressed when the message input box is empty [\#417](https://github.com/uTox/uTox/issues/417) - Can't add friends to group. [\#416](https://github.com/uTox/uTox/issues/416) - startup regression \(reading config\) [\#413](https://github.com/uTox/uTox/issues/413) - Patch: utox w/xlib not reaping zombie procs from openurl\(\)/xdg-open [\#412](https://github.com/uTox/uTox/issues/412) - Multiple Instances running causes conflict [\#407](https://github.com/uTox/uTox/issues/407) - Windows version uTox compile problems. [\#405](https://github.com/uTox/uTox/issues/405) - Auto accept files portable mode [\#402](https://github.com/uTox/uTox/issues/402) - DPI font size bug [\#399](https://github.com/uTox/uTox/issues/399) - User Interface Settings: Non-english labels overlap [\#346](https://github.com/uTox/uTox/issues/346) - send typing notification not remembered [\#320](https://github.com/uTox/uTox/issues/320) - Group chats do not call notify\(\) to generate a platform specific notification. [\#272](https://github.com/uTox/uTox/issues/272) - Add support for the ToxMe https lookup api [\#145](https://github.com/uTox/uTox/issues/145) **Merged pull requests:** - v0.11.0 to master [\#540](https://github.com/uTox/uTox/pull/540) ([GrayHatter](https://github.com/GrayHatter)) - Version 0.9.8 =\> 0.11.0 [\#539](https://github.com/uTox/uTox/pull/539) ([GrayHatter](https://github.com/GrayHatter)) - Fix autoaccept [\#538](https://github.com/uTox/uTox/pull/538) ([endoffile78](https://github.com/endoffile78)) - Fix saving and loading of friend's metadata [\#536](https://github.com/uTox/uTox/pull/536) ([GrayHatter](https://github.com/GrayHatter)) - Minor refactor to split off the uTox code from the Toxcore code [\#534](https://github.com/uTox/uTox/pull/534) ([GrayHatter](https://github.com/GrayHatter)) - Add more things to .editorconfig [\#533](https://github.com/uTox/uTox/pull/533) ([robinlinden](https://github.com/robinlinden)) - Fix warnings, cleanup, and refactoring. [\#532](https://github.com/uTox/uTox/pull/532) ([robinlinden](https://github.com/robinlinden)) - Fix chat logging [\#531](https://github.com/uTox/uTox/pull/531) ([robinlinden](https://github.com/robinlinden)) - Add .editorconfig [\#530](https://github.com/uTox/uTox/pull/530) ([endoffile78](https://github.com/endoffile78)) - Fix warnings [\#527](https://github.com/uTox/uTox/pull/527) ([endoffile78](https://github.com/endoffile78)) - Fix POSIX native\_get\_file. [\#526](https://github.com/uTox/uTox/pull/526) ([robinlinden](https://github.com/robinlinden)) - Refactor commands [\#524](https://github.com/uTox/uTox/pull/524) ([endoffile78](https://github.com/endoffile78)) - Remove avatar functions from main.c [\#522](https://github.com/uTox/uTox/pull/522) ([endoffile78](https://github.com/endoffile78)) - Add documentation to functions in main.h [\#521](https://github.com/uTox/uTox/pull/521) ([endoffile78](https://github.com/endoffile78)) - Merge branch [\#519](https://github.com/uTox/uTox/pull/519) ([endoffile78](https://github.com/endoffile78)) - Update BUILD.md [\#517](https://github.com/uTox/uTox/pull/517) ([cebe](https://github.com/cebe)) - Update .gitignore [\#514](https://github.com/uTox/uTox/pull/514) ([endoffile78](https://github.com/endoffile78)) - Add ability to change nospam [\#513](https://github.com/uTox/uTox/pull/513) ([endoffile78](https://github.com/endoffile78)) - Add xlib native\_get\_file option to delete file. [\#512](https://github.com/uTox/uTox/pull/512) ([robinlinden](https://github.com/robinlinden)) - Lots of native function things. [\#511](https://github.com/uTox/uTox/pull/511) ([robinlinden](https://github.com/robinlinden)) - Avatar refactor [\#510](https://github.com/uTox/uTox/pull/510) ([robinlinden](https://github.com/robinlinden)) - Better cmake && extern to avoid a segfault on windows [\#508](https://github.com/uTox/uTox/pull/508) ([GrayHatter](https://github.com/GrayHatter)) - Revert "Add debug option to CMakeLists.txt" [\#506](https://github.com/uTox/uTox/pull/506) ([endoffile78](https://github.com/endoffile78)) - Change type of nick in edits.c [\#505](https://github.com/uTox/uTox/pull/505) ([endoffile78](https://github.com/endoffile78)) - Fix warnings [\#504](https://github.com/uTox/uTox/pull/504) ([endoffile78](https://github.com/endoffile78)) - Add debug option to CMakeLists.txt [\#503](https://github.com/uTox/uTox/pull/503) ([endoffile78](https://github.com/endoffile78)) - Fixed order of things in the A&V settings. [\#501](https://github.com/uTox/uTox/pull/501) ([robinlinden](https://github.com/robinlinden)) - OSX building and travis [\#500](https://github.com/uTox/uTox/pull/500) ([endoffile78](https://github.com/endoffile78)) - Fix groupchat names [\#499](https://github.com/uTox/uTox/pull/499) ([robinlinden](https://github.com/robinlinden)) - Add install rules to CMakeLists.txt [\#496](https://github.com/uTox/uTox/pull/496) ([endoffile78](https://github.com/endoffile78)) - Clean up and refactor UI code [\#492](https://github.com/uTox/uTox/pull/492) ([robinlinden](https://github.com/robinlinden)) - Added Native file functions to Windows [\#490](https://github.com/uTox/uTox/pull/490) ([GrayHatter](https://github.com/GrayHatter)) - Update src/cocoa/main.m to use new debug enum names [\#489](https://github.com/uTox/uTox/pull/489) ([robinlinden](https://github.com/robinlinden)) - fix the icons in windows [\#488](https://github.com/uTox/uTox/pull/488) ([GrayHatter](https://github.com/GrayHatter)) - Fixed broken filter friend button [\#486](https://github.com/uTox/uTox/pull/486) ([GrayHatter](https://github.com/GrayHatter)) - fix travis error on prebuild [\#485](https://github.com/uTox/uTox/pull/485) ([GrayHatter](https://github.com/GrayHatter)) - Fix Buttons on windows [\#484](https://github.com/uTox/uTox/pull/484) ([GrayHatter](https://github.com/GrayHatter)) - UI code cleanup [\#483](https://github.com/uTox/uTox/pull/483) ([robinlinden](https://github.com/robinlinden)) - Clicking "show profile password" button hides it. [\#482](https://github.com/uTox/uTox/pull/482) ([robinlinden](https://github.com/robinlinden)) - Fix avatars [\#481](https://github.com/uTox/uTox/pull/481) ([endoffile78](https://github.com/endoffile78)) - Fix segfault in image\_free [\#480](https://github.com/uTox/uTox/pull/480) ([endoffile78](https://github.com/endoffile78)) - Fixing more warnings [\#479](https://github.com/uTox/uTox/pull/479) ([robinlinden](https://github.com/robinlinden)) - Stop utox from segfaulting [\#477](https://github.com/uTox/uTox/pull/477) ([endoffile78](https://github.com/endoffile78)) - Update BUILD.md and INSTALL.md [\#476](https://github.com/uTox/uTox/pull/476) ([endoffile78](https://github.com/endoffile78)) - Fixing warnings [\#475](https://github.com/uTox/uTox/pull/475) ([robinlinden](https://github.com/robinlinden)) - Fix CMake and Travis on Win [\#470](https://github.com/uTox/uTox/pull/470) ([GrayHatter](https://github.com/GrayHatter)) - Removed superfluous ../main.h includes in general and xlib files [\#468](https://github.com/uTox/uTox/pull/468) ([robinlinden](https://github.com/robinlinden)) - Limited width of audio-video tab in settings. \(fixes \#441\) [\#467](https://github.com/uTox/uTox/pull/467) ([robinlinden](https://github.com/robinlinden)) - Replace native\_load\_data and native\_save\_data with native\_get\_file [\#466](https://github.com/uTox/uTox/pull/466) ([endoffile78](https://github.com/endoffile78)) - Ignore cmake files [\#464](https://github.com/uTox/uTox/pull/464) ([endoffile78](https://github.com/endoffile78)) - Remove language strings not in use. [\#463](https://github.com/uTox/uTox/pull/463) ([robinlinden](https://github.com/robinlinden)) - Add null checks after calloc and malloc [\#457](https://github.com/uTox/uTox/pull/457) ([endoffile78](https://github.com/endoffile78)) - Friend list now responds to mup \(from mdown\) [\#455](https://github.com/uTox/uTox/pull/455) ([GrayHatter](https://github.com/GrayHatter)) - On going Refactor [\#454](https://github.com/uTox/uTox/pull/454) ([GrayHatter](https://github.com/GrayHatter)) - Updated russian translation [\#451](https://github.com/uTox/uTox/pull/451) ([katyo](https://github.com/katyo)) - Updated changelog [\#447](https://github.com/uTox/uTox/pull/447) ([endoffile78](https://github.com/endoffile78)) - .travis Fix travis builds to work with the new toktok/toxcore [\#446](https://github.com/uTox/uTox/pull/446) ([GrayHatter](https://github.com/GrayHatter)) - Notify the user when a friend comes online and goes offline [\#444](https://github.com/uTox/uTox/pull/444) ([endoffile78](https://github.com/endoffile78)) - Update the manual page [\#443](https://github.com/uTox/uTox/pull/443) ([tsudoko](https://github.com/tsudoko)) - Add header guards [\#442](https://github.com/uTox/uTox/pull/442) ([endoffile78](https://github.com/endoffile78)) - Make Solarized themes selectable with --theme [\#432](https://github.com/uTox/uTox/pull/432) ([tsudoko](https://github.com/tsudoko)) - Use debug\_error\(\) for getopt errors [\#431](https://github.com/uTox/uTox/pull/431) ([tsudoko](https://github.com/tsudoko)) - Add invite command [\#430](https://github.com/uTox/uTox/pull/430) ([endoffile78](https://github.com/endoffile78)) - Make the "yes" icon not inverted [\#429](https://github.com/uTox/uTox/pull/429) ([tsudoko](https://github.com/tsudoko)) - Fix switches [\#426](https://github.com/uTox/uTox/pull/426) ([tsudoko](https://github.com/tsudoko)) - Fix disabled hover color in themes [\#425](https://github.com/uTox/uTox/pull/425) ([tsudoko](https://github.com/tsudoko)) - add Solarized colour schemes [\#423](https://github.com/uTox/uTox/pull/423) ([ninedotnine](https://github.com/ninedotnine)) - Update German translation [\#409](https://github.com/uTox/uTox/pull/409) ([sfan5](https://github.com/sfan5)) - Decline unwanted calls [\#404](https://github.com/uTox/uTox/pull/404) ([Encrypt](https://github.com/Encrypt)) ## [v0.9.8](https://github.com/uTox/uTox/tree/v0.9.8) (2016-07-29) [Full Changelog](https://github.com/uTox/uTox/compare/v0.9.7...v0.9.8) **Closed issues:** - Cross traffic between chat threads [\#401](https://github.com/uTox/uTox/issues/401) ## [v0.9.7](https://github.com/uTox/uTox/tree/v0.9.7) (2016-07-26) [Full Changelog](https://github.com/uTox/uTox/compare/v0.9.4...v0.9.7) **Closed issues:** - Very network inefficient [\#389](https://github.com/uTox/uTox/issues/389) - Very network inefficient [\#387](https://github.com/uTox/uTox/issues/387) - Offline messages - security [\#386](https://github.com/uTox/uTox/issues/386) - Chat text appears red when ending with \< [\#385](https://github.com/uTox/uTox/issues/385) - Corrupting history? [\#380](https://github.com/uTox/uTox/issues/380) - Avatar doesn't stick [\#375](https://github.com/uTox/uTox/issues/375) - translated strings cover others [\#373](https://github.com/uTox/uTox/issues/373) - properly handle non-multidevice nodes [\#371](https://github.com/uTox/uTox/issues/371) - Noise cancellation [\#363](https://github.com/uTox/uTox/issues/363) - Antox closes when sending file with UTOX. [\#361](https://github.com/uTox/uTox/issues/361) - profile import/export \(uTox portable\) [\#357](https://github.com/uTox/uTox/issues/357) - profile import \ export [\#355](https://github.com/uTox/uTox/issues/355) - Windows XP version error \("RegDeleteKeyValueW" and ADVAPI32.dll\) [\#349](https://github.com/uTox/uTox/issues/349) - Instant crash on start \(windows\) [\#343](https://github.com/uTox/uTox/issues/343) - Language settings: Always resets to default \(local language\) after restart [\#342](https://github.com/uTox/uTox/issues/342) - uTox \(v0.8.2 - 0.9.1\) automatically exit under Win10 [\#341](https://github.com/uTox/uTox/issues/341) - /tools/logs\_to\_plaintext.c needs to be updated [\#309](https://github.com/uTox/uTox/issues/309) **Merged pull requests:** - Converted all yes / no dropdowns to switches [\#397](https://github.com/uTox/uTox/pull/397) ([Encrypt](https://github.com/Encrypt)) - Update fr.h [\#391](https://github.com/uTox/uTox/pull/391) ([Encrypt](https://github.com/Encrypt)) - Update German translations [\#383](https://github.com/uTox/uTox/pull/383) ([sfan5](https://github.com/sfan5)) - Adding a changelog to the project. [\#382](https://github.com/uTox/uTox/pull/382) ([Encrypt](https://github.com/Encrypt)) - Added settings for group chats [\#378](https://github.com/uTox/uTox/pull/378) ([endoffile78](https://github.com/endoffile78)) - Update cygwin-compile.sh [\#374](https://github.com/uTox/uTox/pull/374) ([endoffile78](https://github.com/endoffile78)) - Add files created by editors to .gitignore [\#369](https://github.com/uTox/uTox/pull/369) ([endoffile78](https://github.com/endoffile78)) - ui.c new button for chat log export [\#367](https://github.com/uTox/uTox/pull/367) ([utoxxer](https://github.com/utoxxer)) - Chat log export button [\#366](https://github.com/uTox/uTox/pull/366) ([utoxxer](https://github.com/utoxxer)) - Update fr.h [\#365](https://github.com/uTox/uTox/pull/365) ([pthevenet](https://github.com/pthevenet)) - Re-introduced audio filtering [\#364](https://github.com/uTox/uTox/pull/364) ([Encrypt](https://github.com/Encrypt)) - Update German translation [\#360](https://github.com/uTox/uTox/pull/360) ([sfan5](https://github.com/sfan5)) - version typo fix [\#345](https://github.com/uTox/uTox/pull/345) ([felix-salfelder](https://github.com/felix-salfelder)) ## [v0.9.4](https://github.com/uTox/uTox/tree/v0.9.4) (2016-05-25) [Full Changelog](https://github.com/uTox/uTox/compare/v0.9.3...v0.9.4) **Closed issues:** - uTox not responding after it connects [\#334](https://github.com/uTox/uTox/issues/334) ## [v0.9.3](https://github.com/uTox/uTox/tree/v0.9.3) (2016-05-23) [Full Changelog](https://github.com/uTox/uTox/compare/v0.9.1...v0.9.3) **Closed issues:** - \[end\] key goes to end of input, not end of line [\#338](https://github.com/uTox/uTox/issues/338) - uTox crashes upon connecting to friend \(alpha 0.9.1 build downloaded tonight, immediate issue upon post update execution\) [\#337](https://github.com/uTox/uTox/issues/337) **Merged pull requests:** - Implement inline video in cocoa [\#340](https://github.com/uTox/uTox/pull/340) ([stal888](https://github.com/stal888)) ## [v0.9.1](https://github.com/uTox/uTox/tree/v0.9.1) (2016-05-21) [Full Changelog](https://github.com/uTox/uTox/compare/v0.9.0...v0.9.1) ## [v0.9.0](https://github.com/uTox/uTox/tree/v0.9.0) (2016-05-21) [Full Changelog](https://github.com/uTox/uTox/compare/v0.8.2...v0.9.0) **Closed issues:** - Opening links is broken [\#330](https://github.com/uTox/uTox/issues/330) - Add day changes to messages [\#327](https://github.com/uTox/uTox/issues/327) - The baloon is gone [\#319](https://github.com/uTox/uTox/issues/319) - Clicking/dragging empty space near a hyperlink opens it [\#318](https://github.com/uTox/uTox/issues/318) - Offline messages are delivered in wrong order [\#316](https://github.com/uTox/uTox/issues/316) - blue text and dark theme [\#315](https://github.com/uTox/uTox/issues/315) - Super small window on start [\#314](https://github.com/uTox/uTox/issues/314) - utox kills itself trying to malloc insane amount of memory at startup [\#313](https://github.com/uTox/uTox/issues/313) - Recent utox versions re-send entire message history every time a friend comes online [\#312](https://github.com/uTox/uTox/issues/312) - Updating to 0.8.1 causes broken message windows on first run [\#310](https://github.com/uTox/uTox/issues/310) - Groupchat window can't be scrolled in any way [\#298](https://github.com/uTox/uTox/issues/298) - Beep on new message. [\#233](https://github.com/uTox/uTox/issues/233) - DPI UI error in Win Vista x64 [\#224](https://github.com/uTox/uTox/issues/224) - utox hogs the first and current sound cards all the time [\#223](https://github.com/uTox/uTox/issues/223) - Switching video to "none" while previewing confuses utox [\#221](https://github.com/uTox/uTox/issues/221) - when got a message, uTox has no tip audio, how to fix? [\#207](https://github.com/uTox/uTox/issues/207) - Offline message [\#195](https://github.com/uTox/uTox/issues/195) - uTox re-encodes PNG files when setting an avatar [\#179](https://github.com/uTox/uTox/issues/179) - uTox does not compile in Gentoo [\#164](https://github.com/uTox/uTox/issues/164) - SegFault on Connected to DHT [\#159](https://github.com/uTox/uTox/issues/159) - Allow switching between audio only/video call without having to restart the call [\#95](https://github.com/uTox/uTox/issues/95) - Feature: Showing full date in message log when it's a different day [\#65](https://github.com/uTox/uTox/issues/65) **Merged pull requests:** - Version v0.9.0 SRSLY? [\#333](https://github.com/uTox/uTox/pull/333) ([GrayHatter](https://github.com/GrayHatter)) - changed dark theme pending message color for better contrast [\#317](https://github.com/uTox/uTox/pull/317) ([cebe](https://github.com/cebe)) ## [v0.8.2](https://github.com/uTox/uTox/tree/v0.8.2) (2016-05-06) [Full Changelog](https://github.com/uTox/uTox/compare/v0.8.1...v0.8.2) **Closed issues:** - eye-tearing antialiased font [\#311](https://github.com/uTox/uTox/issues/311) - Version 0.8.1 doesn't always give flash alert or message bubble to alert new message [\#307](https://github.com/uTox/uTox/issues/307) - Text selection in groupchats is broken [\#305](https://github.com/uTox/uTox/issues/305) - Names aren't displayed in groupchats [\#297](https://github.com/uTox/uTox/issues/297) - Bugs with non-Latin filenames [\#291](https://github.com/uTox/uTox/issues/291) - Unable to initiate Group Chats [\#255](https://github.com/uTox/uTox/issues/255) - message notifications no longer work on linux [\#205](https://github.com/uTox/uTox/issues/205) - uTox tox save reverting to a version from months back [\#202](https://github.com/uTox/uTox/issues/202) - File transfer icon looks bad [\#127](https://github.com/uTox/uTox/issues/127) - UI looks bad on some DPI settings [\#126](https://github.com/uTox/uTox/issues/126) - Username doesn't become blue when using /me in group chat [\#58](https://github.com/uTox/uTox/issues/58) **Merged pull requests:** - Update German translation [\#308](https://github.com/uTox/uTox/pull/308) ([sfan5](https://github.com/sfan5)) - Messages queue [\#295](https://github.com/uTox/uTox/pull/295) ([GrayHatter](https://github.com/GrayHatter)) ## [v0.8.1](https://github.com/uTox/uTox/tree/v0.8.1) (2016-04-29) [Full Changelog](https://github.com/uTox/uTox/compare/v0.8.0...v0.8.1) **Closed issues:** - 0.8.0 Initiating file transfer crashes utox [\#303](https://github.com/uTox/uTox/issues/303) - uTox crashes when attempting to send a file [\#302](https://github.com/uTox/uTox/issues/302) - Group chats [\#293](https://github.com/uTox/uTox/issues/293) - about double release post [\#292](https://github.com/uTox/uTox/issues/292) - Cannot set profile picture [\#273](https://github.com/uTox/uTox/issues/273) - uTox GUI freeze [\#259](https://github.com/uTox/uTox/issues/259) - Defunct video input device selection [\#198](https://github.com/uTox/uTox/issues/198) - Messages.c Refactor [\#128](https://github.com/uTox/uTox/issues/128) - \[Feature request\] Meta-contacts \(unite/group several contacs in one\) [\#97](https://github.com/uTox/uTox/issues/97) - guide fo utox compilation on Tails [\#80](https://github.com/uTox/uTox/issues/80) - Implement Tox Client Standard concerning the avatars [\#45](https://github.com/uTox/uTox/issues/45) - Save Auto Accept settings for uTox [\#30](https://github.com/uTox/uTox/issues/30) **Merged pull requests:** - fix text color in selected group icon [\#306](https://github.com/uTox/uTox/pull/306) ([cebe](https://github.com/cebe)) - added user icons for mini roster [\#304](https://github.com/uTox/uTox/pull/304) ([cebe](https://github.com/cebe)) - re-enable proxy support [\#301](https://github.com/uTox/uTox/pull/301) ([GrayHatter](https://github.com/GrayHatter)) - Mini friends list [\#299](https://github.com/uTox/uTox/pull/299) ([GrayHatter](https://github.com/GrayHatter)) - Group icon [\#296](https://github.com/uTox/uTox/pull/296) ([GrayHatter](https://github.com/GrayHatter)) - copy log functions to cocoa [\#294](https://github.com/uTox/uTox/pull/294) ([stal888](https://github.com/stal888)) ## [v0.8.0](https://github.com/uTox/uTox/tree/v0.8.0) (2016-04-20) [Full Changelog](https://github.com/uTox/uTox/compare/v0.7.0...v0.8.0) **Closed issues:** - OSX: resizing window too small [\#289](https://github.com/uTox/uTox/issues/289) - Preferences on Mac does nothing [\#287](https://github.com/uTox/uTox/issues/287) - tox: URLs not Getting Parsed [\#286](https://github.com/uTox/uTox/issues/286) - Windows 10 system setting profile password crash [\#280](https://github.com/uTox/uTox/issues/280) - Update utox.org statement. [\#278](https://github.com/uTox/uTox/issues/278) - Release version 0.7.0 for linux not available: The specified key does not exist. [\#277](https://github.com/uTox/uTox/issues/277) - Avatar size check broken [\#262](https://github.com/uTox/uTox/issues/262) - A new Chinese Translate [\#261](https://github.com/uTox/uTox/issues/261) - uTox 0.7.0 OSX - cannot start [\#258](https://github.com/uTox/uTox/issues/258) - Tiny interface in android [\#256](https://github.com/uTox/uTox/issues/256) - uTox is raiding a SBIE2314 error if started in Sandboxie Sandbox [\#253](https://github.com/uTox/uTox/issues/253) - Old ID disappears [\#252](https://github.com/uTox/uTox/issues/252) - dual webcam broken [\#200](https://github.com/uTox/uTox/issues/200) - DPI setting ignored at start [\#199](https://github.com/uTox/uTox/issues/199) - profile seg fault after update [\#197](https://github.com/uTox/uTox/issues/197) - re-add alt+num on windows [\#192](https://github.com/uTox/uTox/issues/192) - Client Crashing Resets all Settings to Default on next Start \(WIN-10\) [\#175](https://github.com/uTox/uTox/issues/175) - uTox package in Debian Jessie repo - gone [\#161](https://github.com/uTox/uTox/issues/161) - Segfault [\#158](https://github.com/uTox/uTox/issues/158) - \[Feature request\] Font size settings [\#114](https://github.com/uTox/uTox/issues/114) **Merged pull requests:** - cocoa: add tox: url handling and limit window size [\#290](https://github.com/uTox/uTox/pull/290) ([stal888](https://github.com/stal888)) - fix SYSROOT default setting [\#288](https://github.com/uTox/uTox/pull/288) ([felix-salfelder](https://github.com/felix-salfelder)) - Prefix cocoa folder with src/ [\#285](https://github.com/uTox/uTox/pull/285) ([GrayHatter](https://github.com/GrayHatter)) - android build [\#283](https://github.com/uTox/uTox/pull/283) ([felix-salfelder](https://github.com/felix-salfelder)) - attempting to make tools/android-build.sh work \(WIP\) [\#279](https://github.com/uTox/uTox/pull/279) ([felix-salfelder](https://github.com/felix-salfelder)) - fix some bugs [\#274](https://github.com/uTox/uTox/pull/274) ([stal888](https://github.com/stal888)) - Update utox.desktop [\#266](https://github.com/uTox/uTox/pull/266) ([cebe](https://github.com/cebe)) - Update tw.h [\#264](https://github.com/uTox/uTox/pull/264) ([lineteen](https://github.com/lineteen)) - Update cn.h [\#263](https://github.com/uTox/uTox/pull/263) ([lineteen](https://github.com/lineteen)) - Update German translations [\#260](https://github.com/uTox/uTox/pull/260) ([sfan5](https://github.com/sfan5)) - Added Russian transation for the pop-up comment of the shortcut [\#257](https://github.com/uTox/uTox/pull/257) ([TotalCaesar659](https://github.com/TotalCaesar659)) - consistent usage of checkinstall [\#249](https://github.com/uTox/uTox/pull/249) ([stemd](https://github.com/stemd)) - Fix application crash with variable length frame size webcams. [\#152](https://github.com/uTox/uTox/pull/152) ([abbat](https://github.com/abbat)) ## [v0.7.0](https://github.com/uTox/uTox/tree/v0.7.0) (2016-03-21) [Full Changelog](https://github.com/uTox/uTox/compare/v0.6.1...v0.7.0) **Closed issues:** - UTox for Windows: Screen reader accessibility [\#246](https://github.com/uTox/uTox/issues/246) - No longer able to set avatar image [\#245](https://github.com/uTox/uTox/issues/245) - Feedback from another cross-platform test... [\#244](https://github.com/uTox/uTox/issues/244) - Calls have no audio, Call buttons not functioning [\#243](https://github.com/uTox/uTox/issues/243) - Bottom elements on the friend panel are inactive while panel does not fit in the window [\#242](https://github.com/uTox/uTox/issues/242) - Scrolling with the mouse wheel is very slow [\#237](https://github.com/uTox/uTox/issues/237) - 1-pixel wide tray icon [\#235](https://github.com/uTox/uTox/issues/235) - error: ‘FILE\_TRANSFER’ has no member named ‘filenumber’ [\#234](https://github.com/uTox/uTox/issues/234) - Error making call xlib \(utox Alpha version 0.6.1\) [\#230](https://github.com/uTox/uTox/issues/230) - utox.org v. tox.chat [\#229](https://github.com/uTox/uTox/issues/229) - Cross-compile script for Windows is outdated. [\#226](https://github.com/uTox/uTox/issues/226) - Can not cancel any call [\#222](https://github.com/uTox/uTox/issues/222) - Switching video input from desktop to "none" crashes [\#210](https://github.com/uTox/uTox/issues/210) - Profile / ID disappearing [\#188](https://github.com/uTox/uTox/issues/188) - Some issues [\#186](https://github.com/uTox/uTox/issues/186) - WebRTC built into uTOX [\#176](https://github.com/uTox/uTox/issues/176) - AltGr+number must not switch tab [\#157](https://github.com/uTox/uTox/issues/157) - preview window does not close if opening video device failed [\#56](https://github.com/uTox/uTox/issues/56) - Some UI items are too wide [\#3](https://github.com/uTox/uTox/issues/3) **Merged pull requests:** - Reduce warnings [\#248](https://github.com/uTox/uTox/pull/248) ([benwaffle](https://github.com/benwaffle)) - Make installation process more tunable \(adjust pkg-config name and datarootdir\) [\#247](https://github.com/uTox/uTox/pull/247) ([ony](https://github.com/ony)) - Fix for issue \#237 mouse wheel scroll is very slow [\#241](https://github.com/uTox/uTox/pull/241) ([master-passeli](https://github.com/master-passeli)) - Fix for issue 230, Error making call [\#240](https://github.com/uTox/uTox/pull/240) ([master-passeli](https://github.com/master-passeli)) - updated Ukrainian translation [\#228](https://github.com/uTox/uTox/pull/228) ([yalvex](https://github.com/yalvex)) - Update of Polish translation [\#225](https://github.com/uTox/uTox/pull/225) ([dagashiya](https://github.com/dagashiya)) - Fixes file save dialog title [\#220](https://github.com/uTox/uTox/pull/220) ([cebe](https://github.com/cebe)) ## [v0.6.1](https://github.com/uTox/uTox/tree/v0.6.1) (2016-02-29) [Full Changelog](https://github.com/uTox/uTox/compare/v0.6.0...v0.6.1) **Closed issues:** - Problem to close the preview camera [\#218](https://github.com/uTox/uTox/issues/218) - Unable to select avatar in linux client [\#215](https://github.com/uTox/uTox/issues/215) - Password "show" button has wrong tooltip [\#209](https://github.com/uTox/uTox/issues/209) - Can't accept calls: uTox: Error trying to toxav\_answer error \(1\) [\#208](https://github.com/uTox/uTox/issues/208) - Tooltip for the settings button is "Add New Contact" on start [\#90](https://github.com/uTox/uTox/issues/90) - \[HELP NEEDED\] README.md is out of date. [\#37](https://github.com/uTox/uTox/issues/37) - Adding friends/switching to settings requires too many clicks [\#20](https://github.com/uTox/uTox/issues/20) **Merged pull requests:** - GTK: fix avatar chooser [\#216](https://github.com/uTox/uTox/pull/216) ([benwaffle](https://github.com/benwaffle)) - Fix dmg script [\#214](https://github.com/uTox/uTox/pull/214) ([RubenRocha](https://github.com/RubenRocha)) ## [v0.6.0](https://github.com/uTox/uTox/tree/v0.6.0) (2016-02-21) [Full Changelog](https://github.com/uTox/uTox/compare/v0.5.1...v0.6.0) **Closed issues:** - No ringtone? [\#189](https://github.com/uTox/uTox/issues/189) - TOX ID disappears in windows [\#187](https://github.com/uTox/uTox/issues/187) - sending a screen capture from utox to utox does not ask for acceptance [\#174](https://github.com/uTox/uTox/issues/174) - Screen Capture Not Working on Dual Monitors [\#172](https://github.com/uTox/uTox/issues/172) - Closing client should minimize to taskbar to avoid clutter [\#168](https://github.com/uTox/uTox/issues/168) - How to compile uTox in VS [\#151](https://github.com/uTox/uTox/issues/151) - UTox win64-0.5.0 [\#149](https://github.com/uTox/uTox/issues/149) - use getopt to parse args [\#142](https://github.com/uTox/uTox/issues/142) - uTox password security aspects [\#130](https://github.com/uTox/uTox/issues/130) - Old "Normal" DPI is at 90% [\#125](https://github.com/uTox/uTox/issues/125) - uTox starts with extremely low DPI and increases it with each new startup [\#124](https://github.com/uTox/uTox/issues/124) - Tooltip in system tray is always colon [\#115](https://github.com/uTox/uTox/issues/115) - 100% cpu load on video call. [\#67](https://github.com/uTox/uTox/issues/67) - uTox doesn't support jpg avatars [\#1](https://github.com/uTox/uTox/issues/1) **Merged pull requests:** - Av refactor \[DO NOT MERGE\] [\#196](https://github.com/uTox/uTox/pull/196) ([GrayHatter](https://github.com/GrayHatter)) - fixed \#187 [\#190](https://github.com/uTox/uTox/pull/190) ([ingvar1995](https://github.com/ingvar1995)) - Add an error check to /sendfile command [\#183](https://github.com/uTox/uTox/pull/183) ([elgis](https://github.com/elgis)) - fixes \#125 [\#177](https://github.com/uTox/uTox/pull/177) ([danielisaksen](https://github.com/danielisaksen)) - Fix GTK error [\#170](https://github.com/uTox/uTox/pull/170) ([benwaffle](https://github.com/benwaffle)) - Fixed some bugs [\#166](https://github.com/uTox/uTox/pull/166) ([ingvar1995](https://github.com/ingvar1995)) - Support jpg avatars [\#165](https://github.com/uTox/uTox/pull/165) ([benwaffle](https://github.com/benwaffle)) - Fixed \#151 [\#155](https://github.com/uTox/uTox/pull/155) ([linuxraspilxc](https://github.com/linuxraspilxc)) ## [v0.5.1](https://github.com/uTox/uTox/tree/v0.5.1) (2016-01-05) [Full Changelog](https://github.com/uTox/uTox/compare/v0.5.0...v0.5.1) **Closed issues:** - Adding my best friend failed [\#147](https://github.com/uTox/uTox/issues/147) - DPI says BUG PLEASE REPORT [\#138](https://github.com/uTox/uTox/issues/138) - Android issues [\#131](https://github.com/uTox/uTox/issues/131) - Add Esperanto translation [\#113](https://github.com/uTox/uTox/issues/113) - Makefile should build changed files [\#110](https://github.com/uTox/uTox/issues/110) - uTox crash on start [\#109](https://github.com/uTox/uTox/issues/109) - OS X: Unicode status message or display name causes crash on launch [\#102](https://github.com/uTox/uTox/issues/102) - GTK file chooser doesn't preview images [\#93](https://github.com/uTox/uTox/issues/93) - Video quality / compression [\#23](https://github.com/uTox/uTox/issues/23) - white line instead of system tray icon in MATE [\#16](https://github.com/uTox/uTox/issues/16) **Merged pull requests:** - skel for windows travis support [\#148](https://github.com/uTox/uTox/pull/148) ([GrayHatter](https://github.com/GrayHatter)) - Some users don't use encryption [\#141](https://github.com/uTox/uTox/pull/141) ([benwaffle](https://github.com/benwaffle)) - Make lang & str counts a bit simpler [\#140](https://github.com/uTox/uTox/pull/140) ([benwaffle](https://github.com/benwaffle)) - Implement some per-friend settings [\#137](https://github.com/uTox/uTox/pull/137) ([tsudoko](https://github.com/tsudoko)) - Fix compilation on arm [\#123](https://github.com/uTox/uTox/pull/123) ([doughdemon](https://github.com/doughdemon)) - Better fix for the font crash [\#122](https://github.com/uTox/uTox/pull/122) ([benwaffle](https://github.com/benwaffle)) - Fix crash with fonts [\#121](https://github.com/uTox/uTox/pull/121) ([benwaffle](https://github.com/benwaffle)) - Gtk file chooser preview [\#120](https://github.com/uTox/uTox/pull/120) ([benwaffle](https://github.com/benwaffle)) - Linux makefile [\#119](https://github.com/uTox/uTox/pull/119) ([benwaffle](https://github.com/benwaffle)) - Remove \_\_APPLE\_\_ checks in xlib/ [\#118](https://github.com/uTox/uTox/pull/118) ([benwaffle](https://github.com/benwaffle)) - Add Esperanto translation from \#113 [\#116](https://github.com/uTox/uTox/pull/116) ([tsudoko](https://github.com/tsudoko)) - Added full build instructions for ubuntu [\#112](https://github.com/uTox/uTox/pull/112) ([linuxraspilxc](https://github.com/linuxraspilxc)) - fixed "Online contacts" being called "All" [\#106](https://github.com/uTox/uTox/pull/106) ([Doom032](https://github.com/Doom032)) - Travis src fix [\#104](https://github.com/uTox/uTox/pull/104) ([GrayHatter](https://github.com/GrayHatter)) - Update BUILD.md to refer to COCOA.md [\#103](https://github.com/uTox/uTox/pull/103) ([cybercatgurrl](https://github.com/cybercatgurrl)) - Master [\#101](https://github.com/uTox/uTox/pull/101) ([GrayHatter](https://github.com/GrayHatter)) ## [v0.5.0](https://github.com/uTox/uTox/tree/v0.5.0) (2015-12-20) [Full Changelog](https://github.com/uTox/uTox/compare/v0.4.6...v0.5.0) ## [v0.4.6](https://github.com/uTox/uTox/tree/v0.4.6) (2015-12-20) [Full Changelog](https://github.com/uTox/uTox/compare/v0.4.5...v0.4.6) **Closed issues:** - Friends list context menu behaves weird after right-clicking the left side of the friends list [\#99](https://github.com/uTox/uTox/issues/99) - There's no way to remove the avatar [\#98](https://github.com/uTox/uTox/issues/98) - Groupchat context menu items are broken [\#92](https://github.com/uTox/uTox/issues/92) - There's no way to create a new groupchat [\#91](https://github.com/uTox/uTox/issues/91) - OS X: Typing notification too low [\#87](https://github.com/uTox/uTox/issues/87) - OS X: uTox crashes when typing [\#86](https://github.com/uTox/uTox/issues/86) - Make file doesn't work on Windows [\#73](https://github.com/uTox/uTox/issues/73) - b\_name and b\_statusmsg too wide on Linux [\#64](https://github.com/uTox/uTox/issues/64) - File transfer layout glitch [\#57](https://github.com/uTox/uTox/issues/57) - µTox crashes when trying to use proxy with bad proxy settings [\#54](https://github.com/uTox/uTox/issues/54) - Typing notification is covered by input field area. [\#26](https://github.com/uTox/uTox/issues/26) - Friends list header is 1px wider than the rest of the friends list [\#17](https://github.com/uTox/uTox/issues/17) **Merged pull requests:** - fix minor memory leak [\#89](https://github.com/uTox/uTox/pull/89) ([stal888](https://github.com/stal888)) - GTK: switch to GTK3, use constants, and organize code [\#88](https://github.com/uTox/uTox/pull/88) ([benwaffle](https://github.com/benwaffle)) - Add encrypt save file support. [\#85](https://github.com/uTox/uTox/pull/85) ([GrayHatter](https://github.com/GrayHatter)) ## [v0.4.5](https://github.com/uTox/uTox/tree/v0.4.5) (2015-12-09) [Full Changelog](https://github.com/uTox/uTox/compare/v0.4.4develop...v0.4.5) **Closed issues:** - Can not add friend when settings are openend [\#83](https://github.com/uTox/uTox/issues/83) **Merged pull requests:** - adjust makefile to recompile on header change [\#77](https://github.com/uTox/uTox/pull/77) ([cebe](https://github.com/cebe)) - New Interface changes because stal hate's the current. [\#43](https://github.com/uTox/uTox/pull/43) ([GrayHatter](https://github.com/GrayHatter)) ## [v0.4.4develop](https://github.com/uTox/uTox/tree/v0.4.4develop) (2015-12-08) [Full Changelog](https://github.com/uTox/uTox/compare/v0.4.4...v0.4.4develop) **Closed issues:** - Feature: OS X video window resizing [\#74](https://github.com/uTox/uTox/issues/74) - bug combining greentext and redtext [\#72](https://github.com/uTox/uTox/issues/72) - \[HELP NEEDED\] fix .travis.yaml to check build of uTox for PRs [\#68](https://github.com/uTox/uTox/issues/68) - Keyboard shortcuts to switch between friends [\#51](https://github.com/uTox/uTox/issues/51) - Broken custom theme support. [\#28](https://github.com/uTox/uTox/issues/28) - Scale cursor with DPI [\#18](https://github.com/uTox/uTox/issues/18) - Contact search box doesn't search contact aliases. [\#5](https://github.com/uTox/uTox/issues/5) **Merged pull requests:** - New file transfer ui [\#81](https://github.com/uTox/uTox/pull/81) ([stal888](https://github.com/stal888)) - cocoa: make video window resizable [\#76](https://github.com/uTox/uTox/pull/76) ([stal888](https://github.com/stal888)) - use blobs from build.tox.chat [\#71](https://github.com/uTox/uTox/pull/71) ([stal888](https://github.com/stal888)) - fix travis [\#70](https://github.com/uTox/uTox/pull/70) ([stal888](https://github.com/stal888)) - Update cn.h [\#69](https://github.com/uTox/uTox/pull/69) ([giwhub](https://github.com/giwhub)) - updated manpage and added --help option to xlib main.c [\#66](https://github.com/uTox/uTox/pull/66) ([cebe](https://github.com/cebe)) - Give the filter button more vertical space [\#63](https://github.com/uTox/uTox/pull/63) ([tsudoko](https://github.com/tsudoko)) - Add missing COLOR\_REDTEXT entry to the color table [\#62](https://github.com/uTox/uTox/pull/62) ([tsudoko](https://github.com/tsudoko)) - Move text from the search field to the ID field after clicking "add" instead of syncing it between both fields [\#61](https://github.com/uTox/uTox/pull/61) ([tsudoko](https://github.com/tsudoko)) - remove SelectionRequest debug message [\#60](https://github.com/uTox/uTox/pull/60) ([Doom032](https://github.com/Doom032)) - let search box search aliases as well [\#59](https://github.com/uTox/uTox/pull/59) ([Doom032](https://github.com/Doom032)) - do not block video device when video is not used [\#52](https://github.com/uTox/uTox/pull/52) ([cebe](https://github.com/cebe)) - refactor list searching & filtering, and add previous/next tab shortcuts on Linux and Windows [\#47](https://github.com/uTox/uTox/pull/47) ([Doom032](https://github.com/Doom032)) - Enable auto changing bitrate for uTox video [\#42](https://github.com/uTox/uTox/pull/42) ([GrayHatter](https://github.com/GrayHatter)) - Add bg and icon to linux tray icon [\#14](https://github.com/uTox/uTox/pull/14) ([GrayHatter](https://github.com/GrayHatter)) ## [v0.4.4](https://github.com/uTox/uTox/tree/v0.4.4) (2015-11-19) [Full Changelog](https://github.com/uTox/uTox/compare/v0.4.2...v0.4.4) **Closed issues:** - Initial window paint relies on racy window manager resizing to work properly [\#40](https://github.com/uTox/uTox/issues/40) - Avatar is not being sent when there's an ongoing file transfer to contact [\#39](https://github.com/uTox/uTox/issues/39) - TRUE is not defined in xlib/main.c and others [\#38](https://github.com/uTox/uTox/issues/38) - Ctrl+A not working if caps lock is on [\#35](https://github.com/uTox/uTox/issues/35) **Merged pull requests:** - Add & fix some tooltips, slight cleanup of UI strings [\#53](https://github.com/uTox/uTox/pull/53) ([Doom032](https://github.com/Doom032)) - Issue 35 [\#50](https://github.com/uTox/uTox/pull/50) ([GrayHatter](https://github.com/GrayHatter)) - text changes [\#49](https://github.com/uTox/uTox/pull/49) ([stal888](https://github.com/stal888)) - fixed LC\_ALL not being looked at on xlib [\#48](https://github.com/uTox/uTox/pull/48) ([Doom032](https://github.com/Doom032)) - load widow sizes from save in xlib [\#41](https://github.com/uTox/uTox/pull/41) ([GrayHatter](https://github.com/GrayHatter)) - Fix Build Errors and Warnings. [\#36](https://github.com/uTox/uTox/pull/36) ([lluixhi](https://github.com/lluixhi)) - fixed not losing focus of edit\_msg when clicking the messages panel [\#33](https://github.com/uTox/uTox/pull/33) ([Doom032](https://github.com/Doom032)) ## [v0.4.2](https://github.com/uTox/uTox/tree/v0.4.2) (2015-11-03) [Full Changelog](https://github.com/uTox/uTox/compare/v0.3.2...v0.4.2) **Merged pull requests:** - Develop into master [\#25](https://github.com/uTox/uTox/pull/25) ([GrayHatter](https://github.com/GrayHatter)) - fix osx bugs [\#24](https://github.com/uTox/uTox/pull/24) ([stal888](https://github.com/stal888)) - Allow adding LDFLAGS from env variable [\#21](https://github.com/uTox/uTox/pull/21) ([benwaffle](https://github.com/benwaffle)) - ToxAV new api. [\#15](https://github.com/uTox/uTox/pull/15) ([GrayHatter](https://github.com/GrayHatter)) - build fixes for OS X 10.9 [\#11](https://github.com/uTox/uTox/pull/11) ([soyersoyer](https://github.com/soyersoyer)) - plug memory leak [\#10](https://github.com/uTox/uTox/pull/10) ([benwaffle](https://github.com/benwaffle)) - tweaks to de translation [\#9](https://github.com/uTox/uTox/pull/9) ([aaannndddyyy](https://github.com/aaannndddyyy)) - tweaks to Spanish translation [\#7](https://github.com/uTox/uTox/pull/7) ([aaannndddyyy](https://github.com/aaannndddyyy)) - Get rid of empty space left after the transfer button [\#4](https://github.com/uTox/uTox/pull/4) ([tsudoko](https://github.com/tsudoko)) - Reduce spacing between bars in the hamburger menu button [\#2](https://github.com/uTox/uTox/pull/2) ([tsudoko](https://github.com/tsudoko)) ## [v0.3.2](https://github.com/uTox/uTox/tree/v0.3.2) (2015-06-07) [Full Changelog](https://github.com/uTox/uTox/compare/v0.3.1...v0.3.2) ## [v0.3.1](https://github.com/uTox/uTox/tree/v0.3.1) (2015-05-31) [Full Changelog](https://github.com/uTox/uTox/compare/v0.3...v0.3.1) ## [v0.3](https://github.com/uTox/uTox/tree/v0.3) (2015-05-18) [Full Changelog](https://github.com/uTox/uTox/compare/v0.2.s...v0.3) ## [v0.2.s](https://github.com/uTox/uTox/tree/v0.2.s) (2015-05-14) [Full Changelog](https://github.com/uTox/uTox/compare/v0.2.r...v0.2.s) ## [v0.2.r](https://github.com/uTox/uTox/tree/v0.2.r) (2015-05-08) [Full Changelog](https://github.com/uTox/uTox/compare/v0.2.q...v0.2.r) ## [v0.2.q](https://github.com/uTox/uTox/tree/v0.2.q) (2015-05-01) [Full Changelog](https://github.com/uTox/uTox/compare/v0.2.o...v0.2.q) ## [v0.2.o](https://github.com/uTox/uTox/tree/v0.2.o) (2015-03-11) [Full Changelog](https://github.com/uTox/uTox/compare/v0.2.n...v0.2.o) ## [v0.2.n](https://github.com/uTox/uTox/tree/v0.2.n) (2015-02-12) [Full Changelog](https://github.com/uTox/uTox/compare/v0.2.m...v0.2.n) ## [v0.2.m](https://github.com/uTox/uTox/tree/v0.2.m) (2015-02-05) [Full Changelog](https://github.com/uTox/uTox/compare/v0.2.l...v0.2.m) ## [v0.2.l](https://github.com/uTox/uTox/tree/v0.2.l) (2015-01-30) [Full Changelog](https://github.com/uTox/uTox/compare/v0.2.k...v0.2.l) ## [v0.2.k](https://github.com/uTox/uTox/tree/v0.2.k) (2015-01-28) \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*uTox-0.17.1/CMakeLists.txt000066400000000000000000000332411354126257400153130ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.2) project(uTox LANGUAGES C) ##################### ## Project Metadata # ##################### set(PROJECT_VERSION_MAJOR "0") set(PROJECT_VERSION_MINOR "17") set(PROJECT_VERSION_PATCH "1") set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") set(PROJECT_COPYRIGHT "Copyleft 2019 uTox contributors. Some rights reserved.") string(TIMESTAMP BUILD_YEAR "%Y" UTC) string(TIMESTAMP BUILD_MONTH "%B" UTC) ######################## # Set helper-variables # ######################## # OS if(CYGWIN) # Cygwin thinks it's actually Linux. set(WIN32 TRUE) set(UNIX FALSE) endif() if(WIN32) set(WINDOWS TRUE) elseif(APPLE) if(CMAKE_SYSTEM_NAME MATCHES ".*MacOS.*") set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6 CACHE STRING "Minimum OS X deployment version") set(MACOSX TRUE) endif() elseif(UNIX) if(CMAKE_SYSTEM_NAME MATCHES ".*Linux") set(LINUX TRUE) elseif(CMAKE_SYSTEM_NAME MATCHES "kNetBSD.*|NetBSD.*") set(NETBSD TRUE) elseif(CMAKE_SYSTEM_NAME MATCHES "kFreeBSD.*|FreeBSD") set(FREEBSD TRUE) endif() endif() # 32 or 64 bit if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(ARCH_64 TRUE) else() set(ARCH_64 FALSE) endif() ############################# # System-dependent defaults # ############################# # Windows only compiles statically. if (WINDOWS) set(STATIC_DEFAULT ON) else() set(STATIC_DEFAULT OFF) endif() # Disable ASAN for macOS due to "AddressSanitizer: odr-violation: global". see #957 # Windows doesn't compile with asan enabled. if (APPLE OR WINDOWS) set(ASAN_DEFAULT OFF) else() set(ASAN_DEFAULT ON) endif() # ASAN causes uTox to be slower so do no use it for release builds if (CMAKE_BUILD_TYPE MATCHES "Release") set(ASAN_DEFAULT OFF) endif() ########### # Options # ########### option(UTOX_STATIC "Link uTox statically" ${STATIC_DEFAULT} ) option(TOXCORE_STATIC "Build uTox with the static version of Toxcore" ${STATIC_DEFAULT} ) option(ENABLE_ASAN "Enable Address Sanitizer on debug builds" ${ASAN_DEFAULT} ) option(ENABLE_TESTS "Whether to build test binaries (currently Unix-like OSes only)" ON ) option(ENABLE_WERROR "Error on Warning, whether to put -Werror flag to the compiler" OFF) option(ENABLE_FILTERAUDIO "Enable Filter Audio" ON ) option(ENABLE_AUTOUPDATE "Enable Auto-updater" OFF) option(ENABLE_LTO "Enable link time optimizations" ON ) ################################# # Include toolchain if required # ################################# if(WINDOWS AND NOT CROSS_COMPILING) include(cmake/win.cmake) if(ARCH_64) # Helping Cygwin out again.. set(WIN64 TRUE) endif() elseif(APPLE) include(cmake/macOS.cmake) endif() ####################################################################### # CMake Settings ####################################################################### set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") # make version available in C files configure_file(${uTox_SOURCE_DIR}/src/branding.h.in ${uTox_SOURCE_DIR}/src/branding.h) configure_file(${uTox_SOURCE_DIR}/src/cocoa/Info.plist.in ${uTox_SOURCE_DIR}/src/cocoa/Info.plist) configure_file(${uTox_SOURCE_DIR}/src/android/AndroidManifest.xml.in ${uTox_SOURCE_DIR}/src/android/AndroidManifest.xml) configure_file(${uTox_SOURCE_DIR}/src/utox.1.in ${uTox_SOURCE_DIR}/src/utox.1) if(${CMAKE_BUILD_TYPE} MATCHES Debug) execute_process(COMMAND git describe --abbrev=8 --dirty --always --tags OUTPUT_VARIABLE GIT_VERSION) string(REPLACE "\n" " " GIT_VERSION ${GIT_VERSION}) endif() ####################################################################### # C compiler flags ####################################################################### set(CMAKE_C_STANDARD 11) # this requires at least cmake 3.1 include(CheckCCompilerFlag) # add compiler flag for all build types function(add_cflag flag) string(REGEX REPLACE "[^a-zA-Z0-9_]" "_" var ${flag}) if(NOT DEFINED HAVE_C${var}) message(STATUS "checking for C compiler flag: ${flag}") endif() set(CMAKE_REQUIRED_QUIET TRUE) check_c_compiler_flag("${flag}" HAVE_C${var} QUIET) if(HAVE_C${var}) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}" PARENT_SCOPE) else() message(STATUS "Warning: Can't find flag ${flag}") endif() endfunction() # Grab environment CFLAGS. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} $ENV{CFLAGS}") # Warn on non-ISO C. #add_cflag("-pedantic") # throws a lot of warning, quite sure we do not want this at current state. ## Add all warning flags we can. add_cflag("-Wall") add_cflag("-Wextra") add_cflag("-Wpointer-arith") add_cflag("-Wimplicit-fallthrough=5") ## Warnings we don't tolerate add_cflag("-Werror=implicit-function-declaration") ## Warnings we don't care about add_cflag("-Wformat=0") add_cflag("-Wno-misleading-indentation") ## Everything Else add_cflag("-fno-strict-aliasing") add_cflag("-fPIC") ## Optimization Flags # Fix GNU stack if(CMAKE_C_COMPILER_ID MATCHES "GNU") # Have ld strip the symbols from Release and MinSizeRel build types. set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Os") set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} -Os -s") if(LINUX) # enable Link Time Optimization on gcc (linux only currently) # TODO someone should figure out how this works on windows, or we need to have gitlab-ci for GCC if(ENABLE_LTO) ## -flto is a flag that needs to exist at link time as well, # so we use some hacky save/restore to help cmake. set(SAVE_CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") set(CMAKE_REQUIRED_LIBRARIES "-flto") add_cflag("-flto") set(CMAKE_REQUIRED_LIBRARIES "${SAVE_CMAKE_REQUIRED_LIBRARIES}") endif() set(CMAKE_AR "gcc-ar") set(CMAKE_RANLIB "gcc-ranlib") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,noexecstack") endif() elseif(CMAKE_C_COMPILER_ID MATCHES "Clang") # Disable warning for `= { 0 }` in Clang. # Remove once they've resolved https://bugs.llvm.org//show_bug.cgi?id=21689 add_cflag("-Wno-missing-field-initializers") # Enable Link Time Optimization on Clang if(ENABLE_LTO) ## -flto is a flag that needs to exist at link time as well, # so we use some hacky save/restore to help cmake. set(SAVE_CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") set(CMAKE_REQUIRED_LIBRARIES "-flto") add_cflag("-flto") set(CMAKE_REQUIRED_LIBRARIES "${SAVE_CMAKE_REQUIRED_LIBRARIES}") endif() # Have ld strip the symbols from Release and MinSizeRel build types. (-Oz is clang specific) set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Os") set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} -Oz -s") if(FREEBSD) set(LIBRARIES ${LIBRARIES} "cxxrt") endif() if(NOT ENABLE_ASAN) if(NOT APPLE) add_cflag("-fsanitize=safe-stack") endif() endif() else() message(STATUS "Unknown compiler name: You may have to set up your compiler flags yourself.") endif() # set define for GIT_VERSION if(GIT_VERSION) add_cflag("-DGIT_VERSION='\"${GIT_VERSION}\"'") endif() ####################################################################### # Build options ####################################################################### # https://github.com/google/sanitizers/wiki/AddressSanitizer if (ENABLE_ASAN) set(SAVE_CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") set(CMAKE_REQUIRED_LIBRARIES "-fsanitize=address") add_cflag("-fsanitize=address") add_cflag("-fno-omit-frame-pointer") set(CMAKE_REQUIRED_LIBRARIES "${SAVE_CMAKE_REQUIRED_LIBRARIES}") endif() if(ENABLE_WERROR) add_cflag("-Werror") endif() if(UTOX_STATIC) if(UNIX) add_cflag("-Wl -Bstatic -lopus -lopenal -lfilteraudio -Bdynamic -lrt -lm -lpthread -ldl") else() add_cflag("-static") endif() endif() if(ENABLE_AUTOUPDATE) add_cflag("-DENABLE_AUTOUPDATE=1") endif() if(ENABLE_FILTERAUDIO) add_cflag("-DAUDIO_FILTERING=1") endif() find_package(libtox REQUIRED) include_directories(${LIBTOX_INCLUDE_DIRS}) set(LIBRARIES ${LIBRARIES} ${LIBTOX_LIBRARIES}) find_package(libsodium REQUIRED) include_directories(${LIBSODIUM_INCLUDE_DIRS}) set(LIBRARIES ${LIBRARIES} ${LIBSODIUM_LIBRARIES}) find_package(libvpx REQUIRED) include_directories(${LIBVPX_INCLUDE_DIRS}) set(LIBRARIES ${LIBRARIES} ${LIBVPX_LIBRARIES}) include_directories(SYSTEM third-party/stb) include_directories(SYSTEM third-party/minini/dev) include_directories(SYSTEM third-party/qrcodegen/c) # Protip, you must use a different directory for each build target... # -DMAKE_TOOLCHAIN_FILE has no effect unless the target directory is empty # 1.5 hours to learn this... if(WIN32) if (CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "MinSizeRel") set(GUI_TYPE WIN32) endif() link_directories(${CMAKE_PREFIX_PATH}/lib) # Windows icons enable_language(RC) set(WINDOWS_ICON src/windows/utox.rc) add_subdirectory(src/windows) elseif(APPLE) set(GUI_TYPE MACOSX_BUNDLE) add_definitions("-x objective-c") add_subdirectory(src/cocoa) elseif(UNIX) find_package(X11 REQUIRED) include_directories(${X11_INCLUDE_DIR}) add_subdirectory(src/xlib) if(LINUX) # Required for v4l (at least in the Linux static builds on Jenkins) set(LIBRARIES ${LIBRARIES} "rt") endif() endif() # Acquire 3rd party headers find_path(STBI_INCLUDE_DIR NAMES stb_image.h stb_image_write.h PATHS third-party/stb) if((NOT STBI_INCLUDE_DIR) OR (NOT EXISTS ${STBI_INCLUDE_DIR})) message("STBI not found") execute_process(COMMAND git submodule update --init -- third-party/stb WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) # set FOO_INCLUDE_DIR properly set(STBI_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third-party/stb/ CACHE PATH "stbi include directory") endif() # include utoxLAYOUT add_subdirectory(src/layout) # include utoxUI add_subdirectory(src/ui) # include utoxAV add_subdirectory(src/av) ####################################################################### # :: uTox main ####################################################################### add_executable(utox ${GUI_TYPE} src/avatar.c src/chatlog.c src/chrono.c src/command_funcs.c src/commands.c src/devices.c src/file_transfers.c src/filesys.c src/flist.c src/friend.c src/groups.c src/inline_video.c src/logging.c src/main.c src/messages.c src/notify.c src/qr.c src/screen_grab.c src/self.c src/settings.c src/sized_string.h src/stb.c src/text.c src/theme.c src/tox.c src/tox_callbacks.c src/ui.c src/ui_i18n.c src/updater.c src/utox.c src/window.c third-party/minini/dev/minIni.c third-party/qrcodegen/c/qrcodegen.c ${WINDOWS_ICON} ${APPLE_FILES} ) target_link_libraries(utox utoxAV utoxNATIVE utoxUI ${LIBRARIES} pthread m ) set_property(TARGET utox PROPERTY C_STANDARD 11) if(APPLE) set_target_properties(utox PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${uTox_SOURCE_DIR}/src/cocoa/Info.plist") # check that the app is valid and when the app is static # also check that it does not depend on external libs (system libs excepted) install(CODE "include(BundleUtilities) verify_app(${CMAKE_BINARY_DIR}/utox.app) if(UTOX_STATIC OR TOXCORE_STATIC) verify_bundle_prerequisites(${CMAKE_BINARY_DIR}/utox.app RETURN_VAR INFO_VAR) endif()" ) # needed for packaging, so that CPack can find the app install(TARGETS utox DESTINATION .) # install App install(TARGETS utox DESTINATION /Applications) elseif(UNIX) install(TARGETS utox RUNTIME DESTINATION "bin" ) endif() # packaging include(CPack) ########### # Testing # ########### if(ENABLE_TESTS) if(UNIX) # Tests currently only run on Unix-like OSes. enable_testing() add_subdirectory(tests) endif() endif() ############# # Info dump # ############# message("Build options:") message("- CMake Module Path: ${CMAKE_MODULE_PATH}") message("----------------------------------") message("- Add ASAN: ${ENABLE_ASAN}") message("- Error on Warning: ${ENABLE_WERROR}") message("- Filter Audio: ${ENABLE_FILTERAUDIO}") message("- Auto Updater: ${ENABLE_AUTOUPDATE}") message("- uTox Static: ${UTOX_STATIC}") message("- Toxcore Static: ${TOXCORE_STATIC}") message("-- Platform Options --------------") if(WINDOWS) message("- Windows Legacy: ${WIN_XP_LEGACY}") else() message("- Enable DBus: ${ENABLE_DBUS}") message("- Enable Tests ${ENABLE_TESTS}") endif() message("* CMake system is '${CMAKE_SYSTEM_NAME}'") message("* CMake build type is '${CMAKE_BUILD_TYPE}'") message("* C Compiler is '${CMAKE_C_COMPILER}' with the following flags:") message("* C flags for Debug: ${CMAKE_C_FLAGS_DEBUG}") message("* C flags for Release: ${CMAKE_C_FLAGS_RELEASE}") message("* C flags for all types: ${CMAKE_C_FLAGS}") if(ENABLE_ASAN) message("") message(" TIP: You may want to set the env variable ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer for ASAN to show nicer stack traces.") message(" See for more details.") message("") endif() uTox-0.17.1/LICENSE000066400000000000000000000026071354126257400135620ustar00rootroot00000000000000MIT License Copyright (c) 2017 uTox Contributors 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. Please note: Sections of this code base are likely only available under GPLv3, we're working to remove them but until that happens. The entirety of the project is also available as GPLv3. If you'd like to copy and paste code, you should talk with someone who manages the project to make sure you're not getting GPLv3 only code by mistake. uTox-0.17.1/README.md000066400000000000000000000075341354126257400140400ustar00rootroot00000000000000# μTox [![Build Status](https://travis-ci.org/uTox/uTox.svg?branch=develop)](https://travis-ci.org/uTox/uTox) [![Build status](https://ci.appveyor.com/api/projects/status/bswtxxs4e93rdw2u/branch/appveyor-ci?svg=true)](https://ci.appveyor.com/project/redmanmale/utox) [![Coverage](https://img.shields.io/badge/coverage-0.01%25-red.svg)](#) [![IRC](https://img.shields.io/badge/freenode-%23utox-brightgreen.svg)](https://webchat.freenode.net/?channels=#utox) The lightweight [Tox](https://github.com/TokTok/toxcore) client. [**TokTok Site**](http://toktok.github.io/) **|** [**Installing**](docs/INSTALL.md) **|** [**Changelog**](CHANGELOG.md) **|** [**Compiling**](docs/BUILD.md) **|** [**Toxcore Spec**](https://toktok.github.io/spec) You shouldn't have to choose a new client for every device: So µTox works everywhere! On every major system **Windows**, **macOS**, **Linux**, **Android**, **FreeBSD**, **NetBSD**, **OpenBSD**, and even **DragonFlyBSD**. ## Downloads - **Windows** - [32bit Version](https://build.tox.chat/view/uTox/job/uTox_build_windows_x86_debug/lastSuccessfulBuild/artifact/utox_windows_x86_debug.zip) - [64bit Version](https://build.tox.chat/view/uTox/job/uTox_build_windows_x86-64_release/lastSuccessfulBuild/artifact/utox_windows_x86-64.zip) - [Windows XP Version](https://build.tox.chat/job/uTox-nightly-FOR-WIN-XP_build_windows_x86_debug/lastSuccessfulBuild/artifact/utox_nightly.zip) - **Linux/Posix** - [static x86-64](https://build.tox.chat/view/uTox/job/uTox_build_linux_x86-64_release/lastSuccessfulBuild/artifact/utox_linux_x86-64.tar.xz) - [static x86](https://build.tox.chat/view/uTox/job/uTox_build_linux_x86_release/lastSuccessfulBuild/artifact/utox_linux_x86.tar.xz) - **macOS** - [Last Updated .dmg](https://github.com/uTox/uTox/releases/download/v0.16.1/uTox-0.16.1.dmg) (*could be out of date, check the version list below*) - [Version List](https://github.com/uTox/uTox/releases) - **Android** - [uTox Android on Google Play](https://play.google.com/apps/testing/tox.client.utox) **You should use [Antox](https://play.google.com/store/apps/details?id=chat.tox.antox&hl=en) - [Direct apk](https://build.tox.chat/view/uTox/job/uTox_build_android_armhf_release/lastSuccessfulBuild/artifact/uTox.apk) (You may need to uninstall the previous version.) ## Features - Avatars - Secure person to person conversations: - Video (Webcam or Desktop sharing) - Audio - Text - Chat History - Screenshots - Group chats - New API support ready. - File transfers, with inline images support - Tox URI support (clickable Tox links) - Emoticons - Auto-updates on Windows. Just like Toxcore, µTox is still alpha software, so you may encounter bugs, or maybe a crash or two. µTox also needs your help, if you do encounter any bugs or problems please [open an issue](https://github.com/uTox/uTox/issues/new). ## Screenshots μTox running on Windows 10 ![μTox on Windows 10](images/utox-windows10.png "μTox running on Windows 10") μTox running on macOS: ![μTox on macOS](images/utox-osx.png "μTox running on macOS") μTox running on Linux (Ubuntu) ![μTox on Linux](images/utox-linux.png "μTox running on Linux (Ubuntu)") ## Team GitLab | IRC | Email | Fingerprint --- | --- | --- | --- @cebe | CeBe | mail@cebe.cc | `E592 6050 AE9C 234A FF84 96FE BE4F 41DE 1DEE EED0` @endoffile78 | e0f/endoffile | endoffile78@yahoo.com | `7AED 9A17 0C81 E601 DA4E EE27 9043 0614 21EF 90FA` @TheGrayHatter | grayhatter | greg@grayhatter.com | `9D1D 5990 88E2 23DD 9900 7DE2 AEA1 0D4E A053 0876` @robinlinden | robinli | dev@robinlinden.eu | `B700 8FF1 2C07 9BF6 E6EA 19D1 601A 604B 7E60 5776` @dkmoz | dkmoz | dkmoz@airmail.cc | `E28E 7252 B1E7 FCFE D358 CF8E 3763 B3A7 93AA FA0F` @redmanmale | redmanmale | redmanmale@gmail.com | `BCEE 99DC A339 ABF9 CC36 428D 61A9 B9AF D2E5 3885` @ | avoidr | avoidr@firemail.cc | `A251 56FC 7AFB 5C03 65A0 407E 6F5D D1C5 371D E665` uTox-0.17.1/appveyor.yml000066400000000000000000000044731354126257400151500ustar00rootroot00000000000000version: 'utox-cygwin-{build}' clone_depth: 1 environment: CYG_CACHE: C:\cygwin64\var\cache\setup cache: - '%CYG_CACHE%' install: - git submodule init && git submodule update && mkdir libs\windows-x64 && cd libs\windows-x64 # install deps - C:\cygwin64\setup-x86_64.exe -qgnNdO -l %CYG_CACHE% -R c:\cygwin64 -s http://cygwin.mirror.constant.com -P cmake,make,mingw64-x86_64-gcc-core # toxcore - curl -L https://build.tox.chat/view/libtoxcore/job/libtoxcore-toktok_build_windows_x86-64_static_release/lastSuccessfulBuild/artifact/libtoxcore-toktok_build_windows_x86-64_static_release.zip -o %CYG_CACHE%\toxcore.zip - unzip -o %CYG_CACHE%\toxcore.zip # openal - curl -L https://build.tox.chat/view/libopenal/job/libopenal_build_windows_x86-64_static_release/lastSuccessfulBuild/artifact/libopenal_build_windows_x86-64_static_release.zip -o %CYG_CACHE%\openal.zip - unzip -o %CYG_CACHE%\openal.zip # sodium - curl -L https://build.tox.chat/view/libsodium/job/libsodium_build_windows_x86-64_static_release/lastSuccessfulBuild/artifact/libsodium_build_windows_x86-64_static_release.zip -o %CYG_CACHE%\sodium.zip - unzip -o %CYG_CACHE%\sodium.zip # vpx - curl -L https://build.tox.chat/view/libvpx/job/libvpx_build_windows_x86-64_static_release/lastSuccessfulBuild/artifact/libvpx_build_windows_x86-64_static_release.zip -o %CYG_CACHE%\vpx.zip - unzip -o %CYG_CACHE%\vpx.zip # opus - curl -L https://build.tox.chat/view/libopus/job/libopus_build_windows_x86-64_static_release/lastSuccessfulBuild/artifact/libopus_build_windows_x86-64_static_release.zip -o %CYG_CACHE%\opus.zip - unzip -o %CYG_CACHE%\opus.zip # filter_audio - curl -L https://build.tox.chat/view/libfilteraudio/job/libfilteraudio_build_windows_x86-64_static_release/lastSuccessfulBuild/artifact/libfilteraudio.zip -o %CYG_CACHE%\filter_audio.zip - unzip -o %CYG_CACHE%\filter_audio.zip build_script: - C:\Cygwin64\bin\bash -e -l -c "cd C:/projects/utox ; extra/common/set-nightly-build-warning.sh ; mkdir build ; cd build ; cmake -DCMAKE_TOOLCHAIN_FILE=C:/projects/utox/cmake/toolchain-win64.cmake -DTOXCORE_STATIC=ON .. ; make" - copy C:\projects\utox\build\utox.exe C:\projects\utox\uTox.exe artifacts: - name: uTox.exe path: uTox.exe # branches: # only: # - master # - develop uTox-0.17.1/cmake/000077500000000000000000000000001354126257400136305ustar00rootroot00000000000000uTox-0.17.1/cmake/FindCheck.cmake000066400000000000000000000033211354126257400164470ustar00rootroot00000000000000# - Try to find the CHECK libraries # Once done this will define # # CHECK_FOUND - system has check # CHECK_INCLUDE_DIRS - the check include directory # CHECK_LIBRARIES - check library # # Copyright (c) 2007 Daniel Gollub # Copyright (c) 2007-2009 Bjoern Ricks # # Redistribution and use is allowed according to the terms of the New # BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. INCLUDE( FindPkgConfig ) IF ( Check_FIND_REQUIRED ) SET( _pkgconfig_REQUIRED "REQUIRED" ) ELSE( Check_FIND_REQUIRED ) SET( _pkgconfig_REQUIRED "" ) ENDIF ( Check_FIND_REQUIRED ) IF ( CHECK_MIN_VERSION ) PKG_SEARCH_MODULE( CHECK ${_pkgconfig_REQUIRED} check>=${CHECK_MIN_VERSION} ) ELSE ( CHECK_MIN_VERSION ) PKG_SEARCH_MODULE( CHECK ${_pkgconfig_REQUIRED} check ) ENDIF ( CHECK_MIN_VERSION ) # Look for CHECK include dir and libraries IF( NOT CHECK_FOUND AND NOT PKG_CONFIG_FOUND ) FIND_PATH( CHECK_INCLUDE_DIRS check.h ) FIND_LIBRARY( CHECK_LIBRARIES NAMES check ) IF ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES ) SET( CHECK_FOUND 1 ) IF ( NOT Check_FIND_QUIETLY ) MESSAGE ( STATUS "Found CHECK: ${CHECK_LIBRARIES}" ) ENDIF ( NOT Check_FIND_QUIETLY ) ELSE ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES ) IF ( Check_FIND_REQUIRED ) MESSAGE( FATAL_ERROR "Could NOT find CHECK" ) ELSE ( Check_FIND_REQUIRED ) IF ( NOT Check_FIND_QUIETLY ) MESSAGE( STATUS "Could NOT find CHECK" ) ENDIF ( NOT Check_FIND_QUIETLY ) ENDIF ( Check_FIND_REQUIRED ) ENDIF ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES ) ENDIF( NOT CHECK_FOUND AND NOT PKG_CONFIG_FOUND ) # Hide advanced variables from CMake GUIs MARK_AS_ADVANCED( CHECK_INCLUDE_DIRS CHECK_LIBRARIES ) uTox-0.17.1/cmake/FindDBus.cmake000066400000000000000000000044151354126257400162740ustar00rootroot00000000000000# - Try to find DBus # Once done, this will define # # DBUS_FOUND - system has DBus # DBUS_INCLUDE_DIRS - the DBus include directories # DBUS_LIBRARIES - link these to use DBus # # Copyright (C) 2012 Raphael Kubo da Costa # # 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 HOLDER AND ITS 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 ITS # 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. FIND_PACKAGE(PkgConfig) PKG_CHECK_MODULES(PC_DBUS QUIET dbus-1) FIND_LIBRARY(DBUS_LIBRARIES NAMES dbus-1 HINTS ${PC_DBUS_LIBDIR} ${PC_DBUS_LIBRARY_DIRS} ) FIND_PATH(DBUS_INCLUDE_DIR NAMES dbus/dbus.h HINTS ${PC_DBUS_INCLUDEDIR} ${PC_DBUS_INCLUDE_DIRS} ) GET_FILENAME_COMPONENT(_DBUS_LIBRARY_DIR ${DBUS_LIBRARIES} PATH) FIND_PATH(DBUS_ARCH_INCLUDE_DIR NAMES dbus/dbus-arch-deps.h HINTS ${PC_DBUS_INCLUDEDIR} ${PC_DBUS_INCLUDE_DIRS} ${_DBUS_LIBRARY_DIR} ${DBUS_INCLUDE_DIR} PATH_SUFFIXES include ) SET(DBUS_INCLUDE_DIRS ${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR}) INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(DBUS REQUIRED_VARS DBUS_INCLUDE_DIRS DBUS_LIBRARIES) uTox-0.17.1/cmake/Findlibfilteraudio.cmake000066400000000000000000000023111354126257400204260ustar00rootroot00000000000000# - Try to find FilterAudio # Once done this will define # LIBFILTERAUDIO_FOUND - System has FilterAudio # LIBFILTERAUDIO_INCLUDE_DIRS - The FilterAudio include directories # LIBFILTERAUDIO_LIBRARIES - The libraries needed to use FilterAudio # LIBFILTERAUDIO_DEFINITIONS - Compiler switches required for using FilterAudio find_package(PkgConfig) pkg_check_modules(PKG_LIBFILTERAUDIO QUIET libfilteraudio) set(LIBFILTERAUDIO_DEFINITIONS ${PKG_LIBFILTERAUDIO_CFLAGS_OTHER}) find_path(LIBFILTERAUDIO_INCLUDE_DIR filter_audio.h HINTS ${PKG_LIBFILTERAUDIO_INCLUDEDIR} ${PKG_LIBFILTERAUDIO_INCLUDE_DIRS} ) find_library(LIBFILTERAUDIO_LIBRARY NAMES filteraudio HINTS ${PKG_LIBFILTERAUDIO_LIBDIR} ${PKG_LIBFILTERAUDIO_LIBRARY_DIRS} ) include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set LIBFILTERAUDIO_FOUND to TRUE # if all listed variables are TRUE find_package_handle_standard_args( libfilteraudio DEFAULT_MSG LIBFILTERAUDIO_LIBRARY LIBFILTERAUDIO_INCLUDE_DIR ) mark_as_advanced(LIBFILTERAUDIO_INCLUDE_DIR LIBFILTERAUDIO_LIBRARY) set(LIBFILTERAUDIO_LIBRARIES ${LIBFILTERAUDIO_LIBRARY}) set(LIBFILTERAUDIO_INCLUDE_DIRS ${LIBFILTERAUDIO_INCLUDE_DIR}) uTox-0.17.1/cmake/Findlibfontconfig.cmake000066400000000000000000000022651354126257400202630ustar00rootroot00000000000000# - Try to find FontConfig # Once done this will define # LIBFONTCONFIG_FOUND - System has FontConfig # LIBFONTCONFIG_INCLUDE_DIRS - The FontConfig include directories # LIBFONTCONFIG_LIBRARIES - The libraries needed to use FontConfig # LIBFONTCONFIG_DEFINITIONS - Compiler switches required for using FontConfig find_package(PkgConfig) pkg_check_modules(PKG_LIBFONTCONFIG QUIET libfontconfig) set(LIBFONTCONFIG_DEFINITIONS ${PKG_LIBFONTCONFIG_CFLAGS_OTHER}) find_path(LIBFONTCONFIG_INCLUDE_DIR fontconfig/fontconfig.h HINTS ${PKG_LIBFONTCONFIG_INCLUDEDIR} ${PKG_LIBFONTCONFIG_INCLUDE_DIRS} ) find_library(LIBFONTCONFIG_LIBRARY NAMES fontconfig HINTS ${PKG_LIBFONTCONFIG_LIBDIR} ${PKG_LIBFONTCONFIG_LIBRARY_DIRS} ) include(FindPackageHandleStandardArgs) # Handle the QUIETLY and REQUIRED arguments and set LIBFONTCONFIG_FOUND to TRUE # if all listed variables are TRUE. find_package_handle_standard_args( libfontconfig DEFAULT_MSG LIBFONTCONFIG_LIBRARY LIBFONTCONFIG_INCLUDE_DIR ) mark_as_advanced(LIBFONTCONFIG_INCLUDE_DIR LIBFONTCONFIG_LIBRARY) set(LIBFONTCONFIG_LIBRARIES ${LIBFONTCONFIG_LIBRARY}) set(LIBFONTCONFIG_INCLUDE_DIRS ${LIBFONTCONFIG_INCLUDE_DIR}) uTox-0.17.1/cmake/Findlibopus.cmake000066400000000000000000000017641354126257400171200ustar00rootroot00000000000000# - Try to find opus # Once done this will define # LIBOPUS_FOUND - System has opus # LIBOPUS_INCLUDE_DIRS - The opus include directories # LIBOPUS_LIBRARIES - The libraries needed to use opus # LIBOPUS_DEFINITIONS - Compiler switches required for using opus find_package(PkgConfig) pkg_check_modules(PKG_LIBOPUS QUIET libopus) set(LIBOPUS_DEFINITIONS ${PKG_LIBOPUS_CFLAGS_OTHER}) find_path(LIBOPUS_INCLUDE_DIR opus/opus.h HINTS ${PKG_LIBOPUS_INCLUDEDIR} ${PKG_LIBOPUS_INCLUDE_DIRS} ) find_library(LIBOPUS_LIBRARY NAMES opus HINTS ${PKG_LIBOPUS_LIBDIR} ${PKG_LIBOPUS_LIBRARY_DIRS} ) include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set LIBOPUS_FOUND to TRUE # if all listed variables are TRUE find_package_handle_standard_args( libopus DEFAULT_MSG LIBOPUS_LIBRARY LIBOPUS_INCLUDE_DIR ) mark_as_advanced(LIBOPUS_INCLUDE_DIR LIBOPUS_LIBRARY) set(LIBOPUS_LIBRARIES ${LIBOPUS_LIBRARY}) set(LIBOPUS_INCLUDE_DIRS ${LIBOPUS_INCLUDE_DIR}) uTox-0.17.1/cmake/Findlibsodium.cmake000066400000000000000000000020551354126257400174240ustar00rootroot00000000000000# - Try to find sodium # Once done this will define # LIBSODIUM_FOUND - System has sodium # LIBSODIUM_INCLUDE_DIRS - The sodium include directories # LIBSODIUM_LIBRARIES - The libraries needed to use sodium # LIBSODIUM_DEFINITIONS - Compiler switches required for using sodium find_package(PkgConfig) pkg_check_modules(PKG_LIBSODIUM QUIET libsodium) set(LIBSODIUM_DEFINITIONS ${PKG_LIBSODIUM_CFLAGS_OTHER}) find_path(LIBSODIUM_INCLUDE_DIR sodium.h HINTS ${PKG_LIBSODIUM_INCLUDEDIR} ${PKG_LIBSODIUM_INCLUDE_DIRS} ) find_library(LIBSODIUM_LIBRARY NAMES sodium HINTS ${PKG_LIBSODIUM_LIBDIR} ${PKG_LIBSODIUM_LIBRARY_DIRS} ) include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set LIBSODIUM_FOUND to TRUE # if all listed variables are TRUE find_package_handle_standard_args( libsodium DEFAULT_MSG LIBSODIUM_LIBRARY LIBSODIUM_INCLUDE_DIR ) mark_as_advanced(LIBSODIUM_INCLUDE_DIR LIBSODIUM_LIBRARY) set(LIBSODIUM_LIBRARIES ${LIBSODIUM_LIBRARY}) set(LIBSODIUM_INCLUDE_DIRS ${LIBSODIUM_INCLUDE_DIR}) uTox-0.17.1/cmake/Findlibtox.cmake000066400000000000000000000017351354126257400167420ustar00rootroot00000000000000# - Try to find Tox # Once done this will define # LIBTOX_FOUND - System has Tox # LIBTOX_INCLUDE_DIRS - The Tox include directories # LIBTOX_LIBRARIES - The libraries needed to use Tox # LIBTOX_DEFINITIONS - Compiler switches required for using Tox find_package(PkgConfig) pkg_check_modules(PKG_LIBTOX QUIET libtoxcore) set(LIBTOX_DEFINITIONS ${PKG_LIBTOX_CFLAGS_OTHER}) find_path(LIBTOX_INCLUDE_DIR tox/tox.h HINTS ${PKG_LIBTOX_INCLUDEDIR} ${PKG_LIBTOX_INCLUDE_DIRS} ) find_library(LIBTOX_LIBRARY NAMES toxcore HINTS ${PKG_LIBTOX_LIBDIR} ${PKG_LIBTOX_LIBRARY_DIRS} ) include(FindPackageHandleStandardArgs) # Handle the QUIETLY and REQUIRED arguments and set LIBTOX_FOUND to TRUE # if all listed variables are TRUE. find_package_handle_standard_args( libtox DEFAULT_MSG LIBTOX_LIBRARY LIBTOX_INCLUDE_DIR ) mark_as_advanced(LIBTOX_INCLUDE_DIR LIBTOX_LIBRARY) set(LIBTOX_LIBRARIES ${LIBTOX_LIBRARY}) set(LIBTOX_INCLUDE_DIRS ${LIBTOX_INCLUDE_DIR}) uTox-0.17.1/cmake/Findlibv4lconvert.cmake000066400000000000000000000022551354126257400202340ustar00rootroot00000000000000# - Try to find V4Lconvert # Once done this will define # LIBV4LCONVERT_FOUND - System has V4Lconvert # LIBV4LCONVERT_INCLUDE_DIRS - The V4Lconvert include directories # LIBV4LCONVERT_LIBRARIES - The libraries needed to use V4Lconvert # LIBV4LCONVERT_DEFINITIONS - Compiler switches required for using V4Lconvert find_package(PkgConfig) pkg_check_modules(PKG_LIBV4LCONVERT QUIET libv4lconvert) set(LIBV4LCONVERT_DEFINITIONS ${PKG_LIBV4LCONVERT_CFLAGS_OTHER}) find_path(LIBV4LCONVERT_INCLUDE_DIR libv4lconvert.h HINTS ${PKG_LIBV4LCONVERT_INCLUDEDIR} ${PKG_LIBV4LCONVERT_INCLUDE_DIRS} ) find_library(LIBV4LCONVERT_LIBRARY NAMES v4lconvert HINTS ${PKG_LIBV4LCONVERT_LIBDIR} ${PKG_LIBV4LCONVERT_LIBRARY_DIRS} ) include(FindPackageHandleStandardArgs) # Handle the QUIETLY and REQUIRED arguments and set LIBV4LCONVERT_FOUND to TRUE # if all listed variables are TRUE. find_package_handle_standard_args( libv4lconvert DEFAULT_MSG LIBV4LCONVERT_LIBRARY LIBV4LCONVERT_INCLUDE_DIR ) mark_as_advanced(LIBV4LCONVERT_INCLUDE_DIR LIBV4LCONVERT_LIBRARY) set(LIBV4LCONVERT_LIBRARIES ${LIBV4LCONVERT_LIBRARY}) set(LIBV4LCONVERT_INCLUDE_DIRS ${LIBV4LCONVERT_INCLUDE_DIR}) uTox-0.17.1/cmake/Findlibvpx.cmake000066400000000000000000000017331354126257400167430ustar00rootroot00000000000000# - Try to find VPX # Once done this will define # LIBVPX_FOUND - System has VPX # LIBVPX_INCLUDE_DIRS - The VPX include directories # LIBVPX_LIBRARIES - The libraries needed to use VPX # LIBVPX_DEFINITIONS - Compiler switches required for using VPX find_package(PkgConfig) pkg_check_modules(PKG_LIBVPX QUIET libvpx) set(LIBVPX_DEFINITIONS ${PKG_LIBVPX_CFLAGS_OTHER}) find_path(LIBVPX_INCLUDE_DIR vpx/vpx_codec.h HINTS ${PKG_LIBVPX_INCLUDEDIR} ${PKG_LIBVPX_INCLUDE_DIRS} ) find_library(LIBVPX_LIBRARY NAMES vpx HINTS ${PKG_LIBVPX_LIBDIR} ${PKG_LIBVPX_LIBRARY_DIRS} ) include(FindPackageHandleStandardArgs) # Handle the QUIETLY and REQUIRED arguments and set LIBVPX_FOUND to TRUE # if all listed variables are TRUE. find_package_handle_standard_args( libvpx DEFAULT_MSG LIBVPX_LIBRARY LIBVPX_INCLUDE_DIR ) mark_as_advanced(LIBVPX_INCLUDE_DIR LIBVPX_LIBRARY) set(LIBVPX_LIBRARIES ${LIBVPX_LIBRARY}) set(LIBVPX_INCLUDE_DIRS ${LIBVPX_INCLUDE_DIR}) uTox-0.17.1/cmake/macOS.cmake000066400000000000000000000021731354126257400156370ustar00rootroot00000000000000# These variables are needed to generate the Info.plist set(EXECUTABLE_NAME utox) set(APPLE_ICON utox.icns) set(APPLE_MENU MainMenu) set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6) # Xcode needs these to find libs include_directories(/usr/local/include) link_directories(/usr/local/lib) # Make apple icon add_custom_command(OUTPUT ${APPLE_ICON} COMMAND iconutil --convert icns ${uTox_SOURCE_DIR}/src/cocoa/utox.iconset -o ${APPLE_ICON} DEPENDS ${uTox_SOURCE_DIR}/src/cocoa/utox.iconset ) # Make apple menu add_custom_command(OUTPUT ${APPLE_MENU}.nib COMMAND ibtool --errors --warnings --notices --output-format human-readable-text --compile ${APPLE_MENU}.nib ${uTox_SOURCE_DIR}/src/cocoa/MainMenu.xib DEPENDS ${uTox_SOURCE_DIR}/src/cocoa/MainMenu.xib ) # Copy files set_source_files_properties(${APPLE_ICON} ${APPLE_MENU}.nib PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") set(APPLE_FILES ${APPLE_ICON} ${APPLE_MENU}.nib ) if(UTOX_STATIC OR TOXCORE_STATIC) set(CMAKE_FIND_LIBRARY_SUFFIXES .a .dylib) endif() # create DMG set(CPACK_GENERATOR "DragNDrop") set(CPACK_PACKAGE_FILE_NAME "uTox ${PROJECT_VERSION}") uTox-0.17.1/cmake/toolchain-win32.cmake000066400000000000000000000027761354126257400175660ustar00rootroot00000000000000# This file has a lot of CACHE STRING "" FORCE because cmake likes caching # things and won't use what we do in here unless we CACHE FORCE it. # # See: https://cmake.org/pipermail/cmake/2012-January/048429.html # http://stackoverflow.com/a/30217088 # the name of the target operating system set(CMAKE_SYSTEM_NAME Windows) set(COMPILER_PREFIX "i686-w64-mingw32") set(CMAKE_C_COMPILER i686-w64-mingw32-gcc ) set(CMAKE_RC_COMPILER i686-w64-mingw32-windres ) # Required to prevent duplication of flags from this file. UNSET(CMAKE_C_FLAGS CACHE) UNSET(CMAKE_C_FLAGS_DEBUG CACHE) UNSET(CMAKE_C_FLAGS_RELWITHDEBINFO CACHE) # Windows only compiles statically. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DAL_LIBTYPE_STATIC" CACHE STRING "" FORCE) set(UTOX_STATIC ON CACHE STRING "" FORCE) # Required for line numbers in gdb on Windows. set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g3" CACHE STRING "" FORCE) set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -g3" CACHE STRING "" FORCE) include_directories(SYSTEM /usr/share/mingw-w64/include/) # adjust the default behaviour of the FIND_XXX() commands: # search headers and libraries in the target environment, search # programs in the host environment set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(WIN32 TRUE) # This is for cmake set(UNIX FALSE) set(CROSS_COMPILING TRUE) if(NOT CMAKE_PREFIX_PATH) set(CMAKE_PREFIX_PATH ${CMAKE_SOURCE_DIR}/libs/windows-x32) endif() uTox-0.17.1/cmake/toolchain-win64.cmake000066400000000000000000000030571354126257400175640ustar00rootroot00000000000000# This file has a lot of CACHE STRING "" FORCE because cmake likes caching # things and won't use what we do in here unless we CACHE FORCE it. # # See: https://cmake.org/pipermail/cmake/2012-January/048429.html # http://stackoverflow.com/a/30217088 # the name of the target operating system set(CMAKE_SYSTEM_NAME Windows) set(COMPILER_PREFIX "x86_64-w64-mingw32") set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc ) set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres ) # Required to prevent duplication of flags from this file. UNSET(CMAKE_C_FLAGS CACHE) UNSET(CMAKE_C_FLAGS_DEBUG CACHE) UNSET(CMAKE_C_FLAGS_RELWITHDEBINFO CACHE) # Windows only compiles statically. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DAL_LIBTYPE_STATIC" CACHE STRING "" FORCE) set(UTOX_STATIC ON CACHE STRING "" FORCE) # Required for line numbers in gdb on Windows. set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g3" CACHE STRING "" FORCE) set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -g3" CACHE STRING "" FORCE) include_directories(SYSTEM /usr/share/mingw-w64/include/) # adjust the default behaviour of the FIND_XXX() commands: # search headers and libraries in the target environment, search # programs in the host environment set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(WIN32 TRUE) # This is for cmake set(WIN64 TRUE) # This is for uTox lib dirs set(UNIX FALSE) set(CROSS_COMPILING TRUE) if(NOT CMAKE_PREFIX_PATH) set(CMAKE_PREFIX_PATH ${CMAKE_SOURCE_DIR}/libs/windows-x64) endif() uTox-0.17.1/cmake/win.cmake000066400000000000000000000014451354126257400154330ustar00rootroot00000000000000# Having a mingw32 compiler set is vital. Otherwise you get weird errors because # of Windows headers. # From $UTOX_ROOT/build/ # CC=x86_64-w64-mingw32-gcc cmake .. -DCMAKE_BUILD_TYPE=Debug # make -j # Required to prevent duplication of flags from this file. UNSET(CMAKE_C_FLAGS CACHE) UNSET(CMAKE_C_FLAGS_DEBUG CACHE) UNSET(CMAKE_C_FLAGS_RELWITHDEBINFO CACHE) # Windows only compiles statically. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DAL_LIBTYPE_STATIC") # Required for line numbers in gdb on Windows. set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g3" CACHE STRING "" FORCE) set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -g3" CACHE STRING "" FORCE) # Set default dependency path. if(NOT CMAKE_PREFIX_PATH) set(CMAKE_PREFIX_PATH ${CMAKE_SOURCE_DIR}/libs/windows-x64) endif() uTox-0.17.1/docs/000077500000000000000000000000001354126257400135005ustar00rootroot00000000000000uTox-0.17.1/docs/BUILD.md000066400000000000000000000212751354126257400146700ustar00rootroot00000000000000# Build Following are barebone compilation instructions. They probably wont work but #utox on freenode can probably help you out. If you're looking for it to "just work" you're going to want [these instructions](INSTALL.md). ## Instructions - [Unix Like](#unix-like) * [Linux](#linux) * [Ubuntu](#ubuntu) * [OpenBSD](#openbsd) * [FreeBSD and DragonFlyBSD](#freebsd-and-dragonflybsd) * [NetBSD](#netbsd) - [Windows](#windows) - [macOS](#macos) - [Android](#android) ## Unix Like ### Linux Before compiling make sure you have all of the [dependencies](DEPENDENCIES.md#linux) installed. The easy way out is: ```sh git clone --recursive git://github.com/uTox/uTox.git cd uTox/ mkdir build cd build cmake .. make make install ``` > To build the binary with debug symbols (e.g. for debugging with gdb) you should append the `-DCMAKE_BUILD_TYPE=Debug` option to the `cmake ..` command above. > > In that case you want to set the env variable `ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer` for the address sanitizer (ASAN) to show nicer stack traces. > See for more details. or if you built toxcore statically: ```sh git clone --recursive git://github.com/uTox/uTox.git cd uTox/ mkdir build cd build cmake -DTOXCORE_STATIC=ON .. make make install ``` For the build to pass you need to install the following from sources: [filteraudio](https://github.com/irungentoo/filter_audio) [libtoxcore](https://github.com/TokTok/c-toxcore) For base emoji ids support you need: [base_emoji](https://github.com/irungentoo/base_emoji) ### Ubuntu Tested on Ubuntu 18.04 ```bash sudo apt-get install build-essential libtool autotools-dev automake checkinstall check git yasm libopus-dev libvpx-dev pkg-config libfontconfig1-dev libdbus-1-dev libv4l-dev libxrender-dev libopenal-dev libxext-dev cmake git clone git://github.com/jedisct1/libsodium.git cd libsodium git checkout tags/1.0.3 ./autogen.sh ./configure && make check sudo checkinstall cd .. git clone git://github.com/irungentoo/filter_audio.git cd filter_audio make sudo checkinstall cd .. git clone git://github.com/TokTok/c-toxcore.git cd c-toxcore cmake . make sudo checkinstall cd .. sudo ldconfig git clone --recursive git://github.com/uTox/uTox.git cd uTox/ mkdir build cd build cmake .. make sudo checkinstall ``` Have fun! If you're looking for a good IDE, Netbeans is very easy to set up for uTox. In fact, you can just create a new project from the existing sources and everything should work fine. ### OpenBSD First install the [dependencies](DEPENDENCIES.md#openbsd-and-netbsd): ```bash doas pkg_add openal cmake libv4l toxcore git check ``` Optionally install D-Bus and GTK+3: ```bash doas pkg_add dbus gtk+3 ``` Now compile uTox: ```bash git clone --recursive git://github.com/uTox/uTox.git cd uTox/ mkdir build cd build cmake .. make -j `sysctl -n hw.ncpu` make test doas make install ``` ### FreeBSD and DragonFlyBSD Install the [dependencies](DEPENDENCIES.md#freebsd-and-dragonflybsd): ```bash sudo pkg install libv4l v4l_compat openal-soft toxcore git check ``` Optionally install D-Bus, GTK+3 and filteraudio: ```bash sudo pkg install dbus libfilteraudio gtk3 ``` Now compile uTox: ```bash git clone --recursive git://github.com/uTox/uTox.git cd uTox/ mkdir build cd build cmake .. make make test sudo make install ``` ### NetBSD Install the [dependencies](DEPENDENCIES.md#openbsd-and-netbsd): ```bash sudo pkgin install openal-soft cmake libv4l toxcore git check ``` Optionally install D-Bus and GTK+3: ```base sudo pkgin install dbus gtk3 ``` Now compile uTox: ```bash git clone --recursive git://github.com/uTox/uTox.git cd uTox/ mkdir build cd build cmake .. make make test sudo make install ``` ## Windows You will need a working Cygwin environment or Unix desktop to compile windows. Before compiling please make sure you have all of the [dependencies](DEPENDENCIES.md#windows). Dependencies can be downloaded from [here](https://build.tox.chat/). Make sure you grab the right bit version. ### Cygwin setup - Download Cygwin ([x86](https://cygwin.com/setup-x86.exe)/[x64](https://cygwin.com/setup-x86_64.exe)) - Search and select exactly these packages in Devel category: - mingw64-i686-gcc-core (x86) / mingw64-x86_64-gcc-core (x64) - make - cmake - gdb In case of Cygwin all following commands should be executed in Cygwin Terminal. ```bash cd /cygdrive/c mkdir projects cd projects/ git clone --recursive git://github.com/uTox/uTox.git cd uTox/ mkdir libs cd libs/ mkdir windows-x64 cd ../uTox/ mkdir build cd build ``` Download .zip files and place them into `windows-x64` folder. Extract here with your archiver and merge when it'll ask for replacement: - toxcore ([x86](https://build.tox.chat/view/libtoxcore/job/libtoxcore-toktok_build_windows_x86_static_release/lastSuccessfulBuild/artifact/libtoxcore-toktok_build_windows_x86_static_release.zip)/[x64](https://build.tox.chat/view/libtoxcore/job/libtoxcore-toktok_build_windows_x86-64_static_release/lastSuccessfulBuild/artifact/libtoxcore-toktok_build_windows_x86-64_static_release.zip)) - openal ([x86](https://build.tox.chat/view/libopenal/job/libopenal_build_windows_x86_static_release/lastSuccessfulBuild/artifact/libopenal_build_windows_x86_static_release.zip)/[x64](https://build.tox.chat/view/libopenal/job/libopenal_build_windows_x86-64_static_release/lastSuccessfulBuild/artifact/libopenal_build_windows_x86-64_static_release.zip)) - sodium ([x86](https://build.tox.chat/view/libsodium/job/libsodium_build_windows_x86_static_release/lastSuccessfulBuild/artifact/libsodium_build_windows_x86_static_release.zip)/[x64](https://build.tox.chat/view/libsodium/job/libsodium_build_windows_x86-64_static_release/lastSuccessfulBuild/artifact/libsodium_build_windows_x86-64_static_release.zip)) - libvpx ([x86](https://build.tox.chat/view/libvpx/job/libvpx_build_windows_x86_static_release/lastSuccessfulBuild/artifact/libvpx_build_windows_x86_static_release.zip)/[x64](https://build.tox.chat/view/libvpx/job/libvpx_build_windows_x86-64_static_release/lastSuccessfulBuild/artifact/libvpx_build_windows_x86-64_static_release.zip)) - opus ([x86](https://build.tox.chat/view/libopus/job/libopus_build_windows_x86_static_release/lastSuccessfulBuild/artifact/libopus_build_windows_x86_static_release.zip)/[x64](https://build.tox.chat/view/libopus/job/libopus_build_windows_x86-64_static_release/lastSuccessfulBuild/artifact/libopus_build_windows_x86-64_static_release.zip)) - filter_audio ([x86](https://build.tox.chat/view/libfilteraudio/job/libfilteraudio_build_windows_x86_static_release/lastSuccessfulBuild/artifact/libfilteraudio.zip)/[x64](https://build.tox.chat/view/libfilteraudio/job/libfilteraudio_build_windows_x86-64_static_release/lastSuccessfulBuild/artifact/libfilteraudio.zip)) And go back to terminal (make sure you're still in `build` folder): - For 32 bit: ```bash cmake -DCMAKE_TOOLCHAIN_FILE="../cmake/toolchain-win32.cmake" -DTOXCORE_STATIC=ON .. make ``` - For 64 bit: ```bash cmake -DCMAKE_TOOLCHAIN_FILE="../cmake/toolchain-win64.cmake" -DTOXCORE_STATIC=ON .. make ``` ## macOS ```bash brew tap tox/tox brew install --HEAD utox ``` For details see [COCOA.md](COCOA.md). ## Android Requires Android SDK+NDK From uTox root folder, using prebuilt static toxcore + freetype libraries (includes in ../include and libs in ../lib), resulting apk is ./tmp/tmp2.apk: ### Setup: ```bash mkdir ./tmp mkdir ./tmp/java mkdir ./tmp/libs mkdir ./tmp/libs/armeabi keytool -genkey -v -keystore ./tmp/debug.keystore -alias $ALIAS -keyalg RSA -keysize 2048 -validity 20000 ``` ### Compile + Pack APK ```bash arm-linux-androideabi-gcc --sysroot=$NDK_PATH/platforms/android-9/arch-arm/ -I../include/freetype2/ -I../include/ ./*.c ./png/png.c -llog -landroid -lEGL -lGLESv2 -lOpenSLES ../lib/libtoxcore.a ../lib/libtoxav.a ../lib/libsodium.a ../lib/libopus.a ../lib/libvpx.a ../lib/libfreetype.a -lm -lz -ldl -shared -o ./tmp/libs/armeabi/libn.so /aapt package -f -M ./android/AndroidManifest.xml -S ./android/res -I $SDK_PATH/platforms/android-10/android.jar -F ./tmp/tmp1.apk -J ./tmp/java javac -d ./tmp/java ./tmp/java/R.java dx --dex --output=./tmp/classes.dex ./tmp/java java -classpath $SDK_PATH/tools/lib/sdklib.jar com.android.sdklib.build.ApkBuilderMain ./tmp/tmp2.apk -u -z ./tmp/tmp1.apk -f ./tmp/classes.dex -nf ./tmp/libs jarsigner -sigalg SHA1withRSA -digestalg SHA1 -keystore ./tmp/debug.keystore -storepass $PASSWORD ./tmp/tmp2.apk $ALIAS ``` Come to think of it, this section is woefully out of date. The android build script in tools/ is likely to be more helpful at this point. Or come to [#utox on Freenode](https://webchat.freenode.net/?channels=#utox) and ask for grayhatter. If you're interested in working on android. He'll get you a build enviroment set up! uTox-0.17.1/docs/COCOA.md000066400000000000000000000041351354126257400146510ustar00rootroot00000000000000# uTox-cocoa specific notes * 10.10 SDK is required to build, but the product should be compatible back to 10.7. * Support for Mavericks SDK is TODO (ifdef out 10.10 bits) * Please make sure your dependencies are built with the lowest `MACOSX_DEPLOYMENT_TARGET` possible * The gameplan for 10.6 is to just replace AVFoundation with QTKit equivalents. * 32-bit support would be nice too (PowerPC is probably too much) * Build an OS X .app package by using `make uTox.app`. * Some features will not work unless you run from a `.app`. These include desktop notifications and the dock icon (???). * An Xcode project file is TODO * It is recommended to define `UTOX_COCOA_BRAVE` while building for release. It will disable some basic sanity checks which should always pass if the code is correct. * You can instruct uTox to use Yosemite blur as a UI element colour in utox_theme.ini by (not implemented currently) * When filing issues directly related to uTox-cocoa, please @stal888 in your issue so I get notified. ## How to compile dependencies ### with Homebrew ```bash brew tap tox/tox brew install --only-dependencies --HEAD utox ``` ### with Autotools ```bash git clone git://github.com/jedisct1/libsodium.git cd libsodium git checkout tags/1.0.3 ./autogen.sh ./configure && make check make install cd .. git clone git://github.com/irungentoo/filter_audio.git cd filter_audio make make install cd .. git clone git://github.com/TokTok/c-toxcore.git cd c-toxcore cmake . make make install cd .. ``` ## How to compile uTox ```bash git clone --recursive git://github.com/uTox/uTox.git cd uTox mkdir build cd build cmake .. make ``` ### How to install uTox ```bash sudo make install ``` ### How to create a DMG for distribution ```bash cmake .. -DUTOX_STATIC=ON make sudo make package ``` Done! ## How to create an Xcode project 1. Install the [dependencies](#how-to-compile-dependencies) ```bash git clone --recursive git://github.com/uTox/uTox.git cd uTox mkdir build cd build cmake -GXcode .. xcodebuild -configuration Release ``` ## Adding to uTox-cocoa * Please keep your C straight uTox-0.17.1/docs/DEPENDENCIES.md000066400000000000000000000061431354126257400156540ustar00rootroot00000000000000# Dependencies Before trying to compile uTox make sure you have all of the required dependencies. ## Operating Systems - [Linux](#linux) - [FreeBSD and DragonFlyBSD](#freebsd-and-dragonflybsd) - [OpenBSD and NetBSD](#openbsd-and-netbsd) - [Windows](#windows) - [OSX](#osx) ## Linux | Name | Required | |--------------|-----------------------| | cmake >= 3.2 | yes | | check | no (needed for tests) | | dbus | no | | filter_audio | no | | freetype | yes | | GTK | no (runtime only) | | opus | yes | | libvpx | yes | | openal | yes | | toxcore | yes | | v4l | yes | | xext | yes | | xrender | yes | | libsodium | yes | ## FreeBSD and DragonFlyBSD | Name | Required | |--------------|-----------------------| | cmake >= 3.2 | yes | | check | no (needed for tests) | | dbus | no | | filter_audio | no | | freetype | yes | | GTK | no (runtime only) | | opus | yes | | libvpx | yes | | openal-soft | yes | | libv4l | yes | | v4l\_compat | yes | | toxcore | yes | | xrender | yes | | xext | yes | | libsodium | yes | ## OpenBSD and NetBSD | Name | Required | |--------------|-----------------------| | cmake >= 3.2 | yes | | check | no (needed for tests) | | dbus | no | | filter_audio | no | | freetype | yes | | GTK | no (runtime only) | | opus | yes | | libvpx | yes | | openal | yes | | toxcore | yes | | xrender | yes | | xext | yes | | libsodium | yes | | libv4l | yes | ## Windows | Name | Required | |--------------|----------| | cmake >= 3.2 | yes | | filter_audio | no | | libvpx | yes | | openal | yes | | opus | yes | | toxcore | yes | | libsodium | yes | ## OSX | Name | Required | |--------------|-----------------------| | cmake >= 3.2 | yes | | filter_audio | no | | libvpx | yes | | openal | yes | | opus | yes | | toxcore | yes | | check | no (needed for tests) | | libsodium | yes | uTox-0.17.1/docs/INSTALL.md000066400000000000000000000052211354126257400151300ustar00rootroot00000000000000# Install The following steps install μTox on your computron/toaster/carrier pigeon. This guide gets you running ASAP. It mostly deals with precomplied binaries. If you're looking to contribute (you're the real MVP) you're probably looking for [Building](BUILD.md). For any and all of the following, you'll need to have [toxcore](https://github.com/TokTok/c-toxcore) installed first. - [Unix-like](#unix-like) - [macOS](#macOS) - [Windows](#windows) - [Android](#android) ## Unix-like Please make sure you have all of the required [dependencies](DEPENDENCIES.md). 1. First compile: ```bash mkdir build cd build cmake .. make ``` 2. Then install: ```bash sudo make install ``` If make/install really isn't your thing, you can try some precomplied binaries. - [amd64](https://build.tox.chat/job/uTox_build_linux_x86-64_release/lastSuccessfulBuild/artifact/utox_linux_x86-64.tar.xz) - [i686](https://build.tox.chat/job/uTox_build_linux_x86_release/lastSuccessfulBuild/artifact/utox_linux_x86.tar.xz) ### Archlinux If you're lucky enough to use Archlinux, uTox is in the community repo. - [x86_64](https://www.archlinux.org/packages/community/x86_64/utox/) - [i686](https://www.archlinux.org/packages/community/i686/utox/) Install by running: ```bash sudo pacman -S utox ``` ### Slackware If you use Slackware you can download the slack build from here: https://slackbuilds.org/repository/14.2/network/uTox/ ## OpenBSD Right now no one is providing binaries. You will have to compile uTox. See [instructions](BUILD.md#openbsd). ## FreeBSD You can install uTox using `pkg`. Install using: ```bash sudo pkg install utox ``` ## macOS You can download the latest dmg from here: https://github.com/uTox/uTox/releases. If there is no current version you can try and [build it](BUILD.md#macOS) or ask @publicarray to provide a new build. Install using homebrew cask: ```bash brew cask install utox ``` ## Windows Installing on windows isn't really a thing yet... you can download the nighties. They should just work. - [32-bit](https://build.tox.chat/job/uTox_build_windows_x86_release/lastSuccessfulBuild/artifact/utox_windows_x86.zip) - [64-bit](https://build.tox.chat/job/uTox_build_windows_x86-64_release/lastSuccessfulBuild/artifact/utox_windows_x86-64.zip) - Updater (delayed, ask grayhatter for it, and it'll happen) ## Android Install uTox from the Google Play Store or download the APK: [uTox.apk](https://build.tox.chat/job/uTox_build_android_armhf_release/lastSuccessfulBuild/artifact/uTox.apk) # Meta [Jenkins](https://build.tox.chat) offers automatically compiled binaries. All files below link to the last successful build. uTox-0.17.1/docs/stable-checklist.md000066400000000000000000000021241354126257400172420ustar00rootroot00000000000000# uTox new stable version checklist ## Last mile - [ ] Version Tick - [ ] GUI changelog - [ ] Host changelog - [ ] Travis passes all systems - [ ] Android compiles ## Important Windows binary delivery checks - [ ] Fresh profile can update - [ ] Existing profile can update - [ ] Update can abort - [ ] Update aborts if version is older ## File Transfers ### 1st level - [ ] Files in - [ ] Files out - [ ] Images in - [ ] Images out - [ ] Avatars in - [ ] Avatars out ### 2nd level - [ ] Reject transfer - [ ] Accept transfer - [ ] Pause transfer - [ ] Resume transfer - [ ] Cancel transfer - [ ] Break on friend offline - [ ] Resume on friend online - [ ] Autostart in-progress on friend online - [ ] Autostart for selected friends ## Avatars - [ ] Self load - [ ] Self save - [ ] Self remove - [ ] Self remove sent to friend - [ ] Friend load - [ ] Friend new incoming - [ ] Friend new deleted ## Text - [ ] ## Audio - [ ] ## Video - [ ] ## Encrypted profile - [ ] ## Toxcore interface - [ ] Enable/Disable IPv6 - [ ] Enable/Disable UDP - [ ] Enable/Disable Proxy - [ ] Enable/Disable Force Proxy uTox-0.17.1/docs/utox_theme.ini000066400000000000000000000053141354126257400163650ustar00rootroot00000000000000# This is an example uTox theme. # Copy it to ~/.config/tox/utox_theme.ini or %APPDATA%\tox\utox_theme.ini # A list of elements you can color is available in theme.h # Colors are specified in uppercase hex #---- Main chat area ---- COLOR_MAIN_BACKGROUND = FFFFFF COLOR_MAIN_TEXT = 333333 COLOR_MAIN_CHATTEXT = 000000 COLOR_MAIN_SUBTEXT = 414141 COLOR_MAIN_ACTIONTEXT = 4E4EC8 COLOR_MAIN_QUOTETEXT = 008000 COLOR_MAIN_URLTEXT = 001FFF COLOR_MAIN_HINTTEXT = 969696 #---- Friend list header and bottom-left buttons ---- COLOR_MENU_BACKGROUND = 1C1C1C COLOR_MENU_TEXT = FFFFFF COLOR_MENU_SUBTEXT = D1D1D1 COLOR_MENU_HOVER_BACKGROUND = 282828 COLOR_MENU_ACTIVE_BACKGROUND = 414141 COLOR_MENU_ACTIVE_TEXT = FFFFFF #---- Friend list ---- COLOR_LIST_BACKGROUND = 414141 COLOR_LIST_HOVER_BACKGROUND = 505050 COLOR_LIST_TEXT = FFFFFF COLOR_LIST_SUBTEXT = D1D1D1 #---- Groupchat user list and title ---- COLOR_GROUP_SELF = 6BC260 COLOR_GROUP_PEER = 969696 COLOR_GROUP_AUDIO = C84E4E COLOR_GROUP_MUTED = 4E4EC8 #---- Text selection ---- COLOR_SELECTION_BACKGROUND = 333333 COLOR_SELECTION_TEXT = FFFFFF #---- Inputs, dropdowns & tooltips ---- COLOR_EDGE_NORMAL = C0C0C0 COLOR_EDGE_HOVER = 969696 COLOR_EDGE_ACTIVE = 4EA6EA COLOR_ACTIVEOPTION_BACKGROUND = D1D1D1 COLOR_ACTIVEOPTION_TEXT = 333333 #---- Auxiliary style for inputs/dropdowns ("Search friends" bar) ---- COLOR_AUX_BACKGROUND = 313131 COLOR_AUX_EDGE_NORMAL = 313131 COLOR_AUX_EDGE_HOVER = 999999 COLOR_AUX_EDGE_ACTIVE = 1A73B7 COLOR_AUX_TEXT = FFFFFF COLOR_AUX_ACTIVEOPTION_BACKGROUND = 505050 COLOR_AUX_ACTIVEOPTION_TEXT = FFFFFF #---- Status circles ---- COLOR_STATUS_ONLINE = 6BC260 COLOR_STATUS_AWAY = CEBF45 COLOR_STATUS_BUSY = C84E4E #---- Buttons ---- COLOR_BUTTON_SUCCESS_BACKGROUND = 6BC260 COLOR_BUTTON_SUCCESS_TEXT = FFFFFF COLOR_BUTTON_SUCCESS_HOVER_BACKGROUND = 76D56A COLOR_BUTTON_SUCCESS_HOVER_TEXT = FFFFFF COLOR_BUTTON_WARNING_BACKGROUND = CEBF45 COLOR_BUTTON_WARNING_TEXT = FFFFFF COLOR_BUTTON_WARNING_HOVER_BACKGROUND = E3D24C COLOR_BUTTON_WARNING_HOVER_TEXT = FFFFFF COLOR_BUTTON_DANGER_BACKGROUND = C84E4E COLOR_BUTTON_DANGER_TEXT = FFFFFF COLOR_BUTTON_DANGER_HOVER_BACKGROUND = DC5656 COLOR_BUTTON_DANGER_HOVER_TEXT = FFFFFF COLOR_BUTTON_DISABLED_BACKGROUND = D1D1D1 COLOR_BUTTON_DISABLED_TEXT = FFFFFF COLOR_BUTTON_DISABLED_TRANSFER = 414141 COLOR_BUTTON_INPROGRESS_BACKGROUND = 4EA6EA COLOR_BUTTON_INPROGRESS_TEXT = FFFFFF uTox-0.17.1/extra/000077500000000000000000000000001354126257400136735ustar00rootroot00000000000000uTox-0.17.1/extra/common/000077500000000000000000000000001354126257400151635ustar00rootroot00000000000000uTox-0.17.1/extra/common/build_nacl.sh000077500000000000000000000007671354126257400176300ustar00rootroot00000000000000#/usr/bin/env zsh # install libsodium, needed for crypto if ! [ -d libsodium ]; then git clone --depth=1 --branch=stable https://github.com/jedisct1/libsodium.git fi cd libsodium git rev-parse HEAD > libsodium.sha if ! ([ -f "$CACHE_DIR/libsodium.sha" ] && diff "$CACHE_DIR/libsodium.sha" libsodium.sha); then ./autogen.sh ./configure "$TARGET_HOST" \ --prefix="$CACHE_DIR/usr" make -j`nproc` make install mv libsodium.sha "$CACHE_DIR/libsodium.sha" fi cd .. rm -rf libsodium uTox-0.17.1/extra/common/build_openal.sh000077500000000000000000000022401354126257400201550ustar00rootroot00000000000000#/usr/bin/env zsh # # openal is a windows thing, just fyi if ! [ -d openal ]; then git clone --depth=1 https://github.com/irungentoo/openal-soft-tox.git openal fi cd openal git rev-parse HEAD > openal.sha if ! ([ -f "$CACHE_DIR/openal.sha" ] && diff "$CACHE_DIR/openal.sha" openal.sha ); then mkdir -p build cd build echo " set(CMAKE_SYSTEM_NAME Windows) set(CMAKE_C_COMPILER i686-w64-mingw32-gcc) set(CMAKE_CXX_COMPILER i686-w64-mingw32-g++) set(CMAKE_RC_COMPILER i686-w64-mingw32-windres) set(CMAKE_FIND_ROOT_PATH $CACHE_DIR ) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)" > ./Toolchain-i686-w64-mingw32.cmake cmake .. -DCMAKE_TOOLCHAIN_FILE=./Toolchain-i686-w64-mingw32.cmake \ -DCMAKE_PREFIX_PATH="$CACHE_DIR/usr" \ -DCMAKE_INSTALL_PREFIX="$CACHE_DIR/usr" \ -DLIBTYPE="STATIC" \ -DCMAKE_BUILD_TYPE=Debug \ -DDSOUND_INCLUDE_DIR=/usr/i686-w64-mingw32/include \ -DDSOUND_LIBRARY=/usr/i686-w64-mingw32/lib/libdsound.a make make install cd .. mv openal.sha "$CACHE_DIR/openal.sha" fi cd .. rm -rf openal uTox-0.17.1/extra/common/build_opus.sh000077500000000000000000000011611354126257400176660ustar00rootroot00000000000000#/usr/bin/env zsh OPUS_VERSION="1.2.1" # install libopus, needed for audio encoding/decoding if ! [ -f "$CACHE_DIR/usr/lib/pkgconfig/opus.pc" ]; then curl https://archive.mozilla.org/pub/opus/opus-${OPUS_VERSION}.tar.gz -o opus.tar.gz tar xzf opus.tar.gz cd opus-${OPUS_VERSION} ./configure "$TARGET_HOST" \ --prefix="$CACHE_DIR/usr" \ --disable-extra-programs \ --disable-doc make -j`nproc` make install cd .. rm -rf opus** else echo "Have Opus" ls -la "${CACHE_DIR}/usr/lib/" ls -la "${CACHE_DIR}/usr/lib/pkgconfig/" ls -la "${CACHE_DIR}/usr/include/" fi uTox-0.17.1/extra/common/build_vpx.sh000077500000000000000000000011521354126257400175150ustar00rootroot00000000000000#/usr/bin/env zsh # install libvpx, needed for video encoding/decoding if ! [ -d libvpx ]; then git clone --depth=1 --branch=v1.6.0 https://chromium.googlesource.com/webm/libvpx fi cd libvpx git rev-parse HEAD > libvpx.sha if ! ([ -f "${CACHE_DIR}/libvpx.sha" ] && diff "${CACHE_DIR}/libvpx.sha" libvpx.sha); then ./configure "$TARGET_TRGT" \ --prefix="${CACHE_DIR}/usr" \ --enable-static \ --disable-examples \ --disable-unit-tests \ --disable-shared make -j8 make install mv libvpx.sha "${CACHE_DIR}/libvpx.sha" fi cd .. rm -rf libvpx uTox-0.17.1/extra/common/env.sh000077500000000000000000000011641354126257400163140ustar00rootroot00000000000000#!/bin/sh export CTEST_OUTPUT_ON_FAILURE=1 export CACHE_DIR=${CACHE_DIR=""} export TOXCORE_REPO=${TOXCORE_REPO:-"TokTok/c-toxcore"} export TOXCORE_REPO_URI="https://github.com/TokTok/c-toxcore.git" export TOXCORE_REPO_BRANCH=${TOXCORE_REPO_BRANCH:-"master"} export CFLAGS="-I${CACHE_DIR}/usr/include -I${CACHE_DIR}/usr/include/opus" export LDFLAGS="-L${CACHE_DIR}/usr/lib" export LD_LIBRARY_PATH="${CACHE_DIR}/usr/lib:/usr/lib" export PKG_CONFIG_PATH="${CACHE_DIR}/usr/lib/pkgconfig" # Cross compilation default targets. export TARGET_HOST=${TARGET_HOST:-""} export TARGET_TRGT=${TARGET_TRGT:-""} export MAKEFLAGS="-j8" uTox-0.17.1/extra/common/filter_audio.sh000077500000000000000000000006721354126257400201750ustar00rootroot00000000000000#!/bin/sh set -eux . ./extra/common/env.sh if ! [ -d filter_audio ]; then git clone --depth=1 https://github.com/irungentoo/filter_audio fi cd filter_audio git rev-parse HEAD > filter_audio.sha if ! ([ -f "$CACHE_DIR/filter_audio.sha" ] && diff "$CACHE_DIR/filter_audio.sha" filter_audio.sha); then make PREFIX="${CACHE_DIR}/usr/" make install mv filter_audio.sha "$CACHE_DIR/filter_audio.sha" fi cd .. rm -rf filter_audio uTox-0.17.1/extra/common/get_missing_translations.py000066400000000000000000000034201354126257400226450ustar00rootroot00000000000000import re import urllib.request import os def readFileFromUrl(url): try: request = urllib.request.urlopen(url) result = request.read().decode('utf-8') return result except: print('Error getting file from url: ' + url + '\n') return '' def getStringConsts(lang): print('Getting string consts for ' + lang, end='\n') langFile = readFileFromUrl('https://raw.githubusercontent.com/uTox/uTox/develop/langs/'+ lang + '.h') constsFinder = re.compile('msgid\((\w+)\)') consts = constsFinder.findall(langFile) return consts def getMissingConsts(referenceConsts, translateArr): missingConsts = [] for reference in referenceConsts: if reference not in translateArr: missingConsts.append(reference) return missingConsts def writeReportForLangToFile(file, lang, consts): print('Writing report for ' + lang, end='\n') with open(file, "a") as report: report.write('---------------------------\nMissing translations for ' + lang + ':\n---------------------------\n') for const in consts: report.write(const + '\n') report.write('\n') os.chdir(os.path.dirname(__file__)) reportFile = os.path.join(os.getcwd(), 'utox_missing_translations_report.txt') langs = [] referenceLang = 'en' langsStr = readFileFromUrl('https://raw.githubusercontent.com/uTox/uTox/develop/langs/i18n_decls.h') finder = re.compile('\s+LANG_(\w{2}),') referenceConsts = getStringConsts(referenceLang) for match in finder.findall(langsStr): lang = match.lower() if lang != referenceLang: langConsts = getStringConsts(lang) missingConsts = getMissingConsts(referenceConsts, langConsts) writeReportForLangToFile(reportFile, lang, missingConsts) print('Report generated') uTox-0.17.1/extra/common/set-nightly-build-warning.sh000066400000000000000000000021351354126257400225270ustar00rootroot00000000000000#!/bin/sh WARNING='NIGHTLY BUILD FOR TESTING PURPOSES ONLY' LANG_REGEX='msgid\(UTOX_SETTINGS\)' replace_in_branding() { sed -i "s/#define TITLE \"uTox/& ${WARNING}/" $1 } replace_in_lang() { need_replace=0 while read str; do if [ $need_replace -eq 1 ]; then # everything BEFORE second double quote start=$(echo $str | awk -F\" '{printf "%s\"%s", $1, $2}') # everything AFTER second double quote end=$(echo $str | awk -F\" -vOFS='\"' '{ $1 = $2 = ""; print }' | cut -c 2- ) # insert warning after translation string sed -i "s|${str}|${start} ${WARNING}${end}|" $1 fi if [[ $str =~ $LANG_REGEX ]]; then need_replace=1 else need_replace=0 fi done < $1 } SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" # replace in lang files for lang in $SCRIPTPATH/../../langs/*; do replace_in_lang $lang done # replace in branding files replace_in_branding $(realpath $SCRIPTPATH/../../src/branding.h) replace_in_branding $(realpath $SCRIPTPATH/../../src/branding.h.in) uTox-0.17.1/extra/gitlab/000077500000000000000000000000001354126257400151355ustar00rootroot00000000000000uTox-0.17.1/extra/gitlab/debug_failure.sh000077500000000000000000000007111354126257400202700ustar00rootroot00000000000000#!/usr/bin/env bash set -eux . ./extra/gitlab/env.sh echo "======================================================" echo "== DEBUGING FAILURE " echo "======================================================" echo "" echo "" echo $HOME echo $CACHE_DIR ls -la $CACHE_DIR echo "" ls -la $CACHE_DIR/usr echo "" echo "" echo $CFLAGS echo $LDFLAGS ls -la $LD_LIBRARY_PATH echo "" echo "" ls -la $CACHE_DIR/usr/include echo "" ls -la $CACHE_DIR/usr/lib echo "" uTox-0.17.1/extra/gitlab/env.sh000077500000000000000000000002001354126257400162540ustar00rootroot00000000000000#!/bin/sh export CACHE_DIR=`pwd`/cache/$GL_BUILD mkdir -p $CACHE_DIR || true . ./extra/common/env.sh export CLICOLOR_FORCE=1 uTox-0.17.1/extra/gitlab/linux-before.sh000077500000000000000000000021431354126257400200730ustar00rootroot00000000000000#!/bin/sh set -eux . ./extra/gitlab/env.sh . ./extra/common/build_nacl.sh . ./extra/common/build_opus.sh # install libvpx, needed for video encoding/decoding if ! [ -d libvpx ]; then git clone --depth=1 --branch=v1.6.0 https://chromium.googlesource.com/webm/libvpx fi cd libvpx git rev-parse HEAD > libvpx.sha if ! ([ -f "$CACHE_DIR/libvpx.sha" ] && diff "$CACHE_DIR/libvpx.sha" libvpx.sha); then ./configure --prefix=$CACHE_DIR/usr \ --enable-shared \ --disable-unit-tests \ --disable-install-docs \ --disable-examples make -j`nproc` make install mv libvpx.sha "$CACHE_DIR/libvpx.sha" fi cd .. rm -rf libvpx # install toxcore if ! [ -d toxcore ]; then git clone --depth=1 --branch=master https://github.com/$TOXCORE_REPO.git toxcore fi cd toxcore git rev-parse HEAD > toxcore.sha if ! ([ -f "$CACHE_DIR/toxcore.sha" ] && diff "$CACHE_DIR/toxcore.sha" toxcore.sha); then cmake -B_build -H. -DCMAKE_INSTALL_PREFIX:PATH=$CACHE_DIR/usr make -C_build -j`nproc` make -C_build install mv toxcore.sha "$CACHE_DIR/toxcore.sha" fi cd .. rm -rf toxcore uTox-0.17.1/extra/gitlab/linux-muslc-before.sh000077500000000000000000000014541354126257400212200ustar00rootroot00000000000000#!/bin/sh set -eux . ./extra/gitlab/env.sh export TARGET_TRGT="--enable-pic " export CFLAGS="${CFLAGS} -fPIC" . ./extra/common/build_nacl.sh . ./extra/common/build_opus.sh . ./extra/common/build_vpx.sh # install toxcore rm -rf toxcore git clone --depth=1 --branch=$TOXCORE_REPO_BRANCH $TOXCORE_REPO_URI toxcore cd toxcore git rev-parse HEAD > toxcore.sha if ! ([ -f "$CACHE_DIR/toxcore.sha" ] && diff "$CACHE_DIR/toxcore.sha" toxcore.sha); then mkdir _build cmake -B_build -H. \ -DCMAKE_INSTALL_PREFIX:PATH=$CACHE_DIR/usr \ -DENABLE_STATIC=ON \ -DENABLE_SHARED=OFF \ -DBUILD_TOXAV=ON \ -DPKG_CONFIG_EXECUTABLE=/usr/bin/pkg-config make -C_build -j`nproc` || make VERBOSE=1 make -C_build install mv toxcore.sha "$CACHE_DIR/toxcore.sha" fi cd .. rm -rf toxcore uTox-0.17.1/extra/gitlab/linux-muslc-script.sh000077500000000000000000000006071354126257400212610ustar00rootroot00000000000000#!/bin/sh set -e -u -x . ./extra/gitlab/env.sh mkdir build cd build cmake .. -DCMAKE_INCLUDE_PATH=$CACHE_DIR/usr/lib \ -DUTOX_STATIC=ON \ -DTOXCORE_STATIC=ON \ -DCMAKE_COLOR_MAKEFILE=ON \ -DENABLE_TESTS=ON \ -DENABLE_WERROR=ON \ -DENABLE_ASAN=OFF \ -DENABLE_FILTERAUDIO=OFF \ -DENABLE_DBUS=OFF make || make VERBOSE=1 uTox-0.17.1/extra/gitlab/linux-script.sh000077500000000000000000000004461354126257400201410ustar00rootroot00000000000000#!/bin/sh set -e -u -x . ./extra/gitlab/env.sh mkdir build cd build cmake .. \ -DCMAKE_INCLUDE_PATH="$CACHE_DIR/usr/include" \ -DCMAKE_LIBRARY_PATH="$CACHE_DIR/usr/lib" \ -DCMAKE_COLOR_MAKEFILE=ON \ -DENABLE_TESTS=ON \ -DENABLE_AUTOUPDATE=ON \ -DENABLE_WERROR=ON make uTox-0.17.1/extra/gitlab/osx-before.sh000077500000000000000000000020311354126257400175410ustar00rootroot00000000000000#!/bin/sh set -eux brew install yasm . ./extra/gitlab/env.sh . ./extra/common/build_nacl.sh . ./extra/common/build_opus.sh # install libvpx, needed for video encoding/decoding if ! [ -d libvpx ]; then git clone --depth=1 --branch=v1.6.0 https://chromium.googlesource.com/webm/libvpx fi cd libvpx git rev-parse HEAD > libvpx.sha if ! ([ -f "$CACHE_DIR/libvpx.sha" ] && diff "$CACHE_DIR/libvpx.sha" libvpx.sha); then ./configure --prefix=$CACHE_DIR/usr --enable-shared make -j`sysctl -n hw.ncpu` make install mv libvpx.sha "$CACHE_DIR/libvpx.sha" fi cd .. rm -rf libvpx # install toxcore if ! [ -d toxcore ]; then git clone --depth=1 --branch=$TOXCORE_REPO_BRANCH $TOXCORE_REPO_URI toxcore fi cd toxcore git rev-parse HEAD > toxcore.sha if ! ([ -f "$CACHE_DIR/toxcore.sha" ] && diff "$CACHE_DIR/toxcore.sha" toxcore.sha); then mkdir _build cmake -B_build -H. -DCMAKE_INSTALL_PREFIX:PATH=$CACHE_DIR/usr make -C_build -j`sysctl -n hw.ncpu` make -C_build install mv toxcore.sha "$CACHE_DIR/toxcore.sha" fi cd .. rm -rf toxcore uTox-0.17.1/extra/gitlab/osx-docker.sh000077500000000000000000000061161354126257400175560ustar00rootroot00000000000000#!/bin/sh set -eu export GL_BUILD="macos" . ./extra/gitlab/env.sh mkdir -p ${CACHE_DIR}/usr/lib mkdir -p ${CACHE_DIR}/usr/include export TARGET_HOST="--host=x86_64-apple-darwin14" export TARGET_TRGT="--target=x86_64-darwin14-gcc" export CFLAGS="${CFLAGS} -m64 " export CFLAGS="${CFLAGS} -I/workdir/cache/macos/usr/include " export CFLAGS="${CFLAGS} -I${CACHE_DIR}/usr/include " export CFLAGS="${CFLAGS} -isystem /workdir/cache/macos/usr/include " export CFLAGS="${CFLAGS} -isystem /workdir/cache/macos/usr/include/opus " export CFLAGS="${CFLAGS} -isysroot /usr/osxcross/bin/../SDK/MacOSX10.10.sdk " export CFLAGS="${CFLAGS} -mmacosx-version-min=10.10 " export CFLAGS="${CFLAGS} -m64 -arch x86_64 -DNDEBUG -O3 -Wall" export CFLAGS="${CFLAGS} -Wno-unused-parameter" export CFLAGS="${CFLAGS} -Wno-missing-braces" export LDFLAGS="${LDFLAGS} -L/workdir/cache/macos/usr/lib " export LDFLAGS="${LDFLAGS} -L${CACHE_DIR}/usr/lib " export LDFLAGS="${LDFLAGS} -isysroot /usr/osxcross/bin/../SDK/MacOSX10.10.sdk " export LDFLAGS="${LDFLAGS} -mmacosx-version-min=10.10 -m64 -arch x86_64" # install libsodium, needed for crypto if ! [ -d libsodium ]; then git clone --depth=1 --branch=stable https://github.com/jedisct1/libsodium.git fi cd libsodium git rev-parse HEAD > libsodium.sha if ! ([ -f "$CACHE_DIR/libsodium.sha" ] && diff "$CACHE_DIR/libsodium.sha" libsodium.sha); then ./autogen.sh ./configure $TARGET_HOST \ --prefix="$CACHE_DIR/usr" \ --quiet # libtool is broken when it comes to spaces in vars, so we have to neuter them # I live in backslash escapement hell... # This is also why we can't use ../common/* find . -type f -exec sed -i 's/libsodium\\\\ 1.0.12/libnacl-str/g' {} + make -j8 make install mv libsodium.sha "$CACHE_DIR/libsodium.sha" fi cd .. # rm -rf libsodium . ./extra/common/build_opus.sh . ./extra/common/build_vpx.sh # install toxcore if ! [ -d toxcore ]; then git clone --depth=1 --branch=$TOXCORE_REPO_BRANCH $TOXCORE_REPO_URI toxcore fi cd toxcore git rev-parse HEAD > toxcore.sha if ! ([ -f "$CACHE_DIR/toxcore.sha" ] && diff "$CACHE_DIR/toxcore.sha" toxcore.sha); then if [ -d _build ]; then rm -rf _build fi find . -type f -exec sed -i 's/BUILD_TOXAV FALSE/BUILD_TOXAV TRUE/g' {} + # OSXCROSS is trying to be fancy, it's also wrong. # We can't use a common build_toxcore.sh because we need to # be able to set our own PKG_CONFIG_EXE cmake -B_build -H. \ -DCMAKE_INSTALL_PREFIX:PATH=$CACHE_DIR/usr \ -DENABLE_STATIC=ON \ -DENABLE_SHARED=OFF \ -DCMAKE_SYSTEM_NAME=Darwin \ -DBUILD_TOXAV=ON \ -DPKG_CONFIG_EXECUTABLE=/usr/bin/pkg-config # mkdir _build # autoreconf -fi # (cd _build && ../configure --prefix=$CACHE_DIR/usr) make -C_build || make -C_build VERBOSE=1 make -C_build install mv toxcore.sha "$CACHE_DIR/toxcore.sha" fi cd .. # rm -rf toxcore ls -la $CACHE_DIR cmake . -DCMAKE_SYSTEM_NAME=Darwin \ -DENABLE_ASAN=OFF \ -DENABLE_FILTERAUDIO=OFF \ -DUTOX_STATIC=OFF \ -DTOXCORE_STATIC=ON \ -DENABLE_TESTS=OFF \ -DENABLE_WERROR=OFF make uTox-0.17.1/extra/gitlab/osx-script.sh000077500000000000000000000003211354126257400176030ustar00rootroot00000000000000#!/bin/sh set -eux . ./extra/gitlab/env.sh cmake . \ -DCMAKE_INCLUDE_PATH="$CACHE_DIR/usr/include" \ -DCMAKE_LIBRARY_PATH="$CACHE_DIR/usr/lib" \ -DENABLE_TESTS=OFF -DENABLE_WERROR=OFF make VERBOSE=1 uTox-0.17.1/extra/gitlab/windows-before.sh000077500000000000000000000044151354126257400204320ustar00rootroot00000000000000#!/bin/sh set -eux . ./extra/gitlab/env.sh export TARGET_HOST="--host=x86_64-w64-mingw32" export TARGET_TRGT="--target=x86_64-win32-gcc" export CROSS="x86_64-w64-mingw32-" . ./extra/common/build_nacl.sh . ./extra/common/build_opus.sh . ./extra/common/build_vpx.sh # install toxcore git clone --depth=1 --branch=$TOXCORE_REPO_BRANCH $TOXCORE_REPO_URI toxcore cd toxcore git rev-parse HEAD > toxcore.sha if ! ([ -f "$CACHE_DIR/toxcore.sha" ] && diff "$CACHE_DIR/toxcore.sha" toxcore.sha); then mkdir _build cmake -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc \ -B_build \ -H. \ -DCMAKE_INSTALL_PREFIX:PATH=$CACHE_DIR/usr \ -DENABLE_SHARED=OFF \ -DENABLE_STATIC=ON make -C_build -j`nproc` make -C_build install mv toxcore.sha "$CACHE_DIR/toxcore.sha" fi cd .. rm -rf toxcore if ! [ -d openal ]; then git clone --depth=1 https://github.com/irungentoo/openal-soft-tox.git openal fi cd openal git rev-parse HEAD > openal.sha if ! ([ -f "$CACHE_DIR/openal.sha" ] && diff "$CACHE_DIR/openal.sha" openal.sha ); then mkdir -p build cd build echo " set(CMAKE_SYSTEM_NAME Windows) set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) set(CMAKE_FIND_ROOT_PATH $CACHE_DIR ) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)" > ./Toolchain-x86_64-w64-mingw32.cmake cmake .. -DCMAKE_TOOLCHAIN_FILE=./Toolchain-x86_64-w64-mingw32.cmake \ -DCMAKE_PREFIX_PATH="$CACHE_DIR/usr" \ -DCMAKE_INSTALL_PREFIX="$CACHE_DIR/usr" \ -DLIBTYPE="STATIC" \ -DCMAKE_BUILD_TYPE=Debug \ -DDSOUND_INCLUDE_DIR=/usr/x86_64-w64-mingw32/include \ -DDSOUND_LIBRARY=/usr/x86_64-w64-mingw32/lib/libdsound.a make make install cd .. mv openal.sha "$CACHE_DIR/openal.sha" fi cd .. rm -rf openal export CC=x86_64-w64-mingw32-gcc . ./extra/common/filter_audio.sh x86_64-w64-mingw32-ranlib $CACHE_DIR/usr/lib/libfilteraudio.a unset CC cp $CACHE_DIR/usr/lib/libOpenAL32.a $CACHE_DIR/usr/lib/libopenal.a || true if [ ! -f "$CACHE_DIR/usr/lib/libshell32.a" ] then; curl https://cmdline.org/travis/64/shell32.a > "$CACHE_DIR/usr/lib/libshell32.a" fi uTox-0.17.1/extra/gitlab/windows-script.sh000077500000000000000000000006071354126257400204730ustar00rootroot00000000000000#!/bin/sh set -eux . ./extra/gitlab/env.sh export CFLAGS="-I$CACHE_DIR/usr/include -I/usr/share/mingw-w64/include/ " mkdir build_win cd build_win cmake .. \ -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchain-win64.cmake \ -DCMAKE_INCLUDE_PATH="$CACHE_DIR/usr/include" \ -DCMAKE_LIBRARY_PATH="$CACHE_DIR/usr/lib" \ -DENABLE_TESTS=OFF \ -DENABLE_WERROR=ON make || make VERBOSE=1 uTox-0.17.1/extra/gitlab/windows_legacy-before.sh000077500000000000000000000030511354126257400217510ustar00rootroot00000000000000#!/bin/sh set -eux . ./extra/gitlab/env.sh export TARGET_HOST="--host=i686-w64-mingw32" export TARGET_TRGT="--target=x86-win32-gcc" export CROSS="i686-w64-mingw32-" . ./extra/common/build_nacl.sh . ./extra/common/build_opus.sh . ./extra/common/build_vpx.sh # install toxcore rm -rf toxcore git clone --depth=1 --branch=$TOXCORE_REPO_BRANCH $TOXCORE_REPO_URI toxcore cd toxcore git rev-parse HEAD > toxcore.sha if ! ([ -f "$CACHE_DIR/toxcore.sha" ] && diff "$CACHE_DIR/toxcore.sha" toxcore.sha); then rm -rf _build || true mkdir _build cmake -DCMAKE_C_COMPILER=i686-w64-mingw32-gcc \ -DCMAKE_CXX_COMPILER=i686-w64-mingw32-g++ \ -DCMAKE_RC_COMPILER=i686-w64-mingw32-windres \ -DCMAKE_SYSTEM_NAME=Windows \ -DCMAKE_FIND_ROOT_PATH=$CACHE_DIR \ -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \ -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \ -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \ -DCMAKE_INSTALL_PREFIX:PATH=$CACHE_DIR/usr \ -DENABLE_SHARED=OFF \ -DCOMPILE_AS_CXX=OFF \ -DBOOTSTRAP_DAEMON=OFF \ -B_build -H. make -C_build -j`nproc` || make -C_build VERBOSE=1 make -C_build install mv toxcore.sha "$CACHE_DIR/toxcore.sha" fi cd .. rm -rf toxcore . ./extra/common/build_openal.sh export CC=i686-w64-mingw32-gcc . ./extra/common/filter_audio.sh i686-w64-mingw32-ranlib $CACHE_DIR/usr/lib/libfilteraudio.a unset CC cp $CACHE_DIR/usr/lib/libOpenAL32.a $CACHE_DIR/usr/lib/libopenal.a || true # sudo curl https://cmdline.org/travis/32/shell32.a > $CACHE_DIR/usr/lib/libshell32.a uTox-0.17.1/extra/gitlab/windows_legacy-script.sh000077500000000000000000000007531354126257400220210ustar00rootroot00000000000000#!/bin/sh set -eux . ./extra/gitlab/env.sh export CFLAGS="-I$CACHE_DIR/usr/include -I/usr/share/mingw-w64/include/ " rm -rf build_win || true mkdir build_win cd build_win cmake .. \ -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchain-win32.cmake \ -DCMAKE_INCLUDE_PATH="$CACHE_DIR/usr/include" \ -DCMAKE_LIBRARY_PATH="$CACHE_DIR/usr/lib" \ -DWIN_XP_LEGACY=ON \ -DUTOX_STATIC=ON \ -DTOXCORE_STATIC=ON \ -DENABLE_TESTS=OFF \ -DENABLE_WERROR=OFF make || make VERBOSE=1 uTox-0.17.1/extra/travis/000077500000000000000000000000001354126257400152035ustar00rootroot00000000000000uTox-0.17.1/extra/travis/debug_failure.sh000077500000000000000000000007111354126257400203360ustar00rootroot00000000000000#!/usr/bin/env bash set -eux . ./extra/travis/env.sh echo "======================================================" echo "== DEBUGING FAILURE " echo "======================================================" echo "" echo "" echo $HOME echo $CACHE_DIR ls -la $CACHE_DIR echo "" ls -la $CACHE_DIR/usr echo "" echo "" echo $CFLAGS echo $LDFLAGS ls -la $LD_LIBRARY_PATH echo "" echo "" ls -la $CACHE_DIR/usr/include echo "" ls -la $CACHE_DIR/usr/lib echo "" uTox-0.17.1/extra/travis/env.sh000077500000000000000000000001031354126257400163240ustar00rootroot00000000000000#!/bin/sh export CACHE_DIR="$HOME/cache" . ./extra/common/env.sh uTox-0.17.1/extra/travis/filter_audio.sh000077500000000000000000000006721354126257400202150ustar00rootroot00000000000000#!/bin/sh set -eux . ./extra/travis/env.sh if ! [ -d filter_audio ]; then git clone --depth=1 https://github.com/irungentoo/filter_audio fi cd filter_audio git rev-parse HEAD > filter_audio.sha if ! ([ -f "$CACHE_DIR/filter_audio.sha" ] && diff "$CACHE_DIR/filter_audio.sha" filter_audio.sha); then make PREFIX="${CACHE_DIR}/usr/" make install mv filter_audio.sha "$CACHE_DIR/filter_audio.sha" fi cd .. rm -rf filter_audio uTox-0.17.1/extra/travis/linux-before.sh000077500000000000000000000017711354126257400201470ustar00rootroot00000000000000#!/bin/sh set -eux . ./extra/travis/env.sh . ./extra/common/build_nacl.sh . ./extra/common/build_opus.sh # install libvpx, needed for video encoding/decoding if ! [ -d libvpx ]; then git clone --depth=1 --branch=v1.6.0 https://chromium.googlesource.com/webm/libvpx fi cd libvpx git rev-parse HEAD > libvpx.sha if ! ([ -f "$CACHE_DIR/libvpx.sha" ] && diff "$CACHE_DIR/libvpx.sha" libvpx.sha); then ./configure --prefix="$CACHE_DIR/usr" --enable-shared make -j$(nproc) make install mv libvpx.sha "$CACHE_DIR/libvpx.sha" fi cd .. rm -rf libvpx # install toxcore if ! [ -d toxcore ]; then git clone --depth=1 --branch="$TOXCORE_REPO_BRANCH" "$TOXCORE_REPO_URI" toxcore fi cd toxcore git rev-parse HEAD > toxcore.sha if ! ([ -f "$CACHE_DIR/toxcore.sha" ] && diff "$CACHE_DIR/toxcore.sha" toxcore.sha); then mkdir _build cmake -B_build -H. -DCMAKE_INSTALL_PREFIX:PATH="$CACHE_DIR/usr" make -C_build -j$(nproc) make -C_build install mv toxcore.sha "$CACHE_DIR/toxcore.sha" fi cd .. rm -rf toxcore uTox-0.17.1/extra/travis/linux-script.sh000077500000000000000000000004061354126257400202030ustar00rootroot00000000000000#!/bin/sh set -e -u -x . ./extra/travis/env.sh cmake . \ -DCMAKE_INCLUDE_PATH="$CACHE_DIR/usr/include" \ -DCMAKE_LIBRARY_PATH="$CACHE_DIR/usr/lib" \ -DENABLE_TESTS=ON -DENABLE_WERROR=ON \ -DENABLE_DBUS=ON \ -DENABLE_AUTOUPDATE=ON make ./run_tests.sh uTox-0.17.1/extra/travis/osx-before.sh000077500000000000000000000021061354126257400176120ustar00rootroot00000000000000#!/bin/sh set -eux . ./extra/travis/env.sh brew update brew install yasm brew install check . ./extra/common/build_nacl.sh . ./extra/common/build_opus.sh # install libvpx, needed for video encoding/decoding if ! [ -d libvpx ]; then git clone --depth=1 --branch=v1.6.0 https://chromium.googlesource.com/webm/libvpx fi cd libvpx git rev-parse HEAD > libvpx.sha if ! ([ -f "$CACHE_DIR/libvpx.sha" ] && diff "$CACHE_DIR/libvpx.sha" libvpx.sha); then ./configure --prefix="$CACHE_DIR/usr" make -j`sysctl -n hw.ncpu` make install mv libvpx.sha "$CACHE_DIR/libvpx.sha" fi cd .. rm -rf libvpx # install toxcore if ! [ -d toxcore ]; then git clone --depth=1 --branch="$TOXCORE_REPO_BRANCH" "$TOXCORE_REPO_URI" toxcore fi cd toxcore git rev-parse HEAD > toxcore.sha if ! ([ -f "$CACHE_DIR/toxcore.sha" ] && diff "$CACHE_DIR/toxcore.sha" toxcore.sha); then mkdir _build cmake -DENABLE_SHARED=OFF -B_build -H. -DCMAKE_INSTALL_PREFIX:PATH="$CACHE_DIR/usr" make -C_build -j`sysctl -n hw.ncpu` make -C_build install mv toxcore.sha "$CACHE_DIR/toxcore.sha" fi cd .. rm -rf toxcore uTox-0.17.1/extra/travis/osx-docker.sh000077500000000000000000000056751354126257400176350ustar00rootroot00000000000000#!/bin/sh set -eux . ./extra/travis/env.sh export CFLAGS=" -m64 -I/workdir/cache/usr/include -isystem /workdir/cache/usr/include -isystem /workdir/cache/usr/include/opus -isysroot /usr/osxcross/bin/../SDK/MacOSX10.10.sdk -mmacosx-version-min=10.10 -m64 -arch x86_64 -DNDEBUG -O3 -Wall" export LDFLAGS="-L/workdir/cache/usr/lib -isysroot /usr/osxcross/bin/../SDK/MacOSX10.10.sdk -mmacosx-version-min=10.10 -m64 -arch x86_64" # brew install yasm # install libsodium, needed for crypto if ! [ -d libsodium ]; then git clone --depth=1 --branch=stable https://github.com/jedisct1/libsodium.git fi cd libsodium git rev-parse HEAD > libsodium.sha if ! ([ -f "$CACHE_DIR/libsodium.sha" ] && diff "$CACHE_DIR/libsodium.sha" libsodium.sha); then ./autogen.sh ./configure --prefix="$CACHE_DIR/usr" --host="x86_64-apple-darwin14" --quiet # libtool is broken when it comes to spaces in vars, so we have to neuter them # I live in backslash escapement hell... find . -type f -exec sed -i 's/libsodium\\\\ 1.0.11/libnacl-str/g' {} + make -j8 make install mv libsodium.sha "$CACHE_DIR/libsodium.sha" fi cd .. # rm -rf libsodium # install libopus, needed for audio encoding/decoding if ! [ -f $CACHE_DIR/usr/lib/pkgconfig/opus.pc ]; then curl https://ftp.osuosl.org/pub/xiph/releases/opus/opus-1.2.1.tar.gz -o opus.tar.gz tar xzf opus.tar.gz cd opus-1.2.1 ./configure --prefix=$CACHE_DIR/usr --host="x86_64-apple-darwin14" --disable-extra-programs --disable-doc --disable-shared make -j8 make install cd .. # rm -rf opus** fi # install libvpx, needed for video encoding/decoding if ! [ -d libvpx ]; then git clone --depth=1 --branch=v1.6.0 https://chromium.googlesource.com/webm/libvpx fi cd libvpx git rev-parse HEAD > libvpx.sha if ! ([ -f "$CACHE_DIR/libvpx.sha" ] && diff "$CACHE_DIR/libvpx.sha" libvpx.sha); then ./configure --target="x86_64-darwin14-gcc" --prefix=$CACHE_DIR/usr --enable-static --disable-examples --disable-unit-tests --disable-shared make -j8 make install mv libvpx.sha "$CACHE_DIR/libvpx.sha" fi cd .. # rm -rf libvpx # install toxcore if ! [ -d toxcore ]; then git clone --depth=1 --branch=$TOXCORE_REPO_BRANCH $TOXCORE_REPO_URI toxcore fi cd toxcore git rev-parse HEAD > toxcore.sha if ! ([ -f "$CACHE_DIR/toxcore.sha" ] && diff "$CACHE_DIR/toxcore.sha" toxcore.sha); then if [ -d _build ]; then rm -rf _build fi cmake -B_build -H. -DCMAKE_INSTALL_PREFIX:PATH=$CACHE_DIR/usr -DENABLE_STATIC=ON -DENABLE_SHARED=OFF -DCMAKE_SYSTEM_NAME=Darwin -DBUILD_TOXAV=ON # mkdir _build # autoreconf -fi # (cd _build && ../configure --prefix=$CACHE_DIR/usr) make -C_build -j8 VERBOSE=1 make -C_build install mv toxcore.sha "$CACHE_DIR/toxcore.sha" fi cd .. # rm -rf toxcore ls -la $CACHE_DIR cmake . -DCMAKE_SYSTEM_NAME=Darwin \ -DENABLE_ASAN=OFF \ -DENABLE_FILTERAUDIO=OFF \ -DUTOX_STATIC=OFF \ -DTOXCORE_STATIC=ON \ -DENABLE_TESTS=OFF \ -DENABLE_WERROR=OFF make || make VERBOSE=1 uTox-0.17.1/extra/travis/osx-script.sh000077500000000000000000000003271354126257400176570ustar00rootroot00000000000000#!/bin/sh set -eux . ./extra/travis/env.sh cmake . \ -DCMAKE_INCLUDE_PATH="$CACHE_DIR/usr/include" \ -DCMAKE_LIBRARY_PATH="$CACHE_DIR/usr/lib" \ -DENABLE_TESTS=ON \ -DENABLE_WERROR=OFF make ./run_tests.sh uTox-0.17.1/extra/travis/windows-before.sh000077500000000000000000000052631354126257400205020ustar00rootroot00000000000000#!/bin/sh set -eux . ./extra/travis/env.sh export TARGET_HOST="--host=x86_64-w64-mingw32" export TARGET_TRGT="--target=x86_64-win64-gcc" export CROSS="x86_64-w64-mingw32-" . ./extra/common/build_nacl.sh . ./extra/common/build_opus.sh . ./extra/common/build_vpx.sh # install toxcore if ! [ -d toxcore ]; then git clone --depth=1 --branch="$TOXCORE_REPO_BRANCH" "$TOXCORE_REPO_URI" toxcore fi cd toxcore git rev-parse HEAD > toxcore.sha if ! ([ -f "$CACHE_DIR/toxcore.sha" ] && diff "$CACHE_DIR/toxcore.sha" toxcore.sha); then mkdir _build cmake -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc \ -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++ \ -DCMAKE_RC_COMPILER=x86_64-w64-mingw32-windres \ -DCMAKE_SYSTEM_NAME=Windows \ -DCMAKE_FIND_ROOT_PATH="$CACHE_DIR" \ -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \ -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \ -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \ -DCMAKE_INSTALL_PREFIX:PATH="$CACHE_DIR/usr" \ -DENABLE_SHARED=OFF \ -DCOMPILE_AS_CXX=OFF \ -DBOOTSTRAP_DAEMON=OFF \ -B_build -H. make -C_build -j$(nproc) make -C_build install mv toxcore.sha "$CACHE_DIR/toxcore.sha" fi cd .. rm -rf toxcore if ! [ -d openal ]; then git clone --depth=1 https://github.com/irungentoo/openal-soft-tox.git openal fi cd openal git rev-parse HEAD > openal.sha if ! ([ -f "$CACHE_DIR/openal.sha" ] && diff "$CACHE_DIR/openal.sha" openal.sha ); then mkdir -p build cd build echo " set(CMAKE_SYSTEM_NAME Windows) set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) set(CMAKE_FIND_ROOT_PATH $CACHE_DIR ) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)" > ./Toolchain-x86_64-w64-mingw32.cmake cmake .. -DCMAKE_TOOLCHAIN_FILE=./Toolchain-x86_64-w64-mingw32.cmake \ -DCMAKE_PREFIX_PATH="$CACHE_DIR/usr" \ -DCMAKE_INSTALL_PREFIX="$CACHE_DIR/usr" \ -DLIBTYPE="STATIC" \ -DCMAKE_BUILD_TYPE=Debug \ -DDSOUND_INCLUDE_DIR=/usr/x86_64-w64-mingw32/include \ -DDSOUND_LIBRARY=/usr/x86_64-w64-mingw32/lib/libdsound.a make make install cd .. mv openal.sha "$CACHE_DIR/openal.sha" fi cd .. rm -rf openal # filter_audio export CC=x86_64-w64-mingw32-gcc . ./extra/common/filter_audio.sh x86_64-w64-mingw32-ranlib "$CACHE_DIR/usr/lib/libfilteraudio.a" unset CC cp "$CACHE_DIR/usr/lib/libOpenAL32.a" "$CACHE_DIR/usr/lib/libopenal.a" || true if ! [ -f "$CACHE_DIR/usr/lib/libshell32.a"]; then curl https://cmdline.org/libshell32.a > "$CACHE_DIR/usr/lib/libshell32.a" fi uTox-0.17.1/extra/travis/windows-script.sh000077500000000000000000000007311354126257400205370ustar00rootroot00000000000000#!/bin/sh set -eux . ./extra/travis/env.sh export CFLAGS="-I$CACHE_DIR/usr/include -I/usr/share/mingw-w64/include/ " mkdir build_win cd build_win cmake .. \ -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchain-win64.cmake \ -DCMAKE_INCLUDE_PATH="$CACHE_DIR/usr/include" \ -DCMAKE_LIBRARY_PATH="$CACHE_DIR/usr/lib" \ -DENABLE_FILTERAUDIO=OFF \ -DUTOX_STATIC=ON \ -DTOXCORE_STATIC=ON \ -DENABLE_TESTS=OFF \ -DENABLE_WERROR=OFF make || make VERBOSE=1 uTox-0.17.1/extra/travis/windows_legacy-before.sh000077500000000000000000000047201354126257400220230ustar00rootroot00000000000000#!/bin/sh set -eux . ./extra/travis/env.sh export TARGET_HOST="--host=i686-w64-mingw32" export TARGET_TRGT="--target=x86-win32-gcc" export CROSS="i686-w64-mingw32-" . ./extra/common/build_nacl.sh . ./extra/common/build_opus.sh . ./extra/common/build_vpx.sh # install toxcore if ! [ -d toxcore ]; then git clone --depth=1 --branch="$TOXCORE_REPO_BRANCH" "$TOXCORE_REPO_URI" toxcore fi cd toxcore git rev-parse HEAD > toxcore.sha if ! ([ -f "$CACHE_DIR/toxcore.sha" ] && diff "$CACHE_DIR/toxcore.sha" toxcore.sha); then mkdir _build cmake -DCMAKE_C_COMPILER=i686-w64-mingw32-gcc \ -DCMAKE_CXX_COMPILER=i686-w64-mingw32-g++ \ -DCMAKE_RC_COMPILER=i686-w64-mingw32-windres \ -DCMAKE_SYSTEM_NAME=Windows \ -DCMAKE_FIND_ROOT_PATH="$CACHE_DIR" \ -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \ -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \ -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \ -DCMAKE_INSTALL_PREFIX:PATH="$CACHE_DIR/usr" \ -DENABLE_SHARED=OFF \ -DCOMPILE_AS_CXX=OFF \ -DBOOTSTRAP_DAEMON=OFF \ -B_build -H. make -C_build -j$(nproc) make -C_build install mv toxcore.sha "$CACHE_DIR/toxcore.sha" fi cd .. rm -rf toxcore if ! [ -d openal ]; then git clone --depth=1 https://github.com/irungentoo/openal-soft-tox.git openal fi cd openal git rev-parse HEAD > openal.sha if ! ([ -f "$CACHE_DIR/openal.sha" ] && diff "$CACHE_DIR/openal.sha" openal.sha ); then mkdir -p build cd build echo " set(CMAKE_SYSTEM_NAME Windows) set(CMAKE_C_COMPILER i686-w64-mingw32-gcc) set(CMAKE_CXX_COMPILER i686-w64-mingw32-g++) set(CMAKE_RC_COMPILER i686-w64-mingw32-windres) set(CMAKE_FIND_ROOT_PATH $CACHE_DIR ) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)" > ./Toolchain-i686-w64-mingw32.cmake cmake .. -DCMAKE_TOOLCHAIN_FILE=./Toolchain-i686-w64-mingw32.cmake \ -DCMAKE_PREFIX_PATH="$CACHE_DIR/usr" \ -DCMAKE_INSTALL_PREFIX="$CACHE_DIR/usr" \ -DLIBTYPE="STATIC" \ -DCMAKE_BUILD_TYPE=Debug \ -DDSOUND_INCLUDE_DIR=/usr/i686-w64-mingw32/include \ -DDSOUND_LIBRARY=/usr/i686-w64-mingw32/lib/libdsound.a make make install cd .. mv openal.sha "$CACHE_DIR/openal.sha" fi cd .. rm -rf openal cp "$CACHE_DIR/usr/lib/libOpenAL32.a" "$CACHE_DIR/usr/lib/libopenal.a" || true # sudo curl https://cmdline.org/travis/32/shell32.a > $CACHE_DIR/usr/lib/libshell32.a uTox-0.17.1/extra/travis/windows_legacy-script.sh000077500000000000000000000007221354126257400220630ustar00rootroot00000000000000#!/bin/sh set -eux . ./extra/travis/env.sh export CFLAGS="-I$CACHE_DIR/usr/include -I/usr/share/mingw-w64/include/ " mkdir build_win cd build_win cmake .. \ -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchain-win32.cmake \ -DCMAKE_INCLUDE_PATH="$CACHE_DIR/usr/include" \ -DCMAKE_LIBRARY_PATH="$CACHE_DIR/usr/lib" \ -DWIN_XP_LEGACY=ON \ -DUTOX_STATIC=ON \ -DTOXCORE_STATIC=ON \ -DENABLE_TESTS=OFF \ -DENABLE_WERROR=OFF make || make VERBOSE=1 uTox-0.17.1/icons/000077500000000000000000000000001354126257400136635ustar00rootroot00000000000000uTox-0.17.1/icons/icon.ico000066400000000000000000000547231354126257400153220ustar00rootroot00000000000000 hF  00 %V :(  %#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%TTTT%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%TTTT%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%TTTT%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%TT%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%TTTT%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%TTTT%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%T%#%%#%%#%%#%%#%%#%%#%%#%%#%VT%#%%#%%#%%#%TTTT%#%%#%%#%%#%TTTT%#%%#%%#%%#%TTTT%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%( @ %#%c%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%c%#%c%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%c%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%&$&TRTedeedeedeedeedeedeNLN%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%=;=TTTTTTTT424%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%A?ATTTTTTTT:9:%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%=;=TTTTTTTT424%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%*(*XTTTTTT_&$&%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%cbcTTTTTTSRS%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%&$&omoUTTW_^_%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%&$&lklTT[Y[%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%hfhTTTTXWX%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%+)+WTTTT\&$&%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%757TTTTTT.,.%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%)')YTTTTb&$&%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%VTVTTTUHFH%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%@>@vuvqpq:9:%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%*(*(&(%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%-+-ﶶlYXY/-/&$&%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%T~313%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%:9:TU&$&%#%%#%%#%%#%%#%%#%%#%5%#%%#%?%#%%#%%#%-+-HFHicpTTY1/1%#%%#%%#%?%#% %#%%#%-+-TTTUTTUDBD%#%%#%%#%%#%%#%%#%868TTTTTTTTSRS%#%%#%%#%!%#%%#%%#%EDETTTTTTTTWVW%#%%#%%#%%#%%#%%#%434UTTTTTTT757%#%%#%%#%%#%%#%%#%%#%zTTTTTTu%#%%#%%#%%#% %#%%#%%#%%#%/-/fTTTTc1/1%#%%#%%#%%#%%#%l%#%%#%%#%(&(OMOb`bb`bA?A(&(%#%%#%%#%%#%m%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%,%#%%#%%#%%#%%#%%#%%#%,``(0` %#%%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%%#%Z%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%Z%#%%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%(&(|`````````b~&$&%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%rqrTTTTTTTTTTTTJHJ%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%~TTTTTTTTTTTT[Y[%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%~TTTTTTTTTTTT[Y[%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%TTTTTTTTTTTTTRT%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%WVWTTTTTTTTTTTT<:<%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%.,.TTTTTTTTTTTX(&(%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%TTTTTTTTTT_^_%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%(&(dTTTTTTTTu&$&%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%(&(TTTTTUomo&$&%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%<:g/\:!W(qr [>".bB&LP8,)^T!Ђ: FN F@@("TB#UJhF(ZQgё&8BiY{ H"0%鱫[`TӨB,Y{" S]G[ E ,^$@_Gqlʤx@#П:[`T/QE\@k,>b)qxPDmkPrY.'ΪS=NėpxPD\ TS\R$K3<@(Be9 Vux;.J*=@,s =SMx3j/~ uSf\72AX$' .*GC0<` uoy",?8B32R6|""C6jͪ^o5j8gZ/VVk~^57/ZМ3WyUDěpT@r-f9/,,H}6m@SQQQɓ'֮Y[g7'9nIOOovjCh:UuoPB̢Qٜ_7{wg^ۓ1z֭ׯo_qWdނ "vը\.00o_zM2f>}ꔷݴi/^I (Bux.rXu?؃]t?a|7^U+WΎp3 "OVݹsz筍T J_zUĜS:q\PDU<;8 bLQ]CUj#c䡥BupdzzQfX,9G. )r-O<|ҡn-**ڞ⏊ڶzv۝KX0nݺc"{pB(_b~F f7[V~v^^^c=|"d:{WDQFk%,VkQ· s5n(@lg)FEEmYl<٬Ȉ;v܃!22+tU=$_ӬYώx̙&M<13u zf>B3`lS<LyR?X^wScەJqU{H ;4aℝW' ;"q%7eaO~kgH7;.j+k8:9w5#q0$$D82V,(U_ YڶmKujiFkѸqn \kIEQcF,c79jVٜ'qgn5Hi$ʺ7W([$U,]_v_+nZk" Od sחk~ Aʿ7[W9BGy"##QII{\"<^t=QQ^Bf@ڲE׋>%kDJ[\%iӦe64Ek RvM&Sq;1uQkUw @ C,K+5kX,YwC^pbZQjUYQ Ist 0L:fsu#(̐30.\.:k$Dv zGHqrH>@C l @p z]vD\ܹDgqHt:PgЫCzqHr* u:q/d.\iյsQJJ{2?qz׭3QZjZu o߾(33u pșc1gggץa4\D?BAO/^\ u zۜKm߶?%@ ,,,4QЃG6`D\?7N9BÈ Eg⛲ v|Qf͚5|^.8|'{=9ˆnI=rЉzt6T ̟7_5Dt#>ٛ>6ܶu[֭[{P`%GKBx:ǍlgVZ0pP>KNJnCHթΤAo.]Ts]u!c7E$) -[&klpppJaK▐ݻw'6jx9ߚ:YqgӛMow^/g2fURJ*y*fW\m pB?Ӽy*]pa,y a @3 :*_d5Wr>b\ Rj.x׭P1w}oC/]RI(_̹?~?6edd42A| od ^#/.׎5W}@ J΁BPģ(g:w捓uk׬oIMMm&#uWREYƘLQczٳ硢">-[;ERZ?$b7[o]ogϞ?n|-[Ԑ̀Pf4mo"B9lUkV Ͽw:oNsήyyy\uUwZt@(%{׋~W=z4O!5U(bT[nkcz2z}m۶:+?./`'O?Qs><22R{)td2=zvppp!u0SNc6sй[ܲNP稈++]Btl6OE9nĻ3]mҩskбf͚B\q#l6mle9صqdrҋ+sTƤɓY,t*""b-nϦQvH]NnzuOx>s*.2L C:CAAAI\ fnO @jש}:')r:+EFDI"FPg`e!#Pg-Zx̳t(::w ݨUԅ4v @ǞL @\./e&COQg4@%93x;}%\:\:'ٳǧ~_Cu3xҁRg`eС3ԧIII>.JOOo]:JiB @nwLVZ]… 7Q`eЩuֵ _~O @IRSSan۴9q xQSޙŋc\:uև`+ @.]6vN9nqsQ`smҦV]?uv}\:WXXX^L"L/֢ :ugy#uxwۻ!|5k͝37:ǵ\2>|EEEUޛK˿]A,wﶿ QgaE 7%񵩳\nK▐<ҥK˘ب#e%'mܸu*UEuƼ0… Y|]fVަ&Մ".?uT&O/r|fz:UW./uƻ3>nڬp>}}:YLb\}_Mm6[9nW[-vy\VsXٸ5UV-Ǎ)44S۽ty;S{d`e2###wL>m-nϮN<0irИ*{=e˖? נ͛7¿hϦ݊ Rqt譽zZ>_$.ǎ `/**j[q_w=*ÆBNC=v(..5xwG:ޟ5833u_`lŷv9Y#RXXhM{y]Lkj=7-^?X,y筘0q+Qa{:g>c; 4*--u_{˲ei굫ߊiCv+.ܙua &|Ԩq5YqPdd/˾]6nTl.^lF3I ^0fso͋Id|0ýrjVkт̴ٓ T4,n;w,Zϟ4itٜG @'nyPRΝO\:`'xR23͵kNW7jQ7^l6qo@,ȁ2/Ճ،[Oqs;v u &O7.a@qk۵ow:ڵkC3.:↭Aiqfs.u# SNi9(EEE6lp#u# r}z= F@l6=:z׉39 @uvլY:^! "\5k:] @ǎSgГ{>}dVwRpppapppu#,$$/Cxx8.BBBeׅd7/zYEB @5kfQgУh~]pHt:ժUu#,44Y;_\oeB.l>q30. 1`30. 1`30. @߳RgУӧOB @~u=RQhÆ 3d:رu#,--KPГ{pwaD\f̘1DD/^zn ~6I>}{QЃόtR0*."=7//ϰCz!9̰|zgϞǶ4y1YdZxI_YV&/P\.bPz =oXԙS= __\̬tG21UJdfet8h*k&c^hT_5L]{X/y&cb=Jֈ4&a~@c ~թf*}?= qg (?@JBC`˜DyWB7?!FqS=DD/}!W4iWtp9*8yA|:Uu.'q'Jʠq_,CɢAjt]h 4P@@H<˸\ QWq`決jIENDB`uTox-0.17.1/icons/icon_unread.ico000066400000000000000000000461631354126257400166570ustar00rootroot00000000000000(F  n00 % 7( #3300""0""0""0 0""0""03 3333333""3333""3333""33333333033( @ #c#######################c#c#########################c##################################$RddddddL#################;2################?9################;2################($#################bR##################$m^####################$kY#####################fW###################)$##################5,##################'$###################TF#####################>up9########################(&#######################+X-$######################1#####################9$#######5##?###+F/###?# ##+B######6R###!###DV######35########### ####-/#####l###&M``?&####m###########################,#######,(0` #%###################################%#Z#####################################Z#%#######################################%#############################################################################################&~$##########################qH##########################Y##########################Y##########################R##########################V:##########################,&###########################^############################&$#############################&m$################################:.#################################@2###############################/'##############################d##########################################################################################~##############################?.###############################~Q#################################B6####################################$$###############################################################################1$######################################;L##################"###################$##############"##a###############&&e############a#########:F############%############4##########4_##########t##############################LJ######D####&&#####F######FF############TT#############..########L#######$**$########P#u#################z#X###############Z########################???PNG  IHDR\rf|IDATxyW}0(EԺh@hH[}$JVMjjAMSE1u ^@F8|Ͻz>pfg.}TJFo`;` 0 66{b-MueerV+H8u* +iU\ ,%rmTR* B!,1#5PAF?8`p(kb%p;0ey*e qZ-~ HL06@l2>W"b\TLdi|\ *kueViBY#p9gI RhQ<L&wAR1 88I,n#guԨB87SyR\rn@(nI~A" )P7pO"2X)3@wTnd%a;wQoTw puP_CtG=1 &suQ*cs`6n[Vt˚W+-5w,v#u euq+ ;IV1g{]~<K* eEׁ[hS=nC/~{i1\f,T]5n |A` n-!|=n7v' e誌ìcYn`gK fgaT]q,0:vvFY8[CNЙuq[c7N#!3kpnKGAb:w6֓7pɃX'?<@G26@!%LS,F4Etбsp?Q6l04AtОp?75{`2[u%,3K1&(.?r8'E`=[\q/癌&i' -cpOTm+0+*q#vVmZmޤhkZ*2G8=6N7p2ܚ `mGoy_70>SmB1?J#h=p1.fo~Sh,!O-> [I萠t8|İ_ȩht6ƽioBkc9j_q&~a-F5o&ZڍPST AG `]4p xPB﮸K"X#7Eܻ 7h>r*52J/ #)n .e:oPB)u" ldAF)Fڀ,/עp6~oxц-R*'gcYT9#F!rm i2Jo|6!"qmjD*l 1ꂌRnU\5b*G$HT!P7 JҧJ@{inQiJiQ6:@ĖM!Ң){:@zT"uBo boZH CDju,f R G`auHo =* K[2m@ J`N4u:@T~4Z\iRXu@w= ekFT֚KI'ҥRҼb"]*X,#ao>.@LǐV L6@lpwU1@fZJ:ۉ VgXd z/*~bO 5Zб0u['誌~θI ymH?#7ĞjckX= bܹ˸{=d?bxĦj5-v2䟎&/-ev73 <7 {NuB+5Irup#_Dzf'r^q`wNxlxK> xI#@Ɩ!lE @OI9vt\TyS `㊤˜U#<W$U^支"2|@OI9rL|)}DČ~R`=ܻa݀[S܂p|-m.q|ƟLTGb^_mGYY@TU-p11^.- px*YˆYͿB2 ` D2;U @˨8 WFTeSJ2Ȫ]p!n#A;TeR\b3p+ LtTer'nNAR'@Y\cS!*2h~nnZRĮ{`u.BJB!j'u @+Ctӵ %j*{ƿcCHgTm.CENq`;@PcHGT1:DANXbd! RlfBڣі V2 @6P0] FU0eQa* P QĨj[@iҗ%Fx(U$*mZT1ʭI@ްPgH{T1Z X+CHWAz:BPvܽ:H;EJCP&AZk!(O]KHw}^+-~`េ[r_}Hg=AmுDTe7M3x8%cIP%Rq/ |Xq6 `IY+Ҥyz:@T` ROZH E4yx:DTCD|:DT&Y9@n"]*+OA <`"m*Kc6 ~8Kg4rM6S&=MžLӔg}P_!0ǡE5}VNj˜Uox:H)_0qEReN*=*R,/sW<"2X uxMgTxlxK> fI#@`{CTupߏ^"Uu>{{KÈT|`9+} "uaػ`*E ~?#n uC 'Rr¼"K 1!jL 9HL%竡 jϩc  &@wB-YrL@dL~ZE/a,>qp-:H@+pW a_;?/Rugu8wclÈx{|l b9h)cySӈEjVrVYi)h)c\leFoM'ô'h)ccH``02I wׁl`9Y͚UD_IENDB`uTox-0.17.1/icons/utox-128x128.png000066400000000000000000000050431354126257400163250ustar00rootroot00000000000000PNG  IHDR>asBIT|d pHYsu85tEXtSoftwarewww.inkscape.org< IDATxypMWǩT:vT$XB"ۋؚ,/K^ZZ%"ĖbB!U#CVI(ZbHͼ75$νs0}{9SQȣ6v" Z`?md?N!r X ȳMMH UiÙ\3O'QUQPP`1lBT`' P;+mAپ}p+mB BIïo2畖 ߙ!+;%K1 yo(% "` k:,wvR' cx~ުܨK K$biV-[])[#ZX+Q$|Ҙ3ZY_1 x ƯMVԡQƉuHA,g3S cQF2U p0!^OoߎZF7i.I]m`Sa÷{H8Hw,3v$CWpSdC8pyjMEm?lK`  x~ !@tK!@os6~H =k @#y LLH\BceOl@OΟ?oA{& H)@M޾rJh/@%; 88}adP j"Ak֗HK0o"_bc&Tv;(s铹OpLѺs}xIpy`אqk߿ k#['dZBR 24+~@D,*1NQ*0={z)6?e9ޱþ2vB6r.K%Ej}fk.u-svVX9f.ثLiQd( - #=\SgT&J))QG>Y9x42J`ZCVV)|¨auC7 q<cƁ%t9iEo7?C=7 .%KVݲr2ug B?dIYlCxбaNR2+m$)^j)c$j參+ p\Ia N*wH')@4AŐ2E:1t?p(WԪ`.@2p<_]$dKQw ;  \.J.@2`3 aw+ o kXܱ&;UD;r ?`FI`|7P=) #prhaj=bIߖWI8Ic$Ñb&>{=8&#t ߙ_{ t=Wv%Bpp.5w)2Rw9 innH U$e_5j&2mYZ&, q+û=j"@v [bQ ; W#@0ӧM%,b|X&y"Sa@0/^E+ YG@$ @$ @@WU;w. #$`>| o$ ,Z `d$~_k ׭ՙld iTk?8oÇ| /p6L\6 xm}Wz.=|5dD ,= ` YZ'/rwLIL-Xd6C. { `.A9ہz92 $BjdN"9 O)4E<jf wIENDB`uTox-0.17.1/icons/utox-14x14.png000066400000000000000000000007401354126257400161500ustar00rootroot00000000000000PNG  IHDR(sBITO pHYsOtEXtSoftwarewww.inkscape.org<PLTE%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%½%#%xwxvuv\Z\cbc\Z\MKMMLMPNPECE%#%%#%A@A%#%BAB'%'@>@*(*%#%%#%868757%#%323%#%202%#%(&(*(*)'))')%#%%#%=3tRNS58LQTY\_`bcgikpu}fwIDATM`ѷ,Qf _tvGerk6gϵGbw01usYVL$IAmH:GIp7kaVtokM#k4rIVC?TUUdehp1iIDATWU0(v{ bCW@CnI'1 `r \[F4_g )!?Z֞{@P\d]o! OݹfIENDB`uTox-0.17.1/icons/utox-192x192.png000066400000000000000000000077331354126257400163370ustar00rootroot00000000000000PNG  IHDRRlsBIT|d pHYs a aJ%tEXtSoftwarewww.inkscape.org<XIDATxyPUǣNۦn,YD5"Q(4j0D0QDFX("aB`c\bF 1!(fKxs~8&w~{{\^AAAAo,GJRSr»+ Z \zjSC/챟DW`A9;/s\Y-[j$`{GVmj'_~{z-Xxɬn5 O2C8r',!` vwTUU ٽM8laG^:X7١nV# nW5h$̓K_۞3IIL P,cgUU×g$u j2&4J,^eI^@]Ɗ.w'sz7$0+fElF ?&IXLfuыڌ~" {3m4D,͙itv=@)4z/`AX)ȼ!,A+2km_,aD-fԱW ENջLgbyO@E71! s  TdqgLlL,@Q"f`Y21Cu,;9l 1C80 pšx#"_$">.>lYN-! >;}>NѮMTXF&iL}c4Xf&l~A4nmݾGfo h ߿ 3\oXR&48"VI{9-˨n `nM6QҸ@Og4|*$܍˗/\I,&ۼyS yXQ鷍~Fސ8!EpڬYTQ'FB?˹*O8GS5hpJOߦMxyz]2x&Eb!4% $^Ct3;zGٽ>^vaa$j5<mN|'OLj[Ɔf`D-vk\44?I7&))9&n>/Q`;OAA F oqhih $n"cq&|z}t&+D! OpJI3n##-2&hC @ava f7=_^^>20  C`A] nx℉,:>2N xzx~uK]*0N.QR1Iܾc~?"~u c T`(07oL|}b|JR5#*Q6zw&rO<ǻ:vxcs_&3(k껋_|ną1qP8v K\bЅ>gzEtvVv:wSE MH46:vG]*o[9n =hNXB ` tJS+BRD E!NWA`DWx>v @cȮ(Q1`EQ,*"@aFD*']H̊(5% jP, aO .@,.#RKЋF@eݩD3C `5qE.-3RK8CԢ|JtO4%"pk̴ȥf4DqCD y\;dxFb 0=@=;=><>?>?%#%:8:878%#%868535%#%%#%%#%1/1%#%%#%/-/0.0/-/%#%%#%%#%+)+*(**(*)')%#%(&(%#%'%'&$&&$&&$&%#%aT_tRNS=CDHTUUVX`aceorx#J IDAT(SmV1 "BQ[)7,'w;IBjh,Wש%pN7sM>`| HÀgJ\uB_!Z )a?060o878s͇#ҽS7]i4k&p*Kc7&7K,Ligy_i$S j*Ķpb(X'QX%:"wjNyqUIENDB`uTox-0.17.1/icons/utox-256x256.png000066400000000000000000000127761354126257400163440ustar00rootroot00000000000000PNG  IHDR\rfsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<{IDATx TVeiu3if͙Y딂W.y QA"@-`94E-SRFMe +K YĨyE?`{{g\^Z|{}y/z4z1 pIP$/,X*``u`Tc7 ֜%xV^kj``:V+ XR+څAO 6~|:v@=/X.lFV#5Ep#8io5`؂J`^j;qWoWmY=c{NUN .`*V#|Gkcbm RZK]c` : =!&c4rF!z/k !7mVs1r$n\E!ս#qD{zoԝrz-wЇBÙI/"#1QO4= - |MG tq\N¢G0,ly> ͋Zx3ϛ?a˖-O_ߓ&߈{H?L$QKK*y%=zl˘yܹJJJϜ1sjxM[[ѫͱ7rߦU]dʈfλ)*!0 8,OMgHT[h1cژʼm>QPYeC* ԫT~ _8޾']W⡞g***Q!#B&<7e@ л@N8≾ KzG=Sr=j`+qqɚ5Yf 'zWF5o&2323~'y}|i>KM+5׿~露xqp)>x 9s&Y%NLҨW14ѬÓ/Z,ZhG# 5Fu Uj?>\QPлIZUf>T@+ ~IEEEkQoi#%Nr7*)=n%:/=S^^i7H:wܯRqp+,Գ)'O<Îe_u8m_~'!Bd؅>GOz~ϝ3ws$x6ՈrMIXHXH@mxUF|g_xa /(5:MNoٳgIuPѣ ?#7|P' u:xFRSR_6yPUz5|Modt@GzT@^{mDzTT=k{t}N3= `'F^3}#ڄe= `͗LuvzT.sY~fƏ?K'@U4Պ~j\ <*]vM#5y4%= wh^3rlt<*`,Q: = [c),,q6=^4^vVd^3m}/EG}tcx X VJG_Fkf+&"`iyO.aiXZ]:wMkfqu=]0y4aSᩯ!`ix?D'!ic,/^?pP9.:."VVȑ#: Ыgw 5z6(/$ KZs a3/ @J΂j6ڜAnƧ<_=@ @24~w yӀqGJGKv l+wkcl(NI@̠fO@8c cP@ ۞leticx6Ĥ3gl޴9 eeeDU'zXRJA g(fw+e o3VVӉDrlNgS @dIOӉԴyBccw "r\.ٽkȈX6 p>j3]:w-V2JӔ?x"Q)@()&,6|;4M4LI4%LȦ`a&`LJ4eph^3 $ДfD*' %;u X۞ܽk  'a}=zl#գVXͿ8RW'-5-@g˳'ՑB ˳t1:r\`yZx_<:r\`yT:W%E$@   @@ @ @ `1`C6A@)q? #ՑB ԫѣC5xq?-_C}l3}8E vs7k^bw /ǁ~pf ݞ e9a&`u{0(Wa}& #?|s^56R0Mh&,`LȠ`i&$Q0Mn&xR0Mij8$phwԝXD4aI4ag 2`7@Ό[( @nZ8$"ԋ}Χ*~^\ԋȦ^DQ\e@ Epʥn`0KlaU-ȧ5"Fne$U(O ǐɳ9+rz1A2IENDB`uTox-0.17.1/icons/utox-32x32.png000066400000000000000000000016511354126257400161520ustar00rootroot00000000000000PNG  IHDR DsBITO pHYs:tEXtSoftwarewww.inkscape.org<YPLTE%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%ů%#%%#%%#%%#%%#%%#%%#%%#%wvw%#%utu%#%rqrqpq%#%omomlmlkljijihihfhbab%#%%#%^\^[Y[XVXWUWVTVUSU%#%SQSQOQPNP%#%JIJJHJIGI%#%HFH%#%%#%@>@@>@?=??>?>=>><><;<;9;:8:%#%656%#%2021/1%#%1/10.0%#%/-/%#%%#%*(*)')(&((&('%'%#%'%'%#%&$&&$&%#%&$&%#%rtRNS "*+<@IKQRTUVWZ[[\\]^`cdfoszz|}~DIDAT8OuWW@`*V `GTDPD&rH>NN2QL4ЪXa!RUo;A96 0頪a۵ 2-}@nN ;xF|@>a+32qTioo9~ڐN63#w;ENΩ:A!y񻯪y#/XgOHkH +J;Kl<@q" `^M g`78~yō88P~[ǂE-IENDB`uTox-0.17.1/icons/utox-36x36.png000066400000000000000000000017221354126257400161610ustar00rootroot00000000000000PNG  IHDR$$hsBITO pHYs3L tEXtSoftwarewww.inkscape.org<\PLTE%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%~}|}trtrqrpopnmnkik%#%%#%fdfcac^\^_]_%#%\Z\%#%VTV%#%%#%%#%%#%OMO%#%%#%LKL%#%%#%%#%GEGEDE%#%A?A:8:979646535424%#%323313202202%#%1/11/10.00.0%#%%#%,*,%#%%#%+)+%#%+)+%#%*(*%#%%#%)'))')%#%%#%'%'&$&%#%&$&%#% ZstRNS #&().134AINRTUUW[^__aabcfghiiqxxz{||}eWiIDAT8O7BAn![1B%}b vg;sӼ:M3)JMڗRbjC1#iMfYՔbcO:Hk؄( [)eTdsg16dsHRq!&/|U?%#%%#%;9;;:;;9;:8:%#%989767868%#%656757646%#%434%#%1/1%#%0.0/-/%#%.,.%#%%#%%#%+)+%#%*(*%#%('(%#%(&(%#%(&(%#%'%'%#%'%'%#%&$&%#%&$&%#%&$&%#%ctRNS &)*-29>@TUUVWWXYY[\^_aabcdfhhijkmnpqqstuvwz{.܏IDATHǵW[QဢF#"],(*aA#ػQ(j|?Ջ)9dɾq]MY33ϙPț9!M?m 02 h&'- vgQrKP'-) >@ nce,~P jn5 v]&hhLp#<3y5 kx{ &kƌ4u@uFdœ7c~=/۟>t?g%6G}fŹ;c"c> :)%E%:HN˕4oZ~%A9HEZTXD7tcFdg9 ` ʤ5R2i34qR;U;"g ʀ;ft%qM?>;;+|UmNY&vu O2IENDB`uTox-0.17.1/icons/utox-512x512.png000066400000000000000000000305331354126257400163210ustar00rootroot00000000000000PNG  IHDRxsBIT|d pHYs^tEXtSoftwarewww.inkscape.org<0IDATx TUWNRԫЫ_WUQ&AFATP1(*"(Z81Q*Q1q(cb1h $,B$op>_w]U\ܹoݟ@0\# &}&! h ~6υd+xs<;>Sa^H o`зTM/ ?hBap]ao› ag@*}GapBmora aǁ( -Q~ƚ@CgwFfžHVn 40-p\7b+6L_҃?l7rX,u  )» Z͓b/Y/3Xuy^k S-wT^:x/i&CSIu b>_}1Z7f`5Pc{@ 7NotsA@C+\@Ä3`g0`f'@pa imO 423`%{_ql;PP \ WaRZXwG !hBs/`3-İ3K ྀYygCGna\ g*C:.Pȃ=:0O @0!^FwߥMeO#? P|5Ž px¯+@@X&4e PiG&Ş WO ~P"6[Sυ={74n[ČsfY8oquܱsk6kkkE;zlԞ{R7nb̜>sqM;ɿSk{j'xt:&<zObo/F ܓbuP?ATSSS\\<>knVöswh3p<g7{^K. 7U}}} o vzJ~ gf'cdo=v7__x1^+Q" )90re`/ m簾ȿe7k f뿿S/|[%=2,q-G^?2JCa#ѽ1'[|&&9lڦuyꔩ URRR2&_;lcow&v|Ιo CbA td~wsF0b׬Hy}8I?a߼3$ 9 5٠~|>ʀ7<л~~Zal}<5Gǧ_%_,ĝߤfY[o@@+?M[[e >l'?c[le`[|鑛笷vUOك@0_M4y:䋐w;A7a{R=8 rĉƶ3zU^E ` {go oSī -ؓ@ߨÿs`3-tMgOkFl{u>=[ۚ!^*;I `#Oy.iϰծ53ALM `hc}kjjbڷ` F\<>c<`o# ,9;ivS#3*iF}  eFP;ݿ8~E k(fK  FL2K,շuQ>}.$nao P5zP^0ᩎٙ$NWo[uvt~$zop`s@699jٱx{3Nq ?T ˗uo9U?TE>wx[boڳw9`+PVV P|Mw9`ʛoySS/1q) ] `(W[my.h,W8jٿ@-JƍFn m XU7H{gW`@ D0hKWu1pCQ8^d*nOq) |}.(_ O@kQ>2 eU[o2hMīzII$E` {&6)u11c2{&>RqSTi2CO(޿~~-Vqwp "R[4hI Pq3a]h$@K`!7a[!\K@ǠCsρ@ `PcǮep= ZU=/ϐã(gFk `jy{yp)w;O)`TGVX!m `JDf^p)MT0@/]4Sw898)+@ad];w}S8 #8P L k*m~fc%-R,n ?foTj{tZ𫇓Љ= n]]]PCK466FڷoT,@SissqX$ǁ@sҦxa|RHg`J^xXZc/(@P4y+ ZXl6Ya5ΙPX_Te1K/Xǁ@sPҦn 3Ɔ*;@آҦsZxb{4Tn 3k6Z8+*mzϟ0CkȵXRF3r(ǁ@s.(Uq \\OA u8h.MA_>8V  @<,ppgЪf)>Fkd'@e@0iS-%@뀓Fo`5Rƥ @TXfhĄ @ 1$frqva5"GHcq 4ThH!۰~TZ{p)x=} W2RA"@бޡ2R޾ t̵5ZS_ρa@ڵkWC jhhl]'@r(Ykc@.l0ՒK @(ޡz] P=@P -]p)"E"@PDn'n0Ep7 !>wūeW2МE~> qK%C͑P @ Zj<:y=ztqA r@M>5aO@p'(0,|r6–/[ý/'@ýb_?a4;s"۷]ݫ*++c~xb-קA fN^2-4$@G{gϞMd  sP3 Bc^= A$Y@4&_hy EUԏ@x{͛6Of0_EIIDGeYYYCR]NNu !IGAlM}yw~3Եs7 ;>ۻwo CS'8|rvt^`S "wp}Vog8k<UTT9;~Mt;.6a0T'>?Gċj@@;oƍii f`ʻ)x"RpovM<%RΙ-UUU]s @X{1ϳ.=>f_ i a9QGkxN|>l]=<$@) zLTïNf8[3 @S' v|&knV?{33VVw(hFMMM(Ͽb@%aHI#[s eee MMMFN vsa<λ]ڷdH̐ɣˣ'J~0yeӦN[:kƬmuwZU lk Ä`@O'B0M'\‡N]碜aEBŬ!4}aϘn G3[ }aP >0X 53>C:}M.qZ%%%c3ГyEsN'p[8H"#I)bV޽k QrWWWt 60V30uXdzꙶW^z3G PW8>jɿS)ZAȬ#)Mÿ*6/>|Zd"oE$9{=0=+++ ۀOܽ&rrpJjך_]~03y q0`«\@  sȚԛFtFh{?&fy3a퇞,RK2E%&$nw !O ,R'<ۖ៓37TSJ ][3ޓ)-~PX,ՎX|EfKsFD +g},NbQm+pK|J`@xs &br_]iii)ӷľM~v0 ytS,FR'|ދٹt9dN򟙿4NlL~ey/`|=_EyYUUUfRSSb́8 u 9s] r{y̠SÆo9p |r\Ȥgķ@@+GիC>'o.LKI[; 07/Ƨ_)˘@?K. ࿟QQ> υ-nK^9>s[W| `H_g^` .w`- ;FtQ^޼ @@}|}=~*ޡ ,[p ^m r ,j^ּ\,Yd.kXuӞHqcY "0p)r`n(E cjӲeY wߔw3lI[AˠնNJY bngj[|\V*0U+Wbjۺ릳VA9ݾz{6|/Vgu5 "0 U:Ś@f?~> 5 b0&y:,00\!wAn6kE W}xi@汽h{:UgŚ@fqC W}kEYYYUgŚ@fQ[[pYfA`0uX ?LyyyʀնHG{ǯY lf2dmSɬU`V}C0dma[Y \]jW Z{ N2ǠK잴:@fbưզ^!Y b? 'q) ]mynsM`Q]fjKX 7|S ^mhllpdm  ?Ն)&Ay#{OX zGh`[6uR"*q\SIIMN>0? `on{q_ xzx^a ٣Qu͚1+l--n`8wWX{ h hٽQЌޡ2-k Xk @sNϠ=:9|:@he`WMMMׇ1Y߯^6@ m岦@^ܖ6W`z@!ظ8oq `0K0 ƋoV,_`g -@[zL<@g<]t-Zh@@[Ǎ7.6HT5 ,9Ãβ.@ C>9:7n8յk5k@p\>/|pц19 7Y >0hܘqk0wApoLJ?@rԛF0M:-L88h[c8kjjb&O\ 'Z~n@}>,_(ozyTy@0u^:Ĩ/@ps7*e˕O:>@ԭkgNId?`o@P433V0mSH +ozc26w諬ݑ_e˯8 ֑Ew!@,,0+Eۊ&2+}}YW @nG mccvp0K0-g|4イu6n'ߊ._)۬?`"rmF8X-驤 bے~5 1o!߭@?cbr {5 ,jJjV`vF7^)-+0ÆoaCUUU8:<ڗ/~A@#ϡgϦMY g_;w~I L&~sa Q`q)<{<<>e] f}mEnA}.#ch'~Xsq@99=P)uEn'j[Z@qwĉO1$'C5!ytz1;zl!=}&9q$ Ox>S8h'>A0(X1NkZly&И*++c@0xEGEs- `0232ĝ'!  bRƤ ?H/4&ns] 8~'4"C6~5[zLUZZ`-Rñx_wF@PTXvx*@@QK0 %%%cF@P ;0МؘV@PL 94GksrhNmmmxc.s̀ A0`={5"bbv2`f@PD̿0`%@@L}/  prp7r s~e 5DP`Ya/3"r sуjhCq s#Flf%JȵΥ0Wr s3XPCKΜk[p<Zb钥sv@й 7Le `0{vIe%/k;sL"C -qDt&kk_ 5w/ZaJ(<]@ ʖ+҃A]:t)Xi`RQ 悒ڶJHՙ y  @@ @ @  @@ @@ @ @ @ @ @  @  0::k1if7ZjLEg h-SfAn,5"͌4܆g7g1if?Tqv[|'O|bc2Ҭqv ~s6ˍH Xz͠dYqfL,sC}f$͊3)*pW S}{=ol {:22LpFxp=I40n(HLPqP~,$TdLG ev;*tT*Hv<矮ذ(?,* SokOAE^ ^ ??eppphZOڤkUfڥk>tAP~7X~P~,j_[ 5U 5N 5L 5@T 5uI;ipȀPS@u^ m Ux-02Ҵ}РP3@ͬaL0pā&Ҧ@&@g pe˾lmr5xtY|L ?>$0 Нd蒗C׆3ݍC)t&! $j3~0TX^+VL*)M"ag )%K2UcP(k~ @I 3@3g+ "' /W`s{2("0n 9Ȭ7 3iN2x00Iwc+]K%Ԇؚ("_p?--eϳ ڴ[E 3yß\, |V$jlm0+qZlx%Lkluc@+m}%u0=p!/\e EC70.l 9D|^L\I }5_/P=3@m+6oW C`N @W+_l7 ndx?@Txx7<CNA0?<vbXZ˿?筰*̰k@p_ /w.#a8 ca܁Z/=RIUckPIENDB`uTox-0.17.1/icons/utox-64x64.png000066400000000000000000000030151354126257400161600ustar00rootroot00000000000000PNG  IHDR@@sBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<1PLTE%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%~}|}{y{yxywvwxwxtst%#%trt%#%srs%#%popljljij%#%%#%fefgfg%#%ece%#%bab%#%%#%a_a_]_%#%\Z\][]%#%ZYZXWXVTVTRTUSUSRS%#%RQRSQS%#%%#%OMOONO%#%%#%JIJ%#%%#%%#%FEF%#%%#%%#%%#%%#%%#%=;=;9;;9;:8:979767868757757%#%535646535434%#%313202%#%%#%1/10.00.0/-//-/%#%%#%.,.-+-,*,,*,%#%+)+%#%*(*%#%*(*%#%)')%#%)')%#%('((&((&(%#%%#%&$&&$&%#%&$&%#%{1tRNS &'023578@DHJKLOSTUUVXZ]^bcdeefghhiiijkklmnopqrrstwxz|||7IDATXý{ QQZjF{C*vĒZhkZV)u:ܹ3ӻyo9s~ohk,9P^whTM]@K{G+2yO3ڪyx~D':TG4?P|fkJn1_?%yƝeJDx U#GFf;_&{R[ϧGx? @h)eI{V.-vPF`if/@nW KIENDB`uTox-0.17.1/icons/utox-72x72.png000066400000000000000000000033421354126257400161610ustar00rootroot00000000000000PNG  IHDRHHb3CusBITO pHYsK?tEXtSoftwarewww.inkscape.org<PLTE%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%½%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%~~}~%#%|z|{y{yxyxwx%#%tstututrtrqrqpq%#%omonmn%#%ljljij%#%hfhfdf%#%%#%bab%#%^\^%#%]\]%#%%#%YXYZYZXWX%#%%#%VTVUTU%#%TRTRQRRPR%#%%#%OMO%#%MKMLJL%#%IGIHFH%#%FDFFEF%#%DBDCBC%#%B@B%#%@>@A?A%#%%#%%#%%#%<;<;9;;:;:8:%#%%#%979%#%868%#%868757%#%%#%323%#%313%#%202202%#%%#%/-//-/.,.%#%.,.%#%%#%,*,,*,%#%+)+%#%*(*%#%*(*)')%#%(&(%#%(&(%#%'%''%'%#%&$&%#%&$&%#%&$&%#% tRNS  $%(+012567<>BCGHTTUUVWXXYYZ[[]]]_aabcdgijklmmoppqrrttvwxxyzz||}~~IDATX_@{0En :@Pp‰[qu-uVܢ(-"Z{,^\./w&m%O-NTSu!3 MYo w1j(_GqIDcBWdbQℽDy*nE61v'T1I~0Cxޗ]V|Չ|6Hg7#yQreg}Rպ'wٜJ1>LPODC4P* bFxW&(]nMC<Ҙt| ig+P2jvR d_ rja2/!!TNx5=gw&Fh~R.fj)}w$]@}7&YC)H iHH$t U#0T?Q$CTEpeYB'ǎҨVf ԢUh. bw32/V(dM^j'Z#zzHg%@f u h* @Mih2?}fW4-B uff^,RC)jNP#F܏ Ph pÜEnor\*jVwpo_ZbyIENDB`uTox-0.17.1/icons/utox-96x96.png000066400000000000000000000042061354126257400161750ustar00rootroot00000000000000PNG  IHDR``F sBITO pHYs11(RtEXtSoftwarewww.inkscape.org<PLTE%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%%#%~}~}|}%#%|z|{y{wvwxwx%#%rqrsrs%#%%#%mlm%#%%#%hghihi%#%%#%%#%dcdecebabcac%#%`^`%#%_^__]_%#%][]%#%[Z[[Y[%#%YXYZYZ%#%XVXXWXWUW%#%VTVVUVUSU%#%RPRQPQ%#%PNP%#%MLMNLN%#%MKM%#%%#%KJK%#%KIKIGI%#%GEG%#%CACBAB%#%A?A%#%A?A%#%@>@%#%%#%><>%#%=;=%#%=;=;9;:8:989979767868757%#%656757646646535%#%424%#%%#%313323%#%%#%202%#%2021/1%#%1/1%#%0.0%#%/-/%#%/-/%#%.,.%#%-+-%#%-+-,*,,*,%#%+)++)+*(*)')%#%)')%#%('(%#%%#%'%''%'%#%&$&&$&%#%&$&%#%…-tRNS  "$%&)-.1456<=>?@EFHKLQRTUUVWXXYYYZZ[[\\]]^___``abcdeeffgiiijklmmnoopqssttvvwxy{{|}*IDATheXQn 1A.D ;E {wsw;;3- αmpq&`96[ŐY#s`Kf>Vd*JV$J0Q0~_u>@? kfZyOr' ZOC$ƣ(KM(bmFD0Qi4  {DZɶ&&#`Hqhᧈ比 DTV4Յk74AddTYApTt*5CDf:,'fa _d rVogXl: < -L6-‘ϳI*Б`O]GR)} NZ÷>}d)S/a̶:*IENDB`uTox-0.17.1/icons/utox.svg000066400000000000000000000016061354126257400154060ustar00rootroot00000000000000 uTox-0.17.1/images/000077500000000000000000000000001354126257400140155ustar00rootroot00000000000000uTox-0.17.1/images/utox-linux.png000066400000000000000000012121141354126257400166610ustar00rootroot00000000000000PNG  IHDRV@\sBITOtEXtSoftwaregnome-screenshot> IDATxw%E?~ox͛XPe (bEPQA e!arT]uΩS9U]]]o9rȑ#G9rȑ#a7 9rȑ#G9rȑ%79VB^pngg%*2ȑ#G9rȑ#Gşm𷮸Q|Z.hrȑ#G9rȑ#K}}}}u;eؤb-ڇܴyhUl^9tPN.ОtZMi<;Sjm221G9rȑ#G/f01k֬WҜq&s=&&6lxT*eV0C۶7^S8瓟򿺮G)SW΋dx«.ݭſ\3chOWrQOo7>6XPoص+YO\ bixpGOOKrn \, ozaҁt?ߋ7Ԙ#G9rȑ#G=Cq\s=)!jٴ`ۅMy8gzqVqg¶gwֶgBZccc˩ئÖMz&'{{82:^UG=͝ӗ 5yDSףroEVQiٰWz:Xi^g (xXOV=1ũ껿/)RRZCpM},3nAX| 6/;>*ۑѱ .RM5&ZoP,m]1 ቩ:ʅ=[RԘ#G9rȑ#GyFy0kV_wwWggT,\m6[c##CH\a[9y /¾ޞƷ=1>`noZw[/TJ,UW *U*οh}~uuD\n >===1BL%DkhkcsAS/w6LV#C9~ }:F:ϸ⻇]wVZ@%dP+]ē˗68h(q쿬 􀕵?:Q^<'w]Y4 ع;Czz͍\fhڭJP<ݗ|U>x|ZOPc9rȑ#G9T4-BKΝ3@eYqfU.tvzz\۴yrۥY3<==\{׬ebyJ@x,$ن/|& Kj+pܱ驉 oXxqoOhF.Fǝe Vsѹ?o (Z wշ,DJ8yeY6P,c"@wSv wrtJ֙:f-;,*s}5<<ÉENjӿu#G9rȑ#Kzc`KJM[ 5-ieSJi\;wg?nݖ[*mRv񥗼⦩YQG9?J%Y:k\xQrݭ[Ξ>-#3V,(%ᡇ #W}{]xN8WodxxE}}=ccYpYaYƽR7' c:F7o Y Vlnǽ\t}Ͷ[FUqsf{EtvV^POv_?mnvq>Yrg[(8K^s~bCN."S|#yEv9O<|ǿ|g_G8~=#6^L?b׮Wi_|yM ל~.?Jo),YglJukw0ó{~ d%9S_>kuPxO>NsWCkv[c ߿޾>ǿ}/WZ[o-:#<|U~ߗSٿynZKRo}U )Lm\|ǚ}G/_3V)@+:է`ίk}.z+n֣G?֛;OG{i+wN7_TDȔWs07!.P^Wȉ9rȑ#G9r"lǝ̝k7&@`Μbc##Ridd7N;V|q +oڴƛoy?Ν;׿MimKL@m~k~_wTF7lp~=D8:k<ﳓSw](sGz<N*#cSn8?\?8co@d:gw{xhy{2em @gM.s`5C8'͝~> oo]-GMPZ:{Mg_xϟ{™+_~m?Sw}[8nh;*]i$` /yJ0Ygկ{u/[݉~%{h:‹ תgyEpNM,Po:V~tT=cz.X[k|Kwꂿ[_c/d쪍G~"+:'95>J9u2G9rȑ#GW"z{|򩉉ixqav\ʿl6|{vo[|^|>;#D\£|-}k/7we˖~zl]UN4Ks> ?o}Oj O{kXsK?ߧzzzJRLmFwnFwi"@8n]O>?RP,g>̃_~}`hؘ #N!VʫN=fyM>rPvxo^O^y_Sw}\Ch>6?7aS޴{{6|΍}+sb(R,LK#]˻yz׃K#>sXtjW\Zuxg߳oN,ֿ8#0G{GH4rv$c!퇟%惷>]co83Y=_A8j/DC Z,?\zϟs*nu/nv3GѠuKYux/?x0V!aNkv'I*4B@Q!]nZrWzغ\X-2-@(N=\~/ȸS@%9rȑ#G95fuA*J|`_xqrr`]]]^{ޣW}?=˥6BMs^'uo}n-?QMKiFVfabr-d0hhzzzaDJHt EP0]-nBavoa.Kxnz w9 ֭իW%ǴtFlHxۖ7={zmW+oL<ӗwPיִtB P-@k p-~Nٛ8|_9$daOq_~{I/caQ!Yg ,Z_c{q˻jy5'[R?!Y$5M+k{F޳0͏ v]L .;.]3P'KJӅݽ}oo{(@CM15uW|@Vs!XK$҈Jj>7zޢ[uc H7[ߵ=ve)ʫۓ9rȑ#G9rQ*?ucH)-k֬ރ>M':^vSzpO_OD)q؂P[|z9-j#%9rȑ#G9RēOyj:nW~oo_o;uǮ{و“ԔжADԧ/l9.0]6.PZ !bXz< =#SUWt OjE߰?1dx>{ѥ0g`f x[`E|U뉍B3${M/>ٙt!s.ySuGMMz=0Խ]y#ΚK]ϏT  jFdž>;R{cb܆6c F '.G&:hzrcKTs2l7yp%C=  PJL>;v;砷~]:`%P{׿|bZ_P. !uE7ïっ˫CXTרIs>莟zU@Dk7Eݏܵkf14\&]tU:zҮ ^ݍ˵qO?t5?eQRp@j̗rȑ#G9rH7Ztww͛;<}ƍ~W.vr/@ٴy=tR쬹90g @T%;KߟfaOgK/lD9s`hhBy^sq4&vL m"L(~{v]򔷿s?S,el ?nnq?<ڂ\74r EҀpGK}'%и7Z]8}*Lo\,;}&Y .ON{-qp_i# ?7lFBv]Nq`m7<\ ;%g]|/Iaqm) ~^( ?!Nܗ|nܞ.]ұl0c#̫CIr;l v\?37i#: [ԫz'7av†k?qɟF0rJެ/5S#SwsctE}?uݾQ|yGtA޵:;h5#\{DZ8vǾzp_wWXq7^LMMfoZϮ{cQAz '>}&+ݹݞ淋 $czx_oשXp.{߿>{yO_o̟")A Z-IԀ` Bi|K.>i|s -˚ mX>@s+&G\כ1,ݿغ}:)I"ɡ]QNJ͉AbMRnc `SR>˗3/c; SV<$9?j*y 5Ckxi!PJ;.\Qvʭ!HW |1nb%nح8%[fC5BXWc|lzRtm*b1)Ȉ4uLj̑#G9rȑ#GFcף777nt̸?E IDAT,i}}E  늫6tV`znYVX]pṟ`tto]vzgS `X*R1u;GZ6鬸6c( ;?Վ.¾{u!Z}vO=5UpDW”[=|)ϪBVY>j*309m/j{_*X;Ȣ9rȑ#G9rdAV{ / _qyVb319ɼfE;kbq&s+DĞn{݆ /5}۲^<1AfelJHj6?'Z*J"CtT*&4| AWV?M-2 ٯ*ho},xWO: ϴ9rȑ#G9rd'=:k<20RթV۶U.wqiT|ɧJEX@BH\_ 2J&k8e4G9rȑ#G9rK/O{vĞ{>99ēOP^: BFXK,zɑ#G9rȑ#Gxlܼy;::H;5nٲ-6a CmgCґx_}K$M9rȑ#G9rȑ㕃WY9rȑ#G9rȑ#G]Ch˱ w]mJ9^rC  r99"W"zר2n'{ ِH2/#Ne*9M >!"v*Ք;s)2pF:J5i8dSJg5X6߰'.:CB.%ULD/ِGNHL:ɀ3RqmBBI=:dȲ,뜴TҶI}T*B̴J:m_`AWȕBQ C>61q~ Y*=D-SgiuVe>PmЎm‰6 }&ߞ[ԡWimcLt$jymUZ-"2~ӎDf蠥ދ9ɡ̬֙bhPյm'‰(~!11P.Mg U֩Lӹ(TaU#I#nNJ 3fx)77B3O_}B$,feBUNOyAmh) ?7h= MxIXKڿ~'sDh`mS0L Rm4J>"2ھDI)SKlU)a:#~}?#,J@:ɢD iB m$d%TS8MO ڙmsJ^3K da}`DP-Jv+VV43N&`ZrL͔֤!!DWYb:@x z u"*3$GpmیDm^1*ͷ}6N(Y!]ff`lPL[#!^xRL"GRQ3_sXpl?6gJ5[*k"Z6-O{$u$3\J6d5B'vH7\E:J$͙YQBlL&#F֦́P$"9jM)~gDfv*˷U"%RUYU3S?=Ե 0pTvh PT2\OemɁLUF G!ʓvGnc: 58-LM)Ҙf M=UCl$$m@e2UZo[ !V3PuA8!?30i3 MRTMuWvGc"ΓEaڤoYqNSKK=̆V~Kk'N3T0hw};N|l"F:AH~EF$M[Ä3"q>؎+Ύf\K <89YFɔ(D?D c>YyS )(jxpM$$d3HZwӰvL %@ā=.+jle}$. #H451GT3y1gזD`i/L#5y&'zL%@(VR>p#VHT2iW ]qmithzK"g.R@CzXKNY{oT,tTXBL DyTraTc ҥ5502-'XHSܥmGQMݑ"D+H1 G1 Ws+٤kCm^6$?AEM&25HX)#>=\'_K&! `H5s u̺CU J6s'NR9 m^͐u X' @`;}uA*hrD1*5Mcz)aM $D!pE4!F#9(5tw8NqH$8xfLh=q)7A;*3t%2ht$ G. %*$0 Ju( LMI7˜f EB-o(J'zc$SЈʙ"BNƌѓԦ)xHc$$aY]{`8ҫGNЃeC}5=ͱ߃ G+.Q3ɪ \1=!Mh+'^u 6qGN _ * J θư*NxLjHNg:AַpgJUQ|/ pTZԄq׃H@JPPxjzPa6$C"w "L4X Fqn':=L9M+UrtjugYY#]ҦDDd@ڟJA]JRH1exT^dnh L ML| g(~IG:&g b$0*`r3S?c$:9.7gTakyY0].T&!^Kq6KlLumnG(M Ja*=H,4NIݨ\BHEǢ̒|AcшO?b' U?Y*b +}KA}Bb> h@ fQSљPb͆{\5)A{Йlt15 "Yh0R乌 soD` =D|`" ՟@ ':t-*J( y p]_@๬X*SD ~@~樨&-%{G%09f iJ)I@)tD;II8P3r%(]*y"}›oQo ˂ʍ8Haࡶ5&K4q? ,ȒY IH.F}PJL"ۆbjohQegMꕗh>*a_l;? c PC,rW4FAA~Q58;UjNx@=ⱞA@S9)mOJ3!9D6y %:Iރ.DQM)iIKKqҩpe$Vx<.$T \jsnF8}5 Mfi[ʀd|~elJ%T2?Y J(? D :m/$07+!QݦZR]$3vfj-$rG4KQR_ oSg Ur~%cI8CNJLY*Y.%{"?Wn b6Zf@8!@(tFܛvgJZOdO0 28AmYƦ%Ǥ(@EŖ!`]Q "ňV& sDH #@@ppT/? љfvG\M2c1 \/؀@ |5ƦfqfD yD.)rM-.W7u}z)IT[*o6 G QE0k \M2S7*ޯ|MQ\ C@(L{nD^A3K#.}:&d% =o JIe9]LB[Dإ4FH'[r֥_sM489{MmJN%^KсrBPj#K]Z]ʩ?EA <S4{#J^)$]Ds螫d"vl aޖ2:e b?b\0jHb7ArAވ%)&`"֍6O@&飨,I,c[/:/. ؀җȵe6(L? csJTxlkֲ' G x D4'm9xkezbF"̦fP`U}AYI{ 醛E㼩%ſ?HM1jNQߦ!o76,庲҉u*&f(2f~]GF w I m_IA%u C'Dz '@2 IDATaJY* kk&*D^65& ʇ$45x$O[腏=PFf1,BZ@KvǬZeVU 6JE !"ͱz}x5@4.<&L}ڜ-!L 27@X^f= > SwOODbY兔 =O4tԛ \BiM gnDDՔa`i ׺@ BQJ@XъCe'z6ABgB %aGa1ҽ ( j(S@"W#1b\oh.  I>d!il )@qFv) R ww܌[) gWj% ~2awN&i-'Y$6*O ?m0KgPKVzzޚS"|jVGL5ofNQ"s=! Cb+Q‡# COWlL/5dy"P@Hm (aaԣ6@gVBx(PBM)%@ {:s:æNL0ⶼ dG΄ n5cVulÈz21E&!!,%Ӊ  )k)ZWc\GLr`r.+7R> o$N[Kwanh6b%殉u7Z&^q ?o_'>!*Hfr'hsǀpSLO6~Ɵm |hăpuVH!eԮ\BX(Dyqm "U~Jidۚ3*qߥA꺄)sP?.0nwS҃ qYKBƂ@/9B$Le)оk ; +D)D }bH Eje4h3bܳ_A4g/5Vfy1fS֩4rT#! -!]fȠ fgγ{`ɄRIie C䷹-ՅѦO>"r[s2@" AȨGA*XfU; NO;"IJME a%bH'- D+D1g@=O"F VmnW^OjQJEѦ"M H2JehQʈ2ѪW+nl! 8⑘C// O)pui<ɇ*a"tqV1]0ێ)$g"jKM̈kI@m'/1"#3ːi }G#2㵣1}>/b'5L73UbCM]K0₡e O_"cCH09JJ1E%.ӤZ0H$fM%ޡ"[O\8qBP! O T$&HL=@@G#^vA3-)@$iBbAE©6#ҒϚT3k=l[-br(%fEM1j,O/#'՝ umx]{D3H8kMK~+Sȉ7h^X5|boc6dIe mm1, )&.G.)wYDpNrIlBr&X1()G QT)2eDBC~H˻6I(:tpn?zRn%Ig_BtBa4/QuY~ 0d_W4oaa48ੌEaP${ h+fHּh XK#HHPqBGP*o4CRL:Mq4O}Б´l<ﺔ",jjcz#)8Qpc#͐Hdmښz's!d熆^/!, ?{Ib&ƐaUM?H3Jm{} '4.,S`,d RfZF:k {%J2ݕfլ9^zz^Z[9)DDlM5:fWq=Զ@wSˉj0E =-ų En.Q9k2OMtĸpdS)OG;n.0@!kTO3CI=ɃU 9ƗfNJB-{. K:IBL-*bpF%K[ ~rJxmfY}T&fyTh7C5)@& ~$(峆8_[QtG,Rܞuc?l[7ܓ97 7TҘQ!w;J]ag} rd^V39TlILd‚憞$Soܙ +Jbr^32 0Lɝ4i$B=+zapdDJ " %>/+QD U@2$ .FoA8L b~◓t)o4#sHפV"ǽC9.q.=3ݣ 0`OH dG0+V]&8gT=FY&_Q1N:*$83^&љ\YPjy'#VTJR 00{pO:mȀ1%/['](: oƱ IظØ7Ϗ& N)Obr5=툨7Ѯڟ.y{`nv{3m`¼OӔ`N$$:GwxǓ{>0g[E7nOl_=Й[/\2"><4ӼKKQJ/so#z,p5P$aaNthv? "v2ouk|KZ:6ɷ€Q> ;=G<=SvLb#PuQBгǺbȦ5 ,Or ,fu˱ QXA5+A1(d/n:x|.I۴[f!aM-G,-ְ'9`D<!v1EU UtM>K˧aA8@P ¶̸\6rIkITE{"Uw)$eBd][ fsL 0Znsncnd|A;FLk H46D7 ې&V9W%GTWI \m͘zj"9]P'Kw5[ƞMg>[H]{oXw ߹S놮l0 5.4kȺ S6>D4EdVT;L>0;H4f۸hCM[H@[tK^{=oi_xW.6<ȃ?>nvW>Koy4=Oݾtk0f@t4? v3y<`C|l&7޼.\H@5Я1^m=7ǸE~2P2 v1ow D ۏ*Jw:pmテ|#hZZêᚵE=CSml̠J$=L3j4^}'@:pL#jB ٨8نJ/qID ܤFr1m$W(l˶6b%}J5 aiVz*㽡l NԽR󎼞 1qnz5:wW7X :cL6P.QfRyZak؊=ݢY 'exAC a'*ʸ&bV/O",&$+yӡ9VQ]_)KcWe%,N.vViۀ,bǾ0zTXn0l;H [mGbs($OJHʬ| MGY&B}vZy+jC dxt4i-%$@ lGt̛.>wtOg.Î`{l?՟IueueI0&=۩}K,ʕ`CՀjs }Ke2^7SQТì!}}W B&EW澮-DdFn [yc%\wnd MYnEur(B攧C#du6گOc@qj8]ǐ,S$z89k+fz'FyaJ~RW45dMONr#~AnNIC)|&eE18hbDX&MTK) {=M֟PZU 'v{U\N[WS0 r|ҳ;%ĂEB2` ,ljɎ>Us&Ai"t\?cl,Hz_ RwFM IDAT(3Fq&| \c36=iK6:Tծ$޳̞l 㱚;0! 4'%i-8~Ww-cȼW}W㟹=:쏾KS|{[ _W>nlaJ)momJP41Ʉ(Wo1][YՌ= +[IV)xL6}ȖIgچRjՖB#eL _e0S1Nrd,Kt P" uH?za/xƹ\#yֈQ8b2t\ppzS'fe3`W"^j<}2ѭqoHE2΄c,[zOP-ErYJ-5?}{ '=z!۰5H,QgHpƼڸA'+^kQ^l5!YjQZ  XA'D(*ӡXl=FQg-2؃.'騘$bj Y6O]:dM[H-"^=*$EOtvR^{  )^bܫbuACUiE/4mw,ւ} kM#mwۖ(rUmUfMpHh_ _""oL-*kIɋ0AMlCF6bת4z@43||)7zw>q^~?_O=ęG/zoy˻}ӷ|1>U{N??5o)\+Lw""N8MS8ZvfS}qW2YmT_*#c8.ّeTNhzԛ!ÁF@o}p]~JPH&pD}tJ07&] F`̩o(O6A&Xs;~'@Зѽ>C7BI(%8Nun%jy_IİzK!|w,BVpuO3T59;6*T}e7!K $ Yjcl\\Obtkp1މi9Eчa]D8rDrV`ryw7;:_>H:Ƈw<~~g!N7޹Ü#o|sXzh"N 7@ĉ'3\z@)1mڲIT2Cf~LuVx%@EL(F٦I.f&lZ{ p4髕5\^|$al U!GdrV<-#1#/X(ɢvo7:T,7{aq͜*~Z,rJ0k>&%QAKVkO٭O$ 3띅* p(R@j9bv1UE+wOVVn]X9+uxĞv\j_oFǠUB~E\ef+݋U؛`GUh z.A"3뫹X+;O/l<.D7z 9^J*669#NoD)fTU_He;R>% @-wM cYV~2(jH a+K`prUn0fUFŪWNo/̉Abu" ; _>kM26-goc+Cy&}ͷIXm{yuWRJ{\gzͷCZ]?-g&XnS@{I+b"GHKk0Wc)Ͻ$j# yX_q-}Rwy_Y*5Tvr^raX 6S2d4Q&y7uEJT~XPq6RPÉi1''xV1 b~'aim׶ly WU|L}۹HSXv *#z*I4A09~I=Zj@Pr3TN 7ӝb(0aoF#yz@kh.ܩ%,A!)̰Cב>^+8Yl7@ۇL6(l3>]Q[_ "I=쾌 ^)T'KR 2 4rG@V'Z[E|Ki0IKZ3vS&]i31py|'չVZ0nGgqE+F)ھUyYLY+4RR1%b=ܑ'aAC9iKł0c'D ܙ eb-&_/1KVw۠TꚄuÐK](W@Dr dEɁ`3h≀?`Ӝcu#l[0@UP2͋Iyrvpo#ChNs=]t8i%Ο )Xhta#74QH:rVQ3L)NT$#K(nuL*6WX~?{zaN*>P dnċ:2}∀WRS?:W@dw0& $qosQ{J? *4 %1-sؚuyDwhŷh$8% o A:{7yӼKS'o?qSKGg/ j-_ѣp)ĩ 4M8MGwiy"LiBJh;DPcfn;Wrڍ1Y{swڈE9vcEQkk9Jgt[[<[,-cW\b|^0~=݀k~V)sLF}nhφn ] MLn@c 6xaTTo̶!6愺e !glSn !1dZ+4G 5iW rpw]fYs@R}αbYGti?]sjMEn@mNO|ѰD0.$rFhtRe}]討2v3%]Qz *8kʉCd9]>9?N9sfR-,TNs,;`$f0" ]ր%b/^ҬUͥOD&*zq}I.UouyEaBmt{'i͖2[ڻ/$a͚xFUW1Ar ^BKy PQU0yH]1ugQuD,f,?ųQWT,7}bLF/"E&"Bєӯ;t0)Q]l99< M;R/Ls<1)ED04Mӱ'ʹI4`0M ]3C͹zQd= //eE?)0tB=L䲊m#db0帮g*Fh0Bq|wJ;{{d6p6!dUOXqk^&Fɬ)!>W{iPV+^aYІnm= C(6 1`8 µS pAF^vY,bmfV)؂.w*B؃I0=q8I4$D1x(Q,o1lf Wc2G\!V竟>W8'aZJO)ÎR3DPJFjV Ѫv `f"BB:~WQJ)%{3'эݾҧ;:Cׯ\?w9 o˻WH?w]|R{tҊt\ 0MR&0!l5[T86 kVwCf)*}#VKVmj6jm71 P nO#MTo/.ۺ-YQ]14Ȼ*. H(yO}E &XY%!6UVm2!]r!79R`t>8eO! s₲]<.3-~'ZŪuԕ2*?Qv699Lϭ04(8deE/@4ਉM[=q`"Ӷ/a:qTY/%ڵ _}wo޹?7%<~?//գ'_w7>޺v'lv74ÌifPH=K|Lu +Gf]#VZɡPo2 'l@j^y&$u>ke`bpa%\d.->D*GIS, hPb*; +$E\%.radxuc5>-R:m=Pp_ ,o77RQXb-ݯ>XxR_[{|ԺNzF(?FJh#44_qbծ ˼Ke \RWVzlwRsP{ӭ@*ۖVTV8sM c-^ն}IlY|dǛZxpUa[V~(ۯ"3+NՕiԧ@,o@֟LwKmϵ{NJPJ0mjP] }qEM| Bt֐6F;-+UfR$hC`# &#!f!#!-1I>'8eQ3ũӬp LtHBnnx]H7'JLno)Q%"J0ӫ_~۞i:s3/wgOooo ^W_Kx8?sp׶v;ug_Bi&D󹾢WC&%e)3^ãhP3TRÑ أyw9u|ͪfG[_Y\RG) Vcm"e!KA5dg|4Z~'0 eM>'T =Ӭ۔zgj${Uk t(o jw(!43,K_p)聉g8hD; %b"R@ZpĪ3 \ⱈѺDe鳩璑ہZ$UX6ܫݍG/ ң³ E14wMN^-p_M|W8||0RГDlGrKMH.|d;M$Cl ^}CU&v"-b\QН4rn1!I'hl&o/7ʮj0fzFtNޮpgbH^ 5Y@Hy; %+ :m*JQds%jJ^.|_ }j"eLHBЬ; QQugy 7n-sQп&N۴ˍt"M (RVRcM^ R}NO'<}G~]f)+?߼|vsO~!>±vٞ8x7_ `6f3M Ū.P#z;YG(jgY&Aʍ/mAˆpzPP&{K&T¯N06~Lcn:1j9(q+6K+j Y}F U.O}WoV;3]V:AbVr*&]E')&t>wW0-zFT IDATO;F& Y1F[S }"):yߊXHA>1:`xCQ9j)B@"lm#n9Wy@e9C5fߌ1 h~;o.8܍h;hĉy]RG;RЍyex0o0g1F4Tf&A W %a  0kO5@@5rQN\ش`b Dg-|XPAْ1QZ!;Ч^TyOCی2hPMdu)/AQB ks4'$aiƗ>7xK?o;7͙O+/~o̟i烯Sv_NcgNKf&7Rej)65Qz s>teG?XJxld9בX'H+Auw^_V{eS\Ċ(wi:akdK]C퐢)I>ƆmO Q2׻SԾ`*:MD8mL+¤/=\-O+e'7oS%n`֡S eܕW@EBb%2S;%-#Q dsLГE%==XV+ߝd 㛏?_gCaz#wJSyy26VUjT8{8c;z<-GELΟBjUr>0!N:*p  +@ kzYIw1^3EbWOA ,h`w‘[Yʇ6$>C} 3R_(!-vs GP0yVN^%pM{ֹgۤ}x*! ~T@C!qhA67ݿ+p*8Mct/}}sۿ֕tcgO~{= lNgOOpqLp7^ iڤ6SS~#`%{No4${eE(1HI-w,#Q}rĊ@]fN `BWrO6QjzU\ˉi`Cy9Em.+(]3f⾒\g#=MסB$GV4) K"9xخ- ֦Tԥ!0;U_r'NIU^"B?/QJ2ǘ;.U]5vA $%7RTXB6UrjA189)0I(Fuc(&?=ad~#{ix*rEĩGd"g6%'~]A̹ ZM-^# >4e dP=Ȗ~ %JriWLIf~W~;|҅Vvs}}ץ7?%?}0>=t??oRW~ƄzS/ih,iAb@Yo;#SePAX)Foظ>mY{ :!bn"_ iBN!/=3Qϻ)3%JI6x[wRn?vӅ.gvg0m``BpL4Mmn6٩J$B\0p6M0ꫝ׽zhlĚ VLFa+:-V#q^˜4BRCt='G[ǡ1ȣmb{~`.$t$GKUE\\2ܽ][鷢k :tRّmIVG[m E"N(İWACo,-g89<ogta,P.1eW_Ka?j)h)ڞ n?Ѽ`#b1E ÉzȻɧ׼FIέTẙmCub &#7lQq>-#d8]y< G*+w;ño\+_J{;?Gk_p {cxpbs|L0G_+]673 '(D6is_}32Y:'< 62G{DxSeqB\5obHoZmۥ㥐L-“/Gw^&*bAy p'T|CGeDk.-A}ĿjB-mފ!)"K3J{6RWEh*%,P} Q8yTgeUQgztw;8/b5 8Mx;_cœ_'_C^Kt̻yLH8OH4mhsacԍHLJ  - zq}uJBHmˀP(mal8xwJl{`]$|Qx_84jAO [gK E ÉU(RU}x<yloVn\h9=TxO* S=FόHޫC@6Z^^t`ھ6/ZOךTaP|%٘a8yļal;R5P̃!:,]{)5R- SixXHk\İA2lP2f̍ⶩ{̻RRzCٲJu9pڨPFɊ=ڨ=h_fSdb 5s#)'ʰRjИ@dFl%㾒nz#&1Lute]=HȽJV]fL RDnMjO>miIE[v^nr5̶>"~qzgVK(!&U>I-6R.a[mV@ x)Ih1k.)M.!R"~]Gnݸ|1_]'y{xjw/Sg7aH'̣t'o:=B"D޴ao]lCe:"6{6ڴ/&"7uGE VX!^͍y/' v*D=rD̍ULZ&pZ+ί;dUsL oZR-"(V1!9o@`50 (Sa `j>7~눈QJ t~Ǿ_1o};w+>=wq'fJ0҄y4f3:8{NJ,{0c"5ڛ)lCFD#5 T6C|m<+aȿsJK{NG *:Q`BrX<[q5R/F# >JmN<25)! Cy<0bܠB}UiW{-ekz-TjSy~]e*]uvn8ЎqeZ5A"%p-w. .=\T EfŪ-yaʅ֙**[!ZHTQ*u-*i c>hWU)몮#a<^/&P1IdئoQ5:Yz$NY/J j}jo.b/O7/>v^~̩ӧ;ׯ^{̳/~MgԹs`&H(M0HN|᤿^?xh:<+H􈃩|FZ?0䆪_nb8ܩ@+"o8nL\PqᔸN.Щ.m;%gG| [^N^'.$|51@j @8<-3OPsR/\dB (a9l$Z#zA)n,mA9Nv2 ,0u<w|o>ʎ,j=XUsՇv"K3պ&B&`b]Ƭ?lr U>0w=o,Mf)9IY"o+ mUhcuΖ7^Bb-:\?ϤUŏFLuH*qc2)?X}73y Ή+}iʹh6{4 ax`&i[l.N1k[*acnkOApaihDvPM}rDD3Mo~'wWv2L8g{ps78f%&l-mi͆&0F yL-LӍg\nwDyO]J QJEhVa1F2s-L`HUX]j❍ßٱ+rhX[Zs*ӽvdfg*5G1z dۈML\ta[,Gז*\Jh|!jI:PQ_.0HՏnEPt=4|2(|em:;k %{-trlW m2dB M.*(^[zn5YlU,-EW40klj8QIfC?1# ߃v鲬JO>(p[I.#nQ'~ªV6c!`ێ꺶N9Q2lA߼uxRXZ7)Dzx:ft #-kbn65ij~ KvaCdVԏkLt.͖;eSa>a$[ʖ>Z3wF,jWYՐ=ӠDV^}{q#piV;FyKԻBےF8"ZC)VIgF7( B__)(n=g IDATW|oR$䛻楷=z;wh73D3!!&0!$ʼn`sopϼ2>D@bI:]v>1Tf:@^ PISOeSUՃd5Mn*$?F?! CVd#L%Z11/RTaBUN$D@‘2Ј<-vq J@sa+@"m+&9(Bb@j".hSVîo,o>3׸"ސsҙ/>]e;KIrMW/mk]M|CǍD'b_'M]~..1L`.qrA6 AҎ68>wd芙y;}cWĨS>N.r-"UP(9>Tc ̒zigb@UDj MDϾv摳 Aho;o;}HS9`Je&o[ 7Ƕvsxg_̕[ A@(Q(gL@ |kGS;Iu_޿3R{V15#ne  Tz&c^ 6;6|$ h(`4btC +?JcFN#V܂c\2ǽyumlz71t#z`Ѩk*f{8fyxgZU4.{_/"Qd/k'Ϟ?vxnNDJTB 8z#{W9yO\8cQK(gx{Wn_o޻vg%OS"TauJ‘?{&9V`c#{FH:I3 lRz0o#(&H6A6r_ j7/wX-@!.:⨵ f5$ 4кmZPPe(i90~§tV!uS yMGePC< 䌪(&,^V<\>|!t\3/kIY.TDTh$4 SD{r^z4 źPbս;xB i @6ej5im0YIxd npu^`n7wлu<%SuGI0V1:J L wP;(Z5#Cv׍uG&)i5-\+#ANCv2 ِ#.Svڰ KQyEpnE?z/qObYE.VC[k(~s4IѴenE񹴪>82Vh7 dEw#-Y9vn*03UֲfF-v]{ NӔ i*8;Mt|Ջoyhe\l )Q[/ݸ=ul{|;m'"p>uow00D)y?ML4Qp^ &.(Ph)+8苕с5m푥HAW6a9-S^Z@83#rՒ q3I0 |pG c8fڎmae(a]ؠdAV}1_,OJ9a O4iuxV!i}Y{ةjCC[&T- 3aA/Pgϙ(=c_gi`F(BFa-\h/ڳR xJF"Z "NJj :,%;v[x}!),E &!wZ0Ak˗̛0Xͭ2l .xSwu)sO}J"Kv3B%aO, 0 P! XL=PqB> ~'|r>v@13!]. Tu/Eɹ yANJÖP3H0%Bq0TB| eRF2 hSoHj ;x4̄R^`>:wD%B!NF8xjhi3nL$+1^Ϻ HH_RI3ΏQ4ƽ#[$ua/ ezvxlMPKR`/e(& t9U$K̉TG;Xga^ e EeϢXB&)vAl590G˃$CPrqW7 hx\-HbK%_wip9vz^=Pqsm:@}e P3@͜*V IS\sY'ǂlR@Xf 6gൠ.LS.ؤw/_^}>26NPz+A%܈uU>BZKDSc)8;{ =̫>$v-d pڎ_n-▎2%iPjYL!05 tsǀ0FmIN bKg7+1m3fk UEhPeÇK^ >}ru/uU&qԵC3b(H Wbb),P] $QXOC縱խ,?v.Р@%,j8ퟦ+o-&:! - x#݇&蹊Q\^k$Fy=-ǠeYyy=23>⃘\#n*4J}%QIZyd gI]ӆ(ii=b_S[^69T$6Hq6k RAAm#KJ]"4wC>d\F:O QZO@(ZR66ɟ͉|^= Հ: ࢴ(_ܚp(pp`Ng٤i7tSQÌ Ivbjx\hID<5waZ\YR'BGوsPpF7 lJ}ܙjbT+$Bu `(@uV{% ڷ99 kKVAl/%Bn⽼ROpTJu΀H1>_*V3D.۪Et8RSI`N=Vs뭠[ 4Tc122${Q\>oC^7|ͶgQ"YE ,2Io&y7SJ-S露#\jOhE++KD\农Jd}޾׹5'ZVjmMol=`T+AG:ì9E3£:f ߔnlJ]JzO`O& . `R:Gv a=m܏H)pBǬHEOUC[J~5-|v!{uQքZ杫(5E6yC <6f.a(LLB$NmNݺv3!=ԡ}ՠz3M@{B]*AUf:LjNg  Ԥ4wJ<HTŞ{Lj;nRQ9hΏD;Vb/P'Ru "d[" (ͺFF?O'VևP»VW*B$ 쭁3ؽO(?uU/?"K9+Z$Ɍ툮d}7ϫT>+! XLRy=qWTTb̀$H)(@{'f#a TW궊FȅþRwײ{&~;Uɤ5 B=IFjГq?wLe'aׁ<.\Q+S3bB BIyo?(B1j_E?i7bCBk5;$=C {N']2Էl-6gSwZyV|ʘ׆qi3l&V QB ֏ `Bq_unu>ZY d{]xD2uan 52ZmUD0У⫸BT#u1fge/P /0+.-7v*ݻyvw]swet')[hRqD4Cn/_}9Q[H'i6!AӭFdMp8j~7)owP!ĦBtڳє@ d JIfFVIPZ|*-XTziG')$/ Hb\DY^7tG^RLI%k=[? "onWe7|:JKwSu|SV]]wv$RMdϺֲYZ. 8| Eu\X`eP1k#o2wklg۪G|ϟ<~hw*z!A^ X{Ίaf&DdN6ۃ;wL8Q2N\n!"FJd4UATQF|R4&in@M1# Eo/5!ԏ)4olbB  I&Iq,~ 1wtsTՀe{Ղ٤43@WmEC3Sl3Jz۹! $~Ep܅4QpOMKtHL-jMv Jaxʔ5GVo12mr9)XVh^JVi4_Ye׃:'d*WH 9u\#/HUr{$T2צ*`{4 @ֶs&" 1a)=P[Af{}*MaVx=b+_pca ?X.]$ɶD~`GqVX.8z(iyJiseOr 'KtCm t2Ax&Ƣa!p v-Y.{G`6P_%69$p$3%0M._yg{‧+̢4|j԰AfE`fot!(,t7~ƾB'g\a)z.2Tcbz{}\ؽR[Njjk 4k!s['lsx| 9hm˕ߐfͺTly8?DQJ^mR8 G̀ߏiD͔6h`RyFǿ5`tVxg _0nJnOE(G&J/ ʚQ߉gګ+닂zg{E 6'^ꂗ͏BrH~ eg!U y]:dxMƹq5j PáQ44[sQp^2SYCSm'A bC $m1tk;w}rK1ZWWaC= t| ngd!-0! Lo| -'B O'`J;'60M2ly7$ PwRQ.s&u7ج\Y  J킮r`_(ᬨdvڶ7K}Nu%6O\vT|0 sa%Vyo+)N8ڂ4sbоPHK8j齌J !}$Z33uUf9FG9D 'kvbGñ U[]$z`Y xf8h88D \fy-Wa(WNIfr2g}@hM̟˥,w*VZ:])G Pr^k hGw*M;HH:H9Nvi/wښ<X\yo} ӝ;_'w\q墂9-͓r !K= iip].sCe - CPę-} P #يC(".:ȳIhph%6햎Ĝvn[:Xϒ2aW5P*WeyPTfU-d7V}D~jRuzR'v'c7;oq5ZSޯ'/ Lv0Sڕ/|B%D i*)V\B>& k9RJXt%Bd{l$I~bUQpzB^|y߱~]*3'ãbO截oY)q\i:T~R>omP~VNUϺ[?h'j֧kׁNpp$KuzFלΨEΜr] p+ 0FLdP˥Wt,NBh0NCfiI fHW 1,ˆUc5+>z;,030ణl, Th,|ILkܢΰ@3 IDATh}5CQ (#(/ìwY9~)y鮮F(1:\܂f86+[n2Cy"جK׎.2]a|a|de.ssTh?32(\? k-Y$陌 lc/m.0F@gPH&A(qz]"VqMD!P?x2 !$|DʾE(V{%Oo8x)(<S62%& dwlԺ2 ѮȺ~P8]Adc*K~S-A"Ì~XhL2/![uݥ#]% &.*A[{7j JEs@ejoXرP\@f0 Z{M+%\=Y:S ZeZh7*w)X~`FLU,;kf׶CCbk& D3k×嚗LT,#ޣ /@ JQV ¦jogbohE2CG1)F;m+W'G/1,sd ~y5r .߸[r3j+]=-Gu3/r&,M7|vbxa2mZ* 84\eR2 bMt~,rA<5&6dv]Ja/xwb%ť{dw( `r!Ȑ):aa4KZD+/0)3!,|#7I^J74*DV:ϨW3Xأ+ $ ̅#3љ0``Y ŘOV$$ܔ/v d;ڄhȳgmrNM"iZٔLE0S]>g}[`)f#0gq:QZ,껺bsn);R<@"SrҠ`ޢ,9 rH}P\F`*OmnKe3tz-Y࿉V<\r\rvD.Sd'RJLhoJ+:Cѕ[^sDrb"2ƌt-hC&%P.UTq3 hY`xFS""B+~RGlMʨuOER2bwD?j w|"X %^TAG1E-7׎EA~f9bPCJr@6)D&аnjn)9d)f&{eRJrxټ/,t0OTSR„:,HX~rCa?oSY@]bm8# r^Fl^\Pb^ٵN\%Q= )>:\a\M|fXīSo P1@Yq[%"=5fB6lRTƭ > d:$SDhm)ˋ|O0$+Fe>PN m;&OK#[܍G-45F7PKJ8$HBG4r_WZiK#6VH+fWj?S1U$)K0:,spJX-^hZ >"p* jN624`ZǔHSuW݉I.ʎMd!r9,x# IAr/ϾԤwHJDfēR>NF10>=q)([u`_3#7Ә4)v5&p˩TF 9B(B Oi&efl ahշ@ErAaЁF(=%;ی2%傇1^H]`@r_FIfkd7joӾHzIm*1#"jԴ2i3li#˰HulSTIY]w ;6U%<[ʗ2*QX aa$Og:iߠX&|*-Vt r,L09L@Q<9CcdrtMfo+þByƴ`Euifm,d'VLkq+$SR6zFH0ؾi_!aI\y 7Z3 Cl$Zz,j=3Ku?;sskc!Id@@@H@3)D(EsH$Rބ $I)$"$e7RBF 3D"DYm9j~a)Ed + JXEven|ɽaKKn 'NLtymw@\QMr=xӤ'gbL Nd? #'בR`0k,w0,d6EG ތ +|V51okVFC$YNVJ6=W$1~{% Hta YjDbO)eq~ܦarlWEwMu^3a&@N Y^>pŧN=J:Wyk2HaeϥnKXj*ASb!@NeыG }T(\} i=~E#NY<bt3wsTcV;z"RY2`yɐˠ0&Z(B׍ŸћÒM\k9ĆfqPN$"G[ aٴl8@]~E=n1jRxhZ-+!b k"(I׈nKkG؊3)sWl!N2-oH2d4F[*A38E{8m|J/30B@0LiմEf>I0щ!F4@)+0ѹ>N1e#.U]}yE3"wsBwŋ$`kHHQ~U>ؾV`b SQOU>r1,p/ǀYf_0b/_p`Fce|r$ 'ʂ1bU-U=ah:|.g G%8 yL H:d@0LqIuBfjѠ=#SMQo="\RSHL'E"st9pc`lH4-flr]5mQ#}m\'.ޠK4j%ͧl\(7RF&() l Wy knbˮ;\L?ZxG՗i?XJ ?3'EʕM:鑜D))j(Ʌ7p )){<ƕK4_g w4tu=͕(q3cbcR0߼i`*72Ul@~HgFZ k<.X24*(z/X-*.ljLp͂h5ۉ˺}yO; gb; I`^PX ^6So1v%-|/ 7Q"T]$G{.y$2qYًIoLЗ)4fˉԺP@$`=l H @&679_knȲ,o564棵$XiwꬥAD0e}x3WcBXvdY(<X(CGvHҝG{( R4A..;@%PH_WmOpe\LjheAHnIT8l#R'8@UI@Ʒ(DJeh/Pe p/jzm̬A$sIP,' XO.8r>_ jEgfM]A+zGt@ Cdq$zLEIB [Rj/f?SS숈oX @ P% 04Z=ruPT`L玑T$;JlMLFt{*>,d''#e>#7r5S|L4")t1|T]sp`T zXLMD M 3? p>,ai䋯 K0Gw?/vJl܊#-IH,emB6Z٦BH]O$d԰#q":b4BA\-qo GQiE4OY{RJpbdA鱉J ;HV*u8B0lG5?)•sVܚ}~zPf$`V9kgF7hN6u?[PO y r:ZkUi1;1!*{xla(c?xy .//#AB(S5AN|4;4óTHdhM~0D^D >@$cccmהI) d&!/!cMD&6,dS16쳙{S7"YRm%9X+@fK.0xjۋ*z[;2YG*^ u(_kRYƤpu"?" ҟE]`TPATPAThe~30? *<⚴I`~Q 7t&Zk,\n[S)Yl?m5\@fπ ϡ ាXѰXr\@D Pڬᎀ3"JeIIR[ ^Ky^o雘IW_A;ٙMxBQ ϼJ[ ⨍PL8%oN'lozW˓d6* %wN@$I=V * * *ూA~SuwgՓvנL/R^cȝ9j1_"-#Ů;x0<3\siԺ)VHKih.>/ `]- @fD0H3Z9L3RfHF\F3퀔_e\v榶ͮsbLPwqVP1)wP1ѳvɿ!=Q}-O$z/W&pƹUATPATPA<6 6ɚOy>p&p}": Y7ގJWFh5F3uYdf{wLE D |2Õh~׎Ѽ'|I))ADRd8Գ M74Qa\Y=@G|;hPm h4GqD^'t8i&eF@JBrdNRpۘD^[Eb~ _\>9g#e@O8 H@?SQ"ʯSI4\q2+ * *dՒfޱM{}N.] s,k+l&-@D,YmBBx1RheˍOkShbG ŢT)1Hix5\qB!D"0(P " ;j/@@\ƫQIL',--p D)eY~`s̄"b2 O19m8vBra8CJ~pGB{G#e`B&AĢ=.]'m W kaeWPATPATPI Z- *ֲ'kkWmׯ3Hcy&l;1Ao9fc_Ic11DGT8 @E]pCWnTHfRJD\XXP 8/*˟0*@RJ  h~~>?&Pf0$eazh"v&"je鿞6ٯ0qsZS؁vb?8KiU,A` xz(<_un(ʟ-󷔻 A@$v*dB* * *^R)Q !& D oBu:ۤΑdf{$_ #[K0<})0NNnv.Y{($HD"K3egY6Y jNDw91l$DRIK _),KӔ4T$)HB Sua{RL@OЋ,drr?/ ?AGE3Ey&B!M{0wؾ/{ `SeiBN K0MBzkvZj/TPATPATkHӌ2e^e*Iy3 S7y/A%VIĎ{%ɣ(@_MtnyFC%:y}X2L&\B7-ZȄgPe2@L42Ht0j~?k(Qm]䘩:460&ĝ;eُRRT*@&75Avr VV(Ǝ6`(\֡ y riYC|@aԵ?CAQX\,uglYux6O==_qvYqff|Ж+V6~0==}w}]AIFFVy:Il8ܯ[剓~? V%Y,T[\]5JEdt `cTPATP .̌uGD Q&$ ~62–\ f,oa^b&#En#<@.3&F><"(CCMjc< = ˲4EDH42DLt8QlnDնF"r &cQNߣnDT@J$~9áLTmH @$P|?`.$dI,¢m]v-5sHHYo.̞5Q Nyz)wRl{Æӧ^@1q-|PFzSDǍ%{]2fX=X`0#x㞰mUi(f85GǬ~SKi[NRmvqG~yB 7iUrH/@Ja'g76WL"˥7T6v>Yral * *x$"!)?_"&6_\_[@ ЍT? R<^4 >,B+!V-IAǑ$I4 @,  a̲YBܳkq]C]3U~&X"tih0xwAj˒t̸\tlH4KS)d)@#d19t.L<|j< qy@$P9`Jc)%<*{ĩA_g >#H)H-!KKqۺb69,pSR{^zVg$9\\\r z-93/G+Qw׮~Dll0e/0hǏ;Zc ][@@FbWg7\rˬZR)5f??1ٻ~p$( Ԧ,WcMݗmX׺\9os7nEygT]O jƆ5솢`3Wy$fqUކ 4̠C$-&S$.px1m" \-=ivs\ւuaBۉBw C}@ Sr_A;HB& ,Z#\3imϺ&;bd8ǭ?ʋA%?` m£ O@*4>Wj*P@c }C_tcK3NR{q/F]KJsgup0PYBH4I'=+7ϸ@Lb~ƪny$ԗfz[f~[zr]d鹉?اN ~*֦05~yOg9m^rUx߰ Q:#!C:;ik '6ZlNͤGʗ< m_ٟoI:^&Ӷjpϝ~󳟿fLMwQ>e%zhTPATPAZOfZHc&ߚR@?kXOD:;>¹k'3ӚOཹp%.E`P""KOY=0gK=Xtx]}mniN6ڧ?v\=R8f9 eY>`ㆩьW\0יgf,a֙zkݩtavJM%)bAݙDA{ SÌŊN}D' `۽dlbOO3C搒 /!OͺL􁻀`Wc̢/#OUQIip8CipA țTu@s]ؙgt;AGsj{`$^ʀk2[u^ ]׀@@y?b-eZߝOdnA0*T'1@O[@fp|-3oU:9_#ū/|տ/!g睸uEeo^rRӎ߶u}0uͿS/9 [M~3Nj V/>N- o{g5q- ۯKnVO۸?E i藞`'=mxAþ+"...Kv]}tWrnXb&8 ǼEPml=ڱTPATPA>(I$P +@ ?{P92&VmC˱=y@,[ U HcpQ:|F#Na$#!yAF,K{^4L]s_/@[f8D fYX0I@K)j."oU?m#ٽFG3I zMba.ʛ>:uF׏t[@z An6@_X5in(?tS`] o5-G{kGa^Ұ^>7<]C??7;Hv֚5>9b /zms_~pXMzv8hCJxtWIGZvFqKG՛^RZ{9okLhtiqy̎Oyڱl8o%=C66`[? K=-M?~\13z za7߾~Hc$SHY6vcɃ8lSC&֜=IOwy'Dz36rTPATPA1CU /^@qgGi IDAT`631M.;WF]&*u@{͛vf?"c(+_4&t=ag HjJV[Sp8.-MNN5kzj?v8ß.--!(" ut ǥK0Qd?4 Zʡ:qzq&T~J!D"IfS!g@'R{66xQ_q#[BJ}$"$ӟ^ORf(#d ϸlpPeu9eX 0So{ewN'=/K'K?U$ц~R5% [V@VCɅg?pe?o𛷾s7}w'ekkw]7mi_?wO]7OM'|5~u/[1?G'y}-};%+6Jn5Pztv~x;}ĩ7޻#7yK`%o}˧owGxÓןy_4#nFsló/zBزr%\v+/>a9ݖS+kN۰GȨUbpbq { P{{f]S2#Y~͍O;ubK374:u2S^>?tLN1]* *HHW T\@nf #PhvPa&-ή0h>䉉 n "" I b$Yp*Ȳ,2S](cQ?jzq~Y zK|'^9/YA(Gɏ˛{Ьz@)`\c>*e+ d{幤{q^2ABt $iݰs37MlڐӱIgƕ=u" y֙>jٙraW?d,w.# Ґpћ@?ܱ~ճO5Gܹ38~r[[wWL maBaqCKk8k/%= {8\n|Ѷ{@ 8ޤnOUѿ?=ۤ42??h5; C1ӥmw;倮8c]vRm둛֜opw_ۂۖ,[V+vg;̵^=~˗Mچ"vaj}_%M[UNmiK'aӡkK,$$R9p'g\/W12 qXTPATPA5J @@U5DZىWbfZnOGp֞0]x`/;PZwOԄ:֎<؍n֡ (2ZVKfQ<,}4Y ":5%@ !*o/`Ǭ_g!&oX4 ]C(_V "|#PDJ}T, Iĝ'4Z)c P'n>:aE?CۊHK)@֮$-oyS~U ƞTPATPA3< s@>B(}[X!8߲Fzm`b#˯&9\+vZn"taWSTUʙ CӃy VlX.O^^P4M5:n)(9lTD0羿^Ж\RE-a]Ѡ7r'}4 ;Ч O#]CGpC7Lߟ ۟xA  u&ăMOy`j:߾^=ccG$$Ɏ;K2yY4 3f;Nwkmg_HkpP#C7*9yÝ{鞅>%u X'l|樂Z35E{` S_t4`ifo/֎9 RM~oCwzʼn'<6}sp|-^r 55Zwp0÷p+'+}Oݙ~[31s~ Dg͆L;5I!4'Wsw9Y&/ǧm5Xw~ض{G}gmȨ'6,r؛I31⏞:~֛6}X_0kWhKl)uTPATPA!(3O0z53K-ߑ_MoV:F3e{lhzPP`@q;;DN 1+EӺo]SMMO;g=@ITt ֲSJi )of2Y"f@W8RA.Q󛙭c0~6C5'"0:D %v9ƎG43pKB@џ2}wԖ@{$3@qB=VFmzjj~fdfǢ'fÌ%@{Ο~zwߞZ-)h`Kw_5G>r˯^`6l^y|~}S.|n=/ٛ~4m%ͣ<~od!IZq?3O^omw.}~}7l }wʄcssVԝw| _3zFLvZcw4۽l%W>5w]Y8{|bCY soxwX6S.zY S{pZ=d0a_|bḄ~`OlϢ:C)W^Oۊna{={UC3i3/T @퐗}§N7|-ngIp6RrTPATPA-$H0an;`QFwlO~2 ~f]+ zA SNL?o w!ߌ|5բfe"i.Tey^J>xx6Ni:Lx oIr t/ +pj8,|v񗮝'Av?{35g/=Hչ_Ξyg>aŧ{z[dwݘm;&9~뻾ϟ:O{L5+.O螯_txųNܺn˶umih`á/L{}-b_ N;YЛ^".@it G[\r=( `f?[]dsٸkvKJLlpluf_3_ۤ3=)6VfYҬ%s;+ƺa'[;^a] [$glL( * *1XD 6޹!5Itln w]?xk[3hLoO2o 1+0/ɵ9Iap eU_~'/Cr1b)pcֹ v:ZtMYJ?W b9v@% $w莻. .kPw䱶:/ wx11qQ P?y#@. ÐɬAQ^Hu$"IJ @J3Bį .!]itgff$pf XW% < b:+ l7;6w)A:Zv5DI@S ivsAjbD{R:\ZDlXiOAcnwEŽpo/#'ӛ1lS=5YmII}l4`Xs j-98!zAs0dDz ̽uڧg5o,-XK~dӓcCubX/,T[R* -JZԥp~o—ǚ8n˓Ey;DQRi{8X??P_X\J=I dPM &Қf%,慴;}Xbie}W֜^ * *XXXC!&(DH $#$ʨБǨ-H⥮rS't ~X|M؆ZiF!`=_yo62H-m4x2A8RzFo[e<⹈H8gK+Ue,_:Lc,0{Gt@q~`^b +c$سn1E؃z>'[vמX|Rwpc8rĝOzcfQ:ٽwRo~n~qqѬՌE `8ީC_6Ԡhi%eW*X ƺ0 :͒Co򊧽'}}wdɢY:.W%AK[mX1`Wl슥@.,Aއ]ni.ib/>{-?CP1~}wdL,* +7:MC3ȡI=9 Imij}Xdamנct7Ko,)CRy,[9TPATPA>vQ[܉7֛YU]̶ٹdKʭCI+3B_'fB.4bTc@nPokֵk؇62u7ʧk,#}@n MӒ\Bs;2@Vk,!}?1 !jqQwmyƐX*QA`Z;!ltpi-{Pw@xDZ ?J)Uc!Zj'Tqlw2"Ksw{.e7aL9s*R1h>glk7ڭ fcTPATPD$Zg2rŽ[@ߝG`sӀa5:::eʔ655卹 %`s{;wwкq''$!jB# .VG \pmcr \wh|G7BfFaPC=x!t۝N pufnC+[sޣSNZX`i8D @4McLIQUUEQ"o~z<;UUݷo߆ @$sJ kvF;#!l@SkjJƟAuRdڤFY֌M Qn^\^N󃸒 zB3xD"YH \m}QlVDIMQFxrcIo?( YKY=h"nBk_Di2sƒ}ۤOl.F V{n9ZPgD F^C<NPDGn{%~A`G璙t׭p D,))?x  C4Kǐ? aQH~:ă' R]N!`}G+%FԺ&'IOp 7p+>[&ZoVwqE6,Fdz@U]N {ЈT7QߛOL"un;n`;O,œx05%ٺP_d0ZQXM0nQ=k.t2222::ZVVVYY骟F248I Y.[m"iJ_.n4+v#D*7M `Y$ zA8 Z[(7vY٬ɬFIn]ջm HDEH3V حQJ䣹ۉ!hp9P ,@]5(˓S 8\gq@`@н1nJ\{W_ -dXlw[T?1-wu8KDhU<n:[f^kd!~b1gyEEŗ勗iӦ~̙OxTTTfee޽{Ϝ9`IIW_=s V;uŋ׮]{Bʘ4iR<x:t1&ψh4k׮SNBܙ3g._< 677?@{)((x盛g̘qmRSSs7/|ر'Or>~iFFF~___ o۶O~ӧOIc޽{O<9<}:hW__b կ~8p@ff׿ z Zir!ĐD3yPu<|_򺻻Ύ뮻À(g :vرcdž6߇EYСCWN-7u] W]uՆ yX,600PVVvwq8G9sۇ<\~5g &iq=v Fzlhb~T&@[HO ^C"$AmZHq"c`n{RQ,r"QHrA( mF JAW8X^\ 7?Ch֋$~,0<< @ //JKKrJiCC?uuuu'Ξ=W^VV/JJJz{{Ю'4 dgg󋁁I&%V]]-7㈸gϞ#Gz <|!{&"6/v@$^r75ЭMY}WUU̙3ϟsmٲ\O&M:sݻ{zz>lpP( z{{ !OmiiiooO?=c DmEG}W]]piZoookk\M 'O$z[B(n1}4"1BIUF=#BCBXE%R4]Eg {W 0B<N`#J+ΩcϿ5IgKЁ+E%6c<@}zD>(../ wvvNJ۷o߷ovܹ믿IH}ݻv:}ѣGsss-[b Bȁsssׯ_xXf͖-[z{{[ZZVX dZk}D'N\[N2{ٻwٳg`yyy ̙3,Yrȑ[N>ѣvҥΝ;p@]]g)?_RZ\\1fKW,S{1C|=:lۘM 'GKj`ŀ$%YJbP"XoHw[[55d2U## Qe,cT!=%W BB QG} !~JTQJ mK(DQ@^<43v+*.6)\6yxAo5BŔiD%kC%S6Z>GKDbu}Dh, ` 2?j'cHPCr$={pe0} 6"677nώWc^~eתo9OK<$Ì3>&`555nw!?%J}(|Q  J%ȳ)PB&BH"~^Q"q zmT+Y]r$% {fLB՜UrFPEQ{x0 H BxB ~d97E~z ׊:brra! EU:%xc!==3vRv` #`.qo2שSZ&KCt{峱5ݘ}ZH' aR^JcLo/3]uP4}.^j3/G*C>Xu<5bZxDZ$NA-˸LY+6:XO\|ID"Dz(݊bQ__qF۱a'O+[HHQ@%(}بP#5IL192Ye2Giwxb{D4w3mxCd:5s SN!Ʉ2XvK/d2^z饵k^J- .fdp耈j -!ԉ(=SGDrP bl4\XK(Ղ t iGys=„{G'^.%R$O3K't=80}&|W% /.M6o<}:{ٱckǖkv֭ 6>o޼iӦ]VSN6[6+W|d//eeeݻ~e;v옪YYYW.++ݹsggg端_`_4ՆBm~? ÇB᰷ƃ<\ dffVJFY IDAT@ 0iҤK:ho뎸t¥j!&.!!.PEQ(DQE!TPGPJ(zSJJ CMcLD2c2i21Mc"4MCMcio>2[#LuYLFm yIq(7ra3K,>}7<{??{{{SpHA###ɻvD@Ǐ/Z3׿;|555'}W\}#GH$v944(JUUW_MY~ݻz)XAA3#Wbvz'qԩ)LӧOoY\\\TT/^{;v444\=xß4 x@ȧ֥_$+ݻ " E>s sgw!ΈlRpT`}FCnt.jF0@n>Xz]NaYp4 TQ!1B1BBi 0M H(%T!s{dL'5`1U! j, KV徳})@ndP:]: gcFA1+pTٲ"7ą'0g9, x"/vk]\{w˄ZPxwGGGIi{o wy端:00]n {PjѢE3JwqK/u֭[@~~gـҔl2~ <~ |ssvtfffYV|%u/_Y oWXb [S6xѮ.a4R'H F54.w2MC$6mLQM!ߢB"*c681kfY5s!hষ0X;3+PyjD@d: 2`@~< !«t̗ F@JQAƀq?"N gDqLG%Y{3@@Sp-w֓bUY=jR8-;dP*wвFmF۹hX+u`Se2N$.v֭[.0<R` C.D`N.d @M 2@4Dbڄ?c Ջf1?Œtnq wFks 7 qB f:8אm\I&fNILNP7Mj7x˃^x|nn_xNGW}_|GW__lܸqƌs|ׯ^zU ÿꪪwy??R/]Qu[/O*TA-vX\1_xѵ,yr&f%Z^eQ!30E')Haux@ 6ے[nJJyz7#c s1 :e1Cr! lxBtk3&B( knyI48[1܄ ϢtpDƐ edFhOHzɰ !JP@!0DBFƤI{:G@F`N&wLcMOfa)E[cRAz ;CZ@"HÖӼ!$ CRMY D@yW%A{{C=?/P(422RZZ{=9_mS^p4WUUy߃Ù nSYci 32i*26R2NHhOL=WUm8h,a(Q b@TBzoYg=S8Td CӘ8/2 .0c7/ 8rbtn 4hP'*ͬ2&"d-#]$oK|k,#%翫u b86l_:Nm]"?޸q}ƍ?/ؗ_/^\WW7gΜn!m\O3#@~~>?e7We/X7pCaaa7lؐ~:q5pܸHpwǛ^A6ĤKaU`Ȁ7y.\q5vSR@im62&r"QiPb?7PW.>Vbx8@U~%d d)LE_? 0 1`,PCDů3ýC_\:=[9fAŁ1Ɛ C#TwldD؃k]|xmi[)fN-i8tH(f'`/L晷Ym^9V/t޴iӾ}6lذdɒJ|lrQR(Ce*p:4eC hhhxl&\⪬YptD=w:s&4 'Ko:74OѦyaSSӑ#G?~,vˊ&^v^Ygm]>Ld\2ûM%ft煣 QVpxf% bэ@rbC$P4v;#VG"iAzDg[55y7z :37Yd]|"~,]ȯp<%sQ_A/=+UMY@H{h?233NP(4:aeimmmWDA9H wW_%0[_cjV&A@ RGۇ$v2b# cHx6JPQ 1<:j=`w$WiBY0|PIn7%0xg&Aa`*`Lcq2ѧ2wݪk?̸ks>44D 5uS籧voꤞy 4H!Cm^,'V?&bYȘ͚f1S7i1SO&`ؿ( /onذaժU=zѣn7}>ߋ/e˖z~iӦcp9*vO>@:~wL .=p@6/^p]15g3q- P9#|h"j:pƓr^+**/^|Yhm/-ͬr;oɎs'we N_~Ob]1N NEK/VL B"={vb~){7Wa[&Dl_ VUmk9V1; l)c89<]yhFk#|@w iiIǮX,VQQa;5G Ȁ Cmߠ?y"D@-=_o<0{ u"3V{:x wÒ 30yȓblO)ÿ+%Z!l։_%D't1!jȐ"WBj(A㚒7mp`_h4O0TPY }n[o R Zbx! c,0Ɛ%Ԭx"N@@c9}ڝە-e&n6=ܑ_WCGs]~ګz͚5>(UHϵ9b}1~Φ,ue-.) $Zѡ};Q 2}N +2?>89+J}N39Ja둡i";;{ѢEna߾}6l8qĴi222Μ9ܼdɒ} ~СC9sL<9C%k\[[[YYg?=88o>Xnݞ={ JJJ4M;uTssssls'kˢA։wygԁ#gsñœhZ2b,>֖SW8(92m  SY8uΣS:!w-wܳp*]fJGN6_t,:TYFӽe}5/g:l8e8`/gF:(#8/ ,;)31ԙ?@]L[Hkԟwb}G"y˾) dM+? h쩢{2ܜ)^(S6޼)S "zY5žwBQ8#yS&)FYb_yu$OZ5;WS,D?v39ݲietw #ZM75/?ٴ-YBnN__h4':|0o)P7MysߜZXξ>{|5-oMFpG"o-E9pU 9Դ;{??0`W4<[ϝRсBmURA`LS;~ XءP[h^oNx_pQ JD+^.n6)SO_;|o]rQ/.(8248&]Om D(AkV;>e0q>ozV4?3-?Y$w"o-M{IXE'Wgv/x| {__)4 dıϕc>h|%N R\2ho5giX͞Q.233eiZkk+t皔a;_ݚ.Qbb̀lHan-P0"B+'Q\T!! ̔Li!LCH hLcj/ϛ2(T` oTuv'@V &#jSxF S_|ㆹ;斮V޷t$KSycR;&cbi(XDFG`N"m>*z>Mo#XX-5V[JB. wߩբaZo-y@Ä{y/| VU} jӦM7nܴiD)oV~O+W2eʩSxz VX1c ~[okkk-[sq___}}=!$ Bxgvv_= \2 4Q?t95ZS5%Me%kj\*jkZ: ~ɚIET%@Bk+7_5v UD;AȈ'(0d|*I@f8_3z6#fc\ɮ=3>;@q3T m8k"!6z`[G: Fά8_`P=\0ܺcM5/l>ȳhm#b,QX3geL_U&Psp;%P1Ld HȾLq_2g)?_|Q\ԺgkW=^7eSr\ʫ C^Hq+VS55//)9{_757pi##c)7<ʫ;[6`L9֎@$_5GZH8RRrfe^![9|xEyH(>iU~6g<$~^\^y jnƽJ _216LhR3Iö#j֨8ӭupep宮Ek&I $o[u )s2./0U.>|oV{$c8+g$9Wt?TVR$l{fk[O?Qto)L+kRԿ|ȋ`wƎ"HưF0ݗEKܿeov4=( Yn{7 6Zz<;-J.-ןfb̓zFGG.FERH?5Җ?k!SiXpxDe[(P?9Pfh窛?DE8P `pJJ iϻ" ` "FሢFQ ~vY@,T2 A~dy._.S5RBAd xF?F4WJ5:əUgT2|k?~5M{rcqfZ:NJ;"u؞H-1n}$+̉ ʋPf2yFv֝/ß$tBl6/|{Ƿmvi:uի/HZĵceeW3f <;w4iO~oۧN***b#SO= /\2''?0'wW]]}сa @/h4O\MMzHyuttpGAnnnUU)RMEM߀]S]4#  " ¥YM]zB摺81h;>T[_v|;xh4z옻ɓx< @GGGAA 466Λ7Dj3g̚5+''u6ê#b~~~^^ގ;1>}j̜&GOuΪ_՚jˑ@oQ\r;QVP8S|ֹ7rb=*79JDyY0?ȉuHhE5%3* Skk1h\c]s2&ҬA-ԫJOǺ*E1F (`Eȗhv'ΟK 3i'Ųb޾)CCCC1 li$R꣱xkj^Hz{dǻ`[̙vnN?2(޾)p<.wt-,ԼmD<1u{cE/-\_SvGkYbc)'-im `.'N5jnQ%JͯKxтx3ZO/- IM*ov\7䢒}se{F`/zl`6"jsڸ ih3[CG9'sx԰%#3گΌJ'j^z97uVsՍk 5,G,jO%WޟHE4_T}ٯf v-h*nAR `>m/jd~MYX"SK+lQSa9 SrTd-tzZ:NXts1/̊d $7jWLɧ&@V;^ޒ:\E]("AFRMW)zF Xh&Bhhh1C@$DQTۧg}aD_ 4vO]2p[fN(4ivDzb!^0Xr""am{v6fbDL@?/6L>hÄEUUqigIٛ"ؽ9ySfdd bFFHڸ$''/HYYYE>ULOAI %[AeSOZ}K$[]ulғ$KDII$%$$ @89ө9ꞀQ- uj1M SPSމɚGV3.R И; +Sd(R&jp˪`:$iyƯ:H6#eFƑ!GN v[;,~)H,)҈ӣ3*Cҟr=8c$gCōNM\Nt2j;IL& ;ΜNxЕf5@R$rNQT ? xǝd2ɏdGcnwsv's޴%?<>ʲ43ot::<+Ols^~67]ZuԸGF6(V\`,<9X:H/EᇾŀԱxu,~|kCkzlBȩD(<[#J;OnQhsIi*gV-iy6u 2t S(Xz5C;/v3Bn%)RR C>0PA71JoOLwTHھC1*c;&'\jQ \\G˗]Qz*Ӹ133SWWW\wvvvjj+DvVlRdaħL^'0Sl&›(Osm8y2/0"g \.u!,lU1s{UZrPq@)p 8 )R{@ b @9aR#Cʐ%8pﺖ`f+.A|dͳm;a giXt۫0ũo @dbZm2 }L^7Kz?_QC0wgܶdGqˍ^G~K_ZҗtȑCvժUP駟^p^ݻk׮ۆ3~3~Cuvvz<{s~9 p5TK?~/_<b#H>|8Lڵ_ޓQͫ%ߊD rF1lw8e).k>Qɘ{d4/e|s֭[k.i~͇֕{1)n p^rEUնd2K Rg/qFg_8RTjg֨-&ٶŃQ<>hlrwv?nqQWrSTRRYdU4&kRIɪ&Tƥ:W~qr;x@ڼ +'"88WϜb/%?Xw1ί }<7I3߆B]̃1a >Lv͸. #&4|3KePONNe۷矷Z3P@mmm$1r ;S, ~2U~d2 Ǐwk,s[W]^AI%8HTTQeں \umPR15_i.x [V.":I뺠@$/e\۟]Zcn{׮].\H$B:t:N5kt(T*^LcȩAd2ptꑂx)t(,˸ᐿ19\FbVYO8MD bl~f˷qqdhvHQF|"4f2_D@k󨖤Zu'&GͷnASMEQAdTMH4ڬiήUGY}}CC!kԑL@se/ Tm"SU9yjxScC}+P}Vw{oS]:%ttY@Yk"*8BB-tpy};=ۺ҄ϑPs9HHTgp " *WԵ AViiLH>hMokօm9}⥿|⥿޿j f)o"u 1Tyfu`ϩ̑E525&L%jJ-eiXLU aRް3.DoUt‚2px ̶Ț&Zd&r9Ŗkcݳ#4u0>>~ .to&jb$$!n"h#;yJ-DzPx϶(4zu#ݙY :8 uc5<-bAmUiFpNH V)L%@g p@UsʉPZB\ 5N y2~n̲D2((j'?pg+#v80=c 8CEZ%T= p )c_7b#.%|k^`'|r O~[ߚsnDjkkA sCC.x<'O)Djjj+aIl) =7UB122brw=W;w7LLL<[[g{ZVVl @zV8[å7;״nQ${2gNGv4v4^No~QtYHz㥌\]-]3p66ٗtybJ[lc:wz*bx@xuǫbߎy"xdpC6QV t\,OP&WNXDaO<ش$ rG׺eW99-HԝsrGwtt#Yhv]}x2EetxťGwv?f:]=>zNJRw9co|||Nm'dtƶ+W7s @Y6R*'kz59DrCeWL|-H sNlϬD]'Fek\=l}L]1jVɪsߴ9yߑOo[J4Ǐ|-<P@(\-UTU:0$<-S ݱӁӁ٫#0+!T{s;WNG+_-~X=YŊa9nhBߚjl3ܔNKue?ۙ,w G0YB078S (Kۜr}DĢߘasXx܎1>0`ei)MH!'j0rA@A ("n^@'>C!H)˞=}m;8ƑqdP)"QM4U4pyh#:p+~vXc1 ]n!K~YдsD0EL=m=?)P,~1+J+ +d f &-Is]#Gs&!oK;r3Anj0zZc[|ӟIWT~=SOB7W_}gYz~=SO=''~_2~sӗ(}k |[z͵,KugkpJ :;uEŖ7.s+=rSy%GQ'cI6Bqם?_׿0M-Y8 IDATD硯~үհY qp}v|pge57R+ ysztAJknA5kS@!NBD("Q@$Q@ "D^Zn[ftBT0` ɚ'рY# a-aΩbzU(t'\{DECh`ŵK5^:cjjM!i*S4LU4 Tj\Q@Ur\B5!'`fTVXFe)YDZN3Yi6%LFHrFSi9: t 11eIb(+emqB٫V|ŶCB%I+Η\\W6%~AA߬.)۵ٷyUG-94 /~7nO{{{o;v|_ mJ闾{gЇ>kmַ{챯}kO>'ޙ`A/~Q>rȑ#G.^X@&/~qc|9;n9I@cxvY$1^ˀ#}_9k?hmB?p{gO,-tRgoepNSun GS/hp[r_? U{kˀhas,.:lOD$/ kaɊfIs?Q7ӦYJ&&ׅϥCyrfk"PЊ)KbMw6jp0QߧIEs.¶$' z柀H tzx9p)N;ܝ?pG3aʸii (e1F)tkTTM4Jk@#ܱ)El,x{ݑ`] Rbo}bu Q\ٞ!|DuT߲mr>{nv6`9)݈q$[1NQ1 9q΁1(ץ2zڱ`@cccyjz=عs p{َ{pKXp * ޙ;&]ȖtwHxq}eh" Wݑfkɳz!+Nn@L&xCckW7EPU*N$"Ar%T(̊ K&g>2d!UA` 0ks\_%A$B%_N鐿cxQc6AjQpe@)4LQrUMUYD>>}3/& O<%L3*R*-eT2̤r*#"٩1MpݜUAw6e7#bX*"̧Qs!}7ss4?Hn<76,f,4~hFXS,S`Wp/ Fl)q_B^2D*fC12n>7b1k KxCƅp.Jy$Ɨ G8W'OZijO%-M)z8O aNe7L4؛ 8C[0n9@VRaZ0KJ+AL3M\ ӐQ@X6 _qrP8s> %RÐs) 4@HTIWqMcHdl_߸#% ˹|@xHW*NѻJCۥ>]Cf݅i@y-Sʴɮȹ># Atg&n뾥sO߄\4!0N\cF,77fQ1:Р`NPJ]=5UX~؍oY,CJw\~Zy_8 s9E*BNM;O &aCſ0&>af=YGrbClM4^PHJPe$mc@bbf Enٝ__yi95EJ9C@K'3'@E9POH+H ?90)Ŋ)!j}` "c , $4q[Neq9*0+0B;Oy3mKck xa0;o\Mb̗o4fN!1|_]ºT𫂞KyOO9jmn!'׎ ^E{"r54vMDt q@]=ᐫ!E\[v7AiƙLy1=%IH^k(r'o'<= DJ.wVԽ-bI))^(DZpjW ?vuH[*塨[h졞ѶoCRf jX=uX'2xSΤ|ѵ!ւ072~GF8'~?(U{`:O'ްs GΉ7t֏? jlH˟pRk 11س :nn?pJT-L*4g/z,n'HUHTHMچ~Ămk5N%iMn{1DMȫO'm`7ޚ͘[/Ȍ*3=eAF!qlGӉGQ9CcyZK[ ښđcS۶rtmZZN uK`zg@ $,gզ.t:d}LtJ]nxZˮ]WBcjnmko}}Rr{w۶eÑ>yvԴ^jYg<ֹÁX7zreiz2tnvqcO&x4lj #4^A7V_1^EDItXٷyL6;,#}Cp,h6^59Zh$8pq[Zֶ>?8 ?\β (I8i?ZqG噠 x9cLp@5d5 d2znuMME"\^|`vBVz\r+wpe89") eh3kiحyɃfk8[.Nb{ zu ų2/y8 E1_Θ14dim[u$N)" Tm&CP*i$3WNv@ao{$=PwTgb';Z=T n]%MkQ\a6~f^vjyPt"",pQmʳKIpA׺M6S852j?njϾ>=?Ztj8ej;qdȪ:#)i;:H4@׊=]Y;Oʀ |j4t%N7Yr@ƶ Hj ʹSNW5UDݛ/U6wټ},Ϭix9T74k ­oFD8>( zILk:$ZmfX@;I{39v~',߅q1-"j"rp cV6t84Uy[kod5C[{ϴN /Cwqq`- bwyfq"}VYqX>y^.=>ph(҇v][8T}{ίX>qL$/׸\=wK$<5f˴'; R#Tp+! yyLN.fmQܚ<nqf@ HZD|jg$3TTBjν,_j+32J ȓAA^)%Y⪠%_7:1'5.L* $H~RrE}cW_ŭ/I:}Q5l۔B2;i<;H!'=>oo djΔN' :+S ŗy|S]8Rwe6x}Sۅ LJzw?P5 ]QQJW u7\G2#M6taGgڢ3mݜv"Z%LiZ-@P 5d\m U℃dz3qieEX]>gF׵~xq4Z᪶046FeMm1R %]NVqb249/?14\/NαRg_WdّJxܧih]uu R`唒txX*P^P&3ojS& Vs,`y @b'7tȍ b !3 ,[*5~,TP׻8!Ug7w7ŕHA] 8U&;7f Q9$qz19u7=Q8Gƫ<-1i8+MwB%2<lr_8"Jq9αHA) UO'}C'lOu} h|{tOضON}|x<[GnTҤg&շkWֶ#L$Bë-:J*~?vtPP4.C)8'Ƙ|Hkv3G^yR@'Dw 2hj?׾ӝN\Ù |t]Dm+O:+N(ocg6T]?fe IenXmlE7IdhH}X]׮p5k% IʋJ:W7vO +*J% xJ:2&R\GTWۭrnt9#)D)x =eKcq2m 8T3dgׯm9bJ"g Ľv9*Ibެ*Grz-W0]%/3w9ys!Y#J:`2΁'.:-;DA %u /">TFdم8MB" .'kAD''GzRΑQ jH(rH5dP&Y<) 3@'#3og̙M;H15~m/PDPB/m ŮvԪ)@n3$>X5%x7+>uPA7,.(9O333|$Y^q$U? w(R/SAynO5 |Vʹ?bڵ jՏ+@`ͤ蓝d*ǘUi}YNbsssps0Ý/Kk]gRwOO$e։dȳ~*5t)%6뗗ݱ tD2Ȝ3!O}-H-CdHLwbkK&IDe3!kyIߙHƶ@M?:}«`z}"Ʉ5 [K A?v'{|MtoݲoWЏ"-(,?4%KgdɟIW$6I$jϑay$PBfSfG\,\JskSl_9֓}~)vo #gϭ(sQFr\v)I ~fۖރn}#'9KQŽ2|mi OId>y`u'B+Z<;{|x/Ϧ`ݚ5NMuCuUҦ߲뿢|B$+-`UKK46Q]kCs̳2[,?e ,v 5 \睏\AA^@)=ݗeCHb80@d@!@ 77'E)N A0CM*"c#g)H5d Y>"Wq3^W[zF@p&Tiq/vHv+8Eq.)CP6inK$Lm=T(" )SgfhPA:QsFV{oٴCvɤou['Vs{ G۪{,!2f\e'cC+ݵ|dMzTrޡ;W}t"S.L %EeBƳxuqG:k !헺whwқ{ETO%`dd]W"@:]b )F --:? (I&=dk)%@Fi$Om=H<1ɢ{M[CHkk|߳m൭mpkl[t-3}GW`&*R%F1I߼ܼ/DE}ցEyO>$I^, 1ڮ?8o]2-9]댛%Em1,Z웩;=ZTݩ:)@llٿQ)hY$ӕ! \๵?8w35(H|Q_IUrttEP3 4 9u0NN9JerJBQpNLW\8cEEQ(ɿV9XV\`qxrJ̉m;BŧWPAx 3wM&{gϵNxg**`u"@fȦ^pS~ZҥktHUMpFqiLI 2!1^"בx0 *3['kw.@yV8(p޷"fe2 1_UgFPۣ@9C:՞ ?9zl5+yĞè^w:uϗ_q25mO1xg?'W['Z۱Y}c;v~hKWu>IWDcol᩵?^S? 6<37vƄLGqZcZ]萘HwVĤiAC +VL8|3u֮eXF}Jovvwȑ[6 l* v:sv1o]Sl!>lLpmӸY`.5r,K/(0u>y0hܴ[cOh]}.VeRf55#ǂ҅5`Q+ۢPPX zb @~9_}SAOXJ55jz, A HD@  ЉcΫB{UfVp2tppr# 3;4*G)]A\-nsNbŜS*Aw SB mۻ'PJ_;DakZ)v^.P IAlMk%0lJ >9p14gGB9ƿ 8#g,,g Fc@Om |q5ͼ5P/zbQG{NW'⪮r;4>,u =޵1u9T=t g1x7W;CwcPbx Wc!?^zUG Ny^2W?9܂8AIAAP DD ($Q@ DgAWR$cz9ȕĤF$d]B$`Ω b9T0 {ОC ":(d{KIku9?_nwC8l)(f3.шj`GCRT|zAH%U7 A ҳH)pk芆iApNLfT!SU g^r7gul)9sdK=q;!el%ؚDxٳ0BыE9X*'Y"o̙pW;S?g,R a*^d?o ZCNp߿tw 8#/bv7`E_FU?p{ۤoepė7}f{QAesg`>}5(̄RZMgҟrQ,^$r7$z,+ ( (-[A -Qi @@tDDL˗験D!c@5`۽}+3<5-Vn&!K:K;: KTDSS#,ɷ+RK2Lm2`信*UrOq,/۷,P2(i*q(M*;~UPA@$GkMsܨoYAC㏽N^{} *含>?ZHr.ǿ@,>G(ҴEc |+gEң\)+jn'je+1f@@13, ƖQωPs qllY7q39$jq' Pӄ&pBrYn7G½Fd{1|KARLȍ'hz jLxasv YP77zS-(3g_^nSATP9%h pw+4Mxgwݮ *xHLX2m19TҋrV\ #E䓿ŕ RM.ID@0-q?$v|3o25#4G0M 劂1EܧxmR9GU:G}"gy[K]jH-1/S0cd&*H@[o._حtߜ҃ 0A_(Oz'*j戀d[rPY qޛT6* * *VAM|$^ %`/BeV~L'72'_ [9;[QAuڨdx<> Al8DAA_ !?|LcoU M^G pR~d,QJZfHe g<880nH^!'jY/0_kkpL]lқseXb @Vʘ9i^> sbn"k2Y,S * * nYXB:̿FRasY~OϢ=]JRќnZغ$ qڥ[\΁#"s+7598hh*hhPOFp @;_m1r2M7( Hs$:/ƒDBA#:QAlz,yVbʘ*2-r3=YBXqoʽŁ%M,tJ9* * *_~0FhwҾ T@Sf_A˖-.TPATPAshSxHۗ" hf*)m-K rdL=],<ʙiRs!87ͷ%%PLiQ-'/\< r~iCPG-rN+>I)1)"gk<|or߸RohN5 dqޠZY`'6+K"cr`ĹB5 $s g2S͢2 iXĮ iCP."r΁-,8aL N`ǻ,ϸm \~a ^j Kx^؅N9ü|˼QATPATPA, Yߒͧ̆[Vْ *57͏~<ŋ??~'>O\[)GE湈ZкkMDµ8oEl7jaI.;3"¢7RQDxq@!'7y5i 7T4%'ЀZ \C!Wk7Oս=03="#hP\p!"qˣUDJL %ch n`bըU(((Aa6VK{v 3sSo39)`)HX6 4SdoQQU^do9 *gU( fwAj(/@|˷ wdwvA|a <$ Cmm1cc)F¾6iæ =F vmEvXn/3`O&=֮<&ihhhpL8{4hPƼ͛:uҥK>)! ]ZD 1:_5LBږS s"}/40( z?kRl>~H Tcn@ {pY H8䄛9RJ BE 9$@8PVEl]ͲℓPX"W8_B vo7޴D8J"wm_JX*JF6 |jq)lذᣏ>:Sx(zرt{g @Ck4tbHV948$TӁ/:􉌆Wcǎ-1JiR`׮]6m2e L2e…mmmNswyρ~Lٖ!7C+siB|DŽ {.$_ ^ x0]աqu< i/BnI8 p$pp(j!@/Dt tEjJJRw3ɝypT|[RZ-Z% 7}tfcL8+/-52f?b}BફlR)cyzhWM&ޞ]Ǿm/gݏ<'w44x㈨9F !-]w;;d2>sfȑ=Z4=o0ay睧TUU%iVUU577f>.@F$;Г("gaa]D""so"pމCHzdϋB`{塀T<4͖?%9 c19A9P @s3$9&:V?j3L w&tAP>IÉ, oDQbυ&]://_ xtqMVwQT$AD x? adr՝;w4i2?t!C̞=sϟxt3Hs)hQS00aS|2=D7h 4np샦*84>#(m)3jsڙ۶uZ믷r'C9/ /~oZH|ڢۻ㪪ԩu;vydcJ[rkMƢE8_jrb1~}cp⦅f]Zj.[6Ο?瞍%KJ6}zu{:vdo1sBƂR8&sg=̷ESڣQ8O޿/vLŗ# H4i/:Ҁh(`@AF.`BAw%ؘ9dذξj˂eˎ*)1ݫl{(tw3;RJA6q _|?/w:ꨊh҆Ajjl<++g [nY$="0p`QKcCzӆAhaEEFPbڵ L&V\yg\rȑ AF6 K{x+pPk XO8J S04%'E>AB5s5 N0w *Եz|{ڄԠqŌ+:Y4IJ6w\8z 'Ɗ24^͢3)u-=P|9KwW"j~=TpAn F!~5mv(mI~V{Ă,X:wq3f%g?*T&'] y! p"*gX=$9䴊4 <(?a(=iN. SO]jծ]yQ?UW]dɒwq/^Ŷm60> %4 8u–rhY*D>%)h/ ;^] {d\@4D;X~+ĉ&NzZ|pi֛dTsÆ{XV5 ʽcG9=jTYe=?l,lp 55c\pWk_;n@]]a;/d0;++۷Y̨!DCW+-5TUE-(w@Ԣa WuIe~3gΜ9sf!s-P__†_םDt''fa~wsy$b{Đ/s݉w(Gtr}l @8!#PThz@)S#Fii03xrZSY孜4ph/3!A JI4a&4fP#yDGܙP.-@tvu1!t80XrA{w?NQ@,v- 3B>8ΰ` vDo^zp嗋c޼y)аQU0j/hu3k`Rx [}H@{@8>i(Z.%Pd˄DJb G/ bPZz5'ޝwP6qCY߿8 @&×.ݶm[7$L#\ٳG<Жz_0mZ}6̚uȟ?_ao]&={o5kM"A=vo^p 7R᥷QCȸ=?ܻglrD-Zgw}tvhhhh@1S0 !>#G;eNe3eG@!Pkq9?q]M4tY`S;MLLiSBd_VIJ86Tsdq~A5PJr>|۹ fԾ O'2a%@ 1yst>2}G/VixO'<8MsħZj%:/}{K}Y> bPDDQ-tp]GE).~r΁s9C/s]ea֭ڄ/`M) =˴ מ}v7DCCCCˋG$FI8%!&8 RP"6BPPpkÉM0!6 }~j bվ,Q$ CI/=0ax=.%@"O(! ג-Q+cًs6M Fm_DOaɑ[ģ=QrtqkpFx-/P.݌KB8JnNۣ{q}_7tuvkhhhhh|yҍ0ΨWp QQ"n1'M1aP D0&ț@_ AH}tE1Ӡ{I _@Y[-v̎cqԆvpƐ˨@@U`߀eA&>3ro0Ltv/biO+mqPRJsWL| dT>=B ctŋqƐaL?g@.yaMlO&@õD=>C%zX7 VT0FK=EXjIw1!g|Sh~@%BݢF =&|YpaO=TOuy <_pp[' A]6% aЉ{cb\/l`_*9!gK& A{}1-#ݷ:<)SsroD!M,`-n?!ZB (*)0a"`8pJ2':-y!y!2@[ijhhhhhhhhhh|遁oȼ]ҏѧtJ6HZ$q`pC(j(yUBB(@0bPJ(H ,/*-&6[ 'c {`BgQt@!"~ϒo}kx۪@J44;w/wA0LQ"@opd"@a&$|.iƲ;@&'!]Z@fCF9Lrmp$9% "E # 'd/]JH2N ߁ae (K] 5hɎ?\[ we#8[ B00 5#II1Mbu1b?# V?Q%+KJjm:nxUQE]t)[.wc^[n1c_|5l۶M3_٥6.wBaƳTo*􅓸[:D[HK(mԊ98ثBnҁ_PW::S~9@ P,|_td>𔆉}0<->j7/&(A}:^C]yW0f#6`=AD!=@jw^ 1bD544 AHhx_fpuk:vo!`O&/_1cX4444 &Nx\wuy ̛7oԩgqƊ+ϟ?1,L{Iඪ|ln!WY.,PüHAkAa$j$JŊD̈f"f"fL4c ӈf,f #f107 0b&5aR0Iag -n1[Ye-f1,kŲ,,˦-fY,kY鬕aV:kel:cԾm;?ى^J7uq/r=szznkH?%`~0|`;$/I}\h /< ٙ-/}>jcر6R)4]6m4e2e…  ?4S|dKNy( Wˋnl;;BIبlR{`_u8p``-_tw& i5aPR0ca4 R3Lj&!bJs8rβ9,γ3cŘeYY3Xs31b%Tn1*VUɹ*@L]t^"0Dg_9H>pם{pn6cv@Hj1sXv} p_E(r"r]1G-"?hfpŵhg> q !zխgUwᅃʷfnuúu{jk3f 5 /o\%SRbtRwas{Z4zڴ!mgoLݻoNB#˯ ̚fg Hcm{nv补W^94L@{{vOׯS^[xgu?'P|#5.twi촒̙ #Ghєhhhhho}„ wnSSSUUjfUUUss~tA`P >MД>"5#>v\ȶBapjID{Hkkۻg/43gB@)MA 7(5LЬA RRg" q82Θ{8s>w^2nYY9gC8ftwxA>7r*a!DYH{reS4l|s)_~NϞPHv`P$GD$҄+0hhh|<< E5DN9_[`ss]/@X^ lk9N8=䐒B:RO~2v̟i#"v#kkoΏSؑz䑭 <_*ŷnʭ{6Mr-~}cp⦅f]Zj.[6Ο?瞍%KJ6}zu{sBƂR8&sg:=hJ{44444 ?`;zLH n Յ ٤HS( P-_I9])D$s@9#r|9G;ϹŹŬeelʦ-q-&6g#]#H( r.=wKuu'˥"2 #Vno)F  q:`Hk 7rϟ &G"=hWs@{_C:}Q44`2.ϧ w(s# Ի .wE/Dto͚fΜ]]?n!88=묺]2Y8ᄪ"B`~gY`>#JsmlL]9}В̜6:۳aNK &TZ[3ov**bI.d-[SDǾ݃z=Ǩ!^veyk% B`РDO-X.QQ&V˲d2#sdGv\Np7RM 7?atP͉(!DG&?[ ]N%-pIg @@sG8&pS$F8PD3JBqrG\~.nY19#'H(va:y^dn"z z 8y"MPG U$}yGe@(Ÿ{+AHR 7> p t ~GYȰGhi46G,6x~^}eOeG#UUqqQTDUTgԔTTn⋍i}}wsQGUD[6 RSc+乥%]Y,Oпg [nY$="0p`QKcCzӆAhaEEFPbڵ 4H-L644\3\rȑ# .˕PG$ 1{+(ˢM`50t R=& O "{Zxr9 ̘ 9p ( G2Hp"JP" @RȑsB9"r"c1929Gr;G @j?D(o@?ߕB A4au_z񅎍 'rcw }hyڴNM2d*9aÊ ={Uޱ#ܜ5,&!F]]b貇6pK|6~|E8@1T.\+VW7睗\2s|ٝSBT=te>bѢ?QCUU\rD-Zpժ]gThhhh|M0s̙3g8w<@_O0"bHآ2 Qi ANYO;w仚-?%"n~X]N#u 083l IDAT@9PPN(A9`0D" @ J9!3H/p8C2ItܾUc  n*!U@a-𰅝_^?RUghh|Qp stUrR]O)uõa*a?ɓk&Oٽ;aNImmK̙Xqq6L/]m۶nJI2OG$|.gx-W]8`ڴm5?i=L%8{횐pl<'3F;inn^vko~ihʁ6Aמ}v7ٳ_$up8%1Jb B?J@ ^:h8ԡv8qMl9 @Qʥ 9"!>)g\)s(U-_g )9c  j)p@@H (RJ-)J)p*]`PPBȑθ9g889cH<^Z>Sk6(ֈZ"J3)Js!=)T7N|)=ማ@C1bĈ3f7Nn8pL/ZhFAY7XSSA;544444,B%~n_:bpA|\rbK ] wGBFTpU>>0*)P1-6Ys`z>2J} y!1`%,"D`߽}F qm͘1Chhh|8'8@[Q8iћL@Rl-9,A  Gh!ZdvE!M@8p1ZTì$P (*Iи+=D`Xb9A2%D)saP̕AkU7ЯSDoGČ3 fƌ3~&ihhhhhhhhhPuzs {#;AJay7uD sKHw9/J3Das!PJ 5?7nhhhhhhhhhhYCE 0VKAR/.``ҎC8w߿ *sϹ~TKK}sde98ce٬ظbŋNJvqQP>XQ9("28qD~t 1g3̈! {z_^yIw *^j^sKR0ߓ>P?PiG,I|ɽOZ@ʏ>Tft( ?ޑ+3;/P7ȝBt7 ^\ eces߳ӲD"RJp?]/@%8^9I-@_hGU#"!J;::(X6#sjA]șY}nʂҀa8a2D?zON OSX{-?!>ݧ1c|]rCnjSZZk׮?֭Q>>K/hC444444444@5^mb9f ] Dѡkڒy,G[R D L^@6O}j% ,̲]nY,ZKPy%oY0Dmd!fci rnq49G0}$Q=ptbd:5Xنũ .JZ{TS™ dd2tɁ &q˗/ʎ:ꨳ>;0MS|4444444444pCz٣saP33@#!X"8 @ A.1GB|G?"QoU@,,H1,ݒ \ld#dt:NRL&ɤR)E@B,ჰ,dŲY̿Q}(˫H=G{a#hR?RqT +jjϗ~yDTݨ2}D/S YfXۼyswwwss/x=?,XO8bΜ9O=ԟo>!'?~yWJKKEz޼y<< / 47ߺJ\sͰa~˞6:φ(ٙ-/}>jcر6R)4MT ڵkӦMSL)S,\m  @@"2H lF6i+)) ,+< *H@Jyy4}:rHE fN<3.]4N k,="]^@BU Vnw_09xkVkΣ0-ιH 5?"v^<2QOLXIn֩gظq㡇.}5ݻ~k׎;Vηwd1&$`ǎPSS׭555⺱moll~;_oN<:xk"8h}6mpSp(-ol7TW·Ca{%X72>'MqOavx%Ϯ]fl _?ƍ{_uֳΪ@̭nXnOmmbƌaF+V4dJJN˗7>\޽V,F'M6mH@~[5S$`[>8+/-52f?b}BફlR)cyzhWM&ޞ]Ǿm/gݏ<'w44x㈨9F !-]w;;d2>sfȑ=Z4=o0ay睧TUU%iVUU577@I1H[Pp  5L;$)4hcqgJiأ*C^D0w c%3 ! DQB,*))9#c0r3f,YE0Qߍ7ca*n 9BY@}Q@Xaځ9>/';zۃ< jDžAph'@] $Rt>]j-[455}[ۮ2L[[[Ff0jjjvqDž/pAos|ǙO_La8H#\u n6\u +^ {6l7rLZ#}=}mcaWu X ja&6Ȇ>۶uZ믷r'C9/ /~oZH|ڢۻ㪪ԩu;vydcJ[rkMƢE8_jr•s^^{׀{4Rsٲmwݵq1=l/YT}9}zu{:vsBƂR8&sg=!ESڣQ8Od@$PȬ!zQ<;@0}8oF8oﳷ x^Hy#2Uz_@Dl{m˂\{#GtWWWWW_`߾}tQ>-=wI 9VuRVQ5U琸SGߣm+ >*`ƕR~g<0FA^z߻wˢ_3ϼk닊Ǎ޹s|0cƌw!?0.B駟>rHJyW]]o38cҩS&7x#փ>f$GL*8=%ĄqPY+^hnOw΄x JK`ꩾaC̄S }R_{ u; ;ጓÍ697l5k͜9뻺؏qeC p#JqzYuve::p UuuE<;0"|iWW+*#FPؘ^s%%FY9mZ{ugÒ&Lfz꫇UTL\r;R[t56֭s-/}8Ǩ!^veyk% B`РDO-XX}hhhh|P]]u7L,jmmѩXrf2xJkA":!}#6=Ӆ0 wIIK07@r6כ e nF8LO)Ax6p@ 1MaDF#"W~׀_0rkj(R㈽_ BT:r{J.wai{d2vZUUգ>d/t*:=F92n%"8o4@zrdmxwi3ְG@6JנsPyRO?})TUUlmm}vtX~7߬_~vwŚ:SO=^رGQ G_ve]c D`7z㯷CaHx껕!}]#B R*;G;?j8PR F@yT7 X9ԝ~zw;^e-Fxb1T0iRI%vΝM7?_Wkm{lVf[߯VW'֌`MMiX55 QrtReN@A*L&ƴρg޼х/4444V^6gΜD"OD5.[̭G}@x 0xZ_a_1-_C *PpQ5|aP//By=BJHh)]V@ *&PBD9@DQ`ݟ|Iuuh2dHYYJp?H! )%顄5 pLLjAo% b#YQ yH:Q/% 'slߏ<K>MMM?_Wnjj|lFؒy>nW] Y '_υLUAs>&TW TxQ}2xN8`]]쭷^{7OVi/Rs6سZYP;RQqZ^nBrlaK]C[~qɒƏ(QS?ʅ 7_y޽ֿvXٟKs>>2}{t!kjG]h*.jD-lcjծ3p5r IDATH* 4444&9s̙3 i;wnnx7F8_Q>[0B> #v@- mp"#bѽ+4ep&_5}JUͥd(>" *J![ʼneAd29} &aÆy ׀(3|P1V"`;5#rc39pFC 0G'@+~{E_m'WP)BO١! /P]]}饗yG^x>XX:d|XW^> υ`ç`J̺8dx)xm:]_aP{],L;ZQ#`[ bcɓkvvtXSR[!s?V\lqD { Kn۶RL&~D.#zhUW/N6pf:O7G.G Ξ=7Ϛ&;7}/`…_zio?Cȸ=?ܻglrD-Zgw}tvhhhh`3 J4ܡSDf現c~ =g_97;M* OwkrOXN-~3sl G|Olؚ +*+3̚5k/7cܸq^zi~?pqqq J4 1v%ߛ0aB"mܽfW,k8rćAg 0 J 1ysd8 p/i@wT< !& S&_k=F7m;dK9/@x8zbK"DH#\5΁39}Tw@{SSӓO>3_CTY:<Ů϶xW>Xl-rׯ=o~g[444444H\;bp1Jb@ JbԤbPb0(!!N=%')58TZDC=/Fɏ$ЊMė,7z9pu[<.?{gC'*7 nx塀@)%,sEcRz駟uY%c졇ۧާ6>'?9NBL@VWQeA. 180J'9wW>AKyM)RyМ-hs[9,+%T?/Oc6mڴi!D>?a,\^[dI*gۇz9tA^xA/^um0ONZ`x`)놢}yT},ʍ7xF*FШA}EhH^1* )j4FD@X`weمݝGOT3S~ꪧ^\5.q]vcG طo={4M3C}'HKK3|3fgu;`ѢEҦF&q!"!Zg  LMOqS@k stTyrz,Y`ݺu֩ /O>htҥ>w}GW_O2޲K/jiiim)zSN9%??W^٣G7>hoQ Ǐͽkt]7?#ݻ ׬Yc,@9묳N:餴}-\p۶m='pBVVaDUtK/-++n+Tov9iFQ@{ A #SO$) vom̸" 6h#ޮr%$eN%3ZT,kJ w+d:!91࿦iFC+hh~n 33嶣"rn8 LR\2>X|w{gmq&c߽B"RƂ@nU>C~ޣGaÆ;ֈaL?@+={/첕+Wn۶GI&mٲ{~V__oz9w\馛=իW3&Mrʹsꫯ^drGuԜ9s222n^z⋍]wI'dɒE /9#{c=&I*۷oС_\\9ѣfϞz'N0{O4>XdIuuɓ.]|&sp;YS :RDtn&!g^ʺFũϚ̵Qf,v"7lP+ޣ@\*υ`~شioy_F` Q&^ )3b߲,{V:r 4bi[D@Y5=X ft &5$YJP?L(YNxoq0j?iIKK B֍HS\.D[`C %mj64Oy37'a=(C~Lӓ!|M]/wQ@sXJw"##,O:`SS_WϿK/B;iڎ;ŲMMMbn۷hDQr `477[2 Revk{K/ٿСCG+NOOonn\ݻht<'`O!ܩ.ؙ Zd,XJIrCc<1HH@ ,rS}Nv"eh5+ @ Ad97jȴPrcs ablApԃ[^@ ws TuV_H0L7L1$h6Y)'2$) OSwTQVVӟw݁jnnǍ{mooưssusssHeTrʕ+Wfgg_ve~7Gϲeƍتp̙Ғo)((?X*((((((((a!Wp4{\T#>1,hrwY/}UtDr3䍩f;N흶b%F˒}܎/BꑗH|<e 1fJ$DѶ#YGs!#sa`acgyoh8p#ࡏ@@"Ͷ@fߎ?e$L0y=LvSm%%%Ǐ|/?A (..>묳pIIɈ#n ;vhll&45?eK<_A__vezٙtۯ/nIeu)#]?R~Dby>p~YZ8:[{xoݞ8]$2%DDմa.F7}ӓȠنAڭr '#uǣ_aH^ $6 - Z:51m 衉<@g`όɥ]~dZ)&)@=ޯ=hଳdb.\؅Hp_|+D`cΘ1# ׿~B ,hk׮U;3nܸǿ~E:|Aċ.DM6ۥ?xڴi߱cGmm-!|K.3ܼy'|zs1۷o_~}@[@?~p;p9M\pA=2|́[֞}vi%~kp?5kGZ!F1nܸ[n%ig=й{Yg曳gϞ={vj*X <ЈO&@FC_  Ӡ TV(%R4enHhkQzD fy, iq]~rbF@ o&W H`d Htdsrp"2 tyZ@K|jq*@L@&ɑlyF%t#G@]3>ix]̙<駟||5k֬Y&>ItY7֭[=+;vxᇍ5\e˖U?~ҶBcQqA"hi燿d ^tP(((((|qGDlݻwoڴi0zyٳ39c{Dp-؏؁8#v)j h8&y5~YCOR^9Q# D$DBړQV.`! :b;{ lQQG *`v"hX^h =rY, ,d2(t%%%~P ?#\ỉ_<}@{8jcq/v,9Ċijy쨱lE?'mųs?Ԋ?^B[Waa^'6>D;JK,p矃_Ǝ,JӨ߰y6nܿtieg]1~|eѻްnݾ=hP.zo74D#+05dDgNʴi~ze{≭kִ ±O3''3ugClE뮋+ kVjjoLܫ,b}~Ey\Olݶ駷ow~Khk=WjUSK^V6eJu~9i((((({N;vٺb@ ;cH{h"/޾IWD;ӛ(43 ;@ům!xnÂۇ0)uȈ[`(%Q!:`x Yj!$dxKOEm%qgݝ |k9!.V`ir8- !-m6a,PٴSc ~A۷2|an B<󌵑AXPB$>Zȟ"t *œR3Xؓ6?y ڗ ʧKĒy/7}ɐy_e$7nv >~ђԴ/YҸti4bD̙?<;}zZhٛxX((Ϝٯ~iIm ;ZK"A 9qPqr;SUyK`"/z ]pgΜyw>].6R<N7<z"'ex<2{K;'Xu,I?;`nڳξ2 xk'\0t/3ug3fok7\?3aa)8̲}sgWݻ7?AqEE"TUeS-iH_}32X߾9bkk;֮m^ZnnhĞWmjH82#a +VzC!⊪;#[F֭7iRt]F%YwGWjeePYQQٛF8!N+TWWԴ.++kll4'إM(A.p}GK>/ `HSĂrs4 Ke-붿T bvW! Dd Pp{"< yF8RgDJ\p!4d̶--7,A)I @hȜ,݊.)ޏe@˴,hҥ O¬, F*5s67_ߐ!ꫵ˖5 +60_>Lo*[R956F \Wat@ii:< G9HGDxF1RQV9vX4>=48u>e3cƌ^x矷jx|gyEU"뻽IĿs1w#il#4atK"j9|o9yo (@us7 9m+riwIj{GS$>T( Q&|x)dH;|  F /#o_/ೱ|ԼCtE[v;A[}}OdeiVziͱ{ )/OfXҎ9&Æ瞫ig ︣ozzзi.X>5v8g:Lzcu{yysMc[N,= V|q͛e>}rw@gq-}.~ӦL34>/:@@ w:bmM&2)&XLj6y$cZ!o)Oݷ @p\V-߻7577(oɓGįlY¿v#j-Q@ӀiUק~KT=F@)-:v LJ\!fwt,S zd^f #117$*Af  AB 0K[#{jnu9TK=PPPPPP6qSi ÈaB CBj 5 i !o _D>dr.3:Y:|mBUi:EQ#EŢHDQRR2cƌoL AKK c,"Rl Bo8L:+З}3&qH49*h Bn1nC x| 񺺔2p}{'"!4+I8Ρl_&A%YnZ]L/8Ϝ[B"2MKI{r%9^ Xګi@ =hkkB%iQ]abLlA7F{V ;< =@w$J ,گ ],$=QPPP`Æܳas. )#80,l>lѓJF䁝ʹ ʌ맢Gۍ/k="aGxcyo hT+)-d7hw7 H2%su_r~9Scq,d)j+b1nxl[y&0OÆ*b_ι4@AAAZ TG3q>y _#_2AL ե'D &}{r{$x-ճϵe\ aIn^%HB"-ab8p$t6w@- -aE6Z!ϥeY-0=oOkiS//@,㐀P>$x;I=` y @Ri6(}D&~{.^dR=feDmvqIgKh'a6C3d(5ﰜ`Dc[[[aA!!QCUC#N0x>t׸P(ԾU@ _3s|`'{?OT,B#͘-H<.VKfs\K((((((((((|@^?7:{͓| o<1ndWPqrGtDx!Kr 2,aN\nȜ ao^VnFzfLYwB7 C){á{q dDӸ!Qʝ N!߻@RCOɵ%IFϷڶkTpث+95#JT.$z,81r{x~g}4,KvYOꔈ  VkZ e2Ò#moWޒNރ<BE!cBm;JK3rB閍 X$p_nפ޾u}<1;ڀ<|?)^r'O_#EpxpMSۂ wi/d R6“/ f/q ~.8ySn|-o}-=&Soa LIp! `1ĸCY;"|b,䒝"ʡ{oD#3Jid<gA)T&(((g#%>蠌QPPPP~#L3BP(9`ݛ6m=z4=z޼y{)*J?'9#*ωB.-!֘h#@^/٬e[Q((|rAK s * "B'jaͣFQ lomm*2_@-7i ze57nܿtieg]1~|eѻްnݾ=hP.zo74D#xW^ݿ_٨Q%'&77Ǟxb5-p& 9Lِ!765E D"|šUy9'*+Kؼy__/??|EW[mk/:]2sլZҢMRݯ_Nn> {=Ǝy0BM뤥OJssvo/4m'}NlIӘĞu N#-[o%;BHgupLdjӽ,Ȁ%yaPqظN,l 8AY3dhpr p5ZMM%K6 A#F͜S),^\3kѢgozc k]"Vo> ꫯ&2;"/&f){1^S~K7V9t5ܧ1A֞@*D詫t +? `1,0w;?,G3VOtH 9\L { 0x0%`{|X  I#$mQ"v1oېFP^@{|⭷޺k>|k%(((8=3<25l 2)B(π_}1 49ATw1 `=S~6c6~1&"3,7'-}vѽ{cWTd BUU1~DWmmm<# cږ&Nz&.qeF ' 46FW.(BxU;wFnm[oҤ,??|%ݻ|~KȳvZt 2"7͍p!B[, eee덍eeMΡ<;:m l'y(Tv0wSfi/ zU,/yNK8T' IHFX ; px!%LG83_*&l)qcYo(tu|{ hENQNJ`NI`sҳzWw3gγ>k~NIPPP@D 9'U^{@a> Al(It ڎ~{Ϊt W={f]|q/תCӰ4. V=MM1D֘t 1#C+(K-#[F%zJ̪4X%"ddhBAAAAk׮-**Nm+++~njo/,o}f2+ypK=RjJ X$a ɋMEK鄇8r\H{OHqD&N1HSr݆4oKTD& x8riJnz@``l@[YO>PmPsJrwOA@C<"lܶ#0+1ߔh:[o%w >8oABD|.4@mmP?L ;e$”Ci:]X @N `hWqe}w҆':hP'xbaVFtv_2^}vٲF԰aÆbwxgc()I[0:SQ4x`ammG"<#CϘ`)QV9vX4>=48u>e3cƌ^x矷jx|gyE*m~Np <;"h)A@L6L<~|s%%u,W `pk&ٱѨo[ƣ<1Q.NcY6m87iUٙጴpzX BpJk CZX ZX!-4C,Ĵ i! 1i 8']\1Gu<b"c:uX,鱎#5wmE{}zM.=o^)&i|-(YL0rF8Df{ syzpuENB\B!@tτmЪI6a`a_l IRF(1XgɒL3RL BPYo;޹3R_1hPnZ!FEE lj!6dH;i'X8oޖɓ{߯'TTQ1`@_+_90m%ҴC |M7U~7ͭ;:3@AAASL2eJ*={w z_J[ Nm lML!x!؅91~vͬXd&/BD ;UϊF3ڲJXeWraHߠ49y91]hƢbZ(4bZi44-i! Cΰ 1d 3ƘbLc s]!DL.D . 9u= 9 ҅s\ `ح{~i u7doǭzK.YT:O=rCu80K]v)aڵ]8up%((($A}r`uӠYHwˀ - 6BQqVPkuYYivZissl^=/_ua3f geia~FsԴ3eew7==>mZ ^wݧƎ'L]SwLn^=//4xpi}{lԩaÊ/;n\y,^\קOν2n…oyyyڔ)~&ևsz]C(!9&-s/GV@a4LVwk9?\ꁂ·1fB 1 !jh QCd !0DIo9b(m"VE;HWi:Pd IDATw[876CEVM|'%#ygi ې}R$b?s/?yTRg3n  PayQG[ V' DA3q>o:ЍGu=:t-t.ta !%Р  " Jik/(gHo#ߝY{Ǥ0_q, %BzF+̜-BMkR]W$p@Ad{6^WR漂¡|x:A ;"Ol]TH#B3|̺|9G|}fyI,MI dO"b: FBc'B `D(G  @F8k]-n95xABD$8pAܠqJu I$ $Z7ˏ!;2k9ɹ%į@'wR_OmL"cÁ5@` [e&2HS,iF6l=/80P뢠Ivp"D ޱN>{914#edߞL|M||)P5'R-@f8$#t5↿c$8iӀF3A$cLt G bdGV^0!T "#쟌DA@׹ C@B JJ=UL yb~0ǤZh,+i?&sx`ZH\oa^6 z G?k OW~ꩧVXpI'M0aȐ!w}w(z饗(@(Y!bܢ,^M19$_2ĉ6{k3W=45ڎyrv`K4.ΉU'Ds.HXU8ay" o$2mԤ;Yg==~s|Cz/ 8O0 ͧ-ˉ&(58ݠ|'"XW]u%va5557n;G9k,x'Ě_= {#Gܰa֭[cƌ X.,33o߾ &ob-t#"{h2s7s@?vcZ [P!1~%p0N&$6 $8i2$;(@`H Hc@HM|ߎP_ k#3QVFF{NׇugaEH0 Hq2U'T2~B-OuaWY(G쏏w94J2E<ӧ_ح[իW'>zȐ!?- W~G믟8qb*-_hO>='';uK._|;_ٳO?3~_@CC駟o_NN2*ey66m}osu]N)+$ZsAF?$us] CJ| r`;1sY1W>V9-1휗2w`kC`ٮPHz:)РAݺuq +jjj n:Y+L;[hbƌ3gΜ;wnIIɯ~iӦ 8pڵ˗/Hxb"JÿhѢsoѢE7t+?s۷o7Ʊe˖;wC-_|o߾O=̙3_u(..3gNݷnz7]z饷zo>O8ђpDqm->-et6>~S 3\Z`rȣ ]1uǸn8 iX{U䕤 ANyn_[ =JzH'̅uC<\'G^A_4wZ1n)u] 9vkãHiM+ffM47T#-Pv`~KGඑ9M 䝔߿?xzaL1\cǎ?nϿ?8.[o7ͬY=%K~ȑ#̙3mڴ?0Ə_^^nKpvҥӧO֭"vaݻwݻ$\xᅃNKKkkkGB^z?> VX;1cQ L7DӦ};>&45?eK<_A__vezL:k__~ 7xWw9@bnIwyJt"0Rm.&6r;!'π]tL%h1fyx=LD9.?EsE9}-ėvǩG^#K@ BY,<-kioGb#1ұbň4=L䍪\wG5=ndKՈ9>-Yϴv!~9o9eN[(aT'㪦i%NM^Ugj8 \WW4?m tV{ M***ê*T w5`CI8묳^xŋ_|qe_YYY_"vܩi' u ++ Z[[ɓ9s9gMMMIuV^'۹)t5cyb qGC .6`@9rw,DW]rURPPP81bĜ9s*++v&C{=93{T5 st6r^sHIY;7 ZFaSoqO'w  s8G- s]׹.N<3l:ִ~薜~8z $#_'C@z^Hw7nZtiI]{=%Tx7T J;ݻHijj[W_}_4i58:}T t3"cET0|xQ>FAAAA#;JYnG+v\{j"I0ƶBy"\Wv/;bwq) " -Lg{ϗnm}OAp =R PALa%[ qCf\rN&F'cc#*˄1ŘESDݏ;ٳgϘ1C1gΜÇ yO:u~xblٲO>sʧ^yN;O>/rmmC?!'|Y2Dwqmݖ>vnݺ־k}knn~-EII֭[S Bt4_:,ļ1L0Z8|gڀzX cLOl@!Bj=xUh"U~ p<8@cZ1@4G/,t | : r w$qK-k<})w߽aݺ}_{Р\x7߬ohfgk#G_yeMCWja6jTĉ9M駗]ͱ'غfM "{lI=srB1S~6dHƍMMQD_fժv޿ɽ)6oW_t=mڟ~z/κ~跄6s5V5eeiSTө橏B{O8ᄱcz+..B 닊Il@v||H$MxwO@b7%h bBBn4`6C6?2ڽ(m|'eQmfxIxDK.W9@N$b\pA4&vӞK~2~v]uUӜ[#ExCmWںXNn8+yݼxv+2r4:&@EyiDcl.\Q٘)AH0 `/+-!p^\cِ:- \6ـxd ċ,M Dp<$ۤڸ;}c&NQ_@@TӧO>sS<7 v-G}p§z*33㎻ꪫn ff/8;;[Yƍ7n;wnaaa8q}uv]w9 >,X0iҤH$ҭ[QF/xo rrr fUW]u}-Zh)Ǘ{?Ɠ^o?M$ P t72@< n @У nWb*gξْLB  @PQYDѾT*nJE\bqA}-Wk?,.Z*|R*VdI N2{]{ϝP_is3w g;l6Y pA`y `K@@k2YPwdHF*y{E._~B(* TWw=<ߴiG_x'Ē. *˖=E=:G5ϟ?2;ۻn]OFc =WW-XgѢa=?=V}tSڬYe;vOZ4yrA5Mc}_,(=6| Hf3, Oq3\ 9P1ⵆ'Ǔ-N4o2Ӈo4fl@dh9"C/ j9O y_QQeyY _C#9֌/_8=*LH 4Il鹀Som+s)Pʘ# N5HwIp; @0 -)xN7bcx_u[y&7 "7wJ_I Zϟok7n܆ 믿wJ{駅5obp7 `0x&>oԨQœ1m. >O>Ѯg̘1c gѣGk &Cx-/~bp)_ `2@ @ ?`@?owCErk60`; 2NtZk-hr SJ$b-pU`ozæW_niNwÇg(1 ԩ/\ gIiiڔ)E[MV(ߙKOWQnlֶ|i ̜Y6{hN 0~|詧DUmsB^>k Ȏ/pO~r|pW6ŠA8?noGk%%^lS כ  666b1$:.J Yʼn"}@b<h-%lWJqj[OBnYIfP08c9ZlxW&o7Mej4Ew?x'W{ c TSח[1CV׽Q~lvHTg0WejL0pLW#'I.XQwSՃH48T:cϫ[*wx(2ImCNCHpl1) `` Ib` }rRA6?ޏ_̓v#r)9)N9唂q=>Z?hB!WӁF4cP@4`~tla` J@'LVcILP#-`Z*4}-!x i)9hh让TTd ^Zf/ާ]^=V#<|E @K |GkkS{\t?v멜 E]xq_kt}>](".(X\,%MsAHHHHHm۶\5kL2e͚5)e$:SgNPd%fheH7MESBV9M+s'`FzȀUy7DgaDTquLe IDAT>g+ @PAEz?&𑺃۟Yx'//Ȇ쌰CBZBd$2qs뎏Twɰ "1FuSQTe Bh{qts[T+D6[5~cO-L~zN=o&0&DA\-qZڰGցķf=?ǸaunG3wy;>Z[[{ߡ?Y`KNV `lv+R  ^fdyv{lr nfpП//;KK.)͛[6lhXPee9qFNz&O3wŘ1!Dx뭚}„ rQ{ ^rLZU56vkl65@A,ԢLԄ#5VI u)xUD4Eb$4>?>*u7O?ƍ͛_z%իWG}_ɹ{8qYQ؝R C1; b 7hhuL!Ar{[ͼaT $Lێw43 cE>SH1M'PMHX+7GrE! BQPò 2wjw~^9"{B?10nRP(%qFnp[3e +l_ȺCx!Bc@qKO@YKGLCpN'"\z/2_ %%%nS$$RD_wk; lڀ}=oA' @Z_vp  $(uTQ¿~ tE@|d܉s;;M֯ox3g]pAqÔR6xp:"֮(#ẺHeeG=h;Q\5*v[93& w9KAgyfnqq`Ĉ^;:}z)7 ýBzh7.lفo/inGUڵ]T(/`ٳgN9v(++{gz6=s˼Z}-B UİD2Zpxk59 MH791QX۵gͮ#%-KyC`ZGƐ ƘVהoˮSÃtF)R(PLe]T (n Gn9=In5ozOA[$(Pbo~84kį׶LPGzzu]Lw뮳5\__S/܇Z;bl?[.@ȗ3\bR3B@{9y?; .3rg'D=l? !; b 'Y:@(@z+'L\miNHQ'?8oά,ozrٻvu@w7],,w0?ѿ\s{C7߼E;`̲u3g+T;ZZbYYQ2:+t9s>Ʉ ~(8-Yrwj >N;Xq{wtEEٳLnGUٛo7.$M_8=H8'2 \`:(`X̏s( O9ajHM`՗R: 9WU)S!65y0#8:Z#m]E oV_wU~?Cҙ`(N7LhiSsvV5 2otReԂ­>k̈́nM ( ! Ӈ5g+"LH.*(_4/ט=Dy[`@@AAEs`~la,`f 0O C3i(03VRZe걑8u֥-N,\W_M᪫{t^w}SL;C=S_|EZZywM7%A:XfC! ફկ~u"*/~`;  #`CŽvq6HHHHHHP:KKЋ%DA zQ @ .GP5#ZA/V< "A@ W}ʏ0'>nu}>%B `8@L8vgdkn;z꿩?))4 ($`Әe5@a,cetP?@.zP#[[8eLL)pgV)횥GR5Fo3RP %/u؆PssBȜ>=܃ùsPPPӟ}Æ [`A}}ܹs 0u(I h}{;A Q_~RQS1ן7`q0bRe$TkkSʜ̐^Q,\ HG0,U . 挜GSn( ٮ_W { %#bnq5·ܑ(ՠ/ C΃+K 0o)Ηm*xn.`\VcY=xh[):Xڝ~VΧ=9}(+*i%o{K0|OnZn(#P) 3T_))e6ʢЈ*ZHui~gn0;@X8O(p> 0M=*ah@ F8ND◺F6ꎶF2K.dʔ)[nSN9 ?Η_~EDS\ve3fϞ={[ӽ^'l>я~ >ls瞛C:uﯪJu$$$$$$$$$%280V2l[0jQf8dbBcWIW2(9)qt瓩L6!QB m]Z#^'1 phD3ƀP.Si` A(?\gΈ}mr Pl%w*?RdQ41Ÿŏ[BP_We|S\N|Oz+VO00)_uuu˖-khhOwD"{W^yW<+W>}z*c r 7,_gu-R[[Fӟjbؐ!Ck-@8*A忬,ٞx#5kּMMMT)!!!!!!!!F1txd>}::1!Fpq5lbKvƧt|V́LA_hhS'퐨 ""Ƣ}М~6Π]80# ?X[W̶,DS$l; -_kS?7Be86EcrN>$>>OCرG} PWWw}544+>_&s444]ve>[nQd4Z ahmm]pʕ+/`0?ybumNX,JEUUՒ%K|rk-,O  hmԘ+`B(v6n5_ci(Ne,8Kϙ - mB;za|3(T<Y>  qDF z?`$@w$p$6fĸ=Tm`Bv7%e8X~o:7A M`Ɣp7֯ME[n}ٍ7ި [n1c`⭷ޚ1c֭[͖;vx㍟}kjwwRsrr|X,ظn:!0t͛7#G>C۷oWU5###--MQCw]WWСC|~ۨ^hС˖-FyΝZCشiѣGP(T]]k$$$$$$$$$fX\mNhbp G#q4sb%g&+W4Z|"h!@6Z1A;D&2YnZ[&79t;"|J {@kfN 3' EbO`Y,# )QE! <h/Hwk0ђ)Y}nK(Ї',D=]o߾p/[lرO>Dsz]ww;X^xaʕo}5p <#˖-[j7nܬYco{cQQVz#GxSO=u_g>}z40``9+Ҧ{駯9×b7pC(2dȠAkV馛Ni˝ߗ*;*#Hf63͏lAfDMNZrF$7# s~ZWȸg[')`J@8f&-E:cxCΕ@@UT4qm_ψ}M]-/>ԶU~e-l sClY]+h( yn؈AⲓonUT(>@--߼67tb= (z.`{l=MuvSCKj9Ѽml1qQ ,5@A0(e5/TF)Sغu3x񠲲_Qlj}D/.ũ}.t<3K/7iR~_ ;wWpJ'47G+VJksB<6lYdIeeeƤ>`P(Zfb:KKCЃ z$" "DE?0!!1@QKV7b1^"co}W4lO0=F$I*g5 S$c"䘿`p\Gi1_m5-Ngj,7l  opv[cWVszm>k?8~Sb4W4U)<ԈujOa~=~^7[O2#;k1AAvn rZr]C(?SO=WvSO4 ՃpTkO~~#Fdwn{'MofQ*!!!ĉ|ɒI;<ӦM[j_hѢPʒH[[q 霗BӘj}ZY8Kͪ' $Kih Xoք88bݚOVA f5wa-Âr /l=*2$bn3~2=!DXŀ̗Fc"bHlzj([4;@%u#\=Oc >!TJx&4q*r|}X]bŊI 8(xga Z['|:+w#!!!!'o-l ñX̭C}}޽{?|8⋦X['<.~SVJ4,z{ٍ{EY8M_-ӧ6t7qׯuxNV{nnnf|K8jhJ0Pi@Ds.Yꮃi劰q O:wlѕj_񐆞!NSKpt셡I- vC7X8!a2)PS/4_L8g|Wx饗z?8yK>-VX="أM#!!!!:~_z§yyyO'//ƭLNm=MtG8#Yo),x뭷!\B⛄ϛٓ;%C3O(>XvSxL%y=oo'*3  cOWB>xz }eR/ϹZqÆFJĉ<0|ȐTN= -+K#]4?=6*^]`ENB pX}=Nif>uj6ŋ=hiB}$$$$$RǬY\l3%2+bf@ɔ W9O 4g%9qъ\j3j([ lMdg,{Z2#A쭆n5gAfd1ƨ3;ZGsŃ }#GOnlk?\Y]=pB̟hFscMo(}p] pЩ?;HQ( 4 z99}RA$[ >t5xϓv[^R&Ϭ=#>fs-T듋cTA9njulyׯ JOd o:.YH.Pð9K`0 IDATRui^CncbP`doi$XahM?l3yvvvwQߝzuSpᅅÆ}>2ujq}}wKK>;8iSmj @ KPSٶm֬AJfg̲O?min&\pAavƏi 46vo N^zHСΚ__lWݦGwq.,#BIIMs%qԡ7X Ljg*q@iVÛl=klB'-@gK0$7NPK |pև'qaʠ6?Ucj*d莨GC!2sť쿨OϭAi#|tۮmK oޱorFp#0B##~X;1ˆAA'~kG;IclnTڄ  ^ 6ٮ,'WjR4_Rf\N_5|} ]E]tKH|3P )N0;pfl(!|F3qP ,ۧ_&RQ1xpziioXXz، {A^>_ @K |GkkӒ{\t?vl\Q,(Ѕk乡!c;|z>@ss|p'Q%%':Wݦ4(>.(X\,%MsAHHHHHm۶\k֬2eʚ5k***R`BRCG1[KSFlDb:h91֌g؎D@Hlӌ3غ=T6ga-` jg{Qynuπ´~C~Ã=j!kV@xj݈:Օy/#A0FO2:1 k-l|0Vf(D-8$\둁$VV P  `M2tt~Pɱ{  BMWK^ ( 3 ExvF)=OsD\R|ᅅ7lа|s;㌜t&MuwŘ1!Dx뭚G&LkX`ʕcT6?߯[c˵1 `A`&( )gtdS(,*HiN}|T o$~7655͛7kW6k;}ݏ>/s2q3qfzz] UxPܭ@]q8x7~2kŅZ}L 3e`뿻2"E;/?В/HO/ 4>@>=8 FA?8дh4*,l( hKJHƹYؿG*$MT8~ G|!&3"{3k \B⛄?W(b*Vf&c+IaڣI#N*(Ԇ)9#Y Q{}L;qbngiS >{`̲ .M0d8L)e#B{{l:r9TVf|$;ۃ}IQ2{mSʞ1cB! |gdɁn}YgF|ӧR|pxN:ܻ)fqB˖)StELϻyVg3E/Sşoٮ#!{3k \B⛄iɝl;-IGL^G|6G [{n4i$pCӕɓ &O.hmz' 7ogV7=]9]:ZUUUEoߟ>w;t[f,K]9sJ/~%5*r`ܡK3sLᇂ.ߒ%yvvGOI%ߖ4@ɀE ?_hW2m]`oVB1:zk<SM)s^BBBBB4)jo64 |Gˬ$c @*੏)-FF/o 2JAʄ6`tZ@Dx k^FV >,^cJ0PuԟQPq@(f! !Bv'FpHYz*T*&ԢdC TA 6[5Zl" !!]=묳rGuH1sR@UQVwA#A)&-vf&V9#xS_T2M& H Ea ݪU9#  ?b͎;: l3W //6A%<5'S 6UlyS7RX61J1f&kav[Ŀ/3+{O#1bD~ZHHHHHHGd}_@M!eUU3~Eg8ںu"JPdZb`EQh8eQ!ăHIDb f$f0!\83\ɳ%QG[=DP(xJfIygfUbۘ;Ci8*584 n1Y'MBt ^u-]_Ao~CZM+U 'n8}&K*SB</γFD y+tgbVdK`nV#fp LNƸ8DDB 71I+R1$X40;h{?~f]s[,Zha*zz84-vXw0H@4J#`Y-逹1urYH6V/!Dkvf/v@HDHHHHHHHHHH|-b w#`ԕy8DZ>= j^l{@\鴟ى,d!vEAnaBF1(U0w{~塎-@D$F1WnFc:chB`{'oĎtg:C:>py)D_ (Pǭӌ4VW2red{|&!!o yĿ ^Q{ZO'1PcTZ8-4'F>z`s/QQ6_oDtةGTo1QQQEQ!rRs,J;:bGwֿ_RSˍ=ܪD#^#A;ԎؗK7[TM('ܭ.I =/1 s[9ዥk8)$?CG@w:j'd?  {1vÑvt/\֑UMC$ M;4X!qD@)4zv]"y68xkd:cm-3,~s=wǎ:|-rzUUU=PBF-@)1؞1jąZ#D~[r>2ݦXEIF@2UeT?/ٷ >m/{p&dvGN ܷ[]p@ۦ?fg ,R0qx'gQ+:okቴ5nly߭ :${P8 3Φxo+F׋&DOnV@F(Qlp[8mQBEʎ huc|@|7fX M{!3#w$$$}`uN8Z?A#2;^S߷mk U1q'|$ic?iVZu/Z(U V u^N:0dU* wPl#25g=$q; ÊŲ ؛ouN Ƕcy T* aT}7W\9{aGwQ`^> n-np+` 廨{MDfWԷ@*@,o 30 V;b! kHH|`B #:h'U@%yiƠ-=ApY}GBBBB⛍O>9p8x<C}}޽{?|8,YԔ62;ޙXyU!|HŒc 6ݏv:]2j!ω[U|p! J !*ȴ:,mxpp)+@^j3f{FnR9 ά][1#"7-Nc>Q @QUU] 791hohl/|^Oԓ#6&5=d>3_9 ? [Mj8,{iF ;wߞVY?~ Imz(@ u2 S>B+  @I3oسcÆƍN-JWG_r׎EE[n\Y S_RН|;y?EAydҤ3ڤ͝{+8Bhm._~h6D8/ =>s|>fLhϞc݈pͺ᰺bE7wuÇoiPaK߹=;{-_~/^x)/OanktGgjU7 }gWT{iB}$$$$$R?<~K/T6//O3x<& fRqmBݹ{.(tF Z0d ϾTfGSe#p6B(2|+\Zu6I=.RlqZPwVwvvrTz O?ts0(1i%酌^Pix<]-+BSLLY<"Yn%d'Zx M4\Xҹ9i88p7_uUѣG]QQ$HHH$7 P"|(hopp)zlh B}7 /.UU]7nH)81wީ瞡ee鯿~dѢ˗*]<;/7mZ#^8xIi0=|3 ʲe)eO8]T'GFի,سhIp|ϟ>)m֬;ڧN-< ݦxpXG 7MD5kVVVVc__ކ@#ەEXی1\9ǚlKs4(0# bMSHѝgq%[#وZbݱ?MQItlpꪫ= ԀPdVB۰^|6ԯAN(J:xPz-~}P$@ J|h %>iΜ٩qG~wu Lԩ--Q8"MReK( 2wvv6,@lMMd۶Yed(3>9yZ!MM~K :YSޱ~Ni)m ~T}}7zB?"=4'^^oOOx0g`KK 5֗q{iӦ%xJ0KH ]4 /Tt7E'ކH*44tD**2N/-Ma}c32yy>" եBO>iy㍣aiIIw=YtYYUW;6.hh( 5ɱ']t;>~?inz(._@[\GEiN B 8? !mۖV#|͚5SLYfMEEE*Y 8`wo!8c; 榪΀BNjmk3)5\6R1_!r{3Y(2qbĉMM7<쁙3. y00 k4}H.RYl"NG|CVN){/nj 9C((qFΒ%niP~#gg[\1"׎N^J){ͣ99pЪ}ƍ -[v|Z-7sۦ9QUvmE $$$$%={ٳSi?~eeeE,-ܾj33S #Cۃu\M.X^,+jjj'k$HHHKP?t d<V2O5~rcyy{oCkD4֬ϏjJ w M&k#b-Om:1uwB(l…N:U(jIHHH$CgZ[R漄ĿnƸS #Az)ب{d@x@ࣰp7cNV Y ͌RNCeL( tv  PhQ _$מjRc$"/X15kK{sB+ʼBSo4m@-43Q'gf2S>Q]]]RR2dqӦM<L> .PUu֭6m0`aڵ/rOwp8ZtRDܳg ?Oj$q<3wޜk !!8gsAb !#*5_D &*lI$j&jD.oEQcQ_,A1.R!J3L?N;<{γڎ!nY?h:m=N5j d<A8܄& $A)N6'g:9 ́-on &eM2/?zeX2&t\ϯW:+]LҔq0IgUJg!%@]{(o` i#]/?A).v Y} ȤKO^@fĄ ֬YL&;0}DUog̘>]Xh~b7⥗^Zf̈́ {6zN;mEEE[lYr?+VOۗǞy景<3hw"D!NH̀3|*v̔+qwlEP>`%f1`%NCySٸϑN[vF2+&b18A I2pxMUmU0?'xLI %+œ1WWxLE(SxLĄ1%F1!4V**R5MjiUKZZSi-{UMU)MMki5ݛJ{4ohf>{q4E_.bAq]_%սBsD~:`Z^l7րE[neԨQ>ㆆ &d:f̘|{n4L0s?iѢE}5|K/x6mTMȾ?~"D!:`nr&e~ T>~Mm '$x,4ؓEZ2dRwɐgvkv 6 Р.*)Jjow*RPbXLPBQ(bSbƕXLPD\!"! RJ)ӒR5IMӤ&Y4UUӚA5JM4UT)5 AזVz}4a(m_,kS;RfZk 7WZ p . ׳ [EI >Ӓl_hv*p%+{#8#SO=#N={ﭷ޺K]4ܵѬY~;C~ꩧz)o .9s~@UU_?{}wcBwuguɓ >nAG]QQ̷z~`ƌ&M*--mhh3gʕ+TVVΙ3gsՅO:? TU9sf]]~ӧ'ob+**~g}{ RnE"D!B`aqܞ!ڞciY oDwd X24l\"-wkЗgZ_߹S 5b RH)8BB&ĄRiE( EEE( + 4EXjRj5e~kR*iRRTUTRJUJRKTwo~Aa7|9 iw$RL;늇Eviv۷ߧ167'vKDIG=B֌ )X1?x7w|w1EP  0xM6^zѮV@v}%Kva]tQss33gr!3glkk8q 70}_WxۺuOks݇'Oڎ:_?я̞=;??/nllm4M=߮]SO[ZZfϞy!C߲e#˿+Փ&M[yÆ 7oօxUVR{LtM61~ᖇc=iD4ržUVUU_[]!B"D5ߡÐ0G%C(Kv'k\!t˾}}*0RJW% ,d!ƀ1H$kD3 f`8ň( M͍ͅR#Mc_Ck@K( Kf Hd,#owC6jn5 џ՞e\~Y`:^Kh bN;ru\Ww %d5@H@uuuLS^Xi^{˗^o,A=UUUA555SNޭhmm "D!B Wz#fM;~s^7q $ 黖%$ := XjšjQ%X"Y@CH2K!DA~K" L 'ukTJɒYQR3 4Yld hL Uդ; V %[RH,'Nszx#\wÓ}%}sX:]K"4VCL\0c-q,~hA ?V st|g T3H+Hץ[ wmW_}5h\u袋wV+2h +뮻zי? ݞ_~_SNkO8ᄮ.ھ>Z_#|hA/.EŮϘ5N4eJRx}{UGE&<XRl0B?K/T__w;6d0p eeeW\qEmmm_$`?j Y DBdTO7pwg8t5OA`f ijz>K{?JT]:j)MMZlHA텚C ޜNjJUSR5MSaV5-ʴXJMƒa$ `A9({NaU%!,=^uUG4v^_`Yn fξ lݺ5W]&).3vms̙3WYY>ַ(r'oM:uԨQBN8_ollsevO2EQr:_}K.jkk $ODk֬a撒c=ֺ֗"$$([GvmY'FQdMj4ƚXRJU_~?%1Ą BR߈-a/;wKl -M#jCZgqE%X@(3lI)̒$?mt#玊o}r'ҟĽ?9G^&_b x8~,=31[Jی]9`hf}7P̺gbAGx[Ưw/]/M5"oXn~oxb)| ,=+>󥗚-k>ؚO 5C+<Zcd[kkcӣ=7hF.χUW'sʕ[KK?o_*Xgi,(P ~ˑA]]ڃnx֎:qG*ӦyI'9~|"D5gϞw Ξ=<|/_~M7O?}cƌ _w戡qqAq"A PH B$@@Dd@D 1n{{5ꌭ 7(O(@}S>p 3+e]G# ;rGů3+X@%+ 4B`!* a E/Ip oڑ{,YRj@31َc (+'f8+>"._`\ C5'$Fv2k}Ί>#D2q0#quk,C˵8jUnlgU-?ƿ*0qfĒbއ? D 5`@Ծ^<0Æ_l~f)yW]5z= s3ňC ydܹk,@YYF qc~qEEj6mϛ76G_)w߽|-kgx߳4 M޺6s+*=ІndDO*+ ӣx'^mg=tŊ;#Ÿ1h ;GJn#u|!B.)ى>S/t1YS?^o("7﶑"oE*u}u"}/UbAx4USӪj*Rפ^NT59e IDATSi-iUKUWUGnkFψ3m'u 2与}POLjt:mL[3UUF#)UUjR5!#pG%Xq2)`|xh|l6gHh> 4p~3| ,]t' G G_i8 4[/z2T8S[6 <䗣p^ē#3^밲[xq~Ro~+-f}x+/?N8sN9([eK- C*jjP[13֮ȑE!j{/8aJqqlƌouQz47^}sM^iSguX&4Ֆ3-aeK7ZgάNa༚d_7͋x\!w#D! Ç Z]]ܬ*UUq#"ea+c,7vjrsvN{YS_Zrׅ/\ ƪ&%k̤0HIaR (  EjQuOTi:'V՞DfN(jG/XQ8Pƒd,5MBT֤$ ?eӉAw÷uIkA_ځ?ۘ!Hheۀ~?AMMMV~zgٱ>GI,*A$|Q8n\<=w>IBg6pnkчr3>',&4qo #5ضo^aSSwԨº|W{Ҧy>կzhBw#Ɋ <[++Vۣnnh#0p`F|%K9%K5O _`3|w)b1#3Su]{9r?+>Z/skE]o).`IH$ $ X!,5 $B@")@dvŪɄa^s}Dx<^jږ̐,q),!RJfMJifb__x 9Fإ?'s}$YBB"l/^|g\xqWW/+?f7l{饦 >;C+:@0eJe_koO_dzg8O}K,i3vGg]]=?aÆhooos?|UWqXpaCC$7FlZOR)Vaq"?--]bQ{]?Tch{Ki b{mxn< `|!yS$b'^}_7cУO2dO u쳍:޴wDBt?yq.|2o /T~~aNڿ55ycO{ȏƍ=.w=d8]x i^{4}vGWD!7\p\_.0t{ggŮ *!2;[Q)䈷f2qxEF|ɲo,>7(ls%0=9ˠG~=z(&2Cاii( )"RB" E$Y"B2At (! X]_$H!efɐK)Y &%P?@Ӥgl`Y>JS_ͽVt}HGcK|Q\R07'xG};IKx?|uuW^yYg͛7o'-',YdWᫍ15rǟ/f]?Ŕ$iKw w/Ĝq|+J1`&MqH썃`pp< GTqDU{{MퟒgW,)(&Z >aÆn!:_L&_>>;f f׿nW%%q/|]w5dR|W^i=Aw޹gF(AKq%#x`/Qg6p` 6kcm>!B_)IE^2צ X?!'X_RΌ'39bO; qϛKVR'K?hesC|vijRjF7}cI"@R9H_8o'T<b=R޾k7Oc+@J6z)02TQO[i"~(F6k0w|޳}fZ[>%wi$Y@ jjhsdte[)q0\4zyH#;I~a0u~{キ~D|s=3OZx~nߩz衇wy/}٧Gg}EsM7xG.\rٲe7|if͚6mZkk .\dəg9mڴd2zׯZJs=9s[BEswEU<0Ž¥.6;[A"DE8D\b R@ B$"P@=T  |AB #C<~2&3 ;y> lW-BH 5śASSJtk3š8%)T)XR !t &'!dmI< v: HؠBuU3)%tKK#hhMC,&If9K߾M:h~ eqxk_C]_ߞm.8wz?;B"D÷c6gB+&p(av+gUtd3)VmMwc\gݶ!GIާi.϶ W KiUՄ, IB@Q@RIЃzj$ (9/%0H @^֤} M'ztHi i `ď}r8(_NCv x ,|*-uē̒Xq8ںqh:LsvFmȿԩSW^{]qW\qUVWÇ6l؅^(lhhxGo777^xt~hix衇ZZZ#G|]KhL&cLɓM_O|0bĈE΍!UIg%B"DYk\aJbvmʎg)5j2ƕĤg.w 0ud|d ZBd՝Yع }{ =( 6G'{&մ(BH"R=/LI`""Mפ iFzNHQb1md!Iɚ|%NɌ; f=}% b?БKBnub%>8G 0K8 ,=/d|Xw9SN9jjj <묳***~0 n3f5\SQQ2px#Yd@dTovbJJJcs=wԩS52zy]uUǓO>d{w7o2dH~~ի7lpy{ェ3&|vM0lذUVm۶:)K/7oi?Wɚ5k:7B"D!7 zdliV+0 h=brX٠3aPmPb]ާWwfY`wWOՀ5@a+7&`N;7vgNm%:s9_0 3- 6n X{T?# qx^(3`%nX( 8j6vF\X Du>`ڪT|$ Pbq0ۛ m6t ?QM7d~r1C?~}(`~#kt>c\ȱMvw:Tߗ`xxphbM2T. bLFQ,`y,%(!wȡsѣ=ݎիW{;DUY !B"D2Dq"bD1B'R @9 Г"h5b JŜY+3lt&x] [[!Dg|[zfA VD:Mn<YOYqefVQ1׈UbtjG! UZi?'\_//!ߛ<$t%>G +55+6^\wm: nd[+hYkS]9眳?ѣGs9;J["D!B_aXY[幗0f*ahp !Z F]q72?bk8 cɸLFĶmvcK޼0[js].!Ltvb2wٶm$()+(lRbYDawxɪ7Naqa|i ?u]<6sQnݑj2~<~;rJ]]ݎ!]mY>\4쐑?z5\l?W!B@̟??bŊ֯_yvi3gܰaC-D }xߞF4 Pb^#ˡuON&oB(o&J4þ+̎ xX7XIA A$ 2 $`EZZP0 AXYf g#B(P jaѮ~?"B ]1s{E.zVV^zols12@5]׾r Wl{R8餓vΝ6B68?>ն|%q≃ƌ)~%,-;O_'˗wB"Dacɷzf曏;|pڴis=rr 8F;g‡x5l$܊N7O췟{)&`0Yau,DśPIas$`h'$c(+dc`dLD0BC %{}?|9;V3=7=r*%.U|6̛w7>CqG "|m:ʰ fI1iҀ!C_&B"|^{UWW2ӣj-[֬YsG8#W^gk&sWz/{r_Q9x}^4R#᳼WOީ?#>.GCCM0@ªf4jJ"U^Вo>VL't(  Z)t 2  dB䌬ٞ>+ʊWy_ˀ2te*m%Y%v6qc~y&MKUH? 4is}#қ#DгX8cc =bߒpj5*\//#1t#; c `>2 6~<>?׵=Oš|K˖5{l'R,47~U+Vl80yyucxnljJ*V QSŔ)3fv}{UGY =`g|A}-=묡EE1̬YNX'Z[SD8À6Fkw6zt>: 5}kWZZ}n>^Û//G=cvtui>7Z;: 5OkO"D^{x 'mhhbbXEEEccrR Vl.L:bkF6 +nSr[s`n/(pQ]|ϼd=6VSP@۩{&'f@o>٨ ȕa( $ b b4fXoZ=.@YwF[r(`ΏӆBM`@89cwLf&؎ p-`FPlIlTR+r;>cV#@A3, IDATxP >Za1-F4܇Gad5N3qR!êًqδ6tbK/5Kɓ'{Q}3ňC ydܹk,@YYF qc~qEEj6mϛ76G_)w߽|-k}ZYZ&ˀ[o]N9szh 7|2wx"t' nbcxU}ӣ{VU%7oo="D!w}Cw$jN@_8SbH16)+-{!)*eYs`y Dƹ$i i^u%VYyFW8W Z/? (Zn[پ 3i?($ &&a"=D |%ݷ6qo %kzj.c{ x8{d>O`Ĉ˕GU;X1 !х DBB69&b|!F];v" a7^ye֬reWv g{ԩ#G%cklIrHEMMjk9fwPbڵ]]]Z^9(Dm}}g=P).͘1Z[}j:4tSrueeXOݴϺ{VzYCIQZяv3-aeK7ZgάNa༚d_7͋x\!)^"D+++VWW777677{K  mΛtc;D`F]+b6ᬼ#4韃RA`^ɓ7jٵBbGIQD2۞?NMm+X$ H*1 vwۜ?YMMMy#zM3 L AcA>h>7HۓC ,}23vʒ|̒$p`~U1hРL(+ϱ[cdKba=/8a³ _))T}}QuuI.m7S/,T\+*E^ݭzG774鑃80ye#zZp)YUBUUr<75]%% À4z%Lt|%K9%K5**YC3 Q7c [[JX0Mu˔L=皇Y)w88/%e /H?L"BfIdemH"@T&qAD|2{%Ĕ):&UUE{PD,UQq @"fB8FGb} Aa\I5<K>b t!HC=!E%b(f.v־#DJ|F%aOb'h(@ޡ|2hZ -_@P-j:+Qˏ?f7l{饦 >;C+:@0eJ)_ٳGMXF'_Yu\Noᆏ-Oe++)-74ꃹPUp c =ZO)K7%쨮NjZlמo"B;-[rW&ŋ >CV/_.ogϞm'y\ŴUyZ%83iyf f[:9ggme{[Y ɿQO@$ !ꔡBRtX$5%&bq&XZeBEEQyuV?0|d6R ^!9ϱ \sY2ȝ!>lO9~7:,B/=H}5gDb|.:ԾwkQS-hmC( kV}e#6>!Vѫ?DBL<`]]ګbfzQ}LH)[>ۨSMz{ǎ-N$DiiD`#jjwg?\J^˼)JtPwχUV&:;kַSo>VJ~;7o v:OUU{݅HAGg}to~A"|Cp\p ^C{a;5 7Ȼ\##`&PG39$//( 31Y?*34"Rb݋՝&75 %[N*o'?tҠ;\3 #F]{혾.a%xG .4=Ə="@"|I@nL*wF@Vw+UXߏL2In:'gO͍4_$qKHZ&HH RR?O sY&H7M\ާأ.+..D Ht<WGQf4MJCմ7R0xLi l 3O]֊L+P!J~#ktĊ}X.`9LɾD="j'|N_ O Đ̆ L,^# %X&YJKڶ\v-^x]mB]K/]>mZwӷ҃"Dy{ Ņ)D1A1"Hy"A A 7; B`Xo5 DLf^6ˊgF`FJ4ȥ¼\P}pf@`Ǻ DG9N09b#3| V@[ Hb\~b[':%$ b(#|oEujhfdARW-),/O87}4fg"RJ]eоq;{ h96 pxWW%{R@qX{*Z"DFWАS|"De^ed8"K8b*\ilIƷ3w}- .l`ʰTۅkɾ+l}VAqD$ H0~zTҭ-yyc𯔒Yf8?0 e@?Pb-=i~@2} D Nڳ{=+'SƗ.m{2;nqJBaD#NX"|ݱjUYg{A{Ym!B Q( rw밥]Z2wsy/|#.oYege6gFckoJ`5`IL,t <9z3Ka[/hڪ/7|&,nO`^f&T\d'!QWu$# $ =a;9o~#0?"D!B"zX$6`Ɏ~F#@34jy)Fs]YlVx/'O'a&Z HS{H@(4fz b Q b>L_;^k`i,O"(Ƙ(A"F'"i!\zd%!^UYsuˇ]Mu :/kۍ^ڭ%YGa%%DuGJv.m.-džwEǬY.]ڴ^~G>۸25ѡg #D?>WX>u;N;m̙6ldow9ZdpAz#&?"LΘeRHHy(h+t>.}Y^A$ڪ*ZE"% %Dj`(!SH퇍 A $00xbP 8DuC7`ZBRA>Q_oAP2 >Tww-j?x{ X^ W ߾5/Wx b~!Wuw!_Ix1c_f{p%˟~WIФ"D !^J"ޛQOUM~$/ [^08 1,d2,8q!8 _%!0_ a2r`&L \ [lɶ$k,]u譺OK6(rznE5dJ ӦtuD73M"\ @%鈓/]-qz0SY}# w a3XmTR, gZ /p$IɁ_'%H$8@*.{晵GEFAAAAჍsrD"HHL1soIsBEV9焐3P>j  ‘Ca9yy:\p(H4 @"MsM ̞88Ee[$mx8"/v;ZA'`쏟рHϯ^t;#a/ ZHG貃`nO{ #М/92-k[OZd8e}%Zx)<;<#lp6 lzvKtWWgc].Ъ#yׯް .$4⠻;n۲Pcc&ϚU'ڟz+_V}u_qF}pPO&Yg/YrOۊ9a,š5{xc|r7'|2˗9o^{{+-r96n6f(Il@ooa][J~񋒧[f޽#[ZJnZ3-!bhx衶{l6lY4= q7vi_|nGGG]] H$uuuE]QB_x\K@@н1Ah" 7Y4p]MHN1EJ=1>o!sɉ㄃TZS54qB@tp f6IȃeHTP `0g hTMf@2a Z& H$1={s} Z^45ݻkcf.9'vC#w#"3p\bQݕ#1aD<B* RZVh?i=g.7x~x:剦Wxo%i)'W}#Etl[fzsiZ9lz+ȽVj3ok~ x)SL|}ojss飏_jǚ5'Nx̾}?uu.jڿ?ww1gĒ\EkwvZf^~w=p睻 ӟ./O]v-WCnm{}}N[oԶti-.qѢg [Bw匟䄆9Jh7MjB|,]{! ԌhLa![pMJԓRK/'Dy'$%z pI a»M_%5iReE ihP B-EFdƣ8 4"ՀD%h 0 `:nV̀d@ )Lu7PMpDcY5{@4>,37h~/hyg=0#mp3B8g`s<:Fءq4Oyq_;$SlRY2'U$ iZy0?Y%Z R~Bf~oa7Igs^;F>y fbop֡!;i/O7w^vڴT^pA~)C&N,9_is544dd2tڴ#6 ,]:LH,Y}f͂N6 οR?d"A.l={s[tVU% c~ư%Y7nlijJvӂH&)!H&)ZZZfn]ݝfGx,ANjXCx"5r)5w:1Jwq͸ˋd4 ig۳lO(p'|J^xjqߦ IDAT~k$Ӊ༑pF4Pk{fK2 k{lmdg.Sq7G $YsJ f.NhBؗT qMp$IXWjU&>=0)((OОkԥh5ΑMG؀FR)jZ#jZaKS]w~{K9%8>sRvN_a7OKEՕoo>l҉K|㎝ڵAe|6c::rr96~|@cck>d]wjn.җ&̟_tuhih乫kߞŝJYM7mudi[H&I&UW[ƍܢ3-1i;sDHSd!d ŦMjkkzfٖgygO@xcM< &ws&wϲB:%bbǛE``3bGxAHdd|#k q0` rppr'5cl5RR > Fx/㤠 @R=1g|aVJO33΂.A싱y?-c"aC2'B\?$Q?e9#>@i⁋-E@5^|զ̉iZiIwt4Ȝ/զ?ul6oU$g-]#o5O[|s]k5c;R Yg՟uVhDʕo_y ~׾aCyk j ]~5DNeӆ&[1Аp-| s##F.gd2iNcÖͦ 8DlZОo 6p t\v @*pz<@MM_䶙u"$#@)p~<# QFy*a# {^Jy1v. #ah<ȝ kMJcJH \x3p;< {)Rn0Kгhh:KIa&LJ'.#1P|SC@8A@ YwS/wzkelU\I:8@̲Dk9ߐl<M^,'1Ϝ:5Sc6> .\X;4dR /ts%K=w4ɐ6r9<:[iRs#fUR*A?qL45gϮ=V cΛWL!u5WIA?ڦ̙́.55}rc[zȜzjw[Rf/0w@ئ1 nO:+/PPPP`ٲe˖-3rh_G>!Hv@"H=8@ܳQv`л`LH.$WM'pFf, r=c&96_q3y n;@ p F)58(!$KlBcEWV4hClV{ w 0a8L42Y:LK \HIKYa>m9"DgK{MA8!~9n-003>^OͨHsFjS啉sN+/5+}FhH<8&~iDT PDFn)[RT#T@͹ۘ㮝9GRmѢE }}ؔ46oakeeT;餪m졇چ)%lߟNGWv{uD%K۰|_z~OL̞]a%bԻڽ|4]{s?qW~鎩So)k]yphlL-[۴=V+{2#'\ ^}Bfv]tpr]R筿 $P`G]Bؿh`h}͚K0pf1*jkr#öJv@G 1tpPWA9TSvj #n?GazR-TtꃢO')oݢigAP 838c8We5z^;|a#P-K!&(q B^X+=A@5q7GZ,LYQPPP{~F@g_Dm~3kO8±rO9"AixSуȩ2KJە;#v=5@qI{n ~QNYCA)@ v$j fa,&:"0tf?!h/=ˎ0]. ; V5 8IX+$z(|-00*=&5̜Y G) xaR PO Q $p+S38!AҗNBTsFD| KO) t*>YfU %V sPs=hݰ{Q^*<ʦyѦ}5qpDKFRjQ<3SGLAAAAAAAAAAbn-JYBQ#>Dhc{Dl=d7o?G& s3wK!Bn?J$v\^ 4J 'Nu#+q@$JyfB%Ժ%N}9j% u 4#;fǩ/y 40#k$|) 8k ѹ}pK]_Z¦ob#J &d)#N|'n?_M<4o-i*xn˚#R^J@ g湀JAmTҗ+,eAƽC=6G4>Zsaa1y2q],Wy7(%4/k<0d^,&#>t7-D@|3;"A`*i{`esB 8{!F)!ۍ)ܬ0a'Ɍ*G@Vzp< .~OXX~LAєx[YJAAAAAAAAAA݇rI 0ƧyBjɕj؏,5(p.Rdol=UD =;I"( 2GY8h #N޸(6lp8<1j%2Vf^]?;HHWFF}} 7U#xJ}^E8r 9Q iB/=n HG~z*DOoDjOrnF 0La@g` 2E}m7~7K=_#pdd_2\C78+l5 zkx/i]4O!>ujeYl;zGA#b(((|03-vo>|QTbu:\&z{ hG]‡sW>{˖-уEg^uU^zW_o}xi2;rlӟD<]d˜s 1(Kb$!s |c[]z+2I,մlKSĆtYI2JZ2H')-NjɄH$ ԒɤԴdBK&4jдdBKP -Ajf\g3:3 F^7 ftP(Q ]7 >R( }`H^m<TI aG T/Tf PQq ANT |&z>trͱ6>7J\Hp5.qѢwnQgO>.? sT[!.\k):XTo袋>O?SVZjUqeo,Z,1DbG51 ҉0h$;f"+PˢsP;F4:]򺖠Z"%4ZjF5J5-ԴD$4كI-jZJF)ca3fg3V0 `a^0a tf膡Θ@ɸ U oi+3 bjri #,Rf{VsTF&硷ęA#H6pFx0 辧C >99@*.{晵GEFAAAAჍsrD"HHm+Vl>眆ŋ kyBpU_\^,_y۷+ l۸wxؘ1+&eiիwmz*/Jn͚={#oi)ia!㡇6nгԲe-ӧjӤ(((((7|i]|һuuu Huvvp k]RýܼQB_̎\{ Of16q1ڑw?̘VPI8>@#RhzI))@ 1;Bqέ q;0Rg08c{@ۺvynh*[o'a\\"& 9/?؏ hvݏQuc","8%12{ hf (((|QWBn;${uϰldm\Mr:v?mm/н~}7c|o1eJYO?Mmn.}VXdoؘٷo?~.uEM;LX˱֡hͷݶ\?َUvtӌ/\yBUUsW~創kneUsmmOw)qۃږ.m޲启@aK㎝񓟜А>p z4= tc[9%{Jռ9Rx_"OK]O ĵƝ > r3HjJk=s-RZ]%:!_np- 2P*v} T:CA 8rW߉qhgDmAftZ N ߊ&@ص9Zp0xv)h‡gXh&E^/F])S0ԡ_y}}} 3*)8i.}___:я֙w'N,9_&M#c׮Tif C{ȦMk֜\VXyٲ7z{ 55ڄs͚ V/`z$._ձgP&Cl9t4_n6g [bҤRg{_O4Əόaӂ$$_B,Dfݺ' ]׻' {.;3x&OO1KkyX80.^`iϸ0s-="İAЙE+MoSS wʹ0_3/yNH0lzpC]abY6画Q0N+$gdT]b @AA‹7C@U rڣ?oSjOg7j/@WW}dɓK'N,㎝ڵMB..e^d2Q]|啾;ё166vOu׮/}iVhih75 ŝJYM7mudi[H&I&qCÖ4ɝ9iIJM d2ZPPPPPbӦMK۲lKK3ϖ' UGN"?L?,L$M>||Y+xr;:㿾(e |s]k5c;R Yg՟uVV|ϛWM~ [ ,XPS(g喷y%%r*[_6 ݝ7rGLj9ǀ4[nkgޞ1r9#iz"ٴaM s/>aÆn!N?ak׮uzH[o2Ƅ@_"h))/IQza9ǴZB Go$ADR3n&>R)pa…CCK/B=^sǒ 1ɥ!}ݺNrߟ5"UU B< Ԕ={|[-;o^u0@׬^+&ק3j23gV7.l"cHԤˍm #sw߽nKa0u?4@AAACe˖-[,ʕ+_ 8qR[&,'BhXpyy1*((( rtٓFMI6 ۫lo'O>eEET[aѢB_>6%nZY,-N:j۶A<{衶aJI6Q+{+|<`ɒ6,_>׿l++gWG X1v/_f:M,}ŞI IDAT~ջ~co9%D\sl̓Fccjٲ0@ئ1 N=Z#)tߡA_A)#kv&׵f dFr1!w. DvǦ~by@a87k.`g0fs} ǕUBw&qU,~aHaxЦ׽TTUnyVРijL!΍0 !E;*(^he5x͏Ͽ;Ҷ5I1ppsp9c1pƙu<$7Ff)g‡=ܱ6ὂ_Mϛ.k|.铟]遂»+LN4AH$! B4B4ByTyޟ P xT:I9!±qAD!+1{/AtO—swDOJ*Z\er~yx ḫ؜Ź[ N 0 FA# #:F (؂ iG'% s tC7l A.&Bn&zo|:܈#,:N@p -BPhErϫ` wCCFGGy%$?F}%!"w6ȯwW[p(TRGPXL;p&"tG;!B6qTxvkf~ѻ4~ cP=aVQ&T {.3VOh0wG}BAߎۊDΠH { NI;x!KNZ:#֟!o$3]08g%n l f;^|l JP(yIPxybGgAq 7t >@t}8T[X?A>{*q_|| "NޟFq^8w&kYMsIBۂ;'#1x4щ$d@߈UAAɠDw "h.7D`^ %ßs~ g@}%Paٓ h@FìZ</PЍc@E{G7 0]NN_tAQ[QܴW9-BAAAAAAAAAAZiѼ)C'澔z Uk@8G|ׇ4 UC3UqP FAΠ3tn ɓJ`B*RS*Rf"`rRZ^t t/pBA{}u}z DF 5R/[T&5f65  É^( qRPPPPPPPPPPxocU\" lGg,Hݚigh*#"6 4㡈~Kme׳{v:؛> s8t1 170b` o^ňa}iYmyNG^ W@Ik< ܁PБ7Stf6)`T2X.$&.ŤfDM?RQny] #p0V Xaa7(*\buG.~OzQƣPAAAC{+_ge˖Z[[K/ꫯnkkkC|yN9B4?.Kxox;q.cnX.1@[d"{DzA BKocB sƠlP0<'6]7Jaz5kV Yf/hrr|Bt%G9nI$QwT9Z7d RAp=G~1~Ž/Yg㚎]>q3gV̑k6=wNh'g6m8&)(((s,\;?~|~E]C]xᅫVw~ !y S Y򁠰G!\GCyh>Rnw@Aⱄd/j> ׻A֙#BB bsP"F*J0e4fTv8MBc xmKÀn`[78/0l(eq*Sˏ8ªƷD"QAAÎ ֽ)I5]Xs Z"<(((((|1wܘ\.H$ wرxb/^zuOOOmm_4B-4M `. BG.uEsE!L\_@:oV}? w@p$(NiphU mɸ4 >@)z̖ O^ĸӇ/l鰻q'-թ&ؙG u"‡'xm+N念78eNCCqB|d<,k~ ۷_߽aC4]rIh Aww?ܶeˡUWM5O?TgWWLGO<߶$=%Ki[b94,^_Xfo OOf7ͫ޾poo\ye@.g<`ƍƌW\1)M-^kCUU/~Qtkٻw[ydKKuM {ư%D =Զqcͦ-k>|T&GAAAA!>nN;/訫3D3 y"n>!۠1"F#(N@ | Kl `|F{N\E|.1.'2<ڜ\VQ5v$0  'Ԡ,ʓ(K̭r|t<6 A6Ƕ3jQ_x32}zɥ'?u;k痕K 0c&:;G445IViALF  Rlڴ6G`6miiyg?gyf飨^Manٶ4* Lfd%'W2$}w q&M&miVw5Ϊ?+߾U}Ænւ5  gn_j^Iק wwM1b1! [fFF\d4Ҝq$Xlٲe \2ZYS㲬0@}#F:L6Ugpȼ4Nw\{\9=aV).G\j\Zl)fn0ǖ. =?j4ǎ^@cDK5 nEMBgIo Z4"b#Α{wy$?,k@/gϕlQ.v3U?/. /˿Tc)xi%cT[aѢB_>6%nZY,-N:j۶A<{衶aJI6Q+{+|<`ɒ6,_>׿l++gWG X1v/_f:M,}Ş~ջ~co9%D\sl̓Fccjٲ0@ئ1 N=ZޣO'5J|)j^/FCyoҗ>[Eq6VO>i?g FAxԃ;=S9[̑緪h3sBW9`38gs q7/Y/s=wMP8fw7]xa'?9wWLN$IiE Fi*i f;N ¸) vxפ&<6MRdjG.]xF< JLj|Q-2ZyqQd{7My;z&g9`b`{%3;/I9=ANiBMƣYspfBg& K:'8[-82(*sRPPPx?bhU91[ٯָ^/aw {`]U (=ܰDI$I\,.]d0"' I1u08^jC^q8Gw=0jLtc6uȾ9yv=L,p;j{ eHIiG8xoE>V/FXVv۶ ^~k^s 4RXbv s8V?7?ڡxY!C#(ׁ܇Ճ^I9q:9\oc$ݘ^$Eyou7Ww7 7"IOg3r'pr> [Ph0xq͊qRx"Nx S;G>Qf, QæIв]{8V-I'̝| k} "nqM_!~_BT/9BU9[5;#M/O01r 5aW/fg1az>ڶ~bj``)4WJ]"QhD̊ B q{Ac"Q*GAmѕXD PAAAAAAAAAx-@I:*9Ab6THl$\EdけAPx8#&xfNfBDBC`G g>l;Q’0 k󻱹3~*?5Map89нX!NH7` FuM=p@tB|ashVDԪ)q3MuEYNfw\E[ʥ?X>ai2Dr,0Pb=Z#rLcz= xq_,8wCPWB!@pu>_1ް8-'bD& |ԣSDLQPPPPPPPPPPxyШo(D: f7'Ǥ>89>ͣY% \] `sBزCEkDİ6 ,a48c?TGsaI Um-EoH;6XAAAAAAAAAAhOͿ5mTUb]4Iu 1cÎp';@ D:>a H@F:'#* IDATΣz pD@)3BkA 8_cpd\PHG56$$8U,R#0扣m7pD*ίӯⱗP)SOkk<h]~= 3/nYK逝 `L/8= *8G\qG@b?Ը}R[eecBY6/ 3ߐ`a(/՗h R ۏ0TܸGˆ9 ~>‡S_Å7{u^yM{S ``kx{򕯜}[l,:K궶Z%,G&}\&Oz04 A&2!(,F8 @ܻ+R%!a>y#d_/PvF%.gSF EkƝZUE8~;55PP8vo9} gg gsܻyWk~%K0 |Ae|b.Ο OE&'_ҳDZϿR o/Y>7n̊#9\sͦg 8Y|쳟ӦM$c yǏ/:XTo袋z /pժUGn!B5=O5Ŝ5*vY; +z؋eK@P {o/sqog3疹'p0 αnp\E(ŝ Ϩ# |g ;/E !Fea4 3^܊+I-hE'q4|g?։\ u08:ν[wd̟ 6/',:ں1i ֢lt6?:>>ZbMׯް .$4⠻;n۲Pcc&ϚU'ڟz+_V}u_qF}pPO&Yg/YrOۊ9a,š5{xc|r7'|2˗9o^{{+-r96n6f(Il@ooa][J~񋒧[f޽#[ZJnZ3-!bhx衶{l6lY4= q7vi_|nGGG]]]"H$:;;kkkur.#6&c2fp!m3o; NWfBB'pbO&r76ph=b*\E S+xJY.u^’.|fv6K?6LA*E*3Qy(|bV ig~r+W(((=<:w}G&㍿IUu< pL;Uw_FQ]f9 ZϿV|<3f"[Eچ_x{n…78cʔXN67>UvYs27Nol7]W袦szs&N,XkPnQ^}lǪU;oiFP{W<*s]w޹P`?ڵmܲ}ժ9۶ק\θAmK6or -j~ư%Dq\ONhhH83; jӤ(((((ҥK+++ΠQO#n_$?zf5$0hd~K ߪ \[ :RN:v\spgNs2OˮA(P<,h_]xb3v ՗o9ˁ9']?~ǻb&n8l#%Tj"N6_?n 04"'߂Oew? O}ӌ/.,>: NǽGԂ{x2]y5y"IIAZ%LQ: k;\@7#BtnZV t ׫4Br?(H!1d:I999CUwZ{a=_ص]uB#{̛G~.But6>( %<$ }Xt DO3x gس0<˟3X= GLCCMs6Κc?w]?iMMVdzWWֻ)ޞoF]w j<ܵkٍq֞nUѲW硡bGG&"f}FF"tL.'FFLy0cFGcsTfS,OXy+F$bÆ i={{{y .GY`A*>7()^O u'TIQ'֞,^ϬcI+a%=rd" \+Da#ym qW=g /BɅ+ .bL$:$pGU⟖y9-bnYE*4\rhWG}sSӪO5fEA JPQÅ _%|p 6~5X;~/=(l؊Y]BMs+SZP({9Xpi>W_}CjX~_];fEZ3hlsN9Lo[ny,^NdpݺaYguuV T;'%<{wǀ[o]e,P 1#ޜ<8X UP_&}ݺu[re.{x@^{m};Z>[5@BPaC!hFvG4ZE8/PǩLY2'0Ȁ UbN~+!ZDL(=b |] {PQI]L-  "z_wj q%> *IZfxȉN#=}YreGgRv3[? ք>lچ_Op qp%V=4=S3eLO5KCwhfŒ%KtNNʧCܳeٲWG2d Rm$(Ν={d&6>'{Oz@)ַ^Y=gv^twgn[ߟ_?RzhW5ҖOOO{g>3ՕzZ)G=,_| r-fϞo| tˊ{+2RcCrpe@M6S 2-mk|UN9X`8 zOfRPʧ5'Ty^m'WJ_G5 ÷7W^g6'Sg>Oğ}-ooOL}xyO6bٿօ_ch{nϹ/Or󭭙Fon۴i@SBPoo󟟟U _w{zx',[6~V8{qtmmO>;\wݼڲbų8_"|`[~xy7ߜzc:f}me__v4@C#%?ЮOo7.cX۞H +B,JFA25jY/Ti?ݵ%Rr¹Sc\O4=;6Wò8>cwbFKʱ`YBX7:eI2?BS.W{SZV|s.< G30!&~,AYem"@B "" < A /5W*KVTP]Pg|Li5 IYJ a PM"K|x꿶TiR9-Vb!@]6Q%wx$)S"06aGcS|Q=|wU9o`````pL/*S!rv~Q $.l~ӎ@{\:Phvp*4#N$!H)D%rTix*bH,K4(`{dm.:og0+f\u7w6[X`*6k3P^>6^>ǣ0MLIH:b#fd*3lP pdQ!$B|Ll2 H"AGE#eDSJrK@&J!=Iĸ WOSxD"<8bJW)HaZ sǽiUS; 8/ CK] E5 ,.j*hjrC*=jv0H)Y*$0]2O!Yr[mal۞P6Ok(3H>ߐq8{fv# !x?r/A"/SJ}Ejk 2@.Jf!EF.M$V$ӭ=%( vpI b`hscK>37!2gl Q%9d) Kܩщ}&d$DM4]\.!iSi)nI >1m$2kZ"NRx^OQht5G!$Sx,\g͏p0i ]$!BC9s fz=x8:/""/Ij @ "(HܻkqRLD8ѓ: ) ,XDoI{BwgŻ $x$.Wg~PVjzeĴ}L77kGrgcmQŠ^rɌs>\ wgC##Χ>_ݷ5չ#îu{gڵW^hQmv뭷߿ _¬Ya#ON~]#xN)BtO@P5f`T4 X4K< SDB/[26LBX…,RATiJ SPU@ETTŒ*y_@A"i kw(4H'? UQ h#y^sH&\"SDy\,$ v; xg_TG|$WUXP?aZ6LIHyGX˦Q*yc8/iIA'6YyՃ%w{-q^tY(L/Ѻ͢]>+(nn*oy.BC:u= ^|q|u/CJ .}6n<חꪹO=CC&'`Yǃn {ٲ#$5kcDx[.tvsYŋ_|qbdD+ (}m_~djJxbqV2`֬+S@Oc:&'o_~dl._>`AZ=o>3.ĻwmwuuٳN@\ʉ\N>/#HwO0u{NWi.X K$2y^eIF|'' ikCdk *"B' }ֈ ӒiY5yii$HoԒ:8V*y IDAToFTimPUaRmJ Hj:hIޔD}k@7 y-!=s-w!UqN7'>Zщ 6-jl:YOFA]Iz7#ۧ|rxaxɒo<{͞\5k=s ;vL}K/tue/·;8kVCm+_yٺ7)_KV|M'~ˑ[n9-Cw޹qWzrsoUH|췾uj oŸ.q /;ܞ{L[Bw\(/ܮ] _hAZ[[ZP.|F'As{J@0+>՘u= <is:#JR\[6bsZ,"˦GdΐT~ǫȧ$M ,^_{8禵߯e5#UdjSӖ<%n>R Xct1yId=, ~djůH~@ Esra<.? ↠zlo㒟LO#_bߊϮ\g7S~٬{K?OY.gX1cIϋ󛫨,n0ves{ٲO?=:2%;+X8vπSOʹۦ|Ν[' 7ٹhk|#Ӗg[Z~0sf?7݇G&#$40000```;koo\,]7[#ߏsX]$1O ⁌n C.0=թǂ#UcSUbAVA䇈U#+A`%JxRw*{Z|^Dyv`6݉FBF\W<82nk_n + иRg ^WT)1eQ%~"=+>/g3ɛ]uN|MM~ibGCCMs6ΚCww55Y]]Y"d{{7яv]P(3r^;g?ͳg7~ǝvZ{UEˢ_GA?l7`d!M7=rbdd(} 3f|D=-1gNe֞=EˢUhq!oA"6lٙ#w``G y @+ďćKȧ/8axl U+NgaW\JYj;z{ m9DEuP!7SqՓkj䳙\v.Zv.cel˶39[dL&ce,+c[۲-۲2e ۲²()UtJWʒ++W:qHJו$ݢ#)S( o߳]R)Oyu,(V$$'JͨG2zMAD->GMEM!/ԝԿ.Q -ֽ}.cdB^d@%~8 Ԅ:<4uoml:}BM#{ѵk֬ٺhQusu; 7,X?uޭ8Q=6t/|lwwNJ.yly7X==9޺(ppP,BAĜ)yu-7'%Tyhq{nI|__nݾ}V\|x (pvmw:::n: V;(p=)@&y,Onyc^A=> TM$~=ktBS?bHxZeM,V)8NA8qT)m ۲lK˲%e˲m-a3m !e[^݈RJI)]Rb%]W)GTJ*vt]בJJ%R:JJRt f j畔~Qzh\P5ZqE%["aDQUP000+Â%3tΤ@c_e]̓[t" K#2FIq7?3껂'h!Ïħ|U p0J٪C6+,\srR>Ծ'-˖>z!u J);>ǣ;w).ZԒ͊6*g)'?w-޻ӟPW/n$'{Wo9qwַv.lv}㳔ڕ8#cGo==Oo-@WWH{hq{G&N|˗3x-T={7iN"wwsYx[)6Im=$ &΅j 82Be'^^GDx wIއȉ aʖ' zKg={&LLƆ^>J YXRؖe i ,$KX KKKScTJ*JZ*+=7t])]JIWd 3+ H$uefz;҉ܚ#~n1008(A6(>(h\Ps\^.˗Z)v~zq+P=UU Gď X8Nػ21HJ #I6L)+]_ U"$(џDr {]o=Y)f¶e ¶l["!,K-Kr̟ DzV JJ){\)~Rʕn5JJ庮 l`֩l~jdDž&iHl_skz$Ҧ'M@[!0ղ9 ܂NfM7 JYQ JR`ޅ,OuX`pmwszGW.X"#(CdYD6 AdYD   @^VOwP!t[Zu#yRXu%?tVY)q=m;÷" r */ k,l=ZqGV JR* EJ01$@) ̂I0X)) f+)dHŒ+b;*)=J)0X1+b!A;}[ؓ&>P~ ɜOL#VE*c[$&!h|kM9EEG^>~Q1zW<{*TLP5(bQPWNS##tcJ))-%3[)fbV,,b$$ B"[&RD\_hJ)J)VvY*V,r%Yy/ JIsHzPTJNJ᨜ski}ynd!KJStݢJJVV%zj喜kqə*Nn9mϤrt3t$RUD-0WG=~7È$-SXԦ3ykE&G"+6&QzrCq. bvF(/)>aTxu=C##1aaWh```:=я~]zƍ֜m۶cW_}Q)f\:eIt0DpzOAM&xh r%TӢ9.k,xQkh_BPQO$TҕJW)HU;^:cNTCeO%%*9Tt*׈Frpl.\YtTQEG]JGJaWYhAkoek|זW=/G,]庮t2nyz{Zi!š.꾞AP5 Iql$ɕ0kT9v213.l9tC5lx챽GNtTR{߯6l;&s,Y;9sf~_|_tEVӇNaq5# Q/R| p@tGMUZٝʚ+Uqdpe| ^?@(RҮQ5d AXk lc3OUD]EAW2`/ X)0+YvQG4"( -ĎeRYf,?$Idg*/kATxAbUBܶZ.@Uu_=ᜅ*o`چEccN[[({ٝE്SN9B`۶mۉ{}饗.] `ҥW޷o_gghpub^{B޺ +cA",=bKVL2BYk╠0X۴2= ~ۀDdfG*X%HHvgנ"+Db ;k75eѨbW*R38b<+V V'u6eNsY怊Y%l'~_j{3'r?*q@"O _)Py5v^z!i&"Q̐? n1Y{gpܭֲ3J77&J5֌KpiOd:,$/WPx͞|C׋/];nCå/~qƍrW]5wѢ?ghd],xp|d9t/[v|Du=w,] `~g͚K/lGdVxv_)+| y}ׯ'|sz{sFFի7??5kԷ90xIyׯs{{˗,XOt߯E'Ճۧ|rxaxɒo<{͞\5k=s ;vL}K/tue/·;8kVCm+_yٺ7)_KV|M'~ˑ[n9-Cw޹qWzrsoUH|췾uj oŸ.q /;ܞ{L[Bw\(/ܮ]!h-qe)!^/kCƊ ڟ7G%T,u\Yrd?5DZWJNK%JTrXʠ->H[:[r\u-9Nuj?tkq\qܒ#- KӊGFeɕ%u\8\@)Jzo[AH fO]_fji")>PvR'L100xCԁMpa5֓paP =9q%gDDI<]֞9Xyvs/̂//XʕON~v|>u|Οߜ͊ /߻4:xۺD5 yf e36o? c]6ji-ӣ##N\z3h .=Ծ+ޞmgYغurpqK/ˉG>rA1m }޽Gznoo3gs}hqd2Az ^oN;<<.u{{{k+gP@(T!YU4D;|'%V{RJ:RXLnq@N?`dCC+X:A'x@Tpy ~/ ffVJ1CyUiCVw`RRI>JctN/e}Dҝ岙A/a?/Y9$R Q;_TW?ZPɷs%4Ϟszv,jUSRnXs u.ݒ~85r IDATL}܇z/CCMs6Κc?w]?iMMVdzWWֻ)ޞoF]w j<ܵkٍq֞nUѲW硡bGG=Ak; qpM2q2v_Ì:Q|iK̙SgOѲ?aZDa```` 6tvvxG.GydhAh$}'$&k,,nP\YXT {RQwpa%"$%HYQRtW8ԩR W0Yy@)fH;C)l7un-v77=Z'ơ3~R@,z_DcۯJ$!ˎeu6;HD|&'U JͿqKA U)99 ri6hP3kzd4HBHlf! 32Lfea v&ו W: 9 5 ?[PN`h?3XI3έrPq_*@!/SJZ;e:|A:JTyyz _'תDփj[[*.fwQ D ^ɭ\o" (/˙H^؍Kꪨah3w+}u.Woe}×Kǣ;w).ZԒ͊6;?'MI[w?=[,^OHDOO3;Vrs~o/\g)=+qzGGvǎ-u= dN?|3]]Y@; 푒}t{ӛ_````:˗/_^-R]`7†xh;Nd<1@e =8#T D֝I tfb]˕HDb_(.nL,{@)9U%$(L6ٝvTfQQ%#U5Yt@Q?9&QOd oE.P ~ʿhℿu000xA-w?gdUXyE_r6.=W/&JȜ|/~QX9.}|,}iU鷗e s9ܞQ>W|5hm6(o߾}J}sj뮛[DefoÊ'|{;7'xG ^wݼڲbų8_b_|>0c-?{޼o^8%t\sͼvύ˾i.GJ~]n\]X)GD ZO LQ\ M{<;A7j mG T#_w|PR`IO<(dΦlP^Tiښi9`8\-:rPd6XMfI/Nm=a'ەi^8 %au=[vGS @STLq^Wi#[S& ZE7K+]Szbd(/C1+(fVPRP."0x?&3|s.^遁ĕ NeȐ$,"d " ""~8Ըrָ1>` * Yd/T5] =,B*kp 8fZ8T.OeAe!f(w_Nd6`6(c5] *vtݩRQx ΦƜF 0P3.'Gξ9 {2BKm ̪ʳVo=t?&ian4i&%"edTn$+CA5h~Y;ͮg!ki```p09)wﮫrX#|QRtgzRtN9.RIpYA}+w9DE4Cfr:g/]_v6]V9:s($Ȕ%DXQ2~t`ojłp,a˓[GKC,gBx zq :m"# D>9ig61G@zvfE=w# % G)w=6-&Pgz3?el4~饿=̎Nj9ֶJJ&L et4C"*t(fgRbWrby(t *vKPL]B\js<ϼ%в.X (ïjbّ 1\q5JVs'DX@)ȁr p#-v!aP`&aUsC QwhZJC*iC^OMx袩 qs(+H)40<…>xڱND$6/Z3_JNEY'hQ-,8H`.QD+J]TI0|AU(\S@O5%2'[@Gq% %*psHURpF&bM`oK.eVBNX} SqpIM,5kF#ļ02Dz=U$G̨b+fo`````````DX#ǹ>?dǕ/3ʭdzS"S6B[O(.dy䞂9Lǘ|tҔDE}xކ"e ʎD<7D$H~Yr]4[,l,``C,lG  L`VN,yD3{ (v-֮WD4ZV-O tcq<U{ 6IAQĚn>%40000000000xUaN# 'N8lO# 6*Sp`l9 ~16+JSo0|+Ey IDBDVd0+'6[R(؝V(p]` QX޸eD@tg; L\tY[x^@b@Lu=z?>=_iQݼ RmEZy /:Wn;n\ ho-iJ@P *b1g9`BF+ici>V=/[i nOܩPp(4>)">"[CKʿ``````````G9;=TU4kЫ&kz@b?bK=q kXyr@SJbО-G?ӑ}z KRਁ_#M2^Ps';VR*mc#GuG@$DZYkDLjy9azaV Pb EP("&=IS(VB_}V(o盬d,d&wf$?c6({NeFQNw*Hi (#Y1Ą7!kLSd`7J$Rߪ/?`(_y q$ԟxt} ~ɢu ^U 0q8zX': Gs2`dy~56V;{< ^{>я]ڸqcmvUW}c꫷o~pƅ`wXdF PY3ũqdɸ7#jA~GB{Mڇ1kn#18 jZ8weJ;I2'Xʀe".k(wbըZN6Z?A;V{=kPܧI0Ӣg*t@l _7%N-^0p` x3 ZZQO/0 4N]uϠ7[O_ ` 1k/-J;ڵ _xa>H 0<\7mx/wUs-jӟ{JMM;OLFsNeG]ws~wҥw֬ߏ-oivDfŊg/nʼn7Pݷ})y͗_>7`dYzhk| [f+L}۾_??miK蘜߿}17|zhԏo3θK޽sضյgϞsDἉnDcӢ|LNLUI%FFkvxboժ+^1uܗuםaܜ~?-K>jM\{ ~:iŊmM>]OlY㦛\}^{*"|^?7^sl\]t_S]\fM{۶9p-h@ K.Y|S2upjaV)Ʉ6s)a&}rMaHmP8q;WZJ\@D4ZSІ@o]0Ko6*ُjAsz=4F+i+,$"M}ޡLIJٗF>y@ŜEǺyu,V𗱣|#123w)(g<@wu;` 0`AW/d>{ M&_ 0`_0 ^ `gmew_~/򞙙]ϟ7Um޼R]4kž=]xWwaÆlࡇfffNGm޼bk%=4 7.xOgj,a/ \o}1##F [=sw߽on+ZcKQv-y~X֯|4 ͠vT .6mڴzݱ^^orrrll Qwl&Fv*8?զT@6av16eG{RWgX=2]BD&"BP:+6}}Ls~H@08Y?@],?6i-GHVkl?k`3vNs4j(D@~?Ton|pT|TcAXD=fƺ9b;Mc\4pB|Gx@csA_jtaXqG00 (\ pPV}` ^Qo6<L -ibbba: 87quf7!UyQNGl:2O|v9~}֮m=}[oᡍ_g#|5y_-O|y?ܭVnT>{Lv[MMuMt|u:5G]ڹs>Ip|oxh=)@+Oӷ~ݻv}7o&S =y5\/yʕk-_Po& saYt֡f٫ī,+O_יbHyrhBDBAP43)T@lXHt՛GTi$mGiOw{iw!_1zűQ$2!""7ꙸ8Swԩ,oV5 Xq}Akn3zP `p }趢}7 ;D4_ `?륪:sIc?=|/ܜ֚@ IDAT9f};3ʽuΝ']j@֬p=2%xp×_v[}׬#9qKp}+ܿ?]ueb.CISmg9".@ 8t BϾz:yf*.i*8G^XL`Vٹ1%5P=HX^|h)T㞳yzP"h sSv?-@ (Vd.̻a( ]yyyV<>F dr~PW?t @(J y7|x$ӫg!~NAp`l࢕] DIrJ޻x3_e@B4&"D&M@)eG@ N\VM U(LBLBUngq_@]`N.@VJF#Ӈ)x{ ]oC|i/@o8|,ƷfI(4j"B 8Ynga~oɎ L{d<[: @9l]#i PH1㙄TEO_~yL?-EԹ赇M5~QA{% >SP&.i |ޡtǎZ@ Z `/IGKn9XvmBZ q r>ٹpgϒT(u) b ?rZe+=n0;)0HׇϜ3{=. j( *#H)*k8x;E=/܇qst1OPn$.Owԓ*>s~7@ 8 |CB{{9'4ܿ@ 6Ev8e"`"d8p0 P.ZmZ^ 7CTg-؂s-g߄5,(U-X@)` U 4>q?Y"@(N{8)dFsypW YiQ\K#&E(BW ÏiAu=AcPT!P[ ʼn'.fɼr qyt{dX/y{ 5 &\ɽAUy%4\ۀ oHGT~4uoĎ42 {@" D dQH`53z`e˚C HfK5@en' Q`1&LAAh"ڷvإ0ygm 10;h>@fy@>Hn2ފ|Ƀvzܙ xdU)/}S Di15Ap+[ @ # {wIlϥ?wd*yow=/x* O]_יB9uhSMDJZsןFEz蜶ןUǮ^axxͲUC+;+V;;V{Y=j 6[f4J5P)T h]ZKu욝|`=/V;KA+1޼4%x=Ve3%5QrGl  #n *+8I4`<+X;Sˆ7@ ָ_|{q+woUw;{< 37ow]w?~oٲei Q(KYn,`1n_ܧDh]8]$H4IG?g]욞{;Mp.WwVj$QJ"!D5锴&ө]ݝf3(׭Yjvuf$)P)Risu}~`:}0;9M7g1 $Ėz@{P:I|aB/+ո;Oj_UvQIOf#~g?{y2x袵矿[bQpYXЯ{ݏ?N=u5L !=׼5~6O~xK_o^{^4hmi4P䯳b%ᙬӃ,C`elS pB\I ~YJR*%P9ilٰvs-ؿܾ VJZMl(LP)PDtN)괫ӔyD Z  y\d'ir٩S3/Dw୳*JClj_*;~OU]7]!w_$EXsFJ@ jN877h4Fî]x%𒗼߽{"&ī%"Xq<*|gv@(*{nd7Vxbߤb^؄n: @833rde{YOŞ!4Ukthtth4nWLwv;ЛKzi{Z@PP% 4F90hvC@sTI7"cђ7=4i,EI\=측O_Kyܾ_=I&8I1ED4ccjŵs{  V~ *_=~ g$x ݽO%y O @͗BfCz ;_Կgpɫ+@z[c)[%>yE{'']~ێ9aoXJ~W?;I0kپT睷⋏rf_oyK`z{㍏E=oś߼qٲq#`jj܀+_rS ',ң05սgߊ׾6o|f޺i{߻933׾;퍍.l/[C #G>UzU;VZ9ƪUvYɿM ~y_, gy)hBy%CƔ9`5 #&+v~/yIXɍk `ĞN{ޔ!@YPAno|c>p?xڵ'G[Wo:/=~un007|ze˒|Zӟ^>tmꪫNZymƀO}nW,[ָ-W_}מWͥ\s?%l}N"@p%8c;i͚ms!hA{@P\rOa }-f~7-zaqsO`#e1B68P|wb)Ҷ]r;GJoB1sydyF>V[A@Ǟٳ?tڝvnV[u[wn;@34 s`rˮRAux!6OpiĴM:,gS/hR*oZKqa+ m$6X+.{7?_sCËdIa:'I^NXM4m8/pi?}忸{ffwk?tTM^8yVK]t] {t/^5>A ^?^H$I;yio뮽\rP2<ܸ?鞩 Ʋp$3`rr;vnj4 |7l:3۷}7ycVh>k{-GڵpSo1ccmDX3>^Cl*Dh6Qg26mڴzݱ^^orrrlllQyeε^W7VJ7rg>DO*ώ+fn*¤PrHwV1pKS0HtUZ9I p>P@`Jz] fa*\l.*L uR* "U# rFtc2&i#+YbzO7B!;*Z4 :m7ƓӃQ%q)v1i'Ct響lþݰnjLL,l>C3aÀ&^048W":H'?on۱cXomᆇ6n|ĭO\&<#+WZnrcjjlb3[ש=Ɩ8rΝIU?4$! émccc6m[_z d2n^Rtth#fFZKnĆք`8fyMcl+.1P"Ēw8qhK((\I(Ƽ'|U)E)<4 AR$tx{3N΃PwsoytԽF@: XG_P^>wD Y: Xhr5D_~O:[ՙ˙0FesS΁^Wno1Hv Yx^8&nѓO_[uY+8睷8t{?Dۿ~٭^y+]O~w+7k馛L-`=\s͗+W_.Y'wpii+Z]|f?m!eO60,&3'r^2e-Hsb\ِqvA^yB_0*RH54pullߞ!NTX\Bf?Gu``=802ՂuK/UO;AM:tZwK^.Z335Di}?>Ǐv3/H)_.zgϠMQLy,Ά.|&Bg9Mcy~v>8:w߫Cr_;L?篙[$k׶{/o&{‚׶l2vU+6 -?Nmcꯞ޳|ySnxnwc_u_w}#'.v w|k׶.lS{h=iJܲ3G :Z|J_9b'mǖP (>Q",=C+/. dh7+_i":k)ΞN0zX=`:eSJ f7c/+~ 輸[ H'w{EYL* H4VDZi)hMZ&=JO׀nP 8d?/Xb]@ \ĦR J5T D* &h߀K,jۦZ]qQp_<]my`j ɾWVXs*B$*<[T:αcT IDATφׯl V;b#SUalt!ӜY:2A{Pm&̤;vʜ0# c|g`ݢDs + y ?=90]*5~ MTPPu!ƺ2Xgy}IF~IHG*S!{{9'4|m }LX)mWL|}wEޟ*cc̊հ_ 9i5|㋏={2PDJD̮JeR(] *ABHiҤ@kMD:'%m4Dſ:==gCw^W6.]yJ%B8MڃP$k TZs!~ 4(SMѩ/x3'_p?uGePedGǸCX ~0h![G- @d3G=0Z)(5!h$FD$5b*G:+'uȯHz[y ^~{:)&# BYL>/oݖh? 2as;Vg#t:j tKFR@ =?~ ??JkP(NvvĢOy5%޴EZ@K"{ FqR/ N,H59H!"gatA[MH*S]KYp#:qC# ^Қw4#@V}ߗP| ~97 5\dCΑ΄x.?@ _ݔאeqPk@If\3Ew&gqAF,=ߓ_m!0@k|] 0%J!"hL "e"`]`sWB vJ)_g7"i" :&5S*9ǂ}}bC|%o^w}vo%Z7sf8m@ )v֝f,<_Y@ kȻ일 ʭ #>g.uU ƜhY3$IV0+*@ad]4Ώ H]v6w!/]L"{3ɦHB׆ "jt!֡bzݜ}@ Qr]|G[dD߲N4#c!`w(`aWt xyݢl~7'[M܇b\Y2'@GDu{%"U$/ (H><4MKDݾu{ 7;4i?DLuxxtSTSXl.eeRǥl7'S8_( qUoM7Z!]"PDCnTY;P)v^f>("J4M}k`^Wa+;A50EjR ;B= }s#C}B`b$9< @ hv}ltHGsL9O(dVd mw ƶQb!Ecp®Z `=Txx"@A銣"Tt@Ds],Oͯ?# D/; CjQYBS珽eNуW(L%a9\w劏@ @ 8ҀyP7 GJ&Q tgⷉYmrMD$ (| Z1wW?>׀bZ%7)*b8.4i@@:MSR*'$I>. { [;4թI~ (H霑.*"Ks ,%M^`\tsBVT/K[7D@ ፬Z\}W `좃zNe@s1g}׀e ƻw0`{!)Pq_5hФHe*CMo?/0^)P&h`R`>I[h0;PSw`>U *t ݰjb;d́Ʋ@ K3`~p=b" F ϙZ2RюL`/'N o4QP)HF^gAAk$qi@l `Vq[nO& B(a?}vb S8XK,b_u<g ߣٚ0Tkܵ}:` @ C|9-{_]|X ]15+}+,ϣA{"Ff2 `>eb2_DcͰͨ 4ewT2M~<+eY@vq۷OOOt#_b8Tߍ3w@Hi˥|^_@0'O̾S FoEMͨsڣ59ki_%o@ ĩ7K#"`"![ RdxkMhhPv8C6@@Y:^:3;9 lGHb0DNuj8 >oYc{GZV$`޽vZzƍ> q "PP"@_pzӳOK`9&\=\M 8|%BU>: PC $@ hE <0_LB9@_nay'{8Fk2G,fgfxx2Mhja o羏/LVhIF DMW{FNgӦM###FcnnnbbGzDh4&&&8p '*<5i#^r uub6ӷ=~y)x @ Aȓ0(*IKxvO^ Gm::C|,YP'_r>EHo,䇱@RHU(@)599իWOOO;qaaO:G|]vBU*^Rm:(hRD,v#L`쮝~UjݨS7Sh'YA @ 0T ,K$ML:vFgGts TS;ˬX"&|fR&D+v 8nL  cPvݬ i @aSǎ ~]lYe+T£_!YDݿ_@ @p 㡌fr"{e? Y2iBAo9 4VLPxP1?q")J .@)544499 877Pg@zFiL@}Dž">鍨ݻA}ïCy#&j[mCXdG-pnش}vc@`P2p4`ֲ~z=򅅅{iQ@ O U~WWQ[$-?p9|/9sn"A,@ @ xKd$v*zm$ $~*?4 ՋsGC0a!" e%CH""".%wȿQs]yV`î9S#ÿEL q L`"-:p!. ˑA@F_ss+>; eu~055{lNsٳzg*P>^'طZ1 g  5<} 6H^nB͇F<@ c{>sTP FN@|4NjELױ!Pe>3;xo8"cs3 b[ȉ:7xIkh17")Oc!i>f/_~YgMOOsz_#1O`+6~s.fs.fBᅜYۮƍqסYkll g+0~[o?}/ "&[nFYSOPC$ !ߕBBD 4~ݯ_W&{j7rقۍY݋rR D*ȿՃtl(@ @ 8bi “vy,x/g/Uk>˒͘ɟhS2dd(X0f[% 6 :y9$Iλgv_ϯΔ|>SC'DZرhZꤓNڹsgi\m!3lnn7~OxB,_5mv4 oA̝79\ڌ*}S@Td@ ~{#<<Sg/@  K`l 8h+y6T?Oo9{JJh ʒ0UЉJG4z;I/`bbB){Ąi7V. &SzK 5Wp`o.=x}?_|7(<[eD;E`aB @ %u;_85@*ckwgh$N6 M/tw:PWZݻ֯_)avџuLipožk8 T{"Ɂ&4n6A%ZOUp#yK-X U01(K.(@ BHz f\Ty-@Tƿm#o\u_1Bz/*jmER+6&'RŗK?@ Cw$_LuYMTIPx-`w}UGv?^{6RDepMLj"%IbJu 'pwgOد$X8•XA-[+ >;}~&5bn"hjt*@ @pS|_EPc^,QA!aÈѪ%Ps(P7IYE (TY}Pc^itF@DTrL0i%7 &K+mKX# ʋ>#{B.K!^ @ 8bο㢵=1;xw8}ߘG A Ö/žx߄iiW,o6lؐ}*̆lV"^9H8:3vأjF+Bd sPF c&"GϞp: ?%(5Â&@  ܂~^Shb* *{@&KpD@<@ avP&q%*l2X`" )}a'}"k]4i %&[P(`d9>J#rs8.F1wz=_Eb~AuX G <AYV `g(1''[1@,V1BuO?BPb"@ @ 8qry-׀X{=CZitsn5uCĘQFbb1s B>`S3$Ag*O@./dZ3}R)aÆ}Uzr?k-{6W( sO=3VkSMIy/ 96m))C @ CۻO=9^G H6LE(! ~_/yX0|D'dJ_ zNLO+0/`{,'ȡyY( "I=yFcڵ۷o7# j\P)w+Ut/ozT?(/P:'9 @ XȜ]>Y@/_))p .eݢ9? < :C·KAo~UB'@^4v]`ݭVkxx8MGyd5ΫPĭS'~<|WwI,ʿ͗>Ex:|sbyv@ AB_dGW! O]xJ[Ty* V}.VȪ_OP8a9\g/l<'i i  -'f"N(L w>`Pg*st6`gt|/u}DS0]Kw@ T⋗.j⦪=b.7t  oB_ǧ@!z1~ɲО.sx\yDp"7i3T Dso( C*&߷_LGʶ~bjAϢ_Ħ ~?2@ @ 8(@}GX lgE,6}IQ`Vн鑏 \:|ye^䵇fSz(S`7j"cR C@*^ޞ?*߂GFd`pE˒sb=+%P.o to] @ t =Q b^>ng"֓5DFlvvuxrO!R *ij%,J; $ "TI{nE8"sף$#LqOԙ.né6Z@ h*uq"=tJC{h$WךEWB C5bH@ٹ$I!/²!"p48$zucXe[ڋJL"Kr1]Ckދz+@ /@ @pOw_~)yy@Y6/jEA1n"6tSNj*"$ix̏lNC4MggfO=du$1ZcPn_JHI2݇EcƄ"aAMP5p?lp, 4bCx@ F׍38&Da jɿsX.=@@n3xy}"tN|B3h:uOTR,A8 BƬR 8(sOxn+@ cr!Y9LYh@( :gov{&i1[,(HBFl6ۭV RV\Au@+bu#X`S$jNe.b=@ a )9$xgpR.s@*/c C 맨0I+ 6"Ohi@Dh[v ѝN`k j! FfPyF}#P\ϗw?C)=Q9zH|G,t"b"@ a$?Dʽl 2fd/KOǷ{FM08<=ܮ |*-4 b+(@Gpل6.S sq{?yDriv#M??_/0,kA;q-pTOTzڸl@ BNm)d;TYmeY a8(Dǝv@>:ڿݙm_^0Xeύ[~N$BR^vllQR$t:{~R zm*5fq/6?faʾ|o>CA_.ޝxH@ a {85ބiHy>8嬧gÀ,եvSu;Νe!q-eXnD cӮǾWy 7uVN!@~$yGcJ#/;rˏgĶS M,&6=Z jD @ 2d20ZX"$ƽ&teP fOu(UX;֙ ^z.hegr*#(gݘQp~S ?R0]ߡH8̹"]IA@% b tH&#lڏN-̇aتT16 Q;{]/|ʳڑИK8ðpz~f@ a"4De|vh/Vn| ;A9Hc j W|*,OwgÌܭU)P)E)=!b&GJRJat<łNKiD|H",+>Ye Oz@AHEy¾{O C @ f}c EkVVF ǢL QԈr;U -?J c5zE> 4@)QH>a6}n^3Jaqmy,KZڃL>0fJF رvq^8,✸ع@ YrS.RL|"x(b^u3Gya^tXk }V̪4,yTwX4@DC9NA_ź &) AfHd(3^iQo@ @ 8d%KE,##lJ{̓@`%T50ܩBe7Gk> ى3QeS~<` yuQJUey,?چثM4/C-V!DjD8y?/Iڿ@ @pd""vV'Od&GZc,w@ ]rs, ˙~yvEA"BCR~s<@vLKЂ A[:vaم=T8I>ѭ$O#+GU8c):`lw˥!oHpw@ E;ad  X2u*>+!Bz_Ln|>ۓ#GX!CELJ@Ѡ@&3n-yԗ3F9Wb%bJBd CN|ը;N@g`1Q:z= */'?4@ @pIiy.2n4HOBn?Dxa! 7m6)NR FPW8?&5tfLFl%v3i6Fnfl6f4I$*i5F4j$ l($ӔzҞ=v{i/Mzin/nvugc5;ne;66e !hl1@,YQCԉikFgzFn.F)16$16NQvƮ׭{s?k9wo^?Lkڿ{C_ׇ~m>|ĩҺ[s%%NQ׎L8ɵ6IKQ4P5rG @ Oi$}=e)"@baǼ<(ϙ MX7E't;HS9㲣~TW{c2X zwZw3fݬS3խTTVn6Y:5:Zf3S+J)͔:h~Z&=4|à?Az臡^A_=^D$zi^|CQ j|\E:;0V0m"B]@ @p6НAIsVOOEW_Ї#ªaAWh''5,8_X]q4.ⵓzk8vJ!6Nw D Ԡi8 Q :h@DM@C? h =h?=a `""&P@&& 4KO\u{9j v1E0!W D|_\P1 iEY5 &b`5Z@ و?qis>meiPY/7u݇I@!t1WBVB\(CH F ;X/u1cҚf+|﷭DJ"&RDtRQ: @=ѠRctks cܠa @0 4&MAS.!i40r6 MZQOXjLA,͍);f LWHqɩ鶀|R@ʹ%@ W,%c{%!>.¨o1yrtʦLu QD6.\ Eꢦ Vp#i@Z-}A)3;"M#EBJ҃a#d@Dzp4老5CyaT|7a+khfE-1+!( iMMIkh3 af;4`&0?-\hc0s#M@Le_ Z4~b!rcr - )a!5@ VȳqxYuV^my)Gi Wg1SA<2]8+xpa@ !@D]gBUJ"*MJ *ePBM0s [!a @`Vt=` h j2=jnv8sT0\7()ZtR}FXzDBgZn@ @pV!uY<9\,[NGxFG'F%5u0N3S'gJ<"WOdј%g@k= L9:註㷠2 "KiDDf&C6GPhHu3#ho Ѓ0$5z_n?FmA )Uv!2Op [58Fh{zQ3 ɟoQP ]!@ n`sf:.Fdׄ&" œBKY 50Kr8)] @ٿ^87ǂ P~WҚb{= |CXInk[p ) t?sE]cV0^a3)@;C&aƁAѠЭ~ cS'yq5k<KO q1^&0>_ݚn-a@ 9 7G,߆8quWMtE9P$ylߧ4C[ ` AZ͐AS4? - vD5~w4(ealaDH&@ @ \@6 o'@ t@vS?1J4rsIP7JjQN!~V`{[pܕң& k"DTNjc3xhv2Qi:7g˩#=ylُ@NۛLaNfK尅W_ShܣikbO$nb i@ *aRf"P`p g 8<DۥYV&Q^D {(E48oOkPS3 hMC?ksM] Vd_ D _ Pk=h@ Nnˊ7˺1ƣZlז-Pg'V1c0Xy qp~?*@ LV @U8'0`@ȃ' K1\f,7ʼnd mkK"4}bB".>hMt4ΨCu=@?Q!l$ = χ~mޡ&B <7MSL,@5Z[_ `0AYR@̇w㱋F>e<[RBʌ}.h/(VWSX1&"3OL(@ @pvb0h Fvdk0|C.ѭ@1!L$j#Y( øl#(\>Ǽ8 UdqAj;mҭ q: Cߣ2:sQѠIχ|.f $=Y\y+Sym Iۦ&Ͷ}(bO~dC' 'od@gl;Kıgg PT\0=g2tU@~w]˿qohW.[}JdS "zr&?L5@mK6 8cEYQ-aRذ|קvuosF a ]6)j"/)f=}lkyBS ۂHn@BPcy}/ANE%ZGzûq)kIGy`{kt`P"V>@ BXYu[BT`6, Pl$KX QbcKWZ|*~Qd-nu*y7(`#"N1p@ LOuo;IWmǖBH\d(D%{+xs"/sC(ID݊ ^Ro';ȸ?4FD@o13* ʹKF!c a kofBep3rڒG26rx|v@j7x&όύMuQ,@ ^et /c0SmO ,l " )meHL#XS%nAZ^],4Q)߿C66Nxg5XGĜ+tF!z/} qo0$A8Jy)q ;R ` @ @pcʮO^oڲo/aNl)ՂN~ +gSG"q Fqɧ`gygc-$OO񩉓NsysT f>t@ @]G{-֋/곛O'V˻"!&yNZ'd &TąEt(7`jzc PH `2io}8 DB'gB_no/j|8=Y95QyYN&SY(6oFLn@ k{®-7GV #w),Ve. )2b~(-Պ[yP]128OF [r? ΃ `9ҔJh BhUȗC)Щ2|LnsdJ'8 6xB @ ^8pjY?'C`a[l@͞iVsEm#≝bv*?`iS@0P)cc`7pNlE5N I[ iu{#fW_\('8Z-;̂n.Z[FQ @ 8seջ߼2+ϏmPNČEb۾8PKtgy:E-/,6Vzc(Ս,` !!vULn1L8N$ly" mMAD[۔$6 >5[ܾϯTV!q,9l N񨊗_~^V xUq>cgZ @ ?޸si/QDlP}q; G͹#S"0t(c|篶k ~z~"rTwbR2t~\ FMDZfB*pAT$,^%+&&Cnμl20u#"VvۼW7jV_LpaըJ60g^ XzA2CHB@ ]\uK/7*M=Q<2뙷5I+Hz%bctℤTNֶ+)OCb-i9* 4`S!#ZUۓA8bb|lG0lcboUNk ]d!Iց" e.Va/H>gnj)@@[O@g֍benj]a?!  FxY朑[t{n_RA8Xr} TЀrBXڰ~3@ :ܾl B{n9&n9"ȸ l;q&v2Ƨ_:.ۧt*VV/9-(Iv3@"B#z[ʋs i@@*C߱]`&en)Ѷ?Q_Y7_P!@1[@`z2ˢQ@ W?'7Xd f(0!(Flh=sAOݻwfSֽD` "΃I^>% Hrq :P5) >D~QRQ#[l-Q[xxb py. έ[j5~\sͫ#n_Mh˖-L?뮻kM,ݻjs|+⮻2j MO~m}ɯiz"0*Ћh)\9iIM<&l]8@XB7^qs6G Զ'gQ `@D A+Hf^_WΜ|@)R ɂ>V:u:˨wM-zp=FИ/-OPsl '/֕@`$zǡGG>7 SO=o~Svx7kv6}3tモ'OVtѣԧ<~?>Gnd IDAT@ xruoKmJ{#>cUX'?Q$CE8bahNGN=  D0aR(g^,n3-&!l9,w%Op2p'JnH/=CpX .`>,nzu{ݶm~>طos=ǏO|<#G`ǎ'<~?䓗^zࡇzg`7p_|뮻뮻 ax-[w\uU[n=~>h;>я^veǎZjw!s\ymg?OZ׿oq79RlѻnW<裏rȥ֝W.+7 Gg/8ұ)0[Vhqb}NۿA,'H3+e6Kr҈bU`|j!Mo׿~I?WwC__ܷo׿SN]{7|%[?/~qee|M7ٳ]zן˳좋.j+M7{Ǐ߳gbؿ^zoתQ{&?ACho<3s9.{jFćz[nW^8n)=\ks='bqsW\q{W^yG}@png?o6>#`AH]<7rTOZ%rG 0.E(xB>پ\1<:A)8~:&R3C cJZ0(P( *0zZ}[Z5(4_Rcb %6ux[״wO~3wرo߾{?ÿkvEKEi?ON:/o۶mee/}я~t|/䒓'O wyUWٟqt+\+S?_m6T;wܵkO?]GS]wݾ}կ}h޽.ַ{x޽0 o%)w}w/W^yu@pؿq[6qC[<_Ũ/}'d  #S.F0K R4hҽH.@)PJ=B}'<)O( uBBϹ? "`XZ|F 0h]s??ͱap sk.-۷M^a+++;v^S;v;oᆗ^z>\z׮]Zp?`>L|;|,e(w>b0=(ng@ ={.}ջ\~=s6\774وv`(')I0ٌ6[(!D:@j DF3 _mHnUAD(ZDNJʥ\,dk%Oɦ@^ȓR}솖aeaq 7Lk_犼`uxt{'Nm۶Q:tPu^{?}scǔRv:vl|9۷)\rM7t}qc.-f3=|+Ν;Mm< q5$ӷx@&=};WvqKnlON<IJ}heC:!(5@Nǖb}8]^z^PR t+?~\o6!fL`CJ3L\x`#Tܒ)]_5>O>Y`479ΗH;/)a`AD?~СC7x; ._|񪫮G>s7{i] ðJvβǏ?| 7`ٳǸm][nK\`Ν?S<}blu믿~6 ?|wdi<;?|5@pأ|}|GH߿??Usn@v@moRA/yX ˔X*pNBK7O@2+03͆~!_0OAueMSJl̅m|CCҩ) A bP~_oooݺummg1M7;;?Wn:7-ߣ\xDto&jwn۲exFDho|~iȰ۷o۶m_'w}ى]Zfz#=O."Ng".87=5P)t _?&[{V@'|0ajjHxl Y=d~H& MD}?`5[_n}C6ػw>}sgZ.{v)rƦO>W$ M]:MM@ g}ߝ}v'yq/Bb|r7X'Pm%P.G`Nkb |_e P\&U)C< PpVUx:tK.ٳgر|3ؽ{:1޺{^W `J!RЎ(;  ?,>,&bt;i:1Y ۗH1q,WThkf b_x)%YJ5]Q~֙ X,"S[H.*na9 ^(?яδ -l߾}\0_?8-ݻwM3}FBBHVjL\ @꒩! $?>.ѣGx cx;ӯ `pȑ[o5ٞx @ f= @zrrN=844#ϢQ1>N9y'9ėny>kc;g*j͵DݓL9aj'2š:- [mw2彵i0):Wi @;M KԕOޓ@~q4)j g >OW_m|g|_6gW>&@ ى.}늧Mf6?re+6 Bo`"+ָ0.@,ѡE!0`Ġ(get)B[yaR(B1pձ)=Ϣy9w 6O:]t3#P\LۑD/!TiW@M@APԠgQ=l?`ٌOӻwW^yşG@ g9|cu;O!ZOCD8 e)[/5y'3~/lCiJaNsiㄪ/Gs;HYA7A! \ 9X .'gJܸU$AT! m%@T2 p=+ l`<#D4 @ -"Ys ?W^ye;BK/,@ pk_l 3^"/ɹcmI0eܿf @qa$0(p*6$BM8Dy*uP̈BJ^],ӒyP~'eN|3@(_-{.<9\:^U"|K VF,a 1&#y* CൃdW!@ Gϴ cz 6"K%^jJm6' .Sݠc\'7g(rSQa,83I}MIC6b@<M -7Vrި%_S%0ͩ,_ӇD=  ]-l <@zp<׋viJP @ 8`(r< u*~c VO~0;2#5euA!Pp<~N熔E~P]/E/V1aXvT"_(*a4#|O6޺=݊4 ։2D}@ :F n @U` -xL!bџ̊N1j4S̗CA`Z<[R$KqUDYEKǣRq}64&-;:ߕȯi Ұ{H@ @pv0<{9BƉS {x*9|AÐp #,ŴLz g¦%T|h`bFh4AV $E2_ 7'!T<@ ,:1[ vӟA'.0IqBpxc/,JƩz AsrFV Y#lPP6^+3Y+(-V3v^RS6U s7tDRp^ @WLPH@C?i1n EW@"@  ~6tdgG,U| |sXiU{A(7l4I '4L"2^_Oގ4!E,/x^q&Iw(LI1],oBP(10C B^rFַdzmt@4hM A\l':=ɍ"L?]THQh-~ „ $UcKj:z%._³*A|)8߳Y^dcb ըk;}fr`u,Z5%n_EDꬠpBm UdG|_? ifڲ7TEcdI,ŰŒWtg}§89cx.,?QS۔HkPMP:,_L ?Cs1#(GDDbءRz7a/T5߄m DE c voS?ԟ~ƺka> pb\ uNK,sKqx '1мר4(xuD=|(<٨w+4݄$kOTP>LJAw7E4 ߣe4!+T5a-- ^Hj(*3ec|0郏V"GƘ | ;^ 5Y=Ղ@Akfa1tJF7E=[h e:bNҦ+ ߒ;6)aGYCŌtT˯ag,#K2)CKv7,s*6WX=ͺE4BPJmض4Ȇ]T!4 lY۝5T&??P`,7|D@_bfpY(($yihD'5@DыO;LuV1ޚo8b|rA.sBu@VDihMq ;`6M k'jl(0c >%O7FMH؊r. 󒔳YTTڌ{~, UbF*r^ 鐌҆C&[kdbF7ئJ[sR IDATKb'7ҶB *L+7{ò/=XKщ v_(pE eK2n|!4&L~ۜZ=G')Izs9į8Ɩ&LD]a94 [;q\{Xm&jy)ef9);aDfJ3H`uji%j?޸@#(Vamo0̣hcY  {h5K{-{֚9xjEmW0y~0yHȲ&d{`ca]QGA T1UlJ ǷWm`x" ){xcro`CcG5}ZU&pz>҃U>hRSZ~_#!iے5I*d+AC T7F+'KC|}anQN^ 55g<:ZN2Y))P͍8TiW#ȾMl5[B-%`BVn}ѫdG^6^TmjX]I-#kKRc f֭9;#Ê.ha+Mhj>/ǟ0o?<,⹚BuAl?A%Q `)~ԃI,&޹![cՈ5aĺ!۰|4%,Łc 1 Q#B,fV" "6$@7d؈ 5Y {?5͟K⦂PPH5ɭ3AДt7V@)iNXTJwB& (9D"< D&ivSe+zvjѱ|'6~-{:b(" ]Af~'+8| ?Θ>񂟙PMA U9W9mrJ,(0;̾=\ZCduJrmT ‡{uxCzVȃHޚ#kՏ@)@Ph P lpX_āixFv%%ySɿBct޵,XAҕ[TTۄyPjc^KC:L"0x4OT 1)[Xp _kl[oadX}g=K̿MjA qlaϮ{V/Lpڱ <͵U㟰|sQz+U{r/u<+n^sn`\"-:I 5".GQA [BM̻`3Av>JJC-W$J$%6q': TZ|J xy`] 2sxRNFJ fSzS樽Yf &ybYӧr&T'{ 0@y}B(/7@NuW_׹>y#*@9< <$67S@on]&0)BGqv*I)L*ӎXb7܏5=/l/}2p…Y`L 9"T߈qI|?8TϧJ.&FJO؍a!]- 'd5kuo|2V)*2GkkxZ޽L[j%AxQ'i9rf#Sϻ1XZW N݄nPN)2Agr+g须&*D_:~GSZO CeBh:VbƀNXN[HHo< .'xG2{Xg:|JY ;}&GMtXt#1fw<v!7~QrLP^ ,̯IsJLfa:,>pD~[>f8+L~H`#L m 6ʛ_ڵ.X~B-l1*Xթ>XC$27DIH 2|8b /ܘds ȾVHrMSU3lT+mIݛ ㊲ѠaRdiB.*%FEh"K4j }贉;Z/HflpJ-9 hԤRE,,YZK K/1EB>6BBMƚjŏWҞ v^\%e57CVqz1y&g67y"`7o7$k&?%exx}ws ٻiVt?lhCQY?:6J7TmYDn%3hط 毉0ubdbpDBx y9L5R-pVx;o?%(;&F@J"Dhh[oǗMXbgc'`>bl&>ٿbIUʴ j{x1?AMΎ螈Piy65_ble" ,`» (`{)QF~\z UŚ Lo$<0&S=JtVC,Ma)LY~M ±#] ZPJMSq16~P}&C:n2}BRD!If(moH ݵv#` @@܂ < ow~T,XQi kT\? tҶ#\pBA|=Mib]YlAY#K @MF6EiwC0[t|@`?n4SYJYUo!eݥ kM - W}#PDᥳX9rc`) $WD[DUw@}EhӇr6HfR//]-ش7ْ5v:rWGLXEMnb<_MV:;ҌoJY`9TuEϨ3|,M PZ?}Uof/N4x(_8?i+BގF)~oaB楁qY_ 6'C$rO|<[M%Њ++?}ǢךmOcK(^t,~ aX4 )|SY^\aFW9^lj wC\%|i=~.: &<L4Ws,[Cqj%OD!';Nt$or3'6'.lS#}=į8]=]aXa̾xdwJ4z}' ]jq?gv0@a&QT84fOPd!6@Z&/t kMzk j|#bѭ2C@7 PtvKOTaKؖ")տiS HRr`+{`Ÿ%(0Y Ԯ`wg !=,# /(a=PJ}<reIIN$.6eh5G@UHEx Q": s)j±їr3(ǽ1 .n[WDmZ 3z`ePl d!6ƈz_}ھrb (= D˻ [/JS<&tڶF(mu?~Z Зo ,]ۼ27 !=h59bpm?vP KfjvCzՎ!B֠h>VamI[70JX(\Y|L7h>Qס.Ag[/?p?I0]SL1<](LFH%v~?7|H@R\4mFhaE۹IZ=L \{Ţ-hC%%wضzR:nqxUeY|ODLcIW, W Tװ23NSDɫML]uRZe~Q aD_&)ʇjr`f ڏ"+otS7M6`cGSR<۽/۫Z7Z85Ae-M-⹨(WE^ͯVZa(LCHdLD/B=qJL{`n}7;*Z2\fSL(w7\)=ik!$~!YJc rָ(o(RݷLwDoOm'vcFJ_PjPku<"o\u x/@:< 4LO$qQcel[VDBd݌QG*~T ne{0Pf6lYSb;'R`+m; :>]X^7dNdl nHDdS2,UopϙZhpnaQ&)!n[6X:p/Ettaqma|xއ:&P _|J};lY}d{2W즦C.`=Fos[Hamy;˷ `1__3p"?5,YwЄw!nYa/o|X{ %yn dr0O5gŅvm6!hMz8#~IdjK|YK F1?u/g9&ȬGDƌ6x|ܢP3wT}Q`)jYf(8-f;S $IFyhjh/`!' (uH+]kGZDRBS.eڶ8@1NӄSҢH3K0+CK7[A8@ly eh-$_.(:C z t$uΰ7]Њ_:c^T4&瞌aJ9Ԑ-%qӤ؎. (&(,6T>[ՠ.yc5Mfh?wPTiy5mR_B)k #~QɪOX:Lp8>޵fٌh `9I,HvJ0qDh㨍nx {XST+ M, @,HY9l4NTel܃:ﱑJ4 W,S$ )ؖf+ 7hz*tM尯 |F_&2DטUr#m]ɰͨvnރ$ b0$^oMu?̒<~xY*\7O9OQ!DRxl-ORfP5q!SWb@*ȡKE+^Q&~aVCή_vW8Iu6 s\v[/ftөb`PRA _QAArZI-w&)*=u_] ȄmhiIn[>Z 8u}IBwDH's`(P$&9 ObA8^47)~%pr[T,T֪50oZ 5J%x]q@iriMCт%VۗJ\80r_'TT Q!%sv^>jֱ˱#UHƈt'OSjaTCUuNw@R)'EB?CSoQ8hѸL-(Yɖv \t784F `K5biΦFu_@% >>DԶ~_G5Ƴ b-}J* v,|"å(6_);śk1 g4qr^@)Р]B\%&v_>1).'P#ǵm+ hmzG2`S^bpnC4uI*+e\%H(b;1g7fg͟B} S c/tn5Ŭ%C8»2gvsnSA/*v #G"@#Z %0hJ ? #2ʽ= EVrLY(ṥwݒTYNMuV=[d2OAEucEX53F~j\Nou#IAVx%Ƥ <#Vl|cvlY 5kR+$N0uAihW[3eK&Cum&4c#2U :i23r_.o4XjaIi] L{D#>5$Z'n:#EC5$l{ Z';).HU;,EԼhWU<0{/p>6Oß=e*<*uSPshRU㙔^i0n/6AN5% Ւ¤L# W`wNX";<CvB_L!A͒5&E:E<%loM3b (H9-cDeAO`Pc)HZ&@;"nu-[ĩ18~0dZG8|]?Rg%&*.2ENp(ԭ_qfh1bA_m H)*I]6=nw$ygPs*:F9~mC;IjZy88usfmhdQ) BxvBhQ2r1}ܚ6d` qKqiɑA$>3y7($^YE,WAFèe@?S6bIM_)38zFb X/2LmT?h@&2rI眃fh{CWZ~Yz' S{iHHjP  3cji2 $b\戶QDcFs\^V WV[]6>w{Jt~n~nSvl}:qCT*N|ryny~h~0Ƃ91v"`„dYx؜4ӵ죀U{6]퀈$--v/&/Gj  s;^4 ۧ1$c6v d~CoU,bLwB GgSXf(FbtSq$5p9yg C1S)aS@ՑQ%ûS˼*uHԕq4p$B/S`@9 s lk*T)D!HɈkh^ϻ./0n^Dfb;Vw`Uv6ps2_I aɞK͊$,eoDe1Gy"#vf \{9ׄIbXw3v{ Y@dhcljSkc΁5bk zQ(Ykﯾ(*cwi FΠbw}-_]OA.$J,fWŰ:fH\1\|Hg4K+MEK1r9x~R 2̕NR%MŤ Cx &kOldG QK,:TjՙG1aVZ+JuRml" vt[1N%9+/%ߩqá$D8@a/@8f] E-VG=LpG"QB2r$s»v"uD'/YAn.7PhK+1P`iJrَPk>2"J,ؐ@kߡD̴ /?-i~Հǭ,1lzYZN4Cj ;"ڮa[x+QVx 3vGr#C˩%ZÅQGl<(0̔@{\b+XTfӽ$"HBNO$ԦZg_d;< kC;f3RM&\^@z%"|̱`G }ABɲEEsF\I%4( /U.0" b6 ]c̄Zz_4}}2?=\?)%KiR*Nǡ>f-mS7 jMr,ˋW{+n_m ʮ .V$hjnH7GU B=Lgcؠ<'b0`l7jHaϹDP06 |8ipݝF/ACPL7`I:9ma[W jʽ6df~!@U JQ(~3(zKPn)Op ܨrw>5.RUP]ܩk& kJ$ڌu$6JdlBxzl!-8j # {} !7AY҂M.l0"m(o6H*!&KK7A'?(ojEXjiR- i8EP] rCfL'_dա2 R˪ YxjbM6G<)+r3w5pZN%vvJ)H&l}*zͲ{ I8d:$)u7o!6eOI2-o}D&+LQ_lXwTKMe|D+hvaĂD~& ۥ,pR:aQ]`˩c&m)_)'mΝ1׮哲Ne 2ɅLDh؋0n!xh. .q(SǨ(Mjiq6Ha. ւu3o$C~oQI[]˺alB rآOT(릉+9 yOڰZNY Ž aKQS<|D.̸f- .*KhRXԾ- %jTc#s >"8f>x&2j 5XA$ [[G9%4IV€`gPlҮ17((2{l¿wɬe6(U}@eJp&f G8V 64E2%JjC X-{m~ϯ3x Roڷr?^ (S Xv5rR\ɍ:1[G<mhnBʨOK_8 q~/@I+W{lbS"USd[^u|WnZԻ+F+G%m;ĒF:ks-aDtzsA#MNvXҿ^|ׂ|閾S cP[od GHQ,ÍZnc>r# !%Hu u9fF& D-ņ|q J ezWJp_h5꼞f!i&ϗy XTBҙ r-WO]ŧs@{&SFF1n˖Ⴈ,&Գe^'Q_E`g5N턠3V idW4iBe&.heg$˳X\sOxc%fY)p @['$o0Gܓ/#QK_ JHtLı}Yހ&D!2ƳSK72j:aG@ /z#gre @ۈzEhUW3(r),̧$rXpKE[Ȉ7@1 -E1&i6a8y0w2l]eCG-|.uCk֯:o}Twc99f?U;^ Y*aϐ7Lw]km))"gu\ti3VƦ/$47`Uת-Z,ƒԚÌǬoHvuŏUpR@2BnOKbL^RYd4pdHMrԼ#ɕeYH~&}> sκ*l!:>X5RF6r:Cʀ( ;šhEiZl':#SL'lXAY3Smubt1*any`T |3"!^c@)R_?xZ&ӥ<v _ͳntް/̧$~j`>6 %ulYu8PfZ $.۫\S2;Fy@%Ee VpW]3K)#ԑQc퐊Tzf%jD4jxu|\0oO-̥@ (9~M̐ d?80Nм 9cN: J"&@멗UCPh RMmMٲq.$]*#faJXh'U'T)TJ}d|P[M6] kI pp qLIW(:8rɂQoŋH!$jB9ǺmδU*3uL\Mͨ&ͿâTp3 ڪxay@\eP􀊖mSKܴ^O>IVllG  q@8_O},l]HbS!*UBV@d }t! 49k4j8c&ex -9pk ԫ/C^5/^78u*+nPܙHԡ%1}頔#l֘%ܗAEtBNۆZY:pnQ0Br(ӹS=4K1ve7ĥ2j3zeQ`)H#c ejɲ_ּh:Jȕ–(qxo#8HX @Lvr/s^xZ |+MNLa[Wt. {~Jy?NһőPj<8 `B^ơ|ܠUAb w*%s sPD=+`եzPy2:x~ʹjl<]" Vygb΃pRZm;\2!4OO0X _J^)C_C^ZFjGJn2D$c!jۦGS­{Ȍ;H8 nOFq(S}B12:P:qaU%aj;V~4WĚ0vP J>o.B*:Is ތʜI@v #E4UϮޓ*qD'oG3M8Ο\7GOd6.c`# s5qd  gls7@!?Nߢ|/zF3>TFUZ_v!!vn $'?v5<#}*$#!jڠ1 @PVj{¼CFEX KzahC쪊j}ot"*cB[@v:xѪ:h% cJ`Sdk;pګ)Ă"8d,rucIDJl[ҢkQr_ ZW0FZ~qlҺ|썵DCm;v'>5($"m`x1YJ;*PΪKLg9Pˀ?Cr@"&ur̝٘z9 @|Jۃv{!a$d?h^O+t4fVeaLN}Bb@AD7X}@:)67z4k/*(Ufəđ11!RLJ;=^J?x/ $Q綯/7rع#eBwlߵW:bGEl`aO K n3b1bZp04Y|MyM1snT?%a`TFKM+}t<}vH >Q:nq n$)"yAD_?㤌Gk+U giS0ߛ#Z-GZv:AF&}|zn].eKݥmҖҶ]r˖n\-ݥvIiRJPƟ{ޯ;?eӞ{3]z>y/L|_s3$/{=8h̉G̝}QÚ@0 d [hGi@@m֎:ƪ?5nЙ.E0k<4SXxo #lyˠE[ix?#9E\o]dtv{3~B}UlaA͑}+#zGrn3Kj.YT:gfuĠ Twވ$+޲6'0iMB!v֥U5$`hNB(ڂ ܔCg_s{.?)L9k;eׯ_w)ۛ+c#źO#3{,ғ \d`0Yj1@~)E9C]b礈bG<+_5bqtc1Qtb]7o0$ty ")FMү p\;tru#K[Ok,I'5W4\ؔDpCJ$7pгr=| ] R6QTьAK6iPCfOsHIn)i`D/z"pcЖAӠ EX!}OpV|<-6݁z։P'7ߓַދc0b NŲzYjЖPUd҆))qpPرQ.y0)iI'*f%R]qe<KB@9#AȯҎc:IpGF@U]5JŽud+4n7<@r_{xtR& 3DD3!f*_("9 ^\^tIiK>m~)2)D9ՙ\|%+ {3P \ Nnѷ'=a)!@Jw"/䀳h~IuߔW&䃩M.cu*LzyF  zҙxBTA4=bau 2p=-E#YdA-:}\'upaN8H­.$a 6q@%dR@F$ܝl^XSr] F@RǞ:5) _dJqF@$)o扽r{ ۢm]xy{-ѿsdY$gzz A[rf6qrȎީv;a@0mW?=4aaIoHYFe⶞MEzPΗZQ&H3i3 dl/|k޻ʫ%R*  g (Nr^~?OȔs]w\@@(f!߿x)'ıá>Te[0 9ljJC<C2Ig'|p 9i(Nhh] D+*F@S\Ty?@Шԡ.?}||P=K xLhH5axXE7I`?kLWLxp2!7$h'$7 t nn @#R H_}a'&ř 3ˡ]38utGrd`V=LJF7)(qHB/5ka+RIBs攖hn/ Ǩ+l0 "(CYJIQ*@8$;*{f.eFp ]紐1Sf;-iR2<3(G+Z{0kB5 BXmX{֏׳3Ei&M[x$oZfۈۖomuW b;wb!{q ezԶvjt΁;tJ(^R_C6UPz"Qkf@pbe.c^^iuN+aP>fvs=hRU&whϰfa8b+JNB0Mx¦N04z>I+Lz=;`PZ"tjV-ղe"%$v߉-".D",tQJգ12n%Ok _)Gb vՇc|e34\RrtGN1LJm2FIVR<Ÿ'@wb5ՐãOCnѝZMYi;gҖ[M\{OnOxZ*&N.s#*J$?+h[x%{ߨ}OGg:d%W)j>n?gve Qə0T $" {o0\)\ Ph= 5IDypCܯ;m~ƫ^ўo>+/_xyw\.KR/<dvE۷o޼_Ws߹;ր(}( e/$6պe4 Md!n{$gMHZՍZ@ά !mNDBㄑ41x91$=B~f0p"Z{d-Hc |l۹`AO͝a;<>'^} &lGB#&%DW},) Ifo9˶m`/akA҃culꨰ4 iPE(sDV%*3{*K YIC*}cIvQtx\u&mD%P9X4HAz"v02EOhCU<>W)w64äٻ8pnѷ[JR:3SO-V3]L ]a{F 2H> +@0:AM L67Nyơ#u N9{Gvwoo~O~}H]q?g"LzĿr@P\;zky's= @A´tcA72kж/h($GГo O-DtH%G ; S.X7G~Lj[nXO),˛'Wslaw !1>D;@Ye |O 0>4sFҁJ8!D$C;Uv>FX%֔ n[/;s̹ap3:%naypA\)2-gtж&'@Բqo'j,س44!pT3 ;R3D݀ It۱BǾ4)ZGYG +J*;z D @3Vw#//};KN{J+mFNל /˞2r7>OOOקf}'*{Җ&@{Mw;]vKLP aRD@8G!]#z zbH%=`ɝ**8FmX!H줢${"ڰȓ"{sFbފ?}e݋=KSbeAWPoemzyN5+̪sDP;*F@PuQ @x]N,ahL\7-#z@/6gLv"a눂t")}G]fr5b,~ـ!|~1BYi"ɞq"#l^⦛M㇇LJw?~םr2gy >qфBcx[ q&z4}a? 4xC q>6 ҹ*'v ѻ!i3nKgCw3$oT4j牠YcGPe#VdR,^iiaiwfzן?ZIƩ1.Qia'zU1IM҅~z b `!'JzR.7]X Z qY >F$gN \MHɏ_OKJ<>{GOulq>W^z]N@קG{「iϔaf#FYtQ#ty2u00ਥ<:YJ.bi58(sT =A`ﻯàWYTۈSiN'8RG9FBkHRzQuLJ3v-F_qBxj΁ xzs/Q,Nݓ0h `6pžd3 6ju$C`ƐDR؛O:Ǩ5g@4 /0 7q !I/-3Xx+u,ȆP-2o`%Ӗ|M / RB%]2)ɏMCTx9cpԡ^Z"2R$ i" x RW٫J +᱗P1t`<rL;nTGf?|_W?7"{9# ]{δ~z}O?ׯկkO{3}ϐk)|^R}P#d#?"8:y(b3vh5*gP/3vH?/}WJx@ FyopBQ\xʗI%1{ L1uGczJ^/ 5j(|2kYRD)$9Daϰ'L 6$qBX_P]_QH`c9xo;uO*EU~ܘ ? t%)vDyrhD!24E]Dxx8Iu&ҳ6  t2\3uZkZu_b;m$y3+X|azd GHƅ뎒Rgd%6w*t:g%VC״G1P8EMNe.PeStX3ڢhne7ؐ|[*ni>|gMu%o>n̅5U0 4kڒXcj:{ kZ\?ozoΔKIcX9 -_ ̠P.x4{ݽY'~ "Cv q }Ѹr WԎQ_J?K&LIA@oOSf! JKnVn#Y%c"m̃q&y:(nigUФ++Wu1%ĭ M\ɡ CmCM `u7 D) 9џ?N ?W_i ^)EŶ-m[FM}?r_.2Li᮱t)ҩ# dAQ8&=RThH;L#ꅙd@67{#&Yn;D/ u[U@>pC IDATg^>(C?0q瘡81vd#%SSg |u]z/I~QI@}aaٽ+\a-AB"y8qs!Zm GboLRSleRo(LZ- 9=8#970l|¼Y3=ۇň@{l Ɗɠ8("qI ipZ"S*D+0!&VZR1Lmu0oK;B-@Şz$!l}{M&H"*7$mDηPF[,,!PkfMy<`'դZA]Qhߘd@&Ծ6.'(C)oA&0'JfO޾GM7_|xIy{z|{ι F2g8}"0_)w|ͫm/ c=0X],ˣP۬R sGJ)}sC26&jb(Eb|.w 8ʼ#95K8lP.K"TA.wt`5C=VQվ~{Xu zЩ1-3M?QJv/-գ(Q@9a`uS0 ,{CcGZDZ;Fs%xLkxx`'j'iK 7D0g{Jhz?/c4{қ\T!AgbPpeb2.Lt u3--4`g 6lo"S͐3X Pcj?-4F]TR& ՀS2m,eʇz:ǽ/;IK1*!?J+֑C@uD8V=K%c'#Ӯf GPv! ǯ :0YM.lou`=Cj"CL>Է❠ǓH}vz~7TQ(GKQjQ8c3c\<e|sQ ,H5UM!`ߧ A/4մ{?)҂(jfAB@K/[`m\$_##:Jd@'|9Oy^q(vR)o߽ȸ'L)aƌϯGraNz.xٶ]2} M;\.y|},y09nxGc#{AՑy  I" 퀒!Qnѹ(x虾(N8#ecMp=r̸!jqIBDk%IBz y;:c}#4]@u ZFYD)%]: : !-,,N, 2f\|PWF P;=^q+!K \9K:FlYY( -E[bGډ!@!ꌘiG] T"! "r>+`6_5t8a}`oNa 0f uxVZ#(@ʘP?P?k>dgq; Q65ŗ b|qor]wAe6LQzHaߛHT/LF9xKL[*"J1S/#h:ݖf Il(tgJRƔ`sB| Qra\L!"jˈEfv"==_SDv"w㞉hrk@I@D]KQ3n?8A C9C !ЁʗN &֩碮>o˝-GBA_ӴL BaV &F 7}rRxLFsX(\( ey)UJ}e\ ԸtʌًcfP+ZX3K udTqsA9]M}zIU֟]Ș$Qy{bAW㞠|;h M87(ʍ(t CǁrXvB(vZmk|+EDr> (0~UWT s D}l34kB VYrFH>Y-pJp\N:!20 "(|a`9ңMp++2QB}ĨA礹fTX W7`ܦŕ2G6r}a64 n0"uקkҖ(cmLt% wlEn2!k&̙\#xW iCځ]׼]K=#"Dsh^!oPYhF~2ԆU2}_,|r_hp!X0]`& 2/ )AX 9;#OH~F NlI?Jh0tQ|a;:1U0nhfwqH}xr `10'lB!xF1؀x{QZA|mtM6#!CF4||%nbkh$sP P DW}/VB@Q R$-*OS#L {” %Jj )s+hk`?V{ma$dpTGd%"w@6yt 7V7CƠ)hr;`P/ih˄JFIQ3l~B4YU'$nß#OWonFtFn^{z!X9)Up4MBbdJ&n&$°HiC/]ʫ%W` J "!;!bJ۹,}#] hmeJX @9?;Aڑ\/%2Ld+#p݌*Òf?uZxFk;)&Q |MZc^,~48 -y[^. PY);"ㆈF/p:Zbߤ >݀JV>HԶ֪Avc2#ASIMR`ggl+^>J3C }ŃMI @zjaL@;#'~ШЖhdWD&$c:8u|kŋgFwU0T:+4꘲VU#qD}.ꏑ328q~XҐ0y4l"kBhw5+`a_BԜRöQ9`$~=mT!-o&:xcp-SoV^!/ FIb Qa 8.92`P6MGA:Ӌo˿HD}_>zҫ/_0h<8C3 f`ľ:n@-k\ӭ,ƪ1#7|,~J 3ќUWh"Wf5urq1i4Ãv9Y [ot H k` g`j/$-Y $vEĝ)ڲ:و@}־($'!6zE0akBFTNI!N}ֆ?ܒ)!d1%nj(mL7^m=%  v^2``KԌ?3ӲMz@mθgȉR„Z;1T;CX t" ?@p'RT݀X:"zkB49VAmQj&I2Ϲs ZpAW! E($2BO/Rz F@ ):^wN=KWg jgק*3++]NolJs~2#?EzS%#Cv<]3FUY̖E!nc\cGxmS~zF0L+OIaV15(nУd1TCSYu,jLVuMcmǻZ\2Y%-BjH5qc-$*S?J"d=7vZ"m%.xo˚ZPV].)@"CtCs2#ia|x([#a݆ ?fU7Hg TI4  a+i/n 6D{IMtFJOZ ey6 %ڋEWZ>V w-@ .Hp  eigZB1N,)(4)W )T '*i1%RKi/Un ֬mhZ fJH닱i`]n j^oGYd?@iۂ@N=rtdֲU@'ABj+l9)Қl IDATF]HkqvI=߬Uը{9@`DY7U@)?;"&%۟~ *ܘ20mddKI10:S𺻀=5RDz\țfNXAg]F(ld 9L1һ(t"4/p͋_|)?~j׏N׏߾y;SbYp8 pt|ٿNv olv<_a>g(o2k0b&@[iF񫏊k gvP[([{˷&46sl YrMWlQIŦ* ^S6|a}zNÆ%ED.hw6=967lPшGr!!i0p UeP~YuC``oPmO]:4L ő5T3$J  /^vSϢA]4##)ni yߺɬݲ֓0_^cy!w Lgxzz9bjv&N1HK WO(G[0XR)\$jYP:7s]+1Z/J 5%.-kC¥Z bL#1h>>S^dg⹽ұBcT WT4SUXzb?I;&J[ђu,vA3@]MJ|p ilGg#qQ ˓Ul(W&%&QAZ%=WE-Cۈ&|αw-Yp\J+I 9$$ qN`YC]]_=zx?-\^='n?MO>ɓgϞ?no}@BB *y7իXXXA1չ;R+qNA*rK8wRkBL 1JQB}rşڹ^U|nCxEu1PjᾙRƩEvfkT9Mӿ<[Q x+˜|mUyl`6/l܌l$'a Y&ΫuT$t 5-,$}$H#%Ss `)+Dw<| ,%ʘl&:E"i _3qI#FOWLTG) A#@^f*IFv!b"&*K?@+3c<ڬj_4}[ 6viM%NS y8'c _Jn D 75 ^̠̜U Ydt]a\+!d)x3AKCPWhȈl2)_7dyƔ %Ɍ-^dNPO%S]'PH=cE8hP&@4? V­mv7B`*,Kό% yytPY !jaX]f!om^Cl0MdOU`*Ż Bʆ/3GI)j˯Bk\#^]*\UQ0 b»"jsP-~ ܥLCm忢9&ʡFKnF L6 <f o].ו(!Tnr ,: SikыfV%fGcӔ[ZS9* 1@u}יEN}"DGf]AUI.`E8i Ms’1- mJݏn\ڤ--IQ4_dU4 RQzN[ hUj F VڍF<(@U-,, jhK$.X De'0htƩ\SW8-%U4iF &ѝG*ng"F dRTXUlKJ~mNu2W _ tD = bD }d&||ДNztl A?FM_WQXP^;)vS1&^f:筞eV:k6jǢ^T+֓ES/5Ӹp\SOǥNciurSHd+/K"-x7k)\y08VX% m~lzΓ\AVрeGV^R} Wm6p.X3M=`IJ,/? ba>nnn&~݇n>D4M!,,3#)'v .:° nVp}J\":ͧXmd2'osMFnتGߤVna)Z,oNme}J~2 %$l= 褡G&69re껫RyIh6@im1JwXᐑ" ղ/}cRfœӂ  wdhe69e ,6qcHkz3{PpF>27z|zl2剙<Y!A+߱MRy$@TJձ@r%fG2X[G k.;pH:C7k0<꫇QQX0Ftx-Z~G [ڍ\ZdjxXRUH+9nq&uD"/w`x^RYgYY1VXǪžUJdz:M)Fdv7~#"DSIPlR!L Qt#e !H7bUhAğ۟/_xy:WţOn>}ї'ϟ>?]\\.Dtpw}u}uuw| @%ҙxA]ګ[>8o-( ^:}B<)V~'!X{W`ghrֻ$4΅ ֍BK]֕²F@#:[ouDaq!U,4 [Z,nW"-THS&j]=~GlqUݨ&T@L*<~9`!ATFS@lEi`󓵈TMpt:Ar͈A!@^J #gh]p4Qt~U.ԩ [cM.H-MM(Z5đTo^Z8IF3V 4?Fw!$9C%F˲X3ϕb jv@kUiiw?ヲ2yż0xf-r5`[!pF_ʷv[#d w:C}0[b U_nP@̒gh.9ZUazVQ}CMMhc,#$ˬ 7 *)u!PN}3@!:Pպ|0hѭr<&+cgkP|}#W#?ST3_ ߶Ak>`oh.+-j5[49}yE7_amtOPFDx~ }ܶ!=/H-"K @@ XFr`J*2J+`|Rd;l:ImL̇8i [*u'HuPq[ w @m0x_/Ҡ."qгjX&ߥiy,;C^CH*KM]1K/Y Be$ا:ΝpŦO1=]0A13) ,,p<ۇWO?ylY>={?q>w/]_^v/>% ͲP!D0}2B`|Ld4о2`e#@zÁ 8dr/ɿԱfo4`V%mqJZPE޸cr-6dm [ČV9䱜ԥV8n%2wڭ qޏTD)\"пx]ɜXeSzliL^xE<jHG^/nUŒ kwxXFebp K[qm iln*YՃѨ:Uൡ/X > J_{,1]65/ e׷$U_cAMAԂaA{|^rý^&_\sVrբdgVx֓YrO8訒EsǍTEM5${N?dQɖD*+Db9 ,ɨ @" ?iAgZ0Gg?xxx -4 ɳ,nz囗~ŗ/_|ߧ/>yp{ww:77 a i9 㽀˻3vVו`OpI5N#Z#flDEÚSԌWCd-] ㄎv'&TVW"D/oҦ3R2o\Rbŀ EatkLįB(Ά| CiyVJ1gbdPC M r4xˠ)ű~>V.{Nf$78muLz 7ct &:t1뽶 zެU$taJy҄v:Ffύ`c5TPh%04bte{GZЭPƏRJ$Jduqe.E |]7l3i0YM^Ag:aF33Y{QD.uy FVݕo@e{uJ}]:+n($VgdfjҖGerna*C})Ryղy6:Nj`U[n^F lKyd> H[2BC! P)Ч]_<lG._ţ/}7o+|]~x8nowa1~~_MѵedtQ[tX@gV<1U޹"؂vg/ i3U )*mK epPZ/jDIyVu»dA񺝦Zaߎpm&g(΂4kˊ?Πhj8h z뗀y‰0eQ| lb~l1]i4vJRJ=J-`z$5"Rk!c*^xZ };ϗVAը1 j&SYm+kA0E")`gQ+Irf1z]zq=q/85oF <:MM:Țf_ t;E5L@[>\|dCBGb;) -G:8p EVEru"A0zzC#EW;so XK2J l4a<tzM-6[**hSmYɒ*ȠWH" %xV<`@O{,o߾x8\뫧g^}:M!ftX8^޾LL?T!ī^ 4E ̶?Io)QZܱ4)Cm pWdXWƫU 4 9;$kbږBS%w!x% p[1VLGiC?өJ8rlS&2r r<^怓 (F&4Qe|xSԈxĒn" >j;Em|ZȬ3 ._ UTဲ%YѾ W5B:#-ڔ 7lڡ-Xd +{QIBUXL;>$| ,$2|Cv?g7c# IDATIx::*TTL*NlF>',PT.Vnj@05Ts'E@yn€]zs7iXEPy~%<5HK64EXx٬LqoV"gt["BSav'uVP"@9f<"O?? <~Fp<\=z!՛W|Op{d/CQvC".'0qOgр䋷`%(GR?rVHtiMz^IzT*_ @ТD*Z(j ]6˫3D[E]Q"0;o>םQ 𕯷 hUFjdߦt.!F-G{;x5*/B\!Fm d_7Vyq@;j0ڏ}|~MEJO޳~u+-pT`\!iX.-~ԊVB =[  U .'?O@7w>{gi>Nѓv#D.._WK:u~pxMC̮ nu>.k8(YN2J x"L5Y۰M\0nRes?q Zro WaU|Wfl_ xjo]&qdk7?R$㭬 kZ(5H ]}ѯopuO\^^^yͣGW^e R8M4g?w^M ~-]@?H9n&":яbˤ؂cR2[UpOpypw„(!ُ0n#y#lU-#AǸQԲ}"VZ[ \mB ގj{tIU.dH6}N]k7Qj&`# Ÿe65.v!dl..#ɥM| w2pC,o`QE*"N3b0A(C`9"Vֆ:+E[԰R qfUaIdeoPew. Đ\*fR,Mnlh/TBUwpTf/I(&rZo̱sc !fo|T jvdzCqca{x E)#(y8( &z,lXfE6T._͎ɚ7GHVy5[%ac-]Qo7y(L+J_{q–"o Բ,B1"\q 0a>Ǐտ=N_|5-Ϟ?{nw^ѣǏ>ztysv_? N bS@D\rB]]uA8@2SPEh>y-G+{扺"!ޚ}JJH5=RIٱOM_!'[k|ZJ}( .^m{^?> A7ېNJrEQuɯ3k%8SwbT3oQ Ux%åў¸n 5n"@:`evؒX&tx`AB X wiDӴ>ny>'"xxx͛x8ez|_Ҽ] B63k9+ i.F|cTq f8@ {0/SǁE45HUQH[v츲U%s[aW$HOKF!5^Ŗr"Fd;xaCS}SBhjyX=ш~L!m!ޯtRtR Uv"!Jv%UIkyMJ[-Ќ0 ZQyU)7o`U>=ةHo%9Dj-ie_vS}O>G_@WϞ¼ӯt$ vEl<8рήP!1p*"*D*ێugʱZUϖACm2GndjZ _BkSRew᜕4z  ͸P`n7}ٳaՈ(QdS^J WGL)at%KQ^OhVr7rt_qU1V3]| ЫSA &ܠ=i%yz)jK7ibOzjD?IᏝt5Ը P՗ d óF}6gzԞaIQ1{ ӘU⾓*agm=F*ԸIyEHc<ҰE@S'qbqMr%fǾJӾi7AFjP+v78h=~T"LB[V, {fP-Cd 4StJC8T/ + u *q=#eZx;(x//le* ZaDи?ܠps,Vt]Jfb\.U*UDrEzNgg /&m2 INW(3~ TkӶ]]qsHKÚz|XرLF$Ea]mCŴB b(d<|Ҥy%WdU5)J qJ9,|N1d[ʐl (kdP+y/ 4Jl.PA%j2V +/(hDc\)4֫CC¢<0̼)*Zb&%"-kh5ܜ`:]XLR5l; *kcXݫ}&6#YG:eV)ԙx7YO6e r=2D;k> Yn(V,Ҏ)ric 6\CD_'z"YNĝZ D󛟼|yٳG)ܼ}thw1=~d>~ׯoWDx{p)nwÏ´nv!5~W3-  <7*%^Ċt23(x)iw^Y8#$[X n.N&n[.gquimֵn&+caZK| z"jL6~f5#PvspmN4RT$Flîcm~>M-.^aF*JN#k"#X, Q XX!@oMea`ju9\4""@gB:IGDg IT$H0Ũ()c>+9u>R3+ۑlf[j3ZOEn HKb$=ZĴՑ!b 7"@~更yn=˃2./K4dڰiW-)嫨m.V,>3lS<(y$hɏl]٨ Mi𫊘g =^dUw`~s AcC@;͸|~{}/^=y.ׇ?~'Xw-3,LJËO_G/v{vH!L !bD…̟唓:FwWC \1LWԚ\[28Ea&T@ml{~FQ3v\Il^Ft`5%YWQ`)%݆[t X\ W+mI^mbMHj k~I*p.lnI(}XP.NNe d4IJ̾uIS$ZN'I.-R1b `,!EyvgYjMz\ct#:c58٧t-U X [Õ\K\ZC*kIa7RLV ubc2ku):b*@qHybGȶ {f^ڢ =UVSü ķK`+N%#mɃ6[lK}cgˎΡU^J(*U3zbV`X Lohbnig)MP{D l?`?iڅq9㏎׏?|b?MaMw=Zi^e旯=vaw./>/}Bc$ -}'AM6_␏c/v[Q Z] nb*--iC=]eNSGtf5Gwp)ʱ[uI Iǥ- -)fLU%6Fw;eK'.#2fV^#$GNJMɬ;rEH,g}E‚N7Y@"s <ЗZZ8\b|2 [3v@ S˧*^(4- Sߏ ^G9C|p9~,َOeL8F7Ytv9 X]׏e&a1(~UF솸 w&gT(f(n`šя&;9œߊ%v07mHFƢoqJC6 ٬S"xuڰ̉|S*f:zMFYJݜV鯀L"v@EH04Z(S$GGtqZr8鴜N/O?[>9Ѽ2BDӄӣ }q?M!dD*DBh^2u޺]S/0S1UoU d9X"F_diDodVTDSgt70vYAnr_QnΥ9jkuPK\3ݕ~jMo?ݰS @^acHa@T_b  (S^q% <2(x AZ͗Ȫ~gTYEGQ Gko0\ax8z8Gnӹ)1JM-T`r6Ljx7@mHTqH$S4U++JM|H 5^aUV=aCtN0ܓJQj2 *AqbšGRMI۵R 4%ώi;Mq~ղE+Ztq=P#frnɑJg hTf()be3yV0ǭ>{ ;3d3Y0nBL DSW(㦅慀hÄ LC@OJ@qmqs>MaDc u+n,s I[q`E7u< [y #=ϥ6R}Ssp'O꭬؄%7 l%.m*=n)qNܝA @5|N P@LPYjt-j#A|֘pl+f[RK#ψ*5H|Ql~[eC|;BsnqV:D "oPicwKq艹w U&)΁6%|>٢̿2\@5n6-S$/BbL~MT@1|חsPV5xcBKt 8Im=Nx7,uؗ J/r"[^ר8qUY^$!1UF^r7}k>o`ݰrf)Z-9sv@zgVYVÄ ޾λr|ȧi2k+( 炁>^(InwfLy> Zv* m;ȅJbΠ p܅[:c6 49..}2;GRБS7ٖc؜OB1-߁+KJ]r_AIٿ ض(cσ]bkx5 U0+3BIDAT/@ʂՍW3KrFXQZ2PYшt2GSi3uyW tM@WE`&~zJFSo#_6ɴm&*_ d#AB)!+S`U+ЊqjxD>RQBVJZBkE3 u#-8,[.3u>z/8F{ve)3$cx?a s=PN)Z W#2]QZ|_ 3Q)htRBa#9 ՋĮγ/ؠ8}աW) `$ן|zt̫g8,եHDD~9o?}3` As`C!{[.q* MH ښ)5CR!(Xus>NT!,wv8"h" L"7|`jg( UHe]W w8{C*! T `AlJ"F*7qgqU4HjY5q"ȾM9SZD!2(*I@{i0ֻHe]p$)zD /ePm/].6er|]gI qnơ*uhu-:^sk1(4 '"EbnXc>G-zRvW3QU `4N@0뜜ɵ`CX'?>xѓ}i=a-hͧon'xUg(?G/|GU]8\h6UD V- -b2 jsu+0-nXj`A:Iq҄&G}C WOju+C3_ `c~NZ)E{Q T-|%Ihiֵ!=B/(_o>߰mlh`TiCO{u-)$s)@@vg3QM^5ڨ'~,}rA. 6Q))TdAa:J2̭\VjGʄTD٨(; 61/T $H>Se3krddDփߡ5j;Fnj^lU5ML ۍxp3F^< G Df0S/9 w`d"=bX2h'%ıXf5܈Jy7C>g/"L̀QO'u" δ_LO|/ޗV1+W}8staf<fIz+͇ m7(Ag+-WFoVF63%+AS[dHE밹=pl7& >s^*ð,Vmr l| 杪(!y6>oYjUa*%+sVU `2 8(0UEϺy"[dG QEk̲c(/'ku CmHaP{WXBhrSą;^+2NSe1DzH32 R豱*ںx0ɐx5arYunw"`X eh֑ܩ56Mȕ#XPq $KL ζɍB} Թ ~snJgQdc2q {@ȅ|ō B ڎyԖ@ptH J_̯$86$wrО{4 $v(5lj(!Z`8L˼&DX׭#YU8wbzmH YײsUN}+9#.Dr@TzE-*c(["X땨)uUc6q - ۷ P*]瀪$7M5jE~W{0ebG+cT.Lb|A' Dh :\ÕI=- GC7ΔV:`W6 %2NSZAk܀L,gZ}1o\ }j:o̖ 4AVMN-fl黑z#AT㴛2e3"˚T0uTR=Fsb9)1 q PSe~:^fKh*t5m<Ȑg )ռ(þ{.`'#Xb MDۿ!ݕDɿdQ^{˛8 xabeEQYd1~%wI='&gBKj7߉5ث\feChF{`U̱䞱E\uGؒ KM˪>P$S =s,.*YaJ)-$bNn!lTԻDէ(G!ml%z!F /Q*6K4 @@'!$BdQ8e2kF._~otMWѹ 59VE[0:`M=Ğ%r /TYW6|㣉Et,PH +LӤ$64D ܀A2b۱=x&%q!J[ `khLsN& dMQ ."/cja"v*FsQw6jf/M1¯d&BNVg/ Pw˛DI '|b2u^ޫ-!Igg3glm&Jo~DGZZb j_͚uKmlD I [I³I:Aa9 ]mC(Zd[f&ڦx2XIGpYzFC8[sY =YX73R|7Lr -2*čۢ~MO uu\WLٍM{[vXj&^[r$j9L7g[JקS;2;? Ú7$|40'NF/UaPqPe>!$gA%XR) B7!."\zxVyp(^A)<`zPRtwr6"\Ǵ -i}psض Tf)͎N(~!:ZrE")c). 7pgj{+',-i@fj"@Ns% 2%fPEiK!$0mm1l}]oYh2φ-PSݪr&-Ba*<%i |}wvlIENDB`uTox-0.17.1/images/utox-osx.png000066400000000000000000006276731354126257400163560ustar00rootroot00000000000000PNG  IHDRe)iCCPICC ProfileXXP]}C03HID4$Y d $) (IQQ$A  A_[[{ޙ[_v{Kaa0 Ш[c=  I ӵ֟8!{=5zoH 5zGRB)aQTIODQ1OL Ro^`ϜT^'P @3zRDZOoX s$CB=T,/kzHgpWg2,Gdz~GjoGyPS`o/AEQPFaG#ȺT|$ɦiI~?wVmDb/[T?|RSE>5S<DGNw`FW)  XQBQ>AHŠ Tjp4f#0gg 6A1B/$I@*B- y@~P( CIP&CW6t14 -B+ 0 2* Cp!\_.x~5@,>BB | DQhE!&3%O$Ɉ$#H= G@f!&dr9\FBQ\( :CA PP^3:fAU&hgt :Dk #Xa<1QTL:3ⱼXyM`kqll:l>ll7ٞm كϳ7@rsp˱ĩIl|ssrqUp sqpsqq?^a iYe Df&뒃Ʌ2 _4m~~{Dpy˂u/hT. m; 7 /%j>C]{"+J%$Qj咓R)]:Yii Df22.2ed~*Vʾc3Kk[ȗ?U *)ThQ(xIqJQR)M[iWYE9B^yQEPCTeRIZ5K_ vRMzz7 ) Z}"|UԼ9Eк5ͧ]NG@[μnuݯzzzz; # ņoꌖ;MP&&M&MM)5f*fz v,-",Z-aK3\BC7[+S\"m66%6mlmj>^>ھہաa1qIӐ3ss AÃ?*>?$r(Ѐ[w:wO;(GZO+r5/SRe>峷wOϼo_ߢR~@q@ `!{ A=y K W_0 Elb6Ѣ)ѳ1Z1%1G܉ >*~41cWqxǯNx>)p2SƧp A es$9&&s'JK1NKMHLH+;<pz$]!(Ww`lfAN%kܙ3{g}ώd+g_:>zy99rr-syy?  ..D_)(l),:WS_Df)WizEt.՗qem]BwK3M3--cuj6ޗ_VAv;=}XZgXR_\{N?2zO_m@}ޠ`PӰpcǍ##M*-OԞk0xгƞ?tZx˘ۯNM3^^zSV޽}~~CGǂyE'~9R/_Emxi{+YU?tYYYd߬oqk~fpWl齐0?zT@t 8ڿz7#=+̡op>RDa|hf"Z.33e͛ %W7ooEWPEHWXD_T]LI\TG^ )! RvXCAB1G)Q9L吪:ZINZbl tLl\<||<g-3JNIMK:lt9%`k7owgW4%Oos!KapH(hGVm=67rqt#(ğLNJeKc:M@ffg};pv6{g9yct]lXvr~[avà~M[BD=t9%^Zk̶3ζgwtww=te]#]O5_(zYɘ^ڼ2Vy--//~_!yEOLv?\zo)ˡߝVV~֖ק7mY㲫Kjeoo18 aBq1&P;xEl&2ә,q[/ y>jZEnVHdJ 5ӐRUWVgUժhi-áK_7f`4k+-uNhhHHHB"br w)EKe0UV\\YmPc^k[x zbnlHJ㍦{=-^Ҷ:t],\zzI+ ( k<79DgLop3經_8sCC [#cL 9,+4x3JHIܐRZvtJzlFP,3gEqg!`µ%Jg.4Q6zy``PՑk#Uգ5_1X?ps cw}iyӽ/W~11YƩU/^NgN{sm߬;9?KS =>|N] wUnncvл_=7-62 oA/ LX8`I ~0Sզ(Uij`<*(H*Jp<=X'$Sa( BϠxjÈ*Uy ˑQRhT'>0NXZl0vFƽ܄t:ч8IkNENHR ݥWϠ0h8K*[" Sb\qC 1125 742 VL@IDATx |TL2WHBX%"բ nTATEA-bZp+ *  $dls&//ol$xn>3s=;s@B@! B@! B@! B@! B@! B@! B@! B@! B@! B@! B@! B@! B@! &WaD.tS! B@! &TJ@^@xg#%B@! B@! ! Zfïy&/ ! B@! 8m~N_c2# ! B@! cgLuV׷B@! B@!dqN3yq&GHGB@! B@g;2BBO4)B@! M@Sp~4>^08>m^4 ! B@! hNtYД ׆jVN* ! B@! hqP4D}He! B@! BD/urc>V6ՅO۪ B@! B@4aס:_N/B@! B@!Dԕ#٩3u崨Ejc6ueАm7B@! B@_r|B6mզ[]Pj7&@mR5^z[B@! B@! Q5g[z[5N7BmL`tj5W ! B@! @#` F?]+Uf6n'@mn]jXOB@! B@! ::5WzfmìndӡPӶWW: 7[\Lۢ+B@! BvPj/1 Jv:5m3ztj[ϖ^WB@! B@! d85ֶ9ZԴ7{> Xi{*i竾JZ! B@! @c&"}_:5-cb\zl5&m[79UH)r?۾JB@! B@$PDŽʽy3_eqgӬNвrԤ_u-M }RV0DW! B@! @ ϖroefr3kMT}c˞QFpۆ?}of@e Lח\[]NMi}zB@! B@!4ԧc!tx\8X}U/oK[<C V@{2nȶbK! B@! @: ז@fzʸfjʔ>V__goK׬,^[Zҗq@tB@! B@! 3@tdr}c3k3_`l5+3|幌#rc0kǨ#y! B@! @ozfr_2.sCi/o2,F׬k&7ɳ3&6z-s@Z`/U3Kצ= ! B@! F6N_uʌ2<˜ӣi夡lE0_QH c9|ɹ0G@06ɍ2_yU[bbb_df. 5'%! B@! ?q_NN);g1Aѧefyo2_r.3cyT%?ʁg&7yoimLBBB⎟v#""] b! B@! BX,Xì())&kƵ9Tg( {K8Ax:TX4wh*) Ԟ7=W[ݻw?4kB@! B@Nfd՝:uZH^A9ETV:fef6_Q9Ciz3}efiiK/$>IB@! B@!H}>^:B@!k'ഗe Gs B@4o22CZ9i㬧, 4mZxa@meLM6ySC9t>bNEtt4hS` O*,,DRR<mZ=r! hx.)lj;/+ڇ~w1;ﰿ zwҾv]]WtW"q0z#eͶ5B*/@szY4pV.ߧMQWWVώ;7"ro14,>wz%= NHB@z$i&8N(V9Tc^iJǓ7QhX3_W3e|6BiKϨϫ1f{F+.~oBQq RRR'**JsҜ:uJ><״U74v{JR! G)m0S[,Zb rNǡ+@jK}9'9؎"V:<%/sUv\ގ~߂G7(]_T%L6^Z7T\BILgrT)U|[>ȶp~?n:cuV6|lwWy> ?GwʽZD BO/o ,3\lq\,][ wW]UbnC+tԗMoܹgɭ1։CVVX~LingP! NkT+ oXrtSM:[pp+IagUqj%_pm0GK£#>fMXp1p7紟Ī ~9 >7OleY "F'oD4{1 lƳwXiC^gyu9b(^aLB@! N{?͛9dT]}Sr_f2^e ޖQӪNL={iaԗMU˚Xo>Jd7v{B@4G1̺ܾ.w%|Pv&ٹt93/k"|UXZM'6cfwywac0˴5?}7z0>4Y4}~rEk2i\;'X>m'-eD?^cGū4ۃ?@qYPrj/V-X>;A){C8MaCgEc`xty>t0myW3#+r= {0џ4{3-| %bْ߯ٷkgS&_h7>Z u3nօ_vG|,}6}wFv~Fˮݑsql|<9gֽFO!}/M>1?.:>-lkBlut{EÒB@!pzT;YW^WʌUO,7):+vsՌ(J+6+cY_D۶iگ_F.3sA5v{Ƌ!y! hX.\8gpe98QVV>T:8&| S-S iY#xul^:>6n}x igD0? +~Ś1s75^CfQ}a{~:r=,Jl?R|4^<;6s)<w`o{`cSd$E 4*[:k2>;ݢ9؀ݝ.%djԏwOVHOn3 qσ&9?O?6хX{1當x涁yGZz1%ݴx|xa6f^U?4f"ItX5s-^'*ױaҍB/1ir;Ĺ--Ut{JF! @YE % $zʎ1m&cy8ex zfi%3ɸܯS&[L3ȄB*%AlI/3湌gvzGB\ӳmOSھ;OSL@0*7l"jTO&wJ@DHR|727ϓ 'yV^ٷă/PrnYcnkN(ktsWt:ї,hn!$DZ'J T>d&9O}Gq*(ˣIC1(ۃQ=OW??uĩݟto\~ dtݺavy*:L:t "tMQH]ll>gjwkƾRlHN(™6]1x)tϵǪYl[uZ:3#$}]kD 4*+~?Baa.=s>/z]vXE.5 y kn_~*TYeT+)tqC͔Ti3qOzF~S Lĕ;3x@eޝ>2i^0p"\e4#?.I؅)=/tl3On6҆}/ܻiYgsۜ=hfHsO5MhۍW_r*}fF̞_=v\4 5?~4Y9T\g=uMY.ٿA8q]VQVrnY2eri|8N<ʟBp {[e >W~MYuן*L6{tǽI! 8=x2諴1\SiU8(=OٛRRAb.}3,df^fLs^=*w Lq_Ǟ{oAdeT9ڥcgJycWB@'vQp!ffc_wUOM4}AJp#&ُE y1j3PFnߝ7ƟŔ N\{o/b9-Li/ hLQD?p.2Bu[-EGn`}@ʄB@/kA=[Q+$,ˌisPm{rρh5boFc(rW2L_:^;]zsDAcPDU! @% 6$`gL UX/#^޸ ب W) 0ZS0qP{MFB1x}2Ȣ&iq,gKc2^Ev Qq'-cf70,KB@z%_9>,W2cqWJƱ7^Vi@7+J}L=*+flߺ@'zB@! oB[:KB@! ޳;bc6S(TZfi%Ǿ\ƁWԭ2(1 J-:L9,b< ! &ZB@! ~߬r>4sZuoF82NriWu8EEJB@! B@! $~ D9^\GP^u}ukK~NTs%Si<~ۿmIB@! B@! #PNWia }L7]Ncc@^W桼hZoL+; ! B@! M_栗y$ϪLITΫNMcv)LӁ:>ٖ{7-vEO! B@! h\_s1fʔ\J >ӁLFPP7\eJ7d*:zB@! B@! @:jt,bO(1ƪ^)hG@b2}Zr:q_$! B@! uK@?K9cLUѮ:SF/Siv[N @팯2+YZ8_`$B@! B@! @ J17r6ʆQhVk1vR}Zgs(SL%2@ IB|m [˕B9C^3e88%v(Z(9lB u3bR3k?j(Lm+dVJae)%g DYW>b#an@-uf]Q ! B@/^t&`~ScWͯn1pZ/gSeßvzY`:J2\_WY/Pk 3a*Z$;b80Uu2%fG?8hִv0ϰ!/B3m,!䔡5vIfhY-֊H•}ʹ< z'PdTgæСCq%gϞHMM՚֭[bÆ %iO! M:KFv|vJ\{{c7Jn9XHe^V:e ѧvQ_b=bO9O* x;\[&3Br4ZD&rքо3{qC!%m_.]F>} ue]o .Ν;@! B@L9WyN+95敌cr:I5ѐ-T' Dʫ16؞<rPcnK!Bt&#{'Epn_zwuc`($ҫ#3% JC$^^/"cVXa1v6u$! B@!0Jc6d0UЧ`uA溪W쭍F#wё׼oˍf ;vAaxS7?Ŀ?:qApZ$AFg̛7O;I*NS\o3B=! B@!|Y0,<Ϭti4RRN PE]A"^i0ꩼ*SecݻMWp'z݂YtNIR5̀YtRk!S(8U%(-BôyT>mn kn0m 2[y\WLWR.9^dLlC6 ! B@ WeØ2Ns1Vui['q}:e|u{JO7*S7F*ȥ=^B5狪`Bh/Z7D]JaB!Cj6hղ%RUB2ڴhԖi Cd GBttjRa1Bi(# KYABB (%сLqp +G)8C6{ޏv;ũԞ GͼAvaC?Ӎ,BmuS[/BGC؎lBSj؆8ejKQ ! B@ {{X __4,;dT^_Wҫ׸.2<UOʆ18o&QiqAqgVvH.tDu9Xڥ@hkڠS~h6[$(Z@TrOADX,zvn-7.cv 3.T9@b([| nx3Gzs6>g^ٶw K+$%I]-p%~pzpgeCY_P>1E~Aρ\CL :NH({`u*YKJ! 8{cNz*'q# Edz' .JЂԮWN`:`r6F{\9(y@'S"59|.L!<܆,R9Ի t vl7:滥56!(;~nۋw aHjܓOFhY)&?ZY/m` IB N[*.AdxEǡak~и̔>u#tz78`gQ:̍g6#鈻'gKsЦ!:Trz۳<=X2y 7mCngc%' S.l҇ۗ{y-هNFbp䐡{Bپ hIRq{0,$ LIAV ͚c)c!"! B@44!wpuCast1S[A|-v`)Ƙ˕L鞶2< l[= Ֆ}3J}Bz]wZnt2yؿw, i& I)&1!GY mKKR"SB;ST7YlaLf(=p6 EP@rt:P\{HvnWV ala+~~~7b$'v-ݻO!JBk$6Edq kR+$LzLƚa`+ڥpDǦO/})i-ΪJkT@#O2ZQ]CfY|FL^U}:C,lM\>{tbΚ7?9Vf nd݋ql7@Zg#~lfS=;W|"n_~g! BtЖ,4jK&q%XMU. !ȁ@17^n&nl׵S0$3}>m2byCNNQc&6-%䶣(DEZᦟhfKG!$9Q)I(y!NYQWfa=6D7~'#!&S܉ڶS{d㉱&z67plgOO wvȣQjb^T5XJstpm7'-)!p: 9rNQߡ%͑)݉g2ysV;$'[BfЅ&]nXWۿߊgƼ%F)G)UHFtr v{Nܾ^K޿Hr1~1ngDDT9جHkLJ,B@FGHelo]v~MI}/Z`f+kHZo_:ʌW~K+7+YǨg&Sqx(=ze%&'fD!F#0N7DfTH-9Ž0:QP\51`Ĵ|)6?J7IF7s2;m܈}";'ĥ]BbR2l =i_ ;r 1I(6pM0gnd{,KnGNc4Dn{.m&"0n||6*[t)}iKg(;wϮFrUil'^\8Bk[5HƣK5&p5z_,w hq+ωhmbks;e{w1wb԰W+o%QnHB!  N 5KyLBh]B@ӬM޻ivoo&3z6JG7敼^r c>Os}XPeJy*1{r~J$<6-+- PJX#:4%]^zSJfGƢ6I$t쵅7.Rxۻt"bAxroށG3.ip9vR~:CANȥ㴏В|\{3ťƊBV 'Va@e#HJ߾\>7]v$ D$ɰ%4 Y۲QrbԨQۨ^94CGC"Sv+1?ܾ=ѵL1iPlW9K6x);e()W!S[bhksO)ʥ ! B -rWWenK5hVG]nASEsw*o23 },2J^2:ŃjRncjO+Ñ] atmCeY/@l \14C6K q<-p׍+i'Zx =`ǎȦca#si&{/6#&K1-xDZoQ{\WN|0=x%SuCW[R v{k;j,ذaxOXܻ&벍?݊! Z.>'t6[s~O\k͘G\8L}hCL+wP*MzMf2r,oFRr?Ѷ0'*T]B@!  VZВ~vOm$n:D͚_Oʋiߘg).[m7. wјt`\O_W{ؽm+bicޢb:)m1.2䕡dʃ 14 0/!aM3^쩌fP5w^4k&qS?g6oMA\:]N\J}kJQXTJ+ Md坠S';Q~ѵ⢌u1pR9 njq+Ach)VMzkt1'Xwvpx.|m@b4]//sIR B@! 8]!|zSOMRwǗϢڮYuͱJUc>1ZN'.!sycZ7=0wA>lt uH~1\%연dB&Qڲ$,ó_tdzf"ÑJG^&œǁ]۷O秙1nyӺu DǑM-n$Sq%I* +\'Э#B!!1CBt z б3g%kSBGYO9Ӳ k;dJŸf2[رcxD0PI^/w&tRډ' x^35%Nv8d8[iԍ͘8m9vf2T<B@'6ݹڳKw;t$  \Qxc^Hә~oڀ6;j&5ݞїI25/ʦ^[Z Hrz$gQ "CߵiiREXeKqt5!!!YPrL=4EeĦ/AˣA` -OqmF5"NZUFKJJKaeLv"nBࠍsrOQԡ: a>#LCg2>e)^ ΋/SNi˴lҴkGk7xô\B@!  K2~G:NM ۏh-韾Ę[N;hycsºz}^ ߼%VѾtjm]rJZS!J=ahߓyyCЪ% [xqمrЌAR9imQF'lh)StщMn:,;NL(t H|?|6 @ՠBc b,ǏkΖ]tzTm[dffb֭ϞT2B@! 4.Z*z~_cU)^d!G`mPZgHLτM~<^< cZ7`m4NQ DMG)KZ>ij_lo6-cXv>GhpV;sf+gf:tu,g;9ZlB)9e׬E*JmERqYpQxĥDw?0cű#Gi_Xڇْ'!p: ,{k_.g3%DSn_QFVRN/)))Pg!K/>HۏLA"B@! @ IN[BJ^)Kq"죪ΛF1Zt² t2yx.nnj^(o4ձ\lẁ}Aq-ⴄ#36эK@|r3Q0Z}v՗ 9%O᷿-QM\x -;tV!o[\D2%r8NA澥%pfQ-N܈!"e[rN3q,ؗy %v#杈Qxd̘<HҐkvIaq nѢjfg!Ju.`[ 3лwo>$ F;Ə ^QOD;{g]*hWdשf`䨑057)5'4 ]n6׻6uh; 0j ]i2U2=eY>h1l͐/&9ht)_ nY̯ӥpgXo6ɽ6Cѩ0$`ch  bdf(mEpY@6-yJhI$zq|>5;ph:LkB0"m+:Ic"mGR i(: { -;JGIf~9{#whXUKoqA׽xgj-ԥZO,~g>%-_]qgC]9(%ԗ%Kg 뮻ӦMgpx'3U 3/:z|$t<~za[wT٠!cPXF'7k,ԞϳdfNw[fa 1a +=M)ATkq[ѫ͞WE1ff]UՁS{?UU2ϠLB1UhU?'v"f3c:vL,&㓟V1^{㇕鮟^DMIÐA[^dU޵7Ž=v+hmT5ѷ@~Sg/wb߻M?7XuC@-Y2J~{!CK˛65?+v^ѽjdu&^JwzsW|c+~NS; ~p*bd8\!HlǾ &Qt8K Dx /Src%0mC,vȘrƄGE+Bi&nj6 vBܺ \Brti#Ebluё!Y4a8)+DspS[ Eͺ`&{K|[w>:_&C *+ +jxicJ1S/Óa҇af$"#o<b̙t쵞CFex7gaZQzz:;<=Zs(}}< yƐ2l\9ϭہhf0̘w 7!ұm`MZ)ӱ`~LNM6Jy*Y7auuq#$)oY1y/-~W4޼@eL7[wђ.zUbAtB[Q1giNp*UTo|겍@mZvI-w{Į]LnA"+: Nrhi#tZd^ijhBoC˙HЌ :vf䕖 4"ɑW[ffA)䴆NM,48~,D:W@لaI1 f#"o'ntG,gOx;va wa{ʇ]icEŘG}z4DZќKgcZA f'q.FJ$[(^c~A G.FQii 8Sx9-9C1rl\;ĻKa*!פcÂ:Ģ/JŁK? pؿe <$=ñ$K }SJrȰwX5?F%}"gp\z+hSD[@?E.r +CFzf:S>k}I-)yeR%KzCgk}IqW09ri;r-\uV3쒤 ?f~w 㑛{^ceX!5w8. s1k5xpk̜$zx2{ݭԿ=~ֿᏯ€k0ijS_^7rLC 4\NQIE|Ɗ< Kki0殼yfIG5 3Ë7MӮ-_l_fwI8{-׻zT}iB-q@g،3/T}-3=Q3{ zW̠B_~*Gg.3X/ FʼY~ߧzS܈?n?~rوgf{w1lЫcc$٨Bg=r3}&ѻ3 l 1_=ˏ;6+4;M"\N N@\.  h_܇-i_is]h)ӔtS UMTlFcBh2jCSps?x_5Z1H!,8w*OB vrи9s,("9!rM X-r x𱗱C-ĚmN pE:bE閷=ΔDE1Gw>1ޠ/Җ׌2)6~ydpK1U6z1<} iFآ~@;|cx\m=YIIB45^('Wym+ęF757mp[uu\|EN}AN[&=LM? Rs޲%Xv\݊˻xj*.Kkɫecfc젶J<=ÝsojMQ{OaɛېM7oGGf lT7V,zn N}ךӞCOVaSh߰ Z:s-7 Cԁu=4,wXYUY[]I3Nl\EJ@9+Һ#'XjJǸ? GJ,6|L VCTx O` {C]u!hrd%ikjCiUabT:Y3\]+cFz%bvk(NTq{H&C9.%6F6&yclj7U?lҬېA,׊4;I0)c !] NVp#mz8d*ќ!) 3&mTA}lT*L0:֜B hqJVA-DeSt;\*ߓh>7m_Gnmy͓qTn.kI;hCvQ$ьH c^"K39G) nriT}t~y S5d"ޟ[\F>Sa`?؅Vt7?ɇW`h}!)}npm{æXPeoilYg,[{ [jLr99^w[cʺ_4#Kit gZd>¦FOYY0 nkuT$;'/: }}c$sb-ZOC\7[$hCx|tk usGxu2g”a=[G{ۂ9ܥ;B_U8 dފԬQ]Կh* ;fn\ y Gn3nJՠ!6 pU/d~*fX 90f3Z!}Xpd'.w_7wV3\ _xUXIی᎕iJB}Nqx;zmyuVN͹?R%{}KW vyp=*o=Gc\ pͣ1-0EjjxO7T?KC.tV`6_^KP` gLપ?Sf墀B9'P!RxNZiRӜBSRD)(( >8r/r{Ϲ瞳k1:QѸ,sDnfmMo:oyJ:!^  :Y8O݆/h5" mGrwQSood=#5,45ۢuʖT)R $v%{쓈=umɚHDKG!{.*8"RҾ&U+UnwLϹ"~xY= rֵ,x-41xRK]4g;!SLƇg!θJ`uXFm ԅhv 4SK]C(,%́ZӅ{*)v'lGVF5aގu.E,Q ]v7dɶRn^wp~dS4Y[Q)\% h09J)x%Y+w*1QVvc:6G[3Mn"o xti~:k{%RB.]MJPݲrErymYYpP뗖 S NR|OWR) K*uXb@RScBg&wr3$| ^I_{)w tUsK#ryARy>*H(!`gIcO=z.xqbQTȈ>?4ЌIӋݑ+77b~ĞKF|9W%4o_8#MHpPѲe0l774–$z^2|%%82![^qm eM.nEUUߩ6nNtDpS<hQC*x+r5Vx&z2RI΀i2QZP\ o$@TLE}Sz0#X4YDR鐰 cLONS_T t%3-|.4[D8r]tkYGӃp)Y䭡i  eȴ^Yo98Vs/{Gϵ1\+RKRvҋȴhޯ7@vbe< [=pa=u:Wtjkùl8:q i uA}E/Me1i<ђtw %mQԠUwU%Z1=\E,4/j@G:Xd_k%2Ӿ9U>&EiS݈T4T,lWY陸z&Z5 MKE&Yg.pXP Je4?N\ыcd[ض쇑~lyb95iO.Ν;?=6ӷaߥ|c|]h5x {%ƉL20 ٙ٧bGpwo* 1!ذb2Oonk,,y8 naTOzmBʤJ=)]mwja;=lӛ|lwb0Nj7(:aXb>hY#VZ9$/?(^HwCa|W26%4̋w 34#t4wvL[30lCtzXv%;߉h%lR$`MclډchAJcؖ.F/$Į):/t~" >r'MƠeAu&a6xy;.k$Η3t;RכƗt`PM㋐aJjb_/II?QѱS9IZiԎo GW@_LLYS@(NL67dݦQ[x:uJ XXsۙnذ'u?Lq^q85nj1dCK知K)k+XsŰp8떥o7kuϣ0dI4β_y.t>?ytz7$,ꂸ_1tҽ_忧V$qsY~ <.ERфس/f%@8cSFRxh_K&fye+SsQ1>nTA./_oYCK\{3wt0eTjE$29 Wq~C]rU.^v-1|PDo44 ݦΤߧiN)qeʖ^\֢Nb6LjVHJ\Kk4Ś8Hӥsnj%,, ɱ0)|V]y"7K7v>|RfQ ~V6j9۽lqrMM[:{c[1v-)R&aeB}bOEAmK5>,xӖGH"r$i)^ga#ݤ( '"7oR.CW}BZeKm`KOh gԤIG>ѦhAMan\؄LDAG=TZR0dBa"Bh|.j6wpxa.:CQZEo1oԞʽr+5LFj~4d!÷:qg/ȷ-#8`z}}!jq0^;4uEb@XӤ^ҒVE ^NcYNtO 'S!c_r|_SY%ev׋vŔT*ku:(U֦1Y I1ew{yTau%-8ءpAaA.Cwx:e'E+udɛ+1)E- O%v i 8 ",(%[^(|y=|9'YJcT-f5}* 3 )A{[0~G|DSc(I!‚IczhEB|t>FJvk#;a(ۤi_G'L94_ j?B3I91-f*`2jFsPW -Ǔ#M1Â8_ӣtsm$6ts)\}ABtx(KFĆ.ǣɳ8}5Rġ2ʈ5`][YKxݲϕҒ)9m/(]v:vr-uoC[d5#iR~#}Gc}ٓnb ҵ]DaA8LdbBT#}VP_<"^,к>JyN^qL׍AgI iˠh&nVWd*&Ѻu.x /=m/oPb<(4?,y_l/Ǖ[ݸx (Ҕ9Mފ<{`Nzi[͖=0.寫MM\8fYP%J΍[1uk5Mh;0Ff0)3l`tτVeCsEԷ+;Mj禐~E\=tn] ??gФ݁-SPlc*I6ngsW ٺLUYnŖ&L̘?utDLb֥%-{B -Q3OUBăhWwO~͚C>۷) 4@bb}K`/\TEĉ6M=,^%'ĥoVm  z2Y24%Jqk%]D{:LsBmlUV!Y0/$MA(dIJ˪tB7Ҁ)e*mR*j *}v=fg:鬤st9CLKԟܔdRPlLXcaQ+qҠԂdӸt`)tYeC}~(I!ܔ,Rϝ}Kbe/=O}_CrΟDVsy8!ТE'/#Nh桍^V'p!>ZuӄFΓʭn\싏r\/K4eJ*\35j LV1r\ n\N[ݸR"iʭӭ_2~ wUÝj0zЀdԸatת|45Av֭,i SQh]P&%o琚!<ФA> QӝhKj;(̯_"ș,ri\#3XҪOwkR6 PLTֶ&^jLΫ ) m& ~0ICM34$@K<}ޔ2G}Xy67+LY+T<>rL 0& B)档]e/+^*L˽ԴhlOkQjB|NuSuIӚ2orA&^my&z= .u:m"Az7n7&M%\¹oT79_V\B#")dQdNV0EQh +m sRgBd+ Z^pv{߿cx4~8;~j}~XYc 4dn $|1 0&`V(aU@wE;Tw~9N`ǜ"/HmZ"%\Ÿ' #k6D3grMQw"(aREl["[x ~CG[ RMqςaḐx?om.ZhӾ)A~hnDEV5wL`v;Gs2OV116~ !`L 0&M ;;jьg4U&0z>'̛n[]nŠ$iu ږ0AnH>W;-(BfV&t(TUkړkw2qV{n!Q϶&jE^:L2h܉mn#= jQ L,LadjZ)*dFFFZFX`L 0&o|&eՋ_e ,+e0XlC#u]mdNmYU{{T{ϟ@kM7qΧ˴8F`j|ҳʩՋ.hh SR#(*DzwghGK hR:z5 0c`L 0&`L 0&R1@&`L 0&`L 0&J>`L 0&`L 0&R1@&`L 0&`L 0&J>`L 0&`L 0&R1@&`L 0&`L 0&``oogmH<&`L 0&\زe3=nV<ӇOyL 0&`L ~XXq?q6ǔ]PǧB:~gWDž`L&кtBp,Xs¸_8Z!>rVDf3Fw%Ȏ P U5 5,yaKGC5.wхg+h].@xrs FSI#'cdW^URSƹ`kaT//8[Yq{?{7Lޢmz`ol +GxW[ڶPնr#rՈ*׮7 &E` .CAmJ^s﷉C/cc4X5yf&^FfZ2 5^|n@A>ok~,Ft68(^2|XW\ 0&@G(dq*,n|}R-lڹ wlś,r🏈 jt5ɪG!#r-rl1oȲGݟm0& ?#eľ(1S"aUzasg?JFo&}a4Bc,|111ƚJUssLYS轛1Sd%3MS~8a7a' C}<@7sWI27L\UڣP7Dj8co'CYsXMSNچ Tjv8=eD0"%[SU3oLHSV!ZShFB-#Ncc,7:8 CLZф& OCclhlg,/-KL\1iB+JP'ׄkA|',Ɔܧ9In #|roE)'o;BFS5-Z d&xN\AvR=*@H֭8{/ߏAL:껒|W[ iZ6)E~_/uBfՄ Y.U[rOwo~=5DafcDZ;h?tJ Lfb)p \}ZR f C1pw?to`P6ZCs܍6Fm m"X3?ZTU3Z=cL$R᷍6 =>Xًd>|56/1}Da>"yɍ6qGWkZP~u0FM\cYN6B%sHT¤HO]*ԏd:ki͌yqЗVVI+sxyc׋0۟EO^Wל_0qT0oBxôQt1s j倨'b=}k jߨNzFM)G±}K8%ԯRΫ/«9 %3O Gjj>m9t̰,1SIC%?Cx5&K@IDAT0Vߠlh7^ Hzl٩P*\><5y%Va[NS A!r3&HXֽ=r=~U6~x Jٙ$'}EQ Av¸O#9pHP_+~q`L <,<ތ@81s" :BƷ) Ě^8(Cn1b5Ӽ߀-rn#Qv6@|áqaIKGx([(R\N-k/~'+k }y@} ul<;z-xӉ)ߓyu͈0m /o}$EOډHW޽'$zi="t)iͫ)ic)=Wۮ~,1U0)|?`歛K{wC;ѽ'"xXt3y6NoǤ35~ɖ&~#E_X~,~RO 9i›dǪ}x&رonU'|FaOIӫo%ˑ$u1>KHjf+q:s<4΋.v\Һ61gD0x+I!?7H_  *U6%1Sz kcH'l(4E3baf֛>Qq/8W|ߠ7e&[ tIJ3&%b_Qx5]$LcV v샓?0B3-f9>rIviϝ2Oi&NgAp7B!cFU0,p{3i4C0G4C!#NNIpM ,| Z&+ t"NPUdmÙ2 su"Ea2EO#rEAPw\5xZҁ`vI_S^-s%:NG/桵~k/)8ʐrWtN"%O*\ޘG+Ru²[b){)l9mWf^ySL1O}FMR( my`_G80NAUڕ5{e^`3/L'=f_B.x9"OkȘ4vMm :ۑR$$ô`dD0*EVv2Brfpl}GWL܃ܼ[R'`LBڶDWmq+\%EHL^FfgvRFgY9(B`dJ؍]b}#2%nNV(Qh%N cE\]wFڇMWo֕c)ִ)C1X?R[[xJG4_(TްM~s${1U8_Lڇ&b( T蓍k Ց4 Xzd~pQt1eU&=%P݌2}6샭 0f)d20j$нӘ ^BPJ87߄͍QvJ'8-M3=qT Rvói*J7QW9VR˕7J7B+0 E08w2ao=eH|P~2#M BR8``]iAD5r/-S`Ly#&)dĸ-빢p)CARF~r=p9VSf%JE#b1)}ɊHL~|zHEwGRssO@ k43_Y0k<|:~4&;UOút:`wIm]h=+&}: ^4w蕨h|$'y/N.ƮH9qMzSL ࿓SΧDX-*"b-ٝF#1](G{L XGqtK0>`jG v+a-xFaLJ”04aKeejŝ0|ZE! ۃGB!D o_o㐎#j 2 i, a b=ZG[2WGpP5hlX-jCMuD̜/<_ 3FE4 Gp9\$x|h7wfPn{M/(/&6P,ߌ }D?5?Q#, Uvi1ie w):{卯cJYzLy0L5CƗ1VM,-LbWw :׏MjtLkA4֙0|>>lx,I-jU}E9kuw`L `6 aNo.5ŅI+fheUfquĔDRu=l]\S'?JAOkMU饺VNc>*m6sp&QH{D=Z 9X *XSg7WQgY:AЧ#%1i@E9^e`#k''rh8Ss\?|&j(_@&. ?)ËM>SbR;e嫜9acP"UWaL 0& }5#"箞H?'.n\N,)Ow_N[DJ&-V 0&PQ'-&`L 0J80&`L 0&`L  X4m#?5FE Ш wp".z聶mܹsHKK{aLy&`A@:3 t@-d?\_AXs1?]WÙш>rG*?7"l8u+>)2fLFjGBvy WM[np3ߎ\4 Vfp$fe++ʗ{/V@N[Xp9N aeL 0&r1 q0]#X%;qx(݇%˘w|aoБhgq"1ul>|׋2?~wjף|'ӤQ7nGc߫‡דʭn\?2ZX,[ lӦ 0fO\ 0G@a>03`D3EoLƌld^Ͼiv~݊cJLq,(?]<!?1!AۡXqɃ)LC`d@雼UծI*J˿4,Bf3MG'=/ʖϹL 0&Dڌ&+ ~pi~2m[9˽lrE3;D&$M_+|'Kd.\M!f<,dbw.F(W&yYUM>R&GdBF"7N>}pi9L 0'@P鎷::%E opL3'p|\ȣTF3|'WRߨG@wtdU{6a1ylp)6f"Lp Xd#X@rT#`kez:=H2O; 4ի ?=J,=4I8.Ն1PT,PXXʤ0h2t3 Caf2bϟ(>t Q]re`L <RAAy+h'G% zB~J@^H)#n 68[(&:pIW ^~s{WX.+!JM>B2bF4hn3&Hq 1t#ۏBKn{sꞹ{Y\EXȗ8Br sI+Q$Id|_Sb_z>R$7)dҢIho8o por*ldېaŠ1#06@mG$D",.WWJFIRȤ݋%No)r%{2nׇ_?|6>>cI!S㑛p8TljHILJ0BVTIRBC^^7[+S+w`L 0gM@Itwo ҽ 7vmׅB]{V0-dM{aۮ ek~n\Nƣ'6,ۏ\";&@EY+tGtrlTZrSu./M$gB7cL3&`&U|Q3ELblo^oc@{{غ ?{4 6.)z5j7ZGo!JXL3Aӹ=`jF8h`U7_\ 0A,0ro[d%CKYBmq';M/Vƍz4R48/TAv4% Bأd{DjEVbQыUO3X]r=y"$K..䣉p,<`\Clp~hF2M"W%i.U{ȦZmа)%%6H߻KhNvBf(`,6](N΍hO+UFW 9uBuXxk 0&3OM탏FjYW 2Hu˱{5+{4E䉐BaѮ|oi8m^Ygr~=!hwq'<:B5=iy!hAzGU*6]oD@!{ЊITh.J.1E[B|?cgӜTbJ&8ߑC4s.\R[X:ӴLrdk4~,AhG|Q>heO_ O+iK}B+Ҡ˸L/<_ Ո5G1c).1hAJ끶>W:D]ûO"4j2Z;Ais#4CC1ϕ|D㧓pJ ي;&`Li&S#AJRɠኛ(88’KNE."`A6$HH)}?Y)S#_Z*, dH+?#V,ieu# WpxDQhFƭ0X}iM/|+ Z |B-nE5g[rָ~LM>H.G"Ӿ!H5cN!EZ6L܅O Nm8Z @WܺG[&`L%P#Q8ܢ+YWF/."M+qV)?rr+bB}FT¯tCFF<= T]X5=&-NդRz+s.GC\q>:s=6RM= ? #梏X‚c r1xԺ=_wzOupFmRs 3Dav1RYc֚<`p¢Cн򦐗v _ejR{#V-b, Z{]z`Bw3\Q,?ݷ ,Jm+JK#p9(r6GfJ·yTVeMw(([d!.⚮/Xou)vݻ /GQxk4\U0DJ7JppPB o`L 0&?S\qc$L箞H?rO.Ǖ[ݸr_N h苗&IʍT@RRR ( d7لt#obLt-f!E>cgnY(27Ã' ?_{rC(&-w;Ak¹%j-pBZJ '9Oi^&b)df[XKyޝԆ߬OI!cAml$P%w?7bP1d:gjP QV7Z`͛/BFKK;WD!)2\ uc$=:nΡ[q[7Ƥ_!#IƬ)KBe`L 0&c ӗhٲek :Ԩus{Ym?5p ۺw` {ÿl/g}#bnC^An MѠ! a팏za`!p.j7+=6z.1%h(|07J`ljFbmO|h/,BMdƄ[hP1&P)G~{Bw 0&`ġ BF^! ( CVCܡ8}\Ҥ%uhX4K;_ymՇ{7a 9u[GVTݽʓBƉ^~0_㛈Sp> QՖ;?Þ\ ^M}ݘڧOIw811Ag zI[ρ 0&`L 0&`K*_nBZ$A2W~4fwޏi}އPcd'?*4hPǡҤY{W}dEүTOˡYb˞&^cq>mXJ?/OzE7,_-p-YٜǪ^8. O!dAtNYy9,O(Y!'ĞGV E`L 0&x^R>~ʿuDGJ|-ǐ_#sUD\O@y:8m \-DݗE_[Aa(p4Ip8y yqWuzbzH4 I8M<&L9~ #¯Rn5mBw+7 $ ( ŋP+wKؗ3< 7IJYI8^<&iRÆHK>y6қg扆VYy@Uv!3ܱd#+d뛙! /cO0{Z%ƍk1&`L 0'$ Ox2$+zѢEOBFtYҊ莤IRp!Go>ң+'kcFBFKN=ξrL 0&`L 0GA2ŋQdZ k׮՛ωLY'Y&,bdr"]2L 0&`L 0g+eӔkd!-G^y888HSRR"<<gϞ:4WgO.UCF"]n>3&`L 0& XlW R[5*gB>RٷLQ5z-VT[XX`„ EEEEV)M"\zU###lݺUR|-}jUxBw_k"t#a{W 3isc<bky9n\,fPt#r'17'quڅuZy!Prf?BgM;1G^Uqٯcq20W$Kr9`L 0Eu1$9i}H;kq¸_8Z!>rVD; |/gxX(6Quh}KI]($ʊ:!d=0pzl۶M٪%+߃Щ}hVm1n8xYkl_~$7ٸ s>Q[WO*ثǚ%)a^YO6`ͫLׄغ|Be*--URp껮EKi++dD>D@5{0`׸=@imz`ol +GxWoUVU`pDQhybDGoCn߯DmSrq`L 0&B} L~:NŜ"/[½/GI ]c.B2yƇqFaPoI!|1V4gDQ"q\%[ڍ:bĿ? vh<л<'n/;FO tʽ3a*QW@D{٨cc[T] cՙ`L 0Nڌ(8J|u 3< `Ze=hf'߹$I FjG6LXq#lI/zt#(ʓO>Doqlԩ֭[={ >>^*רQ#& @WY0g^ їEyȦxXD}֩1} sXoD4Sq:#u־jtS8u8xW`$IfZhaK\Ů%5Ӗckb:W>~59c'ñy4 e/h*z?a0'[|q2VO6]TKP}6t8 ÿvhz,?{u''D5L1&bt Ŏې;v֙:&aKtS.Jb~<~|b΢0 W=[N`k$VtK]}0k, *yws>8EX3 Lq_G$UjRTYDd`v #.4,ŝ\>SUSL(u%w. =_>o4ni]/_.j}}fBf,%Fa.Laܥ4N18!@Pj,(=ɶ׵l[ؽ ҴA/p|-!dx#6 13.,.]҄W˷(]0rN)puK񑓕t^{>uhuuF~GGsDAV"3e$B%6ey(N"`h>w6l).m{}Cs1xBiO'HZ6 SymtmU6va+1g0&`/>ő {D3[^1בmK^GA1pQ e8X u<qdšhB640,D*{#!;R8?`OR4#xRUA2}tݻ.]".t=k*/l?L xqq ދC}!43z~_̃<..\c(LT)MRXrümW^!H.$|V c d{U8Ή I4/3GIAm}o&i'5*ƹ݌X$I%85ktfDuBcAiJ6l퓁 SքB%*c"/m/?S=ƍv #'SJcOWdXObMn ±Bd840\$Vwj)Vm=FN^XLѶGDWcRx:|6GGmѝS_k=S?|.8j=-yMQgI-<,+~݅gbs+o0~g[7x;Sޏ^hL^'dDcoH1sxxf3||;?\{Z`Gj,n~ Dp 牝Ӝ)m'.ME棰&vڛhU$#z=1 B[Y$ i2G&8Z⩏&Kv¢-˥fF05C;SXlwGS `{ IccD_o[rI.?v >0&`/;3tivh;NKq?i + r^Lm5 +7R tw=+3Mrgk-M[#*, lݘT}" ֳ;\HԀH4 >UZI[,/^|DT<%X,G.ӄDk½s+%~ZlL&->@ԳuLe<=9S¼P eqSIw#g)O~q>}1w z?z""be0.޹?D؂@dŴy03| -C\n KIFz5\&&D8,@r{TP jULJ4r|(!ϖM;{Q! w%G4!Sc"ѷ{AjϚ8(hnӃ[g]!sepL nUK؄!Qzbw $¸`Є(40tE"A*I8OiG7glE>v~Q[(2Jѓ,)n v">6~#{:ʤX\Ρ7j~vƢ_NUY}+m/mz:;J\?}8T. 'B3T#e.I!-ƔZöksb)ދǘ6c zۊkV8vs[|!̝=W};P\(Dos2t+ȨOoP vYz#L([!ZhQMx.3|im!vB'#pH޺ }*IP%m#?+F4ȧxeO'@-XD1};u2y8q7~"P;Tp%]tU}5unЧT)U(@҉$G2Jd=/W/m69Ήʒ Muh#[Wڈ(}Q_ȭƷ N-M1enhJ#1p]b\DUöѥ\ Lɾ-&i[͊߈Xx^ne}(6m8`L 0&rŴ r33Pl>ngXfmФ l[68y3vV8e gk}K#Ӯ;lOì˻ϩ{9w5&2x+XXXH;%=Xe@Y'yVeԗ$9|E`զf1W[jWk٠xʦsKVϢr]!`l[2h%,4Y9eN)@i[)ym. .IJMdomAcvǚWӞ4< 1~ꇑFtK(Q"[;P( "}/lh=G#IqGW5M!F$ai`ZT}]daT\8$mwioiR[nkgKG\==}F0vJ`L %AF.;}hgը€#J=BB.ZĆ{]%H]+#Evj$m}%ӫ"F8pRF-$wȬ{ k#=R"3ik$&؞Z:և(2;JqkZd'-(}'L9{c[\<MMBq(icOmctP4o`k%/সyTGy$SvCfal!lӢ"ɪ5zopd&>-puWzXlU3&`/>EZWxJj|U4%RSꠈX"5Kga͎3\\ހY V#$4A`!q)~Yq(KE<*ݻBNxmjN8`_r zєo磇U">giHoh0M[ÿ&üHثj6ƥDuB\xHF^ޘ GHhxhkk"QHʠYU:3I@(Q$m+[1RX~L攎1~'YIav%I5)X5]K@IDATo:. ʸXu֮ɢ!g|̧_µcX:z!f ӿݎKH<`+SvyeO1ݫ5( 1|\IG"^R/ļIL6 5#'L]AX,R$=&z31#']kTa3qT!E?b >Oyv@o'Z?נK>gJAHG3ݨ\bNX-M^F@1q 5wO2+j.@ ն.$V!&S`L 0&`L 0&@E?:7`L 0&`L 0e=`U0A&3:s`L 0&5}"`Le& |@>wH51I~Hm~./ S:=*b>G@Q1S`L 0&5ײi#ܾGcAfP wcSgQO`v"_,^ R !1J8zwwK$Dl/׼r=SRnallCwq$~Y|`L 0&P[ŇL. 1zk+fC`Pm!~ 3ol;[b99(!G&PƆų:v Dztu2 ̋p8t!"u%׬ &~ XU*)I$*/AXS'o-0&`L&`8^$Ƞ..;9H-UAvt}=݆ l77g?ĜC.+%hzzFZ/4:<2u 1&^tnYȽWCA=z1Swf"7Blc\ BqFY٨M(9۠(-K@*Di021AYL 0&xY ф"\ 6Q¶x"|\,aբ)`C85"pMs}$\~=ͼo7I[[C!(jIׯ]9Th(!G&(_y[w{; 8B7g6lTR$\ں4qGOn 3$nņS0mvܦc .nV6RJ3*Ĉ_2W̘{N0u)&_s`L 0&KD@qd iI'wq~eҽQm 22pw@q)b> kQP^xiNmKr\`LF$l j6?Eq)t141$KW 22Y?;哟6IIQi_Cbߴ6L-"!e 2Yqش/]}m :C(M]m%`L 0 (WS2ey`L 0ifÒ,(z!VD)U6}F6h֌]=De=ٙ""+3cd+.1K[4jAцesa"Cl2Mc*oO[#L 0&`L (S0`Le#Ysգ"e}X+Y^׵ruBMM+e>yXlM1XF `L 0&2Ud&Pֈ[|*=Qg3}J9ɮj d_.(\O=O&_;{AwF^8tq&LdrczΘC"L>ªcH:==0'7zT{Qը~C{BF')-5${rQP j1xEx2gL 0&^^ffF( ?)nESa %(KG41DvMt{y_RM L GUpb,^ G%o{Wz|"}`X ai^m3+ˬ+Pz}@;&kp gH"C&LH\!E~q'ׂߐuDb=DƦ(σ!ncr˦?F 5v<˿>D33CZz {%bݹ5"M&- kޝ {u?J74,ЙZv&߁C+ܣ<1f8|"Ȟxul_O5 0b~L1ƲOtݰQ}b@ ӋC0#\]l ߙ0nAj.6Gq3 z9YoFj?}1,0}87&ud~>?D*I_G\F?/"u'0޷Ӈb",*A/p|-!ɧJ{35)nvZ,v64 ;aR>#'%rsbg>KQ~X?kd#^05{|;\'x =]J4-luCx;׊ձA][>ępIZ8elހUy'qV*3?rR?CTWW{O#7x5v]4zΕGPw (zd%'gl}M +2ae#0Qw6l).m{}Cs1xzx=">AҲaʹHזxKo ŗ6eJm9`L Ԍ=)kߴ8sf;tutO"pw@qCBdš+e%^ZlwA? qGz(_"ܿ-q*GWm߰ h*a)ԫq=\I˂iCX[!?s 00ohj.^.Q"B64 @D$~Y`j&|#j^05$~.Aޛko f-Afi4İ+h3t ήB5Bb}Ц=F8>:REK)F,r(={k ѷ)l~+6#fmPk V/+a5LNes%/+gF 1ߌ $ydn8wߵ6|d/86\a `p?'} $y.qۂ``wXhn BcB۸]9y&6(8`.&O cGN ɫq5|?(NFň|AF4V EV8l&&\4S;L5NԦ`XF) ՞xUnKgמۧ&`LVL:blXOCqn+K7rNWA䎽H.A,`nXJ2lBͥ/J/⨚@9R.4'Hqr%4*)1xFѠ^9o"/vƵ05@AAĄ֡!GLgzXL3Fc#74%֒NIQ1I),($7/o1ث r z3'7ѕEzjl_{ֵkzKM~W2_%Uw eNYq&Vh{C#`-nkBꠒJԤWuԮMB;uH+j֪R[UO91AoDqS\Gi( S̱:%H4x6}V݇:m $o &$odXnՉ!+q\^>G1OMTIȣGO -+kK׏1m _t3[gX&–/w36.9$[۽9eboؙOPK@ o)%ٴ =|MˆCM!'ĊAO!Z7UӈeQPX%Uַh 8V>ț:W'?yChҨ$Ofq,6XC81jhĐ>bQ~|v bY9#%.XnPvKaK"]tI,! ,OP;#pc(YP(hޔ.YB6PN$x=y<²2sT2]6eHCFsH&:-+mDyž$: wf~n頓TBNtGyTG$J-ߤ1 nK>|vKQ2+i\HgO@ߠlaf/w:@8-s>F۶p1sA~D4l2h#cg..=)3ވXx^n9{rh[|L)]gL 0&jH&xH7s3i q;cd۶A&e7澝U4fYN'NM6][qho63n?~@^W‹;+~f4ݨq^@_D{Pd<^>%NN%ӝ;wPDSjZ)ߏcb'7@,+CZEH^4м.JI+ {LF7/ P5 ETN/:Θ'Һ8R!`l[2nIX9eNҜ?SRoVU@l\xOJNIt*{ mIH-jPN%'5oj:SCD4{ J64PD ό2̡_Щ-]QhwEGVQ; зLq`(v> ydns5^`Sc2$!xunU5{¬FOzGQ5EŌʼ5&VoxӢsGbXaй8l% :&8B O߻Iي"jTZD , E0oBdqaFPvhL;32fv3G854pwLfBGxB}m_Q8vvbd=$$1_ԝk\֨N! UO$1z9j]Ehbq OIvŖu0lo'y:tكnZUѬvFL1YݍhN@sHM3u[0Z ) H:de7dB--ZOF׆#˸|]ᴎUU`L TN@ࢪQYMS"54#A*X"5Kga͎3'L؟wS*ܻ3^- 7#ԻOk,@rh$lE֎LfFYp\ aؤ i& #O Z~QQ!e:YQB7i;P?[@z|j՘nLЩ9#fi#™R%Hs4dFs"W|^wNb˫-ۣMSOY6KF[1yԷ_sTe-YkȈ;Z6yUZkR\qK;muFzB.NOiqU`)&oE`9(Y ?`zw%1}IG~t=F^9l&ZZ6=β#U]m#j|ӂX)6?KМ^&hn`Bw>ñqp'DE4XJk§=:aGk*MniH KF Nhq1f$ֿ LT N/겏b"#Gʈ)s;U.jSe}.A'hFa->MdZ5;% ]0jE%B6WϒvZD8#|m&Z[|dL 0&,<ɫrBeet*kQh+:i|\(""MI=faccHLJNǝ"v]j6mh(kK7֨olIh-L.d'5wi`͔bƤOhWӗD9#l"iӦ.̰ &L h.)KUoIזj/QD7:Q~ _e—ҳejUVUK[^|dL 0&FzGxq Fr3LOF@l{-BW_֐)?|.\|>g/4<rkqb4BCb[^h~y&`L 4  Yw]R'\Յtk=t=4 :ƦI}ԱvTk&_ޡ:W\h;RpOSwi $֍լ1#2\|Qx ņ9lF 2<&&`L <&Q+]EM;z025cO|=/1)ٺ,An@h m#b/SAs<^ŸCKL1s} :"Y"lX j_q򵨊u PX4$cՄQ?| q,dE_p:=dL$Dk8`L 0&`LE U:|0N.] 7%%HdP92GZ8N-Ա#(o0o6m,hzpK<_A 鯢B =ho!k0UjX٬3e%?!U"Y56._xşM /C_~"f*TޘA̵Ak3G!)pBVJ,KkȈ)K!l `L 0&`eԯEn}W@JMn]!v-pUxiߊI#_| Μ6CmHlbHXx<̠t7nt$.239f]b|G&Zb0rp,tE뿰ґs aȇb*w5 b<@QVd1va1pTxd&DoAԞy(BiQ ^5=GrFP-GL FT̄0k[APXXuAH%rj{Xo" 4l%k?sLy>n5梡LD}4tftw-<k_/XͲ͛"eػV<# 1R1߁QI2 #BĢ} \{#2yˈ^ `L 0&35eԯ~VP~}ѵ+t Zn6vxp!/zfvx+h[Ycctt~ov 8@\?-}z qjœ$ k8K^=]IG'&~X >hCU^}JV HjVMnakHϱ$X5Nb 6VLQ>, spUF:dBP1ZJplkJq9jU44b4N_*, Dy{IOXz.eV|iBՇyۮ0KC\h Iu;$A"C0U8ΉD(jm6M#pTj*^72^@ V2* ;Lͅā 0&`L 0&6ʝ!vϡ삎9IZ۴-ބÛڼ9"f&uםop]˻_GS(Ю~!~_BF'0s6m!*g*ңUf L AS[\ą-@~+U˃Lq ==PlĝPػQUyG9ȣ@;#/, 4{} 3x (8$KĀ=!Y OXHx, _"չJE`NHdsR9&Xٌ,?XMh*ډ^2A[THS)E][s`L 0&`L 0I 9YÈځ'~Q xFy#vjVI 3p9"_$i FTj՛gɷ$ {Ŝaz3Ѣ́Mm D!&h&+," I$HZťOJ$ɧG+m¤+kd&*%AFnQƜ(I kQЄlfh 9z/]ͳ:^=}LG#{XS1Ic&2Ȍ T3 &`L 0&2u y6gD_`T!r&< vƇ͑AZBx~ @he4]􌚡#yH?VhcF$$/=\xbaKaIjЏKOݺeZ8Pg2TŒ :gwbD+MXd.8dyX`_,miZX.[TTJ)b%.-j}*TcSSD>)^ BGIK hCXRJgg'`BH| RML`/R`{,߸Ju{0'qQ@]tYqvHSh`L 0&p-6B=8UK4[շ DLȾ!ȾB#RAהSq@Q[*ǥ֣9m{EbnRN&8͋fg,DŽO"wEN|W!ыx=M_Ka{.@k#C04A_e[x1 "D^D:KrXrr:q ^$V8l,YK>y%EfcLxlC1e7Cޢ5+xi t.ݻ{80&`L :/M[)#ŵ:t_HǸYiRM3-'&`ޒYSn# k˲L"27 8jV9b"]TYEtZWzu`e[m0g7ݮr/+%f_x^ ȹ<*LvA׉djR^1I;`Ԇu-6D$5`2hVV.Dڝi"8Z+exSPʏؓ >K$QcuKuB\x,ƨ^ޘ؋vy:pzjechRR^>X"tJ.c8UvNo'2p2tv;lf-`޺Ӫ5dA:]w%sxdcYp;]Jw1&yዱ9eڙpBD&P"|ͪJH0h+8[ODl?1$p*ԅZ5̕`L 0& 83yŅsТc;s }1Y{Yuow9Nm@61DHV6ɳbNaí 'VNh7cGS1ej`2i5iy4qQxꔏkı|\Фk4ݣ{666XmrJ[f6m.#hriꭱK;e.32hh:}HIљGͬۓr+E3Hao\Q3D\cX1#OǬC&_{O_6cH .}z7DBʑfXA#729N5ʂ/FLx1z|Rk{E0]JJJGߪ%%T[ؿn:hr3z3|ol8|fb= Ø/RF׶ź,m0&`L Xu ~mpiJl:퀉qčCAGLx6UI"yHšpܚ!ʬ{Gהf&7y!h=7k=u { +>o SN ޢPsmlH<4e:隸|\&]*.SY4MAB&(ryX=Z0x~AFήZHZMQ Q~FJU iqH6 G!Ǩ,e)>Cݹ2r yɑ:J0@ي;TUÌ^~#!W'Z/O3 ݄3n>f Djp$AؤUǎ>VRQbéf6M}X⒊ C ܱރuc4  F@7iQ?E607,¡ JlA`L 0&#0'xMK:1בmKIt)6DMHx8X E!l lu;`  /P(`JjBE$B0Vꘃ#c4mB Q3bD)!N ^PQ@%Azٰpg}>Ykg=+4=E=&=_=. `0';KU1iJ}#Zww ܍O+u-aZUޱhq_ kZAhgkOk:]*HVUe^5Nh~IV"2*gT+#3&#aΛt?E$KQ)Hg? ^ޣ'HMя)vr*lmO_n&Ķ?{`Lrpmq.+ I wȨ?ǘ`L 0&p0纹9 (ؓf^/h `V=W1[;X*i{`/8y#[ʒ~ m:3y %p6;$@Ī(XCLtœ䈊-Q0L@IDATĕ64^#HǖYعnܨYu=pkmTm+){Z̥~֒zkRfq_K u|`@aX[0gb GS"`vL01Zŭ #CD6@eMLazX4$x^ Qpldvzc/ i}fyÊ:_1ç+n<鞫av}v1L֖+VD!M`XD-J2űp~DT{ ̆ay!nv#}w0hщ,KWo9xbF:[t*K+ 3& Gb%S5xUxJ,6ו󀧰~3&PDܞ$yسy>Tc#=o"ts †q[Z@eel`kS3+I1fDLY`t.xOnFFF2}}2J.]hΖEi9\w7x-ڇ`̉zJbں]w~-Hi1S] w1li3[,`eJT>?zc=qRMϷ*ߏǾ}ҵ8u &;?^KmYpj4e$o dFhRFo3&C?^72l]#厅_dy VK*Ӽ*{bo !x` *Zl66m-aVl1ZsO{2h*n÷a62 =( `:Fw*ZGvIi}0|-N XMm3^e9ṅ-Dgښuk iNfCL.FiZJ/ƎFЦl;Ǜ~V6{*Sy_{@q^l[R {jKں )Qze'ؘC#uv0<u-:gRͫ(p _=U8NBc#qK,>N9MۦQ?X)Sˢű_qU(//Gu590&RlXZkR/H;SO> YŒvõ=ܻ #_4>Te #++ -)\1?f&/ {0]3d`f}_=4rGDaä i^c xNC_Ag}ޘн֘v|+kή=^}ATʹy<_{_zTP;^ u+I|=΋$~}}Bq˻@8.BHb|OËJmò5}F[{ 13CIr#}#!3Ax "t4Dԉ5E`'+ejY4;VUU%)`.]~ӧ<<<ЫW/t \7Z]ٝL <u"c |Eמ FyD<?k)둰6!c}`O/1Q߫ylfp ,ĦBK'ʎm0Y#,={Bՙ4;rZ~8WhK#2>%mL`aƇ*2>}i,X[W!$~c7}^Em9]11CeCLE$OD Fο : U!˚K/ '#~^O?ڪ`6np#%W$0t u_iۆ&CX5'ar3,,p s͏n|9g,1&#xڋAs5tNfd sb>&h0"ha4ሠAZݧx֭T59R}y4$D@FM rC{\cܞd[νQzD9>H0噈7g4jRcmn'l0hx%;vm_{vU+]K0?/Dg=)E Nڏ] C_`ΤIXYS±z,]r8oL_ 'aqP޻y=ұ=MgҢ1',V;uu fzagÊ%5At}Am WSC||u!q+Mt}1 =t|u-ڐ%]YF8`E/S+݄I[sw)v]NǫD:`}%t_:?= MH4{_=P;JWK:W|ѫ1>`ڢ@ؓ1sdm>kR+Cyغ yZ^fkR4ܝ*vIl a 1׮] ~:ty衇 x"9"} 5m9 0&h\ῡG95aoapoLK˼peoK5N5 &/SB1 8) b/Y??_I*H:"y!ܻTEz% B΅ܚݴaϤ}< Kk>.D FVL T*x 'ڭ:vIfLH)z 5z!v7 -=JySIL ϙcPihQ/1|kL(wSGj䳖0%?+A "b8!ߺv: w~ ?Br/>xxTz?cީyLUuO穰!S6-YKqbx.c|_Ѵ=gږ#{\_u΋.Н$Y@Grd%FbFR 70n-]y1o`?z^8-˗J5<-KtK'_*x3ЋEPO@O :F MzGU%1|I_/,Y|rm[ciL TMq!+dEhZrLAGVr=74ҋZR RBk7HOUҥyk]o24O zߒUp72}*?k?&UȈ}fcU(Yg{9TcZ넥PFB-bsD3 dMD /rκn?kDtldH{*@BrCzj*mg)Ns cu(Y3ܦ!F53Zrͯ!5sAU[ EPeRic;3TP\~)Y V3诡 _F^-]{YIBժ7|מ90x4 f ө"P%X))bzq&hAU)X RDq Q5v# evBF{T* OM4}}aJCRvMܮw]q+&s@_S"9Dg!|3uJ$],OBmg1e){Td$ ܗ SC0t{} #MCQS_v7i.EKx.d}lDNH)s ޾A_g4+{q3D8xs(;oah>jdȼ6snfڭ[$1 o$.KŸXk/ݼy^^^FY0ȣ~=xNiD)H+)bb"@ɥ ;ł^8D;tSg}lNzu_t*6Tj또٤)IGjsWsRK_N Θ>"mj"\CB4_hRh:ԑ]VT+{C|lU4H4НLjPv]jKr!j(sBz.Yzi9v&+ auPcq:Yh=_?zOt&r崲T5LM^S%_ݶˤܨ팺)=ϙl 'ό^08-{^ֿVVw5X1qO [3NPHZ\KgjzYzqHׅsB]uK6p.i /K̵t=]VԳ5HOM$FEOtC 1,{G-PuT߻ǾeǴv?6>s}9(9NQNعH cA̞=z]:*E8_֒]x)Aܺ\=_i5 h.;|ao^7#1[ܰ9( RFIqW C4h$%JR_p,3O<$M#"L 0f؆O ɡ W d hf u2PPl޽IIW{zcX[79 *%C}r+i2q~0>/EH١J]Io'.0_k- eǜ| HZ|_&muym g,a"ʤJb4)kk).=/ANq/ҋ}Ya)bnO!t`*w,550\^[Fda3ftrr_WI,xÌăۤ"G>XM̨7z|(7SYNGDȝǽBB^ㄓbOk# cx%IbL:{btb\[ک;7>;j{ȡ{ɱ3Uoj2ÓJ^{YQhA~8+^0ej6ވ8S}!:<{Z0w !:~"MIaQ=%O2 ɒ&=5 h!?l_>V*yPrZ;Rp*bKmtfj\,rU{o*PPKW{: X6Тe8E}L "|qEGP^@\ +&,11|fFN]:u7xP̋ތΓaY $2]i_>VH"z:lz ;NE}>܊^~ړک\Wa+`Ͱ4O[ZME~Y>B4+}#mĶ(;ʘtͫ0Kmb6`P*/vb-\Ijx[m ¡0Σ)Rqͬk15Sg-s#z{$|iiSTOnǔ14PCghGN Ϡh!C8]Qk# 䠌KiB?%Cy");Gno2M۲@u|_:^|:^}/a% &mLtWRu%΢Ev܌y45bQib-/)9.n\Nkݸ&Mk9Mq1q[%1P 8PZ1p+FFFZ4*9ºF2 }Nbٳg.\Ν;Ku[, <Td?Ǩ H[ O 0>^%f@V2*yGS[]WYxIeiF}ud[E!Pk'#zL9'xh^Czهs ?^\trr<JƕNS@~L7 Q5bTtܻSV3}IY! _j۞sQB<:$-NfMZɋ('Z7.Q-"_ʸ49Okt}M"Gʗۇ #3b$1IRaMǎCnn$@}YVRa/31 bXӣ>ZqNaL Đ011Pziԣi@n>ЋicCIAM)+  fVGWvFAx[zY!sz3XROUiRFυ]47(%t[G/Y>OW#g+91aO81Kgb?r>;*\R\#[#5=hSsrg|;'wο^Lf6tN/z BW<=:_*+A[Rz]]^cjÑ"wdѦcdLV* }eirXˋhGir\֍0"]^4-eP%/F1嵘ui…޽4 qIL{- 7|#}%ō6\I )9zJ1,J(jn_Ebdܺz)1Kp64a&$nWgX=2oIxP˖2-% :vɭ+8Fxȗ9a[ܑ )Mx\B`ꄂobC3q`L 0&p`KH~+,I4, _2bؑPȈE O<JN}EP1bC ")vbe|Y?O8,:o _>"Ibhg*1dӃ{lF(( L1IYKpnSZ%Nk0&td!j)-:ɷwm6Ozmu4O]QdoQD q2{')AT}'q) (uvC𧝧!+c? ,`QDN@MއRɝt~-=W! yL!?DrAz@l,+ALķB^6K]u}؉9&hL 0&`L 0&p`L}um۶I/B"3O=vu w -RkW{S*#ʊe֭HHH+mMLӷV -dT>T9 ,T.p5>kMGOiqxcbR"dD@Gʔ!ySUna?1eʻAÐoqm땛i9>T P_ /AjA R$^%0@\L俅-?j6hg /h#,+MkW.!/>oQO~>g!jŎI;;1p8O/sHʫZ))^!3DaXyH\<[h$&`|vP.[Ir 0&`L 0&IdN dŊѣM)h/͞$\z^ƈ.59O5:ҌMgΜ'mOܟ)MU^rG̷K._U-`jN8.H4[ئq#1SʍŦ"KXd}k5M:3>`/8cHnf.">cULڄtRzwx$R=39[, u[7}  `oOD$CUn=]|V¤%RSS` `J: F+›t6YFR|ۏTT!:!|^!{3#4u&"Nmjc˱x3ʅA~bL 0&`L 0{+e8t^}ń&Ka?UtP +pQZi±+clz'ӓ|Dn ~8xT',iV5h=Dњ?Z)6> ,B|^GIVx~E![ָd5'a9 Q^l!9u_rܮ*iϚqb;B2 j#OL*rAKByUy?h6)3{n$ E݁jTԽ;q'=^B~Ro{a%/XuU&`L 0&D/5p%CAL_B>S"** :Ջf('͆Ywbؽ{駟6$Rr*,3sȆg}/"꽙{ȺVԨ 22I@3FY"Ys`bd ݝiH:z9!IK^SpQ(ut$5A+:wS{Nsd%Tp`e~؇ TOLf/zBV&Qy &Nzȥ(XS:wmGi-E:PL 0&`L 6V4@LH666X~=YǼO/-*gLqTfKQVՏ猘Y_Drr2ƏoeCXo&q }ۘoK< & pj[SnuSdb şa=٠(G."v2XlʰUϚ2EagΜ2f/\hhԦIèh~: 'mW8Ep$5m۫*9 I2 KS1wR"BOn,ti^dX;5:S~W5]J3ɷrMf2e 5~xԹ'@i6*e-"fT>rhDQ٦Iν%, 煍:'MO/-L2;?VF@u%*bxYFK;bK6|uѤd+iCQjE"EoVѱ3PIGv{zkyl=>;h&4\G Q*0eٴBQQ|+Sx6P`L 0{@!xݞԡD ia<1#-p:m֥y1wCqpj/;(gXle=9=h8*q<%5ۼ <$G Qib-/ 9.VqZ7.\4Zą.Q6+%ٳgiIj*ELI77oF9?;5Pk׮Bk*G‚q#lIL2 =l*?~9vd7FYoý}1VAfIKP}Rd, F}kيy/{kv5F!0v-֤7buiU\j6+bFBNcL 0&p0wi8B1"+_a=#,H[(z7>]C?_0eN৒vxggz8U`J^4 AȧI\ L5Ç'ҖxSŧ?g-E.#=rWub[,"q嶜.Д7&inIH-}3 ;˗k z7n跷Ņrgܹ8~xkټx)z+S} ;1G0 ^=r uNŋȢ"N۹ lr͋'O6SXW} e\N*?wj3eW+aj3UÈ,fâ2"~F}ѸDѫh1ʂ , Z}/+mLh`Cdܒb ]|ihY?/ !L ,['/nxo' Ыm1)dr?_r%YV+ ANe8; J3{>"xɭ 0&Cy3iRmX+RF.HLY[^mqF UžMaN=U;JZQ72>/‚Liok4S.ʕ+5"uۭɸ")QQ:ݹkiEc5>d"y '5d.%?X\akF}1i#Ψ,WZI ʑxd>GH!SϠ@ GJMя)vR/Ӷi&Ķ?{`Lês{JCҩBǩ:2j/>#Lщ=u < LQ^.9m)dLVFE7䃍 $L5} IuIG/#LP}. kӤmSGFM&tn8vI.yp9akY  >_y0gآ9{6]g[Gj"ٗƄHZ~Sfr 0&? b;#ѨYI؀?70n-]y~4<,_*/3[^.h9i7K_ {UqhzFzaCΝ_W[P𸺺(eB-eGܚq],Ew .?@h`?7oM".᏶zWLONc1cM ^l#fL^TggL ]5i?Y&[F $@̲$0 6r2w)Y`T_j%q;Xt# Ba!0޿Gq@t^{RV##/JELIMVѰ?ff$^^`X+C'UdRY|FaR +,6l%+!sqpkurC;nݞl^  k3dbL.ȗĺL—L(:fL 0&qv7S=\YTٿ7zBWH;.]wC{qr@JkpE2qKñ" w2(XormONbg#r$|@vk9[U%L(eE(`tBcizzB#f[8Bf3SM|Ml{3-/1+uOUP ]tFy@ڏ%9xR–82-<]](^Ĵ׽,,! 2b[ȴ6ɫ<=f3sǣH;N"tپ<£s%_-ܞ?roF9ٗQ?_Ő3Nj5j32b?Ii#?|nkԽ} 2NjCGI$(h=4knT(N1:d`Ei4 -RhyJ3#t`L <\>ho-::|JAun_q v5.9}9liL 0&=G0mva:Qi pCY\;&KLʚ$U)桰< i@ +E(eֿ+n%ÙLNB]J+ס,YKH6(LA30x1]RKCb5SmѫG;CU~Y/{o ,AڒIC1W<~? RƺK Iri,u ^sbI2ޓL]@\Y@ ٗUC'|dsG]}*7o c˗ёuVɒTd w_r+qNIO-oo_UEaўŴ)7*鎢:iMj]jM6 ӢyY\C9fDriX<2Mx·V7WH֨сȳ]=}zSLms7`gΗj:rnҴMe&|P0@`u8=r%^3&`,|}Oj%PqXHv2YB)#1u}J|sB#tk"98=_k21hIAx|*M%۴\?RҴF7շ Lb.#,:{PI?v}'bD0/0Ш |_*#5OE0CR T"%'7\䩯@;YT EK^8s_[Rv lѩMx~f4l#JJ__IQdgmBo\/ܲTAE7o8Pr2t:-.i-і RYEGU.PӮ7iߖ+$U͂G\-=BC`VQI ${>XюTR>e'r$j @& 5`L 0&m"JF,B1#RFv,=ŸU#zԂ"l%5I/lUӠ1QHN^ F;#_tgA`L!Rijr+0B"Vo)LH[5 Ghki8H>H)pY.h:{L]4ϻڑEeT-1cgcOocfc'y1{[v_6쏃QK+,݅)HokmV* XdqI&`Lv0w,JnPmz`9F#,WRȈ~KvFcޢYv'2eN 9RXpj45?'u]IHX)'`L 0p(օ1^XE6,`e+ 4(: ^5sfn?XCH8j߫6m-aVBokW06AUQe˱-WgL 0&@nCJ^ 6&!o`qVnEGAJ7y5TIFjHlSNӶ)rO-Z41&D/;pg8Y겿E p{Ya 39|]+)Mժ2 (JW!{k8&/& cz#[v1EL0dD)|Ւ< |fƼq`-UPWSؾUOި݄)8cCPoi_$eaġh-l^=j!8s!]ogk^/pK M{+Ϲ/YQxaZB X pR'u@Ÿ:/xtO(. I}JIz907B(ew +1g0&`>q= ^~#m{^Tj vb4xa'WAJ'EF Už`}\z1'zvxN̖&2|&0&w:1i٢?(Q^v<??s)둰6!c}`ORcWȹU3GO8_َsbSz!B:,m(P1-9p=1Bՙ4;Z5_푒bud?^ Fο : 5V!_>H0噈Ma5QHJR#m=1X  G |6 "QrES%9GU`ᛗK,ژ=cUd$>}*8daaAv',JwӘ`L 0yL[{2f.ؓLv)/ @NgǿVRmIHMl# L1dO(!犵Az"@PSƙѾI .|rrNam*ű1mu«T|E**.cёWlMs 0&xXaXOԧ=~KSĒ;oܬ)5]e-iRs2kcķ9aN;O"zB1Ab:,`Li'@<}0W>7Aڵh5>ņ./@&O|mHlIĔ1nL+/6]\39I)A:_QOUpc|T?k&xcXy4xLG7_t z{yo|C*Ic;tW[͗2r`L 0&vvq? A9kQF 't .:XlS&lEƍDiHQVj abSIMG:u%`Li _|@w}2k -wK_C+?cP^)g#(yLɫϥF^L}y;eeooΜxFh4"'Cl(\ +-YBD:-7Wr ~Ӑ^:3{W:d,iHY/ܚ.ªR5C;aheˤGGd%"na](`|Wf^ EO\NÂa{VA=]f~*>hz#@j/WfAv wy CMch +ĖYu9Y!hk&'0jv 4 ʷ[r&`L 0&:th}!Xm,ʔCi#ʕ\:/!W_+R]C)uH('#I]f(rJ^9 qt^)yExQY)SY!0HE u:"5cqZ XF '㐔<ґ_\:km\ܴ rz ˤ{30yu NN):sҜs 2JUi<\`L 0*!,)%+ebZ):s"(u⬔,(3FEg eL 0&x <581&`L 0&`L U$<2d Ff xXcؔe]#gs`bT g1G"6Eq)*yK7 `oo#\F$䒀 0&`@~xՖ>)Dvns#,Ɗ#A<>~GӿuAc|!\{UԟDiоIJ˭13&`L#`<<\eO,Q=e W`ݮHEk00lMeE{0._ݡw'v`kMmRܾ2:b;qP}?%>΋뇖S>QeKbT֜+lpvL <,Q/;^)e?LV#)9 rw 3V#]՟7!A'jF>jx *Zf&U3 &`L .u#QץG5rr"vRBӋOh0e|{9.-G)U8g6`L 0ǁ@0Qf‷_kH>ۊ;Ґq2J`ϦM0mo #a+Gg0D}ʎů'ó+FyC̖ & (s? bMUaspv7dF(.:YC*\ͰR*u|vŪPA_Gg+܁ 0OʖЦP szQh]`%\SM`7;uȻ9 (>IIAI[_bIŦs$%A&+><>m|@0: A p$jeԆ{5W VG'O3ǾK/g?OxǟCax"\`L 0'}8&k3oyiR@RjA^f"߫oO!1iӇRl[ְ Lad""K(Z4}&S)$FW?uw|`fk}(H[s le Ck!c0}Crdž E/Rͼ{Zˉ 0&`2o+%͹_ˈ2W=KpgS[V,-YGL F1X%O"?[ڣ! o@|ů:Y1+_=0s̙e,t|-iP{7aZx ~S‹BX8|dB@Ǻt "QǴ,!9+:p I >BD0yh(x7#1&P4}1T uF't+$$ \^ƶ @I'hh d8iIRyrie|1d%90GY>$>T8Hmp\=d% \9L 0&x dƬ@@Kmbmiix9`fX$51f5~vs"433#ʨPQ&11 3l?.D@mv+BSx1$u߉CgHS]1ic|ѓc_nlb$n0obL ݗS51#|iG[OL ͮ@h@R qvG6p1 @-> M9 s<";14$ʢh<9SKa5]|Ƣ4oX. J'夜ȃ;o9J~%?ɑX `L 0&@^6re;p @f.DDp&Lo~k|xOx4lcۤX"mLJr$yڨlƒ׮W%E2H8'_&ZA='ͽ˷2LJYz0)*"ɂRWѭKsݽ-pν +{xSpZdbӢDBu=SdfJ(3'3%|6/f씚#3S ִ=.`L 0&@U`Q>i1a, nD6nZ=|He $Tކ)2&ރ @5_WajeWbz6/ҀsI1dI_J0V/5@s.zv lo+ݢU 9Kx'yInF\wvIVSMEUPJO_2!X\^vv F1yʘ{0X&`L 0&]=`w~u|mD6veoiWNmN\6H{ZzagprĐ0Ж52< Ik?XޮrFz_Hq g"&$oY\ Fsb@~l؀CdL 0&x(o7|ɾ#>BҮ{"Oތ# 2#\< Oؾw;_]]i)C)@$d7w|+R͇/>_>Ē%!fe9dܼ)Jŵ"̈v% `MRј`L 0&`P^)gC)y,DyLK6 JrVg7^rټy3]}_<@={=Y2e 6nxO}]c+8:69H 6u*2OnXQ5U sYV6*V\A(܊ 0&`L 0AСCChmT1ۃ㶁(S*Ws鼸HJ^}K tm V=;/︊3B\iذ!Ǝ[)ˋ/~qK|JoJA}E2$Ȩ˕vRc~aL 0&`L <8oK,ANN`cccsUVB&,$jec~;Օ(B_ t}9 J 5ٜuQ^#zU:+`L 0&xV(sСC0BXQgAxDh#*IqfNj٣McHe+(.rQQ:$)зǐoyv*u7}K](m] 4ʧ6V];]= q^&vY3b%q͂L1#1&`L 0BL;;;hՒ`Mmj4zOߍDZx2}tSbKΝ;w"55UjG[rK0>>>Ίj ǽcٳp{WQdA#U&,7Sbx V|Ex% ɯ'a[XTZoOף/򂥈z3 &!4uܸk${Dw~EWYiH({έ :I\5~>ѹDV}+ O$1T\w38V}*թ!4}_Џh.rw8zĻbrZU_2E;t|,DA8ܮ4[M9Y7.!)6sãK4r?C=\bm 3W Aϒm\{x )Q^;_ظgÕ;♺N 1TS~Y&`L #Ю?u7g‚X.06FHY1ߝ>7% 3Ce·T.:/q |Sb {T]ˌ.eرcN:%"/Ԟ5 ջ)IYmv_ixX珃 kY!4vQ)jgw`ņ1|mXv8/yVʏE_I#3 G&-=^zOQ_Iܓg$ 7N{@` ]DŽK *2|vEPXEAc{PP,.bl.=,&)>Xd]ƂXD;1sB$[ko|`L$'  8h.cl}يK㙒.»w NQQv,~=q)`$"a2vJYUBY-AYニ=rv'AT4%.-m"o_ \||[agL\DoVʦZxQU؀Q'/ʄPcۙ"Xڒ2zps +Y6ߍ^) 9vnwω <6e}i1}Iڅc yJl\6=`K_C3) S'LŚL8 7sjK, p#om[: H hlD>hJWMھ=bԕH7oֽU&c\GQwu'Om$}cI%f^>]]9W۠5zUA0uv[Ť@?ɼ }FNb 3PS s/í) uw:s>$xۥL$-rj><po{boJ>%EN%-qc:?Gm)svb-c7?&_3&`B FL-}$Iߵ4øJy ܲ):c7_;>/" yXZȟsLaf"fK*X=rةƌqR;-,(XӡۊX3PTVsZhIjI>p_x/b3m=P%4LrWlތ#p69RbX:# :85d1v@_ˈH¨'xzz1~򻴣&/,^b-#&͛qIfhC( l?^?cܲűfTq@+揑$'60lj <9Idg'Q}'`t4hf!' ,G$LRiZ(I>!Kt/Iٕ@ȮNt )1?q!q;jĮ'&`(MG6yFEՊHǤ)A,RkL”)r%3{OL|#zƜnÌٳ13p1 L`mӯq203XĢLoz+hQ92h6F*.K YY#R?oՀX?ۇP1{Xw%1f3&{Ÿq(ʜs"y4{g/yeMюOK)p0wMG)~d5:[g!⿟I^A MtsF}%jv#_*Cc#qag/єL֍FVc%'׌ZpZޒ} <*Ihً1*yU\@IDATQхl=tyœs,Y_X>*6K6/ߖSS+"ދOImqM*i1bHIv*JH˥`iI$4bX%E?Ib.]! ^%A*Id.QiБ8Ǭ#-:X#:M3&`'`I{!9?Bnxpw&WrRfMQ6~pk@-"#Ο鐾/Z 8ڸwɫS13k5T2-[JNV)ƾpB1^u_>}JΆc`F1D/KRUgzhHjhY)NTm"fB8R ~Fdc2ƍ%gtO9X>e8k!YДP :l(u9tH_EBUSB? 8[0]8RbKՁLq @<}0WAkעEd* ٲpb֢G dȮE˟A5%4hFeD>3c1 ɼT^rq3Ҟ{9WiMKI 6#vʒIˢ}iYH/{3޶?`(9z—$~sdHߝZj6&̙AaMk2֌2ޤ"B[2cUT*$/ˆ0ߋUΡ")*fWL 0&@Q_̼(Ư4~ELbɇǣ=KpgS0[VuĴ`[I4{K{򱗍&)7 QWD$Tcͣo+!JAred"l)AFՒU}dc?(/az؊b2av$6F[Θl-z4Hlwih8'[h4=~ ڐ~Z-l鎵A>oFmBWƾSh>|.{8AcA_R,,DE_ H0vb`*GR󽛩s43c=aģX%,-u:M:Vס sTamH9kś$,|I1]eLOl?( Zn_1譻o晈HV#76*R~bݽm= xdc8IjBzDP_9PyhWlB-a٣ Rm-i?[L 0&a1+PXS(3VnB_d :L7#tn@53bYh(B-F'i_@gWg=ߤIGQn8>"gΓ~l  6bHCN8m>\LXiY{`֪z8YG耭59f&¸XD+ٻÂeexy, &D–!\NX_B#ӫ.=έRG=؈}0fhD6ȇ]6 w_NÂοMP/J $bu[|{}kꤻL -axI34R5?d{h݋\4w_|3)sV|VspL&Ue$d#6ÿpQG1?ƖoKK6ŗIkش"NWqw[ޜeL 0&yHS"? }sQ1 Q+eb(%S)ytވڋ2"/YۯD$v (-6… nM 04.4NʋiU1K>bi+hLgO!)])/y%kH7^CuT^璦r-wrjJAjIX+l=  9^5pcgKAV CBFW{4͙`L 0&\,<Ϝ 0& q`L 0&P?`L 0&`L 0&2e2p 0&`L 0&`2s`L 0&`L 0G@EGdL 0&`L 0&23`L 0&`L 0G@EGdL <14h̞D`L 0&D~-+`LBLи>7Kbf0ݘÕ+(*O׊Pdb&0Tk ,pod˩Ǒal-ޯ,TAAE}`O!MrIJM+yi;!7#{MH0jF>jx ͪa>jV*`L 0&4&,> b#R,G{MwKۣM}ٴbP`?TxL_>V}/odehKdX)/`L {O(>AlCTxW#A; @AjbPm13 26jSεEN ;&{>s:`Pac >d/ՠ(J&`L <^rni8Dsu6b)Vyɒbf&V sꎆq- 2z*e3,ʔe%L 0g- WḾ1(,4G.N2%4m0b؛GE5wMsQ}2ޓ0&Œ?MKHHKLV|Vx}|Ž/ Á=at, [)v1H˨ =9j",@jĤ>:yQ}8]z=ys?$?DucL 0&yir"roJ nQb"w_Qg/yb~)KlC.aL 0g@df-L(8HFV=`N+r[(j} ܸqKwÅ][p55ku{(I22If2cLP & x֥SHIOfoa.5FtOfvzY( lvAvIO|fL 0&SNͼEYXv1`s7k|vۥ!id&O9{=eVjjAf5jԀ8{9ܹsG:D۷oK"o,!SevJnҷ}E?LI#D==F&Ƶh\pdh+kc Եlv bOjza2K)E~#fօ$/TyP\E$Ԕ)Z(-v>L M eYTHB<I6ʋ/((99zQ^fMIhy^,-0BQwa 0& ޏ8 aj/ >f/'#%5inΗ'ZȂGC`:h锵^6.?zqH'd*Ú DH"tNk&/#NL 0&x ϬBJ޹}ؒX,YgҪZdD2-,, Vge=iEBLQbQ<] 'K,Ė>@`-Ċ][K6wPLJv0ٻ9GjZvDV(6\ sghr (g#6=w'?+8|HDuۮឹ{2]iU˿5`L 0F 3vbKXku.;-K+fpX)"!_9sFZԋ:qܹS˒ի ?ʔW57nܐg rwrrQef*]xKn \43 ڹ9`vB ~LR쎞m%c441ARQо0S.¹## DiHS$%%a,2aaa޽;ߏoBh9s&z={ <<#hcʔ)M,dX0͛CբVZF˖-qM 6 Νٳ7HmļH5]2&Yz0!oAi!PWѭKsݽ<}4<(-Wh/^Z';;;/(g[fL T=ţ`L 0&,ʔz/ # /bҹs1+WYudxִ|ɘ>GfD$yrߥ|ZZ:Ξ=6m^׏xXINNX~#ZzDPl\v ֭GF "Л `L Tl$H0@ `L 0&,ʨAF9D@hG*yC:hAbO"ɹ"[$4lhM˙^8u* -eF oڔ___r%p?2EF, #'_DF NpkGu8ݎuۏJ1nOw&Dn_*b$B4Q[&$'nR`|TU&O}a67O#~L /tƎPxIS X471X쫫p_EȲMR]rRb;_+_GUU7%%jI,bW&b|TmkJU%@p @<ϔya6&L 0&`L 0GM@cm;kͣ1>{덗qǨkHRՠݗHz!) —E*WwW!%:W]H5+]  fHIXU#ۣW_/J=[ؠ-tMN<+u5 s#.ĂYph&o4ZǬEFTo EB/_̈0(iAWB.0 CTc* +{)*]DC;"* .?'aPX_: ,IEx hVh7#NGǘ85G[c5X6B׷/ȟqU0Yh3 uYiM Xꈳganv-ÃcQǥEmWq֭c&%ŗ-䫻cFD阰$>[6 }Җps.{xl7m,d ܸH .1kkI"tft-|lsTH>Ƶ8Au2v/'_H5_5=2&`O;7񀍹Rcc!gLR+bJe1G [),Ą.@LZ\"`Q8l^0&M?;$=")$(jmJbI ܠ$/%Hr^+"+"KDz$lR0@K=ؒ]-) .^L䊐ѶpPh$oQBo#Q":X9*6;FF6k'yBOtx5.].E˔uE:KSn|Z7+G+ߑ_/G̉IILk+ŔBV4g8NL5'ͽAL6l&aF:>64gץ]ΐ_O;@IMlJ >ܱwEB%pT<֌CEy 쉲}ݞ~g+F&<=۠&$& gՄ[p7L4 BSK>ϲ( FԹ|_D#Ss!u>_t@_@V~.]̽˃`L 0&0s)>PBK<\+mgPdb&0Tk ,pod˩Ǒal-ޯ,9JK{ݟ5.7wWjܦ=cBB1$D3lB47\D[p*nxp't-{$aFXtJ >܈F$ӹ?$cXC UU8 ?h:z38wnxD煼XTv߄@65Q 7xGY0I;IcM:NFˋwhmm_R% 8/QNhy:e&D k?dD)ϕ|ʝ|!^Np J WA\HRWE+G25둼a #\DZ~͚hMR= vCAo R/ -Sbf2xLì"mu A&kbx~.O4hQ;#znvu(yUŃ}t+o!Q4ן舏Y WlKހ%!޽-XC]ѢrnXЉZĚ fG-ہ]3"JM®Msxſ#u8qw1|+G=IWߩ]?V$Ḛ ]XH1aEֶuB.D)u&)AaYcۺCvEi9jnEeG0;7a3p*;D-G1boАQ<1d'{f'<ފϚgk$]G AHKq01 hϗCH$̝UVNS7F.m{ L .~aʿ Mg{}1YU0K;zohS;3nֻ @bb֠@d$zB<%Oz!{)XoB3ɬ .gGioo>! ī3 8ܫydDΈAk_X@_e~>ᣯ`)-|LŐzGu4ϠqYesHOlY}e1CH$DeSw@< Q&m×O)? c{b !ˌHR@D.dh,"9cpW7R ~I/ YJblISVB/8bD_4z[(q[/9{0u|M 3*qf{SA4Lo_?<G|̈́bi>`tvg`ϙ=xwHScqF/ć>Vjub#䊈w̞UQ+2͒+$,?eoJB3V% o<Ŝc׈o͸t}]/);{cnDWx>mDCia8SMQ>=Xoe? #DƶXe-x=zǂ0Y22.]ĥb+/D̈v2^(Y5N}wŘ5DV4?8 {1~!Sd$]P@?KZ5/~QT|=ƱUS0/>)шM$KӁD)' Ve$r-i9Pܟ%kga14.}B0l`;d-> &cKE=`ڱ<F06Y. x <+)[Saksyy5rvcD`te}{" /)NǬaS6>sm\Euba*}Oϵ^>(sV@~ >a5aJ.—{.Fma.p/\b+<S\aYyR$^4> 2{i̛8kK&>ي& e?M싸yԗXvds05wfthj&G0Ւ[4a {Ǧl1@vPk'nR葀KM#,anM)40K!neSy?l D-f@u*SXtdKIͤ+W,R/ijsq.8<.W>dDkVg+ʟhT5ߜlmd!/ 1mN f7g2q{} w-j(S7`̓C6Oi a։{fFDD%Z8J2Yi"n-WR&\D"~j4&ߋl{h4>8i:8c#玢 m_j~cbRX4>19Žmu/ ^c[i935+ o~Y^~!)˩#S&VΙ25}rImwWɺ+/< =iDM Ln!MHԈT[̟Kډ- ĈL0"A۪ܰ#24kR>6ӹ*W1}1M J֡-|)'"<}A6.KF[c5ԛ) kx-A}15f=ZFaBs)2KK+AcAw$|jX&}2=t ]^?[C,?a*1>;eEƪ[1fT|=mOby-FIuatǔaD] s[=s>SV bD@" H~8p@:MNMy˽ț6S8rSr_5/&)oyl*WXVfnm26F\$ Hms0؊m|"Ԋ|E_BMO9 uN4om1DYN}a]Js=$UR`kf}WUh$D@" 8{z5T6(]aT.1K>C;P`{":%65lsb‘8^4 [yo : ^#S@<P A," jw`[Xð"\^6$ý ļcQG۶ĔǴ0fi)V-|zc z? o!q3+?cG/7M(0clo~Ed;\+=Hp{/b-({ +ؘ˽+3X9-$^hއ/0Bfwaw ˓1G@02]"ӹ$H$D@" 0!۽-? 4:(RI8׳^ rU")c+d  (᰷29aI^GY1WrƎѝB.ey:S6:<*W0'ǯKgETPp 4jMӸ8|sogGڹ%V~_PHXqYF;88h2Ve!g/apQ Y7=M<Ι"EMh2UND;KBWqµѡ#m6{!2caR"Ԥ)_Z(!#RE~g&(d`r yEDN$_(RنHK$Htp2Cgoذ]GQIteڣ8'*Al@.58bl{-l`o&{wŇ+Ѡ"$&̚Ckg?6]O˛!b΁ϦI yJ-vU{= 6.3\@\"|xS倔̣PX" H$D@" H$wImGw+ M$W!OHؒQH3`bo)#@iĽHA~)T_IG: rf XXې;\C͂I߅PXw9#axKA ͗Ro=:Ę:AmS]L΍Y-{_NU-3 4c@BMq, NMʽD@" H$D@" HjB@2Dj&;L1 `זċ\ad& vE^aMEl #D޴7Ԛ>+ T>oH0:ͥt>uO?G9X C<*,U4_jnNEJ[Q# JRUe94i w*%S{:4MjזdH͔B& ЅG#+S3H$D@" H$]C y 4J@IDAT,hAȑZW$U9~U[ZʷGDPK6ߵ,^ rS/Qx:~<4Pr_ :_[˧bպC|q$ڳikKIw!OeE&.'1! sĤi/ϏH~bBo/|d;^:FΡ$D@" H$D@"!`RˍOg2nb'Ǭ)y3eVJUf[=}mXϾjQ!૙@+"dا!|()T_ 2ֽ#nCN?m<Pښb5§-Ǧc!Gf3o]g|uB'/YH㎩نEo#9oO&@8iqeH$D@" Hn;5hXdeLMiʛ7}<*e:7YE^TT$J(z8,`, dS4dl̝NQa-2'H$D@"p!Fs7ƹL/9WP3 6ף%r(ܦ:Sr_5/&)oyl*WXVfpa.2~TS2!oj]UZQVe;:kY'7?܀riOXyeBF=4.J7*$d PxEHno~5tj̿Ө-JS;Qp(acy 1biu*$K!)cbv,ܑ+ޘk_ǻo ,:vZv'oLNRD@" H$mB0aTZp6i)V&{%o c,[Izd~荵[W<5}|DHZQ<9|0΋/ VTW:Onگ%deT^[ߪty y-Qj6>]?_7ʿ7!g%owFHltވE(>#FON%صvdWr1}+(i0ס*%˱ϲַ MPd^0h[Ҟܔ*`9ѰVY/H$DC)p( ژ :B!dcgj'8)DKסQxM6.^mr{#!#io}2`_"=]$exEO/<Q' 6N['TnMƽ_v k랦t#B"p? h%3IHPcFo*f#$ :7êjɉT/J2bw_DkT %c4ʪ6S! !IԙXCeH$D@"kE7loН,Ԭ[b-̷PAe$Z= R`TiXCM2>]7Gk{\>%#9I l)íLK 6t{#H^iWHFXyD@"p7K| Au7ڏqШ:v&B;IwUR$dN~::d8yb>Lv=woTCx;ż Kpj?ow@cϿkca!14L*ڹq_9JU㈑):./-=]" H$_[s|LlEB4-xd.&6&gLV|AKek?SP!*s1v6T#ֲFhW!AʘeTVFBF$QhPN2&^" pA@\Kӹ[x:rʫ/2}$d4=GS%Et@cN*(8 aOS;A47EHJg 䇎D uld*VLKFtW%pD^AYxa v|^FFGؼO@G1*kXKe:ν Q 6"ƴᕟ 4D@" H~Sxc3ApA>v̛d0ޡQgC'g!D!;Џm]0uj85%7[$eIQFJ/AE W"_0%*@#Ai_PP'---UDțSFMvvvJ^e^&D@"pW;@_t׮0sCcVX{0ǎ C8z*lv ې)N71I<@8pXL3抿 ąNZ;%+M(3-EW*Kғ$ITJH$D@"C`gzұRt{CYcQ~h߮%;5`.| x% C\xwBQ~*^ L=!Il*eD Q"HB\}Y#HA渐=䋩\7nm^h8::*Dg仦Ӗ$M!PrHM|ڽ)&At:{ FW,;pKrMA Dȝ)‘]܎t6C_F1~e 2|[76l4Ng_1ٷqqe:ʽD@" H$_):eޙXQ^Ok4G~1n=e+ofP)V>zܹ|eheΌW6ud|}}aQ!hx}Cr˹_BX:$k3nYtNZ?{ qGAxcȑP[2VǻBx\,m.]ͷ*֥7}~o 6A*x˻sr(ӹ%dJ5k '߇`j9e9܌ ͲÕ: ,KZ X%$3.|0ud%WZG~k+HUQ"QEA2EYDZ3‚(<զ)ut%{GL qqn.͕$ } *6*`KbaT2 6vPآL!VHBU2θz4bk;M:۪ =w}"Nߎ: cG7*gg\i_/$Hfhx _xGmO+$d,EƷؽg"A?7pDÛLήp3ߤnOBR YKUܫ%/!#Ы0O]5]]r{H.?|c_ŬwFë)Y=%zRq 2 W1EwHNq$eIPmt(T`箁m ~aɒr$ee4GDL!ْ0q /sgKrBMT*5%$eʊq7bށpm.ݺsw?\/CG99pk '6xǑ&^mÛ8[(&LDAhFi?5272?k1j򡉎O23by'L<8~B|Ekm(@. Aga"8jD>c:"qv(Q+hZ#reao!V$Bӝ0l^8HxiF`0srO&a+''ylcwV س F>GaS.{,цn%:ú. ]uɘ:8&#/<͘%)kF;㇫-ϝYl;{y.@t&-{]вne!jӀLCׯa8ko1F)5}~;?ӑ}!V^c1kLi0 뗽 ?âp69æ@_K B5g㸅0Pem~̍Ī<.ꚓ"u EjHi739fL=OY6-ЅHXR ؿaPܘt)qTRm׏X΁X\s6?lM";Ә1,"Su0eda$چ-w}G1w_7Р:NTH$w[s|L@ktYat;c\蝗1^m :UcdfЙ/u ;5qܚGѼhDZ{?BK5^Q 5v7m8.5?ػ}41ل|9m;@*(ܱc/žL N@( {Ni` wD?>g<,k$`Qd&/ ⯋[ZvR4#!wKgL5'h>ѻ$|IG%ogUc|,a0u9{ardJ.#cSúg{1pSsF N5F2\ѡkʚxa{Sk< `(=C"=u1Rx~ercP{>#lԩ=ڵ7^ԘX ML_>,'$x^izg`r-yde .~1tS]shwxΒ;sxur1+=p ') t"| l$d3!'E3z/b U6FU>JN /wFjb&3B$*NQk,=㵜=̋?Br2}1Lٚo9jR =HIIC+9T\o5caPy6E9,KF X|4hrkѲ_%O.5q0\<2J2ajxgDz #q L;\<8:#/-#ϖȼD@" eƀgۛ!wh&R Y-qc[:oSv,n+SHRet[|ȻQnKƑdHMqLs-alPJԬa{(eHШI܉JK-D͐i$ɖ#HLm7E ťahS7 h6m[CAK3I" }iЍ_מrR0kx4H eO"tJQwÛUEO!7E]\o7!j=G݇ -$[BbޑVmUvijcg}CFoW-~wβ+۾7eA JaF/ k]9OEP60 /@bdeW Ve&㹧Iϑ4@|Q_Zm7kn 䈑1_c|jY+y67.ʪif'\Bj_ˎk?%/@sBސOKUZ2T8R אfqsj, FLL5C\i!6)D$p&vyJJs"t[VY^ǦX9JSAbQ($/D?*`ʼD@" 1 ĥcԲ"2Sv-ة݁K?_,>TN.BQ~Nd/5Bַo=m 4bSGĊ;"i^T)c|ޗntIc[{5lI\;ggA2%[#wd'q/IZ-<O? y&LР%bxzO *$@q뼀0ҿsׯGnjoZm'֌<礥`ɔJEgH n޾Ҭ;$Y÷ip57cch_QnN/t7 jO4٘LB&&çx )5( H hb }f_Up PgT1Т Me8o1 0 j2 `!?h)ZM[W-m8q$aܸix]k WhӞ>&.eyWNO+1OAl=jHXYH;u.YBΦGeyͩrK+GR8o\Uo3de4DB&'S'j=T&V41'>?v6sx,I3u2S8z2,`h4&/1sgag8ſudD@" ( X$D 0 T|`l:08܌Vؙ̫t L+AkI!{*#*4v\hУc6ϡw| =|=AO>jvM@SnImipa>ܠ2'g\LKCKRRӗ }օK~jsoq~> kaթlX/4qdH$ B` .A | 3sz"#AA$i",<4HGɹde1phҡi˗'黾e}";ߘ@kޘXŽmJaߠzԕ}[֍FQQؤܚos+I}U.@oMd8j)ď&nb"UYx)ے/b #xs0`jd `|z[|׹qش3 ~qaRSb`d|+lc0z4(*][ȸIHݵ|rh-x #M<5eD@" Sd&ӱ22D9ϙKW ..KN;71s8uۏq(`djsVVȨ9"P!mvQ|##_COU~HLwpC#88;ўJjgFVQYeq#K FlC4jRрmmh椧#JVD#(i#䏈zsdi8߰ȧ7eeuJ$-xunH?1Šb!&jI}1M_""ͫӅ?&ekoYц%#f1rH6 &nꋩ12x!I yT$EC('Ǣ020W 5h3&H>kPk46,fZLY詡x/Af"xt=c*B&UA"!40_ =D UUX<8+"YI/JPUֱdԆƠ Q}0:֯i]QڦIt1YCFk6~AS{d'f_ w^cce6X5kb6\úCf| cրpߺcK0oӫh,:̹kނ3?2^KiƘycUrGՏiqdUM3c}h*t8b(;c"vV3~ƷҌp}Gb1 ~sqGD!ct|JA5" Օ,7i򦽭E)oW(Le{=}}}qM69 <؜j(MPF-cQHb+FE"ELXԗ3'EDF~dwƁHM0-J lx0.eؖeK~fFxt-}T*b)~Lۍt =ZQ/3±J9ky)ˌD@"P 58dMz?Ԍ qNEU‰eXC &JY>dReݞO3y:hhn<t/|5Z>:_ޚpE^wDzVZiH$wxBSE -{QfLuOrSr_5/&)oyl*WXVf2 nK'41j냢<-#}^P)Da-xGHgNڜo˚]kJ^ǵ[]Tkt'#&TeD@" JK_HQɖ^l~^™#Q+1hרP*#aSCrk0=n5 xde%psǃ=qa|:LZ2bOݥݘ8hŬW{{G #bD@" u!(@0 lQPߋsEJ$D@"pHRFe(ϿrmmlR3T5ɐSg٢wnnDV$bQ`z\7ASA<)-(vpAi{77: liԤiS8Fi4حՋq8%Ҥ+.c9e9ͩn.#a]5d$dXCBGeǩ _yxg.z`&7}KhaOvt&C-DHF}[|hpDu}@i|vǔq07;w3x(@Rƞo)NŞ aʘkfML')cXYŐ2'H$D@" H${I ٨laKDO܊5cJm8{H9tzjʐ)S]C#ac#LlMFai })$XK)]}`H(.Waff^-Ǒ{~kH6a=h9O-!K*AEI6i*\"kgTI2""]5& S{,Yi|hIo7ƨXYwPEksʮa8Kj"ہC+C 5qq;#Ҕp~Ix$H$D@" H'$)ó-(/ *e,м2XUӔ UԬ;$]hdcD0|,#fj\ނR8\`#|؊Kங2wpDN3/7ߠV \yS89>m;=лIGV|^<6B jGxxngHΔ~-v-+=º>ØO;Tpfl/Fh=ݻӴ l^hK6芦 ո "S6mI0Bɿ#k7e97*@dHX8=C5ceù`Sptļ CG$j3dc#g:Q Ͽe p)B8iϐ($ፓk!ELƴSue/Q#eH$D@" H$ RSgДKqW1G)C9͖Ԡ*-%&GRó]Z{!1p<a޷TUm?*GE%L ,Lp )W2|gHcP(:}Ȥf[ fx/ wه\Ь&[K{u_Ϻ콞w=QQ`gnkr1ΔtR*XmJ\/$}u52E. ɘ~EmIW&TO>f {Z {Q̓!x'uMx~=ſG)u+v[%¢{>J|>*Ez r\LƘ;&q(?@ ħ\to@@lYċ `Rϟ3|U^gɭL&tE" H$D@"  [יE'ww8yxݓzL\_jAEOLrR˥|UR*(o]wQrqQ,Rr(\q;-iUZb wFV^%s.©2:͔'k>wی<) T^֮deC|Xwl_NarYL1l!<|(өyOb5#NA3l7W߀!#' GYsE̗EVHO->Gi$D@" H$$ed%J8y֢ :7y5PPTBR*nwJ0JYhjQCƙ+nP' gPƯZkiF9Aps+;s0 wap~k#q/ Rxm51·K-N|O(BȀɈ6n24E[ơһ ( gB{Hg?^3xgqۯ4@ zGד +H$DC}&D rN.ީ0 m"7#$ogA@K^zCX~K0M)I68}I9_]0vD*=Pׄq{SU5 BrL35iД0՚J\99#<4Np+}b%^͝*髱1Aԥj܅L J7qk2lbxNeOЗMeoı<ּIy0j8s?i(`,\[P5{n>WcؖmήaCV gK9lLZ}QnSiJQSݬZx!m/̘9b z=㵕}VK7D@" H$2!BLh >Z!d*`G<~ܽO!Z#`â8aɏaBF80}=ZspyIʰuHR9'i|s>I_nMjjJpSطtR2S[mG!# @IDATŨ)LWT{PLSRRzf\^-L_)cN]xO_<; Щ &vï4r\>c>RJBP&V:dČ'#E8i~[F㹁Q^R 73.?sHW߅c"Gߪ\'cHXsbA'Zv^T'^$dJukrF{7 Y !H$DvpdQM _8e%2Ⱥ;`]6P\5P#f@g!AyDJؖh SJNFAIgJԑs+V9yً*\9DqK 9sKʨ{F4TÞߧELxDFQH7&̅Ga@ ~:>قA Ova-ЈOqmMIߖ3>k[ۑH]$TظXH}tgO@TM0+Hŋke0MLꎝo")ÐƀS1!$&j"v ?jfJOļI8ftSfb^ŒsP.8 ¥ r#x Щ;pvg  Ópa'^z xj oeQ%63Cx,G7\d91eR`)6oHCzۊ H+WU0a V~)6䇣tVheJn;3Ob 0GHS9U^͵?| d ^ı4&W[Mg&״U KJS F+Z4]d%Aqw#Yfz?"QWɒp!RGqjyndߵ+N}~U<{5Odҕ_A#p=hE;R=QIi+J8yy(2qaqvOG) S{A|dzfFN*Q#Ia r0޵J$4`mḠ 0m@Tb\f*QHel:fJdQw큘F%zSL$!4u2ݩZ 7UKr!$j:u$'2mi\P+c?LM)$2x9͗fm[ 1=l,r~6jAXbçVՄY0](<oDuWD@" H$ |4sA& 2S"ذ>De2z( 騜 \ݲfO ӡOZdRV4|c )#tTSykh ۣ O\{ÏI JWQ%.[PEXOɉ:h(1#N]ۏjH<أ+z>⧿prQNfY>J->U q슢Ej rbiܷ8+o~NkTSJF5]BhGqYsclS=׃~OU+[N&FǦWٲї[z3q{T>l,D)}?oAٝ‹Z[N}Wl$‡=}T?W>%Bkv$v#.&[謱UX8i)M%&Ճ@4uWܫD5BLbZD) a5h;  1I5k xwD E1Uaɴȷ]LG@ҵ%(X (kMSr`rdg!*pͮTl؟mc'AP{dx%vTSZƷIsӥ+ZU1E%D@" vO< k`gůdwg5qIuy\g7?Oot^U_XOc Qzmiכ @t O^ңJ*<*׌/[hx 2.5$ũ-g/|\o NY(C >NܲQmOQʦ5ܒ$i"uKӥ\C>M :Ʃ"D5\_?s9XMQdL8Xc<҉rvX)uׅDUJ ôm{ tL!y ]r7^MMxe^͠>Nw4'-N cF^:]94 @ ضF-!ܻt-0꫸Qgӣ&S^T=;~! v(.F3%a I3Мlx{SVݞkr8jL_,W{IX2 Լ#bF3|PBO-C'%mL;A#=cop 'rN4a"&LG6z 1xdc~XZ6ON* S2>X#:u#YZ$D@" oSܜIG_#c &0Rr. lVnV w5-5(ی7ˆ&̡R``ҷ=LA,/l5.GWJWӥJ{-:J<ǓFPARsJŝ'%yipE,X*6Cz)ԻR-ΏVM\p#G{=8> y=TYL޾l #OG>mL:e EIP?-koZ+Nf!H$D1LCCt,z9ԴG o7 @ ͫ{\6wPyT1WPwC(}B2F=\\q ˪xL5yP I7w'TZI22.y'f(ԣeL9_Eӆ$)C1xq߭yv2<'.]2h }y)T!ik25QwKbu1F^'{aBG1o6_5=|M).=:wgl'~GJ&^kc$EIMx1Y2/|!(2,v<2P-ǐy=Yj/NU^vjRxkI@j1NZ$p\)6nPP!N~ɸ߰ 2^K'1]x'a)NStxq@xY+qJ5!O ZHε:U;a"uSMʤ[xEK uvT\vD@" H$Q|]u:$e8;9 ΄ =jJs[Zqq!ަ^<ێN],3ʯ֡ ]^N<Չ8d |nm*-Ij[9AU:sSβxh''+IޔS  *N*!/0p>aػ|N=ʣzf`7~E1=)OR0Oңxzd'oDpRV鄸эBL;S%RALPT*0*x NN̽+~]7itζwڷdsQ}'Gե T m08On:azXqS&e}%Uԭ ]o=t Ǽ™D\QQG OmQr r6c4&S#")#Sg5GRB &L0&~FM_L &fcѢt/9fUɮ)y.G'`࿠ضyX} `RWIJ! P)YkLAۋD{%~ؤxѴ}<} (Tw`氙(QDmn/y_Ix*.Z&;:R\܅]?kc2|-0Ng yoAp3*Z6IXE:J$D@" f‘͚]uW'Qꕢ#&7n~SLIßf~v!2*((h شi̐!CL{"qo3<*AuPQe9} J,:8_wc*G] p{Q]mr5,xy)%"Dq^ɝmY~w܁:Ƚ|Nӣ9kpbr2ͦpf쿄Q^4H-hƳ#a#uf9nSf(SIh?7)9D@" H$D@""ߎaB&Y8-*ԟ']_-^Qƚݞw}D/&hJKeFp.Npn1aQS#l!+HmINfc{?fqٵJE.%sDUנU=hJQW@hK<ҩrRS+2JOeA% ok,_yY*%3&8Wg)P*•zlJĹ2졎6T|vm72<9%)H$D@" H$M$)Ch() *%9M}=xJ6WbJP O^oSz=IngN]mQ_7'T4CU~'x碌$s6QrFG}3.Ρ$WS6hҪ|*up.ʵ٘C" H$D@" H$a[%g/ꁩB-xµ ;y a4~#k/ 嗠Jmhs)?w'$[ܾT]TmMZs}3_b^>p#H9*DZ{]BREhn BUy)jEۛu:광F" H$D@" H$=aʼnUJDUy ~~𪩄;\'\::w/1ؔnԱ+ɔ;'&Zw/v-MިͻPT!< LW]FEYj\)Ӧ=;Ãy-=t?)wB]_^/%8s.ETtUOb*J/5V.ee~N_" H$D@" " @˦@<i~A͚֡]uW'2RU}XU7qSDqSUu3 ;UPP^i&q1!C":h[27&3 * p8cNkKXT E / WX17!b܊Ѯߤq~AxQs3cÕfr$o1&0{}dVoR3^1s4< ~ )â pr6ꬆq=D'bL~8(YؒkQVA=>e,N ,&_T ^2jjQSN^gOJ{;,Y%8&MQ\TǦf*Я>=xfl$A`xvS$VE,i1O7@3ѿ[2~'\p<' B(8 '$Ƙ)c(aa U<w-nԕ:9(V s6;7#зiXdjmM4s"%a372fglӐr#-PRp_.O:ue _!q='>->\/kD! 6+pܘ f6l]Z);[0쵝OcSQV[}ZLsNbʐ̷ڰ<ZVۏlPKMObi~2zZiC1H~DsJXA 9ԏC2( F#*1YKlF}r,9z"o0N}|Pj#X%vZ+m`o/dPǹyv;0m9>c9Kvz#`Y!y>=?}E/y JR5r2m|^zͷ~m'_%ƟUv󫰫?OsO]_-^Qƚݞ"AXs7kvM\՟HCWAXU7qċ'U2FIhu ܔ>+Pa?CF/P7aFd;:L+P.{X6ǯ܋$wY1ƹ~؛Cį܅!B`lXe=+'8&g!8~%V1hX òÙ" vDIPVg2Ƿ/u Z"36dn?ê|bmŔAM@5X>R1e8tX37F+} `I #d>?zx r{F`ܻ !2"m%7ؔ F6sS5aޮ,'},.ü1h1gA~quD;?)7b!|&v-}1rr+y# ';Jj l*җqL ڵc{g~o~H!ơp@i-MΚ8D'eA5[ .9"=@+[`O ݷm163=$gy)*Kid>[󇡄o8ϋ1o$Vsc6.;%9i͟ ){v҅MM1gp9s&(V2$Uc*ec)\h,Y-sa[FGּH͵~;\meHIU:A3kŘuT73@Z=Cㅘ0A*&7}O#dtĄ2vd]QahRIeh>e+ذh%Nzv ^xW I'?z6P% oKRƈEH$-̷f)Cg@qވ%X߳a}aHM x`p#:z^n)wR7)} cOB&o{"}b tt_shKC.Ϡap>gBȬCob:qxj}}9a02jv}[]q[C,)DsX!c63՘z?I'ўF59/e aq״Ô%s0W䂜qyra]sg_$$^:W0Lr7{caF>{>h3c1mkApiF p~73j9촫ݠݔc d=< 9EM9zFO *p1X̨|1?i=">6{3ޡv:cZ_!!#H }f~=1-qAm4zlSp5[y|ViO扒 IL#!=?F@E4mgDBF}1Db!-3oƽ_E1_oޜaq8;"u6*{?/y^5qWKG5c\^_RK^s'ۅ,b]l5eau5.fb)GMD|( П@9_)ݵv G";DYWx/%'hbx~?"mI>k9z EY;n3 $ziRT.lY|G0 Zܧ7/&MM9!~71fsY_\\"SFS: )VGJk$t-h KNq1m>V-I0c=E׻׬ǛKSLD݄LaUKp c],'a5HkvmuM[Jd,쥟yx";Gs<[6f1ؑ/?Ěb2 /N L~ihEѺ:m65B < cqAX -Ci3JRqd~n*W$z̭X ՇX`Ր;f'5kö }Ř]-E&KC4j=9:uغA]tF ׅo2tG^&-<绚ƌ]̍׼/ bv = w F aoAlЦKQҎi[pHײ?\H 6Eۡ_L$јc۱&>a}֝"|m?g+ ye0Rw,5+3>іT}h\Kێ k/>IIzY_<+ʷߎ{\S``AR|z+2E!7Ƽɓxx/&<4o¥!pkBKڎk[25^| ;viJa}X -4Z%(DkBY^53*.ٝ۹lL;Cq8vMKD쵫Q_ǰ2{/**BhȷKssS83 #Cu]a^o\6jY Ġhhã8EvK(2ve4{51I!NU 큿/?NByN- xOon-zIFy#Z>Ή;<9OBDqI(5ǗmnϯDZ<~4D3f}YÁX.Ѕތ5`g7W\D_ݼ]!Z :'O4ԁ\?Mn|Enby{/ ;bcF ǝco^b&܉AQɡ}Ft7J.70n qzB=_e#d0AZIMA&3&rZ`hrD]bQ  ;s-2OgX51oDcPRm \w&zTWJ-ڋsh3Q2?&ܔɂ[;Qܘq 4JiFyf1OI͆ 'q^>|kK "ؼH=z0Eñ$jbehXm#x{DDe2z( ZnN$L20`JLØxsqDN_7Oop+S:ow*_ ވ>^nWb eha7ڢ\cyH*j]TFXG Z!2@(Vg!tMGmT_<ogdNZv@5-Z9i 5)Ï"u&غa˛gx IM,Y>5\yXK OJ=#5m6p`g`'$z5-HnMFdXE$`D8{)1:z¹KuϯoEBg])=Lvs7+*~[dR.▼7W>)cJWE-7Rr[(v_*]3s0Z0T%r ګ_J,i~?wcq/c,F4FYOԕRߑB:CiTٌ ͜1Ʃxg3ܒ268 !02B eѳH!y:|)7Hu QNx:CW*k?nlLv0֧@hSP'؛_C*7eabg܈Ǯ}|؝ ]'mbMD#2vQVJ@ǫqc s๗-m|ONoM-VN;ڛGїٛliD;ڌx8؎|kkEO< k`g$K @;׳ZQxy\ß7c0l"&IgAdD@" ]#u kQ -5u);))MGDSoIFjZvPꟻڈ\yh@bgn0[)K%؛V^h_AsJ *Ĩqe;&[6 xKq%Ո))p*M\O3:|ȸ7k}А߆mm]J != OFaK];*\Q Ё{J*3'4_[\w8n7v'MPJqlZTköi\7π-o ={++V% zlgc䝻Ŀ?FA=IosٍOҳ9B0|bjUs옆!~`uo g=0}% ;25W5v,٘+%G=m 缎&FշWLdϵjD[鴌CsB0֢ϐƺŏ!7܎Z빊{'.1& E֞(96s<ś˰bYOW3vf Kγ!ʱcا~+ =^N" Hn GǑ^Z!/$LD1on 2_CWs4 7x/18_` ! _O 0LsΟ9tm:J(^';"E8\H G2b/"~z"5 E biOQwn yt$1HA)2DZr..>3U(WH*ۏ/;Fu0y(Q!x#aYs"@\F2n>,mQ>߉cQ˹FɎ=Q8k"v@1\M=OfO[dmhk[Oa1`°E^b <)Sl;ĞTߛQ\6EU5nr4DF6 cvo*G̻ۖn􌘁RaDſ l.v4ײM,ޙmȜ 1#o}vwvɳ䝃AkQ7eYԝXr:nn(/8>E sfO* Ig㎭q(&ԵWږ/1c{h37MֲO^⍪r/W Qht3w\lO Iy|UEIX SFCdS: aMD8yfW"h)}D]H}55}+%ۯ C[t}XEȪ,CtT:ŻR! ޟ ZLsF/lT'hHfǽcotp<ƨGhlN3J(,><%Q%96wnMmF}2,maag1LMH 0mttTlm||@w`,n$_sxZ:nd,l(%btܝR\)[ӞR+m.OJک-X-{5 SC)AQѰ19ŸK"FQqPy5WɼݶSnvWM3 ?Ɵn`b_+ec*rRL`Vġ'X8B_R%*6SlD@zOb1â+de]eY6z?lEI),v*džǖЉխ f";as9s/ocMc-a^lFɐigotVK{ڲ~.i\su5E`-PQq[%=nYTo56+FPwU?53sWWK?aT0fY%\LF P,5&Oիj7ZUE?z]LNN(ƐhݔUT"k# I_qD@" H$DCV'e!D@" H$D@" H$$e~eevD@" H$D@" H@" H$D@" H$o$e~eD@" H$D@" H$)#D@" H$D@" H$oR" H$7A9->_,5Um'>jEU'j憪>G:5@̙Ԕ"m˺BH$D@" HHRFvD@" ]#;mFz#l% 1LlMFE ?"_]v ƲU@53ј%xA" H$D@"p#HRP ]1kkka\W<X" H!0Io8$eYd Kn1~.(>?L5CH&jBd$-"0Z>#[,C{D@" H$ ! Imذa5kuܵk$e5A" F 8v!kǘ $KT 動-N f0媥U[B,BwD@" H$$en>''UUU+W\w<A" Hl#0?iHJE`AHS< .)b1F B%C_agnVcwBiâ6ƈvzd,D@" H$DF qF>}ZA*²eI&{F I˗/o緸4! zWy#x٩#q'1|Qt:ůºyH_:K$ c\+]w3g fɎd.Y`4K@d٩qةꥡ 3'?OD@" H$D& Iq߾}?a{ )?H{L!e\\\0zh%Χ~_AoWg pIWei<$CF)|N|[c'y錑QZ$՟4sh It69eR$R`ym_o FYiH$D@" (7Q3 KcV^^˗/+?W:4o\yyyYFTBFX2Ik9.{i!$U1<2[`g~ؔ<Tƫ9D)1S&,6)Uӡ[.]L"H$D@" YHRg8ؾt=K.-O?09&O8UY2GI}CRߐx>QMVeec4K_aG/G#Oc{19 nʐ} m+D& >=yҞ{sEBBtG>C#ʘŜ(FH4ܸdN(GE!A_&,P@{FǼbF</t㜙Ҽ IH$D@" Qۗ~.--Ur:eTI777x{sU1XE`~, tgJWriOŠ\ݚ(vצ g] 3cLG܍aFvyö{0ŧG)#B^$C zx&pL#K[1̋#1:g2Z^'DN@NqX~&čIg)Fw3NÝ+H$D@" HRgCظ̷4[~ 6muqÑ2g}DpWCj?JEb`DR:&*.zx~wc,XO?a_2DGw.YTn b5BjjnDabbJ^!kHʺ.^Z%uRU44pm% ϙy}}yo^R(99y9g2&"T-˒0'I@(lYj|b|Bog1[|FmL 0&`Lf,o=.ն/'!- =@84ۿ!c:]EQp#7M7nl[ עwvA[ mj7uq nuԔ 1\N 0&`L#9ù\34iȍzљz6(wS_A7̉2ijIl>̝`L 0&`w*NmYz%ƥ/Cp7|K/_bӧCpm_ދ'^>mϾM1Feӻ"_0tBP#0&`L 0&,[ZdnA`N{o(~'ZShvT4o|;aXc8Ҡi%}gL~M8ƬG.#gtVj , 8#\̈pl`L 0&`w^t7+&ˇ>GRYk"[iS~j%/,R:0^i]vDi=Ci..*E/ABD~'{/MVSf[sdvdL 0&`L IX(s'Mu 1~..}d RП| KK*~Ħ(2Pܕp|`L 0&;E>L6% $-[,⮄3`L 0&`wAUa3ka^b*J8ؑ 0&`L 0&p`ԘZ~A߫-EoSYu֔%^[ܚ|j|bߘ:4f8_c`L 0&2wC+:v/˙c`^xe88nD?V!= '#^{)uE*Ym>%^|IaFd;ۙ`L 0&4nh8w 577.7EMn;mB7`zh6L/MFoUZ8aB_[#}eIl+KXCX!6/t:2 n4>aB'0 |abln' cg)J-3zLY?YiVXk,{ O*q&`7@WL B'g;.* #r\AEgHްb^w,rυ 9;YC|ɐ]y;+b^;) ڍk;X,mOy6nF[4Kr;LNؤ4)H#SqVkl{tvV峒ʩ –ۈ^ 8@6jHQN|CU=Xx'N@Fťե+4m7rjqT@1i o"O,ݎ(Oz\cY]ٵ Zr:' u 7"qh&`7p$L2"_{8H{ - dcbbw`ɥ3<ETuV #NsNVB@Fr6 %pP&u+W:Js-tq%[8KpLFiXzq~ao2Ls{ Qlmc[ѺgwNҗx&d?W|i*A| _){/Xy?aޑDq1fbxנJM)CTOBZi"cg}f̆s6M` +܈& qJ(Y&OkO iP_r-@{tquɒBT$ؘ%Bhnc|Wҥ1`WHE|#i3e4GeV$h~:V#ʓʹezW)I(< VOX6[ O{9V0dGv($k9 QpxKe'} \>#g `w2䷖]F ;#zC)ČlKyp­+\ |VFi<1;u*'K×!/w ɓL={, S޸$2jȌTjYl߸$~rVbɚ\m>[1#u*..CDP l.|Y6\5y2bb O[<,"2&5j%MBҎgai *Q*lܐ¼-!^ÇÃl)ޜBwky O.P:_n<~Q:bΝ_EQܞUg__z/e Hەvyp#Zz4zi\Qڔ?FMD#5vhҾ4A{"'%I7P9E蔷 }D$#PQ:|9rm9?U/PSc(-t0 Q3$#m#ZfTנrR9)(.@b9 ]Qf+*P hU)TmT)9T]VgIAʐR4? X3^8ᒁ1=boQTa"+vbL 0&ppCp9sO2L /OvՉ"WWO K} 'gqϚ{I8FqC8m4r){+E#`w ,jSE׀3uh?>eU՝-^zfsZPe˖[+3X*\oZ^ T)݌LÔbBҟExGWd=Hu]0WWD@.Xך">܇ҧc8\MO| Z$̥EU9Sa6/cs- \[w{W5&8`feHm(s)t+psK(#8ɧy bA|DGLC1qYHu@}%-CĎ T,'n*ӦtTRΙs plo) NJ|JBB>Wr<D)HR _md7HgJOXi\*>gL&]1&r>h)Ƒ[7ƒlxndO^=h|az9~/{ҫpwnR'왌gXI{x 'YJ0xiDVXN'#cB/ЛFKھ?3%G^'ޣHjMȨA'K}jRuLܥz:n5{6%d6V1& T/LGs\hܺr`ԝ>*%(U%ܱbvekV;+; PFfg}wכc6*Ҳ"ELVKS0ǎh(\[zfcg&~K\FDI\Ez+TcSH@4oC%JH7”xPl咴8`5[]h2)E? dզ-mAkB[r:ec;4Cbm(e[wE xT*Ǡf|^dj*'`W&E9MVkYʸ_D4mv/"UZ+2Re'E8Z86`Hqxti(׿x"1sY]9r"/Q2)Yi86p}q! 0&-%P.w6T)&ʟJ+{Tn]}4QxSGaCwXMGKA⨘PHyy8R~B2[A@܊l9۔nWVVѼwxvMyT4{2P\,-mj6;ם6_##Q6Uz-ͩCT.Ķ46wL 0&={;6RsX%B8 7O #]vq.Qs] cnM5Vf `L 0[J֎}@ZIJI+?'d%ż^mFuӡ*P%XjH0dU~u6-%?]~laL 0&B `L 0&`L 0&M&B cL 0&`L 0& BL 0&`L 0&X(s sL 0&`L 0&` &`L 0&`L  .Km$\ &`L 0&`w<֔㛘+`L 0&`L ܎X(s; 0&pp@q]J`L 0&`w^tG5'W 0&pAL=Y= \CNNpB ; j4,\D&<ޜ`L 0&ppҸ}k*&eSB;e^L 0k&m+hl6vWph߱"^'"|`Gdn iDvtFg;s0KMv;PF`$Lc[cy~sϫ]96t>>j{^ 0&`w"Nv(ϥ{\qO冑owGgm3$om 1.E⹐Rb}loubΊ|ŇD2 `L@-VcA3`Oⓟzc)xص`sZR %N5$5GfRVG1&s58XsLwlSdH33Bp"~}x+ؑ 0& 8y Ǭp8hkjy - d#';vK>cl ذp%i:0Y # - d]FE2*leL 0 Cl#\c+#+/b6 B"O 1Ç6`IV'dz>h(M7Nf0\:^ YdϟTNpqʿ1"`&`L ܞvq0+,yw]y/Y+OR^a w!^n!IY+?B+PRu= w 6@Eh,TإK<EGee\wh4;}nL 0&Pc~q0F tKM+j@n1)q d{(T]UYoGzS@ĄUrR@F/$mFhD0&`L7D,('[ @xςku#:vrBB|- `qC.vq/zAA_ߧ~ӠJ}~l >H(ccĈ:oa_~=nݪsS-wPNmX`LzN%P\^ {R459o':8RO`$2翏$ K5=XO茝6qH,sʷ~@{hzG^_\t@7K9dB/'B=qV>{>Q(D)+MغАQ d&4f٣8ݑG&#ȕbL 0$H_Jrr (]܈/NļG:#-NޤRCy1dŋ mcck0Y}ĥ]6-Z(KF/aJ4Lx?{̡<,YʞaL 0&B !{ӆu:gIɁx>n:;\DV )mprv8Ϛ c,|et#^mOЕ%K Mtb SA~nwp`LFpoIHK>emm\;}#}_JKN4lWScO_<A 6q)!s.Bzˣ'hUX=1&`L@Et ^[_wnޭ85K[/'p^8gLwv;ˤq}q8ސّ|iyaRKF e搀N6,[FGFZR%;QpQw?nujDI4Dʺ1sj9: |W+Qeߠ,d9 0&`w=q7E\ļ~!]tx1m*BX =Z7ڄIo0ށ-].LaR~'vi&U$}+ߵhL 0&̀qL4GK&vxY:_&YQoMK'V~k2rKP^AX7w9ۊP8΂ 0&`1嘙/`\,|7h쀺ӇP~Vs@;Yرb>d߁93NY(sw7ז 0&`y/Q' w~fFhӧB`yc oJgЦ:Gk8BL 0&`vtΜ `L7I遶pe@7>gzuXټiMeΔw%sjr?3W[{-աεUt}z~! 0&`L ,,}||Owh׮ӧ?`׮](..qRL 0_@}Z)^OU>[e4 UzpwTi716 dLbaG&`L 0[F27C=^{ ^^^RСğ?}1~f؁ 0&`L 0&swUVh̛7Ϥ@87!aE6L 0&`L 0&M2BCf鰣ojDXGe`L 0&`L ܽX(sm/,]@FJq0&`L 0&`w/\cۋ%H591J1&`L 0&PT|ez͍Hz`L 0&`L 0[Ctg܈4 1,:\_e2H3(C>R )(׆KF}.'d&`L 0&`LPxBkNgVˍHv D{ NR'oNOyJ,hRFΠ=Fg|p,ͽ.=%p&$~9B[|?Pr4&`L 0&C;!mFd\@716&-pC7p HȜٻǎĘH OZ'Y4-ٙ ^`ҏ`L 0&`LpҸkW7hn}Q56ŋrh"fH2!;KAʮlw-Ǝ'棇z/Z:M5h ɭ~}Wp(wfI"6=^:rOAf0dFqcÆ?`CxUEic 0_;fO3 w47c~zA>aSvbN*hJ&|I6F R ܪ!Qybb |/YѺFD'ZP}JAr6~4Z#U<1cT<ե~Kŧ i޹9eJJ,Gzz\M>A1 -ΕcmLdUˠ5v9OIQq }QqT}@I!(j p82c.1 UgQFIU\t5)pG}>J<`FHgg~2 r0.7nWc"IKĂ6/v1pݖM}ݥcПrQ;[c'DAv-pHO֍1]2}z.h1Ԗל~~A D~/؀?&-0"\FEQ'iRxse fcND1f6ClY mh[m@D%?to)P&1iO_s#Ra=_gC4B3YD?We8ntS-c,_e֑(Kmb|*jn.lN?݌[~w6o5>xwb0:=[S fCX0'6ҏA2 "g`" ~hڥ-DKj8eQ sL%j+ u5K֮{QSH?sŹDXjG"V8[Esѿ.vAХm:`Ã幋<"a[Y *?C{!f6E]<RRJ1{@ߺC[1gEG";( v3eWQY)vxMv; /(Nc5qFqЙPɮ\o޼y޽.k>|3gμW31H7+@x+_"o.뚴f_08oޏ>nػ2WҲyر#| Gڟ'bǓ4@?bGa^CJ|dLW!EWú*ԻUG҃uؼ Bը<]S89fe!"ZCITe[1ŧ1BE_MC "FIa>nTrwշ$-QYU$62%|J|,7mPY^.nh܂xd- 0:> e͐TnO?aD> 1 WjD#Uy  }#"ICmK{Qw$MX '$cPO^~c%9Mx3tNp2XL BR :Z/ܔ1hZTV^F.^;8ITbmXxyGMklWG#,N džjWAh*߄9pRc)ݐ߄0&- :31뉅٫@UpBaP/1ҏ9 U5H'PY"[D6(l ]}\F.k1z/-]v-\N}szܙIIN?P~^#/blzt׏kZ,~.z٘>Pc:iD) )XvLIEo8x==\inq/Cse("V+[*ǒչX2YFuj[Cqb2y\k ,*}|_>iaO٪иBܭ5keŘ4uV7V'#įɹG5|}\Q_y7Փ]Ig8 -^+qHשϫxg#ڳzQυ|G25m\iii'?r&M3aWخg|0_1j%7OnNb;fBވ4$* ʑf"=`i X>7.L?bFBv݅q}xܯHCl$XK$m}~ΗѺ&zB d|d7H SMqĭ/sx?Ɠ.H3w.O@0BC3u 3eK#ZMV.pn\5}TqDE6V B71_ ¨OmB7)N@Fr|mcjR#d߄MJ;GYU(Jɷ{H%?2$60^] {xMJ*dO+ma=Cω '+ @IDATTT/F?!VҀ.'o_H ӄ- !>qgxsT~ݸSU9PTNOp:'XKEP`"MP SZU*^uSqc}W&SZ)2D\kfЯCI@X旴ZxB3X?Çk{"xrz*u5jC!Qa9M\̤!Ck.EL `D8 ҎCeЎ;I C޶Uǒ†dg-=s< VZ3m`|ȭlo_;khzknp6]x% bk#tY+O;ʅĎL¸ wq^$MW&L}Ji`iLg2%ߓH1{6Fa!yoH^*'⃄)p_l">#H )+'~6;z#% &K1KPN2J{98d"-СQ:s6"Az= (1'BQ?MBM7-ΩQ0q)i&naav_!VVZj֯y>DF4i$:5㱮(/J\,AZ w vGl[R^Z)5]Pth`)c 9"t HEtu=ŋ|*'b&2g@j*|76靯ބ/R$n+Gv=pOP$kplOT|'1d%M@z*=rSغz=,MՅ.҅U,QCЅ:n1J/P I6_< '\- v lN[NVOƖ1FS^HStF{G1E) 5ɘaS㐒{%)ԯ['ՄEc(jN?ZbFZ&bL4^$iA xo?;jH Ը$|at4l[wUClܩ~9#aiF1Oً?gUrwlaܺ-Bߒ^믊ƍ;]2W ˨;3j;b61;CȖާiGd=Ek4ƄSLj.OBS߂EuKlj)lLז#Xvp,'iڱd8W2,^mh:!TR34q%0d7ߗ}FH}4QM+giZgdQv4:Ҭ&jR'o)z~aP'ߋL6nȥ{-ءx 'A&=}#0'0<|}# d w:GX' H.\{z`!D\M3eaH3 |o!uۅƠv$쥂 ͖{ r U<ՠ];Fq| : "E:G- h]W q9;g $zh%ZZ7O|WIoqҐh%6oT?=C>x4ccØ^ ;^$`67 Dl)P|t.m!1i J϶Fehi'lE( - o`'G`k6IiU/Bj荧N~1; j!m; ٤u+JM` x*D1ғDB >Bm 9OF/AAHIꁆB腉^NV IhD Anyc]ػZ$O P^!}ʗ1i eoG>4ƀ$Y1$ [c0Z t"kDg{~Ochu&HC% W򯶒8 uzx t3ߙm|IF˞ߨđZ5n˦_)^Q'X?ƒ;iH:|/$xܲÝtJPd觶+TfJՇ~`ꍥHԄN(^W%VN4 R (ɢMs'lKsMc!Un/%ӄ-0VtؖV\+̵`HuBxY}v_hCLY2B&+gVڱ殷MEK}Qi-%ͣMl' RAR!}ؤFZbSy.>)ǀ~ZO{/E})+$PccH =<|嗤b>WqL2v4X ]{`x>-N.#e|Oo{ /zD\&7y W8Ĕa~c[6 䙩| AyUvRqsHpN9("a̍oOz+&{ aBT$$ 'i xF4;:ڻbMNA:nÀ>tG33SZbhL*R p4 ZT 8k:rgWF`'S1"(X/'yًӾq?: 3U.ƁtA"#;u~EG8A;\YAD V#CDIS"Wh1^8FF}0&FVlJnPo hodIV@h">`=giHr ᢽl+W?Qmj{`hk1FZ_$h;ȶ1QSii|^w0]%c8#phlZ0FMca04D,bГ$~㹘:)G"6ziU%9+IHY|~k0ѾmI)7ʦDWH{hRQ4cO 켓6BícF|4We' r/ܶRz *"9OFlP-;@hD CK C1(!CxuF k|D(E˓ԯqcص7)G]xOX7C@,QR/j% kYnѵ.CSd/^NdIƓ4KEcP,Yx2@wMGU=ՠ wݤ7Jg.kv⇦hrotLf2 MM<$Tf ܑؠ5nb0ib}bOQ7 dsҾ{wQ"`P^"i;'dh[#"E"ػ?6`x8 enk= TLOF鋒wzEZrYCpC;!PW֣{gzCF-ud$K.Aaex,;Q Cg=%F'.-wO_&8h >G)XjWҞjAogU{o^xb}b>D'0j!-ɋ_%HuIJ{]W>"V`J)M{aNh{ dDKK° *7e8soGXcsnmSE ),@~VqQO~Xcjhg5]-aUQ3$M+@OR ~IwON[Ce8A!Н2]gn>lYbl\TIf̦/ WteZj >ơ1uF._(xx=.B2׋3 B3F5i j~u⛧ `ZP롤?0-M@"h#~쎈\ D}&'&񕗲&xіKƏF4,δ(ԩ"5mm-L7ŏ#4C76Shk7hCU 6o :B)҆~a/Sb꾭/a elzj:C%0Tɔ"QpqH6$E #jh<~V?&)/_Ni݌İrl%m>d6J?5GWŨqvR'mVK3j} aᒈjC٤h4hue;/ju23X>(61l%McsI, vpp5?};j;Vb.p䍠J 96fid:nlwәĆC:5v s!%b5>C,it?ٟvWԴ~~Oѯ (gʝ9CQXJZ^5DbYZ(\gT4SZ(Q ~i;]Sj$#A6U%3sdwZ[ gާ20i~j5 չV i-]']s򿣹gf I%| iv^7cWEk>EkpqHgcݦRdŒeU>90n6BzyKchKN0RT!ZeꮥpM["-5A?`Σ1B'UcQp> 86x\7[c[ÙM=L?sH"FxԪ+i@I̤7= l!~(Ʈ9S?Ôy$V@NF?2a>i鈢"y]OE-wsh7xo$W4Y#h#Ѣ ] ʐIV6?{tB\HoF—kQAay>%_J%!)^[>Ptql ah9,"lD}yA$fW>+>MuCIA|;9=i!@"5I<폾&(qGԼ(i΃CDkS/pl8jSE1GuJ˝^DiBJf]݊sH2qIYqCziqSJ;kcLHAFLF*6RYD_$ C" _H2?KBft_"豵j =c賥ԇWIjgBE-kLO 9'JPLmZFGJM7|t(qUשqmJanTt8ڶß:[LvF|{K3q@M}x1K { SiN ,dS_ڲZqcصWy+bpƖPt|h¥9&""_lRSo`̘wUA`>uBb $Z]o(\>j7&Ka*wA.4:e]*|iPrīރ"L]6`)q&qe*{ !wqP.1r6= ]V1 ((ҾH1yD"OR/މ=h~j~]e m:ҋk BR2x@FzV a=*k@ob&eH5`pTwFrp^Ur[]V}U ]h}> Tb˹i 0LM:"O٦PKD0MZ㩭j4TH) AlP dD9rH8}v,WkʒBZ4DR_FŖF#IMJ(=&SI$GŠ[vAP9,կ&kA,m1L;-#n@/OIUwE)B`"OHV&8 i.,0ԒRŰnؚ2D_ٚS dm+KT = ^Nu42`mULNZ|iѴѰ69_a\%M:n(-c _Ar_m'26<+ C{UJҍѱu"S*j(IfutIMS]{˕+;>I~ hb߰gMHL?rJ*KǤ^XB/ tRMMAXve6UǒXrZjKQԨiU'\HL ^^-͵rhkͣ6BlU<.?muHgqmu5V7]F-u%đ0j7SvM?bWhlMNCj:bƍ3j%-3g|O?4z_ /صk~'MG O@)z%|{Xt4{%pp_l5yic?yĖ>`-VĪ'1?cWDj$W@kvP6q>ջs+SQ6>AAhpڈ\mJw]ewA)p ևŞXqX49iÜe2v=||H{> !76\>}8vO-gXvݳ֖YsU5Q`Zş諻vގnFUӴ4i<6Kk]lg(ܔ?N?vMyI~犻8 #[rSL \tZ)&ʟHC+{Tn]}4+)n.iٲ%Fjv~o7B""Q||(,,tuӎN7osH[yӲgD^y^IEi!</gݿ:jvEs8jxcbK"',ͩ1&`L 0۝.KCz)DEE*?1+8Oi Njj*oqИqN6mZt%mptM;$qqzEת|^A㔮-0,yH(s cuABۍAAO4}0q0teze(59~|WX sp9:`L 0&`9,& Ƹq b=s?f3J@!#2JX;DT˄0eeX6:̦-3'uq*,55bFJRTHy99s8QgQؿg83qDVޣFKKHt>ߖ}#QTDr:MnD:!;e*~jb+/`}O# "d?AZ`<|VŒ{,S_!YnY*ds     Eb<3W\Ŗcr8vQԤI~ݻweƌM\ʉMpptdl%iVzdF'4V2]c#P09^6ߎ6L 7V˝>?8nI[_x!̓ht b`vmS aQ;%cpRz"˂{M sX71;[?=.l1p@7:NDXw>œ@~8TZ&j7iZ;N"Z</bߘUϠu#>jH4lu ֢)w [8S1Sk>m+nؾ"2Y<R[tm3O8;      2'`AyRW}Ȕw1v܉p_CuIs'D5=Ci} p7!A|z㴖vTj^PֺCS%l3Zm; MslͲwrfv᧻:&3m~_b>QlUӉb+lxg]b+anCWl_~LIϷ2O,Vĉ}y1Gݏ߶zbo+{o.5}ZnW V Ԓ6$uCa:f6ơMX6h\ ˼g|bM+ @) PTYEб>"BV6bQ C8vБ@{GDd[.ݕ5EsS4jqI:,*Mۚ j>W;<HjiҶ`넝x$ƿMv;)(Ӹ휉nu'^(vy(jLG4EYW;İV[<1rZ6r7RiضVȧǡ @W6H1 I;bӿEKz3/밤1ѻ0kKb&Fd`IA|X,f=3&    0߸:iG[IIt˗:Jg#? wcADCW`~1D";ǍAu@qCÝM~a*L4Vg7~.wVh vO@z{=!7Z+meή]/# 72;}d{{%>bQsj*647c)~udתX,'S_sSn^[ӰI{.G30YDѺRςScb`9O̲ *u;Ph{,\9 C3 *e:ge`v‡$li·C$_y4`HHHHJAz)^M{U,137!1"ƀκH?O>-cvØ@+q5(GR?%(Į7Vߨ0u܇#"ش3zNM_t/Q-l?EйK1枖v >a=AAF#HֺNȾm!ۣb #[д7Mz=ÊY p,1b`lͲ "yE D]Ds1zǟaeC?t&jwƀMd;jpZOaxc%ŽKMѪU+싵 ij!R|F " AFC>_=Bώr%v?%U0cnO̲u5dֿ;3}cqɜ8%O53'aQpŒaI36=n1MKNa1N&>z/dvbݗI? =z"nV;90zvnŒfصd zF1[Hu2ig<-SmEJlC&!1T,dnڨ']̹҈V XH[ov0Ɲ*ϧKז2ֺ!AQ:a걶rK,/1d4w2th=/Ys7H:M$KVm+7TF %qH h`.Ρ is68I5[qU< } /3MǒOwUy$@$@$@$@$PBռh窎5Uؼt(3mj64vNfyXjbѨy %ҥK57ҁ߫旙 ݺ4w\B㧟~̷0 7ga!LZ42\Y+]+3%-|)h]K\&y=wsdT6* {bu0wÂ% T.IKst|`{ τe&5fQ"mCtH6OÇ!aJ: 6?1 kMnoxv+էА    =֊,Nȥhݷ^]Ěg^fb79zi0{3ߨ`*),sE}~uկ~UitSNi 3# k!S7E.{zn瓉4w4e2ZW1cBvGU@S:=j8>=D,lq<[g4u"rdDd``XFCdg+' /yvM7y(-ߢ|WIHlte8",E O|aPT &X7B.YX8;(8s7"6h.0HHHHJD@1!PN7%]c8 @ai۱Mضm-M@Z/?lq}6+sƧLǧ^F8ۛ>4 C;ۓ -e<$paH xCtC6^w D”%-j2iL?qV2I9"Geq'nI)h>LsO5m1d ^|IHHHHd(ʔ[ T"bEɑ? ~sf4V2 8ݻMyO`N>x2YG0ܟvO    (5=઎5Uؼt3mƺ}9mi6OX246q$}3 \۠{PQlH|zfĵ @)RcS   dƆx13HHHH  @(S9 (29        J @QsH       (ß       e*:$       2        J [ cV!322|8  ,]lM$@$@$@$@$@D2Ð @V`06 ,EQs  2&14B(v|'Awx̻˱jS,806.K'_h<`$&>ZY]`񃣏@ zR5,-Tes@$@$pHYߕC!>'S@.>~v_u+ _B ]ASHLXREk# ~YL_yGm? TBJ:Kv1od B $/og  ( nߥcH~̡2}`L -! nAiXL M#E@8#6 ,e(HH$0w2(4^ݠi#I蕸n12jžªUiٟ3{-cbfc]"^(_4Fq{وr?[V叽ݑljuLwsCƥ|Ied[xwQ}U֔&=Nbf6Ţu6I3jl #)ifIjmGw.兞<)嫷[!)aH\[1{y"ZnigePP:A3m,??)u;aʢ\)E5c1' n:,xG}Lic_-ͱԶhuk?R9q?W~#1#5"mW\\5M8O@7zƙcbЮȐy_3: 1m3e}GI^<%o ˃$Iڬrr߼+oßʽ@ס[,sfNH|7 wj+`bpX2'hw>cϖxq;  "2Cw{7pk7OY|PR|nB3 Ҷ%՛DApppLgߚp^.sz/jICZ+Xf>b١L~Y:",VWaG]0gxT,sf9iOLK6Z1x'*vz t [d(p٧k8ןzXD0>n_G5S>/%ExFqSֺiQ_aC4^>=$G!%~6U,)C^)asiIZ"*1 ֹ5S)n7? ,,C8$pcg uc^txْ{d=lH*AxC$@$@U@09U"Gx|6ebq-K7u¸qP+@}&>Kж_B?C'Z0t}xMF]~P UM 3 =oޠe'O *TłelƏBW ϒdI;'â`R&,~1dl%pd$gfjlȚ%io>KڎVF~O-ؾ2jg`,t_Cp]irAIl|vV'3]_uYלyq_[>qmYZ1|$3ն)ܩ{MaO7qr!4..\/[DJ0,g˛uY$@$@$P%[jw#uWld+ѲEԯu 77ROx66r ωY>j#G~Ki^&Νf+?i)S->~ 1zNMM?+W?OƮHH@Kc.Jo -7#XMg ֒Bo9F>Y$eȫEjt*V:MO.*fҍeTK9u6 79Զ(L?[A*뽥Zi0?A JxyI O@itDa/ah-m  |COjc똟$@$@$Pe Jâ0Huyúئ{X>|qlwԧX`IwZf-@IDAT&)_n#{?~\}8ά.j;!R"Sn'.+KG#G^*Sa{q=@}7a Vv EKņ cò+ 7r"6 [{J~u{a% $@$@$Pe &`nacNƌو *%2caEeT8s^q^Tz(®/j3k,C)jwy'0rHZ$@$PNV.{Z>|(v++b,XҬ#ؕ%B ^9"Ü{H,ܛ;Y X4X> CߎPi$x ZSpAZs?g=.ːq }~/MFwT&]oZɞNY03.7Жyp<1jQi$|UwbH'dw!e $ ܛf?} uߝl)q_ ӷi?[@Ʋ5m9ݞX&!A 53y'  %aw\>F2]ձJyeX-ufiݐf曱g5~5o|XtF&EE)NEtt4v- x&Xo=ҫ@X+ٔKk6-)on̜6&m7R|8٩=.nNo=# 7)).XP щKeJ@bog詬ˎHHH: 0|U7E"IHHHHHH!@Q2$$- EUTzTuJ40i-t:ȓ#K! @$@QZ5=4t,( ʩ%jGms%G#߄z9L OL ٳgKزYYQ[ѩF}^]p\y+;V;/;%kmMxO##d'CH|s ,Ym|CcE!|?āoXl)V@cmv2c-2y|)7H\ľ]x֖$@$@$@$@$@$@$PP)C8rH [4+> z+"h0}m[J#nma] G߭xkGxDwGNwg0DI7ֻߘ>C!jV#J;5Sd)lAPAflIjo jǔSD_bs@.|-6EB{1F"<;nB{kQAOL">)ƑF       6 %!k.vm%iFq"dO< C7YGc)h QOa9eiFN1[YshĈ~o dm{* S2AO!d:~+ѦSgIˆ.-$(Gă!Uqu1? Xʦ|$tM8Bͧ I!x9{V/rFO5 TEeJTlقG}mʹ ~:a|,pA}Xr",8<%X[2nDLt>=-L?܌߶W& cP)ǿ+7`rt̶ׅQ7u͒fcbi|X˘RnQuss9 +     X_ɯe~>aճ QjΥ@Oq&T<ɴOC#<3NSk1tSX/KXW4$#vc`A;e4JNb2 Xn7رU )1}ey5o ?# LUAnBtƅfw8\($@$@$@$@$@$pO> .>+akm ɱ_$.Y/ b0eY'44Bx#!fOn$oM1,w!1@QЭ D":IOm7BAĿfTic$`ǒgFC~T9 Iߗψ^-g      ER<?\oذtmg`󯈏d/2ÔŜU2^'A`Xwq{غIꝈEB$yqfC[З(y*ދ?}ftC7%bXKA s 4'~mٿ#nȸ0xrr`g4cɶ}~"eP&ݲ‹ 0S!5۶eMc7@$@$@$@$@$@j^,UkyPfڌUrNy;}yff5t-5o|XtF$~abĉXxqڔrhZ`4f㵵?(C[{a;#IHvUhvDeơ=Ϲl6S,Xcn J1ۖ9{o&e)X Yo cG6㔵X@qp@$@$@$@$@$pU?yFDD#Sȳ_]Ěg^ZL_q64vNyRd9ߛkr3XӞ2B~!Jƍ1zh͘1ى]hMDn9۠C@ozϣ M oL &=\xZ‰d"O:q=C@jp%XzFe~ \-]4.C\vX3҄}]8v۞Lh 51jg'o]ضwNO6{=q.Lh!_% j*f=WuG$@$@$@$@$pmعsy*s*+pqFUJn#qF{ |غu+o?`ժUسggXyڨNѫϚ$^kFÇ3`s.= Gȑ#A82j%ez(S'\V-3az쉼h &~RX # LUL11HVG2f|ĎBkEiet"BݲT2֭+ '     ('e֕ c6W{X`arAH=ɷ1ۘ)0݂7x!bwyDIT, =c#AY|` %#jl3 c4o1яxiD=o !n[kT%(ۉ? ?ŭ8lšzyX1amg=H(ҟ2<gI;BeMy;1s"wdh-c ¿ô}mNNJw!6Ѫ&9N4}&8o1m4lY`qW3`s3 ΡQ|ڟO<حwzE{E"1Rw*늘#      &ӗ$Š)k/Ǐիw^Ҵ[ܵվur uPN>'?og#}bY gE xo`l2E?K"#i\AFh|!?Wlvi4 #={ 5s&.]=D'1l\2J|@SuSGFw◯g!^;<({/G;/E}_፿5GG~o%#|W!6wa1QTE;Fl ƄKY8֗piTw9W?&ۏ7^5Ds&"4b)"k˶6t AwޜuA(WJjru)";műpkiA Ǵaҿ=d#ª}(_#D +B}LQ~4؇F+OB 2~CJƿbD{u/.)dzOatd̞ T42EoԨ :Vll,NXy.:Y3|2PwQa h2",wE!~X8S@Ɩq?T9PDEWYȑ}N(<,ۭTImbJ|t E{DY`]W(|Mm"t; CF.{(c -9/0k2e]ہ'?ŠeK'zO_aks5`'Q>4>2ПWSiTޒ T2E8p`5ʾX^}G[ٚ0(% D ģ-?bt4֠?(UEĂq}s[夤1<"sNY^7=%GRK ]-:sǶǚ)k1h WNiZcGJ-j^]w<6 rJS>iaAo@]0nh!G''`,4lźlYScb"G{ç'G뺻6K?E{`x2u.zyYpB ~ LhW |F}5ĥȆpD&,3p4GLMbg" ?n&zsΝṿuAcǠZjW9K   $W\AG˟ҥKp222SDQgݻw"j}Yz= F;^loyo>펩KB0asisH tvW1=1j<>/}<ONl&G[D!':|cRA{i~e晗YGXʹ5vN^̴7*J{3;)[mڴq[V:vIM6xӢǔ\08:O*J=)*$ -qgr`qC󯣖GEvM~뺛}]u|=/M}Sb\Ӆl\n!DnYb     ֭ks=[Px7{(-ߢ|WVq>+ý6j{U*vdL!^|qk\ܶTpɒ%07ϭ|Ҝ \t+cPc{@rmA\IHHHHH~q#y49Ē.Wǿe<2wa< @y"^]n1ūPo?@czUq_%u)q۫!E r$@$@$@$@$@$@$@nX۳cvMncmsT=fI~~z(\ϝ&     N6Vމ1{ߔ&=.z e'u \Sr[7eIZ|E wMabHHHH#p2J;QEKDZ|ΜP˂KHHB 3qBWHHHHʒa!SF9/w t l0.Zʔ #ACmɻ,g*^KId"d.ɷ5}W?^R  +CeYk, K~I})Keɴ1ڋL^+ '0mL_^f n`L$@$@$@$P^dRY>R)H pE̹GbwkdtymIu-X 2j1S%bA)     E۱'|$@$PBR&)KV QAw@J|4[L{0`'   %UݻǼfeQ 3IH[yᶚՏ8 2+[Y[l9{F_Ag$U;Z֠D&   Mڹ_eY,)ʔWJ$p0 g\e˫~ұzBYR:?wU3ɰ `;CPgQj>;ΊHHHbteY1++Qvs 'siӦ ?58׷WJ킞eT5֗E85Z8x8uȭR7;X8 2$sd϶r@$@$@$@$P TDՎ?WKd(2%V$@%$0}t,\VAYﵞv.[F.f[Jjmsl[jZ`iRlmZ^2]e" W#^XJ$+> @&`Zȱ*b==/U4qG1V}Q -_|P78=zsC=N:63fLv`ˍ +MWpX0W|7ɖ'ǿ5GXo*t˒N%'JvQ.,sÞo $@$@$@$@UϏ5mg?Ef*V:C P)9;tCaHN)eJ@-^Zl|ВiIPꫯZr`~Ξr(-ۛ2DWpa5r/\[ze'VZ&ّU-S$5 dmW2[mZ%1D/7An)HR_IR 7 @5c|v\9Cb(9kQG:{no <\8 KTZBHx{6y;"?c/&ӱ|:\-he0+6:9%˛uA.gy*PD o3{{Kw*/UFnxqjpXˋ )6" SܰuV}E2|[nw[ 9DXSXQkE_2""- EtQ+eLAF[0d[5D&+ IHHHj0,CŲ۲,gZpX{_+-߾2C1cE>9QwhQOBj^YE xVǚchZRNt7o ݚyNM_5]TVnZ*vp& sZJ+EׯTqPAE,$hdt{e=@D_I\7ȱb!S>X!؄k 3K c @|aQʿݬ@`.ʌ+q*_*uQ=7쉈No1]5Is~w6~VE¹3RNԹpKHK; vݟS":CIefwA;c?2rbz;D7)6b[(Sd{Lf'N@}8>?o>Cܡ7oC^EK7 -׊X8?Gϖw%PD#ty[r;}>a\*"SˍdkEѓ|Ζ~e{ @'k|-otm`cXi./im7W(A/o\?4WMNMΧy2q96t#m#1wgڿ>sx _`LѺMA_/wB# /F4>ebPrv%,W;̽D5Am]<.!c&@6Me8K #4D6aV-ڡ7D @y<hT>*ϯhI8 :Fl'nCдr*s?c7C|*'$I勩HXMƪROFS{L+  BF/ё|4GQRw`_qcT%g*oDT1Œڵ+N>ݻKfr܎WW*O0Wq~ϥף>d-LS&7a'] @D/EMme*ތ]{nnqsKǕ3Q4@Dvf /`U!Qd:ɇD;7='Piga}I!Ȥ؀/܌#Ol;|Pf BjƎ`t CHݳ_oC:^x|0CTd3-ʛәcet@3o27aAbMA5 _ ,sO$T7CQf=fӰ!"i\UA7na5EB3j^UX;QF7cCE+1IHHHP99!rbC!P-ek\?]ִS]a- 7BgG!}X63\Ş'ߘ7?֍[XXoY"_ [pDC"z^C65EDI:snkfhj_kA7L TAWλ~hcϯՎV}y6<-ZTeQFyԋ95 :i! 醅m|[GcE٥m3P(YHQAFCM_C9&_IP"u4 mC9*ekRjv c@_HHHH^q"Ψ@s_xQb}#UMsĒ6+zWtUS\'yUec^6Qkl]!N^@Xo?>77WW$/ $5, B02⋅˱Kڷi ]hʁl; Bʧ*E_š@shv?:*řpt!"n,'$݈ٺ` ^@ 7Oc$<?񓌧< v1dŝ_`2`BqFPo.VV[ nl}wɣ itBTWhK&C#ЫW/ç&ukNZCttS9#+fkΊ0sH/e_eI-j(Ȕ3[ @U#KqƫŒ"-6P" <[Ue@V^$d9<š3~rQ4Y"I4>^G{FOϧ"~Fzڝx2z=4P/S| (Ũ,>N~OއKs/b߆ ?*ME8/[ fh$~UvdڊߚȑS mu;mX!|!Bwc~9y(~i ]d“2-hSw~!u[t Ե x {2 r1 ~ RQJƻ;oEv0u4L`Μ9xWŒ)8XnCS9 \T)p;S`fִSu㶨re{#cs646/vE10؞0$5HIDbBEj^T_}Nu5^~2$_KHAI7+Y\[jB,\usgte#&˝@NnXsի SN+)ٺu+g={գSRR\Ү];U5sΝԮyozv,?[RUs^$@$@$@$P%d z;.W/aԩS,>.\G%\Fݯwαa`/kZb|ICyo=LG*Xئ U -9Ŭ{j[pd q'cɻU(*ڭn#Y0s_%G4Ztf*oHHHHH222{'8Wh]8dWַ]սjRbʔds$Z߿?D-_&M*hk=3h,e̺˗U g     *J&33Xik[VxY(0+-K?3PzU5t    f x#b.Yq׶+JQWy@+s_`9 {VAFkqٍ7vۊEdɑM7DqVeU:    q$NxQpԇL ,YW}߹^qmzJW( $xkv3؛YH:!Œә*:?OJ{b p5b92XӴsk:m/>[.S1Ƕ{34vզ8ֺe./Qbˬִ.Ҽzefkŋ׉̏b~ Tu/ sL1[: @U [BfCvvb\aZ˨8bM뽧Kb:fy⇧\ձyJeXӮ.bK۫dfkjUK.{ZǬgΌd6":wMu~y޼Xgzo f_4 ЌǗ5U /V?\hXWbiq~>tk[}WF!@ @FO~gS}nl=}k#=kf~}qojZ=iKOCݼi:+珗jj^`1:tm/plTߚKɇ_:Xs,!@ @I{iΥcEc[կ~4HmW{v]Pȥ 5>+z!yҼQ#MdݱjtT_ݚg9z]Κ8 @ eƝoM8cUW\56]/:i56eN}geK37"SOW}]_t2ƚZu#mѵ|_;]  @&g˧V}i}rb_־;9Gn{RFK=ub)3|LXѳFc+V?.]}ս"F9i{n}{vtWnVC @wIȺw>z_vξ]v/ums8g={S׺٥or gL;N_=GV?蕅1>_Jjyc\svC @%ν'̺՗|iY/WUь|b@ @޻r.}f,qZF ۪W~9wi}{ϗ٢8g9Wmw.e+˂:=k 'Ԫ^UbFq>Ik?עsdn%_!@ @;te,qZU,wlI]Ϙ;]9rVvgݹɋ\ary:e5dVf2Qk%!t @ @(#g_Ϭrh}Y/gZubԻ_?skQKzcz-lš:Y,;/~F9/^kc[kO?8],3c!@ @\VKسeuLϜ|)G0 k9Z|^tu8ط%t=5 ܗZuh @ ; x麺ϬrwV]lV5#?GW92?+2%0XGZ=|p:ZqBF#הGu9ǝMMi @ pߓjהּE˦~kWMyn t_u|<zYkrtjkߗkغ,u @ JUW\sغluuֵmw3dMVZV-c9#}O۫K̕^wV?- Y]Mܓv+9[4^O @ @߉KV%KwVjuYnԓKn< AiwݞLg;)}٬ym]M!@ @g7{U.?uxQ=_]Z}P j~x/4j-W~D/XҪڮ_%5i5ױ3_9X9u+ @ A{O3KVZS-۷ uF_^ٺ7cfxiMfߚfltV}^ꤦy˯jo~96}Գ>b@ @~OΞ9ixIuw~jY?S)ֱE΅ʕn[,P9JV_Zj|Xzjӏ%ui%LcvOs~f5{Wlj]# @ K{O8͜|tm%KjGvwר5<?I]g/aRCB[]&d*{˺3EN֤.MR-/ׇ @ @@7;U}ٙ_s/g+Sw?j)B=*m;hQ1R\lߗ3eՏR*tZ @ ;rw9biE#={׳tcZj.6}=EK%~G3R˸䳏;U<@ @}fٙwMלkFvo&5ߏvCΥnrTȜjuzrG?T.^j"FG}/ljWy[ @ Kw5ubig>G2}YsӺ>SKM Tk_7u-^F_[רN:=˽WA @S\WjqZ=A.`ܗD8*3H'?z) GVO}YT͑-j44׵.kMy;Z57^Q!@ @/X}oR|kiw̟5SnW_:nʍKlg39b}mO5ສ)q]XNl  @ OW=η&ZZ}f @ @ 7kbũۗMR5ޚSSsҭe56cV{t)- Ts4j)l+˞)?=uܳEwe~_%@ @K`={®j?bUzW뜞R/j\j_WRӀEA7-:ݚV}tKq=KYqo{-rB @$nfK~ڪZŝk:ֺtNSnn.Rhn&˗{-b߫󶾖iUڦl֭zڕLJ @ %Y_ũHK]XY'5wyk2+7Kk3 tx|?jtV^8S:A @ !׽j?b5Jz]J_fv5wvO/Zkiwmju2)vsF @ $pfT-ci_}fr:EJͧΫ/{]jwr/W5oלb6GgA @"ptY0z{i/xO{f]<Ҥ/۫/+]M2|k+4A>dqo͏=]  @ 0#pfa0zƝ?ӜM_ϒqus3wHڒZm03=yU)=8#9 @ @&pdy0z{GZ=gfl<5#Z׍flڬӟt|_gN|Gj @ J(Nݾr9#ړ9:kW֤JMX6Ճ?jWzfלb}@ @ iWj\U}g;MۦN'glJ97<> @ @ -=j^rJlzuC-> V>G!gKj3yr @ #.F}^s=kԾMZ(Xuz2 ǨxIְ @ g Uū[6̺FI;Ϛe #3G^Y&khNfW@ @G]Vk2N_ϟȯu] @ @ \]l?ӓlO[*q?Wf\=#|5+} @ |r5cg]?u!p}9~,!@ @ODOsOpAG-?r @ w-JgyG G( @ @G-M5_u_u[~@@ @W-I:?;;yǥ @ Mc)׼ pph @ _KpoZgi,D@ @^ <"&ߺϕ> @ @/k;p֗clR+ߝFߒV/UB_x$_`L}]:&Ҧ74OwDH=YIjZJ=\>+nA,=qqrq3al_P6#GR=X-n3ƦAm:`J=zDqO(N|~w#o ۵7 ? r`JgsZkM4$$>hϒoqYa+?d~ۑYzQR:މ+}zӜ!#H@o4U5~62\<_pt6rl#y=!H%"%\S[D:$8I'e[^wQ ސrn7y##%=>,V{ |v _̳U,]R kɕXvdU>#|Ew}h9fy31K#M¾'T!&B}.h2!i$g -eʥˁ-5Epܔ] lϖܖ>0if'w6r>:-]ƓQWBv(+`Pys,W|$F gYoNܓ)=RLOs@yiIR僔6CoyD.H_xQ,ɔ I5 .߾ʈ77O'@s>x2L@JI:K.9gͣ]<r$,-YrHiH^D̓:(̟i5?9%ϯx1Vs &yx= h y)y= ] ?˺Y?/3]Yvv= 7#0tyZpxj8cYutfLo~6* 7"9]n%8^zKѼxX ރ3<1>r3T1>` n5&_齀dNg*KFk=ao|,EgW$?5|%y.uh!VDן$Z/}l61.ڦ@=T=x2W!y#g: -?>e&M[3޸XɱWK]m$ +YGוc.nSu޵vqXvqliۙ[ݍ:!iF< 8t%{NF:HԦϥuG`[]0/-нj1=nD~}:ouG )V w{L\Yzؕ-/g?]tˣwV_OUƖ^ޡWtyԣ_'wg鍵Oq=C쏓#>^ui'Q<uɆs ]p|GFΑpҏ+<3oR!3>@U]c"}[; H:5fG{7: r¸:ZGq~u+ yLDj17a[T%ߒx?|x<ԪMC&ִ@۫ʱ9Aou8^̏Adcxv=FGMH,Ad?eqJo>Kk܂ s/ (V)Se} j,ZBVƷ\߹k* YBפ>蹤UJyأ!?p8_U]Zj1PݨOsUet,^|2r.K۽tBG6Kf&=qw$N-,4yJ98/6(lx>|u9UzX֢cWT{ScT#mv_{8mb>_oVȜ_ͳFDTqfLT?K5&>(> B %?V&8>y[m(k Fۧ:g:{tլd#`=~=i-(|ⶨ+SAa|a U*ool\h[7%<I]3kǟXxcfNYs$ԛJͣaٶp? +y{3~?tɍ5 W{^wϽ.r ;.@=۹ܫH{(WND/(vϦng9D삡$]kI"ZS3PnrYkA3_/r3@ +_d˸ mJe1([a0|(;gZ/ z}@k-7έpӾFl :},AףNןGXo~Iw@̫W2mkvm_xA;~4vtc1;G= 5؂}HSןybE[\ jf5rA}>n\:rY:c}>q g NNN3br2gP{8:5޼݊]N&EcM3znFGA#EBm+MI*/; 嫴~CGg#U75ٿdkek kU%*G'0tޖOvpT[YcSktv\G~˰2KO8s%Yz$w$S!{IVѷ5wˤ{z'3C`8ȹy#G<݅ۘ '_Tzz.6\/}rY6JG Җa lU_6q&W7ftX|Q"ȔFAD?lr8GogЛ/(?뺪g}a>R75ZΑ`?I]pC:4w'/~'+ugm^?dA b/W{9~f^Kq7:ڍmw.ƪu2(YXyZe=>aBO :ף?[: g{^YF}NfviFMl#h<`Gٺ?\(^3~~޺_Ҿ9Pfc:&㑾t5[CjOhƏn\c.c9&Ip.".uEoՏ+31r 2Y}#SԼX9>Pq_y>Xs+" onzFڔqI?cXYtcmttgU>ȅ>=9M#EG퇀N1WfmȹIj0 ]ھ:yȳ` gYQasG+ȾCt6ҡFb'?9Oޠߛ8~_QtWxcA#Td3~ 8iN hy JtNXp!+& ,W^ܦNͅ+U8G(xޝ1ޛ߇5nN#3PR+ytsߒWxq~۱6fq^is4n":O?'䈖 !gvsn:[ :x[YzOnsNm|R=wf9g\Ewy)9^#aAWK<=9rr<;@S @cWʉT:beK!轹,Aؠ|fB$k| n:,/+b;Lb哥ǺtzSqޛ܊b}.Z_W07stױgyfUpZ~2W! >bxX>G)V$ο3Gk&@ Ա=cmVYSbcYXc"e!#"gc/)wc)ŨSccI&O\A߰f<*.ͫ?VS]InA~}87KҬI\f lMw3~A?;)7*g2 yLR<8~WDl'jr%ݼ흻477BQZ=)X*>#!{%(r{sr.;o7ݼW??׾i EahpLC-BImЌ MzE|4젊ߔP<.Lpg cSLS|}Q"fRr*TB?Rh uR+4mM:ivyYL)mX[4@ D|1=Vs((i\H;?d^ }+cde>q^uu>c+է~5xUqXXPW fuߙx+bDߑ=s9r.wJe=?mņL ]ZW^|٩@1y$6‡nsl|B>,úx8}Q H:Ay\Bo4:nܝL\7'Ո+1(ʮ`#uV[ЩaBEGzkNv+M+:꓏渌jAaK*ӋlG(h ht]agk8ONoVeע[>Ӥ'ײ/<_=}|b=V3:&vxO_v^5jzŝqo` _-%}QO&Ͽr`i)[^[W-72~[A|$9I$1wy<(jlƳ2.mMC;ep5r?toiJ,0XnaElt/[*v񱂮eR`Rt:TM$p|3o5azg*ƋhBX7)Gr .!]Be߲̺T9hv_cϟm7V`[ l&/3й8,Ƈ \VF-(gYy _r.Lj ?Kό{ Bj^ eTz{ ="M7gxeF cI @ť|?ޞFY)nf.7,h ? \Pu~kx<j#mw-Hcuef7/QUB%1~=աrT1GcJ;9Wi<XP]-MF"&c]J=kreӓ#7h1WU l^)ΙGy8/m,%њ׺.Uyˏbt^YgԖgCȾ~;;e /ZOJDx!8:+'HA#gmߓ.ς瘧3 HUz_a; @s7a,O5q1vx 10:>Rf;T#LJWdԕ>[wz!CDz5qdŧ|Scb@(-sfkA 綜nOp 'lޘ8~X7J?C#Ѽ6!_'ycnߚ_;2f}|Hv.#/97mHƢcRg4rC`3m>D:"W8JY8|_/Q^5ZG;y^\K7g[w6ҏV=F|U: s{zs{,*(02Nh5ieZy2iScv=R{ddma?x:t'AR8 +lR^˱PMH^'1F/iF<3M"LC,Y("\fCCv)]9BɥRܔS:N9GJA*_|3*FR,3+yKp *!Hy,n`*mbMAvuEN@%r 3B>e5S>iTk>8I!0<95X^i}#j.W7ȃiqy?:0}ͽ<~Mt}bk|{138fI R\3cO\dPϝ[ovz<Yi[#tֵ ֻ=VC,e8ZL7ƺX@Rci铇kO@ ~OrüEx.@_#Ǖč}%83rh{ ٘Dc߬qPI/2C(GȠ"ʯ֖,/%̤615\Lun,לa U)l]qfQj:O1WE4d,;|=gq aY,+ceyMgYH7ۣc˫cy?Zq\}{X.6^O‹qXm|i 1:B_)x:z:e?ȷmf}AG,]͡;V*O,wb+Xo6n@g¾ׁUci?Y>+V ^e߭ʍ5FR^ G)w_nq"FOmZ|OJw"甖wc^Oúby;yrf`0n&5 @On knZʇ$yѴiSD8'j^[m.owX)cိ.ms9P^uL%n+|1b'ZЫ7$log=Wn&Uo㽛3Wٗ|Zd؞voMH_a Rv7P$HnphbEsTa'-;B}=l?MdžzoйJX9oC7,wDs@#k, ҧYm5#s~E1ʾM+Kgg;9$+&L 9w^gtXQL=&# J֢WKE4&ېo]:cݣP Eٖ.c f~kܾ);b񟸰H=0geyh}ڡÊlaʣ34FeAGs6Dm]1Ycx>4%4г̓տ {鿥DU}o:8FLODzyP/ J>4G{y"ԫoyAZœ!/$/oKSc*~,9 N;gJN궖Mlb-ɺr|߉usj׃.Dʸ&{+Jsx\xz?r./XqpRtX_F85OSԶYK"M-dG4ͭ>gB nbm6W x$L;O"1HNbM뺧'5d;޷tֲWO}#zpݭn\]%ok;rJ O+_ ~t>lF`Ⱦ~MQ?Xvɜ#ne9Ɏyгq[O爏V^J^^{ QyaqױpHZ oljIi?m~|muљ8 Z8}g0g#yLvg^}ky\=؞1W r/s)׬gQg<)yx*q~>VϞS33"ԫo풾9p|< ^n#-둱n:zWXIћY(MJ@ȗrede?jmgK``t^6IE?_M{7 ɷ/>&/*D~li/Ig: B 8%U2l17XueZ$|X+d@S\ 529v᎗:'v#j}xj,vMX* Ŕ "hCqp\*T_ V} w?bHǟ9GRhh:]s@ ^cɳeF}YUgы2zVށD1!-ԕ q?^;kzD|4ƌ s`pv(Po\~]OM>h?x[_!.ͭ!:9s$YreQ ;%O9exy OKk |:y xbc}E~BͩS ˊly~ 9B%+ #3yhUBw:]kvDl)V+e{ROm:}|u^Pʺ9oW6zS1VbrɎ9_F69L2nݣxaI.T)> i,}RVpƞ kf5 zauKRٳ9  | )r>(Ee;{Ӈs\0"~G;tFUwoJ_'LZ~@E-J^*`8UyKoEyH/a=iոt?2eߟ7xn 㖤8IG$ʗzѶQ 6M?R%-EIGKcbj@-~OWhߏ`Sf]^izaXN Ֆ] K[Iz.ɾi#jc~z}_%2ρK?`WHc8%]Xj,˰"l]ܵP$m9ǜ+lKT6mr2gB(k\3W:W͊)?8jщr, }6d.xLv~7yڙLCR_ڝAǬg:~~ֿcͶmOW9H ~GLͬL`@g7wwt@-()`¾HTJg!#ۄ:-MY~ttCn=M9^%>cO=.BNPYz4Ë{!&^d_{rceDc-B֤>?񩯙*AlJ!T·:1OlJI !C+9R|tᗾiyax,x&hב:= 9s( %wrrMrKKz7M"IP4q%<OP?Ӑ%777bRqKly!y{y\g Q .pVJyۀ8x{r%qzǹ +E'bĜZ+Whc|l ϣY9SK.zWd|Dz6!m]6)69PۆWCjb&.mo@H-~g' y Q5╸pqbXO6ko:F?b _c3Ы}1:`uOomkYg6Y#\;tl]7cZsEQO|Iܐϝ!۫aI݄ҟ'ieّzhQG3tEfugs9[匥Ʋ˧UGj]w)𧡎$m[seF1w:jK{q#wk8P/o}Bl/v]ˆo?:G}>.Է ?Jj=:@]L`W%:v{~C3sKқ^/~V&چ:m_8ye#'8fltM!u%gnn·%XX^~ٜ #67lM/pG=K8-?'J<y.yaOX~C'Es]X?oau;-9ҜSrm%%8XGL>4¦%Gܘk*1q); ֣"[棹ߍcPLrJ0<\P:%8kr-`&&sD sIJzI"c:VB⑼07^nz9Jr"fsirQGXe Mif+4_Ǔ’wF_'JJXoDCHQ+r*,_6EBō5uL~4h@q*–Xq\4(eGGH}|"dž\VV滠lۧ勏|,?"l:S\`CWcb n/T;K/x EJ}gPl!?~'?,ڭ8kk6ޯ4q?soP-|<_Q\Ƽ4q&s f[xKϟPrږugXxQFm$sh,'9'*?!_]1ҟɷi,<;#m۰v\'^t$GyEOb0B/牷dKEN,ٺk$m[(Q 'W :TU?iBUѩK?C#qAYGWw\|~ݛ]<ׯu7ch\f:_At t-BDn?185~s4{O~h9輑_CѼ꾾;y}qmд}O5RB%SvgY򺶨:x;eA1Pt_<7KB,KĥO,K>mֿhm.6Lbvt12`ŢwuYHKٷX0g>?_]X[ E5FdrHBIH:qܬi7U Z9P'Ӥ5b9c [?gLܲB奴!}7] l j!PQlmy%onAL6uVH!'HcBiE]icԇQWh եJĉ6}xVb]xӳΜG7ȥѡ,Ifj]@jr݀A{{1w+3)K㴑 ^[@9TuUx>+.B=b;f m96Mo?Gۈc딴&X~ r`^#ˈ6H|Ӽۅ,9˒srܷOϢ\\鳕=HJe<*j>ӧFj-)\Q3?(z#D;Wl=8h}F82uб)5fc=y%/F6Y97s(YWhZu#sT%S[6no_HK8gm Zsoh܌D%kc]:m}`{srswas2%;Gp{Է]gPc9G_gSN?R? h oiq[樣0ʭNn$h՛?8:‹ho-Z~l9Xj蠧Җ?*vr,@%']Y~uISk?? dɮnJn[wj{{i@V]9T&˾G]=9Qt*ѷ U{x|^O _S|ћ+3h<6x R3Ԝķa7ǖh>`OC0WR;OY-q[1רdQ}ܷ^ KshVb0UG7GnLi'{3{RCnW>X">8vq#A~Xe#qΎC|1f$ID:%)JgJ73eO]{>V_si?ycv6i;6=jekc߻JGs)gVyxl㐦BQ=âi<3Һ!Lol~Ou2(mEOܩ׶sfǵo"͗ܳ)"4aӏf.?|NjXɾǬo}Vf,H,1 ;<^{޸yXXR5SY{bV'$>Kk՚ʱOmM@0kxy<kn\ys{b3KKi3 n{̵xF"Rb ,~<|qs~U\o9zOF@ϫ/n 2_ڤʏ $Rf\ ,НeO8O^tn!~gl]Goe?"j)t&O| H6+Wab Op2+=ol1_;7Zo{&,<* ,;,Ms)'8h>ۓ^Q6bʔ;962vxi8>;ùrkʃDrt߬HxLcXR3(MOH6 -+oR8l|?cIo7R~V|R^X@Ư$u۫b hh<snz>gY#:fџ3#0r{x\}̵w֡W&8POm}S.y5x`Xկ&o_Ѽ?Œ7^10x́7xR6Uxӹ"YF`Dagy. se779J'mcͮOnMCܦ%bfH"{ڡ5 MT=ŗk:|Cnn |M,n".pÛ7#|F$|1$;cͩG?ީm,-)й;=TƂ<.e@2SI3إ{>LH27rsV!776iBZ;ݍϝ>GZu@^YL tࡹx<8k^!iXsP碔ݼ0^}?2e-sXuya7ʒDk?8.Ϊ xgh+ۜu1j&KzVM;TL"/<x5}:rMrQG/E=Mjߟ[Ut3YˆEm}S'lm 36^(QbVBu@6?}n%6JL.O9/5|_ lLQ~T}?>Nۺ.(e$Vn_|nE:>j^B`7Ahi8J6V $R]. uj{zgOo?]^V#yNLqMm5@2XG:3Lۖ~[ ([㤻`,m cfퟶ{{צ:#z^fxy;oux6}` Ţn7G3%L] Ԑ |D4vw}p(ok7=c9v: ?y,Y' DK /ua|`ANlU('Nz/]M8R/yՖM{x:xz1 ME 6{:ux:օ5s6W'#|Nomd{} ɢ|6DcuT}MTW1=AIh3[%c H⹾Ndӂ }{zxF9WuAL-G_?_'!YϽWr/rqG[W#9'(O[oѼ}K;ԃϭSIGƲ1$酜WAq91䦲D4y%ԙMpN'%ߕuim(U%fXUA ~|p`uJG[y렐_YtΤҴlgлwHZ:N_>?yWҴpwquq>пys={.@!V.P\h`rEA+ٌ7"<}WrX24Vgo98?p'QA 9(oE7LuS+*ۦO=mk٫ !0 Dǿы#GS=(#BO7m~U l 0c^~Kc#ŧ~D3SNeW[p=]R{vMNR~e9Pɛ/ Yg0g̵q؏Y{#ɒn}t-o֘56=r0LĿE8ƈ69m2h׋uYRQjp;`5'gzN)&쳱(ezFG_W}I\`??qO訶\g=/DMXɘJ} omzxqv3`}sbQz䘜^OŹLRib_w9yTtMIuZ=ʫ2rl<^w@<X[4DO٦G3k><?dß1IY%ƼC[O-p[ϫcE"ụFȵZM :mYo48y~b7qo ߯x۱r"f$Hy Tuk?ZnE$5 l:&:>dwsc'q&ʄ/#|1':s5߭(yP" h+N DCp}XfB ϋY `Y|@w$7!zl0wΓy/*rMVkEA ?qs ^\6Aenc]{X}c0ˣ9?w[ZgݜơEM7EN>c@,,W'^ZU`HCW#/@;C ']5nQ5Vٓ8ENͅ&O܄> '[^okN>cX3wY[zĈ6Jɼȍrxmfd/ʠ;77`L"14p 7-Pu̓#9'GgE@ec@o2kKU^%1Z5C.H* =8#-?a#E㕟AcH?)Y9yvXO3 e~Yr +u+[ڔt+,תEН% }~[e7Wѝ37OoʉXCKKao\b~LRoy|EνgoM;Kik呟]hnnniK \? D˟XܟpXU~3r9&=qм(o40DzC\ eȅ̒%H^! ?_(2|d+V)}ep_炦9`;Eg8^/NXm,")t9J_bҌ,i .u9="9ٝAg v^tكit|,=L8!}9ȶrt~aI;mw Ɉ<:e3X\ne/`;|(X12Y(T7z=;ة{~WX@=ɺcP̞4{u68ߖܬcS(+}n˝)zX$%Uq-I,a;# ?y&y.3ʮBڒi}7(WEy}sss?\VO|co,!v+o&}_>|Cl~rK qddz2lfa,/1n|7~}xo>AJ.e,i6No'Bײ+ Hmmj*x,H%(6:%ƱM:(ZO#p-hH@WWs6|o}{:+Ehџ(KyOq8.f ĹV&T:WF6VnF}:0r ZR"Ah2ea:)O/enfv#Wtլqe*CykK;XZ.2Q}4o1Ԓ,3KL>JMA7BͺH֊RNR46Qs:@#=Po|oTrȚvH}}$) 8R{c|]# (9 `7U#uiigF혦ckEy_#ٿ^cw|sOн۵cgPO}t+.K[\Q^u$;~ ~~; 6~*B=+/\DMd#@y "tfhCsc(qW*i6Okk;5"P:<͂ƎDay56QޣYqghUyTbUzs G=jѕ~\fGzP֖~/2́rsh{ou$ӾP?4P#u2C96z<>P`Mw!xrT`+w+tkD3DsiW<"nwz F/s|]0=و\Oyc#<#9o>ޜ-?) :?=Ն@V_.;S{rz}KqG2~|p((Uz\aPԭzhNB~y1>c>AC0tŤ-n O%t 6#v1NrɄNy>7J(z@ D>Xd,Yc@TUp ȝ |L)s{12^=0l8Җud.:1qv>).7qHbXS=AkyE[fmk?}nذ0|3bw3||f{Hdy.W//lC:nգ*2Ƴ):t~ш@h9ܥ~Ic9Hy^#6èҬYb\ُW[ot},"]Rl>oT>7~/j3;Gb ЋR75AY= H;=OG@mX]UC-~#SoU-Ds%d9Onu AM9 T'{g90?&ʐ`ZN%xmdp{vV UN E:T_O' t񤿙Obzjsw|=DRi ~ `̦]Λ2N7'-{GqΔrb#|V{M)&>#cZ?8~"BypG|]!9b\*O4!ȣ͖(\pXɣ=:nJV$ -sٶRpax~ܓ2,HOz:ICՓ^,Hu΄7_3EVl\_`agْqql(~~"Z0 aXQyGFv1{gymˎtnPAn-< ђ^JrLxDYԡxE~3ot/1keK Ȼa0"''݋ ц)./uZvuNpPZZ$14Du9f\_1={eMel<;ߞIFYyηP,`١یaLW/8(md7>ҼQlH M!oӦ Py}''!eKo%$U[},6[ Uq WL?WUxx>9|1+!!7'1r~O"X9:}}Cvq wf9U?b7 0=7kzgY7tc]$$J:ncYīcیlb٭6U|-;1&ER/nlP^$?؄[ M21.5%wrWm+ψߒo'&a; Ɲ|;s(i$u_>Bt^ߡ~׺;!ӦUԝ=V~T9ws>i>VX([eS]߲C7cLy@?k(w?\E˫|@1Nͭ>Yp8ŐeNJߠOKPlCA#lo9ѩ|K/O6EK;t^q 15]0I_Kmflz1xDMwVCeX~qOVzn{Dvd_Ύe ʟ#>EcY7Mgb<+2}`=+-S @:#O,;]RXS}yvmsj5 P*J7$]rBc}-xktv 2}pG)|~OEJYjraU/sFMrG%ڎ4M_^pǗ>>%sbu]pX!ǺTGcv+Qe7p m_>~8uѕ睭"luo0#l'H⃮ *}&sSQѹ`=^9c(jH}?u.=<=>,3:9 Fi ';x >x%!ȝ=_C}wc֍ch_DI,}~)1k_xdq3Tf~~ޅ^es O?FQ~howz2h1lkg/:[ewO:+0q B=Tu^>sU91>uDY\Pl4jRDn?xT QĒA$C6:vjS@7s[m3ʡR'+v={h:Nҳ+(YY_YPߏe{~#<^\0a̸p?}-㫯q>-߬94e? y?9#[-Ĥ?qo}Q3h| 7aMy" e<1֖ ;˕H;+rssssssvoQ]ºYBțE,c\fYϪ䱼ۭ|S`ɣF,9qT2;8+ Bk$NQKjQ@'Γ!V{GH"˽kM,8"4EqR8ԾgSH_V ?:wX mOF;:fN[}>jZ^2pp@Z7__'MZWq VOćX~<=cB%me~F$q.Q P pQ+a.Ǥ'7G@~WeWW~ i`ȹmIuI_Aʫ`Ƅ#rë*Y'w&"|.Xr*iNL^JЕuXrp>g* 8e\O[g0蛎.RBjufi%Nږ6Fj`I7/$ B?2%H29Lʪ/.=*h ]:谴~iucPfD>:kLm|sϚ)GLtNs<3ʨ ^kv?x 繮Kz!8ƆJ (k ʖu%? axŲGWt7݊x7 |yX'TӋFcqe*ܦWؖ{zgڞ4 UQo:D,&'ǹzv5OsO \Dv>F|(klP^69`~.+ivZ5WYF3ʋ.ͻ҅}lFq,?g"G6w4m{+h{mV0ڱQ, ^>WY;{#6lA#X:Qz9DX|ˁ?=}6Ss.89Fg3e7C΍Als5I>fʫ8Hy }#t\[ciUqD±XX 99X e֕A?aᡑ۞D`Y,:I4gKEr>g.ɵΟ^ >!˃A~#e\fr-R)~kOWܼH,777aK>,7~#or`*7Q]m keT"d2'^y H'N۳GʱB`~y&L?8aОz"`9rȾL~lr'sY'~ke[k`ō$2\yE_wT )>::s 299=^4yp,y53䇍 Cc4uRC<9 #[֖<?vd\ ܏E盏 K>-߬94ߖ&ᧂX^.zc|ENu($qxƞ ]H"u۟ ]qgvnnRށ}z&Yy3_+oMLwf\卢I_{P_) m qݢxH`o[ndBeHvuV,95RO sP|EYKCDJ4z%o¨E~tf"QWwZjcM*w6RG|%3 cDlUk_?DGͮ Ifuc )ٴVej}??P ʊe^z9((@3Mcξ];Z".>'v}t ͩ`Me? ;* :UIfXբ͚c]<ȸ󵺪q9rS_M0aT/ʾa:l5js=m&ɂMrNO+(f45**[)k+ {jOk9'Bl NNV;h}ymsw[g!\LZP/ڠOA4z-ԉJ %;WNYDcl唇 tdx^<|UO%ĿӁo%wc7=y{H#c-Ǖ܌\{7DZ\?B V-S!x7k7&7L|+@yn0? ާ-]tc F[*?XtBg{S2k]ڢ*jAZ%)^w M;Fb~6mXFZce_57mip 9,Pßib&ƒsrK;thCux l9ȿmTc_)mY9zߓTiK-K6NԄorm8$gl|Mmo8P4U\qp>} P)ְz4 V[%ratZ&S9z0ax1q.9Hm(7QX*g-,5sדhzPݗ,[k=`}{b徎1$V}jΌׄ%Mn#Wo˃Bا6ViLxqzO5'Ou9ps: dev/??eGeW"L(L3_Ikn`DWHs#ywIvss.ǘLǐ^L^b$QSꮶF[o^[ Qk5%7wsJo@=Ş{{Tvŝze-wEw,rq.CbqHPмŁBq9Dr?k kQF3deoޕ`Z@? >G6.(H!;,-p?N'u^a ֝s@U 55Jzn*i' yHy/rIS%r>=s}- )rlBZq d%lc.5>K𤦊)HR٫{IupL~#Or#g,ZP`s5ӓ~FXrNiq؍UoXWu\\3pE<[#>?p~yKo4sU@6I }\{:Wns~5o/M bxpC^j˻%}EXYnQׄ3jF慬띾r0K' YC[/B܃"B@E(=;77";<4 2yҮ[R,r-7~sbqWP==Vnqc7B5Q6o}%^ Fû)7`$j=#<˸RV6(EPZ%n8y=l:~I+67#vЉ/D'_|6,ۥފgk=N۴OnV8f<?f#o;zr7bෆ~^%6{,b[CڑVݙt? 3/w>}+rqy=y\5v9 f[I 7ſj;zJ,Y";yܓb||eηz:vUt"n3aRUv2Oʹlcu~&egv&crruqܾ?7FR7\])OLe5^/Ҵok\8dl] 8WIOġ@P|c_ñ|Y&u=hm9Q󖚲 ,0կoʏXcmy˹l[:/fcgO~>#χ#{_c4 )<̶WB)#Wٽҟf^m4hC5R]FAzMǪ6:y1_ @QfOu#q󓾁#‹CQVY͙O~gZ9[Gb(7Gӳ:W鼗\}t7~z$1&.N`=K$wD*E/2J#q}!rOz8mG2\ kuGHFR,9ܹc,OBk jSa}='rB'jezB xC3$utHv[>+QGb6g9:~r hV~3qxq^6:G}O8Y&R [#Yy|ZWyzOKtӻ!)777 ,Y|P _˾6W!O2'hyYMTw^d^{u~r~<hv"MMk[6'9˶G5筲<[:onN觃X=y+:BX ITPa]Cmac:Y$$fK~eW;*R,o:ӏ~5[#j(rɦmv+okUKZz6.ao*jpf3#^cm<fO CS`d.k·^ѯ"0mvNhd? Ӽyn+u.; .,_7/mI7_,O"iךn69" kp&#E q^!ւ]Rͣ"ui2}#Y^̛~DL+Ȉ˽g՟Ѩ6fޠԖ~z,h̜\biF~}=.*ZУwNk ^C 80tyzE9JϿ}k1Y<Mf>Gv). ?87:+/ .Mp?ro")}.JkMlԉ ݝFhN./nyzUGI]'1Ӷ`젼z5 0rFu9AUcU= V?k`m_c kq%t\g&(>F6i4yLeTkJbSzl8M;M~7Զme3oۍ3owM,6w|^l.m^-r"n,d4Pk=Zۀg(_٨:-348mysm3dy_uգɵaT\(:8?՝_&v59M,̾l* P&ej:Z1mbsbN)!1ɉl3sɐXoȆo=.~|~V/6| ۏY>Py: L/2)e'a[>ڪvNe~ ycyzu}de1wҍbIW0F:,azGۼ|uHi,ic0lLVz3m!}`ECnMU]7Snq:t&Uڷ93NЅ[E?gd)F,Q#+z,y ǥY6^o0yo h˾ 'l͵JjIOG'wʂ4Dc=z }-hKۗz4b_i|{0? 3 gX^>c{8H=]!~X6?l׉Uk!nGZ&TUFǁq9V^)ۯ%{I'˩JH"G??c<]oD˻c'G8?OO3þ?ӻ8|( Anj@}KX1\!X?Ezߨf˳d#kN~Ŵa 8ڜld<&Ũ^M;{n҇6鿕6;?/Io}[(\k}e.79Ⱦ1^ܲ|-@r$ӝ? m۰FNiVZELkljQ4]a]̟Y; ]xNN}Nh{s4>;x=]#arpCB.𼅽3rsse.,^&=hqcѤ-~=wz2͓WCA4eWY}m?;^:Mt^wHb8Zߕ1Ee4ڏ!I/,Z}GNSr|.KEҐb^~ uN;S@(+r 69 ɵrcHTRzt 떷&ky9L pr?KwڒWn,}C^Dwe@oC"y?"P~DK? l5'ΑCY$˹\ x1 A1qEXwa^]t[IhOS]GlzX}#!?̐yE9u?^ 0fA7VFzs!B7>ѿ2M6V ~JlJob!V B^ qX`]q | q]+γ#qaw<m|e7kzӐ/bXn o17Pn)e_3ws:lfbe=f7f4s /׺:AYrID]\6pocO뱴Ɩ| }\Du$u3¦vs==%RJ{l6V\BOʋD֏O'߫CzZ` O9ztl, k݄X,qp3|;fżsF NSǃhwos\P֖k]گǢ >CGE2Sh#;7rp_gӅ87E)/Ê_ڴ+h'51X?6Ym>w{~%Jڤ2,Ӛrm>WyK*%&9Kןo(͸>Šo_;[:+6;:_0;'V̆@dm{yiBR N#9-S'GZG'0Ljo4V?}cӢe20wf^nnn~swx7|ZW~ X5 /vnly =r O_^\%#m~;b̑}R=~bT1WDa<|:j58FmLx);)鿐_-=fھ;)ty ;_"Cy6ȹ촧?AB2Tj^蚻<6*7#ߗ\?弑rCI[Xrg=Urp\"W:亩ȇH^ s^yE"x:g꺹Q Hw/a)^z,8ǥ(OJv5Bclv^veJ"8NO%7s9{?υ,GV=&?i!7^}yw4+Zs2'lSͅek%G^.ij35o )fSfwD^F攛?N7W;EU4ƩX%fU$_eחLX>#Ɖ~( =Ѹlc23fo~SsZ :@V_Eϫ9|㴿Lh?]*eSYP:_^aH!c6퓷5vk=ɬխZ-Z;$]m5/}`NDퟙ#>k!^d!=9WK9:ʟ=cx}ZGaŵ5+Amd~t=@}KXyP!ci*cy1o}i3v^K,2G9ﵵ]#m'eei )㿆<T^%:zx}6j{%ٴ5Q/^t.?Kp{EWGN,tט"6a_ǽy:>aڷˠc|JP);GSsD+^,ڏz-=Q;Ó;^OtQ'TnnnE)2iaerŌ/h VU-K^}5.#œ('ny,11:E,DӉq^ .,rl\ _.y"ɶ b` 'D沌ɳr ]*ˏD@5HO,A~4)ZR/6IƋVi'(%X׌d?X1i)DcI*Ms^^6|3 uK628Kf󖲃iҠj>U<{9n'zlk\ K :5gΑU)\~{onnnn"1 ]o]]H~7鶄@^|#pT5;bYܠhg\D"L>ݾi?̏#1I57:|+::N壱]cu&Afמuj~V8f*dOρ*=Wyݼ& %˵ m]ا~|ތ#LÃy#YѼ(68Y˸f?Si~T~ۂKDaFpd,?ڦ3+H[vAZxЯ1%]{:cgo h29[{ 7f7$P69m9!mz~Ar6tm.o6Ǝac2<c=q|+5GpoU=`͗9|<*'Wf#["ms\Vuˣgɾl}(p'ς >[qflDdOu{'wT1$rz>hY}ؤW]W(D4osbA*;m{d%8g"6;~GI)߻R#?uiHM e,;\?[V`mȹ>/筅es¦+߄f{(FoPNz]C_{qC6iA܇vz6z>YtKՕReH;MdA<:]ncAY KC}l[Z+d1)D3z/;oΫߪQgsȺd?Q16#zD[C 'ts3;;EɁPbVct7qʲ}F,K +#ߨY|&8x`o%eEpoeCP.eŷv-p'>9'|y@3 םmFzmܯVUڷG\HS$ϻ=+RB7ce֮]^}"cYa^3,SlC$l0K Bɂ~,_;s-a+gI/ŃaۖmFDr3u 9[h~YvsgM{onnnnkw"uᡛ l7#U=}s DEƿVzn){1|8x75{@wORŠt99f$Șg(8?<">^d5N_Yj t?zk˯? uJr^ioqs|v?24{Y-XC +,0NGѬcumMݎ,g`RA5XkrɬKmg?sx:Go\=25,>7P& ]S BG͏wo.}W,u+ʯJ87J Q ,]n4ѬNwˇ%.O.X~Dj!7<9ƌǙ|}psy[ܼ;|S%c9qlϒգ.'>QI_eG_AeydM#~Ks!̇d"u YӋJ`[\!cy:} pE\_Cٌ@lc.KBZ iXBc-fI/L^u`.T7Y=3H Ӝչr3L]nn~$u?}#>wZϵP3q$Oa-Kd[ǽ)=<1G݄$}tKʖƄԬ^2V+uW͋{Sί'7/^:@{7J8q ofU_HV^D:m=RUΑPuҖ=2)uVo_Qm9x{m#lfӍ/f+< ٠qFu7+f=K6gO+A\W< :ceKQԥ0i_!@hX'Y?pl4A] ь/qt AV@\`_9ыz6k1E_ڇ:g\ʌPn+X"Te)܆⑍ݦ3ί|<3y,r4E{)Ij̭Ʒ~h:G҉y$#UǼ b{N#6&pc|]QeMφ8~1bbu>ֲ9oOd9<26z#OiYZsO٤[F.oy{&;h>:$}ݵMȲ&Tn2=z{EM/Ϟ~]{s]_~ZU}Vh? E7vCvkU>~q_YzrгrǶyTil#crv|I,Л#LJO8ZQ܃.:8m1\/!gs1rh:OYnu@2䂀˧AfWeoȕBqʲW ʑМciJ(ɨKK@1gjTF(h %«:s/e,ªe60 . /*yFl~a Bu\{:򚺊<̃H\Z4VOEBK=ig9ekDnwOfYs3@Wy?N3rejk|DMUD:+r忔ۍ6, @mW* ~i̓#s&̍ r.|u8pAHxE )R0!#ˍwҽ'.A&_H},eӤJT5m WM1P+ }X7Dۇ&AAfg _ԗa4qnONלYc&W9g{O$Nu϶elz,6]<QY]MqN2+pה}trcC>IWfUNEs~vM)phĻYy]U0J&5߹:u~hE߽l 7]Dd{~'[TT:T)*ߝ?euh'; sV:]uF8߂ZρU&=afLјl<-msІkު<|ճI" (/̑o%Gt])ݐ7y} .U_+ǁͽ^s:{oG^O7k@ґDڐjjJw'Eڍ|} }gawg|u.t7R;w~cDox])&d_62o:Tm,[znk@co`zQmZځksN}P~G61P.Ese7^GscSp3%{7\S/ִ|!=p!5Kn}AW۹48f?K-Xcr}7m w2)FlH}Du&f]a9?IW3iP+ }X%z,v-)m?s5dcS=d! w JҜyaxQ 1'աyj= u-+(Z#<lr\&*"lG3TkW| my|2ˤ7^G7#Ⱦ^ ,y܇ > M6'MDy&^3›-{/k=OWԋ|oVwsA?y,f>ٹ>:~ӌ3iL:68ЗO5$5.2?͑HcC+fdžg˱iG-t@n2~seVyB:.)uA\^^NO:ǩ޲i줾mSn+ڀ^ GpKh~4IlO*_|_yfEеɺxx}}q/Yυd6>x@]t/M8FOwnΕ2>CsCFJk8ZRAHy8^\՟\Cod0y9w֭q?a\`ܧ6>]^6_+K?}"6Z:Q}RJ;\Ni𣡍+/ ݊i~ZvsoS;|Jou~035z>V#lo?F6 UA(!ʑn+>LJFًZMzr>~e]'G;镰Ga/#62܍ؔH\ ֟K|S?2]Lf+nic 9Ŷñ7:h;c.y‡2:_Q@d!=|[6r:zsP2W=v]' F~/}ZOS&F~yLvXQ+lrw߀z& AG|!uIsHo6y4>XH1csO$됯T`vǚS;{i{r|l_%y˟s?L?܎z o|h=s;6? `oئ̺`2l E}nn^Hn֩y>UfS:YP^ q ʵ*x/||?-wCCuڈ6p[KnNbe0r41sRzlY7? x =">d~7+!niHxkNI<y|E};O4V{8Bco(M压#7=Mv#_Y 5sGÝgI:%Ɠxppl??-~qi.'>i \#,/3NOȫao}gnnnnn*7 iڞ Cꎗ$ mWXZO𷩘[.y@wƏt,L[FA6ưm1kVm?-Dya丝-;}1q9vA{mw$4vWCHL=ƧsO=_JŸ6 =x~~^O V;(q̿~GU?a]ZOSu(+!unxs8ϬG77gK]]YG|>C2T0kej%``F%t.R؎.XX>c[ -σWYYÊL7eZۚ=yn.#³/d?KuoV#YʉWkIݘce]ROwk̅%ȵz4xzrE79fpgӖRDžbUg.<͸߬wss ,}^^J3|^!]/ZM=_<:p ?ѫ ;L/ +~Uv+: KSC1)Y/QC'ފݼ 7r捤WYD=d7LBm-˦M6\Co$)o: N 1V?K׷ɹь'_jdw.TҼIѬz:C_;@;FN)g晠"[kMQԋ d%KQr|k<(mY]sh(-e6zfK{y`;Ak29dmZP_wy'y' [2N+&Y]nn4=]޷t uA#sUwPhpmdbvۮM^G_;܏R9a@MY@>Mgbi&kڰpn]CvH X*y4N܊{iU[XRk vuTWz\R;>p}C_*[>6e^k=-jϋEAGڪ$En^ycD׺$XhjjAF}v#>gZU8TT*M/5mMEvD]r6pu{V`toZxd9 -qN6TWkY(˟yHvtTj/uĶԁB-eXExn蛛HTAG\|H5NY6hK}ӖpTF*K86H]zlf|j慬/eV-C\Q^ u8v0uܒK)w(iU[}*7׋b@Jy)G{?rEbK/?Osȷl:2Z+7:_4V)zlI4!qV(53^om=HuWt@?ѱҽ꼮lU-{wr;4G|9 n{tI+0VsN97S̟n<: [e$gkJ.>;M7g<16e]Ss_+"u?[ֲ(a~0X/f|sX*7H69y0mk6'k Nj[{$ ~۰?3e|e=P6b%G}|>ֳn^_ciw}36x[Ow VO=CέFy7@^UysNcj2_͍W[ј~&h7|u!5G.zm1);)//X ZNLu.Oy}ڜozdyOx̌?Zbr7R&+eZXHr6h}it@g9&qަ<_Civ%2Q;!cr KY9Y?gʢ?cK%*Kl1N~ a+[_N_ۃMbzTNeٰ]xZU3g)@ꓒjv_b&7'eUkj&6M;2UlӋzY(>rGFǒ56`6GEؕHFa!smG}E^O+&5!z{102gKNbrPfBбˇͻ^[Tj3#uOMg G pI6 u1Kz}|x\Wn: +yyYurT]$oaK|Bsr/g7s h{gw'gta{O9_.(Fc1ȟ=l8?*~41TTvV\:%یed>6XK;㨽Q}gu)/\tnǒ(/m ñ宕_P޻.\9Wlhb_ y./ƨ΢}+(3BmU]i{s͛D&Vny[ymܴݽlcRW8'Tt9$g㳠}/9i?mݛMmX>Q*/?suz:=bN9<: 6TN呬tHG0A$n;5ED\ ?!@FXηLi5ǖVUz8Rʶ$rMmQӽ 0 ~A GCl w`$gړFǐA>6zCs7Wih;4\L˯G7zcz?0Cw65O;+p̐@Nҿy2@/O'ckYfGjSxstO4}y,}ց5sk[L,`o5^U96XYs#fY&yp?1`ߝGlKk Ўef\q~ɾ>FmeWUWǂ)cd? ?cv.rNfhfm64/xŨ|,LPθ o86R;TՓ7ľpwFJisQoa ?CF%jZn.vr{78k\>x1~2u񃺝&_^FָC͟989<dG )yJ`l#YS2^b f &$?fıϽq)0&j\8O9;r/bfF7g@TH?yVÈ<|,Z!r|В^J7FY P~ű09n1ب-Csb%v{):OAώF1摘:kEIr;YC-|68(F{+[|wt<dW5iG Ͽ5 m/'f :buW Ԛ^t<ւqԹ2e{85fPWmI/t ю~s ^k9Lem"/KQA]Eeː >ʧQ?}h}m7^[UL}P9y"x3Y/*XQ^9op^rh }߶!FU]96{FlS${gt+'QD6 ]O@ڋ̲j˥97Γ ט ,? N3UG~PcD/dڙTO7-mfeT]k$<g/#|X@}O"RojZP!zƈ5عokT۲\? z=hDZ:ͣ3:J;l5#ψW?g YN8O ğPڭu|ӗ28eR3m1C+ |= /\WMOw?~i+BC-OԱ ;M d|k pE9OoOW-s/oNɓW~KZ}P=;Qnèls#?w8OO7oXM;]ҕv{.Gt2oϪA?)~/%jܨЬL::&?yl3wXXخp3rp"3six#:Vg=Mب[&.^%KƋT[sauҰ#6-ļ^|Vi|ߣI,> F15~MbuN:y ]dvޭaF.-Š qCPxuʵho1|a4oOw]'GQ1V8mG&ݳ{;ƜXs{m]':F U?s׊WD2bR7ϳ-?9{AWΛ'=_G/zMYW94{ ,b?g7gI:>bY?k~.?p+Pe'8$ }E8M6H__՗7G=yR>~\cj$Ӊ6yo.#/b͙@ɜɽI>[3F.[9p)?xi蜒| 3xI`֛ni_ +ZYh)5bA;s.r+~`iûX:ɣbЌbFuz-֓Ӿ{}N6k\A rSt,oIcNn>9ۥxsd@KX6z8pɹJ*91y>9@pعGXLPt}ql~Lv(FeG59#sZú~W"w+a&˟Up+.~(yW'gw,["xj ??>aߎވ(硴Umtiv|tdQݎNꁎFo׺{S}X?J:s8>示.]%t@5fT^g}4Ʃ]:/Gc577Ļ^7%kq4-ztYs@p8.C)4%nI[ee-X(a^`xd5?2S:=.?Fi~ sb9gN_z/[3P%V.Ο9MR~Ҟ_TPbpL8$#?nwsO+mW2& QnSj㍉+}[ψ?Ԇە`:%\>/ h&K9yKy59ysB|&ankMTX1 g.L!r8=c\{mß?4ۇp?u77'775v>,=&7Wg(+=n2 3l9iWQa }q2Cֵ̮}@A:Y˲b텼0`rtfZWZn`7cE -rrz=zuOK"FLsuJVݮ[WrϘ6e>$گ߱ c(rryi9H G㼹rTa]"XR]liW=a?ľaM/[9X|h??J h? ۬u[,cw3@UDW?:}5Ӈ(8Bֲ~ TEx9_!IrS ̡FĶ zҽOc<^>m+_B**+o"ZyTQmQ=`xg+ݨg#?iCY.x+TJOC`+ٔJv}t;_O ]Ƌb;܏^8K?7J.(Y}f1D6ّӐ>lu TGc_-rlIz<qz7hLBvzDI׹~NcYBgT69&k.,tdq#6@;T3Xb>jϹN['"a l;'ғbxqhHf5DU|h1ы[CzRʾ :FBEWd8oo-Gխ`ݳQn[*=Ŀ +)F/{ƟP*ߓ߰F#RY }G$䜏 |@G>ͷ)]cѨ/{R[)ՕcZ͸2[IFqX2ZWgMܾIh,Y^#B͟y1z|͚wׄV{x񔯁)Y S܇{Nemw=+V؍P#]_#f:$vwڙ MYQ :Wf7NӖ(r!mRB* ٯ):7j;uuJ->XN ?[v|S=To3gzu k;^H>=Ƴ8NO.'xj'Pj{~G{"%6Yӛ^dU:nwYR6S#ΝbW wub#ډ/?B-ad(|ќ6VWE7y0ʹ4;ec~ Muږ2 ?ͮDL&TK܉47Ѳ}iv 6; |v lt^[b86xL՞tUPw e2Ҹlv}uƸwT-t1 Tx)d.v7Yo\Y sWDgy,M'K?+ V{$i94Dy8ކrE;tP#=nٹ`񌎽g߁b7ty55(;ҾJ1o&gŖֿ깴׍o1_Ps (?`K8ym\7 @KH_-4ӓ3ؙIǟ[r4_\O }KFYFđfss'f7NΚu~x|#l}5$[Tׄc琾(4`8[!3O_#E/r5 ڗ~ygɟs)X/CMq< 9' KMXmFgY>NrX*(Eu O^Ngw,5<۝{ YGCʐ礄o*ePZ>A;Odp$cY_TT_Y[9y1rn[9i1O"L~ćXG[^ p @Ly" )Rvgy?2WQA% &v@.g-DTJ| O20iߚЌHNy9:.PoO \MyX>uaZmy8(k(j_ʥk'W3_%UWhy.2O?Pv`<'жSKαbzYBX}L=)㹟oޟK"ywK=\1A1>NWirq`y8"7:PyFJiⵁdr{VѾ>̱myI/yiԱ$'lY]s/YVֺ9yz%/P#-W(;7? 9o,ɟZ҂ćfRw&e<.$ cZ77.R`J(qKI/ VN!Wa=Kz)n ChO9wPe_kOVt"o8+㚑tkl+7i>}Q+_0D5Y͵9X@:_eKsہAt. ,kܔ"uzouXRmnϣ$hRA{_oooxۼyb>:g3%y=b.1Y:9ײ P9K2uϓU,]R<8wDt*cl s$Jeyٮ-ض67+|Fi*P1%f$`7~BYssss#zKry>H*%Vp }u=׋NrӨG/3V+V+ysA7Rk%\o,QlqP[ IAmHJ#Xci1e\+xO/g s%V cLY$Vh# xyssssè5 ry;}e,zrc=6qI]ey'oڦr,,:%(V|iHus7oThPJVU탧;;_xn^yMa\?8<=,e 0p35 o{y+"sd> TxyX։+}Fr|yOW}[e r0*l45ZzfܹhoMMTر+}N߷ݮ>ֽlRW'>z U0nZݩ>HyiE矲w5S3(,v2ɎyZ?2_Zj>Xyd_ ѱY1'v~x ˌ ݒT5?㯎_yJߦs)ʑESr6S%/@(@hc ʤDqo/c^l@'>D^z虐w4GZEG2NʾOgeo}D.Г/ׯD(_uő1jI/UhlA'v0M(Asywkٻ#9`yL\'9M('p}^Ǥ z~bq.:jm'Z{ -7丱;u߀18$70JǓbO86kO8qKkgk:˛۳ziN]ӯW`U Bߩ_ xz#_G8CAYXe4ʂo au܎c+SzZ9W8 [^ɼVF^k0xP\fyE=u\2&A[1t\܇zQgGb@eT9vc\{# jvWmR7/Or{M  9j䶁o. eaTv&fx^ ]J)0cΙdmQLjm;U&$Kzq~5F!l}綺M# o0F261Huhf5)Uq>+lԱɾߏevd(/ DMn%h_vq\"N&lvuV,k863G/?͊qM.oNu(mg]aT|n*sO[}FhX4ดȝIЍ\9zrpGk8}֢n^=8[OoHJ-f4@L5k msXEϥgԴ#} 笨@rtc;37X C6,qƐE,ɍZO髨:/]וW͒wÊv8נf[q牦i Sk/š׉++f=Wx͗u2㊼0/1?dΔ#ϷYbvplU zc ƛ*$6 9e{&Y((O<#2l9F֡';"%6@gfzsŮe 2}xRq'3Z;\`c =?[W_uY/.B/깇ޮV!IjL#mdb!9ү VS6~\L+2Vs*ߊt9kJDyqyKu؟gOozN5C/eY|;t&|"k*={NG!rW:gLKQ@z4-jqe[_E:&kpoRFys=~kbדY'hMiTvcьaʗKt}d~-^uVW-h=,d<Ĺ8qzCYĤ$f8-?O.6srystQ˝P"?ORB}ly_Ǽ''y# ]㚁v2ӳXV䂞 t_+&܋y>euCXX?x H'fHge a{yۋXD@)p>l޴1z:C}MKg>Z֑7sqmgnl /WMKANm/(;W[`7hFZf6@&fn_]gɘlڲvoϮXVPFlPuK͔hk[eU3CC\qu9KAoct+Ȗ|IP٤; %1!֏C2t-` ss%=bX[8N#w?8xpJ ee,Θ&SukeX -{?e)|&(W'굧JZ/PSӋYmL)_=]X cu<3YLk]`>糦V96fi1uj ]Rg /55[(טbMhU~ev1-٭] %wnXo~W- m6(Wu81*#, ]v@⭱P|t86$gGۘ$f#u3N=ckϠ.6( rYZ,Ĝ1-谕kET.s!EX0W`pwOY3@"L( +Xz73(R$jH6oLVE+PSBi$W$Wu5WKJ=|$8 j2P>*\J//*A&QUY_iLvvėquT|y9֡uԵO:s}M͍*:\Mp,R?XQX6O5Obc?4]8 ~ -5,aX;v0E}`|׉ d̥a_Ӽҧ_>uqHU0Q4աr<&C4QAtT.]o- ^dLʆs>JcèHJ߶:dV}5 P}hogĬSm-n_&}G8 >g>ڀ-ԇxG?J@QL1سi"_mo2pr԰֬dfk<;hk%] hijs d<^X1ðK]fӕeڝuE <va{IvֺTjx&؉ޜ֞}џMwe0gmEr}p?_ĭ|ń3W;=R~Y>1:n\EGskHG?CHzK4쳔έsPU 8G\b}41sp;Kujmjdm%۶}1R1F0ƃǻJ,Pʦs e*z,#Bj0&l{/c-m-q-޾WlSF(EKb'=PuS;۾yƎ3RK  |vRBH( 8)/7*><}zԈƉȴ>wVFi)Ե6O Sv<5~%㢪WݾvY[;} |C:8[3\+Rlz;d݅TژZYyN-q6#kS+Wn,dX >q*3qC6̩_stԿCձcziZ׎S+s6uoc܁| 1Pw{Sԭ{iN1M- vQqΘҜ8p68X\|oƂ ֎j'D{~c_ڛ.T)gtzn߄R]_?,+vIJqG9~dWBl{'qˈc-Q߿V2ixٶ^]N]mRVIh#CG۱/u͖Y]sVbPOm {/snMm xLgVnUk%sk}qxS;Nk}< ['R^uk/$󤄴1_vo%%-m7/sTn؎}]N8نV]|6:Ku`;Y}>͵g6t,ugUxmjrs}3~Zi1e1pIz=hnL!ZbՙwSS}u鱪̌800(VǟBU^NB2Qu_GJ>+0|ΚנGi /YLVcdvlu>!F²Xۧ),}ekiuO]S\9+v ڔ.ֳH;'򜪙R}Nj>)c+bzB$iO;&Ӌ֢R+s6uob.\ 1PwT'EO" kaфBe"Ng[…𢄊C_=!Q>yYbF`x+tx<J2 81Tc*za}I:4se `NE"23&WAvkZ/XW o1hilW\Wo9PEŮkm+vqmI[Jl%Z~Zeu"NKrzB65 Rޑ{ޞcm\CP;̠eIRcXKmZl?[qFzAgcC܄]|%Ķ~Rg84VՂzB-^]W<lh#H{mBE Uk m ͬ9W+1(ŧ_rŜCmN*-}JS??i^\L~# Udm55;N㱳V:g*x`]Ruf~m)W )J<&hwjeB@ Ě}'pd!Zc~[:=n[žzݠqރF\hZv;-ӥ>}6pL`d8&>Oɹ.g麡"Ҝx@Փ U0LŤ`_J_22e'ɝ%Jyb^ύ˞?WN?  m^ߓڼ}ul[g خ<)g|oTzx5O0}gAi<Q2t{:zigDS5S)aN_sp 7a)BuK}ʹvy-1s쵙)h?Se#NS$/mz(Qfs-6CnU;E#Y -uZsq[XZ?rɺG ߋ}}/>q/f|FgSd=W+5k}4[ڈq~2pS?06֦7nfN*kj,HF}x޶^Ggq^ پUvH:Tn|cubj_^H˗n ۏj_'lƘU`:PU;%>c(^< %Olf-zigDS5S)8#^ M:Tkgnv)z8rP. J/7bHVI=γ1Ws6Jle׹zx{-b`v>rQ,sV}t![ X$q+igJoKe=z+ []9V%$[Qz8R"&63VN l5ڦ'U̮=!U:uZ2ݟ ¦WAǰ_dGpN$Ա;L緆]}yc>}V02GE!ڷ*FΘu ޡe5v .xxcixxxEZւiMCcFJ穸Rj۶}4[DNY`? "@h,τz>t3kƒVv.D%XRY n6) /!A#`?; f%Om;z kxK 随7_0wK>nOTN=i,E)n4YR;XHAmwnG8kH[(pZͻP&3H*OhE|CΪq=D[+U8Y;_v n9v3TZcam"VjLb;[[Pr.Tk\Cdq%_aԏdǼҚ}y`ֽpRgN+8:vqh:ʦPUցLp}|υrԑf㜌ãSne_韪|v^j?iGׁ^XCYR ǩpYLM&G8 G۠J\'p̭o}mmL;]-Ǧ(mqsG=s\kٸGWbb!v vT}:mҫ1AOc-=E}&'j#z1TC[뱚&#Ubg:F;ҏi`#BSdn*^WWurqyMK2g/ -DŽs^ f[QmƧ2+K@OꤘE7 8j/~9Ybe.]p_Um6*K}rwew: _)c;Q_iJԐ}YS7g.SoY{JֈEv?u6 :QO&/ꥐ4]+.mA_68٘iX-d8utmg muaFImcyzRV7hOu"U[w&%j1l:#kFs_cڼR58Ѷj?Gãx.]A 64zt`B}pr8PD%R;b)\t*-x.7pl6 &l 3qWl|w-{LTYkG6|~ayk$շϋT3Tl|JX.Hgwܸ*ڏMw;q~[c( WG|ڇM0[y/Ĝm^[괲mS)թ_М~(Ք^u-rjJbx!ͥԟq||/k[lR_l60ƛ \rl&?vi=4+'@jLa3εۼ*ѮR0&F\umc_6S[c`똼d%?Rbc Kc)QYXK%u§C:vubsUlu9Cy?uЗ۹fcs(M+AF[ej硹2mq5Rfѧ] 㴾PZOSgbZi}+^F5I/I'6kZa~P:~TKlJ5v#2m[bךzl.(*<NC:?Rc9r?/%]} թ[Gԧu9ҶʋJ~uc3eK.@{FϘPګY1X /'r*L>%hx0T2YIQy! X.ckvFl` M.I|_A?z׶#>[<8[^ς(d:`68A60|}'ŸŅM[." BP,RLMtj$>p<Է㹌 9K斕P}:Ԛ`%TYKbUbm"AⰚξ4p{f*\u_yzkb ^C )Ӹi=V5Kc6qL%xqku并U~&6gϰvl9.>X:\aogxK |vԋoUPFFy.'m t4>s( !g;چڕBE^J"ՙK9%m :$`ϕqfP,P]c+WUо5v̺RYlgw%޼o~͵T6+,Wg'ʆps&km:']<"PK>#χH&n'XmZد&Vۇ1Y[EyXvnW[Wmi:]Ԟ\/LSކY1h*e IRBqnMkQ/-u+h4=D!~XQfyz.e䣪;̥?7>e:್%ԭ16Nll 24eWՄ'[?Ft_R2Og +Go.wi9Iχomlfi΅G[ej硙F /E'4pEh}*SЧ ni"SjEr :˨afT[f׬FToϚoyV/OzqXB v^2HE~$Qo=JdqG'Vw>ħk[] Z^Hƽ ?-+%vcܘ=?ӗ#6ޚK[駉j9v7|Qښ\f`u<.s$>[ ,;BxE\uk:h[p[myj7p86G뀼7h}6jse-r Ct]IlQTb8.G]}L׫֝Pi moŨ~JezݕxWԧ"-WgK3wx]`k3M?Oeu'].Ӿn1bsSkQ8tWƻJ1/΅@EI6m].eHR:$({owlcQG[boS=(98Į9Mb[|6V'įlT{-1h/J윷8jq6ԅ?u}r~lw}%4d8Xd`A>B2)O  pʄTǁhYL4H^HlqW^ _楼CڏvF_m,nv`ծgYڎܢQa Er-&R*S)/Qǒbzkb XC )ӸJ7vKɎ\k:)1cx){[ }RUBCq3Gsfg?1=vͬy[*5ߎk~{/꒍xRg.tW|- 6OL:c,eV^>伀{te~8ډw 2\|b_!CgX'!uŞGQ97GMNӚRBb'ڶV=B UBauTֺT֪[]w kW=ӧwy@kCt(G6xH/e&! FGm?X}̧u:~ߠ:.5v IǤ>TE=dt:-~79lnjR菫a 8&fJvou'YkI}=}Nud\൥MA~ Oݧ[ t!3Sw5{c.^6zKH=鴐N6aMږb$ ~a b߆Y~_[^}Զm}CzW5ַ X{ʥNF׌ƺ~ﵔ^ˋ_3a6ݲJw+2Fh[7\eֵ[ZanyMn0*٬G .m1}7NP r|ENj@P1R]j~^^꣼ WK}nh>*ݔ-%;vRrUħxW>Rvm|ڎ.>M5^h4.wS2]m_kJ{ӧAlݹcd\ry M7p8Oҭh]"EIe90'G@nY8-ßhJ4GCo6Gr PT2m)ŋ=NV kY{mY/dM4cZRYo7ÚcEXm8Mt:#)} 6M3ϧM!ڲZ5H&|P}٘Syn-Nxy&&[[Ѷ緉HkĿM+TڃTI {uDU<#KcM&T._7KR}l'ձxeX;2RkG|]O8l;P-1HJjY0u:Tn t,ä]/"` D3)qFduĢ8dWu'Cz!}y<+J`+`-4=j a>) fP]c+&Y]KʤOҧ*M 8qdH cSA&yLn82kF2 64`xkg5=)p:Y6յt|(e1](ISAm*&}eLz $lYVU-@ћS>NFbb95\4PRJGi~*hZ[7i6 3WUM'jXLco1G0h+gnh/QKui(sцL]@ lUjII4k/cZ_iE}Klf;=XjSxfЭ6(CqvPuJcQmZnP:@Zd\)dZ^OI7V޿䳣6|!tH1iуN1|F}H0 ihٛ=>}{O1kp]@,Q. sYRa [;=,z>3~1i8ʹK uT!'2Жѻl7B5s&iB>b0V0p,4N u-8|DMK1}C}!=n͏iFv)E-Oč,X ⺉x z.QeD'IW;-Sm'*31cRjS:)c&_>C QxGGz Y`]]Jフf 4IpA"e8T4JfQEaCEca^hgƑСhhj$b܌X;DgLFFIgƅmt7S_R[`NscXJPzoSX{n_m~)ܺLõ=Չjk5⊶cCէɄS|oZn_dmXϒc *-Pcu}OmVWRjkx:0.~)Bk# fj{9JkQߛsJW'e7p!vi ]BؒE?Xȁ$mi+M. e#LlBHl؏8-nP}f8d$hrwc$ģui]-BGNΗ~1o~>.: -CiBQt:Nt: 9y' ynֆ`& ӆK!޹ڀmSk{^ٞh7[㿐91͎8&S_M6l{d_3#1@|*OO{_q3i Ru6S'a+Ym*ٗvNEFzqjf m<-Bi}O'h;_.bXw) IE+kPj/fJR]lnŮc &jc8{28l;?3+w>Ly#|ȧ7O'"\[tLԉ(TVeR/l4bKvU*MpQ/u: w7~#ɝNt:N4(ڌlO1y#\ב]"_]vdX5}d4V^|[bNuY1UKQֱ&ˌ^ɜ/kjkm0e?K|C]Oh'!ly\yE.q<\=/ ~xb[OH+C ?#}P' %+֙1Y~L ߛ~_ O3hj; Yϴn`-tJLN3ɟ%7 9Aj\B:58ⳊymIx(u:Nt:NG|:u'sx{,nGns#r{Z!]'2Ƴk{@^[*Ջu:koKB>3_,H٤Ҿv)1k(T6$Z!'u0TUuؘuhaO U#qNZ{c,}t/K8mď7}s'ľs\?/@/^|sv{ӱʹ-hNdojV鿴E_Af?Zc_Jc jR ݧ?<$F.jzk<5mcPlLpRS; kGTl3~9Vdk-?~iR-{7⾖RI9n%Y1%vVN? 6\().#-RG~Ge Ǵ7yzAai hcYlPThCt:Nt:9'Jygvn}=T9jZ:/ZO7^CQ8\JחsfW_$yܤ=t%+Xje M)#EkqA`v/D<ՙ2p{l2f^yz-[SX1?s/]VX j6V=!r,-Y9<s b9a׌wne͂>=ii5od÷;WZdܳ #}nH[l8,[kKuvaW'pT 4]$} m:'Jd"u_)(9Iu J^R+E4'ENLG@em)#q,8<A}sLyqٟ4 BRk}SabBq9V$\XE,𽢥u:-vCgK˚@^"N:kӓ _v_~bt:Nt. +8_bŬskER|:}~_Vp0c1fZ+W&vvS ھ es#޵!jlSϤWQx]?bk<.p N[al@}%>b{e\][[xb3 N%ky6ۼ 3b Tֱʖ}J41\x6ns'ZZn0`~?VI-BKLc' iC|),=Gן]$t.b_<]o#~|[:2N)-1wl XlxPO:lu" N~Qyǚ$<$< ;>~Ӿ-64YHWl윔Ʊz8Ag?)=a` `v| :FHy-ɡ|Т)נ]X/h8wΤӗ\qh2I E]r ukǮkxy߰RKI*xeg%{3+_._N]3|鮗@RSPwYeF봭 '}w +%COf@ysxdM\ '.d8/|)k&6ξ=8P$>)i(.j)oQ@A$?!N،hޛ-t<hxH3O Kɖ}F#]WC9u~ kJfLhX]+ ?ҩ8rפtf c-mZ؍(`SKk9}^eQ,']5LY_{ K[ W#d= 'Hyz:v㏲>[ӂ,Jk.Ui_{l;Ow_wS3Bxu7 %}r]6%["wb w6uxٷX0cs|Oi~ s}R\ roǑ)مpe5%M} zxƂ:-TZ[G7>wdv&YiAU E UDu*\ǔ-;LD,o sq}. êT0qLmr?&asqR%6;o/8Ft:Nt:#}g7W =榠 u/q365&I%: <`~յڵv %FoEOw&zyfR][d#~C_Isp[B ׋|g w™s3_𡯛yY3b>.䦋XK~r 2Nc&%o(N碘5D(SZwa:=|8Xc%OޯyuT{~ianh >5_=|/)%o'nO߲񳇇0| 3nxН_˷3Nt:N:cg|wMn␛7P:Bqn̂s윂u/]iYY*{N,_5.{;)n\bf+;?[*גY2uu~v,evHʲ5 ZbRgd"]R^[Onߗ N &HX{Z'+fD>!3YJl@eg1: ϋ MZ`;]lk]1^Dx#Dž X~e K= Jm3m'tvz~/X lxX.u>ݸJU!J@&6d}6dGP_KD*LLnF.d<}";RIWŶOtגeX-n8f\!C(;k_1 )~a՟淆?[c>Byx|E;8v:Nt:3&޼1<Ƶ3j҅S퉦/k9ЯHe|h߄iSPE'餋"Eqn)LK*?Xm0'1@x6J\[h(ٻH Ki) lx̧~R28n7]Im;>-l`]# S[{N`"xڋsJsH\?7FE#K#[OW]:zc ?[t=\?SA+E>TE99Տi!4Fڞ }tTe$pęk[bS8N8N>mĽ_W=/?#|`-F]%0 W G>-^:=6"|8" #V1hAyOt9ǗuJVA EMAIJ% #܂- c\SM]uGG iSEB%blBz Oh$4 ! =m;s$%!sE[?d%x¢  M&#?E?!?a__0<4so~`3c?ou_gbѷt-D$o5a\a=,/`C|LݘXf~ō0;w;bn>{wWo̘w8<;CKt:NtMyן7_+'C\<\J\CqbW% ׆h{z_R8<4KrL}x_ B\ῶqr P&ձFAQZRb%,6ZDgigm߹HLP'֓y:=o-zǂc#*V _$A*}(?-CO&`7(FN΋jJt,c]@CZaތ@O΄Vs A^|6#(B^"cN\}v=eE)L#!ꈤ|m fquߓp "c |n`>8Z:jT±V\ lEe)&fq0ZIX^$U'$hd,vG5LzNH<-9nмgvb_zeIlyAp}WDN(*Kߧ{ȼa+8G~#qdaʗPs$0gӵg=9F j~.lk"mJ -uA!!l:.`6Yg3ه qFaW"EGfid<{xk[O?mß>?w~n/2O{K̂'2cнdžP4Ã0|?Aρo*ʲy9cnO0g}nX|2ax-;\~D?|'SMk#f<õ8o MhNt:yCn $\E)BOt /!~H1E_xE)i`b/tÜBKmQ>FaeDΌJ׬qLIq?2ȾtYqo+9yildd7 h]oZOD y7kx;mKʁ.t}l3L`0/1&]q]"Lk v0UPD֢m̎B\$Ͼ0차<Ȧeo^Ik\p0[Jc i[; {f+dPe%ށ Kxpuc?o'G^"C2 E-Ϗ?Q'> C8>xSH/Pe?xpUn)BDUõwz%`94~n0~c\C_nq</14ꐴc~=f9[Bۏ旦ONt:Ι#7Ig;ϦSK~LY"3&xsa5> 6r)B%<9!=q ˇ}?;=C: ̹ <LJ{ |_?8Ԋ{p]w 6 <,cD/3g=|5b,ƟM{Y~5)#o~6!!>ׇi'O|G_'~:E;D1Nt:yCM|ymA:Phl~\rr-'5)Tunq1i]R] agX'=\ _%g˹9i?TOubB1u-(eǚY.Gv<|,K$ẊIK'aC[SjzV{rѢ>y kjV,lb[n`l7נ+##[|lZЫ72kV:za`h6vȨn?tG7onfl9gXܞ͆~`ɮ4G,.2 Ylo 4Kʼj?>\6w|s)?<] b1'<>;)O #D)x<6H?2q?Oz SSct:N vA#[ā:[K)PqK|Ml%'_8'%5ׄRl]4FRiY">6iQuMk *׭8m\@v\1ĿhNqh{%gr$}آ ª&o4~ѕcUG 5(]<t:~=7xUPXWIQӂzzh?ǣ3'=W;S1qRuOwqP~sR!0mЫ(>u_|?K&/?E pf5|7d_덙8v:Nt:pO _8sGRNMus ) Ӣ xN/r&Vt@J[9EySHoFk`G@v=X'qbwMFyH}Sj}oϵk<QrU.a(QO_ +6__gUEtJ18q}]]3!| NO  1}_I) 7+u;N SɎ2U넗##%>D!Igaqѓ$vtm"18uty:.ʛ&i]Gzj/T0[&\>A`B:86>yCcFr1v/~赓^v¹~9k^5-l{; /닖8v:Nt:#7p?dsG:_\_qϱHG$]'|3s{ s:l< ?kS(ihcxeO>K - ychǁ39kZo}N بCGз! gpk[EX}3>zH7p̱*辴'c.cҀ٘b;*:-vP'rmKl#$·&}s=KLצ"b9BK&fe@]y1WYоVxz.\kS)MWɪeZS*:p?b [Q<-T }V\7_ [JWG<8U>/ZLlYͧCѾmサ^W=T+}|1_ɎnnH NQ^woh10'#ob[n0փ óeDe· &_C~SZ=0 ̓W7sg[-8?3T]CZc3:a~ R/ǚT 7w-`}~Jc50G6خb;+[Gi;#!WnKo8o7og'pt:Nt:aIct8-Xik}:Hu4m# Q0[Cq[s׆J6-Enmk˹/Ӯ%vT+S#:/8~DbuY|ZEpG+#oe'X7ĚtF \lVCD56INB?q Ҝ977p4FN̴eT:PzGxĀ8'9V2,ԧإ27x:ڲ5¡Z_l4c%WF Cusë^7p9ł9]9(g `sH>[)ñ6KJ}hךC:|,MƳE"3ejd3`j3T1a/2bN4X{׌tI6ƛo Sq캘4N`녮wl2.O mr>4H_QŦ5[r.3~UQ궦bF=ژVsR䑎ۅ7pt:Nt:NcOTf^}Z&=ٷ@k5/+@1E[Gb^+m.B>]SHWq]C~bzxln5&pmw>1,6t crvnrM}۾!Mka ڵb ¶tK݀s4,ë|Pl$Ɣ" e>ፁ ś[(`%e߃^1`dUi|J!.$Nt:Nt:53Vvnb Q URZM|gJ^ײ |Q+ C lǁm7ݏi#[4)[DmMDZ. +cz`Լ5BrQZis8·+:$}GrgM#$mЁ;jF ; ˰Cv [>쿧p^?MPNt:Nt:{<_kd%_żLV6'W_CH^u% 0uߠCtAJJW3}Q>c[ A|ਏ+ZJLœ}ٸNzY;Q7Fݿe+I|h=9oD}O>߭rvpr1'rd:(XN>ĶB:/IMRoz0>v:Nt:N\ upItmW*ڴy#'"׸/ f-ALT\ٴ ^|q2GVf}qd8lT++'as vF.݇y!D7/ܴ&H 8/#$"|3yO:";cLe;a~x,Kt:Nt:NRvV-RrF1ypf <rFx_R`ls=jv6FhD)܀Oa+Ҋ~J Jcn#߅u< =o56([i'2xkJ;Fn= Jod #OԾM ʏf :Oڎ$zIKU=rˎ}UP_x鬇lEٱGOII˶&k)})[9>Iyk8jox!eb/8˓bMR̐^;iQO^ `94B'oH B={X:R.MBAs;O"!i\Dܷԓ2S;>fE˜8Hee7pb'|GG8c&Hl?;.ݖKs}^cZѫjWabO ds>M?i3B>qbǣ񨎟ϗU=NJzP#Ģܶ/%+kI9NǍϊ1cslEʸ-!5jn-c}?PipLo|&ԍv)5jߍPQYja##DŽ-xq`Bb| pbEi~*Frh3 bꦸgؘu+i͹k/#ՙ #5lx?+LeB4ZP%h[þP~>[#vt\l y~mqR}}Pt:Nt:8b| ^Y}æ?PV>?LWļ-·F8LİXП]_pum}|X?/,#3r|58Ѹl%i/v?}q,n!CX/q Laa8%2(tޱ͓t cRG -~P_fngo [iLk?:`T6+7Kڷjж"g?Bot|I.F 5%ysz#Hj,ܫ2\~?K_C [q:PM;٣LA^kW%̴g'p趙.B۷5l8R%: ~LX|GſX'ϊM%?fzPt w|+ct:Nٍ}w{n+ϯ| kKk5m5:n+iSu:ZJxtejעvzƎs/`_ ʜkC޺kEڛO5ƅ1R; GLH}jڻ!Js␭yf)HUsџfu}Әbn5ħJ)_}:F2ntm q@sd!jݹ6 bmԕq>ʬmϞC {u)?1e9h?u.,-OG?h_Z(؄OM>L=mGuL3́CXFG: $9 "NAz=1^j}[i!ٴu:Nt:NYq~-q{DѲNT۲}h6}O|tQwOJxuL3v{a8+r$OɕQޱ+Eϋ;?76$Zi ^%"N$%fTAkڵ} hˠ>'8i3'?. :z)v(#H<]ˇBOڝ_;nL5שEX`!oۍ⚽>nt:Nt:r g/Yu"=Z.?]`LvBA5F*#񕐵٨O~ Jg\+J iPU"B2mOAt]2hY>A$ZRY&"=R )Y2;F@=yo+/ˤO. 9o5=r% Vvat|| ;O"%zxxu3YɹCxAS9 sт67fQ Kxc>Q#tP {Afeb`zo5{u:Nt:NYKrfu'ذ p-RA'{K'l0`~ 0t'bKrX)kc{׽xϊ&Mjq+ؼb C L }OIVͼER  >`@7Ms(eH<ƝxwY'XL<삶 c'2Dρյ)>΁j%NjgZӥk^VvBegO>hY "N-Ճųo}#V".%}؎ $A(]W %OuhF6a+Kbr(ƾŖd kM@{&ky+gHӘ$z]t:Nt:NlY{k4]6H?Ȧne c 5hSUՄc𘦂VS.pt$I>E$m`U.;B""lR^!2|MFq\eǴJ:->'@ӔOe^z=N #D(P~bزx}l; lME Qu$:PKh1/U3?+Q7=n]mc[ؒ@+v͒gUg “F#*9^})RGܷ'k3&L$R^HHN*>܈_e#([>@8n|˅ S!cg [&397]-(ӲMIRVƪ A^dt:Nt:!ΉFVFEk?:sJPx | "_%^ h|< o?"T$?Γ^}-U*_K쯏(22ce1?˝~]"r#UB'2Aؒ-Q:~6R%ܷAs`.&ˈlPB,xcm6eE&Fsڰ2]GY hŚG[ڊW-_BEĎ]Ej1ij%BB/%yb6c sX}%饂^{[A Ob$/!uB[~ƃ@W|Ażyt7"Nt:Nt#/Yl`\0HKe!ii+%ˤ7u]EZ/_U* YZz/IVOYԍ"9pDƮ5b K~"ouƾC1/qFS8J}<#}Y 8Rq&<^";7+U$ߥR+?[<\4ߛ׈( AʯN/f34:X!%zY*kly"s.?Dr>@`vysc[צjӝx~:c/yr~.$Nt:Nt:/Rٝ^ %R׆J׈$57@GE-} %HSE$m9+^7 d\OuW'NЄq)-($ꋠNܑCzqO%y"s1 YW5'eiӷ" ٷ0*>i96bm2z߷,_tx1k9PIZK\>.xDZPϓx`6rΝ-a|G&E1 t." ғNt:Nt:ے{<KS/uFD_ùm*/d8c2מ#2]d_x}hJzuŢJ_RYNKc);OR0|){qP7w/L7 pqvF:38/5~g1Yᵁ ؆>}?Fj"F:AG!u= 밍"x?.—(!$c(@|B%\ خcH23Mϐ';n| -{φ{w>w{x+_sNt:m>4sprs?Ig|C>mciQ }9._?':Dop]:rέBJ{OVހO71_B| mR_1ӌum^z&_@3/s%l;t1QCْRbqg攆4?[-FQ\[u8U[?$QHm %Qimc5pP>ymdN(oDVHg.6NUՓ>5(>c"ix琱U}!Wƞ֤YkvƋKʸ1!T)U. K[@idEGƕ`}uAՁɂV>CGV#OlnC-c>ڱNHVKm_V|_cQ+naJ܄XqY+\ɠP+ǦXף@˶Ğlk6hQ,pM&YBjVVPss]ϐ>Ul?pZ'@ A^5TDGT0P&A,ٰ7$-MҸ[{iʡ sЇRjU|x ^{eD_x " o =!@7C<2H⫶|& (v."ԶMBۆ.^\pϕ*xf}uX& 8:Á7ǬqÂ=ot:NܬፗF n\?E7-x8D'9X |WH+l(Im0S_e`{m% ׸0CWֳQ9ۨu-j[R[2("v:'olu-t:N9kx0%xlUst^`s\Տf&!m˵ O4SG: %" %w:I u%~AKzKW $H$ZXOV!Q`yᚱ u"?c]ؕd< 9ϲzғ<|Q|/!zoN; XbAuW_{0_:ySeGlw[+F/0˚0>o8=+;bsd=ٺ|ϗ@ 1r)FNg)ٔهNt:gB.3Kk9nȵ_iނ:h+-FQmC7CNS4GdF5Ғ4#>Ymt0ڍ?5N/E14Cokmuݵ;c$~\c;Mkk5WPi&k|Mvݳ"h ~9,tӱ>% To\gx"% r,;5ҙ_:},HCN"7}<+?0e/?g,HCNt: az<ZO*xs{»+ i~J2cz"NΣyCk^z3>H+~VvئB碛1I -Iu1JGqed \k*߱ ZHhlSVX33lš@t:3>z`x w7v6f7Kb' ?0e WÿWj[OO^ʂ4t(Ct:}+^կ~ۿ?iP:t:N9n@3? l쌲eeJ }-K_3ڊjeZZs\#ۣe" Љ$`c|2HŠߵr̽S3kE&Ps |+ωh[VpxqѲϖH ޚ霿7p'ё9y:KH,&2}pGHͩvو?Ӳ3y`ޢ5Hٺؼf*Լ$C$rVFQSuP?ӹ~wԔAOt:NӹxIP!jNЩ+!ρe}z-[ ]/ d:z}Olٓ~]'~Epct! tl9m5r\41@$T`͐7rcNڈbe'0Jfpi1~=1;yX!G+|=r[Gq\xle\(r&x4 jtOx_OhuѦ?ӹi?3?OhuѦ?t:N:Aa㹽wG3kV5Ki7 /nI S,o+^}%LMqr>:zƇWzC0{NKe:| apɳ O5:XcOlqĻIXG=çű =r~u,$wX[^n]N'ruh;\21DR&=e8'Ը.%Z뵂qgpL$=+B[컔r({gڠmӹx/⢛7ANt:!oSyx84}BgPcT_+bm УsI &5\#"v>ژ/H6."#7ΠL|pE_ ׂ(iFs+o9=ISu m-O1x;ztiG.Md r!l_zkJ *!=kV|QԚ%X!h2e}Uhq2 DD2m)¸o_>h^@GE"cNX Cu|(ɤYI(4QtW(v8^!Q Bkw/ ly1XR} _!KjUs,[bq]V%Va[|.?&LݖH _Ditc-Α[_~A^Ӻc[S:r5Z:5R-ٷE u퐃AuTv* JϦ@۳) o'D] 5nZ w!R7 ݑ8E?u?t:Nӹp^UѶp\Iwogk\IL?{9w{E雩NK]̑Ti%}ҷuZļ$gwvxsq}ɓ3Cw˵삷Zd%KB;s1F"fKEET )|ZCg^.RqX^ v;R_N.: e#7^V%Z}Ѳ5^Vzֳbj=[؅m&NgSFt:NPWHY\YMB1 HA3ZVLA#׵<9#Vų TRْQWDSՑZv틂 g;M- _#]hPe 5 (MƩBi%P:aO։HUY ܕ XzB/ me_!+Y;/"sxm ߼Xkv0.y,'n_J6"TUO>E2wyf!h5'cև5oyzK%y>kޏIOzғbj=[؍vpux?mO1|{=}x[Y9}{cj=[Xʝyf8g9EEdOomY{x[7%/t:On~W _g WNG/±=$]qƴ溈Xv'OAKf[;jh_J̭°x:PGd}Nf~kJ >HY)鐍[-؍1:2T9 d?ۂ>14&$ӟW)?rmRo? 7cj=[ظWo>o/^[)շJ|OG=7D}t:ܸO?nkK:r=ʊ'*^ZpJll58쥛*kdMQ"E`E1,p%o?OWŻF]lX]Pq"e11'gH [tkEܾ_JA+&Sv`SD:+5dNɵY[`\KDEl g붶= ^̴\Fw ckG'?,Au6E^,/2z,x|<+2EPxw X>7;VQ6Fhؓ[atV~rڻ^#Í|ssn{s_,7PuW PƯ>z z^ÍnKߎGw۠zη \o{;*kxËoꆔz477,џ,r=7?z?m>ﳆ8,ܧmV0I7<#YV.P ^4^b[ǝS^}2Zcfl岑T'cz@SD:#zS/o¹9|x/% /-YKۇkfܻpˆ[ϜoPg_??7+|?N zy-ч[^}78=nۆ۸÷|ُ7<ᆔiz-s)Z6vIXvK\ :ڟ5l5s/LeD|zF y7 ?F_Pwq$yGTv:N S9_$>gxsm>u"zFvm:Z5* qV}Zт' \a&/ѲWx)7Y,BƣΌ35䚜.6#p^<ONSl?=w0LOHO )>y5E@J:AgE $:Ⱦhr*lCcǮL@6Н? #Ӆm gsw kr<q]O5]+>?\eO'ȩ#-+<-%-H^ flcs9=ŇQ:<&-?Mr%ns&[*U'>a#wBHӞGјI3 m 2ml}4y z})mK{"RiaQVr>cj=[ؕ ov!7/A^z3:.>|g~CMYz󆰶*?sVGi\ck'.:<⥀KyJ֧Z3NB_(+^\nepq'k,Gݨ;S?+@pXv|V֤e%s`,ֿs-_O*|G=z61H]"N3I7D Ȫ㈮RAaa,>^/\h (bsrwk3 bjFIu$БXmT TRnN?Ge|/OBU9իmKTֲXZp0rTι܌ 9}yΉ]@s-jNEZКt|m|ѶK½ɇ>- $mjgKX"HP$"B%yi<tXAĺJ'L)vF Ћ{BA4H/jcE"|h2ex mHxuwxSux!㢮ܳ'~}W w 7u<3O4|7BC>3-|ǝCiY ^'c6,χG,o߳t:Fp|N^%B?I$|Y?5\ڈ;nlp+ )[ۧCC/jt[IP-f=uX9aTMLZ* ¦XPvmT?X!`5PXVlv^r{M_fqkxB5n"lrTHiu"^X>stZ&w i(osB-r.|I(DVjLk@QIF PJщ߮O"L[Emhj%dEͭ(F6)fQDcN2 1!u@ϫS?.̉v[i.۫H\uިڄ^HV̗ ߿ Yc3+#iebd1fxᚎc@lIP z\D{ŧ>b%/=dgHſM&4An@>0sd$,X<%b+solacn曇B>#I?2B|Ǎ_+Ԛo|7uWmJR > gU-sboW)sΟʘ:N掋sog}c\pxYʒ?JOEWH4иL#Wg_:B> 5ຝ-%Z/95tD7%)NLHRw֙F}^b!w"{~MUYe779AqA#GUʎ6'dnwV1 PЊ՟jd>h ]#Cc@@$ ;. ^LЋ6irȓ Esrw cn9h _j2A*yxqy(oP7>Í풻1}]񆐻w,V|S/b߯7YUy]|G]^z{/mOO;B#/qƐ4NWk.1i㦿Q'[䡿lWԉzo̞tVdDyd>XX]=Yv!q<_Iv:FvVhgT:fz-&߈yc>O|1pFv"#-> qGСo(=6ip[ԓ3PoxHk.'I7mx@n Oxrv@Z 7F}_7>04y5} 7}`;­ >?ϧ Î Ƕc}[8;:Nِ/x_s7WbrpgSt7]K_-e>^'z3Poԕlf'^]%G[A݌_Qǂ1ɸ$=;γ`:Knldk\$R5ɾ[-EڙґA۳B/$E׳xfvH] ~6G ́+:BS<94"sxm gvBZ=:;&Þuc]N ž聧 '"nѓPz]I6L=-VMk'cF2">ǭ>y[5#Rgt,z-e5xCtXTGN%~=~`nj-!p6&p2#tܞ }ȕ?rO(#ycGv=yOt:痛nI6%>k17r睛|-SO^cȷC?oz<|榖;_oG<}xs~5/z Ÿ<+!eYO~d>{x[ӟalV 7\4W؇m?=O7NӹS~.~ GG0 U15Ϯ_v[LmύX}G+Wl$B__ʰ&T\Ur\_(]x0昳Y_RYKƘٔfЉ&7oEdjh{t:l#H:sS o9a3o :qƤ`k JmZ_Ò赙tIL/F~_P~B¶F[.9("krwYmߧlA}"vv<OdQcCԭu*B7pr>[ҖtG6_W$6rZݡZiL тXaa]+le.uH?tu4%mokL|yoˤEV?_:,mbR]eu_n}*?Cܨƞ|5ۃ1Q9>Eqn4^Zm5x>@!?8|jRlB '%OI= kkOi̵?~~*:MOϥޟߘpQo9/B̵g>s/An[NtY7K?/\%]~gmy-k?cn9:^}']k ͥ\t:Q[bf ?wVu16);"lWD9Nt|m,'#}辴 K~z0;T1{~eP=;O%?'6+ORW+ۂ5sc45cmO] ^Í?oUqzҹj [OnVY`Oۄߐ?+dKX_[c8+ ¹Lu2_*F6pr3_ڒLnp|e`']2 cA/뜍 E-sQCstŮkxf.qd Eg0LtWĆg R֝ O^N %DL5V8\cJm*H_ߊBOCd K =nAj&P Kh؇ؖttӱ/yKbn7ot.{HӱZ]$p#Ɨ~<{o-~gt:Nt6yQ3e;_3(Rt:Vps}x]&7;_yNQU-9y!%fQXw y?ZLY}M^1e[. "v&p;!()!Y2 OѶ5yK2k޲ςtuTʋhJC[Gy6E_"SnzkР$Rʋ|n!I$U*쎮j>Z**^+9feQ_ԉ:F LE(qڙ&6MA3ƞ'ފVm3m?1q\+r=s4kYE]-iQy&uE?>,$pO\ _Vײ`l[ms>?316ȱDS/mwih |_?>|g(g`5` z֑`EdXM>gF"('0uU͖ Ş{kL|tUS繍%0*ç>lQ{#_KOxUmN۶s2]6y#z#6q{z2aW*)2?>o[//G}k_o?Ut:OaWcb̝/yMo?''CN}~~o{ìÍ~GNt:Ns>'TO>?ӿo4yDxmO?c=?ΰ==ULSdzIc ikmplOUd ~cAcCH-MֿLI}阇xj~4k;DwOyeW g\GˬNBƵt|Zz/cN4.<\^vmx_7t|ٗ}p/t:N9K|?\g~p{~nWgGǒ)%ۢf{}+O'&/qܼ;|;8jL[FNP'4)X/E۹/)>Eo tYM'}#MHYdxkkĮDI/҇DZF^t\ۺ hJۂ8uyԩٳ:g+sѤh}ORAiYW[]gt"M8~ 8~i۱3|g >kL ږ^3ZMY\Y)i;c0ͦ_:VM|uֲ60Z17)]i\6&\t @MDgr 6<{_iZQ|tǚP5d}u;9mt[Eюvn< Z!5YbujQFgwܹkrn~闆=yWKX&h[E7g& wÏo~I{bIiEO> 8Gݑ[r)09bX?>N bǚ[CL3 ][041y!6_Zgw%ʴC|ӼՑp=8+^=C'o捯nm_-^qW?14?o^n{;ruH ~NA re\>l"=ׇ__'< 3IC)eM7i?͸;Nsݰ8o?߇;~6Es'pG>kY9ܼ3wO؂B8EtڈRcߞgOРiH&f&lAG:]8@-$&TT=5g7|H4-ac<V/iukb ejBki SOly`.϶!Ik6Ũ~=Hu*}zqQ,enrBv\R3)"I''iZ> /O5CuO|!k񥜀mQ!h[ ayeo )woB A6gE5vDi l͔hAdgjRJG머,I eXk=xLXYfnߛ|n>h< ׹Oħ[j\8P[ɟSj({[2IF}Ê̑_v[Lmhq 2'uHƴOu*ÝB)sG\>ε׈؁݂p4-/J oT>;7pL8mLSl\D`Z^2 ~qؿxK=eXc8}'jވ #c8S'7qǁn+podyG9kKcs7ĝMnLGIP(<(=1*j%*.kksX$m큒OnxjeM3gjLɱI@uQod6U hY&|G7 U 4i<ꢿaׁ^ۄ_6~h&M#/Mn8~Bj3Ƙ{f&t .ʔ3.քۖo(zZ3DX{aN e&c}NX׶ArCRjpJ˵?F9ׁ?8u:jlOkj"]t5a?kPCOdlsu')UP];C5KbYo<|l^Wۓk?S}sMLU NJpb 9S;Q-; Y1yf&ж^vẍ́Lȍ'=F6 P s:>H=~sx!}$ab GL|M*Ĩ%m2R8p=;Q"ijS|xeQp;yL%cQ,2QBlv*ebz*/'_Д<ِ'x^j4Jz> _˜}7oonᖗ÷|ut֯n_w=K}H_9-> _\xIbWvw҂_@P}/ >koo e {3tL&ix 7 a)?S+;t:;oGosF^ï?p7:חp#B&tvMQEƁ-cq8[T@:]/*>EIx̀m1,=ǘẑ2OOS+WX`ch/ٌL<'dO)׵2?Q7# :NdJ6^C:VG qU/*٧- ר`+A<@}̟=2ة l (? *J4:o}cjBsn%ՋeZŗHZ;Ѳ:H._A9&5LƫCE?OtP[mҌM}@ܢ.cDǤ(GW?#M0mOS'4[#_z&Y0YS|/R֍z^c)@QYYqR{WP]% '}YeC3AYf(iuQ}B;sU\^t\]}e_i/6:7X^ĮO->՟? Ά/_nbï=)wI1Տ?gя>3+WGJweqw.+˿\@0=Λ'c1sx;F''WhTOax3<<$sj]uܝN~]?7:tI䚒?©δ{jU'%PF}.\b̴H.2r- FΏ:6D߰-e<_x\~#`"_K|ıeH^.YL>#u:ƾB9|ye^NG 裝p G}؎I6c(1.UJ_~Dn@"@ʕo5+.3OɃI}ZHC4- }8ds'Mqiŋiglk7~kIc">mt.><Oz7>PzYu±ʾ8Lfn88o,(h+Aۢ:kB:lSro8>;/cԝ 7ݭ=vp5n2fwB[[1u8'|pCLxWݿᆛnwGM#򴌙ƾt:NsppE IZظ~nx.Z!>x5D/TGp@'T[iְ}N'>JY`_i^؊p>l<# Q_LlKDRQ*OfMԉl˶uI ni:R6` C5;"![rmm3P$F]%Ǔ=65i{׏ h̐pSbES=Q*!Slak!:}Ps1 $@ͪyaf ϧV?/4H省9Y+e2vW}W8>s!k_<<o#{yǾݹnLq79-7K~p?'>>exOr҆Û3*7c;q49qw:N{\gk"gI .ۅM#oi/6qI9mp-SnLI6^)`Gli8eyz輤S+5Iܹ=LHl]/`CsY =94~.&̑iPk,үgg*H*򒬄jX2li^[;?VΊ3YW:uvv6DA%"yA}}}q|:Lo l=2O|+#y-J>dQN) om@ZY3Yg%l5!$vQb,cmJO`~N6?e1w8Y[`xk_;ۆÝM7[{nG'ngi~{W~ w x0ԞlMïŒwb2?Ø;?؛9~Gt_g>' 7 7<O7-m'~ axOQ{Mt:Nlƴ\SkL/[!WW!}{/z"3ǜhqt갍XU`C_\vqlU!ȋ"HyCs "s\kA9TB]SC s :ڲH9 d/e,jY_LĕKZӔ4X#+}SDb@$}Eߍ#5Wo s=e<$2V;ސk-=92w,@P9T|:1瘼Pc+U&2l6AYXO:x o\Iy]\뤾 z!A>=IOֆԙ57vʍ8ڬG(ٵ:Ǡ6GTn#;+GwRqꫥ71 H>)%oyb<㎘D 1|p Gw)ܶrnϙ~W2wsxի^s~?>.0|pO;Fيk}qH,t[I?Zq( -hh$7Hs-|_xkaMMz2֛}_Q8QkěS_>XEyyt?vI΋)n[Z֎:D,r&xR&fj׊2袞7=(v-leH+]ԯr}m -kA3xp18e8֎^_Úb}-#}\{3ƵѺj29xXS$Q_ohf>Md;dͩ&aNJ/ʄXQ@_lKpisnh6c|X<+q_7[ԶlZ XQV}g'8QD{C]Y JDdݿBٝOOs}oM7<<2[?xv_8˾w[nO`w~Ft:0)9 | UMz|Anu3ig+ m\4#L vc'ZuBN^|*ZC}8i< Z5+zEmAL%:݂}{v=Ɩk[ mEeH֠}Xh#K#^R^vvDhWbI_4ֹ6rޖ"쌲}'n8TGHC<9kΓ/[!CyE%`E6}hL{[~onE ΦyL{7>axsioyet:Ns.CA"֩]kDMBZb#:"2Zdl"YقGlc+UV9:z̗ R R&Fq$xRgӎïx3)oCuY|4{^[}')L_M-ׇ\ײ~׮ut<lo&<7-=7nxIsc7:nNX{zePt:Ot:Nӹ~??rt_5i8ZQH"L@|-%BtNs0: !rZɓ6(۶>;iҖ ))F9q:?C:XqnQc5fUk995g5f͹s<>aQ#lX^eM+Z,zoKlMm  Xk!>Tthy;>]V1j4dJMqۣryҜhiRu5^.Sj1n)jQfOm?kmf\~F߮"ٜ$E5|\>~9|YV9 W-ٱ9;jEM^k;d~'0F:d~/iR2ͥ:fv,KJj93Ҷ)mERl |lŸ6oѶV}^#6=JQV}fL6fʯhwRhXUmv:Y©Uue63q:s)6%4+:ju:4S'V Nt:K?,JaixlηL|~|f]E}S6A6=7-[ָ\ Ҏfm#Ά77 Շ7Ԅ2#t,jX%혝#u;_WK˕Mb뗤5ѲMg_y s=xjPfKF-抵&67ՁqˑR7en;dzP_rI(0n%LutYpy`\N\VK4\KRw:(kc>;Nt?+1=ϿL)K/V]6Tض9y9xlEʜzsI¿&JNK`Ɣ58Z_rcbD|YJ9WaiLc| _iE6P306- WQV ^[$q*NHFem'vmzmmI:VT?Wϝs|` R,x 31auNm ["uKB4}i)[pqq %;y Nt: WS'/o }< gg6qʟYaK ag[ť'}B}Osl*koycXX%ܓN{]$ٲ[V` jc;dTgJwĤbhעTϴP[S\Vc@fW+K_!p񠞊F熍^)i3gu UC躵Yjcl;+ W6[51x "msQGOIC)0þm?AkmR.s֟A1~UmQ>ϫAx[_)`;+JmEI䟐JZA9AEQ2+ qsb91`,j> Ͷ;7\ /z9P> >;Nth+Aп%ϷO㟜 ksSY3)s/{v]`Gyۮ2`lEڤ A1c,_c 9BƱXFd46Z/+m%ۧJ)6J4_yI:N2K9>v]K5 ,m{>M̊PZ*([͸'LI'}XI^Gc]^X`p}Fc=+\-BTuv|-kR?M{q6&̀EhGyRVDlƎsDt]wb=6Ů}h\{AZ5r[Di}w1Q e}qՇD[LK!YT\БB[]NEc0j\M8P*//e@in}ն8vJO-dj| 涿Hc-تdqZ Ns'su|3'j)'fیU -xbAޞ6V0c M7jZ_uYҾ{ obvyEχߗTt:No ?{$ .T?X|ʶx0~us!sa#~M?m;\"|864Ua wOJIjWrMa:5. c2Kㄥ//mʶ7Cx6h}y<_31qBI%2+#S!Wغ3=EhQSglx5RR״w9t!lfh*oP{% M|yfl^~ہ-n/ ^TXOr"8ouou)nd`?d7 ("M>`1sAіmo A5_v8P6ފbտr%b OKh܊[Ŗ7JcSxh; F<ןc͛&zK~O־ЧYt[iK|,k.X⢬S>o"@zѬ~͖J,YZ-Ug=+ocq̇Nt:Nt:`ABj|[& )Kb<+%Ƌ;%BZ`%?sB3- 5 ]=PZg˔~ S_k , h'phضJ)Tm8/􎎫XeEDq]NveSA^)35EFeZzYJ6Ko'RʣuMSSµ=1u`nGwI;^s+u}lŽ܈L8-" ش>%rM1;În6^8T' tgFtuІOPx. ?!4@\.{*}hJʾ;qQe1ڬCR]>N?xִmt:Nt:N'/3܍ϝ*žV[:O(=}݆Yz_[ĞZkįAK )9#|@ӥ05"(C6چ[c&Rf l -ʛUkM%Pi"ˤ=RעvUq͜7)(QglVb.JgaB3F qRBM4y%tCۆ??@g5[nH$(SSwq{ 5TuL)v,U>]1"%,-t0d҄QڮhG^ev&Ug=yoF*Oɶmt:Nt:Nsl>vf/&P 1ieyIiteThgS ^UdNl(nu*ϒ坟ZW mI 6iTIfd[QFH\$vClY?aE,-ѥ6uȇ|+O?E۱c˘xb_߯˃fâuk%)em@+vcflDl[w =!6H5x_!t>}D ٺF󁴢VkwsN;6V+tN6l~~54:A-Ow:Nt:N+=3sfay (4[&XlZu0lEݮ6 Ty9i1@5&}+ |}&l%Qͅs|mblVݗoeI6 +4nW FONRdԏ+ÖP|ono..RAP7Cs^8_JdgM4M`lyd>6>eU'~j:d4OHt$lю ش"qGGJVzoD EP%})CS$z) z,J e}Vܷo(zڈvDqasq;K^~Hr;[nw3&^}rx9q7-!/6eǚJ[U>;%1_mRX8Ms✛n-)Izn*ZS5]!D|i2Na+۝euob9 syQ{:'̶o+vt:Nt:M?6 mv F7 UY;`+ԯ ӘڅU&߀a $[6.0.Dq ׭yJfm)r6ڭ[8n^<-yPgSoK6dG0G"C4\O_f8. %]+-ϒ B^ {9*HMXGe;Vbf%j|ǖhWM b\ v,nkƙs4 ķwĂJ~TS\(rx򙵱o􁲢hp;vX.awN(o^s>J<[5)E3ZV%CeVP;i;%bENt:Np.g2{޾|LFҒ|sy=P;-H x}I[^%"([KM5HY=:Eկlv,Pݤ.^`fhJ. (LlCl:n| 替3 :-Q0V9XrOVND{ӸÎTF$V15?6xR .7/ı.oܘ3;Pyyj*dvFI}2(ҟQ5⎊=`;tLدHƶ2UMGrcID9ې~}(Q;W{m~}Slɱrﱚ v"vc H(Kɶ!:.K2<hfbۋm|l]+f &}[ U-]TU*))f It:Nt:?JyyZmSCu lA/>]J!~ygޞ4eJ 6v+ɌK l*&|+bqzr6A|TE|_Φ5ߊqQ)n*jWvT:dWZRj@)/ɉI}4bl:Jhy(^ſ,Kl@ 7ƭ p^R{H{I~*#lȇ^G57dHx?Z hi#I>M{fi޷<ݮW6 } y". "`ٯT.^FEAK*I+: 7oɺEPoȼ3&4@>WXвb<{m ]{Kc@IpU@;Vhlõ9#8!Q|2ܵ}8KL:Vވf>Gˣ #mqߦ%8g7{NDr) 1h)?1[J~H>⛈_oDZ/mNųɼ,780e]M@}/ f~( EMnǷT=k9Km.E}b Gڊ(T,IK~ʐ`Y(oŅDZ(RbԿF~k gϣV^+V{ IϕDIRz,?Cܮz CmH_ٵDd62|Ctm9;F5xM@6!aF)n͡Xa5Mk=D:`VoT5S=$L|6xYϤNjL$.}73bbl]grs[dkcIp*Ny[ f/Gaى4gB UNd؆kGo( 0oJs>b}K;ǙFu |GhB1<8jƎ)ZpiSnN~~GiPM|ۈ 61#Fߦ69iYh벤~G 7p:Nt:lg쒭deVۭsmVǍJmvcm}_n):h5OSj K 6.P? QZ3Rx4>v`8Sq@uomU  9_ivzF\5|8.2Xk^oQߪcereooп-jq&;-&BX\2(NcoF -#q"ӠvR=mWZ_}bnAziz}1%4:MR 8oLBTKʎڮ(;A8 v]:a|jRyoq㒍]kV| m5|]\P޺(3dNCkmv mJCڎi87p9jh-G~Ӱ bͱdt*MX[[ej.K@ot^yNt:Ng[?|nϱԥO#*9 `m?4EA?E;l:j|zݭOlj>a9X܉!k6_be\|o x-]s-zfa _ "]ے<~Iq_ѿ-jq&;-M(S?_ךgCZb5yk>F'WL@6!l***c[jv wh=[wʗ2/ӸR&Zjwikm`XF=xKe0h5KZ6O-ǽI|-gexmi$XJv$`&'ƶ05 ;h6϶@)Z|')Nt:NtlLNV[M`'SJpca.ŦtRJ6â!Ża?,KnoѸJ>jJ9lG2'}nNתh$q&Z/8sۦ辱hxH4?ܶ _5w]?v/S]Ix ȇ%4R:}&!3͐ʔy<.CUl nHC*i5MK_q~zDquiNE)&k몵`}A]b)6\&O\}p o7hx)|7ç$D1?ik>NGsNߋ\ -Tx ^ok)>4X^^Y}v?Tx?@ 9ܭ=yW?jcNL-ca{ۢ߶{ܵۻ;gS9^4ba+ef}5X'fٱa wͯ%6 1qESo4oRkg 5*\|pcp[yGφ?w!y󏆳woe.>nW&ğP~f?u|ݧqROZP=/TZ=?>k+iY)/]bW UHIYgXË(8X|)Fȫ&&u:2ex%%UK&Ķe|6|u Fhi4qC0JEy֬).jW}㿴YHAifDOHyXN);9ϫ(uK{ w|,|NoÇ7pORx/OoxGә+"؋(r ]XəyEs w;bmV.d]ܷG>}\hk UŹzvƉ/QSsEٯ_3EwZ}XO.NO%xpqeۘҮ~k*(3{,e1{tlkK֗#ob5ph{V9#pbnoc^ϵTXkny1ne~h[&;k5ڎɘc;kW`nDi}_Bn477bp#ÙPpI=Enm&{CG07#qӆ>g]|' ed xxgnmx'rb*1KOxevQWiY2dcfI67Վ355B,)z;?4F꧔,䣨Aa]$y^[E[?Gs fXmy.kv^օ\)V%Nz6Go3χ BGu˧aޞ66n  hOS;!% j g l?ٖʚLk/=5ɺ>=R6̺Əe|σX&ߖmv|jmHVrhv|mel(4E6J5> )~^ǭAZj4(/v Tb&Wx:*Ht kByE/RqS{OpwRj wB&/ƹ C //>F)7Y|Ӽ/q&pGC)'o*SBRCӹ y1|W^<:]nxX6K;Zsa>|p\:MKSx*{M4ύg}cޜaJNj4_X⿴Oe=ԩ_{hMk0o9'㜘kRi77Əɨe!\ި됗Ԍ=Oш>ylڴ3Xil' uvLvncKjRzh\ &O 9*rwn O~Ebs?t:[{a=5\÷\=:'v~!Z>g\ӟuy|!^hiĢiY_܉e}hG <@6 y)R vmfK☫mv4L JMk+_Y1Xl[kg 8sh+Dv gHOo ![ o- h KֱvHluD:%vKjQ)&B-3>Y\ QRTުtJ6u$! ZϚ)+2^=6}NMKZ*G"\R_>(d:bb GSBYEc"ƮdsRJ7p*&9/[H!Tc聳,)U)6|MŌq89ԠˑysO|,օ76\Ϥn}럅O|b7w;8Lw^N_S/x O~'/Fxw[N7HO~CzwI"/ϝޛps_ 4 3ȓ,Lѷ_ m.]~m?ٸQb"7s/}qSR㒳/̍&p2^a2 _}7o>hoڍ[Z[3oОS_cQ(7 =>0K hm)SЮގs 7O ~[ힾv[b w:xI'j\w&/!C${njAmL}c?Q<6Ә?~B.͹(4r΋Uħ ҶL(Vl '#Qˮ >_c~y3\;E/8qdB޻Ie0uOAXFMB?)~ْPv^Fc7)0GNE~kouϋ ohMop'L[wZ;P^ -D'k}̊du:Ǘ'Xg_ Hٕu\ ,s3^`bQ}գG3s7 J[£FЋx27WSw>W &?sӪ 񆘸DI駦O2uO> 9nX1^M{umk4mYV&Ǣ U2)Oڮy ^-g;Vt[LixWNrmMY`b|&1M} b7gq?1wb#Qy>l.5S(=O8/wo\yiy4uZOlg̨y3i/쟊M?"Vrbk(/9ccZkhvZ1JaSuXv۸R_(_RΦm-Qj(S*aׅ,4(H%:|q|WNZ1\=.Ec:jpl|Xm_ކKrP>Hqy%u;Q~CYPŔnZTk)$mPNE(n%h.1OF VɸnpDonϪr[N \m\^ )cFCk f pcm-,x5JȶڏRM5MD}RE\ݤ5kGltGqܠLkpH[)zonuf&(±fdmGQw|)^ >П5~=MCϚ|1اe0o(?bc_b?b(>'Ç3+g\:}=}ĀM_Wǿo[xbFX,>.P pFM#F=B-ۆ0/OńoˍB3꧟x43c,D??@=7t՟Y*'EVB(_ vmӊ^Jm< 67Ĝi/&Uʲc@V ż9>K36iԟ)Qg|xƳ4~{1<_?y*o/>?UXs?c ϴ_*Ϩ`]s j m-U{ivndd>6nm8H'!+5)SѸy6FU!8.f W~jݚ޷,R5͗?2ɜD:WH>j`Jc}6:&XNOMjcO|cuyjyz\<0mA+F\yWjrʕܨ|[GNn”Ձ%0d.M!esn6)5'&bR^6&?r^';p̨gˏQr;zmZJuk۔!"i$); U°㣩g:nOg,銴NIsʨOSm}੷"V|ʥ?7gTC?=㎏=~!|>[/^}^z"|6:?L #?WM'7}0|y<P' Vnj꿹/v@3*xzyR {1o},e [b!<.OHxG^ *?M.'7,?| :!g$CN&%@}}tR8H45=y0f[T3ޫ.?7K19g68^ıc1`W!V_y65vp,}Oǰps'ם ={cx>XVUS8!wre ϚքL8g&߄V#O_V1wF[mNi4s΅sPڽRI Xn >Y1O!OHT^ɞB}iq0 갦eZt߰ia>rh9-d1s\|GlOc;ԯĨAIP"濍֍̆2e 9Z"LKx[M˘>,-iOHscA>6)*!RzmRFBi\WX+h{xBWӖ~5<7Kc6-^c[64mۥ <ecK6SױT|R|DvpŖ~PsY.m"&?uFˌ>K\_Ȩ9R@0gh\A:Ԏ>D4:ڗ)5}1OLVAkoHmLy͗Mė/?{{'iy ~(I>pCÍ!_¥3-!>4/)y'hBܠrON? |s/oSʰoiV\?0?7\&^No7by['o4ګ o~j}C/ϝ{ryc\ڟ3rVlM{MMet䜙8^L0=W;,=LЪ8kAe?bsɒ9'fKrݙ… gTl^{4hXۺ{c|VKVmΟuY8WSeKyVǩ}&s?kwbT^۞U_ꢀʧ,?5(@R!ͳy0?cx@j\4)sO/ R[42OIDATFb~qdۢٔ-L7;8s%t[[Y֜mzN<FyHsWvnU*C1de"fuaWx^G#ṯO17eUOQ(QuR۴QƐ#lqgC˸d?{v}(L–1F ([1XW_⯊=j7B<*- 徑O)LMUọ|. jh~<r59hŝ"*1OEX'^g"&ϭ7>mSBmbv1sjq*am"}`;KnŘo/oفEy-{w!:ϋ Um=~txOc+FJ:KKQDŽxyGeǺ`է2 ϡŒqYp!Ux$jL̓xkz+c\wW|Ͳ}3.qB+8cY<7!__ixMp-GQ벤z;[tt>bpHI\7q,nxK጖iE|v'z"<`{`F,F1. YZ׆7|p\8f46@+Ohֳcњ&/gqo_0&fZAܗ۪h nF;e l?%n)|k$|,۵(ǶoM?QwŶw,[S17Ϧ9c=Qmo0s&ǣ9>K_(/~n4`>|;N13R[31_k~gC;.G+qvMovB^s_÷Ӈh/$>ٕ%>cA~VMJPO56Ogg}OC5=>MV<-RS47,֗ßTXHٔ6qSXwSYZy@BVmj]dѿxQFl1suر :id1ZWV8FS>lW 7 bL)gmK.'mKMR~Ineu)oPt&էH`wKiOn>0ڌhU("H *qv2&>E}yy0QqL71h_k[#W.2&n`1?V_\ ut:Ns6^d8#, 2@۲s|ʈ]o{-Y˥4Js.N%xJ,%iQeOV@۩KQN1OPg۷@fid)hO6UctI9CV\o&6kY?V؇+U2vu@qXn0MmpqD^D4ep-D^D%XbU1%\ԕU%5e n_eMljcR9u7hdƐdnta| ~{ *o3iEsۈ-ڭ_ic=rx%PFfsK%-8`]ӭ9b7phW"+cE={m˃v}_tAC }jRvk 6lq5>BH!ԟTbNO<+.gĻMI <OoscKu:`}ue=٦-ڞ?Tmصx?shFÃ1%0GCVuJ!bжm巙>Ӣ2;Ne?/t:NyEy_ U ѹ=9/RS:l4Pn|J HʠvV1%cl*1e,kmMf9QFHK-֋gI`>f!:&AHKBgcàYQJm-դ'j\6XK9I vº*jt~rcԧj :͗mo>(ӗ\|9ʱLTf.{tJۥnOpJr rCJ"vIK5ُ?-gx\XD׋sbR7+8 pdQ?X`# e5b97~0}0șQ Fw|hp@5:14~Ru:N2Ox#: x4yt:NglrpTigC9/RbPgM=6!1f>y@mrA,[41mR.S[-gib.ЌG1gE_L|nIS^X}Teonv\^)L506N`u=QhN6b* Ƒaf.J~Mc-oItu)R4XO+n +[ƿ~ѥućA9 qĸi OeL{4yGmHcɯŸ qKcjeMym6?#VoymQ밄v$j Ӓe\F(id)aǂ\^Z17h&;)u >TzP}2n̗2lkl.j4PfێVHc%F2*Tn$PHͷвj&kCk/}_ ˔NKhR]M6m%8Nt:NN6l3t.^,HY V=q[ 96Vba,QKAVc lkB' *o< m ],Z*21Cɟ)F|#|%#鈥uYAnIiyc*~p?hF}2Q,鿍&^#sC9ҔO O2(qHei~%` iaK7qLAimțǡMՊU(!kJj̪1%|jD(Y5M744އW;dA1Kh`PfUxȶA~5gYF{܇LZ|lIѱQlu|*c ڀJ]Y*4rZ%8h?q~IL5HJ)mq:E J ;h.TxIz`"lZmۭ<4.r0<dKWKb# twHm4k |?׆ /"w#A&뽴Bd9+.P!ލXv ^ƿԗ2Mp}[LQ)]2%S{.b\[?O >p۾OTCZ;Ss Ze( B#<0h ۣ+y6"o7'^EMiYLwNFGt:Ng {-} 5Q{ria㏯yٖlI'Y:"~Fk-oy+|ʹp-d`\S: 6>c \VMGrtIp (Q/vOYd<:Y$c)cjc2EɗpT 2b,23 #'Oҵ9g)umcrduu]MfsiNbe:xbSq>nC藖wOPyj ҍY_!!A%Wځe֓|5luU_h穱VrUC´}Nn9d*vhy?$N.*^PfiOed+// /|)q>W:4]Y\?G%(6)kE?FۻA:. Z/X9hDZez\5Y+ډmż8i9} 헇7ʍ\G!&Hm2 KXR-wJoG)l8&pjk hSxn2`˶MSꏭ{чgDc N@NƍrLkP$bC)14Nc/Cb]{4",*#Ql>-pSR՟{ d߄t ڴqxc _3Eu،q7px6Xih99`L2O!bS5ҞXTutċr,Q񕵿W7;wI\jl&BnC' "C"}%mՎnӬJ!?»-8x+UyF=q#~To H8&aMlL~B~l#[}NfQϗq?kcvn38Kq| s|&fmqTVWPȏׅ6TSK?h9[6K>Ԕ7]rG84bfbⳜ8MD}?4ƽZY`T[Omm⣅ﳦe<9L*'eʗҊ)-?;Zg[lULLs1McsWYpt:N'ys<7çpSnTxw yE)`|z1|Wnt:ΕpAٟ`i9o_#cPg{<%qv =Х9 d9i^Kh)WV>˃a%֏D|H-y|^J޼} JK+Oe}0馈jͷwd?j#'l[-QmwCf3f^޷\uS!`jKj&(;%~l+2f7Nt:EȍO۸:]nxX6K;~FtN8`r2ZM[;=odQ.Ax ; U۝XXnpA͏sVUy)Ğh;:%?},]l _Iiצ)BI R4O}>G~4R]_-ŮMJqj#^-Ŵ 8t[yыEqd]ǴԞ*io[Pv,jx?kʑ0!*+b_֩OA᧴ݛs@<͘Z'o蚂]FES ؿT54+zhLLMV8캌I&J:j(oe4-Lӛ^ =nܶo; JsNt:Ή?Q񞧆 O<'D $v羕ʟKIpx"quO卞шEӵ#/gd^8 N|ƷRݫ79L4|siG0Hf{-A:6/EeVm>EzC^ /Qqwu-@Jq||*,S6.X5Pv(G%c71a;k].frA|V}[4Z ۖs **0X=LG;/96 *07hJh[5ԋunjЌ4h'> Xjģ±?FSYn?+ ZGi#ZB'&hܸ-%ʂ&hS Dotyc{NtC?qӿպR5O_ #/7k|o{ǫ_ / DqM4p_b|.`~nKm&/ɍKǵn:y27< On0럞RWn>eC:7qD, k½d1/%t:!s zN Ki>eD j$I:~۵e=gHǽW)n4/y9ʎJ,xEXrOc*fZic`v ^KǃgpiT0Pٞ>oɶ%ve8V@iChYb̃ ]_ާ8%`40k~hZ v{F\(3R/'Oqb E䕷j,{Hcܔn4]nk}Oi^v&7i䑴i?gG趱Z |K,E-~G]e)٭3U3&_EͩOj3W;v'ޞzlW4=|j۩/K7m!,WM^U7@}uy6gQBė6oB$iw(MOi1岺Pihe̬)3 Plfセļ\:ajt:N' z>ݸo(:Byׄ[q 7_n /.pmׄ_/w&pD 987B%b.qMoF$eY2.З4=bFke1ׄwu7]|̡7rLb1~s=bxk{mt:ˉv kЬ5:F'&vc<2FfĞ4*qtڼV`4SK~aSZJj͹[+.Z8~_ž )^;.Զ6˖[X:lh, |#oRYݾ*zik&&%z !VM(z$]f94b&b0p^}-;693#IP} a]gQZ6[k=VL2Kրl: WkOB__/ ~|XJX?y`opۙmJ3XzyWM Ѻ^e~螐f8.,1 mbNS+;UX1Jxş}8[8;Ns% 7ãV4&|NpJc+l_<9'Il>LHSLci!Ou@k9 iش5GKlԘhnhђQKZ%b9_|2,S'S!1>yBA ftid1&9c1^x͘vޒk٪Gu+bhU<L5Kuq36MrYYmڼO3NK?G_"s<2}6k~'7X>7q=Se]2~M獝; ie| 5[i/P^WEq\EH[ټ؏[ u2J"ц}~1czprxoxy@(:xHޞ KG^6x(y*Š1gmzl[%0IcJq<6"ŅQ*;nLՀ ֩qeE/Gdf ɑFuΕn-u~ƒ2v Cujdct:l}MxBg_ ^ vMΜ7 ٍ vGܼ;gR ɊW5'G??BnPWT ~?G19z< ^lڝQm۴j& F.+ԜuW/TR)_x6h~TsYRv )Kɶ?Awn e^ƦRjq |6\=[ROض<oe?ZX2xӈ/~_xU(ıc|TtQǦ$Gя3kZǣC7nvmc1F2sVm"k:^Dc.:ti<($T([7k\M ܴۆZS_2*ဆ;Ŗkt'񝐅TˁaiE6,ve+rNsy06Mc]7v:N5xE0?ف0Obׄ|q ȵׇկn~k^>[O4a|?yquI "AÃTp5m爛OS; HK61~g% hNӹ<%Qۅۙy!Tmغߚ7i/~Ǫ|۾Fr*-> |}owgpD>Ĺt k|Xb}R5 ||[1\۱1;i9nnۘJB^\>[)5{ S.%>JhM} ƭoʾ,c-%[G{YC$݆jr.(UUcK1r;a>H&9^+!8/k!OK@9?nH/k{KlS>ChavEwWlhۿӢhH6cE&]B0*KYO`n%w،c4CuTئ:.2&,*eJ*͛(v:ثE̜J瘖D•7@rK{{uؐt:ptx7G|D~⁗?OM6|G2ax)ώ3 ^Z+nN9b|pç/>l~l| gg ss 4ׄo1[Οrt:|>py|22`J֬AQ5 '*I7ǝ굚|~)&F4<ˬRe: @V^Z·c]BϮr--&aT^|j%u}ȋ`Jm#J 䓲rH!ЮƃunH>ː\> ȅ\}\3ݞc`8tmb"bhWjuqhL%eUshLpK}Z7P8}Mi7.H.8hj5Ӕ/ WZ$]jx]Hy'}`SF~>m2Ϫ}{{8<ʱjiFGsTaް2D=4.OßT¬CㅦZsZ~6aǓ9(1__*|!6:xڴcm66)neiqmN>q[iYԓ%t/¥{*_-㦛n GOO__'K6.\NsE'[|p lt:z--}V0_IDʟ52cUm>Oeо=>͟+wpmǣjq9;'F;dNk-;3oaS _7Ō(uT_d D% [ϗzܟBPZBu-mpZ-'hזqQ1ɺlbۉzľۑ||LUܢG=ݒ_~uBei\_ [dOPr-3>k9f}pH2BS+m) TL#sOkUd_*WK[ڦOYkc")^eWɏE^RghSx)Q?KPrp|\mh#V>{Ponձ4ii-T<(r3?C UXh,b3%8gtXJ}-:Oj_Jm$<gG66k#Z۫Pŀ "-svlGPV-ekۗR;65b}(˘~VvQk>k7r^ܡʦz1}sl&~ұFZ=V/V~qV˨m꿔NJbWơ6~õRnmm9ئ]Bzt|ѷ f,7 i0vLu%qeE/Ssv&ner]=n^q%Oh17uK:8xَca(ULλE8Et:NSOϠ'YFN BY9qXmfOV-UshJ~#S>~_ߌ]r-';Am <۵Ӛ&P?-E8wL9m2vuRz>RNyX~Q}3)mPS1|”SX6&D `3SEGBIGl[(;f5NdM7и6%uIWl?[,HzK٧yݨl߈exzsqRTRyۑ=6x4>om,d}P|8.ThJ2DE 7 m3wl;b\\Ms?7-Rl.`/U#tE^()`1+<ј xce>MA[Ǹʤ"n6+eN< ˞fm av'W@= w:o)a+6Lgb ҘtpjsukcIEfM`e5Sc z>^ŒKp*%ƎI2'X4v*=Ь'oϩ}ݒt:ۢJt:Ng'T^O`D4C+?ikd|'T ؓ'?:a5"ZcA\Ij6a1"vv˧m\kD,ZZ&ZIp!B$}BF2* qB Ȋn-S~<./m1zq uqUFě7if}zlʖʰRnrEÓp4qHj[ IP`:Ҧ+qS{)?/Q&ѱy\Av K?ݼ,"`5g}:7MD{Oܟ,D+V`U牧Y2k,c2A9}6gX gW>-7C;A)i VDKY,z1N_ 6'R'Sῠ}sM#qS$l\mc`Y)yy&amNO#ηd/y~ٰ͡ki-%_Τvgm[U ʗSVĢu2sZKaMl#3Ҹb{bClOeExKnUpշ Mֵ^|/iE˕R@Q`j2PnBT?Χ\r*JvU,`[)ǫ7d jب(+! ))qS ѐ9x${"d,4J"ij\T Z\wj5P"d*X)D/-P& DOlZ)NNf`ݦT@p'$y!;|I۠_!#WY ^t u[t'qڕ uqif .Vt6 9qYԽLٟYY[6|t:Nt:NsEV;ǟ@xыߩ KŻD ΓYT-7DTSر*cU/+-TnEhIkcE҃.KωSئKHW<^Ibޟ>i!} h-7ax*j=.?e }J?X`3&Ŏc$Vu.B}{J6"a\KE/-y`_Yj oױ/ƱYbL@c~ePp?c^ۑԫX{X/J"Za3~i;>ncQOu4*aϾc6-֋z)/ئ!T_ MDst 8P̰ELXQb xS'tsHz ߂="ćَ^SQM^xCwt^cJ;x6coowSsg>??)kنpfB%器1}BNIv:Nt:N9g*YsipltEh$zik,9kJck6kdi^+AT&6|ۺ/ [+o(+k~p SlB2)ljaL87K1X[)4xQԖnҶuNBbӾCi|,Z~e60SӒБm|LQ_ >Q} ./kT櫂ˮ;kTJfnGzoe8MߠMj}a, ܙ浯}g>qȅ{BxpsgM+Nt:NsrKX]9ϋoixZ5APߠ6osvdz B,Qi־=۶$Oɶ=TqΏm%v_9S)86ʖ[^bP&~>ͪ %cDA%s6_T'(Z/_z&b2ċq c^iĈou]Fa$ەm2g Ecie}\1"MlOEiTj RmܘWdin3U',@Dc ɥMSҜT6ZUZ&e} /;Z#࿦Pn+`u Wxp$_a؃H C&:sc83!rbY2؂EUZFtضtײm͍_w1|b0<}>u}S.?~^EvOП\y$u'bdiL ={ 7S9eO)wgp]5cct:Nt: l > KŽ8 l_PUNYKJ}!?$'y)+_3Z_q /}}ǚ,.+J7b|t|Iiψ=h0ԍsqJyNj kzǺ'8d/zԏt}P3iナ2"!>IMq~BؘذQ3B7VĎOS+AЋXp~ecAyܡf06l tmA|[RX$T}; ]/+گԷB=(ZUl 3J:Kj%}=&QL>~[tKڂ_g+ʉss؏`{TQŝbP#"|}o4bǺWu *Ğlj s//em=17]{$\wkϫ঎xs+>Μ3&ׅ3g-Z.zOvƭ?ΚqwڋO y>\$w}(Α<>Ӝ֐@:|ž>8``Nsh뵌vSk9-n|VKO 0+LuJ9etγ|USඝ8&cwhȒǔ_ۣ@Ψ ߈jTNyf˗TD1]4im}~kmN-/Q @9Sv.K#x\4Ȍmk 12vsr4M'|Rֳ p |xNp1|Ev屯PƙO<ك^?)p3C!;7n9>/63 7↧gr {­\]Û};cm&NlO;g]}F |gD7oб}ݙw>p۷R3ggb9I8I/b5O}جpxD%JyTF=>:e!T,׫ TdR%-F/2gJZ[v8@G8!;(b[ u*wۚ~8O1u+]Qڏ(mzI;//dm=1g _w}niυoѓ; =]0ao?o {1yNnU?z*%җ/wg: Wc7 ӻ@n'~t:':6F{{L.S?;<17|ೋo@7Obym3+|NcϋEbۅOkS)?~ >K8^DzNi./Һ^&(6GCY9QՔmzUd+QKmW_1Dl%^΅Z`DK؟Sd%w\@ߩ/kh+ĞINH<*B::2\Ho{ lWF"ise) WJΛ鼋hSR5]ܨ^x/uh"M ٥oiPnڶŻ)$zRE_ p<1 z)MkwoKGkV"}KkW$zKcMi-[ҨF8vɿw._qd<}!|[ObtN't,7^s.h}ׅtuN&ik/r3 _h=?oz>'P/F1y-i>Yj?r94pF /ߛ8 g>}x A~ᑳτBuMnh*SuOF)+^m}Gk[t|+cw6p^Weƭ& O!gwP_ywכjaX?6.T=f3N\ZF#o|F~R ,ip!|Ti~(/k~ y"GtN wyZ}b~n>##gGۃ>Gr~KE!>6FyW鷑ӷvxjLŝCr( 2sKuNiYr<^\+!xqZ絬l?R$kO*:aisjԂ ho)%~>&EIiD%8:t(s";Nu8}JdӾR 6vynpgwwL h"r]8sB|ٮsϤnPʭ g1֕.<}g;p'eZFOIj>] Coئ=>Ws>_+|cRQmo݆ܹ<|[q]8yE}RGsA|?p"3D71 Fi5& ;c=qS:%}r?!R/#idbɟGEԭnFƳ5F'pNIJOx6>Wk&66׊8 PXձs1^XlSc* oSѯuP= {Ke+5rKԴkrh)m_Ӻ_CIq&49;kQl37=@dl#S<}> C~1\efg>>RUn)h c|ȉdSTsƤio_ 1*vzeM׳:IKRFN=KN>Td{0sPvO}f;SHΕ@|HDpuxxer]5{2.Iqil ӫc8[dV35B Mh#;LL>hτ[}kGr`(2,!7KvlnTʓ51G#HjENƫf0܉3$O8/= ~&mvt,/١X5= hǿR%![]r&11sX\}yl]hzUScs mX<1fE{ mio8аI S ֊f)k=s8ӱzy_ܘAepc>ˇ|c9vublęV'^@q61Y$΅`wd%6>7Asgi9ppl.ژsmP3V[ll%4ek+3< s h CVX~ is]9MpmqF{8~7p@XG]p, )RQ.6&ߏyާ urZJn$C^!gm^%-Sg߭H=uڠXy#ܥo#0,)Y,!餁Rhk?6|6c{ঌi>Uy(fNJ;[rΆgΟ*4f[ygx_=b\.\x&ܸjyx~[SDoEgʿo28/m>nx,(1>\ 2 J↊6hoۛy<Կ`ǾV\QLEy|ЇҤ u`bf\w&Пt:'؟uҟQyψݓAq~D'Y' >I9Y>y~/+, a^4N'Wėҙ%ɜCyxxԪ$|ǿ$8"9O屄 15gA|IXhhy͉bL"6Rwy9fۣb_>q#࿕s):B`;P")dMq]T)!}c0:se*w/Y ME><>)#HsL)ӱΟor?+sAbہYo}_8{(z/Շ[[є/'~4]~wO8:NsESgXq ~ϺL.29kGӠm'3<)y*=y)6p̈m5kjy%3-AP¥nQ|LToaВTmn>47d$mw(Bf|yrXTfۗײ4^XñiXˑ1 ղ6:1!egt1?bTT ^-| e0f*_aL~89?чLT]O kM]x{1`q m[T^]qS~`eƂ3/ [ :Y 7XR=[tT60~Yص-*<%-Һ2]xHB}oS)>?2C[>UJgMG]#CE;ZK ?iquI*t5?f!qB?blip4k*m &4YlbFb[xW"Xd([u&SopuCơ TV[UsS4XZXoo*/ϫb[h^_~9wȏH_?/m7i_U6.N {O4o\~4Ijy+u[lpoo=ܳ#_\ G'{:Ns%mSa>ϥz8Ox%\?r/,=* WqD?po<k>Zm D Sz~s>iVK>uqqSW m<:wucO{5( *hLXڌ<ǩFu֖$ cjm,gy<y hCۡ|\6dqc{~|C| SU,K7ap!a>1)UR#Sۦ<8WNNgTދj~k>#Kؒ&[ y,S0&6 Ў@`}D/@lCS1jcJyOp.S}+gaԎbۅ5-ژiXOZhb+ce>ҖQ~շ6Y\??9:'\N6mDs,ʥ2Χϫ]PJ,M.um~v X6Es|Rs*oˑ]l+qL߭i`po?lbY6*69a׏lH!nmioQԧ>~~) Ν?,.|3?N Ypyχ{vS?o_c3pFmܼ,wn^xkoolj,kY3,N&~NR{lc;xmgYɕ9<:G7fJpBrq9#im5T9F(%U4+s6.BXW-9/Mt,‹#'G-_+$V5mmȜhi_,ls*.WHї+b>]tvSYc8~NkSyc:r-ե-RjwV~ N"r&18GJbv ==ShioE^ǂ^"@+/SkO:"nfapP9KLX KJ 1q"wS301Q+@?};mVXY_U@ˏgMQGW^8_ [xWː-W<'j1W4i;JevZb}qj>DH?_7a(~?Qy( ||ܼ>so"~˯ Dw( Fabl#;ҙ-om΀eܸIHk|z#d v<,%׌ƇؘR;T-Ղmf}݌L̡ `鵻E7ULO dkc6v* y$d1T)꯰=νрf յ'$7muZ3#XH]V6,іJm&ԇ_՘#XAG~HJ;In^kbg)KVB7Z$5~?o|#<|Ju]OIvӇw~wHj 'م{~G[8[3Zu?7wG#fo}\drd}[T<;L:BTbI^Կ}--Xl1Ɵ`(AgJ{v<]0m/?Ot:Nt ʫ8W 􉓿%Df -i,59,s4'ֈOo$W@o}ݔKpv| Yh's4M򉥬wWsߌ>_ScSǦd#J}lMcg)כ.>vrjgF)vl'[MӯMh́Ĭ~/q]K`XOl;/-TtܲWl{|fąv_9v׈,%3>?vfmh0TB!':>"{ A4G˥e\vg~v8Fs3곔j.#e]ۥ1--Y~Pf?k/@__E~S(>f Siڪzc*G sR]d'qY-ۊcXy] 3>S1J86m6Yb=AX˸U[̇l ~-?NZQY|(2"jύi ]c6yNo} oO簿;O}/̷[;'!׆;^o~9;~=<6-6ca(vf͈OF?(:K~73桽׽o8wmt:NtSWE]%K֫<9Ǐl/.e:hLpPUۙPb2q%j#߶AKڄ7mgS|b`]d}5>sʨ@Jc[éMr~U(E/C&scVun|BDjJlhU$R=6Ӌo?+!El  gNublxoAV?G;xEin_[B|2/`֭<WW,-p\tҜ` P*+)}ۊ0Qe@)-IvKvrKp(&+^NƝd6`;(IKWt?Μ.Hq4mt[D/,^2ƛ%Qb `*hst'%7pBf/*;}t䘦Cth-J̙T&c\8ڱ^hr[1Cy(ΕLm%DCeQRXhN lpKqb1EZFe` v@;m윘4xM{k㞍Ֆhm?z_~ì{ϧ+?~-nџoxß^k_'Q—W|?|KrPb9|/.8;F+ƹC\vD-/&yx)qt:Nt:=G`Ս5f}Z\Z*G=h= WY#L=>\Ur. eg`|ƹc(ϊ~X(2%->j_:KuTYeG:71ƫ>miUϛrɶ#qQ.ƁbS KjCYúKEӕ|JO[Ȝ@":4U[FJװ[ɮHJhMбL>ZPeU+k|.*n'0(JXo6B lp3**'iUm'+fȌ"YbۨN1KӾ<@F޷ZP܇JԁH=bqm A6c~7aa18P{7>(nu%/+oH)~Hb7diU#~B.>oE=q Ǿ'e"qsmѿ}{>xԎ-UB{*nzG od'|F4%R<*XmFg~|0b[>v(QԿT4OXlǍilPgYjτ>p鿐<|2.t:Nt/ȅUaCf6YֳK#`O3 g9h&腔Ny ZHersY 8vFi[QP846 *BXVY9exf6s B=XP_:!Re^qƨ$R]??iy(-NΔMH}:(v:*Y[IǧR*+Zڈ-QܦufL^/U$vuL)F( Di^bپZ qY]Q0gl6kQTڟAS}qn)DnIk)tN&?v~@{M$VjXUmj9_jPwG ޶&mFLZ<:K>8y׻%kGNzB~G?񭷄 z wlض?㧙|+T8Nt:N'A3Mh%x7&W=/?d$.;F9leNˣVuhNj^R+|be.DKvh戊ƝZ~*Jc]3ێ+"xLIhJ%O6,ևmdžm BݶKiP:;!o ,1B%7~%o;~VJJqv6~X[c+66_>Z͖|;eM>y3!Of{93߻#:g? ?ׅ}xBJO/|ٌ.^^zt:N`?ߎs'_pUd9捽Sի(kOnH_@Yz#ٷ~.֏എ%-&%Oh5J GS34C*MZMe4Z\Řb+k/ ;mh/u} ;^?2)ewa=IY]i!j;@ 3Z@6f ݖ5J%dQ|&Dԋrd c4inŠ?f3w|XC3jKHi?lzPOL-a͌v\0-6M>pMo)8vAp?i;$^DiLYmP-m/0oС1>S]4Avl8 ̖W{{׿ΰ#xۢ (~KwL[N~] ejV7ks3mNa܊?0plq1V_WCNr 1kUssbyبNd˲6q(OmV'b>D\G2% ?)7_j.g?YI-}{__Iq&_]s ;:… vL<֛S=O߾pp3X>~rɋ9M_ _OIzʍg \'u?|[8? $7Z|Ӵ.WY| .Ҽ.O;B?ʺk-=Zgh,m]nXFgZs<>Lm6iPj΅ߨ.]˔c| ex^DilY(Q}pUdؠ \%8q/m6Z֖Me"[^qJՍqƺ񗷓![FDڛnF/J,crf:Sc$ľO>u?vd=K#G\Z`zW;X}C`]NeK͒_߼S?sj5#'영|,O+SYL/dImǓ]%BVMS8V4,PoV?OJ۰4r C|zN+Am^X^mXaz 4n 2d{%$k 6%{)Ԭ\hkje>P*R >Fu)l hcԶOS_F)SSߖ=cޮp[YPKk05mٓ2ݒSe11yR:؉jA(ORf gX5$͔ysOMKduVrM7smwN"?< ~FgK)?㠾g>?>%)Ϳ.κ K?qKxI_y( {?'qs7[))%51:N9\|o 9n|E?hC83"gR']| ,q#(ײRh^iƠn/! jFGF[Qy:Vx#ZIþL:{ы)\du?:d 0d#$I4-gc+Γ:|~L1G,fqC "'_ϾTۺYB N bag 8AA+*U!ϐŬ5Üu|b]W{}#q,bo)"B*6Nפ%1,u=tnjoZr+&A~gMioL. n9H6z^E4[˜pmcZGR0/67tiK}L̚:EsB|矷G68-b]k"*'O$) RG'#`Gάl^ b)./$^Kz!--cAU ' vs4m@K+Ƕty`u  Dghs@;ljm"خ^4gE/*yvNjTZLI:ۻ#[<~s!<{:Ļ>p~n>淄v:Ngzhasχv!<}׿1Ho?G ~{߼7<n<Ѱ7pd/ϑW-!=k!z_v@WUT 2-HW]Mz5+^G n_m^WEm6Z!\ =<PDzIΫ:ZOʑ>|>7D("2KC.ITGڧ-ϢPX/E:D/zޒk;5Vpi@i{"+8YZKx|1&P)i&"_R!*lvQ\ 9%)w\"u2-S>PĭcCJ ʔKEHb2i=S4N1@(CQPVƞqiLc[*cc'a[C4M9o_o>#'ui !tF3|4./hFupn,q#尊At|X%dƆتF";C; :]mIg%qU8Ey'֍ЮzqY i33\64YE{W!Pbg ~cǁ|>AcEfߊL}%K}m@hv= 7l'?_dˠx1 r_qCjd}„' mʞ>EAs6Y9J $i?k{*E1i9'P%nF>8?nL؀@E?L_#䩴*bmx娃咐f!MP뱦) m/*B5JDMdw&;͠^j[봝{%Oq/h ~j_1~^P 8H}x h9IqbK.ةt*es۠ FE.hur~و *r۫,*mQ%=Q*G_-u{kC1r]a'K<}BulD;8ܰ]<'۲vg۝Ng')DypÇoKôtOxo-oo#+)wl Ϟ/,ϣ8ypBAaD%t/rmU %mZCZQ#G'RH[S>X@͂Ufr`Q;MMs;qQEl5l5E<؝+څ+ͬ!+ȻۮSmlv=fDҿ7uB۝Nrx~&O/'7zSዟz?7!9?ϥfX2>>ru<7E[PGm{Ixt6KiӋ1y;-hǷ6oe^ɟlm.(!=-FOW,C`mZ?qaKoyi{Wh[Xq1J<Dx]cG!?/On)>`bNߎ;< Qg s>y^Fܟ/Y}%XTvMRTppazMm&BgI^R&(mWqQ{,yjVt:"Oo>φ/)L*5]wCo䘌rKx.~ROp_wrqu-g}Rfq O,CWC9<Ťy{~='u}ɶT~dr{T9)?t:+}4׿F^ZĿ2_ qYc֒Q1b)1|VUP4bT}SءOym%n<1mZpbzP*)(-2,T jqцE͡#s)c; }Њ2a剶]Io_m:)O!񋏄QMp8<;-sn16cj砍ׇ&[QXɜ^i[W!E+Pu"qm kqO׸"it`c!;{uvp=ȭ^V+oC,7ٜ\.ߦծ_OQt:l_ϹO6>!WgCxSjV,=GY2 )~]$RAPD^["嗎J&tMVuU!yc5\s>{:U=U=s1>k;dج3;_n4}b:n7H|3OKuTxܿ|^Joy| |<&Ð7s>kj< ]4ǂ ㆽ;qpt]Aݭ#A//qR?!/١%@ތ͐(_v qCJ$s`ZlƸBkտP" xbdl2bRqC)Cϴs9d~|r-b߿?<%RFqd?}&e\6l^i^H}(?s|2xMg @(y9yҴ5}g" 2!@O1nȺNj>8'Eg@D[iKݟ90[m/7sI*7T*60?戾$ +l꫷94t} ;#f4'h:i+1W` oisQ"]nW-w6#k 1X]{761O oQxwa{GimnX'OdR>)Q|,ݺ*ҥk7_Rw-]Ua Q[6F/"2 " \!tLi4Xqr#ą.7{W^oI xN>mE-w&swhVB? =Ȉpl!?als;9zȳ.;a5aoq)jV"JC=d6(o}bdyx~HkdzA~s5ig }͎fN9?٤ˋ xZFYk3eL,1-9\Wpzmsju@cd賌R na7 k}MFE9:bL4hN VU]N3 mbB8YZKiBq4?o8]a@i㖴T-{4҇SY!}S:l"?+3j/">? mcCG+:(\QKdj>:jyc@X&o#en 9'kqAhOn~執D[/K=/\J~d8/kH~r|qKZ?}SztX 3;g*Rm7Y/±]Mwv||m ܋7۷ kTb^ޜ+eh.r-o!ךpנr8ev}jт۳|e)BC=mJb}F:";.__苦a0}##3_K?He .->pgHхm Â1Zq(1ȘwT=h:nRkx_XЫQJKpq(u&M=HG'կ6k]oQ>!urc]{)FSԦV]EiYA(GJotD<&G]?RڄQ jFd5bYqm5xZgcX}Gf1&.AZ@C[.@q~]wC wd# V.m39<#ֹ  ﳃu:ph,voa?Z`m\\ Sc. ;nŌ@i8 Π3ħ +,{K-2.AZz]\O,dSvtttM_{3/Ͻ&}௧dy{a~ϹPaz/Po"E_J,'Mrvxgӝ7'\ns. SO auI&\ s{饕"a.Ŧ;3>\vtttttW607I?$@OGY#d[('Mʇ1Qu^:PAϠ/v6h'?rț=>r-x=x~ >ylvJc-X" 2_l:=<`7+V0%!Uv`ZtZ1QBSRؕ=/d/Z2ݥi=8/!N8݌̎Ή[|eq<,tÜVC׏w(}@->бC =O`3&Ϡĵ} >2 8dܒP,y`A .5˜:V>ȝ>C&c>mL8D ~4:[j\ ѠmpeNj|@͋~:Ddk D=0I0nc7l QdF}k1" A|a}l߯;nFT7F(_)BOdd̏:A>so:\58>aq>G\}1 yN{ݦehyDdLǼ!/dQ22y}ɤsjt%|5fʖM?Xty0Oky,T(џF&r~ն)-w؞qnuHvnvT7Ѭ?*gC~zP uȨf_@CD_v5ƀZ֜ikӶ0n+e$W5N(kC)CY9*?ǻ&` u\3|uls0egbbL:=X(?1ݦqg]?BF1} E+_ϑXF_)ld#v~(iGa!ZfRg~JPzNJRx0-pX dc_V6υE9a,dFP|0xo>o5!cTXV$ A݇b fz5|mLWyTmoQ@vM/!\G:r+5VNK^#Wl.գ] gIUqL@+J7k=qFq;,$E< ,sĪNOm<}uD{neEu6>陧qqs.1װћ:;Zݳ^b9x2%wtѹjOS} 'RULZF B&XeC;q^Qn>Wj %#8F$V (h~@YrC5@T_ Zj5p$F}. $bP m$TUP te:s66dݠvU گ(nbNN(^c^]5 8t6: -D}]>5&QԙQ! Sq9!SF֫u%u9G2hq Q*aUS~gC~^l+Zlj? Kz9*Z"e'7s@'Hp汳| 8ؤwȓDF 패@K؟<do뎎 {}_?^c+{H"<қ BqwÄMΌBC9Ňر!orȩN=YI gӡ0kS׬-_.):g-(si@ҼV I' ޮ->XE}H`A9Weq:d/_1yr)X˕_"=e{2ML=t *o-x}2/4}e:1Cg Edn3rW *6 dԈHrR$W(wGAm#oqcXYÐI(*Pl9 ,$%ct5])qEKJFQWU/myH<>5.dc<vDoSyR̝>q75.zcv%N؉rpX.YW;pD  _OܦfC]L[!Yc-#ǔ) Ã'7h:zɈV1R}e~ΔXܦU({> ӓ@ۆ4. L@v. ̧'"@%V&CO<L#nr c;'2 1fYCQ{v`׼֎c/,H-CBWp2vЇ6>w׿f8ȓQ~"(,}15`Nן Mӵ(P7a-ګ|]`m|8uqc qH4Hln8.ډzA;$~U.Hh~9/C5*.m%EuL5t,`7}L*/}!uF#C~$-vT6;VK2z}M C>&D kGOE;ra($>1mS~Gzl'-o~;u 86[bޜ^\*!3;uвiÔE[>AovP7a$᰸,ሏ)S8:*4kkXec31DScn;::::::::::::::pMsjnGzZqg)9/)qۏKXxB~:WNH{Ϥ=y=0o!n_rqĈ*/MχY|oפEu-ԊllBx(?0?hV:ŝm8( Tjۨn&tƄ?޶WU,x"6-@~EHUr,UcC}$\>A/휻gu{ OˁZQ:ͼ(~ Cn#=Nic# bn3| yk?-c ;\CPmmDwqǟxdQuzY'aVլv,o7YC; ZUS>V;Za>jЩeH{VM{GȜ/Zi ݬd w8LLTL&x1Pt@ʍ'\N=v: C3 ώA (ծkXApFfWrس4~1i/koka,8;~d*y`#}',O- AV^´-Ԑ8C.gH.E{ >i2&Ő6D{&\Ǘ566uKƴ2`7vu4v+.AM㫻X܏JGٶ}[(sCx8rb-]B˂4HTJ6*(h}ҮǧA0Nq0)BWgɢf\ `LnMk1\HJY!H ,aFಚa11AdA.~o.trX>eB?'-_y, @~ZW`nonfKWuʩMmYȹ!! nL>rc(fy '5Cs(M{0`b} sm{w!<.ĶHgċ:hrMѶ7(ۢN}Қ[1+fl%XGװ{>lTs4DQqHGͨIܡ,ֻ%I§q`0uٖ^ԩC9yarڕ_ovnc 4K0:ш|'=(gYsc5Pᮗv xV/5cb:^+aDF5#*u S+T~P9C~}vSo}-=0= į>_^*oj \¢ <8d]jߊKx8̕ؽ^{/Z< Ūd}l]/rܐ WW δ mr2OGr@oYgPLn29_ЇB]Y n/0p&>V02 U"("Tle731}͈~ Yڥ^,YU tm 0ھBst ڦEVLc8˩> AY2CsUk>uLűrhZWi E qU&my;*fHISNe % }ir]7dDE7 {( HV rN ,4F2P}< & 8>V3DYA, ?*f={4$dTfH&KX"ۓ4E!/Cց(BxY^vh8)WsuFYC'϶"h+?Zl}ނsy{{q-EV h^k~Y6Ua5!ۊXU_M$ӈ6{JOIr,hWmڐ+ r~M^uUr +pоkMtڕ#o ěs {[넡i (bL068Aa2ccW*|bfphq u=6:heW-0y eNfDK&+bR%VOXm,Ws`8iJ@.614π .mȘ/~'˾cc_ r)zJB#Kp}FeN!}Y~P8 h+TVBD~!p*&Ҽ6pO"zy"|ޫpM$p;{.xX\DCIab 7^vmub0NA2W8 uZ{<-j-VjKQ/)r}c."NSXVYo )SuJcc0N,WDzsteMX^4vUͫ랲 <ǐX\}~ce>m.zwxc؇+.*P8VhhQw8)jBBŘZ#a__y GP[g (F;1>0[t0e ] ub́eݔP+nƒ -E"cvƨobRLjZߎ9!="aLzmc!㚋Z^¬s@eK\AZC d[MBlǥRK6}F%:9 ^0ihc*jquGpQ`*?0 /Ў՜N xT[Nz;:T) *v:ƈx?0ceZ@?hg.;rt::::::::::::::"Kc) *~|K,|*-|Qۆ 耢 1ZH$!ܗ#][IDCZe `, EٴG,}JL=7:|-poQ9ES`ONCGgZOq7O-{tr7):C5 g:5 uPm2> I`^wt]Eu[:yG Fkڑ# lIi+Pm2^EUDFd1FYcIQnj9t?5z2!򣺳BF#%\^}s|_붼?%xX?:(r: (g;5WsAYߘe=GRE98?H4@lZs6h50Fi7@l[A)o++\/BOpmPUI&TxZն蹳'j sPεNe ?8#WTpbZcd{Z@8N!l;|d Pu%$ mHl `ΎG~s94x^)iĝ r[)vAb2e{#sHy1NC߽ep1]qZO,dC~ 9$Ar $֙tE"I=*AԄ-/w51 ~%u &8 \$`'Vhғ򖎡s5 *hA?6`C;ϿiGyq,Q> ȑ)d+GL˫!"wx2g ?vAj|M\ّ@e|5\&PUeDI/`!OJ YP0me|]a^m:(]lnh!U5߳.wzZx vafE:y!նUgOEY|"%.,Um 3T&[.1^o3ΣhLq*~#Y]d6F|AkSjkޝ~X#|]Fþp;?gS~/@8@lG1om, =s`_ 1A)bvfaC~2#->s\f1ԥ~f-P)\ҕƋL(ۯ & ,q^ܸa]iSL8>I/~#=>{Tpp&X.ڕON첳>tmutttlw_LWoYҵtNb_.г΃)G^.6BEk%M^1sIDi}5_=hF<$Ea>j5E0B%{x^-Paz_ބ0qEa1F'C+Aޖ 4ˏ1wPD E5baۈe]ְM*-|Qs1+K {DZf׈6jVM=RV[s2GBo*{usy-,YߟW_JC~<$9q}` AGFb 'YZ & g=v3|k@JWp]6}+dBdLGM`%<SbePDV Vv*lv=;P/=i:m/DnAY㩔/ X )A.Bnejyf7k\ٶ鍵ܖ`Y׋ӶXB7*/$!ה~O-ʟz>E*vTG~򖝉:Ge%@=WBG1={`YNFK6o5w-Mu!0qDT6e ˨󦩘v)ݺz%8s -@[Wup]qnE~ZV }UǑ\q͋NS.6&]Ƞ.syL2;7}FV}WbE0\o2]qqwɷ:Sx"ם:3OJawԡl.oۮoNJ!M@Grof0>2as40cbh:>8V{ Y.ͪ(uѩ'xZDžV yUs|m{l٪Ą{ح)uCe6 鈲 xlǴq%֧PDQnQ7r^GːV~/C~dY#idIY#ʲ_nGP6GmE=ExnXP"\gqTeM\a+T&C!EƇ Gؠ`ciqJמ 4AV 6$~ &^rtW`q,xB:e"!,%,wҐ4oӂ? Շ83qa #@`*; _΢.Y d8=5 bu;fՉmvlg;9?5S}ݷr`#&}F ;rtttt<*w+_lw+pν}b}yfqݦh]Vi^W ˉW2TJ_o3!n= <x+~P< ~Oh iu(0&>2y_eNc!ȳ׶kW[9/zه|S8l^>o!d#E7hScivE-_0 +kYk?\'q>!Z ew?qBfHvvm>HSp5VUYy4㐹-Bs~-4PoA{XX+PrI\k{}{C۹MA@~ptQy<,Ԝ/cjxLĮ>>C\3Iw?~ʮVi c'sntJ\З{C9cZ!"2݁@G\E%Du]a¡jCQc̨gc[>noxQh@yĺt+9>(s_ˁ*9 ci-@MgtLOo5}T?b|}:UJql|7Ci\Ak &@r^s*n{+NNP iQ?:ٹn_upHOʚ#hjqgAahGbg[GcpKEHɎ7vyЛaS,q~\!oUUmb6Fnu5._O&twxq.^@: |pW< ip/.½ϤN%RuV>佐^}-I_N*;nH;<,G[uOW>WRVaױmw`ks~XdNݒ+)2`1ķ;I7ttttxNFw_I7n\'gF~ \ Rsh]aNmZ++`Ȃ-nQ2OL4?orM i_B7d3$ V?8Ḧ́Lil7B 7D~J2x;pܑz(رCus}b,"W |c;Д QbT,#_k f>N)˹Q]PRViH6E'Zd,68?͋9V;"0O8y[v:혒18~n`l\͖~2DO0+>= .A6I⹾ȮdHl oV0 4վy Ca9ӪZ| :BD)X~O m1;G>2gD-o sMLQc:YȘ!aF:ZyMfZdnrgMkTr,qbQ7tVuݨ|v<:l'i'0F)nӶ5Gqtwl؝A`<~ͅub| (Ty`8gW}MDH!=_K\Ǎy܏3 -$F z`oΑ1IK>kp<֚ c&#N Xw'hђF]ֶhs~,d!v_җZ@xpSW[7nt[B;d񅘏yQpe`E{w wˈ5HB~h4 5,6|l?Wyع#σX¶;9?7DVsj΅ʵgcj^雠ꖎGXl1,dSkTb^^H4А]x%|7p*שPVr5k9l51q=z{i$Ib۪5o>ԧֲnfi2 ;^z 6|xZTP gec}6jf]ĝ|!_Fͨ4)jfC"AU dH*DE1$L ʐсhȨ[L=o^2z7x<9|\{v5,^֕ 4~Zյ[E| x5kße|!]L,g Xlpƍl~Fާëظ_._!~%ȶ;9?7}XYԯ/|Jùyb[q,50?0z'{,iTQޅ>"2R 47pr [B ~NBHy۽Dخ"dÎ`rw{fSAc_i?#)/wm]B;=^F) _6CPsou.ϰs VMN6kD7L/ )CـV |яV^M2g>q(7 :[>GYU\#D$tkpK?SDq|EF"Hڄ 3mq#~ᾕ)#Mz+zDQ8'>&"&% 4ڈWqF΃? =tjfGٍ2`-">=ԕrSa ݀:}vnЧNP y!u)'U=c|;<ʴ+ )k20=u{c]n`ka7ıI݄@i)@5M܇˚{h v}&SCVV>Rz"؞qѣc-pJ}ID86Y32nysP­(OJvvN=eEsy5 :!춲?:lzj.VX瀔Jv-A,hv"= 1C9)FJȨ| cv=> ce&zjgя~4]vR' x0~龻AGGGGGǻS\ڢ{kg 1MvfExZtʛU1+ LIh!JwdW:%<BW MId2ze C:oHɠw`(9L$Y]MQ =f>LاL؅$ niދ+a +ĭ;XѺC|"ˁwlbTePZ2ڱ1a](nA4XȾXzXܗDϸ"[t@:Lը,2S.{xo-nu|L">!]Zv@y50vYr  \P(s Ogg3M"gEŸ|"Qs;Z<̵J?F:av#!#Ӂk#CuLbS8~ ]?ӎhwGlB0#/tt3V hL o Q+s]b+T͠' !&]4y c)HKqцp Ц |f9F.`d.y3[Dގ_'hf+;e|lվqoer0 ]~/wJ.F蝖yw ) 3Ѣ[-ϥ ?gmmnO~%O~(}C.b xl8Y{oW?tspGGǻ|ʥ⍎Z~@]/o32VCEځ(Tez=-jw0R.y ޏ k){ xj;f{B(Uu:1 $t&(Ю0 e*y'rv@c_vi 'vHj{= h!jE)>;óO E~yءBcG^BXBYs@QWd`<)IKO 9CEcH $HY:%}>`F4|(J~fFcܐvt1g2~s}q2{xE0ow@]OH9s11(e :5E1#޿"7X. qr|)m b[B%?aL%AB^:syKC"|SY-cG98$ǶS$oWkַz[_ y.*x䘀:p.}Ez'l9T@Gqw"#8Lt軳j;eЉcͩ)y 1g+2p("uv3Ј|4YЎ@m>>1>_s@fǑ\- ;??؆G ok})woq<}9}_M[ro@ߺ6iGGGbϦk' ,,=6llm/ַ@,_W KD{'-_Ưv!Sr1tt!X~b#Sr:(iuo~X"3gr|ȑt(i io?k'F}@}ЛHjY?@{MQmN;asA_$ 7T- 6eepMN 9S`P0YiGU}zr},2AAX>^^ԊtJ:|+id@sЛ\u6#m%&Dk!x[>v5湷M:S1vctM oۚ>B.cQK}7 /+g )J+)cǯpxu=H:Qbq.P#o+mv8ft#t8\ a7Rm ~-_y;~ ~FB\j+H*!j\ZgJ26-hy1.FR ـh,(w$~]Zp=rmY3荜mX.@W [q#7E˖Q>g17z@ee<cG?S|7nқEaΟ韶؆ ך׊5#|5מJWTgܻɉ5I?*oƌ/MeN 1af[z ;:::::::::::J='0k䛤d =ۆ,϶GI*UX!~ESP|cii +0@=" eB\ʂZ'Oim-b-.{J}ջ9{_hIsy\e:N-aSq-FCZDkg5YU8Gw>@O4H??kͱ Gǽt󓿝җ&[oM~ݔ^B-W=^Q֋NNvX(Q/XKOש_XWuzA~W|J^}~7ҫ17zGGGGGGGGGGG|Ή'A}HWy{qw!qB}k#1B>9v8|@w@L=}h q{`H!;`qipet$T|QwEx#0aqpq^6Pxxqk-ZbpgƍAGH5Mj&)D>N}޴(Ǿ7A@|,q DaۍlֈZ| Ya_fX_+dBV c1ܓ@YQA9-:9n溑d%sCQ@)MPD`yqI].mSrޗ`c6B !i6g4*z3taTx>dX 9V+ޓK޸JviKa^aS?\+w GgWoHc7Rra}W >bQǁBZe(% ȼ mk+i{~izd/praXgC, ]1!i2fWQO Z9q0ߔ[bM?fM&: ?4zƘђs9gm ml1ۘ gز\Ps%y*yydxK"a "6r-Mq2sa9|buǺjv /#׷y7߰؆@_9;cvsm"NW>k+8[^2[́37(|j{8.?atGGGGGGGGGɅ\c֗A~ïErL#6nl# 5EBا-'$.sS49 0=Ŗ~MAץA))2z?pr׏$`qVϱaQ_jsJ.߲2;hKֺP6 ЫU'5#3tyۭQSҰ+F7^Mj]<~ۖ>/m?gm\o~|3~i;:::::::::N"W1y]>5*dANBXчPi]x5uNPA{i\({zO`p/f쟈ܥ@_!<<3Y9gih$/<|Gx~1qD&eU##@T.N)bc0 *gR:]qL&2X׮+pɧRzɴS'#iY!v8ꁈ3z!v`iAڗ~F!ܗS<ۉKKIAz:P(Dׅ%qtM|9΅7i;e}xH/fEl]Ę 塛i9؝{;^ˢxޏFs hs P exU_WdSr,`$t"]!-H_M;}^= MG!cuP&tޑ!>AuLw;816wB _%eDAMG]7t#9jiځy|6&ʁ"!C{l; c}?v!F<.7g @|`|唀o> mҾx7]ZmF걁rb3H nD|\c;`CX}gAvd·KI[eCQyu(;O^&}[Љ4,M4Vbݵ`c֥Ue<.9m:9&,Џw#)Y]f+}N P8jM ?#Ɖl "feFFmFؐA1깶mq;Y 'x'U' x[9[6z+ X' KtWW->P6 ϥU')G7^rsbϧ7 ~4~#=鷤`r+^_rd_*,}5k˸wk3;tXE-@qtttttttttHr @թkx ׻s6A0 .+¿J/WuF f"ӟ))hGe:MAz*gYFJ"MF[nå&Xhע!I|5 / X8$oup,Ŗ-xЛSox{|y.vA1ql2jw]hĦ$K27ªr^gs]ǂ+ N@sNJw}čxW&SE3鈘C:҉hM$Г}_Y&,,`9ItTA\m8.| 5z~3 :N Rּqj;<_̵Z|b@=NJ׾\ҷ.']kt/dyO.| b_MϽ6[@=WӯW/+wKOo7M+cӱ=5)S7SX+;̘טջ_^o] tEcg8>8<~/^4^_A<ΔͣW-frkp\$]Óyoκ |' ʂo;3^iPP aR.rGu;spCojuE::p< B s0/ 쮡s3O=c:+ÎîV{|B_6j(*:QOpT.1r wKl;EH|tSFZ<f_6>mp5d!c'Qc^D篥 dr.wE ()eӂ. @(ikO?Aa]I8ou _Q'v;2$d(Ss)sYLfs(q "HD}jO LlN>P&i=?[# Glj@|0-F18KE!y(|3FՑP߆A%IB6,צ7yײ꜐Z}[tpp۩<*@kr!wD@j wUirLuҎz;6me2Zm'/G ܂ :q_O=K-ʠWkDE ϧW[yrVԭӎg~>} },]\Wc^X˜_#i}e)sWt__wc^GGGJ{1ݸJ`IǏ;[)]v;ݾy%uUb9 7RrS.[W'}FkI6Rx~Ȗɼk\0ZZ*\! R/ =0y# > }B-GMG[ ƘKCQexC"?.xx "'tULQ[ - Z~x\+D9,iuqiF7#b@(0)tǥy9fUdW^a*k emRۘc~>b}.AC.PG#'ԲFNۀ;ד'noGFhyTL:/;ׇ9Z78y؋:Ÿ6n]W {'\'p*2"wϛ9+W.EPh -Lxt Q/Yp#:4J'xLR<$E׭Hw+Ulة=ÆE!b_kyPHQ`IDAT$TvyD(`R|qWB`Go}44Zc7^҆c|ojFQ:[(ۀ~ȋ#$y.sc2[j@;H>@攴)YCy :HsW]yds_:-?D_KT.ѷ ]mg}g(qB/ ;ĭx!+́b,Z몾v`a89B\Ž#7As<~NMa8Z1'kY\_^Q8N0)͹)ZaZ ' SqbnRE xsiMX?J?3?c1u{xܻ>נ,REu+WC!n N`&kaweνxxxQ Joapke+Pq\+RkK]`SդVp>X]q>]ȹt ,5e#B=n\շҕ7ҋ'qdzVƽ$TM&cmuzrv(Mg."#˼Lx|)!IWzqۣ>$AېF;Cqmnj:lW¡ 8lAgΦCV|qAؕ(O^EyVGm .A}PɇejݥrގDc:_ Ybbx9$xا>K!Id2+"X< /IUTݐ48h#j9"ui~@+H}񡾝jZt.d) (A3_lrUy7`Џ>#aİX2$\V2)[_{|! _^6@|_FXgږN`&KvG sb[UC/} Q[Nholw7I3?O># y#ڑʒ6p׸`Yl~][gSXeV>oylwT_< >|ᵤjJޖ+oW<oy\#~XWG7l_Kn]m,|y%u]H`tI/|wWzӰ׳󎎎Yܹ.߸_98؁WdV?bG޼n_zc:}kȈZe9Ј|d#LZt ɉۂ .,ܻp@ʢO2\q5$BXtCt;rE 1(i<9,+V<%qq*=.kVNq+[?%NJzS,@QVBznAe̪|B>OY7ds><"ĺwM*69lLL7|J[:Gx2g9o+ylEG+רR]Ts(}җ8&5˥,l>{1vP z6Ky| (ĝh\(֡{CR dC~=kK(v-f?x}5CɊF@($B+ڡ. l&I`'On>-.A a bD^M?ݝ Y|P,pF!~:&ץ|CK5O@^4Yw~\0fz"tpuM1Y Xl>T+(`iy#lLTk8W.G${FOg oRgn_>nSb<>wH_ .xw(>_C<(n}z_Tȇ^G2=wAp]pyIF?FuJ{Ӣ76}l;ynXwؖWNHxVz:J\HC:&aga1p!}t7wj#q&[󎎎I`W [WX;o`~ؽc%^J4@~ ~:|t浮\׮([J!~ςΉݘ?0Dup DKy F{L a -}0iXwDizH(Ҟo@a}:{8'q#|aO"{[>B, `~ajH" {B,'~B@CwxRytxtpV³I Ј6*RQw/k3v 4J(V4nC&C2 %+H$ĸ%`CF9!έ[D!e(7&~@PsHfî#֛{m:{-؎;@e`}ڴ\ `DxE<] ,밝2R9(2}jGҜKZV {67gz yE˘Fˢ >NMlxl#"!/v1rU }&!"hLNg:,nv55Wg B;%"jzh?6HM I1PK9z]6ԝ@;~ M!b! `jݷUeb,#BE8A1|V&)nB2I}G\:Iv]K;1s}K<oj9@s~UqtB1ŀ 9||xX2ZݰchsYBgEX -LַCr\jۻuKGHq91C_0lQ>:̑_Π3-W[N<$ӯo}[?'r賿 .ʠ,lq5n຿?mޤ[ 'q@g3{oYlVڴF;7\KpN+]w&Zo>HG.OlOW> !"f8xbWk*8mHw_I7n>r1ɷ./Wk?l Itj\ژɒ@5@v=뛩llyD0٪Z eaݔjH9~_'y8nX c.}Ƣ[pn<2vL#țݸɍ.G .؝wp7)|?=Idb -de6-ix! KJ5̄3e.mȿGF 793I {A֡̆ d] ^ ,C [gTc{Ga@+_1V2aE4,니Cy;< ̋o*ҮUr+yA%\!|Hi s=+yjڊC>Xe@d.H+gC~ o˺dE BS> 3M\u{Q~jC'\mN]6C%5T>) a#tD߻q7hؘbF)횣|4edt-wYKrx`_·NlǔHB򳜺lYE>@%WNCF# UPvcċ p&ΛaBGN!"ǖn0 |?y~Gn]oMp;NwhyЁ6` 6wo__HX>n^;,Ҹg76"otlaiX;p/}7`Xhs*x>v)@$_ V_קrWmo\.kbZZ.xFʶ\fˀ]?}IlXDCǶW}>i@e UGfKr::LMآ>03q)k >mh -?g*͛7ݻw`D2y8q']Ͽ޹n7Q_.nqį^=-[".ؽr=]r% W7D:=5ݱU5)g.@_ұp^qFJ-,K7q>dp> ./I=}?Nߘ*;wЯw7|g;7K=.~ zYM],)5*1ox+eh.ln}ƎkW~7횶umZWEufmf1"FveEX;wDy";#' Ax0 UO=Nc-8}FOH 7A,]:,n2{X4n7̅xȘ>zP[{be) 7`8R =Vدo<.sVLLÉ`w@}1Z0Ѱ8he(dP}B46'tc@ǷxbY.OpLc~Zwҭy8qMQrU)ųj طdj;j|_M˿$;ZzJ <{Mɉ]"^tÞMZ7@HS5k~bQqvwtt<^y%VrPtqf6wtYu<^],N(.PiӅH<%< 7v8ϤSOH <w?sLg$>%{\!-,;|p0w5,8})D.JXXEuB|G vjH;\ Ok*qAۼb(bOMFE7gj% G怐Q o8`6&)IR qto5j0)Va9;Չ8o -Xy"jAz Vު\iV )7;Nf[m筚@hNFYސGe[h?Z34M{ONC)*_E_0ISOd//>_](HognC-@qtME\,_*ҵ+_H39~F5Qb|_ewtttttl ~?<<>_q e6ˁY ^ů̬Eɰ̭D=v@ю@G&BCԶ"@er-z2|߄h>r.7E#bI葜k<~)Wj7ԁ亮,x:=sޢs˿yψXQΰvwtttK׊\z!/8IX>]WO{^˸C\.rpNZ6 }Y@X2}TK>Xqj;#vAI6 +\0#XЄ9|W,t: %:Hq3'T".|:Cxd:[u"Tns9=օ Aq 58LBǦ/Kw s:b;Ņ'meK@B[ʾjT8g#>;l62q-B&XDH`Z9/c81[ȋ6+bHڑ2َd"ىBR*8re~AɳaFTtw}H|lh_ۃrzL4 {v|}Mf?n1M90/lr_-'0:ls[-?IlKȘ1S4`~y.Px17-ٶЪ>VZ:8O߷qcMnjHG33h#Hy7;Y[#9$F[·KQu>&D zsV@Xrpl'XM8ؗ֎ <q;:~9AhFLj??Oַ,{.yl{#ëN|Fzҳ7|?}[w]qv޸x1](q4|N ؽ0Vo:WNF.1G>$v`y?-;A6.| b_L=#!GwL+R^c¦nr6X(A~ 7u)\CB}Si,^̋; OI}'ouM[v?XUT:%."5qdžS>7%:K:.s|f[Sl#2Wf*,+Y:taD)PRG6!- gtN55t3NF}1"ؓ m"@9E>CGYi`{ՐT~(}]Oah DW!Nm r@Oz۽YAQDK!S̘nHŜŕ\`tZWoЅeP8? 2ncBz8,q|N !͸f#Br |HEh-Y caFƜm+Ɉ~Eڑ2u_G>vXcQ?"\js޶MېkJygnoY-^wt&HNSŎ[[;o[/&n6v8̢} t%E{J..Xir:gO(>Ņ{g'EdJ-  C̾e3% $z+y19_B([eПc~jS' dNVsxzVHRfy m ]]S7 0!@[l8P9e[@hw c}9?E?S0 rF|d?Qe=~PB^)\g28@4Ҳf۷OKS1m%Xiđ4vr/oyG[<~wM.25VysE@1>._u.[e~ϣ# WY^6Z t@iLWde\>E/W,RfW[yCZ;rs-{ 0u| /&kv\y"- uٱ~s=FL6#nƁdeYJ4lcr56TgGeqX[@oҔS-v|8:/r-={rxbx5k7^Lng?⧟M7H3īQ SWRqYʋ/aWx׿ "yL/ Y c7#MmnQN}ms u1P;aޜ.u mY:QW¼h @tQwK Y9/(-dx=^ZMq.8e;t`Ǟ-3X!%s`g>%.a=()qi -`\*6 `]S}b~ѱ~?8e=p׸hZ襪ip92Fo]p{*RW],&qK{{yiנnCv!iXOӗ?hcuVTiiyʌ~'d_A-Cy[y0%-=nXhUF~V>t oIt%>L-4˵0Atwyն=|j畜! fg?d_QBmg]zױ1*?6ʮ{8QyuR(Ӵò몾YKiOO(Иm^S6k1:IFj2#uCCvwJS"OKxG?aֽO]1˷ś}FGGGGGGGGGGGǑa&x=gu~•M!^`vm~ސ@%髕l?--D!`@Td3mMXP;m(ycZtAEhBPʑ}rQ8}ޅ;o VL4vjE3i l7׭S} Sw*/!)nbǙё,}]s*;T"ٱiI D!su2c)Z10 הx `B>2ar"t d(H;B!Rl> _S +?+@#B}jI҇b;Ɓ'7(**'1Ůo@9ln>0(4B:L,'۵'].c@t#D29Mt)9o<_ N]f4Km7̍plhP]G,&-@ˆ݄V5 : QǴt6昁[%}|q.Ϲ8Q8wZv ӎ#u=K9SrUi vqiل OWv|<6*UZQ< KO~bì{;8^q;(o{/JGGGGGGGGGGG \uu+Uvm p?fU͸6_r}]_GNaG}} ׏a1dd8#䎘_4ds=_ !rV6[`ɣֿ&K-?fìc_ʇI r7~q/eoCЏV)o lq#vۀ]'>m[cByoۄ- }epCnLA;yةChad sȝ>Ę)|d9d\" l.dZG,@D~!_t^gHO}!?sZ!X "uۆw%- 'G#31{9[ 1aKZ-ㄲh>*n5ZZ.[%Xż)_$8yҬĜ> t뱆S5>#4tyӂ˾gM>:0~ƔcRjeO0iep |F /J:w0W*3!d9Iw"fb:κ(&ꢣ>ȳe@P*PH|{3Ÿ/>a2B\Uz6)@r^Z~@}\Сz\3yadI̶M v|<Kk7oY zp"yc*wxlO *9poDv 3z6~-O<аr{|Fq =QD+{N-=+ ^/>II ,@sQ2\1đ4 %:Xlbzx ".nAr YXxIh6zBNOz݀B?FPP[#ԗC![E;"2C4qؤ@A~TP@ӵaPh2D#3}"޾=(hfDh>4$0#XlD Ifu3H-Ć{vDrXa #†!5(Ki2g Yq)4<)Y ψ;C낯v_j&1%l=0'.!a~-S#}#Ud;&`C,jeYÏLj<:G =$fX4qQMriBޗUL|2χ!=S:'Xw :;y܏M_qa pr:r1(%:<V9>ޮ C >H ж9;QK9$^k= 6[I"gc2GY7ݎHmI1N"-,Ɖ> #^D]O6wzp]>>.8|hm4@y_N^𩄃x L u!m)Px{/=^;l?~-}Ԓ^?ؿ~>LV N:::::ܹJҵ+k 7RrS.[WkXqFkI6Rx~7ڇkwܷXE^f!ܽ s@>7KhO{VOq/!>lw|lo3F U)b2\ڼZk}I oB{‡5-~~ ^3|J=O))綒s@='I7!vhgWdih[ BP*SR.GCQ6`+Lj`@h:k6 ٍWu' =25Oﰣ:(G@[d-[@!ga ={VQ:VM|Lp;6f i?|@{}$K17XSejy>.DL#!e&7[V>~2 ơomDLlz e$efYVSS._hbơ@5szޠW`; 6>dpG)sR~PO13# u߮  p}B|~ǂO!!B<< oP#`gv<tHyIPOw2\'Nr;->,x{j lkoGGGVN\ٛ_Nw ~>~$ >/y;cDžW:W.XZֽo9s .D̋鈖,YS:se5O$^`!= 4/.)@m#U^MÄx$w:tѡ) gdw*'Wm/IYɉ"a)b s0ǦXp#qp},>utttt<&+Cb!슀].^kOD^_«J3~ ;j<~?H/*oƌ/WP5%?rAzzAdƄ{){;&~7'= >-0Ȍ}J+n귩p4&8mU5]q>]ȹt ,5e#B=n\.^}+]y# lj5op.篩j_@5f2juѺ{$̘ǜX)_ȝ8|d{htGD{i8vxҐz1?Fзu/y|;) ۫K./,3K.;T},^^rFtRP~կ/OP%R2T?? AFs-UVExYaK|1DfƱ6@fc@Eϋ!eF/̩!yWQV2p<[,ۜh1H։=@~#޲ICl6vW`5V-=,3?ݞXXIP{~*߫}wqhDhq=_;qty> eԎ5{(L ![Tq4&9Λa_E?:3B$*?Vae;$>M"‚MSN2s"^ŭpoeqTӔ~Bn,c ci ﷜|] ;3yrDUeڿz/0p+"5)}y";?N|y=}/Erc/nRkJM)}FL}t綾^z6!m\J/ bZ݇0̂Y|=> nl׿NćO~gq9cAT>N-cw7W>?"qt#n.\ײ\L/ێDžxOfo-J$ M`KQ;j.=J-q2"M".尘"?^P.8"WI^4hCA}Xm 6( -.䙧,,x*'$|R=j9_mC4t .dA`bPx YbKYE]xgآC⭺GeSB' ZOѯn7 4R ,y1*zDZ^x fy)k<-Аx|p\d}KG'\=rc4FG,tJzsfQX'IeD2EB;e8pY-' ʔW v>M'sTg>ABC&hsf nNOǼ.o1Ir$#==Y; s4&vN1[vZlِ bEyWQ%"hlR}*d C=";QU}BX #- vXGGGG>|?|;^~ZKY7[c|4}-cb_ذҗO{/Ic&᣿/w+_B}a3)DkEćm{Nҩk01[m[GGGGGC^rwӸa7~<Èg>ոׯ{Zbwlf/7Cڮx,:FvBz7Y C6ݷXNv\0o~/XW/: %~,=x4䛌ő:0#JRs?y54=vy u!Q)K IcGʄ9C>({f$o_wR">p쟒_sQj` 3':"; 8JZx K-SqW~*?^ݑ!.@Wz3H ͯ'|:D Al1l?i&C&PEfwpbfWS>/+!(gm5ʐzLK􅡝$63KCxI:˻I'(yWh P'gmduSuq.qu{c# :+uH?M'R)VI=.1_9&XwE>b\oi$۹`5ϖ][ ]Fq!9ngN^s 2oJK!>O2D]H *%]g 'QwҔryy%{::::W/TO|0BCBL7|wP`9v|j{?ZlxOoׯy>KiX#7-fx;H?]0QV0p']|#=% it>Jo`{o*<-qqq~G ]V⚍;o? \(d%܂ƃ7 ɌDm]6eN lS}.Yh>xxn dQ.qOB?R7!zB<2rT~162r?pɲtw+o%Hmam;׾tE.θ}WΧ[WEvVtUνx#]t7ݸeGM+G\Z37^4^2{{la % {BQf/1iH uJ[WW`Yq;3sqb})` Vu a`} O$"F/GnXV}@_h;sdLGy+`[I/L0Β„;H켁8+{ꕼ vxv~U/)T3-i}=)K@|$9syUv/ x{q_2 x4/m1o(bW}EؐOyYj|+1fhX] N0u( &{Zy pZIЮBE#C+OBAz&$@A[9N?&l}ia vV9G?"F@X^=G9H3|F[(r2=iLcw ,p+)0(ؖڪLJՕ}3L)).uڂ = qPfJ>dne Cz^8&W(r?nj"cr\=^8s3"ce0i>jeBSQ[`KcE6D:&ЀDP?[Vcyi gtݐWPcBVg+Ff)Xyӎ"tx>xVy{CǙ2E&-٦ئ-}v!N7.+5Nq#OjKq'mQ!}0 :NygkPV-H *"R 4~d/9/ë=~r1~/qbs|w~džsYB`'`{/;j|L/>mʶשtttttl`۷ kTb^^q2 4d^ 6zc)|sӸfkw~L+=x#X.BCv)Dݺ]B¢K+T>s5ebEy1 +.!N Y,_R%̺ Yz~( qAÙpH)T<%x/>fu+B>lFZBׅ'^wi_~e'`!(LS2a-Ce;?׫B&M^h #> vLǝ$B9F#t.i&WU<p=nХ;3P%҆#] Og uawf9 ^ALut/a#7?Ԗm]BҦu@'T|,9) P"x.`(2 Le%(ke0e(U"1 $m?:E=ۡ 0o_czQ?#ύ-bl}#Y<'1 zH3B#:2SV?c4k%O7ڄ\G% ߚB`#Z#Zuh J -OwV]wr3[㼊As~ܟ8#Fx@kё1Pm?l {/ ~^t X+/?^{i/]ޥѱ#{9s_##tQg!5l,D=Ӕ`.*p yЮ9H-oBkmgN(0Wn<]G9U ȳcEPl:,z!"q657+a0] 39īUsi XāE\!";W<B,gH>pV e8%Hښ?:cIv4Tt9-Pi~!ȸ)З8)%I)cW<,qkVv<+/ZO!3һ{?y߸U,?]ޢ*oYqr3;+Vr=B=^ TOv.egvnE;6dy,Qc|u aȳ`#.Ejm>( #i}g'F]ϸ汈[ ;؟Lc/QLʇЧG3@L"u}Df09_ߧ119w]hp\ |2dJ?<7{{^jFZB$~sdGA \YU_]:m5lR!';LӅ?`~L =Ob )GB=W8anzokLu؝vE$RbP"U5Q]~l7׶`o(ka6%Ϟ1C^#{OO.|;::5-+>w}?q%;C\F=r&\ZJ|/x{K-xVv p W!aImcxv [4C\ #' ?[}"/jafyC吏 L@}al#@}YV4t%*+.Py//<-n76d{GJ-z2A!q"rױ9W庝AQiu5q|&ںI)N"*y!#^!9$^fuS]U]χ&Ͳ=M6mY#ɘyWnϤqچ{La* d[JB[OSlcCy,BQ/6wf$_|`2-uɖ.'z#[UlmOg2l,;' C;2H+/2>UmX#1ľ>nhgnkIGEPeEף}!qE2B.z~2x :h^JxY hh]Tr+VxՂ+oxWuƊ+VXb+ql7vR" mCR_&l\ȅ`ePnV% a:g)Gd-;خK&t\Fe'B2o-`%q^lC:I~͉ku,_ez1J$:'t.W#^lN}J,g|speHu+|5 IVRWlςΈN$S 9y= &^@0ڱ19H}),bvvm<Gی01ɷ*SEmMj" 㫬c&o8 pYǡ PirC|ԗhQ2* aeKu8ةUGjR.##=3C9+&ʘ041-># _JIJH 7,fS_ynϷ03G[b}jL-]m Doa—Wa~ps=ņk-6Փ4H_?6.V%7Q"3^3O_600X&kJ&`,W^9f/qYbŊ㭯NYbŊ+VxezZ^hBDރslFye)caPv2vl/,rņ685>@vzkWȁr9٫ˉ3׀u)j'Pw@:eI" <Ҋﵲh;6cII73 .}%O {X |"c#& 3(aIx#19rDV2Vz Beى݄ؕ;1Mh`N KP%jCqN߲cǍ qkm:(6]6z>Rn˕g_Du4u'w)@7={ŔI, !pGʻ-P6{.'4ф ^% @}/ S^ >TkC$;cO@f3Od9sLl`V؟Qfd*4 gX'6m4o3N%ї˄?ܒP;xWmg* ̷ɓ,UYGȜ,S_dꙎ ,1n!K[zR1D(ŘX !'LD z a]6dG]q P6=%+RīU qFzXOa#Cb&v/)]`*2rJ4FyN6e=5d^ɞ6vD>0(TUyLݤsD̆4Sco1N6A/=TGLQcm8tT.B 9‡Y\GK-A/bUM6+Qz]/KXLw&WU'C+{p ,!#5)||iÇR)ʙc݉ WIeNxzJ4"Wp O_UʙK9 bzW9xdR>WT \{,,֘vy-dOр>ȤT$/|ȏ8" ' 5~6x[g)(GB =X5'd5\+}~s^z-m>l*L2z;4n(1նD*.1G )6C§lSGԑؿڤۮIGq2Γ>C'aF>P5$ے2 ҫWAۓ2vVZ:b1(P&ֹU8me' G$"k p8-CK` Ә0s"r_=p|ږ‰ F VZ2$GM-=r>tNVhgʨR' T-A3XܠD3cm+<s >觐9Kq]mSVEz/KB"LY̊1Dƹ_luu[$3&Ly5}P3u+pXqa]cŊ+VXbťWx ޺l90fva^GSqMu+=dc4Qry1Ӗ\} zюzՐ?!ݡyK՞ZތK㠵G$}PD,C0{ibXV۹' S}kI? *ȁo V'@DCA!;Ώz8:q|p>t+V/k_;xK MzP#2!,TȼlI/@<Mܕto rX' 79ڟql1XS'O̮3ez8l ʾ0Y[Cay `<-@yIPNIG|zow÷ح^lE]^ڑmFIׂcaE.(8] +JNI8[ǖcƍyM9k-N *<|~Ԃ(C ro۳gmoE}e;npǨ|O)7Plri('6rcؐ Ye"FE2Œn 1! P[F1|mlSrvXv28:aY}5hCvPc'%/-/|NuvF$Whus j Im?f_y9g4z}qVRw!Mu9*+ qxuv6"c'3oՖ {,/˦"{a1m(m~Yqiuc \7Ê+VXbŊ+Vx@Gظu|]@K$iN3-zwoyNȐ{' 1E^ސBchcEY?#*aWj2FwP1e|0F>+ٽr_o1Xׄ%$A\a$^p!QO)΂ΕWg.'\]\tuʕ [r7ƾHq/`r*+A/(l((Ok[AwyKP!y=ׂl1lںȷa9j ٬66 TLrNmPnfaW*/7'qt 8ƯejL$ fCL.9˅?rJD3m&/&b` K~CҐ\߂RQ&ؤ `:!?faM{_ ΏƿThmw%Ǽc틝_L,'91UD{(7/^ Ę~Ie;_GIeG3CIG rv{fd!=+y-1+'TUyRVTw\'wpnwl gL-GD4>m̶G\۩%ZԃX2I}ؠ䪎܋& _=>Z֡LuQ=L5=4 HŇ.q _8^WXúǕu+VXuOw xYek \#]ҪɀXvgV̶"ufxm@~ DcoᏵڿ rN Wt62mDZIY.ÞoS#q"A%dR,EhIhWaݶR(Ki'):xW7U*>v1xȲZIQ@:Jhc`V`Hc/8n|0IGEm>sbyƾ)R+˱>H~"#'yaS֓Ow=~cE]`9 Z=!?S"j@oc>I?u ]Fz8DlQE>A'LD3B~HX2ebֱJYHy/kJ k:'ʺoEx-n5d$[l14*ː3f?mէa/;$P5]P"h4'ڗP7 LX ]6z%.s<le: <#lƓ ڧ@u?:֘1kqD鈠ImczQǴ\%t9:mLֿxR lRÎteL_Aˍ9vgj2u!اK$"u+]t)<8t`}'FҤ "i6vmY9yK0rE"i 5x-jj{Q}mtW\cbF|M>钫=e l-Z@Pm.-a|D.*2 ɇY>Hl%zXm_W[RjvzT# >弿IŶ1q~Xlohڗ_v,]|P뒣=ɉ@^qh۔PFrތ󪳬ULBh\:6$6&ٶĬ!C^c!Xr$2_mQaēOxVB+ .:*ԯK~<2U|+R 4q_hcآkȆDh,o+Vx1q{řp;{S]wQ܊+VXbxOyK~^wD{W]w.LRoxoˋlVu}QךNq?b~[1k ['|E>tمwqC~NmH~ ^[&×z zЩiW f}]_ :ognLGu?qe#uUx2/Ĵ] l9Min3u⯲ M`GuSR2 =`QwAԡIF,[Y~#yAAڤ7}G~lMz[Y|])ip&w'ω8C7][ע|O(|Rt }) RN!&zZ{tlWu!>MFAyvQjG|Vzxr) 5&^|4g_7- ASg}D 6>bi.xT^GcoYA6&Yvx<%*H{ n/40^96TOD>3]ȿ뾩YZumI?<#u"و<7>Gyem : r[5d;A;+\6/}qli|$N -gCXQ#2?rrг1ry18Nlq3o'{Mo3G2?& '3q~m҄ھ+{ >[uADWBNn6`MBapvy;>Ύ;IP t8׫7b#w(Gf~O&F\]=bw,, Q XY^׾/hP]u.yl]$^6F᧺ Ŋ+q{㎻w^/VXbŊ+[5 [e{-~&NL}ӛm(}?iE.n+o~g/35%̮GujHr5偰vr9/%MxHw>Xƛmb ِ˅oBu3r#;Cn쁞^GdQHkS$WefQD#êk Jffc6!ŸZuAhԮl5->}ʿPCFqzO{kyrE [e㌥"URq&x>Io1GQx(V)ڣJc }+Cm='i ;6MTy|&]6HƛO2fza{@c:6d ]ry~<_h*>Qr-2s7xMA>DY lď(O >6&xulBu!D. ұDP}`6-x}@1I@9Q f2aƒ6^qrY6ʙZ~g.r׮ɷ]ڲ\",CNi#r]>QnkAitK30`uvȁX챑t)i!8ݟ,'j$|92 sM8+$YH{ĺZKcd`gHnLVeӯW]n/G?Di}zXbŊ+V6iiرmldpRȻR 8xzW(r"_{Jrhvetg}}*[+莇jW m;j('F&It0JeKW؆և'ȩ||.wZpJS6p%ʃ*S6DH!"0{$CtVC T|[ĥW;)NG&D-sM }F%'[D\CvS4L }&6@2njϿ`;bBoSA)޹_GZ)םNt)3$ϖrTyN个|٫ N8zNнi>(}5=>Y.8ߨ}r׎qȣ, H$&1G 8.+f`LlSMu^*;adq'qX2/2sG*a(NT9pԉ?Gڳt8@B݀%Z-Zk[mXcE+VxUo,59Q㝥py;,u坚qkV}sGJ{.+ />P -oq?&Ow~Wyw|%/= CcR{wodݷ:cŊ+VXqE)޻mwkdb_+pi|˝ߐ&Ǿߧz;wBNGD7Q(1~χ1뚗rHk:blj7Tn$xA 14 ED'{o,rLЄ . DŽG>d͙-/Ð%z|&xgYkrV8kr/$ꡪL*|(*2#FHVal=>亚E6,rG66fx9yuhIp0J6%弜LJz/>ɯl8\ږ?9 7X$A~_{F.Ge0)夯8XO}ĕCta[qIv@*+[-,Se+WN)㙳e8s2ㄎsȐ(˕Gf /yo b\m*d7PrN楸'!+lFI!V Q= 혛 +sK=Aiv(1e" 0uߑ}mDPu6DBY' V7^n)jTdƖ65k؞\mϤfnؒ#Od>.$WCUuoU3XVyɎe+xlԈ{ =Ws(sUז_)@kW\muFO=<6dOǬWeZ1>Tc=u$Am6VBׁeh.ʲ OuGS2/Ce,Ӓ|ohn|. ڃ92hu;z僼?t%bN+VXrŭz{W"D po7 _@|$M |uۛ47MͷIZ%>x[;](oSօ PeŊ+VXqV;w44gZ71_߶mE X?}:9҄؋Z]wM⚜(xJ,mI\^FIe^k'%x.Q R}% Xǖ؂{FSY!a,!(ulEbhy8!_”fr;H9cz Dm1lv z\88׭h2ɓe%eI/"`18϶baz} ONٚy>)dXW\ J2 v=+DyT# #"_TV8UʩSe8}>S_;NNkXΪ?èþSX7{ Gve>iǸ ƶrls/6ۻhA⧸Ym}$R}#6"M=&C#%T1XeiR]|PK&}_QNߥ&Ԗg H|ʂ4'zô^t@:^q:ܡI@`'-iF[^eѪ(njJ1(nԿ9qݎlıg)}Ya+iݥR 9k\ʬ}o:kN `=c}P ߮4{yn.[S=nI~Nl3' G[OC%}aHiCrs4dwni^:y֘tRkYdN'IWۗ|BaNa:3 "Ǘ$O8$_)ݘtedo'ў&"uvg"F'%YMvm/]`6)/z$),վFj'=h"|r,1ІRnF]P}!+VXm_G-wyH .i۾rwЪozs)wywċG:.-n[m|(rwyӫ[6aJ?_n wl.+VXb -ɞF\W'`mLtxodk<5 Q;ycj>гi P[_8fH"'{;Aϴ"{y_y s;3S-y=슟(Ce'8{2Rݓ9]2S28Ԧ)TG-Atn$=4ԉl?ğ#zC^uUVzfgBL`mI#I FaAYc ǂ$D ı^&0 ֕Mzb{ { Ia] S[+0fȘL$l nz^B:^:Qy?YY+pgrW "E9W8#}AqEjZrE3ȋ4&رNp9ۤ)C^yﯠj4x%B&?֙>y"ӛqz$YjHv|gּXc,r'A{%eE[7Fm3ذ:ڲ2 )hdcr㊍2i)>&SP~ARΫgv< l\q;4tX# 8}@dr 2uИS~KFFߜ#5vz$Wj}kٹLh*ڎNꊄX̿D%oz`loWc.|֋:NLw6o/kH,`i3D2n_thf,#~q1P;C|7QObD! eo3"80PGf Fᨥ% `f2=U%tl'2 G;C~R'hN ~'H | >M<#)ΘW'2}lF\β@d+ӆkI f4}7$]Cv>6`:{SA߰e=?`S- Jq¶V)9m'aN6GOHzXeGT7nnW6ber !5}Q)M: ҳ2>[4hRǵ d3ҳ ~gf20fu,O[Sԯ}wЗCdUn*[KaRshP3c'4F.=`AF%[1|TSƘ-N,ǻ?Oj>RO؂X|#/RzM$m#b'FKko>r;x SX#I^v YO WkSIKEs ۷ s2uԞ 3Ab&@[=NlFР6ԦDȫ=f{߈+V\1-WOznŊ+^e9-σun l9_ks|| _\̿/ٱ0^C^ k_X>v.t_mTl5] }>'bly>YT{Ff PƯ费"s<{rczqVc):ƛY8m3ۏ6;[P=(yyM04ۮ35^!1N gB~b;ݠ:(byȧSuqɧE Vxqpu$/q|>Tc{Ӊ2uZROb=]#~OC"' y\yO+,eDK`D ]㰇4 9u8q]rt#cvHE5&rIya3t^AOÂM!ӓYuZڂ1=?`t{vȣU9]WK>d'^`!Ye<)^4Ɛ*k;zؒP.pŭ֋(:ܧ֏HlNJ4t],tU &.SA$i\`B,TӾO/ Yqy]Dž\|DݱK!:@/ۈgB@/ AH\msגŘ!a+Ydwl]? Uňjgw˦ oї x){ 'h1/ۏe).By*pf}׬^J=4>ak 3"u~FO'hAtBqҊ+VXbŊZ,:{>LWNZґxOzܹRΝWXjKr݉v"\bgtldUsc H$xaˡ8Sy/(^<6QzcP="^kg3 7D О&"ar>Q䑑1Ճxdy$.Kp?Vd)xFDN,gNs ҙs ίHB Jǩr8p|ޱV?=d+&/H8C/$+> u6Ɨ˕/~U%Ʉ>] yպtl&QYR=TYMcMj% ˆ)cm1"q~0o3۪ۋv*+e9'mnR Tu& &k")s<$G6ӓ[_tG/]ܰOfXbaW>7${Ƴ}5V}4Zfl advgNN힟n86\xI _0af/ fq0e [xfa 39'sӎ݈S%̊/g+ple,(ctt+pcݗy[@V:j<b@juozg<#6Ta$Xg]5>ڱqQmc2E1\|`30o2&;ۭZަ3h_m6~fPߤq 9},'Oj{hR\u(omg$+Nv^F.czTdS_7@OXf>ڙ7 </:H,^"-RE!'r(gFZ1x6Y,g;ߵ d"=d߸Ϭ߳E)jtx ψ娋"W?_f7V1f:p>!eX4§Ivy:fQF223< {5Gr0˲ uu+W.˰J@+Tx8u4F 1mb%jS`q&ku3 lHM@Zs@ؠVL23;Hzm\‘⩶^c''@˱OC1,Vqa=sݪ``Չ2W|ϔp9O= IE=-哟5̳VcϔJO+(Gx[bx15_Kyۯ*,+^!xuN"lm7A=wd#]/^CO[ C 6 >QЇKj/8sŒav۹M~Ό} s;LIO#%dnP^0^TMg% zɇLЎ}b RBLv >TXA,|~KRmS'$#jS61?SzO5*Ѐ t|SrƄLT _SUG@4>q Iz9 sLjHROY}E H%:l@-3(mfe/* 8RL&~=׾XUޑAd8WٍErV&N[VeblE#?s4A2[#/K@]^q^n2yHMx`DM!ORV8uJ1"66캎^v.d2cjs|Z] ʶ(+e &ԉ# R6zf+zDDZB%ԾZs 赓feʤ-8RrG2s>%;lm(ko<PSO}x"a3R>(,$ Grh:UATX) !}G X /xQP܁^iUC괙Lsp`ʓ(m>U7}lHnx_kѬMkՓ@SGEn^,ևLmxa!3SYT6|: ϖFY6*6YX}> -.AgiG.z}KB6X[͈ےz.蕂kbŕuǕuNJ+B;3%麍p N̸s=P/ q~Aݿ/#g)ÓO /=x)Ozæ9ypqݵe|ק ys Vʯ ]'pxe9 ;8p|{~B m) P,O$9_~e+LX7FB}z_(KEXǡݨV<9vv> Hю}"yn!j[kԻ&3]*rm Jy~j|# = 9`?'KLPQ?Q:S?ʬG^IN +V\yX'p\X'pXq@8p pe>vM` Mу ;ຘFdv8Y{cwR~Wx8㍜{Aw2xA״uP.6vuօ/%8<;avo;QЗ)Æl@2H)2K0~LEGn ٯܸruA-/1۝O RMK }Ry\^ذ oe Mnf}9iz,F'34KGKԹrʓď2e)2X6NcXݎySC{'Q4c(ISevMr9nlk{4 f!gluǛ#SgR?Tn˗[&pD!UJ"m/=$dc)}Jl`Ί3LnƵ&p$l Nw%O6*;!_;!/X v4{:)&wk\H%_;l,ًGEdnK/Xun ܖ'8pYLV`ֶolK? up"aZmר V. QY&f|=~(ɠ&pSQsٯ,N<Qf=2NjzuNJW W +VBy^uZPy>i ^/D_(#B=WO>POTe(C㟀_sM~g!Ny+e1W[A\mB;Ξ-O=mc|K]<艷b+ ",~"iV Q~Ht\U}L~u= >x_*CA*}@c'RރWX=oCEߗ$@3-wm¶CU<6 p4HYgD a=]M0>RK뵟mHtg+yzь]Ym_11XXDĐE-_=H<-#rgC'$be'm˶m]p?-:#3g>u^ȉ/V6 @Gl)y*uG&ŋ]ʬS bra&)>CVyPkD[a^:Yo7$VϼV?!ﻡ>X8g yʰuϙ'?Pex>HMo5n"^ߑ?"Xgv/^eiggȡ>spV vR{?݀>$|M}Έ!dHi!ӟ!߃,;HA6ڲ/ AS'xwr3Aar)Lvĸh3Ek#3S7|M E[wq- 8X%.'8ƅOF/nOv度6㫉cLlUsrcc{iC\ʐcnS%  -T/gC*|Y JtbŕuǕuNJ/Chϸs2ϑxC^FYbd78Ay_S'>QgJ+è'a|p}*vOC?Ӻy2\@ϕS'x&uGa4l?*^ǎm!ݚKs5!'u!1"L#$ScB:{[ CzŐ D4r{?is?lyCJ@FU@^)9sDk噱2"+Fҭ@k+#|UUf\ Kv J[۾juMbEnVe|dcu`I xJG FuWC~ ev Y+}=dIt1󘍔/Nf#[d9E}ta3Q; )9b@^hMmЉ),>"#18Z;2 <1r6X:Ƈ3w }1s9'f펎L!ϐ2. ZlAcKVдm[8cw<~$dC.̐mH97BcV tm.!/Hmtٵ^~8t6&a1tO'c;Zp=De&mKE{!Kcx/$yoĨ]<ϱrYtCo{a>Mڂ.h6)fb`{JB <ػ~PlB?Bl2yL9Xyb:r6={}B9v\XMɺj*ʔA^>LmpX?NXJ::cŊK8g`yB砚q5-QU?zve@ 쟂G=EV?J=XW/> ?dqCo`{ =Nr&>LU.@G9 ĵuƾ Kotd.umVC@{Pc$!Ƭ>8Xj澐5wbO7_ݨG޶8E>qSTQfUCSjm6lڶ(U'7sĶhm x5>m(* 'a|*^/IHY~4E:?Czb﫛e ݏ#m;@m}Uz)y)97nd?D&pɔYO+#*=0v1iSbC6&iM2C`^MSM^@6Pny*;" )z>-vW 4Gm "bt': 'de/hu|>t1Qz.2u<>l_n |0ߒIxv0)D#ʉX-6#lF]6|-緡k̰F}L=u)m@ih?. FRګ=P~vA.YK1ll>ulTF]qMuNmbǤNPE%Gd'8/]>rUgfnեS/,vAlLM%bFDu|{o zֶS|F'p볍[>H,:;u,2|(o}gQ ?+ydg)o2Ԛ$d3bu8XI'N~=5Bo֜'4r!Ts:qS[ +V\yX'p\X'pXqD(ck=>꫽=_sgVpze}e :>XO@0rE,p^6<^u? d)|{]o/}K_Vn,w^_8N,J<O9Mx&DuRΠ}s&)c[/nN`q/h^:!ϸƷ2pN2=CWkp e2\]Wm(_߉8VNģgL xȰj^ۋ%eu , ǂL&8wm q7tҏ9˵1| 2ĕ>N:~Sy >Uuk;23CKٸ"t߬^ho[XZ_vT z|=~Vf2$~x }ڃ"ߎ߁w~&p)C*ږ}e_zQݿ"yvؓmdmH˲JAKق@BWu3̓h3{ jMY hKj(o.[!/OB[^ -r,K`Q.E"9{c[% PH%2MB4912J"gLnK7bCvr~Ze,z\o ]~G}7b6roG{8I->7MhǁY]/T IQKgȧc]*ɟǣ(d.bqwAݞh{ĴQL:ծf+mɜ1u~Re ?c AX:{q{eg ?h;!L# nZR/mbŕuǕuNJ+Z?Y7ZƏWs8gzF=+Їpg.c/𱏕rR8ixcyg ,\78WhtR:Wחu!׋<` _};?^o~AmՍsƅs紒xVЍ,r 0x\탱|5vv=YpsOlW ;rsǍחl7nU+{pekKA!b5_i~\C?Wy|ٗ\Í l'?UoeP//eXy+^aX'px/-8,>XL/Hq Hn30q sm F:]'ں%eޥ+fz:d+fx:mjO 5&6)/ي vaYcEtN\SzH ,4]jO8O/r{eLs ئ(qf)(.赅 ꏱ!*(1xMXy &ͱ!۪!PqOϗ8鈐mvWʪLE}5I'/H<@O m$:|?  i=cM6#41؂H함>uDP^m臜d,c)cO0,Qc|uo˄a˱vf8sT^p۹6Ge)6$y_B=d2>L>P6}}>x~ML?憵Є$>5ͤSchq3%9#}OꟈՇ5+dd|{4;>t&&:>oѱӅ,Y1aW7vjnm}ulKG?:lEc$Shgb)5Nu3Om )(JT_p3p5N(}[bovIzX=O,~-.^>Ʊh(o~{N5W^QCFo4vFkIM׈}Hż#Ç,67F v{D0 O3)u9@|>",j>:X6AEz~zE~ C. ˹oTOB7 @k?g,NeI)'}e"{mJ_:۪6yz /< n(7m~EJYWHlDY &? ,sǺNJW W +^qps^:Hz'+p\ip^-6y >Pd>z`'4طoxco+U6NH)xxy rn34` zu~h2^~ ?lyqr/t ?_h{])=Њ8lk7ʹ,> .6e$Lzk@&*ٲce7b.# (G޼XKT-1^R5<~Sۂv 5F2sh(^ږ<_`yvL{w BN;G8,xۘO~lZ!hJ JI #b-r7zmd?,F3 FgX]3/lLH_Udה Ï<`?kA8ό6◁ʟbV1i#$?D"&;녊 -<~zGe[uec'Oe~h*O~1~<Ȓg`Pcʚ[qGaI'de xoߠ&kdFuO)Fm~ ˄qprBeL0N8hz1ޗMOm%BT%upx UoqPkm`a"v켝ñw]zGX:hۨR^:qf 3߄׉1wk0PTQ b ]qOmgr&:.k=J]6 /tX-jx[oMO[E|)_9V?QgC5.t٫\O\*2A(O@#cڶL#1|2-e,A}C34uNJW W +^q8>^^G6Ged=u'U4rcN,8y' "jp2W(石  oP M$@+rx79Qz</@X5s2rqpE 88ΜՄMNx2>B;?.<ʼn+W*?eds2~Jye8{N$Cy ߜvrR8]@(u**I+ۮS'NGN2a{o,]fٰ?2~ϿD.2~&+^渒'pį/+Ok#ꏌxzЉiG1t|F=t ~؆Wp F6bշw~'!> կo(mڑTF\k9B|3@`V}VmZ"dF}$90?jD\'Vc~~;9_MslA2yOYw s:m *Λ{&33aCEQC] }rÀ^c^/t_6|EZǐ#DXju!_MI_yK%k~.M S|W_ӎ&xK RU4&KB^uU1ʤ([< ;mB{ϩolg 775}|ƹ Uؿ;'x\oscE[ ˈ鏯Qф:~^'䭀xΉ+G7-}޴uW F(K>X뮳 8| 'o57@["|srS|fov]J C ̘ϟEm]WOዱc_\ˏq<{Fv=<@ K:`T]"j 5~ӽy^L|ch-$N0mIߟa)n"zVG ?,~ٌشۣqၓs*mKuhxgXu&1Ip_컰 dA=Kf}G)0zmeZ8Hn"Np+H 5xbsOFXYxs !}dbdk+ٿ5m5STͽ٦IƂׅy5?b uϰ4c;*tF^XnMD9I4Xh˰yrU)ՠ1⵩|\h<>=}X`WqVwƴڌuL';_|՞dϐOm/źVn͝hc ?׌: uuDmב s!Y_2~ނ!UFA"ngeqwGǸ3L#; ݬS^ 4qDžqfIΉ璯]/|`OgN|Xm l_8|Q2 v؏~|Yee٦1cí1mG^eK?bdO( Q~@-zR>9heg@b-WPԋ8@'.TX}I MHKy >dX(72>d9ȕ'NV)]K\>2'5)%F dBF4o2i"R/O=eS'HD=/-Dy$mRxZxEu.M>N8 9>.WI.irq+O.O=]O~}O"@A5;U+/Y+A_o+l '?JܷZ~ŊW *k<09OW쬊T1T/c `.tln8_FE=@@1qvhGRɛ|yvϤAyD->pEE[>jtbq!fzNécTvrr=1bn/J)nW^ElOS"e>z8ﻰ4<#R?u Y&[곇!l` L ")qeB'pN."+>lsyzep.pڲNLQ־e 丨KE=*Pъ7R` {e~']蠧 Qv : ؿ'kLieD!lh ƁBxaQ멸o6=CDr5TF*<'ĢVVi֩яsRK1N:"yaz .#x;u=|IFOvlߵ"3Gl +zɿa=c.d=aVF>n3l/1QGwQ5}g[Amb݉~oz#c;A:~ZBFl a~dyOo?&Ѣ(*vq~lGgv@v}_ rX{7֞Mp/a)b{Ll+2xz60wqr=li"<^?hm3)@u?7:!dvqC1}#'OdvWF:usv[kX,(;姥 )KiaOI@6Wl~$E`;̇&GVyC=Uă۾+08 8Vs0_5e.[8K}''\8_FfqNkp^sMָ 5\u&.@+z\}8a9+dpi_k| N Wn)7 N,\Z:ؾ5exx#WDkiCʯP^R=ܼB%owQmlYBWc6ݪd _v@?u xɉI2mWpLkK#s&dv8*T?U[%5[i@>PY0p[ǐ1E<7pY"uL18)%x#ZlexPHͯUl*]>(؈i_I{5b'(%66wgG+ <׷Eߥ>:Qӧm_ryy(yV`SOmx-v~ć|__2=N o׈TƿקTnV5 /97t99YSC^B9pJO(_뭕@/]fP9{_MGйϠmf1Ÿ}-;~hp)}kD,?K)c|ʨ+\dyD$Y `*mtJv2ɧ t@]v9+l}䱨6PUdŽ!dl~X9u6lDٷiНZ+=Va>klDxR[!4GE K~c[7PG8W]7xֵq/{6."x B6uȃ3ۑ}he?#pXK2-v6죷w)}c٧K{u թن"*ۚY I7_;ll v's}!6v[%lƹa{rsmBwcmq E zâIGP r?GZ1@W1b\|Ai ()O\$ xuNJW W +^q )Z{-S\eGʑ/wvD/.#_I+_j.n)kl2g2x-O>WF.OξpSe-Ç?ZWR^x*2՗*W۩1JxΟ7~&00e9"8IJoLI ֪#=W _(l| \[7 _+䛓6nkL?'/`} ޣR~6/_!2৐!х2?>z1CJJy*3eel~2N9оx=]o> Zuc-U+^X'p`>e~Yg1Tt1eDz,vKujXv~o>y<G1!1|6Z] `j[Xm[kHs9`e&L<ӏEryĈ]nﻋ`K8Vֺ=y*6r,?z[0lxGl,ϩ.s[05n8p_bpOfvM2 :}S.A)=D$ :2 R9kC @ O{ 2Ph|[mU3bXC&/&6[oXd 7ێm]WheUUܔxX~]A^PBzN 2ȈA^vdݍx)2>foU!$:AB@:'Oyu@crTU3$r3s 445kw Ieņ!|ǡ1z_sL$J;kfrfklW徎~֋m;)v!V%Z2\ePMYt8˕3:8Ї:cŊ+ +8nBq NrΧ1ŹWJN*Ïp)_uvAGIdBDk:u!WYk՞ >.O uZLk}Jpe7D ˾;+'\|f 9;*'?U7ßY{E W x_Oq "@*eO?Wk.הO l; q e $ޠJ%|[wm۳/ѾX&̀FPaW%I/+Vji7|1ecY&hԜ/N\ ~myL0~ ]}~6}1ݼg,d^rsgvC?=@.~n}j/8h#m.-B?j!3:8qS]nal)NNHJ#vW潼.}Q9pG'>a\f&GrQ:!]q߰d{/:e@mm/׷(~¿GGc<r{x1~EUcl;#L#=I'#D̞r\h_; > ;e*mL]pƪC\Gy&P,~0u=˱dn"od#L>`۟+!bocu|֖~KaxZ[u2}0*)/>F,TSa3|"A4Xm˥2 K2a[=.>Mŋ'&pTde>#ø;eZej#9;"ur'D9rIJx]3بkc ˳,]B/]:Du'};;Š}|M۝nLoGܿMc{13k-ɘ3]ou=C'SoC uնɧނگUG#ՉSMOxwG +V\aX'p\X'pxkr;2w_?su_:+A8@z uxNŋRH\I7C)ϫ(Qy$N  'a|CVʣu$:c,6~2>|>2G?݇-eUgWoRuZ2Nc?^)‰OeXתh&?(ȕ;z+#'R _sVC7c<}+f|/ !ß2~7HV eD; oMO:'hQ~惥s*2 OiBG-orv>sWxչ|RtMc#O>9MV'O_?qMߏ'Z03_56%r.VodS.8+eFݕ I8mlEnK}4Ǭg/-ʄ"z&ʻ5@x[m1 CōIYx">!Jƹq 퇊kAJȲa?dJ3 CeMWAu%oXUOYF9|].W+urYA| c ry mUȆdXu1htmgbͶ>LC}4:qQvN6Ml8^uU|~WpЁg>=2LAL&U0:4ĶÇb!ruE8= =Bݶ)< #M@,|VmEerUW K3"vL^rMIy[B W0hj{Pm@:GT]M (өvz0.CvrLSq+e jvn=x]9GkGg쫥qv S>m'NBevZcZ@8j?jдρ`6;rmÆ 2rѶ(S6]6ںb6aR AQONl0㠥K:&E<[ bI(:bϋ?2IddOHf4yq$khXbŊ+V\u#?[ʽI\un+Op=exR> zN \x}69cU(8ˎ| _A\=Rϕ?U?'.-2/7mY%)2((??QSm0x2O1168uLkqo%A臜)彶Km>S?Q܏DR bHqW^[s%w ! `eے~!e >Dve 0+2[Y9ĨDr|]MHDD{K쑯PHO&:sS'i*b"1my-̀q|c8C ^+0[dkuGOm>TvĨ3~$ \kJ9V4^@ڹ^IV_AGr;c'يh(7_mˆhJ*kU6|D'6@ BTʫ}ܣER7a/ 5Rfm dKt\ yV6,c-7ՆlEbm7ӣL'|~Uv1[޻q)tŬ&/G;1l@H`ۃ=A/1`tۈ;D5bq$Y' MT7N}ģal7,.zě]$e䤍C!ۚhA:CIDAT&u!SSsHN4c+VXbŊ p:UZo(箲N,c~pzȯ@hkqpTD hd <΅xu#My2~2ϗ#?W|#^{nR2P2|וp)ͻJVʷRceKm^O+7F+g=|]_/qkяaWj?3O?ͥr[6>MXƟR N U8>zg\9/W#~ m1?DÌS'3g_\ʿ~)?Se@q瞗!W 6~aGmjƧ*卯9x9mv#tŊW~K~8L=Co}9ջLdT{z(qokNdr+z ^5w buce6gr"Զ> rώ6(lCsudlE.N@#xH6DOk;6$^pپzY5$֦QSt>h}ɞjBG "G%ٽNq8$UkFEdpK5w'N3a;Q@' 5ʉ3gZ:8C9pq>Pd؋A|Ή$_tp_R=O@\uL^>-7c1%;G-,r'0vFjy#bid(ﲱi0V;^#(˧'!oed,6j y|5mSl3)g y|P>(QΫy2ϳ0MDLAg12lD9MWHhX P ' 8 16y\0 5rAf_gbrqН 4eOh\4c+fEWPH5T-,ȑ$kڊPC1k>cwҠi,10A"NjQ0oo`Xb2l}q׋ƴbǞil+momǃMSe&P".AE-Q͋ @Jua|#\59Yq?ף:a#zL,ެ+VXbŊ/ԑ,^rn_!+˿N@8}}<9yV3FN8q@mWxSz5IXrכpoqb~/Ueue(Se}菖7m(÷?ۿio <$ ޴?rp%[n.#S~J2ވS+ 4Nnx2>C)\22*/R?Iڐx`S?- ˉ)kް#o,_uu9Dc I6r73pU})O7^[㋿ _{q% kog#;c5ăݘG;Wgyeh#Ybū qr(:.&nԵť9q/rm=b#qϝfg򅷽mKw86w>#AF>%ة\ :.ڪ36&9O<OqN_Q߉:?_9w479'|k>NyW89NGzS6ߣBl}6l0ǵOA<&[AM]shJۦom[|X4d,+Ddfēl HhrH2 T3e9hyG(iē2? }ژѐdLvzzp+VXb i#8_WK ;=Lʔ*#HWq-2o*RkտNo('d0IU"}NyRx{ eϿ'@uK^M_zz6& Vs>[\?^2\}U٦-\2N#h+_\)p>MyC?jO>U =nsj"7RNjuה@?, Wz;'JLn{&+krȕKe|gr*PW9;Wbc=Ř;H0tDrMƞ'סY[6@O1hwq{)!{?1&sA{!lyn.|+teMMg?I<ԽUsu5[DnYS+$u{tC<VAzmDDkIp}A ^xhȧNPOyɎl1FfMylsєb%3_]n41$3'}(! u~եgSk#i;1y^%:(гUR?}fc!2i}R˶;\&@rq<ұ˵9aG/ 3R}h+Lcao;Gu\fP}:~}=)v oe]]NUv(CgUW rD8݅}ۼ фΧh;] ܦY..f 8.Up#l9ay"*zI&&%[o]y4xrK 9CVG9z,.AFL2.Ꝧ% t^XbŊ+V\qN kAŧ#?ZC\gQ\᪫څs"hϕϾ~d| $qp ᩧR=+ÿwvs7%N >sK=2'opuNB9i2\8_FA'/(eउ>ġ\&u8WAK` /|V8qrN_U_YʓO kЇʅ+p~\'W>Z>Fܜpb!~זGJm/{[~n]yqĂ6ACZ_7NgD!_ .}Vv۾R+V\yHqf[.q=‡K\r)%P.EQPya4K 5ԖK 1J#Yh_uq`1Wq%†ccj M|ZV#^Ԏr0mS.l0l,&-UF'kOl#W9 'õI9b2eBvqDXf["EHD;8^Xe{(Pzvh>yqeNW :/1lEԋ(`6Ly0;"U}&Pq|}eHg)SAY3(d8ޝR~P[cI`)Y6z Os٠곥 0G~r8Qԇ# \#sb(˳]dQvO\|l1eZB>PrNCr?qu$v#ñ#xXj_P;zټX鳁D,;6GG?i5z'a;DUܳGԷv]&;6@ cf8/~NrAC9DO~ʶ7o| U8kQO'GcnR?֎+V,<^`/Ffc/E*U_sل}@_}S)c?.5fmۢkZqSѶe6ԇu39e7K 5ƣ"ƅE`hn|Ka_,#d] I X> SeyCCIm@MiCJVP"sϳ7#|Rxo5enU.VȝIbIxjLǠ<6X1(N/5.;A ]VO(}fr-rUmtIطA4a2'Sz 8R \)pG'b,̫$dSe5b@AXSu$~a8PR![Kt%"q 4KVji'?̓Xu5 A9xAS1~35eTRtzMT.N@rJ`bvbbŊ+VXr/ 97>Q+=M8_9;{ U$81cx9; Q' uW?z]~2 NvE6MZy2pb b8-MZy#e&|qͅkJWp|&N C$R>3|!ǵ{|3ږ3zkc7NS2Yz܌l#4CyYdR~̧d,嘙'yl46`6SːCxv褸V/c* yjNtb#1<&E2@ 8C592ITAzKa$B=Qw[""8^xlǩU8O>W.:ϗϜ-٫Jꂼ!iNNr67*=Y')^㰢V1~N?d*W-Α+Az]JP F9FB> vL!@/8GBc_+*{ Me]+b;;NN +k{sl`l'LA3"!tu$h3tI1Վ3橭h)j da6I>R7mTߵI&$iGܴnpPQ Q_JN ;G+D5V LQ`,Hk* ODR(# _L+:mNS>h uQRY,}qh{XaGVP=U>*)w`Lq[OK|n }ZEg-#1B5mecSN@ObGߑGAo0]6ц%y(/7ҺzejJD,ivTst"\H* !>6єd3XrP.TX1Q9xJ My׺d*s| 8aCl_ZC^_^/+VXbŊ x&Bppb-xSg<9u/Pʡ<@ګ8״0*{<`8!:2I ?>IWY\k S *&Zoc֧Δk'Ŷʰs5ZYG UP'\qP|NSOå &Nrȕ9?^mCCw2|#e g85E^l'}:m}6eR+_9٧5㐯$?֔Xmxhח?W2‰*c,Z[}E+Vx}1G5hbW"jLоH:gDN=}=fJ,-ۤa.,>*[PeqlV_93R3Z%M|zAS=Z@1~KF'xP^xK3ڶ|-t3\7#;Q|J|M5qBv;d?& (9%,m SNQ &́,JM=ё¶sNM0 6GC)x:y.hs8~aY!ER=QF`8QZ'ia0Ә!BYN z Εdc~1huLτLR{E+j4mHIKP &`PAqձ!H̉Zʼnd+MxYCQ,oA'1Q.&p\Gے์(t']lS)1C$Y5#HN'm"uT gCQP{mb LDSQ2/uQ&yAe]b ;KlhmS㐔o֗ A{2Ei+Z-zu݋ui{Hlc> YqѬN'qrڎFhЫѾꀹH85:A&i6, yo1@Xٽ~>Uqtle}+{+VXb<'Ν-g~FzN^{x9[~V !\`;x|4W$^t pnÇ>du| 'pp`ZO Z傯.G++~^q_AT|OR{&,\ubS#銧W]U`ǴZ?R_+exRyV9+L yM)oy ¾xR|ns ЇZʗst/},q?F]sN!}8eZk*RM)7Xt07VUyYEhy_ ~j_VO!a/SO+^]1nh3=G.ꑩBR/Ktȱ%)U}jQq?ېj>:]P‡Ŗvt ?>=2.Q\;E_5M8;A$*gcb8=]4^S#68fbՇ [<*s*H&.cPxd׊*=F~\9X { I//JT dYJ 'x brcs{z} ^$b`l59q'AD 'Ν)&:\9y#k2O,#W#U?xH>ہ\XS|;:䈾!=751dE&@\`F7rVX@~a |%@3E K2j>>DnRt 3u|+~8GN Y6YoK6-EY(cv`L,Rڑ/9ǃCggϜT>3o<C7邧CY/ܿWr"MaJ'yk7A^w606?ֹPIU>~8A#/sĜbʸ&l׽hDk>l߽rl\?zGXҷV벃cc+"D "?-2 |p쀈EƘ&>K?0s.R]/ӽ,@ƛ^`{6gԝԓ}|/ɻXhw)bl=gv貀vII_bŊ+Vx9/x!U)DoVzי|U:pAU 0r/XΞ+#c/or%s" !q1ϗ70F;n)٤ RP ڧMN`y}p뭟m\?XC//ዿ oLMH9]+??UĥlZm} *$ J r^ Xev0Óu'i8镊gO|:|-ه~@Y%$50^˫ΡAro_|#TB:q6eX.c֧A ڽIߚ<1gƕ/=|T:^ YLr?{Vzm(g 傷 jҧ+eK/mۺ|AjohŊ+VX>G(=8aSҤ~™꼓)tnz/ZyxNJݷ~NJ3e|R~'xה ?r @qu얯9pURzF+x *|5':Y',Ce?۰_#1MX"~u׌ w_F"䶷h2τPm;_N7~c;yT <'*[j6G|Vտ !ה[&i+{4[p"SvœO)'(nt9ɆX:#zK $\ o= 7ۢI+y2~[FȾu[? ="[7+Vxe UrQ )7d3oЯ6:2GnEŴ7 jh(~}ף˶=&q:C G|Yb L<|, m^vk^9@zP:PL`iLmC_$͆7'mD!οIF㩃reNNgNdYO]++Mj=DgU)O~l?pDHNÏ&)h!A$2/t$sJԃXt qנ{ >)ʬm'#icmW7S^,68"H~hSvзO(b>kn!y=bz5E캼l}bH#œƅ)w,]ċxrAe=vZ('Ҡg}A{…Qtu}/L/Ey6xbt]~p5&rlF|N̲L&yV6(@382Bp/ VˈÐěT'EA;Tx+VXbŊ}#Wx2q\=(uו+I?|9'$yϹC{kI-uKjdI2-ɖym<$CƓll~}ld>xުU7s֎kX;#=Ǔ{z2-_W1 D ٴxܔ#oR?cT`@euy[!Ԋ+D0+s)݀|}q%l3/~/Wԛ[ Ja>A /bLH׵*-NpM4N7K?YDO €}AY?Vvs9#(O}||=6|McNϖvҽ_$']s|E [y>*TX`[<k{>(`~7x0 }|+ c7OSЎZwzȾ46^8 g-bjh-h+0^g0+uكiĦ7ڦ0'_ݞ_SP_bkkuM" <ВؖB7^3 ʺ-bRoc>c~ě1;:"O@',X` ,X|h o0 3|s\Kqv`p_W}!"-xj +RjYq }Tʊl^vtkRq~ew(XcWנ V=/o_4; x{K|ޔbW73-A!\+OPwO>iBw*ҽ򲮚>llL/._)|#2-O 66̟+!"dKF9sOʧP,CR0G@^f eʰc=xѹ:w@z!hu{1tK;0ӖkD?35 i1Mh}<_eYy x+#:΂8EVWuTG绬R"C.#:TQ϶hCgxyXc,kv^S @ "l3qj8FuL%\ (+HKSl]}OM{>>hsW@}[p՟q`83O*%Qe{}h*uRmtcek×-60lVԙЛ@ z#15,F3mÔTX͓uy5 fY}z#]^6y:ESkvaJwZLȴ񔌩F~WyS,X` Ĺ _MKårtG'R_V:ng*|opAVyH|Hp5N\WpՈz׭p%&ly_U_Qc/c?Ysϗ‹do(#FtRʗ}ӥ)'~ږ;flw+30K#+U d>Alq7x3/nHq\>2آ=[`L:\;lY_%^y׻J'>\.cܿ/j=Gx38%6c ] ƿtXΗ?9aG,߯c|q^x ni؁9?aܳso,X Beچf dqYzO6&oNO2hmWfusslآ?S >OQ+N3mƟ]|NL7<1+K&`v#v1l ?[ب}nXk~r^_l*<ΘqpHu +a'Γ*rZ{)M1! TyaS1,16*؆uc|TjG. sjDIZp~WG2H x_qeKr0ϕ:p.NYp?5sv zx:><>)3+Zu8_G_d19PΈ:9G7AKu_P2, pj7xLD&w gmCwDF-Dk'˦~AsEnlKCs{;^?IthOvB;⣒K#:;O!?}L4ehFcDJA+ߔ )6ؘLNhDmidO w:u'h'z#&42}݅9>"nέ11Vmgپnaݞo ,X` ^D\A 8^-FMFZ+-Znׯ)`Ig_r󆝛BO5_)Vk;9P :]?hYܟSCQ+yth,A"|ǿJtӟ/@)_kVQt|ގ`KW7e,gkp%׬ߩU=.]@1V:~vq8pp{$W1f?CZiC~9"H#X+16A4lgSO 91աV0)ח򫾥?_#p KtB!{FY1mg[7(A;'/f\g|seU@`N1 aL߂ zvvN{(G٨4YPˎd}1r U}OxFwrusjk;cmfw(+?k3>t27+o\m{6τsK27V.t'i`OM6qZ >2#42ujk|TYvN&/nIm2<S],T1ȓpPWD)rՍ8k+9D@h|@lFͣ-X&OQ?K`Q&Hf.@hXflKBF0~b7Ib n6>s; A'<߃ z`o^']sU+WJE{1玲/?[O_xjS?G1EڀAOq~cw)0D?kn|\9Ys gd'Ko5*~ǹ~cw_={ޜ|%;sk  -nlx %oq$1fB Vy |+]O{Vnǩ [ck\*x D{sdMˇl0Zao5::;|P<U;>{n&$I*p _(h4dc$4OPϪS~D6x;@hP,DE"HAGou!)#9+($̻-ۺ eOc_D`ZP8𜙫^VܟX9׬\*| V +#O5IIeh9qLj Y=xGY:NRP>Qʈ>1OӿsX>pu9w;=y'm O_> mo &MXO3Xۆ{1vst S7,c` ,xʕz!aёtO~̮._*H J:?Wd` ޽* ?&,W-D d~R7R|W wtlS+\:lPZ_0a  Sfc\X;noM`mB)L:$%X{1l@"{#d_oJcg{僌tT[>fwG[PB46UGYvBrSxu*ȚW S.(y|PƳ]eZX{C tc0wA'\3pK@O\+pU^pu yqm. \5[&WIsٔd;\ R_mZ$xSr "?Ne"#ʼ^%8 sx ~n u'W`>S74.#[$/ǫZC}OJ _9U;)if.1P٧ml惸d+;s(^x^+H_yU RL޴!3ݎWg,5bgW2q.6ÿJWP7=p?o(~SK7R~'YKodg>[O~\:S?_ڍ ,؁cbgrfPm~;lx|.oɖ~7bC&#@7O۱ vg@^6}5ṅƬIVN'TBk?Y-R^8-WozഁSWmmoogfvuTt|&Y}mlwπ<D؋[m)@d+_#/!2\+!ϱ'imhEydqޡj ~jWa>WkVNp~r)/f@8ي4\E1gC]" !p*x)vXf Ǐ7yYe5>I6R<2ig<ؗ ׯ9#|  .uG|\H\=u/|x[W:-%QyEZX& YlFT-A16 L[ԷǕo3Q?EѦs #L$M 1/΢3_#LgB z*wװxOҾy8{fg0wK`ɬ*h SGn Ͷ=eQ1! Tۍ?߼W r~ ,XNTVMB.{ NMN^l2![u8_ؿJB{~9FYpzYOi}{FGQׯ_ w+C>Ex^Ӻ{O?U 0Z%@E'm ^\\_,c|_kVϛǸF?$w򳿦6ɠ :t}(CأO -]){dtq5g+kts}IGVxJJǕJ1ycj& ^ፔR~Ɨ/*/e{Rğ*Z-t ysgJ28}׼\_X]jx: ~׾L-XM| oܮ ʀ=ȶMLtFשּq1i(#l3 sr Ip\:> ;u 6ncCZK>9;w{)"Q.:?DٔهLp2Ҹ06syƇ9ThONa5FdGoJȻ~+Y`;+WH9VT /L`zsD,ZEYhQO!cgQyNA-fu\>JDV uȓGQeS;OA oQr ~ Nka(}4SdkL?+Bn>IgB&am"fkcfk)C&#aW^d'DLW@WS |Qaʷ䟐lm 魄ע;1nynX{*s4Z݅}͏}7)HDUv,X` (7xS򕲾pO/En(k^ㅗW䵊Ƌ/+pa|3ƛ: 6xu\vqJypӥ|cƻ-zNE?^z^ވ<&WҽLx*=_"`C7ž =Wk? ۊhJ#_JݠpW^J,l|ひJ__11c@?Xʿs OJwj[:#?@ ;-`|wKG>Z/r `>E|_POoz?R|G)/?V~7Kg>g>xSswt?U+n2ܷz ,xw:Dw5Aˆ6/*oC٧͸yжMg'|k!%z~)o8!?*1Oۢ:YIPO~ ]c8dE60j#cNgl% \)uc2t&D~rIm/Iz(ީSi&"pkvnuGY+i 6DJ`+"e/Rn*% |+nd8N@}Ye*ܶ,D-%N|@l} ЫW@.Z :p zsuSԇW} +d6~0^Ye0V$I5hOc{tg 5+'P`\;]#m+r,}þl `lMuZ Cvc_ 7AXzeycv F۔5nm}-!1卼St۾N-힥4jYE𭝱n?8WlIQSqJN $ @&twvVھG0$ r~hX^.TI o {s;iɳDG42.7 TҁTd`AU:"#L A|8~@3ض11+;?1%L#ʅfܠ,v.VDMeS$Vn&B6x"|~xlݢ_` ,szp^.||l\K ?+KWث7x}/֔g})[!Jl7lFh42U׿]E?\+J0Kls) MMR?#q}&p'(08&|^+\]W)ݯե~t7J=gJͿt]z^wT{ﵛj?åVx{K-co+ݿo|?kJ/RGHo%e˾toW`8 MÞcԧ _{B?4 M~hNN,8sڿB?)߅s;``9wvOiotG?k5:CېȪ/$/' &E'"z<Ћꪐ9hh>eY)o:GJV?& o$JԂ3#?< l!džyEjow^z|o`KnA21[y~͡=g{ˡR4)0sD>=U6}&6xUh}g O"6 _yQf*Jv[~#k9D-@C2uc{Xk azPo p>4/ ) gJDoe[Z>*cǥ29@$f  ``!v<Yvwp*qMR $RPTH3hm[r扼<x,>A$?c!(2adڋxk-=oxG5 mX9ΩamhDNEVA;;'zE+z 풍iX?O!guB3 "U<=m\ Gë3Ķ&} #l n0!m6;6F>K;ADنe xĞ3q(Q|ש~`3MWvH:;䑰mW9BW2_1|q#ڂ }Dy݆ A{AVqDܷgn:2ٴ}%D0*F1Mf ۗp,Duc\ N}ie8ZFqYnĨC8lLI< rjUES_TWWD్/lkm#؞6ܷ/tIs%d#Rԅ `MlsqV[y?u/?(lYhu9FG8 IR.i ,X&_P^^K(qtz} >S';ҙWޮz- 7)aэ-Iy-{^∀ oG7"[R~U}t2ײ5"|eاO?U:+P>cR)xg}湊ƅZ/R~o.q)Jߥ\}'K_~O>vcS*-^_=fR(j[J[/ v?qWU/u7<`A2Ʒ{Q{.ca//*F$#fÈZc4ǔg?  A}3Q)~[fA*Xu@-Ljh D|bf<^׻{$H2O'?r|@Cb>Fc|f3!G ON2o"ڤ_>p "F2fIe7;tiZ\ ]0'<)7Ds`$?C;u>TNecv&ԟD#h!X6qR:F ؀XX T~uh`V˼g>uK +m}_sbH^x渻ݼ_n/QrS)ɶEQ-Q\€seիU +Tc -b@G,7'n<<)@'ضHk\cµGwŲk3P DP(lz S}D,<)hjbF +4Ù>S;lRԇ Vhckΰ4ݭWQvl|oa'lz9G2ukKOH9b,8xyd@ w:<g*zŀw*IP=8N1V$/i'JCZ 1s^D${ E_+o(͛:K݄ g,k甏GNd:ױwQ@yS`?q2 gސcs/R ƃ&Kr48Vz4cϓ$g_9G` 1σ2a6PKa3cLUm4oP+Ȩu`vA'-cYbsCq%UG{$΋:MF#-X%b Uip&1ж99d 6:։X._WlUFs15`_o$~ZV>ruxl3jԑgƋB 8j.g2~RPIOZ~8^`]܂2^y-X&OWw[:xRmSz (]}{\I_~YSu= ;,/Յ{K/Xe}kK<޲o//RخnxmB \V_-z3Q08?(7}ch9)O^ڮ;&T7W+Dx))GH>/ZVjK HZWf+t}FA#òmgW7ʲg=w< rBމYrGF”˛7a<{ZY?tY}⓺_0OtORO?gKʫ|_PPv++c~÷O}l-Xp _o!|_Sx+?bׯ6y#=F9'R`'tn `;l3CFuX?eyo'bW6zD"oDCQ1|bdPH6vY|1>F6nHC ,l2A05N^6 ί:,&Yb-7 =62- |jQ 6}='Uq8u ==6&=ϯIn$Y.?v09*_JY =&0ĸ]1O2>~9;$5/I9|<#3*n _L-d')om[s>O#yL^/A#K$}cbNR%Uv˪[.TT}yl>yAuS^kx=:COIur( ieFHYWc$]ɰ̊U髗7|b QzYWP7tJ3u~m$2稓/< \+=}Gs|rS{&`xm=ӤR 틨kt)KP0R>Ava3?6|IǤ,+5>$}mEm6386UdSSgPcQ֍\?%ʨhḙZum<ˋ Sgn7R` Ol@t/n6C{j7I@t#߀2^ڸZa{6(pUHM9`zx~8zX)Ԥ(ہ6:[4Y`hi‘oiLmdcaP^` ,q./&ݸ^ʥ˥}9S<0WtJt.W}olx)/:á \h?ޔ<ӒկھK$w0vO ƕeGе_Y@ /Z1'~RZqDR~'lL?RU羷ٟ.+7Ro./oWJoR?ZwRP_KK0:Xj^8M q8̟-elcKke3X " 97Čo ZDyjniS]2|y#-62m>:hk.긾hBl+jOD*䨲~hev?Ә<| =tO$&@T _؏ ";mV?O9ⵍ'juATͲ)mZ\ ]@gh{'rmϸ~[;(+\.//{."XV\ "|JW8>} E5H}@ia'].Ec ^*W"4iogW =!H7.Y1FVpvepFY^?,Ue;"0v:ӕU&6'ǀ,SxY#rr# MFsԝm)?9M6!q6j/O6]bNuҀøۋv?uf  ^Xʡ]PbRD8,qw`Yc $k5t]_SWu%|%qW?T{cWv+J_3ʃ З?]ʿKߧ}l.SO|t|o,$^q|?T~xtO?Sw Y_Y3(Jr 飏[~ ˥{?SgJǕ48f jի j+WdXfS^x C3f7(Y/.|r7xY>sJxkvl |o*&"*qSѯpj>ek6B ;%x8ʷ%< ٢H$Ay , voD̋^>GյH'{`As_]ӥ3J8fSxC[DY _p~ae+NB*@ؔב5 9[62$?RW^xK ޚl|CV/o/!6?y}vCesS+pl8Vd`2 }c[1|~%vT?,`T?W:upW}Z_ [|֜g^cf|y|<_^TyLSn/kP3e'v1 skcΆ[m/CFAGl}N)R~<ۉ6,iѲէl;Lyyh3VL5̃?+]̺Ai5 l% aa.dmj?KkXYeN+e /{(6:Ѿ|e:J ĸWR25AG5{9mSǘYn/gԳ|y^*8_v|X~u[F;aOJuYh۶oUPCj|p &{,G~־g9b@y3=ޞ+&#l@5h۝nBV F} tb 0A˰sXlf8;rf2ӵ `+b~o#S¬LqBt8Qg Xnqw` Xoҝ?_?J;5{_ ܃Jݥ)x{KYUC7~a)C) (Y_UK/'J-_{U&xtWKr%Pϯx1{pP^=~I}xto_8ݰ~0p0x)I8V["p)b z=To({]?K~]>qd`~,8s]ȕDA?b?tt*_}xU+yƣ?>)+!.'&wd)1<Q@{^2# paǗ}h2 @ 7С]TCPek.}) _}Jys+^1TsG6JJ#ud ?ڧA7m62txo 'm\*mLw|shaiξvFEʇ,q#>T`jU],MQeQG)ݜF=m S'ٯ`}kqt7:u cGb^OR۶|~M8S2.%E3ȋzkt,z!|+ Qμ^1m xCt&W,>Fl2#eP1 DcM$(˲)ҿx;TDg3BW=z$fuqmך$]SO9sN1y:.8"@Cr]/m! :~G Gr_m(h9}݆mbYG3hAzٱ鳷5ю:9/[B*܎dccYBا6h(A֠GP>z3p(Iўe6LPf=wIOp=`?[s pJ?c@I :>1phS9%n}o/tuv<9i4!HDW*^@Su|U95|݊+O$$tW-I_V{c|ן*R KaeRz_T˗qLiB' .xkdyyïC&+_h-$ٸJ۩,n amkPA1ohsm ) h~q~)8cқ辟m+Tڒ !XO,o7Jv Ƞۉ:rG'>$" ֚)Ǵ'lI$asʌ'i6Ea_[hnˑ&g>52,}WJ}/ne[;D܈mq\]}3hSM HW@Yw5\RV`?rG?F{۰@Kr^7)/Sy*d&@똻^ `F0}Q\7} ;isǀz,pێ}AYIS42 2LC(8'yF؟]M8胷m$/y4"TkȄ}K}K[l'A`Ơ,CO1B#1ԩqf񉆪(v0srZ͍[>~B;Q@S_ {`crQGi*2/o7,=%`CŞ2N3[ϻ9-M&#7 Ե|l(γ6 ܑrh>c$_1ILtYO > ;|!Ɓ+`•,7m5?b+p|0Vs͕-@B'G>M_Tp `_,Iq"ȆMs;a0NI/.ƣ+j. }/?#/5_,V x~u2#m@4qlw7}8VQ}c RLj}HW@q dO| >ǎmNU<þv}rK oC\j% Gω:~YSrs s"E`cO1`]q%Q_Xmʈ9 _KπKK:oiPmE0fIUȏG9P.y fM9gb#/ODr.FzM*:2%Y&1'㛷4r#?vdI]`SyJ^Z.Fyٖm*mȄG*^J#s>Irgszy$DDVURf<=@4} >gp9!a'V_k'lZqik';KJ W @㝷jxԾ|{lq kuIU5Rُ< eWNeȈ]bN2+`[{ن ǵ&Wе;zP̼dn(Z҂8 'ڀ]ى5GXd; ܞRn;q `s6)'v2귨T'ֲ0Q dk2?>&dѯʟ輒 rKshH8.HYq|=^miJ.'mjvhSPךsDp{yWpD jY}ΖLK?Ou=)Op,Xpa ;p,x+__s/ ⋥_[?|.\0y@J:ϱ@Z{:=iu0/xM`u `ֽVЍ)ǚ7 ׸^_sBzgY=V/V?'Jg'd{}e?K/ +WO5C86lGJ|}8ƄEO=Vb*[]8_79>vA?NA|[.h!:pϠ ]@9V.s_@7)xb\x߱K>w`W?R>|wxg)B|^ysrw%~f馴Æo.3BDT9Nz4Nn?jP\:TPA<ʲ"ًPh|g ,# aXڜQ3w\o6HYervkCM;qJʨ8¨1GDpy : v)3[m|{>5Ʊ=SC[ʼn:'<@@ɲ# ȎxcB;fs9  ,:yBuhdqvϲ_8>g|8vӈ2%[!cy}`66 0_S[#nQOQS~/J/':<ǝ,յ의>+T K+<)f=: +v5r+A,6PPAs¶x u>u?Aj/,+%bLZRx>QUmi\l'q?f?y@)rqm:{eĔ^mab|FAaKM'c b.Lkd8/^oSAUV67C;?:n&5 6>^m8)yڝfDe ]@]6WE|$mtcڏ쫷n4yz%rND F,wozRזS.AWJO_|oc7Jy?`s}Japɷs|W1y )o^'sQ/=Hqxs6Q緜 X8\ʐyo LWDA)+HonFð^Ƒd?3D ɹ?|?G4NS5bT|l738p(Z*-p|"VRPMfҀͧx"Q#^Խ'04T6s.7$3 A50s쓲nc pd+WdAy{΄Jg|mf dS1๠2*1Qȇ5)51S1656!Mv'\$7@[lf)[5m}$鹐P̀jy d\N֝ ysV_Q |ҡU!<4ڰ+, $l HL; KhTȏ:GP_[Qye0EAA/' $K>1gS˯Np=kdp@=p{ vkX*pdJ֖ XFV@j}ys7*6BY @Ymf`۰c/QJ9I&3u;~͒ s!|. jfD%`ݴ[_ineg !o&#|dр&ÿ̠~ܖ*tA`m#tOM YfLm,.D۔t2f" /Xfa]m.o{nSc>oIqbO9e|˶*6&v=p8|sېqp yU6>@6jܗ F,woj\E7Xj3?3O>YU\)#L.s[0g>[֟yZ!Npϖ*\bM^Ε{#~lps L>ҽݥm0R> W(0]s>+=1Ο/+qZE[ck5-=PO_ >GsE CK[KJڃf}T.NTދ~]tǓㅼ$[ma"Y^ڭ?Əg̩ր#TޔkB;$ڑ- 0S{qS۶1T$ zљD?d|ʘ k 1aTd٠jVvk35S^j\W̸s^)XR+m N?)+tp|[Cs'i\* _T >AF1##9S/'_Y  wS`n5jxX'U#w+v7[mYPv+fX\#d dwraJ m+/?Yg< v]oz~Ն=pP_,ė)vMpYfO1!&'"s'H&vo6geðF,^4vDƚNa9bNN >8%@1' H-'):. ܍X8, XJ{t? iS] B8zRKw霧zVx?^Ks o_Z%|q0?#c/`)` B ]^ |[WP|muqeW+\X>T<]RC>tI{5ϔס>+c+{KcO!_)߸QE\v}O zu%r0cćH=_B_/]ƘL+o*x+^<L SL4S~a6suIHmUDte]1R킂3SAm 8י !C]\ok;OC xиxކd qɆ:jf3:~LC9ۜӊ=8O fWim7E[V1jnW c;hHcQ8::L І#ڬ7i8K͌$Qg-.|ըeWq& HeMFiHc{z2Dn!m oy$!X:>;xDExX54Vo.su#КD]+ $p,3oW>yp~z!8(|?<+eg@BSp&hk+WME;Novi %1z䋌UڬcAt`i 7x]ԉU7~nk*b[#o'׆߬6a3㰩hdUpBfjC|ʞyP8mTفLpYf B;ecZp܆[]m7Uڹ./ܙ8`YD{o: r}v(R MXj ?A`݈%M E? ``_חf|R^~YdwѯnЪ}RKt4)(QQ`g.e-3WЪ? <^yUA"kX=p)/`ڴzVx;c>R~GJ_Pŋ;?wY,g{] ,^/&.nwRY?b) ::ĵ>?W)_R|)Q?HK|O) Phg`M玀>xΨkSpu a' ,8%wtl!?27ox9ij~=x>5,DzPgk)19v՚t-/zb6E+D+x6gU80k)@[qPU>v/R u]C1u^hs8C$#/o7ʄXm(2L]am۶7/>!r^7a) ae 5Zu.;@f 0 8 0$g.x S,^V6_Q?gԦ2*tC?$~v= 67ׇ݂m`S}#섚)YA^U/J@/&<##5Qz#6B$Fб'^f,V4K?S? keڇtjLpmK̨┝W57\ֳ/3`GR*<z>ne޴B^Ma #2RZ+p(ou1oڜ2+y7EHqy?}M0lK3a0%7FNcma9+`jc.^ӱdcҹI JƷ8v7n?>mC ny:Gf,8̓͠ mNf@ZATJ^ ÎKǂw#Kǂ7=pβrWoMLtS+psD|^.WKמ³;8rxtWJGKs n,=|7o矷\7 &8)BWBv\ieTӸ\)3ߨ΍cna|{80@W:x D<|5U}e!>71L ࠼͟a-)B=1OJf7B69댶5هjSG xOƔ>$ڬ|ׇ]<c\nYnFdTlcnTUB`EpbT?GC=[!hΐ:VC⏞]%,5Oܔ"}!g7Z X[íoVGVU~13xIQ]ˍ ^YCA5y!43 fxe>W=9?tٔJ(2O`\_9.ves}1O6>1|b9X-u@qܾ uDzSYs8ǹsz?\ B y;:nN:!pm:U3c Qc&ದ٠(|4 Ӵґu`p3# V8A<&ĄS}"igї-bBnTl-t6AלMB9xl;ēRss ÎN@ F,woz{Joefo"`,pVЫ@p^3t/TyJO](yקŋeQvś >Pq~J k]?JpuGȃM{K _V3|W7V)>ZK ҿm{E  G`/u&ׁLI:sL;^`n EI΂t Ǯ8(1kt}0ئú 47ѵ6RٷzK[q<اE}+pXV8X/ ʹ(U[50c>?z۠6I-Ciե(x~oU]CrYڬ2'?oƊ/!)JasHiein5ږGco I1&t ׵s?Gv_o@6 h,y&cӆ qv-v-vg#ZmMա-rml6g^?u0QƏ22C3@&1#&a{1.>Yt>&M OkJ0 1φ\u+.j0IJyಏA''=Wob`!X!} [F} )R0ac%M4Fh? Uq=?`[x |/R8i5# ey}8ضNjJm1 X. _qd?_Ѷ2m IPq{arG%NAc w_X;ls^39?S8Zy;u܌]A=s}& fƕmߧc;=%;=v ^oWS^7ʺ=e)M M+e^ 51y8P@WNo  +J`Q'I t;;yZΔZمy>E1-_8KP=;s YOOr- @ɤNSb_M?!m2y [s`Yղ\m mfXfvc_mAT}58x`݆%M~?JR{K|ȋ/'?>%|M o}ه~ZBA|= h/);<3+9+Ry؂:+J׎]ᏖrF))?ewozc?> ޣ k\sōe4ڄi燺D:c,Xf[3g270\0;ġ)5옧C u :"۱jؐm~)&p{YPC:|㱎D2) D1~/P@Bj!۩}vK  ݱg۴m`g然- 8*3QyjT?E^cKR6 aOW,ߌzmcI;nM6T9v;c>ghwt`2mV[@d RcBGV'T5,7Vvڇf!ѯӐFdN'<*hXSԴv9}bG4B^3&elo60洽;+M')QW >$3a)1L.-~pk2/ A() HU0Gx}9X.S_i| ѮR9 *jٚR"GOSVYA.>o4!EGøƁ|*#_Ƴ$=(l3e ^s ]#K\]:A9@]<uG^'TC$ 5CB:۶{59Alx1VT]=p'ƧrZLe=QQClTXuT{HZ\?Aqq1E\Os;~dv-e{<1m685$!t)Fh6]z-f5N`n ;/`欞vנ>F~v&m}/VOC^Ƹ4gymR'-vL S]c:~ձT̸lyY`Yč*qbp,Xpa ;p,xS>|-^s[ݤדܼi4yM ӛ7Jw5=_r|\jM\xs_ťq*߮4㯖ז{/(wOY\x;A/#}=T%ؤ?9/7P,Xpă?Ƿx_r(x$un6Ze^zFt)9UoȷzuA<1.dcج'MR7>c).ѝ9-@,)9:_2$urw1#onc2'-d~ϔlg$ú(;n8$<{h]`d>aL"jD8ngĜM~S}2 { 'LO lZGA77|t4T9NU&u^g23ʵ~>!1؝4"s:yȀԬʩ\_925 lo卫km"Botmh}ugUH>@bc ypTxǘz4J븝XNn3Ѐy @3V(2eFEUOⱵArhđPb?vE6_(T^0A$2|V Um~@!~/U* fE&5똧/Vo^2@X%sj='ȝ }Ju:p o Oz̎mME|pd&,߾~P.|о4֨23jy/-"Taǭa =!T> 'aZmtkeUV6e9GD?'iYj!p`uqb#F o7Ltk#Z=i:ݙ> I:57;`P;sm~L5ncjǺ^!,f}yɏ Hgʏ\Otj.Z^FրɤtjZp2Fdݚ__]8,˰pX8١sKxP_J=7rł5yt|}-Ð{}ӞW菂dK)J=Wʥ˥+Q`zPB:˕=\ D?quFn,X`v%8j q] Њ:E%ukԫ!*y%+ [khvaݷЕFammd)i'j='e_}) )!ؠ>9ݸh﵄Э3f&ꢝ@S}r5k>egdk ./R4vOb3_C= p'> a@[vFr>&0!?1a϶OGc84WJ-|11YTOb=IK ti1j ʏ3E}'`v!+ȜNk:p,Ωl SmNօďl+mH'yO|E1yR*,8}"KՁ? `5e47,8/0}C6,0ZfXo {j3RM1ԟA*tC\?n,gkD7x`5Vc=n:J^V1 $/SWA OXR._RNn8x|,+uD@6LaKvC߈ -σgg8^hg%Yi7mP|3)[2β+LmW>l Y"3e^=F>QO$KuʺLTnۚk/r[g$S1jgFm9 X.W?z⌏sۑuHjCO^ɱ-|ʔ5)U> ra60NIo i΢05qfjBL ܦǤ\njújlf!.|>3M~l@bcq 0}NL&ͦP%#ى`݈%-B/ϥc=A[RyX{+j'K++z.6tgWGG|x[,X`[2m$r8p笒7u1Ia Dy 8.|}*jZXm]9ٸ֖w-sMvQg-X>PfY{Sg`|??qvH!Bw"#}/ao6٥[\0r[}B[.=vE9/Tf7@>} |;$Yב, T'TIG3g,!Pz6Hר((9Oi)*Eɔ,ZyjAޕ8.C!:ZĖ&["0: h. ; N]XV`>RE܀uckruPm垲QNÔ>T Ϣx1_}>$a Z]hyZϴ@JrY =jBʓhg",`5 =V9(Q39z\Z1 ^G:>c"m{SgB2˄'lyx{JxڗϬ r/mkmǷiyG >D|OfmqoPQwʊڈVlAzmSpLr|-Ǽôԏ⪪׽8f{79ϏJF󺞜T0ס &Ve~yFMPL-ta'"=! f;g-P WFm1O!O^׀ln֍ 2*07`TͶ~+Q3뼏:eaaVe 0EX&UG9 ʲ~&& oV$f5g5 ܄|$7ǏaҸ+'|P 6aBva80V=KEOr׌_Oa*uo@3c2Zm 1{Hs00dSI;8発ړq!*27W伎L9u$uNP^*l8 ȇ~%^%6=IUY=ֵ*<CU : QviT+(쐪rj A%c<,0p8}|>u <π\1#`706`+j2>TN0f F~'os, 0Y:Vc9&c,YdĜ%{7t\ t:.m0%߂٭m;B$m$ad{K;Ŝd(`<{]_fAk} .<@rl@cy&?p;+Ouh,;@;hP#y>c wb6ovmvC:-`=×%; 穱ӾEjEն kv}j@:Y=~̝Do.*շ۶  &7j0YF2=u%c K݁%c[:} V x{~q)|m mA|] |_E qT7nH:׼Ϊ< d"~$xT[f׮iL#5Y:>v ~4B!(L!Oˑy;jCvGpZ15 DLZFElgmjΛ9y?*|lP*쁔l$' ?3$ 8f,JmNmv_R.;6ρ_AƏa;e3vp$te;Q@FGi@Ui{ dm1 C}}'@~9~F#|Ang0a35Ƕ{@[mKP *؀"O!?Ͳ>Yt@֏<(ȼ*Vd%KR eYu2!RI^ )N JYFqg'LA(?:a U!"'j<Ъ|s S_}H9\9| SB06c (WπouȐkShoZG:t W68HҪ!#ԇuuL<6f}7GN^KЕk8r+񋀔 ,X`w(p` ,88W;wtAzOY]TVKK+]{rreu}| (:F5-i j7_CZ5~FL}(}]#2-r^@=DVv9lowQUD+xFY@||:VF]@}M8BnTBی_Iɩ07f?j>Ӡz"iVpJjV*#n-v@[6։d(0OsNMH2 #mpw6z1@|Wu"6.DБ|倓xr-'LA`\ӝ\XËs8_:WV%^ sGsסTK{ Y4/(LDLjONǾFp~C!眐T&ӠCU}A8_Ĺ'#9\@<+;_Yuiwv F&|sN.ʢ(}!gg'QL<1<9q.KŁ5VfJY莾;s{: !m2\shK>4S}yK(;)EGh)L2+24 7y+:Ń D4ܨatPӁ6nPC[*g?f}5ivݳ`4iɕgqʶ>ԧWu l}\'kQ:Y'htL}FsYΪezvbԟ5~mv\~/v=vGY}u!:\2z  eXV;` ܹxKB}nwʊ7uf?(nb Ntj\a|5-Wut#k[^`޼2^ eK{UVgJG\O}O)/+pށjGBĨ-ɶacfB_EٛG@?|w6[ٌIW)_ï5[SuuږoBȧ1;4ε6#կ\<ț|Pe Dﳂ6}ɺ1b[6 94~1:y_}#߯ouuYn'ϼLk๏̧⸎2Jd}GQTQ3qaݴec1:>vnϾ~Qu8QNωFڮT%[ۍ?&&|و ZȏPI0-quL?ltzrJ^G?X ro٪Ӧ>"WIIrKt?ShDoxlBP)+ΰTƁq D=''VJh' @@|9"N=!axMYn8`;Elv,!{#bsB,uY/>*46J;Q"JG( me~)9JTr瑾 cCS?7u=f&/hLavZ^My~TpSN=N㋡Ђ$:6f#$6HɧjK6ܡ> !"t}?ofh<6B: 7:hߡ(d\֖ 9}xHfþr$<PV}t|WsK8FvYllL(q|95fČvmv!F:iL!Euj-ڦۙc.r ,X` ,XV{<=U9ŧA9@89sJwRY]\_+t  ҁ E_C!|ċZ*<€+Rfec)ᕲv=Ngw@ĵ#sPP[ 8iV.jm&i)da5 o#߉i[2*Lϴ'j[s63M` rj?6Nثu~>QmucTgYNQ`'>`d#N*en Oh؊Vѓ-hGՇ`Jo=0矸0y;MX[e򝈜7o&0+o ~҄A9bJSԵ M@:nC-Yj J!O=*`im eX衊Թ]p+ו}澃u%rscA*ec :@1ezOu9y1þ--zSSm:b2a<_|)y"M+tSJs}r @>Jm|\ t~X ltyw2V:Xyg3:?` Ӥqf7u϶> &&md?}pw&{8mqψq*cHFZQ̺ mǰƜKk'nn= duJ1l>>$lb'f,-ǡ8P^sh0fJ?ǂw8,+p,X`w.ޚ+p޺\:׷/V4^2/^/y_$Vp"O+w]q/I鿎e| C[B@W.Sd◮ޗgIdݯ0Ed5@Qio,ԺԷ@#l%χ2mx:g|/%fݐ^omR3[mR j-Kr\]r{l eGz&j3{>O|$㶳M·ꭍ=DK+HZv *Hu.:X$G7)>%D!< ]s1?6x-:RO5MmՌYU&+H!Xqq/Qb~ L:6j̸Fmgd띍M vݰY??\Xr~n! (FG,>UJ4V&_wHy av c =DE>hpU .8q ?^+6Ҿ8>ƹ@@NŸ1O9AnP8V +!Oh#h\/+>R# `P&zv6:N|2?)YF:n5x2+pU79<bl6)GħG8dsed0 0C_l%r|68Icc:Rй-X!:B= 2#:(實 lԻNE>>c@#on8O<]+Z]= hEdmebsC;>W?]3'H NVHrUx~A䉿!z{"ЗFi5:b4͛U lӱ^v}10+{sܒS s}&1uNܸ.^[_Yz é a=}6ҽ襃{ΕG/+_XCg7 \w7AGp se a*| 9"ԉI-)SD0 ^.OxJRu:e 1…qp>A:<:ƹ y\Cp8qUQѸV@[KRrJtΠO!2Yc-}fP+mư ӕ,_mπs!e/ʮ)?H\wKFcĜ4N\|*zVslDԁ|C0O,?y <&[N߆MODtxL-o ,X` ,Ewzy/YCQKLH_WRv# 7/KsW=P?H9CݥKwϽkX:dp_}F2o#x" {tΨ H H+0e9uB%Ԙ큺Ir|Ȁ_3H[+AnݠxZHfE _PGFm:{Nw[Nxc974c̦ٯĶt+v_ӱȗ3co;4׵}w: ޾lTN}'t)ވ 1E9p hGr :~!^%QGE‡<Mj'hS%k$| M ;3s0Pz?gYIuC._(~8y⪼Aysm#?K{ʕ]-UM6Σ#yà pBZe"kt|O2|}y#Ch< |^H`\P{00A<`.z`rU*2_bA$خG"hrdb=;n^G~C"I tFj%ߦ*ۂPAr:Wggcc0f\2F9?E<9eS:8DLS|njG{c>V>5&:Vx0ҝcv&C;-m爸 ,X` ,XL36L.5g Wh<+'rrp+eurprprxCĕ;+{KxnW)_UF9ӃWM =А7A^Aۋ-k.FH7IF6<6trmD[}Lݗ\r\bl?UG>s@+e[a (cJ\NTm:6v6Chw#9n <ޜj_6$ߑlMUBmgçWU_Y Nٗ 2'LU8=iƚޓ.·D8X&&w⸃s:9G楣uyqyKG'Wv.7q>pZܺ\ؗKog"%~E^Q D,Wa<I ]8p"\1 iq]E*2 8VgɄQD0gly{wx%beĻmomQh;ufwL3d4o١27}F[,O۽mGt|nFrs;lu[tٶB72L ,X` ,X-BgXq.]O2b3wD}$wz# [c{VK:)/.{qoY]\]R/].+&:(ĨG>h uRQz)K;COxͰM;n2}Y8/p*#ߒCf\1: Td2 ƠDs>"v۫lmȣM}k<ɞH58@65W,?(#~aJ,meAgBn;m:"ꂟ(ancKЩ@Fg[_gվSF[s-1$۾3?ċz`d;RݷBqW)d)n*-ux!a|:!vtK,pe$clQ:PHB8*ݼYg踼p|>./8&.e ]yAy/wwHu-RB]A]:H ;b`r |qu Rgd 7 V€w3亙L_;vDR1e+dj,͉n{K_"޶^ ݍc/yiP&M}MaoҤض6mAnm֕w ^Ym'GH/>0|;Ȯ~&ȓzi{r#S%S]ɉ}txu:i!.iۉՙmK2/%j+3q.hnߦ& E}Ե!|OLS 3͔Nʞ:|'.rw s xW<` ,pϽ5~My⽿wx.V5+/x@Bހ/f3>L:ה?\}U]{&dKWǮM8`rR\neRՓꠂ)1AB9WD9dhlh[ nS`tƼLܵü4ƆӪfJB""R /P|a?*3 s?e,3<~y~ *lwPȶYE^('o8Ƕ:xOK]klJm #Ssz1)}P&۸#\H":EEC\,_<摆`܆Em+qU8X} &1Ll"mۂ_kW&lVVR]gdߧ^b?/ =#ӯЀzs"? ^ϰlD_@V^@}}Փx#Vr ˌO2?r"+ +D^ @E>aª=GA#Ԥ G@0# wP"kY]d:\psÂreRJs^.^S/C+~*Na^ũMo#|1>Ck|e2}&A8 :]o#|ĕVnXqϯFn/Žwꐜ"tϡXֹ@!wTN8rtt7o@?9Fԭ +oSaFDaFGG80!5|̚pl[u_Q> CCA|b@c=l`:s~| ӨjTo:ǕesQbAFEu;lT7Y @1Qv1YWD} 8}tjEF#B:$7ɃmϾA_5w&ƈ/ H-ȸ79Sv‡&+{*7nvkP6g±}]ܪ :gv 7+|4L'9D:q3h[ ]heu}bGR5wmV!OyxOA_Ŵ/+޸<\Oi|"=(l 򃲪6Yb\j[)xo=hPG/2H 2, Q\l#v}ݣ36QbFSl9_r[Gȣ!3Mx,8uՓr_O7qq>,急L9?오S3v :d PGlb>L UC: DV9([#m'G;fq9>Z=T ^qSƵ,8Qrr>8am'>7p5 7xh+#9`d`:K8XdcRǫm[`_2H]B–GSG%cK݁%c ,s x*M8tZ78Rymݺ^z)#S[ȷꭽ&SI&xޔ~mɛ'ŦDG7i]۵cv[+g!0G̴qBC` jGܧi]},[F\VF kas;՞x nǬg}| ԧۂ3ṕrhln7P5!_eTkn~'yaZ'/v]4Q1c>/L ɳ:vqpzar Q>+@cl(r|Btv_ɵ\G1Q~9r g]܆ gY|QAm_/HCJ[u?8'8vU42=(IZ$?iN!]8Z A'8w;YZSGl=8V!k R y O=N$s}cK»acQ>Y}=&m ȆIc[e=p7</Ra4>ȉ ]nD3:iJ&6S\6F~J=|ԱXʆ-71-f'5Ab\_K'kw:cr㛁&:ѽ4ު :go6b_n:R 8T i۹n6w!@›/#POco'Hy p,Xp7b ;p,X`w.ފO~!8*`f_ o#p8:݄dz6Rf=ucV1eS?ywǽC)~CK8C'C&9 6eym]-u: =Yw"ey@+b UO}E@6uET!/Y8^b]1im:j&A~!L}]gGúv(i ߍjYB3Q3r+b9Fr_P6_Uv.3֏H۬䷀Ho~x[g`+ckd!Z]k@] VY|h+:TZc֎T?Yv`$>WB&mem9lMsc5!/0ׇ-e[5^m`{"("|EO!lT 3.>(#bc cϥ"Y@"MFXHl0Prrvї Óu84ɇCϑ|p99ÌϸNW(W? G_g]F'8)<78">TlQţ'U GH;m)n @5:NG\Lˍ}qT:M`0i`c7]l{@_L9Qs488x4BP!->s z{ x\kA1s=A3]6pz^\_c-w.c0&:ѽ4ު :go6Xr*|{͇,p[)@a)On#%cK݁%c ,s\C\}IAa^ӂwpgʬ@zyǵz?4ڞ%id>Q:&$<5ݨ<]*7o^`CSy2ʴi47G)Y;7rΝLP>x^( Xϲ'>=ٍXpƺ#Wv`< 6SV:Mvl_76C5d|qNƈ6veMp/ph F_Tshk'AFf^e7lvFbs;ث,O3D;mY gNػoz:<)(_WZ9y=\wq I04 |ڠZgZ̢\yT^E*|\?:.Ozt&{WC]9wltysf A:"vYy="/+mqu+~\PL,O#<9^-2聂nQphP5tFY?4FG`⸜p9' W@6 䡌zWS㹍z)Hu^~El_>FJCS|:uxNylE vW<<Ѥ* q: fuDŽ =)P`=%5RbX*}|ӹa6Bnrv3s;P۝Oslo+T,_dVl@IB,|`Ң~I^LSc9Ӡ&mþŮv!s2|4 HcDȞ3߇p4;ǜY2NkزTےrě/#k&17OY~HwL=un{?rړM_2̦ ښ~ xRS16B\F{;MeS>S$mmߘW Uv=lr5s Qq9f*bs;ՖEtG&Y eM?XmI'h m/i;Ю9m2s+">ű"bde[08_YlჩƇe3LB>dBN |\^ɹ?2"yg uk +!_\]&ixCf\K` q0'+paw CqC=d0p,6ˠ-2A7p+܄\EIyqqsAsB裂6V"LWDuLIN:_ 8r27`~0%| :zaC  U*ZƍHo"o,HW `P;}>=o 5 `\Cb`V` :"Qr- +ų65al2GˣP%tYz9ږ&I6ĜArbV7^=kDI`07eaȞAd=pT:Bx Q+@q@,F-auhNFkxX iͱ6!P5ۅϭ0sFtq~f;?ܖG`;Y2NilC*k/l[I: ɵE%^}Q7h|(F=C*@3# d򻵊XiI~DGvUm:_H~8Vr}M2]2ϕF=q`U.@z} `-J7<.s`15' 8ÿV_O( yܗ P P 8=CmE >mi{c|m|0ZtL ɪ܀1t->s踜]1G#zs/e0`)&xn%[Vke}*t9 #"ʨ UkX Y'b;<7170 ``*SI_nsy$qK9>EFՍ|}xwnggD0zamef dy)+~bL`l`]" Pʻ82#ջc ކG2Py+-f|}05vm, [ssVn>mC5ꚧB?}Ą"κt$ 2[Έ?_c_ь0FnCP0 nUߘF])ˏnK~]:p,Xpa ;p,X`w.ޒR7xA7-qX>HНxެ>(z`Nԋ7CjG80QĘmv&le]mf\5*يr51} ھ $/Ump{[bl{6?NU֡U̦yT0DwaNfnjFx Oɵ0dY'a_m7\?6jPm!*d*0*-RC_ !T <&t#A.[׏TR 9x+~㼀+j(Z{#+K~S3^4G f@TrSy b*Jp1[b]N*MpzHBH.CysEJOZCm*>W c`y듵29:Sb! )'" >HtvyRAdNJY r/80ZN< SmS^Y.g޳x"oj+ȇNu( i3S7dQ}Bnǔ>Zַ ٬b4Qߎk#+xrm;`$[6D@PmevGkY W21ifAհmv>y,rumexW~*tKeSم1k'"; Ͼ)KcIAejI2 Bd5x&dϳU?*o#@ p =rtYΉ"mf0F޴Nb=B4;1.L2W:}qwpou6җ:r/J X@|_"2W`@M5 :Ű㶂?i:fnC-xWaj!Kk`K7^=kVVZpc}*ugPK<OuG)V8uVwr^ESq>7ϏȽqU6TcΫUb,sLQ՞;؆o 8+؀6Lŷ = SPjܲc|ik*C_0Ә%LIa;R~ܖA Rx#t<pVl7]>&op j딤61g?0GX.ȏNԶK-mNq1B56[]CS^ Pi)2g~^jt[ƀG;] S6ev?{ QH'\yc}{"ڴaj)C#nҠ%cK݁%c ,s^A KLp])S+Kݫ!?0W^u,z]ǍƙJ*Ϙң>`7`W^g%~~X#/ Ѩ=>4CvŶ|prClzePǔkoҔi2b .isHHY32KRFc7oWے|6T)@tGTnVnsc ISݢmP[Q S|z#md@;IG#I~ _Uv^]e?^[5qd&3!Ȳ5]ڦ eŶ6 ; ^ ^<~0tyCwa-AnR]*]nYrm-ONAEcH}Nقsɍ0BWo*&Wr(R ⹞'pTcYR^)b.eQ`< jrע'(2i!~sC3`aF n`:"co;Yu9:Zc]z9&`tNաAr v )*{Wn2ʯQ*qsNp ԕx8޸^9On#[ `ε]-: iU@r9ؠcF)s2!:s>l{Y{'cxi8 H &D`#DA.H|ΣSOm[V<&/6BKY.Z4~ ~ .OY䳭g,dE4jǫ3wȀdu-2GW}p,Xp7b ;p,X`w.|MV``c[,umNr58v'T6FAVtt!o`|u|Fz&+B:NM}xB+gآfL!{TS|@Ls7 mY iIT%$!4bBB W˵㢗WDGJTz("\C'"@$&TBTURu{w|ߘc5B=G35Xs&]"9lOnl#Gmi]"zH\g`1/~j"yJݢs)l@4GA1DulqnJ,oh̴}֦ M!.<ϩɡ#Y2\>Yޑ$h%d8"q6+;R%N4As {_a»Lt*zt9W̤C}6,ob&I^[qPIK\_,W|] `N/N(|Rh Y0`-9_­טC|c >ccG s[)8XF8OZ-l\58:i6ceH0,q3 sYxF^2{Eh;r*7yLMy[>Xv(ViWgz tjVm:d]״#NAzm!lOrԫ6|dP,E{XЉfFkA-A.hu (ViSCZiDMtr)?,8NC(<z}KTicOGr 8 4~ǚ޲NNK1gG>% CBQ밀c 0C/ħoL߽xo뫩{2b1q}edfz;MUСBau]/O3tz%͔e`^VxZ|3o@ C]OU zm ͜]IĔz9Gd$7e 0 Nk*\YcZm]wZ%=m@lU(5h:nv-؞qgR5ֵiץΝ(UJ}Q\K_:P~ 8=| /mGEGM-O/!mBkɡ >~gG[&.зm]4݋P˔mჸ#]dIѐ/%T\5oӊ$]ٟ\ /ch<Ւ^Ҵ>K^3) r!,ײ)\rdi;dvegc#:CWcŸ\1JO ppG~*ȣ}ژ41h<I!1oy[N7`yL\ xv ,eIDATcl6#&iGp|e8^%hŽrĎk:_I!zfjϗf1 xeCE#~;đ<q~5\A~u8جͅ j ۢ ˎ{ЉST̃b2Ke0nm6J{>VĖ4/Wr[p{g>o2X>mh_jacrQU\X&Hbet e+t1Qdj^(Z-ѧp&VQvXq*6Q(<zKTicO';:p qr8\-; ޛ$4ZH:/uRXp.} O}z=RW9(Esg *nF 8n 8 0`]<p1ғ7-,%be~U;(#]_ԭulT!;|y]k|%Ye}ͪEs~lGo1)tyAueqKY&%Kf(Џ-ZQKh)7 *:O4|d}&MryeD:> Q[l|y:2vLaOЫWP=.M25+ ;`^yȱ!|EI~UϞ"~"ڛr b ?:Z,mFc\ƞ]:lkpmaOWv Tˀc[͎͎}5UyKwi2lչDO`"z '^y9!xnc'G- BFNGizl| sN*-}N;=:xUv!AF?kMme9I+R % Qk O:KiI4yh廻iC1ed/ +@֫t?BTey.t-#MN&x۶BPI}6O0Rnac5M=ђxE?5hqa'wERlg%P/e֖Zϵ=lފM'ѩe:Ǥ#mޱ LbSoe+/"QK^=aGY&k=P8]25m~77/椶Q^;6xV]C1M+ UY.ieֲ*HDLʗsYtԋEͺHN2I5]UM1"g6woGXr~n }:4Yal\! .(V*ʮ6]G)'QU0!çYL1ؾ q^!9&b "e:p 1& ){nG)(jeo41FB nl iR9 /\Wɹ3ƈg6Tqq9:Įv%YsG {C 9#]>2r--3[͏mum^IE c| d7m+6Z٦ Op/h+_WȁCsrmS)y;\, 0FSws ^YY]]M'p@:HxYH4 U/!ae]u6P)\rc{v4~o=UN1 tѨnā-|\ܧnFgTЧ יEJzlyis=@[7Kcm{l_:вv툛n}oli_dqBK>{p.fy8Uѯ '9Q|{|'ݴ]8òKG=|#:[)X u: ž)K}+Ç zYc 0C7>RWؙtΉkrW 33ً?^/tE#\hCx;>A|M0Tb<NAOxKe^#`:ۧHɐڐcM9KmOnc sk-1tmC;ɹr|qBB d :hlې8퓖xʵX?6 =REwԑ <Ŝ2)"8%*QS  #$~)lbmIa է%8_"^#oɢNMV# ٺ hi+Q :NTUŖuJzK܇ղB6P.yEyuY&)ѫڐ6i4c|kPΚAVؒ\j/6 10/|@ݞRo'].NK\BH9i qG T<Fx*Ly!W/h&Ȕy,7Xpu"[O_QnÇW3^%"zm z DLsD5 B [N7RpBR4񡧩l- WgY/8^J PU5͉,iu>c|.8\Aąkr7Eg 3m{v`+8Bi_ BH-ep\ߠ0S v cV=UsD1ayډ~tcy \;jq"=,'Ʒ\rlW|f{3Gwtd'/ن;cĵ|29fKfc8tU%u/y N>be$ueȽ? ̚qu^@ J, )F8 iy bٖVEdEhD#p|O|ΩY]/ay4i7}tSIh饢Ӽ'%В`~/R&1g\C+D9WAU%Ӡe\㞍iN3TE#trIj'BDz(b ç|5wȓbkCq/F"qN_̵~z) )7];C+q'Rven 9mmC:|oׯT!,ݱ_3jtSeC:ȣ^)?,0ưc ųr˾h28}HZzK_QtS_aus\du$L{.e q.^u"z5/#/ovy|vtQ4!lP[ Ӗ\yKd;e#e3:JZr/cd 5(eϱ,ۡ]N g=ȬY<%~»_!EO\Ya>F]bBҒH(Ӂμ6~dJ ׋vq@Em_턴SQ`x@X{qG8JN~.HmvR$B'nd=ǟ]>-X@3iѓ–ƫuDݯც]%62Ob-)qP^f0SN}uKKB6K;DiKӥ^ Ջ]ң?o;"Sq TVN͸OUΓ}nZ|z 5%E;/1S%^`yqU Yv9.pەw罇]gPO[:Uy<;sԉ(C\7h4|*lvKFkbl.Г5?+)|m<> 0G+-3 `9ҡOY=t?Z2Yף1ȣE 8TF˩1Q_'U+z͋q'#{tn]/zb^]{.{Cl6E{oW.ٵ. Om:_!ڱv{N8_s]jœ>~ (pp iKP0'cF4D}qSL ߢDK}[P)-(4JDӅw(Eډ@$K(@+&Ozb8] =]~JYM.'@/wn욋!{TODW#$!Q/˔p pScXqs`X1`|YiK 8'p]5O'7|x)]R%kN#ʲ[M 2fcS@I 4E}@1q?v~w\k(mU' 6t9 wh_>=̢yl67rZ+`G/u _]HDHuuo(kXR&*F37I"6h2 yH//3 ArUPa;ߩp}ώy+%@ԗ[.{M[#b?PK=vKD[q)^B>CgD&/l?J ma레j(qHc$ D'Q7 _(g݂rs.tIz8j!SX=Ն1.["%zniT](Sn_w7 yVqYa:m2-AjW~ijGaљl Dž\qt{Z|Yש-*jKN_yp8vm̓y8!?SF<;J{ӎjeAv[2/bCW?mk 9UELyy}(+AS9~U[|C9pLpߛ&Za5U*Z7\rh]<0=Թ<B;ԃ)4 ^FqK7Ʋ=ڶhfKD'r:P~>j7vjQnlCm٢,w ɔkf^҇>v_Ar. 6F)j?c{xaǀ77 0`. 8{[,kTx|noxcm;zTӍpl_ƯѐwM[Lq:;;42Y[C>?|AȩiOdWEsL{ T:hO 6㰝>,.$E:ъ&rJm]N]C vఱxO XPAȁ%h*o]3#^9WC.bgDS eb=C{ p]7C@ڕpD;1'o ZgQt>6c¢}dehH.CZ1oGt!> !HniOZKDsh/ę yU+zid9.P>!".Y?߸F'@ ߪ:dNR/bN$;u pPB2U lWJ-^$-.H)uǰuDDZQc:ZDwAy(;PC4p ygz*qpQqO؃ڱt9).؇)uFk=O=/|q'\ħu0-.46I_ h dx>§y9d<KKPx#Oi #ee0,4d8攇qz]wV=a˗msttH dIc|Y .#a٫$y:˲DH!Xvb$ 8ʅ$M򌯰9mQ*{J" FWK6i x@>@Jh%ex  Ct@^Ա,e0r~è|=E 컞SyG{zҀߌԀ 0` 0C5)t9Sy]3Rz%_KE+ )GFgwMx Fyy/όyYN(] 1Ru/ϣ߉,ӝ“f4嗛-6GS#F3LMb*b[nC:@ioZtWpn9!2Bf>)m]tjzNC/ieŋ!Y*die~LS"DӉ`뉦{(?%K/OEV8635eHc5f1Bz%tn_Y SḊ6g8HvV_<ɹ2|6F)j?|죆'p pax́ vzυ qHn<;%f tME:%*$ }Ve(QpuӅ@SAcFS$b)բLd3 -d&]n2ËǦk5*9"怘N,͵^e.iHh\$`*1ހ /ҡ;J/miOŜ) .UBѳB$Q,9}(dG-i/YF(xkmՠb@ Ȳx8doBN*NIķ_"$Im[ێchϾᗯ}xll.].D:jv1޸fG ue>czW_B4LxG$_tFZ!$1-_!brI@Vט62գE&)HO|ac64G(1I"%^Ao3nk.k؂<(UZuUO:8} _ص3 6ʆ6 &b '*AP ҂ΘvQ]}Yngx]>Jg8OL-(}iwLھv>}xڜyFn Or. Qgσ6aǀ77s\.U0`^xxxhz x6.xYیl)s/}^qg]7xYۃWwX~M'K =X`JL{7͵r5+JU6`Kmd?(>2=rҢroS P׈ @?ξd<b:|%#yO<^ںfBPDij[= u.jK⌗\gHbCT ?cle+>]7J@u^5'~h@kNяښQC%x;)JGM&D@擵җ3Hny=#hQ𰍧65s!#-[@лz+ XyKۺ3+9G>ѻ l{ d}2̺{%s(^G .׭TFWqN!W?htJ[0;'TQ$tSA러Wb7H1b :uIm`wшC^"dإW膯b}Q eZTgt'% #Ts;ĸa .zK1plM׋8ӱ߳90ht_"2aƈE]|0J'(Ofm>Z$}h'h$lmɱ-.\'qqfs{d5W;KsナCPi*6iKMa%v"B)AEd~e:. 8 0,90,Ї}>Ο?s<5ǣ>ESv[0Ƴr'[I Hq!n<_buS׸H:F>^lk~6׷R:w]Z~\ $D+es[QV !^a1hC3!e S j[\ 8Rs@s%1|bi>@1WZL,z&t#Ga3V9~3%qAΟTF*D1?^ 8^e2MCHelkٖ| %ZnWB#ʏ6?@ GjzѿҠ%}L*H &URA߆_F, %}hn5% r^T1Ђ]|Tze>iyyo'Tz-'FfW8Nk-N}g#_Ć:骕,Rre@XUt"eHq }QyhЊez :v)̸+@ Q޶w} h׎qt8]D-3ed{;)}=!1Yz3 j:G+;>^ |fq ug&vpm80[`MPoh‰۠&kDٳ.fڟ}~聙=>ՖWsqO]=6i|t Ņ1GZ 64=#-Vs $/Әʾe=&*x*J9a2G"%z+'Ƥ<9dTN읎/mub{Ƽ-rOAB0ѶOBלRP)/m/zC/s -3"geCұ\-[z۩G!'c+HhA_LȺ~DJ^C$|Jmrxz9mA[ΏŪ'kVm|D(ʴ) 8 0,90,PQ|A{ ^`N0` \< "ijs\W {.y UXHit˛2l/T)wX=aא%Gg4"JgHGH.9n]v'NI+ [@ݢ -]( HfMx ("~Փ4rW [" H:MrJmQI^1@O(#ylxhQsir÷LΜA|t &C 8&h!bxe#@xCfGtiK'NPq=U\\8-׉܎*@M@ S ٮ8qCiV N:jSIA NY(]U[ eG`]sH+ *jlm?bQ+z]mmP'Eag 9Feye`iX1`͇áaǀGGGv{ _|0 nwnn<p6Bi: rjײe}5~ =Dlma2]?Lemt}'-䔗:B!R[mhk!S[kbնEL1[ JLxɺ>SiP+>A&An0^altr֢O5/c)Zl\ƋV n%b  ʤ) *0Mӕ<6Z]S䲡E}kp?+/aD9NWaL %ijP غFzEbglxr-Aꊙ=ule˶xG':5~'ۧw~g?D~]m[=Y˹E6jq}K(?|r9^QJ ;M;{dK2Q]6S)4)E<ّpA4~RCGʖ-8^%{TkIBB2:oP`|ӑMq^x0_Il[gv 8z 8BTU1LL= 8 0,90,P'/^ş۩ `mo{۰cl\q'%|=߷>}c6Y+wx-Z1'M߷s$eu}J+ssL]*^r%mPuH%$%VhoBǵ.Yp9BDhs#I;V\c"fH5nY:E- > ye%YTV=~;@̣n'#'b P ptӖվNJ^g]\y"HZ(:B M ώB^IKEhlFABab'2*gJHN[lcn@Nٿ]P[cTRSpR5J}$rzl&h m i+~ӾcfUk1fűTd]NOOr{,;F~s\~.,n ʱ~Q 'S5CZo$?qP3ycYP$tZ)O` C+/7mƣMHv?F97ݷs?Em,'Hp<:ZXS?^.+˕s-dCttf{S0V.Ę*7h!c_,׶8c8X,<=!c5rcgF69s`8o[]=ۓ9>_7\_|jG 3_l%,qQNFsD#3khv r@#Ov˔yIj RO:>'T\ԫE:4B>ohW:q[5JeYs}!bp@.9q$]J줒>eڗ/[ 8Fwlt|H,ИA(0bB_{JesYMA0OE3aF;s-Q"tC"Ri_|pp ( .ؙ3gow>ظy{^0ųs_5&7LݝS?njry}eZLMk}Oz}ov~ 8N:d{ZLz]rAkII<+ٰS[YOQ5|l%hMǺʩkM%ׄ^u-5I*nܠKmK(C>Rnk8g9ad+dzdssq׸s9/w\P#%Y6#&d+˃cR'}Ɋ\$ c~D_%""lE@f^+[ZVHO(cdrr. vqԶ|㮘 u R27FO/ R6;Ll k1lNr~R.qW[dKy%fߑ|66[>= z &^rktˊز^VotSTl!"Q@o)@^Oe q1 |W)9N'hk7M@qfofLzŌ4 Oq vm>G 7x)rQ*V8>x6k8ƫܞݲ?Ѣ=Dp(c&9p{%ħv+re>k*K /m>>9.i_p5ll&v>K{6cbobBK;=pabl\c<Fs1/6|Bws(xcO0zBƖ3cz1oזR)Y%R/IU(N-H\Dbq -LҗOuԶ$somRV(`Tƶ𲛭DIvn8h6\׭ׁ܎34ّ 8%EQZhQ}&lmxbP"|>y!NJ^WY4H K> .t\!GܘcHh#ZcFf<y!lsw]iǠj:@Ri_|pp (aǀ<KEX+cMfm gkZ̃Nk26r͔MƋBVVٶOn'x]A:dy7҅t d^-˪H|-UƳ?jU.b3亻pdңQq^u"u\eBJZ}] 袹%̨xD2y eؑ%]ly# ?!F?0׏tQ& y|hٕ~pB\ RTnIe.p,튮zm%RlM]~+nGrl; 2π]݈ⶒ\hy(_ iM@Wv ]ۄ:kr^rg^ߞJN N3N5[Fyg)r1|o*-sXNYD_{koNg*z΃H<;<&8Dvb\c]}y&lmչc:| }t%"w4OQT긺xN΅a7>+4WH97ED;a'^U4Y 7l5:uwC ;(SG|pp (aǀ<FMl3{0/;s  ׳eH೚.ls-w7R/+|OyD@ )VZHM9؝XU!mR{:5^vB]Imytgݺ!u\xL]GL.vEƅ b&RK[2JE EsmI9Gs}X8( M?u A*rzD( Pt݊>8un >&XbB,* #w$@OE!Okݎ"eNj)4铇 ƏsZxCl[݂b~8<4Wa# .2{K=in$O$R7ō%jmƓзN]J/}/w ^gx8 a7`?Mcr~jVAvQ3BA&F]-~Uld>])lM%tPKB:NS~RۢC4 ̲wҋ|¶x[ t̤Z3XF $9m2e{̙u \'^pf-ܖi`c& [r_ 9-#/h zZ4شFI,o=bo=o >~6vm5)@ q^o>q \8SXu-csS-/@LܕH8GL]c췾~k;>'3o]7F-5(\C./km.!' q&#>'BOp%$E^ O5S.O Os,عCQ:q_s60!@t@~&}B9^R;DrfwK?]v lMSd`yo`rn#KD5Bm11=uRz'Rm@!yvμeS$E_;e 5J9ΔQ o!DyE\J}>>E4Vpv#itoDMO;MjAp[fb'ڷ}%Nhu9"?L4,0ðc@ <boyۓ9}Ǟͫ 8 gf}F=|~k:x<ˋL5{.K-]Vߗ/*G$eOxK]gZ^Gn__M<$O7_wwA '_ uK( @]FueC2qD$>oDx璤j$ht]\12Zù B0K[ȾusB?5 DhS(H.۬zEyN8GmiQ%~- :V:L[y76.7_N@3#br IS;`'k䶙eo|HqF:)KK7'4zEhn'<鳵!uh7l$׉dQNg,xEJse$' X/sr.[Zh8@l!½V* yӭqC;=v!ߛ|SQNZQW\^z^Ɍ<6@7 !m~em7'`De*I@WZn#lyLr )Bgo;)FF-ҫylxc_}[i* xQ~uL %b:1-y~mr[gص'Ok`s,!ѓ fpӛNq>3Ο9iZ\A)bb^±:Σ8 x"b}&DƛL!h&(QދOWI2rmgeR’O#k?;\ys鬣 a Id]H\ CZ腍>_2!>:Z"糯9^ܚ4[8|v NH/x)A$_KeIꈍvEW?!^r|Jz힣3lZ\cq< y$?e6avq} EteNlpp (s_~[`jSxǞN/ 0g ^z GC77ƦשPuy +1("q{9blc4>B 2T"W~H:CGגkC),ԯER*P^Em `ҎdF"Rw?q3(dirQDn#Hi /E\]r= m>,B~IFy!S-}pcK3GE2,l4k>Y70ǖH-cn(`DX <6=hh7Ac] 5Vg9Ƅv#&^ }"lP9oLcAٿwЇ#⪯7͙06a]a!A2@?!nu߷ĬennG%vBgKUrlԾeJ#,zhW"%ʠ칻Dv̗v#^}nŕ&H.TzZO>Mz >k8&, S7iuW8tzX%F{܀~:B|V+>|>C3 J;/s6} iDZ۷Z+/V{|y2u^<'I1 LceC+-z ~bPh1VXN,.%@MbR85O6-  M \.8zDRZR-Hb@>ԝGШDt4B =pv3gP7#P5W0V@D!߅F)eSʰNiaKX(zLN߱=iۇlZϊ-tۑJ\gY\hڨU^u}OGZ-wRC=&iFQϡ쌕ZƫmM )EKixǀ77J\p,=o#WG~GW+_^bmО1 aǀq}붙ۘOߘ)S|`^~-ћ)KuHؾ͔ʝv~uRJbI"NH]uoeK-9?~B.m)hLkyα"Ku.Nܪ豯>pݲQ-˔)V>^ZDݿ-EQJ*U $)%:_O*5 UKͻNdը_r)S+\O9 qGe|xn\t VicM7UY/c-~x#߅:R[y:Qy'ʘK(:sj'7^u{Ckk N?_7u6dt͆lz6ktkZZ%#Q "eTtTR\$7L2\ X +NCG6Nm43q -/i; <~||j)dGO'E)^_o 8S4tj'i:-z >[gI&Nj2b/tPBdQp u #<)~?|O w{Vm% gqʼw9?1}eoy` &"_v&]$y#/@U> JR"-9zC_%_vٳPq5*/t!od-ˀ^򢬥 .|J쟼 D/ <7KۡCId"C/ډZPL1y+G͂nyVkH{6tM8T3y." ͉r1` iؾ}cyt\N}lo6>b׆Ӑ )˽<&E8 tb,Jd4Iu8ɝ+(gthh}':ly;r */.SV@?9eNWڅlD]Ogu]pZ46J՞}ܸ׉/} 7zɄrm=dߦ6;sfY$3m4BCȑΠ4;@i{.⯳"!2 T _53,ԅGb&e sR妞^R Ƴcߕ1fMٍ?*-b2z~L~>}ZuڊAjoX42AK.zNs+{fb]uV[]e? 8-d$WA"O.RV ^%^< Vhs:_32{`?1Gc;Ykh/rlӽnٻjn}vGaϱ{t`w3[^Ǝ2_cVK{߅%#]8G/\.\ i4A{|3%=.ʝ!Mml<axtǜ+kR ;zbnǏWmU+K8āh ÔW53=+=iX>}c"h=#'v:ď-;L=9 \ rcYB1ZB?Wې'pI؆<.yaL)&ՇL܇0qO c_cB 6dX+~q#G^;b=}:ڑEO|ix|ʶ~ؖ4U6ys2m]q(Jߍ]쌕Zƫ4#[aiє)sixǀ7'p1e ]/cvu:)ysmG+㯂L WYKyQ^~y܁]t6O?f?=?`/(NvIvޗ?Wm)`y}?|ro>e948l{G_^gO=z;^kox/"n{گbO|}azě}}٭w~?9v؏Ox>(Koyڥ}Kewb >D1{* *',_۪D2^.tyګ$zkVK\tn!ż@W d>r .$ق=Mzi<"P9ږKt %/'>]KiD{xrʀ{|7׼n}He<^tNy5Bt{ELJn <}Mr- Ģl#U䥃`J#2ȳDfAu/7 )Ku(G^](R{\>rE +xXDr'.#55D;- .QTܱ3V{Ru[6hNj %-|:imOMJt8#Gf6;ݏs 3|(G`\n 4cQHy=UxK\Ƅ8ǀ: jبcU/P׉/P&GI{ \_RIeT"G(w$yW,8qrbO]~:hT0֥Z&H%vL/}]}ُ?[~jcU=^}z7Wʑo䭱ObByV!4hf3w3[mvnQ??sv};5`rKr._EŽo|mG+;|XcEk[0d ;ZYllFֶ>^ ~[_9 uȯV/bFm.UF=[:L76ݫ^# t|@1u5 <'4 O6-7YBx %h0s+>V[džnG^d5})cut 6H$vllЇ:9<W/~"˦~e=><,!w^1s=%1yԑH9Y>H'\< IR-[ =ت{PO;ϵ/Cbe/~my;KB36/r&oqlmv[=7ǯ|qO ܿ~~+]?7c{C'6Q(\yˑ}$3~>?`] s^rˮد~ۏ<}}}/F"CAORK2h]NIc҅k-;tMJTu}'jYS4EMy I1Bm[(,2b ceI7b%[K6 D \^9R,RnvSՕv$؋S- hNH'ik eד.ށHEA__ OOZ !5Ɔ0IKrm̱e%ҿG oT-cS0аsWgH KH(./VOmܖOeؼ '!GaE=#M3%-@M[pқ>@-Y!r$>C p91։f\S+Hvm mL?I*|xٕ#kGS=mjdJ2^2dTΝ G[IZ,SQ<$l M;1Ĺ@}5||v^>VkVeR"s6=DZ|a$(c)=.)ħl$d8bF㠧8|¹Nxa,$8~oEmz rNI@H5aS$D?m4Oxڮ ]|(n|FF+\hQcixrLJ^2X.awz 厥okZ&KNV|l:Qw"B 0`tbcW8O#vGW) /Nx]~|~]y;.}߯lbҗ]/;7z}OO?77-/ۭ}{ዶK lFv|}w{_<{x;l}ُ}]m6۵'}W~}ͫ._j}}W!&vG|-V{_K/yg#?u~'aᡟ~M?ڧ؟_e{&jO|gٹO|W]8oK?j_8;ck?e^ɿ'7c{GXMoL{-%9_ecg_2{ bQv;Z Q'*3w:y4] H'Ke tї)hiNgcBc+A./M#}EJx,|"iEJy;t Z2n ir q$/]$uEN||$Ak vU5`,.;HeL6ze!zMВlkdki<ύ/F72sBt)9o^p⏹m?Ki=چ7lE\́|z:"vCC.\yM۫Ʉ4_@0yGI!Lh'?UGy:>SK5+"(v|bPp])EY}v2SzMԩ=Dd(¦) e۳,*=%1 NOm3<=2]ԇNYvzO|oJEJ`YۀӃyx*u`=خH|Ø dcBY_H!XA -|Su%|W:1p,G.m=A/AfGڃ!gg6@ 4{{V;vvp9-8nw3Cgs}"vkǶk=yutxcvʮhg`_'k$ od?3Mmo8f7w5zc9>\q6tinWwO WVAWJgmbzMd| bE|DJc%-*s8?a[B /qaUxnGr 0L4r tZ&zaJ#qI5GB9I|5 1šO#Ya/imXq>PP[p=Hv)ڒ:+xG9'ydØ-stoFq4@ )\E,q纴K C>PVEÏ}i>mP[}?H0)WÔr-% ?rOLq9$2qDbZ^Ek  䀀#5JӉn4X\|IOT?mtO}(eN^QVlТm&xlBNOn'm)A@Ϯvз"v)Bo:k 0`> ٙ=|s㢽O_?y'i7(ya0wx}鲝yG+_*j5ˋza|9rC_e^xmL/^_oxWGS0W;H_t4S>S՟g|j+ﶯpv[{Qg7vG|Ƿkᱲ?~;sٟ>.oW_Kzڏ?Ҽ~i@;Fdm}|lgoIoW7ikvsJ;v>v/ϧvE(o/_g3oQ=X Ex[<hP_#//T~ʥlVLgy$ )_iDԕ{ }I 8J⢵2yArʂ L+G$ݰNS=ʮRIG\ ^xt:JRz Ro#1~T̼Ak@v _C\"2 %/넏:Qw hʊd1q,=Ź2/3m$ {"y~dl?^͂mqT7+&tsSrKTζ~ t. ~"985ӂ2.|)O}ؙn3J(N,x>ݻ[\<6mOUrzqqۢvs~[/0o70֡}ܮ&~Q2@dإl{{v쇐fwbg{+ݎ"bw6ڛ =k}]k]A&G{ K~\!5 G3f4w){|N-X#;Wm|q-<2kCzc;o>= 54P/ڬm#1w0N-G!G1t_cOsU&! b޵Jidd`W7 }yL+Q9y])Ry|`2!PULcfCJ GQ,5I)oN8?" ќ|(/N?FY}tr>Lq˅9 )&QOOe +bMvZ~+= Hc؊3傾3XZK(̳zv!r2 o>zsh{3_>{ 0` w=_}D!_ۚ.pc{}y'̏~sїa?}gQ?1˿/7dtdֿowWo/=E/{~]vEO]3y~핿O؟;?|[_鶹T^/^`P^7gdG\C_=6o{Ͽۯ>lZ \A8bKn{?2s^jz=cz}{w%zsG?_^wm/D{~X嫿oy/) c'[r+<%;^EW:xQ\^ zh$ZDQ7rSJ|#QtOq 9uD~U:>:&FnPyqN蹟Vy<آREHOִ"n00nH:%bΖt!ge(C52AdD?mZCrz)ۓ/ڟ:lƁ+[ANh:Q&GBQ'ˢ1'9 Jxx" yzmPO?ss;~?"*ʯ݉ 2X_a"nfV,Dvpabn&3fb"H;|/ct&o;c=?.;xswؙ<;sy>-LtdW C\E|c i>D _c~.-Po:3ͦ6F:N,#؋ 1_j{Axͅ#[_Z h|~-|ˈߎ_cH?r1Έq Jm5Ni]16\3A֘XOuL (q6@zY刾8HWu媞1$ZH  *xFZcvƤIk7}!y:x*IRQT"t<-S MQUW%ML?NӦow<}(;̫TO+PDly-5RQ+ʆiv7 4]ݯ 餹靲j۬䯵?F KK'sOy7`__fFW> 0{liGX3 ~{ov .\5HG\谱s3_}ec_oȥ>>k/^ao?յvqv/G%v񱅽/NWط;lGslv;|[}}}]x;wۏ?GngO/^i'~}[=6f6>K~ﴯ?d{oW>?Ͼ}|3xicO>n;q/|S.۷w}eٷOj}ﶟ{?칼@ g/oþow}Wx->aWos{6f^Zl5ͅH/b"lЊ<.z:_,*\D V(~1WiUIpzgb9Q^|Gee~՜Ie>q 98~A̡vzܡ?g{ۘ-~6[&Ĺb9\ 30Z%5_J7MY-o"?vf`U|…k6rKǶt%xi` 𳯸RE~n!r8 lie}U1ĜCN'~r.C*CzIv aJ,g^h\.%V;sRŭEfq~fs'Ww䜽4\1{/o<|V >]fEI0,FL4Br m:[:aQyJyBIs')4Ĕ<5'!_ NBKF16x 15IиpҾB$.e2M`XOrH[ j>@QJZh/<>gS}'R={oxNӨNcn> Nޙ m/ ip6E ׃dp})]Oܥ.Nuˈ]KӲ2O]T+C-[ <ң0Kډ*ֲ 4tҚvZ%yPϛmփ&e;};MYzYmAz{w0ُҀg3._ҹɅ ̙3vk+0oG|=?{^d9son?Wc۟a³2`̈́ߞ}bgzo>ͦH3ɞmttEOєP3C_i;LGq6_v8L w0Ћe}/Nϋu信ez}݀K65YJ/T9')}B6]]h([q :5'{}oIɅ0cqT۵Dj3+nycDڦ܇RC7M\Iu[sin Wه"x~'C<u+:F!:n~* Tz 9قdui^醎R4VI~cx^m0aLGlKFb%rآM闈([wz hR}sǹگm'R(9.bҢ-$`<Ρ0F#?O'M% +A; rW/ЇFO_ 6>M3hmQT6SHpϊڊm`E!:B֌ P2vv3VVH .hEbTH!sHB?#:M(u݌brz1%|?戚Ϝ PTgG9%%$ UM4'k\ cTl:RN Ֆsp&VҶvF<$ߴ)#gu!x9Zn;[6=6oi\DDE%>R[= !ĄԨ&4|S@`O ufts '1T4> 0`=}׵x_~R^c|%W;,0`<_O5.9i^ ]7yS圜1g.e'|_0?m"v#ctY}N]z'%y.t Z'{Ӥ<:x%b/GCi %Ė#UhYi f^DŽItݩBWbo߇@^ŇSox%ܯ&#m{6b:ܷə=cltn9gvY3jۈ7%x#hH|ҿA8y^oǭql2#R"%99J:] e>.z~Xqܖ""9^ Z ּIq ^`ak?E߻QuxlHXT$?}l6l|6v{ϳ3ϿΠ~Ny[Ͱ|!-;5ؿ tij 0@WF6]4GH?@;@CyV+;+\]+`G5̔l|rcŧzD3,c].׶@B orҌ$.hD<ڥSQ}"dLHy7BPBtdoG"TO/-HIfJzч,֒cyK${mFGR]~ sZSM3x§8WhG91u*Uwنe#-˔hnWCOc,8/>VxO8OU۟V3><_u"d2ovK2y6ʔcPuB (X'e2 t8Mr_">=nۻ@g|ũbFHlT>M[S-ݛҗ8Eշ}>ʱ,;S"W/!̓ξ(imֹM! NW2sHcw:|%doL+>ut'e.O Ie oit^Lgٯ|3u]BAZ +WC>.PA<)h]%lVT mu*R?^vĈ7L 0%BRM4'UR yRV@'/g\gr]m}"Nom,uS u3ۋX*v=N_ֶ4:hS(t_Ki;!iN42^`4MV4=wkilI8!d֦wPyT )I+%5> M)vCrYKmG?Lu`tF-ӦOmHs1_O*3Ofc4 FziQЯ )Gr4Geˍj=N;pBk̭bΒa7QuUPtw 8@'kvIheHv6]cR DeNs2o$3>NTq 0:J+[@ .ԜP(ZN$F %t>6HHO-i ]],Fg4ʘLC1s?OR_c \k_>2<S3Q4j'y֐Lt6@*h'.Ühȑ jTAΫ<􄡤D 1et 8I>b>[5'\26'M!&8$ZѧwGim:](pzly-('k LnDw|`k}zJ)6'RNw8dT F*LdzCI}Ќ1">ڮ~Q;kiwK(ΰ|kb* m ْHhU\e\\[qoa+lg\d4*u!jAk 8 0,90,P977^_/>eۇ/ ؅aǀz4-NyÃ-cGu} (5mm'/+(^N/O .<:$ClNY.;r;&Dj\Pd4,HzQTvGt*՛kY_]!@}6F$^ ]OjY獸֏HSD$5pL.TC|V*)A=,B#f!.H| ? ;$rIOOAEQod麏xf)n>]2X?} h#)p^QV|aƏd]ce_6yKdtźdP-vK?(~bX_O8ɗi|0F I6d3>ibj=)L<(v>A%ͳӹ@bP$\☪ \ۧG38z񆋸7ȂNIQ!95IsnR=W ,'?j(?iƺĚs8hiGsS w=×Ē^[E 5'-qp[⦅°TCO6< ٣ӣ R at$'>#;:~?3{fA7?`kq?9ʜKl7+> 49a5MCڠhl@C_sUR= [Ȣ(?r,F |*+E0?yK}PDeLuMy;:@xEGj>7CT'Z#'싵?G v̧ 3j 8AlvN쓦\=}1O#IHmTIBտÃO8p*I6q v੝~Ӄ0J(FLvRSHmo8 d# JG Қ~-؇V=;]rR :uр|&/Aeu{^%WE"0I Zqo!d ̣OsǓn2 8n 8SZ8׮aX1 \9_m6=0" 8 V2/rxy". TWٸ*E9UЖ7M@w2G N\Ej vNr*z!=Yߺ!L}LH](PN8|Rꅝ|}UqA )۠9]p¶캽@nRpZK[ŹJG71z&$t^gBUUm$TgMd_ e_SCI ee&%2X.,fmwPLu /n_9 ̈65Jbp̽(ǽK f~`5 O.|@]ga .9~0\gW80 Tau_{?ľ _S @I&&ik8]p-A J!76\E LjeK#l(>5I:%H~߀,H (^{$Cɧ/1N@D?w2-Aěܗs]MDDL^)Xa2a͖%Ul⫎0pk?]+xlALJKUgC#@17mJ'ڳ)v蒣`1ɨhM"i< yـqIͣ I `r}(v_ U ߶v dho 17=dozmyyn{c;:iʹ;x$˖0m[ 7Q9Lg vjL dUń/~Ir$Gф\> yj?s9H,(QQW~<Ѿ?#|#OV YU |hlxII)⢏r@Om/had@&6- 68GEcϔ(s P_QQzYR8,hl&Zˎ wm=O@zF`wI} ~Ǎq7'cw_D 9M\NT ׂX,H)_M>ʀl)tY۾za-}m]NBiu>qJH@io~(M)|嘗)p p3bXqs`X1U Q 8n|n{hc/`_C^,n+I;KPor㣕'fl!]ߟO{tb&/23T5dFrKѻτP =%PAU4ļ}Aw'ma+b#ψڶBZ}@z!עoiKXrDl~*NqOۅ:KڢeB3hA/bi]|_6/YP5մ^@[\ԁ\2Je^#":ʑȩ} :5|?V+ĄlQ3@':"\ɖˤ1|' n!q5%<;-`Cf3醋0B.dXݚ@\jKú!^[hC̱β:@3f}At&W qnpZA&| w&7u.!%9OYI;lKH2찮S#z93NF7\xcQ[e&Ry3ӶF6ga,a[Yv@WbkoB2~&)em !pS>/cxFp{lڝMv~lKGD!:cZw@K67tK/vEKw3ȑn4ԣLCG/yXbA)G2j>u{^%Wlh:9&];n0AO=80,0&ðc@ \xQŽ뮻:`6}wC9<\\o 8Fd"o({<;Mz:nO-Jf].zU[2WJՀ.ÅL ЊH>|ku~cO-=JmlGFζBWմKbLe/Ps5}n\B4WWVv/__nY5ٖN h'yq-.7Lq[bMK4H/۪R -.鋹ǑO֕>Z gƄrԍL+R5 㘞@BQ~ q3E -omyLP{: }$y oWaOSe6؅]<&ѲrSһdJ]ogFg^\FZI"T+YrOuGBۅ2~h_3s=/{#n{߿3{77lMw9/_Q+eMG 0kOZ1c[xAYH<֐6#s"0"RG:rqdOҚ.P&Ysj Xh62SF|D 2N F5~ZFyJ rORr^cTҐƴ/Max;mcuD3;d<8UnX*LB^Ct~Gm*ګrimV_[ @N)-ؘKDD9H~((?)C1 *^k b< 8؞.FI;7b;'Dt=oGp p3bXqs`X1Uc> _B0-s xvYCO@zƞх. 8U >vlgWVY—R. ghٗ룔!<^9{_A;5SQHdF(8u ZޥwTj@97jpJ[D2 Jn*z@oQ\ Vk ??eB9(+"e= w-BPYQی~U7g|"J*x^7K}Z_I>7?c iHeC}k< ␫7ȏzx{[@1&?V㍭b)sF7Ð77B}Xh1p0F-H_I7cc BnskRZi iFU!4GH\,!2x 쑆xí'g>* YOdO0G[r¦h|T&|ᾍc;@Fvٍ [#;^=yidȎ`y:ы9C}hs.č@)kӼdm./^5;m ;1_hI}T/sR ~ ǹP~II-hXYM4ߩ tD!>lcfK4c _Aaw-4S&y{jP5>/J巓1ϩ} 807%WH"L[ݫ_ά[{ZK6.fZݠHiM| v 88j[[6M:Ҏ뗤alͯ>H x ]βkNg m)5t˅3F:*W@Km)6/^.cIQJ2p>!HCr# .-- Ɔ- J<# 8`Bx?HDrB s9I4l{wE>cb\3QO8 !/9*Byήx*GDC/k^R1-%$2svZ w\Ƀ|=&}eNiV_ϢE:r7$KDdTxsaǀ77j ؀>x졇%[:|)p ]/`GH̵<|O7]X?-i5]:*&]FPHx]6fi[ߥL^!'{B)| pt$zpu@}R]&"-[AtV)e'v7v6PEE57Tᯊ9tKɯRM[9fOv( Qrm(}>"6.jPM5#}Cf(W&z5g)rˈyn;+l k:jwsTsM@I}]F~Hqk¶RPq~ ,rp3t A9ǂ)Hbnhv՛fm6҃2tMV-@R]/1+.\} [ 88Z}̋XƜ%d%ȠkgXle^VFw΃uhgNYYvmxЁ+Xp p3bXqs`X1.\`>}}|0Oػn>s xvaX߅u5}M_yI? q7R=Re:RS V 9;%]ӵk Ju#Cʜ % 8f(O RGU\" E⤾J~+m 6| 6|&SIuR"M/!u ϨwB-_"t#l٭c<@9oGDPî_obV|*ݞMcxCp^z5IlnN>^"1//hR\#]eMZ0'Sv" nA!Y y'+mfjk p0qdפJYmXpC6}ڕc_׼gTDR( ?F$>CkKAD.&Uinx"zMOמ MBM3hO>6FΝ?g?v喩9cel߼;G/_Eƴ'/^BZkʎ*uE6ľh)`p>]Y_?ԿH722~3~ qhh4xלcˤ'*DD;Bl/ʀƚ\";n_sk&ȈO6;xgyng*(mQ~?{VeKE[Px%rl[xW<& YMY#S9Wk;rmww؋\o]צ?.{/?>H˫جVyc?aZc[例sWԾԡ"A"ǒp ]H6)5b ] r,71f)TPr>}4 ` 0\G62# @:ovS|`<6\ġFq\(vx.4=DdO6GxI3N!|EDSɓxcixCz(\TPʝ<: BU ^)wbEgΓZ/>hA<%ze;}>- 199#lt Z ['N N ~%T@1mv"D\s+^O( Nj;Xm3ǣOWG%qɔ0s~a8s!aǀ77?=#vwFie pc/\bO>E/[oՆo 8>& 8"]/UHuDyC!W=l8#ʴ*:ᩘz"f]{6j>NY BmE5^\/!6xA> q1^dٮ)AYج}DNqtu4rWBB6W a%2}rϵNz}I ZnPcvQK{tsQ1u><6xMR6S~Lvv Ń.nf)t7`',Y!%(N"x,޼tO"DNE.azyHҨˤWrζ$>A:3tWxdF:hoXb;B A YDO\kT(cbaq ^ǩcy11f.@a~ZO<,j! :@>=c_߃ƛ3;۳u b!w~vL-{<إ]#]]5Y#YfwhBO C/5!=YK[%1CoYUD9ӫo}:^iirXI $Ǿ1\'B]}"5yWT8~? eu׍yj $$$ [4)YTp2!?#a)0bih@ " 15t٣檝U9w_wڙrʕCeծ\І5lB0s"&~rkۗq/.ܗ>N:rqR4uuרiPIm㐮ƩmO GAu9tB2<-nQC̎ɚe-h pؽϧ|96H(}jO1EKv 8*}CSy0`ֹɋkCP砎v}ʃuzl]*-С9lɒl۰Rx\ulx5yÜXqJں}":NrW> ߌ8Xt8pd@w_k qxjѕg +u,ȥZ}Wjq_puеko@;CwոN[epB UyXsUp%";x1|~?5ͩ浲ӊnhǢQmCgWW䁾Kus:{Y7'TٛmMlhp0y|`pp;??;p֭/ػ; 8"(|S}orҼL8hkr|F=8ăݕ'=.]}WF=:~*pzlnY$*#/xNzb^P߈(Ļ9Bݓi ĹN[:Q Y"N}3MUw+qx:cSjzk ^_2ydP;'@G+Dvnaqn}C9s;M2tl]=J}4F!uyȔt>E+vԟ+Z &]:gLK4@տ^)X)⼱ijc^+`#'P&mDVbKҧ(h8MBiuԎ"D[8~yzi64Y?V'k?O) sKStBΓ ˘ft@Lq%4"c5Ҕ"J; rmP$jm5b(WhM_^@vu _SԨʂZד|،5@W^D}vh>V.٣ҠdB27q In8pL,+w|gٺ/}+OW:4tFKɛ(8FZa籀t>*k휀'pHWoxkJ͑bAtAʵm>>Tr>'w >W U+mq̠EEg9'ӯIqïTq KGEXF>c"ZG#: zIP{(+ KnGX~c!)'Ĥ2{:)Bɯ'r†t]W)<)鞃pKZPf_8(vE^_4 )Ҍg_V΅!lP,vpU^Dz熅s:Y7՗/cTq';ǀǀDЀ[pm>8J ӔfفNS}垐Nx4_)*=ḡ 8jfyQQHs_=f)W;=X\dwt' /um5=r]=WY]AC q`>uz2OB>:iRݺΑ&س.'[s+[ٰnd}\ec+)Grg-}e@3&YSoFE'hJMuM~f9}'%0g~yeϽFVx*=Br=&S6~ `9K]' oZqCa8Dn>WWIv <T~d&mxgNeşn,VO}^,}K>lھK*O|y vZ Sʶ ťL 2zx1]PױĨyevk;@)!l:fmK\5WI9d%RP=6s| >ߐn\CLIWcgiMќUfLŗC;Ru/W7jئ_I 8pkaX?(kUnO c1eLUyҒQBك%X]!pPM^θj=r*>>fXJ)&cJkA刹 فCzqBW˚A]='y. c屴%ƩZ"*S}κk^8=$r7zb*k }6y]]-HpOk \Pf t8o/bAQxUu~J?"oeW/< 4uw:H'>8p 08p 0`_|8xT_V;N#9I7:pP\t؁xn(|'3,L]Zw~J.]\WW6yTvWo~a=`~F]xW&nok4`{'ƄĺOBM]( EW=@>Pw?}<ml-sȮC2O9nl}+>ݰ42=}@k_ grU6`5(~]J- .TVK|E:00L K4<1nꊱwQ6G:SS?WPJ͏Py>"^B׏(Յ,ZtDYtrHe+g`J)g'OrkgINM7ݦi:>gisrnϦd*Yj\+>qHг|<2_}PMxs;>-Ar+xFѥ퇗i6lt޹Xl9'seJ_S}$Λƨ擈KM{ǎIJORQ峾#SU5+"B+&e̮E:s*B䠦+?8pd*r&v?w>[ׁ)_, qM)ajb"g+*/M?2ᳮ@e. Tؐ5?K}}en닫Щ5j=7U [O87,\E@3JM 8 ǀ#ǀ (8 ~q* {T7dQ{ׁ ՊuDo]!׺" ]-W+"F7m ]_':c B?|ɻfPl}ѝuwNF}<ml-sȮ8dW5tow_Iu=|O{:ȲFubzSJ<׫ӹ\Lʄڮ*K 1;'A+#枢ruY!_ ƀW FRZn+o|2I2M7ڝI^Hy~t>>Jc-:̏ӘG`U9V8pu\]M"ݺx=}燏ҟ/o7N/+x:oUMFkI6Jp=1.\j*{!/ŗHz$_7;J,tn|Jo?9b?Z'i:Wa;op^2N3ݳ E<_<ʼ"5kf!7`r!}"ƞ/{@r`9 &MՈ+ڡy/*^%ج ̡zD[ϥJ {ŋbu.Zv $dmOM[:8+ێOG+*#mͻ_}uS)~H2W9p{鼝1*Ol/oMo?ܤ_Jb}&{m/ljךNĴa-OuJUyЁ(u|:ö>tA=Gf.zdsIJ<휓u:C~;yʆ4YF@lÓ~G=-UE(8 oVC̮9u@C}g)q߭+d2uFy.Z֚BŁHq(2Ղ'q(!yPXQ/ch6Fco+Q~l{46*f^]W҃-:I[?.>N/~~J^N{i9DsREҖGdʯY[JVJW4|,_O[^N?rtOE&-ў:m 2.7SzqJo=ܦϼ8}Gl;],pXtdZ]"}=to&Ƶ8:~GEWWx>nӚנ3@E1~CDž?ߣ(", ϑ5( ,8<:, B^Nu77c^6JWs?Ae[x]6VOG(^>|z-:euG[G_Z 5NVpUk09Ydk 8*dsfZ.ʣMt;p҅h68B2y}/F6ǵ$ wؙ|H[eۤw9Zl:<(vPc;պDGh{GPQЪ3\Py#B%B+2v; YcúM}Ɔ<.sF*D2!4ezN㤨;ZI"WJw?J=BAW=EO}F< b8U?uZi"̓+6=vOϾfBT/ՙ'ٕMvi[}#x ǻ ~5FS?!Vջ2q@? i\r]QWqh>n^PYpTX87_ǟ@1^xͼcc x3}ŭ8LN/_P^{p ~Ie4EMtês"BU.oN)Q߯+e R!eT"r/&KԯA~7;k}nM?'SH۵Y eo՛8UԨut6+/U}([p];* \Z@a mUz\鳳ZFq3&}@KNYtՅ ]u؄ b}c@<򽆕8F`9D'6nfwI 8UQrB oǐ:oҔ#zY5b)lKU^B] 7aDZDFT&[8Vt1UYOEh=_\Yo}jxMg<9~tXe3X=PDfpTЈEYmKZ  ]v?zP/_ac{ˬ+ʴ;gOhLWGPg^y#ptB@9QܸBu9BKU<RvҼys^w,&x3b،'.'{ɧӧ~FMF}bB v:hؔwg]כ+y~҃s6rX(~q5ɟ tϷ8 ѭ錘M(2'rstٻӭl}4ʜF2Z&E޾q9`+[oS'|(,)wl#3}w[[,!,OûD˗yhʠ3@t('ae"oW'C/(y}B!'v93`(σ 5pش@y`ݶiۈBݺmc/ 7,$-|Q(qpD혞/~*}W>XCYzž*N&L ڥ9R7A]R8$sw#WyɿF_ڮC舲]W[gcDɫ^nlBz!3ǀǀ сcN 4+,sϧw\,j]"Fy|'.w0h 7dP-=%7ؚ)T'x%UD2h"E,gG쯁֭H#U2}迱ʿ3[/y+쥍Qo.tF߁.թle47hcs6_]讟r=ʶ;yC0q{+T#ǭQht9h (D@_ٶL[yP!5JS Ѕ\]|}GU渵XEIzkt)i}Ěa=kbuzn|("hNB&QPV Ig!jB4xs@m)B nK_@8b8B]buL2'7œiz<}͝j^*3JzX_J˯^gb) 4, gƆ e.ҽ}^?[/ߒey :=O_|AZn&iRp>;G}3*N8q1yȟ^9āgn<7<>:"*qd6"0sYa[qzJYؼ{F]OkC-UF=ufBm󞞠6.UǮ~Vj ǹ{f4Zm#Nְ8ُZ*S h"Uҙ&ZOX6Zrun_|3{ϫKD_1h).~ן#(<]*~L3d]0A‚l ^&AB=-q"~7\+t]td$+[7F ޳|L^C,u p JJHD̆иLq {`4 ,! O P)O)Z$"f_OO zR@+a_ {PFKi_)+z5]LS8StܖUٷA] o5`5`ЎoZVPؿ[mʯW˴\\*H2ˋ4ql>Kz*qJ}a\g+"27~tǾծ ^d~z.^#k&mxXV) Fe[7J, S2Cw)ߞKS"V39m%X&߄/ ];2Te݀1ާ<̱ʆ^ȋz43KO:}]̑|Enq5}\7"D_CtB۵1XA_vhc~Trד61ͣUxy(O7g]7yRuG 5].Ӄl}7MՏybcwl; dBs}$f"l/ՈδB|U(f!Z t]ZmsV>}OeFn}Jk(2"Go{^eEr\+TϿC^H~=#b^ֺttZSDP\kY~*"rkK\"}z>c>n5굅_eW#l̯]o\ݔϺyMU}̳\ۅWAeX/e5;tvߵKˣw #Fd 1a7y׸bn$/U>.nÓ#|>k}B3;͟m|0` 0`>(8tKt:IXߟDlnD\Mc}ErZAqax2 %#Uʛ"nX^Ҭc"b4U.VH0?#4"S:VM.[ e=T߇R֦,Sgl۱/ uh |@W|x7[Sei Q-+aM4_a3~9]>vTBw;Ӊ&O6i:_=9}GKѱ!i6w-0`FHM u׌SPz.86jnux*ʤ" ]Pknw JtxߓxU6aʫ'QM*]A_"!lCӞ2=_ݡʿJJA>N~37L D*:G8d@*].m:чCD~n~m1>qOqt7>wuai*j#{5!Pt; \ϓtԵ;e\.;bA>A7joˆHuYC۵p'~/74|ߪ jV9U.i F*v\e|TZ}Lލq5][[m{+/ [ x 0` 0`:wI)L݂)g)')"}߶s&W(=DozzFS`!Nc2?Ce߶K nY(⍍(TQr5W V"\\7Nbbx:~xT:TRxoWɶ>O^>BU~;"^PdCu=]oc=wOیaH{:};)Urr_ 0²U}`O/!jqmWXnqXNJ͹6ht(},vo>zoYƏono}+'%wkT"mz|Ml҃Gh$]>NogQzxtO2&ɒ`9J_|22=yc^5nJSY&ozU|NuJYjY6qP]ud~j)ݛK9t^n귗ΎGn'֎tJǢ*U\(M$3%ət 4IdNu x쁚M04LjS툡@b9C|I3H!*ED$"~] x )њ9tIɯ2^7C>fu\JECԲCm{/ʓ k2+(QE_*|mڼj}Bg?q!_ٛu|h#١cOW'^O~*\0JSҁl6)C7Cw }EzH?|=O~_2X_!dK; $'ZN0OjكюBӮU(MFn%a:h#x[* teuu5}u^90FUʷ'kiك|d%EvΞZ۠]GU45@aǣwlPE%lG| 4MN#lr Hu(t}"lttػn^|+Uru[חBu74y6A?Uנ.@e]I&:W5Q}mAO%D8YH|0Pwlgfҿ) xN%6؀ 0`]_Mi~D4)QL)76"%ΗU7+0jk>v Wwnv}EES.;uaA6B.D!W덊 ؐG{|;}F T=Z-K!b,RVRL;Κ_npSs*G*"WYi *c!ɺ3*RbFَ=[ZZ[(:= ղHCr=bXTn3exG}S6Z6*멣ǟd @*?eqWQWҡn֕6#H@:}M\pUq˰ACБX8┷8GkSldtf"Xq|i>woF']%7JZ7Ix } ڀ3ݗZt:۳i:wOM]7|^_2WRӹ/omҏ2}N_/,txZV*N 2l?-/ӿy/}o~e8}ju'V{R.Vt)=u駂ҹa!Z=FzmR۞ge@x]82O$LB{y>!`}g9}xEzW^0=5SlLYP0:}xmH*6F)sU]Iyvq(-M[5G ]U4YD(F^^OƑlcg|J{?8^5|s<8)eA>kmVZW^'odt`~&~ܧ$LSkZkqFcOPLn-4B, bg|&x9Ci˕<fZg]f@3^~Dm%Zrkp| =E:66/PE8FG*eQI'6Eh+pH Q?&9/c=+ATr9{A'<=]}}֯]1LaSE=AS1/iZ2uNWa'dTᗌt̑j^WW58 1wLJ/{>f 0` ?F_7wj~x3\Dqߚiݙ GivXqx&wO$ddʥH5aNihODlf4@B(|_DkQZ<>| %o&D;hTLy@!?"aӐ@)%x.Hސ㻧j&kTcrZA7uYlC׬Y&Ub_Rleʿ(8TW~еYAUs 5H6:]hN٪LF}h%M }Qt͇|mb;:] M*l Ʊ;5%=I@aلPD>("}mG铯oӯ_Gyz}3KoyqZd2ɜ}Ɓe 'j.|Mꂱ uM&W:yL!˺J뭋zEs4J~yϠzWb΋< kYbhBמ4:C}Mu[9͟xJPS\1^cݟ&?8=!]k`HQ„YA§ܰє-2-&AӁMe ,I}o +-@ *p[dD[8oAR%/'wQؼWvz^!aSM ʁC2:TeӛnSkGV?mjCWw~^j-JPhɃC}nuhD "{/1` 'p 0`_|'pьgӈ@~~fHTy,o%nx..Gbdxj2owl}7llRVߗɃ+4#ËvQQ5D% YT:8l9ӎ#qF~ P2'ܒj{EƛzvFˋ8|ڙrAfdrfnR)ZBf?Y [s" oe!]&jYTɃ>{]}mЪK"&]*͙Qε}}} ~o!K%NǪY`龬G_/Y3H7:vˇ 6mDn r@VpZGPGy'Wt)ua qvʛ>)MgjjV<)b-sT^3$ |t?Pke8^jk2oXu}Vd_<-y"WxtT%XHJi%/PyY2ڕ\&G]ֱY{ b| ȻL{N)تz=!VjqRr"C2l{$Jh''E&w"tV]IDATnjX] lv+xAW C7ݢ LLfwxh3h͓!*TKf)W6W7u}84]^\_#>=!>"lR'oFXdCrm{+AB?$eD/fa=W.P!ʆu=kꠑ))o@4(>Z΂># ]uXԓlr.ߏܬF慎:/Zԡ49ǣc(z3z+gBF9Jk2Ź"KE4kO5˚v+_>K;N<ݙi~{ZaKXhdPfq::Q:(:Wo=/O3olү~a~ _X_y}~mm87Gqb:I_JޚJiz<;N't_XWuZhm]&DZLi(p2Qjf ˀ[+}TkȚX"I'5Ly׵h&uGONAtKwqPwD/+Z^Ok:?}4} 'k_Z祏=M:AЩD礙ESc'1 O9Mg#8r WDqbMw; UO(g$Kyr~ݎtqL'Aw TS8 6>=Th_'Ż}x+;@oNC,L  oOe'up=dawy^NwhH mweIVEƞ`OA<P'O8>z EMXWer*K$ ݂ljW ^aa5α78ZCD>'pXfA)*ot2Rݗu3pЂ]Y/FfD\٫/qFa z)חV2*28*[-k*6vt-V۴'_Vڲyt]jv=njC'u]u})}yU_4y=zobgO%^̍l|7CaSŎ+\$V?c>3?8hvtp vb%M[T#Vx zM֛n5#TN_{} HL?߉|'&-=|fnw`*.{эlLo]6sw2$K~ t.yM"`g 'YDHG A7}@S5ve%<@o$Jr/ik)y eI]qf-ʺHWPqfvQqÃ23IV!LtEA)O>.+iq -b"m7Ce[ZDΎI=Mn鋷;~K GXkT*xʱi3պW68+ug/>H_|HE߸Lk|..."]>ZʯF*踚X&i~4MGttDz콣%RET[uI(]Ԟ#)UN XՑx2 xW^US+LXq%]j}[k{s:wחWߑ}9쑿):zZz\_V&}\74GFA/*|SfD'=QyZL+qZ+7ȋS:Hf룓BS29ݲYiQ vl)53˅%czPW7 ץ{VX Cz.BXqBP-SS#S$g堁Ӵ], ] NO8OK?v25W˾}/}'8 }C=6\Աe 0` wweόlo,);p*ވS|͎f:6-+ ^c|4xH:>I>c#dݳhݚ^0MҽQ{ t[dq9=MGi*T~{N=q/)E:m'fhklwosa P¥"CnS$e$̝ck ' xAbFH7F/]&WăY"5H]C~(ox?5E /{nG?e"__NElvxM <-RxW-'3,&$nѽ4z$Mʓ4sfgl5c淦qnhxPOR G=niJnmF*m..WvX^J5vP%?B tn5u6qZifiztKVhj:#5&ؠ>,ҿPW6 bJZ?ֶfyL Gш~yZ'i"7Ml~ WVc/(: u:A# mch6)2\IZL^eR/]C(/hShdoՏ y#T&\V|לkAu陠bzF7z/7YUλh9Ϗru_f( 41΃/X; @>/w\dߠ[ ~ 5myݎp50=ر|>vfTQ^+MǼ<-l}7|F7 0` 0+e"7j5qIƐ#_:\~Uk:)W(rlpٰx8NDG)qs2IN'[;4p:n)2gqz6IGDSdƄ*;OeCzYMڰ!;Z-oAT}7@5:y ]ߖXJyԳIMau\7!({x_C#ɻDgy7:4s&wsƋi-+x uOH-T THU@OMdXf-{^o:g<ݦG5ͱ:Љdz'u:׎i8Oqx.vv^oJe-D^(SIDU&,1h(ͦ4!4ac[68XNٙ0ttQ˕5וRt3=ڝ| e^Ct=b zCoNr5= 0` 0`_i6T6EFqoFif*#TߤM8yQΛ 䞊t\\L::].VirlaQ0&?]t^qsG~jǭQװL)4IIn~4NHvt.45_" x~-ExQvzvrWL4SɌqPG^7K#'|7HP}r$ ˲\͔vc8VL&Z;WWx_eGo*EU[jEz{N$s_w6P@sj/.TYkq0Ō5:M4Ռj=yIEj}¯։5'_Y8 lX:tvX)'C: ?C:qIԏM8İǣ1U++ Sd)|Xb 0`J상~w_MivT_UgǓ43"?-5{t}c}%˯'sͥ`28?,Cه42 x^G"ͣ3?G hUo*Ho'yX+.q Hœ !ܾlY8T;J13s9IiJ_`7wLS[,GnݕJH]:j%Kl EY¦nhCJ60`{-I->~AOvq#f3L+1v$>0UGsUndd>)jpD5<ڃ1g 1Qmx7WPd kty^W.bp\6xu9@ s~ΠWqo$OJL'Zf(:^BUQ6T o=W@xDjATDңF+;}c鏊ߨG(tlg 9iZ9dΦtW?e~Jwu긭cE-9NǛwC :ШMȘNJ?/OH~]h/5j$ה[<[pM'{sӧwZ1e +ڿV9C8JY {Kşi.s9q.r<Uc%ǪppYF/F, DmDjDsaB8NeZܴT݋LZK$ftHS cd9et5';r5b.d2hRHm()owY|6%t|/>' ؋h;B}; : -sU|DHwfFuU^ uU~ +]cT_! rst6NB\q}Y]t?O|(}E[.=slcp¹Nz}U%B]<3cvErr](z 1)"m;+0T6Rl &,:u:Oyʷ>Ԅ=^պ\u5+zS-y-t9C]gF}m1hT8jtbo"#\i'ʃpA~x=`ttk/.ȏj}Q>IЮ:0tk=t= ZP9V&eR|x{wp/~tt]X̓nuӒx}u{·?Զcot_Q0#g l"cĸԱ]RbMi%^PdMU=R[0Yȹ=2GQ#ĥ\CN3w)ܼ(# & ںP<Aљ? &9bβH"Ԙ`*ΙN4?A @j2F:| zm!8ZOyi1tly~M2#;1`+Qɖ|\YJϰP;aVbrxL۲"W]tVH'pX#ͽ7qC;MzQ>r:JVّcc 6mE?(/oN4^ l%r& 7XI߸S\ӏүooہ2V#陈T3'!14- W&CDM_,W+k)wx]27%"6/RyvIEdCBΎ4'Mu,ӈ?Tr4!=le;੟(_/z[s$zgDv82_?Ad_yR}$:zk"WUyd/FKn{N>:zc3|gXs#E)mhΏ5Wq^oyAmktyEsJ>!VJ5#=udX݁N_ײ d&k]'p""2{dE-M?6pส^`zW߮Jij aaM^S_av:pgت6MΑc08p<8 0`/>r Ttȁ{  In=\w٪+GX ^_vFTߗyg9i6~/b]*棆'ZS ~_Hs4. *cQNUؔ^~rLf3V߇f7@?HfKl%2xq f^k"ʿ&8i .:Ș`5Ҋs# Cۂkv ҥːj{[F5eo`[L8𪃕8k;pMna eF 4'GyXk*H)ⰍY5u2=~-FSu|;/E dN1Q $9 5RB3_cf͛5֚e~Jm&Ze\T^1AI]{W/ȷTVűM䶙F=v>~Tv};<3)Uy8 7U8kws+AiOʁC!O R1SKTG;( 9׌h7 (Ç!_F-W~jb>m}e^;4P:N|YtN`E C_9Ǭ6A7,`*gZ"4h wu=)v.(7+RysrF5[*xuV SGltڑu$Mt\\//r[>21?K\SiBY訒r晎 ?zp㕆IYʠ]$ipt'yuX4(zbinF?'rh{S$ ."賯H.eN Ez1fen枫(pH} >|VJ6bcQZK)E~Lx+-Q$dbxm@ELG=^q-Mt肊(a-H88N48pcHc8QKZʞ&(8~mۦok)O_H ȌVZIV(15G+Yya܆kJevp~uב6|UEM 34: %Ͼ^)hӲKeݓ0r?hWFHs ~9^rG<04z~2 }&?)̃Qޓnbt6U# XѾ܆vv`'M?O ~j"wqdIYT3+^n>1n@?7Ɯ?7WZ"U"*|sڎ!F~ugت6MΑc08p<8 0`/>a'7_a |{{ƻL"&8qg@V;Ry=ސ֓MڌɡR,]c<+@3I3 Oo+[q?)= JtPȖN+>QM{_VTQ3_x6B~EKH;赱 ʦFh+|8sX/ 5wK|ͣ&_J;lh3~:E өGFBAڑk9&2c6ѯ(,T4%QgTg>l4<Q?J֫4OjA3~UR5*"2F]DP5񨬠C=ʩ#]l) Ks~ts=1Jo)1n|g̺@^$kp$Qr?HI}͊Ry% 0ٮu.ױ^ «#f<;*?d \ĐmjNPdkPꪇBؾxu\~Y:Ҹ Ht{(O7kq:99MC?3NQ:^^V(fۛ@ ıN+s^f6}T m ^G OA1"] S;d~8tvqC]ا,E7ڇ~pY֮Eڰb{IS6؎Ba vi@Fȷ=ic8!94m}Y=(vqZIՊwwpR.QЪӾNSO=Byl7);^nbcum?j'B˞:^ށ jGI7O~jougzmU{&H>G: Gc c x_pȏn8L.}BoHb篭|%xR*bg$Weޜ'.WTc&ׯ xJJx?~5$Sȡܫ0I(,ٽ7ףSY2 E͍Yob'X!e5J7~sRB]V0wn^n|$k ]y8pKZe8WMRDeпԦ>>].FmM+_:̱Xr&jq<ꚍMhFGDsd~ڿ7mt:8VRZ%k6\4`>@Mx*P7C7Q88Ŧ*FP=̝RϤd)5P}vNAK!*xp>-ElL*{%$<FAs83bⴗy:V䐥<7JyB7E>vJlg15&/: xD[jk,QDe hCܢ~K n#!zLOF8^g~uB]:L#N}S[2%ϤڠnPqDDZ8F鶎c 8t\W=-Vف#'p ;pXWސ_co3onCM;pPA)ƼcV9pPdKB8pJ OL8%_./5jׂFe8>L?Px:W*Ԡ1.&d83RngOsY"NuJ2Vd}7 ͱ@`lH:z҅˕a/f}gLT MT;.R P)/١#϶\xR <ɹyl)]Y0Ӑ2+U.[!=e0$5+@̍C9,obRѷ-~gOc!8ѿqu7Q5N?[^ItHJNO_M~J&=i: 6U|MO; u<^!#ؙ@NY)Yln+D^-k~PAS>XkNg9̉~.yLFƩ2/ő8TPloCz.z].;@BGei( 7VvEnɲBQgSwĩ9'UAtBXgv`|.@K ;m (d-;Mavun^>!e"lědx :PB bp7#USs4;rFu]MZ$lz/жW64f1`C8 Q_ovs`:?t'p- q#ρڪr Qֵu]J_<ؘ_ aUI J/зBmRIvhZ7]_ϛ hDMEF!g L[gGG޼.oռ:c¯⏭}l!SnjP&i9?BfhDM}\ueZy7: #*N8P0ɧ kRRzWkG?:6-Tǥ5Koxm\lRL&ƞ ld}8lxHHuP  BgAXrȵNۖ{d(SfX:%XuvdK 'pgQ'<[<ΔPq&Ua _غbӡ)aAn/  C1t|]gSk⌁ YO*rDPY2(0ݦ}'ո{6WyݲN 1b%qICsDcw*:тuW!ܪāӇv`2+:gV{g~uz??C&j248BkezyFϫ{k9U{SǃNz1;Y<5CW~v-UXIPVOURruuKwXT[,SzU>Q)==)h^ݚG΀GX#baWK jӢhuQ}XgC'niX|^݁O-!8^\}aI;7ޛimRy@MFJ`ZqTe͆']W_L'dNo/3{BDž%;INkNb 8z,+_3c ޫ"yV eԿeN.|`qꬊ5099K(*U69p>dFZNtēx9EdV[4oG7ײP LAڭW }4jK^7 yʓ\Jގ3bn)SDTa'`cD\pfI7E'leUnô:@|\56vyFp=לz24)ٖq\#aU[igpC}Qo6iƢeף1-ō-5dʠp @r9j9pHͯo>HQ:7?~_dt"ot9Qb M+TSmئx &J${f(;)sv@jP:vW|ɻžAŧs6וOu9t\{+Y:mGBnsO99 І\Tʔhq͠IdEg]q-r}htTR&B? k| vp].QnczuA!BvO&M [J+ -uā#Y굎ʮ'@{,/vI6H ] !Ӓm W- W-;};p9}6vu_׎+m]{6Uty>}Q8p8 x08p<8 x " BxP8p }2ViEU^$R3 dYy/7KdVUTDntrRMuGA27*dSzcVQ@eR٣|g8Sy·>&3)X:LD'`aeh8dZ^eN^*)؅TѶ 'p\z~Go-d>KotgtQcIetrɜ@V,*k~ 8 gII,&rrg~Ŧ?jM]6d,RAxGڮ@Ȏ~/%0z*mϞ} ܃x]lEu6QPk1Ȁ(]۔yB{lBܴ!O@[96.ubi)muTgOaӖh[nƤW#y\cgad\oѠk_u}pyѫ8;p38p apx>08p C\F<4t8lv8 3d2q8E|_:| _(P_2FQv\Yo]$uIkkVo8ѷV:,Ɋ*n-;oU2`{Em0 D C&gX_: yMʰ>(k.+6c +2z1c:8MS\~݁caBoѷ#\xI )Pl koet28y!g*x6UljqVDV"s>MҚ]\ۮ1Z7(%c WE`oFɿu2MGt4ilNuhџwEXܾ-(:6-\ 8˔K6=mXnӃ˭X`ٷq0Bb3P lLTʘFW(A(JZ+f:dX'3"Ezо&MǓƂELiK`[)gy(7"E##DtX7O8S3*|I^ռƗ#v.UK23;p;tne4Á'4K^KM_͞q1pPEj? OѠ^t\p=x|'oL*͏gg=Q+VX#|T=Ӈw@UznV5ty[-ZIu2WQv~ Ц2m~hYW?-˸ax죾lSߵ%8Fǜ6j@2u[}D~ī1J_ڵTBep!zi "jGz.͞ьRSG>/$g-mfY ښ`e ]WG^{>O[дݗxȓXvpLFq|e'S-M?8ǀ_p}jAX-Vi/lA=8\ C<ʭVX," C~:Z:z(o_|087vģ}oŁC j=J;.Ey=zkg+*XFzLeحAQ)\Bzʟy#M1loFZl ۃ:tJ'B4x< XY<ٯPQOz,j_ϕqG(oĒ<n+,AވNJ+N +⸈ِS#l"fC{1#\#_o} 7$t깄.Vk;{bvV#VLi9JtkH}4pi^%^.[ç|Gbԇ:ǟ3:Qը \}r?Ӷ}ݗ;Wr=Z.Sz2=بm8RasW ʮ#Uj됀J|_/xx*lrvSb̄[B1ja ~KO]P^`-hC=T_ #Nfp E<ƭ+oO$_,u ykZC0pTFF\ ~IWn9!D)_kj ˂1j0WdX8plV *;<mw-y{, ;[vhl_u~_d㶍T#^K  t:13 pNNNpxHǏGّ8hSG8rDueAw=<`g(f |FM|{6 I/|3AF%[b#5+GDŗ><R^VatM/X 3}=a=:-APh8pDKB\tgfw^M@74:HQ+<Î*Yu z\ƺy+v ؜pRq6O QeRm ؤ?̿lE:i!~}iMZ@ċD{J'EzE W勞/fݴJtRUڟqdT;>664w.Szqv8m 2>/ޣKo/W }|k,m&':NY`)#*F?S@VVC9;c/ss+ J4;>1`;OY}:w8ٔ.-}nA7Fj"K[+!t mSE| 0jD0[vV_]*=^ 9wOX)Nm빮 Ӊ6^!pn(|[yc Nl7O⠙,Vy:쬧KTyJvOX.*6͏wIJsSiM20JI0.Gr~@2O}EnE^wyEsumѮYQ)_0(k GS8pp"}&=;M?^GLdN| n;IsoHN߁k僚 ~+}hbEas>KLe-y|#P5+;FdPkW3gfvsX!xg PUm^Dk[h%u$2n;gD'9hCh ?JHASm?ʔt]sV ˨*y{2B׀) ؙ-hiW}.h+OCum gWv=Cu BWQW&l 8R1Xmݠ>x"u'B<Ʀ 3j^c1`|`p0G\v6qc.wI_k/wқo.//m6GMW;s]30}(ḑx޷ƴ֗CϤuGk"y=*KpX)O[@IWَCyu-\.o)8/ ꍝn_d7DA[PfJH뭳a\AzV=Z DuiljNJGvDzM:^]zS>zQ:)m [IKH3QW}⽭zx;%/}n\l[yOYVpco.uD{>` l2o Ʀj U.Mͧa#9Yҍ5/qFȊt~OEIBen76rhÞj4+y{us,xtq ~3.pT:qr:U,6xUvG:'y&tWy78O9њ"UJs)_x+/ޙO?ʯZfE To+T>q/BE7$ ORսԉ6\j*[gS6:5bT:V+٣HnRn0_`V/I2!#MMå |.ɼF_:;6:J۔*8KY~݊`u/էWp ]̗->78ut,rm+rڇ^qoOxIv!Nsbװ<\зycW&_H,թ,AeZ,p̗5k#O,|9`Q!EF!v}]kPIQ rSm#ۯs[I? :y1^$R;p(u+"Mo?J|z>$2O|JsO߿y.>i"zˣ89/}1q;ƈ[M>d-.=+zќ @I ko.~ e=ؓ5eI]"dMؼrWՔcE]pҕYϱLL$\:(Wفl m9m!jx8pd=!Fk >~ ֑JwGt׀~؜j&cNz (nŖuZ`Vơ>}n;Y#&^)EIe5Z%kXkBYڨm~ꪫC"w#kE@#G9nl궳jːlGuOCz2p|b!e"#p(]WP_aSUPwkbq:}f68p apx>08p ނ06iZ 5޽nݺ|r}sȄMFFU$@%_m . g,OUyQNr'N9_U+7'lX{9pf8,st&ͷce<-^ׂ>-ŏ'uOQH6 ~:Q&۞@$mne3o[x:*oحTzF/z)"6үgQ֗n6vr.]o?^7Y+76s_|+qǛi:$=zz3cՔf6jdiFy#4K|Fzd[9ϨߢE9 Lq,4l OQQb z=UBE*^݅.xa q erE2܇lO]S5&'w>Ӝ)wĻEz:N&μ1JHcGOү븲4:~>Q95g2z=Gk?ĽUZxpx};IE|'}vz7=$]8&H͹yJN{MZsyUw5qcS:i-Y=GNq삶(=rP}dtW@V $PPt?6 @$ 9~՘ltC'nuIT}R;P/ t ~*/ ^%ZY9WǚCuxN',W'?N -X&ε踱pX@@ 8jipQވ^ڳG s)<'4hgv%w,G`G졩^*D[s }]OkZkR>,qǕ>g.Sseջ,L*C=Id/d9t/n ]]"O*Euك! ՛⻜бm-mY}CӾ<_PچΞebDK٦!ݶDP\䅞˕\7aPqPͺ8Dy-6}Y\u8ZG_ }WUZ|&F]^E_a5vN>8p apx>08p ހk.F8m6g_z9q^%^Bȍʚ ltwJJ )̚$̬#5aĽLt||^{Z7 BGwݗfuuR_9ri@ȢvՀW[UWy16JCPafi oIoI{VGPj 74n|2er RB~Ml/:>;}gѮr} s[ӣizx.]!%,jZ7ˑ(/N<ɦ5bfԛClxɩMI*WqۀěM;`A8x*ޑBCL`CrT:嬧$EyyD:<</ ՙ ;"RwQJ5ޔ=-:dEBwLJOثCV nkKFPH]cCuYOfT[uzA'N'u3Mz8}h>4׮_GԎo<?}[n1T4-W:x**a^o~5,R̈<7'|]kO7$}C;okJodi&-Qk$-<.xq ˼͝B$uؾ\nGD#ZOR⮰@qPųXAUؘx~eb9wve^roeiǒ:PC>ItvRwmĨ'B )&CPr-ySg w?-}TVr}`PkEK׼Z-իtrihY_k({s.w_G!+>qn`'ן T}l EMʹ!W,}6 Qoc%5^7&27g Fdn2L6# ?[b>ȈM<=#_cPio߾^}UT|?b>_|6#o t[p~OHJhDdϭIa_Ž9G˯x1)aʱks؛jKt"Z_ JtPg'bEOh ҄Fgn2(-Yö\CI>]BBot=+.ИZt0_XʨeJ<*L'!|ί[q''L~ʙ3 Npȯȃ 5zg~u9N~MU c~}ĴvlGx~M[;vWmF?K7^W| b`}Al8'xVHS_^K+'q}T7c5bN< Ee+AY"G@{=lcMc px[gSɜd$p<Mݣ*۳X:h-c< ?O4S}ܞ񑮙D#g/W]98\ٍq[?!iG:Q3G ^@[L(E[8"#栱@d7 OAVhk0E4+ۘSYU98(uEeV-.Dua5TEztgJ_sMҏ~1+z*Fjc' S9x"Gr 0?4;S*l&LE8oz Bsν֝lA.1;u+Ǔ{~m{g}P]k,0*\0'sau󱇻s6b;@_?ϯ:)VO; !<3TGg(βkUT̛31<8l6ͿF&qem\䧃;4ySx:aSNu7tpqkp҃tX%$.##Y9Kv.p*٪5D[!K%pT#b1\ZD#KϬ\ia3Ynu\btH($Y?wn9b&eNbf̯.Q㕮GEnsHٚ@fL> CPH@/R|HV:km!z93Zhb*+L:X4"g9=eoөL6}d'o|KU'i%׸rh>ڣQ_L?x~eRsd(=м˥l~${dK</+tK;J'ʡSX[ёl`Gbn+!ij^s@BU絝ÁI&1q8g78:^>ޱVf6+Tb''U[1 N T?!2_#oyNi8B6S\k˨瓯*uxVYo\WP]TSs.=KM犡hgo\^&ZtMqm8x>l'/iOBK]4p>յ$]GG'Pg4 ,HilX[Ea[ۣm|ܥ?JN4W}ʯ:h+n?O N9}j_AT>C OsSOf( /jJ_/Ǿ X(/8ads @k}P7 waWSBӖn[;xk"$.;heveTKdfȻ a%+t9xlnI\1Qi"M':/M]^ /A9׳O [,f PYhU :vS>ħce)ЭOUu<ޅ{F]^+&Pc~zzhܻw#V峟7O#G8p7z~OǔWkTX7ج{2"@q"{+ZkW)@ijY<3)Vv zttY!Jwwm-`C6qn4GC\Wl(lZli: v&IΛn*WfHr3 o8PrJ_Wmiޤ)>I!E؁ƿ%]d&NwMO`Kg˒~g~(/[)Ų}CŒpb #Fp }!"\+ ,g)<]r5S.TN*SOVvY?omKե/9^Tt OD\5St3O1lQ"9͆7㌜Tç?AQi(DÈ(:ku&Fu7){vxF+킺_ttj@ZSntcMxgt.O);uFGr;Np1M?"}q㊇m\z1Jkځc]86mܧ=JUO]ώOc8@s6ugiIqbS'?t٤&@?e`k Kתn")r^#8i^JO2f۔9B>@V>w0+bix9e1T8`+6J# iVlĪp`15?U.8rg12S18y"R5OtuF&2rBv8i,jZ.5j)W_dXq>J*V<]B!kxF`(ODX˵ >tBg2xY8#ZtL"" <`_o;YYTs*tam}Lz難i6?O;_Kq{~=֯ҿ"KIsoa#m/4P|5v52 |1Q9f(~YKN 3+4fT\0+݂*/Gu3bu rC\0rp裝Nc^tS9|tt܁6r ҁj iM^ONN{N8z-ZO3Жn[Kَ;ȯ,T"!RZh]'pfUVP ѵ$eS kU :Zxmo{qzjO旼V۟ QW+^ypp0y|`p0݃ n>B8oS7ܹcw&?//󦛼 獗_~9kߞ;?JǶq YOѲ%Y'}ӻosf*23rDJTRA IRӨ-`*1/V 订4j`@@ $UH%FJQRfJ)e*Cs{;oǏwwv3۶m۶ᘻn'E] 8pNN8ptb@G|l1[k[G9OXg=\u~eRՈ G]& G'eldgiT[]{`g5{PS>tj:\c7m谡HS6 kpF T۹E{,}?fVf0 cyL"e/%<ɗ)7>x=>*},&.ɚHZ"+mz2E8_|FPP6+E97|$ /T6 [Ac2Y]eILq&c)il]e^)dwtz:mȔBQ>P%]@ܶqi`nlc6ۉѴkOuG>3׳uwчZ ف zk5{ywca?'qرC q?<Ł8OƁh:s*G|z( ?\Tl}>:5|-9SUPyl ouTkZ'$oc8@W=A x4IewYZqS&h>xl }S1Hk!>k;d:º]e;>,6yAYqkhk 5DXD&lU^J9Ѫspk[\w!s__dd>?bHs@8p0xs}1a@<',dl^lC^ E06dH|E>Pj;2B0)GECL~_Ku XrVaCSfm) c\D甆+9|(x9]P(#?#oͿu}57}77|7{=>"ā#K8syGa-NҁpGy᳻N~]|MRwwpwj[! ZRz9Du"^o,M*hUuM>G~eoU@ZY x4Dw9Qt*]z!E|+YV§M1\41)>GϽ,Ux"?X"xѱ 7f[w~зsÎ]2{| #6ݾ+fǚ}x 'P 2N}GJtG/ N-pT7QQ-6Ǧ$'J3|3P< >i~8x8*;$s:ױk^hΑQv!z1xi8~w-;pۧԁ==T9k\>I\SG'DWDr\be:6K2~=}GdpSI 3uD8 >J[xoAVtיV*v޿$2?_U=EsMpcysBOYc-'<s>X%I0}hUҌ8 (+8p(I+'yRR˼:mʇ%~5S"sa݁5_y}^~ frF׿|z#.J@t4z N3AwAcdvN/AMsCTw(_>J{0ܖL5{I^Sʗ(#Zg}:_CQgY0_U[J{ku4VYA%!%V Xu}אj8ꃇU`} ڨIAUj*#23߲ު/žv ɹCls ugqyB{^ FDūG9DYW T<:#"){G!]/A3ېƥTdId -Uyu琮J]Z ˬ*8ցE{ǽցE;G|N*1 ._N 3XHÁrNeᆨ7ttGD<|p-7@qAS:wʦ8@0c>QRiZTFy)8t?FkGT8i:ͺ̼/(~xyǁC;?BH=sKzOf1jR2NeP>kPE]ʭ%P%f۬bZw;rwlod_vw$΍ ʭ^.פ/;@b'`UED8*OoA8 8Ac+ӖXt5&NcT4/'"hF'P;h/^:]I2*c<K~6؃B/R+Iw뒑Rué^C_ks?usoCzJZXq 'Ux?hm7NC*Kcs+ׇ-`|'z*Qa9TNmDKjkm5,#xCs| )@E̗p 1`i *]cY$GU9eD̿m3PS] e,s Yo#(1SXGEJۚD 2֕р;Y\,2+Eǒ*dr5UNWq/&bL b u:Ŀ"|"ԛ iS҅L6z!l2%V/e#ߙ#[kz{l jx\$;EU}B,I9(cG9ඪ>o|.dru \]B-bS!cOJ / @üTw^!WX;~5(ג uҤ(R Qtl_G 屓Y`8؆Lon6n_ٮD5Mx#Ob ]I9c]:/ęJ׍BԱ;Pu w!y .GUW_ԓn<7&_iN\<(c;j]HYP>qɍE,ݗnL&vT{*7x4ŜGՌaN2:"-R;MD֙<2|rNF#HTߏ)Ȟ1F2(+UvK xM9+l}ty?irqBh^v킆e[yv~C{x8?7mi8io=f3f?{}n|YIhKؤkywxľṔDzǾ&;i$QE%WKAwu9N^5PK' !#@Q_KebHeS9=g"5ׇaO^ J;4,b3T <> C f6zP[/1 ©;J*A`>B>ԃA`䅁\M^_i& 訰X(ƭ xPd6''\ݴ۶/Ե~χӿLSMG#TXCgOe["a' (|W }Q@:ʿ &QC^#%[BMZUʹ) ;)^zXo1x+PZfM`,LOu9ieƤѤ/\VUv:_U[f+v,<8ھ㍞rkmZXJuc{t}Dsy}9NѢŽց@Ѣ$n~I^N1w~wݿ;sn__rg҉GSi8Z8J[gi۰yP8|oǩs݁ﮢ !^7 Bl6j(l,.C=%{%'˔yl>d^Dﳭ=9l)Z ^rȮHvSqYf5x>OjMQ_ EDu_kFF"[!4%O-[v{ }>dFl/Wq4q*̞wOZi{{GN8{G7xꛊl F#YtcĵX) n|S׋'QwH,es:T r|$ 7ո ?riRdxCN8XW&w=lڏz􆲨D;Tp}1AL:Rx~BwUC~g6.͡ɾw~ϗ+W{?dO3Cɪݚ>^CnkfTv4Zy P.`}UT׸yIQm*ԖQ ?Y*^XU7T+Ke݉bIWBY/iu)k쯗IYu-~(lE]+@f]$ӱGjUPc};-a( *8J;.W2]VqI<)h[5pEJz_ekjq`CDIIʭih.u y#5Y ܒ GaGLSn]o|pZVU,wy>IN"/y}k8Z:ph8Z8<:g??h'U|૿mkݼyΞ='xS '-Z]{Gp{;g{|Gkoro d7E8eו{e:ǹW<&$txF:D\|aGT*zJ-%'Փ9Y]RD'p,~()¼ᶄ\ZdF*OI7Y/6oZ̯,<~ٛ#,1;=ɾ|vǁd{vxqi+LCX59/ iBJ0lع*ŝ*0uhKgSR[v=Cbo؛ٰ? F %;ȹh8?'Nt͐M+ՙ$"\E90ơPl$Dl&Hž8t,Wv$ nXpK9'5(]X6 nI8< bEyOlҫMpsd (xt1QUYԇ6v?ǧwVqGv:3;5qqxC{әm <*hWD饹OOgv쓷hl4c5# Dt:P[box[r`ǧF[8p5S]3qKz.Ljn2А 4{oĸ @6g3QUp?iF`u[棤;#A%/8BЃS8<9>t\mㅠҽn@ۃMivًwdh[Zo{wg9"iNQIh?k19Pu@u~nm<7v|z׌Cz܁Hq-g}׵uȉ_Un FƐyPGȘ2VّBNAL7kM-ЙUc\ K)URI OFq T9;>o܁o=k97Ȗ]z=g*]gqQ`rS#a<&:DPG 3纞%-Q7(*L87"9@D(k?Z~UQD}?"@GAU[T K [%XW(!Ҕ؋ _ܞO̞L:qn(~Sg&S|_ tRs8inp ]ّN`T9$bh'ǡsS]{@t@atooD}{LN/E-7vac; sLm؁Ɖw>z>g`6dϬF+ +w#B<c8-fC\QH}>Th.4};LOc}~>skykÇkKlƘ{.0~scuuqg}ej18B'{4Z^kh|PUd172Fĉ>Es!fb&|/#߯<ŹOOqh=U&TQ!3wg'Nvz@Ql2v5 :<6Uے݄(>|! Ki'hM 7G?2qQ MoM)FUpQ(GGOٟޓ6_D= zNf⽉GmGum-+"00u~N_Ei:[*#UގۊoHq_@Pҁs8 *σ A>gFTquHzHG2"Cq[M;e;s}wd v5 ޹U6sq&`RxuvjVu?7})g=#tu*HE@^W'CI@ w` YteJ[2|C 6&gUx[K*PZ~K ~̣;p+SfD4UI`Z~ &\ I;J%}5SN{6syXn[ T_}+:V>)ݩ@VPX3LdZǯcL4{!R髅B_#Ns-NP~k_uo-Zkh8 -Z 4nM&?ycww8n꫾יŇq(7mQy̳>m΃™#"ޢEUܭz|ւ,՚QRc0Whl$ m#rݎˋHT^aնSSvz^B.pRp#Px-z<m0=<رr9-PWKNi&8Q*{^wMޮo}_;(ӑݰv&M}um6Uu4e:q |yΚj@dfq PB~C'Ƣ#{kwkn6|ckw类;44T{8pz8.m#\69ٯ\ڧOla#ɺTTlFX>7Fnop4߾3gw(JO.;9k(G.ciQq]k6NK>tq^Fpס8'w{NIjI(ס<*ǿ@ްhƜE5QW@һJ<gQ}=l~ PA;qߏM3SPcx彃w*eʼn1QvEҋX!񸔉~8o[]U>/ҒʜWsX:۟9pԚusZsq8'8zh s;8mNp|DŽyE:{Aq") wA+}aGZXk0y.Μݰ&䅞]yh5-\_ at4:p,l*)i?#GsX:ZIz+mtlEי v+ a&\ҖxgSCmSoQF'!dW'5sv*fDFCECr+/_ғsMEuVyM_vJuK.W <+:oȝcPW#4kjV"P6syj>P/Worǃ2ERGAYMM} lPTWYfJJ\7`]OWʥ6S`'Rz>8I=w`mMN"/-0{ 3WGhq}ʽ*-Z|6p_3=CYj=>ao??SA?&q:SiѢ*G<{{xP404w rO[{=y~IY;~@uaIǀvkg%Q,ccRD|Pftø?_C[>X*#E؜hBKh(VOSKzyMڏ3+9!^cE~U~o/\c}{/'׳󣩍T泚/ۿme~uۈ] HtxzϾD|^!|"66ل~6}˕1mmZB p2Jl+@l)8'lnyυωlFoC~{Mx451[F*b%ryJ,M̫bKE }먐7Y7U{\;ٮdyM3*~NosǍ=ԟ{/o{vNm}QGϽҵ+ q4Dcœ4xDsvИJ:}#o=o58s}S#_?{h/ -\vi.<8[7Y ƺ6k8-N8ot)߈X~R73m"*FZNW5^4W;ҌGip9Ba;o' U\S#ht^c'99Ȋ:4ځn=yјnʊ'H/}1Yy4 ƆfN|q*a;D)b5mJ9Oi?bbmQé|jzځ~N!xdbIwҟiJ(x`#kH6ĩ# #ߐqރA8B֊1|ӮRi0G%k(ĝQT.!`ܔ)L CJ,qw9HcWn dyQݜjܱP6ްˏ=سyg{gtKp_cW=B5(քhC\fxVsHxѢ4@ҕq?Ⱥ|Q}n}AP/!9lUmMmXل, 6' B*  'E҆uWx)80KOtx^n *QR>eIj-ޏK}yW2\Z4(50UKqbS13BUuREC*I8nES#}PW[82TU4! vzQNqrU|jJE^g,&dYgR+WO(tTq+(+.ѐW++>zm]rEn;u "\ې%ByuvEZ*hgOxzR]k8Z:ph8Z8/7&?6?Y̹{_ΩQ*ܹsx e"FlGwf^\/"55zYBW߯3D>a%cIPTRudC.v-!z=$ }nr ?rCc{PxBS$Qߨ !',CQkT7}S4Dkb?CVP#,% w[ O ,ԋӶRF!`n@tnLOGك>6?kKs~Oj un2UqB,#2`a9GkA 1c#W$)٦xǣ/z6A6E[wAcSYܕ $QfC/CIkH!z!s|~*M-Pf@oVG35%\Wo-ќF;m)8}]P.A#S&UٻypСI~3ާGG9Ml:]s>1 dԾ2&Soj+opdkz3WFcΜat'Ux~#7+ò<'}[/!ͥ J5E8K~<ЂKqfPw<4}~%%6!F mSZ X6p|_ e?iOHҺGE^kNcdN{SN+d> &چ;^nq0#h"u<}g'(c:Jc'zJ8i<Ӻ!s[<""PdLTpVYG7%pK|_Z&>Ba(OرyN{gIy>ё^zۈ$&6{_S Ң@CHSƗx_|?RCiܵiþrǞ["[pTДL Mͺ~G'үW,KڷhIdבI}^-AqOVV]hqy$M!6{iAI+1@vlZ@u'PK+31:#3.綆^ 2e|?Q.@~ ӺU/&y wNF;gųxQ[R*[i2E@npK)O4S~e^'y=.ʋmh#J|A(8NRۗE\<<@u.mP':vx7C^ݾ"D2@~^fmbHu$I, U[zy 0PʮȬIi,Vq4a-uF,/Z'6] -q1@,nz[N6%ocp/&3B_$tdLhSVxZMOyfGZ{GG >cS8QG༁q N޸ApR|ƞ{9q>,EoE{w!~sUki76IwWQnU.֐[qf|&87n'{`Ir*yk;䎿瀂 g-JCc ^)yt,96eJH1rFoVuPLVe;@S$e/_y[2[DຘCrkJkΏ_oyؾ塮ֆ vep֦Miff+@k3}Y} ]_PVK8NDΧ.̦9`gJumߵNT|ǨiPMUCU:P)_0Sl$F, TF[&"s_K؏c# Ǒ۝1w$]GNW}eIGN8PxplGy#k#9N zf=b6xEI} $ܚCTמȣjS&gZCwו55@A;S2>iA:#Mj@sbط5h`񈛝;3ذK^Ov~?36S;f68yZGcѡ5/ݭ;t6}|ԾAOL/Mee_4{O_pMk1O Ǝ&3u4&fGh S:$=!Vۀb`tjnO;UvN'6ٓСUt}gAJTrwԙؗ:6b+0eZPfB称ѩL3T Q+SEX`>˄eQم5tJh 9Gu/POAݐ_k5;AOOPO݋χW|6t^>/;"թ: `{d+%2o{׭D 25,g5)O oPy,r*tV&vܡG}ՠ2>O8+¦3" ]Q _Y_" y Qm_'/)f)+L9â MX^N4޾ؓ=ǩр(/{xy:ph ǽցEdNހ.^IN|Gu6El@y PxJ:cSWFvUSےz)f/xzG(k?^',W5. _OYb=Rod3q_4cNqO|.\k(C,FQW~Rc{GS;8wyrY:%u5zc1J2لD};x_Uw#b|S#y{C[w쳿p~G>d/?j?[G2V].+J%~I8b5YSc|+[۝_fOX)ekHJ]o堐 Щ,O9g⣡s2PYgiQyK<'Db\,IOQ,dlceI33Xg[r*JW]$_UmY/(y|jkBiKQ`]zu2KKZ&T e1T3OM/鰵R lMY_=8Ҩ,”9,Uhur,u{e_ ^beߖcq-ZbCqouhb= ͩxt ܼ{GD3^y{^Ǧlmmo-򖷼~$|gvM{^@~~~>kx Ωfpr uz8~{wyEw6lZr(N5 q "߭s:?+vU:\bnwq政XYדmX}L+ps|J'2oBC*}OUH.nƔXWG@1<>]*%]8 f#w?W\?3;K#k?7k'pd3nCXmZe,6wk!(Y5t=F^ƃ9Ԕ56u>'s%F!dђqf0O;$'uHΠ&1wؐ,2lda9W$0o k2l)Se?8X9y,˾:3hj=;Or==߀q;&Op"c14򩭔o:'z.u Mǰ (mS6͏cawfK]wF"mѝ}c_9}nWO_}df}vm#18lN߹V~GvPrvفSN:k=:SXf>!uWgz況V7n]W!:aeo@LL$_ȩ?r81wR""P+ӵ#YcYNuzOS"8xoϱ#u^dxAJ Eqtb-[ p&U u|#_pG 8WKxf %#yjS6dڪ;DI R=rDœ}X9pbF)~/}Zš O~Ne=)1]sf VwŹRaDj䍕>8qPwk{9t9r8vc!](?ٝ:T?VyxQ B3e?yKJ46M5pj8gO>0X> vpPj+brH6mr:8ȫa ` Z;p$P&t_,Nz^i:ph ǽցEfYozӛ:P_~9s^{?;OO?~~Ȯ\ _ ΩfH/j}*i-$Kԅ q8tp#}?`Ouͻ ⬁*| 'MI<@5MT ,Ӻ˯}o_OՓWBWLK~FZӽmFߝ8BFong]5 ߷780:78ԡ:$,$|d~fy &*N*8ЅHX ':3;pj޸ c<8 \ADyGPw8pP69hhNsՇRv+D$rj2Gp'==9I5 7dkWڿw_Kse!_u_Sx7A٘ƉR i^];`܁70B)H+\: 9#9T?wٷYw88~݃`wٞ[]=={gmNN{82θ86^?8p` +Gqzzo~H[Y>/T<;,t}ۻXjs#\*Bz1HWN::}h8p U=?!B ɉ ͉<]O pv 68],YTMkwPq^A9{HV|`ʦ6F'8Dltd@{{?Np[ȯ889Di=pŽxA&r\xSkE2 %Q*!q`} fҕʤz\[Enx;4.TTYFW\:EX-a*vD<`nKeѳ3&xt CU˕G\ '?cPtEOJi0qzKt]r[w_ĸ0Oeֳ;K'udz(wZNu&ցCy2|e 3+$*|(ddcE(&lRxjD> =Bc%/+v K dJTwBAGd _%3{xv=b\Y7F5#i_yUH~Qfx8"P e>ʮCծhGLV^L$x.~*4eMȄܢ/Tףgqx*LH;Hg,C)Ǜ+EKV]Y[&[.҄ 8?_Wd׵-ƹD!3W|8"%GzM. Yܹ:phq/u7:ph >q3 7&?8ݿw[[s_oc{'3?_$zu3Kt G8ppc0{=?hŃց78pt{}}[Fz~ydv=+!H 29=l/PCt:=,l{T9^"u~iֻt,4ܤ˒^>1Ryd+8?_2 LΥz+ m'1"Gr:kΎ_o {2nfz@ٮ.ٜue6l VyR ȃ;N,LVq^RAq)q%8>15XMٶS#P#d7BEliC czq cS8rl{--ᄏ薎mHOPҁv|؀AgN7'ΘR Ջ a ŸϨ*´yZ lBYf o)sx`GHDu+ίϏ&8c[Tnfb߸TTC PGBp)Pe]y)VonԷG电-̶{=۱|=$tTٱ=_ەyC!s6Pw8A#T6^o?N\θBqZ6,w^Ee*)z\6Qugk4<4Tmr s_cYN](Vj>D 4qZ#p`z,{bZڱ8 #\Z&vNX_kx6܇_+8pt%8l̙Q ZZnzNA{*}--dlVf! ce |FDcLJe^7Ԫ%DNfZ~ dJdZwMXW~x:jW9c=I]TyK2M<йuh_evTLa+yJ4j*S,8K8(mbP.u&, (]j2!\q\5{E\Ȣ.EۖPMu_OUv5Ι4B2_ :҄+6IꈺN[y'Ew-^ d)JP"㾴X<NPU'E9ϯ xћmѢŽց@Ѣ*y8#˗H}]bww׾~÷}۷w|wԝkkGGsmoo7܉ǨG&I*-v>2Lǯ]U<6R+_nIo`u4Pɠ*_̈7c,t [2Q"~,T7ٺ_'ors[GOc;V+6%v{LgFҥ" ~ J.+BWrx?8`>3G/7߼k_;op 7n Q;#<=9O]i+F+ + Х\Å W /.L.GԱfZl{uy:yY[ 9IbC!cᛐ .76[]<\1sSkPI~6"ӮMpP\PmB2Ӧ̝<&|"BSur+u52̼n~~|M#Y_'0p#^]jT'BMaS׳tQ32"^_ۜ6؆vW|G8^˗/MvP>a]5]p"GJ\ZByuc2o;RQ,O\k,O e"%|&U{E1~CN)T~#XWpְ'wp;m8'}!>A(} (6+Ql u^KkIPpw=uiyaI\H6$hlt ߀ʑ'N o7bC𩮂68>Mqb3Lxt$6wS?h|&Krڃ]\N z/MOpth~J˸ '%^Z?$U+G\:CHh">o5t r߰għICs5%TQ'@{@)/kWG`]GjE'?iE|#ʢH>5nCuVNؠg DH/ᰅ# ANI`5SߑZg}jybG:E~)aj]ipHG#@{L( %ͷXG:CrHJz7ɐU)zr 1+g|F`/o4DZ)T_*rYw J(Et#J{JYE)rOƁ@9@MXidGu fFg&qs[ium6E>aMq]GR6gRe9Sm9,cзt(qk֙;ذʦcl zH?]Te3^ֈV Ǚ:}/mv}8&oyKǺ\˗/هف֝:p)s F:>lo5aM!ulPMdI7Sa EvWkf9/H-PޫoDE)V_xIg6N~ZQdU&9ntmS-p2ܶ2);՝䠏S=ɕG T0>yJq0K#BW#8mc ~N%D)źCG2q,Ɏh&6w;ҿ1;7v]or?履\?c&6ٓ%GZ >:iL|s,[FVw=8ph<'ϟ>w}tl?ul7};2qچL/N1ӟ8p mg̓V;b`| 2)Ag׌|: RʈI$y IN)81|Jd}wv)&.yBNGCPf㉮mm |3lӷ=]`Ʈsk+iǨt(įVL)?ʄJiI|`N>l pҼz=*!SOc}uJ1CrOKmDErr[\Eg_ִ:%0Ő[&6S)eyR!!U6ˁ.z #;ʣk!7Sh&s#Lvq9qps`t:wjQ<dq4ևZ8ȱ\Z;/}h>? 8R 5)Pe*.#VXE)^xTKA"rHt鑢U2 ,@?"z:_i7c)oJ_6iOO.^Ä16_E:IhF3l. oDVe<42$Z9βC$l+L:n{9Eaf!RABpYʫZ,^,\'A!XSrwXv]P0ZהKM& lV9M\PA%J-ҶVykڵh(#˧2B:GC"^ͻ}[Ⱦ7}mѢŽooɱw3xh6Pr{j֠[*ʬgWT̮v5pbvhb&]Sg^>KwuڳWTh,Sl_CUiھC#idSM8l-;mvDg;#svDҒ?'qrq`vF=(zHrn᭾ӣ?C]t>)$C.(lwbgt]OmGc ް٥JNmP;~3WM6mkv J Se '9gO^TH|yjk,F~}X},齍 Wr2oxSuv`}WY! 2-scA:: Tt,;lJ{Y#ANS\R~>om mKs T:g?#!z0_QSԇ?:IQwj;;\m!ijmryiɎ1ca'gur]Y#$?ē I;Tuz \\<yPx.:$]Y'95%L.+J WILJd+A`}J8 GS8hnGH뤔j|UsQݾYط̆8pG] -^29U7!5/>s>p_'ZCtZHFO<S^9nLR!!5`IHSbv4|BQGgX>%8*[ү(ɐ+Ċ.ċL%SXpdH*ҁw j+ch:'%hyp׮-ZhѢE 7*Ν9; /SOO7}7 ??l֜:=ÜZŋ}sǵACmѢ @\;3qC#}c5@z?ɵ@gٔD/nSbVwB_]Gwut~n6=wmgбÎ]74A)|l;fO(|HwH"{R}ۉ|kAN_+ugݮgk2{,]o bv?3݉mu6W>Oa}GSuA\m~eIDATA\%QT1r<^7ƥQ6] ei~PCGYWe{/"t~|:7÷e;0(ل5QIHs>ſHHq©<8vyDS}ǚՏ6 pM?IFB`E0 hxj6zuhy'L檟qې,5IRg_ Du5ԧ#{Ad#,5d-1-8  Qd}؛<v?kRzL t ՑSr^V{DOIҷT~:S.ҟR#&QKͣJYW6˜e@6?dv!3uEu [ބ"]Ӂ.DRӷ;{Nq{74ooW7+=s-К?فHvz e7dYMl~}fcۜlv) Wt?'0O㰮IQ\OQb̳:ǒJ>z+kWupz840H=uP*fK}P 꽂hՉ]ҝIWEY5t^ +@V3BaI&ɪqN?ۀ:Pu|H(5*TuLu8_#0 8"?~q`.ut,¾+ɨQȔip]P#cR(y&tDiKwRL8P lPuR?!AJI/WT Dqkn1_>Oޘ'#}ˡ資sܡٳGf/ځM-EG#ue38@3U_`nm͹]ޚCg=*zl'9zYcgOngc9۷ڻ/l.l؛1Cvnom{#=.F/yeBNkis &Ek%"d\z'ZGSF AJ 5m(q:=~((#9$r)#dB2 W>ZC8¿oF="غ'Yc5S#v>6<~&sbؿItc" /99R8AK.zs=7D)Tg{tk,+RѦ:JM6L^jF} lzQQڷd:m$u hd!IףzS<2+3 ̴ϥ38u> I}%GtUۑ ӾhOtKtS:oN:vCMў.1EiΣ!:tn;ٲ׉W\MJQG=}j|m6DpZŃjK6lPf,BWAuw^K*:k㍊#. Lw ո֨&<ceeޘ&T t-ZhѢ] >p )~jſK7Nr N/_KzjN}qG<~m.wīMNܨgMbfXm=TGʠ\E3Y'aLd ZثH5{EY%4%]E#X]_G)P(K8͘Z*령vIsLn(EQɃNRsOl`sX/S. |Bx5,,tz2̣Ŗv Et`W,Lq~=WȖZw_e֖i\:lg);us;v<&$6XuR>4#ё́={Keotv۳J ۟VvfiQV==ϯIYxVϨOˬύ;Î}|k5W+͉}pj :دӄxfO3{^:4"z(܁c O8tp|jӎ7nn̶6綽5-s:mvqϚ]ƹc-͎eoo>Mg{ع=ro۲nعm ^T#}Jh5> |*(IN*@:(TiSF_|N (s@6m'޵AO7 Nmsܠy",aGb^g~:~~ l߀gNN5ttv oy?Lgp7A:udS'@(J .>ଡ*e F8|t1(/y c;2)"s [%<%-˻HKN3|6ڗuJXj+_NWh`z3]LǐӾhn뼯|ԝڡ֞2ƚ`ZP(_ʫ:ujI19So4phDXzz|7ZmvKm@NM-7Z/GvSk#Ժ%7;O/W;_NzuUsȆW ~e HC^G+N%2 K6ܹ=4W s9mޟ#S~ZI/Y&}A!xޖlD`(h&45ƥ^nնW[F)GPT^9|cDLs'r%0ZP=o:)ͥr7c/?Xi2*j2|ƈ^H6IK ^=|X-ZhѢE{k|ą ;~]ʩ7>z!{ߟS+bÜZP1*{8р{]-q}FJ're߇su kleþoCc&P+ ZH;+~ < 5 ,ӿҩNi)m" U_+*,8Rx}s:k]5yQe^=/;Ws{f{{jۧ䭉}>~CSO䎙}>}3={IgH^:&2Rxυ#Ӆ&M-O6 ].o]V=;շ^O!;Su##lwm<p=vxsxpM2D ش;mp}V;Hzەѻӱj$5`=6qE<MR9P2tGF4ԜqGIŝ@9 a0P+'$q{< H櫋^\qI&Xr[(.-/-iRCX!ʝ鄔e(`K~ҟx i5ݖZZNY+pWWF;e^/8r1e^j5%CQr<:/=]Z;7Dmn l{{,hSqd5 %ٓ0$ohp[T.!YHy7cB^. E˵Wg\fnsBI/e 4AUY&ZR BAQ5t5}Y|0 6%cD4dke\I$aEY *+z Ā2 2Yt2\u[!ףh)!۵"ȽوrFxni̦IzKD`5QMZ֐gR(o]Pɤ TgR 6d](tQ|ǐb,s*;blqM} oKBOke9ee>*tҸ#DI ^T<ơBN<.Z9Lu^-ZhѢ]T>ԉO|9u:|}_}˾stkDBy <P]^ΜpeOsQӣO.z*#U88$RA aƮG1G9x?Qs \Ĝ4;Q#8~_p6:ֿ(͉}7B+9誓NG#]#՛>I'.P7ՊR0ٖ>OO IgT&B^è>ND<k(vPK$9t@>_FZ'b0vL8Uv$[p0&;-xݞj5j댤 "Ix/%-4 ^hN'^ [ a>@.G/TQHLDu!@Drς"A qV+ dgO R?eT<v]~"aOKY㒂> Y /a+UPܸRxZPߺx@mnjI^ t@qtJTv=9ɢj@<>ʶlFB_E"L8aKF٦uć󃰓m| x-ZhѢEǃLqd2!{|?G(N9s&S'Ǖ+W@Nck‰thѢ] L~Gz ׄcAcSOxɏxnB&L76֔] }PY?7Wfl1~ +\ɦT7ȱF]uR*~J>(utn -Z*@I4NY Y}E9nS_/;6'y6GhEG7’ģ_9w?SPPV(!Ҟ9s8iSbAi{Nu˖\;d;m_[x"S=؛̮n³J7=eyI_3{~4gĞ>#3{c-§[#{fOCse3w$Gf/^du }K'>Hlnd6ВXt, 9/Vnޔӷ-g7ͻ}}{Nc[{TN.=Mt_gbc8Nmw6.;vaгvdljzNJg\K/=+l1!.]UOPC:Ȫh@K8$?m”SO\Jn*!c:.T 9j4J̄xIE''~tGC'uLLɄfOKj d^)|Fy1q<"z+rEu:^ }FXy& k .It1Ԉ,%=a)T9(CR4oF60iDFG(7"s^ȼfH*DU5^gQei"P=0E)[/XOݣjlK : ZzqjI(ǪB%$ F@m81\[hIG&Eukr7*:p='F_&>NTu_P/*=*^_ZhѢE-Z/L&&\MdgϞͩ/N?'stɟt#j pniz h3hqw_ᑄW 3JF<\[śxŠ %&yl_O@o@ r*́G5Im蔨hʼ&&]v]u+>g |6 Sw  Jz a$ҙ̇R^u<]ls^X|Oy 9܁c:]M uv8)).]2d26Dfo7:=.=fzxewzy6I^we 9ԍC{} vd1f.-ў {s7#SG>j>c)=ESxGG fې U3{|{n_3=yFu={Kγ]⻃Dgݾ ckoݜ۷nOM]{QkT^.紾\}^ mٻ!Uj:uЎّ1 ZN!Xt<9qzN@!9 ;)H-yf`C-8TTi_t,`>2pcաhjPCmU6xLi2yyN2(9RIZHJKZ/+XڊxD Db(P(|h2ޗ$2ң:谀,ƿOytm^lN@N~dבubT?|dJUK,eN ?|r~ԩIuSXP ㆮR!sݞ֬N80O Z}8j?9bzZ+miPpI} լʕq'z_Q Yue~RD`IǢ&:) =1:<4HIIiVVDG}W_zH ﬊23@zd|N l|}?_&v%(ښllD:O@n(ZIgYW=E-ZhѢ|eC FWϭf|~oo}~kNgɩU\x-Z;q[/~!S2W\Ӭ1uYi^弪:4C҆|ԩNUN NtU^ožBăB,SoT6'^m$u'uQ3$D)zH_"&[9VR}R<_J+܅h"IP;P/q}cT'ɰ#َ:.erʻ5M4=T|=ߗΡuv`vK7MݜƤoF=:صB}yǩpƳ8pܜ7͞e?#c^+,fPםו1EǼO_ԧ/ _-}M]].ܘۃfou챝=~c_+RҜ]{|yow_T;tm;~vr={ByOl+ۗlүőD>!tMntbwfgg#mk2iM:`LN9ԁ=ʛذ)"ݻ9\rp@n(!ك8-/|Ws@Y4m1BkZhdCXc NX06<٢ =.x!W%(pBgQ^yg2c>9h0*nN6$p6Uv鯴12vg }4@MPJ1EQIR˃u탕H/ fJDZ}˄}n3'#ChR5QqQhA5VANj\J6!ʗTqz^~\FekPRRK^u64RZ:z}u7A09:e,URΫ_eH,TA:*YMZr iбhP/Mq̵rpb:9RU<;B:Zю&q8l=)1]EjlhURYPrD^V3oN'u5m/F35=^c552!6FFw? 5KP-ZhѢE(Lrlkk+4NN L݀?P?[}΍кFP-Wk߅W6 A0m'A/8$ U< ZUWnN#&]彍˚VƐB6bݬIeū:BcQ YaDZğmJ)I/\ܗC_mion 3ãf.3i7~x&:Y>oGT&XЗPځ8!eE% ֍,iAwR K/DjN}cRf3~VPZ Kc|QӳIo#CƁT,tsNLR1Ipc0&q׎F;o+ʆ>m"OTVQo }p'W={hn/vUɶ룉MG}B9]# k2H{uRwyOJKtR;@/Cچa73w%}f4{t;9xIfş:s N}{پJ+=={pboݘ[c{xoNۛ6hodWocg7vg4C;zGsa; eOc4CvLC4mg0mwgaGGmBmv诉[w:MOԧ# ԗ}MLc:C5S XM4p32| ,~H_v$ ͒KB;׋diU)fCua~2 \'ԙSݚPЍ~Ewu(՞!DREy1sˡOb1:52&h' Y\U۔R6G.ry}8e d~e|кJ=$RtR)SuӦS+c.#dJuzzDyERQ] L,ѝ<9N{-R'AnWe/E-ZhѢzg&q:ݑ}?+vvvr[8_b<ϳ-ZX?ւ2ooZ;ro &JyA/(-Wk::*%Llfz *;s<* ~IǂȜJ(ejhwŎZAMllCɍrtҒ]5zv\T& ƧU\@$.+RM:DžZUd^Ŭ!]ȝ4/ Z2p8bHr7v;llDc!9$w(9E U {s]cH<^""|G{cu8FM:dفlݓ}P Ogϔ<oNG%XcM /-sop~9람é:GJYI*yʖBLl'Rx^tQty쁡BceĮ[ϊM9yذݿa_zߦ / \Hmɜگ9۷wlS{`bwQc=!uyӮAx^W*Gc&W,8q!L;Иmƣ@lϤG;HNvmg8Tف?ެ W}Q3l8u]ǞC8]@itc*TL%RJP=1NJ >sdP5=`Q?l7j`8* PmeYb^#OpDY'!jR$#Ja3 4ߖ8[WgE"ɪF. Os$L9aky?hØBh<1P[F4k ɈyM(ŲhjhۢnG`D]Ɲ,;׿dl[̏&+jr^%VK %i༂rPHG5JME@L@W4 !q/nνwBx/RכK@8ZhǒMJ}/y5Tm2eNTV6tE6} ml}.} /8 &hŎc8(qM:=0Xܹ^VFBmL cGTS^й zi{95 ,-ZhѢEā_t'7ߜcw>N9֌ ?21'@oѢ7}׶t<}GﭠZe>钄rW+SAՊN,w:/cGo@- K@.{CȕQN&7ӄl:TjTYg/N/QN٦e,ʢ-kMj }{jkj&̝Ыk(ļn>AJ;Ո! E{ BjXE!_Ԗ\\%NBzAg bzq(*S3c^FZ&*Ɓ ¹ڗֹMgWjs C>y#?MfTN01"EtMd@Z'8N{=m*؄w%ƊH9WH$O`Ss~ ̞KGs{@t88D_]WGf׎̮v/b4==)qQM$O|;2{T_QQMeQ+o۞E;Έvީ/rY/ }JBwg{;s{϶mIϦHYu?Geò>ueͧKKj%攪MUۖ)J͢@:T:GJEWƛdq`[f)٦ж;-mLI}UѓshBPSHK9I D 4{>1'}'ExV۪,ppD6@MOO&S RXe\PT+M̎zfG2PgSͧvStCtk>S\$[dlfࡴ·ʛX fop$76u-_Q$Su?Ƴ8_c⤄D\*{¬JČ};u솲^s{S{Ԟ5gf4tknܜ+=LrxeWDF=}-;w x4 ..*;={nϾLϞLvko; gqs]}R;v;[eu3{rsjoݜ%ǎau#dCأ~;ކqC ;phmXzj3'k4p]9Mo!١i1 8lhl"2uE 'I6 ԃr![0z{lE:^&Oӟ ^seY!vⰁ|9>:"8Mc6I?4HNH?nHq8Gq y耐I,SKWQE[K{zOI,Q0)y$Bғ%;E)X H- y1?$ǁې [b{2$%|btJ H魯i^ JWrN.f PyB6.xAa議?rEO*x, 7b,"lѢwfn6Quo H'.'Ro\UݕƵԈz%TQE/3)e_z%?yع =9 f O|Aގ<+QdM`U9)g C A#J;FUw^GcTWz4/M(z‰w c~"?#oӎl<{ z}8"T0|}CFN>:ⓝu7RtvܮN:vEk/)fs{SĞO؞̮pS-fZ;h+{5s?a(74&< ңYpߝu 9ןʸO??$nBJ!ic;N"x!8VgzMisԳ\&*A)j4疻qI/\p ֬647?4 C$x*] 1 V4W|NetI>G)S)K:"N"KxJv(6|0Eɨ,;DZ^?HJ8jqy!a6z?n8c^ܮ72b!!{2wItD}q>ǧen68)6'+@9OO-ZhѢE=>?.=g9vroͱ8p$iѯ/BNGׄF9&t-~pͯ|ǟuyuy?QSҺ<$-U2J!2EVCJ!V?S&ީmƾzxGnGC{ұO @;BD' I%~)Ԅ0GEU$)i֙D]غ65:QGDG*21Mfvlؓʣ~FI*w h%cPүӕ!d~]Ÿˢ(k(%+V_xoRN]ٳf9+Tzֵ!:գ|#W:ܹc?9w.P8oXo}xD *g_y\% >0ѰG2whN 'ot8NSee6x1VCEr=.`udD!]Nʫ˺nHY+1Zj*,nȼ^{z&mHs# ḧTI8yM xWߒgO&rd!IG]dW67#t c8="JHq-6;tődASzsl/jP(E# &NP'寧wKsen / ^[4]!{2w 2Pֆ6jtu6щEL+s<؛T[-ZhѢE->/d|:<9vrid| <}\ԗ>ul4ؾ}ߛua4ّT#*y}hyxePy.>G(Q3pr&"Mdpp \XR*( e>1h{o_&?tC"Q8Khs̹*j{뭷z1shŷ~XW~(념(qO5Xw pJ }ԅZG ~G vk^d#Z "ԅ\imn@wP8\y)܃iA~0+811A7}yRfQtGށc!$skCCԛs")U/У&6r -8cTb^RX Ix;o];7B;}~~~r/J>M]޹}ƻp Cr&{)ȸԦYyv:+啋+W7/WGڠ޵n\{|f|MnX3*F޷·/ '8܅<34<=·I+hZ8h]/8y' =!s9 Iɜk3{+ef"|圏 ̑:4Fӗ."HGX,zP.߃uo3ՙVUvpwBˌ*>t6@nc;8wxXUX)szr]>I% ɔ¼isRfl[徣q<N0!>NחoV'&XԦ 0` ~|ݱko~˸ 0ુ^msmb\.tXszR:㾁D-?|L83ݸAaU7=\o:{7a)>~Χw0 =C m=QNαM Rc |]qr-ӊ.ߐy7n^] ֩=zwew;|1R>?&=>ve^{ߺ}Ts|wi)}|-~)&OD7[,bDCMGq pdxum,R7>?*/^orSuUOʷnL;WGȹ7&,OM7ʷo]/ߺ_߼ㆺ7 5'Xl\N!Ė}A;AG^1ʹ oqAD8O?8d=<Ʋ<^.PwA6P/G}&!! g8lmh|MM1"/mEh[nS|/kf TqNR__ T@e 0~<X9^0OPVeeGMB^^;Dr+]b-dUQgMx}N}Շ0Fv Sy@}Lr-a~>7a/ƍh/]/;<- wݨLޭ)6qRv`pFvC眶{aC> iX;Ob"LZ*JZ ]GM'lǏntnn=3(2_ٞ1 ި/N5P;H> &;t+coS_Z7xn@$YS=9F& i5x#3ŊBŮ-'/D|`l73/^pʢ Vb'ނ](u4_;g}twF(K\E5j} ڤ 0`=i;=wWGGGS6ٿݕ8M0F}üۙi'.1 [&t|@C6GDkq  xf{ӧ<,V!{n│.ʰ@H5;*N|3dǁz}t#1d|Tiը6#X"o?M Q~ d>-e8m' d%r9]J+'0~Bn{蓪E aՠ㇠g-dYNlT7 H\(A`| ߐ\=t-"Tfd\w̧֨rclGxBnjXN'XFW"}wrfXX}kGGzxZeo1.EnYhNWxg YC<>R(Sg]]B1*țܐ1|#g<*T}8=:1X+Xch9XN},*E>> )'Ih9)#[Kx|}M-o=VG.HGrǴGlZ^qdqu.qn,Ϡ|ūP6w}w{ז_YuuT~~Q_۵Mۮm{uQ޺<+o\:*߼pT_oNfU嫓t^rc~㷏90E1p i!3(̣)"r zsGo =4!71'Е x 'g<ϯv\x"ttԷũZ2` }Q uB|wҸ}v j@xgű!ii Z-&;A&[񂌟}l5`k]fN>XjbCzL>OcA'҅6d:ؖI#Xe~>#Wuɵ'ܠ|4}zZYquzDō߼sV#8֝21U!5Txu/OxqhUs.XP$DNdS5լvTG-5i.I<NnC."!ԆD^3ĹY;ZOW{eyee۔0! |tU>9XP6I>K|տC`ErG  {sKyҪquU޼*o(ݧ;7[7'OMoz|7.}bߞX{j|멽֕iyDwyT|t秥|c4/OrctTʥB7R\yYЉSg6.N.&g:(6xuN 7SSĴ׮e>=pT)qm!-Yw _AP]͢0Փ*'X*ljlN/o:wR] 90" #mLFA}% ] 5fYģ^Cό2GG<:RYՉkdix"f޷jh  A{10ƛ:M/2U'|&yuЫYnINV{lwn#G.gĚזC@ #:j s <&>> BJ>tt$H6I~fZ'omA4%;Q|y!Ď[k aa[0`|pE/}uܿ'g?}w0`Wq#ͱe=0:[+:Oo,Ûkǫ~yF||t ^yJ jy3!}Cg=?vZYT^hn˕5AB ""Ղl/I]‘_ EKc[dѬ{9ǁq pRË>ɿ #m& n&ml6d/ |KgHDʪRA`2w8D}wqh^:/с_?7+9*>*ޙo?Ynϵ}{i;>=*"7/Pm_!$:λqtY.OW괔k{;y\(eՋqi\޺2)o^wn/7~ƅmZ˷{WKyr)o\pi:f)įOʵɬ\QT ܱe#\)&c+w$[x`[(7F'eG._{">;+.F]cBlNЙO1H5dqcwXL ~.3&#c㑺ЛA6-ewD9 l!8#'iI{ 7LF{*@7^ (EkSR^'J |t'(ƺ;'Fmh ?96ܸԶYhbcaJ԰k;z98{H(N֟{jGp\S TFHF9Pi܀@MwBHmE$:}uZD羏}iT&gI{"9 G҆~VVf@ :c{[&wSM wk 0`__؀dy'w}c~o<H{ 0oGY>?"$ myUSނEzF}톻"IEu^Uq9 N,ZqCSa X8ï81;m9 yf}kS_do\td:R7,@rcB]Kzoo^-kbkA[WGߘ9-~y 8~e\^ }YFo˂U%I'6[lن2; 0` ،nʿ~c;Aǀ1xwh;xS?Yq^@o2n .ɸ8T( y gA+8(tP=1>z:lFK6>.3u]8=?loOX<&fwI7Às;ZW \`\!s[+X͍͐w|Tyx 4j\;#>1kj<_eh>qCź 2FB^Xئ%rmذxr5dY_yݡDǫ@;n%!2C|{G:Vro.Wp.r ^ ~Dda)scq(icV|Q]rC㻋eL\/܂[KѢxC@yt'=we)4 9-9;^__PJy |ʸ{u\ ^won7ߺ1-̣;W'Kqy¸<qT&r:ʼ\Zʥ(W""627@e&nc,& #]O8QSrsi"vI Y8iU;ؖ0E$A]P+nސ}th'`eƟ5B~"yP*S yywxhac]' l(N3@r>uJ9)Ce. ΈւDʯWr7=KHUzW2l!02phg9sꗎ&L=tX~ñmoWSઇ+Nq/%D[CG4Γ"ѵ ̉ǘ$>Ǹ*IiS|!6 rJׇo0,;:s9/Yӗ?lX81Cx0` 8?j 8!0/9bs]-Xп_Qt::Q噵#; ѵ< ;@[|9ڍ!NUG`vjXb[nt!؋Sp@6qB_ooir[Npw\ n qƦ^:eO }@(x;;Ciꯋ"g1{T=+j+t Ӽ8e-v.=q7 FlBn4By ~aR8CHfׁ?,˻n,bD"HG7"[(r(GIMaE[޽2&ƥ >F??#V3{]$rgM]>xcU>>(Ss8|wZaB Qbtq«I)7Ainqy}eR߽:)]oo>-߾1- u[{ԈׯL7XʥUyiU^_Eyf }e=6->3v A}z;dݜz-lW1dMn0*G <)(> #+re\K)W7]#$f}-Ür2* ƅaXR_u2ArZUP֓[k'˅w sf,Wm`<ّ ި {`]NV8 uyZD\S`S}g|>v|Jێһ⯝`e߫yїRl.U_yo 0`?{1S pBo뿑W<9cuj@։A'QxWTۣ/MXk?26^#e)՜hWm8]u1>x&spnul2LeU^EK..Qwa4G`TH/ԔJ,eBo+an؀)W^R6l@#Fg뮪[vyܨnB+$孺`JCP>w8Bgΐ/Ba>k-KvP_(e^%ܐѲ|zG,aoT{oU{wG|G-7xmw8Z;h]4<@> 5D5Ƽ]xN7ɻx<ǔ}iW/K2*p`||9AxsƵiy^y s&w];&r}(We٥\-ѣ2YBchp^8VހCMw/ц (Y Qc ]=sv|c=@b 4n!ࡻ 9ISq|Clj3ƃ.hOO= ll:}e7Ad/ DwF1٬玣@qpzڱͤgU&V [E0\ .TYcuGp2[9o9469TxQSo-趧ն Hj7ҮsP'Nv`ɰA2W| v6qWȟ`h+ /mWX<5]ntq\c]жy'Nz4 D['quv׵9}Y3-rܝ :䳇 0`NǞ||6 0C=s񋛲om y"u0߯(SXz=cj{sgRrvBeօKuk./y;FؕM j,#ֹIS!jAжۏ7n84c*܀Z( ] { A;&sg3Mx ̓ryCTtDBOLJ˲(Mcڸ,=ZQ\@fRmz4 Q7= hӊ,җGh 6&!Dʤi9,{;yEނQg0|1#rR>=1_/e.7oޝ yghU>'@>G6u} Zbm$ab]%*>"cZn|T Gry/U6 pCǻO(IOwigy(KaQ^(_^>{aU.ˍQ<,Vr}(W1JWra9+=ceCIޔ ڌh;tчN@YDZf5u 䜵ILD!M0D'e""& EL!t$9aHPa#PR4;P +.Z3huO ~Q=B۔QVqq+!^c]["wFŨ=צ\2tɾ AOJghK|*u'clX-f *~摥M7Ы2,80QP`MvW$f שM̔oj[@QYmE ߤIׇ\or@=?6w@gDtP˺MuH/| bX|܎ܰqf~VD;NڞEv)KڊhI.1Z~k?8rxpHǕ]Գx=j@BX :8i2̠,]o ,K ;yPO&# GsȋGiqK 囓ed7m̃.? ȳWӎzWh3r0+'Xm8X!NE#n/F|Uo/K's3x*{{ݻ}r^?yETL&9+@e$?(O+8L#t#F!Ŵ (ߕ`;<o !oh]WC"2 d}wIE>nKE *lg!#m@@/F:dܜӰBzfP@ܿ˓&>V{, *VP-$$"m]x7_蓝5vo=u-5;v45*X (42hҚjҰN\峽` &>|x u\yvl,unGG;y3~x !4=o 0`_ؓ ~G*Md5&,ӬwI_+-""R6kqs;x9/K0E;zts_xr}<*d~M6=-0JAtLx" ^ `9K^ATnG -ĉz3@6sRe;lPS=h?b:O]cZC.<8)OL1virj{N('q\podw'%G"Kو("8:d |L0dF]P*HCQ|%FYƍ#_9em /nPWWT;p|qw}f=ҧqyGpżf"Z.iǧE7]RPB/GP ?DaXimG@'!{riz$^w'se0#n]w%1| tVrqF+0/KpYcw-f9'3M3cF~CdCwQ^&8"Krc ".C%32nGB9~d}Xgǃ1>;N!W&.Lɖ.fI| c 7p;&}Nr~ Ed9vD<` 9&6nhC+mְcϷqP2ަ~G/0}\rjkߍ49A[ IO3쥿l},4!7]Q>0c9FNca0*n Kx`H6VoG2"r'46юn'F}ӝ= ,ާyZl(+-L9~<-Xo;Vep* 0`a?X?Ǟz2?zpP'k<~}0`mOq+ Zd2 !0JKև`Ze?Yo[ۖ2"}\78toach8 Pk6;8 XǪÀO*tl#7"%m"\"6D$4V #LW]}bFR]FMR9~ZX1-0Gi9\C=r\uȣR>9,e9=ęV|^޿;W}| ~v(_ u*р;p ImFFndaeuI\ˣeӓUyv,>NeT^4zTkKy꨼ywwnnw/ݜ|[ywR+WKy KW}aY(O-)ɢ\Y:fzwouTòDSt6v藹E0ȆLwe$vѕ|8{'G~h >G? d8/֯># зvXec] 0`]%1i0ǞLW<`E.U7/sٰ9`lƘ+yJ+5r&^6#V"6CX\iC.+Kc5*G(j,e.WS؝>Ǔ24|o2I* ٝDlcII;yenڻ`դ }q-3X3OF|^)ow~研s*rT//|,xuG#/&ӲD)|?"0 ^7)4wxB)qseߘqW:[7Jyf)nN˷owM;W&ˣqyҸ {/- { XlK;Sa13зMk y8"[w9GkqMpR'`S)$m3ȷ?*D@e*թo7B7 c[=d¿^O?] ^$Ugp d[nWt |8[A[W ,{h`}R#$>>蛫qzj?_#< 0`ΈH]gd|64iO>,/R{ 0#[ŘG92|0 Wex}M YG2Be{ڧK'ꡡ0aDqS;|܈MǕuF s" mX߀_u&;İ:rmJ6A1j>TYrښX]et]ŏ)Cl6e iipAP` M5Xy*+n`$C/ `P}#= F(GBY:xG#dm>a]7.r {Swwlyćrr$>Xx49*;#ogU}[5~GEBwpY>QB,b\f~VC./9/OK~V)YiꪼtmY^YK 8-o_wb#@ߺ_޸_/W/Q{d\! 7`>]Cg_\G^AOA-B1m@<|NKgסHp6SEio=v!9CKr,* =M!rNB.j\_Xw8[@*K;4g; 撯A6" 0 qt/2Ok^ݼ?-fɻ:]O u.dcٴo=OXi =q`]b狨m{xN伾BwA^HAǭcy\E[>^P 0`yi<ɣ#ŃVQq}ɟI=NIßcCn cR8y0C`i2!~:G/D`{wQ~޲|w8(CRw;| :*7u>& BBz\[}tY.tUF=~|qGUs]/ƕiy^yUo7^/o޸P޸~|څڕʥiy2xivIy~oT7.Qj?/W"YD6oA 1`l߯;}Iǚ2EwJfӨ9jalz&aFl̈4BEQQNe We+m0yl ׶jcCG.kIouח6{{yM#sP!:#]f >JK[u0#~}=>6(Y/w eCE7g:n hp|<_Zu\K QmL_edy1%$ØݴA:^lʰE峽3h LM]{jC}G<Nd]+zh(GH>$Y(I0Ȩf֚SڛBQ 2sttb{c' mtu|6 ?h)AZ^BBSh 01E~B?/߿޽{ݻeه?Ǟ o/S؄q˛8yG? x4~4- xOUf*:@S8뼘t`ңL0įb; ]&ٜ2y-'IX8.!%6~E3(#׮ ͗?AyD+A b*PR;!t:Wej2_sٌi>dD{z ksq~` X8k %)I9V`rصlZl2.1:1GdyG|B o5Qt90š>AtFy]fd;TT?f>i /s):U 9B>78Q˂+BY0iH3B`UrT]'v,MP'7\,lXi>fB}(Gcz R BZd^ұ2pLuQ2 )FC!JQ(Uf$d3(3]Cp`%qAamTb1|< @2~g,r 5_" ~z(ߟ{s\;(~)pgFO~p~~;S︂96꼦_E^PuO!cYh.ʋV˥|WڍR^'oOO˛HycU޺,Xo[׎W+n. sު<5Y8o/o`_<K \ BnXڦ|Ϛb?^ FbLDŽ6IN181(b-=^'Rl%} mMZBd!.dyMwDM3Fh Zp+@˛m9E}@beyY~L*AHkz9-Yњ00PЧXwۖ6 񉂭(Bjhrp9& -&j\?ԳPtMG'8=Taf:7L'c 0C'80hnrʕrrSO~ZayUb i.h-y}ūgާc֡%=$u מAeJZ˧%+sf#d*j\e\Jy! _dC-k*P293AZ $9Fͯl(krk*Ϸ&dd 7iN n0dZ\qsיFK85i㠔-߹KP* )⟃_ñ! e>?` +"ʞo@x|j6xhUy<+WKy QyQyIy[nʻ7@ܜwO[7@_o^W/O˗&Kqyª<3H?}aoLdY.Ѳ\1p#:',De$.2=܉f"Jf bD7 3s)q?:QXuWt,I(`f]|PBqI=eY3I]2 \kvERldu"m7a12[S(K.\ϒZ'۝w}VҊ*]+Å]/3hiP@ 4lhJ)]`!Ʃ -}9k,4Մ~0?`Um :7OjdADx8';=@`q96sz\>V/1:R GFwNNC[hL"ljn/k\6ssgAz 0`݅y!~7xW_|&{|Ѕ }^>,ʯJO=kƑ7^|Eǧo܂q7e:j7rppMg)ͪYaww * *8E-Xoxsu5tC@\Yj ̫D }y覉u^cAY>ܢF t ZV [sny{YpV0xw%x89ÃG:480GyuR-,Kjb m"OL wMY'"CMbǎ%.S|EN~DP`֢52]vR Pӝ]5B򲁸B : 2_-An|r,U:j-*P."v9ɸZ"84(/m@9I,㦍|7L<\f>QD;c08fxr=U>/ʗ wg3|v|zasp2=`U>?\/JuX ;RP;݇zw_. ͍2d%/Av}zu2*7&ޤ8 1OHYBcHx¤!'Gi-Mp죪}S&܋9I5[|EkALb?/˻RpB@ +0L}Bرo񨻏1esn?33ɧ88K񒶩 4zfK;;OlRH"N[t`XlZ0Q!U`GL:*fMW9}+ 03D LLmtP wL#k}>z+$[:1$uZ']߷'X@g<>'*nʮѭkkݝ@ _V#Oŷ0` x|>x^6x4xI//??=w/_M$q֭NO⿧ȣ2=m.eiV0"`[ c'r'H]ZeF&y^2۳F헓兾xnZmrGnG=Rٴ63lta"|̌:2,9t=,rK!4W>7mm@wCxxpgrhU<↍EޛU~6v["a)_[ y7Rn?B8y:;SQDVw0'y >'tU.Uyb)/\(Kv7W-|Bkʛ~uZ^A.dٽtVnu\.a:*FW@\yGw'ޡ5՗m< nn8%uP<@w8G]P#$PMDӢT~m|'Ft8Vyddȏh5rl"|>ނ&pj[iiHxXl9Yc8}VdKS;!ϧsmm$t(8ES qB8y[]lAM<]3Y_N21mh-jm?7 䧁w 0a ʼno`;. ~z\/ſ&~~%~{»p'a~UNYX2\*I@-iHw:H@`1;`?AXTHYs'O~:Eu~[7)"PeΈvٕI7˻"=?6hǍ ,V>`N,_ q@( $Ch+.s3-+bPhJXՉȏw`ІPRμ\3#c uZ_C5zioփ@?ɕkFDyهi\2ضݗFoP\'Mvy6hl;l`ͯ6l1Cb,EȰķJ]6݅mXYv77{F|6``L@nZC圆\'`IK]>6Hp>RH =m8iG9A]45Zk=l6eSzn>Mv|Ԍ\ЍX׹ԧ۾qrwg C~VG6k؈#=o3wb+WOc|e6vɺ8~.# 0`b'N>;~(??G.?gO=x嗵'6q.N x߻"7qK&,2rݴEi_qKjmaQziQ{>};!z1M8Ak]a}>6dn/U@;!"?\ڋ(2'O5tɻTUBDzL2[fl<˛z\cúJp; |2V՟`#:cK2[-hmr@ʍ~)MqAI$6um.m@mq2?XI9Z퉇1Ba {NYmtg|~9>,;*?, ?@)>`N?*#4!>~wP<OqCy$$>3-V9ҸĻq\+/ݸPyBy |^yK&Eʴ<yR/pG)7KxMFruu 2ZFnvy7 ߾?'CFZeÓJ7AX Lf1[cuhCb -6kk2Gaȴv6GNIȒw0%X-~tGze*V[ l;[L}"Wu@#7IpW;ϭKݏ'`i܊v 9cAq M +/e(צv֑ǔ=-Zuu/r)O=]8^xrmK1ȓ|0`Egx v_</) n"O+xq)!!/:,Ts4פfO&0a!ޮe*EQj}ҙ6Vm n"66Q%2kČy/4NH͓-|_Fݤ9=~"\YadhnhMgęYgM* RQ|_mЎKǜ2O凿97u0Q>߰~Жf+dt ؒ˃o`{yLu(Gݞjፌ@MVwsT@N 6Jvx Ph飙uQ)<僜WWG;o۰ RXF%.І%eÍ 3q\g::?B#Lh =7yN2 wИ;U}(J~>F|Q>:Zfcq^>-g)9_ϡbG||+_"}{L-nm.ёntUV‹{EE2!Iy||Ҵpytu_Wc|^y~y&Bc+WeˣnY"\oeyj(Oh^Wy7eH?#3Yb1#V(zcflXe➶id<2}>CHcnNC|2FMH0QOtt4 0`l"m.,*٦i/[[ilW ~neH 8x׍%>wP!#| w=Xk5~s}5!hg]42CڻW۶2M9)18dZVIQd&CY7뀜)3dteGMpjh2"~yvΙkoud<ʄq*>!: Os#F)";TʋWˣQy|ڸ|vcR^FrC29Dz\Z/q/||goLgqhǵǧ#$[@`^X# &oBh*iʻ:.CMc*aG8XU>H>~R6ZR!ϠGkcPurC %P#a6XPEٕ,ph<$H7Փe>ʦC"3 kWԳY mOͦ~*#Y BC(6mI vIέ.[`+C_wnwm&!7vx~ y  l{ Ur:~yL^ w~e3zd 0`6}&ȓ}λn\z5|G#J?|g{ϕo}[~ʿҥ/R2㓒_k#i'1*y 0bXCZ'!<:ߨ 㡇_3B$o$o]ݮ fED3࿡>A"_huNu2YIt=g=t>WD9-0BWPF?ds ϯ[L?% A2ng H]x x=f Gќ3 /S8gHp$8DO~n0E @XkޔEl^V\w@^ߣ& ڌ!R6#?VӶn$NՇ@FAuĠϩУ?ckw8cN=V̄V)Ejf(mM Bgm\i|aRHP;rx=m&FN=CG O:Bݔ@i~7nʰl+7l.q i ƺCnf&m"w`Xܱ%Wro>*rW1F٪|;xd9W䃟5X>9\xt q E\u6u!K܇!}ip>n"dUʳ<7i\.+Ǥ|WJ)^ZW. qqU۷ #p橽6W] l[O8٬7E,O(ΐ&B̩#a2;6AZN'f'-D)X~B5"u2UD֯td2j o 1֫vƄ}Ðt>Z'L=ףVxgBCqڴ;x(~p5Its!Cץ(Iqd|jen ph|KY[q/QY_}RBѝQ疮Nak޺TB!<́X@4}uCxfiD9o6"n:ڙ 6M}ȹ1ܡiQ va/׶EH["9xm.} >h>pIrey%FTV#u~%̗n2z󑲰}\&aU} HWz.N}[;?^·|m?؀28G O^swMx饗ŋ?__._k|??V{W;i?T_^{=nOOw$W 7p3Е+Wʅ tWn2<.8ɦ'~UB)=gܮ'@Xw4O俉)9Gǝ0~Gg,y@ ߱i+']FYյ+!Co mbAS/+:iC-yZQI[C_u[s(_!mIDfѼ\)_?=ϔGeLw^,gVNqls^oC__RhtoElt {*|o,5^͹X֦#rm*E>2~i,//˫{ryP\) @+Fz*9>Kp.LJXJasʋq;tUnAOZ&,D/Q+mXG]8.xE_c2˧>T --V ͆![?V!G:#/ΐK37'Yʋ>ک6{@o eiGAHyCC q!U)MdVzSxC F?f_6 '\HiH~H23_#{=n"sh2Pq10ZR1ܸI6v!YƟ)A0E{8Ae7p˸m8^J3qD*zQ;H6-7mpAېPHk7{> 97MtXh9.V)_w֭e|4+{pk֊ ePAStÎAQ΀NG"fk\WC2iaF= ֗6 0`8xqڷ/P~+y+}Wx?pSO?gLɟI?aw=[،y"7o'qm} t̷m߉ p<21Wۀms:o:oӡ k*#r:lj1m Tm@'i\Os=. Č* '= @SGҮe W /P # h0WH-GeT_Sb'x}kݖ\jkzgwݰilmy0ҁ 4 De lw{0ʦsC@[j*sTM"p#rpPwYG rG|>in:X,ug[G%2??Z1-K|E//sp%.E<٢ܩ G.Kȸ2YQ;jsPz 克{़ti\^2.^WH>|wP i7$&$BZHg=VGCV*ƃO1D! wBf&9܈"[ї;1P?v-뺈sx(IO(׍f$/H-+iVm|GC[;޽\YrZŤs>X'[ rك=rǧKC/F(7E=>lh6n2׾dT@!|L ;n{<Ǩ\eƅUyҗehTI0x5Л6b=!b}2a;x`ǏgcW0-2NCܨ }z{Qwi"PHVTò7&Y85N2MJ;O$bt*{(8Eig߼ m-:s6,ϥ sQ2` z"{:/_tsܟ؀.~+xj?WYƍz|>slҀ)ߦϡL= xW~!ѓI龆ntoE_.NE].[[p^xhq:K˃gt.?*S##'_B~]}!HwaYouzn/ ѕU8]kUyj)O]DO]Xg`yNOs*(avFM3 lL!Fâ *ěL:MQ`ءm*ho AbsH/6q@2ɹ!:q1nthծ>#AQCz_}D[7wLsXqfֱsiⶪ/ yZm-㤏Js,4 b:Z=PPZ4A]@|-:&Ȅf@wċLW[,\6^'ߖg?n( mQ_UvQmϰ qj R[ SdMlƩ Dyivx7STrb(K}40[wP]i|ҷ4Q7zpd "6T?8j| i{|0X,5SU#IQ|޲}~ {CǏ&ݹi`>|PDYEى;z4)fKn`|U昗1'G2/lyD"<@`*8~z Dž6dLl5՝6evJCЎQDz 'ڜ/ !la.†rg9)_Gsr6*O~%~!~`Un,˗E޼BHv9ZFނ (|xbW3\g}c$lXm޷9-eD92Ky}Nw " !.uٝZ_Y@T2/Cgu'R8i#lW2LRrW\iu\y"s38h/D݄zEK47!5ǧ< * [[oM[Ahz&8P!_9cyCSi ˡf LW )ZE_#L(ˏLPY״=;P ~38OHB^*ɇuK=ok0EO:\͈k&D!КD"vَeLk>M}M=@kyr 0!"y:Ї?'F}r-|u'l} Gp~ho xIDJG'#ͅ^P簖뱋8yZBwm|2-89yAUgo_錴d;`MkC9t-fml_B!,oC\LmTD2L pL0К"s>&mKe*:%ck PMgOφG.j_XZ`AڭDW:Pfw@Զ`' a;ԎS,h:L½scD[i>wВ7ݢDa"۟5{ly .KOG$Ox4yRO w|%/(Gqx.)m.|cں@dz8A=[Om|u4KΏxbG<"CF4iCIZ.ۂ| 0`Ca۝?k駟&79?c 8Ggߡ܈_`ʠ<8߭$=*TMm܂Y1{#>7Zr0ͯ S Z7=:y v.J|_[#^Oc?"8"9? WV?.,6LO7$[ z0v!ڳq,  ϙQ}`L`L0qKy٬\ ĠǕ"c0Ѓ]ʨɑ̣5z0 atmdc6fڰDlDMcCDϼ u5F;Ⱦ&h27KCPBI@9 kb 1Ʌ6p@\2ޏzcp9*^.3j{!&,`&qd-UQvO sD4k#)yxm.\xm%Sfvi(BW-dL(yvR%+VUsPulYQdAȸLxJی0622mVYN`w8~SUѿJ¡:Fqt*y5C9;8lS.P2C=~o_q{{pȻxL]Ý99*_`WnaЦݝAwWM˭IOa{snX8Fq4󖓇s,g똮=Hs<@*6ZgN4 9o.sB6ut& C0T- ̋ق?pW}@}d. aMB@My~kwM53 0>x) !~G| 0Uvb>Kn-Php䚣7[iZnMYj_ԸCN_fGJ =P^(}QPrv:}Nު|`?A㴁x-E}vדuttL)% $>؁xDW;ޠ-ЂgyD`',7` sX}'^{;S~W%_MlyƮsm{oi DPg!U]&Ty: ݽxrrǭ>fXlz>YU6!%4%F[ h#GWQt|*A7q2˧yqeZ2P> Vу^]C ۦ>tmG6#6et*IYc4Myq(1#cD+(w7y?G@aew (wv7}q LxA Om`I*sV[ ɟN ',= SAwN"J~?)𿏹AntA{wgX[Cg[h0𷆰jH;V5bs7e{d:F|ĎȾGܓ65X%LG-PTI[ɪH96؎lWS54aǜMiէ<y`N2U' X4@M0Еo#x][d^60"vcff|m@x2"< 㦍{G\97~F^6t|.Kyd$7fp@S^ylm0LgKƐMq3í?>xUmIN!hJX'\/Zi^ h\_m:D|( >uJ@X?ⷔƓ(5E:yp@06 mk͢ P'c^:8*6>]Ϙm6綟mZ溘wL^r~nӀ 0`7|J_."a8|0aN Q#f #Ny猼 d<ːXGs\y:0:7waĿrоnSXӂUl.tK6ancLc͑ +'6MMz@{  8v*ŋhA>F![GZʜ#yZ?xl͈i55aźe+U7g>/ًPfxƒh_ 2Z9<ꈲ| HkPl c9lmң]a %Rw"֡;F0|r 4Ҩi`Al0*B3"3]c;ǔQj⛘l&WR6<6oѯTu^hͣѬeM"Gb]V5N8_+c~` 9/=,д|xJsowM*; >x Qo:x#pKdⅤE21w `/29kaö2}2,ߴmBSR6ɸmp,v7ӂ.;4۴LglavpZhL 1ny}cNH)O6Cm Y_R])wO { ; ^ vMZY oqڐe!dh ][(d8fZцƸ6}#=0tȨĮ2i] U>M5TKzChbmlە "Iƻndm5}i,?#.8=]]Hs?YqzY#6oXH9>kd Z<qO4@>:O }g;ńD 4_1Жhli,c*NqpB>>x̌nf|N͆]tUP<m$m%x]ـ 0`ٿ|=oVG~GOO)>0ჿwI״7>̭ύm&U3>v: hgt }+9GAbFJk], xZ`7 cǧ@6X0I'h'*nCY`n<w5"q<kG-)([w4μ \2 xXgk"lKs}mЉ L3v0{xc:j6{U#8˳a 1}Un:ƕ+9F5 2xF#*"dץIrv'3g'c $G$&#?cC#E9 kmAvx BM!5@Z#WKkCqgcH/0Nk=GfҮ,~1q"x#8o]yWGO`mQg Dq>wM`wDN|;%Cy7یV$C;XI1菦WPN$"!l7a[w!nڕh|r:mDayD}-[Pv |r 0'|G+ 0|0,^Bee1ϓ ;}rO2GW}RC̰K-$r| ?Zec'al'?g;w14O^m ܖ P1d~ml%nCPԣux!IBCC1/ul7cMb\+XB"9/`孞@W0' ,^tu6Pny׭!Im4NbK+R myZ2yڑ\ Cw$WhG sǝ9JB K7ӵ;.wvh"<(](m33Px]c]#ƘuƛY/V<1&L:Վ>cr`tth>*ن<%XG8;Y3\`gD[,8yZZD_.{=Fc)Ҟ22)5 N/vGGu.)Y{1A~u}".CQT;ĴE2*I?ې7z~$Yv/)MjCiާ`4>q10` '|R.0`<f v7##7%,͈UOffTz* x/:y!41 dE"wu Q <Gd!|d_`>U(9<QyQ9@;Ѥ٬3T&S$}`~\ilf"3 l5%|Rkq\x#i7bn1m|vXG0e9lUK҉X`9cYRS?q7rtRE!k9,&D呿( B'Stm# F iawBXXXv&htZ9-J29AQ7Cڋ&5~:;NԵn4"_>| 'TM>eu3gkdbEO|,/|k>_Bq,XG?!7\as6!zPerNӢ$QN>B!?eDlGSAuB>v *BOeeFG@Ym!r3T3qOF"f䆧j^j,ciׅڊ3[!o#x L㦻l_'6@w;k#pu\"7  #<X߸ia t@-)0Nh}%T{MLq91$j_~ 33 V8t>u-YmdׁdBv9l:sqFXCFH/3de(،7҅\wPŸ,Kxۘֆ^d׀~R_/Խ uxJc;@o%]3l3̈́tydWs}AFŁΊ[}Q, =>9N6\uG/=Pd?OӖ0` GG=5`3[Xj$IĐdW\7\獝l'~ n^}} BnG@O4" { 遀Gc scjuB_{b 5̷1/# 7fM~L{EI1yL%vP$ku>﶑;%!oHT[=m:v0YW-D@X+ڝXGv*s ^#E.G.oɻ:av[FL]N2D_zي&UF=Jjjg!@̌i#JW}k LB,x9AFRxfht=O9[a\7]̳,ɼE[}haIܮqU9HI:u$'U!luAQPnZl`B5,L[~.h_y2/&dx/ʥe: B]Hb%s6YRj63M$Ѫ?2"S> |Qy)#3$" P[n0禭k(}\n1}fc|0f]-zwHs f~SƵ!uBnqr݆xGoS'`hu0ΓWVkU3qVkE( 8Äxx̲4@d3)O' yלO>AvZtPьs>b<+0` 0`N d^ qibU;7nAvs1.P=j$%,9l(љpbOuFٞՎ.v bqXM*y1Hx)Aq7v@o 1yT~3D^ص%1 Xr!]ѸۂE[b/avkRUk ]㭛?]D#O6! L"Ƿ>c[^!4"!tڃwzặq tP:,{񿓷)?3w}n+םC"μ["uڲ&78w mv(YNcG XntDe_3!,NQ)&SxU'W lSHm~`WKcw2\Gu7uǼDs肥 rFb{(Z/y$>t=1pf&LPuqi4A4:zo@ԗKKj?bc*lx; mɎ"hguNnJS=YSึ:'&l)nAUPv6<kL{Feh;8 g)An$c(\0|Iģ.M8Pv 8pqs=hZj䚚W`lz]v8miA`,AQWNs>å Iw#0d+9iða+^gp0H;Tu@`ܢkAqB$%Lq +fEBmcmܣOv,0tm _7"ҧmP O> 0` pX'>ߘ>oF?} rYVd_u{S o7>D | ?uu28s?vgAgM]gEvCu?O494oW'fRo-&(mbj`!M%:]|Ɛ{[=-*D# ؃(\$Bd.uƁ2!WL?aYwL]%zԫKq5N?-+J~VW }U?35ݎ -VnCd3 6-?z;խoq;A:rP}@o}Qq'u 0` 0`#o^,~; S\Ŧߵ(&w xsS} !慝lP8n.cyPm$|YoKnxRx9/bU)2|( p !c4je2PaxA]1.c;e%}mD]wH\Ǘ~>juV," St> 389vc615~#YL0` 0`^]P.F<ߺ Fuk}e#_+$C$_"֠N?y'fe,0idIzLӓ|3Xw[:*q؄8XhMnM䬈{}-*@4[l"Zi gx؜b5_FS6l0#2"ʻN*- Cnmg!:bۊ)/o2Leds\ATi;}@̭`6Y%5CiDLJ'v9˲-Yǁлtq,1^zPF)?>>e:hyppA [A zl=e[#Q&nG=֓ek[MNzy%uׇNRH&riwf5/gz뚢 Y7Ipr"Ѩ!AQcMC _uLw\.{)New\T/2VdƮ>D"f-ey ce7ȠG^}~ ?h<a}0V~ 0` 8߾.;ؖGōFԓ: 6fzh u; 9 㞦<'3Pǎ"u@]_BG]Xc<ؐnyG/lq1ntV^"թN# QO-(?Xta>02sH Tƌ;tA41/&AS(;뫹JnEpheЯipZZA(brTC!/@;SԁW_AjHߖBG x5my7e-狜9H̝@Y5) q"!ۜ(qU`2]Cr'2^#t+bYƹFu*#t=*&Y&:=`JRj7؀Ne{|0m3h@m,g6!g.uCۖ Kd4dd96'v YwX4(7XmÒ܌!1ph|;2[v#@KNj. t~bA݅oK wsgtܽ;rzm~͈Ů^0CJ7'tUYD9EdcvO5Ϡ]'m_yCߺc҇MrY 0` p{064$K|"Pd~?i]c(Z+,ym` Z+:*Ao}[i=<Zg\|vKsdiIOgf/.LW%GT 'cpZ,0gfyY.x|rs]5)d"lehd!Z tFD0|NU dF)LD6/9ur27]4OӖ(Gd{(%U7 1ɏ8^Jm8`qۜ1X.+M]~jG"m/ی򵂽֒HetΜT7dmJ Y&|JDUTՕim76uQFdB1{ѬjԫP6ִd|L~Ɔ1ҴnB }ouiе*S7ГfOۻ<+Kt'CȍZelzl@$CKM6{P_$h ]_u 0` 0`,7Nx  ͔.e[NH;;bIDATZ`|F['yqCO_t(`B 7tIFA >Fcݐǭ~FSaHڢPx`4e]<^uDOIHf'Շ蛾j{ >Rkg:$lmxD'գZn#Xh#-?ݎ|+xqP{re gm2]dM6zDލ[h}ix ֭}H}E,qjY|Ev\Pnt\%P9-X'8g͝Ӡu̟վ/ۉ4P"Q41'A /cavSak˥M< ~cD~i&ttfD6#b~YHrĹM!~9s%\@ߗ [}.tۖ#r ZFV: 0` 0`G ]i{"_╢_gόI[;Y=OJ'@gyGoWtWx?vb>.+vszukš; . cSϱƂ) d:!ؔBө/#M fXy:w)^a"t:.#CD X'yt$Mfmd"\d5N5C:nmc6^MOӔbџ 1'2 Ǚ=ew n`8׻ ;B vvM'9OwX:f&j2+ U~t _U#Ԧfcpq# چؠҩa}@A!5 x'DoZUWAyN,'K&O> >A=x@oÎ)k 8M ^ߴEjo˗Si͠:i'B;Cl3ʝ<&G {>-6+e{F;5` 0`<] -:7cg.uݢ0mzy&NF:tuܿNz>qۧ g `;[W+tT" cmE.{;0;*;<(t CwRln'(s2;D88Z:ZCկ)VGm]A0[뼐fC/cuas|;kb^;H]˶Gmc{D-ǸFn6C"1d$EFȮBVAodKe„ I^1)^ҦX$=1 !;'u}ED_;O E*3m1减[IL_:ټX)e'v(͉HFWƸ˂B#Mx6Ytǹ軮qHJÑi]ѵC|`CwK݁)2Îc r;&uˆ%!|h AbY˞f9B±cKNoOcϊjǍE{Qe;rվc܂a'їGbaHm~HhVdU70w:Q?ZOVrm 岏;/V^џ:vC<,s}!+'=)g>w80` 0`'lO^7Vo87$JcT>i03^2I鳱 =u>sanW;2 rV@7 ԾqNu3lM{@; Cω 2>3B ! ԡs|<k[J_sOvn|lMl,s\]CԦQX E! \QN$R5ׇ6 @ʠ4Wrë '|xQF4:AAI0cBȾz =66f @#ހ]04e}ַYNu&f2% )"W=u-/K5mXhcBG6ԡQuf8+o !p{ [t@]OwB8FXqȎ1.Ӝ4np=+,0f턞t;tiˌf+مvs։A+Wjv߫zW$od/iƽ 4ǹ9t)+gn&dUS2׫; Ml#Ghc/8,eO$uZItv=HSWfwGb&po"K+MZenG֭7#Amr'`A/}]aǾ'sĺ]?τlD^1 mۉqڇQ׶:bו(!cG}I 0` 0`cQ{Ӈ_)sF=:ϲҹ4"G vv}2I^6lv]_ Y;k$P9l3Њ9L;ǓE8+;gc&dNg\Vޮ?JG=׋|ΐ]oy/\!yـ5d$JzQ HkME2Z'I ]u]ʓ{vE܄C뇃%rوW[,gmC}>y? YaR"A B-XH"! C%$釒Q55s͵s{ys9c1Z{vt֘k\ƺBh:ȫ|aMgO[a0gnF!+VB֏N(yi YK?vtŰYa_YNA_C1˙z*)f4A<Qd#q nr'PE׋b7Џntv Fw;===x/КCLfK/БZvP5eon2:{OԈVF7J@V`(`D02a:j$-P4Jn&) f^rcLȡ/n{gi yտ'pE{@Hxe( >#`y郏|ͱ aD|mlZ 2ǀӋkz[0ϗ4[As<# +]fqGa uRz0l`/rL`M2g@A7/v4fwM$D_ȌiApQW`(ZL|B2wTM9ᖕ5yBN#hմN5 iP|8j,|g, baStApbbbbbbbbs wÏȏ~<|~,GK}}??5o6 ix՗~u*r͹&#Ψ.̃8~NH@RY4~/"ME Z !K?t4K!;k\]Y ?gAaSW..H}P)IlmǴsvqգh*xmÖuA_@a4GYh>оƾ.!=uM9?Ah㺂l5r|BD0lm,%ZshژP;0bi \oR"[# k-~1PQ+UR˦-fSȹhsl}Ϳ7Q^&&&&^:Am,ǼH~ Jx B9ULo1h确ṠS.s8p .pbvCvָ8ěA{So ,巊hc{Es|xSFuC Dʲqbp{<pZ]ma:G5laڥMn˺.^490ACP>33,W:`ބMY21dmy^d HllT8V}rnIB/MXP*k&)/ܸr*5xQ؁lpƻw0~lb@cWn۰q6lUFBY4BKB>9k,C>1W9[8{t5'DdP{_(=~/Fibbbmcwcc,p=Xts*8u")_kq)Q(@WIk㜎1Uvmհv3$nmJx#Fؒ.7+e_. x'p5MW1j߼F@id#}n;$g*%v=ɶO7 *m}.; YbE=`93^)'C VR qoer$7>Z9.uϳ7k)U!'1ȸVCyl")k.>+Q)(eeY \'+~XHQ&m;J\VB0Е.XyyѦoey oHP+@mJm.+#`;ЮeVw} 9rV/9首,`l (r mE PBcY?Km>vgdqMv2lK5n[2zԛse) _y4㪲SHWjNħبTM"{^ Ȧd)jW ϛٞ [11ȼ@S_u Vݍ}o| oW`2uj',l֡3-śinP>%>ƈ],RmH۱Ve|Maʸ,&j"֍-'J3ʸ#O X2=h\4F 4H/lۮ^ER 3ԁ??0 {/&Y0@1н;\u!yFno>aH;|ot*:611111111/|/(]?!kDZr'? 陑d<Fpo6 zRV]ؿT&BgD'zOe?B;Ȇ:aU潳Xꇨ6B;I2#duYsqN+6RfS[F/_aSC{8wGY{Ul6{Z=,u$k Ҁ֌{5@ؠʵQ[43k :fIc V+ >n2qڞckq8G}ssg۟L@{;S:~y^A7Btٗ۾֪nY#9ctaO?J FxZ޼QI/b?J\j[{:t 1 J-gJEwWݖ1BNq3F({PXͺ=5g 9ކ{s >NLo>efjF$0XWq qSc݃d5L.AÂك nLƐ/&g_@Ǎg,<2GD;Fk^ϔ'zb`| 1mT]4.>$3.""Nɐ}Ix/b\l!%܈ح~1ךsbqPa|ZlE]QryG}bSkaburFyRu$CWiɟO k `x|` ^;.cx1,aS#;csDgeuZd44x+|w~g䮏?|ɗ|I&&&&'@gǮv)cGǺ=V{zz:^ft:]T)P Af'18 5>^̲?k>xS pwh3 ]v}\9Wh g)/= cksè:퍄]`j*{AT02ϟ:OۈG~,H=8ci"ujEc9d[oR8@%)uX1L9A[T=ms<h-pPu#M&k˛bq?"~̗k;-0E;SwQ?^jbTh- m۱i@O:Y/)`ӑc F@؈z' h=ތ#Hu|ErO, Spe Ȭ? >My=>FFІ4/})ۯ2"ʉzyI KNn՟QWr(ۂ%q*Ҁ1!H0ܖ Ci?F5q d>0*`g5_S_7S!{#>[t}:Jo88$Vo'x;'Ѵ'Se|uwĩRg jq*?p t;~ma0CC5NMa˘~@"RLOe!`@|c7vi !MrĤ(AxO\7:}5~䳮q &.xl1(;QĽ@29LP(h~>@Uv^06YfC7< 7Em(_i>hql~|xj0Gr׽X!y zf>m~Dcc{!ʺ3zy.7 %Aj89WA-y #~VLW}.Dl3[ր1vqc4l}O_Ee`J8NO{Iio=NU@5jkmZԇzbbbbbbbbԟ?WW;V?c6*`ghJf=i|0x"霓o//*"!q {.ʺxk戯neз+Fjo_U$<.O 6IgvmQ0#; pJ%F Ɗ|GK }N)a)sIᝫX4 ߠZdV׾qJw+֋`=q"La$ :.ⵀo5qj;Ӏ[ݏ:,xD؛hjXN._;7aK̉Y\b-D<`a L>/[M,ǠO>{r)qaD{[ 23F2]l24uXZڸM@/ΕdH,=2j`M5ސǾ~s kh-Y\6{~3(WW~WFU_Ux]8EGz8L2"o`o ~2!;?K3Q7lf ْLFs ĉՁ?9&gT 2~\8EEnFgϸlg")^ 5fM0~Oќ>ŠrvryٷIef rQY~&.I)K=0"z go-2( ~\zؕ?On0 #~ V @?K/}_Ux "6yιU [Kl)%#69Rn/a͹^j&z"~EaЇ`n#jk{aCq2&_D㒨#lpQl?Rn[ ‡#J)-]k _&;Ly7h3q8w I&갸scۗkN܅%JgD{s`cqpW8aٜxU|}Q^ԧ"7111JHǚacX޼a96FnKvtls#z4NCj!4=ur]4[2 L}6.3P_8oxa/uoo|'XA1Asd~yOY$uFq # 8{kΝ߹ƺ3?羹<>H1T@}7ʶ[nlgD\؄#PG #>>{ ?g=ɶiU\-I[qV fd8@}6lA=7ق쀍bnxe,&)xʈ?'ddwLf\ `[<_;סycol`|@l)&* TYYۤǐ1 %Go!4!36kPZ=H|%>5ݎKMR 2^9SJX;,@% ]O' '< ,e.qd:ymBĕh\`ޚ[lWw)lu 1ĺؘ qɿƟ:g/[_ ]kxpt]$ `,D[~s M]~ ۅq6%`O_Gz#ʇ:'"u}H"{ z}jpU+x? n'' @U"v{̋1%ڛ:Hz(vf}#.A`o&ni Km쭘FDH Up?nFmVF ;]d. VY(w\hz 2 Udj_W7؅F#ELh_~FzՉ#P.jF([K›o Y|.g`z)` .Ի-L|}Gw;hC1 igyߌb~*[2as\Rvyi:vJTYQȪ'ݤ[b\B_Y޿]uZd #;ݧ⃈7J w="džYlCw.5et\e7aYzG<茇dR Ea ielV(C1\߲vcA.My М}@Q;9s%ݾ ;θ*v}`0tq7v*>{ֽeayЇչ=#==11111111_MLLL| Ft&GzlWQ6 ȣNG퍮!޵8F;oh6t ݏblcv0Ă@\Bm=cq62cR*#Ÿ$p|2IEZ2W=B=G6(I1Dj/Wb͚;yϖ,훹仡qPa)0K]cp8H~8r|8js$d}ĭmbeeIʯ1v!A\xmg?Lۻ`5[a @=i U[sQ0y zae HVٗXJsL.W]ivGPG>~TZ|7h r#U/7A ^FTOH''g6u0mYR.O#]. }y 9fۃ 7&.>JFO&5uuR,m `)<͇.]_}W2cۚm(HpzVPgFyiaےL׮XF*Ҧenc4ۭb4΄qyjmX/M9o4Ndߝ'"+:Kfg &WHcl#,i7:KgPRZh?!>_G:xcuA I@Fw?r֭3><-R\u {&^_bj?_=`,*OXcͳؗW0׋,Ng6mT,mɶf{>;11111111q5OT^??<<Rk_==:-=LgE|b J.cQB;+#$QaT656W/v,EZ(9P%AxM_# E551h?m 9PsfHO]k8h_k}N~oesY@{ٰ?Yǜ۴ڑ 'E S.25#"}c-"Qq=n$"?A,XsdN &^`6'i {G/.4Wõ|F܊q #a>4\:Vx.vlPO}g&ndoz$wR(}0 ^鳝6;='- nFӚ~ꅑB PN ^ ?o He >4=m1u|7X bPXqCD1d.In۱bRS#U#JGbWѷVon'ɠ a3n5F1|,)Ijs,#î:S`P}<2/i* \Tht^k[@/-~ X% s{T2n)5˥}$<_98{@O p_>ˇY6VX az~~5XJ#(^_oO| 8^SJm6ulEc뒞?u}\F5汹@8q&,lY~E}X=\d#f$շ؊A\n6hwӰc=Qr^G}K\S3o:7q[~m*18 GS`[XP+2.3pE47pjC|6}e|F\9Ɨ?0 WLTC_+ݗ/kabbbbbbbbb7{9#71116$VWyyC4Q݆ $v[ ng~f58~f"k:{}+g/Z `GME02ߋ01q&tGs MC6Լ~S>IO'aMu-ǵQkaIye`2Wlk&22<4h06"-.-ˣpEd߻}YL|Jg?:4^b}Y\4@9ʯ&nLŨRQY\Zd)6b*76&aWW}Ï؏E_?g,Jh_UW cǸ@7ٟQ_;Ė>(f^lX>@6cFv: MtٛU죈:mxu `F/ęvkFK45^ ]iʺjos/Z]fXzr,!zoʆ|n H),dP!π ^ h"NtF6p!CcZq]mqS F HE.yh(v۠.#w^+evA?2g Q+gݎu$luqcM' e/ wI͕C 4yq7W?usG_Y]%%ҿ|129HD5@ VƭnzpL|棧s6`_ߢ\mhq4vd@+r>==˺7Faώd^ʽ\#/&`<)S+c-Y6)v%7D٩h7^mGZ䮏WW4111;l('8Ǯ=` dm#XP} I.H(G3AybɪR0eFl|M! b.Nǻz01ț~"ö:Uou?)[Sױoݪnhm)o2p?^uԈtk䈰ۨFuK?<q] tM6f#I{_nsȯ3fD,~zaM 2t}l}o@Xnf֚ڃ,;82t%+>kڢm."τĤӓbT P۳䎭m}uD;bFm#ȶ 8HXӯ[uwq={ =k$A->HnE^;''Pqr+aEBm/4T?%l.>p~XkFV1_Kc#PM'RZbT|d3R|P.:ŇWDϑ? ,:??ggmqtxuX"09A`)I>SMй8)-2/:*m(+@{.ܐ"2qE),O8m*1fLĢ/2nGnmeoqy6Ǐ~Ȕ7\u#zBWZhSOzR?yo8?#KOT{eGO]C/h2O s뮛 | ݴNX*lnߛNoWE!˜Qaq3ڡcyoG^?*6:>b}@f=3-jaK4w+=ý_ !=]JWC?&po:^> q}y.P_""Ŷ/M~&ξC:lS`?BWyzj_g/YO(6:>x6ZcX-;c;C2:Ɖ7KKQx]o'IyR;';xzQg|7c:FѶһoc-sgdoq_;ئ=7(¶ ҭe(?m[Ǎ!ԡ?wGޙwEvw|geklz7>Z^}W_k tPgf@߹Gl53}ms_s !3>p-:ˈ1g$1΄m#د[4Mq6qc:M0ΌǸ Hx`/AY󃶦OƝ&@{Cwp vv.Vê[]Ԗzc~4 ]tw\,֤Gly}߫HѠ=; _+i"+59[\X"o}Vl5kVű7b%5 ese;'c,Ѿ>~>``djĻ{=b74x}cl+4M҃m|4+%c=VV;ɕ,n·>Q{JR+XZӖkkA;jƄサfb}A;;+Cu0^4ӂ/i fCylu17Yq (@#֒ѯ~8邨vt؎"w~+"`&d#+A11eLs VXB~8A k ;j䝵>(h|_1F>[aͻO/"9Qdg}#)I ڊ+B!^ t3h.%G:R>*F6,@ɇk_U_uC<|7}'~'4111 10O1ny2|)݂썸ԫ',"vy8향{[8 C x1,KqbX rl= Xxy㹅vB8fRM q,JӅN\t{wy~aXJ64[{sW/Hvp7 Cl'P"UzYȮkH K}m?8ؾ/ALz{( c׃0# ֬tA߈$U{^pM/ZH1x.mnԠy,nr ж3%&he|ޢ)->(K<Rߖ~dFP r1/v_V[".|;^jH /QLfNaaP:2z{=6 J&WwĈ .ҵxQ8H0YCԛ ٬P*zzNQtUĎ/1ʑ y39l8uO^ ZX:&1C-?L\[fz&f wMLI 9;IHGF+dgFk} /T]F6OMTBe0?$S>-,&P_sоŝh( O S\7)i/֜FsM0h@9!b`z17Elo H:^H#(Ԕb}ǡc07r?PlސS/jYG:1"nbmm([7 .\fr74NcbOg1.y)nF9Dῑ=pnZ @6 l*~ĦdN (=G7mƺI!|XqoWm^ #!-}͕z1tN9^׶?11111111v_}]]̟/wyLLLL|s:~Q-(qwiwA~zׇhΥĪh9NB ']="|hsI-1(*Č ?k:36zxMy7Gp_Ǻ!x.lLj7y|,t%7{Xۀ] @5}< b] #{y|kNp;b\GN/@rsIBh2*Vۺ@蜌Gq թٚ)׵xdیkyzf!BP,UR"baoڌ|d2!T4 Ȭnk"v4nNiF׹]:bK>-qNb'Я9٣=<]/g<0tq[a`wo>V[ƴ&%y-,d:$)}'"}à/@b$ l!Hz}LLLLLLLLL\qo(m'#oo8B:111 c݌K{FZ;Ƃ3<:@ǽq ]K @6׸ (G3*'#>1<%з&c@$xźv o>&#![\?{uSͷY_mr!,H/<ۣ/Ȣ2Yfȓ'Gl/k[1).&[!.li`;RJA-VS8U%xǂ(S3ds?n`M ≺\0?{QխaBÚ~Uld;*zh ty+v:o@/]@uslFnQ oԀu,F+(>`i5 nJ[کaiO5YZw)j#(Nq }}c_s ?.n}X8¦r! Jos<,PĪx#_~'g+]K}nwn6RĪZQyS<5U& NmXؙ*'f_s|̛PztXƲiEP,5r߆tbbbbbbbb-G[__3(www~)o 9.cYӂczn=Ϭk@[1PEX gOJ~uKmhpitR<|- 쫟6E 3C>ydx{&Kg xq`ݫek5X@LktI,7?{73ɭ }nñw4[\AM|+4,b"}i:}x52ЭEjYS$މQ x `|;v$%y" )sea)#zTLk<oFyEb2$݈kF0u|}*z?91},9{k>mjV˦;7>+Gơ4l-–|F}.+h è:zWEonN7Eű 9cC/ǡ1r VayډQe[C7vȇ-$>4ݩpǀͧ7p9u2peOC?@7zbb\B?vy,4^3ȕu[fHkbF,iK}GfL csKـuJK_@6}1J~ǰ/>З'&&&&&&&&^__}w~w>??ݻß;||OH'&&&sH [Pp>O:f;+*%G^ {5vbLS\SlCgςtN4V Gik>Q-X/UV_'#ޓ \B]Íx[}}yXEf?Ў[{@~N\l?d<M ȋ5ܾ;yye5rpEm6LFD#W95͛?ռ\VдC֌MWg7.gT:JOec9tq@G޴z2~0.X&YĆ|0mYE=G|GH(ވa 4XBō.Ip# 6)|S&P IXCé&hh.i.k[I\Vc/0"A{+J@ycѲn$"oԑ %n0/gl`b4{ X1dj+d8o#P?:|FQ^^(w3 X/G{8¢>uQ7S dIЀk|UfeZٗ{F}_D] &IST]Qk*]}(?X#1M ?֘Ok_kؽV{t_rīw苾($[[KKC2111F pj-t(@122km8tїz؉2乽l]:6h:P%G`C`Y 'eԑhķ~ =-;A~q1?8v累 wр6|hD-uCnhY؄>Ī(B3!4_$  8 LGo by (>zn~"|byٓv5>3OmE^Co6ŸSo&ȹ X[TQRs M>] Ԧ2IeNa't`hƮP7Ymx1֚/i= dU{y%`9)>PJ96w,T(x!x'n8Z]3y@۞&N}{ޯ.> Y:їU~`@̼o|gxr:>&mG *;4/,jY(ޑWY?2;x[{[V%>Xe+cT&**^/;idՇX$faGA4q {uERZ!&|=Ie\^ceyA&4- -DIa+ST,.묕>z؟&h9ON/mT\.7 Χ@(ohr,7g`#O{+1u'R&< 8Nq]7xX~ĺ@m#uERW.Qf:?=_h\sGj稼lgbbbbbbbb??t}iUOǪ~|LY7mqu BޭM8e4n?H ۜفE7ON0p?}&7؞} ٴvk6g[ =B`M#2qYukys8}g>@4Oqٶ  % /u#/,\X\s0| 9LUQWS0) j6^}FBEI1e%eu!oS"/&_iAjSJWA)i8%~EBR;['dDCKRQʇ^50,[H#繀mskW+kAJV CZL*iYoQo!~ z܌鬹;slϰF Zl6,[ܟ~(MLLL-3ȔtEw0k,MllnYK9s?+׸`r2p"~a&[)Gk}d2lTȿ088ܱ[D}tcw=-}~Om(bA7vW<&kyasP3{6mVh2IъЩNU(<~''&&&>s)8~߾C,MLπ] `<*(~B׈d`\Kw)O* ;3ĉN`; :mL/=@+UԾ olTEop;Q|!t o 7|2[TIibm؇Y#aV)/muLE[πtG_%,xW!186[v =b&b^& d"<G\Z\G"XqQY!yK_hH;/4a z˰1/ȡY. mM ]k~ʏ~V_ D+Tf۲o uQfGƨ͚\>kqJe!^<$/v&؃&L|GB_ o4N9*[G])6_gl8T=Ta[B?},gLx o#:/GibbbDGDZ\cEb:ʂمxꎯzV\ύ"䱄0KPS{_1PᅙFSV> QcVtm>M~:e ׊Np*>˩uldz"2h^= 5%fPew x݌@cx*q9QH-L̰*֏>ïȀ`@#v۾*^ ہ:|l͆2Vi/ ֧|LnY=n @)}vDb[ZY)A_G{1o.5B۬JZĵȐfJ#(Yݏey-`m 0感Zp.P|d=fψdRv!,D0A&|YxX^m{#!zrśyon zUwa&oYƆpYA@d5Zv,r/ 7[2#o`I #@1uWLA1hB( Ȳ'k(JmI*x~a_k> f.o\ƻc$[ö#EvGwoꑂt`#sl:DLutﰈxZ DUL$nWU]@S- $ I$6pQCYCܷj|ybB y7y4cU0̕>H(vȋ`2ʼ'TaF J# }|VG@Y)h(xe@? $Eã/>|B! Ҍ'QSPg1_[(Q9oC&'®KLC<ښ p1/G?v 争Gwߍ!@GʬxSXi+Oł WZF{1 R-vjϓyI,-pnvīG~AFʉi{JT+ڀryMv9,\]5{jhdĢgIG$/2FL0視wV[һwç>)"xw8y%UF3R5mяw^u{Mзoܛ.Qئo&k[k,u?g` /*(dsu1}YdA,iԶش7 Vh-so[ƍ;nĵWP~0h&kTM{p{k,(GcϺ31C~sڐ,ƌ8m@Ӓm\{&-UZeS߄ju:3vn#BYrl.CNrYY@e.I`Cm?6d7XqBLv+3Dkš"D4}-D+r"g}My+_eaG _6ɟy?7{=<3 C`Fn 䞅OEKܷ)'#R=y58-EYv 2ѢMi-tVYC2Y>~*3Z,YqAb]mO`n,pF[r>x$" c0_9|'~idtXuv*"SeEN>mƖ` M) \r{] (vtQ|Am{-I c8k2, 0:PccRf:7ȼ}K&py %j Tg )c uPlǎURyy]vE!݄`\~Uwr5?D h Kz|ZY"Y6}ɰۇD [c!)|K7|گ(>01118-ڀH7 86Bhŕ?g;:[&*F|#ha:OG@z'լ\'B'=qul9do"t@TS^,)z$˦8/Ir:q&pj XcfU&/A!s8 wE<:(Q7\Z#Y YOO ^hyyWpC4sqFs$5[7n na׷`ǼX88Fa$@X;=%.ݙ7wxK+t7_!p16cgf591u2hVH?3XhSJ/MLLLLLLLL0k&ro1111vXСWC?koc4t%lr_u4CA; ]&E#WK ;\hXek8STxyp' ,]6I5+V9ܞpB7nǾ5OR2Mc.E$+9l> Uw<4鈼zK{S,DP>˄&>u?g})}~,\C:oD^vH>%\t.>#>^mS۵m]VF :kunqzǙl{DR[ v{Q i93+G.@&{K6J. &LMa T&(4(LYl"ڗ(1>@oeꄜv1=&>G (_>.ȅđCa9 :'V@cu# ,ɫ}HghZ ւL'OoĤY3b %šs@}@ک$[g}3Ȇl)80Kc&rG_ 0@u,oA13}@񹂅'&&&&&&&&÷~FnbbbceU\ :n39u\?q1ًfl?I@?7ȫ?٧cT7?40y1X0Z9+1] k9!=xZF$\Am }y~l@_-%ϜG Ȋ}9DφbZVԂR%{6Ez|Æa=Ap+bĖJ<+XΑݚ7^E׷:lq\bI䃺 i-}/f߆#d*tO σه5R%R~B#3cMv@uU9"Y[ܳ4M n!o٦. ?œɘo-޼>pbWim3c'X2pYa˭hOXk1ͳS5"sdr%>fVvBڦX_7(kcp9`)VF2=zωY[\Y.F>olR̘竐^aJ"?Rh~'~&O|2<\G3V} tY6@ILо6ޣI|CpJOxz>6䧌q>޽œ(.BgK$GŦ @,wcnI;w18P3aWPMJ~on A",E~\vRF]1!r?՟^x/N!Pr̬3lFF֢='l.ۂl646dL<E21_|I7"k,я frm\/3=5"eiĕ棏>:Űwn@-,-`H_,5;󻰡p_9/Omk<~.}[&9c+~u1)!8꬈]bx% "xv`s;k͆ wsPF$i$&:ᬍw ^!boepsCl.뷼mOُ@`T _Qg\pq M$yW9N">ī9MLLLLLLLL6~݇//7x/(MLLL6p,12# dkX|,MK-8cȩ47|՘jF>X:^5}^.'%v3#/7qʏpBF׭uPuij9--Xd|ƆUo,M~x~CoW!`m`2W3 ctaOHClyQm9oߙni^SNXp΢W"uȍV} ÀI%$MylzAP!U륟 OX[XkB0L_jv0نmeM>Hˎq{4-09gs-@]u%Gw?#O{7KRd`DF/Ǔh%r1Ο ab {[yG,zVxI(a 핟Uձ,F8t^Q2Gnar52|rt ,:ŧ_OG ӘNr37d +Q6#5`9lȶ8n6>z7˜rvƛQ~;s>/ SGֳQ_'n8ݺ:j~.?QM.|x.ro} m<]G͑]ǫ+#(sOu(eyܘ-R#.b@^ 9~.)˂,G(;HBYX*Dݾۅ=KϾlڭ@qd7'kcol!C9b77=)M \^8eb5%oR!A[ т98:4h4+J5Vx É xƽ}m2aW{9(25HhKQdJɲetRn)ź(.n$3CѸhj7;F!/ak ~x@8EɠkWP^Go~u E,_q<:n!v&ЏMA#N!e!ihzp 7;FtmuӅ|-mCmyT`r^clXq?b &w=Zb>C"NA9l#}TODX#J#ؘ1Fy͎z6>.\+uyFA(nHV ;9̸l#:R/0'm \m&K?&&&&&&&&&^xXx ѦxǠ9O"~{9t\mP\<8>npo^Ѕu}=qKG6-\懈w%n-q k{K#JaoMZ`tg5Ё+19xL޸m5(2p;3W6$!,kh>[[8~τYkFާf87 y쑣p(o 3TڏF+C֏YK_m4iQ|4!T}1go.mQ\سE]j܀Knb>|%4O'?b9VF;q<L AY;Ru)!{~4\v8mȋ*r񹀿,q[fz }1y.{B2盜qC: K:{@i,ofJQ|[ kOK;X_ƣ""4P7 ^qQA. b8g#b//߁oK#FHqdM}.Y/VgI9>t(s`|5*}8n鉰OňזVas BZX[аБ$&ܼt1V8`̛ZQ2`F1No+9="E#5 $[o]}4K}q{P/PM1\qirlVyO%I9Sj.V7 t:gEet!4y9x cuٹ`O^ ڠחrB7&Sο5r!r i8wpsyb}1 F$[}xYOMLLL=p^ϗ p<x[}(}O3hv5r8kFfa(#f!7ƗD ^'/WP;nc7_z6tP{_bZ-~᣸Ibi5%txkov'bߓ0Z 5s d{a~ou< ly NV 5i@q륇t@){qQ*C=MH-dҀ+H b:BC;/c\XlMpAQh&&&&&&&&&^oDmMMx9Nx.Žpz ty\%fٞu!g7cf1bAlj߇r| ?? UVA&M{ &m.,c\ۏYi[W_Wd[S(5 opp3;^EWdΗx12NeʮgA{Pz>gBd7Pֈڌؾl\ ٸ ~;'lyUxbۄ XR&P*^,ކ?3V:hhpEXJ^}צ\; ׻U߁bO4A@;yA4pts18ޱpx6?)"0VcD>3M HΙL]1r; 3HC6ڎ%R[{s&^O{R\٦,k^_~N [ :aMO?%'O\Oo[!g.#7gpm` -F:uN Qet6-HoԨ,~LƔ%{Ν&eD-oiD?mR/4/UFRqLxk&r `GgD{\JOMqV;mWڒWMν -fK}@jC[{!첞BuX~u(_=E79dEDR/$@L"f=8k3?p'3 91#[)tb.ޝȋ.]KPg(d_ z0'`>k+h;exF}hm^BbsuGiy~PAۥ3|8?۶ѶçmwO3wѧM}XC^66?lܾ;||Byg؛=⼮9;3H j0 !/\HQ]':8Ȥz*cSiy ImCOqj jL'sBv}+ |v|@gĎ@\~g6+0>S5z>Ax*=p4;KP >Xi),o{bmPp4b:6 97x0_9fKS b8neBx]D]ľ*2Z0yyAk#4[a 9.0H3m0O} *J?NG#eƬZ::XhMz j|<``>FܽAm ۓ-#EaqM>Goa @'\U(ܙo˱~5d^@=G炼z1=3"_ϥ=l,՗X6"5t(:,PqAkfk䣷 жv:y@h7J<2EycGNZr{P#. GqwF5qY:h.K,?c0ǩ阮Kptxxē6pζ`˻Sy.o||l< =HM'@h[2/Ã_|~ JCbx!8!0#[C>*, PZ? mUְ34 BSŜ 6zB6mUG={?* LIcŢ1Qݙ  2>F[\M:s'dC4ׄ6l xVo[7D`Q_|u*{[Mju@o٥: e>>pGK€ W]DoBr, h5Z}Dܠ&h^ey'HUT7v8e߇"ES=F `=Xg:Cc=sl[)VEdhob5 8D4 0#y@{ƹ'UR殍ʰypbQ $3f#F#x)J{c|G8D/b[m2R^9G|~8?^_e_vo'&&&^[ǼLt(gK+:$m?vj\TGXm,5bI=|oPTKm/j3\č Z+"![MCQ1c;0y:`\ S|]aX +ws >=W`A%3r>`x0[G@cWcE]Zc(SXԿ@(` w>11111111<yٟ٫6߇{(ıvsM%_q"/ Ƙ *"5Lk Aj#$;#/W{ AkVǢl(uF{ocw>Y >;,&N|@ؼʊz ;]=|xFl.x'2p!8ns q=><1-\gq5|0ۖZ|mE%oz_)ۇ2ԛ&,wv ^9hGmHFLlڞ,nTQm0{|xޭqØ;AdrMʓ(t?2IrwPt=\&0zИIs28{DƋ"LG %o}b*|mqM/Syf$;y |uu2_e]'c݈# /^[NLLLLLLLLLLLLL\<9t. X2#F^8 d;/Z(5uvopDg7"鄟,˟ۚ}1H/4X'c(]x_ć zPZqMns NFȬ[(q] JY]d~6k5<.E ~sY)#}G9*/e "[DTF& "tM\j\0; IS(FD}˼2宽ZD~}ȉEj췰d>p'{pAFd[d~Seb˼e]gibRf 7h5VMOn9!y7L25ȟm'cy%)NLLLLLLLLLLLLL<8 wr#j=p 6u"wvQ;u>ĠLI(sE#&Фҭ(|?+֜%]BE^y kɹ:ֵ9 ]9 Āf bGCI q쭞jhi#/u&m1ЏѵƛOx} sm}B."܂0JN_0eH l1@xzM=: _(xCHY=.B9&vK*`[fT{{!dIҵԎ2 V3x6?٦dx|f$I`\5=`727|Y>ȶCR%K?y<:9VT7 E<_IG,vWԍOiE egJ7vwF]Y<sb܁>9 y)\CDTK, дzBB]^^. z~-%Yeqmd'GZ67/92k&O.ĚHf4u!crl 97_4 |o<#9fٗoϖ "+,sgj4IHFnrK@>I}&0a_qx۳F䬋*bASp@ x"zdѸ@?^1h.ċ1Xm>eazB7 ?^S>Owј-YZ|k 7f@3{9?_ԑ}3`m}xԷ)ebej;ktHsyR^nxO[}+ϐ|#\ɠ5w"އs du _㱬-K>F=Y4.G7=>`pƝo rƔ6ѲۋaH@cAm4W&qGvw 9 6lf M!Hz6b{bG^3cY/q _o;zH;chldY&&zOj0=|&LA-ϼe4O5>c!!5x- נMiA&(GBkg_zFcnE >ZA˂P;}.|U__bF8HZPb\WE4>VF#=/H2<_V)]ĝb/ʭގ@;cۡX|gWO|7su6G5WF>wG)cSr15Bd}LCe{ 85tls rn!ۇ^mn=b)-F_O^ HvBm'8,O|x(d<8Pv8-6+=,O!j;;#Z3\7\ k1(\e[\>ժ6S]=:?pq.+!h YH}v@S 0l-cn7;=Nmʃ~W~pxo^y4/Қ~ ֑Pƛ"y^zשqMF(e;JY?,GV̀kɎFleQn޸GrKm{~ ۏnqM܃:ui@(iGX5 =/ emV YŸ4yD^K{AۄoaE֦f bBb9U'-Y/v1]ġEGoːZ*(:+H=h,5DJI I)PP}S l>-.ڶ|]o|%\җx?N?40o ug͕&FM<^F?ovCM>Y:BiP9K(x(L`uUdFeV>9(^̓i\ļ_.CdP 'KQԀ/oQ{xM#^+#ׂbd@FrT9 [/$ eU bV;y\ID_v`ŀꨛjD}y9_͂ꮍ=ږcv>x -g9~k)N%S|gHLJ'&&&&&&&&&&&&&^c^yk| Fo {(H&3qyʲ݁P'nS@rz4&5v _5sx\9Wbk *ek’#;$K\)C-$TK"ók@lkLZ_ty},0{DFi7۪C &_E6ѝ{oX]\h7R§;xD9ϸOHÆXc2Rx@4>tq]% 2妚m@O7ƪdĈ(zJGȌmLA`O0Ajj TƓ9T,ƨ/oBtU5A J.#7NiZV]| 7D~c m#7{m̌ec5ϛP]xDb8հ]ľ{huX[[c귁= .%_># _Nsd dLڿ>eٶʀ(@i E(DQtuCTy~5ט1&sttu8\Y;Jcɐdmã0<'El<3 =Lו/9EȮß1 D<xk}|G]7]e]+؏ፀsWym5؊k-A O!ĥ=w`*ρ ~";>|v׾N>Ȑ*y{EƓ 3TҠWcC5a)7MBF?5!k=џƚ˞[XۀZĀ4* w nd_'Ƨ*&% 6L4ȳ~BNƖOw2>YrItWi<ö9-4Qy.qdyNaBTo1#¾9QxyaĕiL@Z?{ #~.Eu W6 ^ c)c $2m~= zła~m޴oFi7(X/vk%=0+A}kC{%>5ϰ2xDO^֛*0 Y&?;Rok!En6 f:=7=y?==p2swmbTӕO񭼑ل 4ayo+|\L'zـyɺO 09DcQpBXӜ_KA|K}ge u+ S,:{[#9ARezOKA`cg^  un`c=L;_i Y;ӦoƂKK~XNLLLLLLL)jˁrkblw|b E}fmZyz$s@ChۨM6^]O@6ni [g#spbE GXPv?{E oxi9 W@?=_ w.>w*zksm.w(:o2οÜ?8V@x]+货UXK]PZFâ:pKLVm7 <\u|2\_䘟oKVfSiɣ>tzބ[`''ަ7*׻?d{Eum掱#l)֗!Z?K{@!la5/molVw>a6NːOk-dh[A)ƽ_{Y|!~Jx$Ka$ա[kǟ7v,{ n~ƌ7D .Է1WִpC=?E} d=dK|x]2?C4` ,8iO|qēɘb>`rXl#}x0~#fs{;+|> `cǠ8 zGe#9 T_ ׈@}ς:y.ݒ9f uJA @k[k˿BG|h b+a]02M݀ m{ fK{onTMBqG{Xtx`qHww`W|YwT?b?Ɉ-Sn|C (>,{7@F )5;Ykǯbbxy޹d6|^cd~3aDjVE‚ bWs C.C!s&c)bOG8.Ns 6ָspO7S伾b)ې pZ`'N]#"ChqyPGL[A day@Ob0Nl 4uSB,5ʏ@|ÄAkTk4=l@`ڢ7P͐+aMOmEֲk8Vb0 ꢞU7r+";1&מ@iEMg(ZuCb\x\ }ߓǸPbsɠ頻Z^{zudp̾X¶wY`g\%]DϏ:WsCܮV6-F `&!ZrZ!ʴp}cd%t7d)'Q;ɡb`Y4]LX~lO6IӞRR H9+>E=9t762b+ɺE8 }߰YV¦K; $n mZ$>vWֶޔ8hy yưMa|kw_"dؾ Z["|y*'SnF-:M{OLLLLLLL2 {t&&2f=~7;lz8)cbG]=R$O | gS,3#g|xG?ؗl Ⱦ%¹%r2 FB̈9 'tņ:teы$JzY:56"uATSoo} Y߼4Í"L#@% |M Ty%C6V +a]/K56_S&SHGya$i|)}cM":{S?(OBAkoFf9낸^D^UƀHbGZC+vp'&Ǖ|,US@EwR)MK֐ՁR>.hSTDth p8I[d~].[ش[ ЦdshЉ' HE} EzNje>> 'E-Dƙȱm*sBIc,֨ɢm_cҁROi=KڸpWݒn0Lޗǔ '(E{-%—_+uk} Xb6N6mN@O&#Ismoױq+~]fooA/+ /r ꉉWSm8aΫSpN /ӈ t>n>k]U[ȷ V}Gy ۔Hsȣߗ!1Lm[h/fHF_;&>F9<>C5FUV% 9^9\6n?1 zʣՑA>5?:Y{5ko·5@'p/49| } ?![~Bf f?+8| Mzo\e5X>->Ej"Ӆ)OHFT<?}@q~qb3JO.?R{}.%Blc}& %luIy' "g~;sȎ&umC MAhz%ƣ /Jg~nX!lŌ6%zvF'c8\ tYKmA_)t)c.m x<2a1Ǵ ]u;Jc}s+P8:OYcW0&i[N7Gn,״ɰ/pw#4=u߿X_S\/ tacxO{qDyY#O~f5' /w sݧ@5K8Gw`oXH&#^B΄n}ÏA&X d}|Z^O\EO]>Rg,ھ/N1B1 An;D}NlY\(5 huA}oc@bJXᆇ=i·P!RndtAkmpMmrn/fBxaR31111111&{|Y}ٗEnbyy~~'Z:'&&^~q[='8'sm=}ԋbB XPF*i ǍKΗcXF<-.Zj8Vm(4U?`M3'/i~"A\uiE| y1q4}^.pDBV&t o}$$KhE\ސ nUVnkoR]A˄_օBoE1kL3ngc܃<hEVΝuh(<-zk ?~:/ /|S&`։X.o.,E^Ͼ͹Xkjmim=. 9Gm,QdV9+#Yjݾ5{EX`}p('w6/q]B. Q)̶rvW1md.43SǟbmxB=r:-tCu}F+ոz>)C>%?u^ Sˊ_vFwBFҕ۔}hޖW^iTv?],9G: 0ɐv:Uj;x'~W5$K|7~c&&_5_suEi__X111J'ly͎WqJ92 6Wigux_zInh AK= })~`v71:5FHe|@VT7n+b fEİ\I)/?[Yܵ-MOOa˒(t!d+?.ezoR^zonit?pJMm&c{ڲ}z8ܣ[p'w~4 ooP;zo2旈uGm9!*:1V YTR `^ k'C`T Prڲ2V c78ѣuf @RRwn_LJBo rSd]S Xu }@6=F5+Z9 mH1|SxH !v b_<V(.o Ytňv+셱X[ЀI\|хl)'&_^49 ÖFFje+V2nQDKChB(AƝme4E,tFQE{?xKAG;>o|*I.YV諕Fy!ĐmGkf+C'epRCħ?_=JwwGn &7<'5ʎl6ePNb #X}ZC6X+ M=rLW8{۲ [{\,iwyOWJho+z}s1>eGPc=5Rxw;pxQh+uPU$19"B Azo%b`;Q[<*bEVfO@̨1L[g}9zRno"c2^e0Cf#y>$N(x[%]&h'.Vt`CwFk:ZNNYH*`C\G'sYF).5qxx/W#n|/xp}}wxTـn(׍cMvBE>0,AL(V@O1Cf2 Aʂ2&$)#Y`TG:o )YudZCYg &0]=c$;yE|((6H,f}2x/`#ӾGm@\HiR: ]G;T<9<RT3+f7dtm>=n6lg_(ٖ7SFkR9-y>SalK"/eyoe}pӑ7bƍbmX;17 [o ++Q;w}w.J8JK|39|LJwq}&@kobba@o/ )x6s}2yN VCD+m^7O v?@g{Z'?^92|P9z*D sЃ6En~GchOۛmb"xZIwazrڱ"Rg|& ? P~߅d*7> IEJ(cr_kO 7(m&@P}3$= ?C^ξXq IZ}ts,ŗ?g9Ǥ22C0~DnD[R"p@82;.@>VYWuc oժE<F7!H(œ6h\p S+PQ ʌmmXp#eѶwӂEʗG@Pʩ>׾"˱5l6ZS,gZl'"YEml}PgOlһ>pe̼M^U*I4e Ն04ƍE va .7$[vmU2ATRMA f9'[{}9y̵߫Z5sZg;59nQ_=I`E:ur?y@78ܨN6P x)!7R>?xF }SߜW&[oll7hdk8tӵYtd ^#aȻ}G l\7CWnb*B_OUl!% YN=vSsa |r42g6<|xeExNOĦi@F5̕{TC_ɿ+I\(dk5I-,X` >i?\JY𰀟K~{+u??臨p0Y`g U0}/}nopuzrB:kJj;2XOdgU?zPAO` ':& Mht9tm7?z p[k_m;zJ8!Qdخ'>0[GUudOv{${ `} y^ZGc@Æ7xd<c]2 sz f/ 龁M$]H]̡ܜ@EIJ|_]emR؃ol.پ Jߚo;Fgܑk]k! dxSJ1:[c >' :ҿ|—~$H:u3 ;xϰ3 aRAUJlS6Sb2GDO sGF~7ЃB 0`Ѡdڝs@{Iu@r h c38/HW,zTOug]8н`K?xM2oo75q(E8>Q_=cMJf@DC;u䚐!IrJԫG 1Iݙ)I5m/=.zLSd@qSO𚿗IMw^`蓹x!csIy{|׽<߾^t'c:nLε7R qy{Ta4z̉DU&P}'n^V =g:!CWs&\kLۣwP8:ږcuöUy~ye_/E)/|;c~yy3\܏ٜwsգSuoau.?tW~OmyL)_e?]޻}\JƯ:**~ ڽy`/_&N쁰& o .^Zs}?\_ԡf #V8qQxl9`CÁǂ*x÷Ɓ{y~ɗ|7,xZ>~88ȑOR |>>:S8p(>>)GVUϯ8q|2Ƭˎ?ל=={gR6NB,gatOS>pK܋u:F!zD1v }2kyxr 8-u8e_8'ו߾~dѓN7C1[6=[}^XE#"}u6xszܢ^,=gWkLӡ{!}v)^&(sLvC^ye]_T}_YʓbO\?Ώ޳\k֊k1)F=ZPxǿ}[Ӣ僊3=ʹ]GpʺeO `[8}* [^]p2Uu[xat#´C]N he!)zz#g'/T2|'-s~ʏ\n:wWuȶyB%Ox?`& rn9' LR,l$y|VJjוL#h S<}Vc@wA>9N%ltgM?ґaF*pPרoot# l} }=jb"8,6==QvS'}C[ /~EؔLjoos#_uvu;|#)ћo6j<.gghmIұǨkCeiYGqUZѷE!ם9d~\oSD+ܤ9!}?VnʑAm%z`,chP> P|Cn,PiY|YЯ,_RUpKX wOO/eK ,X`M96\g}{u,Xp[/RG? |Ooލn-Xsmq; جi9L?ƎtZn:ozOúCG>CiU{Xۋkm|9[Eƴ{dZ@Ql ͠8$j:d`ǾA]6r)bé\)h[a'O?p)@u*wڮucd}ᡀ*:︃|lny?{^c4^x}(Ms([Y ctj (rP%5 l@r؈OJm+}J}^C|>PƊB?B_ ZKڿm|aZ=›ϧ/X` zCwlⓟd?q#o=H[lf`1->NӠ l>akdvʻpj g_SqĄr n`(lsx-1n-X0F7k^l8Zs aP_~/ӊT6C_{l$-;XuLL@h:8nԺETA{jTd;C>Dz`5{=6r I<Ѝ_^sDo }ûa}FK{ 9d|J9|}-Wv]<[^6Ȑ[5QqdeAmڂ8 UR s #߅qÅ1'r=ES!NUƼxPVϺHY n~%&ơ sg g`9Bo|@丕υDߜ!he5g =m*޶, +CՑ9Y Oh za 4|hS>S=CgL8;+?o3eoYyOP-,J3ֿ &?o=X& ̳f\W*M(ySpNA_ϾMoSt_epvt=ƀ?3Ema9z6~nnK.b ,X` ^\|J6OT>V,Otvxoxokl{ >o.!uK[^ ^+p|W ll[yv֣[{;@]* 3J |!VCوmkX]9nk\pDʧ.%5_̩Ms,y蓚HPʙ>?"kŶ~^/;W톫F(jJ 0}Th7uufk`ue.\X$<(t0isܤ]j4zgB~\ r\kR"1_L1 5VD]TVar.כrĚ[o֢ϨUQ qAk!*'4xĆXe3]2'[~bS Btm#D F{oѳL;( y{K7 >7htjQ.U~ҦCsB'rm׶d R#@`FW"5Sa*1 LH:kZQGSxwԇgw١JhY;YǴi'!3a= 0 y+AYUhг7z`DuDr_e9γ4:z*\=Ջ֞W ițx^0Б&#«.e^m'ΕCʅ ur8s 9OTt_ F 8 @|@|pٽ` nL1ao>twWxBg7 7(?3se-ia`Lx8 <54\ɿ\0> p>D= @(?sCx ,X%@`x6iG̷`}hoͿY>WU7ys"ڂ >)lH\mU'FokZ+,v[+qh.[X۵/ym&8,xh[/HN`MuA1nL R%q62T$I8h-6(.0qUz!?ȆwjO㔷0':"7 tbOii#Rbqę|{2-a]I_J8-e^jk#Eff:椌W_ʬ?bB< bl`^FX(jZ_%=VNhK/ ]+9 y &Y+BH[E IwAE!jmE '͘ [ njl7g j^ boGj?#&hꕢˍ_Nz>B{t,{ry|ZG&[iɉ+c~}Bln8!>YZ)>*J_*j5d_ /Kr,7a{^CXﴯDҼRn~#δ'iUK#)? SykPYaQhրOF V}0SF*mr57WXŮy󷩯njm/VCX5_I.'Z[52!Бzj]^a]5.m"غ"P A3V0"a+xB/E)-kUgZP6'R[oFlWe]1fCzURk]}DAZ4mbV#YМPMd R@`k_$Q aSQtdhLbv|_y5H!94_)nm1!۝-c ;~W\@%ώٲNDsPQ9v0װ>ЩAB"AWbZeo^P:/u?i3E:&yAnILu'ͰJ2G m7@'i_9)ߜ\BKuMu-L tL̻ٖ^4üΜך)h/j8Ti .lggy|wkp'?y8{~,XR+ o.o?PRVgHN4n;fdpftVZ 5ZݬY6d1߹My{~UP|֟o5f`3H=sH?_"OVLuWf>B "&D.iKwCA_4ewc:9PKAoMWWSK!  c:y`7BX4^ !YML]_GO/㛞*ĪGS{LGNZ6+laCbyKjc6ږ LrÞ=8| D֝tt6<~0c!G0 'BqEl}A1/O}\gY4K*mRzL r_]!q<62j 8]M=G\])wM]_*^%3(ᏖuyR?_:Rű86aEzզ '~Ck/.̭֟&Dy䦔k\齧ZOU!b[ǼNĨO̽\Js Z'W OcӺĆ6r[&9QytpM@5I[wh" ɨ~($O V`WuE(]?*O黏P9š6 ." .9BFDA#*϶MM?x/,a+Z CeYOhYH$y8]YC[UOz }xxCHTԡO6ɗ'ZVJЏͼYHukP9ɚ5 >ޮH8zsN3Ƶﻸ*G˷~HPk=鸔4ـU 8&9q˿a J{WR.+wSV?|S:ˠgY㹥-O6Bmݍ> 0C:)DAR1-o== P`5G_1]3+ZV> Ώㄳy 1t5u3< 70`G5vF6:L!NfE:WY_MnkD=>Ֆotv-ۛ Eڹ1;׶9-Em1O_>uZ>; /h" ,b9p`9Xqz1>MY|4~i |BK>]b qeH9XR+~SV%lѪ\q 0ѼRރ9\W`a]i*>3!}-ï!Nֶ ;cK)^?㗙*Oc3of! Ӛ^ Y.p+ %W̚k%mZ:0ٵA5{ iO'>Mf0}td z%C@k`CɛJF^#65N pV6x.O?[_tG?ڳrɣWL ˯rG}>m}4cfV#]O9y8x^[Hw$wе -y ScNV3)zxOn^.Xi#6:GLsկf;Ɗ4j!bIDATEXbk}٦Y "mJHl@D/nQ;sJT&i ߒtc56L Og8>Ҫlt:/Zn9:.Ow?~W\~rRΟ/B|pנ8%Nնo~הMo-s|zWʻr8\N/FgJ]@; [,3ofViR4h Ԟqy_^|>9A,H[Lqz1yk |!Y^#U4 /H[+i3)Ar {զea98OwMb{efYEQPQ6ڏr]LHܞzpDe ez>?1\þQz1kfz=BO Z-Q5Ԡ<'@*ۓՆ0.} 1/?9 (Qb.̆h(HV2!O_y@3 EIpۅ61#|`˓< ~L^k֪ S/_}}=\ĎJ3{+ Պg?ti-lNbSh8\'+[_[B[ബ,g_{*9ysl5!PgӒX5!l3<h|4/۬4WD QTPH嫠i4P8 9%QwrXǭټ=(g6Fp BMX7.Zʇ17BlD3 q״X ݞi$럵Pl'^Q?FhGݳq'ux85aus>T2^;k ɆP bQZa+ĐtseˡayrHԝM]t]ZF@wXRLG_鬮؍|pyPl;V_ղG0)C<1v#,4>ԃ,|Z5@+3,W!|rI9[Tޣ#uCZEx9+KoA G IrhKG ]ch*'͈`!ywO-2^tgMPBe T|F}t [gW'_ٞ~?k|c?R8V>ukzkUEzA{#0qZ5GkiGѷK"h!a8ME=mJ k[SҗĔ^:]!^i*8D/=ũZԉP󐜍cn# +^LpֽaJ۳d)4m@;z}T?cǃ*Z}:Fn˗5Ǝ>N>q8;;KҐކ؝"xhpܤF<{i4!rcS,8,8||FixI{=0in V)lIs}Qoi ui<^VvR4e}Pi,thky=7w&*VKǥr챲_D}_|V^?b?|Otu9'Tb)jEyӗ_/M_\4u˹»5iHyOxspOʅ9嫘SLs)㶬z9%Ԡ sUnC̛i/5:rț*f3A>`6kvHE}PY+Ay~NS6)XM1ut@Eb5i\\gz<> ؞c\6)o{я*ĢNGrMI +v+K_ J $A IC/q04zT|ЛX j["@օIPn$:|H~KZ7@qwW+]B#fBsKsaMZdy.5?4G1}9/̟t Ei~Տ!p^0HL'dYETKZǎ=tajCyFm~n4TmzTi9e)#voص&΄u)ag- hUQFzTY"=׀Ea)YzUt|O7r%Lүn"%!A ͏X}ߎPBFW_7E 4JU[vkVn=A zЁ16R +;,:*wN7>r|Ûc_>]oիˆ]?Â~8$k'qƀb! ގ<7Йg_նpH>8ҟ{Lԥ{z=_!PB'2!G$IHXGڒbʥAfmRd RidfC|8^ᶎ3B88vrlԂgkS|t[>XGrCoՂvc>p&>*<Բ)P{OفS[O䃕V_cY>\ι<oo8?!: `#G/d"i.Tc^Z+ > D|V bƒَ<ηJBfี=>Rs|;:DOʅֺ ݦͦzͷU{mk\]>fb ਀C y[n)N tsR<o Z MyZQm5!@?_){ĈWrUX~D:I9)7~aywW>-_GW?-ldR>\)k~`7h/r<~QWB|86+{e#6j )'Rްwc<@_d#]?G>%Ř&K ۾gUHPPc1ٛztOD̡թmLO;Iۖ՝<82E%WP,QG2ru%h$Pl5`A5soF yF)yFږ>=>{lyΦ/w/)_}8yw/hhmI7 P8rf#y:\+_uoǿ<,kͫk_-ߞ޷Pݷc?#55cz2i}W:K5y9:pJC!F?z>9/{tYְax@ T+?rleHC?97)y94 JKAEN=mVeRST@Q8,<*4<~("vA<Ȥ4Sՙ#{_m>Ȍ :?r<cÚxlR}ZJeL};'ĢL<3^n_AHeoAotI3sY:D=7*O $!2 Z6|)?o'|_'F+m<~8c}oe'"5S7}ɖqM*R&qG|e,'_7W -:3ݶgZCH7yY+ѽ2cjZίQA%}2~H@0‮I{ꯌiF:}ƌ9?ڜkTe}:3~R'aU%ě{}A?А1 S>l&?WַyOLjO(+G}8?#L[f,/(s{oafr -D7:/ w9`ÈÁǂ;x_CUdLZi~+ {zҙϛ=,x9*|Y:>+s(}^BTh&;沿L֗a޷^o[ܷ:4is(b j}t4tF|L}g~|&-Wn6R1-N=׹b\/i S/ij dH>oe96׉v1RNq\q%P!}g9vFBjY?;lh(V8=-wogG#|[.oxNOI&.7yWܮR5<`g?QsJ%=+s* N&ѷU{&71Wr49yVsbL%C:LK1bU̠D*_HgZ J,b?EY,ΈݞXc<cvק1|OMu4fx+y^z"bBךMQg/M)Tx94idnPk< bERq.pF̯^EbBw@yn΍;uE*CO! (&˺`])A:lr胓Gc5|-Ě۰Np0*l Ӝ֥p&8H_`'?Wz-܁ 2m?Rᡡb۝;3Q]PH[&\[Z1\mKO_3o ,vBcЄO}|C8Ŀ 88Nž٠l>"κ8dڔ {ʉzSĹSF~tM~\8Z-w؟Nkyeң|0D,LuHx>"9WL蠠.q r8nLx# q~8R]S J2I4YN7h<)&(?#="}&}jȦl8}81?Ay/*=kj) "m+ic5Ɯ9uH[LUR1ii=oRADLۻndm+=o_RK ٩i*K@& @h w?O<&QC#2`?MtRwwWMC472~)z֞# ؼ]/YLU5s8c# Oʍ8nzc&1Z{ {Q1veK̾5"{*)T~TݰAopuFpUyot^S<ź*Gޚ, f8 TyAs*I=rvͶ& 3N  y }Yqk1Wx{>Y tCZkM1}-RQx8Q-/ov<`cYѯ6uq`;7ΝrαuPot+3\J9i,rc[ +ɟ/J`eq东9Oj`p<1^9*wVw-J?)Ӌ܊97~Ogb>ʯR8^O++1~_PPCXsircXp<Xp,X`/]2p|uܥ!>s+,[> dZ& e3i.[v*\^5}8}W`O:Zg0ugt/{5?w/b@[ v"_U^G W(f*/P+o-%Z;#cQXlYN29A!C''e f;yr|DCtS>RVw-kю.\ҥ_BӔvcc3ZeWRqPAZrϱFEW7_9ǜOz.SX^v ޢq"oUU]ogH#:j61vu454&#~bWY  džFF곏f TK1]V>(Ә=ىOERz-EU9QCպ٨:Nrl3 ZX:|C~r"5lQY]GE{kS,__o|<&:Ͷ|FmOmO_~lYrswKCP }g_Z˞*Ol9jv'<*I1X cQ_w˅o(CsaH<1~t(l$pl ZJחTp=A PFpI'yװ1jBF%ԅn"!C:@ݬJ -R$}ZHuty+ijr?%U(5Hji0lf2ߘsItbKe?&I?;^Qwwmu8t V?شg՗Yk? Deu I-X5|Kg,y GfUh?uG٬!_wzU>"hQ%9ZS/byVg4GOWPNFeΠۑOvWd5Fkvg,7*4Y|苬;vB| 뇩A' s3E6SlRrhSٱU10O)m̈d1޹לYVn^#QCAq/Yۘ;$qk|:4}Rѫ6$%J58T z&m|AA~ -9_{SdL ,rrc ,xy1p=o2{!gF?@YK{OWT?FY:bѤE*"m̢|ɫAva&Ds7 s5 jrv']I^ePyW!}.?l]ZrăWRE7Qɦz8ӌd j3ѧ+4TG^1k(qOS` ~LAw$P}g,n;i7?~I\YqHrOy5QPe=)OJ onJS!O 6 |R/J ve냘$SfUPl>'c[|Ƥb [[Ɵh9F r$$1$J3G9ӂm+j“9~Lsk]M9B;> WX \.Ql5M0ڮ"T]<6gSFq.vz3֡gcԇE1CY`Oϻ$i~1`_͎*S6cDtYrj0D͌g~ɣ8Vp$p9ncsԈUt~#Jhp I1CyzT1p_-;K=p9=^O++1~_PPCXsxs-8,X0Áǂ ,X+G* ^lh:O +?\d8=U~v  TwI]̣t-2@&˓IrrYQSHq^Azv5 zML{$4 *ҝZjq%ƇGTRCR=e\lU9Uyey䩧\oq\WY1J$hvnˋwlzZHHFa ``t80}pbW1A`ʑRq F]7V;C*cTd!˽ylv%TSX CGPL{㏺|r"l0dD*k-79Mxj1hNZi9/WgrӝG;xS=_T{qPl/4v8Xt#gc5+^xƝyYm/juZ.TrcB?>WwնlDumZZ8D1~-9\Bd ?㠄loc;*P{[3*P%0o}i22AjYPVAcrJ@v5=Z*An kJyMm+a9& :ћԧ&D}Y*_ylq[[~Py햶>z,Bocu'Osɾ%l2fH^k")MjY_'h"Ey@.~J U?׻nB| 5#_y`LsKŭ ~|8Iz*`!b)\ZYy)UW Upٻ\˚ UZc⒃wz=9Emq2"ZvB'N3_#1 .?,j^%hߵ\} s2|1<Zg myN<x$W3Vu>#Ļ~CR$ΟE3GszM0kU 0'8NuOI-~LkҷɜnM{Z}mN}C')(]p¾z$s&:ژd+1~_PP{{׷PFy5Ӣǂ x8X` ^xeWj_|.ϻq/+?*1 fM7%nI%,Po?hٜxOV]ꆉӐ|%=͕u]h y`Wq1 aS{ZNʱ~G'gQ쉘'pVs|suGs@o>=mp W2: ZfՕLP6O]W'^G7'UH*rԎ7t]jÎ+A=Foː vc^YcN?@gΰ))4}5LteMЫ {.*5a4]ELM6iΈu[Ѯ3+"Sn?%d-xZRAG:9=LХ? jzܡ!YTA[RZ(r9k(zsCL!kp>\4/i^$T 􍶱lG_QÃMǀ|q:ͣY|?$'jCz;~J7^k =zk:r͵y䪬utzR穘%96zt3қib2dUL|mMWI)F>d 'p/N I{ZaL}cǃ8Rv*G>9NkpskiSlYԣҦFoɚb}j\q:"K߰m W7o3zˇ9gʹ(<6](F-~z9`ÆÁǂ ,X+Ǘ66hn\*x:\~T?G,Gfst~{ȏ-X!x '{'6=>h4!Tyɡ۷2'Mq;'zԼ0vuVDǕl^Dt96ڵ=hu#T7.V[DNLa &|ac zH6!_7ѦlW$3ilШ.}v\ ,j2m2ySz*ŘdkV Oe{QCCjGЕcĀ/OBP@+?<æot& =6L3H[{1щѱo.lv~Rm e1&I0vu"+eEfz.9n[(*o3/4vJPyL [\v1Xc ]n<`| OSkv]ڃfΓ>'E*ӓFvbxY?Rݑ٪lŷ=?<猶UA=iڢsU}D,r}U6 up7Li@m_7@ɰ@n1|tIz@}|(A8NkgEre^RE˖BExecU&4'4kPmoe8RQ-q?.m'Rko2+J `Qn~ 6iH*\~OA78@!QCud"?Ü#. ! RiݮdeMQI1:f` ђli䪬1;ߢ$)$ ζvϤHSĒW)!H|ifsIwRfczYZ_g5lX ?$p(D7VyΆ UJ=~C8/ȱUfe)xut *3 YئHmO)*y0š}nWg&_a1}[Żho} ]p{s}^H?Ԯ}zx}胈sEmLCI!y5C}|9`CÁǂ ,X+'T |{ }3?4?ܪ&g>g\dFM?sEU(}dD@zy3|6F.D;=5 Y~M#9fmzse|Oc@7ڍr{f7I*mG+m9RR<٣eOf?x vS(~8s9ǺǸuV]4_&ߓCG$r܆Gufsk/B :&ps}'0¯JRYZ@& >"prMcO rI" ~>WV.]d07҇IG9ЫFmn܇Ԋ p1'p>qMm-n5tHMqFT,흪C (:D5mB+H8ăvhnqduA?vy~-O5㝶i,#FF0vo! fD#xٲ;ZA9Yz=Nvk"W?d4x"iI3U=&YY*Kha? F6CLՔFPၜAApv@f)fr=J]U>ߧјG,'DCW'j3Jt/ǛuDllrmA8M@@rLq1 zd[av*N- 4ҩcNձՔua7*EYآʉ#WJ뚗5fXCI0t:UW] YHq l;XZUڂ2>:[$^k1#yC>}^XB"ְn, a}p'z䇎gMrcdgԎBA`jgTח9Qysm x' Zڼ>}= >GD͢QfR dM(| 6,8,8,X`.^8ޮ'qd9{2Аҥn%~grÑ' >Z_Eݾڽ.en dF:0Y4g{qqTO/9r)ek>H-FY1ԧ23mtW:`6׭U\J|)&MAH+xcKe1j~M xUEé27px+8fnZԑ,qDLC~aeup;OD#o;زoB;,jESv|7ƴh軫)sYi 8iǃ0' 67[7AǤ!JfQТ^.+o+$ѪPlENՕs,bp%eR|Hcy)cB *u4J?P+㶨"<00m+CT9va|ʚG+]waL`{HP:M=۶An;^5oiS 9ݗ9'H-r̡8<ف|D0-龐b鈱O:Ȟ&qX~_,XI譼AcS2/ˆ;T6tMRG_O_%3i>W==`O3cI68A>Ls]ޱ!_jaGUum׭%.99T~n:U$i>{"{&4>h&}p$c8 6tJ4q IJÈt$O?w[`g 9*LmDGֲ3k[<^0nVOÍڣ>K884euvLu~Q'w:mp$܎.s ovmD{Oz[胈sq, rʋ--?`CÁǂ ,XCwGTMt:{TʘFɤArPpK qYEMvˌN yz?0^=N{ܪԗ꯴]rSl_>Ib}H}Ay6 z?<ņ_@uљČ +ؚa>N# :mQyD8Pԧ馝϶tGH&>R\)o&"UOgmLqC:E_•(c8փ*\u_$ Y`F) Ėڡъ V[uHIoU@pfi6p/eBv.Ɨ5۞|#8ݤ;LІQ8p50 nn9Hx-#@vKz^n[BLufIq]Fj@ ,!#s$Yl~dhB qgg\gH :~ˀ/?U[O4Dfk3z<ݩph!_fz5tV5rP'؏>uV| }69UԻ! Ek jGkсITUY>D3ӳ=g۾ϛ(P P@1t>1Z$] L4肿5T ; gZqҡ:7j{0 /\ K9_^ E//q` ,X` ^s~Ft`yh7i}jϙh7Jp,h@ȳk|am\eInAUl$~Ç7VGesR8q`>Y.F9rK5.lyí*LIŵ/oqHW_,y8"!䟷W+i{eڡ"A+h_] \*:?>a] >vg԰3MYU.0BOA j΍mŢ_^?Opên8rb"֊Fv6ŐJم`av:th6E㉎:plS:Eoݬ;`߃Q] |`  \RLݍ=dcj#^pp)׷Eܵy]S&c6V=Z+Q{E_~BeO,X` ,x1qO[Ge X | {~0[$;Ddv-D/t*lOER$Z& <}^n!?^hY=? ڸJ8H}O^_Ɨ#!B5*bÆ4q?Mz{2 _OJY~ң8椽9]SU*#ĕ7 1IC ]pl)0I 1b"5]D #IY>eB*CWMc#f\2kGO[ W TIcV80D CÃ(#?%\J cU)'qxГ% /wsuq RIm_\]|2a^k~! H(7w`-/4^m@~r2&$q:Մ2S9hWˎz*$ee]a]/ MOK{U759Bү-c|,AltήQ3EG('b|x kLex=/T]H Ԍt˖DcH"5&D6b.i@~#>*NB@*otFQcIiѬKmZka>_Ȳ}C`?$=_T~m"\u?|G m$z LptTmԴ} k4jUw]eݳN+1d)AuspAWLt'qzfЄChΏ*N|{AXv_ńw٠a`=MSY4D} ]LmNTFsQ]?8@ڹ^PM /_cb~ӣ1^cp7Ghܵy]S&cU—ChJïy|9`Cǂ ,X` |v%bC~.OlRV~?"-hL+`Xn (7s3ʋνeNY#y$މ*+k=6[alZw]Q'w GL7*B0=R^4*1n[ 4:߰-g × iJcv{|Kte!qYcņۑ7LJ12y^=| d==0%]k~~`?8EQ<1ۤh<bYEU 3OP J d#+S並&) Yt|v+Zw#>ʻ((}9B)SNqQ#g_Yiǖ0}Rrg , Th̘1˚.Jy"1AؿQJtzLN%5rމI|g݊C z()"JY6kStV6=om !@֩th'ar.A7}H?yL痧IB' z@ > s\pu5cz:wzKCuF+yl70nȟKD}D]t^ >xHoJ:Rw Feo2O[B+5tbNM6:z<;Q?0W}J[pd;h:Ogs\a=jݺ3<%o{h[}9-밷|'uKVo#h(q9`Çǂ ,X`{p7HF{HvE_D|5e*&5 iA>cI!i >l>IO-Mz4m:Ggdo{}J7< ^T647tfGi ~B K,qxWʿ-Uw0r]}N YTugμ):w6z䑲T^{uA"*3;aۍnfK]se<7fc`= \{r5 u/4U^9R0;$)kd\3~16U Y52,P61~nW'ĸR ֣R񝰩)Kjpg)?W-rrE2$+{mhI7T(ڄK9DgľVθ':\AsCm c3ۋ#v-sa-?*'-3u̍1դ<ҋB*)fPhΟ9H9휊1@b6!qO放;lonXuht6>x Xg,DsHSr2U1ٔ#N]YdWTR~@fmCK>W_ nˇ^p,Xa9` ,Xńp{'y_M> zsD À*6V{{NoqƜv[=6aF ʒ|Ħ$e lRe/H TM) 8! \}G`cNubLaZ.D'힭.>uf ڷ?U̿a=@Gd'DmS$_ߖ)sH&E(uMUGg$6bJ9n>b* *Cn=n\zVT_ͦ)"a%4u-H0cL:ݗv>+yԏ m2̮`S9A<%>RvF5?7gb&I;θ~pUo׼!S) ew]*gUdu2cnt#7i61GIe[DtJ6H~Ǣx3MD=+y!9>ZGO%x%ON5$A =i e>}:#xx0J5e>猟ӻ{/}czltJ]Ǿ_#n WHх.ni:Ʊbʣmcj rM=YjWK -4/3LyX'p9F STY7ՖyNO#<2ݦJ`/4#͡A[+b qTee-DsMEO_ =y嶑c1+*~d Ͻ{؊t:or+=1q<~x̗a@6!Y79bs0-?|dz=,z{=mG-fdig:}Ejg6{!y5ތU c9pFb9` A?+pϟ(e[aahjA9֗U͇)YLR? 9a3Aظ7KaD4RF4kVGމDEb򪜕-ケr-;rߴg ^'˗Mj.|YoH?<7ג#曶xfyn)')vb?=/p*g gݫ # 0`CP7,zC~{ǬY]ͣ^3tirtSWH{X|Wmo}.^ !W+q=j6Bl\'qISYʉ> h;E4;zT7dO=Qki蛫Ʒ8sK[Gnrj4Ǖ,K{9-'(|~xƎY_iiɳvGOX/+~rF48Ww4VJ 7?z k4)@$UONEF0+7LCŴV=U5 *dTF<1d%G*^ c`keE15).s$uVxи Gs'8ԃJJZc2_cL^˫~z, 4mio>Úy ѩuk. Ao(dO'ʹipҧ9l*](tDW 5+Rf?*Sv ٺn)CGӘզJ¸Qn[omm6l+d,D'zJO|_Gv02mԾZZuU5]R]zCO}Gv:7ziOɴC8R5\w/ /=o:Ʈf[EWi B,8O ,X`/kO5@;@_蓧>e}2}f\?xü$[ OdyHǽ ?+LE|awI}Plc3vy*('[67a>mE'MtcPY*m3V#zuU}گeoyuy|^Ur)e}Qʧ˳m\V8]>srVu$''LCEg^9Ymy|ry~_b򘱩xT#̋O ݬ1lC8j50\+?UK7j+] oi!1Cd suۊ,3Y;@-kxf|nnAAn^ %k;JUc 2=/:m'8WYMFmAy[:X%fH_=Ak@GX$͔•fʠ y-z:C D"WI 851~MAc6K? G'Ņ8hw+QzO줄"r־"|c4gvpm?g4zD=ۘ!}OvdS/V_n֞6HY9ժ[p,X`~`9` 삧po5w?';ȷ8=xӿOT.>m>/'\ylUO8m+}OOZqB@%-F G/bZ>3 G!veDǻnX3TTDOK۞|aNt:.E}Ȧ W=.w6[oh[7΍s On΂kS- .ǯG\*Ah^JO-!ZJrv j;?B<ܸiZwQ{G'DalL+-ڶ8%F`{W7! 4+?h +"= 9fT{ȣzzTmcFq?De'/4_I~dYG˱'q107p1mɲ;B;XV+ፍ2?r@i޹/li~-_Eo,oܽ+5>D]'ч]--#\Hzz_6~ͯysy<_l//Tzި<)w&CtE˨ךSE ЇόRrR5>92Ō.\SiQ(zDVm6w%_išٙO3"Y;xYmOaE_UnZHݪA<GD\h_B6.fAuKu)t#^H=]hQ~34'\47z/=:yX/xgyӮ,eR/˲NF5:k~HQ 4W%zda5F~tSZ7}^~68~jy,g,Wm.Qy͓gw,KyjuQ ]Sc.aC5ݕj҄&oԌTlH{mG6:o1OpAdyƑR|El Cee`jM%)fSƷW57 >RtI_PY=7;?LdP:>fŋ&R _E⠄ƨ}v4^8Yke 8Jm.r=,_' Gƕl'fGNʉ9 t:.R|*[ˏGO5#' <*OG]^Z)??|ҩb%׸ OUWw/)|Gyӫ3TY+ u8<(~ >L9+߅+s4Cv-t#{ 4Zr̢Go,!PBX.X^EkFPV~ЎB<: 0ݥvFm|%5,0smWsxAr5} ^ gucO~P&KHu#08DP/SH `?W3B>rT`]hɟ["XsO4}lYu(lؤ.ݡea&L*hp%#uJ} ҁ_X6t!_xEB ~iz$^߉ֵ ǟ-??QYZ_I-lWA7+]|Od,׵Ozca1]!pb"zjô!ٜۤCId;Hh}t g}8˃FLh5f|Nvy^ 7eis+0"t(2&gD(' )[ښS[^ =ț ({5_;QWq7z=V\T誄 #c{ ьYY6;=so(rfz)cEN:?JVM״r50/9&gN h 3:tօGoJEu25ӹ(Xx[>rc zhNogox㷗GO{Va,8,X`yGz|_*=x[#['lC8%|2xnPo32i±ЈqPV ]3?G2&nkbECu$C%fЉMxF]Og#et7'1g\eiS_ q͗A_IwcԜbo<օ0ԥO65vI7)6`˖Ml<8Vl_r-}|orIygJ9S6cS5x҆fh#+L<%rO_l˳jgԮstU݈vηE&~Jh%m[~θV?b.f4Kl:0 6a@dU'Pz0jSAcbdl)ODL&B m@9Xшm*m8ыMS!OM;%g~{;/i[\*3ꪻ \և<,`!U9<{*'_mɪ}B_؈M=<?R/\ؿO/ySͻO囦[-[斖 '漄ʼn]$~M^R9\_d'|8xJsTp}kvp@@zLՀ}4X#Dc6[9(C ~r* gꤐEIHeJ@8H&J5mgIzѮ鮌 0S28GFtҿH}px=wTϡ0""Iܵa,p-Ƣޙ)~7't8ofF坃A|LAPN(0uhz:u6G:\:\5)>״sBo}5/uRT6~7iKώklISz}A&9g}xHXJ BEjoŌCeyCXOv25n&# 2,8<ȡ/~m_z+Jc9` 8'S8'P~;w|>e>٣/}Qopm\N7JMYPF: xrc=|˅\@}>fQ~Aeu>T{SPķ]ý:݋  L M## ɺG?6>D3>̶P ԔU佘9zmѷ,mNMC6f8V'W_Rto]O}PV\gO'MѥlFs7Gi "I:AUC3H#J~ɏ}M_͏e3t\'Wm ܃ sl㜿Ym }t3<:RkđnۥcmgYNT~&wώ㏬ʓzixZ?jzL_U.˛nWNyؓhvqAq~}/O]-W`'.ʱC:fGy"e-_Pd)gk֕Myfs\>~BMkQREWYlT$Qv.ԅ'PG[Ui k+X!'a.Hk]x~R!z pL&4R'v(2zjv LU:k$\\]autzVs~Ovgf @DHigJ#k'cUF\VyW'<-}I>O:uyT=n[%r6$!SAm[*^ z4dK5w|+T?7~beGx[BvE6~9~rNx1*p,D;U~_mLeKf2m#rb:Ukx=&S٪@TS :V^r̤yÔ. =Rz̔Kj'ۣS{R/3km,ױr#:yU{Ѫ_Xzqh@/$7UِM}3^ڻV6m52DiS[DeQB&v'0O\ !~c d6T&u@vR0LN9yШ3M]"5*33ӻі* otn9WzbMSw ߟr=iQep㏳Q{\*#ϯfPH]$j=|uQ-dݽٹ )'?5_]Π9oT3汹Mz/ՙ^DXW_j@ ߸/J!kΚ օLqO8Ӊ}miW '7\FH7e'fxRwS^q>m_uyϯѸpsjlK;A%FYA~il$Äz I;6f*C0/&tc,o Tt0m?"`P>YpFJNm{y qf-+挩bf%9}~qTN89/ wKy˫ʛ^TyR|g7G%G__.,<t.7MvldE3ȇto,Cy>Җ/<{Tӟ`ro#-6G[_H귭@۰+i^oZe'ZWg'Z2QjlƇ %c>K ⾱@$ Oq 픶C`9&p=Űg5m6\>9aR@<J"2˘ȵcշi9Ӄr#N/3N@Q3dĢ-]U6uuFwҫ}cSh]h339ل7..KvG1A->s: \8^oޘC||\tCO[ y@"2C諼ҨXUeF|p TS4 R\K@Ֆ-F}ٔꪼR~w}6Ф{\R܉؎!{Fׇ Cl["*uf f,;AV&F<}XF`t9ə ?A-b^(,+xN= ?[=^7DsEey䪜^Z:}GuR6BPF!6 4֘(@WAdS'ɺ​Uz%K ^=>`e,!r[g]6$B'hml9@zEGo~¾)/ӵ=B~Зr1&75s58d"-p#rh'ל~y7=]+_cd <-%zp5J}\ݻ8jNQBN4d]ad.mUen#`KpKի5R7}1cedukqz9kFY72q!mFuT6t4=#}Y}eS}9u9D6] Ku::zLDV,dE`ԁ$NߏtόO7tw#oFdۭ 0eASc#;9 -V#٦7x&Q˒!}bVLښ)#mezo?/+, 2neOO9qڧдql rWfMʄYD25BeCܭ crpZt]6h&k ݦg9)6ԓc!O׿f|ǂnsh۾*—_~g8oS~{RKv9o/7WIn*[o'Wџ[+ۀ7܅]`g ~|7;,~Kw|VF鞨6GS,p[RNp8|p劍}¥\iS\?1J1<9Jtʓ=b99(A]u C{ʦtzޕ,K۩-hL Xg*&q'7Dwpoŀ4F˔Q SKjvV)e}%k+^ɶѫHg/O^lw?]~zsst9dsVz!}!E~EJ}i0qD j";0#z)Bftb<_#LGﱭ=W)I0j')-V  1LEv&φ6߀w)~REquqYlS>]7=]ʳR'_[(Qx^)eͦ\mX#\].--wVז?T^Ȣ>?)|5\~'ٲR^rz8)_E_x)05Z6\If@cEH˲C zBy2B_(xLV*!]n%wA BG>:mh>P 2#D%ȓ&9jDR:^SXG-H>q.sWE~?GxgeV}:D 88fxack^U}}?|Rǥ0iobS&0WWه( ?{jsrP `~'\:@'r'ٞaR]GHKԒދV_i=hB>6V"5pcU~lJztF*(OyʓIO^A/4{ .8U+9SvFY. /DlIUKR!]Q(ibJ)ؿ}ظ<*AihF&$TA߀x3/Z!bգVC~׫լ8@# ZcOP_rS))&CW#=w)S|qTN#5OXxG ~ j41?U)̋v5pJ؝ 8b)&c;OJ+s;tQG„+8oγ(h{dk\;l<Z?ڏw[2 _aS><U&h&|P@i'u{~}Y>ܧ4˾fu=Mui:=);=ӼlWG=8.SЉn&Zzk kO\+5 }^mfh^j1_kaJ:̉XWz8Zku.Ǘ۲Zocɯ7M<'GZUXYuV҃JcZ9${&;W˔SdJJa$@h=yTzW]twiRQqR^W; ?+(ܽ:=WCA}p6㐋Nm‰ʏOP 4j>JyteTyʈY5$bV/5l6[+iҡ /t!4+{3(+zcW ke?#X(O』CZ>GmPmfW>RoghcQQܻwa0.*@GjIEP0^EcĝutAli9&7Yb 0o {Aٞ0tɎ.$0ϙ!vЫluNJz҇];0w S\[ONw0zSmwLv^]&/ZMNi$|ŦeyFCÏm'p,XayÁzڻ+)o|ӿ3)xx[7:OSO>_>@N5r ,/~_yx#qScDt<4fFOtOÿS L'T^& o;N<˛7RMdt>&;g^Gq BWPei=@_OyO%=FʨX6 Uc[bJr%o::{~HnmmD%"ɖbZxG_+rGo?<c?7*?ޗK@9{\)?>+#[Xfm&<9S;oq*b/~<_+_:rxΗ5N̳% וl?Myx*1'w׮ądGr {h Mk1ug\ї 2_ܔtT=̅vUow2xǡvZOP^!jR,5:⾢dɛC!e<(KiTˡM-B@>G2>[Lz)S40KD/ 7Y3٠ѩGH !3<+`YǼvsLPcx&TY 0scU^4N86e$̎ z2:%ȆybPD?|e4O9O+OrJ^pȯf_b"0s$(H۫}](MמU/ 1N_)Ggwp@0^Ϡ$& ~Vk3l)c/1bjA8[mPq"@EZ>zgIy!]:ΩCAF'ȊvJ<>k|\yzx6!UfXeʱU B&ˎAsmh'kkh`x,(;l͚qډܨ [C\ucوCM292y ,g{'jEP_ | ޲2b`kaiSCN,/rSDB@)'Y8u㤮U{kZe=' ,WG-+}ԛ> "vDw {JIAm)V19V8/:}I~ շqvmyo#ّR< ~C>LUI<ĥ~E^ɣ<!킜(l;|ꇐSJ)03f̘7`x?{QϴyRǪ?^H?%q,3k]6j˓z$GQ-ofT?흟(g7Weĸ\,Eg;۪vP} 7{]ƃ*Z~bwŖl!|لd /ycƌ+7-D52捸#虗Jy5lۼq=/xGeD.v,xPW\u#m¢_纈zƋ-Zr]TYBƛL|/DbB_j]n%'h;n'*iR嵉ś6VVIgqhO7.z[L]hKLOxMuEOs3N(xt67+_VqT1 "W6W)O"$ql@'~RK0T 甍IϴIuQI h{ĉ<*Y.xRBtD=kː򒋲A(dЮ 2"G-R`ħ6k(HCfE]?fB~<~̙<—ѣ|a0HmmKPcXi7s|1l#1ƕ)҆?hk7d\?n&Vv_\uDUe6) z-|Q1^#\BhǾx=?ŏci NSh|ƌ3fpcy|=Un۞('?R9sW=wr3?Qr_}?U>w}6@?Z>WLy߷}S0EPnvw?Ql?zGgiƔq?#_,?U,Ϋο , @|lBkNM#0+9mjK~Z6r5 x 8E䀷:Haz/>+)&OyEIWsD6ʈ8# j(q30]&H+2DwX(v)YXh}΋LYfˣTOVh@(2X_}$FIe4L ʤ\*9"˪'> ؞ =B @W+ѳ3|#{ghy"5υXG["AB. E̫yBmTyrγL?A,L)+2xmŔORR- 2z:wX"vxNꚶy~El1hsq\B-BS YV.V|aAWHy-g|sa^;m.Mx|6Ps1_ 㞍 5k4i 𭾀 +1> )a?ˈs'6\;QCPI'Y 3Gll8ïO4eb2#EZg#'6DEۻf0G`NN욢T)2(Bto&vHql~qDZg\0dEr#h'x[{F"I5A:C.Rٔl*Eu2adNt9 EjD^8 mdy*MJYfʺQ%3 ʗ$RY<С $ic3Voc{[U ??Z~,O?[>OkO첯"J`B[!/>{_'|sؑO|&}Dò}us^HQ؋T}cFKaˈzZ,~\a7z{J;*ON OL ж ,8x^#I;-¹)319 >\v2Ppbq%Aw~8?0Y+`#~mMQȴdM;Zܒ^F~z2eSuKMSvGuFB|`dc| eY.ʍRN@*#P8/J-L#rTVyh|8+Y99~v1G(-Bg୹[<- <;aA:3C/qUB@S *'r;{/ʒ.Ϙ_Y?_0]ᘠac3}? Aqş| S9HAw#+:|Z x8W|:@qGX5+ȹ,f)VfB,M/S+1Уҕ3' A#ZmEȴp^Th+riI21tpB:.⻋CzK^{vѾ}cEO̘1cƌ7=~;>g|-cܯy(w{~o+7n?51◼X/_~Z3{ٗ_u>iM'߉{;bvǎͅVg{x%mf.?l[]yG~ʏ1ag9cƌC&ul޸ l>22~xG)}>Q>SNQ`i6|y2*naݗr3+872A] p!|mѼuflE\UR( .#9+*P5&N#POh\ȗ&*6U m\6.୹ 7T|G[(p,t<=Sd-m%H6aS'T7 o_=id."EY"Eg!zvբ_9&j`& =)fj!!ufW"{JWy콾)Γؿ^""S)zB 9%)g'jc 'cen޸8:yt;輜{E:ISMtNyA y6mק1Z iDk屙%g 9h^E9;uƹ УT0ź.Omr~ =: -%{Ay?"[ pa\8;p^k湹yLwo-V\Gj>0s<}$inubxY Z5(J΅|KҰI w}ptm8R^sb3H&# xGdBR+ZynX$>HcDmeRԑz;Z$ zKغI%'ŚhU2 J+/ZԑPկWy~ǿpTqDSv~6H-LjmUzu2m~l%Ho kݞ'-+Tg=k0t |["Lô O/ +qm"U:rA6⹐}v]MV2xNǩA񌜗 ̵l4ա |"6\q ?<MFn6v[H#D6<Oz@W&P䕃 b}'VTO[*#_~NQY&]lCY! |1A{qmIPSKpV0vRBR0ş1cƌoJ|)l4Q_}Ii{ww:/KxUE.O]>[cV!1iMw<`Z E;cI1>KV'|o0G|f̘q8ܼaoZx9qu߉w#a/l~ҦSwtǼSۿTG."iب~} sknUs6Q2`^)#l|Л#{v'ccFҒn"azAySvB`AU/}lӓ y-3$ U1{KT0jAaLcaOD{ "gMc&Z4eQhk!>CD&eKp<3_<(@'K#rogCLmMW@ 4rq2mEɸ #SGiשR;E Q鮡,cqPv#l>vMm5Pk݈gƌ3f'sW7|_Vox~7} _m\#tE40<"_P]**`VKlӿЯS5/*N|w#n ow*+(iW7񲭮/B>ҽI핟.?3fL5~KPk#=%b?b*Ǥ|{v_O/0/qO hn_(7B5S>;*`||ͧ2f]v7Y|?WQkƤ٠N]y-kuuj䋼|#Kم`զ"ǫ.P{_k^˫WӨ:/(dB&(Gjs$GW moF՗ΰ6t 'w@7CTt9H^viQy&hC)!2VŅAԱe_dwIN7xǾqJ=[z5s*< R)DĕYYNqZQ񲬎WeZPefAX $Oe歞 p4v9+w.ʧ+iyW)%ڡ?>;i7lel&클MکZ#.x'UY1n0QdÌyot G|X tϲ'$B$f V?ldeh_H?7u ֱ@-SA:N4(bHT_'?n"g'=[C=0~X搓Ycn? Re.zrƯ>f3|=lf |SAV69QO<c27pj WyDĢ#T.:F5M#Q5d6d_YjGщM d1IuAv()iϵ8^gGմ˻JQrȾ2| 8waB6AYuxYAmk]D1el{ya;զ&M?ڙ|4#uE9:S pe\ Ge6vNEY^}3Ԙ2ڶcz dgsi5@T?Eأ)ng#ɠFz ԙa>z j8韄DUiHMҿ6GvEcڕ۲F-:aHq51cƕw)>Z~`ެoB_:`yo~,SX8pGؼԉAwH./G6?Gp ދn,k|Zͅ3{(^e҉6}5-/>B֪%h SI|-I~z"k<_F|Oŷ rglKmS)vȊȇ?k_WM`߉XQs'y 8Z{2kF٢ʊ1#ONjdY7Ov݅.p bjfs6"G\ ֌.HA w;9 SM%}t-B"R>im?w@  GP+(Ϙ= \-w8E[n wn$5S,AL)҆BgR$G{S̫g8SֱoPG@;ͳFl S'EgwM;"^ypOማneqq qV?or8O1l 8$KcT;(;9JOYc8F*?4nPFQvh8i< Sqc)$Q12 9s9:AP@E<s :Q@vcD"h^.&zixW+O8_Ύ; e{ x8~9Oa}B>-?ES*>%U8_us<{n(8W1qc$yKff6tkpT1#u6+NAYo3k _?cPMiPF'ߩGG^PK55H{0{#[jތBNId,@1 y<3AҐHeTblL#d^g=| aŎ_dRv!oeUh0 ܺ;HE[}MN^<ކI6ؕ59781V{LfXq;ꐆ͈ak8 0e/6ͮm-.Y j8^s\;C{;A/ K7<|\|Oo?3fs[xs{ok K|ƿ۟,[~򯗿KK/ˌxא*Uo_˻Zg̘1ck|ʻ>JY(eyM" ,}߉2~ ֣ ueKL;"z9W*SaT0N~6Z/}o.\aGS}0/r\&z/o{ҫr ͍ Z7fs>@`H V&,"2Ty8X&h b *ssxH/&T,@qre8 9x(OKn X-(hg2hi \b^>7+7p'ǎZ2hX~Ķy0-փseF}cq[cMd}~f_?z&rd7WL:̠_G_-F84XbUe;>=wy!kwa`Q8foK%57>c5m 6ɈSGۗR8Ҹe67i# ?y16E>++?3_.U_@85fUbi@2@Ts@OzO :>Үʸ#Z3ic8WՐa'pⱬv2uODfC:?yl9%|T>ˎu^'ZB ݅g8փަ>JbuN"urm3UKn`> IQN"9$zջ5ҳrgyQ^YG_}Q~+_+\X4 zTCp/ JYhSxVƅ܌x\.@E}ѽĶB9K&]6DlIE^gspcB_<ۺV5YFbG ;q ΙT m6SCY%,TъvMXh\'<6t`q\Uv[{]DĮxIU??J'2m0VzدjMzޟ1dІ>C<? &YAqxB'SoDfт6Ho.E F9e[3i#%pݐq\Zqx\;W[y#94m:S}² d;g̘1c[oGnFgby{/}/7oG=Z0OJ󱈱L^puF,@Im48\/SfBp#} yVGh FD,[*œC"$ مC` vG1F ٣mP]d|_ 7Icm͘uQHԠ8.Qdꌮ:Hc ¬yyџBvBv'h &gzKB6Ȅk}{T pQ 9yD>hZ&AGz{xp`B&\!ꁆ kxSlfzH`x"'m׈c~H;miw3f̘1O/?w*O~.~#|[~2vqwrSOQ5FSf̘1cN+4۞;}8ߑO~g9Z9el!77nc]kڀqr\\ 3#m/nVe֙m>cՓ~mHRB&m.0g3H{VE7ƤNI5n7&vz'voAq[rw~phAϘw||`7N Xys%XO5->UEQzKXG‡Î8#bu>Z_G}Pvu@5㍅v\'8~↋s;A1,u!7;lwԈL/q)PGq!bIPMR:cƌ3f4j;q|oOC#Oy(77DW/`ƌ3f̘1#kCĶ2rƅR]rY1 ZUV׫*Xf ">]ݱc]@,gy+|()hh;n[ˣ_GkE>Yw~q7[P;mRO&̓FzB=Ww0BhtP Cd @޹.P6Pcdkd2~cRryB"K!-yJx&lڲIOmpC/a@@øn8?ih'v 9 c"t3zr6dzКcl㌭&Քc2.H1q,X=u$ _AE{Fp6v[^{8_0lsgKSP[( yFW@?wMtޘx/e:u ?kcw>FюE@J5f Y: m2Dzs+#vp>oX'hgˢOFV+F@٦ nyި ͂k8q\ǹ3cƌ3fp__K'~Q_yQ3f̘1c6𫪑_8 ޵];h[).S ; X_141xl]d~Fr^$4l$ 8Q0z-*oG~vlC#] khv[s\YӺ6?;&N4R[ :S$l'c{9cg_X,r&X,5pPAJߎ-9Z[ ts~رRxga )D$\b0jћ{lT1pѝ9}T2O\y9$$i,m>KmqÌ-W@7q2ϣk:ga;ϩc^S#`+/3#|6p؈erIͮrH'"}vYı!Yc( ^AX>;}(x'0a^PO$6D*F'(a#f&cr~<-LA 1U$= I듰s}V?r[{CtwIQuru}pn|it8UwbrGֈt6j#Fkw(}F_ǜm.1&~m>nt+3K+_~7cƌ3fl>Ws'c?)f3f̘1cƌ~_l>| @N Yo3@I>h$Q]ܞة ү49ktQo461ƒqPRιWϼw ٍxt/XB0/݅@~Ϗ1>mR`g܂zѓySzyS%EWBlxPpC;Aa}yK/AVX󠣍 kn ZemB 93OBK`xZ?-"\zmE#T7}o[&3P!6I 6oh"dY(s_o#qaQi%a.a{(zme{K؂FeSk?|EIʏ'f;f,9? :Il0G(geF`mk~ٲMidԿ8d#CqB_jv=l6[ƶ [K# /lj$;qhܽkhr܅=Eˌkǥ8C1%;',%̊Of(dc,YP_|)ﴱqLt e=[v ω3R9uLhK2=4Jg/U.pR~kmұ1PD-R C7;\6VnrE[=d@c';o=" [#_ hSTa6MՍ퍀I;f*G|*m"փ8t7cƌ3ޜx7.͘1cƌ3^Ox~FǢY ~+To< g]|{.d{@k3@n-m4-}ݹC,nzeWi"\S$Kdz˔A]X7?W c<)kD^ qT>[i)8xC=q-Z넺Y/=-Q4`< 456׌$@sc`|}i婁zP<*C& >zǞos sY ~woC֩z68ec$T;qu좻o(A 00[㍙\G>Zz6P=]HmVcuڂ*")4cƌ3ޜߴ1cƌ3ިg3?ߔ߉M3W%?hM^+>뭸 WA_ZF(hT=\d>+{uο4ڪ)e ٬}eA=yݝ8]1sr%(6i!]`{:%1:flu 9h]/L qZ.e|hŀg Q?|#hNhwTV1ETR.(F.:flCj 17}b(rN1Y>B< @Z@]'Y6~hP\)b YV9p=Ϸ͘Ey5^珐xoCیٟѥF1WxIqHY.1.%"9-v,ghqnSړ!Ie}dB7B{m9/ޢoF6tb>yf?r r0߈|tW8w@u]}A[>TMe:kxt=7MCd9;V[[QsfOAɁPށh#ڇDh% n^}A{SD_r*oƌ3f)׽oT]F3f̘15?f~F9|*}|F^]_ȸuK:}–p"(_ q #Q6a_؊TކDݶ׶A @^&=% KdŅ~eD(k~2ό#mnMĘiԣit#7D17ZI+Ȱˌ<?c@{1C#!LRUP!@懭!UbmL6f6d;!xG;| )!oyzpR~j Kя=uoad~2riLȗŕdhB#Ņ\OD U5&QxM;VAu\ &d $T.hH{(6*\iw.l% PfOܑ]WR^RyY%ڝ߁E|,+")T,|;İ1|.7:P*4&>?BYw15&فS{ScԱ9਼gtx-{:xYɞ:?<'IYONn?S(K@ChG;p IvGY]%Xh]Ǵ'WȴnOܶ[fN[n.ڨ wT1S3|%diT,/G?ЃTmnWu+m&\ eS#g_vSzDf̘s=3f̘1cƌ3_z+zϕ:)_n|"vUǯ,u!cϞ˺vwcTىS% ʎv GYot}$de0NYՓ2?k,- k>~/xhl_h3(Vٲ|o2.|I93uyۃg~וo]w~syκ?缮rCcF呐gY5VK ʄȢ!_GtݎX4rY/neRlTX5j9}:`^ett A#d0nR,pq3kx`d˙%oe{nO2ßAXpcT=Ec rg2g$av ǰP,LYc~VOz ח<=|W\ ~W׽w۟+?ny_;Ѡ{@O V!7ټ[-5APo\gA0^_e[,}y JL@^~܇`SU7*9^m6l%h1eYT*Z4٠OXd4oѻŘ^c_xnƌ3f̘1cƌ3fx-|=iTwkǾOuL"tEwD^ Jx!6k S7Q>`JBrM5C/mD_θ^1~ق ^?v-q$@:%dTc̀Qo)A01pcl DD n Nl؆<@n|sc %Q; ?ˀҬC!HV&ȋXnȪ}M -xx NÄ(M`eR}efk~ mcfJ|yCVa:tE#Ҕ֗cqE*sZ3#'qou>p(h7&*ꂘ|:uqN=Xp,MTⱱ1C]U4&h'_psOP`6t0a-udr#^1|.Ϙ._Az =P퟈>1cƌ3f̘1cƌ3&|/͡Оh9mwS-# _75ЉMU1u-*F_K[@^M!-H], HWB7:ڱ -|wS6zcx"~96xC$BlL}T:Y !j6->2}R.c5D*<@ģO&u8(0O]0lS=FW1syV ;M1""&s|DY, ȋ>&DShGd}Җݑ͞lh8@dRCOvAV5#>,H6CdE2>zYggkfqGށ3EqLqЪ,VIu.)?z!ö`Đ[C+)d߄=q =.{l~Va\͘1cƌ3f̘1cƌ76x|C;>wU|[7lQkhS5oPF[LmVcy6!GN"2yA}9xW5\θ,p Y]uͥXPmu0:Bk,%t\xhE$>VMkHX0:& G\6NM yPmq!*}s y7> V4V+nRY똳;@D:=ւ |QN8miL '=iwFٙ= &WC*g#%`F5r+JP24M DhfY90{W_H@S-sKJ:o VxW;~ FJ Ћˇqj HyJ{*(D\1Nd'y[U߷ccKcAT|Q RS ?Ǒ=~<a%Al4s&Nx{: Ϧԁvh wPQ#1RfZIDATC56lvealxc]/>”4 OD+m$0}Ir)ψ 9z lo$S-2b4^Npa Y[BQ/ +GwD85%.ɱ%)D_Ƀ5 5\iqIcy?h aUFh/ CZTtP"Q)7ƔZV?XDx9WS%?+aGlmxc`L7TH#D>bJl ԇ8IP#B| ocg&s zy a(3dH̓r\ԣ㹉22W$ o OketRLW%9_XW(c3YCƱ_63,O {юr :.Gf;NLrзf͞2\wr/{" 0<}_؇NV1b8r+&VJ/ڃXR;g @;Xj9ƊLp9+ "%18%։3SPH:q.`dGʏ%Ԭ~ G֭]?%Pr!yTc1=e,>W*<6vv#vӊzRMQR 91e'q~I֬fiH"f)2:^3n&$xMQc SL83#9ڇ;߅3=q 8_x>z h˯  =5z~ySSc8t۷"$d&ڡ7z+"D;O S.=t8hs!gg|ƿu!#9ou 1MyldIVSFr3f̘1cƌ3f̘1cߎ[y[^ ~.;΃8ڐ|Qx!i]hlz}C73Oט2:^  ڣ|\AQ>F$Zj1ϐͅ6LysVjOPn zm %2Pxyi-ݖhPvsKK\!:#Ϗε<( n\8^. N&ޭb:*˅m:eB!O}+Stt.g:89&JĐx@֡'<ʍ5lǣLFq 2U!,ow ]Sɏ{sZz\uÇ6 {_cn@V8X:D̃qHDN>[=,s G!3841ۮxԆ)څK{<GvO='I;mdy8 lO|űk1_<&X$TA4=؋qti(4͘1cƌ7+3{3/O>3 Ug˓?S3?Y0^'{'/ᨐI3f̘>3"}@}ngL6_9۾ꫬ@9ɂ3+!l} }ƞQőq>ƒ4cWGqlpWqsN/q"h`"iTI0u✷ ( rTM& 1.;|c>-yP8 Ƣc^x ?FbXȢc{lxDxLLX~z䂎0D.e.# P71GwVn>/?fE .PQ+”X<#oxV')ϋ kcdsllt%`(iCuUP8?E!zXoBʑ/Z=B}Le!2BߢX^\p5&Q݉Q9Mԭb]dVJ']޹H2gru|&[iP{Ӈ{HzƮ◎/vq m8]]1aܫ>?:Vܕk: 볺C0So.?Lmcjƌ3f-ŗJ#'o'xC\^zG/{c^"OztB{w\n "yF]t\߁R9mTAzp?p!r+RS>?$ eu<' _v!iK512$CnwXoE)bcjzmԋsCt}V.εPc<ۣmCHw;S9:-$ iB}ܠw.ay}fAhxV֯ I,@#Cbf.+6c'yDia=r̘hGM kc]g!Qe .x^UmbN12ؘNA ?z赏bIT/{0^h^Ss(7n^o:G&>(ciYE9-osؼd]4P1Ag^6 룟z<] ޙwh'D$sfiKou,2U<&Q0Hl?A*Ⱦ-]#}$^$z>jnz| jt ʡ/'H1j^7`,A;:bI(0m tm8zB_MW)Ff[4~)-f1t,ȡlÛXF3f̘1cF>xyϗa哷(|[L^*{?Yn=dScOPԼcƌ3g7=v O=W^(ˣ(ioi+6y7>O> q>s9S{_hߊyծփqۮ\5Mzо[k ƯGHzn2o`l}hz}H^1bo#4]_P˔r_gz h):Y~Æm0kVsiȯ f17yMv<0QZ:6e: x歜y-D,kM8.#%˯ 0?٦Cy(ic[*lO**'8wON0ϡhg7B>[|kզ dž|r'컘8~TyjAO@V:%o{=`:V{jsikZ&>ٰ͸_c[v=w޹/FLLfD= t#ՙi\ن8h{"h`1[v|ƙ+j~'nHgB,|EYuҐM~=l@S'E.5R/& _zg̘1cƛ=\)'c/}wyw?by)j2ڿ @VO|*/u3E؝{,n!);⧻j-mIg-GT-sqvGG6cƌ3flӆmMcpc;t?{~Wxv]cyC"1u;EPfpL 3M!~1XإCڲzy "[meKP&9n/d}v7X2jhu3 _8ފ}q0pQ1U)7pJr7oR`?#ItCD^P\Я}c[]ZD|,7A99̺gC,ndQ8(#bc7}H]a`YuVߎ=z^8g#io&>S+y(s &j08!u ?A6X{I?,9*(g߸Q~nz^AQ]t=>c q:$y" :/蟆q Q8mDc( h_N)##C7hϮmVI.@NM`[?DZמM,43d4s4fӤ`WW}fоHF>8I] ?h r<-EG\u-ex` v@Ja(٦-񝇔Ϥ=? źAǎ@햤cjwMJ1=ٟ1cƌoRİÅCx}RmHn?8|y[vw+>^}o^({fPwX~^#D)7?c织\> ۙT[ŭ\h{mq/7;3.7K#nj3f̘ώ|g|Wuԝn~smA*W3Z+;BVP^vߊCuw^OMڰiXcU5]vסrSSQuk.u=P& t.,3勘S[thٵ&s1_\JBj\r h"ĺ rXq(Ė 05`֔a`r xoioP$:EѼ x\(2' {JLd2Aɢ;q؜'kXwuv;ǰ b LM9<=C ԡmp@?L9嬑[yf-i6:0Y H)jKF v×[=DG{ &sƛbr{-CSȖjk1bmٙQAaCk<@Mec(Ao(V'jж"@~[]G9b`S09K\bZ-kwKRR?cP$*\!,@зq<Ή$ 'Lvb"?@4YdCД)ǼcZmmQoݜuSз6c=Iz=B_ Ԑ=Ĩ 1XĘ(nI`{Rm_Mkޠ3u"mۡ?s~uȾ}fs3f̘1͇>DyAT[]zs*Am@< !F^@9SSӑHrQл#ȏ  }(!tȎG KZk}?G`}a#C>|tY O m! #9snvYl)gą:D-6bSRD{Fz*aCv؇̌2Z}d,fh]qޢ.1j㐠19{8'njcK;`C7cNBn7pH6Eҙ Gh D[JR#Uh`',ҵcFqf&ѸNeq('j8Ju Ԣǻ"nm2̘wh#3V5! GԕM? [$rƌ3fYM/T^.ϗOj67R=1!񈒧]4CwK//.>ş=rwp"O~Q9[drG,|h'̘1cƌlУ}|"M<^ihһj66FнV+%@]K"s{e6kl.K">'}JHl"Ayt*d2o mn6/LS2/{zג[;XSDLS ΛDc!EkGGe6ZI޲ź,.%sKZ)پZlc9H#=jA4 Yĵh}^)\& .Ҟ=AB{4?RаO.ב(EMYF%_Gw#X0DGg"], kPld,K6 bm$e;ޙ@:GU y5o [6Ao){Ȳ<d=PB2nچc~Z_zX$/6&7wXYNͻfȔ$ tZ6cCrE)C~,X D$6?q|po6vP:3#pG(Xv^c?u|+h>67ϱn ogYct.kg}U,y$ʰ386G_hPI2|*B6VSD;$=#$[[mƘh4xzD#:x T/.qO=Ͷg9-o rs=y;btd_bZDu૏\>ٽ2o-t=ug\Wפ#p/|TxBS46} &K 5mȁrzdYu_"Xn%"h/GkTrKZg4w }DGQ. H y5BI#;0#wn,h2Vu=[ n{d^EuWIV-]TՎ |9xZIL[wOCGA6}_/N`B ;uU6Ty<^bV;Me'p]^)7Y=¦wߘ1cƌM49P+#$ LY;p.Rkl[?DZ9spz Bm'1O vE Ѷe/|}vLR"d7O3ƐNjoŠ=Jc@syDGp<侁L:9LxR 9?q\ n6]5fο$wr|-1C-h| { n[3GY@>ϸ'!Evջi߱wE_؃;mR1@u[Aݱ6a4Vzub33f̘Vc|BSwŸuϽ/voPGNm+O}" *wŝanݼYȇmv+T`g[r|8;i)w3f̘qבO;)u l1|b$?t)l}bmj f /=VfHoz'0Ye+:@!߈e$i {i;r'jˁ8."lka!=]諶)}WD (lŝrr}q`r}vjnD|ābO@ݶkhKd9*W&6#9/q'Zˉ6#o 2!AoIՖn Ɍ0o0:{⨼wo՚ v]z {5"PdtQQA#CQl/R!0h<hӧ: u7âO'{POG& ]¨H*og^;͌kOmg+fT)@NȮ7lU*Nݿq]`ᘦ~n+;lGGg^m1i[oǤѧBAO<:.hrm5%G+21 6t7s|W˟z1c[ohq./X1cƌ3f.K}]sn몔% >g[#P|7H {oT ̶T0&GlC0ۦu}TnH6uخWD]6fn\{hl zcHm1'&A\Pӕt@2uF;_k1# _^]qtQGx]EQ~׾V~;,W㯇ckTHtnY#AWrԆɛahnli/ULetG;&~jϝɷ CS[h!U{ Sz74p~bs݉'b6*ǫEUp.;ZoĹ@9-o|}߶,sY~3dxW_9+?.'~㬔Z)_;-6 slG)]M_B̗|ks|tD2ǣg 1]lzO5dŻd_ĸW\Ƽl.rc:lcűނ2L)LKlA`kB08tZPSuԅ"j!wJ/K!wM:h7xddLcud`Q`ٴ jd[VgQ\yR+̓l 8Kp%SzS!J&:$os_x,My0Bܨ>8:;Zd ?u5l݄kD +IE5`MK<(}"ړZ`B%Xr. t!wO/;*oGF%;/&Qw*05v0|Бy5W|leAɚ7Huz.9cƌ3fѠG܈Dr(*Gy|%F`s}ˣ V5z'N RxJA;}p;=ꔆmذɞU,|–*C<N\3.GA~в*Lhn9d.ڜBqS>6GxtjvhdSwB`-ZA u %!W'ThZ^( Bsp9<XJл !IЕBt'}w~=* KD-vP'^Hф]Q 2>cƌ3fnj<^>|{3f̘1c^q_u 'Wx^Z~ y뗮"Wr>0fZŐ`i DžV׀}xdAڂ*B7nBʼ`<%2kK֞e.RՅ (󑉶^ayO^k^O![Z9!ӶŠk)E0]-Bu~Jb2-'mlL;I-&k,+mCHeAU1ٿ BHAD) |VSx eg.h øD$>= )РBu)+RKo1 @g%8|A xp?Ay 7rN@tJS`1"VeV."s\ j#e)P+,!<: JtǖNrvg ')cc@@F% ȳ+_Z7 cAÜ˙(Fyz Jlx^+7Zv6{_G*<e~ALF|BO Zu>DvHǀq۱UUF^p|UIyPrу#) V 69kڱ/ҋMmVNwAds^Q{[]Sb72A! mp(1%SrF.pIb<׆/v޸a'`㆙3TaYe8F5y3 JP}1Pɡ@l*,4H1lhi>ɻ†}zveu>7R7;*%\—x?6&36LV\vغm+VhDwн6'gtcLA*jE0cM`S-df̘1cƌ7Ps)3f̘1cƛva[_u;2/2"oru!loî 0LгEr/S]P :u!_qf{?+7 Os"l d $Ƒu- =6: iPFFw&kՑRbgc8D 7B5Qd;qȖ$V0ًEu6οӲZmd͗ԻV 5㼦8yvnYyd%6؏<%7$bQ7գQXO=.RLBdl!!!IJ"c|ĊomkBDlu\>@Ԩj Χ-j6y B ]Q&Zm`pp SM]g)}[ V(d$G"EBus!c4,Q"*( 9)0{m0 :Ҹb{.uDex5հl@V?"ae8nN[c[-6vӓ< m ɽ̸w3"Lxq֒w[A ٰ S(fU\;>G xNln/u>'wdrA҃lзڨAg&h>}q^qC }@*4¸'~ҥ@o.8`^?h1?l-ͥay>ݫ ې?JEIP ѭ}Mپ Y@6Ҍy90Z`8wfΘ1cƌ3f̘1cƌB\+5}9aځ_Svkz]æ<OA\i!^r'XB_A\Bk<Vn< ?;}Ք4s5=骫#l뤹oz9r>НRJrx R/czDX'3]E UydQ<^݅X(Cp ٸ ;|C3ev vyϕ2QA?YF7:D[mAz6*ll! .-I1,8Ȕon1H{\[&6GFu - )!z<6HՓxo͇;So{\oJ]?"RmBE\?*"x|&V= ¢2<e`E؊ssو  NA ~:o^PmC{F^9د@{8Ӄ0b#[7~,2$mlFNB.8D0g/kC޶p)z-% `,𘮯?E9c]B/~Ta#yOm3-{TO9$^\k@k3f̘1cƌ3f̘1u}Qe.C}G_~ T^;%OM&Z(kG۞=@Ixs-mFFśj⛿8vF1F=ǭfE\|[ cs/&V2ˣ ݥw Kft Dq9ֆ [dhv7bRdf&~.zU_ړ S-lQ\,q[n@^&j6뵭oO"XXDS.R~ UZH6܌YvfmՔh϶";eƨ~IdPnwkiIMY4YګWo_3a~ $|fS1m^tozFMe4 2ʱ쪞:mѦ k(xЁ|~YU~#sD{z#Nvȁ6]f86ؽS:u^'Pr?qYK81$)oo =boK]Z[(U9rxND7vliJK߆n 蕧T}&][^Ǒ؞`) mR͘1cƌ3f̘1cƌw߭IW^H^Z d[ɏgM#.hlK@ĒBcRG_E7%P3K ~=?\5dz =]J.*zMR\lF< Py 7B7S濖hc*ؽA4f[n N8n0A:P4ɠ( ].1 ހc2( ʴKscNe1(޹LD b рf=SlI']|Z>N:yZ,u7 .*ASB MgggS9{3Zw7k1'J,+.qqRq*|t C76r@\f#ti_6$؄.PAf ~*! )YmV%Nc7̲P>G`Yӎ5bU(sQ-5[?clMm1nO|NzP lbAZmZM/ϱq9'Tﬡ9.`jض%(.6.3QGxY&1FĢC;. mfI|R8^^ W'dx҇g_"3Iy xbCu1$[ -Pl{'2ґ}?Nj'3[ɯ 5& A-D=j3iK6fbQg-R_ӈzKo.Pqg|h ԅC_ݽA/r62j5W0?. d:\ZqBhv݆:Z!8/^?1f 'fn oQ47ccCD[&Z:b5cƌ3f̘1cƌ3f\ S_H`.+j@NGlBfJ.ѳNT_eLPś&P%[F?Aw71|*+x a-H&Pu:+wD0+TtY\UE^:m¶!NdmMP enxdY\a2XGye-)<ޅ̸6jXB4䎴8G.+ дȵ豳Bx-˶9 E hh e]wQA%#rx͙LY!ܥ?ls|R>Gox6A̖#d V7.|);XDw 6o$/sHyk@."ja<Ѹ=ĺ\?b% zU:2U iֆ1t)"f"}ψҘ!>cBd| T[ǁZ5$uF.USjar< I9} .~l[yP*#4ˋ7w MI듑ȒLŒ󲕁&Ad&IVJiCecQ$؞ RJԈx< yR%Eʹ]DXPgoXݳC`;ہ>.pva"mHvaiϟs3-H㶶~ڨq^(§l=wB?hw@Y~r6?vwK^].lK]6l'#!'GQ ڔ hM8Gp^F.<#ASm 9]z wV: GIJ(/ԑob>w0&iYEܩ&HcbBZǹsF:s+7~k=ޭe&1\su>"%ds»0d42ä[1X2eIG״xy#^Mv`r(ٝ9*+Ae+P˖f8n/<~|lcMq>>tC""%pDDzåx̄ "1|w:P>HP >Opsn( eDaǐ Ǵc~E Q6S6x10`p1J.A q嘈*7}t Ʈ _DŽ_P`Ϋr^yO1M;1=)ڈ9!eD3$P gwԃq9w1]W12Ee1)ҠQq\so1t*c%p^Kb<8&z=or@Pia9͈|B! NIώߩ;1t8rAًפ-o" ~C13f̘1xOg_[/?[|'\@O[qƌ3f8 ?3|<>p^~>3+dw3_Zuo^]a5 ) 4uv{({q}&~/qӓNۆ&F-FPi,|m(ru;1FIT5# v^q@{>Cu#8!nʸq|Tg}QicQAqg3G_ !4s))F۪LKu(b޹6@Sft`Ev.qU:7REO![dqsY\ PtX2{e;B'"!*\,FY[&>v 10DE fψV sՏ] D$1#KbSZLƨ S؈%lGoCuF 2Xly=Hβ0m7-0og#OWoG#4#aG}rKA=60؂Z4<(*6պ nmոenOׂQxx.DۉkKbL,1" j|`"_##{&Ű41و!{8WUWE[zz~{-ֻL"`sAҾ=?6lA3f̘1͊˳Uxrb; PS1/^ ;/|fycϕ}r3f̘q3[<ϜO^"Ozte_/=<;k)\5A6D u^p.6/;]cS [95>(\cҶ~ж /~,?ߣUMwڡ$ص}޵EI8Tƕ!'J7qÆKT+cGn< ՏlAY\qstPY yuvTk2&JnL+1M@rGt\PC<߇ovw֌gKTj/c?jݑ/yut7(xx$Gz%엌h ۶9Muvѡu#PiP,ʲaJ '_,ոR&CqoQSuAC"ꋁYkb惜-6q Jkۜ& pȥ8PeUVΐ6e7 ]תX1ߧ=O Io0,[CHGx<#8ؐ&qkDْ~P|E y2&]cD\@:+WDk'ʉ>1:~붝o \`wd_'v0b2xy^h'*,fm'z|&_yAkգ@j53f̘xS(wGo}rLO[>Y?v51cƌ |pSi'/ C`Uyxc,O@|u^F;}q*mp:ڏy[t]< 2p (@;-W4B}_d2~3Tpo߆Vf\`-F1|n1 o1@(a@s A]h-3Hx.;sfC ZaUw~;PPȅ!8=q~0Rm ƣ;*^ EE8(|"RZC9MMȰ9+"[G_ygaC3>O BxgN=lܝ6$|^$c#&9cñ&llN h#:s9e7H1t(qƆxfLiܽ8]+Vcm|mbG 6tld[ DrnjUd7t"N+G[eRB`d1 铠xԩi5PD|}n+#cb8fcTcv: e~/d[M$!NlJh" bA:= |k#L{ 5Mj>nm4cƌ3xoxOox|G˭O>_ʣ_z< O ē/Ǝ_۰q"?FA݇Ǜ/n=WGY.um;xV)lqtSw1s\*fy{y=ը^ĵXda2ӊ nxL]{vimxٯXB i.[}-w鵃]g.w?\vd^!NӺN&YfAPtkjkx.@ccEKF6p6\ֶ&@ў)چ^< Pzb| |LdyЮۆ=.m.gmti\vЧ?2# ﲀnjoi"fYyU_az`

:]vOo=Q>6#nj3f̘qݣiv1cOfHy䅻p-SoUҿWz ѻN>u;[s]{uɺL L.Ьۖx TlXKHLj2Gw ϲ|Ȕ$),6I4cv'鞀O_A|GإFv\Oa~юy9.S,KosnDsV.N1xz?!H>}#صV_\ʝrvzVNøv{_-.`_ aVpz m~8⯰l687ڝ:tlz0 o6DdW+.0wfbs6;sԑc͝}O, /›fK1'hg0`.TGy˙Y//ϧM;EcXy깏Tz]z$K//<2x;6e)=s"c0 }iM>cƌ3f̸.}|"MC0is~E`- 77Nm|,SvNPk1":7]̋!9onw8Y;HO1\hs1܇oqxO<J_Q sluTWVLYjTYV?Vrƙ~vsp55絵څcHyCw7Q`.vNpa^SIPĵn~,x=ڱ?+g秨_kFcLr<8gԤ5b=GyG"X ^dcI6!R?#q7V;y;Akt>X@|䋑sܰ?e$|_u@l;7Np`)YM[T'B|]0Tf{)%Sɍ1&-:5R07@Y%q\8_.q2U'!ǞX$Y9͆y!E8`L?BzGbNj]bXSQfaz62jcl@憖4GP?æ-s*pP<ԡ 17?m2cжB Oe5F &Gd}G\ya>T!e0u0e_,` v,y8|L>R.0 `ξo@ٷ>=(u|p;<xdlj'Nvljx'}/XgB(ٟ&a[mFΘ1cƌ0/lOX/ -X~'˭'>6&vD#b˰_B.H~xG<`< tC7}̘1cƌg?nf'ЇG|=}<>ė]ڍ4ݖ  ˋ~Gx3cѾ>iISͽbuEQޘ&bS{.# \Tн\E܌+BCWĥLCeǮ׀0]N.yB InЦ.q醤 1SFsgWZjժ޳>Fio# |0JGEv~RdiR[߄+eXylA=WuOUxp!IE1|!arBȓ]lf{}T^Eṟ~X')'"[5'f׷w?0~H5±øofdM lFf(hqaˌavz`X1l+R&_CkpmVR>]Be?^"-N:Iv86*~19PcNM9`Y.SNTgf'c f{Z;'?>sCpRxV\;hsՖȼ&w{}:oxU'/vQC][ 6lצ?Yl̯L/0鷾5My} _koB_g xbҿA:t`=cácڢIX~`qڷolذaÆEg~J-kj~fO~CD{9u{3ͳډ:6o{yB?uCVek TIʦυSm?}0D_xG<O<#~Ї!\zcÉwdA$lBܵ6/XndFmѫY`=I贏u("dK Yk[SBnFơM# =d. .#Uհɛ .;gU'RȬ>'R_ɑQP=;)#h'+6ox["ミv.23u EvL|m1'ـM8d_(.ӰF_NǍMYӓ{~&lد#a8;Ld@Gz(w $[^^ 6}<[<`a\;d!nTGz"s Mx4WǁMFugz?(9ȓ=; ~̐>z"Z`8]+8X- W7ÉAa{k!0F<.$z3h7I~(64~8mذaÆG?;5^aƟ|?lOʘO NiBO/|k\~m_(?-_)oNe?_}S $>.IF 6lذy4m>Gח7ǏW)>r<[CX6w^?oēqc쁢/u (즷W 778"&џ{~Xo s^ kJxBR+7=˒޹5%F ʣ_ Y#F& ^ژcL2[-yc.UrPh;b4cmP| sYx oWb|dz}|7rHgLɌysq{ nAt}_؅E\FBWHG.lV?C: p5ӑ^'ds泬RJV:l)Y.͖fX ln%O>ڏN˟|5㿼/1b=㊟ o9TSddCG@u޾#=%s%SU?Fvce&c _ f/6og{3ses?cؙvsi<9?f|~EgQu3_Vj6MNo>ֺ.Lf;^Ox}ܿbmۜswOLrzN |]Bb66Nibzl@'7f˧LʲhC-֢׶y[ɮ-7:-@ric  cqaYfZː[l@>w}h͙8H"SLݼR&!~Q>"mdv\/y[%:; *ޖ65ٱ .nXhh}m҇|~$s~#S^wi?3߁or;ݱ#ʡM$+ܛ7v +. 9>7뻫beG=Hzqbr>" Mg޸~J-t)1;ʛ6=YWr}v,A҆~RÀGD߰1o޷Z',oCawâQIJi1& 瘨%ḣs#'6ۦrmyV_!s|/ovͶ5-uҔ{}ڗL,eyۉ%[I&^ V^ެYQL&5\V_J0>駠i׃OyZ*3BVZhǢlg* }@{˺Qmh^n%.}f䡲g@Cޖ~cI7nذaÆ ?+ӿ׽lذaÆ |Vs3 "]?>yca5y[CfuL+d|}xa' t#ߎf=Ʈ&e#mF#t<ԑl\h ?*#x2r 4cTFѰ'!BhÅ90W R\5UE>xA?4O777X"cLVsOttc^83l>@mh{g>Ʀ'Zb:(L^59sWdeWlXr\-#{Y<_@l d$A6lc)mZ?ddv =NK= eoA6\y'ctRYaBi{C̰F{ RfJtW [*9F}XNs$WlR·dFR|;xKmVenoS9lH?]Q3>r>?/ Z=}r9F@ۢ?!kZ:N'4f$4҅ *@u4>QWLRH`mmlm%1h0aR:*P(gz"'!; 3X;꧍7:=Հ(jԩP[\B\ؙ}AJyHƁz"eu'HQk>zHgPiO>/g?.^o) |jI|"9ǖ|Ky%hVPmHUF0ާPM+_*TTЛΨ,wv-f^irJ / ^(N.Ύ8pH{H|'0,yǝ=5{z[HyߗZ` "m*_g')Qo1^a◬9JUuF6 Gt!2rm얥a]sk<:c6JKckw;46`Qg628ir?p"W:}M٫s-GY>BV'ZP=R܀ c{d Uqb#榦W<_".?17vM '8ZDLd:CF91YVݨff[*Ԍg\-s('?4$bԧm1I]5 WZSW>>bBm^(b._L-Gƴ=sY6ѓ睑aﭬzFʱA|`.Gz,) 3yw{+9׀挜8~/ { \^:ǔ%:2s>`jM@{*B{N I?bn5~$κE|c$fnE+u2]DO0p7}0A&|~>XZՈEy"rG$eEkc9&,___N׬DsZk!7#̏r?^G M6qf: ݴY`N׬p<Zfbr~I}]rK)uGX9Mkߗn+}YnZa2.1.KY%7U.8,m>XX~ԛuM靠 jՀ'B!d+L̩XزdFikf,p.^s|\ w!{!䃗6+Do5X;uv,\}_9RWV#]:*f۝ďʒ=McO>pQ{sOWTVXfx zraGLt tǬ!s>+UIIR!qD~:@b}?Ֆq:fDwMa7y'sD_<r,05D!u8sqAd[$ǼL{B' LH" 2eÆ 6lذaÆ 6lx3i~~lFF$z>7꽇5潥߂ޜߟ;^_#͠&@29iHн_1`yƐƔQ7ݖ!Id_ GCne>;Yθy'O^1 yU'*޺s;"vC-ƀz[mkȪ(}~W뱎16PΜha@5}A{TڱYdsW?$z]kdM(bx0໾'a!0ϻmz޿ƁMl VƢZ[ΝshAzfPdF5O 힂5ewwBR7}0u]Ms\wN[0 $F4Xg \+3ِû`!md9rKdܟ<\O}.7y^R /S3L%cx*Fb_9ǎz\ˈx˽b 8Cre{ā#t*,݋_y |֒wSS?%_/JZ{ϣ6ov-lNceZHP"4V.lAoa2)u˹>7j,2}8>v/94 N};gڏOqP_ϱM{?yMd%-P%!eGćnDTIWݘ?|xؽT@"yן?B߰aÆ 6lذaÆ >I?K/_I'|>jvzJ?ϐi3yWWӫxN[BźDr F;Gl-yx ,50dt}blP!6SX,%'At~kaK=rg}MX8kFXzYMʃt$ R}3l]>^rf _Dmk,Gm0>))G$"!ӵZ )c,xHIA֘(+gZRHFX| $TJ|<0+'ĩ8)a;c'Vu'Z;W_$ ݣ|P/&{a X@1<'7}q⸜ψoþW[GL7woÆ 6lذaÆ 6|d#{Yq6?'2c[[N確Ew&$3Ci?P}ioTg%FmGu?]qCHkjxôےk  ό'Ϲw/)v |'3\__[lhnn}kT쪢%za(Ŏ.[`L]RL=U$7Ṩ@̦OZ4}黶tuӇ׬DM+)b KAٓ"Or]ql0 (!1}Mz&_K,?rmp0-v\ޜN,&~G1:uCJ613NiՆ˒,;wI0=HV{)TyCO(}>-7v!5kAt2.DT4.(d \scbu ٘ D툴 ߵdG|>4{- AVo7[fotHC e5PωC<@?ݣn"&x`( hꤜ#gD|赼=x_jo1>>FgNorS5ioA HG>q ;h7cG}ӇmÆ 6lذaÆ 6l8 |$y{ǂ@~Ư=3+[wwB ?mdOY)[RPC[U7v\*X'426#Oi+ V[.-^7dw<{˫O1雺,{ ڹfbo;.}"vjQ#:WɃ#3E(i@1ȾyŽ|.Ѣ]HvE61g=&veZD"P']2+Z{m`#PJ(+~諀-_R#+,yjG?z*ul7jv 豘I Zikl!7x[l"VO@)w1'J6Z]>QPH.4,y T@s1ZqXCH2ŦphQގ9RManeOوafۯo,^(yӎڴ(6‘V ϲ #An#X6,^wAM9RqZ ouĪ#ꯏݏ~FIi*\`5AWxSl y 6Φ#Ās > C̹G#JF*M?2=`Ur{3+ :C%{J"dY"uPgTP'Ml}+գk5)Ծ}= 3S)w*jzԶ0< 6lL雑}s_;ыG_ ۟9gV~,Wl_x18a^b.ѱ{~D8oŸzʹ曉ճ pЧڛˡvbtÇM\iM^7jSmX?عԨTf&`jܚ*;GW0SӮMD_ - u.5&j:9(wpuQhq>_f f<[=;G޳6zpm OqlB}vk!,P7ˋŇ !=g9+7h;2v?(wv1| m+:xX Un/yUj]Zv)wv!nDO ēY~ѸJگ]wf?'\ "y?ɩ@Է|i%UK@$ BK2HvY 5>:A;d5q4f^/_AJBܽMR]kFk EUޟsQ^ǃ-~Y+QI"~};B%Slҷ#YBe-1#{P/[Y^åcȺ'2~Bs {FDE&.᭢g'nWo<dHP2զBM*ҎΐioDAҙGz1s%a!`q'_>y,+fSOkq47"|H6l7Sӗ> ri8>ӷ~g|dl'C֠E_od7OSϿIEONoL_Η/t>|+wg<mx 𼿤( $NW 9Z`59hF,wgEQ+!)Tsӿա_,7Pݘ{R_ Mf/AAeH?8jH{s5⃿q櫗s,=nNhq:bdf>@E.b|hH^Xbqym߻Wӫ˫igX~+=Xֆ˳8# hq0/ -J\uÆ-F5/'TpkD/*>X_n x^ TnH;Z83Fڳ`zDrH'T!~Yi }Ml5#O=WnйEa)%ek @VH\sLc#6J㹞cտ?7;^׹J |D} ;wuL"E;eu{d*P~kK€Jf6釷Oi~ؑe{'DyhDՆ4uqsજ5=p{ mONO 6_ٰtG{W,Z L7r3ٸk3qȭx^Kγک5&.$Z`y3r(!W6PQ6s`uk^t"m0 Ϳj'hs<.mn8@'Uczmm5?q4X zGiZBF;[rį0խ " E8vB':Vcg;iTCSa>T^h1OX8>_s+ ~ LoWWɿ)z6OW#Z;( 6lxwQ`|r-}N;{WiOyw ,&~fႵ/Nߩ>|+w`ˆwԹX6ml8ӷo6?6'_Ϙg-S57?HgL[vp6A;Uz'?~% 6 f+;`ìl}ݷB.rG+H4loS:$ػ^m/QWeɬNA`{@$@2˱hUߦ]-|视99“wWO˳ɮ#HkˎyNُ/=;NYX;m%+lS~UHQmY3nsy6I[;Yԅ 6X^y f SVUt^Eeˑiו_M64%>,<fO4xkn7ioޮZ mڏjEec59׭!u^Plp! 2Jigչ8 zWN6z vEwn%]?0`c~)$?z>}_%t;*ڹ Y(>G# ;@(>= URNc8Uo6)Od:u5]a-$ߒX'\:.OwoujiC@t ^+I 68 ]Q]ACB6sROvDOop}!BocI8Z6@8/O. >{v𒐝`Ek }>Bήcw[eG6@V1ۘ}kY3d2⠶L̑<= `~V(<'N0Yr>:;x|^g.`ήP:@:sfj*|-]9+Ԧ^36RCqj@Gnoo|>E;_!m^΀L l?NVj Cao?7hBg`W7 u]w"V=UMPlˈ/f;})tG>ǡ;1_zo9ό: 6vs/cP zEP:Jk)y$@([7lذᭃE+>ߝ~1w:MIYl6(ߛ~ߙKMk;{ G|YקߕC>IM+~k鋩s5π?;^K_տ;}{T}'iY䳟_tkӗ>u`t]ꍴ:_~~竿mNeZ|:zutm?)]׆8F6,ߞ?~WWxr;~WGw~W6_k_/|kgA~ UoU}=h7e>ڶB6ˆXHlaVө@Yb&@!zϊlaGm"Mn=m\xi(0}AVZ\g<^1~BgHtEO*?k.E#'zg9MOoÝ[BQ}u ?@ U'ˮ sk^.鎸ܘsܮڜ7f\]L׻i]<}8QүYYƔ2sÆ v8+-27dlvW$ӧ>F\MD_c:;m r߁ZnOWg{*fIe6*i=Fl^"e#}bڐd$ zS;n|: 3=WXx"as#}1"X'؟c0:ک{;Ochz0 f>IP>ՇC@%),s똵6F̓)? ض16].IkT[&ICt[ooM|h<\[5|q"&{z e!PC=cz23J{b֨o, ]#JVTyeTc!b1! \>ɟSyZ{*|/hoȲ 6lxO=ߜOVG̗hiXkcqԗLbS?gNߛ=+=O>;SKXö_:뱯0{ :E_QSm}wG;q$?;÷k[uX>Gg3}1%8a+gyljxXgq=.'}~/fsB6+'/Oi7//O@pi5a'Ouu*pQUMY6S6Q|YƲ36[BUd.c+ۖlLRK H{}1ߣLaL:X>׾;eL{}JgjzVo KyKVL6z ~][FlҮwk5_?!br765To'f%M-X)>gh<"C!7)d_.(k:GR[<1=QOY=ɶj"YV^Gciu&ý,譫=zY?Ms+> ]%Zǝ򚠜fk Z3 Pw ok\s0\wAYӲc>@eMA*9~LZ`xgka$Bn-N"${@`e;56,. ܯ"@Q1ܔ\=*Ő!ҏt..|2$b ja>Bq6cY1˦Qv.p4ְ MGU2Ȕd'*hHϠrgT\oY,fߎ545(_5922]]|Ny3~{s0cъpry{sa[P%lJ>_vɏv!#lzFԨ|r-k~t# rg‹gH1'*>0<ɔ Y$O. ~칐yN5ކl+g`t+_}όh_ŔlgģAΏ@ө|^;,cve-8Vg=;7M=C 7lذThk+C~_%1a?e@'ݽ?8+~3u$F B#y6?TĆʊx_llOyמ85O۳!oMV|]!g|+R6* ={O@#A,~Z*ϲ^'1WZS5 }\oCY+L֐~ػ/H;e~eʎBPÈSlu.ҏL~t &?։`XlИ5oo;ξl@KPWvz͕?+`azm{-kV҈)Erٝp,s?I\II][Ph3|C^zRyn>/O~Yc5knS:$v(˱$ dW1O(Q'iJrK*o5ۗ{~fJ?|H7TgPl*~ӝ7[y|ZWudž}C:k&<{?|z;koW1n+ќ>Ƨ/}!cmt87Wc{'~ƳO#Wn^Ӿ9_Eiq 1ڬx/Nz|?swLxڑx|/5ߟ6#W̯Qe<ؓ+_-t -<Z?{wHϿ?Zl_&^GX)Zܣ~e"|nGoorNSN,*r^e=>`gi?^cx5~ ̩oƾ͙6/ћsهx`y,fчO6tn] | I퍧a`\O/$uRV?ruDlтeW01:"q@03j;e{59xyumYޠ{.1vw͹`".υͅ,W0@=%S1 ZYyȏk(bˆ_XzEy/Ḭ)`+/{UΎ-!S[+/=_#Ar~QnqhXmذaÛ<K_0-b?nQ~Kӧ3m@;7>SygeSY|wC /O'=|קo?_Tŧ/}caoX>`L_T|E6+y qN_n_LScF `~9h8@wyxL [?Gp(pn3O#<޷/~wx9͊GɎ|gti-OLzڑx1^.gΟg>nC g!>ؓsB]WʎBU}L[gihi;ƃ:ă;ve|+gAgn20$y Fu:g=0 o%=fm6ц/d8yO嘯-I?!'aI}e ۷9#OSFh.XԽwCo8@_M?x_.F 6uL_tE݅׽2ѯuq vqU^ =.h qiޮo9X3~%3ua۰MH'Oi=_<_s# kMˆ|rEΑ`.m2\ף}6*ņC\39m%;;0C`LNsd">Xۋ5'05ol٩Konn`,[D<8qkD%^*Hh+io&e)?WtECwHǵ9<"_0OUn1##{fʹxRuaЍZZ<S|]mCpr'>_ra>bjVRó! 6cP{k6?dž1?2jI+JߧMˏ< ԩ:Y~448e'pٶMQ8u;ӯ_lذ# ,}|8amÆ ~(t>5o> 6XaÆ oL;Ӵ{o^M|f!{J8 W>ӳ>2gF/QOl[y[AU7Mh\9աi[Vmu >~c>߁V ۬:W-HД9HDs_}E`s˂iwy7Gbn?9M'/'ǧ)P[CioUMDljvfg[aT|:vCX|Ožھyt2HHͱqnZe!Fmnr+ BŀiDeWiw0}5]~*_O&:puyW\Y OS*Zz>؇3 .罓YLbUYp%lsӮJ['o-OmMto)rsS;>󒤝q;.|K0M yVSH Kti Ks^EWos{13qdMCU'!v.]MnWm (!\(U[FzJ^=MvdpG?Ɓ\h9ozWm"8-?1kJM'.NR.FoͯK'>̓ QLO@(5T^2/aL"dk>2&,ZcDag3@ XxD^}N^C=nO*A >~l6P Q&ҍ8qXՉsBy*sb`SDsf8Ied~1k4 c1@(1/-ЕWe_c5gРϳ ϻ,> E99$r^Xx 'e6pwjD'ydsB&˂ާXY1uH#> %zR։:8/1b`k({hУҦW Ԇ 6<z}%6lذaÆ z9>>|l` #[)+ÏK_N~P9m>t19_ |eqg~t|+Xi[s$ҦG]g:>mfoZ'ݝklqbWxnԔ݃/Κ }ɮK!2?—a4kά`u dZ)#/`)Fj(֓-3闹es䊣X;P#OWg\vHS_g9[Y_tJ;Ir xJS\'}Yj)4ǽy*+_s5m@e%a +8Ȳ'YȿH'j[&SH-YBy< HOd;6NTN"t~4ԓnhuyi+o #h2eq˹!IaTps=y<^~|Bae6xdއ(BaS儺kw;?*h'>֐DCHz=GkGSVX?} k\x+ACHֱ6h7? ʟlMdku|ht9qÆ >O߶k)6lӯ%lnذa >@vy`uC$+F2@eo~|9 ݾ #jzQo=-oS=Q>*fCyspv̇b;Ye{#R*w-p3q B 3ytn?<\d^\0pvH_ W3K)&Ǝ+gX;W;ι\lwޛ O7X5rVB$6PjG5e oa9/+W%M lp_dFBƈy_ڈ`[?m..LZiP>3MqVlZ(±Q~X=b'XY~Gd+Pۅ>-eckm_]SJYcZ q|GCKӇTs mk\}OKݤ@}1z(} M6Hq\|S;O F:細 l-FO u.}K9B^jrvԺx_`1LC->,MUxd AnkUl>mGo3?zXa ;>D{4=>^v.˶WZ먾$=ވRc3l`A[鷊Zs%&@+#īn@Lb'0<[0%*3YAP.YW>x>}5& z6ofLUVeOS弨ÐCXIJC5d,?҇{kh T[i=粹aÆ 6lذaÆ >893>i%WcE,4 Y;z?u1cbמ U^w/!|Z)ODy>x=l7; 2F~Elܱ~t?x@m1[+Ř-ݱ@0=g^l'\A_eH{`bT|ǧ `iHPcV9A ۪Hn^bl턨AfƑE`[Ffve|\9fR-bSƥwMqnqɿ,u!̏n?6 ]{B[$U9 'ym:T(*zOց=z2 -LXLD*,W.&U6\_/ws%bomriZbkPbWtْB+-VMuG4&iΤ\ii"^r=|uk}NTؾbJFɽk • ,BFLiHUy_#m,h@w0LyM}+ch@fi34Ͱ~ n fSG ~E[О lfq"IiZi' ,=K]D;h;s}-GjS-v6ۛȷDi`{-wxfީ8rHIWZK|1fZLKY X|Ykl9鿶3Mv_Xxh y?.А#`08BO`May uA2&PvSZjȚ 88GIkѵI!݄ ʫNE5i*ØpvԎ,,Pʓ|\UDzG*Zy6rkZՎ[*d5 ɘd3V{sϑ%5O+ }jtZ“G:'=ѭ8R '"4cr»٬Zh)"=!:Ć&իk/T{jt ،Cnto(b8Yv]mƑ]'_aծwҿDͥ]Ax+RʳF _zZY`UW[w Z3m8:Q a)[߲ DbT&Ne}F-r8h J5mwtG>p[9aC5~@+;/}ZCcA8 LS}gٓ*K u#S1 Q-Ǟ1?3@PmJw 6lذaÆ 6lذȏfI&^sneg~^m4+y?Pr.Ny͡'cbsqd]Swh2.NʛX~_#F .VxΠloյ|?*cA}ckv̝SQ<{#*;àwAЅֲ0ү<@I9Ѝڗ[؋P93gȾؿvGQ 1{ F'ȶFܰaÆ 6lذaÆ  ul_~2>\}_5ĺ)e=-ߋnڪLPq 6or0s9o=4v~i3 #ܛ|s4쇭GU_\Z@ ^AGeFo%3x E⣱H5SCQ#?f5iߦ2f?뢃Sʛ*:*Q }ԣ.j'%s⏚t } ⠉1҈e&渥b >4Ys`֙Tfmu%үk5~tŚN{VJGt>i`F~ee>]?kU&%r˨9Aj zԾ5K^*e]JߍKQ+vՏ 86j0gm' ȓgkyԸt`Ns<qh=dX ʟogtPY6WW{443bXsÆ 6lذaÆ 6lxUZ=c$d#?/?gl%} Y8$2=CLjA_DF]}ED[ dh{ӈPF}y <'rLF`,bŷ7<o2Qǣ=aщ/Y'׍LŠ0T~_)ȚBE_^\ػ&BDVNl#mxӓƆ 6lذaÆ 6lf%xϟx"?4<8ba^{OR͂v5㨻E~1VgҗI*EN!ԍkH{e_{vhfiD]խY=5}= #?3QƬ3CPbhn_82 pt:o"+88& VCvAP-*=QɧL&zgP2v?U嵾C< ܁. c)ձޚPv%:[8yeĦ-b,7lذaÆ 6lذaÆOk|i{ybЕ-dTt?@e]:ɸ6汰,}܀lh .ԺL ͘GU6t4UBt#2z.GڙJ8 @aL4.&rF4#wUmkRAe@$FA (J!uNc+i8sK4D:yŢQ%ٷ^kŢdUKp/}[jiu-V}@Z1YAXǦ2&O ,6p􃔃Q `-(_jl_#qn(ܶd֥Q8nSjJ,?#F==yD5lwk|L障~$Ƚ̮*e ϝNWח-|6cL,<#O bsau/툽t_'ڋ ?_Y lY=8^[vv<Nj`}}UQ&6/oV vvG:#^}0e͕IIy2 :Dg'm푳5 yb"kPHaEKY> fBU|#WtαE8mذaÆ 6lذaÆ ρ\Os9xgg LdgB[lZ}~t."n6+|1^5NGuAEڠ6X7[aQz!ru ?gz77ڄՕ6 O_EEAX,50R% D{hRlg=kBn"x ڵDz: H̅z,#c͍,ʦ t&> GQi6o?YXm>j=1|9ÕԎH: b4Qk坼9&UC}e#:V8+F]13ًIdV?JŞҾDlǙ <d KL6dbhV_.G;B60@1_9v /2( bDž1X0nuT?TƄ4Oa`ߧe>m,@cP3Z\㟕3Q >x Xqco2X.eNdϯ!V^S02֜4  ?̖v??UAS}W[ H$O2dM0 0osG}Ld9mgc1|{J矦RdŚqL\( 6lذaÆ 6lذYP>ϩyG=Xn:h$Z3O}둲Ce/ש}>No,>bˏe~ޛ>6pXs>;^ 1:GQOI S6C6|IC&Iu]٠۱Q ZЙ-ϖ rn^&''N\s\rAO6>Q٫ݵy2T7l&eO')F<5Iډ~g8E6R.6HA-jg?M{~aR2݊ k}cFydE55iDSoao>O ^ênΨT =BnPtrw*ioaـXo3d6lذaÆ 6lذaÛ9MuF4v2Mkg}|/aTz`^EaxbCz9kh4kc!e9ڶz.t.Æ Ḛ;K &кV}A^i^]u~APN2?o;6ۦ炮9v̥|qM_2M<~ȴn$'5S:,(<J>&<0҉Q>m@=f7z,e@z@&ok3_U0 C$D;@}͏&sj LL2ꧽͬ8'3縆2K0 aX}32=LsZGHi'{F@VxdS,Tv')/$ׯ^鈉|>B>΋/rZ0]L2GP+ԡo"a _&w/'+& Dy2fPq3\`Omu {`/mysN6KqH!:Yίa<:9WAy%KmFٰaÆ 6lذaÆ 0i}} 7ȧ?Sp GԛEY~ fk;8&\h{3 N0ssipRbYXl0`QS{8|aHYVZ|բ&q,eǢ"yfe k Z]0Kh&Fo=pۙŅX >~ (l6z+9_BiOO0?qT;\Â:eS}5&O`S6.gwq;%^uC|>c+-AmwwrM ft,˶̄4Y,Bx"O]#2-7rQޢDK ˯$ĜN9<C!ƈZ0YC[>ޑI xjAqeos&m%yŽszvnW@Mۈ#fx*@A*2HERs'D]-be~}"o9H_j俟.`|x)c*; _'T9 l95^=X?pePzv^H&b쀯r6}YQٱ:/E <ɺ 6lذaÆ 6l\MIUFGEW @wԏe{~I/*ֶA = {1r1 e{fF"aûoh6j|v}sA\۵jzZx&/c"uE׻iw}mVh' p =nЮbZHy61Kc<7qoމBLF6ȧ/l渺R\YK_oo率BEMgLkYnaZu- |ԫe{(qqziƈϒmAfI ;cG!9PmZ^e.mNf{26z2 +#D 9褵)DAc>g>ǩGM'\gY2Q@:#Y馿-::gl<Oa61 u,@M|gIoJדM.>/Z< _|"1iǚk1ȧg$sҿHg{[T6 ,KHG¿<WPZf }a!欽5,*qSp &o ?ފcS‘Ⳡ>i;Y+sIKFOiFY?qzv=/(t윁sL[RYӱ06lذaÆ 6lذaÙ>eR;(Ϟ|>1:ܟcqOGUyc{jH'n>ҦpyyeƱQsSYReunhErn|[>͝շ &$pΛ!_'Ǘ|u'M+ ٽZм\5:O19Fsy.`uq+=/;:A\Nia]@/E?H?W6:nWz^`x,dqtPq1ssPtq.A<ßN\I1N5ڟcխU*0'sʌzԛq tٝ:5 q y2 QK<$"60^w!ȶ)A]DXI#Ss(Σ3e5ne?^"e Zј썑)=nNaY2JƪaÆ 6lذaÆ 6lx&]>I:JYQ>rV{SjH&^lC{X/ ܷ{7,P%̝ͫBfe~Z+ 4fU1?#/q<&e~n cwٻf @ı-(#67";q=]+î9v?s8!ײ3G=X4By+ V^sAʃ?Wi8̏u92Wbe{bd F%sfuBʖyksՕxo5z~-g{j7|y}rٍ%n/_{+2ۋ.nm<.on4)7fM93B/sHg'nvL. 9qʓ]N7*|km5KZ&ݥ]7xYEJO|44]BXY 7Hpi5=[㺗L\pweÈ;/slKA b-͑f:~OHnqzRea&f\T3j0V#j:p",m1Yw' 6X W̼/mLtԏE8,7fҾQ-pLe)>GȂ(ՅvD0b9]pmNs a,=[[+;5t[[c_ᛠf;>f LJ>HIDATGVQ?̯%ui`(ڰ omAm_ g}1rS2:˿ey5_{iL;?G7 '[-jqLp+YcP:*[u}!4!LY]/̶Lj\Hϳ0z#G927Ce'Zr (dzڙsɑ,3=(X`{ºB_5? mt-|Ͻ`{c(P'fA>5=$I 0Z5SQ㸠cߜ&@$w\C-6ɲ5 7q!JDI7K(vrv+ЮM_`moذaÆ 6lذaÆ }?zYCSl|P/3|{?!PnR7Žɐ/޷4uz.S/nRF;šC._X٣@}%ͣOum·͊ C'kԶ1 q<>CƗKac˫ik_w/H@ɯyvkuZqg;nn휲cԃ, jta<फ़~Gj^s8]R r)5.]&l+B_EQu?Uxť6qFbvDxSd/~4YnU{@i^Q%c-+d\1ۡm5#][]"olHQ nZ ",m!ZvCˈʻ MgKfY2=s_ S,@LɖX;Vĝ$#''6d #m4J6y-m㢸j/ *#sR?OTMxBǴ=|p%Qܭҵڎ9<:|5iCN]e@Acd];]}\/i" {'=&0Di7p0+;IЗ呤;n^UG$AmDȔ2*(b.}%^0rl4;+/7ےѿL0A=*CșuLA9ǪՁ~tqXA^9џ lL|rZ l} 8{H{mwÆ 6lذaÆ 6lO4ro3x^V品H6تʏB۬ Wﱈz5k \A>FC2J|G<@`aN-?r)jҞkÄ ."ߒgMkA]#u 9*Ev-Ƣؾs&:9_6owZu,z0A|a18ӀtR7IY ~>ew]#|hRy#K|E;2l _^C̠S9,y'h!#VGPyǾZv"YIݖ0xFi_WX^6r ,Ŏ6ox'#ەM!qi-698fk ~69< ~!\xX`A=OxeyȘʸ=dodvٟ 6lذaÆ 6lذoIIS#>o9ۍ},`Gr15>Zgk Y0/wv>\L?~wzF>uN6jhżO$gQʊ8tcw{m$ױ,)`=`2=[ /&;0]<0Z$V8;BM@x d+9yL 6lذaÆ 6lyQX9Zo m/pXL+ \„#iȋ#7]iT>bKyC5U|3H?+)nnW\]_Moq5sWFΥjivwKju`ԓo)6qh`w1eLo~ ֏9틆|u?6/## ( r}=\l{fC:Yv_Aɬ0}S LI=rqx FIM864Z6xVT|DQlC6@ЮJ{`u/|! 'O p3Z7x45&Nm1 d?}˔!ysK>sL(ژY(rVel;*&"窐Z2 CD&TޠDykxе!dIzW o§k\~"hNKdfz=炪_vԨfq yO 'O[A[h =x>Xi''׍<= (g9͖DV|?mxwQ XP'HOm&@/>e?J_^ՇVj/13Si2ZY.wdRx@V-|vP};); 6lذaÆ 6lذ"X<򳮷$n?} O)]u"Xx,jhۓc| '+nyЂ4vӕ<- ?q8LG!w+9}H%mLhy8⤅H 3bzkז+mx}w7vn+Q& I]^ײl@!/@l`c۞wZ>]KXP,>|Qb\2{@\HY喑6Tfou!`p]9XWL/ !z}@IXu`],h FƂhygFۦGd̒Y7cra IQ<[~,1MmB^(x? !^0 U.r6&d! ]7bY.m.G|uY+żMb}R$ycF:7@^2lO (ItL}~5_^ԡ1]XQ$1u<<jm S+SO1H_husA߭YP">9f8_ B>oH tԑ, R6厌W8:ROvG$4h'g Z^b(9 Nv#5w6@ߏeM~6 y"M-A_&Z AwЖqWYoqM6 ڏ<$[2'>`>Tt0]S^ƙ6[sNmO}X k8 66lذaÆ 6lذaÆǢ}f3q~3pQམqHm4k2vvFK>/|#eicY rTG:{FBz2שyꤾ PzW[fů=Dtij yY&KypE|`wwpD[_چ̈5]eg  arz~Ҏ-̰N7Vkר;eS nM|#Ҹ*}` >W(g$p/ )3Ўx)>GU< #Y(L`6`Tj_vMI1dgsQ]+),YY"WX~{B@ڦ^T05;-' )ohe]]h qΈV)s@yK&{{2ɭ~)ObZ`Vr /FX|_ M4 gTXovPI !TfR?sY]sƎcsp1u!iRmPm%3LhDZ^Ěr*˖%-3GFI^]<9KK{SȉډrDVKxMij }ԃƦ[YsG,zYr +N6+{1 P.#3*P.Ef0%.c&U{+yu=z,H٨0wi-TY#yP3=b7gb2QY;"-vAk(4g: 5/Kl,5iS%x0atcuk㍕SJE|Q6^?}̰/+8jglEں!Ce/ZYt3UˡL[R$MA)7pS V_1ُ=*W@<^C02q,+V̆UWko"uC&M"ro<,bFm{kU$SYc|^fTNHFwktV&뢓y}:gGLh#tLTYOk~~ 2>O>'|^]hGdž K禪ʮjJcȎ@)_X2)wi7b2!áR'X/?+? jJ{j-Col쀊9un J`H9}SI~ѲR6՗:U@G\/Y[ mlg,42i=ٮȼ6*)ϑG+Ƞ$A}#-6(U.9ոOVE/U.`3'"^1rLP{W󯟃U^Ay!dk2IˤˁV:<Zfo!]T7:wEaÆ 6lذaÆ 6c(>K_yZٳ5Zّ~tdsz2F#ZLWY_fFdWqjt_yȳnυրl$ԍi? Plx>_;k(l ;2~/?ʃ/ {,;Y|nvWڠTlxm̝6vye>)3g?.?Mv52hos7CY0Xe|=IOdDhe%.[= =Ȗ9IS(ЕKu#`Eg:qQ`*~_{‰ɨ-@EO'+.$M-*q4ȶ6rt~AkŽI=6&ԍM/9&в?˩6HZQ8d53fޞ4@14 yC&}6 SqAm~SWm:<=|#~q򖁚&dOyHyQ5ڤQy6KP82?/| wy!Ǫ1@܆0yS1yl*䝇^VVC" t)q(6k\Ҏ EnrkĨoXd26+ֹ- IG'#rBs_`Sm ȸQdjlmR3䓁=ڛ8* +]QΡpf{>nbc-XP7Ys92=_W97;˒ <6$FwnŽKE?GL 6lذaÆ 6lp6?sq8y> w?|_`c{g߲5 z'н+>{k3uS}O+UћdͷBK̳gC4Ce\xv:[da,:dYB"'_a/#4F?X`߁<Ԃ%H'ZF|#eL'ٸj)ӵ|v3. Z`qr$c7aw^IJ\C%8[H[k}׫y|ϛ/ f,LLC1S?>5Im~[5[{b'†g|&6r0bԭ8'ɍ]y#;Ʉރ "3;N(Ao| ՗쬶:QwЀ\;T*5gDwqim}52k>}~>eޅɢ\|FGo=P_6d![Q-NͧGxۑ1Ǯ2֑O6F߼]a/3_eⳉ ̑5F y!(j-O17(2Qq2ż&Ǧ1!/냞@|匾v&.ɍ >&Hڔh:_ f[m?S\-+Gko9qQ?i._t ǀX@lۼOsٔW]l==-O'/n}Wֲx%[@Ӧ9 ԑx. F#^쌻X>6x*+m6}m ZxW;叄t20rBo1?;=I-)=heX};M:G3qN ;q>p9o@v9y=V|^ŚvBgS~HA_<2FI@2'm();4_֫yuXQq(={v_?6lذaÆ 6lذaSoM{2>'<+1/ !N ٖ7k;dxnc7RqcGɌ6i'奪t, 7[!~o8 ue>Mמ 9mN9Ƣ;BEK_m0V<|~飞rA-r<@VRk᰽zM, T:R;=ջud; hhφYw@dYb<(-ҍ v㪺KFe7i M(K͋ MR,6,M"?1k}b:cfk^tzdŬCHYr<kqL㢯EWUlaoe.xFS@HP,o3˳ჯ1*ADs{;ݿ6t FiՁ{2/y!t2 #h'ʎuDf'ms7^̲S žÓ5TqbN9]ȫ--~:7!Y9fz #S!6;C8+og3<4%A8%xku$G!*K}Dlm֩uΏŹ؛+ },2fVdWyӆrwh@mQ3Ibc3,|tmhgQW 6lذaÆ 6lذÂ3 ?7}~ЦHZ'ބڽFө7ɓ5BWTY_FfgW| cԗGM8yf;ΖB?f+c:qϑ(@RHh8 NDK`&|9޷sPm[c| 7A~zmcܐ*C]]lHpe]mVTs`-w?X~PR=/{]#<$ 6)ת:8^Ɠ X^*Z+IiWHdcO֎quuzU_I٘GKX'mLNdzF?f䍏]OMޟ}7og2qo;j*t5{e9`-_e&Fi0Ҕ[<&GS:|^{y _:4)7f^M?5/PJ<.Z >eN~lEm3Xyyƫhe?]sspL_H_STS8z?~z;"OG:C8&ɓ|@mF9! q)X{~I;b7iC3,hKH{}[ Ԛ|ɻ_/"IzNoqx>H7:=g1)3,t+4OLd6/x!Oe}:~srf@ø_EZ@=ҕ&6 * ֊: 6lذaÆ 6lذ, > ߏtp}|E1tbaFߎD~zD%"jX/Զ\=y,ՅO4B'F2I"jjA2E'Mg10 ,8cb-XU5Sr&ak~Gמ qz<.bgETA{k*=ꊱȣ4׈V(#Z #6nLvn}`T>SGۼlnvV_kk:ڎe󕯱\̕wf]o~"KZ'nrb'9f*=cn 蒿ЦmƠIÎz:_+smy7޷Mcv7[۟0֗/Z?{~jw?+{OB,ԫiKf7c&Ys 5"p4bӄӫțǂ(r):(@ RN%R^%PEA-fz5"#ru#\6s" 6j2zlL9:iv͎u[ʠ../ V_Slmܐ .k@6*ev]ec6A>}v m_}oW vֈh Ğ$v:Klz3C+hi"G}yo7MC+ ] k˻|Z3?1~:E_z~M_~b˯.O03]M?aNQka{M7X 荖or6tzLV1kI`FJQK /'ɍO;\[:4孊yY2 5 9 UZ4 ^Q ոN"JGCё -'\΄\۱ś5u"c-ICz̶汋ٖ?$M]X{<2b!WtxI+IgnGxs4N3mxP_8X=ijQbQ[pD0GlJY)?eތJ> 1*ە{Æ 6lذaÆ 6lx g#>_Tt҆]\h>/ߒ} ݧ}R\9m;pC~_@ICQ+yd)?1ahڢW'@6\ExMu^='ƧKO{ "=wdg:ᜒҗ޿6Y)ȵd_D|Äw> r!,}59:rϘ5(W Q ˜E uoZW>u ]I-=IC1->vƲu}CYO8XA5 4 R?a!b5kZ=W0ڑPv)x5wӏc憐w9]6_,vM3y߿zF;chtt%v$%VU}ܭ/ijVm{76z=HW J/,~nC7~9ع>`;* f2-E9hz}4Lp&,uT޸C'wdn2lSײhŽ#[GOBX}^h&:;/4V@lj|N:w1޿wFgzz{9^5 1]C#ET)I^7lذaÆ 6lذaÆw||!;GP9A)zZ_Oj2-9G'Q[̏FװKJx&3@[s>r^^*b.'IHWHZ2Vs Q?دgLB.|E7$HF?D)oM־(/9=  ufu4nwnZ CJڮxCv~Ҏ?aď]NG.7[Oxq4xg~`ngp9.ɦ?iOvs?}֯kW,3GXFP农!:cNagD۪eԛ}hgWnP|i~ , -Dy}x*N##q6Y0Qym$ntWܧ`K;w2@=q8P02O|O`넞nq+d/f<36U3r'fxީToVvw<+ w);-}e-ĒpCO=/Wso7g|ti2^sz~k{w{}K 0;אZ3s{O_|bi6b1f/Ύ4.Mr.1,<|ʝ6dd?0~Dnz7ra0}?OK1w|1f6j9أωc.A@5fpl=}*v6S/w׸Y;" ^dgҾ*MuӟD쒗#چ>sjW >譀;^Kr"r  2ka6AokU OSv>֡[-s<ΩsD! 3%ڰaÆ 6lذaÆ >|~?p2p^^??EyϮO=FZLDMzp-vWϖR9Nyģ3kX F.O ;)?|aݽU i4;_2 _-k ՞k]IlT`1^F(׿*(&Hc"7$R'׭5CȽ]e3 tGMޫ֋Α%|="D_`a>d=+䝴6Q^{LgKJشAMM<_0(jӋMȷ2o\6vVH>i 4X$;NfDfmUի7Hlf~H!I34L#3ę̤!3#3Wg(#p@Q]]Uݵ/o]rH}9~"<"#ェ]{ݏ?7zئ 2 yԯPFI(zrEҐBoJ)(^e%44ip5yB7i Dȍ[ND7hYl F FOF=d)ͨ*hd1yO#qНA'h\ȇl3yܘϮsyX޹v 8DX޽=LQfܙd8W"'+獀udVJXqvu^ k 6 #i16 q',s6 zcD/?Mdy6gSh|sxE"R=.}εtivZv䕫 xJ> ,p]mZ9.=A8y+ 2\r^'iWmSIA_/x`xM6V' VԽDz#).ۆ"V:kH de8Rv +TQ(C6bжx'EFLߡC:tСC:<vk|e4$cJ?\Tӿ{A@Gm g;XnyA!5,ƕ"@ BTXWG۠QP<1jJ쭂gWu ׮^NCTܮNt 0Ay(g2dR[o g\OU"#^}̫I>TtE*ڠ1r[x^.IM CԅԹ偨JxNGi(1AZ ꋦhA:a<P`x7&k6GT` Q`{dا,dnh>+o'nFC;²c 3\2W K6K*} A A)QVJPXiXWt'nH=4pKRl'SP10@!) 0 7JJC!niO؀- _v즙"%r ;˙;)kL4˓taK힆&s?ٓ,7aOQMNA<}dўO%! =YB-|t_=.;s홼us*o^OA޺9C~&ܝ{drs˭)/~2@}CeM8x~i~-*_yD1eA%nLCr@TN M_yv=Td(]_䙎ҋ!Cy%ʡ05`өhCRyk6 ^~rn&9 #6Ry:JUypR)B=)؈˄l56#U\9_RM}QM?.Zʔ)DiM3*i#"wСC:tСC ']^u{kPGz\CϱJ:&[`/1Nd{>S=(ӫ@YXwlxًW}|OĪ[Ä>V# |rhCJtV@*z@cѦG(Wدg"hg']n~Ó) &4&L)4eEXhX!W˷ jj s}Y|P.R5QQIp  ǰ;h9M&‚(C}f2>JLgRy(L)bg+yQEL t 6CD3q0'-U|3AXەi_L142&iv_/u% ^D H<COk]@P A#DzڔlvzB59: G΀BBo.O%3y*PQO.F"l <3 [C ʓ[#9)( (ףyJ$9 } [@Br wk*\?ؓnܗ7IL~rs*?5wnCrCˇ"W=>K| w ǸZASh?4,m!ItqcN<4[Pk%Q̯po8 KΑCK_O cwjܢىLոH=q|OzDkahp]PLux4tĺm^_GAljOOH}GYcq&P|RUocq: Lm`/eTNBn#5}v9Kp/oxS'GP\'y$O2gEDO{ryʵPn#> mPitCn/2E&!h=渮$Xs¸'u:rX'e!F:ObzQĿkI^43B_?ŕ2J2H?eZdi>HO`<Os PJDv Ю@ Ebx>(B!v,is^wP&$+_~u~$X~秸s"x4J0GSh ^עΑz^Lkgǀ6:V۹/IA;hҷJ9tBx }( vH` _",wСC:tСC{jwqLwWPʬ|uǟc ʂ'ݤuxGv'FƼW$`U's|pL}+lH}X-5DͶZ<)=8o>V^}&q}F7rrH)gBtC~& @DZcڜ/qee!sY Kpc-| yL87~h6D=K94ʇ^6MƧ~胖|&fR'߯qQ[Ȧ8h[ܬy CFN#ehQ57QpIS7UpE @Mh (܈_<ꞀR-ia#)C)Y&i"2eeO)-4ʝr2vbFs(PH¨/OnzBnZS;O @7W \&r},۹qW6d){vƤ4Wf q_?^Q#sXA24㼅$_y$)c tB,M(Xd2)!"l$O6IL]8k\'ȘC%U DmPP"nrpr}"q~-]{`P']io7pLec:E%&W/$@FA[~:־b;MSDTo.¸" (ұũcg-X'4g=g;Ý N ~`c{9(:tСC:tС#Q=߷+ trm2(vSA)މ|`TI7(Σ#uůďDb)Eq*tL,gA5 2}u/jxyWCK3_7kbܰ'k 'bs }sF1B(٫J&h岥\z (Cer:.R`)|fȳ46,F*OV*ON*Sys[Hd 9AAq=1כa>.ۙMЕB..&{w.KfͩT+M 4n[sL޹r0/\Y_n5Kak w[){4O(n°FtQ<gV ]ۓCG6D7LMα6߬M %+ "UkFFpB(`~kP[2A|/NP yoZu?nLГ&AOB*"4 F k&C)| $#_{MaE6lI/ccQvh͆NkNRҾl0$T )1ݓ! hF 4? h~&@;gJs yϦ,BOѸzn3@ϓRynk:yvw( Oo@ΎR93Le 4HIQ4Eh">Ah}7hݚ\\""o{sɝҏoBo˛w&vx3h/ri+\ܘ`/wTK*=Ihmy$k8 8lh[33A&CwF>9^|Q7uufCJ<`J@ (FӸ.c!v5b{"!7QP>f~\Mu߸'\>;o8 P㣉lzr,t4^"/)׼"?,u,r4 nUM_h4Օǡ ~} 4ymʵ0?樴/C'MM}Zi:tСC:taoec% v8>%i$qD(}VtB؆tW>,} Z>}bP<+/*13 pm>3$9gss\_4߉ē92]X"jץI~q: Nti,yy1V&ܜ=+/5!(cghv0)F̧M-nHA|4$GyEknyꚺ|$Q6hDAcPY8L$kO攈;7nh=@E}BMKSڦ F nkM,F t lFMp~#B6)A (:F<ח i3[H<#mM];#\w!OaȍTc\s;S[c+"E>'νu'7''[թ~u&?6^D~ ٽs?wryPÉ'\FNN-R}>Z,9Dh9S{$SOǓ485L̳Bi >|57mpa5t@7#@6qĹIieB唐vː`̤@ۘer6:>BWHˡ1m[\'3yL~p'7;=ynO>K@nL7|K[rs6D|(w6~)!{y*y_1GO@;O|ya&yq )Cs|Zߢ-$BNA< eM3 y\; !I}hz<#E89(C|CTu' Lh|lBEF V ē@oEZP1X<$10+7C;k=%-(,tP_"f|jk߉ nbIů5jO'-TLm*yZlk[4^>*xGQՁ*=24؊i]B-R1ѱeCiQLJrr'@cqȐ~kz R 8su9fC:tСC:tQw--y\U!?~6Q2AO~Xφ 3@b'zٵ>'np(cQ"6QxHaGCRS'aq 4ѣA-G ׺JدX|.N\3.CxPI\WXhXeKf r:xG U\7W[>s.lbN n, oi[W$eh T'dlSnАs <`+3s  Ns!EI#O n 4:2r4$ir}ҲBې6C'%PH>-S4tÆI9CPpPvv@B4 Φ0s"{n_.&rT*0<ݗgAϝ2z剭˩ ؂ )))k95$E.D>|}/G7yZƁ|}yꞼ~P^d:]97n姷fsw.|9&=ʵ|$@<9^Ƚ,&r4kLu&/>|&4|b.@=|{)m*i Bk@:/c8,*=8A~} zq>9⺡&mfmOľ9#_޸tTFuBpd+X:tСC/M.I7D!B>L%%P>ƽ?` -Q\ {z,,UE[]ʌMΫܳ3(i?%}\SJIM݀ȇޞ֯_l~ȿ|\mybo; n۫\H6Cד ^w& BՐD7Mqa^YFnB6,A+'UPx0$s(xU=I 4˩ d}}5 fz.*?!zkHnB!}nn| !ivL)AO;~$PO `Q"͓:F!tdl+Jhؗt0 y t 1xgWaӰܟMmj8W>>Hc XrsmmQ}E Ywi9?Z L;196+Q+c̲, pjESrZ 6|4fpsLmD;ݫrqkS^~nW>$(?y1g>t 75o_K| ]Wa`!Amlsvx۲ KCBA1,X>m2oɌ b|0=q.k|eZu!޳ B7Ѿߣ0td>=fM30DU6^EEoA.mk=:I#9uVj8,*CڎU]biПH hJ[ }Pux}z`D;vv̳c cR:tСC:t 'x ~?".pL-`'~t1m;hm8M>'`j+8eP3RP"lׄ|vJG4#̬Vgoҧ 6nLႽƥ2rNV޼ ޑm93m &΅3l:M؜Iݶ<ʂ&E*BH_ρ9` R.6H㚆/H:W-$-.*msqúـ:uDQ5iЅ$IEWzRL)E3|IyB60Ap_k#G!{( ə$:"~&2Lvr:( y$\V.n /w̎ȋgSy7rvc('6}7)4&#/ yN.o޼ˏoksyTwP{iOJ&?[צ͙{k.䣽L.\`fH&qL MP*ƈ~40ΓIe)46d# | ڡR=EOaHJ8uBM>VZIpak?(iK]ƍTUiq>QtՐ8(ĿY/G!N|_Y>>P+_UJCj+A^[Wa5bygʀ?8)1:82:_ ~>7k~zr|eTHVNnx50D8 y>X?xvXl>~q_0}<egXQ:P_JPg:ӭ`~$S)5]C[^jסC:tСC:|*X^NE̚:YB,i%5c"EB`6~k5c^Pŏ{ :ƺ5В(rz)܃OAQ,? hgٵOnt:D<4^V3s#օ tB>W֬)stMԞA~UmVݎ@` o9zµ;y0e{v',{ru@߿1oL&X~tc"?5-|/rXn?[3s0\f 9Yx&؝;DO qT x”no7b81<ڨ05j)$dP׊rmK e)+0 b?@~;XJY[bIuG4q[2i(17-iɰI7Tܘ1_"+b:iHRK= Ms7 ߴ4?mq7SGUc*JYhQbr"+tui=탽PO}U5q'փ֕kADZ[G,kA}ECD^ #Z-O|P@zy3+6ٮZ@:Tqo9Xw-VPO˭KӑO:tСC:tС/>7x{O. %꺗@^(4VpqqlKFH}=.X@С.1:"EBbRH{N ٣*S&D˜O nfVpC6W$uea"6M(%K33 9nؠa#Qx16r3䇽)=(K:N" ay4á=Y0P]$G l8` xRFNno&eL.g{ r.O L٭D^mn*/ g3#y#yH;5gvD}1Jd4Ld0H$2CW{LNϸF:/}-ne\z4\?P3y\~t{&oܛ˛Qv/I*NSx6\Frc)z[&T f|5J(S9x7ڢ~2M K1Hׄ6G0m;Vp"xz#{y TvTU /GP&&G+넏 z6{6~Tٍi#H+㲉X\Y>#ccЩDtСC:tСC?{@Im0P#ZnE0{~C۳lsUZWނ畠X(|6']׏R6y-\rŢr{QߡCf蜥 _wtb^qY(P\+R M}rFM+Y~Ua1q-a*x:ՏXFO@i & nzH=#b^ ma>ӾǍWeaF j N|M }" &Fih|%% AvӾ $Zd Ál# 3i*gC|&Bz&\Z|ȝ'7"ק=<'"'E~v_ͻ L~t3_]]>!MW'S񍩼u{*o=4}h"4+@Tnort?2 ~/{>| = 4A?yO7o9F4C5F/ _ p#$IqSQDk`a'PQAqWTTk#meb46X.q>Q",ib]sctԏˈkBy: 7[sAp|Ye4s)]ꄏ P{ ?EZ NG/ڹʰ\;ݺ:#S]3N%20'ar7-ChD?Qe} |>\azM]!3p5׍2:v"|DDMфv ZgCI1e4?P;_ 9fn!1ͺ.ߨ*V~4MBN@W yu=Eߒ!ցdu8J8!"l#겜O;NyD %Gp Q C!^\0ΧMmOllkN@'xX/݇by=]&crmd!䇼"^|:E2J`~Mxl:tСC:tYÂJx9jD?c8iS?Zo/t}2*Xׄ?oPͫeF(B/Cf82HqɅJf( esLxј*SŠ||v\+2F_=0g!. 97p bm Mr 8Z.:f 5үH8O7K %G7opFd8q6oh5X@iz6o V 47R1ٶ%Eeq#/(?'w_Y'r2!1+W8 HC LNN3939s&h;Dy4^Kyi/_˗i/;5gNiğI䉭DNoew'ÞCP%ؐw.7=7=q(r@=2 d&߽:\ȫA~r ?ޜOn\޺;sGT>S8%8qstmMm}edy 9ΕX6 <,x " }5G4G>O`Ij\1^]A $ J]ЁN!i)_,GY.Ud((,C TSmbAY'TGW:钒ΧLERFC \<kE,GU[uަ6 }nRbDu\AL ud$KXR9(dh Tt~PM!`P#7ٱR,xBX3Q񛵀 4k gND,#"2KrB견,ɿ<Qe'OϋI١NUN6mu[Ȍ*s"t*xD\:m+M'p_p.UL@|:례b4:}p4WtpR66СC:tСCc6 y{zԶQϋ8ɫS@q9}~ j ǀ+ G|6@I >5Eq2 SaCm"Щ  $)]-^Q^| ,mD_Y`IGUժ%`ѸX=SXψ)fC2%:)VQ>rXf+FY9xPSMc L9<^f\_O޾O~62iưHiR2pSutsS̯N+BS0xc,ºCK$EIzJ|)S N3"٨'(QmMiu=16|(Ɂȇ|ɞv;ܜʷW[?8WHDL}k.L޻G||eظ9ͬZm]h}ⲏC_v݇ %p6V@^^:D#$\ 3L|.4|*ː|k4 Upppa1(*zOB.qBGwqW YA}I7G^2%cIrz&~Yi>EWY_7g0mM8Mi%јNQ{)&ubBm镤Y8DIM}+*2XWfI9kTSPoneUˑWIy3MkרA7PB# ^d $-P.ϐ|VCy#L׺}kB~5=Sr>|Xp}GuMtl&*Y _eWSSɋqk^t>) Z[o!g1\+Mc>m*ANbRk_Ae&ԥy@=`C:tСC:t޳ԂUG?CQGzG_EMGi+Hwk5qYƝNJ6-(u2@aa#䙯|+[ ņ6@G4mz>5<?V#[4Hq)qKZ\岝KpA(eDK %$Y!3,W颴KX%1!C7C {$7kMh.e4"e\c'(M#Ϻ% |d!nB`0RkEH|_cr%u& {r(xzp!<§6 蹭L.dB7]pC#"/-4CWO܀-fОpM'h@|!htu:  nxț7D~չ|T^3>ړo~/_:?> ݜkfsy~.?f|0O}N{ {P3zb?cO5o>ֱBz$$"T.iݔ8p̄ǹL!w.ӆ/CɄtXLk~HkH8UQe6`}zr񫫭V9eyXUZzh#W@{8 Om=˰@Sm; _ۄi"m@&^dv%V=bUYJqVCk}̿ 25~%J^(wTrM>lVGSBL0n1_BZw\Y^R:|>+X:tСC/M.IG" |`˕&g9ļG%=O2a=rXNx"ʌ \}j8|Uy5 \as u _oCb?D(GQgaqn#1]HUxk J@Su>|iWAE_.fSN Gpȑg\X:WazO$ AeO)>ox{@6Ϻi~pC%U'!]=ma+˧C{^.S _?r34TCH cdyNRL6g=Q]Yc `Pӆ5/i UHP!FC า#j:ȡy q_CInH2fca,ꏃ^s T|1XA8laڵXs4ENsL3 i"(kf"fnJof2q K|iy\?2 '#Ct1 :he!"1eQ`e]QÌE]g=P a~AV'lȉ5s-ʇh¨2yq'|?-DAQa0eY!˯ q ~ņm)E%_z>fXw@q_Mtb+ȚAGLWfw|~ ]|<:\=KkJ:-AؠHHs4_C3g2Sz )32#7d3д F ?L3. trgKD?'L4 < |= _SS"_9#Kgٞ|TP|nCt~S  yt"<ȹPR9Añ.Cm g"STDX֤'g=/=_ry|fc==O7?9WkwP^9',#('Mؒ VOAFr۔qoCƋTL"B&\Cc%92ALs PXwmQx 3' `QF)8ݔ vF>qs&-Vmm!JytR}SNY#Q3Se׹^%T&er DJ* >t 8Jˇ2C MX9:t*EO 0iEo"ՁT"IaQ/Hy s,q:xK^W<!NYq7+B(EC%o)hsdV-":?0z@/ >C;#Zk`ňeh7k#趠,{8*ˀh9[C:tСC:tX W?нa>kXgLƬz+mg ysboФ?}+mxL\eP_$@9ϧ 6QS3tktYpe\/ Q\X99|h U 5AOqiHzܜai =4S a|!hd4/d# 4M(A|n/JFt429S<9@?'ә\ffO.nYs=y~//NJ_} _kn"/$©D9(ʝӧPڀpGmΘf"{ݚ\\9@}Awsyv&߻ɫ7r3зeu|D|Xye"vm&;}@~tO4| WCl˭h(P?{蕻= r}GE %K 2x"7p= ]<ŃCX_BP8z~B:O_Ezz$tۇڷ2djI/#߼׵n4X${XGײa{փ~ zPh+ GX>\!| `sQkcDPNCNOgAZ疪qre1j-{ r0U;Q717bTCw"OJ׀6*4)yf;Fg쯇Êv Y [ W, ɫKסP6’ڪl˝lc{Nvw!9 TO>> d`~#ê}}Dj;u;o=8>hm5d]N_$ x=b :tСC:ts}D=MuujKϿd 6=5혨<9 t?C>z{پ/OiG_#{l}l45yNW>w8r~1qrWl+@h^Ҟ㼮 v(I>;!D_+9buG3DFHo:!MAƍ!j?:iT򞀮0$BSPtg"́< ;CyP^<3@_8,<{@&ݾ\["6ENo$ ]#"ԟdo*rg&r񻳞ܜ/潅BO΍LZ&3j&\+gGWʕ|T}m*߽5oG2ys'o|4'\Z!7 @H&rgrt/ e9 mm?*sLB!B~X n3IQj6xJ8OՀ%нn6aoő1-c![-|aXw`pd7:@賩R7}D6P|bǸ}HA|m:04ڠo ϐTd`Qw)CVmSF0/+zz3k(l%$嚨 6~m\|%>zy"=5BX;.&^ kD:uu{<&Q'GV[z<?t!D@ҏ%_t񎪉:\y29 =.; dm EGը¯ }mOf©i?]1À:HyN-,SeLv,OE NC:tСC:t8ppo}~rO.`| XGG]"PcX'eWC'TdM!p̐8)z8ڏ-3WE'I _k5nҼ^:=`=Kk0өCcbYX/U7I y@S.jUsx@_d C'/'۴aFx _u}7f !CP(3l2my"@Q'gG}9 |]&F*qs@^ L5©|čPqssH?ө\؁.ك ݡS4`>-=w56t wB~t-^fՉ|T~ybtq7#ͩ|Luw&߾?W"ߝ{Tޘ%'d=0'y"W\WCݜq/OeC4Y$2cz~&h璡tKxl?1zi)㧲Q&9hA3Gl 7q(:fi}"Cp s| _o'uJ{7pr{^7X۳~q9C%~cnDU3D.P^\W exyP;j nJYʫ{QuSBNlcC ,@cvyhGgG `Fi1S⺏޷b.뢐W py/~rb ;uq2y>>) 2ݩKB1QovM ;7-eUU`.Q?Y_é4 ̵̊|+n FCC=P4ئ7PpF l]>xHSe tpDf̦L /&VsH! ȚI}W է^ovQS k js^>|<'׹c?(Ǣ,ߦ[#KPn? KQQjH4 #+1Iߠ| |1Q_K;"{qB:tW^ :tСC_\kO$Sd8ڽ6UVJ; <+!>Sve~gn^lͤ1ߤՖfP1`Xd'}PHSԿP딭,TClQ=]Ǿ)uԒp\zdEq%0 1,|T(bZ& 9\e;#?Ӳg.H&gYNQaԚD2q5nuǞ1:-D "5t-ԌַBOY`$k+J.Qڪæ-\at΂CMS#*Y^% >Lp(P\\aWsAl\/&v&86>{{|uOw[&>Ǔ悎?WmƩ_\6$=F>1Xe=t5y>7(Cךa!7z-َB>OmFʙ!$%w yOnHȇ=~ey.$L_t[X9fҀOCgCpt,Mlj~dyLfhGdG)`6  ǿlp| ~0,xd%(~qc|@612&iH1}E+z"T2$Q6`To9yC{!51wxt7Az 8)x*jWZ5JB#^f5h X,c9/KOS(f~<1~cۢ7&ei&SV7RR{rG˫䳾nKBn<\tC i8|k;W䅳;{W%+0O՗Enl㗾DhHp\!JPĘYB`fXeqM{9^Ӆm|_ ۴"?AGqʇ uWM'ܯ yk`~Y W3˺AFKyoCGEiڌL:\c5[,* y :ď7ѺAwk ΁ @Q<5R;j+B-N8.*^E'q90?8 IC'ǐ2W#{[YcFcLlET|!xH{qV|Ř/&m[FP^>K7:uo_*5jy/"ļ:tСC:t#<;>x΍s~tE˟Be\@o!'~K Nŭ0$Ɵzڡ"FuP9[24>ƣC!}fj6,*Yjj3Qv2E#|]tr2rY@IuZslZam(xTd`&n`؀Iȡq۫kϘ۞AsIX)[>i'0mkBd@,t q G|ZΡ .}zsIz3 T.gKd>%X^K똩`HkC`er2$~_7pMt8`7po  -1k˓3 IzAxe. D<3a,zVh'/J|\"_>ۗ/N \=ٓ'7EA)߆ ==)I(>&1*xS"=wn|w|_s2o^O?ɟ|<2o\Lv{=y^.1[+^ʇ@>\Y &w{Croޗxޓ ?-7p9{q1G%f$7:&CLj륺4@:M 7 ]>S[? 1t3/`dFD =hh$yg ȍ*Lس^l9:&Qf.(f#BnryG4I?EPaY^Uߕ巃ŵmTk0+C]sl|f ]J^ nsYgAj j WSAA?opjG(?930vus֖gG:7|PԔqO+b2]F6Ƽ$br[YNDYڪs &`Y p_T_D $eT.:Za$ı4y @>0tRJ՟8O3|fD| ƹnkӍG^eq ԑX>=UP ԥ&cjiB빊р6~4Su`A x< hw,!yQ YLR$灊:&:v}%ZE~:tСC:tСC^z{=qep.B"/-@n#f%3I> wRYDaL+Tȯ@P^BΩZ-4v]~'?(TdXWam &!p:nȫ ~g ^61t9D}:sy$mq(tB݄/7܃s1?DM=;Ye572nFM̃g,SEdHԘAWIfeؐD1FeFS">`md0]U<Aٗ|'e,k P_P+`4QA.LpUUJ!ա6ͮ;BuO`6D:gTo٫ 6>t`<F/Z|M ;(thf:!47&ئvb]ܦ7z*}X{z;~(ltX@9uT%5ɪ3H_gp76~<wr;qp2)ۢ>jAS-QB#4Ț6%['/F'E8\Mh)wޡC:tСC:o3y r/ZQ[QxyrLrREp xq/i#~=lBcN$uzhcЂ\cF5hٍ@KuWfXJ]FOG "9P=XVِxxM;. u~dW>T:޹;VCdJHs5 |n#+ B@|i"[I"#&^tS$h)5ď$3ȹBryrG y/n䥝Dtzhtf tg 'O @|||OtN䥳"F_ man?pt>ɕÞ|gm~pG5^浅|Jȿz#81c'r,p.h0/`n&هLOt_!fy4(C9ϡ>EHG"2)䷁㏛0|>.F|+Tymi x7ɑ2|F+Ś[oBEPDł+_ce%2Pb\9U㤀۳dS@T 5vRFmT K,_eH(nNB&uU/OIL0nGeB"S1Jr8nqrhW(\Bq="md`16E}MWk?ZԓgE"дwރBT.taO4+M4*mzbpيd3 eowIiR]i67BeTUC:0T^r@6/>ZhjJ{Qo㘇8릻BF.2==ΰ:X;\n +(b>{Y2B`uK; ]ޑtsW^y%:tСC:txp\~krwH: xZ}48k!&!M⭫mxg7>8j܆]\ g Ѥm*D: Cz٣Ӹ#}`|ƽbv4VQFU}ǹFl7cUx%~.=$a2Xܑ=;_=#sI Ldr͇B٦q_F'hQPҘr?zP]<֤&Xh6PuKw%FM%p6]P76T7w8|@bu 7@& 6Ñ85?)!i]uʅq'jW Ls}Q"vadIȿ@܁?`,W;COEƠ tms|N_~2v?<u@ | Uɍkfu%Ǵ!2M/O'Ŧ)\ OƈC$||!`i`kFa|{p?=Μ\_mPy:/ԷX/q]y]wºm}ҡ¬n]Fy!rG'm- gX "w nR:cPZ)˾%|c?aS[(嵳p2CEzF/ˋvg_?Op։>(##P1m|N>ln 6wK6b5._ #huLȯԙ>Xt4~c_nJbXw:#B hnv*mByk=ga9Cȏ&_mOohlzh>*E"4t#@Z:jn@h1)N ʬ# UoNGA14 KE\!"Fq݄8Q#^+z쏅Rj󫡍:tСC:tСCpo߂=2ʴ#ܗr,LQʻeyױ%:Ej' ׁjBEQkTP=*9FJC=5h*ըHD7F'D*G5)8DhHJZt7~q!B*ǣOp@ [kX@JPM j{@ b'V maOrij'sP7@ld ɭŌ+Ď)E1EEO@F]⿗mB~w/Ϝy n2E-pP _ں7PSK|-}ov&߿wg'Sƥ|7r _rO[{syme,C{SҤ/?%՗}~|"ˈ_{rCo n#~:eɤ7 dTf=_{mlq2C1$t =Isx,eC.4Mu#g2C[Zv"T ڃ!,ɒ>:Dj(1C&HNWLZw 2TE~Y9:$N,6_P_zx]`%&b}NF-ɾ}AZZ_1in'ǧ3'Ø7kèA S{:*◹B4ԔD3N:tСC:tСÃ"ޖ(y?U<NMM66Ty@>8HD^Wq6}aD6C >(2Bߖ\l:몽b4]q+o q&[c qVl3i _@vR~XP]g*ס.&>Po0Q%B{oO|{q%ĵ qK/x 7bA[x 7$V|E4I|?ѷQJ7ad3T/@H,Oӈ+ {;Zz]+&LkeXѶ+Їo)|y LH6Mrm _(1mrk"to!ows\^7o啫3W/!}+onO(|{ʫ6ʷ*}<[YOb | js7[oy_nGn$v{h=w?+O2mY䎔TQ4,GXJS9gԀӇy>C9C7Z+$rܸPP4DN@Yiq>}XZtef^QZ6.fZ2Ԣui 72 BG W Y ԟ>hfTL[Wڍ7-U2C &#LWWֲo Q13R'50αɨ~8 C'2<Bp4}ke vY'91\i8$7ߐP} iTNK+"T.Fo ]lF\oU z\&vZ"|@~}+ /9%Mce.a Mc:tСC:tСC#">x0toIB>ep~BI5w**uC"1LMh ٨[CZGXLu4g1B IZhuGb{|GכтݸqAbGf ZkϸiBE6+[]zꄱ {f$.# bi&81˘<BWȃVKs|:);@S1ju1-v˅$g\/{@!7ndrac.Onp"Or\ȹݞ^%Y̋-%V.AH*bd\Ld!Ws4L޺OG3yTTui&߸<_߀L'7W[s;|wzAO~0I凳Tޘ ~<țH9K-6ObC-r-q<ܚ?#9_җZJ{d׼x p8lT6,tx Bs`o>B0IǍEyB_z94f5 _MALMs"1Hq:er8XV7!b<73<~2FtAnvX`@9W%eHfb¿Gu[늊>ҾHEAn-V:qR ?IKUvǢy֗7+ӭhTS,"8ui}\SwC>Ui/t3]GO\/ ǨcزJRe;B?zNZ@Q!W'? ӎ8~RlC̏E튴nrz˒BقV؁vbx5M @oV8WLZy(ܶ7X?u@6ٕ ǂ%n8:1F2ْ_ĺc[D:冶)41گކy#WAtQC5~8]KTk}trӊW>~СC:tСC"ߖޓE+9'Ö*~_^G}.P*O{\ 2u=䷸w73ȟQ?z,eZuKへp>4_>Q_ZfyRt5X&.G^Ou_W~C<%*XϋdhAD=&DCmpUA|q_G#B1vޮuԯ:Nr^Qh+(gyM I;:LY1P50|Ufdu_$|crRb!;6E8L䋃|1Yȗ\~i(/LK;.33LDO^:}yl*[iI!|It7k$!π^hݙL>۷3ɭTwe*߹r(^ׯL߀*D~m*߸>o^7![S6B^}y}<q*oMh>g#yw>Ae$eռ/7P;Ԙ2F2E||$W@mL7eV?Z[lq\ v}|0ye)!^%Y}vc];(}Th]g],yt<#@OhDhԋɤ O_>ܾM>y9 2ebQGœ6h+ $_ =Գ]>+L BeT ' W%{"W;AM}^>ZżU~5(?j_!\a!VeyWe9z~XO_zHF&/Cm?\3݋6eBFg\P4V'"] 6!O 6X'Q XhS)^ 6_ |ҟ32;@n,ʇ'pxZ2oP >űƏriL/O^EUclƜE\fe9o:=hh#9VquVŏ:B~J!e`?%RM8)2ꪏHnzءC:tСC:<*S~4g)]3jżXN^>h<S & m hL1x Ҷ( @j:yu;G R4h6Ur ,Xf?󁟹SDɵX%*ϯ qrD9*=0K"i"),},$O19qy$.J!J]TB,bz6{eL'cy2Ӄ<;E7DՓ_[}Ku;/o h!y+=_;8ӗr.zt~ _{/_WI+O:ח_ȯlw(_TJ{ Ju< ١6"~N\tD7e\G[yN&o~*oN74ے+y[l(C7O@n,R }`~/1|g+OC{f 2-бz f74n2N`A/BO }n q#%d3XXƓ9L|&9[ 4N|!s3U]꤭/h¢1tg1 Wyi.˸n 3A7N'?<>k&A7AvZB2b ."/$FCG"&j(^r _pjeW^<]`f6Jb3f2Ogۓ)IJA tž#TfX)4!}yܻ̍#  Ju?* A6rPˮ9PWc*X zC*CvpV~TAD?ϫkqŤ-vH=^w= W 8xś*~ ٲM jg<ǐvO\[K/z4] F"uN ouɋ(ΫQ&I@PH8f{>=zߡC:tСC:qaOd]425݅M@o@qʓX!q?y 2}kAxY5@q~ +UD=.ln"gBlllISIQ7n*Vfد.Dc.UAyY \ N;bd,d؛00pFh1 d LT.T2g3ya0~qWFsK"y{B3rխL~m;_=';~R䯞OoߐĆ7$_zvO=ٓiLۣE_E"/y"y_=??5D_*sjccKQs|L@_G↌ r>OC(Ky JZx-t.{2 6 ݠAX Bvk4@YG?k mD$mcd8^M{Oӄ-`H<@O"Oǯ{3^pzW?ez nn@@ 23Gf`N? )7 d?kX67U ˥K É?>!D Ch{nؘC[. ݠœU8 u>'1D z ;s;5NV,Vu~7[:iu"b^x೾ˁ$63?tY."~C E 9fyJo1VPT( u~khAS9$G~,? pQu1_ @ NYYuǂW$69E)Q]k ׉mOFƋg舯cbBh2[2j-Fmt$ƶ`+r^+5x}x-6Xf JTmMN Ii`?\uСC:tСC&ָQ+xh~jp9B˓/xy!# x}t< 9%#=Ժw{cE7=>h0|*;y&$3O@ׅD$g<7E^K["/o|i08˯nv_~s/_=՗N巶{DN gs'Wo=Eo~I_9{%f_)Ѕ&Q u:DxtT飙;9=ѽ|,7gr=FT7CpslS~dg=KPTҿ-74 8 k_19g/{?PRP<2=fFax$ ]4 x e%|o\@nHLP4%C ^7k)S |-8 '|϶#^[:>LMy#*kDdN@뱯u P ؊mi񬌕/e 5X#--;+Ca-Rb 5:VsFI&"E,f i@amx6 _BkDRatbJ1@Y~E0*k׊Wa\]u@L;(]Mg2 "~]G_QKC[sh+ rUAzoGqczL8C*w " …n .y ^ >M~7s.7@Pgr+h?֚%? LWj˿f[IԍPdYXrcnkxyj-V~Bu+zpc2DTKTH3Q"G܃1$e@qGסC ^yСC:tqɳEґ,}|ͥ3ܗ^ϯ> .aq{g Ukex]9/.p y]A'#XG=&1(ua^N񩞱L.C< DBQ_;F_ mS_ ʐ.&ϋE*⥝> cO"{$gS.ߑfO|d<?{nx=ML>=;}0nݔ^Ef_ (?<-@)MT((ShLA.ZE}&8E@n2ĘHI!O@rGS)7[^7߆?[JQ!l Gdb|" E@l!3@4Cin ۇCKF x80I_7FL(Ԃdstu +_A!>ɫ6e?eT 8f& e'wmw^Zo|a:9'|U䖼?-|wGI|)&t ?i'C`l?@k-vE>7}K~.9_ H HjsŴ A_IecVPR¡.psQ''A xB-&E{OYmqdP/1䂹b> ƽKڥi T,N= ~׶) c'0pCڇ~"PZ3;,}bFho(!Q5PDR7QVEB }k kXOϪz2RTdF X>6GI r]g}J*% 'Jژ+"`Ѣ 8P(|r ⫩|JS{.Hiy\e~& NP0nE2"ֺZ!:Ik]Q/]Ř^ZeO(&MO3׾#O䊌ᄄYܡ<׿3Y:x𽮻SZV ,r!6P7(v불&^\JbR~ uiU~ n e*6@qtS!rA]0xE^~Jхɼ} ;5`kEE.-+hwY(bi3I@%RJ~w5AsX/5`_FOt#~yĈ~U[xVuԑpA=n/ *aS?qx&FfE<9]8Fs]Z&;kL,T-/x|!_κ :|mСC:t08"G')$Azpw *Z֟fVTGs[(*xu|ƕe9CSn"ȚRx K"#TIK@j T+u'TAMqDЫY,Ex(]E+_g,$m=\7pL%yb$@?ߑwfd<:jM|TTn¢a #5 x /GqǺƴTaiMί\,.14bEksb$rsNjףbH.))K,.q18B}. Pn2ѽQ7c`BeUfFq2[rIje@ \xr(w"ppK_$>=dP؜ov }Orڃ VBgrw2{froƅ?ꐠT^B%z~C)4\ 9@kgwnmd<s%tǾ6.XMV"|y;+=/~|]ޝoM|w$}͹j`% уz2 m Ka(_nd&P>w5zC1J]wUю ȶVc] +'\>І!6S?u. 7c 7A@O&'Vm$8'&P'  q0"B;˳:e7p-בQ;M#C9 oV-H)OQ>: 9@ߠBPٰ1r<@M96X;6A?AG7P^ ?!tq<5=*cZWc)$h6ڶPBQM,FQ `v j`Lۮq6خSY//C% 63QU%oy 11~vE^W?#?z/?cݸްqPРl)\DU8/Qׁ}Z-g1ZH0p4ז% }i/E=Ek:$@%m#Ebs4dž_ E]=C1:q<ҩ@"@孳|uEJe,˸\]Ci:FzaGNYB)Qpg My&<-5#GFձH2TN#P^!M;b?8&dkb.S{xu^*PI' cBx|[$q[cۆQ Ui؇|`FC(T.gED2jz+@ yC :tСC&{8$&4C7t0zː7;ˇCI gYU9V +íoP3( P/ >}}9G:DhCѾ_&z<]t(؈CehBe#rP:NߑTvJ}ْ䛻9ֽQ6eK!Xe;!k;c>CF6GaK 5 k؉0iT"0.8u¯HQ <9'@ekD9>> Щ*!|9R1cBJ |$="ҺAPd @y'iþlţ2 1r1^ [<0oiZ .ess8<-COŻ?`i.YO.;@p!x><ד8rA  _HcGFzC>璹'] {(O|F*=X81SJt~շqܠ}w{;/ar_RW~|Wηq@W,'8$2MPTy>>!BR@iCkT^fȍE|D&@x 0q%@პڎ'Upl. &} @vTr !& 汞/oqt!=t nU nY_t @7s& lnTaƕPui Cy ! >O >jƔ %?1|E8O ҆^YŒ?ڧq}:XdTqMu=\_e*Z<ˆҢ4=,idPH1#~|MXElkjrs0ί>𳱎Dʍ;)>_z9E|{+;g GEn\řeٮzoBi _ƫ.i/Y.d,Pb3H9n\C\gB2^mN*M4SbxD1sQuu1M.u%OM=o<2k)hX"*KD.h?lzsF^GOGx wr$HYQ+ߦlgiƉ5oC#\Xp]MUMEu%61~3Dٛf]%A`]^ۿW6$0soEocۆ|Ԇǂm(АOfKpmW/|>Z UyaPmtqC# :tСC&7pp/6p'}!~mh~W9 [YXla6e/t<cY"J6Z˯~nS+\gTo^("L>!>Rqi4 (8Hü҃ |39P/B_+ɾș-~$?<+hG|&9xO^nnREoI@˩^P (ԥ1c?#f@f}uls428BruGW@22_rTu!r!CM}l!Ĺ̍B)My" ex_eQ'(qM̕|= D L<9i} 㰁@7p]!XN438eCnPlX }8}7h,TY&{r;y^*cXf6c3nDž՛9 [S.C#u^ ~9巿Г~U} oޓ; *v>梅W\E?eQBu=%P׻$2,oUqb^k ɓ%Jin4q IzO %z LSc0z9^zk0BGAՍ L AM >[76E6(joMVnM̵$Ln`!FB)O4!hazɲlK2;Jnr7hFm6EOQ;L"6[1cESlC+\[FHUtGm)cDġjoTa=MmC\>.u~1a}| ?9efpO"Ku=:/__=)/=+o]'+u#l, gHj{|YN ;]VXO8B=Ƌ@^BES gQA8 4hC}xMPn9HJ  7eKDixd85<$X \aBd'y~Ce U MEzEV<hU}&&Wp^tUﱼe^)Ӧ J=VaUwÀ&GIVm57B{%e]Q8Ap5BWy/sjC :tСC&l I}i4]C5$l ֗p+T g5`SG)驱QBUgdo׋(!Y&c8NNDÐoJ*}mlj1 fyHPe mcn}ڎ ;)>`S_%`8cT3TdW TJ6Ԉyb ~Ɔ)_yy K20ПlEQɪL1+NLiYDzaa͵sbÅֳ'3~9l,,|c(|=Nsa3mP6 #[r<]8NtFQ- 7n w=6Oד<Hq$w:\LJ9dr1x7^94 Kucdp"GrTڞ d/,pJyā4^3G}ݗy>7_@1>@i&=G-kC7m_nP8ޜm%}0G6pPVS'3G.tUP:wo#i_$aliqWmF%]ćIzy#`r{tZlӁ韣ϸn| O4i`uSS"tCtk~Q[gr?m!`\CTs'p^ӎ< ҖV4M#2m2YA v!k_-aP\C}b&?H]F,]$AnTc}UrC(Ǹо?|l°!6h&`9CuL1A>^^ב<1,93#6G?x 1LOy,o(Jh6p-P,A @Ok(t0#*B @qEKp=m`˄X*y&hUfKD^ه캉X>Gx$8WI@5UK:7cuW=/M:rf]4_UF(82d(wV5ɪ&bXzӄ\q}G4y.iX&B6ptDC:tСÄmJqn8pZ uw:Y oya5rRYqk 3jf1B5"z2 2e(PDCA߂g0KC ~wEL?Nm9B!f,~gH*bN8Ce!YeBT5g9Fџ.0Dtvdc69=P]W4DP(¡zbӎTMk|yE8zYIZ8~YafR,ȡ CL_KfYt hY t ?y+~bE% e|E=TAĹ(;H,M!kI_1L& 71m Qړ <@C q>p@#܏h\Hטp`0>a8[xח'dr8IC9{(Ǔ62̵͛ `s@;X5y2: Fb*BDO94<Ӯ}I1n˅}O+t_rG|P&16IoP7RIċ _JޯтPIo$oޗO7tǘ8Y _?4LJ* OPۈ]7}`Q/sI1xs J^G~!ГBKz"9L5x\bS i}7IQ[sۄu9Z8ʢ'/4O.-~*Q#}&2bKy%NnrGa|QE 3 ։L#4 ߴ(@Mm dxM ױHU_ІѨ><n~Uų >>2ycZ%!#EݝKP@kLe >,ɐ/"=['ꈐrZ %-Lqca,b#9l<߾9rK7eqd'ph"4.F4iE[ zM׃ vʲ|("Tw.mXm*@J;-*zi퓇kH7׀Ju8/mrmz)הW>:D[q\h+ª-d:nPVCC '|XYǺpuyq&ײqyɀ&G[:VS~1X,DlsE C-`$Rg ^ZAC# :tСC&tǿ1P7pU7hxڴߑgwٌآ!5賂>2v+@ȋQ~l_e >d!s~Wt-?ArS{cj Bd2؄{3ʗYpCWdp64ɮ4:Ѷ0%<}ӕ,FN/9(u5Qn>5dCLaSٚ<*&kĨʆ確x,PlGy |큞zOH\kMN癜[d`8H W ! e Շ8>.0GeKcL9OeH*6]yc HY&L_m2'p0ZD?:V)!{mWR BE&lL_ Ј_HmCת.OrD}Dfʿ*u#=|1!o G 7}}Ձ,=B c\Q7mkS4*Q^_0T}rH5) Q-I"Oĕ!=iS;*BJX;j<c rP} ?0](dh9:z̊C?@5d6c #ts*R̡ 7p7CUTlL4ihɠ'wݐ&wroe(uakn0>FӁ~`gEm8캨0ʧ~Ѵf==A7JmPS ? 6ㅵŸU:>ħ#Wɓl2*zx{|hg[9nUajvzAh/y*CwS6lCNSI%?H(SSƫ}ǁ>nPl 5e,Ҏ5VS~CC,Q]\s‡U9_yt 6 ϥm6pt9CC:tСDcNHKͩnHCHO;Q&Ր2 Bi ~>x㳌Wf/b(~߭v)lRA%~j<]0a@Mkq6%(!Q{FVوQGB-Lc=G?^8|,N# I.#G%o?o'prn_^otѦ:690KO5 U)tp+~b!nf-J\Z[Yͪ頇9]?4qӇwrDxz#M|F1Ht_Wp=/ۘa'il0i 6P1xe6l` @7pOѠ^ܨ8݆M:,ke0ݐA3!in؟쁱\}}d"YX\\$17vs=Ex۶d}Xx=7Թ FF#(s)YC2a[4(=, EBec7+K9A&(oy 7RlCb0M mXB!CltH҉Ł=<}qx&}8pq~y>_a)+3΍l}ԙJJ&`}xρ/gWa-nޚU>oi'Tsk-K6S;q&cP>T\֕ӻ'M=7N?Vo,ȴa(+C !ӭSٸ~ZhC (yݺAFwkL 0>mXe Kuaٛwsg* ucPF:mWCvBϹ~[ӭ~PC%clmWS m>mpHC+>`_**zDc SDϑO T$# St<n$I*4Bq?|it~MT|rlx`*}V?-'0[mJDL% h$SWlku nHl@>1УR6~mNgg gi&2Nt:S gMOd_a0]ӤsdJ|#Y{\gWǼ=m]*oY jEA\ʸv21 z=sn!]qO; U`5J1B;2 H. &hK ozkp7Ѩۢ`;zV涷eoc_ؾ%XuFУŞ7;pč6DeUQh̍0p)n߇ttרxY}K5ՃD@{xI52BIfS< {zG]]vdj!p&9ЭF ܦNE[-cK[7J8W[f{*M؁?~t>#uY JV&ǟwox]Nf)ec r;Sː\ -۫@99 "ŹL)*-f,Y6 ;W>IיHpƘ..Y: e˯-Ču:;Itw&-3'Eߩ<&30meIRr4a'NJsɖvRf k~ 9 R W+]썫tyr!bi›~5x8Fnq?IDAT}Je n%x̆e *5<ڔR2A'BLװ#lz#(RWw0I+_U}y;/+T.ٕɝql'&K>0INzVϿ/ -OhlpXZI>]ǟ%¶Jwᖨ'dZ]p{:ۯEֵ#l&{"]\vx,~6:ZĻiD _qZ;=J y~ܱa3\:b恝*$Nв.u'>"HX$@^A!7]i]̆rSйU[x-8:W{=#;`ڪ2t'[&EYIe[(R]DƱ4eؓdLd79YVyŹVq*kd-uik.s׋J,/8n0KYg߸hݤKٲ= W1b*KV疕kφQ| 8QJc͕=?3Nq:}_tʫ2LVp Ȟ-l7J+Fn< A (KDBh19PT炖=@6;|lQD}WhGN4é`X5lʢ- G##tˇ_-.Al~Qgo=jX%r8~g8q! v j7}ܮm>jF.ʻDyzlˁ..cewT݄vu~/D(i:ggO}~?=In'}1'zև2QQ]Wn202_mRZW!O6bG<4W+9^#v˦ֿlmӝ8Y^i2< Q 8d|1>/祥3-#ח4'g4NDkTc8(r=li,8XJs3RJkOpָP=ڤǫUzz)dD[l$n&tx!uțla)bXO @^M4bpE s ZSV]X7Q 1ön+gLlٕրN7~ͯcNWy]'݋їg+ BҨrzn+jphl5J9ňL1Qā#6q^3TJ N$&4Nv5O=8+ =e_qE+]G8l3jOP ` D"qX8EP[LS2r vg|S>%}h&K_b*YXl\WV[yN8OdYyϱlIJdjF$Z PGұvy יW-'!"e]J||݇E;ox 3?쯢as3jZJ2+w aHN :˴o!^WHN7(<\X]vP/`o5fNYmd%d}QziwMWc~wG/"U9!+u-h}sYЩ[>J>h\KDY1߭3_#{4:/F,}BQk+!z&QϤ=qQcǁ䶊T"u\߇Pv?:і!W|/*M>qR7BBq3>`92G- O ~@82ݺyl]AC>t|>N,R^܎ 9ӎa#"84ݨU,zuB>2_!;C?k fOc?n[m͉VƤLu)XV/gGY 8 xap0` 4{Miz0K NS}-N~ Qд:Gv;q֛b[ĠE<ߨzP??h K0vU]y So)Pl%sb33<7p چ{n lt(.to,<]l4s_k:>Lo~*_{>wң{i;^KVsxQ_Iz1)R{9S7l82SiKħt.lBO KҊvx\`3G 1cƽ2ݥl:Mw&!tͦt(Ύš66IćҠ""A(xO  W: 4ҚH]rYCnvCuW*AHcyTR׍ț;q7W!TkcvԬlE̷Ƃ>s~w˪ ]x;u5O<olwZsh+C߸| ~^Z:_OZ~G[+e$Rj꣬Dފ8 0`m] ?ߣ02 %yVTWZn+}nQ [gkI0{)g 5D=}Iބ㧴]vըi= zeKI"NwuHKǛZ-d6O6ݾU9I.}%}ƃ Kǖ8YW_sjqgNgu&$)L5rh0Arֵv:QSC)~Uɺlb)sub6cG>]bM~ѷ\mM8fݽ!C1Ul$a#MI I!q$`Ը % |VA]8nk%4E'PS'"k7A +%iw]gQ8_?Kth_'ph_T_㊹ hivltN`q,rNjk8\]KZN3(/ۗ>&)8T@>)C7a}*F"JӅjvŞ~a=l92异Frļ Dԟ`0kצpQI(QutUv*lkeCtmkNCJSD5K/(O1s15rଁrW \&]+}-=kŚZTbս6=$B9%(I>69ҟPN!w2ftyZk vSFWi{w^u_kd{T]mK_;l!L[8gDp?.3*)r5@43ve`9r@:*{QL9pDdhzbahq=Q_![G[jD}e[q̆uTilq: ]b駀}W1u[[>|i].UZ`n'o+Ien:i.PVZ&ҵ%GB- a[^Xgn <|9eA DycYn%?ZrJS78p 1` 0iBq)Fe\9pdIz y<硯 {k[Wigf 퇝g4Zj]CYB=<7vY4Cqt@u3L|\ܩdT4MfNGҿ+T~z?9IYzϛ\ep>GuuI\iXIlűHiי/JZ|I*wÆxOLi8S]@Ayky6i,ʏϗb=-{t_ʆmޤ6]-|Xz]-Ӆs.z/GCJKzV2>#~?ɭ[ggd8\/ <1"OByEh9i䣤 ZZ槄ج)D+iCsFЈLĹKȧa ,v5`PVȻnIE؀.rW|N>IL ^=E?~>ʬ2/7y>,c[Xٔf;;pЇ*DZçKjQZQvPGqjUIx&(0z4?]f;(sGG:(p_MW,f,輎c8/$=$}ӻg3N?˛WN?IfwC\D== g'yTFl1?L2keEbB:XmG <Qls  Lp~78 3~8< @[Ƈ>Λll`Ϙ@)=逸1Pۅb8R`;UwmAڐm,kZK Ct-Nqv?>u!u۷TF9!;UWvHp.)C-7Ơ}_@=¶hWF8pt-cҶ~8m䢜EQ08p 0` x8l;=}q-1̉ w#n&:;7ZU`wcVӠ5l+q؎.K">?siO8겆$ţ*@;ʨ`PY704bC *~ɔ6_+]X.ٺZ^n '|ps'csln*= Fv)mZs TF}*ptXT;fxxQ'v8o)6}$ݙ]9eT|jtNĄsLQKf|هdT)kʼ:csϯ6QbL.pؤ |L FeXᬡd4*㴦8~ ŚG2$6iFj1y7e9'sMV-eJk ֡yU&$]BFh`K֚JQR/^]'gi:- 8p8ǮcekgFbK=ۅOہC]Z#.j[3OG5#Hy;GYXTjUն:pdaM FO@7>RqSy^k"F7G$Sc,Ja+!,͈}|u o.PF %18p 0` x㽿R4}oőp|n @>I=GS2 y3r$^1 u ]^ݳdz@*+lωn`*mdz}UxÁ5_ss6N?Iٔ/=IPz]׳}u.8FhF\)ELҷw8^,;5A/e,BeL_B)g#7WpB |8r.݆wtV+WzxK]c N8Yu jYQ~|֢r=I&&?5/ pzZM[^<hP` ʳXo%0r&O!Lj-N* 㼒F 3)} t>1=JOz1eN3ED\hơtCXY@w%{58խTB}%Wu1IC8p\1K@{a o!f3[b{<qvqvI1VPftz\=C=e"x{&fY;po}8I/@ԧ6mǁ:@Ă{9J7HQQ8F.Ms곃:Ʉ'tG'm#e3ѤOgHA^(C*'x3O 08 _vT_,rJIb٤j_g_+3FGr0d`t@:6'ّiye')FvP-ۆY-eR]6 -HBA9G{sdZn?L4<'ƜR1*r&6nE;r6$1Tx6*_inrd~f|N\5մ<īw9G\\bƫ.B4ec^Ńyӷ}ˇӇfفr?|~vy'}Lukv\vcU>MfuRLp 8 ][cZ?O| N3#1hk8< k51ZkP*𷄄Q]>BYx҄EmZSೌȣ3^H}ʻ ʽLh^-U4f3A2yXmV[K!fs ~cmիOCzKlށ6!Wk c>;]e*CeT qf' ƓG8k+7OBnAGyM0љo @1yyG@ΟȈ,fR[o߻4ۆc"͟$}ݳeM'+TǴHmsY#8mlxL|~蠪WNN6z?4s}4ќfv*#4zD%'Z]!9'xM6|d4 `9ü[hhU 1_r TTU]WFBmV`3Xk]UB¬h@T r}._F1nPGm_Ph#:<'E3(&u/R m*s$z궵'dWCFK6n}xs:]!o z6}&c`ԯ|O:.=]ņ [Ɩo9Qvmޕ柣 ׯ8]\WQwWho&ف)ڕsfobăǀoE  0`&;өNxqhw׿x6|E߿wb!S7tD[I8C-2Uؓ[=%U<].ܮEU~Ek7UrG qG4HX,RCbÿ*$? !Ϳmk۾<7dV4b5h~&2`YO#J_秣O7Sɬ5?!??Hy{:O q-FVޒvڠK[6+x1SYb;MKպ6tY?*P>]d=5hyy>QAS֡ 3_b j][_݁Pi"lb(Ta(bkt@׼ӍsNto4OpdHer~;f{v8p?z.qFc&)kG?;p\qwK҇T*=}{_Y_-i8p•HhQpg vj[-,fϦq`a3,Z./$_evDtM޲:i]̧eh#hZVZCiu ]m.y W@ʽX ̭8&i::&y'aPsJқD^ƶS6gYi-NK|u]Umd]1G[_eKq[C-=hP(FĬcvTe;BjyhʏuO@7k" _6f8xklk1{na}l.'ln"N;Ѡ2%eBu0ًerv}чceMòuu]TOY`KӞ6cca8$ۇZ7ȴ6;؂;=#'~x ui-(ZA6\5{c 0`Ov}^+T8pp<:ag>}h̑HenNi|q-ߕ+ˑU{1UY뻱yd~'J8u.:+%0UE:._[ ƛc<^7Á#狕^_}8~t+T.4C9CwtMkFȞ\|N&nW~'o4Ip8)buoٜO' T3y.ڢ|~`~m6:qTOyF닮gk^ .1ଇ)zIh"\la4tqyҏӂ5ž>EX|!&qlƫSkl#y G m`XZ܎н*V0*5 @rAT6Ne}8|?+< VzqZ8Thd!N*$r1IC<+QqҠ*׋9 ڏDzJZr2*s\5ʃ9 5oJ_籮6Okt9Έ{ / rrqLF}?N_Q/m_OF[~&( d(¢e xku#_jW_dS2u Myv:]!Aӎ'FW) =:džp}oց(꾺Qo!O =Cv4bB^~k8p|:<Gӹ|vw|;h&w1=\0 >-Bp7&Pם黲6p,^[u n&iO]U.!>QSwV~&8꫁L׵Q5HJR%`j1`[ǀ 0` ;p/mq;p{4?9A>ʡ]mM$jz@|/~oDa]҂9T|*HR:wTZONN9KЩ'Bo6q|;;Mt S3.20s|/}vc {~`o:qq?cٖ8yz?`q.xr~&\ɑ5X.uBs F5Yfc-l0hZ5]Bٜ{}%coK [9ͩ\ *}Ȏt@ "S(eSLaG!OnƧrwD MRUBJ1Hc hMuW(&VT x;IJNZCWeh}NEF%;xe'm%*8" >cv{,At$h#:yb?:kT48R8Ӈ=JMSquf7̩<A(vr[v[yko.1Eoq`܁ʳl!4m̍@%1碊?mu{vmx]hA:|qCIԝ tMQ$qrkb囬1`[ǀ 0` 8{98j&cFفl2g>K˫ƫzo6bH;PP/%ߋw4 ʆ,G-X% E`(8HM;B8vdlLl!G|0?NQ"Gx{Mύ0I_4KW`b8tK3/n˛Izf,%DgGqGȰNԏtLCtnI;@W`}v0JWoqSqиjdڕb^wrX Yer-= ~"J_}Dlߘ]+.)0t0 2?w5e"1Z^+(uPM@ܡJըPG:Ч/p7~F"<Ɓϴ;er׼?oCJmsRE;p\JX㙻l9p(߿bMBm^ k%P4XzN3鱃zYSd٥PD'S3( E:9{s{T'0N5rEdD` -R#ҁ\:)AÁejkH8h7n2p&D?D.'<$ Uݍ>17?|/TM9AjOMZ(k/r1mqd[RɵXF\R4S}dS!g\1*]V{ WEEHLE(j-Hہ *mܟ/}8/ow^΁c[^9T?3#|WhfkC(Fb_zaWG4Gj9߻ʖud׷~B-[]{27A;Y_ݗ! N6lܛk޴'z_Z6ZI1w.=b]=5oqvkѮQm='O[61ԃB][te2D6GmMn>m.V_m}*'OuyoLuv!͂vm]!UpB:l'f#sX*fc 0`O4_>ics`sHtU;0I|Uqݙ.)K@'3BƟdZ o7ŷu .A CEH`23WqUV)X t]Ǹʡs`9'i<{SPzf*?Q )~XW`tÏ]xo&%wW<^M3^rV"86uJ<ߦ5e+7 6dK8Dy^A ? f.VZ1[>8K/t~uJ\IZ\bF<NHnx8{M?oT$w7UH۠4}kU+zXhF0 2:!d6TE1Af˰\O5;:s;W }|97E2p8cJO9,Эr<5U'4N`(Yp{m%bܤk5Nȯ~aVlc ^OsJ)yj&,w.zxV'u8JSϹq ,q`e6(QīPz%8їRB4NDn+U%.f64莹y<@(Kڕ:׀sB;G <}4OkFS^(O<*B:2ۦy,}IO6}_W>ݜ5#]iCr5tl _h:[k1+ҮBzxܝ.~ATy YG;_j9PCثE핿ItlX4_poFWk[y}PaKӗn}]仨$SDƁ#ݵyG r}N8k{Fޤ6vЁQmexp0ୈc 0`ӄ_oidtr1ULZvڰcbqwQߏ;mA\2ہ͗^03RBGiC+FuʎUz*峠M/|AsE^(H>tcfֳb ?Tc ~(IKӉqW8W!43§p,x췝qXޯO:g5n<3ݦgLlEZKD4ѨlҕBs}|أZlrN(-qPpxvP]JzrI[O\%\8Vi%rxGS4$E3Hl6,gd4Ê**lͷI3`$Kk)j}'9]L^ݰa4)؆ Xcu.=omQdm/RAE:EW6Wh=K ͵:Lc,u|E6tE֕-ѹ@YdžiUU=Oһ3wzEï_?^=I8pWLtluفĘ Eoǚ-oϪ_Qe;Kp}?k5JL5+[qp jE\!ͣ]"䩒M?b6=Y ؠmiQo8us4%$@+мNva|_IkGP-gBCU)K2ҧYu^gU搝3dKfM jt'+tOK`fSUk+p|ЃW?p£/D? ^a*R xtn>rm5 U]!~O0IfFZMN6И"ݹ?JΓK5JU+/jBhFp1u84=܃xdݥ̈e^Hk+f뾌|[Ճo(eFI7u|-/`6dv?KG;꾈tKZЇmc x*[7-Oj] }u9 +s.S]BOہbh+[T7۬MJYV8 B f GYZaυ ,3dӝ0Pz"}}E~{ im>duԼ B7Xn,Wuu.9PE2j2 /V"Мq2_D莹ejAlݤ*E[(Q`^2`[ǀ 0` vS89cJx.c}YHR,F[ltQxu=ڎ%BUIg&+t%mƒA|CjOOu< SkDy"Zt 0T!t~&?ƛWI6Sݼd>2268?>+\&8qb=78}֣ N3sM?^p"ƹy@t])68Ojf̺ԽP?z|#Jdz+2],xm(rIX)ܤ/kuIRf5FidnވjQc-*76ੀXul<5p%L}C4a3ejY(C%2wn'%yL( OAB&:dkLA05$4g.~}n!6m(|q&m7Y/Nݳyzؘo}2ɟ8O;r8z%T poiYU?IcM=MD}6c_ҒC]Egv`bu!Z^UdK{cC8PଁM81A,Dn^Oj-d$Gbbp "]GA~^ }RvP}#!eq gWBa).ĝ_e^qԠ͜~¹R!J;7AY`Fq%Or^x4(r~u|!en$(XqRQ38Rbtl.GepjPznB͇*uTRniP/t(};O҇=J? o+kS;peD ũP*W3D*l9bJ,>kœ_x4gJ܋̴~ ܐ{|| htx8:ݼ*z墷O|MS_rS!DY_{ɇ4_E:5\qnl+I -s\1Z@2“Ý胬6^7B3 j=7+o&6Cu(B)mmLxK:PZAM!+`A" O.m\X J6]zV2` 0`U䫋UzmzxcIZ\zVėjBZ!fPޮVc=.x$f6mqZkZ+M+*n~] 28_08u637ԛleR; Z9uIQkj)Ş':u],؞> tӨx3Q4lpa{m-ޤXR~+6Yc 43t+I-iGbjG\mhd`?F/XH;Z >5mڦ~cD"@W>qJl:B #MٺԃƝWlpv>oDklRP-Pj흪1:֛L ϴI"Ҋ$^}WkQO6z7ߩꜫ]JrbVt%=kX-Iwzr>y>uN/+^ؤW ʿNئQk^5^k4-WZϫXSbN ]Fg_OS_'ׄF*$pNaUiНM &P֟DNIN.|])Dkh$(=Q+ɡlL 8N74x,-]dFк}|.[(!e@z7<@ۃzZ2@C瞴yc?YBnYg@Ѓ?N8۟Av5q } 8hV"x#FơB$%:zߧN>>QJx3Ss_>\bUNE]D156Eu[zh.ש/m]5952ւ uYR䍠E 'p pǀ 0` )MO8c iJzT|5t}㻱h| 4I2ZKlz vIwu}tu6!B{NZFK5vy]zDTuzeFC; {l^58bvR>'"N8ոϤS3 Z Wea_4W O1vi/c2'l ZG}LKxbt$u8b~:=;^row2KPBQ:V<ڢ@]<Z6̧˰щ[Blv^*\k6R2W.FEz&]lz|3BNkicͯ|iF1;4eK"s=Kƒ,lx3pLp O5=кn ]}u~LGKVuՁǖ,uAs\ ZzK` WL׵HoJ=4SU$_?G_u `2ҙ[RL^K><}['ps˜q~zq~]2֙b_/9j=ӷ'D}eGe9JujA_KזRf=% 6˽4's X٣h,6_LٙwrwV,@^5CL Ǝv-7\ TmEk$og CSm:e:-K7q' CpKEϫ!?]~"P> L G=kV U{ HS ѣ\sz',_Nn&qۣwZ .]OfnS/t 쵪 dLgSz ?w~W/?^OHp287ƹywe<_סUomiփdP!ojN6I2!WTqRY '53P5KYnʃ։ [:AM8_;~rJ]vmhu{?Gmcqڞio'p-wh\L5ekdrJ|_QQCt42A9ny##w!G+ow,.ɿhqǺκ];26%C\FЁ28p 1` 0i_͓7xĖIv`ÙC~}mҥ=w o}zyGw^- *zF)풻|<:lwtʰmG4eU49>vPxZؚü) QlBcLi&&ʟN6v9㸡⽏ EvrTƔqWSN`:rcՕ˚Һ{jN*-/DfezQm﹗>,W6W>Rަ?\.2_fXH}j{D $ r8dW` Jwd t8l|=3Jsf_qzAvrCu?y~58p(x,ve~:OpX;U:5/OSWqjT׈L:ϗD:}>{BgJ}E> -[5,W2Q6 ' v+d57Fᴱ:w1L: NQ#AO1j:#?i7S1Vpg[E[ӧ9Yi #gW(ʹSX7Z;qX7Xbu"eqy✱ՍN1p_WpڅO"Pfܹu7F$'FC俯Alf9NvazK{nBSg{ލcہ06t(}g랝x(/mwK|%{ ezngLYoQ}C}mP}Oӥ4P#ۼ^@@[b kcpʵH{Zmz!巰Amcui}<6m1>Е5r8UVĢYSgF7őPd%18p 0` xǿ4aIr'qxypQFt"ù>>`N-h;z<غTC]Pӥe >ZJ߸Jen:~I(}8qz|HWWekFil 979Ճ8eON1`"%f"[:۔Șg.9|(%!Dk[h!SC OBXkՠՑXЭ?]zԺHVYhMfCZx;NޭS$v~S'~"'Ep'pv-JR8pp~K8pOhE8pxphKjY*mY)lPeYDba1Vi4)1 ʹtY:'dj|ԑ@TDY!dQ^Òg 5 tR{+ED YNPloø ӊ8Tr;l2wg-'TR/A,@-rih.˺4s=@&V u@_1#9|u_Ў@׎(볏?Lzкk}p`4}s[?N?K#])lH+-WȘ5S\ִ'sYcѵ&kF)g=9J[ `cl@vBcK(ؕp=Ymgw.OC#(]./e5nFW6PWeo]3'dmSH@77 JfDg), m׍m;TմY赵'ҡJ66R5FOS6DǩjSu?x<#-y]NQ1Q]L!cQ؋MḻOr/eG~bNWbͺk%Z<5$m0$=sJwot}WGW-wz1KwGt eZWԆuoi>$]go{&F&Iewil_s?TEJD{&M]|x^9_$]lj7O\J}Sr؈lGj4} 7~ Y(EsREg]Ԡ|))Kh :seF8[hD;.z"TI[O| lMGfN1B׾G!Kݦ9ӀdeSl+d&I"}dQ'w.fYї/ť&9X \𴅍PYp>J_ó+TK~qɋID׈.MY'YvqcySׂm8ll45'48z?qr6+uqM c t)q`5*RL- ‰BFjsS585@'MSB! ?J JGCm97CrYNQ)Q&8%³+ut~b{>7KYwm$mP_j*s$z[jh'J6e88FU:MigGiۿ'^s>c칁s rZ2)ϤRf|\ fԨ)D Tˇ!AJԽ H (<=+8鉔dGe(T0Ѝ+也x\)?эFmӲ`ЁH]sv]zes&Q/n@U'.ώR3f&I:|yn_$ϟJIz#ӏI_I:+MkŚ#]k8:F{Qs8hفҋg]WyBv]WuZA}\{/t#_beS/NB2`T4fTՈ]qFe!D@.d\,&ܕۮHwSO'B-Ӓ^HF=8P*j>TBCBPfc+# X OF*:ަjU7WHwlɹ5h Ttt Cw]M*T@6%o/1`[ǀ 0` /єfi˫S&45*8o9Csxu$bwaP%&qr%!ǻ(ijr{e֌Bs}M*`Z5 _UxZG!NFb7Vfөn'barXw#s ?B-db66(㋍m}Dsʵ+r~>A^fG\'}$uֶJ #3Fl*^'XmfNgezJ<Ӵ4>M5mI4O46'Fmr[9DFj,Y~>UtPLT{'w{w8ݽMwN6ΝIs42-0?~ ~тpMMzU *rί|IZe[j%sBHF892Cذ*`l(h7bSvsuM7vgk]CW\z F"*2~G3C5y(TLR BP\.mg9E6yH+-FZ~(yB0N6: e"_U? Ve`hRkkN oyR:^,W6O7_W~t(%5*8=)fP4=Z&=*w ~ɱD!few ]*AbՓ3~]28o4j!EƝvd:n1T k~6Qgk3Ѫ$ tfue8]TY$=}ij~9F7/Q]kqئG}vVI:ڤ+s:7 "GjIfSƄfnϝֆ(* sgG!AJ*ftW@INb.ʑRb=x$ޒ*πMȜ,&"cgrBWi#yr;vXWeE۳'bn D{biȱwswMtws>|Y7M҉RO?69OS)=^+oy\.}2<ǀ*j>3zyX}ehaFWmM'F1(Jsx&M7t_W1Ҳǵs ߩW>)TkOq42я!胪6WB-v>VL&>.eLY9%H 4G=_E T$ʈY߈C.*&BۧLLn'SL F3d<>RU,}w-{n1{znj[Iޣ RhFo>۞-htJxy1}Ct' ?.۟ۤ/l>9飿M>녮$y&"Q!3 }ӱ9[{jG/y]A~mvԚ4z}y;\Me=!ی<žܛo49r:%pCnb8 0` 'R7rȸ?qOƪyjOehy^juC:u'+(Ylf ePe~& ?6o uЋ πÈ(8RJtW_,Q)*l[mh5j}-<1x3M7=9%gydKϾ_i>4գ2)wX;p<9p5s5U=/ҟӗXOY% egSiq2:Bps2ΒtAŏN+"}ɩJ.S&mj"6e\pg}!v 8 AE!#FpfE]@$A=$+1:T˕6D!>@w[J:@7߃Z |lMYYjCzt7sS=CySwcāI-s73B :}蝓5Lo~䗶/7??>XhiE 98L`/4EaЅrXyBT x =RoA=?q c%p? o=hk\;N-Ar;ٰ8Q<}oߡ l:=gDߓ#P]YV"`cI%_ 1k5uCHz UYuVtd!CaK3J&4q()khN󓔞.W>?O4'4jj2K?FJow2:-_k֟O&;p8J=N?jZ:Ż5lmKе-<4/=<+i'8d@5y 24G!o HT-`WeТ`{LCZ-iu|3NC^MTd<7F.CQS繯pk eY#[Y#GD^;oc~J_Y;M;$=KXt}srո^t2ѥ2%w(<- ɰr;.gяLi#6CI޲ޜNʂv;t㢧ρG[8}o!MYų3ֳ'0@~C/o-Xc+E}FԆW65&]^[qУko@bzbHΝAoӟ|9@ڞ-m0 :eO76GpȮIs[ ۩;2vЇ8ָ8%(yݼK`n9x ܯ]08p 0` x?vheS?t\aӐq&n1+NK?ÇׁPdrCQ ]Q:U@]XViBV>V+^av"-69ILѷI=]SHj)]\6}굇yZIv=4O6M\ |afb}y<*0S޲iO6h?,d_ku:CnFYv׽cBXKU8S3nJ=3f'K9L iscwQagd8+C{w ( Ov[ȃ^'plӳ8N~[v͹IqƁQJWR_ZO~4՜'pxX8=N?{u^<-[+KAo;?`n p==0Y:FۑfTk 蒑 RZ mӒks R 'hs)eg 5 z¯:>CWYBRl~]mTDZ v~G+C3v5B58e7ripګʪP[jwulCS6vc [rup\ʹہC7A4i.۟Y-λ#67>rJ ]-vEZH=^cT2-l1 .ׅA#Pc˫LyאҷFW!ػKO`U#,iBA\F)7X#ߞL0Ϻ56=Z8@ͻKpW"Ϟ7 B5t8Z=i(Ö@[ju.z/POD+_1ۨgo`-G!9 W]'[y|Fw?hlP'J> t˞n٥ ,eX6gV/|מMhnEMK* 'p 1` 0iqkp>':ఁ#߯ h$V%)Y't2?5J}#,v!Jen};;zɏ5C1nF:zHT8pps,NñoNyK=k+yZp`f [(u"ǒm뇶K#rY0Yk̠,#!I? H_|F94:eNR{=]"!ҁNE G;_SFSU_]ldw'pO#ez-oO|b?COƉCi e5 4 먙:uйSe=fͧ_놧[ww<; [7<%=_W4E郼VGao(iK:N{:dD"aׇhb qyJ@]S7!?y.meFÁϠhqO9KI{νm#RJKB2i{xzlK*#^Cբ?ևvBoA#.vufZ|h @-=sV:׋yd6{uPa9$[zTŻ7v9rs\Qc&h|hp0-c 0`ӄ8aJS8v'pj4-唇|C^W4w;[&DwG-}U %j!Lw~$`X!ŷAYL黠#b-!=pÏ19&I}oޭG@LA7u岌.-:3C9#S dyo3Dީ4tO5׿2>j.CM.'ppoy9IԯE/l.Uv&Ѽ2ޗ:MOTJJ>Z"qq.Wo _iexh.i~A45W_fBy>|)kIX̂A3I;r̥:z*8ϐL3ZN+| /kC?=r:`Zh[1asLשxףnt~Nz4wi8O3;pwez:-.4.4f|u;P8p`+ϹǓLj;pU8pp2(ӇCu>5НBe8tAiEwOoyJ3w~i#Oj8! uQmY[XTUlEvewVve@aTW.ڮ@IO4(n-|]tմkx3@=m^薛/X_$5ZHP+wz ; Sp nʎ=`gI8Χ[7 JWtCm#}*ZRO&~%Bz^g]@< \FK=%nXp!􀠓7c 0`Oف$| ,y8x&:;+nqʃ\@|n% W< tVlكU# G*n)e]ho4Z6ݱ 0Ѧ ^!yT]y~͞@KcWsįS+4򲂩]v1)-5K]l@Ғאڦr6ȡf8gL^xTblDAbķdo7i>JeIt>O>w?ϧwGDx*mz|)=^W^H봒V9wWu)ج ^}-C4LF7m'o^H&<鍴6vghbyAW4I ?6o!9.Xs 5?%%H8FZ+$}85?2;ۤ2ߧFSו#V_2_" tE8r6V}RHI.lÞYEO^s1.˽2A% B%{[D((wѯ5 Fqٸ̉MеFcm=֬9qu#^5G}o>JwM_YOlӟ?^+#Ob!8ӡ@=PeT)[;p&`\idu<1nH uGxGԭrȔʞ4rޘкV3QyօHXq0#4*,d !ϵNC_y"\^|f0ۦ6٠J$6tq"}FkJ.7 IXՒxdT7= ?caz/k5GPlWJin55ئKe M?|IloVWƨ ƌ*=0FE_nx!.F%k4&=-W4}sML#g*__+͇NKZ}>ֽCҤ)o:@W@O+ U:p0>%A4} E<.e@GxA}de.0c8p7T/*^=u=k$׋s{t}ɳ^nD& X'|ykdsQgW랟4_ߦ'_}Oج3ƑrUܷ"mRY] OAai`:_C9M5/Ι oAM{h4hlנ>=xվ6;?Gka뼠rTCs.mu<OFw9D&@ xGeG79p(qxRqר.*sC3_*i7Ցut5+gˁ٫ ݶԶl_ ۺdųH 6v}qS{Dm{=Oޱ ظ7Ւ4tlrt|3£M y% _E-=xJ^\Y1`[ ǀ 0` 8G)m<"izc#:6ד' w((hBkJk>adě(/3>d,lsr!Ӆ釠Ul}tiWэOh +ߔvlf闺}#l5(͢qGY !zQEEI /**8%ka)ȃlH?WiFUk`8qLw֪Z3Ei-23$NlB/ntraGJۨ160iɇ\/8]_t__ qTYZ˦GS%T_ʰɔ~rR_?s$'–SNpz^͡M=]ʀqzkb L׽?rWEZL2MϿҟ٫^Wk]q5 M0@ l8~qำ+/;NqPh9p(~q2\oe jb{{t鳽gaM}kO]D8NDך-tHx4}sϟo~7JPkTv %'Zw]T}l8di3J:͖BmQgJwLNeq|BldJ\; KaB &ٜU[\+z:`,!8 [h_-:CWia!:h5-P:9F79pTNȠwQ/O|,\tDE]`q},"ۋCe] 8pvqS<{uQ];N7mc@9щ:puV!>qkGcaoӴ8@>>j:A o,Úe2X>~w38p 1` 0iׁר.:οW:+Ka8~WLVZL;qC;rNrBa†M̓̉T,7ޒ6SGu b9hol&.L}TN 7ğ;6<(HzynpLnUfv tbhm7pckuc/=53D>Mgf#6+z]8+S^ljtb=^uf'ҥ 8p)v2ڲf kMI4{i8rK1!Fըe0jwmxa,w|8}p7Ix|`muk=~F'ā7}Po=P׏O^uclZYd鿮iM]% E="(HF?xvp0-c 0`8 #v؈t{'͕hx%8 rt{ c}/.s=dABs2?"o4FPpQG!J6)]V?qJRҴ :u&Va.+1T|8fR*,(nlf Z(oeza2I݇Ey>E~LMxr)[$H\fKH.LM}`Iw(/ 蹒wC:F(e~8+@\UQGZ\CFI2?|i16,]?o~~~&+t"]WK1Ky[ӣIZ?Nѥؔiy#}rGZ)Az$;p Bå&$.2XQfCfITXd浚blf).BeIx+CLa.zryuf)+moHe и^-:+槩.:+Uuް8G Ƙ@AlVںn?31M=JW=8_}#8.Ӈ>p>`$}sNO6?#铟x C1ܿrRأ{66xln9Ry2kݞLoF|byz7 +T9ʺ,5Ы2-+걍}!E ; J{jb*u}y*}`"$htp7hl:@diX<߅[h-85E-++F>GAznw+|8@o:3nvFzjnמ<VF'PCC{S݇nZ'7w(~,-|6cgӞGTմ;Ĕ^k~n,Sno_*(=8p 1` 0ijǁ~ yx,|/_a~f ﵻD 0C·ܚ*&~^+T&[\e<%_$ ګS,!.+}~Op ɒdo)kk:piKɪʳ;4\̟p(>YHUdxj*SWHުCe&kUL̦RcK}Rx3*TP5wU L{,9^Ky??MFs?cЙ_ [~#GvV76mDF,%/Y)WN/)68i9Q;W"\t*=4ru4?3ё8ռytvv9I;cmbJW6=8x^{M*[pIEd yۨiT<+0Z39S#vuguB8p412}~d'/~ec?uՓ?^)SNP?:2͝>7V8>/~Sgc(&*?QiWXScy崍<'%N'mVy'en %ijuhqMTrsNs Y^`%]>|%)+ۿROlYej (K"|>tMF `* SzޚSỌ=<e#=\=5W {`uxMt>F+uwLӏ6N/nG3.ŁtC\%G00c7Or[lMo5h{.BjlNAe5/`' LFGgFn+6$&ݒGmmwQ޴k73 '@:.!l:D 9 [uྕ]t nQw;Ϲ7q]7 Dm,8p\:3nWYmmڂ] ΁6]у܎7w(~,-nV(/OTxI WzܤH6yYxp0ୈc 0`č|)A`Ghk:?&P(tlNL )\G~8rgm,QS BBU6U#<325Om-. ^?h~Zg&f(̪ сt&52bB>$yK*vX%1&QPq wC'_I\kt뫳MqFlG22ϸK^;NMӋ/?*4Z]6ط-n%2,uX@5~Jcj2r?ݦ]Y+-V/嵩Zy^׮2GѓH6ˡ=uʺCcB B(a!z]ow]@&! Ǯ3*4<$Cq<N;d OUز!PiQ[!#Z7n^8vrLn/۠ÜMaK^{wN|C%lmޛwlw.3жXh(MzhL,:'}eMڃ.ɐƂ|xs[ 08p 0` xWT|'Λ<.߁}~Zk֚?|TB;N\/3ir3]DWtm'>*,W%٠<mw54yҏZ}pJ}Fx?\< b@ͳ]I\5Q>*+7 )( PvQ -Tl 46ݺ"ۢ{>| vyl?[ˀ7'L5}ȧ\k$MZ%κ]y('gk7ظ_caR'1؜I۠5FW9;@y)g.)M۰Zi>X+n[⛦vHd8TZF'k:G[{w su2==I~; |N;8)lӕT\IW>6xeJ} XGT6gO7`7f)V!3BE xTƳ\a\WWr= ԵYOv@kUGpȪvl|#ƞya^!6%E8ʹN4<=;U'wSDt5j/FQJo^~t,-,]i\z;Kk8-tZŕ.V׵g^Z뚒.N&5r)zW⦳JEmrM7C曉>H Cѽ\IrεT'"=uRL=IϿ}#kدL?~z|)ŵ )zbښĘ7|:;UK?ӗLWŻQ1'wYWJJ zhEO]a,  oEZ+(\~&^׌(YyՉb _(BЌƹk RT )t?>~o<8p 1` 0iKԧol b+:<;{/qlx&ϗ-Z "tV:3[%^|O/!Yx*ئ:Q]#WБSFOn뮎xе7/NBo=xu`25zx]V`ř~aqC\5lAYm/z`1.4{bwا2C.ބd1Lm7UMo`m^x_/·ta=b@X?r|q\8w!m8mױr =rT3>)|# "*ビ˹L koYw>}㿰?}>71pٵ/@œBuȵXBb1pM2x%h5XQDFI,!莲 ƴ1oo8: H6%q)B::>ԃ+ki:}ڗQfů V& 8Bd[hFd.$kgM Y᧭y`|Mp$$@$_C}DPƞAf(fYsz?1dG6p+L,+u~>ƾz=rvXCҴc„w&L0a„ ^&>eW qcKON:Y9qC8_2oq 1=䢭N[@ӕd1:KpXbřmZtabCf-;r =}'.ҮXsvaWmgor^|2Y1W| =BQGH.=/s-.!Q*U7[:-8dlbgM+G;m},/~ gS_y`W 8hIygwi;{cc?%⁽m~a-bq<{ʉ(ׄu$S`FGst9˕dsnGsq6>rԃG  H)Ѿfx*gM1h{S}f k7}X9 $m- ም!Gt3{3t#>!]J3njƘZ趜enھҾO ,]l,ix=QG Pl.f{ۋKX01Ě }~( Qx"BϺ|R$Ec7EN^ "rߠ^իوD Z-;¶Kn^Qb L 5>jCEQ(t#yen" ~nA5'|IVdQƌ OnG2CAߠXm7>r>"}rl/_Fնx8a„ &L0a„ &xa]9Z+W+\xQg~Z/)>mcklRp󺗄ȶG{ 6̼\xJl3Sܐdb*#&eiOeG'cbωS46njv%eYVb9W;HbCrE['2-ʭ(D\Cm;,?z`rw@J/OS{vqes{|>k~ٯ}7no[7^{f7ؽ;<3;_rE$'K[lyܖm>tM}8 ]\-0W!k Qf;-viogJ7Վcn]B`mm.2+`8h~;qc *r`ma{D^z}cWsmty3ӛY.ov _ n TJ\~ń6"%^)ؙ.@SDa 8_ D&c&-\HH (EPsF#烯lmkNQ-S**%Fbs 6Pa#s?ƨ0\im%4[mhQ)l%)T&y]vgϠLˎq8]g:PI.3k'?,0Ql7[ni7[.(8V̖솏/f[ xyeγO __o7o {Kl7No#c?O|>'C>m}Ywhfg{f{;ol hr=4;ɵ-7?KЗvكΗh>zdږg]a[>zf:y,-l칲.3A)W2bGBҋ'΢pL).w'ٟbG, `;Bɋ5 #m`)-B_!-.ѠO'&>3.}XH=qc1yoGN엜h}Mcn/i hS,J G7x9zg-e-$qMj;i/OAqs>2[Mmh17,c\r1C1 ǯ7% >%GeGl4O=Z_T%VIJRID:3a+R):y6&HQ)p`_LZI\k-`/#5tPMt}f,GͽR\, IN3er;|=.so+b?q>qD~)BfbtTXP?G1dE}P`H'bfIr60_4l19s?t@_wȋ_ O[r΂A}@Z4DO(3녏*C-yяcWuqi0F׋hB;n0Ԯ10Ght]lq|JۘIO4tj]klrB.k?. f'Oڢ@09۬Q`ǢDy]Y 7Kr+td_C?}}i站,dng0eؽ{#Sp7덭||lfvΞ]\ vyw<5:gթ0ɅF+äuo8ot\w<{Į>.|آ\>vTl^>]XC-`o>g^n7bå ͞=\AH"<_rkQO\klʵdzE]넮%L7*#|A)k[ !ܦ{ w/cuLvY͜HzgJl|?2}H߭ sd_א.cГyN݌cz.9PYF7`.C߾}ecq>_S/'+_,Ozy ycldcJXf3If\8CmbupY!t~mt㸯zɄLpT}W|'[!~' Rg2 RJ{v5~FR ]mc`gE)_v$G؁q|~ϲ3UAsnĎYbaŽ8#s8+iN'PEQlb%o/>ٛCYo؉xh?Bo=>}C+6WvMOѸAH5(kP4O#N%vKA)qwlNn =ו1[/G}i )^,S|EwU"nNVs1.f5 mQi@id&3}/+1&bP Orw c=r$azŠX*WD=БSj6R<#Q<'+I'8;#}H֨k(C PMvJ{B+t;k[l"<#)hsN6d=,S/WSb|Cw_qNzN%xZ9](Ҧ )#Xc1BNRᐧP,|' +/ZPi@ףѐj@`}A ~&_1C.eb &0=c„ &L0a˄g)m%9M悿J *ohr3"y,KC>t.ul/K6F',iF(p<ψyTԅtn@2Gr{}AU|863U, y葯 $}LbP{H¯ \" Yt2 5>)zUTrdFm%N@& 6AX ۅ,_P'Mmfr~Ej/I-BɓLȋSY{U'vɗ3Xcw$E@`31&F9Ҵ"'6쑇OeRYbC8׽ Iv&|77x _䳭ϯ`O8;-O8YAk9'ʣ=z0Q<~ J務]NmqnÙ}~'[>.!~^?z_ cS1Ϝ[;~ëh:cocy5t++i.vCKgN/|ƹ:h(_\x'*w6Iė>E88MvOщWԩ31[DBv=-V'xdZ(/v1|hlAq:Qиk>(e>4 Qoi˙f/Г9#n~)[&+8.~}on>da'~qoOEَG8 ̃eߦݖ}^p.)7}Z4|^T1le{cPlS} PvQ ;=?q$:-M^zfЅc3 ݬ2~+M}2‘cv+3Cj2gNf̽LaH<bLj'H@po#,eG %!SG ^,t?BGp}|#nݕ:  e@h 'upx{aDZVT0J\: d6[GvT CNq,5|[{%z`<$~%T[B}D#NfwAq% ی3kSv;?`h+C< Bɓ p,hGt~c|;LOبh?l3΀uE<}߇z?w~iA{d n |Ǝg&kt*Gs}< oo|L2RV' !ё|~}.d!D2,/XcN>d֦ryF-Q.dϔ#T -p>8~LOLOɏ5}N?!nwp;!fz:Ҁ~0jsyYxXvc{׾<]ڇ??S?5c3 |T^4on's:C^P*O'NpiT;gHr~l;Yǵ>ғom'\>|pL4?b x2&ͩ-eT_p8ȋR;7P}Bʎ;-Ս8$Pԡ~C$$Vx&X vWCiP<7}F<~h%c"٢$ d?)c)ƱZ}s[96֞,~oA/#,m{!_p56 q{#2+d"q~][܃iDŽ 6L 8&L0a„ &Lp,p8dΧqq<[Z?y6 FH#Fֱ1Xzר页zW40Hq_")㩄 1}~-,KK'z>niAe|p1[ģ,ym~{}rьDHZ$TAD{- Ж [Ǟ-YmB#>+^<ۇ_iq{fN`]]BW{?yO[&ٌAG[82l޲{݇5O?}Oɾr}fO/OĞvB?nciKv u'P9t5%>b&v/i$x-*:n3.@-2'V/0FW,k}%-z]Ʉ?Y}mc98WNR?:_v}yڥMb|tѧ\P˓c8ګ;~-{+^,ؐB#:210/r-G?: .;hT )rz>X]^MP1c5BW >׀ha=Cƨ2#o?GNPբ~^)1W{!%^DRyi'1D[ڶ|@$CF6Vv q?ybX72pLnĴc„ &L0a˄p|p,}s=7eCyKeQi=m3煥$erTɋܿ)3t D=çPH~j<J!"w3VK ET~{ڂ:-L(r~Tր mVN5w Fxmdy!RГ mm~ .81Dh w4uz1l6,~U58fWɖڈ&4Sh`ΧP'QϴLu=U \|Q||Z"E򜻑z3ۭ^§JPO(۞8̹ؖtN/, İ+ozd}}v3_}꿽'ۇUp5GC9G1">\=@w?w}SB6 D o#=17|b\^سm7 梎]ol;_v7׃8v3Ѷ% 5 _OK@L6D?B)jԯ@etu]>ZCͻ v ɶXN>&۰Q mTw/złI~-Zc}K8c~T+̎3mgge.;'pl~ۯ;_~oe/'kO{\/ݮȺ1W? 4OPK&e^y!W[ d;#GǝM>C`?j3.IU SojovgbSdSŗ.WAM5@QL1Izt9gȹ #h}uʆ@c-Σ3m<Ы=$̑JDӄr]11@_F1jŁ~/R )Mr,T]S^}jmm [loGz9=NXHϼ:8^sjQcu'Y?Y!I8̧&1-0a„ &L2QpKf˓L\Q-tCWm#eZceu;?=uYƿ\iB:j|^'88_g}7d,Avc[ : 20Ͽlԋ.xaٍb&J^e,QC>-tMdloǣ6^ryÈ[mm=oS0rq=-h2j9]{*Ew9ІO6G2Ep`hP~J6cY h q9F8Cb&^w6I*99hヿ$^*K| ;h* 807NmkK6л k;_'[{}X.S{tT5͙-+^AjQopF_ݽc??g[ S[#5dA vD<޹1{v'bٝ]gvٳ֮1o1m1/#WR.4$N!}U6T2Wd- 5Z[LAC8[G=K'* 8~稬 Tʓ#x_?~Qd\pdzӟj"W/ugL w!GYKH#VP~{q"6ROi: /@%MH==}Pie!"Qh\Izxb;? Щ͏jj_׮OL 8mlPB40Jˮ HU֏PH㶶wֻ#O[0?]89?+";w^qgx,Ns :rM\&1-0a„ &L2YyF.`bYsg0RY:VF=Jsy>!rA+wzUdL!Dg]!Uf8-x^dD\wZy1aՊL ׻v )ުוi/D ؤ=U `rSc/j;MnF=3!9c:~] 3ȵŲ͠x+ tGcOWBa,V`seİM/p )u@RBuY v3Pܡk.5y mJ)sr He|fqT9 #ETԵ;k pX+5' E@^OxliN q17@gå.3㭢aP4ƌ#=ox!hgN^ 2ol7.mП!+b q0Ž_.ȭz+k^vBB2-@҂1y'ASE s!͌OxGu^8V<#:ChmEl>Xe@A09pǁH/ \G 8.?~-nV 8SA`x. }O=Ii{yt- qiZ[ۮpcݻK3쾼 ś=0&cߎ:"FтW ߀_g'[>}.AM.J ]7v} OmAa(SRnQZH>.}WӮqlzwri⓭=^ڳw^F|R/ #yu8!sŴGg3{i#{pj^9W^g_;3V秶_f:AG10&|~qUmC ]U>(NVJAc6~Ⱦ#.aWl{C* ߊ*Ȋ\hrm*]1 sNw#€P~\oAݚZO.HF0I4Ήg}ү>/o϶bݔk҄nHr'bQ =|HTM)YEZ?E^Q61lcm$DGI'`;iy\ h带rSS$:}?QoUOI/)H}e a*63z{*u9DDNV)GyOQyRjo!d HX$ȥ^LPc+ R񬋥H(rHkw,"kzAb&>n21sˋ(rQ2E)ue%'gwmߋ;>A]$$V9z,4Hoj'mTufsQ?ԋlӪľBŞBAG(2Nk2NO0݆ &L0a„ ^&3:eO-.*|s&t`9.F9GFNo)ú7s^HU˧ agS&r |^漻^Eh^YƠj`.3^4t ' h>/ՃBRiQ ^ c,#@^ yd<+X\g:۶HP]/bd[€_qq:Nm]}COR3hTn%h[*Dm\/C 6W@oUƽ؂tW\ħh6~=O_y޿//xmkKȹpMxL/&?r~,vmﵟWeKe)sMPs/9 :<$zsS Ru^ ϤG$=m]O9Z,v4b8 &Ţp$C:Rgt 2\*d(ziCYzxhYZv:dU-٣<*`; oi~yp_Ay`DY>Qԓwzioo,AH]L$:`FtīdW됇}8! }aQYO?XnYR$?m[?w[Ö)š vTw 3p?~|r2W~yd:y>]cKscݖ uv IYS*r`~gΦ&0-0a„ &L2i I2|I7uX&uS*Ĺe _8 _Uڤkl$g:«)k>x ,:U e^͏ho r%%#U_,vJwJe5N@sҙ?9>.‹$YTGCC+1pm7TtI돋 ~y,lٯ7Ej_X;3 ]mD%=Olc>ӧfCWg,gyAI%۫z>Z1xsh # - 8 Z}" mϵ3/qqݲic(Zkg\NHB4ŶAu^7,棓Չ꙽r{x?Y+ثHe"mlؚ_Z+zfO@ۭml S^2(zK&f[DŽ7kkc>;aSlh [\':O>a_υk?4!Q?\ ?I -;=Rrzr1}. GIA-Q$} B~JWz`lʤ{ghe}@#:o o z!s Ն|4ArLc~ /A:poxsG+OW;>>x/'?}7v^.@L2<6cfqж/cNՠBF ́O_Ec$B 3czj; A:4Y@v܄jѳ}PN!։;m:-x9#32- x9HCg mK}&.زoHVhT0b[qVvk3vZ*|󓕝.gZqv̖˥=xt^{=z<^.l}+.ͫgvvlekvc3877ev\ح/b-8.A ڵFk40fC7M̈́6glnck6;=-ޔ bݫ@lGH+z4D?>olB|O !"1u&K@VH0w*W+`LP%7I|/F j@ltK91[ H>̧ށ<lۦO (.eZ wVn>9X1/ 8>ם'^{WKgo?}m/`$E;7a1WMb[2^zq; Yī37:گi}~ op.0^;+ JI"cfxp>ptzQ:k!ƃxoE)c <D#֓-nF!ZjG&A]}cp@_Q9@5Xl}76vpDw6;<vMۈnlѻl^?c 3'<6f<𲵲?h&Ac1@d㶱0rr"%ːɼ;Թ |(hh _ae]d 0b@t{#VLȑ:aiZ1a» &L0a„ /Z%_P|nxK8,`t># q[M>ȳVL&zZc7y7$=>!S ٰQǾQNF*7E.h3DCiVve.( GIDATǬ_B*@[g(ޘm . f|έ˅-NvyiSeG~{{ۃGdg{ۮvmdmzZOgbooQYvqui,N'ex#SIR`xAHfcQLb׎c\9mJ;ȇGW綠noX|ш-HJPj3vޢqԥPE(v ˥lF)PqX)Kuޢwq;/#{1l~PV|%UPȺwA+ ʾŸ7+]?pns;}|ǗfGO=׻(44x)DACGpp[zFC- 6'eJ8зm_ l`"ӏ[q#DigtK{zP8IlGhQʍ鑾EY~DW g >E=Ǿ7 9_9X_=u~Qn}x 8nPoib2?ooFL|C}ym7胟Zy׹%нs,A@E1?$pb/r2b! 氋4-0݇iDŽ &L0a„ .Qpy3?yy};[o6Ηs[l;}:+x>٣ӽレV3>L6.̾}靷ŅV\ԱՂlevx[c#ڵ \ݝM+}EnlXw|o@|OX#W&ͅ<~ 0ӂ77u.T0ag_SG͢\<ҁcc|UP%ɓWz 5eQDwQ: 1^ m;=Oy)!d#nOڀAmJ mؖF#+w]v؏C6=S/_q!*\q#NyCum}޶ |" !2q`֑C] ߇">ٴL>~cR+y /VR;t| 'Y"Û՞oF  1WڇTSc"{P"Y"Z:RoGA [ZѢhu#Q}l%֊!OfIKA! 36|˩ۡh7M8Gt~y}7~x箺B:p{ʐ8Im鱌tn)&/vGŽ]#xAe"RuePo^ShR5'9 y(##|ѫ\-GۏU⺏^-%#//Y%[3AO}Qϱ' Wa}45cB&ǢP} [ZoblPn$.kL\F&wDuP}R˺qcz#X`CcWp"/0Zy4~e>['spY,,nq9NR{@q |jD3T1V\@3>h'k[-''vvՅ{ D sa_Ǘn67h -gvzRcZ{pу]<˭6V`tesH) Ǡ)QT-XpP,KD!VjVyesN44n/+XNueYC[q)dZmKBٟmeA^;m;Xm ed6 ʒۖȾMe{$_^Gήcԇ?8/\aaO$G>?(C6*B6ӆsc@M} 8bTiM]#ǎqYx-s-ʜwjVUdBʣT]~ecF?#($o?Is<Ճ2G}{\1pS5#l(Z k|'B͏!|[oQ0cXhHHC 1Ǎ ~;j0f?@E&Mf̓i 8^ /X_lHm}pÐP;[Pm"Ѷ#жuz>2/ 9P0&M}YN=dXo1=D<-0݈iDŽ &L0a„ -|o+T [#u䤁ys`ܞy8&8yя.ɠ$2scL  ;1u<']e~RUg07 1]L-k$@C}e1u]P* zUV rj7XBd?p}OcYHpuGs>tZWj1!C109@27g jGJ'C04fp[L@s]ۧH?d:i.i<,);ԣ/dږe˱MrG.V\ _sK|Zղ۹- nEGPPr1Crm =9;G<^;[`h|d=}vc\OXk.0ljnV{u~j{B}" 6H| ⦆v~QN0 ^fj|6RqkU{~0R.Ye(wp(k u1O,'VncgV)Z!|B-Qd#%?dƋ~F~S?QEۑuZn㇞3;^w=??ŽOZsA}} p!_chSo <6I֘1_z?єr:ӣ☐O"?Úx^@%qOO4_1P>DDb["q.aBjOKXVd\0*L.]7~$-5AR̺|A1j;'(Ϫ ߧe63Gp8>*eeaqDVdrc 3ke?tR mtbCX8En`@cc߆㮐n"A ˀlapJiv{~!vۡ,y T%/_OBy}y?|^&B"w3V"Wۼ-W]JLavm# .}X?\AiDŽ >L 8&L0a„ &LpLJ~_|eZā4[,On&95Xs%B=e"lE&:ғ;d:3 *r9_UeR4I`줋r:qCڏ=%1};ژ-CAr[6kbCۦ!mr6k?NK6d3lSvJg2ey!;t7e>PG.xؕW`LcW0op\Oa`>jaN핇3div ;o,wv>>9g{wm^۳ڮa ?ٓ]\of sZY5Kuw-!fۭ lӞ;\Ѣ8b||`韚}CٞY6 9 K]h+?[bz2Z|P4q`Rcl4%&do؎ |܀`(#uq s{,T_m8?h$?KZ3Du _ .>_>vzNno?3wv>'p. hS.vd` W$70~ac 82Х}}[Yc_".v(G{Hg$0~b2a~`({.:ܦ'0Ԉ4u+lɪd4$iLq!_90/2'4#vWY%EJ$Օ6Ճ? /$#fAt>CDuTPMzJU@DgQYBz(w}]d[SV9L>lvr+UDVѸD9#QlнLD_E\5f #`*[1c[%qts[!nPߡmyp8Tr;hgjl<!|NWg'3Y`#~Q_ṇMԗ O'Z>dpܡ%`0Vw1'|M UROy_rs;;]VqzzklrgK_|z˛=]ܬՆ vK$IJlm~+bl[nY,r.nlmaht|peξeT ~L#ೆ# ue2E5,ns=>GQq]4 @ l11uq$胩x>ePFpC6==p}axk;8xxj 8~ p\sEyF1fB;y1CUN er>9%6:q Z -.:~xKؙv30j~r[sy/_K^u$=oYv;G ^a9LOBx$ȡPQ|`il3юxI.YuAPIo q~Y ?"?c„w7&L0a„ ^&7 eɵ` u.̙x:_e'~9⼛0xN\yp;]E{hw]e^/?{ւ>CX'繐##&@.^J ]=_st' mR)NvN~G+Y\y(˔ -eʓyN7s[ZȆ zFJD(kl1ۧ6R:Y&"(.>z9^HPE𲿠y_>/Yyu[>BfVA8mm91|ޘq Vnؕ_Cd1G4yV ,7e:g(F$5  i!AC>^7e\:F,xz7{ A+\<1*\?=S=co+leV#;jo;ϓ+'3{v3Kml zk):|70G,a+e!]6Ez6[BOG*CT+ƎR_Xˆ%MYR<GۼL}34_C i>F!@>Z:ᷭ!szĞ| ]ﯟgo'_)A,ZV)6,DLc/H_huևӼ{ U{|7 }`X#`16ϒi=fR]!qۯ,BݿwhlfDLQ]q+h emxFَ/:C_+ubP+C7hep~3־n[p0=Gߡb'"A_%t1@s(<~c!m%Y']H(7/}QT?ᜠ~Q_Hck/"4-0݇iDŽ &L0a„ -?o{^̎o~^ 7t1'y's]|} S֑e.,2œĉ'6ywaqu.bws!.tJ; N !,W^qYzDg7TG[q;]d,Ů e5PfF*P}v*J6d4 R72՞SK>c_hbr/gNV~c9{y&|Ϳh"ơ>:ܶt6![Ǒm6_o86P9o֩x{ 8WnKMA'υ[-_x/k ;2VbW7z!f4r(yI7A_M69<&K>4Wņ~[[-cCW(\ ơ0 tnMn=%?W{މ_ۿc?k{kk77_?c#>q#q$l)' X{*b)J=p}~¿D7; .?cS[jvh@s^kI/m ;nCMd|O%<1[l=8x{%/%[%8( ,eŇ3P/ ІL{l']H҂Ͱ{voPA՗e;#s - yxaO 8nOVCC坈`m=evcH2`Uc+Ռc!mvLFIg˂˨tئSwAP LT PpLôc„ &L0ap|?jP'p褔Lٞ ,}xuA|`:B)xAY~Ih3[)%#5Gh-TMܞ@`d}{D!ʅ[ۏY7{q^Y:[G["' FyPz>t"9ϼyA" 9qˡ/5#_m JL Üێ~l}U#hn3`=a]wAغmv9b~e=dL dxi;W1/Hk nIA\2 ݵHUdEX-+̑-N]n olKXm:$O._1'` SV+A+.)bl !Xt_Cs%l5|-حo LWs[]SYf|.0^[wr.oֶqc u~wØfi .lĿvѹHg@W^vH?~h;szj*93$CDj6/wXEJz~j?_}σ+;6q/Ͽ+T\Wpo׺AChoqoU'~kbtelÈ `p[dBa"HL`8>h7ŹF~˃g¶wzJ̪T ^+lk 7uʕy,G^ls=G.;l'rEG}p^7k:f?ovCʑq1`NI5Mɔ ; M!];7 vN{LJؗ^IÁ&(1ƹMEϧnZr4#NEZOA߁BP\EbHdE(~ifX.Xl@Z`hc`R1ТVHsZV'f= `MOp}\^ہ21iO 8&Lx7bZ1a„ &L0e,=8mMO+TxssHA:sd:2٨y-i4ʹR-?w(BcWlzAd㣜 xQ #](aԑׅTtð2>M/Ǔj GH^"!e 0h~ACc$ I"0uMiBmcY7{7 ~bU= 9V8?Y@S=@#_UA݆͌ N % ;KyHr[a=`lO(H}>V#l3LYq:J!<7`,` p4]Ǎq XՆC6ܔ=Ys:r:Q(c<:bLJ  Z4G.95z Lׂ Ԕ:z젍bso A*W8"S{2M: {N gGۏ(5B"h QeiWSqeȶ= #Jbqơ}2Ǻę'<{ p\v/#>̮1W|ʥ1bz|k%.cO̹?G=]ۂwPr`c ӱ8UVX(}[>O{"ǘc#a*8cfF\ 9mv94",WW. {5nc]U.e~ cBsA^8sg0{ ' }I׆B6R^P>: "qehyt|#/MίBMȽNtF'/(#}P??=+.!Kݴ1H)*w1mq3ܖPRqp#܎hd-A#'|61WV! ~oo(m Idn6ic} dLӻkL><4"#l6۸y oc>}yO56*>p6-0]iDŽ &L0a„ -c7xQp<9ϧ2ys\8}YZqYes`7PKw_=Hp]Wb9H2f츎px/}΁ 0J}հ}[d.7:Fce:S"n}#_^]%ö=(ʺ 0P⑞Rh5fe&^R6k` #8΅l 6d~BvɜSm@Opw*ǥ-c[ 򖫙=x'vc:va73nl!mvzo;|-fvf(* N5 9lVCȩ[!38[cnȍm>Ncbh{yնwhhaw꧱ :#ɷ<ȨVRQ iZ1a» &L0a„ /Z=.xR$\2C3W~y₡vg=PI6:Oy@X'+PRBz\[`b|L_aCBek*,Pk֠jRGbz9ǐs\hsthG|h KAՇAu=N/SGygܶ$?'tk*ԛ- ܋EMv&31Us6>'P b /@v,A)"gm/:oyBu^ytN 2!ah1BgG'"B]rhΔd%r{m**V۟,y3,YB1S+8om1yWo@g.Pd}qj|1+zm m^Lsg9K|jS˧rkXk;Y-llrf߷S[ܖ's6ݮfkP%z i\[[#vV;W\m3v+^q˻#zN=OقBl? ~s$Ν58`{ 墣9 ?N;=oXF*ֱOT!jJ=rsvE'phbC F.l9,T|%1e1c);w 4[&ow]NŽsOvup̌76WH&6PL#,5e|U#.Di?VEs@I' ԥ[+%##J3(XTsYxB~@-mxbTΣ>1 8:G"}&b<5v-BJvdr9+P4t,Sg퀇jV/-_ /^fƉJEDQu C7+T'u NȒN2sD/x m{G@M܂j+D R՛(q0s1mx 2o{8U*;@ȩ}Aj! BQl::^(A'ξɷ )'*%80&0-0a„ &L2?7[7wGxM GI8#WΉY+3Tҹ,.udȷHg}|0u划9YGHz /'~ʆ3f -B'$hq3rDEEɲw||Zg(4ݡت?^ ח/H˅x腒^vԇqP$|? @tK9Y$Cdt >v}Uvɶ*-~u5fC1/Y(m(|se/td )n~fۡO˭=3B6ߐDVzj gA#r~dΤ@<(Շpl*\B, [C~$2;M}r׹]*<'|ȴn+a}7@ lpO8].3F[/ 3{fvbkO}@~vlkϮنnvqʮw {_ײE}n[>b;g cGvDހG@ڀv[Ţ+A(kI9w96 i4 m&R96ZX"Y95̡K~G$ѷ\Q78'@LJ~,P_ 8z)6tQ|SxDUDpPX@E1n=WJ΅gq"C :I82y-q=wf;vخ+o߲Ͼ3++Tf+ A[Mʾ@p<㪾|p(24&Mr޵gAV%8vJ5ieIp@v69l裰DĕяkW#bA,Np.6LEV};DD m[񫡫d  KrQM6xw,9tm#mc Cm :6 8#$joLpHUd56*s/byZ1a» &L0a„ /enGKq[Syᮮ,3'pL17}AΣCh99g`!k LqBi7ڗ}UɗbFGpU Hk/fcA81r1؝^ 2egk8E #; xX9d/U@$r-(6#zmU\N?oQ%켜)׹1Tskd1*;C.n,iX'C!e6II1>9'CAjSHLsOJ;Ky1t6l3H(׼agxHdT6&N rDy O%L:GصWyp{4gF^C~Cfz]4C"c}֣:L /YzjzSnU.Ӕq%w Ņ-ml1 ~mg8]ti{蝬(anQ0Sy|W6'u-h6;ۭ!ok7''=x||r.7achYUt=̓)Ü̝E*ؿy$8=HcU$Jp8(9^Tc6 [>ychY oW;ng˕{߶Ͼ+l`y~l# ?-s_1<)C9>gWMQe)=U(TtY*]y!˙RB)DWy!=^PY tEy'>QSeV/LV@rw@:QeGnk@ʉۚ@(`1^pMLwzs>ҡ!EPW|b"lTGѶ1U?7ۤՎԡW)R&6q }=4@9L 3eG >erj_qB*;/$"O6c 8r{GߧQX+8zEF  }pL0a„ &Lx}ﶽ^§o& B_"rC'ž#rSAz-(G!&9}=w82ni|#ezitpA:6n!_1 ;ܮ)}B뵓Űqm5Q2T_/I$գ-1~r?7-z'O-iIlG$"kLPw}AXxL W 4b@cq8Gl%G9mOhIȉ:#pQV#}'dCoCҩmqݡ>x'ps[3JCQn5 N+5<׏Slw`(e.@uv^7ǘb9_䰿@nzYhj]mc'vcr{yܳ| a޼E7s{̞]=ZZ gsaH,| cZV>8;rn,Ԏmx7nssA7f.c81^s-D3d%ub eOl g2|2 u~ʘ ɾ!h z,?pT(rc/iUyw /Om}{i&K5p+o|o"K>dw\'f?1OMu$c!H}W;H=JB2+z}B:cSiZ'R^R5xXwZ/)ۆC"9QJܧQ"vCnl1uz-.q{W~?蓫Omҝ*α~DC})Bϧÿx UQ#c|Z1a» &L0a„ /zw.8^⹩cyY :g09'XLίSy::!W*Zθm@K5ճ?+y@!J+Xm#jRrsm@э6XGs,A1sWv(%6>;ynK~^usR\ ~"UI,@&ZV%D_t%l$krj/L'qqLD.(YMlzC+˯#l`FODㇹxnE(;}u*AݬOd8< eCs=}6=;5Yoh͐6({:ss6G-Xg}+=ץ1K>Ye\xByVؿʡ,@R,DNTl@RAZ1$e5ۦ?-f~/06?ٷ/ƾF R`R8csμF?a\mebp1NȕxIsP&1-0a„ &L2Qph 8x*㜴^a9ͣ .w N_iENթh_)2hvS׈_,`Bo@7Q繿N\g9=oʈx "' Fǰ&{q,۩>3{eX ;nSn6m1p_om6|? L껈!/Ʋnp |Wƛw]A@I״앟7vL?}}+{`oWW{CK{ui3wAzzenfxx\A>_BGթ]׊evaU< |?a3;?[|}4)ųm{-r)$q,g"n0֞ b&Җ܄ ]} p1J1m8F!G[RޠW.[-4"ʾ}{LxT@]g\t}|Y[@67n [ȨTF*+`4s)YؗQ(Mi'N>Ojo\YuG=-s BVP8<<GYOՅ/2Qe0H/Vf޾=P(B'p[=Ls z1Q63>+,wvfǐ<v808֎0vz5}CA@B+c񔠛*ZꡫFcjiIB:$0O_ZF"m ɧRA";]=I:Db[at2_F GF!􈡘V?T!{Wcwy1!2P<?8bL:P">'מb[Z9rJۨǢAhZ1a» &L0a„ /ZrS|ڕ 8p?Mou'1uqg|nผ L9@qKu߃w 뽉V=1צmW-:jxjg!7'X'DK=";N<[d9Z~F+KH㈼Ϋ ^Cmv4JjPBrk@1ǝznc >~j#^Ϯ'dB'IOex`?k1WTPUh۔y!">0nw $KOFS]>`q!k, b/`+wZ4d|bi66|% >!df ''K{^me=z`C{k[5Lk~+wO}0.|Xߚ1r |WCx#_,-vpn܇TW}|{34^ZOᾼv[o6hj3|N)!\A[,u|\.bJ6| x3=:%gr(-c8 Mqy `cCqsr_s>(# K,[AۼcG{5b3;ۿc]ޠ7|:+f` p'o w7277s)x$6S{Te(Xk9S>?o%#m_X=޺p-z+:|{Q!d?‘c1/j GzˆX1y+^tG,DJc 67!6jP9Ҵc„w&L0a„ ^&C柴+Ttnp"ZSy]ˤ]9unz(^D {n+﹗x͏`i V]z{9@RĔ|viwGڨ/w]^lpڠ}/kCDZPK%n?i[=]Cr[KR+fEԻ.l_~oT)jX뗲Il+r5Ch@xGE*7x r2^uSڡlL}|]5@"nC>q# yWN %#t &;A?"~"1+X[ilãۙszL{6֤'dŖG -۵ 8;j̾(#(*?Pjׇ%FaZjt'Dg'S7t[e*Q.+o. @Nږ=wfr3;?/ <`c/_-lxٕ*WklgHlmn1z;xG`^ vZju ;=:[iN̮gvI@Ozkl>E+>Oh!-xuQښ5hsM#\j-B@YO uOJ,rYkrq&_4r E|/ 9~sႎQH?a ;[uaG时?iOPЫQx_}~mvSƲ5:@mBNxxtD?i?/@O]@2ROPFJ1'qHN\O[N  ~2 xunTTŜ>8>خn#GpZ]E']R@Ы ?QY@si ]e;l#. yu2}V[a=s`+xe!HCצ~B80=kz0Tڡ]QuM꓆LVqsoC5-nE )OZT1:C2(5N~oidF{y~ϱkS신e<ԅ"F|OLI*eĖƆs epL0a„ &Lx>7|o!Ox i2y*H7rV4tAGq݀:q- CU^c4&_Bmڢ^VʍIPIl3E(WnʎIQlcuQ..>|m(wWNfˬ0mR!!'Ot؊q1c _]yb @pRɉ- + bh 6ƐZ=[cjb<+'DY2#vcGz|u*l% n/*} q:cK\ge=@,hӐA>43, Tzֆ(Hljb#cNMz˫EIXzm's~|>[׹}24//*1w(?&6^:Nv*v~Uwz: =bvjfĶ8f?}j7٬fҋf֋=C_=%myO"a Q.8o;Yߜ_3-+zn5 i C;}s}8ކ}>gcCdc4/˸1G* \KCzj/&mD<|'{o[- [{zǿ>cp.C 1  _IAAan.m}E|UO8 oGCüRF`d|Px;#a{t$"Gv 0繎|ʜ\CY"ULP)V$Ypv6V:rs+uPp"}Wmrծ**rC6t54)˧.YQ1 eACմv7ٷYhUi4 fh4k 8lk)^#@~~pD[Q]ZCpݺ#_˧~˺737ƶ2G}9i@gDoWK:h})|ěJ DDZQl*ʲ9 (Ek*g,gs[kxzoCc.rԵ3u`phO}{}hva8+Oddzn>s*n`cO0Ц=@m+<Յo֗쒠Wu,A~}_ؔ\KeHG)Ɔ6rXIHyJ_!S2WtmPCA7!/>|Qtإ _3੎߹  (2__bp!:}[pvZJ_?,[ڣLmxw,@k+DƠK QP\۶?DTbZf}Q0)4/h;dXz"@1R>5vzh7 ):ʼn吩}vZ]/'N&;-(`!8"NYFJq[A_⌙%3񺍮iWƺjBk̃Ҵc„w&L0a„ ^&ƧoK΍\/6ȩ2:Nt'%?tyy>GE[D\sB/q].t߂dʰuk1c6[n5v:+m $ o-l`@簯yS۬{߿L᧹zG߄6qO"E:3ׁb x([J_|=}{)y]R@>ႈNp>)9 i_{뵚4_.l}\! c[nq^yxcVvkg3;jGg߫B0\Zp޼S{u-k~ t]sK;W8G0(w'K[.Uqyf =@mfOכ7s\s! |Z!C| leA~Yö#O $3cxMʼ>#ksn#+C/>cW 1uY-3;mب OxcA{Ѡp 3 &O}QePBꡍŮXg"HS92ev!OA3`CPeTB 8$O(q0"УC{nQheMWO};*: YAsiRMqc9w;4}v\A-zG@p`m}4 ک92prx,C&v}RRL ܚg{/aCH-~1qҊqz#Q':tziWT= l'tFm3 b|xu@F&co^cv+hK1`UA6vOEI @ט=H }尀O)u?#Nz3ڟR~~~'^+1)SG7liכ(n?ÿFM?k~9z?u~'L0a„ EY?5>,X\pTWy-~MC:uzq*[NFmC>_y4!zjy) u#n35|>Y5՘Bw;曀\Eך"{:U`T+ȯX2M]ҿuבVp12эx~K&n8shk@r)p_}(pӟ_3u~;>)vN {hec&>bghqQ&7C.3:퍜q$Om92݇3|vͼ,!yrm]$i>ZA @-ȵYx-!n1z@\gem8z`Cg'~)dAy`lcF=H{ jҜsJ >$oglTmFRB:D=MdzNp t@a7>WY0.TFia mX;nO. _"H?\̱m4e >{[=8;K7v>@de\pٽ !,Pvukg;z˅kklsnK`]-m~9dP?C >N9b[=b xA@O ٬gvfo|-l>lrqfW/9=5I0^:WWngmW٢1|SoCfZ?Lggv1;+mg>]1{^^]_]<6|3ЯD23~[Ʃm<oh[!^V=|9ttDy6ԏ89v RQ r6dC $:"&S, -oS+5C]x"udІtr{HCppR.BN9e;A]d˲="l*e[71u;eAcrK`[_R3+GNmQJqlz~ f۶D#ΘY9.*Qy-OWZyxzSnX >Lb^/ge_Q$ՏcQFQL._+R0A^T9 ѯB)mz9} 8vw֡ü ^Qm$#!" }ٯbg#ɏδz 4;B`G0jx}1Vhz9Da߀msu`,@ʴюVfY[Aē8|32zH&_'+˄<}KRWnc2RBrB3;5wTꡓCs 1sw9$D/}#E]%fnk/ }C"Y'A|Dr}ʒbע.~8{ s{@je}3[ G 3b[Ym5qqn6k;==bek[;K..Ys1m`_4^Ѳk4싛y+w\.*Vk~dt{>dڣ=+ھ!pjf<%}[hzo.nl@;cvy٦Be@E;7x,PZTe50xt/]5%h'd\HzT؛E7 eI+,VʔI}c / S|\i^[+^EӋpAP\w] ȶsL#]q'nhqc! 0hx&;( uIk7˵h:^m`w#aZ,8:۹\ts1P<'ˌU'Asu[tw]Y1ؘ?82YE'F0fG(C!HT)ȧ&r/Zt>c{57t~w~^s"`X yklշ絲Au.6QA87j>y Ul{ܩI'L0a„ _whG Wy!n ^<5r =R.8xVm3DE@, ˙HGɎt|O` V!YڌCj"֬!Hgho_,gL|B!?KhΪCB- ٴHEZ o8G4brNsԶ!d#^">!J}HTOYc Up8#}i yi,I R RY6ENqxW<9̓mJfSlq_+U4t9J6{ރP:ћw e@`2Ov*n[mW^%V>&TJނ* nkU|&o+U͉7>{nox?YoQx?36og~YQZCן7u>c?s}ooii6ggg~þ?` {~R~;}t?9}}>j}C~[~}?O}5OJ>Saݿ썷~s>h.n(}c gg?~`~~{{„ &Lu?ڿw|9x.,4NHʋ:z.\C>4r*v IuN흃'" s+nTtv#?@'+آQb,Bl r"~*~X%xHiBBTGG#wv'O碔_xT~B^u-.Z>i6=ZrD(N/W%:Dr{|OeNk +5%*+ID]EC(}$"HNC*1z5-(=Ua*; Sr(^ (;+8uYə$f^%E,Gx䠼XJUS\y&Y_enp1ұ X="IT. ZR.񓝖`Ꮶ@['x=?~КWJ%fL^^iw8BK!^G^$!v93WЅ.bwzT~IzbI88te豈VKE$ޝy K6Ao3[fyf73ܞNm;f+zi_6ξ|/}cʵ}[_x{Ǿkz3z㕥`a=߻_sx`Z,-rifk[Z4ro1SҮ.m/׶⪍OvkМG.g 3o[߷_s_ ?p>Wۯ|tnキ7V{{>|oyme=и}B۵[޿go_}͝mO mY9!A#R*,Kfl]t#0Pehcuy(].mʍ*eJkVcSmC1! ɤJRJ2_gc;NsνޗODsĎzP&#~&76lVnk6 .>tXz=!;L)Ͽn#?ö1"mBY풺Ꮜ "wj\|Jq"9 sSSBNP@CYFyFqNCNj̞ЏHmM!:Ek$|Gxݧc2/[̡ʧ6FHC5lS9ܒqE1T3o2a0Ծ"?l1b E"`_uv{.|;Jbѝ}O"@om$1PL>4W_[UAic}!|(d?9vk9^ a`,铨|6w ̨k%CMI|}ݨ'^.U砬pް~ZݎnK;HWKh~3,ItcO^OKo3_o~sONүLMkX7f~%9қ>{_{oϾ0} Yz"}ֹi-GJ:x)M}"->x|ӹ'M_OMgcPIMs&Io^./=7~/7W]H|00I/{iߕ^]z(M.|*bJ3si8s č,oFa/6mI. ;EӜאg~YU=s>MVg~#( *ؿtm@|؊yO{ƶxv%`||&#_t7.Nx㫵8G}Nyܗ^ >Ofo\G1bĈ%gFv@GHb!LEG) nlQjgZJ*y jz$G}Lk Sz>_EZ1XYR7? -Z.y"/B *?0#y\a|cCܣi{=C}f@~O=YN|{^ƈjAUp^e},N<&>n|m8Ź Nk.cOQǻw%Q \byϧ%{zC c0y>o:mů08w]eIcfd9e=|ikŗFQ^^zF([zU^Cb˺} 1K$8$Siq4b::1-]>{|t{}/K;OW&Wgg~Ow#]KGl-gb/;g?tzgݗ^Kk_wϽYO\zm)bz^4q5}2yeJ@>*}W GEty_ÉcrO`iO֐۱?k<;<턱)H=ݧ{Եf6aX? o;ךNO"x;~9ӣm0\AFbp}o|"niװm׶4: vA˷ӆo.Ǥ ;3~H\?omƕbR&bk;k$~#N`=~&f?Om]y~ܹt6w\tߝw{o iqŻ㓋\Ե+_K?kgw9o|t<}Y{&￐׽[A_[^zgޞ>wK/WܛKN޻VE[qoW<}/.-IvOsu|=u}.H3>DZ]wR-m's !{z|jZkvC]$bz,aBgkڈ=oBusÊm7GU;?<.$kk]O5Z<ǚmhYW{e]#[ ;5D-" 8DCFq}l t/ &ĊyX-z YeCAzu~8mjrv{'0֖xl[?XO'qi90bĈtJoM?oWx _PyǿxWJoƯJ~P#PX*>V+Az(Vޛxys/Ns\})ѲfӸ>tڞ7"~UƳ#F1!_e;VrN#.[^?^$Pz]m"&ƒ~}ee,ofP,^$Ӟ7tkݖ}w\rhcS^"Zچ /HsyP|xvs砾"CNM8blp/mS߫n%oA?00؝]iwMd;rF)ls/ROwz6DFw+K̛k{(7 Fu5 ݓlj,:8cx76uy-@ykVz"jZd]nFV >4Ukƹ-Uz#V*G|r|Gezc|#ݎ #dRkSf:} _+K9큿)9 d^ݎ=Eezj^Oۛ"3]Bg_鶽E7y:/ܑߕ]+]xOm鎋ws(g3O-ғ]?~Avy2͗vŷ輪~>4|J/F#] t9vg kV9jcq*{;vwJo;Js=/>aC:VaFh0QA, (n/ngȲ,j~{;"qkgSm5]sfs [A9uYJh^ A !h` &#`(/t[u_jɨ#k6[;c[ٗNTEFpTN> Ǝb[n;C#9OW>frnfP_&_3#F|''ɆGӏGo +Fq0Ż_}y[o’#F1b/Ix!s h?W@>7>|^}6 Լ7#Lx=^ˢ #VI9W :Qz ۯvZN}ng:c=ùq;!Qw Ffxs|]ڹ`s+ƅ& |mPy2+2,\1qLz}lHh˷]Հ\6@EqΔc v`~:-)4*.(o-Ѷ?K ^ڇ|Z:vCkSe(QCo9bn#{\u/'tZcyk th鳤R*+9/c]T19[dSqq=5NoAO? HK ȔFƂaWx(<ʐxݞ2ueQ䰇,zY~#Ʌ)se~>n-Zq۹IGߙ_8_-9@JR&9cT\-~tc{~L_BqA_}tC{)O3.Pᓦ=}Dg&Hh-(UFɹ4M Ə.ӻ?>O?]2I/]StA-#>I U gy*ǝU\_8pNEH:E6kSM m۬>삼([z?&cITzc3yӟQK>5̖;g@qm׎IP26 h}/E/ 8F'_/Dy(}3F i,0Oߌ1bĈ/<pIR(K5$^O5}5]A) !խ![Vj&(+ \y> w]˯WQ,YP-?زa:徃ܗݯ2odQ`B1>aG0CFȑ/]@s]܁,.'re~S?DyS_7= \g"|eQz_FA;@xê#hm H|s+ё#N{#fޏBQaڃs{kvX|%Fx܈hD̵{_}3J>cqP嶆ۚ&07bKXkbz˷QkmD`Kxv~m{S'PK16[[3Oz;r+fԳekLДXȢbm񢬲Oq/rx:G.zkE2-ƕ7(7!h *nᙎ@'`ξB߁d _M 6U4(E9yn rKdE&.؛;~ĩ$!d*\:9SɅy/쭴(7C 4{pA;٠ͅ^ax\(!:gAn[%{iop&0;W0)':Jj.]:HWR|V p,R_C8.B-0? *9_Gx c6Ώ"ŏ~QZAhCbwe[l-̰H)ZA*ԈIM-h9 l'͢~8n?:1ljE-K|e\-Yܴ^/ sع0ڔ:w,e=wӃ\W~PCb2]lӻ3 װCڮȴv%*1.1SO1bĈ#F\@ 8imf݈޺6y/QG_z}^[)P|B[p̋ԭ*WsG[njݷ+?ʢ\mZ+M>8 #׳WhV?Z2S3-~\:8c/[M@;2!.u+[⓳ o]1R:}O#<B*f_ юzuXE~rʯxoNcz1," 1})O5j~E_GqŴλrw5P,iד{LME 9y@/9A7ۧ{U#P8)a#ԣ/nMB}xʠsr.p]. 8cOG B]9U,SWu!!0ޔ?A!{|ڛ*B<"r^=Jr>ү>#_g"MՍYZŌ7tt-ki:?J˹?qq\hMF*9Y&0Y CwDZnddSFS =P%w9j&:ϞדY,Azӄd3ztDs?#/ qvG=nYCkmQ̍OuA_CҷǙ4ўSWQ:u)ȱTϥܫ]{)@7c7(i@K~9E6}8>1'r ЍOSsڪ qLjp1bĈ#F8Mhg>\*cx:oumj;3_vF=ĸUL觉byUs!K/ /GE^z ;>*jfPqX:%X+*hmn<6u~T%u| '㻯hI>-〴#a(2B%| |_^ܟe7]^q1/c-@H=C)B6$S n/8'7lLs9E~PƧl0 r/\/\jl(GEgK.V eptaZBkx"У=pr{<.CO749ėgdڴDWn8ы63%k/pɾIj2xӤB̻/5!=2-Q;`&/ԉmz; IDH92E̎DB 亮ñ3 ^?.ae]} rيmW=F!^"U' #>5|;5bĈ#F1b᳿/W|פwp躿kcDl_)kr GEo 5/8/[UC,!gg菔r}0ʺo5Z<v2>cmۃ9a~NV Sjȉ,W&_^lmJ%m9u!3!f6ߴK*Bcd 8 0T-RA>s-G+%@ c }Ŏx}^k#xuZ+`xk2 (w3}0a|[̿*dh4v+{wve\yѶ>dhsPxWKFN5bYP{Z^˶xU2}WϠQAY#Fto0R]vݴ<ڨ$k;lP[ ?ެ}xE~(BLWq >uJ;y,{9(B:k\R"rUlC/w/`}H{.؜/fzEsxkoV|EIzɋe+ߝݑVwܞ;xZJ3"P,ݔ%犔Ԗn)br- 6Z0SCZÁ8kx7k5yA_Iyt[<1// =Poo~5qG-'>{0:'yf[>h;pT8ۢCJV_iq16`og(ndGCkOQmY!6 oYCܬh ū|AGyUXmbm$rZkYdۨKmuͦ>d<&[$X l] $3oc SLyЅ}=e6."L!.\5$\Y>b@Y 6<0z qacpm0ĩQ~)O_Is^zWW;߿rz+,<i#*/c Z `܎fi5{bQ^6XpEmxdy(3GV$>ΒqjHPϝM3Y}z~ ~훑6{k &P>Q d2/-xsırDtv4}r9VpQ}Aɷ?>ǥݱiRP7#چ1##՛ۍ6N7݌z}d!:#(!: u;;yYe84bĈ#F1bĈ#F4W8еnV7ef{:eMxF~cxD+*em{Ly-[o֤Q݄2ߐ뇀bQSfnStΛ73P:,Ɣ|Hm\g-ꮣG:;:C؛oalA16Z$XE-d4Xzxq9WEH5Z1" b,9X({Tri}Os6q1XTcPF^GWG Q~-}gQ:b`)6(vr Fv:6 )jiu`Ȏ%Y;Y89ԦlV<|f?Ե;@\ . .ڸ}o?{|6Ѕi !S1vʧ_Ur=-OpҢ q'Jm\;@Iڇ5N+8ZeX&Cy^XsfLE%J Q,rCv6PgfуUzp/][JX󟮧w>v%ҥEze'}(tJܖARnϦg޵K)]xJO??WJڳ|dGJGizJ{3}B[~!%J|慲)?:l0Ƙ( ,&&My>!4._-v{H~H!F BX|٘NϾl6nSt|?O:O <4=~=)^.s?@<!˚v@s[ M.""%`_ [>,K} Iw*偞K9f*>amĈ#F1bĈ#F85:ӮmIk@oPuJݫq?N5R r[FeB-K6(;8 O1X}E@yx?i# TW~[/e9Q|p9MT-?KJd#JֶZ>V͂NFڜ2R5;8!_ȣN>~_fbt$R"[d:ոyLY#(vƨՍoEvu?cǚ-QLjcN&`t^t~mon\E\Iha'} >Ⴞz^>Sw/47ž.t pJZrVt("I[Y@}s8!rF$lI.}ÔJ~u~EzUWVP'<7{?X+˕ez'ş㡶[v<j=k@\M[ Jֆ;F[^gөtyz{Sedu6^Y>Ks ῼAnS\W1fW)pW=[}]߃ zq&uml*>>Z-ܰs =Q,k4:8)yƏeU+]ƶ_+TF #F1bĈ BߜB%KսM{!|oE]YTeKB\?GDPLs}$MMPsQ,}<1dɁ,38^.{ϵ]YڌcR۶-"dD h[ r{* P-Ex2Kus목-y 'oMV{v+?=d}ЭSXnNAWf**I|P{|h]dB9+ 1Q~hbG=}'Ԥ=gي kKzZ96;YOg]#-~; S|PϪ\tlFPT nrxʕ̇!&p>d{Ϭ{~jӜ^U Mk>} Ɛd,f?6풓3`U|Oyb ?&e?(Rs@Eu/Q199SDβ7ּ+\%T"lݦawyA_Yz~铣}B˲lf̯,ٟ ZAy|B$FZ}C>Yړ8U+\q1AyɎǖu7)α@:Dy%<"}pMSh_:8JO]gk@O_Lhsik)}RJ< :rBDޅ3&]iM5Ƌ%Ж99<raDB &9i{D[& YM. -!58[ >&ɅOl.~s\e N z%舀 ɊS^Lbf繏ʯ%j*\n+3:wj9zʜtd& ]'6a(.[|n)G >\jJثtږfL lӋp]-Ve1t%0Rw@Pє=B0;"TC~Bj§l۬b1I>ƪ ׆1*l[υ(}SR}ےsC*5D}\Uu;.j$_f9p)qLj#F1bĈp_V{i2O+Єu[Mop!C{,5.Hu.?cݮh a#xA6yvd6^kw>mڑԏkw| NE*$MV֣z )5=-b3/aE|k=na 9BMWsàSC T7J2-3rY\QlAN$_|ܔ*Tu/} \R.Y'.(2C>ngx DXB[`)7oq|?/(h0rq-cگA?&"+H%z‹z}.&6<< :.T> .ٲ8B:nk#?DiO]o;Q#_ ާoOB`zPnϒ1CnEQphJ/4a<e^LB>-SY"Cc^] >p3{w`'bS61bj ^:c9AΡ{-@-|Z!>x?La@_ϯ)Y..|uڒZ:lȇ"Gu 198KTqͱ~5|tpEzb>MW2]ٴ h#wBv[ڿx^O2=s%-K)ݸFcPȿ ]N VA L(NP,^U*g1r}God}];9\X2',L{v+(!o ~Qɍǎ%ݿioz6z>]xatK'evM]k9ޗ5dcioC]mII; 9}J4-~w<g\-Fިd(Ror_OtZ؜vǠD`NĖs2Qq+Ĉn"˕~Q|4o=9v ʰ >(Wט1|1ɭNxR6cI/RKWrv#4*g(AFVK>EoD}s繮 C&XN=^|"dݪ*hr%čqBd2P8Pv-hc//d΂O @KX1 ;bg\.?r|A3ȎИU 3I҂rI:ZNa3M7!t&*]L-ǯ)=z*U f:J?S>HO]tҕv,MInQZ^?LkGZ1!䬤Yz$vCȘΤsty.ȅ<ۄO-9k:lމ2;fLWjd^"(OZGw>W΁xc!I΄QW<|څNV4!>|O'plBlD`-!G_[rkϓ1h5^ mwIIqlrq!?M)9RSΫQgvBycٶmo" աPĘ#O^mv?s wt?UQNݼ$×7'pmOrK>|_ߧ/a/xF1bĈw|OYwpzt>#=W+qW쥉^|C/ܜS|M'~Pup҇î nBZ*FUV!/AYP~Z_fK(z<֋ae?FEwDnt6|Xϋħ>/KA叫NZ1?G*սp{C׷y( 'I>mS#ґmndԏ=ks1CJ>Ku:>itJ+?౟֩WڀUi̋ /{~pXzݱᄐY U /gKF~mA㡊}/lƳG[G:s݂ok,ޗ 2Z-z6ȁ菟=ؿ/iXKRݎ(sc;zٚ@Vŏj!j>evO24[qk%]APfUpԎm`MSy1/҉ X锯OYMt|+/<=ǹ޹=$/2U, 22Daf<Os_yyޱΘ)!t;ҖSuL Ioh@~-]th}}L~iqFJ .^@L.O $-)]_rx \"VDGQI_L`t@^'8EXw&y$YކeHclv>k `'52kŸOIu6hQ<gƸc\Ǜyx(\-ȖϷ1a<\<=1%ΦTژϖܢ};O!C d} 9}mExmz>cДҘ#ke׷wdqctMۘ2E:f]|3O2q׹㇃6-G(>B=˃_G+PS79 xpM 8xypɲK5bĈ#FxkO>gϾ}@7&|<6_o]|^A] TZbAjj|jGZorF; |}V#'OYf;[bcg޽%e޽ 7ݨ%f.t}Lgn`OpEeo+ݲ [K9Hr·2#}o#"PKmnys]i7`h܁s7[ sYʿ7D=κ(H6Dg>b|/~Zتz6z۟dKAOV-'^QY51 uԉ>zu}V='/KǪTR%G6>j'z㗷:$BE vbY|y'ǔ=yɲbׂݖ<>ogDg`-{YD~CnV!•䧯qI V^ I]We@|8T\_aq$lpᛍYp.qQ .o'3B-`m>} ihOQئ-QCz_b]aDls Z)G5A$=uLO%RףVivZ"AZAO1PmL;.MQ2 v)]GkW05F Lu]hQW"+$_Rd+9u_']tr7,5)Ɗs%IgXɰ@fM7STĬ`'{yע|nxyۈdz {[S( NW 0< #n k96rIPD;9np m{ <*Ww1bĈBY1bĈ#F1l;>~wYk3xex+׾ZǗ,8\G]Wo֦DB~hX&{\|nu(_XXN^eY`ބ޵]SmF Ǹ6.xl"n1=l;TlnNMloݎ5q ԈcJgl8V[7-'@' ktg4CT#"E{wem>z^rx1-fᅔtAZ^V/7L>MQګN*\AJ籇  A*v$Utx3fe\_xrk`ﬦǦ{ưiqst6 4XISr,:NhP!>ʹR pl~ws0qBT 8Z@"peO4`>A#=1jnYM2@>6N؂/'-@-D|8f$>GX:x!(1' W(g_,ws`#FqkSF1bĈ#Fp\ek Cyp^ #bEϗY>LX}U' uq@l;"=u<"e7ByҟpfH"u <޼ɩk ?"؉rDK$t!C ܛ{SR=n*`)}I|!Ǔ0Ɖ̏$cJp6}SX[LER8R/gNl1GP7hqcE~y?'N!2^+F~k>kWm9ybs5aܡwΪ<c*<,ouJ%z\W(K.wp2|!_FNy 2e6_sAŧuiuS!>*cd?ʓR%0f"ONOG@:JÔ>уUzp{u{}~akCW{\.Eڻ|&R:brO|. c6eSN _Ȕ:~'=y>IZV bt8@Lt[3@4 ?vɾO͟AY-c-QhPN}>ux=Im# GQ?eϓ` Ѣ\"(9A~R?s ߾e[JZ(ggѰ&AI|&o&#͢򵭟>[ǃrzQwNb[E+}C [JQm?@CsF%o巍W>c|l;Az;1S7{ oڈ#F1b|sX%]kW.< ;͑9 <*2 /8p<ތ7$uڼFʝ_koe1mA{@EW"ٲOGX? f_$z$YI`3sO(~lDr߱\#HZh鶑G4ߠc:q]nk0l Tvc%C0Gen_o>D|y>;!?uy!k[kܧh&.44m Qkj<+~Ɇńuc#*,>߈纾 #!P{Sx׹v< QHʈ"#Ea!*C&Q\ Cml>1Oʃ"];tt {iWMSjo/͠'h|嫕TW9qSkh_2gr/=$q|(m~كY.Nҍý?@i5# 9"zz{灬[3׳?Et}ԣo.ai.WT<>@"^.&\eK7bݏVnm=bT-Q!9TMYBP=$}(m|d|)<&NGD3:v@<o6Kvb0/UD辽ry:0[tqvseY'km=.oy|R^%TS;Ƽ"'bOcjqV;`ht #F1bĈ#F|ÝJ җ\:y*|⇬`:.Qq%ʋU\Cb!^:ъuY[6H%['$x|CHKI?I||'uUCVKA^!v纃 b9ܲi,oGB>lR%1-#?+c#*y$~ݰ$R )lx g,NՂ^˳F%\|cuT+rZi uuLWكt(ݘ!^o~O $A(Y#НsAd\S|\,}!S7pUWV{~zj1S7Uzh> ezEOo\=L]9LW4D5,nt5>g2C%A%\0qc)'6z\O+Je.M,.]9'ac<>ux6uz2=p" s?: ~|ߵ'U e9\TOoJ!>q?\D!aIVN;Wz(0?'˜\XgkJy֙^CX䚁ZC4b3 t+ҩy?aJ/x%K8BBϥ[X'2P OYmxk| צ^@Qסh_^D4ir\O$6}8^8G- 5w_VџYmc ŵQ/}`M9Zfo:>$/suZ' ɶq?+;ߝnSkI98ċ!^ӕ}oc[#RT y_Y;k( }hZV~q.E/{3xvn\?.s{Z`qX? nsg"p$!п:N`qlPrAśhs cWa}8t./'xO#ڟEEgyzO&>i~VZI\ՃwFڿ~=ݸ&GWjv99n\A MzCW ;Թ` 0T+H_>saqaF̓\(y>E:o#-iwP}`7C`>Y%kHl)gM+}ۿ w99 .Y qDgsȇ ݕ8dwVC:bĈ#F1bĈ#N\7wH?˸àuiC۳=/ ^ o%Sh$>P;lCNMl79Ŀ:s4 p=ݻ¯Ug5آ^.v`F&.hܷ^DH=z!d#~EYnj*vȺwr@Y tD* Ss,cD]jΩ'|rT?PF-iE^FAĐ|>=x"l߈׌Cڇ7`:@o5i1zrm kh馰-Psq;Hzyd>|n)Ʃ)#o`Y"mԸ]G;};G<kTې܄%?E77 ty>+eWs>MGh5cgЙu2vC7_K{7_:ͮD4; 8lQƊ6pEs]<3/CysW!s|u9]ϧ؊*}·$T%y@ozXtmY^:@ge5ߟu@~Kf9s">~}e׺hWC}v10w>&"B<&/W 5;ې۟9isYp6M `S^%,DEq.e<@10/Wr{hKYp[hh">cyv ±†Xg)|J3>`΍kйzv%^?ױ/'}A̗0I 5D|F'q\[/ʫй  )=>1KIz }6n,Ačyz sOGsi*F Giu(MAi:COPr|&8S ZAZL\ϔCA8OۆӉ/7v ϙChh{@<_vIE6Sȓ> X\͹fkU 6`HmV2(1}Wp#9$Nů}3L1Rf}q $С; hE6>  o |([{~m/Bm# XP6ٶC0_(cnŽPeۊƸveͮkbgPӃEsġyV9ta 2yɫןO-<huwk-) ܶf[wN7v1S??[wW|%/yٗ?규WgWҿH?Ŀ3C%J oxCz{c#F1b_}Oo)kyKo{yN/ƹ9|y>~c9s/J|R=A4K/y6:ʺ%ڼl|]+x=^SuongrXRp?(uJ? ЫTsd~wJEy#I{!qn#??$d~^`g3MbS(;T%dCM㺲2weRoϠM{j.?"u.wY6u<0]UQw[!bg;ڐ~2z }S)8z1 &VzNrSº~N  wQrs\CЋvBc|ONM۫?ϩo}Pr鸏 kXim+AOLgn ߖf~k[;`Kcj ˞ Ot3eߌ ŔZ<\7O''_ *ǟ"eAÅRыOՅj lG^vJicg%Q*[iIJ:EBE.$`9]hE>~YXY.>=/`}acR\9ŽIڗ,pa8.| hBp4_^rurA]̇!9]1$t(B2&Y'lp!0ep1A>cx= hw.#h(͸HD\foOxL8䃊>HfK!2 # gDrcɪNױTnFNKD]_Ru%v[Aj(Vg+#0x*c@ɛ[A2k@1Wyc|8:j9[ i4z U `1tٜ+/-!.P&Gp2ʜ - 'owNCX)Gh8:Dl-N m3Ğ;'pt9q.&Y$q qJW|,},},}p>xϮZO7VB\-:| I"M/E˴{7fizsʣ-gGi>?LsW@8!r|.ꝋj|yjGz r>Y#?]MZhg&uIƤm!8GHۥ <,Ⳍm1S%[X5@yQظ=/Qe?RW vL;3R;rc7:zzq7'C=Nlm{yOt=_|zMT> 6' 'mS,3'pnW`1&Sn+{o= /3G#'JϝG S952{%"|S)+u@u'/a>B!@so`󊿘+e]Wt]sO|Kp ]_U7uݱ?x$X?e|DoQ;FNmeO|nІ:wy42lbc&) 9k1ttvEd7뺥U'Ǻt`U[ϙoyz868ʏv[1aݤE8qc̺&bF}>t [1HYA}*C} W=W3(jRȋ|;r{yl9&"94ط\^@<{呒 ǘܕ`ttt.8/%sLk/ 5`zՙ,|\1[hmPB \rtџ\-F͘:n_m Qv,^u;c%)ǰRRƺ#\j=3\cߏ \\ R%b]M~D>v%/#k;C\|x`:A-1/8ej7[u{2Pbdӂ{G1EJ? @|ǚd 6c@kC:>^l@y#~+Xb ڪ<c35ꝷشư )MvSW}0xu%#wnHUW-(x[}sbg"ؔ5cٶuBНdsn~7Ėxw'gč\ 8Fí\qaB;_;kLO}gs|d_?u.[_?Yk\1bĈ#F|,p|+~ozkZgx~ZqK'.z6zF J]j,6RGX걠_  \+Q,u>Mu7s[p=( 6hKl#F(v; (1 E^bWY+y3wӀ.ЦWuvۺl mB dD9`Y˵Х {Hֈ)|؎"}9/\67>NYB}V'v+p YǮ>^Xk#nzwА| cw|x||% wcEFȴi@{NZ+.-#\7'5~xVqpu9P D:| Q>.#q(<i~DЗs.ν(jTPt61Y1 2,EZf!ءs km^ea D!DذSDֈc݉u{hE&3c0D9U6}<]8.frpnC"zS3[0$s"*1|Z}-b#Fīz0?Y[A|G>fo7k?bĈ#FA&|nc0֙C7xO+-^Ma*KtT.e7J^ΗA:#_2Q* )Ôfnn H?8 a^>b܊]LuEռw?ie D+*r9+i QSm p4-1yw9^9ZK7(WiK t ~nthtU,3r| NfFpxJgPb yAAy΅ u@S&Vx.^D⹩Iȁhr#S6Ԓ ?{lxnzAs"EM%Cov!ld)cṔUh Z'rx|P?1=0:;|y83NhGH?q@_<0'kڜ#l@zlcmE/ |Fߢ0 trK(wWrO ;qH?|Id;ύx\!nyWp]1bĈ_K~ߥ_Nߝ?Kχ^aS%/1bĈ#Fxtuv` :sG޼ -@M];.e|nqEuh&Hj}_oOeM`k('P*<.0= ڻQzXt<*ޟ(:d'Y[u=GG#9enF@Q֣3 2Ĩm"/8lBѵLQBidn)k^+hz_☓r_)t:my?)nƶpS e);1zp"O5+(Nj1_I.1 9$034Hz>|Iuڇ41S7gFGi'l (՞ϐ a"@|^RxLcc欻$ ,3`Ѥ܆D۲IwsȫUS:)~! D4Ǽr tUo`;XFψx@N̷;FSDx="tߎcSI /Ҙ숀SSn@k9/sT`zg yH7vA_:r'ok(tvT, +kF1~CA_+'?>rCWM?I=9S .|o#F1bħxspkb:oB,õ}שѸ6!JP}u:M&j=#@ 5# hU<>],#5Pڱ6#I%Hه!b3ExV/psh;n^O~Ǧvǁ谴'{q!4&I|ЊӀ@c_>2ob~o 6Vr<7}6O*K򦓴1s,Hy5?H󸦂5[:L]wihrLNG:`dOHVr1!iOPϤE#Cɧp|=O _[I "?zTO_j+u ،܅GT<ϡ˱4CS7Qb1BaHmu;>[tR(z_mp]t qc-%sҟ '߶q=b<yKF-^9bNǂŕM oN:N JRfM#F|ė}ڛG2o8ZTJ#F1bĈ]?Zgb3E4xjװZmlA=%~WEޤOId}jll#W+c<#T Ei[qcĶ ^Y5Cb|:?Mouz|'۶d5Ia|4n z;eǯĦķq(bcaS.ȓ\Q '6f_Xǎ_&D};stU~;4cqV!߳-m*م?=W$r8. =:^Za dTrt56@sv~8TY EZΖyC6.@?$'nn4< ^2AIEt>Ohn 8Xj/аz XwB[T#֫ů.vU o@mH,eD;Z<,QR5>)wx~=> k?z;m,R1yL&/>N }tȷQS ~K}o9 j?kU|p#U*:9y9@vG.6tͯ==3YeĈg'|j>/a \ s?v=rvApI6U[Ot)xl#Qvq-{xo4p1|cH:#׍SƧcĖv g >}ɇ :~pD f~dFD{/ˣMp~ YziI e+Wl}-C>eSygfCLh#DOG?m`Um6YU gwSOa 5cz-),eZ$uFZܡ긾;%y|b,Wu(\CcM\47_2}N$"`:zl3FN3}?ȋJ۳ʢ܎WtzmTq_8 ݺuFpe[U?rBڃel[=2ycGk7b%~xo*!q̭xCtInDĺQ@eCmjnStu{W_bah_sP& 6ncB%+6Y@9UMs'h#Y%;bĈ_|Iɭ7>/Lwߑaܔy׭n{F1bĈ#>y^j["fA}LnkߨqW/1ޣYJ ?U{Xg%~_|϶xM?\/,:lzQ!5~rTU݇wlv/[6n "_jq"鞩w@fSjl;3x_c?$52}8$l36\o;68C:☈8~o_6~x9D3ö9#,}-Zl Ff43cC4mXU,^eMeW侲d?W }t$7h{C@'lgΊJԂyZΎ R0kRf2ŧmb$Y+UGNQOx"k`HVGwtC!C>ǚ'yG*a식UՄqƬ')T16ԡƉLC=bvv`|<@qKӊ8{yLi 99bvU%_1bĈ3z0/+צ).B~Sۿ~oH~nz^:3^0H#F1bĈ[kzcĿ*8֝b^z} 2~C(]/Q_)(~ "5ޠ7rP&2{BQ-ү-n%4O QsPlWe\"/q; ȵv\:"pPy<[Ɯ~b_ѦFl:vWJ#!>ibO.Ap?ca`(\H7k>_>[A]'czc(6+Ǧ C1>H@{7ZZ]dsj^L5az>>Gڮ6_v`}%0P=~gO+x[ECj4\ WCTͪq|FeE'thzy_|y@#-`Qo%|po A}S/ԙSu*zet(W$0sI/{v3(ip:ͅZ;I_2MVGb 1dv^B@=@*XNbyPO>~IZ:x~N< ~.,)~a1,0XgDֆX`eRD 03?X7*` D@:5, ~\^2/_akf*5Dm뢬^DMzql7> 1N֜۱eLP赝"Q& H1PZp50#B#F|jޅG>]V~mݯtj_RIp'q|4NJ]ڧ.ק1bĈ#^kr K=#NvfȻW`~o z]ӷvS =jH'KԉDN=5,y8hցy# b<0/M?ʽ΋t+Gt?8C:| ƨym Oqx3tr*>) 齞u!_;/ٺ1oGS۠ѣ/SmP߹>d~Etzιǡ y֤BCE>Hk PN'M4胥fFsk'k3,Г6č/b C (2*>e?3ec&bSThHM qQjB;C9(XB G6DjEv!*N{]4+0VY}жy*6g :>v>.UX;~<7z}|_iw3cD޻mw'8Pm](щpY䓷6uwJƚOp]F?k16'jw/ 5ͻraNaGu>yg>qg7w~}~-=vQG1bĈ#>q =ELעO0xo' ~pO._CL*7ޥLkKf*jП[Ϳ,`K<^9gM&1^c-Ў|[Fg>M]u#hF/9i5+%4r0llہIhGU~/ky2#lcݿaY+pl[c ]Pu&j>ۑG=~}X~)p}݆cb>kЯr(x:7ʌ|P3~ݓNHKc(D@(7{ qPnjK>!B}3;xB~q{SI2ڟtPrH&ߚ| ~cK/cs/- sw‡2/ebc/n q񂓞cY<޽Q):!ӍD>1_y9\!b4Xړ5& -w5u>A#CO0"nX6DKz hv  v| Ρק:K~oΝg|K~k1G\ᥓN;9!Ғ)WvB[#>|&s%$F3q(;2 >\q bry\CZϥ|1xԴ<#yW3~\#?`,r㰁vh\tOOʸu{#N Bm8 #6}c~9x<1q1bYwU/Mu^yݿ{7ޔtz;^}kQG1bĈ#7>n[ZD.kUƬCx%|b5Z7HPũhaMst_QFCv߂^,Z\iӿ nnm+ِ_EE)yC+;` ݸGM9/>`mXd?}DEs qsa8MewJ}s1m:q8.TK 9:fnq63@V6O5ZB~/eʿ/PTJAHTh zU궠&al&F1AŅzfKȍJ-@ɅaAa?ЂDpF@čEXxxAC|*#x,WZHAUңp ||ȳ8.=Qts\ʶ:-}[!] P}HcTkfUY`9wJr!hKq~&>D'Ǹ&Po`8s!=/H{ Yn4t#FtK]*#9w]Jo|Ce_g>q#!k=?~k;ҟ_1NS>bĈ#F >xVu8MJ4J ֯F.̦Q_>Qmo)h:lQ,d#@"ZJl@bm[r֮dI~(19~P.1jkS|r!Y{lz:>P7X_$ہz}bľѾEB1B9iBZCOyK焈1c cMBT8q, C=t^.Ƭ`n8doL@^>hw}'T , (oB4S̱AZ/Рg᯷xC%[2A)kUCp.V|lkOP 7[s/ưףd>a 8@[1luPХNROOuM<yGJWu϶U2Od@̃MCR1vE̫g2I MhZ0xc~Z9l`?̽l6QcM&"0WX&0bs6nDTA1ht6ك{I:S벭~FϷ CNE0 C/9Gql㸏1yj}kӇ>BlGj)}GɃ'T~MU'^{Õ{~!xtR*_ד{@l<:15) '[WYD>١],3\oTp `y^Gi>iGw6E)9;98q\M^v~;_giTx j:+v8 Neq" ~N |6d>b?w|S}ufs9}W>k&He=M^?q|݈#vw}wOIoQ=cئiw+K.3MYû?*_z_m5"/zOŧޛzGf-ԨA[_ϫNI#F1bĈ]'&oّxIvף~Z~Y{hvgRSL%r!u~APs %|wg2+7볜tipf*%.c='q[lXeiI j̜ۘOVqзWV+V u4:U$+WQi?>?kYT}a߶k6[q'!vЉqkGu{iю(y5SIbc/#Iwlw룠lͮ;j %^CMUژg%؇{{w9ytDꒇp  ].3B].3ʋ=`X&0 8,c/!HOY]:*O|Bl"mO ʏ8Wenۣ2ɹ"/%a)}E5O)~ @n ϭAYwPW^lӏO>z賾 T=:1n|,(bkKdH:YA@ʙ$9bbi_Lk*1kRIO_֓)ϝdG#Fx0򖷤7 ZK?s?~~42&rQvr7>fsg>j.O=w?6'skp繻~_~Boy&߻:G1bĈ#\O";k0c9E+u3^D^׵u'ʌWS$Uee$Cnޖ|@粨\ӳT1`4w6FEAL ˘9L^8*)!7a^$8u7:)nmI]dҽUJ-079l,\yH?XnwAk c<Ч@>.(5Oczk3%L:eJ^3x+ĶrmKg!ϣEȫO[} ˳i;<:(֡} :Rs|p!~BE>NUuFnC^|wŚ]m(j".}C"Sb[$ --hVGB-,€.5\_'l񞜞H1``f+謖]$ͰIulE g23>?5nh/ -GĢO Z.R7o\zFm$Dlk3Vz4۾'N M<՜G?wn I-3 Fj`M&o Љ'1"Qc(/ᅮ󦁊 `_EQM\nۑ( V"rO殓)aW!t1Dm WxYv4L,P:?F+:(W8}O9USy>5)oB >?P_?qs?켈wFM/r`kIfs\u5Roԧ݈#F1b&,W#_uv` :kP{Vp[tT5jUwzmSZٿxIܑ O@e<]D)G}ֲl@6fY_2?ۚM";-Q]ZT*ǵ{! x7*^NYN:R}a5k;]n٬.|C?Fd;vPZ >UpqiFUs mP~%JE\!>K L.02 . .q 8-ʹbE'Sّeh|_ 8(IZ…⍴j.@]H| e(|%ئYwH1Q+D>ծwrU&=}<{s<3uHR5>e"@ݔҷHv,},˜8/1v!}Z7qZGNC1ڔ4`vV!1dē*$ۄDgMѿczk6N]`FZ<17#]wyrt6u| cEcK9.s0s}UgoC}1;X8yFؗx}ǮƆh.pA?w_ K9۰WHLUlwg<&V/ezUWܞy*VxQ{I<{/_w_XJߓO)cޜM݅CERSoLy.šq[/\T"~ 晵1v!Zo+DTQA#wxXg>1p_=_W./>qNX0y?"(7:xΞc봑Ue2ul[q dZلq܄V#(W˜'+c8׉m;9ԩnۺ7IVت-P/z5vje bZ#4k㰻} J7Gm}{A{Izԏ|GB{V& GC7_m^q F=;|: _+ u{Mn=(to/M@j‡i u7Ssrqz _dFFcZ6 >/22"(8~:n;mO?+>5薃!-rLn&$AG 4A|*<`^FcwlTzwQXۮ![)-Ta}jzG\eh7~LCǣɠ>FPrWS5韀Ե8Cĉ~(GCa[ʒp,CkN 'QW*%/Z|~PN@ȦK+U 4|u$ц~#!nX[%SlY 8m;hbI-@[sۦT\f܀%#j?C6E[`Ow:t~F&/ U/<U+|CӖz:"rJ7`+T"> |[*.rQa~:^8+TNW_W\K_L_/z߼~[_2bĈ#FpVPqy.4_'Zt+Tp{PzrˣF`ۛ=|%d*<. #^+Tp |;P?;b?C]|m/thb^'|xwS,nU+̋x׼E2C ?2pcO4E;BsCu~ kCH^9-=O%zWz3[Q{g@w4.̶% 66m źX\@qW׸ϒ<Ӊ>qc-yFsg(^P-pg$]O<9C^c?#]eY"Ϫ_fDߎKGUA˨PbuQxrsx_pQw̟XdۮgmBU|66Wg՛ smMgz7 z[]qC+؁s+ngu,5#9N(>Ͷ{u_C:R>Ay"\v_Vy0&s[ "x5? eo'o~^sKDj5EQG] lmmA?樆 ccpr~u˺5Z<qS5X p[fo횷 [cu|I8E0 _r$8򎹅#,ry!j;N(NЍTONp?Āiohvz!q\9w$W'؏-;cJ~;cI/Z{u y)wW7}K<Byc)=E鋳0{H(~ҳ{fp7=h@=`zK)׿.'!`/Y%w U?ޏv6E1SG;IeG: 62˩hnj|DZjmC~^ESN8~H k!krnÚtøM{D^Z}"jH bAQM1NJOv͍)$]mB/ 2G- eô<:HA)ciumn $.NUHQC#B?|_YbQl[@oo-N_>l\A^.'\;n ļNuh H(cɹr툡ǀS)Gݾ`!ҶF[([=D!fV&nm>Zr3s$S( dHMlu'WPzn!lErUqx0k{PĆqۜ3>5=0e =ޘC]3՟:xrm񆃋8G#F1bĈrB3şS"ؿNeԡ.mN)'2kҽHbNh]`u?N пȧu_jaFƶO<Gl #A>Oxna CDOx(qZCsW?[:[dAGyHc\J-}GMWI@*90e &`[' 2oCܳ5_Pcn}uXe&L4sPbV5?kW ^}F{8ƆM=<9ܾOrыzE< 'vd K'oDl}r㭡嚼B1&-Ygnf=}|o(K춾PB!ZK+}q|ɟumYRe/fAlFF43识'9ygj\\hfu>g^ѵ qܴu_TE#傇tlthkFN)iJ='X/d̡m'ЙOBhk?}O8¼`=/eE) &2C5<@@ӎ<'Ga02G'Ð!LN0jpS89VC9}vq$χRq@n9}טz4}𤇵P=x^><Վ >G'uؓ-֞luգk7ʩ7bĈ#Fq.iWQVc HO7w]oS8]x#ǟmbUc|uh?% s=slT}gln}| + K3傶m}pP? a :5Ѕ$=^D;|lN儏6=>5t |q9h>@Z`qv=1YX۟-|j@H̩ @x"6XԺmdy.=$~99_s>?}L|bFyZttvc9||C0kURG 0C|e=y[>ES4@\Q!YslW mnpZLC'wą7E.qQ-2IQZ)a=1] 2䃋;/-`q 9R:'{#~9xTm8qk#Av+ISV]ĄȄSU# k8i#@7 ixcxKN*Diݢ7C-{|hGXz5q'㛾w~w'ndў~F>d_Kk߭'mcJw=1bĈ#FxLq XKHhd7|m|lXTՖ@ A_̦ ϑ(A7`~+޶za_QuK /cDآrkPX>8X(Zc٧FvJo,8bI}t4y6ñW`l hcy|-e_`E\&K /6(kr俪;KD>)b%XztÜaP#ྐDYGPhAQ|*Dr. Ϗد!,`yϪ CW iYFbϊ>8VN]"(W>5o4Ϥ eI^> ^ __d/}eYYE0cιp \ @\WpNJL+8 97|46p|A2>d㶄Eeqv Mn[=-GrEĈm$" 0䣙N Ap@ i qÝJZjH5T;EP쏌s̱\k~9筺=s̹s? Am$(Zw-dmT¾#I h|d/6; OX٪~8 D`aݖ\&"^c--dI3BRh~ou)t2ƴ^Oi.bߕą ĵ+>S| [7#l^ͣW J_XkNCrV؟Mzo˯|_~߲5Wk<ȷceS  AxhI"b"'Zï >>ݓ5J;d/#| [-/Hض/5&ڶ0MQ~)/g5-Q7m|taʷhR<0V rQU2Y2rY㴇?~)f=Hh ԋb֛`7r {pB)c^>sb~P@1cRΰ:r)-v䤖׿.=\M@ h@4N6e8{Ϸa3|]]mJ;n} *7qeP g% .C\UC+3}JoH axa6c TKkѲ9jt{旗ٗ??p'xƟs?O7FP~_e ۿћE~3X /'x'x◊_?_w7_ћf?5Uk|:Mُ6UQWe,8\Oym"VބX Flf 1t[L_Nw5fz1&7a71R} Mvhw1s%uߴe?*t*5d(ډ@T$)5.K|04GQ A#ʩ訫qP2̎7.P3ɃF:lf&oNvU 88kOXXƼQGvP`/Gdm) d^3rڌuC۾m2.{qs P5 EHgu/bݾ0cRy83 P6\eV:vCՕlo7_*`w?!9GmǖxPuZăq~frMhХmd >%ahϔ);j=Ҭ{`ӆs{ư9CMo(eP[zxQ/O(>֫ןϦG7}}.ma79֫o/mЌ4"K3m6 Lh甃Z:0t*^8 kW:թ@P[Q* Vh+:rymG<$u]0ǡH.(<~{McR+( 鮐 mYhu<1 ڪ&U^n (Jb!O sbGw v\bʷBfsh.帏?5Xx+{*?4/<Ym<0|;O<O<O<oGk\hjl.|謠*V%|~  sp j0{\m(Ƀ)6nLiuކ̟(lcR!@9>C@Ƅ?!'qSk' aӆl?iA'oU @)c҅,bXĶ qT|96VNPϱ"v8~.] s V'@tqU"c=)@?Eź|3> >ٙ( cU-ww͹%Fb @b^GtFO pBcv}ZVPWb_O߾|?~yG+vLl>@"yꔶ/̗ IԮ4 o.aG/XUgfrkſ5 (ɔ"6G,!G:6ԋv/xBiZ|/}#*oVo1/m`gf~B}ȃo|VA> ab_DMA>Fqc+<d>oJbścU ^\9Gѹ:G3ha6(6'%dL G سbs8(:Jj?ʔwz6R#%m18 4ZVC|-\%6dZb+ʬJʠya)hzm6l'O>ޞfA_C'[}+oG;V}_˻ wO| 7jݿw_~~/(3@r /x'x'xos?mP/ѮQV _ܴlL]Ъh^t_K@-aTqPV?ɰ hrA ?2" |~7kCnJVNd(`͙/gnOrȖg}Uvt/feWq>>5dsQI.E},4.#h4谄DnQ0W(G{u$*BEvݨkK؉x%l`*k9]ǰ+Ƃ :ۇY[6}ޖBHzDEj;)k/-** ʢ%H*'^Q@:_S|ͥ`hoǃ/~|Q3?u,>;D#naEeM)shG q,O_iTt^GՂL4/XY_ӆE/yh7@mзtRD<, eM/MK}/ u}( = N yam<&I"͚?v- g1ڐEXl͒z("~-(-IS@ok! ,us: j& m*dAs~m;΀r5еU usEOؽ9_`*"py4ϕuk9,ռ0,gN2vٕOIU,X #9w}RʭZq2fjاY?sB?pgiD 0؂ϣ5NtNkg(cǃw4@K;h gW'lʏg(ICډx3/j?~~O W_~oͿg[o7w卿wig8 _7z|<B'x''T[/[?_^>SplVpm^ulY&9'MRnqfݯ}`\+@!}#@>et28X04?AxGa}۰aJBDCmc$5YćIA@nP؅X6# i>R`:\ >= & >hxteV0-cy-x7rdA30 r`?j24j mλJ B.#dq[5'$ek_p#bl;e#(Ѵ;|{ÀZbvN.Q@I>Աڜ(3ʓL%(UW퐲O~`30˚ra-D|Gف+i$9,;(C,*@dg#Хt+qni !/-ի5w~8 ôY@asZ&QG྿p7d=v'm]m<@8"yN }(X ߚa2䁆>J# \kxza\074E& , ?D ÷G0f\1$-Xg`+i t=+ $㥤x1NsSzB=@:s/v(lPÅn[vvvsO!pV8l+pZ|*Uگcc'8g*| \ Xƃ F?X/Wɩ&rCg_Fk>O&/aԗ7??!;/o\OO<O<o޸zy#P\j,t@[(ŵ_QB^p37 Sc%gs O@CRߺnG%cF9&!}0cp*SM!61;GUv=Nv0:Hk>Z6O^~?zۗI>vuGt؏v*/ԫ|4E;?U"zqV *UH~ am<iQG;#@/K{n=NǦ;;x 63^C|/O{'+-zD*$`5嫒AGˣmvenyr) 88woeB#ѴF&s[O![@mXC/{u쾁]>" h:RaGcT>|e ~zm̵]#mbmj?6`ɰcmo5h (~Cc|Nt2Ɛľla͖3|>:x xXaᮡ8" }J 5.uV1+ ?ΙPt ٭.'TyVCNq>o2] eV4!ZmPiIcv6_0N_lˍwq3T<\~@ 7:bFEAkc|a;x irҮ|Psڢ*%lG}OP]ПюːzCFI_Nn.9TRׄ _ʰvij/u@IËnЃQG]sLٔ\oOpNxCQ#TEkqDLϿ_ܐ\ȏEAr?}C(>k6a򜤀b4AilDCÊ61>N\O 0clomy*/e{r=.Q5הA}:WSQmT_g77$SvhcZXTvC#/p1NAIQe@MS Xh賋f>},T>hcmCV{8a',E /pv9X!m& #E ?6X8T YCp[1d% >&qیtq(h˺DH_ |Eݑ` E0iB0 ֘Kba GӼVW#wߊ:s{vfK5U. [_ށ @5_?^$oqU} *h)`-bTMk m.zm ZEG{'BnT+l=koBqrhVƶ7q1iQ^ }d?xف:|a[(#V`S/7> tЎ鯾a@jТ8!YR1ߌ"t*}FƛlyK F*[ҍ:&tw{7صv?:-7F/(Y;+d`So d fg|MЦ1Զچ![C7*†ּd>EԂzNuO<O<O<WN\u|~'}#pĦR ƦTݠ3kt_S@A*\'d&V~J?9rƱ-7c2Mц۶8~'L%bߛ 34?UQ $/r܂OO 吆GbQt|v~]a^c:>|ՋD>>|'+_~+^8i6{xR~l|w&^`EW73 x/0h?g/B*F *T-m|Y"^}+~4W J"Q(kt8ߥO/> _yd_,@i=7_B^6]Ip;Y?V.0| %bç0kl/J$=Q*SpfcW~a tR˟&Q",yRQi+]uh;.lL;GM9owɝ m5V:*?9 b,1wEɓrbO<O<O<o_Vl#3xpKE~} BcA[+,l;轅2D@B}OfTED`|Z1޹WwܞwEv>x2U+ey b@lAg(,AR 9x3t5Qb?l U 5޻ }u~ i~u~q3XAm_Ç/_>e_˯|6f<7lT ?IG Z]r;Y!9Y* >+ڷc1 @hic$-(P X* j7ɠm#~G /O+ }=\J`eBib'( Wyh8ҏjzv:Ly$or&a}d)4uD|mo s)6+'sO<O<O<O<\3i?| C?@g \Cf>˸PA[\[=op2brʨ]i,ծholY ?A=s`y I+\[m,@KЉ6hVDZBAq\;*9/>E9gS7`vr=r*R93o9Ʌ[m[tOb!Nmۍ_2g9 w%Bga.e<(U}76L~MLO+.ge-]pn_ߑ]HAYTwA0V!kX#j~@ t۩薯pO,II82)k} ??GϾxߏχ}=O<O<ķ?/7]~o0:h&Qt1DL׭kko>jxI^S̤}4I7b:'0N6PGUbQ?+(J . -н4A}6.yOn ܯeWMcAjDȹ k5!;a7yņ0>GLru9VӽdW:}O)tۄ1Yω__poplͯfxv}\{AInbsEǠ}#;VrD<دqB/T-}&E 2x"!×u@/x#t./qȎB,G|~s UA&1sB=vjv]$ '1{~#+klA`@~C/0Sm`1Ԓfǒ+Ͽq}{@ jTfca]zԩzɍ[\kN 8}<08G B_He lyyY ]$tbZr(}/q?k%'siѠ %;Q d)?x$97FI6eV11,x/IKGNShy+0F4fkk+ocd>X&{~_Q>}GF'@(,.K>P O>T f$ f;VP3 5.;jg9dzz 8dmo~3G ߪT 9sAFg~xr̟|CCZ [97jtGj{OAmМ1F HivR7U)|{[Z];CqH-' z u ½5%Wx,qG-U >68abŸrVƱ wꢽ+Cq * Zn ԛ߀ƌ;9_k}3x(UTPE~ ,sQ߰9F=6񨳄l?X=m7gi>8wC5섣Qkn]@tBگ+o?/0^Rq\22>_l{k@z= [⤬ю5Xel<{>tj]I͟ q-cZ]ŰB7L1u2ąP^Bc"3c |N1x-AN՜ӆ@]0>6+ y@l+[(W =jcBumIXC_M xl\臍4To՘:Y%ƀ?2^6|{(v=$9; |PFMy,/्C׏s,3x1tT eƋ;_q_!g 94>>\G!4kFD?N&rBq[b?䐾 1Ck~c~MFM)J"rxu?,WU`ȸ@=Ccs(Tq^I|Q]퀆d@R$+@Wu6PjL8~a/plo >O:{Ų5u<Ƈ]*~[5.\kK0|&#^ࠜ_ @~. _>͗;J2nЙbK^<}N0qRB>etTѮڒ'@D}.Mڅmٳ%j|u=nc'UŲP_ )/@9`3bȼo1|0ǕmOq3ؒ⧮߱]>[wbX6;Oz}@f- u{$oRop7k{76*IZc ):-9 @m||dXkR7+r0h{kǯ"7>=B;wK@5T;: m]hmiV R1QVB5΅imܘk mKFJ4~t51>;z<>'RzYs : *u> /@g.*f\`dPwMJ|zCЈΔhS{A5F7PǾs <dӵj3XdkNAئaf` HB|5b qtw]YΔ e3Cx_nc ^ y@:(G8#t5չ>A_=)VO?e Ԭ7~G :pol#c `:ib)t8Hy'ty/W.q KX2>-2[rrAdq[3])ĀCf]D|;0"c$z5žb99]67U;3y3f'Lh#.Dt ƾl7Qrq1r\ǺA=sHo͊W(l/j;P\䀴a)g5ϾRF6-ۇַE&y= $k\ˡӕ y2wΟ={0%&ٻ+L(=7r hMk NM[VuȘ^ c[%gt1Lxa2|qv2 м~5}g6 k﻾ˇf:|92i44Es a;Z4xhX‡_X㎱g\p9πtmuL@6&M!;t|Ϡ>J}\7 "P /j|[ǹ5kЯ:}n`Ç_>G8+8>y^/p^PbVuu d9Fߌ:.JeG>*K ga;9Zb+'_{]tؘ~:{Np>fN3-on=ɮ ͬErsW7'*qELIr@|kj@͙|_Kx]u lPck9ؐɬYX/Ns6%ľɫxlVd[07qyr+M>|6t6WB [c3&L9S9TvHi |3^4>h)>hUa~\)ܱ D2e.VFc)|p7h=KQqmQף17! (uX_~khWmuۮ2I;ĮӂμvA]:-,v\}f4ٯhp仳9 M]d.:Ę & *XZ)YlˏaS&l3ȗz@PӠ R&}0dǮQe*o݂.4j8O8Kb~$7'!< 92; V7٧yA7Yþc.~2xym+a-{}/o^֯w1q"7W/p\7"?RW" Se|U\*c Y@9ȿPDZ`W,qSV/p@x{? ԊOXuB?-`}/pH>Nڢ=sr P ;ƕtc9rj Ѯ 08Tng&; Ek>.xBy7G(﷬ qkR8 kba_c\k' 8"X2з39r}oGlW$RJ0 `wܯ9}#yqc՜3^d/>$􍰉_ ޫ ΟVt3{휦Cy `,61a7N;?_à1})IWviMcv&R-& y«O,Qֆnoάk y|П} dhoyC~kuMc/thuk.–?'Ix< 3 "l`Ū-w/6Ia_IKV}_W5$QJ4d@rޝg[^E:}X5O`<8f?-ؐMI ^.3kd8A J6' ۙgten=]󁐙f9i6U(Wم u^t淨=}ѿأ$v}>0Myh(Ҥ@ेGE_/^B^R<ѬȎxاZ_ n q/&?^b Qh#Wt 3h#W\8_ۜۀ] /1ɆsZqGilVbO~[VVr^Z| : ]v'<8ΰ][W 9yS2w~%Y7'5TY\ 2on4r :l^HGh;"u^U %Q 1k2EhDG'?5*Z ?xlF?馋ٰ#u#^壯ɚ]s&vs@ ~re6bv_٩voXoz[NNma2#~|SKUݐ=cߎN W!b_ Jͤ-`j2,n~ {g暟_q3?igoI܉p{,)iuzVh)ݠ x$/1O^YrD] M; @6Z(hm aO4k#&1D;y6z#L'cׄ7BWzV`%BؾO,@'rTso)A_'nt2ƒFJlg}ZTk(Vau^1֮\wltwpΆS\m|?#>[ss@7uMlnCȤGǃtd6>|'3^r$Zbq6rL1{}Mb0>9hM2jx}D}A.e#>^j0(xX }H6J1hQ(bwC skѥǸM2N%@]T88e֌gA%GvF$_kNjB[~X˗hG"Պ JЧ5gЙPlU-e}ЛDwhαjFs-U}P`F䚇q.L+|'1Vr!ñe;Pn 25NP^J\esR5h\dm%}X|f ݫT̀Ѵ}Hz=j6fٮ|9w Gvh+[QV(o.7j#M `:goV&!CD^(!MV8!Ijcv:j|@< i i5=^`$bτac*BzZ\d~mb-IG)5>YG@)ځ i;`kzBr|uϽSdZ2 GƟr!{]$YT|o9%:nc+(WarɟeOq;&%*!~c/{%3!zKr,/z!LI ԥo#NsQ$MM@h6،m'qM[v@xQ}O&ム5D؇vΚ{VzIU.#c r"XWj?gbrknOyfO[0@ՍUpsP?Z$; %{-w {kx;wv(YG)@A8+9<CNvO3WkXcAf0Y![fdG1Q'Bc*mTLS`ge/p~6#,|x3یy8Aj'׀챎Ւ$Vɚbqo'f#Pm렭ӊI_R偮>x ՇF0<%X|uV:lHjKF|a{ث|P bc2wDKc xD4ܗ7|ٿ0l_O%/@6E1N?y(SX+HgOœn5Q7Iy$:yHve>Y+Awmۣq7IFak:GRO/a[{5N遌)>]1k^RЍQy1Q  = dQЀbrc1r ՠ ᅕ27d[!UC#P\%a ]aDmV%tsM-F}6"8';Z?x]'SNHG/+>!dZsK)Z}Т+NVN2c("zot۶o_jMn:~W<@~(b4"8/Go:Y3P(2 AL!~1 Ǔ'Lȥρ/?}qZҭͥx0PJWPLy,>?;,&\H)Ơ#B G"be4+y{6m`9~06_9I ۜsm_Q|^XduEx-0YØopMV"V)#;Ե6̧8OK]cmu?쩏? ^p~^7NבʜB%a zl 9'%|+&1rph/~",T AM(յF"XƜs2?3V+BƜq 2U<1HrGAU|u6R whV?ٚK4 r*&_a,p+' Qsq_kGjףx7sXP/pD٢ڽaB^z::֫|92;tosMW`}Z y$sq5t‡>n5~cNnEiÈ˭=#1]7asȓA9E?!v](x9W<<l9w!>\pxxpp.)s$!]컱࿫kf wr;u$OwI6v*ɎH7FP*?D/ī EntVf6Kcbat6-]vhدg4aG:Bݟ%6،|F\Vh}I8Dn|P8eyc'r*[D?VU_9bIt)gzՖ@zij@Voqa#aUإ^8pɞ`quH&Ѝ{>I+WKɾCl9dh&eCx1uqC 5dXeԱ6Ǘ1CC_VE7}%_OPmTtTi%ّjkr{T]"L^(]1PlzLdMb&\+?㘾udӮju V]Gڇ'wZ' WNe.vV1<j6f~PqyL6Sz2{27Q4րc`urѠIa}}h!c֭}IUz|}&MVi^^I5dtgF7Q lQmts,>cy(Y| :X<LPz,^`PsX=>;z<>onn{Ś1@]ѫc(rWot>l`8 +XtkCL|۠eWcUSݱ::ǘcEn!+ }2֌7x/ׇyG{3a T]xY<7g{#70ǖ5p.ud0G '+, | gX`~`w#=9*g@*58Xޏ]/S mLoTev>bM'{˸ d?3by]5Uv~c팵o 7X7ݍ.Uγ@MofUUsk؍%D ԯQ_܌r<˿|4GN<boM&/.eࣖ.ֆ-ʺȓx?n^vyesՇ#.Ѯao7^yg#vBg ޜܓbD1v3Ly qrϪ<|Q}/j*WT%:yNqF2)Ga?Ŋ*cwK1S OLPNMB$ex}}\|;y?PUO襍WAA dy ߒ Sa#ٺe~>mtGPM.\v SF`aҘ`{ D oSJ_&&A5נN gA _SiYhwڹHD X`k6!c5_ t%B&d}MJ/;3>Axb-cTP@qю/@1'g%\ȁgB4 qyX}byƯ۬K9ȷl[l%V['@e;>m@!Z|T[ 99gο^@p5czz⡶B3(A+~9_hJ>X!f%m(_0Ƒ?xFχO=?F3=^oIOAo4ɠ(0PL5mOߒp6hSt5(> /}Q#O 3~D:h$yUєm~$x 7|_ ::c= ؞iZf>/a 1xf k#e`mzNll}fsNؘڷ2;@mݛg/cU,cny͂7XFqgq߃Y]7O ߄?7b_X8gߡ@ 5{O2RKV Bp*6hze Fّvf dNj)8Č>0ΛΎvz=vuc*e1'?V׼+tw'|0b^Ċ@ٌàz8<>ÑVԵCK>:Nfj(_x8_5dž6Gz''+$O_{\W'8Fzt!Z!:`_v^90 sk's{GC~f*z\ vc#ь f+wVra7Fh6.з5Ĉ"zfbBxhtἲ}T?)MH|١VS"xVkC?݆b֬9EO_}}$d#az]$W[9?NNM OyJxjd_LXcx,iMv4 fa{[qxE\P;d%V(/ HY#/1>%j<Fy`0.Sg|+M"!bU)ikBǂm/:fqlWtfŽ!H׀6y(%XlVP x=ĕĴ},.x M1dةg)ل'|)80/|%T2舑)u [G;hkQ/$c,֏|)'/]$<ҸG`,Pe;KrJloG]r옐̩OqX(8FC~-mkYAm(ɸ<͹P s}KEz.>>~c|ʮaຯ'Cje8E>]AL:u!Hk|@XV2b">8& hKz>9uIQ!U5?mQM5 yyCo⓼(VNq\+Xk@𼮰\ &J2}AvЬMmNʗ0v,࣍bۗDi8]21vy A4PZ4b?yj'?Yemrl[pѧ5)>#yOe1>Ȣ.i's_= ,灘bD&8+2OOKTSLC3z\@ Y*1 yGory]\ex[DU4W%^ 'Ś9SQѼ}uLȬ<9균8ϳSDěy35=_{~ܲyvАaNя:GH $~BhXW8 Wy5NlzUNl[H<䅍%1 \sf&JoԸӣccXVX 7O_)yLoTev>|G {Oo8kzc3h/z=T;5fcwX;k<<=w ̩AC{6͜UZ?q)>7ƽ}#jU}VzȆA&+ݴ?+ߺȝ ~-a@n*+uF ՉU ؈m\K<P;z% S=@ r3^+nT; 60mu2d .)@]b|Nl|1x+_m,49y6J8!3dtw:8G9m>__Ch~C~v/b5}kVĎvW>cbUyD] >aDk&tl[;rC/s19^0G vxX3O"i#.5FmTlro|M{KSRˁl•fGO+Fx.<ϿN1ĘaV̋Ag]Ɠ:I W 0`胔s _o?JDZ~9mϵ@|[aַj>%kxg/p/cȨ@Fi~q t&On+-to 6N}"uB\ ky٤]&oxavV/7i(8VhV)/e-dj!^,;9LUh@eڊDյ/ :&ض?`mC"lsJdV 5 yGŷعF^<bU{'-s(8*H/?[*VXrslqMN'̧T[&-oU(?v<@fkr߄yhmн/(yUNjoeLV!Pе X41604g"3_'eg63h^Æcߠ)S>$ 9,cE *OWdv6>4;.vo=mhѧB|.XX0yzh.-i&E DG>hI_Жo`/d5לrQI[؏Y9]YG߄FMٷv{x9SX 9ќMѓq(P񉀴$9_4x>۸wGum/Xg \)@R6:͢m1V<"T6b㶏>F _VyD8`t`|`\>d$9I껀?Ѝ~E hLfE31{/{s;ȼ2Пc(Bc2 2_ ' y@>M6a*ZW9&L[rcXEdilDб>:NFObc*/LX?Ѯ<1gRm98} WӇ֩fHbۤ8 vS<zu>AxZ~G`ձġ eʃv<(,q a9˝wm7'w qvoAʤh~'@y5|88 k1N3_󻢭PcP@s u-m~k<\>`r} ܄J\V^Wjw9lcjr ]bZ5HR@2> "0jLw]{/z-q_a{ zTг9yCHZNFeޣk5&rCf:.;8yC6˾M6W7+]ݐv>u>uv^|}{3iѷUS<* ՟JowL?t# +4YXgXpB2p[4QC "z՜ W` ~ {ȠrU͉__mxU 5(۳<6:ڎ>W^_?Xe&m>oQu&|lҋ)+SSL^ƵFc`?CO~)Ya /t>nU@Vc@y;@~as˾m3eIiP.c@r18<*d,^|̈́Feȥ}۾A>3.00['?fO~(L:rSasz anl@J16g4e1u}8?gE/Cqdw؆t>/fEm  =ra{6[]D*?9h2p>NbFS8'rp_]Mtl/~.T͊x\TLhrEo%;H;#Lj~,q[;OƓ\ύM|dk/p(i|/͚G|Ia12!}bF-NmCQCghxcAк[Ŧ ;Bunk|^P2>^fw–QhQiwUd_1;b; |>кk~İBqEVyz[c^wg~hOs_lqec8a+Y5yc!}PH^.ƴ qD.lwݖ[> _E{WXs粟O0gdvy?[Xݲuc*ɌZ Pv/+Z0(tМNd+Ƽ ۾#:BJU#?5h]Qc1!z&c4/!>p\q9S x.!ٕNU2Fw|>@Î/7{!l6_VkNZBmKGh 51N9{Gx o>\ıIQg3@"x <ҊAAY٪4]'<(s.i]JLЇ'PwO+⤌XwE3zuu'e6,XRM+`&?ٙCCVۅc8%a2*@Í~Y8c0:[:?N 59⩸c.CULc/F2@F)_cnAG23w3 &ch5 luF&1|xٴ:R݇UУ= d-rC@5&|1dD6 <J8@ۻ!>tCtgi/|&o/x41>Ev@Xp'>Uڻ#V#/m5;! _h HvCn7o0|N]}@'@uJQ6Q ?XMk6M`: } x 9z!'V:g#ħ<_ES/| BZc0Z'PB8c7?CեrUdzPMV'u CXQ,Qq,8 σlN~aY #ٖOԢkCsR:uLN/Z;޿103qlakuC]P-ӪDSv ea[I}W?e7ed;r9y5_?Mgňob43Ӑ6Vkڐ*mF n2Bi8CwwvF~ k$d9N) nk/nz,7?x܀>8!80@oʵ!/B6p_qHo35˱b"49Dcft堊T+?:ȨX"=|Yh5uOaǒyRkIukK / k!/P.kC@sYDZFYvig569V8(\c@d'g~+-m~ݝ3(<[|~tԸe+9|VkXO 1[ƍ|Š2qЀ7 w_e]^p[>dy#[[\CX>c\_+=+:dEj%xSh度9<'m>i ac8^ 3[[?QO_y\9<_ohÑ1XvKS:cvP/ufvhSq-[j LcU-}7 ea x}\k}u!vv` X`b.#VAle+Tfa]l~ۏ6p2W Uk jPY]ĢG@{SL>ԷFZ6eǬ㮮 lH׺Dt9tu%7xOMOסm X1ÞҾD:g<6jnѷ^:A>7>= @a!6hӸUm;u/AOC e>Џ2w>+ovrs=@3wgf u.[Y7(sڲcIE`G_uڏZ`8v\mIzw]çMCdQFkMUܫX'׌Чh2\AVKBx1u̬9/BI+@լu#֖,6:c>\y/pcu|8 :`r s Yv@W PMY򠖻2x9ɗrcqx*5%QslOm׺S{K}4j ]V|o @J {bX%0\6Ev} XW cΓNS%&c4ineY~wNIb5Mpt|5_o{ q{uS0Ś6:[ti?Ʒ[|K8]LBŒ8t/Ǝ>v=he h\{'['nK—. vnos_ON@bNkB%{;Â5#n`ގ$`؝1l?QDza˫ Ck\o+ q! >wk]nμqM=cx6X!d`[R{+ZXͥ hjOͬo̰z9v\Ae+NNc!L6z7sB^"㫘'Wi;V=jj-ukCjmiؽE#л1 :54VjWNW9s$U'~4'Kg+trNg}yu<&fclደ8"!k-lxz 49Āc 8d'Q!PKٱxʕP," %D)eЁ }rlڇ(aZsp֘B.tiĚlOnsb6cgF/z7bu' \XJ4?dQF/C/;1>: }\#+ .5yc+vk>lY|N5E 0["d_07Is_u JTMXOη"D09V |A Ov>{~c O]CظJuOtz;yv2w6oe[PX*@Vl+ˊ|@o0\ NfPc?bP/q6):ij\?!8p$r\5(*oױ_&[}e*ݶ[۷)7B.iNZ,w{5ĝ+.ǜVs,gr%Amݝ cb-9`gI4\Cf[K;x<]~v(uyVŰ٭r: xCN!NgMOm2gzX+M98/Z:M- m>$#{3lX6t#DljPo^ UFΛdn}8m wlM|8qaCU\T|\Ӥfy$&ԘL6wqNxu XF4qX7KP%WE<L7{-~vGAe<)?K☔0a[yk/8v?`Jm`1^Tt|ѡgvSGvIn+Un}4kйo\g؃heɷa5K1t@Js}@7 رQ9dt{{ W o }YsoGpCVt8葧>Zzu,ULp݇۵IghUFm0Nnb~@u3x56\Ĥ>%;gS̾vȰ6%=r j:Ղl?{g1} u=C }|mﻢ])ϼ7^=ŷK(yiߐ/p:,fl9N/6 @>1gc`r)>s·sǴ6j>Q ! )Q20gL4Cvd[8tզtq#^؍fcHCmCk4mhz$ov ^dJ-A~=SL =!ij=s,/Gqޞ/p\{\ DntīHz876!wFknG_$LpU껣ҫHiϧ;OGyV@GA_+{m.t9/pMF*H|ʨ4TmUI+D6{lL" 춃*/-͏|lپH ߚ+ ƼQے1[Tznn~;h`'pƻ;nm['7].͸3T>rœ1p<J \vǸZֹt@Uv7|X@˛'*GG>"!ԸVjТye]E67 vr;;[~Kd'sWɋZT/xҖ:O`6]c=wiW. ?69tucaò8|?p#W}yʝPmq+¦CIoC=aU&|bXMjV5|7VȤ6f繯Ds zvlx슟w[u7 t7}F?HYOy/Jsd91hJ.4cv {!h]:_1{Yǐ[2hs"Dr)#O΀|/l'X׬Df]t`MZDo3L9:=xęUW^?5<P,WLUvS~NcNJ}/0ж',c;sa%|)Cj|&:bi}hjv{A}/zAR 5Q:#v_PhHu9K ѷ7D' Ѹ]U/8!h}oL(O}n?2hmaھRFmݝ` 2r$ѯ\^#N|3 ,m5V$ JO u?v~9\Ŋ-7>:s &OT8YE~rݣ8oϟPy>UeU[`=f;w'*2h+{S&b^>;t1//䃼wt·x!X-lc ]U /u.@|+Z }pjoE=yxԶ0+< -|WNVewñ y41>[Κ<]Ԙ3FK_F BugG«C^+*M 'aɃF\ |]XG6w/pd wm/pE/pyj&MC%֙}!E}aFYݮ)rF:hYĬH\?bzkGQɶ~n,6j PnM<ٟj N~X@VWkUǫ :e5qg@MJl.M8rL56!ݨq402C 12@yuS~n[_@4]f2߂(|DcgӺυ [6 &}E!P%Tty1*jĚ2!`}݈G/p+A#y>znܠ /p@t(6 'jTU{>;c+yi=kG=w9K{bSUg y, ~G jl>VQ"2>Gdʢ:睵r%\nXA0>+kթƕ2Î}uS<8vP.eM_bm'j W(8"ɠN+4p)lB֠%@Aru!&oWN/MK[fITy#/pPm܈W{/:'0\.Π{5;|tlM#ShW}5UKl" Ovsfr+qdd k*"8,=lCDOP˜8 L6ۚ4k]E%Cݴk6ɉ: ]`t&eB4Vg;=v<>1\Ǽǝ {&h+tkx_U(;{ 貛xޚk 70@O?уo?@UXu8ڐhf<6k|bhwsyk;7c웭:ƚ'_*_}b\T-['nNح%aGZ/$y8;;:?5x l9"0ٙ׹,5> ncj*ܕ ⑑ԅNUs4 ̾Pd<4@D!jo >Dxd;Ճ$Eq ;ƿGA]̥sD8X6ˎ4Ő<\_2Vk[ 22?oH<֨ۘ0ك.<<\籥Y*^>.%[_MmmrU!礘O!>.<(xfo $וC82cu†~[QGyZ>1i)̏Ud$CZy3_9t]_/0b)JRE mtK`sC%٤ȯU<!GW0~/PI{,z}8y iSHV3Cּ􂿋g3l U-H@|jϱ+ =*A}D6Ա!-Hl;}@)nǂY\^m_clXgW%=e}4l+_Նo};}}q d%g y]OM⟲>WyE c Ax$ԧLU xмptv>k2N o{Om]ݧox1Nn?5yIX>G|:>a _0Q C+t_~h<ɰA5 /8qyH;v&,6y%A,*Ӽ  ;@n tYIlU?<vQЮ&P_>tڵqvOX*tt{֖\ļ\Vt]2u|57^pNhs#q&p*#QC,[4'"lv-N L>@TQ?j.,#;R30]Z ~4 nt_#j5W8W/z݅mV[Tax?&3+]yNVj3ïΥr'tGnG͇AsUQAC@m4<⩩k?@ߞނj[E{Y =3<'%>bAl=w bU^ݹllg]Pz r}\n$vz Sѣd'f v:;;TnwijgC<qh.$9I5t'Z2VqVOCnIۭf5Zw]?ngưɹͼgCMM<'Y\2}ƺAWd=lO"=) oٳq;/>M>*ƂԊQu[`t~WX6׎1ȼ^|? Cz/ƧȐ="tv1(0vЭBl(M-;:`6 ۇ?±n>䂲ѣa,-E9mz+:!#y4^̎[¶7v>2C/@պe)8s1ɇ1P'̈nCpl6 g8 D]/u|c{SAc:^bCh'}@E:v|+\ +r=PqD7566Yid#L]lhCVkو|(d4 FSKAc_i + أM]rNY9 :1XA{EQMk3w9')@@$v%(A:!&=4ٵ^۷lǺuc  ȯ\ \nXp-ʀ~܃a(k=F;OukozA2ѧx8_J9+E+sК+&d+fq>:mA@.XEEE y}&/1X+A. b)>C!bo-XѴ2ڊo(׉Ź xPՖL(\ #}E[Pj__<|0h>֚sv1L %{@,ogΠ5 .i=W)> ?)DŮv܉'[FO^; .ՉpbhqV1m2w]<-uort6·Rf<=Wx87վs5S{>xyUK !g7sp&78gf*ϓ=kOE=tg| u=Cԇ8U~vH|,c[9_#kC!ffDp ġCyq. WkgE;X=|E>^K5 5'.|(9m\bߎ>VVP6#u?7?v么R廮1A|+>V§i;c;zc:jm Ag;  0ziX$kOa?``jMF"^~7h;a^Mv/:e-H~b]qڴzuYܳ2Kcx\_!ڴ؇fmV2SiZm6XƀAX| 9uE[+s&寐e_:k\@ayy/[m].$Ob 0 -"NL>➷e]4>V<< eg;&K6kwXMgS cc_~}+p⇾lg/MY+.Aþ>m&/~%\ رDǐIھF@u1 ۭ?Ĉ6|БXgƼvywz@]l1-~N@G ic1&LV hOGȃXU^H4g| rjz66Gnmv̮0Px1A>lɡ3|!vnMxxsY.zAWldmB5A*m1QϹμ֐x1_. {8wOWm< Y;n`2k- Xe?kq.|x\h4Mtm̓!i9؝_Э>D67E툗tF)ɧLgR۸b@Ȳq! Dea#8NvduU[/p xlp܁upB zVDe-#8Am1xa𖵳n-8Z'VH:>?+NrEU~2ꅭvs5av!1K`y ʳ~(ÕoT ; W>[`wWŘ/m5hVqm2gTb\o-[Y疑0QJ>lȧ <n~Gq><&Fw<WqL3>a2Xl-(_.+5뱆Y$m+\t,sz@xքݍ 8QQ#C,c]c(b=N_XF7Èq9D FΎvr suI-qTtg R;Uq_~0@+_xCG|!1pnCcevLs^@ kqc|y0@o"V7~V h? lUpo_G4#:fG[6dЧA;j.y P.OIZAʏ۷B]WȂ|y븭=.FE[C4n2ܗqQ bj@%|hx)K] ACש9s[H Ҫ6z)Vr՟i C䯶4+5++22zI.{,ֵ-1G>11h[L1 d o£ # ;&$~1T;Ylt> ۴l۩K4J4s|mږj񬾊t(, Ƚ쥟ZA%ҟzu@? :Te}^·'O _~^kuP/b1*|ζ4k/\7c. /Gm6^m('S&ϡs >,g&`/F?~)pNj7*JP>CfY#i+<1P VH]9QA1b&g?Q&)mۻ'N!<2m;c]QE쎙oM,fr3mY=S 'lWH+_-ZFe"DW PDؘǒ:>Q$SHs7g,^@wX=nxuHYWNw+'f8g[ķB9oUMCm|E=A:MʷܮbQ y#MjrHUgпK=^zwKgo@+2 W)SVj[ί(=6nbv~Np1~ 횫ujF/?wW1puEyHQ5ڿY/p?Dž[sxw6Mx(R匑fkڲOU/w?~QAv 7MOg,b.>pl8Z6f36(;}F+/v nߊ,bX(|f|}lY x8u:v r%W"[~AO!>*| hf}ks.+1֗&3wfT -YxA~n$۲ Յ\uDn[7RmX٩̘VyM}G{y|bV3$Kj"[ODDHt?L;r A6H0As dEx8[m6Tԡ=du1}S<>x;+he D FœI̚ҞEc].Ի ąR4dXN_}q k>|t ZF_khmFUT~?~?YNrB9$6->;rg7#`uՄWR6".=W} Vr}f/ߨT/WXɜ8g:)Ӆ @c#VÙ;Kߞ'Sg̟`<(RT:ew+oZKU3WvQ bH2؝ ||~ym-^/drrgrߢxO߷mNĆ;8}kO4.zRح>g;w}-=,q_.b|8ksk.kZH۵/iX(HX|i/lTęi_E7HVͫ1&kX䲘*ħz1f8Ї8L@}A iaW|"]NƐp6> P_% n (4iF]kjc-~NYq,C*!:/>[m|x}Ǘ?#Fu^|Sg^p.u:jصv(FP<҅;7㴾 =6S^F_d@L9 y /9>CFR)c_%!PНPƃh6@A >eQ<ڠ_˚>G;hAgQ LO}Ƞ!]1).sv9![ bh.h,>$ %rߨ7Զs. (L%.rQ|<:#쯳ϱ XKuЩvK,i|5T1YpDN;WesW]h+ڌXm;Y*>lG;s%t߮J PxI{ {pB>@B^,Z-}㫋])ss#&RoTaj6i6gg R~uo.[+ NW9Bq Z2]'BkYVYxiizuȉ.*yip<z n'{[R[ý- (D' 685U,*ȬVw{dSv߷,gmty:_xuo㎝R V߈mSE1)yR`]톔.Zh[s"xj='*_yQі~lǙܕm<{d\6r}xZbg^ނa%uoy >vnu>/ QOuz07؟W_~P/ q(cUXC>Ghd|WنnzwEXc[7CY7vu*5ޤ-tK`kaT Qk[%VlP.S]] Qcy8Oˍ:ԎcZϵ49Gm Eshþ*iEV؜3=bht6ՎK!FY>d%Vd):x@Ki*Z}?|e##ϟ?|˗O_~N> 58f<(EE)L#1S?`t*_3t&[Hӿmcfhb<~4#QtUDC;,q; S P+EC/I;!Ր6jʄ^+_>Z˟>DB?CG}I@u(`NS~cMrd|w^)NkmQСOh2nYډe;*hwϣPmw+RjjC]ٺ{k㟾:17Y_klxqz}:GE}[-;Rx՝ܿ%:;N911\@i=tOC*985;u.G^3rtY˛'oU x+gs5VG<ֵ!\T[e<菸nciwczۉo 0mS>y2'jQJmGʾhfd`9m[n__+߱8nsI@FzUݠshI'TMlq\>憞Wk=yWqZ \[IކXc@tD]lT?遯qOAuQ0zȘ_cg E ',tawk&6MpÇ?L5pLH#A'SXU)[q㹭MhmD}a ċ!j \wo}cm2+cnTWuA瘭$]3!&`X }B. 'ūlX_ES0'Oq48N-۲?Ѵv2[A[j.2ZWtrY>[ ~EЍ/Ezi?9;λI S>ڹ5*qZ}lPO~U@\_ϊrc/^Vy "&G:4U:j˛0 ?\0?5(dwF\W`UT}G hBgz *ЂP^7#}"T ):Jd3spmyx/jBfq]P[ g=,Zۇg C6\\ rc|1|˿֪q<c6Oz|@ˆͽw44&Am]oWti/-5ze DL@ݗXHNQu<$/e9fDR7ps(ո76DOոW36/pvvS=!h3t|W gPDb;+&:Vҡ5}(ޕpYp/mV66S㽳}PxRw.oU'7#:5> b8|9[UF<Ъd|Ba8&?ُ#.k_>rCag+ؕx:j]mxgko1HvyNX[\Ɓ?{g;Qبv #> u~Bu:kUaI]ϠRm?w]^8ױXG*6_sxL|//g_۲RMr~dI5S!lU^<,[u/3viAFw }أ-%VlXM&ML(2 S>P3 .7*62V"C;Wp^6hcFMOɾ=cpf Wj+|@4QL/SRmDgPЎ ߊ>`rQa< ? ԏzvA߮*?z)%F2f ɛYqîTx1f71 cli}/b.ׂ MF[˨'PLF,mFčm&f;+4!j6^8Xý.G۵ڐ㰮ߎsO7pD!E!?8C"UKrPg㺲Cq [m3vsPGsNvqUtۮ@eu1֗\B 8.+~m;[鳝 /4&S޸Uaĩ7pu ;;y\,qFgGr!8vzWv+ bm69^1 QZ|37)0 ֧xc.o[=!x%We;jM\^_]~T‹h67p=7b1LN.>߂Uboꠠ^xp61_O͍]R O-.m },boyyvE~6@OsMGC9c` J>bK\{&_&C_׭[ŽC*?l]C6XQ 1>`dA\/ؾI//ڱ#6łvE1h;*DH6cJ<Yj#zf^P dtg|(xu;~A.}ŞF=^RpF-3"g ݌#|Dlq_W um0DkmǸMn447@"ҩ9R?o\~.D 9ďl( .``@_; /tPLg]l,~~YBu4˩F lW~=܆}>ɃMo48[p]pCp :vd*īÌ(ds G@[f4SOڷ|rd%vtQnW;n!N~"v]֯t|?"ЏfAqⱏP->׮!bqvj~Pȗ<>+W@^^ircb@r1vaA%`L39xHgumZ+'=}zE 9LջVwyB6L{+AN;Vuv]S} le5/cc%^Nt*7d7饮&`};1Pᐛ~Ǘ~c*I%xU&j U]4w*⧌xphEyF/ZB@s~%F1x H߻ю~ŃEƍ&Ya< B2~u 섑j ¡O6dZe/Tl TnKqǾz,rkc}0>Z㇗/ws~̇ ȡ2'k 7UtnXX ZZφt@5Q+#y28! %s~oI0يqIba^\1+UWE'V ^}Ɋ?UmYVOC^~u.t`W?iǗ-uZ*F䣉i羵GBڡ,>q]1!7ӣ@5j=N>& XC]unᩐ_ |p3„IڛCPdIʼnfab!+5-?7@2ʗ>EfUz `LU/-d<,64d(@eq„"le|@F/dVq\Q[9/~r3lo?tLoāw\+y{'oA5s_[bDNl݅SŎ0՚ 5h[ 7F\C14yL<Φ8@U$:-l2?gH&j:jn9X&No0X~wy:Ŷ\!1vdNN@ύtj.= ,jv޲6݄rQ)A-PΩEN#:V<*2:1W.{uܵ[!ݎL**w;%Xy_gU PjN _?2f7>ϱVY<{_`A$U1zhg4eȬydkksMmØWq'Lj P>P u{Nu~̗54Notiq@Dhopy##pMҷ뎚2Q ֧Mdz-Oʬ> [ƚ/ϛO+g 6@w=b/vk&*t\h2Зݜ Yn0g=&~,5E+i t+S&xCΫ} :'%J*c րoܷu  16A0_?ňZ:q A+"tO%=V9"Vë88N||D >Om$AZI[ѲN|#|wsw|t^&C.lUGن}hd<ߎbmcihtU`Ŷ8}l?éwG]?[VU-zK2$PYsR< HQyvӾ ΃U/LjʷRf}[k'RQ<{箭Bv+"k=K- D8'֯z􍀾@}-*bN:(ebViH9}wZb8cb(o;KV2&BЂ9 p.4@2O>&TtـeoT-%e&XY)Y2`@OAI=b S\ E6E!TR~Pݕ၌@l m* 9җ&"OXЏv^}W>P݊uD[|uy!ŏij\ d a@y? ./jmeh\LE}{i`~<_sX~G`<=i{ $,sPYr1`_΃h'R8e-3,ǐ GeAc}UT 6g׀OM x3Vo*w#؞xAڑj;N'|r'~x=湬c~IUy!+~5zyh!~3X￈LL1GM*4,۟]/mAιSZ-V:*Gw|w-d=|6;?EC!|^x6[] $ꬩo[[<2wa6|u^;"w(UwBIk%Zm[Čܞj .vOK-|_v<]_!DGm̝A1G'xoݾir }<luQX-6xu>koÖ |cN&A SRNa Ilxq#jaۦ_l;˗y_ qDambEMO/-H=Œ1\ ^YXV3GKcWj0c9^UBvH@7S6'ȷ6u~ ЋQϟ^?~y6.] lB} Ÿ܁ƨTPM0}61blQcڽ |//*6jNOw׵ٶV)*d5>Tq|lfaXWa`ʂ.Z^.?,#~#.~P Q腔Jwd`d .`K~ؼkaC8@C|s3>ig}<u܇@b~ ɄUbkBd5P:`5Ylw|v@磝 b Řz!0cR ^+Z9qj_>ʩ1d-Gf?{83 yLo&ȾwW@P R֪]0I Rl^֚VPJS~wL׏-so\7nnWWV&&^nօ2ؓ ɣY!_lYlSqO"zǓ1/ϓ`;zxy\;ˏz̈́v9~uc G~s^Z$5 @A_76@ ?u@WAlawr2u 5x[isX]V\4.1smYc]sل:x`BAe)0}lk;^!y^eJ9);u{SQYg1.ݪU6bXvK1w)cakltTj*LuzbVVgbS':޳nF䊗lh>O9fXLN<0YtD/d Fe]q +:c߸psͲ[qLRB(?|8 _:\2Hk #jacّy u2C>G &n{yWc8N$x=8'2QM1?:1z :c^^w. dB)ܜT>!}XYa8k+!Cڷc6y & 9 ?}/k\+ǧΙs >_ڑ._p~@/,0=Z3BFsRwBJ̋~U<#"6WXw8O?cݩk~M2 ̡Y2%ܸFbGAp\p-l o~C@y8 %c`2<:~\q(uLcus9 衃C]O>Jtb <8Hf >qxn:515YgV,:|>IgynU$0pa}q $ΎбfuT.G|x- LM >l%*.a.~c#~cDzls2y.}<Ǽ#oQ?r>t1 5d_hYcM1?{Ƈ2Lc{zu߁lv;&_'y'nv\G0ٷސ|jne ?USs:p'6G>59u9>MY`ܤR_Y=;ߐP]k`{Fzޅj4͜mgZ1GV炪Å|! [bX+گ]Xc7y2 h.|tف4' |;pȹHVuܳ.%-;=_o2y繶D s:BVuVs>tmPRVĮ;0:k^~|o16ˇkaĆ?Ϣ< 0ӇnPp|Mcc<*کvFafdtn)m`3fs-u=y9J/]8q&5C:dMηw#n;gZT>ė,x NGeh2v/}~YdZCrm!o@Gc ha;xtc\aoяDu4ox4룘-kLi=V7c{ 䠆G ̓B;gyW)Ǽ<ƺs=a2#s|VW~ؘ-"xX@xҶ2jXϬL v +R@ dN'c? wt2?9 1 u~ƞ= 7:8+ ksdݪqajئtɰa#vV6;l ߐqocƶY(ؗyydt ogwaF|P!D/@uш%pֽoK^z=g.|DI@qaoX=ڧ:XS@<ӥZFxA"v51f,ܳ~|hvGl\ @mNo= Ic>̵|sΟbv-qS );^K1XGp=G~cI<)%" Ӝ9'6&c6Gz?@+n[`\o|۬s\opF6FoR;c1OD9E7)aCA@E:H0p/4L94r]ZEOvi6ن:#UTGl7^@ ci}zwus{9X 3&*I5)L ]n@ƻcm'zf̪B]SsFWsU.mm|8f6ǹ0=;QjO5[m/[xayK. /a2tJ/잭ͮdrŬxwzwZk ~d;\~ho]$]\8%gZ~J`}%L l9dat0'x[vk.o{ܞ fu1.!Le;ˌ2f]s9~?|I'۸k=I/ac>!{Ӆ~Ʌ7 4딁U?9K$y\ã{،fD9CR<sxk?b/tR ilSkX} M:cbN =ey@V~F p-avgǗN~]],kj[Ek|;fpk Wѷo~۟?/ny Pzy^ [Νz3wy\@Dqҁl(O2,ѹ߿ o9糬ӂ#6K3G=/8?'4{;@@QA5^HC_h%k<&Y@2CCD±֗ڎ3 X~muq>Pk>dky\x9<;<'/@ z,Uk+Sբ4x:ǝݳ>w0\_|PY_:}rNfT AGnuG_}e Vgc̣t3%|p{\u_AV@)Ű "mŝ=\;_Upc;M>BNw>H9?ţ0@&yyi|mZ3fPAɏ[CW|l^yW6lC59v y$3SW4 ̾'nzP.}aVke|Ɵ'q/yƷ~~7jX?6ߕG~xc 2CX_emslðiHw+Iڀ39C!q`bPq ڡ =RcM4X^o /O 1@]4g5=̹@{>D -\8a{gm'Gg̛bBGt2v:/΁5mOE.&\s0_'wf7}C/'rΡ@"ߥT>̾~q{ O縲{:/d|g K⋀_hֱ׸Я s-rEr𪬎?A})\GW;F۫{ڜ|,|bQƋW8$u2 g۲O w;35p'GA+P ΐ/o7 ͵&87c8հMPPOPUdqNdnFԋu_T@uȻ̶gc{xѝk#x0߫:˭틝*XqWns\lX̚# |&իaͩc_a@Lh7ibGa|~eO8ٻ.N^d}0d ֙_s2;w {aBv7ikÇ|}a仟cz3b,>|tnBvۨ_xը}wF:(&ji`\lw kmNbeIh&?cO9LA'ݙE%t¯Ut]õ/3\hb:2$eY>NW^%ױadc_ 5 ܬOk}?|||0吐\JT<0{ǹ7 v=Hfl1`2G!M#P?(??P'0@p_vWǬL@jk kIܷXKρO=1%K4Ƃx+6~e G>>ƨ'd|&ӗ1^p}e$Feh!俼qE $m~$%xwI?`ͮss_gB #l (tYdy!_ ޝy7Vl` \m2UMw1,-ٸ^JվvsW\Ԙ#ޜ[tZ6;~Fm@ȶ ͐_Ecsc@ljx6c9p0w<x?fx䳯-eؠ7Z; 3bcLWyuS> /EIE-j}k0S/Մ9)OQ,a^Q A'HrkܳSy@CU5džm5ƌdS?8ph@=2ڇ Cϑ$& ۀdc_ç?uk-S/ 8'XN"aKm }!_t[߻x KCڔt0'=1.Hr g@:;0fIデғr_5K^!Zp]CgF<#ṙundojAzz_@ڄOywzs (Of6vGp)h IIHqCJhB#\U<\K P^(q4_ P֏xxгW| @~^x+npxo5~[+UD+,hB9t@g⤚0UWFzg DoIL#DAWjwD֙'`ވn@1N5cA}|kuwp+0GCyWr xvDK{3OBcT4ΘddWl!sv^³T8FHc|@Һ+t{<OY>gj6^H*E^"swDe,M$pN+7!Յ\bBz UC1S߿}O_>},~GZwj<\F~cAҁ>^ 2}#huCgȖ9ƸF^rW + >* 9O$ÂkLyP7Пp;}h7fǵzxDч7az?|!ncb1j".FqoKf1\R\' ⢍_ann#gQ'h?|b}N͆S/| }Kv3yqFLO2rt' Tn"(C+zvD m"]'{'f VqogkHKuBVj :*8 7?s#P-CPO@qk]`T}d]L y&sϨ>~8pA?N"5Jb2ʸ9?g|=~yα|b9 H۞M߾}맯_|_xڜHU6U<]t:!#A+;r r~T k;:Vv# Yo? ٗ?bgڊo'Ov8t(oyhU`#zou|E^>`Y9 \3_/+7>`gN\wsk%}eX'8{ƯYߦ];Ӏr]Ig:{S3qwc  Y)p:'U`BntZ ٧Aiow:f^hd7F b3v֦MmĤKʚsWM 2š7eY*pS,cooE[ϑg@:ZȽmKbjr- JBεV6Ư.{w(}')#"0reqy&=Y>|GK^w Tqq?¾qq?=)t~q]^ćF6 4d,2<ԈDo/'7ss43?E8`(xk>Z=T9 ?sIҵA4ʶ@_DG')ofW?p"<( 'g;|WP,g^ GMPX:ć4xsA]akL{<>{X`t@2-9 Ȳ8R-cv @96bnƟdXإ>ϯb!MKgLJ _ :կ]oc VGL!Z@2@r8E, ^06u!?'ńC?n8EI>q#>l>?L=NZ^o0?*'n Z3 gx:|O?eSءA}q1 q$}-|.agԃMsl {;UA~#[+~,xd٨FaG]sa]̃x{!j6Mfl'M?G>2/7K'1;ȋQ@S\Ѽ}苮u: {cqUIQƕ0̤JBKWOsIã!H_ۘEy?wly>s@pG'#͗Lăwvo<kGOHRe$ƏlVkuԒ*hg'F+|@.> Yar.K8('aqC%T0΀?0kq"j~ieC8gĕR#alak$K3Z Qiy$N+0w_ɥ,sF(M]4ֳ 4wmk4Bu &-r ?kʆ A=  #9O‡Z(?tc?|Bfb|ұs(0 ;$pl~#?r\o$q6a[=/I>H %ዊ9HvFS oa(;é׀N;r)犍-`FWoNBn_ic`<|9=NiotJj?:;tA6^'9]!XD/ IM.VՕnܻڀvk\]7zDoc|< Kl怋8`ʻ~#@.O_`3%昒8ou|S/TQks뽪p}ܸݳū1vOR:&ߍ>pӘϓj%mv4ە=E`ϩ ȑMuo8?kgT@P%<\n4`hN 3ed<4^_xVWu|;cyG L}{wiwWr^1m:.\r%3Tow[٭L7j/ [ J`{)dojtV *:W 9x֮.!b>;czoF\(5&R;SogjC;~SBX~U+rZ #-B>s|'HGGǒMT_ª&υ3qyeIGzy^FڧRxa>?JF:GmOui^y5k4zOq3c;|X[dw\ >eN.5 ۮfLgs+y$j<'hҏ|d !w;޳tvWZ1쿞Sps>B7:uH3r-r);h/:|M>mLFs`vl?w4KDycQV`>__8$y삇Wsq#DBr$5&9F&s-ݏixΑy (nd{Asdh\Zƶl}rVғV89g>c8_`?~8N'\y.1oܹ>a8&(//~oÁ!ק_~~tG|s!G;hB+cDsFo&cG*~ ` |C$;>mjЩz!R?~.w/iz-І#He7d},4Nu_̹*r`k97Nyd ]A 9x2>S|ymrYևm<g7~6s&@_]JxۼC(o>Y`'7 t)ѻ=7{:=@cC;tw7X}8 /x\Lnja_.~ut9ZF1Mc*&hD]1vѻ!bHh^Sj.do^/诀^G|Q7D7<>nC>;A1yݚuxuy6se#_Id ?d9=Di0l3 ~# ƝIGծ{@>zAK?;4&7|䂍Gށ:6ܫ ͑>  nAs(xBw~i۟~n o|TbҍZ_pD<δ汾8l6G> p\̀x{@[;# <='% ;^p2/ۜ;Eؑx(+fC-Ѹm-Wn[{EƩ̵u~2IăbƴCxAgns y)g/+-FFMUvwky |X7L@eE'ؗazft:r?u,D߂94kТ+AGwC}DqSC'qs^^ӛ ;1v̿Fua\Ym6YG<|$DLu@ n|c?ascX_~|1M &vy.̇8!_β}>XTq$LyŲ  {XO?c|t> ;uO, FZ^m1lc?3`_-qQƂ5C礧CmGq >g [9 UsJOck_GmuIJ$_ flq+ƃyWAt<6mO+c_u_˯GԀE o˱;&~rf/Q\<>yӂP}eQRhsży-rXLӵN+.~W$d/1$Cso] SZCv}[X&}_ݵЛ7Pk.tl]W+\V)mr]K!G]>8a7A]cQs8:FJ}]{+EE5M_7-7]MF;|2F (oZ+u>5)<OFO 9۞Sk~H9FJesC[Xge,k2q X2 }Y;g!P@:ha ݑK@ruj~R#)-$;?hׁ,+ Yo!]kٯ|C;뤱3ُx IJ;~gNuX&ސJ[o!w|<#&Fjs _" Z ىcR~%Xi}*nxhwYۡp5yXVԋhd<y]a Gx$F">)';{'tv!2,9Nz-j[w6^}.繩Yq[gáuva>S5Ϩl19]c]5Y{Q.۟v<ړoVWc}s@_Ri_o6"`eɾ2WLCM? oV1[3}%:嘎a9u~\ẓ[89q<'M5Ӣb< cx?r7:@=.d1XY6t܆P}0uM.yaG;0gP\,ۡÜ/ֺ ))ܤoA3 |5a>;Zp_H 7\0?|Ѭhً!/m\Зk^Lkսhzas+f=G-_eB]~Eɳ.ZR hv:-@=v8LȌk? />ǗO矧wb$Lvj\r ~W2>SLOy\}?EӼ.`syfP]B.xIlʇ@sv ShMCֹSDŽm),M =\f9ao0;#8H`FC&݉xxj)k%״ 6MPj]cezW;?xxF]"?ޔ^t:xOgG y&,d;A9ɕN*s@̵gp.Ϸ2-Yy^o%0_=f@V޺=!۟ x]2Şj OFl1F |׼#[O h{\y!v]~1ÄU芲^~盖bY X\䥵}5=Wr>t7j<I@bȰ>9*}\^q.#V\Tgԅ㰇.rA_Df -36NZ<}p_t4+{`=`덏\g0q>)8- nH!+[xCWa\DԱvß 幒P_s} G]Ӌ'?mfK ȶg>C:c1q C~7U(Ѝ=c`?}6cI0CkhA qۘCP/v4ŝN<EE,$_SQM4M8\,V3v7^k1kry>`ʯゕ4ץgcTGߺ3C%xxƬscr96ȱ)GY` o\3=0ۜGxzI#ُ>P4f4vs܋G;/YreҮ/,uۃgya~kצ63 }舸:c\ }đ+Е"xKe^kzqxuS̺~FT5ϜFx:IZSb^R@GWa#ل-Bn4$r?YBc#'BF=8T_W+pX@>з=ac 'G=.1؍qΙZsك;M5pGGs',u\9H9s-tTЧ?|o~_˾|cbޣBʙ[חcF_h~Wt= g uy5FCOWIBP\ y3Ȕ&c~cGk xB5pOfC#GT]/U/oC\Lc{c'0Tt,U7~2+b^>Φԫvɖ]{P}c0`;?S u>h3b:׺qɄq37'l;@? +31q|?Wl}sztM}kqp_vh?x|>fX|u~jdUY~S5|^\f3oe}?^X@kWwÜ}x9OU|c~i|ڈgS:uWu];۵:\+.k[?ɾ(k#/ݼzq%<]KnPor@%djy6|حa*߃zݺ(+I&.@41T~cxdsἁ14!(}b# _M!k}'8?^aF:Y{٘.cOy$^sYЅf/Nr|?ⱷ1o"J/x#o"_%]bɐ䊋qg#,νC4l3降>xԞ]wߠ|ѦxN&vT7@Fvvx]h~}m<~|HmA>bramZf`‰{:2>Md~΅$~ +vz5jÅu_%4T=oGˇ?Æ~npZ#k!vh}!U BωdK$b7n@o఑8_޲_뻙p±`b񟵻8:>7W|v.*WG_(9yǯ\J~yEG5d'A4(?1N^ך.0Uչ?8 y%LTuVv9%`?EG՚dWڿ&>>_!zi<'PsF!ݾj*֋'S^9?(?= Nb,P'H62:P#4g65d{-?1r/(O&$ T(~!r1s~ӿ>'> ۀnxO*7`}4vͷŊ_0j:t>3 7?` ~?uBc8)G!m}v]*{_ 'ŏɟ>v!^ty8M>׀Q7x^Fy,z˘~Wvmr"#~Běq:a"K2U^jgqs~ ؾf~Fɀ.@ٗBIs]qQg@y䜛=b> %&OqE|ƄX9wI5M7x}{!!gt|5d9z: ?LC >x~9InX{lƂ~cBܜ/lM}\Gp0l-–x*g {. }@'`D6N>qc?GWP^{ q_s}6ZOyf{+WOVHg(,lU, ˯{5(>&a5b+9F)|G"Ewb>lwؾ=y"6gT T+V;C/cqAlVzwO:{|Ӊ8+{:G+&^gl5܈ ut'Y; hTn\vTLs[=Sc o:Q}am.'+ޣCn/c.ʛ-]ae}0m, 14nc_&cKظҼv4߮片̛_M.>--% 'sUJc߅.]ů@1~gtw5ĿMib,7PVz]cI޻XQt&]뷶?zv=qoLϳ_BmLZ} \,HOqyn7Oa<LծCum1O*W>ߐ3"Q^` ?z1:aF+aP"?/%` y(=k|I8!+'+^ZX[w(:XD:L!R~ިW]Wh~Gx 183cnR39#< z3 9l3z3:QWo1N}?>.?mǧCmk7@*5Ӽ"r9Wt sd߯ @̔G okٿk8ɫGͯaҹʱo˸𹳦'?~!Kr1mOr 0ܠlAŇUF_dfEAj#yx4}B/B͉12Wm E?HL<@W Y0,[v'{>+hƺ:_1/+Ri˙1ǟA:ڕQ(F-eAu,ވ&`j4?Ora⡅<LjWσ ũkq~?!Ak1v̛mrĠσ9iʎU;9\t5_(>_d*fQgTl O^3мU^@WUMUmtCe?vh/~'F^GlÈSq\wG?WNHeQ,ƻw!s}jl}dwK5kwףoskKN 4 qVru|Eu/< -X1c/4~>+Vs#x5$՜7u8dbbǚl2o8ql|BN?i 9FyGPw vxlc󿋉]} [1[sc$y 8kG2NQy8ˡvO;s db)Ywk- ůju|ȿRqk{K:@f{R`e"bn3O@wght W\Jƾ-o_*^ ̃t., ?^:.s:l-oMZSX GGlcx=y,zXl#1w[]֟?H}59+|7x#/ .:ٝaCS䪱!CǴ֏swΧ߾y 2n mvQc'߇mO>u/ĉ3sw^e^Ea2/NK^:ڷ!ŖLg\`azxbL1+dSϟ}pvzRfЍc079}zP|15\83( 2V9ukUM<_=0}vx.r1O6xH{ 0>̰t|} ~'%yL)qgs_w³"}_ycpaddӱt0.c?'7O tCm f>Ϙn4=Xd]7X>9v Pr)+㉟ۈ7Ѱ6d 35~ΛtF?a.X',̅zϷ?՜, *|b.πϱm|ԤpS#ÿv?c T?@Wك̅0~NuD,}:~7<@W +_9|/>c̡õMj~y"^q'=|Qƶ~͞}WvCx̧rݳ_?bY'!օ%rbȅ9`tjP/q5.ĉ̛_Mnzq] ^oR6[|v't@sk~j|K~Orq9S,Dž /Q$,s|zɮJwe^_#!OB,p |Oαo$ /l|ǯlx{Uы>x2b[CDn? C0TNCzm`6|·Qt1v>PetP.w7=h,AopaAq×% |n nw O~B]_)щJ zъߴ-21IR7[A$Gc('rv:Ϥ9AmlhxBW*> Wn0^=%8s:_t~آ:3r ~K:A6]n<Ǐ|/{]_ %pǵ?o}.c>;T69/hsπexB `m7-vg& 牡Bʋ`R m(~s}~s8t" M gJvy^#`75'b<[䰪kG?dEG/5E(^FXA# ι荾lv߼̇uG (MHsS PNKo<5~,XN)zMVݔ:7Ī7pj yssՍc3#GkgW4E"XWx!_S7ZL msVA s5+t:lwqccYҜZykQy%g-z< Igt<"\+?=\a 3_iUkOe]7ݺj%RL1G푑?(}X vĨ`9o|kN 3J:YXh;كů6.L_zjCȱ3Ǵ5?#xjtr {H'A@F}4а~\ 9_a/rª^.ٿ v[+,ی ]̻vM<쀿1AWx"XZ9UKa}rԠ+wPb=_`(E>wA}!d@yEZlwHyU7+9 x8x[cǂ< tvXmfC`+/I'4 :t3T"XsfF/w$}^uKTPc5}f=`4L:E5(q'v8|;{:'[It:lw=.ƼX[yBskٮE啘V-q'\˵76GW_쁘.W'1WX'| ʂ<%,| .Fx~`X,5dKGsajW[,ˆ7`cRj&O:}uXB/ zknw}fU<:'>ɘiJ612n Id^>(Gkcco111nЇشS~<Z8F-Uh@:9ULsq&cܾC냘[ǩl"g4ƴ1*ߠ\S1ɷ!yU|>|J5p>5c#t{7GMso&( b61}~ dǺS# 50tGߏj9;g7FcF™0 J<\1\E9*ORp^ĩ4lSϱn)I/(c%qUק5pvYރYƼ6N!2G׸#Nsȍ8?G90=ۓ_9{.>x_Yvfr=tN9N@CvCEQs8΁0NN$MrM^#;7p<2uMd=Q8' y(`p~93l5x"3Z/>|7j>o*KzQb=?!tYǥLo5מR/d{qߍhkWptwgjv\yݟȁ6vy=m|- Z-{k[ˊZ˵- R,=fjV:` ǜ썧S^ ?NDγa%n^~+gRƪ5f|f  _1mv?5 ;h>)5_8R1 g<#Kq{_s~2j8U&$.P+Pdz\/@đ]MC,4|@REr=_ڄq=2;CS'HВ.|o1cMȄG5gV62ݤCFCgƹ#dž0xU vm:ƛ$%MLQTb<؟+&{Xw&# q|o˱,{hu~A>qCqR<~f>ǖ5c-x~ ɗ^৳h|PL: ;QA1Z6?LX`ؑGG-btG< >et)Gu1i1X{gmϦgҧ^lJ{#7gt8Z?8F-7>5\p= wqzFʫ~~Ȝw3̀\75JI$X;/ 'O^վ"":^7@aV<;#qC>s@ⷨsg 㜗v:AM^ٮѹ`6L;Ox\'--sױ8G/ӹWhy1~:d\a׭xc =] lBZ9{9DW>ka7=^<xm[t/sd޸9W=+7X*&ؔ`Zjyc,w#·?,8AF9F~i 6Ec>(4d6 I2ݓ1>M~a?ˆKP!k x1FG.50>?dX$Ԝb8`??O[|)s~Rϝή1hCnb.@7|.A$?N?ry˦ hqg|H<{xZMY?rf1/Uc:Da d%G L°u Er|EoAqW%tO3N'][;V#JoU&'(6in06. տ .o^(,7yGѣ4RP{+f̗3: Mm<7!9ZJX|q@<`6WG6PVp>wci}0jDϱ/IUǝ=537s~F5U 0"Htr n`Smъ> 딎 3>Ɯُ058W<ijcj~z 6JQ(ȱ 68yS,o8Cq+9lI$)A%&x[sMnZ}Fͦ`CN7As%G+Bxw9 ܗABd:׆@\O P zy֠yU" Ḭc)$?Ϸ$%w*: 9O' ޕ{`7j ?e`[Btj&_]tTw;EwB4"'Tr&g;3QKPku0t܇] ͫaʣ {`'Tv,5Y/羱rZ Hv&WqNuԇv,늹7B9/G^:ۋ=C\DN\ 8}UzL'eQj7٪WWjgٯDZyX]L䛹<~]z\ՒRd)w%V_6m&{dg}Ř7Xo|М;yZdxIo9"YF>8̀Y!Mc.{޸ }̮FOzlSe+\b)^3fسl|ͥk{QO EngL<қO̴ba7 yvF䧤|+f b-^~-&DίcAEVޚ˸6-]Cd5QWd#1y° хޜ۠O눅9=5})a ]'s8==]W6D DH:{\/ϼ5t])GL7S]`ޫ5޲(7dXwm]S̆q c(Y&}tn5ח쿮7'RX"lX A CJݟz9wA>o׹ZkD?!)]KPeq\lfҭ{㬫3x?|z'4|qi]#f C2ٯ:w2! s)|(ڳO?6{z.NW}sL8l_0Qw#?`6Ă]ՇL!)wzFass)ωI.EX>B0y3Z7kg`~~0?Q9tJ>WE'XLO O,ךo@a(i:##q{lq>=0o[?<#anu02|ǿaҷaA 2GI 47m N';ɂG6< XXm:.O9ğ_H9ǘb5J&9.c;~^nY퇊7f)y-413wlVlFfC^Yp(ǝQǺvK\սã'R6_'LH:Wi"+KˇLj<e.F ۙlSWgpRWkp&N `룃|d;lJj[:-vA~1 3 *jd#o<|z_b6Ɲ]n\xx=hŽke'nts:ǽ\Xiݘ8'77"N `Ny)^̬aD7k&8-ZᙨF'kOҘJ2Ro 邏l`o ':{.Q7(֙xp6Hr 3on-:ۜ{FSLw; EzXCs,:/"LCFmpn ^EC=$wQɣَlI`ȃ"}1pCxCxŶ 5+;CMhN#Q$Rᐨq79*1gwslSE |a>pAy0l9WP0^g^ |Zx,yVC<%r?C6U}F d:w}B <\cI訖_o!(v8\>_@L6a fŽ`:!Ozs?*(x *n0 zu5e?oUḲk7m{mDȨNz ۣvoBĈ<L8dle#ЈC؅-Q_ *W?C^ Y!H5s+T9iΖc"ܳVoMLnZTw=>::iEj^c.vk"d{->Or=LíJ? sA?aϟQ#|1juRw|vy 7t}-{mZ^8 !gky!˄7#uxwaqkpbXC?3.DJ3Zf]8VZ uFȨz_HZC-r8>3c__KnxdjkiIW:5s]?_2(/^CἛ<'l9WoӾ6+F:"z_ ֟Ki5/U,L}2Ȳb= ymk2yO_ >f_?SŪ\FN;N'!dFtv ѩ:pGgƖ9F|7>ˊ9LvS{`i‹yw$ܱmuVf[*[]9]{7rxw؋Fd{&'Z +hxuMƨ9GAV^gOv'-couW-Pm1~$F ;硇}gg:;=Ȫ[7tuWs.z;_!mW'L: dOPtv5%x2e͓z04#7B06jix38 M[/ oec1f]-<|qMxWIy81YxsbC!u @g?>) d 8?ML_~5-~~9?\[0]PFsZnk S+1)۫5:1F}##|=ycjO9z.qV7DtlE}yScٟP6L@2"w؝Z_Ž[|?yUCE+~G $= $fʦbcgqђsU&>( aZ>aկø+sּVgi͒+X?Zx <9>hq֗mwɺpOe[# C lC4&깰<2V C?ٝ|<MxUB{ahvNOx*lw}>1jSp[ 9qC'`}ϱ 邿(qɔ0NCGF| s-?w<w~?p'Wcѿ;OBOU=6.V Aӿ!k6F=]y'\O{!lN0<>9y`#+9M>T b=aQ@ο@En4}(@%{h'<85|3%@7cܐِ/{c'^dZ]Qdbn |0h|a 5k<-P$:w4JlO 8]Oya^7A+lq?O abdˏ?ѐq"4 @hƓfPFv1a&4AgPy|$[0B^h+k,o}])ߟB.;G4lq Nuc-/XvlazrO@<\ Nu)rL~򝜟eH5l˹c R"Hy@Ua Îa ^=?|j. hO&%c\iN0_TQ Ε 9"dϻ3\d.CgڷuL2tXn'켺|XxF8ֹ x1ZugeO+G Pfc`yW5a<p`<S/Qo_bN) 0:jƤ<@vѰ !p^S6?Y -eG"c[Oq͒~T>lɇu![!7rcV+ϨM\9A\[a '"0 Z؃ɗamvqgw[ Lsr̼G Y F7p^O*qU =\O*wO28vk)YWG$qazЅOG_\Gh ;✅"9aW7sk^-Wyg1Tyc>=Gc:q-'#cMnͱxz.j[{T} Sxvܰ->{]|20L|+pѳ>QƘ_UlXf`08_*tw,P ğ|=:auιNwa;&?nHq7k#{ֹȏ'h<_f 7jӷ?۟4c$Tްם U2 z#M :cOdtnَy8:}?Il]xvU_dw_ټ+V9 (ۘ ql4cޜgq'2\\ZKɆBd$<q1ywQ}an^Ad'*=Er|ēP ˿3uBV:ݠhȇ>_߈t`ʨOr.qy^mT~|"pmIcicyFS-?L?<}o%:U|(|R  ac0> ߿+ PO_c"Wk??c Fx~i$A%f[OXNsC>>O@֬: 8|&;ENk]=<+zpލ9ƍ mfj#炾Yk}\{;fQ5:ջ+GO&ډQɧ&?crL>:>oy 6mh= /0Cs7ky94K$2ps;t |f;Elб.tPLqꢘgd*͍)V++9P}|tsݔקTX+8B<1mlC-3\zW(a Əsfp{h}@&}Fsx+L1à(m{aʝ#XM Ƶpm\/bQdcvcKCw^kc׬o[#癇VkG5&3|=2]@v<m¬[[땋i7DCπb|iA>IO21g=i⣟!T;@25@Vs?Xksbtgvz?S|6ujX( h=:>!'@#ܭBQϾe8~B(g. 9Y:xpϳ#'|~_۷雵ӟO^R~yf/7j(V4JX-59R>EV͛_54ěgi "v5G5_1?c X7kQ& +Sκ,~Ў1(*aYo#NqejzTCؐb\1*dW9tPc#+9h3|$!O&t?dM 4%!u?ͤ y-v416b>|1x0y?&(]O4'2?4 'ƿ"iM2~żӴ.W0ZC>U\n#9T^PIgWcy=9|#mF/^m!Nhc\%Xv泉y|7]g8@O!8|;ce×x',yq,ȧ"Űt xO[X} ?krn^ =j p3\3d؇ӼL,fUenа#ŋ@|嫜=vpœskFkf3']+%xWכ7hWEKJ#\1 7sFSn=}_&;5E 6vLo[xO~r-c夓lٍRdyv)iV?|D:4Mu.?3>LPݵ|i d@] 9#5:h=V9WLO{]0 ,q z{Ӣ#ynmΨb) :΁T ݄l o-wU2'/j[>ng+Ʊ(~:@6fݒACxΛ<ӁR㠯ZW:|k#s\i#Q00=d7GoVt:l2O1П`g66615Y]LL=n M7w1N fE؊籖ȉ =*GR?k16kxv=C\Lx(X `,v>}| /hfzXb;s~.n;>9¦󽋷]4SN lſ y'lB6˟gv]807,+?I>zRIh|>|幦sM|׭pIm @=V&Wr ۀFbskz1Z}g1a2150_Nx5<E6j̊rVhk4e KI+V' 6WurGq8c3~mc-!7c1l\rY'1PbzL=d A}kq!>3Si1?lF>nҰ>}`o}3!)ð~TuVm# k$҃p]^qvd%yXts͕Ϝo3 ? EaJ"H"hs7,%['B6t3eL7 YG!qn\Nc-sXc}_}S=Gk8Eo$Fg5{8sƇCFpcS㼧EK1ڎhoR >N1\$*|0j 霷pW_5_Dl;1GqsN>ԁסNQuV$j-aFs_8r3Ko-} 'o#(az-@~/;ȵ E._Q^|9wbO16wqS[=^ |Zㄪ;#:jn=sfUUlLs#~ð5_ ~ȹmm#{׵Wxf+G sEB7/֫'x\仜 "-9jsoyo; g+Ǧ;_ ##쎛NâR]MW&~uo"lWu~>j>GGs\bVL5^W[:~.ֲ&7R9x[rx>vuzܬeAY7p:J^WrGuzn|X~MsUL.Q𺁺7&֨k0Ŵ]&A~]AG-hQA%F|>Vs|CfɄݞikɈa`xC ~p||{/NY9&1?~2[HdF>poxϖN0ЗPBgF|t=Atξ&@O@|V>lw]_X6c8֍C0"ޡ\w~ %aJ~û^usoq{ 6ɦ=b E~&3(㯺#t}`g=F_5A;|m8 _!+:trX?w@C7qkօWlKN3Ǿ0y/ndXR,iY},2u^d'ԃ~؍>{~3Ƈ8y~a3jac ֔:^s݇E4^}ҟ^x Pp/pdW#=9,p찭k1F 珌C`>"?]`{m,KIq_Mzl}w|u9d.JV}f=ʩ|nz QDW-NngxTrOFgbv췂{R Cp^7ttkHyb[;ؚSݟȆ&Q |hj(YgR 焈Ƥ.byl{ xڿمrls5xa߉yGg¦#n lwx7a/9N's36sXzh^._d\Ʌ]v4C_μKL6F5{~/ÝpkF W쐧t5$bc4Ϥc-<|>?ɗ!@{>NFoe+Dz8ւx)x-5,te7=5edϲMd?>b1f[}xܠPe6y!cȬMj}~ii ABgomVw%Z{; +d`c{ıƷO:8՞Rf1Z|e|d$>kԗ hAx=RLyw mx|^L y Zu>dK0Z<).s"!4?C\'q̮!:J6H,@!m's𱭔:FW_C2/ǯC/3lɳF.)N"4q^9F0%(OAcDK{{pC-18L<*󄡎gn?;1?gMNb`To\wL3pv|NQ,oOנ|n-5]`'(>Yj{_@]'<8[fa#?wyO]<Qƴ tx/Xh<=kZb}TX`%~&W6#x:TVSj[?u?C{3WNvv~Eh}𡛶.aڟ&x^.y99~?jMd#zFԡ<‡~kZ`}v\3QFgd@{FQevѺw,?\21n $~r?mf{<=tE]Bs8hτ_XPmcfc|'/13*?^Fw{,劆rL|kʾDFidcuoi%GdKx?b=3e̓_2 }#|0z@yO|?B_.<ʂbػQN7oʣ/9({FC] %EK\}x=ahw\R};XW@GOX~i^9^_Wo^L5V/G* lF-6gB}g^^G| ^5/;8N/fjw+qh~3Bn]uƃɶo&w0F|'3yvՑ}9vלF'&nu.W@gyCtf sCȭ?t5bUj#=O}?a&r Ok.sn=~5=aU!*umޜC8忉-|>2&C%-I[sK}`Cѷ=JscgLd\j2Owƪ͗ 2|z\X:jb7n49Av>eG=źZרmW{7uī5f}j &s"q=t7aH˗zF@\0K)`6qmxF<6q8Ŵ|"L7/eBǛGEgD;qN]Qm c5|TCڻX$+3jZ2C> ;WJ=qn0`ࠌzX+Xz.b-TOXF7uj c"|lKX9ɍz_ł9_o-Hk7b2S&j~ёxO&?tw!3X_*NC&͗_A7yn7;kGj0y AH+S\f1DG؂@S 9.ɳ9Au1 * X@r 6zn{@J`"* j@7h/ s 5_Hqk7TN3us }{4iyLN15P0 zw Pn ܫ@ js>SüoG/_8!/~`xP*!:h:wX`#?+W"V5Sb>3B^˨ D ) 8NowZ¬8HOp5(rN%C6c|ܲmS8sӼ+9= Zyɪ1z@.[asn:8@CԊoǹ_!gpqؤaE g`Pp.Ácm,eFYE>`k`'tv,갵\T@Yٷt]ڵϹt1NM &$x==3!<^kfy 5J!_LSWn[1)PHg'!plP 0$6>?]\9rlKWN֬O[ qa+сxEہ5^ҹ?w#NЅjanPz-r 6҅̚_!$x!tC\! m"f[3/3_qI5{qsCj51u$̃LJs8b8:Fcp u9q0}}bL1VxUbve:YyBGb:yH{/d:Fs}L<mpldn8t2R 1^? S'}Mx69Yb>~TS{򹫁f|f7IǏx B }8A<>>lTc$]k x o lB' BF4$~#P`i[0|u;V\D_K:7g;qyޣVfLgrWlWd~8m_j׿Λu~4ާ˜u|qvਵR̗Ƴ9,Q4iD Oǡ:71Wk]gfثh &Cׅ8dhm8sW}[]ǵ^xE1$00'Ïck(t{$&;gnhG_yQP,2R=DIQxo_ >ȁy=Nï -{nb}KcVy_@8&g<Ӄ]/,hk\wQ|x`aE:0]<.7tͷ<1uT ?C"gZT]ؑ/d~o%D?aky9ju:\r6))/_c`pS ^2SnX(V>W l+2 g1#R7+#x#N.ׁV`oXRBLêesɭO ymځ\5l7gFXj\ 4F6${?vj'|"I\ꏱzWgKۀG_@ .Vu%N*֓iǒu~|!?+c#ZxOPIf]8tJʞ}Ʋ9|~<гA~7k.7?GDwx0y1a)C /Ȯ=(%èIk:Z)؏`f@p7vށ9Γ9dd)]PӹPqƣ59tG>jy /P*u|_`ϬU~CIZT;.os 8oS^'[68C%xD+z5̐ 5gx\=OF0۸3o`rW>k|Z*s N11x,KA!_P#2,O>Cn^~g,>z>. f&w A1JeXڜGo]^L̗.v{< j~֭ l o'ߝp>~(;(yg9 Yb<.o7g~mqdB1p]Su!b9T﫽\p~n@Sl 7pܭ*vjU՝|^pckYM>$F9ޚZ7pn\1'M|MG>T:P~?nC7pyB17ǀ;_? vt˙e:ߍ ȯtVӒ$Ls10dlC| h>uګs/=zW:9W鰶Oz#0FtB^qPrBvھkrxCӕN {Q}Ikg1/Lcc0nՊ5f5ЩD$3}sk/c/pXFl}䏐Oj%8TPUb]ٔt>^LJu|.C<,gAd~}4ϬB oQ@s|0~[O ހ?vu=QyO9j6s"9o ;#݈Fny:'?Qǹ|~ƺoa|;CHkr-KN|Lpx7~2l !QsT[ًm;v Soad`9h+ڇ´ۀ?(Nvt?]{9`t15B㟁1?7~ ²m_8<9S.o|x#y4;|F:c_vuƜy"_xB2:_/oW\S W ^P4|*O2 _~A_G?gx &n@F}jO>np?}?>3c AH3c:Cq 11h||84ʆq:Hy rM8)(?r11F;VasݙįdZy AEq>i IvEK8 4:#nG‘ι:Ubs^?gi+rQkPȩM(u$0dW]pԃtg'?REٳS̷R_v.nNmKaz `'c )~K t~2=764,>!:Kn ]8 ^wBl ]ĻQ/{>8_ߎ.[!4~>~`C*Z/"ޙ~?Gb>s~w][Kwy$sGzohN{_a@_S*ȷI_w& ބwݠ{gs|%/{.Aޣ:ff;n?ۘ~_&c-xR?ǣ=/7y #2LBbG6^?ӷoV&6bgaQHYgCihy! -hSݺ.;QHO'Śit=7$A D| UX$'G۠ iL ~I׈LznsZ/9+Ɉ[Rcb<)if|Q·Z選dk =0t11EQ~'y3:?g7LgNJoBsDw_U*z9sZC%s2oXW!qaXG/g3iG$hsKY GW8N~PU`7p]UWWsjHx!Oxv)&j~tQ/.ym osU>+nlv{W~GWV̲ǛU.x/њnxmNԏ⹐da6ԀZʥ7x\ڗ•v?JO&u=fH~z &0縇䚟q少neeE6uK y/)tONvcbf yv.[Qf8_j<݇E<;28J E9tQǎUxt{gFiwŝ݉Ey]]Ŗd}7v牄6|d%6:?ѱ:6X 7Qt6ct_sÁb' ?}kݎ]iXrqf!;5NL D=7>瓰<3)ruU]. *2L\]䇾s O)wazgC4V ؒP0',WnQl'oFl?Fy$ =t ˂S;pV0֊̗b3x c ޫʨc=:ևxnVdmQngD}b{O?ɣ>s)#P쫎ckMH~=Y`Wo,x&4u9].&U[t48[_.Н_d9ftxPluM4wBN.lhQy0&&B8 r 0~]<$h|1dhU|MSƺdbϝc&.8dՔU9X`qpþ=ՙSô (}#"5&:y" vc)(wcAɀdЛ :;l#jB'l I+*ǧ|O ^nJ`nLO|tOS.J*>ʳxU9y.̯f_ZY_7U?'poJfNg@w?;_W#Z'8[TqqL\}[k\dyW^=.^UW}1@cv9 DzŇW)4ck@]WgKI޵]Ț59ƇMWpk _վVG[_x~7p 5ZhNow F>:gLτ;?5ދИ5.b'vs_s6^u0e_L쎏 4ssiV`?.'Xjg?zX}C5c_6U~4?TLO6?ī4y[5OoX}e`{F;uac[&ȝ>CqʿMDۈwk~/|sQ]Q˓Q;_Z/W_ߑ[yG_gyr.C![9u=sEdhTohP2: KSuuC*ӺE\z>xp;{ρ1Ylo?AP6uϺA-,>0P@5 cNh?0ϦW?~ηӏ3;bK]T_6/&B]Ge6M`["7f >\/0o@Z1K*c,ClPn֍2m}!Ú;Ħ1 *3z7ܣ5N|xUߛkRo竃c合=pPθ*t5g;9}?xlvy0m :ηVnx/:LܫRhanP<9#*QXP+:_ͳ:5X0Sj.`3l/NOXv_秹x6b> Zه]\PR]*n^Eۆ2 ~1<>7.sZ]aQvO;xowsv{KSU}U2XW:5=/=ck.[r6jr|9;j{U6e{UHuYJ*ZΩ~Wv00{D굃Jny<ZP9vRWA@}wr+`l8bDCx4C6/2 OS;1owZ{D9tP}5 ,׋|&feF#Cgۃ#_Șٛ'sB؞PV ;+N/ơP>r܃}#@Ϯ E[> >xhˡ>b$;X#6x!svu}#*w!>C]cgΧowOBp|ts3Vl9rlн%`k&%to45 #Jz`}`ڀ7xtKuj؜7LIS*?$?nx)Ρ1>Zy6|=αngQsѸR55&[`Ei<^@s&<y =I@3Ck[y!El3' P5=h OعƸƇ[3v;#w5D(#㟡 1H͉}sqǕNmOI3.gϴo(`2=x^|(A+ VWD\O2d&JvWh'_a| =9oa; _R1ƚUW{cG&>vXQǑew{|;*.WVIz^9q1m-NvADTi| Z# erk[,溒sHO 'J@'ߺc]޷gO8̧Gx͎Wc +aϖPKyljxmnxWtlw젃hBX]gu.ud5JO/1ae+sفh _ p)=syǜ7,'s@NN9~ĪfYo 6L`{*3vX!_9)]!c&O_ƾ9kۧ@_FהoN>_%Mu-|XrMw2p"u d<a0Y87ė(&_jG?_}>(q_cr8&13%'ΆӞJٛ} w ;T~*"59V9ER3qk]?!1J ht>U~(Qhk den [v1G΃>axDuy0cԞpwl;%y[Mx&#NQu ?_˭+%/teގ&>܁dq؟bu=sV=O ~٨9Z ѝ|bqΎ熎9I05x 939g@5" {uV__a1s.\ypy[z\ _?}!O`θ$r!8 Ay͞># ځчK\/pEO@~uU#[} jn٬jUQ+*)uWuuKZ {ҩ s7'ӝў]2l WT}Co~|?{:.5ܠ+׭^-`s2W-snL/ Ց9|> y69]>~*=ÅϏUqLޕlq /?_>8xKMܭkς9i~%[پ;K6<';n;׮jۮ[ծjN]I?bl.rmt+xk1H\C~UU>+ wv*kvl 3ǻ B#Ka, V?졹7 kGpaøl񦝣wKFg\L= r0{\(.ws[W*}A:׹8[ H OV?nV_0b^:/#-!P&S|j.5>)|+Կ 7hzxCd69_ e7\Ϝ:Ď 1ݖcAKfIG#c@]o0 fu?؍}v; Nʣ+'Š.:x`]1t1g.1qLae !>| =BG>,L4օbmll և< ]@>L5p& G78Lf{73ujv<'Rc6#q0g0'\^)c}%;ߤ1A @yDϹ)lv\C1c%:1ɳ=l?֐ 2?Bl3u:jbG '%<^䋑kIko60ɰ``pɝmdE|~s=\eyW,Zbi>%$y'hs="^4V9cA/c~u{c{{zn%)GN F<&ws75xuzW}Fw=t=>o*~H)8 [zo3'w|m:ԵyK}@:?tIu`:7< Q>D΋%>z^G%ѫ:_Fߓ>X'鹉2{cvG\VR|\8AJ?m5Akxoh/*gx6oF>A?u/?'I㾣;`g\O*S7W>I>?kRlsךkrER;\vX?E*1ׇ4-(нs9Sbilq ed w:/[i-#:=r98Ona}>}뿬>_}7o ؀"_ K拘;s H&4pygz[;XK=">Zf*̞}秞SG??h~+y#`cUN1_1Fw'": `1\&f'[\Aıw:Jh 2!qry\?'Ը>iJ |r\ԩI$ttZl&IDAT*["=\c2Yqnrx)Z DŽ&Sq,Ě %v2  Xu*=#w8LJ za82UM԰ HٿS:mi^vᓠi~j'X @7[oV aTuP]ӭu x+P_# ] p  ef蜮_fFɩUsqeN47zV*;:pm{ľ1ߏ `~5Wʾv Fvux_]+,Ε]KQn>W찝r+v%K@SEλWurae;rw\5_ EJɀE\[ިʙ]oNs.Wu**ܜ;;MijyK~7߲׍soQ_{(~)&́9`]| _#~Ju H#Q8GA[q]~ 2GCAu.}li)Wօp-wu_]|-rZ/K> L-yV?yq9ҏ%% 5ΠF᭨sC~qV@_džsy:+tu[tY0UooZ`ͶBLrs#|^ދ~SʼV{kH$0p}x|ߨf?{.<`վ⳽ޅB{uSslt.N%)j^bMNc1t`N@W`V¶S GB tC @ ߤa^50dhG)ϑ#1A~Ȋo.#ZW1ع)RP5 zd,ÌCd1}oecWcRc3>I T} _5 n9(T~G}|zyuRǟ0#o:go苺#[2ym5P܇E7jgm kw~ۂ/2Cj×'<1H$sM$9Aי).`B \~d8&jw_XVM#h(wu!䷀oADH=!@?9WiX#}דIyWsv<_w&,>[R'EQGg~Ȅa+T{? J73n+I_f/Z\(#~?p]GA~ﶿ>@@j/? { W%~#=Ao Jh-dDzi8S^g9طƪε1.3=')ǘQ%v@8v=G~e#i#~mO'o @&u\]<'MA8VA0>v{%t1:̣IqMPX>;o 0D;TwU*5 kaL4vq]0)㑇PTn67JG@ƚJE|~p΅G]PQ1Hx]O#qqZ8(玀:j^{<'́'H7#`֊WW0v% ^.<=17Dm/K;Jǿw/Pd/(%|7s 7ئ;"xϢORT]5<V๊tOtWdeom'y_AA?|oO$rc1+/nuG15TzΤYu`N y~@N+7ܸ$+w 58F] ~Mq}^|_;/s^Q?/.0̗0cވiy@?0j e1 ̏J/#}+ -itsN_γ>ot9ğ\k<97v׆ָ+:zYsr ^*o?|}e g1F kZm'eX&otQ/Z;~j'~G<# ~=D'vc\5+U%OL-s1p3lr@t OgoX&C ",CnfcW^zrj{/nP](<[ݢ_sCUStWs_FnGd5}8/f vbGMRleg~WXʷE; d~"@}%uXRy0Uʔ2feSok (B@{rxz8nC.>fo6r=M#Ĉ ";di}a΢_usY 8dW$ub9}: F< goP.l:a ƕh]r7OT&@#U9_O䙅^vS#bظkO6<-=2) riU?Hu1["X 5:rfF>䂍 R{ѵpu Cq p |:iN2-xٞR1mRE:& g W ~w/ 3Ǿ6p[K9}F I P[Ð}<!䌘r0.sHt&ԩzE\#M>~*Lu,IGL P8jkm}ƈLA(;q'@x 3w1R O1|`{-PxC|k?y306'oç<=S'9t~ a\%mL#N`Z/ǿ/Rmݥܠ{ f_>v>nFǧ/96g<7ϯE-] 5->犎c{ 3='ꁐ9y ["d޵ zt}FȏfWW-t:^O݀.` y$@iKWtGL|M{ l\r~/@=g25OO 8G:tu!LȋhJ0ΏuVZ W pSG>8jcNMGUW\= >>Owp.&rex0[&< xM@c^Mkdvs+5a\_X[y*Rt,w/u@q|/ #`whP-[tP=d@1 ?t?'tN]>y^쳜ggw  :l_ڙo1)s*4^->ܧ ܘs^D]'գ,Xݵ]T1ߍE\G\cq@e:gH8C?,ծ\upSnNvTMu{8x :} (߷r9n#jj 'u95>i;xt>ar&fbɸ|v{$3u=>lw{̪xŤN:F>ms=R+o1!sѳʯ¯S2V &"8s^䢀|\WQ{d.w-y2Z2QzNqO71|Ys!@5̗+}7KUɘ6LCz<ȫX{̡e@l9:sywur6r>]{vyүFr{,QSDž#^|hX#P;d0n1X.g3mg 8mCA6-'?N]G^e@eXe|/P7ưV~Rh풬&a]%#FY,6ż}2knD ` 17[)# Aǯ!߷&߀냰&m&2#n|׸:FId5R9H5:޳sxh:Wqjns|2Z[C 42=V>}xms8/B=XGrH~'t~[y5}~9~RL1M70_:+j6WycIt1&`6#>9gGM~**ϋ_ਉ>[{GD1ҽrn[iqZ .[ڟ04xF*߀\t}4G͋90r7Wy^O޹ގ\!b'{ 8D P)!ݩ{^CW0ݶ 1KtZ<]BUE7wWnļ'5j09} >$\GzO) @,U:`#e3k}lX#6qV|3k ̹-|?HI#oTjg㾞HVÝ]~w:kV!kKI_\耤!vNhA]7Jrހ;r/_\}wn,#u_~MǟA?:OVUBZkg)HQ!cXdn?8gZA"|AQCG nf+?;{.q=繌|?ʃDWCI>H@~ɋ^z@}g;̆2ZYo|YA țy-&PasoEW@0q'{8@K*` qu1u$w#;g?z܀!J 9Mq$>tGy"#h@K&bOZk9'G>AĒ-c :ͧ,ckxE\zg{{ik6 r#+XyBcD~.9_!>\8c Yǚ/]\`=bD^C%60ݸ,O׋_H~`-@k-k=#&\x%a7"DVK>9&yw?Cq%8A?ek=Ηȡ6mEխx+s~V4.^y9l7>Tn)Ÿ8v1'jrkױz8ytH_{`p_\O~럋#ٻ{w@VM{'zvu hr|RG@wyM7`՚t;xU cۡE<=g,TEkߗq;ӹ?җ ;Ň˄g5PQ2& ls}'T g=ΐͧ߱%mU3^ghk衽i}/\ُ2;t\e[9HO1wɀA1N~yWuZf۫W@vHud{`oQwcĀ2 kJru7g-z'2B+}=CcgL6~w:l9TIP<kyL@_śذO!l^d\w3>}X'6A&uA37`cߐY4Qwk= kU8uTmw'E;5#8O7U?#~%980Og|EU ?z5O{m@Rs9s,1Y޿aHjhuEat=JD+>0Cckl'E j,WgBaCk4n (CYOTA~'#(V%Y>xpkm{J 9wĘ`!we9XOhN+І8:VؽUf܍N9.aG[?׎㩍 υOtnϊ~.c{7>/rFΉVqwts#np;r◰2IWPݎ yſ1dmp0t<@|1nW]`[k`5WI WY;:a~l>u:xyts/svh ώ a6cI<{#zRvط;pPJ'r:[sWv >7Ee\x1ɗHyݾ8fN=kb#]t)o/緶{)f[޼J)5c쪸nt5dcsv+P;6>ǀ^U7܂ň9sY{9y_]'[CǨ}!6dqvOF> C|4;#DV#nֈ㧟٩̛4e7ӿQɴ`G,~&H^sl6hy^c##c{+y]ʆcKT~f'>_PTIC]7{u0G2xl~::sw2>'_Lcӎ]~ﲃQ)<*aKOǨw\#}yH; ;+ky 4hȔ1ogy%xu"LjQaD뾘7X)GN,/X&7DWAf'h 6MN !ܟ*prkAHN/v_QߣRK)'TޭH["l;\Gy@w=_p S<Ct*m 1yyq¼ql: ^[ثg^D̕uN=O">f_e);@䱲cxAs4[<<<z~ /ERO$(zi_}:wgl:Mߥxv4>IAx4R{h yYO=Ut@"ON`t~;< ?]Pukav0Vt0d(h)(,\쒯\/ qt~2**3ӗׯQ|9 }%GM&%s~ O# h `:2hkdjiE^/Pfw_Bl"ǫ'{Ľs[>0x؃.0}s 7J'~πKIYrNxo|5H!őy>C078J+d.|]Qj;%?TI&@Ǿh҄'Yq%/Ȍ= L{ SQWXކGǮpo_-@ո/v6*cBwi0Yb&% RFUGk#&ek`Ǖ7fcC?x \qp;p״V @:$6+rO+nl۵cP`NO3]7 o!!C?uv{n߭D͊co0/r<_0;N\v cڬ2]g O`sS.}V7[Ok;V~4QmYݟAq;ߌZv>B]+Vv=Aa\s$N7gqA14qЭi?y( WcU6;u@e5;]uuq 8=B{m܄_@*T:b_'F.7̹-[bjmͯ#j~b>r-׷uu1ߊkh@}Nuϫ<|=vjv |c3r\Nl㩏ovvm[=|'l6)= j(xcn?aC8~2?M,[1xGԗFɯH̕<'=Z# tKڈ.>V| Pлs -& 0vlrŨ2be#w: rz~2ol S'{Y h^c8\qsn9qe9.̇D}Wqh~|;yry!#Z M8_0mo{sAkYǻBPFbR$ GYͧ83=n_b`7qm%/\u?5ׯcÕXS*x8'F=2k`C/ޟS ,l/~AKk`-s%y]}3I} _=kw@ ns&B COkqsIu**v#$T Cc~w\n:'@Zwr0%Tӯ<ȮbN^M9&:j8ԍ{kIgɜPN7U` v+j9vccIt0j^-b`V󢟑9, YeLXĘqg־a_])W>ڒˌo1e|9>@S'Z;<ԚA˝8 cEͽ鸹3"cgHxS̼_@H,a9 {B|>=1QݶM,Yr_x<ڳ5S%svSb9&Ď&:W Gh_BeWG&Cޮ.Go4ir:3o=> 6.qQ|-ב|NޔN0;BF" I>oObl7|Àu?b~*wq+l1s80Yx09>a(-^ cl(W~rMRrW>`N=2¨ 6sQat~;Kl|Цk`|ú531逗],/|&#3y70pG;rh_Q`*㩰):C^/CxaFeÊSOO0O)fcr5ӷV!:S:]M_c|L$7$֛mc^䴩J ->]#xˀX0r]ξ-U-k-W6i@;Ca\3>Qu2[ vj`ʍм+'֮­_>uǝ6.<kㄺ xht?_w_b`jdLB> y@gKlex(boKS]gZ-I̓6*P~q7߫_~z)<y.T|3|ȼEaM׵q~`Q-G9>@|V2}41iAGs}D~~kT/p(1ob/p{vQq~γIwQ~ kJ ~K 1M6xzz!՛sduN?-Zy Zujd9weL5-~V~ϪKRjs1t_5u\9rG9tϧKutt R?=Q#3VmWqR)g .e|ӵ7t;R-KS_8"u-s5˔Q/rW ۯ\kt="С6~~5Psl\Gc<T;i! k|b\@1sVc3·UD/ n_هK7^s|պo3 -h\A].mQ31/SX#A|G튟 ]2AaNmϗo7ܡYH?c%9F-L9H`uJi]_+đǢ1>jHDo~g} sNsb;\Wp0h}4qC=/Gu?>.x-1tf?PCyEI1l# Ts;i)ɫkO?OzuMC >cq㞍gC}_A>x 3c?C@}ec׵ն6v=|=v&j<ӏl5R;E1!;~ErQʞ7 V~n{1^K *+8{%+~qr*ƓbU]'N:]]U|'{9ձ|Vdס˻^;)Tk8-k㿵con,T/>b{lE[ '?KenXbtEkj`y*$T#88~b?7 <9nH:g^5u(s+FTs7nd-<#Wvq:h{`}|g`k}4Fvs^{ e4^FݧGwzU<{B .qN~e0;or.yJpoT^upbɇ:;{ODST@5Nq9ldM+.c'R1 MwvsrB+<\~6;?_t-{;Q:0P3|9"xC5 ?p0߿e7q?`*`ӛ#h!;X_UCYULݡ'%Nc)s: YBGu5>3 }1 YrJje>PM[kLd8 7š+M ļq Y9] I6u5M:(Ɏ@Q 8apCv8}(9}Qq˴5EUDJh>xŇ>Wq]'a&Z3$,yt}egGeI^hDg jTy)s9j}{f>YwR|8)+#[1Y>Jw g/ƫ1yL\O&}m T-qO%1e5Nk= Tf4:9| đVy^ ھgpE _w:H|Dc؀Ƚ%%-83dqþή8]/ū6+e%M:ޚ8xoNȁful}26=MXxk76蚓W6 7xbU ]DM.Qb)vGbVKŽV;Ϥo?'hW3|f Ŭ@FghѪiM՚ܴMZ&g ue|.S6UeN5QI'tH+T:,s6d}kBːbl0~y N>^b V!G"q"x Gsyc$ƍZxx Ӗ}e6a'oeO-xf=֎(/C6Q}~zXXO-䀼4Jl̙;ɿA]%yt3c#ysн&ELJ7H.:zg cXxO)v~RVcb|)8(,F 7i Gf`ۈ3(?S%+M{[&&@֡j 8$h<1Z% wN֧%dIǹĩ>f$o⣯ZhA^d q:_ 87o4G.r]6kʏ}!65{#_bnذe˱<: .s  "#ȄgwN.85*O=+(5'z}1?nMqIt^ l̐*>nS |Vt'ך 0Se 1z9E!Qs+{Fuưu%>Iϛv /mWeng7lHW|~?  oR#jvovc/Nޛw>~ tV|BhN擲-NjW|;VEZsKxmu/'\UțV! [1W/lџPCdu^k̥,Ѭjn'*]-N>mBvkx1纾=nn=^sww^)$ݾZn'xBuʱ˹}e*'b'oe x/me{lbCb:Ҙ$slrW?@5>`;X\:r;·z?d&_=ߠ%/g}-F~.v<eOihn^ij$ߤ4嫋?ʋ?7n|7&ftWȘ[L.+o2tx^CdoK]~'7%ݔ#y7&\r51|%uF9e#|>lIkĶuS>9agiNfWm} =:&Uw]Awb8?!X#LҨAÇu~O?yUAYP9yJky7 8xp|hA޵<&'oɾunrC yIyLT'ˬ[ O,=GO%j38t^ɟ3tm 9Rż69 v@vP9TnP 95pwg5\M7c4(G05ձRy5?3k2c? ?AG|G9u.5~7& 1'?֏qcvNĖS>~(RG 8Ys!V=u{OJU/km#{5v/.q!Ozj1P+Vߢ;Fcj V{/bF9xQr<7I4.Ȏ_c"qtVx|g&}L^OG؏|'VV,;Ӑ>ׯ'QϣĘ;nۧowkXkS7Q/l~=ýtJSl-͒68 qx~oktWa/ZKԊr H't8-oE{d-ƚd|Y5/xN/tc{OiY)-#JӇy`!UT*]&B߰ǸŵHssƐXhq SyZ]9Xanc9<.yqU4K&јS{|'<ɇ5\ֶ$~qgۀnGc5~})i}g۷f; ;i;`ӷ j>ǵOh_:mWV˓%]<] :?'*ɸW5\b+Z@cutLP=S ]ˊ.SZaγx'gb{kC.\ڪiMٝ9͗707&\6jQ ocoWD[mHguwe.x_i&q?} u5qdN]loj1<Ӧ5 /1c[ƤOkÿ N(1F_ypN=,Y'=rzjs l4+{7\V8_>8߼!Zc|Y?V1 C7~EfI3ĿFge{#N~LzhWAx; dv< m$.W0t4-EAWnɂ|q|p'zD&qk'FmU A9v4.7'd*9ǃaMq [;,gqt@~ͅH~zG^+G}%q\b8|7a8Iw"NJ;3E&mFqϟId`orkuJN#Gd1br[nxF CDZ/L, cO{Mqe9?Im_"66=Ydž;:i*|AxD,@1hC{iCopUGZ Cۜ'r{\Q8\v~98gLNQd\B վYsഷѯ>)'orT=ŕ~. O2`}u2?=A~;xu-&!kg4?:k`~˹'=\+Qk6i/^&5-5_Omp/oKo[ׇ>љXU_a9wbV<;ܩ{a9ֺF]|V0ټ's1r!4">ٙ{qGlsw~ahpƯk@itꆉ:6ov~AL4d YĺZ_ךo!(k'cXJ{rǍk)o!#LP3)]A{o)iYWOz@n14m&w@xicL\kvP&;՘,u9@dc#qNp]ϯAY!4̵;tKf~U߳|}dS;&<۞b2FQOhD%1dA'ἄ89O&$ ` :oqW JٛBkܮu'S <9%^2^؄#ʓ8.F 7zW=`H;]+e.Oygյ'nrSvU\ƃ\G՘; \v;lkVy+!V^wYw>n *FWDG;ǣ]+ /[;CEYVs*C+XSN 5؄b״E\YZ6e͒ ~kWP} a ɧZ%tq%usgE|%m~|b6Ł돆W@ZYtW\e|~.զ0H7}vfO7s6w'|ngco=g9ȜAv܊᱙_Xy9awn\u_̓n/wjgXuoTnv"v驮;zϨ5<"e|Wh|I D^qG#m>۪A.^aW/C wMp@j2u.V,>{Xfe=d iSʷb$8]a/]ϗ9>c-2cϦ (_r;<'#}#p؋u7x}?Vj=+&ۦ֭o㱉7BθYf-۽R:y4{bNЧڪ.1́ g8̓cwMo23y9c:O`\0 yDlǸ0⺎)e \v?ޤkns-vjx: `ԿkOPUq/-bco2,jpCK rKlu'Z:#z8T?N*qYxmeߚc9lܝ<e|%o g@!;q5!3u g1L1@})V|&·`w:X=U;]g2uQ~s4r`*qW;]>;2PPbT=#r>!P U^}ӗAz/bPZ}loord; 2yx CD W+΋d7//X&CaE{;/cB@O8&u |<1Q^A'ڨn] GĮ +\sdD e;w mMd cb^P;|78Tn}>}%i9)q OEYP0w1FW 1>BxTEkI8*:r2Wܬ1s|Ur8쩚 |H{$/ceUЏ 'h 3hZ@U: }?`4yUZz/ʆ)c0YQJ>op~(ş^ yb1iS[< = ڍ7~\w'>[o5^r+wbN2(D#v)#C4N9Vn[k(#t([Zt]_|b&w7f5zO~Obx||;-圷Nn2we⇱^A{gk qav'8\6Z`q6v5v];FK[$1y\=v6.#)'V`?P+Hǣ^..!=o9G@Iпn^Z;;ꁹ/5W=xnj 9SG]Yo͹|>{g?[=K;_|x}N}{o0ƛ0}Wx5 'þgj-> e~㿋9xgQz 7Zx8S9}$zܿd/$r@>yyk ^sxR!c;jb%X:2'ngǜ)RMgƢSs76ɾQM' N5S@S;]$=wBh<BHH*_ >"jǚ9`<8Gb\5L x&X56 `DJ=GRv\{"jWmMi6g$/҆$16M\ S78!//R9eU)  4-ʬ}S7O\tģ|7dx 9yKGF|'SFJ)\ "u `>Tvҫ5L&mnЁ>e8Mŕp59AۃYxV'=k.x0F\I;=7&C7(گJIutuBN&<>Tz迣W"]]DGsOG |Кm/{W>~yvWG& } V'@.=H>|Xp ]pe~S5ZO;7F݂uVy_Zd%K/61VxzL-c P˔Vz'EGܡd̩lё>[P=F9|lo>_Iiq o͠y}()]a^HϭOPWk"^jH'oBƯ&S1֑ KZ@sq Ԓ0&1~RW$ԛ%3]\gЅR+'BÙyP "_s6}||稃H8N9uЄ7c@MreE|KI0􇝵9 Ut'Ŷte}obԜ ׹^c6`4֫wsT:g%{ǰ[tvG"O8#_c0"A30Uȭ ~[XL\2>'^^`}Tm{!n竰Xjm沐qAk/c\ė8wB{i/׭#E+&.%Ɔ?lo~Eѭg\`7CM3uM6sCKp[&)п}V\1Rŷȯt B!7>x:__oC&2 /Z?|~xh& h}.Σv4Io^g #!V2}bc^!u|ȔDpi6g!njb>Ѐ}b^ΐ'q}}*բF x_`eI PeG 8'S=+8{t,'3\A~ >Wp):8Ϲ݀c[_ ȫtϟ~[6 >W36nǫv]D<_)~K}.m랪 z VH}+$V"08QaLxcvy@5/^LrRCk?11L&iͫDW簳}8~]i$R} KVy|\9 @U)]ˡ4k /v$Q<ۻ8jdLtsj~20LuO?o?Ծνm}TW(1g-pAA; k;>t}N1ƛ|[wT_1sOrE]]*Oㅟ ԥ W5+VsQ+V<>9'\Q^}֥e[6B:?W8oq|Lc1W0vw^+%IK=xuV::es~!PZ ߬9$S ?"΋#昪A 8^z|y T]Yg 9>aC֤|p0{3T(ad5GQ0}%|!;I_['{r^]R=o0o&U;>`xNhM3 qqŘ, Or,8 EOS>5i3$Sև[)?1拾@n:1VTApyyLjlF<۰\[~o]]Ee6QY^19E``NZhK91M090: Y,6C7zW6َ4Yj ϛ\86>סw>':gqnշt lg]`|8V\z!^V/icl!t=ڹ&lk ;J{qsbz,~B1|) c5᳍D^<v2Tc {s?!Cvl oE7o|<|#^WO}ڮPbY|c`'6K<Kߔ >/Wڂb)*`Z泥{8ߧ#xmc}6Dޚ;Ksv>!5~C r^x><\PwZ0{kojs^ͿXOvGtmXxwuJ±V @t.a>ފ{.p\E^ ֌zxoG> 51j9cU0džW%tη)'rc_}7U1o~a1v`-n*/F)hkj,iϮI)-9s 1buP՞2k:ڬy͙`wH38aC1goQg 80gս"YY_y..x;1т&}#<ّ5|yדs0鵤xd!r0߀6H 4W &uK6;1}o&v›:'*<:< p~F] ?qN'#.?5q]б^3渱kv_dmk< PGV;Xjߚ۫U<6wh~,l\f}'=0r/FY=TA~:U}ܤ2wsҋTΝcZ ݜ+jXv~)鯳r a5:jԹ{/_Rbsv}\gl[7kk'gV"\̏b-<,n|D 1s?3n~_;÷A |\)f)U <;Twʩ sc-@m 8k/ ]/79ϝR>@c_Xq{ۨ\v*B1b[8*V|j+Arj 5bQa\N\yG \_x%_+kNVA"wDG#"}<7ksl+n4;3V6|hs[mںhBn~N>y(o@nt볳ӹT=̥vu~g_rMbm yD3Awit)|tqc0 n\etٕѷN>׎~5M_$"ܷ4gBX<}/Vm2m2s)=ֶŸݡ_< 4 t#uKgWosM Y#KO-׍s>at^bs/u7}"lby}cᣚ&u$s}o/Y>1 α_&0-M@јgEε: Ahq'Cʲ9bԻ}Q3~[@Wjl'cbSx/ 3;0e0*\bEɁzOs~cǤTJjO¸CP^8CAC';@{iP?UuVvq|d)td[@.sEi^K$jLw{:yyB2nzU>N'n^uA[hd!״_^jEEl+<=Pq\v5:.9 LQ%ӽaS"i>-bð`ſ ۛ<}oINB5qoW: t{B] D%IS< s[;BkԱBӕ&`\ )?כ.UɹF2ɇsP'mFi=^Qk.>u|{ &QEĴ@Sx9&+S` *=`Ps-|;r9DSV}-s n6cq #)GSɇG~란)lu6pp pHs%|gPеVs"oF }JkuMwuEO PӔnsco ON&O) p^k;2>y)Nk^Qy:&{=B`. |!R6K{gjQ9oYɘRW/c`ⅹ^!2׺~{ XSo-nEz$G'օt:{ܸC|5..dWU {3]*Y6W=pEF*\?d9EW1t/7*'#A}N/zɳX/pO3euZA΍L}򳠿3{5b8kWo11#4\y/г6X6K/|}tn nps=5fB|sklуs|,^a}xSq |M2o`]xu8T?@uS^穟lhg-|t{gQgUZs^ ?|:n?jy'̓p1/?n;{>ޢˋ!;VqW8F D q7oUlX{aOf~A=jkt9{7ָ';N|\_k鯁Cck|SmKǕ\qAq >oe %:D]V9=ocbo2WݍW~4 8ObVY"&k}49? a:S~:pjCzr,~|?×s$i}wغFЭ苵 8kAv q Ҭ<:08vαZ:78Dc7Z:U dm',%<ُ<Zfg݈e|=S}w95ԥV|fU5Pq<vGOؓ\fK@VwCy`VIx%g5'sqk+D)N9z'?GK{c8:ߔ-&K:sm~u Nnh+֊8vEx3./ї >0dOk5I Үˑc Ks6 OFûCܮ8!ۮ)Z%Pgkn)o Psj{ m8Ft\o,xuZ^s]xʗn%[<;'4r!+NH$O}LwƊ3vOH^:NK}2/1PVt |{4g GcO~&sI`^t]m.y=D?ṇr{8dE/xO1<+ѾQT?l{EKῌ>6f_ :BXx=Ӏ:R WsOW޿ M?I=V샺 iΟ:scnO&N]Ot ~V><@V(nW,ﲎk7k~y9㋜D'#_eoSB.9eXb1H\+ {KG6wcoǚzO׶Iz-\:<~n8#);:1|ܝZ%Ԕ0q2sE5uWZcn𳠑򄜇Fy aX`Q? g5,p,RO! x3F}}.9o1%~y:`Ѯm c|7^گ]sğ>r?<)ϴFQXzE4m d;."<猺bak~Iޤ0)c},MCC|y8|Tu(x7WPuT2=?O 4> ࿣^?[NR rO,{Wy? g?7{9BY+* /x~5':ݻ+~w߈,sc(~;r.{m̤Yc/ \杤gC]mւzO'~(6e̝a7c0S:IC&L%ېE0F;PO;b8s=R|h;:`Wluyѧ@u73uc>=zpNIاEnC<wy(2}f46c^onq&tD]uSAٮGXYhNtg@cT/7KF7qɮU\2SlW|GvYVb m||pLH8Q$ѾYS t&=Nu6P:.aj^2&G+*e1dIJE.v>D˼pmRgxH?)VM)[#MF\`kh_FPGG=ídou ̵A4CUIPZS _ |}0eXk_xBw+hv7Q5g|^;UzJ {Lk7'-SOӯt*=I>o燹:zS_Soр4mP7 qcn }QW#1` ˱ǿXZB8p i+]Cj|n>+z̫c=OpJQ`Cuz*/9Gr{=U0 ]Z=;]5uN>7O6/X~Pl6>:L y/&{[cg/tgWa49r':y*O@YØm6!;n>L2>/ܫ%xc1~Z] Pe_' R G?o0# |/VM~GW {AaG h"f@9)l7%C |39/_ tPɷyDqiry }c65RE:E)Onj|㽁9(y*IUX^ĺ1I]#Gc .Lö1ܦk8ڝm_Oa+2˚:N?_)1橹iSa5mW˓\sT:!ZS}oP`C(uH)\q o*r.'FtWd /gvڽinty/uo^Pw3\b1/'o׶ia M)Wm*?Ʌ:;psfd;Vv+dß]5౱m_o O`ta71OSލC1;7e :T5h;ӹ)4s9gypV+0@8z!2>yRƃdrWG~:ﺱ);Af;= %akk{'}=8 |Ff9nfct}]JB]~ Vyg@漕1J lg BKs`>W ]!ߙk^؞JLh`J||6#@ă;rA1cVQf~k$;sةEd:^oOyA3utahNhɯҟ7bNSo#Uy .-==uc8ĶYPw]knpGK5--N=(Z=Ogq| ئ=㼒ɯbxu}!N:?MGo彰Y ^{ſg jP?c@xLgLT\d>c Y Kc-qsZu!oAU qY}H5cY0nmxuspy3g?9<';3f]nZG?-1dc(9zEŗ|!/%g(Am5?-a1:xN~ MyzmƲkr< Tgt"`ۣ\)@q:Am]yn :&C ǣ7vMcW\#@T6?=1KhpP׌ϰ)\?np)~U8,(w1}OIZPV #ƩF>7e㛪/37Pfך "luưb-cюcƞkuAo K=տc݉yX::N_DSjd;t.tGbhKxDꇽgx.&`r;gKL~V9]jZ<:?˹N]t5}.ͫ>~60ﮤƋ];F% gWYTXDyL&r|f \ i^U_ob@S5%Ѓ (|lzicshsulք~Y[qoqnSqgz^Ո6UF?׭%1$}ئ7mwo~vp)^ru4~Y32)nN wb>W[|Mx}^5ޗ=\j T_ek"r_u&w^cӭ|8M} s.+{Yc<~s$:77 c>l~P)Os~&_e71n0|UjMz@0+Q/ XG J-ެ/2߈!N&a!s:yGnglj(y#ε ?죙2R1wb.ڢj۹2oiznẢ\|8.b:[Aly{.\MӓLu:}g<'9h?s}C5z]w̹`C@?=nP1z×cTFշC:֊s;iJ5MUL^Wz8/7ьWޏe9qMJyceÇ{9؎Fn͍M fz<FR<wQ':'<2 8v9A=Ufm X7٧/:P_#~ y<4Ek1'o;otX_g̯֬u? GBp%'wWp;K'>n_-~u9BH{ZzIծ=++SR|>jl9rV~ ᭘֦Bs{~V2 N睁xU\7QS8p+G׳}2^V L\aew^7rj<Ҧ"'T7n\A.M'?hx750"V*n 6;&9P &4m7;o_"CƟMP?'k`6&"w`!3D+;ykDqN עJ>\t&>pu~g1Sji^&IqRwຯD_=-GJm8Yˡ[븒Է({4t:1<$ K*cEpo4c0<1 &~zmW/hRfrc'9+b."μa})1+kC\x "y3z+`ZӬZ X]`OcO]u~;k>Y捞L}d='^9]`m쵾Κn )T!OSt:沮%HoE!@k%Kt2ڈbLy]uѻӸ7X-0fΗBA_=޲8vV1/33O]j1"j}ۦVWjwn-lZ8Ώ_c޼}[NGYN]PV}p XW A]^Wb<vy ?5Ⱦ%wxǚUv9a@dz㼛<>˹mp"_miv=b|pw5Lk7OܝKbެvq]&v N1sg~Ѿ1ytFn>BˌVym?ű ;꜀1 _!9}:ODWPlI04xL{u&ZNØ<Ϻۡv(/uGzՆXMi}mEcsUMf}͞e 7B1y& `*9"vBQ@\c>m몄sK%b)曭bڬsuιÈ?:.@k05NUx87>ÿ֙PR_<1 ϖvWr*ڃ?>0} vϭ.>WׇRɻ@kX\д>i cvs8k ?S!pq~l;8a& G=`3Ufǯg+t9|&9g[= EB^=|HͯvjE<5?*gΩ>h65bXyF9I.!l8񼳆t-`Ӝ=sX4h3tG=۳ | #s^Cr#ṬVyxԱ1~l<з۫bf۝V\ C#Q1wB߫Z5ql}_'T*^#rmw'bYGS,>ܦWtKH#6y;$GL_wsNl]C>}b^#ERAde+B i0xkvST8u~za:IzWg>L 8ryt&>i z(:MsW+<7Iխ Ƽ/xa601m \#ѯo7PXA*CuwiFcC+GQaJw؈渆.Hd;b[T /B8ȋWC;"=,{`d3z٥~9 }yy%~o˖؇w OY2?=G>Z0CA{}b)8'5MΤnjqVW0b /t\-=n/͜!??p~MuWAl8'Hݐcb~fSt2VoɃ؎vkž#C#O  VQ W>u5?DU8|9qPcO@POW{doj{{Y; Lj{zŹ6]ml6; E_ਵXj&y_{V~7w~fīZ} O F+ldO0vWe}Aϥϫxf 'k z#sr~^ G/@=#>xꇀ>{j?6PyC?`Tm1 _jG_@ y%mZp:zOld}C0,:G<,Asmc+Ot/ph+Oi|2P7NM(=[h C&[jk>ߺ8%xw_ .7ktUKCSdKYU[Ս_zuzިwտacUnܐrP{0 L^C5G8Vخ57˻uuw{$;e{V%s73^: sv2M>yWsxwLorArb?.j}Q_̷?nJ]>w1߈8% o {$f5s?OoS7S9(c*r݁F ,a>51_@uu?śh+8_Y',e+3&I8P-t%B;yܩ 4z8wsgޚY%v1u:O NsW?Rr)y{%q}CWxɟsusE}褝c>U' :0:$| 5`ȟlc(wH=ꏼh/y|V=mzmxȶ)WJU|mɍG?OYi˱rthA`GlL7Enڄq\|z U8z`{*'G*d;~O9bwzs:ط`YP/MgV9s :c'myC~ |q~$6;d.#*CUO]Йy"2>Ǘx~mΓL|ROOsR]t]$4 %M8W%V|ū݈&emEGG/p8"~ V&Ϯw꽫9rMq6'\lj'oWުt3]p:֚:)V_GEUrGSVУ_-^u0(ܼ9\0{vsٕ`伩+TV5xJu{3WU9"xs7U%Gc[|\\srX텿6cGOq: ;>Z|;0RPX^ZcW0d|,/R}>O ]Qw.\nʭ.tgM>u~`W`pNPGV^oChވKr- zm YvYO9no|ќsޢX^ ;sh#Ʒ04,M#1?ñb!9vy@쟔MgVy)x|otn~mQ]ޒ|vǧ5 c6u,Sk`v߀!"&5KgpL2C6uM 6{@$vgߔnP:m5M!&|~_K1k| ^]~>x?Zi9,@YklC_jʫܧx>lb4ٹ܄K?ks?f׋@3A2mګ?`ot;?|S)p\ޝ究7NH;'lXjͧa)z&cOr2og(Vj!мptO>dC= 0Avv9-s3/_}M1︎Q}Nx@%GߐZk+ K{ W{-5{[ m:^+Ǯby@)7`9Qagl|g_2 vW0p36::@yn%j.w͗V+  0h j~8lkxqN]'!?f_|7~=}7>7!ӵ.w:O=3m $\uyԹו #䭯U;}QZ$4.My$ϘC!Rkr` %<ˀxz7lC/SGmq@h5pf4WVL1'r>rr0`[+t>77gq?dZP6@vT_|uyO'ÖpCg|SNONBI<v92_{vwR?GWTw8?32fc ]O͉GxRypB>1:wJ 䏾ROwkn3uA[t :@HCa[a|qʦ2FW>>{ |N6 ~gSIMm[ 7_د\@uۯG>]EG8??˚r@Djs[W~GB||18 _@Yi~7Js? ݆x܄^'-~`_ק:up>O%1dnS? ʞAWWΛ?U>"PZr v4+k׿yװƻ;Mx 09F=6cb.わ7|o:#> ї~nPsC? k/"!yxFK5wm_ƅrFF.CN6 n 5ED||p˾i.3hC ?Iıe}GR>79M1>9ǯ8u:cC=\i+Y8a !RrNBw0CTǕ"b m%!oS1IsK ;z=f(ZOA=%gGE.l1b1hs>F!p~|؛Y VDKO0|L)>G; 8a#>ǀcdo}۬g^psHj^~86cOY)|dJ5:K_χSs:_c\94)8\k>+8ԖA|tAؼAqtk7gMn-k[?~!8WpΓo:RվpO2X?uwO| ll@j5{_ kw:6 Fh(OWm-\?lni,i\-xu^<@x$odbAT|9Xyڀ %j}IĢ\k]slpttOt?]й|[c#߿JT6 >Z U䬔 _+J>[tC S_Pʘ#ڙّ'O-)y栘y}$2yzJwJUHeuXb𣾴fxXO`|GH^x0llcLs OtG`^?@; 6]]' /O? BCoH890?Ru%ihCry=*-QtI: t~Ht=RwC+x9߭Hѣ}"BW 㧜zjWiؖ:_`;{:JMן|..ڹ3/=XxUzkޫs{EŶ|]ž.ǻXՠ)^.c͜8F/-</4M?^whgIgg{O?ǠZ[dJ:γoO3`3Q@]o5] 76; \ WvVLT:^1ç'nn;M;|`bXbW~M},'V9{1@Mwפ;c >Gszn ur~k3`}/5KoV 9Njn4MfUz9Gկ_}^ :dyO8f3cg_'jm PERtߥ@q5OJ@5T<僇_,&||o rPc)Gǰ:"st<,{ ױRW{7ۑGqJk:lp <1b#ȀOʀ)KU}u?c-ס!.⋝pscN$95bӏo|kWcGc-~-+j#ddL9vn@S#aXǹmdSK29 Lՙ'_-Pmژ;?yϑkCW薸>v[e=u 'Vs>eg rεir#@:(t?x0ig_KY&eێ 4/^7DFV >ob8Jh?؍C+xNuP6h휇6SjBr(`B|wu< cw;5[}jfu+2!3M5̫5՟qY_369~܄9Փ1anC[$f Q50F1vvg|wq=f.jr+l<ęd.Yxyj YNuղo%4tX''ԹZnwRԡPi+{':]-ҍnd8y!>ʹ#ln sڭb^yNV;@~uܞk$WI+;)(NNyK+zc9 A1i~+g\.L]?,rz]WK4 wU:;5𔚼,W=& ]cչ!/,eavµl;:;SoͫbqnZ<7۹ndtժѫwzuF͆ħzإ9d\ DjEI`Ƈ&Se#TY|؇cw1뇟7}o(C{5u1` xomhؐ/N75:.Wu\re ؁N|a 6wq{v-VcDzoxOӫ8BM1o' iu3"jYC) ́cNN;7(,SZ?#Я7کU ?8A glCB>#xG}PZjOױ&n0pCmY"'~c5aV _V\ h~|y b`}Lr谁O`H%r2FUè76PCGӀuF B)x ڵ(|~M9T&RFڡƇ ):\J0Vmڏq.<3:*w=\zȇڧ)36vol7aMNg76\^KNe v&qXsIn ^GD7H+djNy9=Mf9$}>~Yһ{['];Ne:׭ו[s;/cL9*+yy|m7)&zEǷ30vx+q/%UGͿsxQ$x]xo?7ߊQ7&#O+a;DmH%HO:7zv9}`Ak;6/5x'%uwa0m=vmlq^{dI_@NJx.'sQN\yrW7︒%߽ۚٻe.+WXn=lup1Kc٧ftY`ZoMUmb7;NMy 3{ɛ~18"e|>:Z1ׄ:,ohC }>܁ m1 }Z@n8u 5zks,^*\w "#3r{|۱C90c6oʢ/@:,희~C}]8s)&|^q]gla,vBG;Q XBέ[!Z8O'~1ģ^EgQro}T!\yX$uۛz~e.6/ 4,*mLjtC&$ yN#9ޗq+@V9n&~s U]˃7-g‰es&!a?A1!;%B}"%c>EY{NQn9ίP =vC{"ܯc["_jbbbwq֙y:;ǹC0\3X-N8cYz)C˳ ?k>coiqew3HU+eg nCk6{ѐ{ \m@y }bsY@O_xۿmmA<_1!@"gxO:Fie2=&cy8lǰ?݋lǟx5jr;鄉Iy3@WorXjc^y 273y]c7p. TfSᜧPm2]54CJ61=V;*n|o6䫾=x 6}Q&9ŵZ{p7aV~{=-I9 m̬= 2I%xM2)_r C؅Ժ+C1+ЖĖY8o:q^ JWC9hpXWK 7 _߷9ꮏ'2߬Klnꗀ]67}]?ɹ82Ϩن#]g$g/SJdgIwbsiOr/珁n@5'(:V /]bC,(ctLu9;*4/511{L{6~UeyǹȞG::bE7l׈yy }E"ʚgPMa>n{zO} 3 U=:_l6J2y=ϧ~OI9#hnOOGWg~vHγMè_uPPnb<:}A)%:mdX6qf;٦x~=05YmȜ'[ݯC#IuX ;i͚6bi}YK;]';KE#Ն󯜻+C'chk$ooF{:V6 s9 81y<)*^ԳШ}ۻyHz.h3|g~:?B_UAY}:t|0흓F6o-1`H,cCg޶w [^.3 @C[Pn |uCh('' "U+FuQW'2 6@hLeS$sc"`[~X٤>A/;Wt,Ƹy ÜĠ#뿓+bLU׮.!S ૤Ǘfst2S=R3|g]h#@K7=iǖ_'`14o5[>vF6FSC&9B"g<[#u1OK5ʡt"vdRzUC:ZEnsњq&zU 5e8e| -I7񇾇|\t0% BHtJ>-\%Gם/0qm%RkGk}ã~#~6g~6r b%|Y>gADo;f|[2#7B|sy︛ !y'9x_j ȚAt]ZBV5xTB66#%' X|Cu-9NrUJ'ddr%T6GQm0~kmBhx`k'D=U }+t;x7ƃV' :Q8Goqc ty ;[ysNM,i̫ ٟj<)l Xw'Wh(+qBe|F"7n~eM^;-ʀh^mI_S0.8aYiJ. _e!XHDgw8WSd6hej;ԳaXS}Fl%Vmz`sY[͛}؉XyxeQvЛ 3xƊH#4F-|nI=x޼\_~s‚lE'}l*k Wj'z'r&ZжЧS2P}Fߘ珬Ey=aH }+H HLjoxHlY2WcOks+o/n4jl2H_` U0J"gm~J0n?tm>Uz&Ɂs A~x]\wQhLLju'k9=z\Ң_49c%'h: _ׂY}1)~6jv`yGAn\7?y5yH&tb_[|IsW"+ߒd,_U"̀&Hy)d%+I6# *FjKA_;jK986x雼=9㨹hO2Hmry־RAg0:=ǹ(" hi%Q{! J&V3Ч ߿*o^3_5 #R-,7xOI0tGgss\"&;dzX" Xi&>>&Y +q w6'[ o,h弬w5=*[S9Ef'ݓOyπZběT]>.;\oT G\ӭfgv hƙG4[}0}/k8tZzf{>КT!Pgg߬-:f\êKGkRFb `.*O;ڇv__/"v+ ? "2aףY~]X{<(௰M\]웦˘{0h#3SvOAGGUO2k<z< At3[{~V_AsĺN/[O|/*^萭j6}>`N#IH7֥O9鱉_~&{dz-a4?m|L -pws=^QiUEћJ_?WEqjz:xYLy_dطt,/g'vO|~PR)/+R~9ȡ_mŪÎs ,ƈڊDbSgKh8fAC& ?2x0&<ŏyTyñ6czppk@|x'|>DtL `;MrUP5?w_xMc8ZuFVٵO`Ӑ3 ˹S"[D]xY&OjhBy&dؖV*+qw8o/xrÀUfx#VHܡ? ܤb;Dh?% 9F@|ψuZ&r5q$fc)*=chz!"2BH/ϩ#ܡoGr|yE{d Z@õCU oX;di2`Aֈ"}ucB|ҹƟ[lNyqnb{{7v G[_)#'/fsWqrW0VqmP6$*}π=4%Y X3k^ǫ7OQjKXeX|W؂(fx^l%OnF8;x֜ pv dN]\PH΁ש_;%c3@.y2^f71'S;^kX"TˋX+;TuwFL댹nnO0/xtH:N;JgB T+YW_GCRݵLO!f o?ǻ 8MrWqOl.q#s 6 a+ۧ}ϯKu@?[K|zD+H󼠿G,(YQ2yqqme*;kK[.wƘlcUVr"ޝofe;׋1ܭO;ɴn*;'*ϕ\s >ow/ֺ^xxYx)@xd$G9r 5+;xmYA;kb2-se s'Q ~ǦmlGK}/b*9?ű64N? ͈BN0&;qG;ufbCya6Վ/%x:ug_9O~k_1\KC[eK9%r>o㕩Ql,s} M*c.?jߝ]|Dun Rݳ%| 1C$elƚC+[?[N)lxea&S{gj5sSrrQX]'EЯ~w͗1Wl^\| \#Ɇ)ix- ļ,*`* UM[џiMaٰ2 NHS 럃@Ymzm"qy- վwq@}J 8J)LFpS$s@:#{ؼh8L@梟#T'+[X7uo\iU큻5axľ׭W*m\>p#rM4_k>$a6&֯?e0Wo7_ Oyu=o z~D5_?-`ooݞ|}Jw ;uN Z'Mko1 ?W=6V{f5e篛LLEp+N0082N*/Tl}ښ.8TVpĐmY{Ȅ9ݿ+= =aظ/Gt?=f[cxVA~dH@vP PUi:ނ\6s=dk=/L1H2`: Ժ 6CYg!֏rga- t xY<\o! D]H7ϰv,מ!⁦jgfmP6㰖MSj}DOu~1.t*L|0sy [e5`@e+yƚS&[ =]dkkF7*BOJGMt f>ewm̎Dw}ďaZq;1fzO|;Wj֍}LFez=Q/'sq=m/ l_g294ϙ~KᷯǪ}}6Vj<\qvtCHYC#Y+?KnWj6Z5[lVrhs:uvj,by5X/phz6Po a8p6~G}q} 6 R"@~ uz6-EmVDNl>rU?|OcoA<*4MoK~qPW Uc'q5p\A?/8[yUzca}r;*}ƱCv-h#r82Qס{@.9w]դ!"N,yrj"W06e <ϴ ^ e@*ȧocihn/ Ogz|2cPoF+9#R^wkŢs$^ _3?o|T.nc;%B kx誑^E w^X5BO^C._g)[_[HZʡ/-ޭ7m<#B"vH71d=+ufA'WZ@S بVG,;ƩwEj쁹UTkC6Cܖ9 <{;M93x0瀌ar~ثH?G$5i:g}< e}X+:BkxEMmX+[=6!ʱ|Tp-GT|#41i>Vve&[=&#n( I%ns)O5:E^FͷD -7ȡhqdoYǺjir{` GT.gExBܺ/ mh}ؿDc{Ou=+WImc%9^.=6wFxUxOcjz67ð7mvmM.x{h2ޟíK3wuq>q Dоyo@yG>s&=amEL ru6>[$BϑhwE@/#ٷ I7e _r~S!s=.EZ9Zk_hix~<骬Rñ.xj&3<Ϥxnk: i78Rhe( )?['?)l;FHsܼ.Y '#|k_k5~Vg9WuىnZw;#ol8Z0w]P:J&ywF?_}U ~Jn'weP9\p]_aQM1AD~d+7/zvfVg6UBi)1 i,~į?¢#! xɟPa@~eBE&vkಯZ7]d h+ΖbETy3z(Ghڤ!X\eA{9tG\8ve>KОb F;iSd~'#/m(x? hsz:\uϠ8b}>%4\)֦ѐO+*E*G@l+W ulm7 ?kVBOa(rMt7!5؆]3&σȃ3\czP"5, dn箞W t 4/t=?P&/||^y׹r#~/Ϩg >?*Ƀ8u,D>T5#{c[),o|)`Wvho'_PY}m'{GunB ]l?0 ,? s8Vxc"3:u𵘠J][w9նK lH7"7u!vCkrfq uYݖ䙆dtbdrR4 c8η_˾=9 'dυa_ψmהruud4I:ߺ_nu=3Q z^"gPFrO o-a66̑Iaވm26/7p5KvP<i[%I6z d:Ԁ#@;/3oS>R f-k@1nLj[W2jެOS6v|ER  Oz`/j'DE+_<.i%x ƹkjEƔ!fs'7Dd3@G{DמhnFc6Y2VuTH</UH`kqB a=8V'Y=i n;~F*S-8I7oԂ9;14&z@UlZLl1r_UvxLPl̙6.<(|wv.l޴{WOL75Q՟+Lpxű4_xK^,~]y-A<ЁtkV̏/dmdȮI̱f ˓rw%F@kG?v13on`M&>:9F΢ލ9w򭨏@ܧT_]S=ԪpDfD) " uO4qNOq{9'[ns}.* QJDzKA^ gMCX#P7(tίLm|~{yD @i1yqжCd_~дA/"h#Ee120NozlNCcrf[&fwn:sj\<]xO\EMӶΘsBVG=f^zV~!x>gPTx~.֧ؑ9=ab27/Q{of:ONź;Nnnth<>XįPG}vT^ ;b ~WifJ!~CO&Z~0c{ (CrzVs˵0 e"Up>@d5#kT\c:1j2Uܯf:Aco6]2:2_j>q {~o [#_<Nn8?@|N<8`6&o[X.>C BN rP"# q,,W7eITuInj缼_ rPq\OȾ-Pĭ#CVh!I{|v?zh\Oxd_-bؙL6"5TV8cRg_zD}Zo8AUpΕg_<+.s|;@}UboVω2 o"d=(øTBYx[*Mu<w?w4sDcu֜!}R#19b/D]f<^F[C6d |:@u˗~.0[iPֽ/MY?7s.>e "6Bދ;7pnM֋uqPŒT5c?\D&jޞmo:=e|ɛ;4g.'> uc2}T& <պԎN+y >XԵAdt.mr<6Nq{>sޯ\R2APym{m9'8<>}sʅEyq>T"cWE؊Fj䌼ul<Yv?R[NφHVCFZG` }o)||Ƒpd?Th7RcH SnMf >(s$s<ٯ@5$ vQ 7pq^ qp{1) WcchS۪)Ahי:~m&P.ޚ+(>xl潌`VXOEw!6mׁx_ƇCn|9OsOkY썮%uC3mƭI۠ *L0䮀f*ZQ:u}`)bdz*hi;8쵸,zgX8 9Zk=>@y8ő}`9xR a{BsmיfOӠo׶:GDP'=l.xޏ=z47{r Q4h@_uHmcU6S1s6#'}ΫBXW󕏋<4snxAƦ,[:P59- eG-qVmam0J%v}ˆyBˠrau F)!)Kݴ֣n\ \g?ќr 2|x[+xW4qtP# i>nu:X!|GE=+ڞğyx)hxY#/]ŰkYact1tK2 5 hEύ{eaSӋ򵁠/y c@~Jwtj__N k)#mώ{u;`G#]GOoyCרuŦ7D:`rm4;?0F1bZ_9@Ly帪!sx~v)WL+[:Dl.ĕ$|'Qm,;i 2ܟ\͡偡(nG`Wd^ε 5sqSS:mG}dkWkD9q]]'zݝҌ_ xt:W(gj0j`! ݜ*4cz<H}oE}<"d6naV0v=r|4 x?=&1d  럥Pysmh~ЇhÖӗ?#Irh{˵c -mY,>g1nr%bo <|EzgHu4Ц%O%$k1*Tb&oc'{G_K Ύ7L&q^߭#/\dɃ;k{A4#{ ^{9Od 1C6p5~/: `J\v>/Pރ6I;dQsokxZ|1)߾~*cw>稌>C #u_ YWҙOo|1d! y8]]ч%nO7\V~NF0zm9BX&|=E7@9|@%6갉}rvϊ |n݄5'7KeT@Gȫ6Jg믁ȸ=9U2$5okX_zkI? ,ɼi{Er9눳ޗrw.{`jN&S ;3ޫdĥOANX~QVd_ 1㤢3stkK^g{:;С_Dg? 9La)`#/>|\l>LI?c1k@l !O8;S6P,. XQfqMlbvv!"e.y!I|<`xR0zk+[ܭ_7lQndwڧ\i]ʼ`n<G_f79&MWu{3Mg(oS9s0{^5&\f`r ?X f>bä&ρm';čc(bv}]9 ~cg~,!v&ɍ,裺o:Dk3 1_G"`) 3tx׬kPzZ'3_-X3< 8:f=E2~ s=nj>~י~αCa߀x~6/,y Hֺ.ڈ> 's7b1OG#|\=* dy?ts/8 a'q `<g{&5$[ah}Ė1tx@wV3rm HqrJmنR ]Y,!M'Z'n};rsM%sh5 m-@ ޗEciJyMIDAT!>xܚe~'#}U8 8@zƨ)<LJH*C] M۟ANk;K 2uZzƠ`xlЮG>z~D!$3gx̖3S;AK[8WU9 SGo ݓ߃avgէdlg^Q&5WԈ%uS}zq1 63{y3%tDLr v~'Ϫ;l l\8 6vG. ,*.n/ 'Mx-'9?LJ>)=®Ulڍu'esgEϣx|BdǖT 꺂T>;Ju})`; ivﴵJY2Bv9ӜcotXҋ}l׳xM)] c@#.C% ʮStouk7 ^}c!oWy n~xl 9<хQ7# _ 'z9&gk#=$-mH[>ǎn7vGdZ]Q@Kqd7Q"<5ZGʠ(a: ]dlsBφU *Y//Pn7n9xWZKIU'D.BmXe.m/kO~6~3 NJTfwk1wVxg]a ̴ϑֺalqٝt.t:>f09?/v'B $52'Ʃi[ꍨn~H&Ƙx&T-1Ld\MfRw^=2 ϋ ؋68׬s:vx1֧V R0lv],_r=̆Wsd0&yVUHc|s  hcr0 Y;kwwn&'+CC~_OQ6`[.YeAM[O%0wW3^tM)d8 Y+p-٫&WGEQ\SPAǓl1ecl 0Iы!OKK$E{6f~l6uyõ'k&fyiM0ӯGezLw2U pCGN\g~Ue>Q9tka{AdFؓIxbu^V򭹎S\\q;6:,_f>u/Bɦ$Otq}h8T뱮É]xz],~`W=hO4dUO~8q2T|mv-7/YPv r!ճ1|m-vV !a p~ G, `Dw61`~}jn3@DZDΆ M'xy؏ٜH~>Rz'!'[F{2Hy<ǮxUzbw7Cbq9l+kُWbGȏ~ZcJ<H4#_\/)qsN'ݿky@1AD*4hrkvޕuϥrA#ꗘ$s]JʸRa] !?̝4|^0e8VHKl.ϰlػqY"{M|6>ק|bkLudNdG;98^ZL~ۉ~y)+~z7,0ͮ3z$7A+z~b,WDAKDj N} Yk+{3?3dz_=G1W.GGP8뻒MP$~Ş;2|]>tcK4{`\8&_G ܹDx1ÝA =Y0xBZgLdm#&GA65LN@lx5ڵ_c~8߻>aTIcz`'Ih)ƞŻʁ6ejwrs>mWtWٯEyڇޭu<^eT#0!E.XD{-BCC_ao|y? #B+hD%!/mtca_;-x F?Z)ux[o?JtNHl*g|q :veay u1ؾ}Oi } ʶS^?_]>`بXNm=,fڪ/D1D=Z*.~zo| xMB"VigK_<<#NSJjJF7<$9?@OF<."Ü>k;ԩ=o(O nb~Q6蓼1TO9Oـq=ul]h)IJZAdTG6pl 􄌋,{,ϫ>! IU9;.1!Ƅ\<}Pg1GbxvDÀ OpLkmSNj=uxl~0/W@*F 3WWob|_ѯ_˱ u~{cU&jk%~(y:iDSI-z `O D_)^k*oߌmߐd:'W<$~@7*w/mq, r4l/OIqHά@yLƧΔ: D^F /WHmX{tE0Z73ϽMO6^ (g|OV"Edq_h5x\Pb#Y^ᣋ_q$W~w05f?nWtK{x4us3U{hԾvb~<\lZ׵V6=֢"WtT:%(1u2y-FPN;|YXh6tŔ- \ -2(VNh0:y\l 8^{f}۩\ϑr%x)v[e;kd1(BP#zkjC>/ sQj!{.aLy/qmީLk} qNf3uDމ lW) Vt> mm W. {0Qb+c92UU1a<AxK7搿Dη1nϋTC9|S 4}3Žʙm~ՔN5߿ G?ի#=ˀߪkΜYP̕A?`.R6DUsh / q]#2e0, %87+[x,cJ?_&> bwU9'9ٓQU8M`궣4} "nx0u]>iFǜZ{L?1qX6/8p^ ztMSdx'8ٔ1Xg}1 BUS ݯt4G#7{{ cgP ǣ0:?O=}N"# ^`r-kߍt-c} C?glǀPI!|vgn rt<r t4 qi}Ŏ>s"_Ba `߮{ Zhxpz}X0A:d[8'eE6SgOћ~wqB0v["3ɀqc!V9 g%^7A 4o- |GOP rdѡ!vw'e7KgbU@ ~Mm6umԌ:'k<Ͼ^}K͵1eh$"_{hjhFG[# 9?~Zu9ܫ,b;x7q"tOBd^r\Z~ 7;:W1ČoWu#ꭠ_8]0<︅E>'@\NVMy#i̡}f EhbGgckqW͢)줖# ʟa)n׬ϳus$"(kUr`絶87-U1ǐ#=BaYs5Qn3i1AQe5@ :[|T>up@pe] _`A;f??wxq(y1Fbm+< no$W8c~Uq= zkn^dTv4 oTݰor6{vm?c}kUrrG^xo2Cg1|2I--vqGw ҚosҎ cbA|ڟ XWuH\׏kb+`5k<<j)KWR/iYeyӱ:+7#MǾ=|e)9C[p`xچ<9B8 ڵAӗFkwSIZZ?Z6ecvi.6auka?^ ıxB 5O2'<ηqd؛l8逓wu8?p "x9~=ld0 zMrz;m*p"Ͻhmc~,tc\4I30ŮH@Ĺ|U% XP\ = q|Fۯq6x}DkqS /?XgW*XǬV>N"NO7pD^9, ^Q̏oOz.߉qQr*:mxM"9D嘮aC;W6 N=:#sFxlMo~H}?Sn5ѣOWynsy8P~Wg=en{ֽ W7p5W+m67# ztX B9lzD|ObP,dŎU+5mgytJzV;4_7nik}~t2 2^m\[l~QIty,ԟJ<9xL{vش1|rS#ZUa|ON%D+31 ν.|}XEWd8<:cdۏk 7ilroSys^xT V5Y;ԃɈ{*p kJ݅F_y)(kPAA.M -j(*̮ݠ)9=Xm#ڱsYB>xOcpN-%~`F= ̬F\A8axWh#ex8pסt R)}*`"٣ !@\1s'湶s6UfčX+-ƻ:7b9<^e:S^thBģ3M| s[e~v}Zx$4xMqǽ7`+yF]9,Ό.Zq xcݮ\jmkIe\4s#! e6L@V_KXe |J:PրʎȥwvAiQOv744gŔ"~?ÜnSa[nkn'Ɉ]G}? c_ًjudnUn [5d3?s^;2gG~Eb^6b;_m`;Q ^ DPAM6<{%)q/`Nbkr:8tk]bj7|Eky #QGmAO`O*mbgA!Uuk7۵8Z|N#2!"wp_H[Ui]'S[4LvK)v`]'|>[9sY-kXH֟҃(skzZ*!KM|\"eeXzWʣi\e{x䥹_EPOQ<,*vw}:M5%? ~ 9q x|g 2#:aC@vk6F-|'#)焎itiRY>A@'5t2태¦}~Z+ݛڳ QVGtZ$\ [m 8Ov4.gc=@I<A7˟↌?W&Dut.1Xʏ 8VF zK_s3$Wl 1^ic !l^|>?7"m+'򱹠Gw<iRG2kVD,ۓXx&qeU,f.J?/x|#+#s)?2;#֞s2l{1/z.jǿL6~l 4ӠIɻgk9~oLcWk_Ÿ+^fL__h{7^}vٵóby?km;/RfJNcU+Ŋ+<{cjkhQmx?7l"[5 .]W;^xn<}GuGĴ>oyn.ye5|s^w![m]u珈^kqyzSs̾5]@'1H|.uP![ou(LyhB)zOԢ%OO7Dg`=Vu#ꭠ`+i=pϥ+k?Dj%Մ끜X]Q~`}ggio@$xX6zxВ#E{3-sRZ [ /rJm}^]yoOzInӎ!#b!ׯ{V^ysB(bwq!k>f|h8ّ 8Zk{Yɏ|bGYWGC¼S^EWtuMNkhvi/un1Vi 6נn .ly6>( }`ɜmAfW}Ĺse:ma7ȏqZ<~]_}89 ^}̞fo(|”ȭa]b?92ւcjc 1M]Be |"l=0z`tUxNǏ2jʃI >Cg E;v#0/Oy+bOҷȟۨ;ck砯1 9 _Q? gL^5'i'zu9(ٸkEl-ć[|C> rU)C ek7pϿ}'T2XaaD1tZ?bݍgp{ѷ?N"`jevB0NٮE]l/}ѶQ4;ovpI5xglޭlcސǤv^ُ>>wgփcsy% \[{N/ubVleBu>؅w%>^Ֆ|+c~6[t>=r~hWM8v#{+ݪQ}[ &[+k"Ӌ|%\;?8 ڱGƀWXŰ?@-/n\KS؍{ps|/al 7rO6 Dh}eі# H {١(WŶ/` uf1&ΈЇ<ΎѸ e5;>!*$‚1\fpJ8^o=qb<YUxs|'6ɐ9H 1\ c?fzU m;Du2jе듡)P'S ㏪(e0vn/ZgbC?4w5ҶnIOy/c:mXSwAT;0P\b{]ճqg;a4pC,Lj6:~8!`G(MxIsJ^UX-o/e\{]vҰ.\fL ^AC;QZKawg>K +ȎQցsǸLf"tYG];ɑ6Plcֆfkp^HD= '}[m g _ׄks%6r<_A;;;i?x>wjf_ENv,nz;k*G7[xp 9{pĉw7l{{8t|f=Ss ƘY}4jg=˻NebR[_Ӭ I%XCoux{fsolɤ=^'3?h+&jZ\!NX|q,]U2Y\൧CٍPW7?!jU&=akbF l7~ 6\5)|whuUB ʛL^ (}8;ޖ11>ew7=IƀȧO|K}<.^[c|#8`>y+VkL7/g'{ kYtP&b~ܥR;wkMZ:dXnO[;W D/1 _޾w|9Py˹թ֯k20GtKlG~<#:q ?0*]h~kKg̩cVH?& x˛Oێv\1_1yO59G-zʏ[@}<ؙ?ZcZvzҶ8Y_"AEZHv>z'[vu xo:kRjG;8=aӺ|Py궪c:>]v|~߁ _@2jPG~bYe&z.h67 W$sLJ/;RT[}]X+S-g(O6VF}K%zБtqPg#DvVUvGvg'm Xx.{x2^诶;1o;Y9_=׷cnKo6lf_ym$R3h9ی(Zy2s+0sODMIk-T~xGRǰAUzݎnʗDA~v\r>)4qΙC`Gfvq\zt7 վy]8>S8OQۘDA#5p<29jh#aj{v=LgjS?J1]^.cJ RC__")P,w| sM;e`}\0}exعz⺭=f z|W{I{\q.c-+xlq3v K<1l1zy}e0 tR2Tqz~K^e7>@LJY|1X#oFDZvt`|і ~#w;lENgrU k*zό1aY)jmZKP\7Mksgjm>o?[nw]4v e29/p|9 s )ooJP0Ðի3*rnD^ XƸUqpퟁhkG(#Pt}M&>2Ęvx̫  מ3P`~_Ƈ/yGM3[\{ Q%vLPk: kaeg6NoVї@Y?C'D/'ΰI' ^gRG qPW^)).H7s͙ ;oOvp}ak=wDE29\K yvc};/<|\1`DPECs}_3aWcົᱝ81BŽs:Ε=ʵV|7x?r,a b-{NJV0 hW`,vX!1ޙjpa407w}w9SЂRT59tʷ)6T+9ɰZS=VI>i6ׯNv O^W?3;׿xO_kKQ62M^]6q'2*$'7CnFѲ৮'gS9_?B&¤W@Jex]x{+ ;rbχY|UW/0 '@]w8^#wӋKțν4V}t^6 2~v}_r; ,>Fp~Gje1l |(&x?o C )煸*Ɔu@S cjO^%NoP%&\ЯI21ܪbdIXƗ`2#7|cNk?S%#0<(S[_zd;MG\@/!m5uƤNѮd1|x8C p`0eh3 2C[hgTz7`Ͼ R~s@ ~xi%ۿw ̕HTf~BCEIW| = bk>SAI;e\$x+ia̛2 o=0y},Ѱ_cgp@l~oo [~Fp"c YsO;O+ O7xOaP n;VuB![/bKYaU3D%Nwl g'Y[GOG=}6!W.aFUgww)S p>-PU@gEcexf->c]%\"{y5x+=e}{tn3:15*#h62'pZOt^n٫l/MshRG kQ#29@iLGcǟ` j W$ q_NxaFe2,\zyX[ǧ;I`36E~)vkBp3櫵}g ʫtN8:p^WZfM!/; `HkC{Ku9t0v>?5s#8> >clҗ9XX{ՇMkadA^mh:6^"Kav:!ZIkDFnQT6<}O }a"Q>';#86nP a/(;: }ie@8mI3x 듄!$^ڂfycG4$#y8WBD -{if>,i-a`5¿GAHtL~ Ň'e:yI:u'>7K4ʛ矅g H9<@)$_E@?( 淀X֬+E$|)FFpoT q!" &oЃEWMBy{m'y`Fm5yօ"_I(f5 kC$%ܢܷ`D Y~*Joܮn&Ez sQn#rt w2=6by4[HZ"$WϏ:n Y?c~w@/s#P > /"౭~| qC\ߟ[XkK<1~6'{{t}<땨%ٞZ)[^U:11x1Ơ6H |?[r!Dn(zwjWm5ײ$՚ 7̾d~޻~x~\'6T~UIGh]lc2vjnPWx=f!݁}eB9[gY:Ps*A0}=KAE1<Ԅ=꙽Xܳz2- .b<;zL'{=/}PQ,ӋʇrzdjZSQՓ8l9ʺ Bo9m%dc>u eyӄ[4J\̝\j)]@2(8k:3t-m]tmqme.1)*к@X=wd5i8$=QG;I{1~]MhW!2]g,=bbo\1GiUva;24GQezxdV13 |X,h>UA,X !nfk}>Tǻ ] !5AƚJs_ȧk 3~0GP-]mu:$cSȹs!1 s ScOC|S 0%@hOu[OZx)k򀏯B<>'1 (vC\YWݠ7”qNm+8E=嵑c Ǘ9a^=*JO^jc||~eOAƟ&.|"wrg=d:oqa]X[&]eq ğxYah.b~G2n[r($#m5W^"^orntI+ ^6]U Q~f6$nf'> ͞qGQxeϴ [%a>u ' '7N8SG~xzgY"fcϡͰe?ދP2 q*<%m?\c|{c~ߣj,~M(z[ Șo&3-D_`b%iazٗW20snn(.C㕸m=QdE1u'ovvŘ;σ&>JUu7!yTYx#&`vٚe>*B^]$i$8PAGym=/zUѩD4pڶG+Ng8{G-Ѳ?9gi5ILq ".|`E7몉DR#N%{VC~TM>2YxD#3h]|!¾:p/+"m Vb&)ֽQI>݋Bq-0g}v:ͫ>B&"L *ߦd| vHD6xa슲@[<ȉ5U+ޡvuv)unn6gꉠ<`2wk=Sm=!?dHplR>фs/cݠj@k7#J(]!aH+s{' `ec+Džw boQ4_Xtq7ۛ Vgj#}F\9Yŕws('쒇\vrs9s|s =1Odf~f7Ben؟1:؍r-6a}_u6 ;{#0[z#xj gveMpi?UnH=Vy <_Ýc90Ȭ7M|kC`Wõʯ2 q?YaeoL6]FxW $ַ<4֊E}qk;E'%:*6ܞkDНH)d};tÚ]T7 =᏷9Y[4V{@20Ɗ/82<ݼvkg̖*HQdʟ2Q?+s)Vu>1&b8\n |z[ODa~p1 *k}CQs8 ʊ< S#+_r~nkt=:D9Μ~}DM^kFP!7q"(1&hמlO-В`/ Ġ'}?ށTu⼀sh.?#=/1  ǘ S`G&]=`v_(v޺W\`yjŹWAkGUo+Rx o1=p>J9#Zt?\r:ہO??7+?<"3=e )e~* _-Xm^ z_ۅ= 1wr>݄fuHS@xAv-Gʰ3re=RWRb@4 3XsGo8bib>b䐰_!_<;~Ulsw8c(wD7 ?M?kPof%=:1JXaNo-3q'AߑYO11Uz{EK] 1W!5݀+*r7c|71mº>)o?p@V*dFdz/` ~}=5#sXG|j1y]W#нҿDF^֗vweHm^%kh%o7|-'ugi"AM0 w| n;0σ0ǃ'=*v'"-j7`W/,+bS-SFFK$ >DeeQGdWॵ}gpdׁmF/[LHgAOOGH >V,/ 'AF 8 hps<})Ze54r7T/Hg!\~/ϓ<$ymA?>Pj ,&EN5P Ha"d"uXiM~_з}z#skFgbsJ_ 1rX/HrO N0JD>_CyF S1?_ i=Baf;i6;e!V,A&~'ǿiuU_ߌ.! vG?1"cWĺgjտԹi⨁bX?V&^a:MT͑v w}z>+dp^zمs}y ^n<mPiShv2(O@pL\3;6O<yІ;.#hld(O{-Sȓ©:!*/0c\ ofv}߶/4ڟW~m*T""a{4|E}[8xMrXſrM+;hgZ9i^orϐ3PO}Jo^1xw|7A&7O*~e_bῊȎiW/D↤Cl uVm+yDew׼+ TK#S>Y|wb_<5Vt;}X!sGƟb~ uOTцV~c|]3P>%|ʓv"ѭ^lm@D(|E[Owm:_e=ȯƛxu?OnapՆ]۞ sê p} />LyJ YLVYQ"_(,6L`k32=@x}jse X:CxC ~ʽiuL`~|̻׍s( x5XynXkUU0+N=5}f ,jX-=1VC Mt!5AѸ4R xg|;MGY VF~0'7ډ51:Nqs@%c<:k LqbXRϱte:_ FANAmEOHnfz_qbx!m Nj5LM4'OՆq_ُk&y utvVTϭϋd0X_Byu?: z' E}*2]Vϊ`yCt b:ťc㽨w0# 1]CVW͑Gە0F tA>0tSt>!ed߼U?ڜ{SY#UGo jɸҾ%/*םԦ5H]^,7Jd+4;?6$]9";''l^bk%$hsڕt6Po-3L_iN2Џ4 TCzLخ{5Kd)i#U: \@b.. |B39yiN;yz.*ssf\;įWV35{>#veVÇA{e/rD2Hrn"WrH]eQqO5A{Gf>B۸ {ma]|Vkϧ3h עWdpjA'Ezlg~D?F0YzI9>({F_rsqMKՙbϥJ䲧o z]ChAGW}4C ԍ>Wp^%8x.9cƣ~Fb Z (zH *lga&{ d3s?ZxzlEvxɈ`o$+Ǣ{<Ѐ@$_~$xQD/x2&zhq y ࿢OlQukuC>%WF#o|iG'FZacoU䏗CR̗I $rH0{'ם9G +b]L<FF-_iQN>}y09ڟx41G&T)'W#>qG~懄3(uhZr#e<,Oq]%]/V~jk}z?>w'pq2濱ۀ.q}}{rye=tw #3͇ky`֯\ߛV&^J c'ƣ|d^Id\:Gq#ēx֚< 0ÿ2ӫרQHo?e '/!+#EmdoAv|?Hty=8d= >>#i1ѧb8k>v۠M>&L=Obx8_Qb||-kh'#6 ٵܒB[M#.ceπゥP8q='kH=7^kk4yۋab.!Fspz [X7ȐAԿ}3SzM ˑIWe>>_z?xpEB8 SB2t)o\o${nW!'uZNmMfXglNJ{Gπ~vxxDk |~{E? 5 ? /ͺ*W@V\ %y` t =F<I/lO{+/3y?ۋ|y8("a༲? ~{z'p j;Cayb-H Avn C GTm@.}1 uD.^_!ۏtѦ=^_n/E5 ~HZ':<1ZkI,j:ˑ'6WC̯19;ϓ<tAWŢȣ5cQ$Cb:ű`Be`]3Eqz٬~NQiU<1IHcBJ0xIctMXkq{ ځF<8IROZ/'SԠ+ڽKWi^H}fS f~z 6l7tW$BGC\&qNC_֩mGV7Q6,cuf3-o^.Gùn:ol'؝ש6aٚ!ǭUq^9qD*1h%hid aO%y`.[Ρq,q8|Iߋu[hy茛O LCJҚ _4gȬ '5aD)' S x r>X y]N_Q:z d=7jr 1T.!V_YX"/DF&%c|7k1;͏]mo{TÊB'bRZaG,Nj~Mݶ1 I}zu6Y+umѱ³vb,կִkЦhw.^0eDx7׻:] d>ũ A&*ABd3h#xTn&ꖭ_[許T2ymÌ4m&zɹMo=c뤜pt.vPF#8+^e s }ic=cO , " 1.ivNR19?CC>3JȔAyJatJ ] y<'0KV}|q" d23qNNu{`K|fϵ3,spS.o?f:@r=ZDvX:OBΎBNKuRq0 t5޵N!12˯ 3*=j{60( N6EG炏MNz;8౓̛;)>ABvrMBn%]7pn΃q]3@BGnQoZ~X'͍qxu4ɛ:,:uq0M_ScBs#6/řg ޽'o> ЭBT נK謆(Y 4~!z͂3곁BI_Q}= ^DCQaדt5[):y yG fk|qm㮭7? |ʗJCd&xCS GgozK?lj&=gsנA)Vf< ٵC$ϲPBZ!ԈR ǝa<`v):^ LsW1Yh/[Txv9 Es}܈#x*ߺĹ6Hl ?$Z_@ Sd}G )Z1o= [MBqľ38>q]3@BGn+65ܮu&ʽVaКPQk bs/xWl\lIb̹+@cU/呏CU"s*ozkn1^|\\f=8Vv17#:wtǝ<|rDn:Z~ZD<`۳Pddy)įc~fCZO8[@2 |^N+ ٚ}kvD91Y3O22N}sc*jG$JPG@iiAם׽҄ki'7^8'zRDž;AcVmeRY~!XP%ت#G}n.^kMxqm ؜˧ `zxbR^yv\wGCU!V@ݪoZA;^Vx:x@z^fs;Ӝ8VԊ}P$$3I'O_> | pu; ;Hk}hwө{~ֿ[SR @ƻ`WmsKi+>g`\<=p;zmqO ǻs~ĻYf9Z2ٙ nG>\MƿqLgGoL\g-YȐQ;;6f0ܘLE>F{6`q[;CT\固 ̫5wh ] c3p3 [i0qCR]V} TIlyCduCDtW>ܟʱ)vbuW6ת|RvtTdZut}̽^D[qBwqa67Ǹ֭lǛ2h3?;<u7oF;ȫ`3y3U2ΎvWr2@E[Hj>'d<,N=q=s~ur.Ӎr%&S Bp\\ٜ"RvAϸvztfE&͉,ײ.Jͩo4~GΉM?} 0aqkI|y6"֓*'/ktmg6,9Smb.# G"/q *>U][LmwG\T6'>8h;Q1 wKc 0?'[ 2,W|_!tzDja{ ndxA?cz :,ϵ_88e8M3GS/e>W0D}sb:>)~kX1[g?ALƣk׏q__c8O0_sp U۸#׸'fu}uHgo<-H=rz2f&3Vʚ\i>7_xh]<2Wt'τ׻B(b& | 3ּ,/ zh `NTgYž/Lfjݝx{N^m.jQQ {9)Á<[y$OBt Efi5Ek=,bQ5>1s OzNW1鲭|޸ӀF?7}>Z%T07;MnK1dssb:Ty6 ^ d\H0[g?ALƣkOSǼ][g,f5xB$jJ=#9^p^mdHo&:ς׻+KLcDU%"UYBe|טNOϋe[[ؘƴ>-:ny-kFQuun7o~8)#= >VB.?,l HPW-w۶uݖW6>f>glqU~sc /938]3޴gYxue)Rl^[c{"f2i<й'| @jX4='Sŏɋ՞A?v~'ؘ, <sj257>c6=&d6691fn&A=uX3;z8s֫z~]T(^xG9Ȩ[;f]fi1~Axd4 gk1c68^J}to={{s=XU ό:◐łO B_DY@Xd7cX2wm E:'cx,7+3s '^Oz;2ֹ;SbVaKcN=tũ>3헶NIyߑw/`Ni~IUb5oqO|@iN&suμ36'ݭ(k3P#2ޮK'Y$]T"{cn\86cj#m8} P[x7vO1<c> .=iC7jY-@jc Xe"($<'tֽ}+=m2G~Egve~ _8ϱAM1wM$>p~Os*QӐf_V1N>Nma.'5~;C39G02"=扈j~BAȇp!s- 9S73e,[vsLNlrU[>RY 2^+R\#;3T1:=Z#/+}UdnKxcʩ@lsS)b*ϊalMο Íڞ6yŷb]^8ݻv9_P_7#o-1]|ѭp:ũOq8*Y8[12W<>z,iXtwn]Vef}4o ہ"4+d*{> (>.O<80Y:jAY|#'{4FSͦ>sOQ*Vz-rAzdW~ce+'b<1;ڮ%ۣbF52 {DmvƁ6zO1b>%5)kc&|cih5%CDU]E.yl6u <#Gmڟ0PLÖhrrnԻ?kYogc3˭(tcdN 8 Oh(`N170? _eM0"z`s4gf~2L}2p9ٸ=r_IJ}sg@e.b2e&,ZllFݮOs%Ю9$em8iGiGECiMeخsſڋq`u*8Зb-'pZ<5]>u dDcnk;|ŧ]A3;C2sG;:XXO/Z@eTz mag|YlyFN(khs ^>xWn@<ٽk3vѷ[-,N/u9lW>f6y&&wE]MN&̶bl9$'r`ౖY~Ky[p O4+@Mx5ˍ<7\}Mlox?WyZΓ̧s6@o^ #|S6r.N&gU;|W)Wv^V/~l}_>x5{eN {{r<`H?EEA7ݳ&v`Ws3q=ǹۺDby{hSL}Tbk-\]zݛ: ^\i"F* 78c ?|H ލ7pe<~yVl+c: ,VAjel $-p!of.qBsr~ oglB-C¿gDxUl*ʹf|l{ ϳ,4*6o;$zcL9G]&1q7lӀ68Vv\l.o1GW >O;|K`~_^P 䲭'}:_sφw8*z^yuY_"/OOwJ\=)cՙ~6/#-xC=iDZYxdFC{2QK_t %؇2>}1"NɈ`ڇ#9WkɵO)Vd1䑍S{ پ?޼ıv5>ڊts~GaaݸokJoh#}@fBWaq0_p0~VƓ3͑O17]XwՌk6è|nث\<_}/Ǹc9=kTysy>7םC p_ _9>"Ggkm qx"EdW*G:d$M%$Ah]5 1ޤcyf_?ֿ}2wAf HVA[4b?LH[Z fD D!46BE :@(8X;yk묵s^9gky5bp/ |yJDSږ/Epj-_gE8f,سǩ9_'N]?Ȓ<ρu; ?)3ܮWEc֞/Gfuncם cjOSmҵUjEGj;ܖʶ'>"IeZX4}eHWn{ҒtێV!g8`5gjcHփ}6zO}La١#jݸ,ơǤs>d ϚMjD:BEkP  2/ v!#|ʁtf~m2"v~WEOm=~wo\޼4bqiHFZ[ ڡM8Гv@F1߳): :ayTNjjm뭝Yviя7#JC:3~Ƴ]?l]A9*ȸGг^8ocvyy||еbBG΄l#rgF7ɤwδ9Zxk<7^N"wwz#=.N[KgkIiP_#9ш_~6= Ǭug[Lҧf\ܖe;`;ZvsA?A9 йIgDei[Q{57I1_rsC١9m}޸Ny4гS[~=ŠkhkLh|I}×7!zvV Z:|yBͩ/0_|~󇭍~rxbmC6΋-U{.k3@.;:egKo@(6u-wϳB>+sȯuu쿭/]1ʹKulvlM{49<_*^r~s56ǏϼF_Ev>ޑWqk:&wR_|e>V]4]^>oڽvպ$GU I}k}Cst6vM}1s蒱i h _S01af:r;>0OTf|3!`*| ʸ<h e|AKX]9s;`d" /s9j%"glچ+u{{݌Tx?%">nml!Ԁ&=@+.xU[!({j=cG紊g_Y 9{U:;Kn;ɵ5(O[C1yCm{I|$$#ґl17{}C/UIv^2k7lñmwy&HSt]Aa@#o5ҩ}gtNQ=a}Ƙ?M7-Eb~.mudڎ=4:x>2tiZXC"SVl,v!Ǫ@6GyT.irzU;e߆zNv:ܨ˛LғlNʓެġԺFvqK }P*!:\ce 8TW4X>EYVvKڦuG%(nӤZFr/uFb yGZ*L>Ta9dQYoU'JΔ)w {΢[03GUe;(ԑ5fm"̮3L̓ jS#{T$4LkL؊YQ7 NbrfZmW9ƽ!VPM?5h tr_cck~_vG}9F,e춱`x9 S5c k`^`Vln lO(y3QG5k-mM|'{.~nC|[W KɉoIj:|iRO'{cB>|_3/'94Y<|jVjFjBWL^4V/i[NcqWt{kAxیO=aӡ'R7 c[:H}6g@eo3{?[aK'U",c7n#W+.~fu ö:<K㌑Σ[m`fy xy3|P-k9Q!ϮmT_v2}~|DWTnynY]6d)r<?W_ֵ@#R7ȵZ8iq#-RGj?˯e;*KʇR=mOzZXh'+VsǖCR}Wedi*H=O:Ǥ_dh'/l#Y|6ߦ!š>/.K4jOAa$Z6<w(nR_:68um~$\!',!V9mCS~"X7sDD_K:z ೴|ȱ!́+r$Y?ڏqgIIv֩#>ypLsCmnTCsPO&^?8B7) җWwYJmY43AۇxA|曩,%xt5ö!z~#cXwg0 Ǒ#FǾZ#>|5 o 5qӉtH*~[tqܭm֑Q|@36ٱr{d,sO<ѳ5hֵh>vŶ~Xmg u[l9eQkN?NH3IM8įam[:cOێs^,g;ηƐU0]z )mgZƏGmtyHv:˾еuom` ?V% ;]19f>ulAf۷rv+x5hL1m6RXlw 6T]v S6+o^E$.v) =(8Ҟ>^>vGc#&V\qا9`R'm"Rڲt>mFv6NF˶⇰s}.~isH }MR>n}/Y9y~*f}tyZ<e6awN>GMqR]ϋ=O#o `dQn r A/P c}],@߂[;tXtٝQv Azj'`mM0;?hrGX43A'^P$ÒSdˌ|xjmC*[b!w.]_?~،@l{9bk>W}EC^vٚOm}vE՘CT]]`߰alڦځ}zyYc?[8nf /%NMk&n\vhʏ>}~KfM^MkV Y܍ ܄>n7Mf|FM=)-77Rvf |n+t{R[%٠ հ%Ll//mٜq]QN`斎[iTꉘ/m3![} ;rkIm$Vsi'Sσy]\W}ҟ?;N/&Z/q;_w5R'M{#1JH^P{{?@U o.ʖ@~D aV +4(=~.Q}z94kmImUhpmKX&Bv|̃łI אiI!>gi"|X'==xF=|RWi|7p'涧3Cǹ1ȱ'k$G)Y"voN)5O#DO}'^^\ rW揟WnKk<2g)!\<+罱k\ ad85 zʥX _!ՃRIR?񤌫6#؈5ҭm>|vܓ t?Gs/!`GK k.o$o4D0MW)%Xi?^m,VI[oŌn ͫ Hi"6tSq`~d^H}U6I[dc"Fz(Հec]9j4VRxtOʫ[] +tnsAϑco'...߈4OpjnN1Bn5ޛZ犯WqK;d|}\.s}&A\FBɩk<+罱k>8wo #űgse's-zqs},AKF C/6@ raо:ZD?8r؍{"uf62´eRqI殅km,"|Wezq~НӬsP8Vm,=,=:AȜIq\v8!tkXjO8Q ɶ}޼QNCAڟl zXҐV$wHs6[^/^1oq5b{/AzrLyMcMҍ ;#دc,pCQ]O!FrLs/v̿Ff},n[@eFWJ?uqƣ7#זvX3|<2cl8{cǒT9hzf|15]œIk?[Tؾ732Ieo3G:鯀8cI;]?ؽq~Ƌ S?D\C18׬JC?X#Xk4F]v\{ӧ@#ϼ\]brƚIAn [ZvV,w7c ׸>-ٻ$9-|O'b(e $Շ|IəI,OυW\%ɏqt~]NqZ˟j#M:e=箏tO[)&f24 _<|/4A?Vգq;zmܜj̵hf~ ߉M%`'up̱3MtL+3^6rl:G1> ۑNڧ/)a6*R* XY8גKȼ-Gn;8&>@[}f1~/j_x)tZD~>KFȵm~˵8gG:J[Scn9vrL.I:f̀<ϱnN8pǺm,kҒ72GQJW4PWTGU8Wȃ;eGe"gcH]gTyq,_$pP>HÞhKB_~'8ȝAH*[{>&A7'_^dMzW.V}ѶzE~oʡTt:Z?KnXG@ZHc[%ٍbH68e49M ,}vOhҵᵏ"m=?Q'e/(ϓhyD S)|\)_~~&ӓ3K0!d'}8u[ŘA{WNgURNV]lHxIWtDN..^k-;k|Gn"`ç5/N}™7*־~L҇i7Y&f /֜#vY@Ʈ9޿t#cաWNBw\S[K>WT[|ģ{Wq~ʘVyw͜zY.n Ƕbh+@[ O'pD$a\]sͮ΋.luN?a1@e' ȣy!;aٍ9kw4Gim;Y vLjqCp)x_z4_/zN`+Rk8ضm"==X_/꘰qSYe>]R,V{xCcEO`djھx ]+e.\Cq͗~|Wus#ׄkv8 Z#1:Aբgık1֭^m#]{cqxy:\M<#&TzFc!ԏ}HdyP7&o#m~G A u+IJ[?7ȼj0YzA8'>aw"NrTt=@|e&D'mE*= |FרJƵ9K[}9J{uc N/dמaҶc_gg&fqKNZJ{ o0ClOZ@s}$vu?:oYcԖ5^C\?C"tym/>A/=[3OOw5Ͼr?{;i0+`6kh;f QHNAR}hwHbKT\$;m* ,;R-8^Wk`+ Wwk-+s`=>ִy_]{>9]lq5!N\|똰j@v[TFjyȷe[r?zo8i51RKg;Gw6f_mWw(ؾ|ړ\U?8EIDxcI 3j/9_lBqҳrKi主O>@bA[i!wtاL č 3Aڵʱyh=V. Yݷ!06or\T5^&śXu~''pq&oŮtȁI±oOu'pT= znvf.{35-~8ԯ_N-u!6ݫGӊ?:[bbLڧ7`6r$JJ&l݉DݘTۉz2Iv\O:@XJgӯYOJ7fZ<6 FǮ~\{2x僩 tfT%i:(ʁP"`~W3G #ŸOQ:@K9tosf$ҰVz.dkDIΟ  7u8G0?_.\3Y֓wU |ZjP0S:sF>:2+AWvz>tو׬Xce=56&ǼCs}k9X?6!51&9bSS~8R'+Vf=|V 9@ev߁4ߕrdErjW#cg]fx7ouwX/9n~,_fbo7+ P7Iw>7Xзr:Q˵0}\OpVx29mkB ۲RQՕm.tKj3/nX2.t>@?$X,'op}`/|u@wx3Z^+r^^X^ >{) {s^_۔c^ 9ΩGڢ #V\cֺs`<%GѲ5jǤ. ά@cqIKE}K^w"Ic<^,~یvN'|Ă}뤨:l/w9ػ"O|(b-C{ƛ1\_Kҏ,lE9RWt''s< ̞}\CK^N|s޹F_ȓEQū^Wly=ʱjڭ3,h ޖ0g}+TH~9%O3L/-xz@ wUy뜣>IWooҬ1V 4u>vY@Ʈ9&wzJn;C=V1/ٞmά؋sdL $Jтl5^B߫3SKۡ/ A^|@j-~xܖ>0M}DfVh-X| ǔ}2aƾs=s$^1m#,:Z>\GBȚy@[/fnܢϪ*A4ގmBreq*:~,V,g Xry}|3CwN:q0Y_H~ m0_4F?~5utI YK@37&܃cCsXk@ m~b՜ kGr|O6'<\v}\Rk@/hо{ڐ֪}i7l#>/y22&Λ#M~''g LYbtQ|= }醴ɇє7h44!<`n>zJKmu_CcC XgiGKeo}x~|9@NjCƻ':;#pVk 8絤ˈ]q kh}}HmSym X]G9Wb#ڰI:ضڔbWmAľkF79r"j߽B:˂}T86xN;Y9Ui ۓ5es@`d쌓|46G\'mh,ٓEG̨ }-ྞ_B2^oWRWosh2qZzlAUCm4p Nm?Lhqc_ m(G>etqmѮIXsVm |wNVn6U ͋3U;}xEIF1`EfYˏeyOqj"|ul<|ˍmjᡞey=يwd7G.{xye<&.صYrOScfr/<2^Yt0<:}hŬa'l9R.!hUL!NcFW9'/I/IvWUV)&qGщS ðIr6 j-v)T: Eu)S-fݪ+ʵu81W/? +VWNb+c֟[/zWqm@'hʁ׏Я-/rrCN2k'|RBpMWEvyԯL00/M}O ˨/̏֍r76l>w@_!+5p]jwĖqW>ǡk#ejN:ݘ1$j"luƯ浲_:(aojD]qwO^&JHe$t$?fnS;thܑ/c]L/<͗Pj}ǷGkO^cA* ]=mԑǼDūz50vi}֤.AhYOǖlta{᜹])&v ;/IO:6F: N>d 9}KUF.5GO3F:\&C>N@=)6t4"GͯP'\n8pJ{rG#m;vGǦ6 2~zBU*4dP7QSPT} Zs_I]X?# Ek8%9ţcA_Im~O8('ܬa{I\k֒^<8W7%李NiUBOnhx,G5uq}M8Հg7&$)l]q]q2'^Dohrށ,'0tkSCcbC?/E%N$ gƃ9-s2pii!So Qr$^RGE/ |QŔ9s ,mXYE,9D͝_+T>ב |×3}RG5ȺOqKǓ[yE~'o<$9c^cǾO%LM]vfrs/Ѿ鷬 K`.IҎ]8rS y%" DX ǁHŽ`w͵EwųGl~^^3h_zLcul/4 UȄ #@\Rd\!JxB~ i>?nIJ o ^kY}~hbid|~(q8ӎ-e?DTo4}Ǧ˯k嚤m8KBAM;goL S,I3^8\Ӿ-;0S/OpΓj<͘ 'J5O9Q$?7aK:i#n7ELc85#GM

    ŧkH/\Y<<:',5@kNXQR8v։Ǒ5j+}5y鸵mzlp򩼃7pv+o!HC,5\nxǭ^?`cy~`q=s,ћQ O Ŝļ?_/=G8uۭmzrg5S6/truQ}Z^h)l}|b#HE]JR /s2:< ˌ}*Z򚓼d@ < 纔\,iUOmAa_߄NN!|-n:r%M^ | ۲f ۂ\\WwO>uwY4x0/\7p qAs~Mֱģ-R>ta)G)DŽ$ݺ`9+We8q"' \/|T(k+B'x؀H,_RNx[>t|L,~k5JE?u4JyMjy $7OBt%V}ZvE.^kw}zv >z 6"ЧdT=ؔvƋm:+>e۩OTSIy?Ա8"Ǭ}Ok2˷ E`ǻ_z,)}>CK-Ԭ< ÈYP\s a s4*o9朿%Rg oYmHB}zf U"-P>rމ4z;;'7f_+Nbws qz ]#SO=H6Z1 $}P}ù uM:A'̩&lD|4tzXœSkZ]8XU: }j}`4>:}bOyL㙹Vw96ἤo9t\t]I}ecstw?C>]ѸvxvDyلcQkOX|\wUCDca>5}f&'OkwܮQ>X@C1p,n"12Xa=swOP A][QnF5{tHY̦35-]>cv c&cڊC&!"65U,_y :Ә1 9=:yIrZ>E\_LĨky;;7kp? >ڵ-u屷`?1k8.dp95ʇLIW`v/CjqH_qpn0f>4_gi CA/")m^-66꣏#$_zs)N3i8180J~GW_i'} 7p8 ~V'#7+lz7VXk򵯁KoSyV7pjuV:=o "a4>+}![,5fsOܽQ>c#7p|_lY3 霮n)׊MxCTw?gW^ba.ָxŎ`l$#c8>ͦ~#Ǭ:>=-|O/GٿQ#:M]u FbNi!tZ`^;֪}2/ۑ5T|ns1I]pxf'}h1"<.goQ7{a@nz^[=`DY@GõnI/w&Y:W\RϢ}zN4~Mڋ ҡe(:'Uj<~ovUn+zlr.1(vAcmѓvisn1xG #! mR;:X䏥Hcs2T_B+Ҝ7(X:%ԟPv} xgʾ3Q$~(oֶ~z0c(yjj57xr&I`'A]X>6b!H-5qOg0˩2),{lX?VL}r̽7po}dN0YI}|\eΖ,Y}).jYa`Ҳ;hC-'|?]w::oo~rŽijp!dLnel8<ʾKߓr~\~g)|p oHhQ:yvaV?mLoH}/>|1KB ;AѼS><3qfs5RC+td. <9~|n/Po×>#AjQLz8|NX G$g<ó쵟' l{roQ.I0 M;r:v_ b sm|VĤfu ~!#O ӗt'6n0}8fPL3lpd{]!wmq)^8ή>"@G<3SRee dRKڥȴz㴃c@ +_M 6ML8iXh Z9 ljbQ(l׀6)|hBڢ=[FDG}9vBs`oٝiGy_!"56tLRc,f`wĖߌrTݗ9Tfʫ0=Cr*.ZQSLļ#6)qrޚҴ<6^jPE?ׅ&-M!2;1t{u?w-1 gm$f :og/3G9cys6tח%1:Wv^`=?`mk>Onu<#_%Xm뺣vz xm>Lm[2M3)eҳ31XDϯJyjn=ƶ7:ӟ'e] 1^3VLj7 /6rw |aoem<Vk|=I?]o>uyǐyѾ=Erqqn. iWAx^PKpk7,[GG"_̳^uq+1ӗW\>׎ b^Cn^+r#b" aͻ\ +"|߁딼6ԅ]dIEio͛ N_&oǯ~'|h'Lk$A~5)$Oڌa>֙>%sm煩)r:Xks7yO?d|*~L ~0yw_BJ\ZCjϻw%x:JW Aic|! !5M}Q&kcJ^d jG?Iy80מנCsmr3R:j'/@PoP 9M/@ח%1:W2:m<5ob6-;Ki͜ [#-=,KIΥaW(3kD彛:+<Fe4rIߐϿ##QCFo]Yc,ouίxl!"= r|ߒ3o^kC cUJٷxRJVz+MZqv.;iW ,d+19DAe@GdsZwV?F1gr}ȣabaHQ̒OP.$PǞ||*]!JwVmܞD_ӟUDZj!gqAثǞheOngݰp+q@4W^xF&X_J|(rok1>- _evx̩4N6ߖ]ձW81ONW{ A7ϝqxݮ[v:8SW.E+5F>|Nmzu9 s#rq`Re{vC&Ƒ`cכg4=#2늡׋WivܼAˊ/`Ɲ҉vqЖvN6/=mk;ed_쒡=^n=lFa1I5:!0l'?zHދ#۱Ϣ|cLtC˓F$hTtM5!)`Ӥ!!=A>>-3 մFÑīAD>VkHf)&$;h>ߗ%@EPҝL^s7튫Qe{~'kAkXD&QqR_nؼvTmI9Jq}@I77)iL])!:`š[)7նC1+4^qDC#V]CQ>utoڸu[bG&XQ+cצӭ/b/,c4fq/i6+.Ю%1'vjˇ̥!+םꮅRvluј/o[2r> H'e'gG;=p͒!խ~yl:yP+c>I]L?G3MTנ rOynh3rz>2gR_>{>#:nEyз#KXܷ2Eo(B/S^}l*f֍֝#d<@|X~Χ97x_@E=?ԧbr7cf:\sw=FxD}Loo}lUNX4'ZʶÞsm=r=&omܤGX\b~&~[1qMSkNWe#}K:7cE r27/|VAjyG>66γSyì^Z#W "ձ\E<$(GZָվkIaR=M4w: UUCgS@%bw]F#s/RXo΃\6">dgSv;.do8pPJk%ޘJTUsNr pϯo.(o^#G}fj HbOע5xG^CwT[ycOmVf5M# jG=μE OTfj5kҜ'q-U_kx;ιBl2s8u_ r]Q8uhQJ`4cڏ3|nXNYz%ߴQ11bRk͜ienʝeJ&cbPN~^rT/>zQm!/>4>чh\n|0o|ò>DjC;tYmЪԔ~T9OCgUPBJ K=$^v>z,Ԍz@X Y7p̮sk|5';}Vd>28a6jkL6ٮ Gyn#zl>G{tF<3**yuU:&{G C:6lƾVԧdkBkw,8C\qK5}YĊ1bRk͜ienʝS.P+'@~Ogf'jՅs;<ܣe · 1VW{5Զr\VeWσsqrPim/yq!@'9؜^*⢅5wEx淚qV8[ŌB3G~]\].,4p}ϱW^zx x]kb^/rv ѝI֋3 lH=-[3a_1V1Ɗ>g=puJWr^ۭc%iE=Ǐ#_bk=Zk ;"N}\G)7%%=8ެht֗2 #oeο1ʣ}$+痚h_ys!u{kӽ?:fL5Um ]VѾ(6ogbPt>E\5<髏7֙ݫnZn<@t~{XVOƜkr;=i&p9|!16=mI񔏔9ւs1D]:'pmXZsG}]or~{kscA帢Z񛺺}Z,Vqn5_#L\YG4IEWGI4Q=M,m`K߄a~;xuď@P5;SkkM-u]rUέ|gSţ7­}HsRmI~,.Lj#i%!w^XǞ$v\%=/5繬Y:y³G'}70'G>iÚ3Cq ŶA)Xjy@!׹>c3jС֟ŦT|Njvq5ٮځ%5xkioAcg}l0{G|s8FORv$k G8CcWy}[#fCC^ Ȣ Ss99Q0/,'|(1ř]G|Q֏]\^ e1]Ȝ.o#J֊mʘ ].*0K݃ŘK|.us9a<Cf3_MV5/_bϢgJ5I@!5 ץʁ9 ŷ6R;kWyt{Ny`]{Z#EBmzsq[E[vycRSTZHE1gY c!:G:u:2Jօzπct׿ [VװFO׉3.-̉>>ٹ 5^?r|{1mqXph/{@^޼ȷOe) zxDvcWs͏voG?³u}ƛ`Z͋>3lDrHK% m:$s|m[kx.VLqK=ZkDf!%X˕q%y{RMX01F̈́)P o>VV 5jŸ7(x5Q}G\m; /ArUXsr8Qy9D>ȼft,/=Mss9@mf]5p۪z'18ٺmjµu.ݸr IR?L&8öZO'._R7 kyk_8o]fmۆp6ȓ?)K+s_͵<ճr!A=~-JVǠabI'pJd'}X⧢ ª[3u?E0"ۂs9QGcԹ|tt9ں?1;452kJJ3u==k^B9p*| u4ʹ`+A}|-qLuOvâ^l]o+DuZ>sbЅM[,cv,>fFXߝ'ݧjo򉺣_갿޽w|0Ϫ'hGLV1Z:35a?®gzۭY},}Z~|6~9̟J@z [#MBjʿԎ%PlǮ!HwnP_nFn5zKk].=Z50j6*vK~}cZ λ[MuBrm>1d1}yNQLKux >nmk׀YGa.e^c3#yKȗ@X^~4a5֯vk^Y"_ K/uGjl% )ך3嘌}j>b]W39prI=2EttM_QƲv?/]nB7^b9~Kz5prcDh >Cfj}Ac{޷u^ny\axykbl(;K4}R>D*1Fuk$k>3u_(St{:kєsgFW2_I눊d>ݿG^gWL] mu.*Dz#sYtVG6Ao?Ծ2Q.A_ZZQݾh8>ԣ!uϬ(uUI22| Ogx}D6/5:ÈaE *qk~~Nw@ x\ӧz ߲?I֝gǶg7Yܫ6RlVU!,NMnҝch<2*mk`ߤFu4۴ F'W=p2 Ɗ#0Vpݭ<kuE!c'd7` Ip7~9B !ꗛ nr& p/'|$V:(\y~!6nb|PH/ 3EG#75|,5r06w7Nt]سvtb@| R#&!zK2 kj'bw􊮮QVMobO>&jZr96@~Uqccz2lm[7ir}&ہ56O}? <>9Ψqmz Vr#kA6pǒx/bIDATcٟz?iz>mWePqeFT=Ok]F ݈;8SL)˕i=]'Fӄ5Zz&9s=H>8V{j曬KWoTcEr &^a`YzE>;·v@cx9)j}|(ScȚ֑͇>Gɳ/kNg.z}dz:Gy13Ҏ8+{Q-nY Q+gq >||VA⨱_%FzG؀; A; G Y„/t^.M>y>Ug 4ƹlr,,kA=G+z 8R\Kjd&m" ?{v%$sի~ݫV"N՗mb5YLupV|x~1yD;&c"ő~0tY1Y7ȇpIii}oz|/Kdȿx.V.#Yz܆(/-u:CϏO ٷwXx}L7*E@ZX,ln~Z/v:gX/,GwZ1Z/+G&Ƚ-Y&$Ӎ2>tcwy^JM \X׃ۼUꛔ%L#ۻv0Xpq{Mq_q8Jyc盖7\gک%(Z{Rrm~貼5xMYr7p_?^baĞ~`0|<y)X zWag :k+ٵi.6š9$xǶј,ֹ{z\sqzxk}\בCK at[="GJ`y)Z(p䬱-%\v~nH5 Yؗ哎 @q ja?CZҁRJD֚mmx[h,7Ŷ+:A 0o_F5s ؗ%b@f﷡"=hL}lrp9Zn*Y9EᘶMe_B^5㝐vy_+к`;_=d?ql/Bs;3<9In_f=[ƚȏg"ҿL"7Azu:*at)r FȥK67Yޚ9Y*+TºC?p~@N6uP%An*wZ|O_bՐj}|)v/|t2y^p'[zuE >G_F1V Aһ6YDujb.HK7/1NxgaSkXv0־qLao=Hⵑŕ!0Ōj >rgD5(k@mYX]r՞)j`BE@WɳFn!5W#mkGG*&7o~Yc6l؎J?h_^5 Ǭئ| IZ`*:MnZcZɅ]۲xNn*jM\e1V@;;[+0\ K~A8֤]; tXM}hld_)- ɓz-/G>A?0nB^-˿>]_r(^(kp-=8*T@;!|ǢkP[del&Z^#5ocy㺸-c;^ɚAr}c<5j$ZUBmޝ%w}۸nFO9Wy}|r=x 0ueafg Z^f^J.:_딒~gD _|Fy7~[nzx1Ř1WQXGoyYE0g=ׅX>S$+yOϫ}O58Ϯ H fϲWDxG1ڹmy_aX;(jmm-K1l>egH R|8ٷ9bYt  { " ۏϽuYVvk۟پ@]D_Aaͯף˶>AZk({*[ A~C:H47#5v.ZPgZ_A'<`t O[ˇ0CX4P>1g2V4GʈGaN9{b]:iumnK; !8`k{N!|t󤿒aR`mx@곲a?YIAmeki7GkRNK7i곣eo֞Sؿ[P(k-m;%l)&uM+3\sz;zp<=|տu(m7,'1J[YM"(rvڕW18'#sfU!ԧ1k'01vl~krQYڣ gzZ*)Gѫ~]Iɢ8 r3pWmymG -Ec]N=D v1r̴a8'fs.Wa2@O1l9( HQ+ɩ6imq\IG*m}x t7iI"ۚCJg9;MtcڷX|W c<:XDX,(vJ>rεᨽEIEU975{Яm>mi߸^rnGӣ}o 8抬pupc ]6V{1"}n?25h+RoW|kJX>}{Yg yP.(3&5z"MikS>Η*^0$yk@ eU~_Qu1'=}=흆~6G'n2@b8בG{bٯCvvYkYzm!1grC>R]SPCi\ƾsH:rtľn)qĨbtؖXh#W q\__:~>30:<>"'} 'Z@?%Acsj%kް۹4.q-(9]==!k5 epQwl:>Xmi=; hb:R,糎En统:6IdUT=K7;ΡW;5^#%8F\I>%v^z w%,[M7б]Fϥ<"Q_4'3@'f/F먇>vcIL3r-JLݮkeFW{K2I!zϿ<`֘:uֹ1b^Cז1.Vf͙M<u0g({چl9d iqm+vt0K" [IEщ[٩,I_Y-oĎ͖>;Nj)Ն;v+Ml-6C_Zk&bVvS:"dܙrԐljw^oh ^>.Zm{ҀcVn:x5={Fc-wyܫg$8.nK\(.rMϸ>swfj]ls@h+ҧޤ!8n9-݋u m1tIH-ha~a'w/^z|Qzd lY^/Gh^NyhV# 0n ?_mZ?ưquO[М ~SWJs:|dYxfo|ة$8v%rO(rRI>r'{y֢ s(uWdVƷ9GG6OHWRl5cft8746:2xS,0vOo9AȉVc0BΛqs 15aj>|x4gԏяK3schnߗ(kW_ =ׂ7N,|TJ>#s9ޠtJ!_rljNB ~D4kdM13U%M~*e_$ŗh=%lO^HtZ= `#wn ^ԡa3gwޜo^ l5_I>c=Nǵ)Hk'rY5Ҳ|:ϥ WJ%5h׈vJ;N A]dkmA?6BY lG2~o; {k /~X*QNaȘBdâ\cg?鸶` tu=u.sS>*- (z`rlH}NvsetMw5s:iFpDrǍF9}6^W&$ܧI1̚>w@U#p>6|:ڞM?-s|F ➻##YBP7Ua .Cιenp^֜xr[ǜR[F> uaҦzuz-Ѯ | o" ramGrw ݁C6)"W}BCy۳o_ʘh!uzJiV-`<"f%᜚ܖlG@cC?4fUb!ZjIEG]`E?H~U,_ g$+X~XcumzOPKO\d}EE} g5J4r1ӌt2+=\vYa0Wxa"唙~97~>oqlr+8ۖwk>1Y) L=wDXl%IH3Gq"1sSK&d߭?939;/$tdz 8Vt1GG1>z~a}=>V]d^+XQ)[F37~Buoo0#o+#zyzy}¿sS4bI5PK{5cd]Թ'ph]fm`=;+Cu8S13S!mhOH:+c,}>YW#:vE~SH ~ Qzp&n/T [֐V}%cyin+v<湐z98OxSu/kO6l7k0:^,7жou}Yg!ݗ>m㞆_b>Sـ*ēqf8"Oׯ5Mkb]e$7/Grz:c[ښMm*!d^䗝;ZEeok_KnctGSu$`֠n%m>I\O󟮧c EiE9dc2O CVm|jJVq.@׃bq]h) _Kl!d7 0:tK3%]'Op˾u$z-2ͨ #5Ƙl0 -VъFvUY_ȱjy4eG|PAg1:F\̤ c*ZϲeaRx6v&q,")x1ځH{ [-\:ls~vk򸠯}s׿epC?YA-BgW+m 'mohkyVHӷ3z݊{{xuq{<%7#x{``^ԹZ{y^sDs)>IJ[#lN_ヰөy!O_ V9>'}|}}jh"^{ebK-|NN}Lj2bG1$x W<=H3-x8.Vjkٶ@T<N [p!0^wNO3N^]WO Yk߅mזy82[O~>3k@֔-8e;!XSʺXtoԶ"m\|dE_Qʽ|o2 pM#9Ԇcn Оs^FNJ?߶1} b)%+J~*瑺AɇcxI&>cttݥ]oNx lZs/?j>[v j(텮7Ge7+zdG;t'u&Y'awO h^a[9^mI>'W&7]}(ԌaWBDڮ۳yiѼgfFt&y*Үs]pɃ|u> 9s3T?eº5d {p ҰhWXYoKOVyG?>=pZrHyRq%3#-*i~x~A/2}* |?o{4cwct霚e4DǨ];>ʅB·k8@8_FC d߇ϱ4c&ht7Ad)Z;~dǒZヒj5iYQW<&sNޚmto/yNOۇjX˧ؾz^ ȄeP_QjyDrq%ຎQ$7):9l7b#h-0|rp}&WCqױg^5TZ4^f|GDǴU,_M>M_O(猕./ 6RRgG[c ߶w@F)(gș/ϛvSjshb{z,$S|~YLr1)Ǽ1Z9P>j(h(<}%DcPʮaFO=!wǻj@WB<7pdV.[@+%HuG=yqFPRW_2pgDz1U.̍|tɶ`rzv_6yء", {Gۚk#yH;cjʀn{q޾ԸܭCHVvOHmx<:vwJV|q5mnSg㹖%=9 zKB063!k &`Bֽ#G%J/wڼȷsҢiszrOg3Yo}ɺ?ɧkq!'dh1ӋP)zE-ٓ|ux`C>nGc0fylVvPYVNSsuuv94RSF&Wb&ncgD Č~zYS*ّ̢A//lτQzKj>~Z=EedhK2[ٯP $?"'sf;sS~CBd2bws-?q`ҰgQ7|@i9k>9g~O +f_ɧ˙ucn*=2{zlvWH,br sͺkˋs CE>ѯPcZDڥDr~{pq~ZLCaWr3/P1+#|yb=9(FeyZࣷz덽HWmFX r~Ŝ׾C8e"]txPaG^[ie o.1g*#kw<[㐕Ǯ:sl/ n18qx+m]_n hCq}`|r}1D|7#q7p@| 7l  Zuom̙lxl^ eĪ` V| {rC٪|FcgD Č~zj[Fcս_TPoHD|_֛#DN*g,~1F>/K߽k`JizGq0r>Hkk⮫e5!y.zloH>J%:tZzoǒGfW6tGѣC&8d^80\[X~%g4Q$KbE:@4>,Aaҙi5cVʿȣcJci,WjMcSYĢ ̷̌C}c 9󵆚>*&6IBc_juzlXy._3Om?׏oAVzMrMږz>S xL%}oj:C|,6Y?IOYxh>rC󿥾G>W66~Rkc͇owrtqqqq}kzҷWp0JAaݤLi DW//?إ}z55l>{52e-WcMh$.usl-x.Ac'H+OZkKqZ'xMo,GIOx;/o,fQ5n `ǺXmT5V+w1n'y!Zԟ&zfH5:r >jйV]%+Endh;Ǜlˍm5)u"׬9Ф&=iv_5ujWݵ'av}>;hv-`v;y )}{5|׺]Z16u~#lwNKBcH(?\%rv}XWٰy(rmO/,3z-yXk-L1]=?{C߲bM!HCϣ,vc6]Mw!R9!hn>9me>=KRr("[|AX6*h>7w4> <6l:O3}E˖O64kHmI0΁TӏmI \w&7#uad%pW'%p ǕtTO/zٿ3$WZSM9kv}(un}[o=:sY@b2 zZo1$;??}F Ϗ7`?ά~Z9\ӎXxKFlstO+7 `NS/Ǹ>|qpyd{Hݏ}|s;N@Hs&}iS1?< czy0a{lzc6Qd,VYDr!%S6iwjA-7p"7p5cTչ(k2E~nZ_P]ֹ0 t=?hVKcU__ڤhl1c1ѫ8-MN"F/Wtݻ8bm?s~"=^=(6xCc=:p~:7nzLX>2eIuARni[4bp{is۲ag h?f[)Ax8nn"˂Ǻg͘OnuΓ7|>j­0s+KE޷H[-ʅ`$hn<>zJb 7Û$KԌw0} >/ynXxw[WzbGZ-|ny2^ǭ?ٷJGK˽8K<9k~Z?z^Dt6\MYǺݣ:C?$sc`]Bo7ð~ؗdzӺ}R[C!À9po7B#|x'DVݲKsU.ږP[z!๴dD/2'j+l:x,h%?W=Wbyxqgs9 =-!膎= zݱ'x.-ixFy7~]/)G7x9F7Ue c!Q޲Z@Ƙmi[tD6$dSHg7Ig"t}c,"gd:[U`ֹvm:U?ĺC~,L=lGx}h|H>kwbfemKf&֞4" fl#mq{{|r̡<yf{op3|ȹhGic̼ަ-xQrY&C'7aGPb8:_,z\SqYB eߥ%m<ׂ`+s-c)E|"`_º;bӝՈ]Q:*?I a<ƚ`u&hR%'+:+w˓z݈KWidEEzN x1ָr,5 UMh]xs]+R{K R~#$ŧ9"qn,~m@StϭO {>Oh<WW]\\\\<??=roF$$Gɓ@v5R.../~C|}ݒB61#¬jL ϫ{?nMcG“ӊY7-.n5t_z zbixBy7;aF"ˀ3Γ4i1r͹bYn{=h:ӏ"|?@kJ_U=93nfuҺc}M6Δs܆-3ѹA0Yt}X>!gY5c[o?}XZj:GXuUy\\\\\+TnyoB^ol8X{9U0-Uţ 8_G~7)7B>%Ǎ%cklcM)K1jXDpqg=%=sce fNپIɾԇ;?{BeN mJa {aC.Sވku"ۧgΪ[K9d="9;Fklͣj^9qܤ.CGֶ!2|M#]HDuXð&8aBBy9q˖6V(&ZjXC| gӧx@Z;oZ`R atgBT5M+4& c$x5>}$tNKk}5P;D-\ ~yn *yp0W͓׍[S7,tU<;` ^n{\׃Vvz{M{5wό9ǀ*k [mǻpM>G~ѵN6ҍ/:ꃾ:5l3 fOKcp }Onq,د=Y;k4Tl&bۤ䭅Kw~kpfcĴ}^YHլ7PTH?%~u$;m=>nKTr1I#~}B_u=~`(6U?9S| rħ} 1#y&g!, H5 l-KcFSӖX9}>O9{(#^fE'"qN|"Fbc"tr> 9\[=&X -FL-_"tXc^+(UfSȵZ_Fᕺc \_zHRV?K}HqqԿdKyfvO3wß^>+i}Ki1=>O uP}!pB6WgI3=oӵ$*M*qӥ}g+ 1j,W@oOR$xs_7#@wyz8SI:>F_TPuPavH/$M % nA2a[$4>=ײJs==y)\X|v h tbUǪOLK_G֕XmgQq%d^ k.1=s oԣ',?~^ˑxm)G6$+iD^x_78/)`O^%G/v1#W^d5t nWAM ~Xk-1 =\32êIXi{'> r_;=,d?E}>~Nwzz US-F=5:HC"DY4_O՝3{rԊqfJ^)MO)zk v=ۋkrzQwy|7<9r7X@Ħ%`Bm XC677hyFx9֤W(i,>,ޙbd2sJk󜨧\窤,t<[Cb6v 饭xz#s3| ([ Asc׶!'9}txķb?+{-4".tit?8DsD BZ|*|=IK,7 `?jyX}b4VיsI'kMBWBs-u.S4Q{BiϯQ5Km 'HM4zkr>^^k|Hճ~\ܩזE]cvj9Rk2%d@뭃&sa]^͗ꍓuvQH z'BB5ctMzkol0dP9]3^YѭϮ☡vjuK_nlGJ;AGKofG[Ql5S}ыu-eDέg+Ysih0͔(w|eOaQ3)o5/ͯ|zom%y.. K:\O",ų]Z£7/k|,U\O1y!|:yaKxqs js<[zsaā J7V~h|LIEo7qg3$9/Ժ.jxEA7=^wSxK8VKX~eq6̽Z3^\mXqX ?OOomȁuzQ_ ߄_/1o[~ /G=ro4Xq T%acrw3BsYFƙyb7Z_u 3~mg+tVK[e5@XzNXkR~݈N*&]O:|ͱ$^p k.EΓz15lk?'H5u.BV{ts kVk _Ĵ)r2|s~O}o+ ~ɿutшWox/~)-}ś7{~/..|fπ|v6&m[DC)_.YI_ 0|\dTf)~QÓhMh `I>@m/׸'IM:"'ګhm YIu"I(mƂ])p=t]ިDgBt,n3˾֠2'B:w9l$_Rb2y Cr8sxO^g6lXޓ ,ܦEII?VX6,GGD!>Գrd٘=9oK^[=Ck+$?G:V, zZ!P&1 HFigOH?eJb`ך1՗Bn /igH=K}|l ]t-O0ݒ`[EShXz Ňt{ҡjTG*Jx90I*#'n<+bwF5N}4HG!kWt{G$ڞwz "v $6lo% } "1~Y鿼r]3'=ƾM?p:=IVOo/tO{[2OѺaD Iu}%7/yr_I[m雳T"ȿUۋC{Uŏ{Q~%  "m_K_Ecօ/ cC_g_"3&W0kK__" 4QsqqqJgk>V4Ll#Pc3~YAEM6a0We1܂{=r>"|-8.Ԅ؋eM-+c,eYiGgž{B)svW]OX, A^_}>9 aPyផ(ip Bg98cm(7oĀ"WK- 7ΓDcm5=!lT1]6(!GO@#S![[%N:BX9 'AZ3jo'wWC:,dY_D_}"m, pZ OµXRv,=!=qBQ_ӼsXeQ )?aҶIMtYPL=!= UISV(oO)(̼,"5!j~ul)#?m Y:9R^w㺈@2= <) fnR [.Zt:`$֘%u"1|LuԯS7Oi|Iv/Oh᾽XKL&0k&a,RסqP&ǧ4?XJn{H#m58qnn=}7ا'H'~7OS㻞~W7o)?>A?_I;WFI{'G>7h𦊟~;CۧǾr?xҿL_?կ~3i|8?_O?6}G}=|PԛpC.N&? kj|@qyc.zyGֈT~0"(:~!ׂ֒Fc= jkB3v." [om;Vv;_پfkHUkA{λK{!Jgqe\s#5/X;D}roE`]DX<_n@^3`Zk%g<)%#9zR$߃5Ѡ&Z0aG3ryGaTbFܱiݧ8֬$)ws$s /ʻڌB)!ϹxE _n!ooƧ?k#8~6 9׍h??'o`۟)mwO1+ŧ4~/O}} /u?/~o|a{~s.i߯oFO'?yzo^8;^FsUyMFƠ/Geݛ"IQy#fMIqtTon5AkzԙzNT|$_ qO}?JnƁ68G"a,cy{ˣ>][r&R<nJK>M ?;LyLo@s,Eb}Wk%zBk6~Pbzq:8EX+=a8W~3c6>on" ..C >_"_Cd?קȟSkRzS<Kez? _r6sqq1@xO"d{ro%7+-@cRǘD*Sd]@1wkYvq7'Ǵ^\pxnKKQ4..^&.NXm/r/lNXOga#y o;-v ʩM߫&%wrZSy `GIK+5|r)//\YufdxYr zn5h 5m~:Dj. oh;x?v[++{OfLPY^aa<8־;Zfto{'Eb E ؤWGO_+z7VA 8P_9&S{!I1d2dd >_ؗwLyU^13,=̬Żly#H9U3)Y*r7]YiKi{Oo"O}=X K]gI?ܬޓRXK ==o_ǯ4པO53BY '1P\I5 cIRJ:'_%iѹږ+E2)uTzȵt,5Ƭ YR͛DrK89ǚ?*y=9 XKa5CA~eR"?Q E я[!˷,G|A?o|?ݿ7/|=Ϳ7~#鮂QS-ϟ#O?~;ņvI_o 3!3ڡ%r/Z齸8 !nN=i[mC+͓N~O>ih{`]$ZsWnX<"7OnAՉ<rg^#r߈x"yȣa x7֌EN疨3x\\\<1$![;yU'=`nB/EBz,^ydJ|~F8Sx5u`s璤_>5:# rB /Va%~X"iuF3muEq?uo|r䈱^E'uvy,¾9?)^\j3 k|y_ ' |m_O>g}y_h7D7zoiL_*O?G~U)}:ǟl%}U S~/~ҿKř؈[0daPLX:3O"]Ge|{p, \0QizE,j3ڧe/۪>}$:Ǟ3BfǾw9|\~j1^j~nyYy{k? jڗ=Č+anݜH4'z$=SqDOgH4^=E'6:)>|Wof7T\ŸRӋCz1ɇ^}T<ZhdFhnku1΂;~c~R5'DŽr\ƿx_٣Wep^)>(^v\{D'D!m0tagtqӪ GOC;W?}˞ӗS mI{N;9,"boֳ_8 ߓgd"7̄Y8֊q5vcº꭭dVj22yn/4n=# k#ru[k#c\M}0X@!ia}1Ήsȏ3%u`"f8s,1g|\+rq6!`q&b*ѿXm.:wHx[<)Z;^f= =z|1hR屐J28m|^3e,T:lZJ>F"=O_~{y08 ~V^OVV~mP  ɛ^p֚bDmZҏM엝{r/ DXRfYf z%Հ'F/?YG?|II?$#奱U>>ݿnW$jxJj̒x&udynHK/,n%hX9J9At^s^ ۓU,_,>zx>μ0'Tk& {vKXd_{:5k[x^Vd,kbuX ,D'$E-IEJ3}sAn^ŧNiz(|~!?*J [q-6es[&xP|c¯<ߠo،O E^JL_GM[iXhrqq I%8<,G|㦔UD2xyzQd-Hq] 5u[^!^}5o\-FZ>ed, a] ֜9 ճخ?Gd,-SSyL.qo"EZHَho?OW~^\\\z'5-ˣ7|Ҟ|H?~kHk}<%W"؅-՜# 9\vq1?׸y>oKROV0K^#M uF?m$jӒ~l"e<ޒ'Aƚ'K_J adC]^~rM'oUC䋔p兖]ι.桵"ܐzB{+%ح;ytK9At..^A=<9{ovڵ.E>}Ux4ItTBYoI̼f, Ze_#{{.ʘ9#pX͕ԟj,z,OsBp?o>/dM'KI,zk<>ޒ+yۮǽ8c o$^^l[/>g8Vyk,+A qu3絪s ''y>|xzNRSqQ'cuZZɾ9@37']/ogYycsOF@)7Afj85+k-[-^Q| (]9x Jao\ȹki-Bi ЏO[qD{X5 Y/qpor V'g> 4^>*E@/;CÊ\\\\\Lo 'gDl`LلiN_wKޔʵ@?6`g͛(Ci5@=gF;j5:ɡVEKʱq\9>l> ]u`Vux~,]h|] bD~:@?5V$8v T]F u^߫^0;Tple׃rqkIPA8WmMC iƊڈ֢D^p~n]Գ2m !cSS>IJ>5M߫#)46b&ٗ:"zOwlx ZQؖYV\Hu/ʮcPΩj@hwMA0cPW&Qߠ?,@W|բR]\1K#:W.y_l7_GvNj$QJ!AQ.ByvmS?JҬCB,:4ǻqsgRqi?Im}tՆ4 a+|_[b%jM r,ӐNXڤDyQ:xY:7)d8*y-wim(u|,i[}"X\XY;s&\sSOh/?|WsDt B6ibX$QM V^8V*ZW YF7묾/|(G}~_|rKC?T?lTNw<}^\\\ ~۾>{-%o&ə&%q9v/@gc٠ߪ˭_w޽̽Z#ݓ{e|4/G<2<ּ>K.b'\"Z^_]>/xE r˾A"=fA%]\15sdk>oU3kWW,AyXìVd׏/y\65iF*دU@ qj?㵏r\Ɵ{v|1. }9>%޹mRmEcEd_[O?}u>ћ5S Sӿw=}Ohk~Ox(G-g~t~|_<Kemr1 yu69\ {~s=Q#Z̻|nwy-k߮t,3y:;L2x <"-grڬ|ya|&'kIM/mZ?@|>9 z@w\˃u5<1Ig{{Lm,,G}^ p8̉uϋZރO3"?o/>@i/-׋_x~ҷ]{f+k]{ d ̼փp}ЦP mkgF!sɯ;gC UtSAa}ϵH#ȭ1WӟiHh%ɻ^ ql-=}3d ˫mnUͳk4:/K].;xwr=ŧ/l}ȏ)]?lU|W=}qb }f|JO忔>ܟCoO /E='fS>F xƏO7p|oxW14O&Aoǖѹ뱲=`҆M5$+g9?O_U_#jg_Ԇ;||.0x 51ʱEBX5'O׃dƏ+څu1rOO[S5ڿ'c}}Gr ^Xy" KŞcy7ܷۡ!%_u>2GK<,])#k֘ݘߋ;)YX b=`0A"%,3{H<}ڛEDc"۲\\lkޒ7xs*{yׇ)Rɭha0 :Z\cMsIY9'2/~ڹF9I`v2R)>*ebw|SJ=ĉkYNFXW׵%/Q"<K;|zKZG>qi˿-VZZ }oHs?$8X/Kbe<~C ~j'\U7\Lf"$a@`3MUZDE[OE@ŶG* *`*2ZTT1Hd<<ګjժΩs]OUa5s"05MtژF>:C?z}~(  ~ )w|&:`PH?; |Ϗl'@< Oyh?kAl&7BBjK}-l&=`& 7!E&d vȓ71"F<[Lܸ|=IM'z`4!hK^ 7N~s)EsR@YE'(eh#T6I&%'^p?H G/+ |;M.Ï5&J=V7 "4|y1W=#$PV` xd"5FjP^\$ OHdΎ/u8BLI~_Y;c/X.2ȉ92hVo\:y51r-ͦvQ^SƥMo} R̿޾u_Seb侄K~RӖozBy˧t']lj}s kVSH- ;:!B\޳hi؆p;SIJZ.ѣ=i{*h>BL6뵄@ 2tZf8 ʡOxDKw P+߁\1jJ^pĹYkLK4mO)er#񸣌o62nI?)So1֐/lF& %ś'|DR&?ȉx=|bph'rx|<?xcB ~ 41~KɃ|1?ⶪk.~tǏIC@_W 1?ME"6G8|۹ &D2.$)|)="cڈqm#~C\J?Tso{]8 ńCiKvuR|4eܾE VST+mLM9~d(.ЎcxֺN`+m%bؔmqqWڧ3pČN>&w9 &o:.$1[4!A #Faxd? Ov2cH}q惢JO@.aܵ>}`b3s֠zdhǡ0=ڰ~1i%fv!_1N_7H3S񁞞umqmr Wm9 [Jy@5',:'RƠ3.0۸8dkJ>TƏ-}ٷO|ѥ.3M+|HzhcH8%~O8VHX,_3F bzqA }F}I`ҹrB:٠M6WEp^>&|px"~Ɠ(}J`Om"Q~aS GOHRĢe4uRvhWG ?҇ڈܧ! d!)!!ϴ.RJ0Aܻ@O4eBO(b-ҵw>ZMV$v|GK[ a2&4kG3&./~ |dMcZ#!ˌ{4~ 0s?[?ej2h\1~x_eR?ַt[Uu?mЏ|=AM .}> ,ȿӞjR^W>LLSRjn 29~s[}(漍WO #cSʸ~"M IѓW]ʞo|R;.Dr\o˻J'#n Ăѽb7@R X^Ȧ>mM =̋$A]Mܖ!U ߕ;xfdmm fƌ&Kv>dd*7GܖM ;:nq2E\6 3).v qL ##:R+U[/'&-01!)tʯ */M=F;g|Ww=YU$ؗҝhWaҿ]{+<т x@!h)?tcM~rcr'u_'Ȑ^v_gou9: *埵 AhFh\Hrli>&Yp[.M*AXBIso{g3dBiwv8~Cʋp8oЂ};7͏+[lj~k}@X|-J>L~;/sƐm%fxz vWS̞gm8;xLE5՟,k }1xP?77S}6Gz(-W/:ݰI|7};N\>Hsc3\oIGW@G~ɐvkoCbz}c?:/{6zB7#>)b|1GK UiSI.Pʑ/,/u(Cd~ ](HmQHEY7u{2:WKWF1zC6Ez1}4ioj~ہwlI'b`kW3j?8[*K##9ᶥ]Axb[#5m =} lt66gzՖ_Tk4\7fxy\>omI;DzɖKS3X9 ciح|ij^s|~GtZ1yt&lLZi}V$&^EX0y?Ӡ6scHhDqrکOA5gNcvy1q%6dQSTXյf{1Q5R&_)K\x)  Ba \{UxDw3TRf&%d,.Eu|7 +C3yCö/ nw6o-*/:|-uvH:ŝd;L~ܿ>OB-?ch:ee$W7b.7P5kp5T܂:n%5_bL~./!J:Ww~'"|09ğmݩ틯mm&hZ(l0I8y[\+ޏJVCAFb&NJUil6r6{xЏjLbǥkɬ}z ݾ6xѦlЅ fAU'vCX|X>0dkS6ƶϼ7xXx>!I)p$Ӽlt-y&-"]c ܐm)l@(ݧ_kJ{ܷDzM_ҭQ m7RBnuuxPZ(*&k!ڈ0 5*6J$:FoA>ӱϷ$Mڈ ohniLh=y-cp>tOMm ы_gޡ">uuc}XЯG%/ʐ ZT AӐũRd8z݂m٥@[,|翯ɦ4Ud7xjPEU-0v :a/r;J'zMQ\gR˷1&}eN~aۖZy6æ\#%6KUr"?h)7?:/BP(,#9}GhHm.&# 1sٗ1vxIo̶ 1ZLtNI^M/1?^v OLwl۲A^}CX/?7iӗ6!zlGEP8)?'t 쾮N1;} B0W1k ΃Dy._Ş[ĔP>qF!^7&Xx>KWM{ǧ'%%DZ!Ҁ~"),:OlXS%EThع2:R&t5Z$hik N8n=yS6"xureņFT-G\+ŬuM=9|iZ{C>MhRe(TY=H:-?oPDKQAۼ=vt> Έ3OxU&X1Jm+bql3߇ 5;zkP( gpɸB5 ˶YϷ۸ ?ϳ7ɮ#ЋmaQ{d815Wy\|ҳi$SI6h~jm&up UB&c iXeAvw.ka}}aTṷda.DŽ[mph_O9/}KbR-SC) f2n.¬hu~a] !P(macYi\}i2 G3EI*K:ָ/Cڲolpq!H (aUߗt0;k81؞9b`[iǽfkIGVnZ{(Yד:E.dA}o \"9$6)^ qiY8NSĔ)L P( f=СwAǶ]oW-bXZ?SR1> 4C<>)Lcu*YOSQLB污GC>0P(xcmӏ7)[lu)6>s }ʏ)s )WyoD{{m3%;Kl`ggipl xOOq~2!vo7WcS\_( @u]^0Suu_&_Gzd];1muk_LC4ôMc_DCC|i`.'ul=c }ٳ Eǚtp]>x9tk6}iC֡zT%w->!|z5=C!\5FSx5ૌ`SUˍ쟅[bu1'~@6Q mf.#H ノ!m 9b ?~QV/O6'}6IP_TmiEk{`OW#}11:R-'g}A=&ݎ ?TXWUg噴^b7`]]̾eV[tr[l%%Z7F?Ặ=̯kck#;#a=G[Fiϓ&DN $pauj\}{:v$=X;'n̶zde6:8mC蠵x,dno CuciF'Q>c˥tMm6{'@ĥcY˪+d\>sxhSԍ}f "T(;=(GĴֹvqB>~mſwT>:BP(,{Puq .spT!룼#껵O_n֢h&{@!f+ґRem{&;L?/C=kS=耤PLO,Mdk3ud> '1b(:h1uQ'_ρ2ɤI94aՍ9J1u4gåcSYyD.t<%@zW'% _M:@OZ>.b0 TqK=RhH#gAkvw10{cHl>!=W,=u:r˦5Ih~tڒڒԗLoQw>mt^l=5ύv̟ܘo6>pi<r($nW/݇ЃliPd,VۚўƐ2W@KǸ}A˻41:d^r_hHc /Nz>=OS#ߕ6xy6UkLG12% I7y+nMy| 7=g»ix]4d_QGtz VwF+'5bFcOBkhm@;=v -8ӪZLG^GU]ϰݞ[߲_ul~_>{/u)}П+rY@nfjcj qD]QP$gul cA~dP$RGSįAoyh2s &|S}_ S{~'vq k:}Ҥu]}&6w+Ice(T+UQǾK_3Ӎ}4zya^dY@ѝ >l))#OQR|b}6cL(`҇Ha$?Ӿ6 PA687^u*¬~:hn&P| &s`4HB"Vf'dҩTd7IO ޿:8cuA>:Mooz0˔>kmݐv-Bp<q ZNDt s-qΠ9uv.9Ws_0<_?\dW+}>mO)6DzFXD&i 4>5 |F^^8}Mϸ WטFnybh ]HLjPamV(b[=ۆ^]iťS'$Tĥ.C2EWӹI]1ҫɇ^p,֖I< ?%h41#҅}=ҚtmQzj|IP( c {עy7 lSmҤ%6%oJb7k'~#hnqjG Ж2NR|#H]l# | 2qvylAq:e /K4rPۡign?&@>7mڥI^롡W.݇q_-4LS>EOF%3;Mǔu$<7FmW(g6f:dkvojk})H4P.W^ vWmjeZP&N{ w̟?1ևCZ}*b11ү 6y)4c|l2ZZu[=ql(š,LGGt|)iXfiQzzb!1v^Yҟ(Pcl}E#տrltq+O,j "H z`?諡)˙ >zanj\X4P W`FKmse:Hto( n" ;~عn#&es@;;qj:CzpI^j6%]QY|+T)ok$ S}wtm??&"XOmOSzt}1[FYi /uuQ?MȶB~^t zb')|^?C9䓚:}_z@u>r5 Ç^U}'?mo?=ݦ>*1lS63|91κ߷4>H}w]T^Bi;r5יHf x%(=_GlPO&Py^=lsR_ I"Ҧ+1'ʪ( ݗW:5u抁6)mgZķ^|icM[:Nzw8(E)'`}t!sVv#},>Swazv<γ)iZܐݘp4=#d 467ćDPV޷uxŃ8`Nݤ,t¾ߔ K=?}?s&?cCm{4h_ŮML L8.5w{:e0@!b69 iggv 0Yso{FF:ڔ뼩Ј}=>/L_$&h$: ZK>;itVIf?m_ỷVR;FpY5lڐP}M O(ngP _5J`}Ĉs6`)l|ş}L h'Gx<#49?Uu{UuyA?å{8I$) Ѕ~C\J^n_lJ~':ODL8Ї'xi(n"md k}瓹lM1F8n(vG#uemkg{5d~}2TL<~^\_5Y9;y[j%4} b6Y,k4BoI؞@r꒻Zwh ]^@>35-`f ks '~_nM$) ]:Ǚ\ۘܲO~1;6: qHܫ4ߵ9QL/%o; ĐOZlט8 ';+x^‘S0d)W`rM6x"?6O Khn:0 O2 fĈnjE <8E.ȸ +G=kH3k n4۾<$/܀H1jlscÔkZ7f~. FDnIPѣ~n5+miyn#WzN_;l[AGl=amڔރCet'qicVcGBh~pc(2]\ħ}+6_F7[։VIcL=<}׫d8m!Է9}79'~ok ;:'`t.JI×CwIM4\;da= TƵI;v5})?lvrAJg1;l:n똘xYQ 'H;bE+^&'Z*C\Z;1]N?|&!61EcD,pwFo&ζFh>ޚͰ`Dڤc۵Isb}o Ɲ2v:S݈R^JkV'z~Nt hig"߰mfp:~}alc>}ԈI{ M^ Ay[A1&;x31ȃ֗he{ҧ=À>!1t'4"賽ճȼNW5bjWCHo} $>k#zt\G=flXXs U\~'lZ7Tu$g|xlz&?h|!itbk$6FNgbX!~] 퓘dUL9J+hMkJw6k?c;[՗'|PݷI{%[F/.F# ƓgCyOʌ#6{ tRֶu{_8p>#f1=֭4|uت:!@gzωV;qe=Ѿ;gaj]Nk)WdQgEi]ڶ+ͱ13mgզku_m̶M9iٸ!$Ik X5yFC&@H!K惔$Pi$M|d?{?>8Q^&9@0IDә;IA\܀xm ^B0W'Ul2hMJEN/dBaNp.Ţx,ts5Bv s -e%O9w|nIg,6Mst̡s>ldMl#td̥\L>$U| )@N$ߚ%X:NJ{ԡ'N0$l9Ƭz4Б4>zV?Q EMm /h'[W]iL )MӮB( R-vzgvߍ6EHgCǞ`-O^Lԅ@It_YtZgr&U]Fa[[g]>(8)3z"C*) )I$ /LF_s{-1xlbb^ h $ e4CI 7| ^Oz" ^k3^ _ S(،o7n A ɒ`>un>s39Lka;}@ѱm l ׄ6 MnO [n4(%Vk(I! "ōd> $uc}RG2à^Zy.Bm̐̊Md:ك3ulP<߷v?tDdt њ4i/zSvSݸ#zC)Z9MRJJ#IPRtc[ĝ#pz"]~K~#X)p>ɥdm|AXI\v $'}{ M?mUMy 1xlbrMt-6&hBĥ݇.L@;&Rl5Zm*s[i ވ;x"#rhOGsQn&LBAe >voin Fg1]SCZY.K@R$s"6O_m[ՓC7<] "-{nD?/wk,n/rܕ>-L^ϗ^R:ɦw16@!Vq]h 9¬M=|D5@y~Liլ"nߗF` .߱@i/z]zc ў N;cOx>>$:00i} CM &3`&84ѥ@7&z^L|{A3!+um1!>Pӯ~}SM{7:D55*gicA9L⠺i4h 8B*M@j=*+lum']ބ2, ~?cMU7cۜB__ 9DCMT>ibmҧn'ich;}']Cc) {AHVB4&1F굽7X%KM$%:K}}G'M]y [>?N^>zJȟvZ=*IK#.R.Ctz+(M_SCzksd6zm{W ;|no-"'EG*kqϧ&`7\?%Ҫ ԓ i DͱsX1CKt8#>ɉl>uѸr $ k.~|3K^Cvw=[f<{mo>u:ZN:f; g@x L<-Ẹ2onۇ x:0.EJŝ +` ސ1Zc~ RTN'멟/plZ<sꇱgחO1Kŧtmi}ټN7Nn0x&8 <$IBaڡ'ph.ʄd dttndXf)xOQH`*_ $zvMRBq9_8Ҿ& v~ yZzLVulo|so; BPMvgA7tsBGRخPc6?h˶gUmlm)ۄ>.9<DsB<_Ǘ%ڹNEa.TOqvv}mRρBP(WtOm WోmAywF^@/ǧGk Qs!61T3# YI ~ (+ˆ$SAFuÔ"]))j6l*ɭl= 5[MoJPfJ_RQw\}J H{r@!0Trz7U:x^4͡q^t_^qcȊ_5ژGbG4Jr[+CM|P1I<2[&_紝KxK-I꓎UPqMWJ# d [Mϐcߌ5[\GS6-)B%n'}䍓C-SiP=<1gJ7P[$!V1;ѽBeϨE )_Iy{\/mm6:Jl[|v ux}@u6#16P^\<mо[mgۤI[c:*T?$LSέOi^HWoį$ivrixU;/u!fɠ ׿4OIexKQ}j#>QZ\u[bOm>6ٖZyz4;Zy0ߵJC= )C'xg:|?BP(W. .0r>B D$JIIl#}h7N(/1u7xcCul2\s}<Dʛ i/ž/_JA:ZuW/'@ƁO5#@.cɺ7fPy_%|R~>h1hi^c0m:%.tnFKˁg N\2F7@:M 4#z!o2 jMӖf6#c}w)Lk pd4AÖFۇmgjNm Xu5KtZx +?Q:%U`3. בR&P/'Ɛ1 !e.VaCS$BPX$SSw';,n8ۛW"OڐyUI荹A03K1 Fݱ ?Ԙa&pt(cmWn#[//v'7f9!Rtjoj5p2:!%!􉢓n*lRӅ6j<؍MK۴Hge'vȷXSC4z1|uF} (籐Y#/@r)mM5Dm1:`|cwlSQ*l6LZjNelG PmUtCO`ӏhjOKTGtI|Q7fp|j>nGuSl&ɝ{ /Cmsۆ.xfdq}͘glS>K`;Ov#Wڵ4oqS~n#&xkr86ߖQGVxAYdgV-.>v6۔BPXß1 .r nHvL~粩,MrƐhO/P(88?$Ovk lkA߫E27vkv]9.6>o.&RL?w|t0+AspO MzD q]4..v̏cK$9r?)6s1>4}$5cl;KaWE`,i/1eI |Sʃ~Sը??~\}ϱzIbvtiǙ/O++I)cۍr,d#bҌ~M&*Cj0)3$ţ@H_X3{e, A,M.s_|M ;nvBR-$t铡h J(6@Ơ#&dƌӍm܅vդ0}LZtG[t,ѹ#B+c-"$ \)G|7rHtcWv{&w2ݶ]is`cTFb1ˏ1N)]$u[ ?4u%&O ܖ&vqqOx֦g16(,2'՞`_ǜg;Rv|شzق8ŦKmK_N=u Щ;qx} 6S@r^1P]V?x<_CdcP( @u]+vQ0itlvQwX|# yTc 16SU5OzACs7?z6+d3;{~QᾇoL3eP绿-vqs;GX m5JyWα^[7 qM]Tϸ#`&;=2Ljq6rƺ,q?}2]WM[7my꘲'l"ĿNdêIOM=͟}LvW_Meվ*Jg= w |A' tzR8ah|:x^ m[\A$n3٬XbLul(hlX3'FF<|Q8.06ʸ-U2}͖Vj"+ n ڴ%rw 7C& vږ"vl5I< 1@|B :MÛQ빍4JGi?rS ROIŗUU8V ˖gJgUT=oSnB2}x]E==0G|ʛfQJ](+[R´/^#Na"ۦM&nբBfTP.P/&M`?.Ưz0hjbQ V7>`ZŧQmnfS^8W|YvXlESGT9bP]W>uګvkh݆h9( E::I_]xͫ>pM- 22gSqaEGmHi y{}$NQGKO,f E" /,q`+x#!T/Eg+[k@4_F?։z1t$)e|6jmţΥܗ|xڬHǦF??zCmٟB/ב֔xiedZ-JD,N>.! !r]!=I_q}!M"5^c؆.[H_ rE`=a">5jelNOUI_ n8~8>C]HnQtcɹ~tlW?V' lR&pmp8x1Cm\#81>͗&6f7aa7K/`/{E;>dfe.~%Ob1dqc8Y&SCHPMH/ݳ}qG[SN&LsuI8vlu;{]Lӱ h˞åqmW )su IVG/]Yqv'Z(u8-j ?/}j}XC<>QytY.=ճ3U>/2{6:C&pحT{ 7˵k6M σ2 З8N+8 Baa`Gǀ0 %!}ʼ8nh" ́fhvA%ߴ'Xﶃ 1Bhe6mkO ԧ́fL})LT}-pY-]{d~pxs1\y~K/&C7I^m⥕,M&hqG&`ȡMuN$knnc ęaap^zR\!w|&AR}QXߌ%ʎ'<-MO1˼xe:H5I|:ާcӆa I RGPӨ)2$&qNBq LX T#1g? ;Q}cP(VCxǦCIC#.\ t@ =k:?R6B6ƎrԿIa0ZlԞso{h-0^+%VdTcL7,B2vQ΃$Ձmsۅcg#6n5j@\ \K[3$VicctR ׬1kulVj"}10'Ħs P NJ6P4yc!=LLm F } -۴cXя$1BP(Dx.w@(f¦]ܖoФ ݀D<h#+[(,~ kgU8 [9 %y>.{qǙ&sĊlo*;?{GMnR!Y5!r!=#q 6zե>7bħSG\Lv?> A~ir#BPX,STW+cs|U6QiR6_:O>% k*u[Jwq4b:d? AA`7cUD{"_1*^9qjmlqP)˓XUZ}G#81|z}0^c3'CMyT Nq~}{nv[~d ԉ<64}MKc!nۤW/tʩ[m18^Fݎybt3yMCƝc e(@d9ORt|->'ʷN_#'bu!w_䓖FDLvU mq:qbʹ65ëZ߽Kf< Hd>Q_%RJǟ8C뭚:>:ON0Kݱxt~ Q:&p|_Le^9}ĉ mbc/MF j,Z cu{gKгC/|[F\9n?yxa6{.v&>ϦPئwEeǾxOL l{b3yX_vXEj Eiu)ˊ}dL|M1.;QA?΃0ӵ_ ~k&|d؊Hu>JiiƂL+'+QOPحvZoՌ%jٻi3!#?K >絃ݝ| ]FO˦;?}q5,ZlOZ=N4| o)wN=сv˴>zgt*k.c5M9ՇbS6s@U'+v@a6S9Crf:sPЗy@$Sw[m~1x}^>]1H5nYFWWgƈCw43EқJjP> <\DjLS!d]ϭçvJS.Q.e2M"ib99|L4F}e¬'ӡ)}0?PGapM=jLQf}ǐA/6)ժ PGgp4b-DlU#mZ,>ZU 5ALW+k}'\cm)[# )q14V]SIXM|cȸ=ֲ“.nVKNLbȊcؤo 5cȊNJ_jV嵴9/)9/BDr;$4sjq=uz7/DM׫NP_>"}M_k~ M+6>tC5Ab3,>W:2:Pyξ2W/s}*ԛϔ5MWMĐr 1u`X;_^o546_./ [btPɈYt$g]EMK᱋@z=~h!-VV^.E~b :6RHݴNV@84=Bn/W7Zwnʌ^Z~ "td6lI_Cck(n~alLsy귥r,-'x[|9mjHCGgvLu4Wҗ1*R: Yu\R|5egX-XxA}1ABtjZ/֎pPR\-v_[&Wl˞߄XGxT=_y/,Nװ#$(mCMai=Y(&uphzOE8Ap$+`ܖise~y$r\v -n$}i.݂//I&CPz[.QPFBa4t=ҥ!Y/&hHKyH|N-Jv`Or1i3j~N|cq{ Q07m,E ^k +^8}L! CЌ#uT̂m'va# ;VKk'vN2lWo-sչxD×>%|~/xABR(D*{!4bǞ?_)[~?t|`H$U##`%)cLy\<P_m>GfA8#ԛAyO|'xGW7n)i,3*4sI&i!v^?~j ߄,sSmդmډkZsz{ h%xHY&Bc$`;LZ1u$޳7: NY0\1N|G}06tvǻћdۇ-z 1=\dp[qhİ }rm|!j{a>! _ B:C?ot$'A/W7f`iͪ@˶trz8 yT/Aw.c!ئt2&8vQxw㏻j$96E[r=m<6BksK>4~]s7XhcŘ7-c 1|qXK+EOjaƵBԳ:xnK[OȃX6n(Y^+X~h\ RX ]k >_MXKgqs:tӞ?Zy!_'۲pm/O%֋YkVxGdX2F0 Xw qH ap2 _c|F en4Sa|Sx0IVL9(H  AS\rthbCޟcѴo,H(fR7vL}!:ۚ0g1 Gۭ͐&azV)+1;hk!h?_7CF' KdڰI4*`ߖ~/~mo2{d> { \O'͡{|XZ|6lR(H9Y҉'!$ºƿv |)F/l?r+lt,ltVS]|CY_XORbC2Zl#Y1jv2C/a&rڲ415fod_c~1@_0Ib / oqŇ[Q}9jW!%G!|=3+TusoT|:9>h=AY9zͯϔUi{ Ps Hw*P ab08F=êcFЫSq} 1>1~Bm~ԑV?'~Lc?SWg'AH?TH\Wn+wN6FnCH#q!tOim bnzkH!NfQ}_ݨv@رv)v^צFI9m2j #җiAOi~Kly2MǨrAczj$;ɴrƷ/< _:tzTݼ7/}i"luc<Ͷa]Ũ6NdUeNO}O9fq֔ ?Ԩ/v^R ϳpUOHT3LIVZ]f Y fy="AVkn3A5TDf_oëՄ;f=R5cׂMeqjʰ/;[X]HóGGQL}+诿m#Cm()a2WZt| 9ZOJ4Oͦrzj=zx9Q^.ã~4^Ǻ'ch!=͊BO&"L654?l 'cGb mg8JgpH@yH# JT dיRB?}ScicCCI7YdaݧėDɦ#P'MtFɖΎLW5bEsp·qsۡ5HB~HahMԳNs@J)!*O'_F7˹i2f:u3am?"ҍNL ӗ7a_6:ࣉ|?^qiNvn*SaK=0H/*cuv!}s_SRhjUN|8TPj=w-J]b*$|1K!<#an)7i&>Jp?5:0#3f3ױpCR:VhHSx$96:kRiqiGK5!<]7 H;CmL1[qӦZ ʋ15n2&u_rCԐ:1F$LmC.ʳ:.!3~QZR/mP혱OB# %=\۬7> ׮)>:@uym@dMsc3_1um\k>YL!VƨSorx hA;-mzQT2CˈOD4Ķ7BBO+r Q(߸NT^EMktb V/gy]a5j~$a٢>ΐŐ*d zu;l[V6w #A}K=B`jEu C:=D5}|x;oLBO~ey\P7>͇): !1t_[b ]ӯ@i(۔6fDFOGFL2|hm!cʼ-mw?5_-^fFV o/*%elu|¶3&S:~ .C1n^XY0&R$Zں85 q<I)z>F kBW !A_1>B1O_ Mƴ&U y9έہvO>Dv0 ڽB8G`Oy/'[eV8Dv;)q打 BI S Pcr?@!o>ɓ&2Nh?*ّ}sXy`iϧH L\^imZ@/kv-]/k֪= GBaڇ0ģ&?P'E0*YzL9Fʮ=*2w͒51E'H0/ޑF`} hEĎ^ތO@vYvkR0apqpRC&%j=z #kvmSxt1=w*+wsCl,c c[/SSҤPX4Q~}Ykk:^~8l hKH C2?LZ?r]N}|$i` Z"2Gs"[q;L3~iUN+?5~| '/K}1!!ؤ6vmRbb:np{|M>0Ox8R]7Mc5~m2=Ԧ )eV K  G4VuSt94u~~#A; R½yҮ;궦aAIǜV&uinT.mPSʬX[rV|lR[|SqxY-;%܇[9=sEM}*Tz ꫌TmB/tP=͑v|( 5):ƀ.Me -׷gKJ]ޢI psČ'鶅 Q8C\6FD< {pCjXtA:aX%PVTש q=ݴڮ1ֹ"C}oΘ>+FsF Gir>6g:֗9mnTL o1ٶuB}̗'Toz^zQ( +"2m%I7 qpZ B}ಎ3 lS[$te$lZ6t!eGP_,GjlL Փ %ܾ=(}C%/}* +i<#\/O^J$,%sMQo0 RBƭz#a Z}z!YbH}9 [ Q9:i |sBnf&됒c;5!4I,]|OJn'do MO)HTzN S\ -_._c G!{95ҥ-3:cK -CDCOS9B>;ǁ/1YeGP(8@f;ol2rTk-\8-@=+ IM B}hZzLF+'5IX*m-]ljoO0 ާC]7ʸ,gMbI,)8 B~זprY2S=Ac,<^|؇Mg۷ 0t YvյMzLP.5B߱SdbtV>"@/, $ q,5]`vSO!r}Nǐ[B>#kX.ׯ-C%݀E+inҿ~OuёW3`rI u?^R﻾׬w{ՙkLp|qPu!{so]·ݵݮz=Xχܫgؼ;69l!P 覑?r[: HBoA"APh7^<%_YJR2&ແ޴vl4.o)|;!u|?m Qw y%U?bВJPpx:_I̺6E=/!x9mv[ ue(\\$_^MѭS͵ frm5C(0x i?fш!r\պǝpBW#WUo??o_"+Ij^ W}I-Cn߇ix<ޥ1=o|. ˞o߷W^w%յW]Ygf I _'p;V~GUOgU-EG;X8XqcGv1ۡq1'sO8q@uB0pXYڲTȷHqӖB-.Z!iY7sy>))?\r\@-6O$Dj9V'UBhyJPXBhyuAVoUB>kihm w#5$>d6kmSrl:bG"iY>W[\*<<".h(M/O)b>LmGӵ<7V}M#9=rWVǜX]q]_{|wn8f ?>i4BRX=7^}Du1'W}mzO~]=RZN; jy|cwOuUW}Ҏ@h阼wz<3y^BW@[`'U=z>#ƜgI&p^40A/{IwŦck>1LG~_u^`đupcm?d]&p6vX\ei͕ GMa1)"1ho.ud t h2M#d=8.qǚlʓa^^9zV }H馻e1@ė⃗іUmr A _.CHt<pr ͂M?xʑ걧TU ?qw}MRPߒ~ -Ogκg÷~)H-]]yYkKa~!2͘x^lNm"Q<o(Oy?RU?z_yKW;<?B <e@\^;/nx贴'p`vZǹH};Mz ovI *-[[ ټPv &BaՌ=]9U07:9PQFfw>(].k@cHBee(3Po|ˍsPU'>s'o-ίrҭ]JU~g~=vy(yxď8K\u >&ROxOXu'ٴ}_/~auڕ'koL^0O} $W@~ᑏV_2l OJ+zه/.յ7M?_}u=^aFO_qet|+j/sDuKI-ǁX[4?>K|.VM=[_ a1 8Y*6κ|g;K1Cr8q) ǺSH( aIs!|S~^螂 #8_͗OmgGN@]^>wTd1L?П\{<{:'{ R9u&8h`_yV yo„LxgdkSdz˞& ۔ޣ3!y7A=3`w";=㊽cxRƛNw 6~WG~՟}jϤ}V_:[ןR 'Wo경w_=A[qjG޷+_>OX{~O}Kӎ9+gOsJ?u9v]7Sڲj`'s+pZ>Ľ~=I{܌ұ8o^_[ g`MƢEa;D SuҹmL90UBERȍ -&eih>a_7r %JhTRgI).Um%/+ue.o .ʔ&oD[GU{i}2z~pF"Ү_ʡ_m mI(KS.Cժky70iFyTɧ&oWpLiVGng?Wu۹iI)rMN]Oo'#`ҿ6w=yqY /'@0ZvvǥG~Ӫ9\?rj\ٮ;W]kՋ.du]PۏX VW[g,[~W|7R괫.lKYz7qc\[ :bSؼS s 8x i*TsD  _z!=s/05$3S^^[ -~m esB4d<7T?MO\X\[=s3:ՖxYʜ+SwS>sb^]S)z.8P 'n`Mt.A7 _7UO_W~Ib&5ڞ.Fl;;7\]is{?[OW~}n9U~'[}W ߁7[9)Xsͫ ג ?M'Z|ot)4y^Mom ߪyx _rͥpB hCX_2& rxbCO~+^YAk:ijMȧ8.8tXPupxͪpgCArۚL<^X] 4J;OVg|ۃ?RvUg;=2?yQ{)UKl=z@iǟPoZ;fnvz܃xn}ۦ?Wՙx˭6P~񷪏Ӭ^{՝L[\OoPnmȧ_mpyR#'q1N,s@z[+%LҠvR\B}ҷ9rrt,>n"fz?-urv$|KvIՁNnEϥ[au\/!b= +'7ƾ.c锇Lb ɸA@7Un'pi6H Vg(n6~K̶i 6pBy<*xˍl`? ԓvC7$;yZU7;ρ{L9g?>7.~E5* 4U=mG^A]y}@ (Ρ5Xr=㢣ר6ۜ|B{~=wuo}qvu=ڻ o7iug/sK?Y>Z~ }5Oy{݇O/T'ꦫl8N8tO^bAw~/V7ٶӓF𤏓|~!Khp⃗R(cV( 6ɦЋؐp)Ds$!$Sı:TCu&O i:9lΑ/+;;|xOJm@ha=qPD 'vn5#_٥8r:xq]BU]?Z=nO(B4O{k'o5*/oI܃FxIDAT4mBN|E&pַN?8Y`2'bE}sm^SOs{~?Dw\pNu?_r'h`"?745AI(IVbhu B:+;u9qe >.SiRXh}91'e ?H)C{Pf:,&op8w|vE$5!QEs^Ul_G?^zǓH͂m`&k`&s`|TOH?Eo_]|2<N8fv](,MXtm4tH%<ȵWWT?V*40AYpZ<.ꔿ{ڣZNO;&@`ixbkV9O8r56\N4SW)ڔx &stnoqz>aBPX%oڲd69xHֺ"}ѤP(>0Jy~jWH ⏷I0Z Ha)\(d(PNP[}>n8# [nk:.|Ox{?pMe[v]/) Lx~ӓ7kT Sڦז<ԥf&s>ʯ|nOAN&1lg&p,ep}T?ʛntyW+ꏇ}խ%Bi}3s 4o߫7Nzy}Rŗvy}RAHIg>aՕy6Ґ'kINù.^GO~'^uzѥy?ꦯ'>Lػ} _wWɦsQ>Ayz O ˺,wۄftkRǮ\eZu;mBa.8Ӗ_"]ɔ K/'KDG&ZV6YP:yY)bNj’z 3?/5)ԁ"31U)L}( eA/o_,Z{62 IFh2ǂx^\3~߿0y㢷۫<^꿼v 9I1-L g?ˮi&s|=Ux#섎W擞R7y? }Oƕv{*ףhfs_ }J O{Wp\J zU_O4iZF,^Wt2?xEGq[].8t؛y)7Ϻ1n+g^{fug7;{[S7}>'Rw9pSM9[kOOy#z'Bi{ٟW>b,XrEUP?o|ԖmG~#v eᄎL!󐦛M/o|icFfvRlNUf)*J31TQݤXXuR+]>Kifcx!?Tk\%7z>r[Xck:$ZojGlsPZi엤הʧuɜͥO3uٶF{͟KhLbJ}=jHWCN ~Oq賃>y#aip3S !hgۧ~vʘ -c'IΘ_}I5<& 6V眺<ϻl; znwA_s:7O|]ONs3UGV?`'o ^WU#U#W<0w=OmLx&o!C$ L4'ps}#+=z-Б!x`wyK)wOg?v>կ}~yXt)ӁIg6ի d-Յ?է>|?S߾]KՑoN<$O-w t*7NkoxWi'̓od ?*tŖa7ldьBdhKYu` ׁep?ڒJluAen-,`=Rեt%qd洝ѤOmĖ NQ%P4Ձt9|ׇ|ܵPc) Z{c2wo9eAnB:t-uGzZJ D`}2PE27Im )c&\JKs{Stp#`'&ү4Dk3x6U |Hסs0q6OIPθs-_B\~ŗ?m&oW~.lYR)O݈ r>xx³>f]Oy/840ɂ^r;]]{U'o⏛1hCzytR*sWyOXS﻾NV>v Ǡ(e!_#/ꁏz}cg=djCUi?Rˍ^ L|5s_8'۫?v6՛I878w8:"swC2>'T16cNs|M%x"͍dP6ELlA*\VҴ'W ަeB޼mPkLoFx<?XG9:DG9cH>)FhB`*=#O1 ez|H/&6OkESF4-֐=EHKWW_wg4w-Ak 7D-Dys|uj&}Oo9#h#ܮHۯz>I͐3w8)R|heh"3nKFh:Q$شjiYy]܆&oDkBe;"_7)Z[|w>܇2`}<5h Q^In#x55&oL7]W+t&q|.ontC\RҡAon^ .x \gg>Zb'DE@16cr}OW9.v^M-ny~ݟ8:S7ξie7IBO}N|:M!ݴtMN;Ӕ=Ŕp]O8gUoט=퐺gd]MLdF'/=_ߨoN~OwtLsf^IflRVN:l!9Cՙw{5~z׃ϛ).#mΏw\uh˪r0a]dc:x?k˦@j5|¦#sG'9g!+ ԇutr_ȿIՄoC#Z0?vD/e,+ bi;-$JwvU:Sd9/1;[_wiW[O3x^b'm)'okJu>h_rkP}V{^ca'~N쏔eW|{,7LxS=!]=a+K8E{nPHwmOiФ M@B5[9ą6ʧʺZRhep2:mҖ%2?3WwE{ؚ+ ^ti+Bӗ҇C8UCNb&P ePw?K_dѾCj4́f'UVAh}O.Η1vH6vy?X]p$L &gKB6Isk櫟USom yD;>HEa3+J>S*@SƀIxbyKҏ}% W<zU_+'|bexInʪ *D|)7:P(ؑΟѱs~"6oa,wOj#k'eP?f?w˥P6y@(~P&x)=Cu7_Vǟp&}0 |K_yng|e|J*H'e'p='jt|thepy;?dUm5co;:eozze_5W=mv賿nRYlMnA.[.&B_Ԕ/kN ~5A]I:?Vj)~r2h:KZWBY,Kk58e~m)ưo}胫<ԇ5*SvM1$?SOn+ 4r>rN,W֖20~1't|*AOy~Xy+1M8\'S^[=kF<={{uLI’IH_×1p=2z̠&!|!J 9_ 3ɶ Ǯ</mux˸l8}|Yܾ\4By: }˪bQNy4K_ _9 )C$\ {alS0 ٽ !]Z;bʶ!cbHP~IZ֥F%d̍S\qL -cZ-ݮ\9\^.Ms|K_i:::j p̈́9n SȔu275M˛s.K`YHۻ~u}lqL6sqT !>K'R?1`+N7O\"jW%@ Aey7^L7ˇ{o{Ƹ;wι9LgUE{[.u4z#s)#'i# y0 ӷh8 ӤP(b[Brr),u"fqeHǍnhK |ˮj/ޟr&֔02v6[Hr1"=gfՂ7(ZOSKF3'Rϐ|(΢Sԗ9Oo,G\ K|B^gP(l^qeULas&p ?H%/ǗM>thR_!I d-(~B_(K)Т2/osBNH]_za3$, >8_MTM}tkkev6~~KRGmEO GQmrn=+_rucC[.}h"ǘp|)MnR<ƌm@$CSTUjxLMvi˒(#D"MF߶(8 BaC }/l/)8d|C1Q/7@P)”cP( d\+ɏS8p\ sVUWwI 85SfJ 8d1\_?CT 8K udYxsJB4_;zC>2RjrmT'7i혋!m9avD"6֣۟uQm:1u %Ŧޱݺ䔭s_Ấ a>OR͏-x "xr֯(fק 7GI;qf \řPڏKS~}6GD!u~1ԟUr}syS#. C,;Lٹ YǸ3 ߹=t!WO_%6.Zr9+BKL991]}4Lߊ!w̤2 bM/}۫ٸ'p  |K^N.e{cUF}~\r}n?߲lS,p[8ZڶS.ۄ֚r4 ! ~.VtǼd!n(Z=Ч):/s7q/}/}dkUGu[=_/BP.mes?f@DIENDB`uTox-0.17.1/langs/000077500000000000000000000000001354126257400136545ustar00rootroot00000000000000uTox-0.17.1/langs/bg.h000066400000000000000000000656761354126257400144410ustar00rootroot00000000000000/****************************************************************************** *** English i18l Strings *** ******************************************************************************/ msgid(LANG_NATIVE_NAME) msgstr("Български") msgid(LANG_ENGLISH_NAME) msgstr("BULGARIAN") /****************************************************************************** *** Splash Message & Change Log *** ******************************************************************************/ msgid(SPLASH_TITLE) msgstr("Добри дошли в по-новия uTox!") msgid(SPLASH_TEXT) msgstr("Вече сте с версия 0.16.1! Кодово име: без шапки!") msgid(CHANGE_LOG_TITLE) msgstr("Промени в 0.16.1 (моля проверете нашият уебсайт, utox.io)") msgid(CHANGE_LOG_TEXT) msgstr( "\n ВАЖНО съобщение за WINDOWS потребителите\n" " Съществува проблем с актуализатора, при което той не работи с някои имена на .exe файла.\n" " За да сте сигурни, че ще работи автоматичното актуализиране преименувайте .exe файла на \"uTox.exe\"\n" " и активирайте функцията в настройките.\n" "\n" " Нововъведения:\n" " Вече се запазва езика.\n" " Добавени са групови аудио разговори.\n" " Потребителски зададени РВС във видео разговорите.\n" " Поправки:\n" " OS X подобрения в стабилността.\n" " Видеото отново работи под Linuх.\n" " Поправки и подобрения в потребителския изглед. (Благодарности на @redmanmale!)\n" " Поправено е заглавието на видео прозореца под Windows. (Благодарности на @thorpelawrence!)\n" " Поправени са причините за сриване при групов чат.\n" " Натискането със среден бутон и двоен клик вече работят коректно в X11. (Благодарности на @dkmoz!)\n" " Уникод линковете вече работят под Windows.\n" " Имената на прехвърляните файлове вече се запазват под Windows.\n" " Автоматичното приемане на прехвърлянията на файлове вече пак се запаметяват.\n" " Вече аудиоизвестията се изпълняват, когато uTox не е на фокус.\n" " Съобщенията не се маркират като непрочетени, ако чата е отворен, в момента на получаване.\n" " Избирачът на файлове пад GTK вече работи и за OpenBSD и NetBSD.\n" " Поправена опция за автостарт.\n" " Поправени известия при писане.\n" " Добавени времеви точки при изнасяне на дискусията.\n" " В разработка:\n" " Отхвърлена поддръжка на ToxDNS.\n" " Инструкции за компилиране под OS X вече съществуват. (Благодарности на @publicarray!)\n" " Тестовете вече се извършват за OS X както и под Linux.\n" " Добавен скрипт на Python за откриване на липсващи преводи.\n" " Намален размер на MinSizeRel компилации.\n" " Обновени множество преводи.\n" "\n" " Знаете ли друг език? Желаете ли да четете промените по версията на друг език?\n" " Помогнете ни да преведем uTox!\n" "\nv0.15.0\n" " Fixes:\n" " Video now works on Windows again.\n" " Autoaccepting files in portable mode now saves to the portable folder.\n" " Updated Ukrainian translation. (Thanks v2e!)\n" " Dbus notifications should now work on more different setups.\n" " Development\n" " Added support for NetBSD, OpenBSD, and FreeBSD.\n" " Refactored the UI.\n" "\n Do you know another language? Rather read the changelog in your language?\n" " Help us translate uTox!\n" "\nv0.14.0\n" " Features:\n" " Real Updater.\n" " -- uTox now has an updater built in. Currently Windows only.\n" " -- But can be adapted to any platform if there's any interest.\n" " Added musl libc support.\n" " uTox is now compiled with stronger exploit protection.\n" " Significant reduction in memory usage for friend list.\n" " Fixes:\n" " New Nospams no longer start with 0000 on window.\n" " Fixed button alignment with Language selection.\n" " The tox save is no longer truncated at exit.\n" " The tray icon now always displays a square\n" " -- Even on broken display managers (uTox looks at gnome...)\n" " Bootstrap nodes list updated.\n" " Avatars can now be deleted.\n" " Notifications are no longer ignored when uTox is minimized.\n" " A few more file transfer fixes.\n" " -- Especially the last remaining one that would occasionally miss updates.\n" " Development\n" " All remaining warnings we fixed, -Werror was added\n" " Tests added:\n" " uTox Updater\n" " Chatlog reading and writing\n" " Refactored the UI a bit more. Which cleared out a few more of the UI glitches.\n" "\nv0.13.0\n" " Features:\n" " You can now paste UTF8 characters in uTox.\n" " You can now manually set your nospam!\n" "\n Fixes:\n" " Mostly fix groupchats. (At least they no longer crash uTox instantly..)\n" " Chatlogs can now be saved on Windows again.\n" " Clearing chat backlog no longer crashes uTox.\n" " Plug a lot of memory leaks.\n" " Scrolling with pgup/pgdn now redraws the chat window.\n" " Avatars now load again.\n" " Custom themes now work and won't crash uTox if you try to switch to it when it doesn't exist.\n" " Lots of build system improvements.\n" " Lots of file transfer fixes.\n" "\n Development\n" " uTox now has a unit test implemented! (Hopefully this means we'll never have a bug ever again.)\n" " UI files separated into UI components and layout.\n" " We now have our own build server!\n" "\nv0.12.2\n" " Fixed a Windows UI hang during file transfers.\n" " Fixed a Windows Crash during file transfers.\n" "\nv0.11.1\n" " Fixed crash with some transfers.\n" " Bug Fixes\n" " Fixed building on Windows XP\n" " Friend request improvements\n" " Added the ability to change nospam\n" " Added notifications and advanced tab to settings\n" " New updater\n" " Started seperating the core and the UI\n" "\nv0.11.1\n" " Feature: Export chatlog\n" " Feature: Added ability to decline an incoming call\n" " Various security fixes\n" " Fixed icon issues\n" " Better build system\n" " Switched to TokTok/c-toxcore\n" " Improvements to development process to allow for easier contribution of code\n" " New themes: Solarized light and Solarized dark\n" " Updated translations\n" " filter_audio optimisations\n" " Started using clang-format\n" " Stopped using clang-format\n" " New, shinier toggle buttons (thanks, tsudoko!)\n" " Better support for auto-accepting file transfers\n" " Fixed UI issues with the lock screen\n" "\nv0.11.0\n" " Were sorry, but the changelog for this version of uTox\n" " is only available to uTox GOLD Members.\n" "\nv0.9.8\n" " Fixed a crash when trying to create a new profile\n" "\nv0.9.7\n" " Some minor GUI fixes\n" " Replaced all Yes/No dropdowns with Switches\n" " Fixed saving proxy host & port across restarts.\n" "\nv0.9.5\n" " Inline video for OSX\n" " Fixed a logging bug\n" "\nv0.9.3\n" " Fixed a message bug causing sporatic crashes in Windows\n" " Limited the number of Messages to resend at once\n" "\nv0.9.2\n" " Source Cleanups/Dir changes\n" "\nv0.9.1\n" " Fixed a crash when sending a message to a new fiend\n" "\nv0.9.0\n" " Message queuing\n" " Better, and colorized groupchats\n" " Experimental Inline Video support\n" " Mini Contact list\n" " Refactored message handling\n" "\n") /****************************************************************************** *** MISC & UNSORTED *** ******************************************************************************/ msgid(REQ_SENT) msgstr("Поканата за приятелство е изпратена! Приятелят Ви ще се появи онлайн, когато поканата бъде приета.") msgid(REQ_INVALID_ID) msgstr("Грешка: Невалиден Tox идентификатор") msgid(REQ_ADDED_NO_FREQ_SENT) msgstr("Бележка: Приятелят е добавен, но поканата не е изпратена (липсва антиспам код)") msgid(REQ_EMPTY_ID) msgstr("Грешка: Не е зададен Tox идентификатор") msgid(REQ_LONG_MSG) msgstr("Грешка: Съобщението е прекалено дълго") msgid(REQ_NO_MSG) msgstr("Грешка: Празно съобщение") msgid(REQ_SELF_ID) msgstr("Грешка: Tox идентификацията е вашата идентификация") msgid(REQ_ALREADY_FRIENDS) msgstr("Грешка: Тох идентификацията е вече в списъка с приятели") msgid(REQ_UNKNOWN) msgstr("Грешка: Неизвестно") msgid(REQ_BAD_CHECKSUM) msgstr("Грешка: Невалидна Tox идентификация (грешна сума)") msgid(REQ_BAD_NOSPAM) msgstr("Грешка: Невалидна Tox идентификация (грешна антиспам стойност)") msgid(REQ_NO_MEMORY) msgstr("Грешка: Недостатъчно памет") msgid(SEND_FILE) msgstr("Изпрати файл") msgid(SAVE_FILE) msgstr("Запази файл") msgid(WHERE_TO_SAVE_FILE_PROMPT) msgstr("Къде желаете да запазите \"%.*s\"?") msgid(WHERE_TO_SAVE_FILE) msgstr("Къде желаете да запазите файла?") msgid(SEND_FILE_PROMPT) msgstr("Изберете един или повече файлове за изпращане.") msgid(SCREEN_CAPTURE_PROMPT) msgstr("Начертайте кутия около зоната от екрана, която искате да изпратите.") /****************************************************************************** *** File Transfer Strings *** ******************************************************************************/ msgid(TRANSFER_NEW) msgstr("Ново прехвърляне на файл") msgid(TRANSFER_STARTED) msgstr("Начало на прехвърлянето на файл") msgid(TRANSFER___) msgstr("...") msgid(TRANSFER_PAUSED) msgstr("Прехвърлянето е паузирано") msgid(TRANSFER_BROKEN) msgstr("Прехвърлянето се провали") msgid(TRANSFER_CANCELLED) msgstr("Прехвърлянето е отказано") msgid(TRANSFER_COMPLETE) msgstr("Прехвърлянето приключи") /****************************************************************************** *** Keyboard and Mouse Cursor Strings *** ******************************************************************************/ msgid(CURSOR_CLICK_LEFT) msgstr("Натискане с ляв бутон") msgid(CURSOR_CLICK_RIGHT) msgstr("Натискане с десен бутон") /****************************************************************************** *** Audio / Video Call Strings *** ******************************************************************************/ msgid(CALL_START_AUDIO) msgstr("Започни разговор") msgid(CALL_START_VIDEO) msgstr("Започни видео разговор") msgid(CALL_DECLINE) msgstr("Отхвърли повикването") msgid(CALL_CANCELLED) msgstr("Повикването отказано") msgid(CALL_INVITED) msgstr("Поканен в разговор") msgid(CALL_RINGING) msgstr("Позвъняване") msgid(CALL_STARTED) msgstr("Начало на разговора") msgid(CALL_ENDED) msgstr("Край на разговора") msgid(CALL_FRIEND_HAD_ENDED_CALL) msgstr(" прекрати разговора!") msgid(CALL_VIDEO_SHOW_INLINE) msgstr("Покажи видеото в полето") /****************************************************************************** *** Friend & Friend Settings Strings *** ******************************************************************************/ msgid(FRIEND_ALIAS) msgstr("Задай псевдоним на приятел") msgid(FRIEND_PUBLIC_KEY) msgstr("Публичен ключ на приятел") msgid(FRIEND_AUTOACCEPT) msgstr("Приемай файловете без потвърждение") msgid(FRIEND_EXPORT_CHATLOG) msgstr("Изнеси дневника на чата като неформатиран текст") /****************************************************************************** *** Group Strings *** ******************************************************************************/ msgid(GROUPCHAT_JOIN_AUDIO) msgstr("Присъедини се в разговора") msgid(GROUP_CREATE_TEXT) msgstr("Създай групов чат") msgid(GROUP_CREATE_VOICE) msgstr("Създай групов гласов чат") msgid(CREATEGROUPCHAT) msgstr("Създай груповчат") msgid(REMOVE_GROUP) msgstr("Премахни групата") msgid(LEAVE_GROUP) msgstr("Напусни групата") /****************************************************************************** *** Group Settings *** ******************************************************************************/ msgid(GROUPCHAT_SETTINGS) msgstr("Настройки на груповия чат") msgid(GROUP_NOTIFICATIONS) msgstr("Известия на груповия чат") msgid(GROUP_NOTIFICATIONS_ON) msgstr("Вкл.") msgid(GROUP_NOTIFICATIONS_MENTION) msgstr("Споменаване") msgid(GROUP_NOTIFICATIONS_OFF) msgstr("Изкл.") msgid(GROUP_TOPIC) msgstr("Задай тема на чата") /****************************************************************************** *** Settings / Profile Strings *** ******************************************************************************/ msgid(PROFILE_BUTTON) msgstr("Профил") msgid(DEVICES_BUTTON) msgstr("Устройства") msgid(USER_INTERFACE_BUTTON) msgstr("Потребителски изглед") msgid(AUDIO_VIDEO_BUTTON) msgstr("Звук и Видео") msgid(ADVANCED_BUTTON) msgstr("Допълнителни") msgid(NOTIFICATIONS_BUTTON) msgstr("Известия") msgid(AUTO_UPDATE) msgstr("Автоматично обновяване на uTox") msgid(PROFILE_SETTINGS) msgstr("Настройки на профила") msgid(PROFILE_PW_WARNING) msgstr("Внимание: µTox ще започне да криптира автоматично с тази парола.") msgid(PROFILE_PW_NO_RECOVER) msgstr("Не могат да се възстановяват загубени пароли.") /*** Profile ***/ /*** Devices ***/ msgid(DEVICES_ADD_NEW) msgstr("Добави ново устройстов в мрежата") msgid(DEVICES_NUMBER) msgstr("Брой на свързаните устройства") /*** Network ***/ /*** User Interface ***/ /*** Audio/Video ***/ /****************************************************************************** *** UNSORTED STRINGS *** *** TODO: *** *** FIXME: *** ******************************************************************************/ msgid(ADDFRIENDS) msgstr("Добави нов контакт") msgid(TOXID) msgstr("Тох идентификатор") msgid(MESSAGE) msgstr("Съобщение") msgid(FILTER_ONLINE) msgstr("Контакти на линия") msgid(FILTER_ALL) msgstr("Всички контакти") msgid(FILTER_CONTACT_TOGGLE) msgstr("Превключване филтрирането на контактите извън линия.") msgid(ADD) msgstr("Добави") msgid(FRIENDREQUEST) msgstr("Покана за приятелство") msgid(USERSETTINGS) msgstr("Потребителски настройки") msgid(FRIEND_SETTINGS) msgstr("Настройки за приятелите") msgid(NAME) msgstr("Име") msgid(STATUSMESSAGE) msgstr("Статус съобщение") msgid(PREVIEW) msgstr("Преглед") msgid(AUDIOINPUTDEVICE) msgstr("Входно звуково устройство") msgid(AUDIOFILTERING) msgstr("Филтриране на звука") msgid(AUDIOOUTPUTDEVICE) msgstr("Изходно звуково устройство") msgid(VIDEOINPUTDEVICE) msgstr("Входно видео устройство") msgid(VIDEOFRAMERATE) msgstr("Рамки в секунда за видеото (РВС)") msgid(PUSH_TO_TALK) msgstr("Говори при натиснат бутон") msgid(STATUS) msgstr("Статус") msgid(STATUS_ONLINE) msgstr("На линия") msgid(STATUS_AWAY) msgstr("Отсъстващ") msgid(STATUS_BUSY) msgstr("Зает") msgid(STATUS_OFFLINE) msgstr("Извън линия") /* * Leave %.*s. They are variables * The first one is your friend's name * The second one is the state your friend is now in */ msgid(STATUS_MESSAGE) msgstr("uTox %.*s е вече %s.") msgid(SETTINGS_UI_MINI_ROSTER) msgstr("Използвай малък списък с контакти") msgid(SETTINGS_UI_AUTO_HIDE_SIDEBAR) msgstr("Автоматично скривай страничния панел") msgid(NOT_CONNECTED) msgstr("Не сте свързан") msgid(NOT_CONNECTED_SETTINGS) msgstr("Нагласяне на интернет настройките") msgid(OTHERSETTINGS) msgstr("Други настройки") msgid(UI) msgstr("ПИ") msgid(USER_INTERFACE) msgstr("Потребителски изглед") msgid(UTOX_SETTINGS) msgstr("uTox настройки") msgid(NETWORK_SETTINGS) msgstr("Интернет настройки") msgid(PROFILE_PASSWORD) msgstr("Парола на профила") msgid(LOCK_UTOX) msgstr("Разкача се от Tox мрежата и се заключва профила.") msgid(SHOW_UI_PASSWORD) msgstr("Покажи полето за парола") msgid(SHOW_UI_PASSWORD_TOOLTIP) msgstr("Натиснете, за да се покаже полето за парола на профила. Промените тук са незабавни!") msgid(HIDE_UI_PASSWORD) msgstr("Скрий полето за парола") msgid(HIDE_UI_PASSWORD_TOOLTIP) msgstr("Натиснете, за да се скрие полето за парола на профила.") msgid(PASSWORD_TOO_SHORT) msgstr("Паролата, трябва да е с дължина поне 4 символа") msgid(LOCK) msgstr("Заключи") msgid(AUDIO_VIDEO) msgstr("Звук/Видео") msgid(DPI) msgstr("Точки на инч") msgid(SAVELOCATION) msgstr("Запази местоположението") msgid(LANGUAGE) msgstr("Език") msgid(NETWORK) msgstr("Мрежа") msgid(IPV6) msgstr("IPv6:") msgid(UDP) msgstr("UDP:") msgid(PROXY) msgstr("Прокси (SOCKS 5)") msgid(PROXY_FORCE) msgstr("Задължи uTox винаги да използва прокси") msgid(WARNING) msgstr("Промяната на Мрежови/Прокси настройки ще Ви разкачи временно от мрежта на Tox") msgid(SAVE_CHAT_HISTORY) msgstr("Запазвай чат хронология") msgid(AUDIONOTIFICATIONS) msgstr("Активирай звукови известия") msgid(RINGTONE) msgstr("Звуково известие") msgid(IS_TYPING) msgstr("въвежда...") msgid(CLOSE_TO_TRAY) msgstr("Затвори в таблата") msgid(START_IN_TRAY) msgstr("Стартирай в таблата") msgid(SHOW_QR) msgstr("Покажи QR") msgid(HIDE_QR) msgstr("Скрий QR") msgid(SAVE_QR) msgstr("Запази QR") msgid(COPY_TOX_ID) msgstr("Копирай като текст") msgid(COPY) msgstr("Копирай") msgid(COPYWITHOUTNAMES) msgstr("Копирай (без имена)") msgid(COPY_WITH_NAMES) msgstr("Копирай (включително и имената)") msgid(CUT) msgstr("Изрежи") msgid(PASTE) msgstr("Постави") msgid(DELETE) msgstr("Изтрий") msgid(SELECTALL) msgstr("Избери всички") msgid(REMOVE) msgstr("Премахни") msgid(REMOVE_FRIEND) msgstr("Премахни приятел") msgid(LEAVE) msgstr("Напусни") msgid(CTOPIC) msgstr("Промени темата") msgid(ACCEPT) msgstr("Приеми") msgid(IGNORE) msgstr("Отхвърли") msgid(SET_ALIAS) msgstr("Задай псевдоним") msgid(ALIAS) msgstr("Псевдоним") msgid(SENDMESSAGE) msgstr("Изпрати съобщение") msgid(SENDSCREENSHOT) msgstr("Изпрати снимка на екрана") msgid(CLICKTOSAVE) msgstr("Натисни за запазване") msgid(CLICKTOOPEN) msgstr("Натисни за отваряне") msgid(CANCELLED) msgstr("Отказан") msgid(DPI_060) msgstr("Потребителски ТНИ 60%") msgid(DPI_070) msgstr("Потребителски ТНИ 70%") msgid(DPI_080) msgstr("Потребителски ТНИ 80%") msgid(DPI_090) msgstr("Потребителски ТНИ 90%") msgid(DPI_100) msgstr("Потребителски ТНИ 100%") msgid(DPI_110) msgstr("Потребителски ТНИ 110%") msgid(DPI_120) msgstr("Потребителски ТНИ 120%") msgid(DPI_130) msgstr("Потребителски ТНИ 130%") msgid(DPI_140) msgstr("Потребителски ТНИ 140%") msgid(DPI_150) msgstr("Потребителски ТНИ 150%") msgid(DPI_160) msgstr("Потребителски ТНИ 160%") msgid(DPI_170) msgstr("Потребителски ТНИ 170%") msgid(DPI_180) msgstr("Потребителски ТНИ 180%") msgid(DPI_190) msgstr("Потребителски ТНИ 190%") msgid(DPI_200) msgstr("Потребителски ТНИ 200%") msgid(DPI_210) msgstr("Потребителски ТНИ 210%") msgid(DPI_220) msgstr("Потребителски ТНИ 220%") msgid(DPI_230) msgstr("Потребителски ТНИ 230%") msgid(DPI_240) msgstr("Потребителски ТНИ 240%") msgid(DPI_250) msgstr("Потребителски ТНИ 250%") msgid(DPI_260) msgstr("Потребителски ТНИ 260%") msgid(DPI_270) msgstr("Потребителски ТНИ 270%") msgid(DPI_280) msgstr("Потребителски ТНИ 280%") msgid(DPI_290) msgstr("Потребителски ТНИ 290%") msgid(DPI_300) msgstr("Потребителски ТНИ 300%") msgid(DPI_TINY) msgstr("Миниатюрно (50%)") msgid(DPI_NORMAL) msgstr("Нормално (100%)") msgid(DPI_BIG) msgstr("Голямо (150%)") msgid(DPI_LARGE) msgstr("По-голямо (200%)") msgid(DPI_HUGE) msgstr("Огромно (250%)") msgid(PROXY_DISABLED) msgstr("Деактивирано") msgid(PROXY_FALLBACK) msgstr("Безопасен режим") msgid(PROXY_ALWAYS_USE) msgstr("Винаги използвай") msgid(NO) msgstr("Не") msgid(YES) msgstr("Да") msgid(OFF) msgstr("Изкл.") msgid(ON) msgstr("Вкл.") msgid(SHOW) msgstr("Покажи") msgid(HIDE) msgstr("Скрий") msgid(VIDEO_IN_NONE) msgstr("Без") msgid(VIDEO_IN_DESKTOP) msgstr("Работен плот") msgid(AUDIO_IN_DEFAULT_LOOPBACK) msgstr("Стандартно повторение") msgid(AUDIO_IN_ANDROID) msgstr("OpenSL Вход") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("Моля, приемете тази покана за приятелство.") msgid(CONTACT_SEARCH_ADD_HINT) msgstr("Намери/Добави приятели") msgid(PROXY_EDIT_HINT_IP) msgstr("IP") msgid(PROXY_EDIT_HINT_PORT) msgstr("Порт") msgid(WINDOW_TITLE_VIDEO_PREVIEW) msgstr("Преглед на видео") msgid(MUTE) msgstr("Заглуши") msgid(UNMUTE) msgstr("Отглуши") msgid(SELECT_AVATAR_TITLE) msgstr("Избери аватар") msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS) msgstr("Аватарът е прекалено голям. Максимален размер: ") msgid(CANT_FIND_FILE_OR_EMPTY) msgstr("Не може да се намери избраният файл или той е празен.") msgid(CLEAR_HISTORY) msgstr("Изчисти хронология") msgid(AUTO_STARTUP) msgstr("Стартирай със системата") msgid(THEME) msgstr("Тема") msgid(THEME_DEFAULT) msgstr("Стандартна") msgid(THEME_LIGHT) msgstr("Светла тема") msgid(THEME_DARK) msgstr("Тъмна тема") msgid(THEME_HIGHCONTRAST) msgstr("Висок контраст") msgid(THEME_CUSTOM) msgstr("Потребителска (Вижте документите)") msgid(THEME_ZENBURN) msgstr("Треска за злато") msgid(THEME_SOLARIZED_LIGHT) msgstr("Слънчевосветло") msgid(THEME_SOLARIZED_DARK) msgstr("Слънчевотъмно") msgid(SEND_TYPING_NOTIFICATIONS) msgstr("Изпращай известия при писане") msgid(STATUS_NOTIFICATIONS) msgstr("Известия за състоянието") msgid(RANDOMIZE_NOSPAM) msgstr("Случаен антиспам") msgid(NOSPAM) msgstr("Антиспам") msgid(REVERT_NOSPAM) msgstr("Върни антиспама") msgid(NOSPAM_WARNING) msgstr("Смяната на антиспама ще прекрати ползването на стария Ви идентификатор. uTox не обновява Вашият идентификатор в именните сървъри.") msgid(BLOCK_FRIEND_REQUESTS) msgstr("Блокирай поканите за приятелство") msgid(SHOW_NOSPAM) msgstr("Покажи антиспам настройки") msgid(HIDE_NOSPAM) msgstr("Скрий антиспам настройки") msgid(DELETE_FRIEND) msgstr("Изтрий приятел") msgid(DELETE_MESSAGE) msgstr("Сигурни ли сте, че искате да изтриете ") msgid(KEEP) msgstr("Задръж") uTox-0.17.1/langs/br.h000066400000000000000000000100041354126257400144230ustar00rootroot00000000000000msgid(LANG_NATIVE_NAME) msgstr("Português brasileiro") msgid(LANG_ENGLISH_NAME) msgstr("Brazilian Portuguese") msgid(REQ_SENT) msgstr("Pedido de amizade enviado. Quando aceito, seu amigo aparecerá online.") msgid(REQ_INVALID_ID) msgstr("Erro: ID Tox inválido") msgid(REQ_EMPTY_ID) msgstr("Erro: ID Tox não especificado") msgid(REQ_LONG_MSG) msgstr("Erro: Mensagem muito longa") msgid(REQ_NO_MSG) msgstr("Erro: Sem mensagem") msgid(REQ_SELF_ID) msgstr("Erro: Este é seu próprio ID Tox") msgid(REQ_ALREADY_FRIENDS) msgstr("Erro: Este ID Tox já consta na sua lista") msgid(REQ_UNKNOWN) msgstr("Erro: Desconhecido") msgid(REQ_BAD_CHECKSUM) msgstr("Erro: ID Tox Inválido (checksum incorreto)") msgid(REQ_BAD_NOSPAM) msgstr("Erro: ID Tox inválido (código anti-spam incorreto)") msgid(REQ_NO_MEMORY) msgstr("Erro: Sem memória") msgid(TRANSFER_NEW) msgstr("Nova transferência de arquivo") msgid(TRANSFER_STARTED) msgstr("Transferência de arquivo iniciada") //msgid(TRANSFER___) //msgstr("...") msgid(TRANSFER_PAUSED) msgstr("Transferência de arquivo parada") msgid(TRANSFER_BROKEN) msgstr("Arquivo transferido está corrompido") msgid(TRANSFER_CANCELLED) msgstr("Transferência de arquivo cancelada") msgid(TRANSFER_COMPLETE) msgstr("Transferência completa") msgid(CALL_CANCELLED) msgstr("Chamada cancelada") msgid(CALL_INVITED) msgstr("Chamada enviada") msgid(CALL_RINGING) msgstr("Chamando") msgid(CALL_STARTED) msgstr("Chamada iniciada") msgid(ADDFRIENDS) msgstr("Adicionar amigos") msgid(TOXID) msgstr("ID Tox") msgid(MESSAGE) msgstr("Mensagem") msgid(ADD) msgstr("Adicionar") msgid(FRIENDREQUEST) msgstr("Pedidos de amizade") msgid(USERSETTINGS) msgstr("Configurações do usuário") msgid(NAME) msgstr("Nome") msgid(STATUSMESSAGE) msgstr("Mensagem de status") msgid(PREVIEW) msgstr("Pré-visualização") msgid(AUDIOINPUTDEVICE) msgstr("Dispositivo de entrada de áudio") msgid(AUDIOOUTPUTDEVICE) msgstr("Dispositivo de saída de áudio") msgid(VIDEOINPUTDEVICE) msgstr("Dispositivo de entrada de vídeo") msgid(OTHERSETTINGS) msgstr("Outras configurações") //msgid(DPI) //msgstr("DPI") msgid(SAVELOCATION) msgstr("Salvar localização") msgid(LANGUAGE) msgstr("Idioma") msgid(NETWORK) msgstr("Rede") //msgid(IPV6) //msgstr("IPv6:") //msgid(UDP) //msgstr("UDP:") //msgid(PROXY) //msgstr("Proxy (SOCKS 5)") msgid(WARNING) msgstr("Mudar as configurações de rede/proxy te desconectará temporariamente da rede Tox") msgid(SAVE_CHAT_HISTORY) msgstr("Logar conversas") msgid(IS_TYPING) msgstr("está digitando...") msgid(COPY) msgstr("Copiar") msgid(COPYWITHOUTNAMES) msgstr("Copiar (sem nomes)") msgid(CUT) msgstr("Cortar") msgid(PASTE) msgstr("Colar") msgid(DELETE) msgstr("Excluir") msgid(SELECTALL) msgstr("Selecionar tudo") msgid(REMOVE) msgstr("Remover") msgid(LEAVE) msgstr("Sair") msgid(ACCEPT) msgstr("Aceitar") msgid(IGNORE) msgstr("Ignorar") msgid(CLICKTOSAVE) msgstr("Clique para salvar") msgid(CLICKTOOPEN) msgstr("Clique para abrir") msgid(CANCELLED) msgstr("Cancelado") msgid(DPI_TINY) msgstr("Pequeno (50%)") msgid(DPI_NORMAL) msgstr("Normal (100%)") msgid(DPI_BIG) msgstr("Grande (150%)") msgid(DPI_LARGE) msgstr("Maior (200%)") msgid(DPI_HUGE) msgstr("Imenso (250%)") msgid(FILTER_ALL) msgstr("Todos") msgid(FILTER_ONLINE) msgstr("Online") msgid(PROXY_DISABLED) msgstr("Desabilitado") msgid(PROXY_FALLBACK) msgstr("Apenas se necessário") msgid(PROXY_ALWAYS_USE) msgstr("Sempre usar") msgid(NO) msgstr("Não") msgid(YES) msgstr("Sim") msgid(VIDEO_IN_NONE) msgstr("Nenhum") msgid(VIDEO_IN_DESKTOP) msgstr("Área de trabalho") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("Por favor, aceite este pedido de amizade.") //msgid(PROXY_EDIT_HINT_IP) //msgstr("IP") msgid(PROXY_EDIT_HINT_PORT) msgstr("Porta") //TODO: Localize or remove. //msgid(AUDIO_IN_DEFAULT_LOOPBACK) //msgstr("Default Loopback") //TODO: Localize or remove. //msgid(WINDOW_TITLE_VIDEO_PREVIEW) //msgstr("Video Preview") //TODO: Localize or remove. //msgid(AUDIONOTIFICATIONS) //msgstr("Enable Audible Notification (Ringtone)") uTox-0.17.1/langs/cn.h000066400000000000000000000175241354126257400144360ustar00rootroot00000000000000msgid(LANG_NATIVE_NAME) msgstr("简体中文") msgid(LANG_ENGLISH_NAME) msgstr("SIMPLIFIED CHINESE") msgid(REQ_SENT) msgstr("好友请求已发送。对方接受之后将显示为在线状态。") msgid(REQ_INVALID_ID) msgstr("错误:无效的 Tox ID") msgid(REQ_EMPTY_ID) msgstr("错误:未指定 Tox ID") msgid(REQ_LONG_MSG) msgstr("错误:消息过长") msgid(REQ_NO_MSG) msgstr("错误:空消息") msgid(REQ_SELF_ID) msgstr("错误:Tox ID 是你自己的账号") msgid(REQ_ALREADY_FRIENDS) msgstr("错误:该 Tox ID 已存在于好友列表中") msgid(REQ_UNKNOWN) msgstr("错误:未知") msgid(REQ_BAD_CHECKSUM) msgstr("错误:无效的 Tox ID(错误的校检码)") msgid(REQ_BAD_NOSPAM) msgstr("错误:无效的 Tox ID(错误的防骚扰码)") msgid(REQ_NO_MEMORY) msgstr("错误:内存不足") msgid(SEND_FILE) msgstr("传送文件") msgid(SAVE_FILE) msgstr("保存文件") msgid(WHERE_TO_SAVE_FILE_PROMPT) msgstr("你要将 \"%.*s\"保存在哪里?") msgid(WHERE_TO_SAVE_FILE) msgstr("你要将文件保存在哪里?") msgid(SEND_FILE_PROMPT) msgstr("选择一个或多个文件以传送。") msgid(SCREEN_CAPTURE_PROMPT) msgstr("在屏幕上的目标区域截屏。") msgid(TRANSFER_NEW) msgstr("新建文件传送任务") msgid(TRANSFER_STARTED) msgstr("文件传送开始") msgid(TRANSFER___) msgstr("……") msgid(TRANSFER_PAUSED) msgstr("文件传送暂停") msgid(TRANSFER_BROKEN) msgstr("文件传送中断") msgid(TRANSFER_CANCELLED) msgstr("文件传送取消") msgid(TRANSFER_COMPLETE) msgstr("文件传送完成") msgid(GROUPCHAT_JOIN_AUDIO) msgstr("参加语音聊天") msgid(CALL_START_AUDIO) msgstr("语音呼叫") msgid(CALL_START_VIDEO) msgstr("视频呼叫") msgid(CALL_CANCELLED) msgstr("呼叫取消") msgid(CALL_INVITED) msgstr("呼叫请求") msgid(CALL_RINGING) msgstr("呼叫响铃") msgid(CALL_STARTED) msgstr("呼叫开始") msgid(PROFILE_SETTINGS) msgstr("用户设置") msgid(PROFILE_PW_WARNING) msgstr("注意:µTox 启动后将必须提供该密码。") msgid(PROFILE_PW_NO_RECOVER) msgstr("忘记密码将无法找回。") msgid(ADDFRIENDS) msgstr("添加好友") //msgid(TOXID) //msgstr("Tox ID") msgid(MESSAGE) msgstr("消息") msgid(FILTER_ONLINE) msgstr("在线好友") msgid(FILTER_ALL) msgstr("全部好友") msgid(FILTER_CONTACT_TOGGLE) msgstr("切换是否过滤离线好友") msgid(ADD) msgstr("添加") msgid(CREATEGROUPCHAT) msgstr("创建一个群聊") msgid(FRIENDREQUEST) msgstr("好友请求") msgid(USERSETTINGS) msgstr("用户设置") msgid(FRIEND_SETTINGS) msgstr("好友设置") msgid(NAME) msgstr("名字") msgid(STATUSMESSAGE) msgstr("签名") msgid(PREVIEW) msgstr("预览") msgid(AUDIOINPUTDEVICE) msgstr("音频输入设备") msgid(AUDIOFILTERING) msgstr("音频过滤") msgid(AUDIOOUTPUTDEVICE) msgstr("音频输出设备") msgid(VIDEOINPUTDEVICE) msgstr("视频输入设备") msgid(PUSH_TO_TALK) msgstr("一键对讲模式") msgid(STATUS) msgstr("状态") msgid(STATUS_ONLINE) msgstr("在线") msgid(STATUS_AWAY) msgstr("离开") msgid(STATUS_BUSY) msgstr("忙碌") msgid(NOT_CONNECTED) msgstr("未连线") msgid(OTHERSETTINGS) msgstr("其他设置") msgid(UI) msgstr("用户界面") msgid(USER_INTERFACE) msgstr("界面") msgid(UTOX_SETTINGS) msgstr("uTox设置") msgid(NETWORK_SETTINGS) msgstr("网络设置") msgid(PROFILE_PASSWORD) msgstr("用户密码") msgid(LOCK_UTOX) msgstr("断开 Tox 并锁定用户。") msgid(SHOW_UI_PASSWORD) msgstr("点击显示密码配置栏。此处所作的更改将即刻生效!") msgid(LOCK) msgstr("锁定") msgid(AUDIO_VIDEO) msgstr("音/视频") msgid(DPI) msgstr("分辨率缩放") msgid(SAVELOCATION) msgstr("保存位置") msgid(LANGUAGE) msgstr("语言") msgid(NETWORK) msgstr("网络") //msgid(IPV6) //msgstr("IPv6:") //msgid(UDP) //msgstr("UDP:") msgid(PROXY) msgstr("代理 (SOCKS 5)") msgid(WARNING) msgstr("修改网络或代理设置将会暂时断开Tox的网络连接") msgid(SAVE_CHAT_HISTORY) msgstr("保留记录") msgid(AUDIONOTIFICATIONS) msgstr("启用声音通知 (响铃)") msgid(RINGTONE) msgstr("声音") msgid(IS_TYPING) msgstr("正在打字...") msgid(CLOSE_TO_TRAY) msgstr("关闭后运行于托盘区") msgid(START_IN_TRAY) msgstr("最小化启动于托盘区") msgid(COPY) msgstr("复制") msgid(COPYWITHOUTNAMES) msgstr("复制 (不包含名字)") msgid(COPY_WITH_NAMES) msgstr("复制 (包含名字)") msgid(CUT) msgstr("剪切") msgid(PASTE) msgstr("粘贴") msgid(DELETE) msgstr("删除") msgid(SELECTALL) msgstr("全选") msgid(REMOVE) msgstr("移除") msgid(REMOVE_FRIEND) msgstr("移除好友") msgid(REMOVE_GROUP) msgstr("移除群组") msgid(LEAVE) msgstr("离开") msgid(LEAVE_GROUP) msgstr("离开群组") msgid(CTOPIC) msgstr("更改主题") msgid(ACCEPT) msgstr("接受") msgid(IGNORE) msgstr("忽略") msgid(SET_ALIAS) msgstr("设置别名") msgid(ALIAS) msgstr("别名") msgid(FRIEND_AUTOACCEPT) msgstr("无须确认直接接收其传送的文件") msgid(SENDMESSAGE) msgstr("发送消息") msgid(SENDSCREENSHOT) msgstr("发送截屏") msgid(CLICKTOSAVE) msgstr("点击保存") msgid(CLICKTOOPEN) msgstr("点击打开") msgid(CANCELLED) msgstr("取消") msgid(DPI_060) msgstr("缩放至 60%") msgid(DPI_070) msgstr("缩放至 70%") msgid(DPI_080) msgstr("缩放至 80%") msgid(DPI_090) msgstr("缩放至 90%") msgid(DPI_100) msgstr("缩放至 100%") msgid(DPI_110) msgstr("缩放至 110%") msgid(DPI_120) msgstr("缩放至 120%") msgid(DPI_130) msgstr("缩放至 130%") msgid(DPI_140) msgstr("缩放至 140%") msgid(DPI_150) msgstr("缩放至 150%") msgid(DPI_160) msgstr("缩放至 160%") msgid(DPI_170) msgstr("缩放至 170%") msgid(DPI_180) msgstr("缩放至 180%") msgid(DPI_190) msgstr("缩放至 190%") msgid(DPI_200) msgstr("缩放至 200%") msgid(DPI_210) msgstr("缩放至 210%") msgid(DPI_220) msgstr("缩放至 220%") msgid(DPI_230) msgstr("缩放至 230%") msgid(DPI_240) msgstr("缩放至 240%") msgid(DPI_250) msgstr("缩放至 250%") msgid(DPI_260) msgstr("缩放至 260%") msgid(DPI_270) msgstr("缩放至 270%") msgid(DPI_280) msgstr("缩放至 280%") msgid(DPI_290) msgstr("缩放至 290%") msgid(DPI_300) msgstr("缩放至 300%") msgid(DPI_TINY) msgstr("小 (50%)") msgid(DPI_NORMAL) msgstr("正常 (100%)") msgid(DPI_BIG) msgstr("大 (150%)") msgid(DPI_LARGE) msgstr("较大 (200%)") msgid(DPI_HUGE) msgstr("极大 (250%)") msgid(PROXY_DISABLED) msgstr("已弃用") msgid(PROXY_FALLBACK) msgstr("逐渐退去") msgid(PROXY_ALWAYS_USE) msgstr("经常使用") msgid(NO) msgstr("否") msgid(YES) msgstr("是") msgid(OFF) msgstr("关") msgid(ON) msgstr("开") msgid(SHOW) msgstr("显示") msgid(HIDE) msgstr("隐藏") msgid(VIDEO_IN_NONE) msgstr("无") msgid(VIDEO_IN_DESKTOP) msgstr("桌面") msgid(AUDIO_IN_DEFAULT_LOOPBACK) msgstr("默认环绕") msgid(AUDIO_IN_ANDROID) msgstr("OpenSL输入") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("请接受这条好友请求。") msgid(CONTACT_SEARCH_ADD_HINT) msgstr("搜索/添加好友") //msgid(PROXY_EDIT_HINT_IP) //msgstr("IP") msgid(PROXY_EDIT_HINT_PORT) msgstr("端口") msgid(WINDOW_TITLE_VIDEO_PREVIEW) msgstr("视频预览") msgid(MUTE) msgstr("开启静音") msgid(UNMUTE) msgstr("取消静音") msgid(SELECT_AVATAR_TITLE) msgstr("选择头像") msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS) msgstr("头像过大。最大允许尺寸为: ") msgid(CANT_FIND_FILE_OR_EMPTY) msgstr("无法找到所选文件或所选文件为空。") msgid(CLEAR_HISTORY) msgstr("清空历史") msgid(AUTO_STARTUP) msgstr("开机时自动启动") msgid(THEME) msgstr("界面风格") msgid(THEME_DEFAULT) msgstr("默认") msgid(THEME_LIGHT) msgstr("轻淡风格") msgid(THEME_DARK) msgstr("深暗风格") msgid(THEME_HIGHCONTRAST) msgstr("高对比度") msgid(THEME_CUSTOM) msgstr("自定义 (参见文档)") msgid(THEME_ZENBURN) msgstr("低调风") msgid(SEND_TYPING_NOTIFICATIONS) msgstr("发送正在打字的提醒") uTox-0.17.1/langs/cs.h000066400000000000000000000077121354126257400144410ustar00rootroot00000000000000msgid(LANG_NATIVE_NAME) msgstr("Čeština") msgid(LANG_ENGLISH_NAME) msgstr("Czech") msgid(REQ_SENT) msgstr("Žádost poslána. Váš kontakt se objeví online, jakmile vaši žádost přijme.") msgid(REQ_INVALID_ID) msgstr("Chyba: Neplatné Tox ID") msgid(REQ_EMPTY_ID) msgstr("Chyba: Tox ID nespecifikováno") msgid(REQ_LONG_MSG) msgstr("Chyba: Zpráva je příliš dlouhá") msgid(REQ_NO_MSG) msgstr("Chyba: Prázdná zpráva") msgid(REQ_SELF_ID) msgstr("Chyba: Tox ID je Vaše ID") msgid(REQ_ALREADY_FRIENDS) msgstr("Chyba: Tox ID je již ve Vašich kontaktech") msgid(REQ_UNKNOWN) msgstr("Chyba: Neznámá") msgid(REQ_BAD_CHECKSUM) msgstr("Chyba: Neplatné Tox ID (kontrolní součet)") msgid(REQ_BAD_NOSPAM) msgstr("Chyba: Neplatné Tox ID (hodnota nospam)") msgid(REQ_NO_MEMORY) msgstr("Chyba: Nedostatek paměti") msgid(TRANSFER_NEW) msgstr("Nový přenos souboru") msgid(TRANSFER_STARTED) msgstr("Přenos souboru začal") msgid(TRANSFER___) msgstr("...") msgid(TRANSFER_PAUSED) msgstr("Přenos souboru pozastaven") msgid(TRANSFER_BROKEN) msgstr("Přenos souboru se nezdařil") msgid(TRANSFER_CANCELLED) msgstr("Přenos souboru zrušen") msgid(TRANSFER_COMPLETE) msgstr("Přenos souboru dokončen") msgid(CALL_CANCELLED) msgstr("Hovor zrušen") //msgid(CALL_INVITED) //msgstr("Call invited") //msgid(CALL_RINGING) //msgstr("Call ringing") msgid(CALL_STARTED) msgstr("Hovor začal") msgid(ADDFRIENDS) msgstr("Přidat kontakt") msgid(TOXID) msgstr("Tox ID") msgid(MESSAGE) msgstr("Zpráva") msgid(ADD) msgstr("Přidej") msgid(FRIENDREQUEST) msgstr("Žádost o kontakt") msgid(USERSETTINGS) msgstr("Uživatelské nastavení") msgid(NAME) msgstr("Jméno") msgid(STATUSMESSAGE) msgstr("Status") msgid(PREVIEW) msgstr("Náhled") msgid(AUDIOINPUTDEVICE) msgstr("Vstupní zvukové zařízení") msgid(AUDIOOUTPUTDEVICE) msgstr("Výstupní zvukové zařízení") msgid(VIDEOINPUTDEVICE) msgstr("Vstupní video zařízení") msgid(OTHERSETTINGS) msgstr("Ostatní nastavení") msgid(DPI) msgstr("DPI") msgid(SAVELOCATION) msgstr("Ulož pozici") msgid(LANGUAGE) msgstr("Jazyk") msgid(NETWORK) msgstr("Síť") msgid(IPV6) msgstr("IPv6:") msgid(UDP) msgstr("UDP:") msgid(PROXY) msgstr("Proxy (SOCKS 5)") msgid(WARNING) msgstr("Změna nastavení sítě/Proxy Vás dočasně odpojí od sítě Tox.") msgid(SAVE_CHAT_HISTORY) msgstr("Logování") msgid(IS_TYPING) msgstr("píše...") msgid(COPY) msgstr("Kopírovat") msgid(COPYWITHOUTNAMES) msgstr("Kopírovat (beze jmen)") msgid(CUT) msgstr("Vyjmout") msgid(PASTE) msgstr("Vložit") msgid(DELETE) msgstr("Smazat") msgid(SELECTALL) msgstr("Vybrat vše") msgid(REMOVE) msgstr("Odstranit") msgid(LEAVE) msgstr("Opustit") msgid(ACCEPT) msgstr("Přijmout") msgid(IGNORE) msgstr("Ignorovat") msgid(CLICKTOSAVE) msgstr("Klikni pro uložení") msgid(CLICKTOOPEN) msgstr("Klikni pro otevření") msgid(CANCELLED) msgstr("Zrušeno") msgid(DPI_TINY) msgstr("Malý (50%)") msgid(DPI_NORMAL) msgstr("Normální (100%)") msgid(DPI_BIG) msgstr("Větší (150%)") msgid(DPI_LARGE) msgstr("Velký (200%)") msgid(DPI_HUGE) msgstr("Obrovský (250%)") msgid(FILTER_ALL) msgstr("Vše") msgid(FILTER_ONLINE) msgstr("Online") msgid(PROXY_DISABLED) msgstr("Vypnuto") msgid(PROXY_FALLBACK) msgstr("Záložní režim") msgid(PROXY_ALWAYS_USE) msgstr("Použít vždy") msgid(NO) msgstr("Ne") msgid(YES) msgstr("Ano") msgid(VIDEO_IN_NONE) msgstr("Žádné") msgid(VIDEO_IN_DESKTOP) msgstr("Plocha") //TODO: Localize or remove. //msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) //msgstr("Please accept this friend request.") //TODO: Localize or remove. //msgid(PROXY_EDIT_HINT_IP) //msgstr("IP") //TODO: Localize or remove. //msgid(PROXY_EDIT_HINT_PORT) //msgstr("Port") //TODO: Localize or remove. //msgid(AUDIO_IN_DEFAULT_LOOPBACK) //msgstr("Default Loopback") //TODO: Localize or remove. //msgid(WINDOW_TITLE_VIDEO_PREVIEW) //msgstr("Video Preview") //TODO: Localize or remove. //msgid(AUDIONOTIFICATIONS) //msgstr("Enable Audible Notification (Ringtone)") uTox-0.17.1/langs/de.h000066400000000000000000000311611354126257400144170ustar00rootroot00000000000000/****************************************************************************** *** German i18l Strings *** ******************************************************************************/ msgid(LANG_NATIVE_NAME) msgstr("Deutsch") msgid(LANG_ENGLISH_NAME) msgstr("GERMAN") /****************************************************************************** *** MISC & UNSORTED *** ******************************************************************************/ msgid(REQ_SENT) msgstr("Freundschaftsanfrage verschickt. Dein Freund wird online erscheinen, sobald er deine Anfrage akzeptiert hat.") msgid(REQ_INVALID_ID) msgstr("Fehler: Ungültige Tox ID") msgid(REQ_EMPTY_ID) msgstr("Fehler: Keine Tox ID angegeben") msgid(REQ_LONG_MSG) msgstr("Fehler: Nachricht ist zu lang") msgid(REQ_NO_MSG) msgstr("Fehler: Leere Nachricht") msgid(REQ_SELF_ID) msgstr("Fehler: Tox ID ist eigene ID") msgid(REQ_ALREADY_FRIENDS) msgstr("Fehler: Tox ID ist bereits in der Freundesliste") msgid(REQ_UNKNOWN) msgstr("Fehler: Unbekannt") msgid(REQ_BAD_CHECKSUM) msgstr("Fehler: Ungültige Tox ID (ungültige Prüfsumme)") msgid(REQ_BAD_NOSPAM) msgstr("Fehler: Ungültige Tox ID (ungültiger NoSpam-Wert)") msgid(REQ_NO_MEMORY) msgstr("Fehler: Kein Speicher") msgid(SEND_FILE) msgstr("Datei senden") msgid(SAVE_FILE) msgstr("Datei speichern") msgid(WHERE_TO_SAVE_FILE_PROMPT) msgstr("Wo soll \"%.*s\" gespeichert werden?") msgid(WHERE_TO_SAVE_FILE) msgstr("Wo soll die Datei gespeichert werden?") msgid(SEND_FILE_PROMPT) msgstr("Wähle eine oder mehrere Dateien zum Senden.") msgid(SCREEN_CAPTURE_PROMPT) msgstr("Markiere den Bereich des Bildschirms, der gesendet werden soll.") /****************************************************************************** *** File Transfer Strings *** ******************************************************************************/ msgid(TRANSFER_NEW) msgstr("Neue Dateiübertragung") msgid(TRANSFER_STARTED) msgstr("Dateiübertragung gestartet") msgid(TRANSFER_PAUSED) msgstr("Dateiübertragung pausiert") msgid(TRANSFER_BROKEN) msgstr("Dateiübertragung fehlerhaft") msgid(TRANSFER_CANCELLED) msgstr("Dateiübertragung abgebrochen") msgid(TRANSFER_COMPLETE) msgstr("Dateiübertragung abgeschlossen") /****************************************************************************** *** Keyboard and Mouse Cursor Strings *** ******************************************************************************/ msgid(CURSOR_CLICK_LEFT) msgstr("Linksklick") msgid(CURSOR_CLICK_RIGHT) msgstr("Rechtsklick") /****************************************************************************** *** Audio / Video Call Strings *** ******************************************************************************/ msgid(CALL_START_AUDIO) msgstr("Anruf beginnen") msgid(CALL_START_VIDEO) msgstr("Videoanruf beginnen") msgid(CALL_DECLINE) msgstr("Anruf ablehnen") msgid(CALL_CANCELLED) msgstr("Anruf abgebrochen") msgid(CALL_INVITED) msgstr("Anruf eingeladen") msgid(CALL_RINGING) msgstr("Anruf klingelt") msgid(CALL_STARTED) msgstr("Anruf gestartet") msgid(CALL_FRIEND_HAD_ENDED_CALL) msgstr(" hat den Anruf beendet!") msgid(CALL_VIDEO_SHOW_INLINE) msgstr("Video inline zeigen") /****************************************************************************** *** Friend & Friend Settings Strings *** ******************************************************************************/ msgid(FRIEND_ALIAS) msgstr("Alias setzen") msgid(FRIEND_PUBLIC_KEY) msgstr("Öffentlicher Schlüssel") msgid(FRIEND_AUTOACCEPT) msgstr("Eingehende Dateiübertragungen ohne Nachfrage akzeptieren") msgid(FRIEND_EXPORT_CHATLOG) msgstr("Chatverlauf als Text exportieren") /****************************************************************************** *** Group Strings *** ******************************************************************************/ msgid(GROUPCHAT_JOIN_AUDIO) msgstr("Audiochat beitreten") msgid(GROUP_CREATE_WITH_AUDIO) msgstr("Audio aktivieren") msgid(GROUP_CREATE_TEXT) msgstr("Text-Gruppenchat erstellen") msgid(GROUP_CREATE_VOICE) msgstr("Audio-Gruppenchat erstellen") msgid(CREATEGROUPCHAT) msgstr("Gruppenchat erstellen") msgid(REMOVE_GROUP) msgstr("Gruppe entfernen") msgid(LEAVE_GROUP) msgstr("Gruppe verlassen") /****************************************************************************** *** Group Settings *** ******************************************************************************/ msgid(GROUPCHAT_SETTINGS) msgstr("Gruppenchat-Einstellungen") msgid(GROUP_NOTIFICATIONS) msgstr("Gruppenbenachrichtigungen") msgid(GROUP_NOTIFICATIONS_ON) msgstr("An") msgid(GROUP_NOTIFICATIONS_MENTION) msgstr("Erwähnung") msgid(GROUP_NOTIFICATIONS_OFF) msgstr("Aus") msgid(GROUP_TOPIC) msgstr("Thema der Gruppe festlegen") /****************************************************************************** *** Settings / Profile Strings *** ******************************************************************************/ msgid(PROFILE_BUTTON) msgstr("Profil") msgid(DEVICES_BUTTON) msgstr("Geräte") msgid(USER_INTERFACE_BUTTON) msgstr("Benutzeroberfläche") msgid(AUDIO_VIDEO_BUTTON) msgstr("Audio & Video") msgid(ADVANCED_BUTTON) msgstr("Fortgeschritten") msgid(NOTIFICATIONS_BUTTON) msgstr("Benachrichtigungen") msgid(AUTO_UPDATE) msgstr("uTox automatisch aktualisieren") msgid(PROFILE_SETTINGS) msgstr("Profileinstellungen") msgid(PROFILE_PW_WARNING) msgstr("WARNUNG: µTox wird automatisch beginnen mit diesem Passwort zu verschlüsseln.") msgid(PROFILE_PW_NO_RECOVER) msgstr("Es ist nicht möglich verlorene Passwörter wiederherzustellen.") /*** Profile ***/ /*** Devices ***/ msgid(DEVICES_ADD_NEW) msgstr("Neues Gerät hinzufügen") msgid(DEVICES_NUMBER) msgstr("Anzahl der verknüpften Geräte") /*** Network ***/ /*** User Interface ***/ /*** Audio/Video ***/ /****************************************************************************** *** UNSORTED STRINGS *** ******************************************************************************/ msgid(ADDFRIENDS) msgstr("Neuen Kontakt hinzufügen") msgid(TOXID) msgstr("Tox ID") msgid(MESSAGE) msgstr("Nachricht") msgid(FILTER_ONLINE) msgstr("Online") msgid(FILTER_ALL) msgstr("Alle") msgid(FILTER_CONTACT_TOGGLE) msgstr("Filterung von offline Kontakten umschalten.") msgid(ADD) msgstr("Hinzufügen") msgid(FRIENDREQUEST) msgstr("Freundschaftsanfrage") msgid(USERSETTINGS) msgstr("Benutzereinstellungen") msgid(FRIEND_SETTINGS) msgstr("Freundeinstellungen") msgid(STATUSMESSAGE) msgstr("Statusnachricht") msgid(PREVIEW) msgstr("Vorschau") msgid(AUDIOINPUTDEVICE) msgstr("Audioeingabegerät") msgid(AUDIOFILTERING) msgstr("Audio filtern") msgid(AUDIOOUTPUTDEVICE) msgstr("Audioausgabegerät") msgid(VIDEOINPUTDEVICE) msgstr("Videoeingabegerät") msgid(STATUS_AWAY) msgstr("Abwesend") msgid(STATUS_BUSY) msgstr("Beschäftigt") msgid(SETTINGS_UI_MINI_ROSTER) msgstr("Kompakte Kontaktliste verwenden") msgid(SETTINGS_UI_AUTO_HIDE_SIDEBAR) msgstr("Seitenleiste automatisch verstecken") msgid(NOT_CONNECTED) msgstr("Nicht verbunden") msgid(NOT_CONNECTED_SETTINGS) msgstr("Netzwerk Einstellungen anpassen") msgid(OTHERSETTINGS) msgstr("Andere Einstellungen") msgid(UI) msgstr("Benutzeroberfläche") msgid(USER_INTERFACE) msgstr("Oberfläche") // "Benutzeroberfläche" doesn't fit into tab header (Settings) msgid(UTOX_SETTINGS) msgstr("Einstellungen") // "uTox Einstellungen" would overlap with version (Settings) msgid(NETWORK_SETTINGS) msgstr("Netzwerkeinstellungen") msgid(PROFILE_PASSWORD) msgstr("Profilpasswort") msgid(LOCK_UTOX) msgstr("Trennt die Verbindung zu Tox und sperrt dieses Profil.") msgid(SHOW_UI_PASSWORD) msgstr("Passwortfeld anzeigen") msgid(SHOW_UI_PASSWORD_TOOLTIP) msgstr("Hier klicken, um Passwortfeld anzuzeigen. Änderungen werden sofort angewendet!") msgid(HIDE_UI_PASSWORD) msgstr("Passwortfeld verstecken") msgid(HIDE_UI_PASSWORD_TOOLTIP) msgstr("Hier klicken, um Passwortfeld zu verstecken.") msgid(PASSWORD_TOO_SHORT) msgstr("Passwort muss mindestens 4 Zeichen lang sein") msgid(LOCK) msgstr("Sperren") msgid(SAVELOCATION) msgstr("Speichere Standorteinstellung") msgid(LANGUAGE) msgstr("Sprache") msgid(NETWORK) msgstr("Netzwerk") msgid(PROXY_FORCE) msgstr("Verwendung des Proxys erzwingen") msgid(WARNING) msgstr("Das Verändern von Netzwerk-/Proxy-Einstellungen unterbricht kurzzeitig die Verbindung zum Tox-Netzwerk.") msgid(SAVE_CHAT_HISTORY) msgstr("Chatverläufe speichern") msgid(AUDIONOTIFICATIONS) msgstr("Akustische Benachrichtigungen einschalten (Klingelton)") msgid(RINGTONE) msgstr("Klingelton") msgid(IS_TYPING) msgstr("schreibt ...") msgid(CLOSE_TO_TRAY) msgstr("In den Infobereich schließen") msgid(START_IN_TRAY) msgstr("Im Infobereich starten") msgid(SHOW_QR) msgstr("QR Code anzeigen") msgid(HIDE_QR) msgstr("QR Code verstecken") msgid(SAVE_QR) msgstr("QR Code speichern") msgid(COPY_TOX_ID) msgstr("Kopieren") msgid(COPY) msgstr("Kopieren") msgid(COPYWITHOUTNAMES) msgstr("Kopieren (ohne Namen)") msgid(COPY_WITH_NAMES) msgstr("Kopieren (mit Namen)") msgid(CUT) msgstr("Ausschneiden") msgid(PASTE) msgstr("Einfügen") msgid(DELETE) msgstr("Löschen") msgid(SELECTALL) msgstr("Alles markieren") msgid(REMOVE) msgstr("Entfernen") msgid(REMOVE_FRIEND) msgstr("Freund entfernen") msgid(LEAVE) msgstr("Verlassen") msgid(CTOPIC) msgstr("Thema ändern") msgid(ACCEPT) msgstr("Akzeptieren") msgid(IGNORE) msgstr("Ignorieren") msgid(SET_ALIAS) msgstr("Alias setzen") msgid(SENDMESSAGE) msgstr("Senden") msgid(SENDSCREENSHOT) msgstr("Bildschirmfoto senden") msgid(CLICKTOSAVE) msgstr("Klicken um zu speichern") msgid(CLICKTOOPEN) msgstr("Klicken um zu öffnen") msgid(CANCELLED) msgstr("Abgebrochen") msgid(DPI_TINY) msgstr("Klein (50%)") msgid(DPI_BIG) msgstr("Groß (150%)") msgid(DPI_LARGE) msgstr("Größer (200%)") msgid(DPI_HUGE) msgstr("Sehr groß (250%)") msgid(PROXY_DISABLED) msgstr("Deaktiviert") msgid(PROXY_ALWAYS_USE) msgstr("Immer benutzen") msgid(NO) msgstr("Nein") msgid(YES) msgstr("Ja") msgid(OFF) msgstr("Aus") msgid(ON) msgstr("An") msgid(SHOW) msgstr("Zeigen") msgid(HIDE) msgstr("Verstecken") msgid(EXIT) msgstr("Beenden") msgid(VIDEO_IN_NONE) msgstr("keines") msgid(AUDIO_IN_DEFAULT_LOOPBACK) msgstr("Standard Loopback") msgid(AUDIO_IN_ANDROID) msgstr("OpenSL-Eingang") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("Bitte füge mich deiner Kontaktliste hinzu.") msgid(CONTACT_SEARCH_ADD_HINT) msgstr("Freunde suchen/hinzufügen") msgid(PROXY_EDIT_HINT_IP) msgstr("IP-Adresse") msgid(WINDOW_TITLE_VIDEO_PREVIEW) msgstr("Videovorschau") msgid(MUTE) msgstr("Stummschalten") msgid(UNMUTE) msgstr("Stummschaltung aufheben") msgid(SELECT_AVATAR_TITLE) msgstr("Avatar auswählen") msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS) msgstr("Avatar zu groß. Maximale Größe: ") msgid(CANT_FIND_FILE_OR_EMPTY) msgstr("Ausgewählte Datei existiert nicht oder ist leer.") msgid(CLEAR_HISTORY) msgstr("Chatverlauf leeren") msgid(AUTO_STARTUP) msgstr("Automatisch beim Systemstart starten") msgid(THEME) msgstr("Stil") msgid(THEME_DEFAULT) msgstr("Standard") msgid(THEME_LIGHT) msgstr("Hell") msgid(THEME_DARK) msgstr("Dunkel") msgid(THEME_HIGHCONTRAST) msgstr("Hoher Kontrast") msgid(THEME_CUSTOM) msgstr("Benutzerdefiniert (siehe Dokumentation)") msgid(THEME_SOLARIZED_LIGHT) msgstr("Solarized hell") msgid(THEME_SOLARIZED_DARK) msgstr("Solarized dunkel") msgid(SEND_TYPING_NOTIFICATIONS) msgstr("Mitteilen, ob getippt wird") msgid(STATUS_NOTIFICATIONS) msgstr("Statusbenachrichtigungen") msgid(RANDOMIZE_NOSPAM) msgstr("Zufälligen Nospam setzen") msgid(NOSPAM) msgstr("Nospam") msgid(REVERT_NOSPAM) msgstr("Nospam zurücksetzen") msgid(NOSPAM_WARNING) msgstr("Änderungen am Nospam machen die alte Tox ID ungültig. uTox wird die ID nicht auf Namensservern aktualisieren.") msgid(BLOCK_FRIEND_REQUESTS) msgstr("Freundschaftsanfragen blockieren") msgid(SHOW_NOSPAM) msgstr("Nospam Einstellungen anzeigen") msgid(HIDE_NOSPAM) msgstr("Nospam Einstellungen verstecken") msgid(DELETE_FRIEND) msgstr("Freund löschen") msgid(KEEP) msgstr("Behalten") uTox-0.17.1/langs/dk.h000066400000000000000000000100711354126257400144220ustar00rootroot00000000000000msgid(LANG_NATIVE_NAME) msgstr("Dansk") msgid(LANG_ENGLISH_NAME) msgstr("DANISH") msgid(REQ_SENT) msgstr("Venneanmodning sendt. Din ven vil forekomme online når anmodningen er accepteret.") msgid(REQ_INVALID_ID) msgstr("Fejl: Ugyldigt Tox ID") msgid(REQ_EMPTY_ID) msgstr("Fejl: Intet Tox ID specificeret") msgid(REQ_LONG_MSG) msgstr("Fejl: Besked er for lang") msgid(REQ_NO_MSG) msgstr("Fejl: Tom besked") msgid(REQ_SELF_ID) msgstr("Fejl: Tox ID er eget ID") msgid(REQ_ALREADY_FRIENDS) msgstr("Fejl: Tox ID er allerede på vennelisten") msgid(REQ_UNKNOWN) msgstr("Fejl: Ukendt") msgid(REQ_BAD_CHECKSUM) msgstr("Fejl: Ugyldigt Tox ID (forkert checksum)") msgid(REQ_BAD_NOSPAM) msgstr("Fejl: Ugyldigt Tox ID (forkert nospam værdi)") msgid(REQ_NO_MEMORY) msgstr("Fejl: Ingen hukommelse") msgid(TRANSFER_NEW) msgstr("Ny filoverførsel") msgid(TRANSFER_STARTED) msgstr("Filoverførsel startet") //msgid(TRANSFER___) //msgstr("...") msgid(TRANSFER_PAUSED) msgstr("Filoverførsel sat på pause") msgid(TRANSFER_BROKEN) msgstr("Filoverførsel fejlede") msgid(TRANSFER_CANCELLED) msgstr("Filoverførsel annulleret") msgid(TRANSFER_COMPLETE) msgstr("Filoverførsel færdig") msgid(CALL_CANCELLED) msgstr("Opkald annulleret") msgid(CALL_INVITED) msgstr("Opkald inviteret") msgid(CALL_RINGING) msgstr("Opkald ringer") msgid(CALL_STARTED) msgstr("Opkald startet") msgid(ADDFRIENDS) msgstr("Tilføj venner") //msgid(TOXID) //msgstr("Tox ID") msgid(MESSAGE) msgstr("Besked") msgid(ADD) msgstr("Tilføj") msgid(FRIENDREQUEST) msgstr("Venneanmodning") msgid(USERSETTINGS) msgstr("Brugerindstillinger") msgid(NAME) msgstr("Navn") msgid(STATUSMESSAGE) msgstr("Status besked") msgid(PREVIEW) msgstr("Eksempel") msgid(AUDIOINPUTDEVICE) msgstr("Lyd input enhed") msgid(AUDIOFILTERING) msgstr("Lyd Filter") msgid(AUDIOOUTPUTDEVICE) msgstr("Lyd output enhed") msgid(VIDEOINPUTDEVICE) msgstr("Video output enhed") msgid(OTHERSETTINGS) msgstr("Andre indstillinger") //msgid(DPI) //msgstr("DPI") msgid(SAVELOCATION) msgstr("Gem område") msgid(LANGUAGE) msgstr("Sprog") msgid(NETWORK) msgstr("Netværk") //msgid(IPV6) //msgstr("IPv6:") //msgid(UDP) //msgstr("UDP:") //msgid(PROXY) //msgstr("Proxy (SOCKS 5)") msgid(WARNING) msgstr("Ændring af Netværk/Proxy indstillinger vil midlertidigt afbryde din forbindelse til Tox netværket") msgid(SAVE_CHAT_HISTORY) msgstr("Logger") msgid(AUDIONOTIFICATIONS) msgstr("Aktiver lyd notifikation (Ringetone)") msgid(IS_TYPING) msgstr("skriver...") msgid(COPY) msgstr("Kopier") msgid(COPYWITHOUTNAMES) msgstr("Kopier (ingen navne)") msgid(CUT) msgstr("Klip") msgid(PASTE) msgstr("Indsæt") msgid(DELETE) msgstr("Slet") msgid(SELECTALL) msgstr("Vælg alle") msgid(REMOVE) msgstr("Fjern") msgid(LEAVE) msgstr("Forlad") msgid(ACCEPT) msgstr("Accepter") msgid(IGNORE) msgstr("Ignorer") msgid(CLICKTOSAVE) msgstr("Klik for at gemme") msgid(CLICKTOOPEN) msgstr("Klik for at åbne") msgid(CANCELLED) msgstr("Annulleret") msgid(DPI_TINY) msgstr("Lille (50%)") //msgid(DPI_NORMAL) //msgstr("Normal (100%)") msgid(DPI_BIG) msgstr("Stor (150%)") msgid(DPI_LARGE) msgstr("Kæmpe (200%)") msgid(DPI_HUGE) msgstr("Enorm (250%)") msgid(FILTER_ALL) msgstr("Alle") //msgid(FILTER_ONLINE) //msgstr("Online") msgid(PROXY_DISABLED) msgstr("Ikke slået til") //msgid(PROXY_FALLBACK) //msgstr("Fallback") msgid(PROXY_ALWAYS_USE) msgstr("Brug altid") msgid(NO) msgstr("Nej") msgid(YES) msgstr("Ja") msgid(VIDEO_IN_NONE) msgstr("Ingen") msgid(VIDEO_IN_DESKTOP) msgstr("Skrivebord") msgid(AUDIO_IN_DEFAULT_LOOPBACK) msgstr("Standard Loopback") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("Accepter venligst denne venneanmodning.") //msgid(PROXY_EDIT_HINT_IP) //msgstr("IP") //msgid(PROXY_EDIT_HINT_PORT) //msgstr("Port") msgid(WINDOW_TITLE_VIDEO_PREVIEW) msgstr("Video prøve") //msgid(MUTE) //msgstr("Mute") //msgid(UNMUTE) //msgstr("Unmute") msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS) msgstr("Avatar er for stor. Maximum Størrelse: ") msgid(CANT_FIND_FILE_OR_EMPTY) msgstr("Kan ikke finde den valgte fil eller også er valgte fil tom.") msgid(CLEAR_HISTORY) msgstr("Slet historie") uTox-0.17.1/langs/en.h000066400000000000000000000575271354126257400144470ustar00rootroot00000000000000/****************************************************************************** *** English i18l Strings *** ******************************************************************************/ msgid(LANG_NATIVE_NAME) msgstr("English") msgid(LANG_ENGLISH_NAME) msgstr("ENGLISH") /****************************************************************************** *** Splash Message & Change Log *** ******************************************************************************/ msgid(SPLASH_TITLE) msgstr("Welcome to the newer uTox!") msgid(SPLASH_TEXT) msgstr("You have just upgraded to version 0.17.1! Release name: \"Don't 🌟e at my 😬!\"") msgid(CHANGE_LOG_TITLE) msgstr("Changes in v0.17.1") msgid(CHANGE_LOG_TEXT) msgstr( "\n IMPORTANT NOTE FOR WINDOWS USERS\n" " Autoupdates are no longer provided.\n" "\n" " Features:\n" " Add `--allow-root` option: Now you can't run uTox as root by accident\n" " Add right click menu to Xlib\n" " Add support for loading groupchats\n" " More *BSD support! (FreeBSD, NetBSD, OpenBSD, DragonFlyBSD) (Thanks, mazocomp!)\n" " Groupchat creation screen implemented\n" "\n" " Fixes:\n" " Fix a crash when changing to a video input device that fails to init\n" " Fix a friendlist bug related to the Tox profile having no friends and groups\n" " Don't flip video preview button status if preview fails\n" " Xlib: Clean up zombies if `xdg-open` is not installed\n" " Add border to QR code to make it actually readable to QR code scanners\n" " Fix file transfer text\n" " Prevent a crash related to having too many friends\n" " Fix crash related to dropdowns\n" " Fix ignoring friend requests\n" " Close dropdowns on changing tabs\n" " Fix crash on startup related to QR code (Thanks, ColumPaget!)\n" " Fix group settings layout\n" " Fix a crash related to Tox savedata being too large\n" " Fix two possible memory leaks\n" " Fix a crash related to text undo in message input field (Thanks, cyisfor!)\n" " Fix a crash related to the password input field\n" " Fix crash related to FPS value input field\n" " Fix selection bug: Selection on double-click doesn't leak into neighbouring line anymore\n" " Fix HOME key\n" " Fix END key and make ctrl+shift+end work\n" " Sort languages enum by their native names alphabetically\n" " Move Language setting from \"Profile\" to \"User Interface\" tab\n" " Updated translations:\n" " - German\n" " - English\n" " - Polish\n" " - Swedish (Thanks, jony0008!)\n" " - Hungarian (Thanks, baloo79!)\n" "\n" " Development:\n" " Try to upgrade travis\n" " Travis win64 make cmake command explicit\n" " Disable incorrect updater test\n" " Auto 'clone' STB with cmake\n" " Make uTox reproducible (Thanks, bmwiedemann!)\n" " Some fixes for *BSD systems (Thanks, mazocomp!)\n" " - Enable tests by default\n" " - Update build instructions and add instructions for NetBSD and DragonFlyBSD\n" " - other build system fixes\n" "\nv0.17.0\n" " Features:\n" " Toxcore 0.2.x. support!\n" " Settings are now stored in a human-readable .ini file.\n" " We now support Tox URIs.\n" " Dropdowns now stay open after being clicked.\n" " You can now get a QR code representing your ToxID.\n" " Estonian language support\n" " Fixes:\n" " The zenburn colour scheme now works.\n" " Calls are now added to the chatlogs.\n" " Saving inline images now works to paths with non-ascii characters.\n" " GTK should work on more platforms now.\n" " Exporting chatlogs on macOS doesn't crash anymore.\n" " File transfers are now supported on macOS.\n" " The force proxy setting is now saved.\n" " The tray icon should maybe now probably work on most (maybe) Linux systems.\n" " Lots of UI fixes involving the bounding boxes of things.\n" " We now handle signals on Linux systems.\n" " Filter audio can now be enabled again.\n" " The Windows tray icon will be reloaded if Windows explorer crashes.\n" " You no longer end up with invalid fps data when loading an older save.\n" " Datetime format is now saved.\n" " Non-ASCII should work better now.\n" " Tooltips will now always be drawn within the window boundaries.\n" " Development:\n" " You can now set the library locations with CMAKE_PREFIX_PATH.\n" "\nv0.16.0\n" " Features:\n" " Language is now saved.\n" " Added group audio calls.\n" " User-specified FPS during video call.\n" " Fixes:\n" " OS X stability improvements.\n" " Video now works on Linux again.\n" " UI bugfixes and improvements. (Thanks @redmanmale!)\n" " Fixed Windows video preview window title. (Thanks @thorpelawrence!)\n" " More groupchat crashes fixed.\n" " Middle/double click in X11 now have the correct functionality. (Thanks @dkmoz!)\n" " Unicode urls now work on Windows.\n" " File transfer names are now sanitized on Windows.\n" " Autoaccept file transfer setting now saves again.\n" " Audio notifications now only play when uTox isn't in focus.\n" " Messages aren't marked as unread if the chat is open when messages are received.\n" " The GTK file picker now works on OpenBSD and NetBSD.\n" " Fixed autostart toggle being a no-op.\n" " Fixed typing notifications not using the contact's alias.\n" " Added timestamps to exported chatlog.\n" " Development:\n" " Dropped support for ToxDNS.\n" " Build instructions for OS X now exist. (Thanks @publicarray!)\n" " Tests are now run against OS X in addition to Linux.\n" " Added Python script for finding missing translations.\n" " Decreased size of MinSizeRel builds.\n" " Updated lots of translations.\n" "\n" " Do you know another language? Rather read the changelog in your language?\n" " Help us translate uTox!\n" "\nv0.15.0\n" " Fixes:\n" " Video now works on Windows again.\n" " Autoaccepting files in portable mode now saves to the portable folder.\n" " Updated Ukrainian translation. (Thanks v2e!)\n" " Dbus notifications should now work on more different setups.\n" " Development\n" " Added support for NetBSD, OpenBSD, and FreeBSD.\n" " Refactored the UI.\n" "\n Do you know another language? Rather read the changelog in your language?\n" " Help us translate uTox!\n" "\nv0.14.0\n" " Features:\n" " Real Updater.\n" " -- uTox now has an updater built in. Currently Windows only.\n" " -- But can be adapted to any platform if there's any interest.\n" " Added musl libc support.\n" " uTox is now compiled with stronger exploit protection.\n" " Significant reduction in memory usage for friend list.\n" " Fixes:\n" " New Nospams no longer start with 0000 on window.\n" " Fixed button alignment with Language selection.\n" " The tox save is no longer truncated at exit.\n" " The tray icon now always displays a square\n" " -- Even on broken display managers (uTox looks at gnome...)\n" " Bootstrap nodes list updated.\n" " Avatars can now be deleted.\n" " Notifications are no longer ignored when uTox is minimized.\n" " A few more file transfer fixes.\n" " -- Especially the last remaining one that would occasionally miss updates.\n" " Development\n" " All remaining warnings we fixed, -Werror was added\n" " Tests added:\n" " uTox Updater\n" " Chatlog reading and writing\n" " Refactored the UI a bit more. Which cleared out a few more of the UI glitches.\n" "\nv0.13.0\n" " Features:\n" " You can now paste UTF8 characters in uTox.\n" " You can now manually set your nospam!\n" "\n Fixes:\n" " Mostly fix groupchats. (At least they no longer crash uTox instantly..)\n" " Chatlogs can now be saved on Windows again.\n" " Clearing chat backlog no longer crashes uTox.\n" " Plug a lot of memory leaks.\n" " Scrolling with pgup/pgdn now redraws the chat window.\n" " Avatars now load again.\n" " Custom themes now work and won't crash uTox if you try to switch to it when it doesn't exist.\n" " Lots of build system improvements.\n" " Lots of file transfer fixes.\n" "\n Development\n" " uTox now has a unit test implemented! (Hopefully this means we'll never have a bug ever again.)\n" " UI files separated into UI components and layout.\n" " We now have our own build server!\n" "\nv0.12.2\n" " Fixed a Windows UI hang during file transfers.\n" " Fixed a Windows Crash during file transfers.\n" "\nv0.11.1\n" " Fixed crash with some transfers.\n" " Bug Fixes\n" " Fixed building on Windows XP\n" " Friend request improvements\n" " Added the ability to change nospam\n" " Added notifications and advanced tab to settings\n" " New updater\n" " Started seperating the core and the UI\n" "\nv0.11.1\n" " Feature: Export chatlog\n" " Feature: Added ability to decline an incoming call\n" " Various security fixes\n" " Fixed icon issues\n" " Better build system\n" " Switched to TokTok/c-toxcore\n" " Improvements to development process to allow for easier contribution of code\n" " New themes: Solarized light and Solarized dark\n" " Updated translations\n" " filter_audio optimisations\n" " Started using clang-format\n" " Stopped using clang-format\n" " New, shinier toggle buttons (thanks, tsudoko!)\n" " Better support for auto-accepting file transfers\n" " Fixed UI issues with the lock screen\n" "\nv0.11.0\n" " Were sorry, but the changelog for this version of uTox\n" " is only available to uTox GOLD Members.\n" "\nv0.9.8\n" " Fixed a crash when trying to create a new profile\n" "\nv0.9.7\n" " Some minor GUI fixes\n" " Replaced all Yes/No dropdowns with Switches\n" " Fixed saving proxy host & port across restarts.\n" "\nv0.9.5\n" " Inline video for OSX\n" " Fixed a logging bug\n" "\nv0.9.3\n" " Fixed a message bug causing sporatic crashes in Windows\n" " Limited the number of Messages to resend at once\n" "\nv0.9.2\n" " Source Cleanups/Dir changes\n" "\nv0.9.1\n" " Fixed a crash when sending a message to a new fiend\n" "\nv0.9.0\n" " Message queuing\n" " Better, and colorized groupchats\n" " Experimental Inline Video support\n" " Mini Contact list\n" " Refactored message handling\n" "\n") /****************************************************************************** *** MISC & UNSORTED *** ******************************************************************************/ msgid(REQ_SENT) msgstr("Friend request sent. Your friend will appear online after the request is accepted.") msgid(REQ_INVALID_ID) msgstr("Error: Invalid Tox ID") msgid(REQ_ADDED_NO_FREQ_SENT) msgstr("Note: Friend added but friend request was not sent (nospam missing)") msgid(REQ_EMPTY_ID) msgstr("Error: No Tox ID specified") msgid(REQ_LONG_MSG) msgstr("Error: Message is too long") msgid(REQ_NO_MSG) msgstr("Error: Empty message") msgid(REQ_SELF_ID) msgstr("Error: Tox ID is self ID") msgid(REQ_ALREADY_FRIENDS) msgstr("Error: Tox ID is already in friend list") msgid(REQ_UNKNOWN) msgstr("Error: Unknown") msgid(REQ_BAD_CHECKSUM) msgstr("Error: Invalid Tox ID (bad checksum)") msgid(REQ_BAD_NOSPAM) msgstr("Error: Invalid Tox ID (bad nospam value)") msgid(REQ_NO_MEMORY) msgstr("Error: No memory") msgid(SEND_FILE) msgstr("Send File") msgid(SAVE_FILE) msgstr("Save File") msgid(WHERE_TO_SAVE_FILE_PROMPT) msgstr("Where do you want to save \"%.*s\"?") msgid(WHERE_TO_SAVE_FILE) msgstr("Where do you want to save the file?") msgid(SEND_FILE_PROMPT) msgstr("Select one or more files to send.") msgid(SCREEN_CAPTURE_PROMPT) msgstr("Drag a box around the area of the screen you want to send.") /****************************************************************************** *** File Transfer Strings *** ******************************************************************************/ msgid(TRANSFER_NEW) msgstr("New file transfer") msgid(TRANSFER_STARTED) msgstr("File transfer started") msgid(TRANSFER___) msgstr("...") msgid(TRANSFER_PAUSED) msgstr("File transfer paused") msgid(TRANSFER_BROKEN) msgstr("File transfer broken") msgid(TRANSFER_CANCELLED) msgstr("File transfer canceled") msgid(TRANSFER_COMPLETE) msgstr("File transfer complete") /****************************************************************************** *** Keyboard and Mouse Cursor Strings *** ******************************************************************************/ msgid(CURSOR_CLICK_LEFT) msgstr("Left click") msgid(CURSOR_CLICK_RIGHT) msgstr("Right click") /****************************************************************************** *** Audio / Video Call Strings *** ******************************************************************************/ msgid(CALL_START_AUDIO) msgstr("Start call") msgid(CALL_START_VIDEO) msgstr("Start video call") msgid(CALL_DECLINE) msgstr("Decline the call") msgid(CALL_CANCELLED) msgstr("Call canceled") msgid(CALL_INVITED) msgstr("Call invited") msgid(CALL_RINGING) msgstr("Call ringing") msgid(CALL_STARTED) msgstr("Call started") msgid(CALL_ENDED) msgstr("Call ended") msgid(CALL_FRIEND_HAD_ENDED_CALL) msgstr(" has ended the call!") msgid(CALL_VIDEO_SHOW_INLINE) msgstr("Show video inline") /****************************************************************************** *** Friend & Friend Settings Strings *** ******************************************************************************/ msgid(FRIEND_ALIAS) msgstr("Set Friend Alias") msgid(FRIEND_PUBLIC_KEY) msgstr("Friend's Public Key") msgid(FRIEND_AUTOACCEPT) msgstr("Accept incoming file transfers without confirmation") msgid(FRIEND_EXPORT_CHATLOG) msgstr("Export Chatlog as plain text") /****************************************************************************** *** Group Strings *** ******************************************************************************/ msgid(GROUPCHAT_JOIN_AUDIO) msgstr("Join audio chat") msgid(GROUP_CREATE_WITH_AUDIO) msgstr("Enable Audio") msgid(GROUP_CREATE_TEXT) msgstr("Create a text-chat group") msgid(GROUP_CREATE_VOICE) msgstr("Create a voice-chat group") msgid(CREATEGROUPCHAT) msgstr("Create Groupchat") msgid(REMOVE_GROUP) msgstr("Remove Group") msgid(LEAVE_GROUP) msgstr("Leave Group") /****************************************************************************** *** Group Settings *** ******************************************************************************/ msgid(GROUPCHAT_SETTINGS) msgstr("Groupchat Settings") msgid(GROUP_NOTIFICATIONS) msgstr("Group Notifications") msgid(GROUP_NOTIFICATIONS_ON) msgstr("On") msgid(GROUP_NOTIFICATIONS_MENTION) msgstr("Mentioned") msgid(GROUP_NOTIFICATIONS_OFF) msgstr("Off") msgid(GROUP_TOPIC) msgstr("Set Group's Topic") /****************************************************************************** *** Settings / Profile Strings *** ******************************************************************************/ msgid(PROFILE_BUTTON) msgstr("Profile") msgid(DEVICES_BUTTON) msgstr("Devices") msgid(USER_INTERFACE_BUTTON) msgstr("User Interface") msgid(AUDIO_VIDEO_BUTTON) msgstr("Audio & Video") msgid(ADVANCED_BUTTON) msgstr("Advanced") msgid(NOTIFICATIONS_BUTTON) msgstr("Notifications") msgid(AUTO_UPDATE) msgstr("Automatically Update uTox") msgid(PROFILE_SETTINGS) msgstr("Profile Settings") msgid(PROFILE_PW_WARNING) msgstr("WARNING: µTox will automatically start encrypting with this password.") msgid(PROFILE_PW_NO_RECOVER) msgstr("There is no way to recover lost passwords.") /*** Profile ***/ /*** Devices ***/ msgid(DEVICES_ADD_NEW) msgstr("Add New Device to network") msgid(DEVICES_NUMBER) msgstr("Number of linked devices") /*** Network ***/ /*** User Interface ***/ /*** Audio/Video ***/ /****************************************************************************** *** UNSORTED STRINGS *** *** TODO: *** *** FIXME: *** ******************************************************************************/ msgid(ADDFRIENDS) msgstr("Add New Contact") msgid(TOXID) msgstr("Tox ID") msgid(MESSAGE) msgstr("Message") msgid(FILTER_ONLINE) msgstr("Online Contacts") msgid(FILTER_ALL) msgstr("All Contacts") msgid(FILTER_CONTACT_TOGGLE) msgstr("Toggle filtering of offline contacts.") msgid(ADD) msgstr("Add") msgid(FRIENDREQUEST) msgstr("Friend Request") msgid(USERSETTINGS) msgstr("User Settings") msgid(FRIEND_SETTINGS) msgstr("Friend Settings") msgid(NAME) msgstr("Name") msgid(STATUSMESSAGE) msgstr("Status Message") msgid(PREVIEW) msgstr("Preview") msgid(AUDIOINPUTDEVICE) msgstr("Audio Input Device") msgid(AUDIOFILTERING) msgstr("Audio Filtering") msgid(AUDIOOUTPUTDEVICE) msgstr("Audio Output Device") msgid(VIDEOINPUTDEVICE) msgstr("Video Input Device") msgid(VIDEOFRAMERATE) msgstr("Video Frame Rate (FPS)") msgid(PUSH_TO_TALK) msgstr("Push To Talk") msgid(STATUS) msgstr("Status") msgid(STATUS_ONLINE) msgstr("Online") msgid(STATUS_AWAY) msgstr("Away") msgid(STATUS_BUSY) msgstr("Busy") msgid(STATUS_OFFLINE) msgstr("Offline") /* * Leave %.*s. They are variables * The first one is your friend's name * The second one is the state your friend is now in */ msgid(STATUS_MESSAGE) msgstr("uTox %.*s is now %s.") msgid(SETTINGS_UI_MINI_ROSTER) msgstr("Use mini contact list") msgid(SETTINGS_UI_AUTO_HIDE_SIDEBAR) msgstr("Auto hide sidebar") msgid(NOT_CONNECTED) msgstr("Not Connected") msgid(NOT_CONNECTED_SETTINGS) msgstr("Adjust network settings") msgid(OTHERSETTINGS) msgstr("Other Settings") msgid(UI) msgstr("UI") msgid(USER_INTERFACE) msgstr("User Interface") msgid(UTOX_SETTINGS) msgstr("uTox Settings") msgid(NETWORK_SETTINGS) msgstr("Network Settings") msgid(PROFILE_PASSWORD) msgstr("Profile Password") msgid(LOCK_UTOX) msgstr("Disconnects from Tox and locks this profile.") msgid(SHOW_UI_PASSWORD) msgstr("Show password field") msgid(SHOW_UI_PASSWORD_TOOLTIP) msgstr("Click to show profile password field. Changes made here will be instant!") msgid(HIDE_UI_PASSWORD) msgstr("Hide password field") msgid(HIDE_UI_PASSWORD_TOOLTIP) msgstr("Click to hide profile password field.") msgid(PASSWORD_TOO_SHORT) msgstr("Password must be at least 4 characters long") msgid(LOCK) msgstr("Lock") msgid(AUDIO_VIDEO) msgstr("Audio/Video") msgid(DPI) msgstr("DPI") msgid(SAVELOCATION) msgstr("Save Location") msgid(LANGUAGE) msgstr("Language") msgid(NETWORK) msgstr("Network") msgid(IPV6) msgstr("IPv6") msgid(UDP) msgstr("UDP") msgid(PROXY) msgstr("Proxy (SOCKS 5)") msgid(PROXY_FORCE) msgstr("Force uTox to always use proxy") msgid(WARNING) msgstr("Changing Network/Proxy settings will temporarily disconnect you from the Tox network") msgid(SAVE_CHAT_HISTORY) msgstr("Save Chat History") msgid(AUDIONOTIFICATIONS) msgstr("Enable Audible Notification (Ringtone)") msgid(RINGTONE) msgstr("Ringtone") msgid(IS_TYPING) msgstr("is typing...") msgid(CLOSE_TO_TRAY) msgstr("Close To Tray") msgid(START_IN_TRAY) msgstr("Start In Tray") msgid(SHOW_QR) msgstr("Show QR code") msgid(HIDE_QR) msgstr("Hide QR code") msgid(SAVE_QR) msgstr("Save QR code") msgid(COPY_TOX_ID) msgstr("Copy as text") msgid(COPY) msgstr("Copy") msgid(COPYWITHOUTNAMES) msgstr("Copy (Without Names)") msgid(COPY_WITH_NAMES) msgstr("Copy (Include Names)") msgid(CUT) msgstr("Cut") msgid(PASTE) msgstr("Paste") msgid(DELETE) msgstr("Delete") msgid(SELECTALL) msgstr("Select All") msgid(REMOVE) msgstr("Remove") msgid(REMOVE_FRIEND) msgstr("Remove Friend") msgid(LEAVE) msgstr("Leave") msgid(CTOPIC) msgstr("Change Topic") msgid(ACCEPT) msgstr("Accept") msgid(IGNORE) msgstr("Ignore") msgid(SET_ALIAS) msgstr("Set alias") msgid(ALIAS) msgstr("Alias") msgid(SENDMESSAGE) msgstr("Send message") msgid(SENDSCREENSHOT) msgstr("Send a screenshot") msgid(CLICKTOSAVE) msgstr("Click to save") msgid(CLICKTOOPEN) msgstr("Click to open") msgid(CANCELLED) msgstr("Cancelled") msgid(DPI_060) msgstr("Custom DPI 60%") msgid(DPI_070) msgstr("Custom DPI 70%") msgid(DPI_080) msgstr("Custom DPI 80%") msgid(DPI_090) msgstr("Custom DPI 90%") msgid(DPI_100) msgstr("Custom DPI 100%") msgid(DPI_110) msgstr("Custom DPI 110%") msgid(DPI_120) msgstr("Custom DPI 120%") msgid(DPI_130) msgstr("Custom DPI 130%") msgid(DPI_140) msgstr("Custom DPI 140%") msgid(DPI_150) msgstr("Custom DPI 150%") msgid(DPI_160) msgstr("Custom DPI 160%") msgid(DPI_170) msgstr("Custom DPI 170%") msgid(DPI_180) msgstr("Custom DPI 180%") msgid(DPI_190) msgstr("Custom DPI 190%") msgid(DPI_200) msgstr("Custom DPI 200%") msgid(DPI_210) msgstr("Custom DPI 210%") msgid(DPI_220) msgstr("Custom DPI 220%") msgid(DPI_230) msgstr("Custom DPI 230%") msgid(DPI_240) msgstr("Custom DPI 240%") msgid(DPI_250) msgstr("Custom DPI 250%") msgid(DPI_260) msgstr("Custom DPI 260%") msgid(DPI_270) msgstr("Custom DPI 270%") msgid(DPI_280) msgstr("Custom DPI 280%") msgid(DPI_290) msgstr("Custom DPI 290%") msgid(DPI_300) msgstr("Custom DPI 300%") msgid(DPI_TINY) msgstr("Tiny (50%)") msgid(DPI_NORMAL) msgstr("Normal (100%)") msgid(DPI_BIG) msgstr("Big (150%)") msgid(DPI_LARGE) msgstr("Large (200%)") msgid(DPI_HUGE) msgstr("Huge (250%)") msgid(PROXY_DISABLED) msgstr("Disabled") msgid(PROXY_FALLBACK) msgstr("Fallback") msgid(PROXY_ALWAYS_USE) msgstr("Always use") msgid(NO) msgstr("No") msgid(YES) msgstr("Yes") msgid(OFF) msgstr("Off") msgid(ON) msgstr("On") msgid(SHOW) msgstr("Show") msgid(HIDE) msgstr("Hide") msgid(EXIT) msgstr("Exit") msgid(VIDEO_IN_NONE) msgstr("None") msgid(VIDEO_IN_DESKTOP) msgstr("Desktop") msgid(AUDIO_IN_DEFAULT_LOOPBACK) msgstr("Default Loopback") msgid(AUDIO_IN_ANDROID) msgstr("OpenSL Input") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("Please accept this friend request.") msgid(CONTACT_SEARCH_ADD_HINT) msgstr("Search/Add Friends") msgid(PROXY_EDIT_HINT_IP) msgstr("IP address") msgid(PROXY_EDIT_HINT_PORT) msgstr("Port") msgid(WINDOW_TITLE_VIDEO_PREVIEW) msgstr("Video Preview") msgid(MUTE) msgstr("Mute") msgid(UNMUTE) msgstr("Unmute") msgid(SELECT_AVATAR_TITLE) msgstr("Select Avatar") msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS) msgstr("Avatar too large. Maximum size: ") msgid(CANT_FIND_FILE_OR_EMPTY) msgstr("Cannot find selected file or selected file is empty.") msgid(CLEAR_HISTORY) msgstr("Clear history") msgid(AUTO_STARTUP) msgstr("Launch at system startup") msgid(THEME) msgstr("Theme") msgid(THEME_DEFAULT) msgstr("Default") msgid(THEME_LIGHT) msgstr("Light theme") msgid(THEME_DARK) msgstr("Dark theme") msgid(THEME_HIGHCONTRAST) msgstr("High contrast") msgid(THEME_CUSTOM) msgstr("Custom (see docs)") msgid(THEME_ZENBURN) msgstr("Zenburn") msgid(THEME_SOLARIZED_LIGHT) msgstr("Solarized-light") msgid(THEME_SOLARIZED_DARK) msgstr("Solarized-dark") msgid(SEND_TYPING_NOTIFICATIONS) msgstr("Send typing notifications") msgid(STATUS_NOTIFICATIONS) msgstr("Status Notifications") msgid(RANDOMIZE_NOSPAM) msgstr("Randomize Nospam") msgid(NOSPAM) msgstr("Nospam") msgid(REVERT_NOSPAM) msgstr("Revert Nospam") msgid(NOSPAM_WARNING) msgstr("Changing your nospam will cause your old tox ID to no longer work. uTox does not update your ID on name servers.") msgid(BLOCK_FRIEND_REQUESTS) msgstr("Block Friend Requests") msgid(SHOW_NOSPAM) msgstr("Show Nospam Settings") msgid(HIDE_NOSPAM) msgstr("Hide Nospam Settings") msgid(DELETE_FRIEND) msgstr("Delete Friend") msgid(DELETE_MESSAGE) msgstr("Are you sure you want to delete ") msgid(KEEP) msgstr("Keep") uTox-0.17.1/langs/eo.h000066400000000000000000000154641354126257400144420ustar00rootroot00000000000000msgid(LANG_NATIVE_NAME) msgstr("Esperanto") msgid(LANG_ENGLISH_NAME) msgstr("ESPERANTO") msgid(REQ_SENT) msgstr("Amikiĝpeto sendita. Via amiko aperos enrete post la konsento de la peto.") msgid(REQ_INVALID_ID) msgstr("Eraro: Nevalida Tox-identigilo") msgid(REQ_EMPTY_ID) msgstr("Eraro: Neniu Tox-identigilo difinita") msgid(REQ_LONG_MSG) msgstr("Eraro: La mesaĝo estas tro longa") msgid(REQ_NO_MSG) msgstr("Eraro: Malplena mesaĝo") msgid(REQ_SELF_ID) msgstr("Eraro: La Tox-identigilo estas la mema identigilo") msgid(REQ_ALREADY_FRIENDS) msgstr("Eraro: Ĉi tiu Tox-identigilo jam estas en via listo de amikoj") msgid(REQ_UNKNOWN) msgstr("Eraro: Nekonata") msgid(REQ_BAD_CHECKSUM) msgstr("Eraro: Nevalida Tox-identigilo (malbona kontrolsumo)") msgid(REQ_BAD_NOSPAM) msgstr("Eraro: Nevalida Tox-identigilo (malbona valoro nospam)") msgid(REQ_NO_MEMORY) msgstr("Eraro: Mankas memorion") msgid(SEND_FILE) msgstr("Sendi dosieron") msgid(SAVE_FILE) msgstr("Konservi dosieron") msgid(WHERE_TO_SAVE_FILE_PROMPT) msgstr("Kie vi volas konservi \"%.*s\"?") msgid(SEND_FILE_PROMPT) msgstr("Elektu unu aŭ pli dosierojn por sendi.") msgid(SCREEN_CAPTURE_PROMPT) msgstr("Trenu skatolon ĉirkaŭ la ekrana regiono, kie vi volas sendi.") msgid(TRANSFER_NEW) msgstr("Nova dosiera transigo") msgid(TRANSFER_STARTED) msgstr("Dosiera transigo komencita") msgid(TRANSFER___) msgstr("...") msgid(TRANSFER_PAUSED) msgstr("Dosiera transigo paŭzita") msgid(TRANSFER_BROKEN) msgstr("Dosiera transigo rompita") msgid(TRANSFER_CANCELLED) msgstr("Dosiera transigo nuligita") msgid(TRANSFER_COMPLETE) msgstr("Dosiera transigo kompletigita") msgid(GROUPCHAT_JOIN_AUDIO) msgstr("Aliĝi al voĉa babilejo") msgid(CALL_START_AUDIO) msgstr("Eki voĉan vokon") msgid(CALL_START_VIDEO) msgstr("Eki videan vokon") msgid(CALL_CANCELLED) msgstr("Voko nuligita") msgid(CALL_INVITED) msgstr("Voko invitita") msgid(CALL_RINGING) msgstr("Voko sonoras") msgid(CALL_STARTED) msgstr("Voko ekita") msgid(PROFILE_SETTINGS) msgstr("Profilaj Agordoj") msgid(PROFILE_PW_WARNING) msgstr("AVERTO: µTox aŭtomate ekĉifros kun ĉi tiu pasvorto.") msgid(PROFILE_PW_NO_RECOVER) msgstr("Ne estas manieroj por restaŭri perditajn pasvortojn.") msgid(ADDFRIENDS) msgstr("Aldoni novan kontakton") msgid(TOXID) msgstr("Tox-identigilo") msgid(MESSAGE) msgstr("Mesaĝo") msgid(FILTER_ALL) msgstr("Enretaj Kontaktoj") msgid(FILTER_ONLINE) msgstr("Ĉiuj Kontaktoj") msgid(FILTER_CONTACT_TOGGLE) msgstr("Baskuligi filtradon de eksterretaj kontaktoj.") msgid(ADD) msgstr("Aldoni") msgid(CREATEGROUPCHAT) msgstr("Krei Grupbabilejo") msgid(FRIENDREQUEST) msgstr("Amikiĝpeto") msgid(USERSETTINGS) msgstr("Uzantaj Agordoj") msgid(NAME) msgstr("Nomo") msgid(STATUSMESSAGE) msgstr("Stata mesaĝo") msgid(PREVIEW) msgstr("Antaŭvidi") msgid(AUDIOINPUTDEVICE) msgstr("Aparato por sona enigo") msgid(AUDIOFILTERING) msgstr("Sona filtrado") msgid(AUDIOOUTPUTDEVICE) msgstr("Aparato por sona eliro") msgid(VIDEOINPUTDEVICE) msgstr("Aparato por videa enigo") msgid(PUSH_TO_TALK) msgstr("Premi por babili") msgid(STATUS) msgstr("Stato") msgid(STATUS_ONLINE) msgstr("Enreta") msgid(STATUS_AWAY) msgstr("Fore") msgid(STATUS_BUSY) msgstr("Okupata") msgid(OTHERSETTINGS) msgstr("Aliaj agordoj") msgid(UI) msgstr("Fasado") msgid(USER_INTERFACE) msgstr("Uzanta Fasado") msgid(UTOX_SETTINGS) msgstr("Agordoj de uTox") msgid(NETWORK_SETTINGS) msgstr("Retaj Agordoj") msgid(PROFILE_PASSWORD) msgstr("Profila pasvorto") msgid(LOCK_UTOX) msgstr("Malkonektas el Toxcore, kaj ŝlosas la profilon") msgid(LOCK) msgstr("Ŝlosi") msgid(AUDIO_VIDEO) msgstr("Sono/Video") msgid(DPI) msgstr("DPI") msgid(SAVELOCATION) msgstr("Konservi lokon") msgid(LANGUAGE) msgstr("Lingvo") msgid(NETWORK) msgstr("Reto") msgid(IPV6) msgstr("IPv6:") msgid(UDP) msgstr("UDP:") msgid(PROXY) msgstr("Prokurilo (SOCKS 5)") msgid(WARNING) msgstr("Ŝanĝante agordojn de reto aŭ prokurilo nedaŭre malkonektos vin el la Tox-reto") msgid(SAVE_CHAT_HISTORY) msgstr("Protokolado") msgid(AUDIONOTIFICATIONS) msgstr("Ebligi sonan sciigon (vokosonon)") msgid(RINGTONE) msgstr("Vokosono") msgid(IS_TYPING) msgstr("tajpas...") msgid(CLOSE_TO_TRAY) msgstr("Fermi al la pleto") msgid(START_IN_TRAY) msgstr("Komenci el la pleto") msgid(COPY) msgstr("Kopii") msgid(COPYWITHOUTNAMES) msgstr("Kopii (sen nomoj)") msgid(COPY_WITH_NAMES) msgstr("Kopii (kun nomoj)") msgid(CUT) msgstr("Eltondi") msgid(PASTE) msgstr("Alglui") msgid(DELETE) msgstr("Forviŝi") msgid(SELECTALL) msgstr("Elektu ĉion") msgid(REMOVE) msgstr("Forigi") msgid(REMOVE_FRIEND) msgstr("Forigi amikon") msgid(REMOVE_GROUP) msgstr("Forigi grupon") msgid(LEAVE) msgstr("Eliri") msgid(LEAVE_GROUP) msgstr("Eliri grupon") msgid(CTOPIC) msgstr("Ŝanĝi temon") msgid(ACCEPT) msgstr("Konsenti") msgid(IGNORE) msgstr("Ignori") msgid(SET_ALIAS) msgstr("Krei kromnomon") msgid(SENDMESSAGE) msgstr("Sendi mesaĝon") msgid(SENDSCREENSHOT) msgstr("Sendi ekranprintaĵon") msgid(CLICKTOSAVE) msgstr("Alklaki por konservi") msgid(CLICKTOOPEN) msgstr("Alklaki por malfermi") msgid(CANCELLED) msgstr("Nuligita") msgid(DPI_TINY) msgstr("Eta (50%)") msgid(DPI_NORMAL) msgstr("Normala (100%)") msgid(DPI_BIG) msgstr("Granda (150%)") msgid(DPI_LARGE) msgstr("Larĝa (200%)") msgid(DPI_HUGE) msgstr("Grandega (250%)") msgid(FILTER_ALL) msgstr("Ĉion") msgid(PROXY_DISABLED) msgstr("Malebligita") msgid(PROXY_FALLBACK) msgstr("Retrodefaŭlto") msgid(PROXY_ALWAYS_USE) msgstr("Ĉiam uzi") msgid(NO) msgstr("Ne") msgid(YES) msgstr("Jes") msgid(OFF) msgstr("Malaktivigita") msgid(ON) msgstr("Aktivigita") msgid(VIDEO_IN_NONE) msgstr("Nenio") msgid(VIDEO_IN_DESKTOP) msgstr("Labortablo") msgid(AUDIO_IN_DEFAULT_LOOPBACK) msgstr("Defaŭlta inversa ciklo") msgid(AUDIO_IN_ANDROID) msgstr("OpenSL-enmeto") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("Bonvolu akceptu ĉi tiun amikiĝpeton.") msgid(CONTACT_SEARCH_ADD_HINT) msgstr("Serĉi/Aldoni Amikoj") msgid(PROXY_EDIT_HINT_IP) msgstr("IP") msgid(PROXY_EDIT_HINT_PORT) msgstr("Pordo") msgid(WINDOW_TITLE_VIDEO_PREVIEW) msgstr("Videa Antaŭvido") msgid(MUTE) msgstr("Silentigi") msgid(UNMUTE) msgstr("Malsilentigi") msgid(SELECT_AVATAR_TITLE) msgstr("Elekti profilbildon") msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS) msgstr("La profilbildo estas tro granda. Maksimuma grando: ") msgid(CANT_FIND_FILE_OR_EMPTY) msgstr("Ne eblas trovi la elektitan dosieron aŭ la elektita dosiero estas malplena.") msgid(CLEAR_HISTORY) msgstr("Forviŝi historion") msgid(AUTO_STARTUP) msgstr("Lanĉi ĉe sistema startigo") msgid(THEME) msgstr("Temo") msgid(THEME_DEFAULT) msgstr("Defaŭlto") msgid(THEME_LIGHT) msgstr("Hela temo") msgid(THEME_DARK) msgstr("Malhela temo") msgid(THEME_HIGHCONTRAST) msgstr("Granda kontrasto") msgid(THEME_CUSTOM) msgstr("Propra (vidu dokumentojn)") msgid(THEME_ZENBURN) msgstr("Zenburn") msgid(SEND_TYPING_NOTIFICATIONS) msgstr("Sendi sciigojn pri tajpado") uTox-0.17.1/langs/es.h000066400000000000000000000140271354126257400144400ustar00rootroot00000000000000msgid(LANG_NATIVE_NAME) msgstr("Español") msgid(LANG_ENGLISH_NAME) msgstr("SPANISH") msgid(REQ_SENT) msgstr("Solicitud de amistad enviada. Esta persona aparecerá conectada cuando acepte la solicitud.") msgid(REQ_INVALID_ID) msgstr("Error: Tox ID inválida") msgid(REQ_EMPTY_ID) msgstr("Error: Tox ID no especificada") msgid(REQ_LONG_MSG) msgstr("Error: El mensaje es demasiado largo") msgid(REQ_NO_MSG) msgstr("Error: Mensaje vacío") msgid(REQ_SELF_ID) msgstr("Error: La Tox ID es tu propia ID") msgid(REQ_ALREADY_FRIENDS) msgstr("Error: La Tox ID ya está en la lista de amigos") msgid(REQ_UNKNOWN) msgstr("Error: Desconocido") msgid(REQ_BAD_CHECKSUM) msgstr("Error: Tox ID inválida (checksum incorrecto)") msgid(REQ_BAD_NOSPAM) msgstr("Error: Tox ID inválida (valor nospam incorrecto)") msgid(REQ_NO_MEMORY) msgstr("Error: No hay memoria suficiente") msgid(SEND_FILE) msgstr("Enviar archivo") msgid(SAVE_FILE) msgstr("Guardar archivo") msgid(WHERE_TO_SAVE_FILE_PROMPT) msgstr("¿Dónde quieres guardar \"%.*s\"?") msgid(SEND_FILE_PROMPT) msgstr("Selecciona uno o más archivos para enviar.") msgid(SCREEN_CAPTURE_PROMPT) msgstr("Arrastra el cursor para hacer una caja alrededor del área de la pantalla que quieras enviar.") msgid(TRANSFER_NEW) msgstr("Nueva transferencia de archivos") msgid(TRANSFER_STARTED) msgstr("Transferencia de archivos iniciada") msgid(TRANSFER___) msgstr("...") msgid(TRANSFER_PAUSED) msgstr("Transferencia de archivos pausada") msgid(TRANSFER_BROKEN) msgstr("Transferencia de archivos rota") msgid(TRANSFER_CANCELLED) msgstr("Transferencia de archivos cancelada") msgid(TRANSFER_COMPLETE) msgstr("Transferencia de archivos completada") msgid(CALL_CANCELLED) msgstr("Llamada cancelada") msgid(CALL_INVITED) msgstr("Llamada invitada") msgid(CALL_RINGING) msgstr("Llamada sonando") msgid(CALL_STARTED) msgstr("Llamada iniciada") msgid(ADDFRIENDS) msgstr("Añadir Amigos") msgid(TOXID) msgstr("Tox ID") msgid(MESSAGE) msgstr("Mensaje") msgid(ADD) msgstr("Añadir") msgid(CREATEGROUPCHAT) msgstr("Crear Chat Grupal") msgid(FRIENDREQUEST) msgstr("Solicitud de Amistad") msgid(USERSETTINGS) msgstr("Ajustes del Usuario") msgid(NAME) msgstr("Nombre") msgid(STATUSMESSAGE) msgstr("Mensaje de Estado") msgid(PREVIEW) msgstr("Vista previa") msgid(AUDIOINPUTDEVICE) msgstr("Dispositivo de Entrada de Audio") msgid(AUDIOFILTERING) msgstr("Filtrar Audio") msgid(AUDIOOUTPUTDEVICE) msgstr("Dispositivo de Salida de Audio") msgid(VIDEOINPUTDEVICE) msgstr("Dispositivo de Entrada de Video") msgid(OTHERSETTINGS) msgstr("Más Ajustes") msgid(UI) msgstr("IU") msgid(USER_INTERFACE) msgstr("Interfaz") msgid(UTOX_SETTINGS) msgstr("Ajustes de uTox") msgid(NETWORK_SETTINGS) msgstr("Ajustes de Red") msgid(AUDIO_VIDEO) msgstr("Audio/Video") msgid(DPI) msgstr("DPI") msgid(SAVELOCATION) msgstr("Guardar Ubicación") msgid(LANGUAGE) msgstr("Idioma") msgid(NETWORK) msgstr("Red") msgid(IPV6) msgstr("IPv6:") msgid(UDP) msgstr("UDP:") msgid(PROXY) msgstr("Proxy (SOCKS 5)") msgid(WARNING) msgstr("Cambiar los ajustes de red/proxy te desconectará temporalmente de la red de Tox") msgid(SAVE_CHAT_HISTORY) msgstr("Registros") msgid(AUDIONOTIFICATIONS) msgstr("Activar Notificaciones por Sonido (Tonos)") msgid(RINGTONE) msgstr("Tono") msgid(IS_TYPING) msgstr("está escribiendo...") msgid(CLOSE_TO_TRAY) msgstr("Ocultar en la bandeja al cerrar") msgid(START_IN_TRAY) msgstr("Ocultar en la bandeja por defecto") msgid(COPY) msgstr("Copiar") msgid(COPYWITHOUTNAMES) msgstr("Copiar (sin nombres)") msgid(COPY_WITH_NAMES) msgstr("Copiar (incluir nombres)") msgid(CUT) msgstr("Cortar") msgid(PASTE) msgstr("Pegar") msgid(DELETE) msgstr("Eliminar") msgid(SELECTALL) msgstr("Seleccionar todo") msgid(REMOVE) msgstr("Eliminar") msgid(REMOVE_FRIEND) msgstr("Eliminar Amigo") msgid(REMOVE_GROUP) msgstr("Eliminar Grupo") msgid(LEAVE) msgstr("Salir") msgid(LEAVE_GROUP) msgstr("Salir del grupo") msgid(CTOPIC) msgstr("Cambiar tema") msgid(ACCEPT) msgstr("Aceptar") msgid(IGNORE) msgstr("Ignorar") msgid(SENDSCREENSHOT) msgstr("Enviar una captura de pantalla") msgid(CLICKTOSAVE) msgstr("Clic para guardar") msgid(CLICKTOOPEN) msgstr("Clic para abrir") msgid(CANCELLED) msgstr("Cancelado") msgid(DPI_TINY) msgstr("Pequeño (50%)") msgid(DPI_NORMAL) msgstr("Normal (100%)") msgid(DPI_BIG) msgstr("Grande (150%)") msgid(DPI_LARGE) msgstr("Muy grande (200%)") msgid(DPI_HUGE) msgstr("Enorme (250%)") msgid(FILTER_ALL) msgstr("Todos") msgid(FILTER_ONLINE) msgstr("Conectados") msgid(PROXY_DISABLED) msgstr("Desactivado") msgid(PROXY_FALLBACK) msgstr("Sólo si no se puede conectar normalmente") msgid(PROXY_ALWAYS_USE) msgstr("Usar siempre") msgid(NO) msgstr("No") msgid(YES) msgstr("Sí") msgid(OFF) msgstr("Desactivado") msgid(ON) msgstr("Activado") msgid(VIDEO_IN_NONE) msgstr("Ninguno") msgid(VIDEO_IN_DESKTOP) msgstr("Escritorio") msgid(AUDIO_IN_DEFAULT_LOOPBACK) msgstr("Loopback") msgid(AUDIO_IN_ANDROID) msgstr("Entrada de OpenSL") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("Por favor, acepta esta solicitud de amistad.") msgid(PROXY_EDIT_HINT_IP) msgstr("IP") msgid(PROXY_EDIT_HINT_PORT) msgstr("Puerto") msgid(WINDOW_TITLE_VIDEO_PREVIEW) msgstr("Vista previa del video") msgid(MUTE) msgstr("Silenciar") msgid(UNMUTE) msgstr("Reactivar sonido") msgid(SELECT_AVATAR_TITLE) msgstr("Seleccionar imagen de perfil") msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS) msgstr("Imagen de perfil demasiado grande. Tamaño máximo: ") msgid(CANT_FIND_FILE_OR_EMPTY) msgstr("No se ha encontrado el archivo seleccionado, o el archivo está vacío.") msgid(CLEAR_HISTORY) msgstr("Limpiar historial") msgid(AUTO_STARTUP) msgstr("Iniciar automáticamente cuando se encienda el ordenador") msgid(THEME) msgstr("Tema") msgid(THEME_DEFAULT) msgstr("Por defecto") msgid(THEME_LIGHT) msgstr("Tema claro") msgid(THEME_DARK) msgstr("Tema oscuro") msgid(THEME_HIGHCONTRAST) msgstr("Alto contraste") msgid(THEME_CUSTOM) msgstr("Personalizado (lee la documentación)") msgid(THEME_ZENBURN) msgstr("Zenburn") msgid(SEND_TYPING_NOTIFICATIONS) msgstr("Mostrar cuándo estoy escribiendo") uTox-0.17.1/langs/et.h000066400000000000000000000351311354126257400144400ustar00rootroot00000000000000/****************************************************************************** *** Estonian i18l Strings *** ******************************************************************************/ msgid(LANG_NATIVE_NAME) msgstr("Eesti") msgid(LANG_ENGLISH_NAME) msgstr("ESTONIAN") /****************************************************************************** *** Splash Message & Change Log *** ******************************************************************************/ msgid(SPLASH_TITLE) msgstr("Tere tulemast uuemasse uTox-i!") msgid(SPLASH_TEXT) msgstr("Te olete uuendanud versioonile 0.16.1! Väljalaske nimi: No capes!") msgid(CHANGE_LOG_TITLE) msgstr("Muutused v0.16.1 versioonis (Vaadake meie uut veebilehte, utox.io)") /****************************************************************************** *** MISC & UNSORTED *** ******************************************************************************/ msgid(REQ_SENT) msgstr("Sõbra kutse saadetud. Sinu sõber ilmub nähtavale kui ta võtab sõbrataotluse vastu.") msgid(REQ_INVALID_ID) msgstr("Viga: Vale Tox-i ID") msgid(REQ_ADDED_NO_FREQ_SENT) msgstr("Note: Sõber lisati, kuid sõbra päringut ei saadetud (spämmivastane number puudub)") msgid(REQ_EMPTY_ID) msgstr("Viga: Tox-i ID-d pole määratud") msgid(REQ_LONG_MSG) msgstr("Viga: Sõnum on liiga pikk") msgid(REQ_NO_MSG) msgstr("Viga: Tühi sõnum") msgid(REQ_SELF_ID) msgstr("Viga: Tox-i ID on sinu enda ID") msgid(REQ_ALREADY_FRIENDS) msgstr("Viga: Tox-i ID on juba sõprade nimekirjas") msgid(REQ_UNKNOWN) msgstr("Viga: Teadmata") msgid(REQ_BAD_CHECKSUM) msgstr("Viga: Kehtetu Tox-i ID (vale kontrollsumma)") msgid(REQ_BAD_NOSPAM) msgstr("Viga: Kehtetu Tox-i ID (vale spämmivastane väärtus)") msgid(REQ_NO_MEMORY) msgstr("Viga: Pole piisavalt mälu") msgid(SEND_FILE) msgstr("Saada fail") msgid(SAVE_FILE) msgstr("Salvesta fail") msgid(WHERE_TO_SAVE_FILE_PROMPT) msgstr("Kuhu sa soovid salvestada \"%.*s\"?") msgid(WHERE_TO_SAVE_FILE) msgstr("Kuhu sa soovid salvestada seda faili?") msgid(SEND_FILE_PROMPT) msgstr("Vali üks või mitu faili.") msgid(SCREEN_CAPTURE_PROMPT) msgstr("Lohistage kasti ümber ekraani ala, mida soovite saata.") /****************************************************************************** *** File Transfer Strings *** ******************************************************************************/ msgid(TRANSFER_NEW) msgstr("Uus failiedastus") msgid(TRANSFER_STARTED) msgstr("Failiedastus algas") msgid(TRANSFER___) msgstr("...") msgid(TRANSFER_PAUSED) msgstr("Failiedastus on peatatud") msgid(TRANSFER_BROKEN) msgstr("Failiedastus ebaõnnestus") msgid(TRANSFER_CANCELLED) msgstr("Failiedastus tühistati") msgid(TRANSFER_COMPLETE) msgstr("Failiedastus õnnestus") /****************************************************************************** *** Keyboard and Mouse Cursor Strings *** ******************************************************************************/ msgid(CURSOR_CLICK_LEFT) msgstr("Vasak klikk") msgid(CURSOR_CLICK_RIGHT) msgstr("Parem klikk") /****************************************************************************** *** Audio / Video Call Strings *** ******************************************************************************/ msgid(CALL_START_AUDIO) msgstr("Alusta kõnet") msgid(CALL_START_VIDEO) msgstr("Alusta videokõnet") msgid(CALL_DECLINE) msgstr("Keeldu kõnest") msgid(CALL_CANCELLED) msgstr("Kõne tühistatud") msgid(CALL_INVITED) msgstr("Kõne kutsutud") msgid(CALL_RINGING) msgstr("Kõne kutsub") msgid(CALL_STARTED) msgstr("Kõne algas") msgid(CALL_ENDED) msgstr("Kõne lõppes") msgid(CALL_FRIEND_HAD_ENDED_CALL) msgstr(" Sõber lõpetas kõne!") msgid(CALL_VIDEO_SHOW_INLINE) msgstr("Näita videot teksti sees") /****************************************************************************** *** Friend & Friend Settings Strings *** ******************************************************************************/ msgid(FRIEND_ALIAS) msgstr("Säti sõbra nimi, mis sulle on nähtav") msgid(FRIEND_PUBLIC_KEY) msgstr("Sõbra avalik võti") msgid(FRIEND_AUTOACCEPT) msgstr("Võta sissetulevad failid automaatselt vastu") msgid(FRIEND_EXPORT_CHATLOG) msgstr("Ekspordi vestluslogi teksti failina") /****************************************************************************** *** Group Strings *** ******************************************************************************/ msgid(GROUPCHAT_JOIN_AUDIO) msgstr("Ühine helikõnega") msgid(GROUP_CREATE_TEXT) msgstr("Tee tekstipõhine grupikõne") msgid(GROUP_CREATE_VOICE) msgstr("Tee grupikõne koos heliga") msgid(CREATEGROUPCHAT) msgstr("Tee grupikõne") msgid(REMOVE_GROUP) msgstr("Eemalda grupp") msgid(LEAVE_GROUP) msgstr("Lahku grupist") /****************************************************************************** *** Group Settings *** ******************************************************************************/ msgid(GROUPCHAT_SETTINGS) msgstr("Grupikõne sätted") msgid(GROUP_NOTIFICATIONS) msgstr("Grupi märguanded") msgid(GROUP_NOTIFICATIONS_ON) msgstr("Sees") msgid(GROUP_NOTIFICATIONS_MENTION) msgstr("Ainult, kui mind mainiti") msgid(GROUP_NOTIFICATIONS_OFF) msgstr("Väljas") msgid(GROUP_TOPIC) msgstr("Sisesta grupi teema") /****************************************************************************** *** Settings / Profile Strings *** ******************************************************************************/ msgid(PROFILE_BUTTON) msgstr("Profiil") msgid(DEVICES_BUTTON) msgstr("Seadmed") msgid(USER_INTERFACE_BUTTON) msgstr("Kasutajaliides") msgid(AUDIO_VIDEO_BUTTON) msgstr("Heli & Video") msgid(ADVANCED_BUTTON) msgstr("Täpsemalt") msgid(NOTIFICATIONS_BUTTON) msgstr("Teated") msgid(AUTO_UPDATE) msgstr("Automaatselt uuenda uTox-i") msgid(PROFILE_SETTINGS) msgstr("Profiili sätted") msgid(PROFILE_PW_WARNING) msgstr("HOIATUS: µTox hakkab automaatselt sisestatud parooliga krüpteerima.") msgid(PROFILE_PW_NO_RECOVER) msgstr("Kaotatud parooli pole võimalik taastada.") /*** Profile ***/ /*** Devices ***/ msgid(DEVICES_ADD_NEW) msgstr("Lisa uus seade võrku") msgid(DEVICES_NUMBER) msgstr("Ühendatud seadmete arv") /*** Network ***/ /*** User Interface ***/ /*** Audio/Video ***/ /****************************************************************************** *** UNSORTED STRINGS *** *** TODO: *** *** FIXME: *** ******************************************************************************/ msgid(ADDFRIENDS) msgstr("Lisa uusi kontakte") msgid(TOXID) msgstr("Tox ID") msgid(MESSAGE) msgstr("Sõnum") msgid(FILTER_ONLINE) msgstr("Seesolevad kontaktid") msgid(FILTER_ALL) msgstr("Kõik kontaktid") msgid(FILTER_CONTACT_TOGGLE) msgstr("Väljasoleva kontaktide filtreerimine.") msgid(ADD) msgstr("Lisa") msgid(FRIENDREQUEST) msgstr("Sõbrakutse") msgid(USERSETTINGS) msgstr("Kasutaja sätted") msgid(FRIEND_SETTINGS) msgstr("Sõbra sätted") msgid(NAME) msgstr("Nimi") msgid(STATUSMESSAGE) msgstr("Olekuteade") msgid(PREVIEW) msgstr("Eelvaade") msgid(AUDIOINPUTDEVICE) msgstr("Heli sisendseade") msgid(AUDIOFILTERING) msgstr("Heli Filtreering") msgid(AUDIOOUTPUTDEVICE) msgstr("Heli väljundseade") msgid(VIDEOINPUTDEVICE) msgstr("Video sisendseade") msgid(VIDEOFRAMERATE) msgstr("Video kaadrisagedus (FPS)") msgid(PUSH_TO_TALK) msgstr("Vajuta, et rääkida") msgid(STATUS) msgstr("Staatus") msgid(STATUS_ONLINE) msgstr("Sees") msgid(STATUS_AWAY) msgstr("Eemal") msgid(STATUS_BUSY) msgstr("Hõivatud") msgid(STATUS_OFFLINE) msgstr("Väljas") /* * Leave %.*s. They are variables * The first one is your friend's name * The second one is the state your friend is now in */ msgid(STATUS_MESSAGE) msgstr("uTox %.*s on nüüd %s.") msgid(SETTINGS_UI_MINI_ROSTER) msgstr("Kasuta väikest kontaktide nimekirja") msgid(SETTINGS_UI_AUTO_HIDE_SIDEBAR) msgstr("Automaatselt peida küljeriba") msgid(NOT_CONNECTED) msgstr("Pole ühendatud") msgid(NOT_CONNECTED_SETTINGS) msgstr("Kohanda võrgu sätteid") msgid(OTHERSETTINGS) msgstr("Teised sätted") msgid(UI) msgstr("UI") msgid(USER_INTERFACE) msgstr("Kasutajaliides") msgid(UTOX_SETTINGS) msgstr("uTox sätted") msgid(NETWORK_SETTINGS) msgstr("Võrgu sätted") msgid(PROFILE_PASSWORD) msgstr("Profiili parool") msgid(LOCK_UTOX) msgstr("Katkestab Tox-i võrgu ja lukustab profiili.") msgid(SHOW_UI_PASSWORD) msgstr("Näita parooli välja") msgid(SHOW_UI_PASSWORD_TOOLTIP) msgstr("Klõpsake, et näha parooli välja. Siin tehtud muudatused mõjuvad koheselt!") msgid(HIDE_UI_PASSWORD) msgstr("Peitke parooli väli") msgid(HIDE_UI_PASSWORD_TOOLTIP) msgstr("Klõpsake, et peita parooli väli.") msgid(LOCK) msgstr("Lukusta") msgid(AUDIO_VIDEO) msgstr("Heli/Video") msgid(DPI) msgstr("DPI") msgid(SAVELOCATION) msgstr("Salvesta asukoht") msgid(LANGUAGE) msgstr("Keel") msgid(NETWORK) msgstr("Võrk") msgid(IPV6) msgstr("IPv6:") msgid(UDP) msgstr("UDP:") msgid(PROXY) msgstr("Puhverserver (SOCKS 5)") msgid(PROXY_FORCE) msgstr("Sunni uTox alati kasutama puhverserverit") msgid(WARNING) msgstr("Võrgu / puhverserveri seadete muutmine ajutiselt katkestab teid Toxi võrgust") msgid(SAVE_CHAT_HISTORY) msgstr("Salvesta vestluse ajalugu") msgid(AUDIONOTIFICATIONS) msgstr("Luba helisignaalid (Helin)") msgid(RINGTONE) msgstr("Helin") msgid(IS_TYPING) msgstr("Kirjutab...") msgid(CLOSE_TO_TRAY) msgstr("Sulge tegumiribale") msgid(START_IN_TRAY) msgstr("Stardi tegumiribal") msgid(COPY) msgstr("Kopeeri") msgid(COPYWITHOUTNAMES) msgstr("Kopeeri (Ilma nimedetta)") msgid(COPY_WITH_NAMES) msgstr("Kopeeri (Koos nimedega)") msgid(CUT) msgstr("Lõika") msgid(PASTE) msgstr("Kleebi") msgid(DELETE) msgstr("Kustuta") msgid(SELECTALL) msgstr("Vali kõik") msgid(REMOVE) msgstr("Eemalda") msgid(REMOVE_FRIEND) msgstr("Eemalda sõber") msgid(LEAVE) msgstr("Lahku") msgid(CTOPIC) msgstr("Muuda teemat") msgid(ACCEPT) msgstr("Nõustun") msgid(IGNORE) msgstr("Ignoreeri") msgid(SET_ALIAS) msgstr("Seadista teine nimi") msgid(ALIAS) msgstr("Teise nimega") msgid(SENDMESSAGE) msgstr("Saada sõnum") msgid(SENDSCREENSHOT) msgstr("Saada ekraanitõmmis") msgid(CLICKTOSAVE) msgstr("Vajuta, et salvestada") msgid(CLICKTOOPEN) msgstr("Vajuta, et avada") msgid(CANCELLED) msgstr("Tühistatud") msgid(DPI_060) msgstr("Kohandatud DPI 60%") msgid(DPI_070) msgstr("Kohandatud DPI 70%") msgid(DPI_080) msgstr("Kohandatud DPI 80%") msgid(DPI_090) msgstr("Kohandatud DPI 90%") msgid(DPI_100) msgstr("Kohandatud DPI 100%") msgid(DPI_110) msgstr("Kohandatud DPI 110%") msgid(DPI_120) msgstr("Kohandatud DPI 120%") msgid(DPI_130) msgstr("Kohandatud DPI 130%") msgid(DPI_140) msgstr("Kohandatud DPI 140%") msgid(DPI_150) msgstr("Kohandatud DPI 150%") msgid(DPI_160) msgstr("Kohandatud DPI 160%") msgid(DPI_170) msgstr("Kohandatud DPI 170%") msgid(DPI_180) msgstr("Kohandatud DPI 180%") msgid(DPI_190) msgstr("Kohandatud DPI 190%") msgid(DPI_200) msgstr("Kohandatud DPI 200%") msgid(DPI_210) msgstr("Kohandatud DPI 210%") msgid(DPI_220) msgstr("Kohandatud DPI 220%") msgid(DPI_230) msgstr("Kohandatud DPI 230%") msgid(DPI_240) msgstr("Kohandatud DPI 240%") msgid(DPI_250) msgstr("Kohandatud DPI 250%") msgid(DPI_260) msgstr("Kohandatud DPI 260%") msgid(DPI_270) msgstr("Kohandatud DPI 270%") msgid(DPI_280) msgstr("Kohandatud DPI 280%") msgid(DPI_290) msgstr("Kohandatud DPI 290%") msgid(DPI_300) msgstr("Kohandatud DPI 300%") msgid(DPI_TINY) msgstr("Väike (50%)") msgid(DPI_NORMAL) msgstr("Normaalne (100%)") msgid(DPI_BIG) msgstr("Suur (150%)") msgid(DPI_LARGE) msgstr("Ülisuur (200%)") msgid(DPI_HUGE) msgstr("Hiiglaslik (250%)") msgid(PROXY_DISABLED) msgstr("Keelatud") msgid(PROXY_FALLBACK) msgstr("Varuvariant") msgid(PROXY_ALWAYS_USE) msgstr("Alati kasuta") msgid(NO) msgstr("Ei") msgid(YES) msgstr("Jah") msgid(OFF) msgstr("Väljas") msgid(ON) msgstr("Sees") msgid(SHOW) msgstr("Näita") msgid(HIDE) msgstr("Peida") msgid(VIDEO_IN_NONE) msgstr("None") msgid(VIDEO_IN_DESKTOP) msgstr("Töölaud") msgid(AUDIO_IN_DEFAULT_LOOPBACK) msgstr("Default Loopback") msgid(AUDIO_IN_ANDROID) msgstr("OpenSL Input") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("Palun vasta sõbrakutsele.") msgid(CONTACT_SEARCH_ADD_HINT) msgstr("Otsi/Lisa sõpru") msgid(PROXY_EDIT_HINT_IP) msgstr("IP") msgid(PROXY_EDIT_HINT_PORT) msgstr("Port") msgid(WINDOW_TITLE_VIDEO_PREVIEW) msgstr("Video eelvaade") msgid(MUTE) msgstr("Hääl maha") msgid(UNMUTE) msgstr("Hääl sisse") msgid(SELECT_AVATAR_TITLE) msgstr("Vali avatar") msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS) msgstr("Avatar on liiga suur. Maksimaalne suurus: ") msgid(CANT_FIND_FILE_OR_EMPTY) msgstr("Valitud faili ei leitud või valitud fail on tühi.") msgid(CLEAR_HISTORY) msgstr("Puhasta ajalugu") msgid(AUTO_STARTUP) msgstr("Käivita koos arvuti käivitusega") msgid(THEME) msgstr("Stiil") msgid(THEME_DEFAULT) msgstr("Vaikimisi") msgid(THEME_LIGHT) msgstr("Hele") msgid(THEME_DARK) msgstr("Tume") msgid(THEME_HIGHCONTRAST) msgstr("Kõrge kontrastsus") msgid(THEME_CUSTOM) msgstr("Oma stiil (vt dokumentatsiooni)") msgid(THEME_ZENBURN) msgstr("Zenburn") msgid(THEME_SOLARIZED_LIGHT) msgstr("Solarized-light") msgid(THEME_SOLARIZED_DARK) msgstr("Solarized-dark") msgid(SEND_TYPING_NOTIFICATIONS) msgstr("Saada trükkimise teavitus") msgid(STATUS_NOTIFICATIONS) msgstr("Oleku teavitus") msgid(RANDOMIZE_NOSPAM) msgstr("Juhuslik Nospam") msgid(NOSPAM) msgstr("Spämmitõrje") msgid(REVERT_NOSPAM) msgstr("Ennista Nospam") msgid(NOSPAM_WARNING) msgstr("Teie Nospam muutmine põhjustab teie vana Tox-i ID mitte töötamise. uTox ei värskenda teie ID-d nimeserveritel.") msgid(BLOCK_FRIEND_REQUESTS) msgstr("Blokeeri kõik sõbrakutsed") msgid(SHOW_NOSPAM) msgstr("Näita spämmivastast sätet") msgid(HIDE_NOSPAM) msgstr("Peida spämmivastane säte") msgid(DELETE_FRIEND) msgstr("Kustuta sõber") msgid(DELETE_MESSAGE) msgstr("Oled kindel, et soovid kustutada? ") msgid(KEEP) msgstr("Jäta alles") uTox-0.17.1/langs/fr.h000066400000000000000000000305341354126257400144410ustar00rootroot00000000000000/****************************************************************************** *** Chaînes i18l françaises *** ******************************************************************************/ msgid(LANG_NATIVE_NAME) msgstr("Français") msgid(LANG_ENGLISH_NAME) msgstr("FRENCH") /****************************************************************************** *** Écran d'accueil et historique des modifications *** ******************************************************************************/ msgid(SPLASH_TITLE) msgstr("Bienvenue sur le nouveau uTox !") //msgid(SPLASH_TEXT) //msgstr("You have just upgraded to version 0.9.5! Release name: Srsly") //msgid(CHANGE_LOG_TITLE) //msgstr("Changes in v0.9.5") //msgid(CHANGE_LOG_TEXT) //msgstr() /****************************************************************************** *** Splash Message & Change Log *** ******************************************************************************/ msgid(REQ_SENT) msgstr("Demande envoyée. Votre ami apparaîtra en ligne quand il acceptera votre demande.") msgid(REQ_INVALID_ID) msgstr("Erreur : ID Tox invalide") msgid(REQ_EMPTY_ID) msgstr("Erreur : Aucun ID Tox") msgid(REQ_LONG_MSG) msgstr("Erreur : Message trop long") msgid(REQ_NO_MSG) msgstr("Erreur : Message vide") msgid(REQ_SELF_ID) msgstr("Erreur : Cet ID Tox est votre ID personnel") msgid(REQ_ALREADY_FRIENDS) msgstr("Erreur : Cet ID Tox est déjà dans votre liste d'amis") msgid(REQ_UNKNOWN) msgstr("Erreur : Inconnue") msgid(REQ_BAD_CHECKSUM) msgstr("Erreur : ID Tox invalide (mauvaise somme de contrôle)") msgid(REQ_BAD_NOSPAM) msgstr("Erreur : ID Tox invalide (mauvaise valeur anti-spam)") msgid(REQ_NO_MEMORY) msgstr("Erreur : Pas de mémoire") msgid(SEND_FILE) msgstr("Envoyer un fichier") msgid(SAVE_FILE) msgstr("Sauvegarder le fichier") msgid(WHERE_TO_SAVE_FILE_PROMPT) msgstr("Où voulez-vous sauvegarder \"%.*s\" ?") msgid(WHERE_TO_SAVE_FILE) msgstr("Où voulez-vous sauvegarder le fichier ?") msgid(SEND_FILE_PROMPT) msgstr("Sélectionnez un ou plusieurs fichiers à envoyer.") msgid(SCREEN_CAPTURE_PROMPT) msgstr("Sélectionnez la zone de l'écran que vous voulez envoyer.") /****************************************************************************** *** Transfert de fichier *** ******************************************************************************/ msgid(TRANSFER_NEW) msgstr("Nouveau transfert de fichier") msgid(TRANSFER_STARTED) msgstr("Transfert de fichier commencé") //msgid(TRANSFER___) //msgstr("...") msgid(TRANSFER_PAUSED) msgstr("Transfert de fichier en pause") msgid(TRANSFER_BROKEN) msgstr("Transfert de fichier interrompu") msgid(TRANSFER_CANCELLED) msgstr("Transfert de fichier annulé") msgid(TRANSFER_COMPLETE) msgstr("Transfert de fichier terminé") /****************************************************************************** *** Clavier et souris *** ******************************************************************************/ msgid(CURSOR_CLICK_LEFT) msgstr("Clic gauche") msgid(CURSOR_CLICK_RIGHT) msgstr("Clic droit") /****************************************************************************** *** Appels Audio / Vidéo *** ******************************************************************************/ msgid(CALL_START_AUDIO) msgstr("Commencer un appel") msgid(CALL_START_VIDEO) msgstr("Commencer un appel vidéo") msgid(CALL_DECLINE) msgstr("Rejeter l'appel") msgid(CALL_CANCELLED) msgstr("Appel annulé") msgid(CALL_INVITED) msgstr("Réception d'un appel") msgid(CALL_RINGING) msgstr("Appel en cours") msgid(CALL_STARTED) msgstr("Appel commencé") msgid(CALL_FRIEND_HAD_ENDED_CALL) msgstr(" a terminé l'appel !") msgid(CALL_VIDEO_SHOW_INLINE) msgstr("Montrer l'aperçu vidéo") /****************************************************************************** *** Amis & paramètres des amis *** ******************************************************************************/ msgid(FRIEND_ALIAS) msgstr("Définir un alias") msgid(FRIEND_PUBLIC_KEY) msgstr("Clé publique de l'ami") msgid(FRIEND_AUTOACCEPT) msgstr("Accepter les fichiers entrants sans confirmation") /****************************************************************************** *** Groupes *** ******************************************************************************/ msgid(GROUPCHAT_JOIN_AUDIO) msgstr("Rejoindre le tchat audio") msgid(GROUP_CREATE_TEXT) msgstr("Créer un salon de discussion textuel") msgid(GROUP_CREATE_VOICE) msgstr("Créer un salon de discussion vocal") msgid(CREATEGROUPCHAT) msgstr("Créer un salon de discussion") msgid(REMOVE_GROUP) msgstr("Supprimer le salon") msgid(LEAVE_GROUP) msgstr("Quitter le salon") /****************************************************************************** *** Paramètres / profile *** ******************************************************************************/ msgid(PROFILE_SETTINGS) msgstr("Paramètres du profil") msgid(PROFILE_PW_WARNING) msgstr("ATTENTION : µTox va automatiquement débuter le chiffrement avec ce mot de passe.") msgid(PROFILE_PW_NO_RECOVER) msgstr("Il n'y a aucun moyen de retrouver un mot de passe oublié.") /****************************************************************************** *** NON CLASSÉ *** *** TODO: *** *** FIXME: *** ******************************************************************************/ msgid(ADDFRIENDS) msgstr("Ajouter un ami") msgid(TOXID) msgstr("ID Tox") //msgid(MESSAGE) //msgstr("Message") msgid(FILTER_ONLINE) msgstr("En ligne") msgid(FILTER_ALL) msgstr("Tout") msgid(FILTER_CONTACT_TOGGLE) msgstr("Basculer le filtrage des contacts hors ligne.") msgid(ADD) msgstr("Ajouter") msgid(FRIENDREQUEST) msgstr("Demande d'ami") msgid(USERSETTINGS) msgstr("Paramètres utilisateur") msgid(FRIEND_SETTINGS) msgstr("Paramètres de l'ami") msgid(NAME) msgstr("Nom") msgid(STATUSMESSAGE) msgstr("Message d'humeur") msgid(PREVIEW) msgstr("Aperçu") msgid(AUDIOINPUTDEVICE) msgstr("Périphérique d'entrée audio") msgid(AUDIOFILTERING) msgstr("Filtre audio") msgid(AUDIOOUTPUTDEVICE) msgstr("Périphérique de sortie audio") msgid(VIDEOINPUTDEVICE) msgstr("Périphérique d'entrée vidéo") msgid(PUSH_TO_TALK) msgstr("Appuyer pour parler") //msgid(STATUS) //msgstr("Status") msgid(STATUS_ONLINE) msgstr("En ligne") msgid(STATUS_AWAY) msgstr("Absent") msgid(STATUS_BUSY) msgstr("Occupé") msgid(SETTINGS_UI_MINI_ROSTER) msgstr("Utiliser la mini liste de contacts") msgid(NOT_CONNECTED) msgstr("Non connecté") msgid(OTHERSETTINGS) msgstr("Autres paramètres") //msgid(UI) //msgstr("UI") msgid(USER_INTERFACE) msgstr("Interface utilisateur") msgid(UTOX_SETTINGS) msgstr("Paramètres de uTox") msgid(NETWORK_SETTINGS) msgstr("Paramètres réseau") msgid(PROFILE_PASSWORD) msgstr("Mot de passe du profil") msgid(LOCK_UTOX) msgstr("Se déconnecte de Tox et verrouille ce profil.") msgid(SHOW_UI_PASSWORD) msgstr("Cliquez pour afficher le champ du mot de passe. Les modifications effectuées ici seront instantanées !") msgid(LOCK) msgstr("Verrouiller") msgid(AUDIO_VIDEO) msgstr("Audio/Vidéo") msgid(DPI) msgstr("Taille de la police") msgid(SAVELOCATION) msgstr("Emplacement de la sauvegarde") msgid(LANGUAGE) msgstr("Langue") msgid(NETWORK) msgstr("Réseau") msgid(IPV6) msgstr("IPv6 :") msgid(UDP) msgstr("UDP :") //msgid(PROXY) //msgstr("Proxy (SOCKS 5)") msgid(WARNING) msgstr("Modifier les paramètres Réseau/Proxy vous déconnectera temporairement du réseau Tox") msgid(SAVE_CHAT_HISTORY) msgstr("Historique") msgid(AUDIONOTIFICATIONS) msgstr("Activer les notifications audio (Sonnerie)") msgid(RINGTONE) msgstr("Sonnerie") msgid(IS_TYPING) msgstr("est en train d'écrire...") msgid(CLOSE_TO_TRAY) msgstr("Minimiser dans la barre de tâches") msgid(START_IN_TRAY) msgstr("Démarrer dans la barre de tâches") msgid(COPY) msgstr("Copier") msgid(COPYWITHOUTNAMES) msgstr("Copier (sans les noms)") msgid(COPY_WITH_NAMES) msgstr("Copier (inclure les noms)") msgid(CUT) msgstr("Couper") msgid(PASTE) msgstr("Coller") msgid(DELETE) msgstr("Supprimer") msgid(SELECTALL) msgstr("Tout sélectionner") msgid(REMOVE) msgstr("Effacer") msgid(REMOVE_FRIEND) msgstr("Supprimer l'ami") msgid(LEAVE) msgstr("Partir") msgid(CTOPIC) msgstr("Changer le sujet") msgid(ACCEPT) msgstr("Accepter") msgid(IGNORE) msgstr("Ignorer") msgid(SET_ALIAS) msgstr("Définir un alias") //msgid(ALIAS) //msgstr("Alias") msgid(SENDMESSAGE) msgstr("Envoyer le message") msgid(SENDSCREENSHOT) msgstr("Envoyer une capture d'écran") msgid(CLICKTOSAVE) msgstr("Cliquer pour sauvegarder") msgid(CLICKTOOPEN) msgstr("Cliquer pour ouvrir") msgid(CANCELLED) msgstr("Annulé") msgid(DPI_060) msgstr("Taille personnalisée 60%") msgid(DPI_070) msgstr("Taille personnalisée 70%") msgid(DPI_080) msgstr("Taille personnalisée 80%") msgid(DPI_090) msgstr("Taille personnalisée 90%") msgid(DPI_100) msgstr("Taille personnalisée 100%") msgid(DPI_110) msgstr("Taille personnalisée 110%") msgid(DPI_120) msgstr("Taille personnalisée 120%") msgid(DPI_130) msgstr("Taille personnalisée 130%") msgid(DPI_140) msgstr("Taille personnalisée 140%") msgid(DPI_150) msgstr("Taille personnalisée 150%") msgid(DPI_160) msgstr("Taille personnalisée 160%") msgid(DPI_170) msgstr("Taille personnalisée 170%") msgid(DPI_180) msgstr("Taille personnalisée 180%") msgid(DPI_190) msgstr("Taille personnalisée 190%") msgid(DPI_200) msgstr("Taille personnalisée 200%") msgid(DPI_210) msgstr("Taille personnalisée 210%") msgid(DPI_220) msgstr("Taille personnalisée 220%") msgid(DPI_230) msgstr("Taille personnalisée 230%") msgid(DPI_240) msgstr("Taille personnalisée 240%") msgid(DPI_250) msgstr("Taille personnalisée 250%") msgid(DPI_260) msgstr("Taille personnalisée 260%") msgid(DPI_270) msgstr("Taille personnalisée 270%") msgid(DPI_280) msgstr("Taille personnalisée 280%") msgid(DPI_290) msgstr("Taille personnalisée 290%") msgid(DPI_300) msgstr("Taille personnalisée 300%") msgid(DPI_TINY) msgstr("Petit (50%)") //msgid(DPI_NORMAL) //msgstr("Normal (100%)") msgid(DPI_BIG) msgstr("Grand (150%)") //msgid(DPI_LARGE) //msgstr("Large (200%)") msgid(DPI_HUGE) msgstr("Très large (250%)") msgid(PROXY_DISABLED) msgstr("Désactivé") msgid(PROXY_FALLBACK) msgstr("Repli") msgid(PROXY_ALWAYS_USE) msgstr("Toujours utiliser") msgid(NO) msgstr("Non") msgid(YES) msgstr("Oui") //msgid(OFF) //msgstr("Off") //msgid(ON) //msgstr("On") msgid(SHOW) msgstr("Afficher") msgid(HIDE) msgstr("Masquer") msgid(VIDEO_IN_NONE) msgstr("Aucun") msgid(VIDEO_IN_DESKTOP) msgstr("Écran") msgid(AUDIO_IN_DEFAULT_LOOPBACK) msgstr("Par défaut") msgid(AUDIO_IN_ANDROID) msgstr("Entrée OpenSL") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("Veuillez accepter cette requête d'ami.") msgid(CONTACT_SEARCH_ADD_HINT) msgstr("Rechercher/Ajouter des amis") //msgid(PROXY_EDIT_HINT_IP) //msgstr("IP") //msgid(PROXY_EDIT_HINT_PORT) //msgstr("Port") msgid(WINDOW_TITLE_VIDEO_PREVIEW) msgstr("Aperçu vidéo") msgid(MUTE) msgstr("Muet") msgid(UNMUTE) msgstr("Non muet") msgid(SELECT_AVATAR_TITLE) msgstr("Sélectionner un avatar") msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS) msgstr("Avatar trop grand. Taille maximale : ") msgid(CANT_FIND_FILE_OR_EMPTY) msgstr("Impossible de trouver le fichier sélectionné ou le fichier sélectionné est vide.") msgid(CLEAR_HISTORY) msgstr("Nettoyer l'historique") msgid(AUTO_STARTUP) msgstr("Lancer au démarrage du système") msgid(THEME) msgstr("Thème") msgid(THEME_DEFAULT) msgstr("Défaut") msgid(THEME_LIGHT) msgstr("Thème clair") msgid(THEME_DARK) msgstr("Thème sombre") msgid(THEME_HIGHCONTRAST) msgstr("Contraste élevé") msgid(THEME_CUSTOM) msgstr("Personnalisé (voir docs)") //msgid(THEME_ZENBURN) //msgstr("Zenburn") msgid(THEME_SOLARIZED_LIGHT) msgstr("Solarized-clair") msgid(THEME_SOLARIZED_DARK) msgstr("Solarized-sombre") msgid(SEND_TYPING_NOTIFICATIONS) msgstr("Envoyer les notifications d'écriture") uTox-0.17.1/langs/hi.h000066400000000000000000000144601354126257400144320ustar00rootroot00000000000000msgid(LANG_NATIVE_NAME) msgstr("Hindi") msgid(LANG_ENGLISH_NAME) msgstr("HINDI") msgid(REQ_SENT) msgstr("मित्र अनुरोध. अपने दोस्त यहाँ होगा") //TODO: Same as in English? Localize or remove. //msgid(REQ_INVALID_ID) //msgstr("Error: Invalid Tox ID") msgid(REQ_EMPTY_ID) msgstr("Error: नहीं Tox ID specified") msgid(REQ_LONG_MSG) msgstr("Error: इस संदेश लंबा है") msgid(REQ_NO_MSG) msgstr("Error: खाली संदेश") //TODO: Same as in English? Localize or remove. //msgid(REQ_SELF_ID) //msgstr("Error: Tox ID is self ID") //TODO: Same as in English? Localize or remove. //msgid(REQ_ALREADY_FRIENDS) //msgstr("Error: Tox ID is already in friend list") msgid(REQ_UNKNOWN) msgstr("Error: अज्ञात") //TODO: Same as in English? Localize or remove. //msgid(REQ_BAD_CHECKSUM) //msgstr("Error: Invalid Tox ID (bad checksum)") //TODO: Same as in English? Localize or remove. //msgid(REQ_BAD_NOSPAM) //msgstr("Error: Invalid Tox ID (bad nospam value)") //TODO: Same as in English? Localize or remove. //msgid(REQ_NO_MEMORY) //msgstr("Error: No memory") msgid(TRANSFER_NEW) msgstr("नई file transfer") msgid(TRANSFER_STARTED) msgstr("नई transfer शुरुआत") //TODO: Same as in English? Localize or remove. //msgid(TRANSFER___) //msgstr("...") msgid(TRANSFER_PAUSED) msgstr("File transfer इंतजार") msgid(TRANSFER_BROKEN) msgstr("File transfer बुरा") msgid(TRANSFER_CANCELLED) msgstr("File transfer बंद") msgid(TRANSFER_COMPLETE) msgstr("File transfer खत्म") msgid(CALL_CANCELLED) msgstr("Call बंद") msgid(CALL_INVITED) msgstr("Call आमंत्रित") msgid(CALL_RINGING) msgstr("Call इंतजार") msgid(CALL_STARTED) msgstr("Call शुरुआत") msgid(ADDFRIENDS) msgstr("मित्र") //TODO: Same as in English? Localize or remove. //msgid(TOXID) //msgstr("Tox ID") msgid(MESSAGE) msgstr("संदेश") //TODO: Same as in English? Localize or remove. //msgid(ADD) //msgstr("Add") //TODO: Same as in English? Localize or remove. //msgid(SWITCHPROFILE) //msgstr("Switch Profile") msgid(FRIENDREQUEST) msgstr("मित्र Request") //TODO: Same as in English? Localize or remove. //msgid(USERSETTINGS) //msgstr("User Settings") msgid(NAME) msgstr("Nombre") //TODO: Same as in English? Localize or remove. //msgid(STATUSMESSAGE) //msgstr("Status Message") //TODO: Same as in English? Localize or remove. //msgid(PREVIEW) //msgstr("Preview") //TODO: Same as in English? Localize or remove. //msgid(DEVICESELECTION) //msgstr("Device Selection") //TODO: Same as in English? Localize or remove. //msgid(AUDIOINPUTDEVICE) //msgstr("Audio Input Device") //TODO: Same as in English? Localize or remove. //msgid(AUDIOOUTPUTDEVICE) //msgstr("Audio Output Device") //TODO: Same as in English? Localize or remove. //msgid(VIDEOINPUTDEVICE) //msgstr("Video Input Device") //TODO: Same as in English? Localize or remove. //msgid(OTHERSETTINGS) //msgstr("Other Settings") //TODO: Same as in English? Localize or remove. //msgid(DPI) //msgstr("DPI") //TODO: Same as in English? Localize or remove. //msgid(SAVELOCATION) //msgstr("Save Location") msgid(LANGUAGE) msgstr("भाषा") //TODO: Same as in English? Localize or remove. //msgid(NETWORK) //msgstr("Network") //TODO: Same as in English? Localize or remove. //msgid(IPV6) //msgstr("IPv6:") //TODO: Same as in English? Localize or remove. //msgid(UDP) //msgstr("UDP:") //TODO: Same as in English? Localize or remove. //msgid(PROXY) //msgstr("Proxy (SOCKS 5)") //TODO: Same as in English? Localize or remove. //msgid(WARNING) //msgstr("Changing Network/Proxy settings will temporarily disconnect you from the Tox network") //TODO: Same as in English? Localize or remove. //msgid(SAVE_CHAT_HISTORY) //msgstr("Logging") //TODO: Same as in English? Localize or remove. //msgid(IS_TYPING) //msgstr("is typing...") //TODO: Same as in English? Localize or remove. //msgid(COPY) //msgstr("Copy") //TODO: Same as in English? Localize or remove. //msgid(COPYWITHOUTNAMES) //msgstr("Copy (no names)") //TODO: Same as in English? Localize or remove. //msgid(CUT) //msgstr("Cut") //TODO: Same as in English? Localize or remove. //msgid(PASTE) //msgstr("Paste") //TODO: Same as in English? Localize or remove. //msgid(DELETE) //msgstr("Delete") //TODO: Same as in English? Localize or remove. //msgid(SELECTALL) //msgstr("Select All") msgid(REMOVE) msgstr("निकालें") msgid(LEAVE) msgstr("छोड़ दो") msgid(ACCEPT) msgstr("इसे ले") msgid(IGNORE) msgstr("उपेक्षा") //TODO: Same as in English? Localize or remove. //msgid(CLICKTOSAVE) //msgstr("Click to save") //TODO: Same as in English? Localize or remove. //msgid(CLICKTOOPEN) //msgstr("Click to open") msgid(CANCELLED) msgstr("बंद") //TODO: Localize or remove. //msgid(DPI_TINY) //msgstr("Tiny (50%)") //TODO: Localize or remove. //msgid(DPI_NORMAL) //msgstr("Normal (100%)") //TODO: Localize or remove. //msgid(DPI_BIG) //msgstr("Big (150%)") //TODO: Localize or remove. //msgid(DPI_LARGE) //msgstr("Large (200%)") //TODO: Localize or remove. //msgid(DPI_HUGE) //msgstr("Huge (250%)") //TODO: Localize or remove. //msgid(FILTER_ALL) //msgstr("All") //TODO: Localize or remove. //msgid(FILTER_ONLINE) //msgstr("Online") //TODO: Localize or remove. //msgid(PROXY_DISABLED) //msgstr("Disabled") //TODO: Localize or remove. //msgid(PROXY_FALLBACK) //msgstr("Fallback") //TODO: Localize or remove. //msgid(PROXY_ALWAYS_USE) //msgstr("Always use") //TODO: Localize or remove. //msgid(NO) //msgstr("No") //TODO: Localize or remove. //msgid(YES) //msgstr("Yes") //TODO: Localize or remove. //msgid(VIDEO_IN_NONE) //msgstr("None") //TODO: Localize or remove. //msgid(VIDEO_IN_DESKTOP) //msgstr("Desktop") //TODO: Localize or remove. //msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) //msgstr("Please accept this friend request.") //TODO: Localize or remove. //msgid(PROXY_EDIT_HINT_IP) //msgstr("IP") //TODO: Localize or remove. //msgid(PROXY_EDIT_HINT_PORT) //msgstr("Port") //TODO: Localize or remove. //msgid(AUDIO_IN_DEFAULT_LOOPBACK) //msgstr("Default Loopback") //TODO: Localize or remove. //msgid(WINDOW_TITLE_VIDEO_PREVIEW) //msgstr("Video Preview") //TODO: Localize or remove. //msgid(AUDIONOTIFICATIONS) //msgstr("Enable Audible Notification (Ringtone)") uTox-0.17.1/langs/hr.h000066400000000000000000000153771354126257400144530ustar00rootroot00000000000000msgid(LANG_NATIVE_NAME) msgstr("hrvatski") msgid(LANG_ENGLISH_NAME) msgstr("Croatian") msgid(REQ_SENT) msgstr("Zahtjev za prijateljstvom je poslan. Kad zahtjev bude prihvaćen, kontakt će postati nazočan.") msgid(REQ_INVALID_ID) msgstr("Greška: Tox ID nije valjan") msgid(REQ_EMPTY_ID) msgstr("Greška: Nije naveden Tox ID") msgid(REQ_LONG_MSG) msgstr("Greška: Preduga poruka") msgid(REQ_NO_MSG) msgstr("Greška: Prazna poruka") msgid(REQ_SELF_ID) msgstr("Greška: Uneseni Tox ID je vaš vlastiti Tox ID") msgid(REQ_ALREADY_FRIENDS) msgstr("Greška: Uneseni Tox ID je već dodan u popis prijatelja") msgid(REQ_UNKNOWN) msgstr("Greška: Nepoznat uzrok greške") msgid(REQ_BAD_CHECKSUM) msgstr("Greška: Nevaljani Tox ID (nevaljani kontrolni zbroj)") msgid(REQ_BAD_NOSPAM) msgstr("Greška: Nevaljani Tox ID (nevaljana nospam vrijednost)") msgid(REQ_NO_MEMORY) msgstr("Greška: Nema slobodne memorije") msgid(SEND_FILE) msgstr("Pošalji datoteku") msgid(SAVE_FILE) msgstr("Snimi datoteku") msgid(WHERE_TO_SAVE_FILE_PROMPT) msgstr("Gdje želite snimiti \"%.*s\"?") msgid(WHERE_TO_SAVE_FILE) msgstr("Gdje želite snimiti datoteku?") msgid(SEND_FILE_PROMPT) msgstr("Izaberite jednu ili više datoteka za slanje.") msgid(SCREEN_CAPTURE_PROMPT) msgstr("Namjestite okvir oko područja ekrana koje želite poslati.") msgid(TRANSFER_NEW) msgstr("Novi prijenos datoteka") msgid(TRANSFER_STARTED) msgstr("Prijenos datoteka u tijeku") msgid(TRANSFER_PAUSED) msgstr("Prijenos datoteka zaustavljen") msgid(TRANSFER_BROKEN) msgstr("Prijenos datoteka nije uspio") msgid(TRANSFER_CANCELLED) msgstr("Prijenos datoteka otkazan") msgid(TRANSFER_COMPLETE) msgstr("Prijenos datoteka dovršen") msgid(GROUPCHAT_JOIN_AUDIO) msgstr("Spoji se na audio chat") msgid(CALL_START_AUDIO) msgstr("Nazovi") msgid(CALL_START_VIDEO) msgstr("Nazovi - video poziv") msgid(CALL_CANCELLED) msgstr("Poziv otkazan") msgid(CALL_INVITED) msgstr("Poziv je poslan") msgid(CALL_RINGING) msgstr("Zvoni") msgid(CALL_STARTED) msgstr("Razgovor u tijeku") msgid(PROFILE_SETTINGS) msgstr("Postavke profila") msgid(PROFILE_PW_WARNING) msgstr("UPOZORENJE: µTox će automatski početi enkriptirati s navedenom zaporkom.") msgid(PROFILE_PW_NO_RECOVER) msgstr("Nema načina za vraćanje zaboravljene zaporke.") msgid(ADDFRIENDS) msgstr("Dodaj novi kontakt") msgid(MESSAGE) msgstr("Poruka") msgid(FILTER_ONLINE) msgstr("Nazočni prijatelji") msgid(FILTER_ALL) msgstr("Svi prijatelji") msgid(FILTER_CONTACT_TOGGLE) msgstr("Uključi-isključi offline prijatelje.") msgid(ADD) msgstr("Dodaj") msgid(CREATEGROUPCHAT) msgstr("Stvori grupni chat") msgid(FRIENDREQUEST) msgstr("Zahtjev za prijateljstvom") msgid(USERSETTINGS) msgstr("Postavke") msgid(FRIEND_SETTINGS) msgstr("Postavke prijatelja") msgid(NAME) msgstr("Ime") msgid(STATUSMESSAGE) msgstr("Statusna poruka") msgid(PREVIEW) msgstr("Pregled") msgid(AUDIOINPUTDEVICE) msgstr("Ulazni audio uređaj") msgid(AUDIOFILTERING) msgstr("Audio filtriranje") msgid(AUDIOOUTPUTDEVICE) msgstr("Izlazni audio uređaj") msgid(VIDEOINPUTDEVICE) msgstr("Ulazni video uređaj") msgid(PUSH_TO_TALK) msgstr("Stisni za govor") msgid(STATUS_ONLINE) msgstr("Nazočan") msgid(STATUS_AWAY) msgstr("Odsutan") msgid(STATUS_BUSY) msgstr("Zauzet") msgid(NOT_CONNECTED) msgstr("Nije spojen") msgid(OTHERSETTINGS) msgstr("Ostale postavke") msgid(USER_INTERFACE) msgstr("Sučelje") msgid(UTOX_SETTINGS) msgstr("Postavke") msgid(NETWORK_SETTINGS) msgstr("Mrežne postavke") msgid(PROFILE_PASSWORD) msgstr("Zaporka") msgid(LOCK_UTOX) msgstr("Odspoji Tox i zaključaj ovaj profil.") msgid(SHOW_UI_PASSWORD) msgstr("Klikni za prikaz zaporke. Promjene se odmah primjenjuju!") msgid(LOCK) msgstr("Zaključaj") msgid(AUDIO_VIDEO) msgstr("Audio/video") msgid(SAVELOCATION) msgstr("Snimi lokaciju") msgid(LANGUAGE) msgstr("Jezik") msgid(NETWORK) msgstr("Mreža") msgid(WARNING) msgstr("Promjena mrežnih/proxy postavki će vas privremeno odspojiti od Tox mreže") msgid(SAVE_CHAT_HISTORY) msgstr("Evidencije") msgid(AUDIONOTIFICATIONS) msgstr("Omogući zvučne obavijesti (zvonjenje)") msgid(RINGTONE) msgstr("Zvono") msgid(IS_TYPING) msgstr("piše...") msgid(CLOSE_TO_TRAY) msgstr("Minimiziraj") msgid(START_IN_TRAY) msgstr("Pokreni minimizirano") msgid(COPY) msgstr("Kopiraj") msgid(COPYWITHOUTNAMES) msgstr("Kopiraj (bez imena)") msgid(COPY_WITH_NAMES) msgstr("Kopiraj (uključujući imena)") msgid(CUT) msgstr("Izreži") msgid(PASTE) msgstr("Zalijepi") msgid(DELETE) msgstr("Obriši") msgid(SELECTALL) msgstr("Označi sve") msgid(REMOVE) msgstr("Ukloni") msgid(REMOVE_FRIEND) msgstr("Ukloni prijatelja") msgid(REMOVE_GROUP) msgstr("Ukloni grupu") msgid(LEAVE) msgstr("Izađi") msgid(LEAVE_GROUP) msgstr("Izađi iz grupe") msgid(CTOPIC) msgstr("Promijeni temu") msgid(ACCEPT) msgstr("Prihvati") msgid(IGNORE) msgstr("Ignoriraj") msgid(SET_ALIAS) msgstr("Namjesti alias") msgid(FRIEND_AUTOACCEPT) msgstr("Prihvati dolazne datoteke bez potvrde") msgid(SENDMESSAGE) msgstr("Pošalji poruku") msgid(SENDSCREENSHOT) msgstr("Pošalji snimak ekrana") msgid(CLICKTOSAVE) msgstr("Klikni za snimanje") msgid(CLICKTOOPEN) msgstr("Klikni za otvaranje") msgid(CANCELLED) msgstr("Otkazano") msgid(DPI_TINY) msgstr("Malo (50%)") msgid(DPI_NORMAL) msgstr("Normalno (100%)") msgid(DPI_BIG) msgstr("Povećano (150%)") msgid(DPI_LARGE) msgstr("Veliko (200%)") msgid(DPI_HUGE) msgstr("Ogromno (250%)") msgid(PROXY_DISABLED) msgstr("Onemogućeno") msgid(PROXY_FALLBACK) msgstr("Ako ne radi drugačije") msgid(PROXY_ALWAYS_USE) msgstr("Rabi uvijek") msgid(NO) msgstr("Ne") msgid(YES) msgstr("Da") msgid(OFF) msgstr("Isključeno") msgid(ON) msgstr("Uključeno") msgid(SHOW) msgstr("Prikaži") msgid(HIDE) msgstr("Sakrij") msgid(VIDEO_IN_NONE) msgstr("Nema") msgid(AUDIO_IN_DEFAULT_LOOPBACK) msgstr("Defaultni (loopback) ulaz") msgid(AUDIO_IN_ANDROID) msgstr("OpenSL ulaz") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("Molim prihvatite poziv za prijateljstvom.") msgid(CONTACT_SEARCH_ADD_HINT) msgstr("Traži/dodaj prijatelje") msgid(WINDOW_TITLE_VIDEO_PREVIEW) msgstr("Video pregled") msgid(MUTE) msgstr("Utišaj") msgid(UNMUTE) msgstr("Normalna glasnoća") msgid(SELECT_AVATAR_TITLE) msgstr("Izaberi avatar") msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS) msgstr("Prevelik avatar. Najveća veličina je: ") msgid(CANT_FIND_FILE_OR_EMPTY) msgstr("Nije moguće učitati izabranu datoteku ili je datoteka prazna.") msgid(CLEAR_HISTORY) msgstr("Obriši povijest") msgid(AUTO_STARTUP) msgstr("Pokreni pri podizanju sustava") msgid(THEME) msgstr("Tema") msgid(THEME_DEFAULT) msgstr("Defaultna tema") msgid(THEME_LIGHT) msgstr("Svijetla tema") msgid(THEME_DARK) msgstr("Tamna tema") msgid(THEME_HIGHCONTRAST) msgstr("Visoki kontrast") msgid(THEME_CUSTOM) msgstr("Posebno (vidi upute)") msgid(SEND_TYPING_NOTIFICATIONS) msgstr("Šalji obavijesti o tipkanju") uTox-0.17.1/langs/hu.h000066400000000000000000000417111354126257400144450ustar00rootroot00000000000000/****************************************************************************** *** Hungarian i18l Strings *** ******************************************************************************/ msgid(LANG_NATIVE_NAME) msgstr("Magyar") msgid(LANG_ENGLISH_NAME) msgstr("HUNGARIAN") /****************************************************************************** *** Splash Message & Change Log *** ******************************************************************************/ msgid(SPLASH_TITLE) msgstr("Üdvözöljük az újabb uToxban!") msgid(SPLASH_TEXT) msgstr("Ön a 0.17.0 verzióra frissített! A kiadás neve: bork bork") msgid(CHANGE_LOG_TITLE) msgstr("Változások a 0.17.0 verzióban") msgid(CHANGE_LOG_TEXT) msgstr( "\n FONTOS MEGJEGYZÉS WINDOWS FELHASZNÁLÓKNAK\n" " There is currently an issue with the updater where it won't work with some .exe names.\n" " To be sure that it works and autoupdates, you have to rename the .exe to \"uTox.exe\"\n" " and enable it in the settings.\n" "\n" " Tulajdonságok:\n" " Toxcore 0.2.x. support!\n" " Settings are now stored in a human-readable .ini file.\n" " We now support Tox URIs.\n" " Dropdowns now stay open after being clicked.\n" " You can now get a QR code representing your ToxID.\n" " Estonian language support\n" " Javítások:\n" " The zenburn colour scheme now works.\n" " Calls are now added to the chatlogs.\n" " Saving inline images now works to paths with non-ascii characters.\n" " GTK should work on more platforms now.\n" " Exporting chatlogs on macOS doesn't crash anymore.\n" " File transfers are now supported on macOS.\n" " The force proxy setting is now saved.\n" " The tray icon should maybe now probably work on most (maybe) Linux systems.\n" " Lots of UI fixes involving the bounding boxes of things.\n" " We now handle signals on Linux systems.\n" " Filter audio can now be enabled again.\n" " The Windows tray icon will be reloaded if Windows explorer crashes.\n" " You no longer end up with invalid fps data when loading an older save.\n" " Datetime format is now saved.\n" " Non-ASCII should work better now.\n" " Tooltips will now always be drawn within the window boundaries.\n" " Fejlesztés:\n" " You can now set the library locations with CMAKE_PREFIX_PATH.\n" "\n") /****************************************************************************** *** MISC & UNSORTED *** ******************************************************************************/ msgid(REQ_SENT) msgstr("Partnerkérelem elküldve. A partner elérhető lesz, miután a kérelmet elfogadta.") msgid(REQ_INVALID_ID) msgstr("Hiba: Érvénytelen Tox ID") msgid(REQ_ADDED_NO_FREQ_SENT) msgstr("Megj.: Partner hozzáadva, de partnerkérelem nem volt küldve (nospam hiány)") msgid(REQ_EMPTY_ID) msgstr("Hiba: Nincs megadva Tox ID") msgid(REQ_LONG_MSG) msgstr("Hiba: Az üzenet túl hosszú") msgid(REQ_NO_MSG) msgstr("Hiba: Üres üzenet") msgid(REQ_SELF_ID) msgstr("Hiba: A Tox ID ugyanaz") msgid(REQ_ALREADY_FRIENDS) msgstr("Hiba: A Tox ID már a partnerlistában van") msgid(REQ_UNKNOWN) msgstr("Hiba: Ismeretlen") msgid(REQ_BAD_CHECKSUM) msgstr("Hiba: Érvénytelen Tox ID (hibás checksum)") msgid(REQ_BAD_NOSPAM) msgstr("Hiba: Érvénytelen Tox ID (hibás nospam érték)") msgid(REQ_NO_MEMORY) msgstr("Hiba: Nincs memória") msgid(SEND_FILE) msgstr("Fájl küldése") msgid(SAVE_FILE) msgstr("Fájl mentése") msgid(WHERE_TO_SAVE_FILE_PROMPT) msgstr("Hová szeretné menteni ezt: \"%.*s\" ?") msgid(WHERE_TO_SAVE_FILE) msgstr("Hová szeretné menteni a fájlt?") msgid(SEND_FILE_PROMPT) msgstr("Válasszon ki egy vagy több fájlt a küldéshez!") msgid(SCREEN_CAPTURE_PROMPT) msgstr("Jelöljön ki egy területet a kijelzőn, amit el szeretne küldeni!") /****************************************************************************** *** File Transfer Strings *** ******************************************************************************/ msgid(TRANSFER_NEW) msgstr("Új fájl átvitel") msgid(TRANSFER_STARTED) msgstr("Fájl átvitel elindult") msgid(TRANSFER___) msgstr("...") msgid(TRANSFER_PAUSED) msgstr("Fájl átvitel szünetelve") msgid(TRANSFER_BROKEN) msgstr("Fájl átvitel sikertelen") msgid(TRANSFER_CANCELLED) msgstr("Fájl átvitel megszakadt") msgid(TRANSFER_COMPLETE) msgstr("Fájl átvitel sikeres") /****************************************************************************** *** Keyboard and Mouse Cursor Strings *** ******************************************************************************/ msgid(CURSOR_CLICK_LEFT) msgstr("Bal klikk") msgid(CURSOR_CLICK_RIGHT) msgstr("Jobbklikk") /****************************************************************************** *** Audio / Video Call Strings *** ******************************************************************************/ msgid(CALL_START_AUDIO) msgstr("Hívás indítása") msgid(CALL_START_VIDEO) msgstr("Videohívás indítása") msgid(CALL_DECLINE) msgstr("Hívás elutasítása") msgid(CALL_CANCELLED) msgstr("Hívás megszakadt") msgid(CALL_INVITED) msgstr("Hívás fogadva") msgid(CALL_RINGING) msgstr("Hívás") msgid(CALL_STARTED) msgstr("Hívás elindult") msgid(CALL_ENDED) msgstr("Hívás befejezve") msgid(CALL_FRIEND_HAD_ENDED_CALL) msgstr(" befejezte a hívást!") msgid(CALL_VIDEO_SHOW_INLINE) msgstr("Video mutatása ") /****************************************************************************** *** Friend & Friend Settings Strings *** ******************************************************************************/ msgid(FRIEND_ALIAS) msgstr("Álnév beállítása") msgid(FRIEND_PUBLIC_KEY) msgstr("Publikus kulcs") msgid(FRIEND_AUTOACCEPT) msgstr("Bejövő fájlátvitel elfogadása megerősítés nélkül") msgid(FRIEND_EXPORT_CHATLOG) msgstr("Chatnapló exportálása szövegként") /****************************************************************************** *** Group Strings *** ******************************************************************************/ msgid(GROUPCHAT_JOIN_AUDIO) msgstr("Belépés audiochatbe") msgid(GROUP_CREATE_WITH_AUDIO) msgstr("Hang engedélyezése") msgid(GROUP_CREATE_TEXT) msgstr("Szöveges chat csoport létrehozása") msgid(GROUP_CREATE_VOICE) msgstr("Audiochat csoport létrehozása") msgid(CREATEGROUPCHAT) msgstr("Csoportos chat létrehozása") msgid(REMOVE_GROUP) msgstr("Csoport eltávolítása") msgid(LEAVE_GROUP) msgstr("Kilépés a csoportból") /****************************************************************************** *** Group Settings *** ******************************************************************************/ msgid(GROUPCHAT_SETTINGS) msgstr("Csoportos chat beállítások") msgid(GROUP_NOTIFICATIONS) msgstr("Csoport értesítések") msgid(GROUP_NOTIFICATIONS_ON) msgstr("Be") msgid(GROUP_NOTIFICATIONS_MENTION) msgstr("Megemlítés") msgid(GROUP_NOTIFICATIONS_OFF) msgstr("Ki") msgid(GROUP_TOPIC) msgstr("Csoporttéma beállítása") /****************************************************************************** *** Settings / Profile Strings *** ******************************************************************************/ msgid(PROFILE_BUTTON) msgstr("Profil") msgid(DEVICES_BUTTON) msgstr("Eszközök") msgid(USER_INTERFACE_BUTTON) msgstr("Felhasználói felület") msgid(AUDIO_VIDEO_BUTTON) msgstr("Audio & Video") msgid(ADVANCED_BUTTON) msgstr("Továbbiak") msgid(NOTIFICATIONS_BUTTON) msgstr("Értesítések") msgid(AUTO_UPDATE) msgstr("uTox automatikus frissítése") msgid(PROFILE_SETTINGS) msgstr("Profilbeállítások") msgid(PROFILE_PW_WARNING) msgstr("FIGYELEM: µTox automatikusan elindítja a titkosítást ezzel a jelszóval.") msgid(PROFILE_PW_NO_RECOVER) msgstr("Elveszett jelszó visszaállítása nem lehetséges.") /*** Profile ***/ /*** Devices ***/ msgid(DEVICES_ADD_NEW) msgstr("Új eszköz hozzáadása") msgid(DEVICES_NUMBER) msgstr("Csatlakoztatott eszközök száma") /*** Network ***/ /*** User Interface ***/ /*** Audio/Video ***/ /****************************************************************************** *** UNSORTED STRINGS *** *** TODO: *** *** FIXME: *** ******************************************************************************/ msgid(ADDFRIENDS) msgstr("Új partner hozzáadása") msgid(TOXID) msgstr("Tox ID") msgid(MESSAGE) msgstr("Üzenet") msgid(FILTER_ONLINE) msgstr("Elérhető partnerek") msgid(FILTER_ALL) msgstr("Összes partner") msgid(FILTER_CONTACT_TOGGLE) msgstr("Nem elérhető partnerek szűrése") msgid(ADD) msgstr("Hozzáadás") msgid(FRIENDREQUEST) msgstr("Partnerkérelem") msgid(USERSETTINGS) msgstr("Felhasználói beállítások") msgid(FRIEND_SETTINGS) msgstr("Partnerbeállítások") msgid(NAME) msgstr("Név") msgid(STATUSMESSAGE) msgstr("Állapot üzenet") msgid(PREVIEW) msgstr("Előnézet") msgid(AUDIOINPUTDEVICE) msgstr("Bemeneti hangeszköz") msgid(AUDIOFILTERING) msgstr("Hangszűrés") msgid(AUDIOOUTPUTDEVICE) msgstr("Kimeneti hangeszköz") msgid(VIDEOINPUTDEVICE) msgstr("Bemeneti videoeszköz") msgid(VIDEOFRAMERATE) msgstr("Video képkocka (FPS)") msgid(PUSH_TO_TALK) msgstr("Nyomd És Beszélj") msgid(STATUS) msgstr("Állapot") msgid(STATUS_ONLINE) msgstr("Elérhető") msgid(STATUS_AWAY) msgstr("Távol") msgid(STATUS_BUSY) msgstr("Elfoglalt") msgid(STATUS_OFFLINE) msgstr("Nem elérhető") /* * Leave %.*s. They are variables * The first one is your friend's name * The second one is the state your friend is now in */ msgid(STATUS_MESSAGE) msgstr("uTox %.*s most már %s.") msgid(SETTINGS_UI_MINI_ROSTER) msgstr("Mini partnerlista használata") msgid(SETTINGS_UI_AUTO_HIDE_SIDEBAR) msgstr("Oldalsáv automatikus elrejtése") msgid(NOT_CONNECTED) msgstr("Nincs csatlakoztatva") msgid(NOT_CONNECTED_SETTINGS) msgstr("Hálózati beállítások beillesztése") msgid(OTHERSETTINGS) msgstr("Egyéb beállítások") msgid(UI) msgstr("UI") msgid(USER_INTERFACE) msgstr("Felhasználói felület") msgid(UTOX_SETTINGS) msgstr("uTox beállítások") msgid(NETWORK_SETTINGS) msgstr("Hálózati beállítások") msgid(PROFILE_PASSWORD) msgstr("Profiljelszó") msgid(LOCK_UTOX) msgstr("Lekapcsolódik a Toxról, és zárolja a profilt.") msgid(SHOW_UI_PASSWORD) msgstr("Jelszómező mutatása") msgid(SHOW_UI_PASSWORD_TOOLTIP) msgstr("Klikkeléskor a profiljelszó mező mutatása. A módosítás azonnal érvénybe lép!") msgid(HIDE_UI_PASSWORD) msgstr("Jelszómező elrejtése") msgid(HIDE_UI_PASSWORD_TOOLTIP) msgstr("Klikkeléskor a profiljelszó mező elrejtése.") msgid(PASSWORD_TOO_SHORT) msgstr("A jelszó legalább 4 karakter hosszú legyen") msgid(LOCK) msgstr("Zárolás") msgid(AUDIO_VIDEO) msgstr("Audio/Video") msgid(DPI) msgstr("DPI") msgid(SAVELOCATION) msgstr("Mentés helye") msgid(LANGUAGE) msgstr("Nyelv") msgid(NETWORK) msgstr("Hálózat") msgid(IPV6) msgstr("IPv6") msgid(UDP) msgstr("UDP") msgid(PROXY) msgstr("Proxy (SOCKS 5)") msgid(PROXY_FORCE) msgstr("uTox kényszerítése, hogy mindig proxy-t használjon") msgid(WARNING) msgstr("A hálózati-, vagy proxybeállítások változtatása miatt átmenetileg nem lesz elérhető a Tox hálózatán") msgid(SAVE_CHAT_HISTORY) msgstr("Chat előzmények mentése") msgid(AUDIONOTIFICATIONS) msgstr("Hallható jelzés (csengőhang) engedélyezése") msgid(RINGTONE) msgstr("Csengőhang") msgid(IS_TYPING) msgstr("éppen ír...") msgid(CLOSE_TO_TRAY) msgstr("Bezárás a tálcára") msgid(START_IN_TRAY) msgstr("Indítás a tálcán") msgid(SHOW_QR) msgstr("QR-kód mutatása") msgid(HIDE_QR) msgstr("QR-kód elrejtése") msgid(SAVE_QR) msgstr("QR-kód mentése") msgid(COPY_TOX_ID) msgstr("Másolás szövegként") msgid(COPY) msgstr("Másolás") msgid(COPYWITHOUTNAMES) msgstr("Másolás (nevek nélkül)") msgid(COPY_WITH_NAMES) msgstr("Másolás (nevekkel együtt)") msgid(CUT) msgstr("Kivágás") msgid(PASTE) msgstr("Beillesztés") msgid(DELETE) msgstr("Törlés") msgid(SELECTALL) msgstr("Mindet kiválaszt") msgid(REMOVE) msgstr("Eltávolítás") msgid(REMOVE_FRIEND) msgstr("Partner eltávolítása") msgid(LEAVE) msgstr("Kilépés") msgid(CTOPIC) msgstr("Téma változtatás") msgid(ACCEPT) msgstr("Elfogadás") msgid(IGNORE) msgstr("Mellőzés") msgid(SET_ALIAS) msgstr("Álnév beállítása") msgid(ALIAS) msgstr("Álnév") msgid(SENDMESSAGE) msgstr("Üzenet küldése") msgid(SENDSCREENSHOT) msgstr("Képernyőkép küldése") msgid(CLICKTOSAVE) msgstr("Kattintson a mentéshez") msgid(CLICKTOOPEN) msgstr("Kattintson a megnyitáshoz") msgid(CANCELLED) msgstr("Megszakítva") msgid(DPI_060) msgstr("Egyedi DPI 60%") msgid(DPI_070) msgstr("Egyedi DPI 70%") msgid(DPI_080) msgstr("Egyedi DPI 80%") msgid(DPI_090) msgstr("Egyedi DPI 90%") msgid(DPI_100) msgstr("Egyedi DPI 100%") msgid(DPI_110) msgstr("Egyedi DPI 110%") msgid(DPI_120) msgstr("Egyedi DPI 120%") msgid(DPI_130) msgstr("Egyedi DPI 130%") msgid(DPI_140) msgstr("Egyedi DPI 140%") msgid(DPI_150) msgstr("Egyedi DPI 150%") msgid(DPI_160) msgstr("Egyedi DPI 160%") msgid(DPI_170) msgstr("Egyedi DPI 170%") msgid(DPI_180) msgstr("Egyedi DPI 180%") msgid(DPI_190) msgstr("Egyedi DPI 190%") msgid(DPI_200) msgstr("Egyedi DPI 200%") msgid(DPI_210) msgstr("Egyedi DPI 210%") msgid(DPI_220) msgstr("Egyedi DPI 220%") msgid(DPI_230) msgstr("Egyedi DPI 230%") msgid(DPI_240) msgstr("Egyedi DPI 240%") msgid(DPI_250) msgstr("Egyedi DPI 250%") msgid(DPI_260) msgstr("Egyedi DPI 260%") msgid(DPI_270) msgstr("Egyedi DPI 270%") msgid(DPI_280) msgstr("Egyedi DPI 280%") msgid(DPI_290) msgstr("Egyedi DPI 290%") msgid(DPI_300) msgstr("Egyedi DPI 300%") msgid(DPI_TINY) msgstr("Kicsi (50%)") msgid(DPI_NORMAL) msgstr("Normál (100%)") msgid(DPI_BIG) msgstr("Nagy (150%)") msgid(DPI_LARGE) msgstr("Nagyobb (200%)") msgid(DPI_HUGE) msgstr("Legnagyobb (250%)") msgid(PROXY_DISABLED) msgstr("Letiltva") msgid(PROXY_FALLBACK) msgstr("Fallback") msgid(PROXY_ALWAYS_USE) msgstr("Mindig használja") msgid(NO) msgstr("Nem") msgid(YES) msgstr("Igen") msgid(OFF) msgstr("Ki") msgid(ON) msgstr("Be") msgid(SHOW) msgstr("Mutat") msgid(HIDE) msgstr("Elrejt") msgid(VIDEO_IN_NONE) msgstr("Nincs") msgid(VIDEO_IN_DESKTOP) msgstr("Asztal") msgid(AUDIO_IN_DEFAULT_LOOPBACK) msgstr("Alapértelmezett Loopback") msgid(AUDIO_IN_ANDROID) msgstr("OpenSL bevitel") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("Fogadja el a partnerkérelmet!") msgid(CONTACT_SEARCH_ADD_HINT) msgstr("Partner keresése/hozzáadása") msgid(PROXY_EDIT_HINT_IP) msgstr("IP-cím") msgid(PROXY_EDIT_HINT_PORT) msgstr("Port") msgid(WINDOW_TITLE_VIDEO_PREVIEW) msgstr("Videó előnézet") msgid(MUTE) msgstr("Némítás") msgid(UNMUTE) msgstr("Némítás visszavonása") msgid(SELECT_AVATAR_TITLE) msgstr("Avatarkép választás") msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS) msgstr("Az avatarkép túl nagy! Maximális méret: ") msgid(CANT_FIND_FILE_OR_EMPTY) msgstr("A kiválasztott kép nem található, vagy üres.") msgid(CLEAR_HISTORY) msgstr("Előzmények törlése") msgid(AUTO_STARTUP) msgstr("uTox indítása rendszerinduláskor") msgid(THEME) msgstr("Téma") msgid(THEME_DEFAULT) msgstr("Alapértelmezett") msgid(THEME_LIGHT) msgstr("Világos téma") msgid(THEME_DARK) msgstr("Sötét téma") msgid(THEME_HIGHCONTRAST) msgstr("Feltűnő téma") msgid(THEME_CUSTOM) msgstr("Egyedi (lásd a dokumentációt)") msgid(THEME_ZENBURN) msgstr("Zenburn") msgid(THEME_SOLARIZED_LIGHT) msgstr("Solarized-light") msgid(THEME_SOLARIZED_DARK) msgstr("Solarized-dark") msgid(SEND_TYPING_NOTIFICATIONS) msgstr("Írási értesítés küldése") msgid(STATUS_NOTIFICATIONS) msgstr("Állapot értesítések") msgid(RANDOMIZE_NOSPAM) msgstr("Véletlenszerű Nospam") msgid(NOSPAM) msgstr("Nospam") msgid(REVERT_NOSPAM) msgstr("Nospam visszaállítása") msgid(NOSPAM_WARNING) msgstr("A nospam megváltoztatása a régi Tox ID működésképtelenségéhez vezet. Az uTox nem képes frissíteni az ID-t a névszervereken.") msgid(BLOCK_FRIEND_REQUESTS) msgstr("Partnerkérelmek blokkolása") msgid(SHOW_NOSPAM) msgstr("Nospam beállítások mutatása") msgid(HIDE_NOSPAM) msgstr("Nospam beállítások elrejtése") msgid(DELETE_FRIEND) msgstr("Partner törlése") msgid(DELETE_MESSAGE) msgstr("Biztosan törölni szeretné ") msgid(KEEP) msgstr("Megtartás") uTox-0.17.1/langs/i18n_decls.h000066400000000000000000000153461354126257400157670ustar00rootroot00000000000000#ifndef I18N_DECLS_H #define I18N_DECLS_H typedef struct sized_string STRING; #include typedef enum { LANG_EN, LANG_CS, LANG_DK, LANG_DE, LANG_ET, LANG_ES, // 5 LANG_EO, LANG_FR, LANG_HI, LANG_HR, LANG_IT, // 10 LANG_LV, LANG_HU, LANG_NL, LANG_NO, LANG_PL, // 15 LANG_PT, LANG_BR, LANG_RO, LANG_SV, LANG_TR, // 20 LANG_BG, LANG_RU, LANG_UK, LANG_JA, LANG_CN, // 25 LANG_TW, NUM_LANGS // add langs before this line } UTOX_LANG; typedef enum { // This ensures that all statically initialized to zero UTOX_I18N_STR vars // will render as canary "BUG. PLEASE REPORT." strings. UI_STRING_ID_INVALID = 0, STR_LANG_NATIVE_NAME, STR_LANG_ENGLISH_NAME, STR_SPLASH_TITLE, STR_SPLASH_TEXT, STR_CHANGE_LOG_TITLE, STR_CHANGE_LOG_TEXT, STR_REQ_SENT, STR_REQ_INVALID_ID, STR_REQ_EMPTY_ID, STR_REQ_LONG_MSG, STR_REQ_NO_MSG, STR_REQ_SELF_ID, STR_REQ_ALREADY_FRIENDS, STR_REQ_UNKNOWN, STR_REQ_BAD_CHECKSUM, STR_REQ_BAD_NOSPAM, STR_REQ_NO_MEMORY, STR_REQ_ADDED_NO_FREQ_SENT, STR_SEND_FILE, STR_SAVE_FILE, STR_WHERE_TO_SAVE_FILE_PROMPT, STR_WHERE_TO_SAVE_FILE, STR_SEND_FILE_PROMPT, STR_SCREEN_CAPTURE_PROMPT, /* Transfer strings */ STR_TRANSFER_NEW, STR_TRANSFER_STARTED, STR_TRANSFER___, STR_TRANSFER_PAUSED, STR_TRANSFER_BROKEN, STR_TRANSFER_CANCELLED, STR_TRANSFER_COMPLETE, /* Cursor/Mouse strings */ STR_CURSOR_CLICK_LEFT, STR_CURSOR_CLICK_RIGHT, /* Friend strings */ STR_FRIEND_ALIAS, STR_FRIEND_PUBLIC_KEY, STR_FRIEND_AUTOACCEPT, STR_FRIEND_EXPORT_CHATLOG, STR_DELETE_FRIEND, /* Group chat strings */ STR_GROUP_CREATE_TEXT, STR_GROUP_CREATE_VOICE, STR_GROUP_CREATE_WITH_AUDIO, STR_GROUPCHAT_SETTINGS, STR_GROUP_NOTIFICATIONS, STR_GROUP_NOTIFICATIONS_ON, STR_GROUP_NOTIFICATIONS_MENTION, STR_GROUP_NOTIFICATIONS_OFF, STR_GROUP_TOPIC, /* TODO REPLACE or REMOVE */ STR_GROUPCHAT_JOIN_AUDIO, /* A/V Call Strings */ STR_CALL_START_AUDIO, STR_CALL_START_VIDEO, STR_CALL_DECLINE, STR_CALL_CANCELLED, STR_CALL_INVITED, STR_CALL_RINGING, STR_CALL_STARTED, STR_CALL_ENDED, STR_CALL_FRIEND_HAD_ENDED_CALL, STR_CALL_VIDEO_SHOW_INLINE, /* Settings strings */ STR_PROFILE_BUTTON, STR_DEVICES_BUTTON, STR_USER_INTERFACE_BUTTON, STR_AUDIO_VIDEO_BUTTON, STR_ADVANCED_BUTTON, STR_NOTIFICATIONS_BUTTON, STR_AUTO_UPDATE, STR_PROFILE_SETTINGS, STR_PROFILE_PW_WARNING, STR_PROFILE_PW_NO_RECOVER, STR_DEVICES_ADD_NEW, STR_DEVICES_NUMBER, /* Old Strings, please create or use more discriptive */ /* TODO REMOVE OLD ONES! */ STR_ADDFRIENDS, STR_TOXID, STR_SHOW_QR, STR_HIDE_QR, STR_SAVE_QR, STR_MESSAGE, STR_FILTER_ALL, STR_FILTER_ONLINE, STR_FILTER_CONTACT_TOGGLE, STR_ADD, STR_CREATEGROUPCHAT, STR_FRIENDREQUEST, STR_USERSETTINGS, STR_FRIEND_SETTINGS, STR_NAME, STR_STATUSMESSAGE, STR_PREVIEW, STR_AUDIOINPUTDEVICE, STR_AUDIOFILTERING, STR_AUDIOOUTPUTDEVICE, STR_VIDEOINPUTDEVICE, STR_VIDEOFRAMERATE, STR_PUSH_TO_TALK, // Status info STR_STATUS, STR_STATUS_ONLINE, STR_STATUS_AWAY, STR_STATUS_BUSY, STR_STATUS_OFFLINE, STR_STATUS_MESSAGE, // Settings Strings STR_SETTINGS_UI_MINI_ROSTER, STR_SETTINGS_UI_AUTO_HIDE_SIDEBAR, // Status strings STR_NOT_CONNECTED, STR_NOT_CONNECTED_SETTINGS, // Setting strings STR_OTHERSETTINGS, STR_UI, STR_USER_INTERFACE, STR_UTOX_SETTINGS, STR_NETWORK_SETTINGS, STR_AUDIO_VIDEO, STR_PROFILE_PASSWORD, STR_LOCK_UTOX, STR_LOCK, STR_SHOW_UI_PASSWORD, STR_SHOW_UI_PASSWORD_TOOLTIP, STR_HIDE_UI_PASSWORD, STR_HIDE_UI_PASSWORD_TOOLTIP, STR_PASSWORD_TOO_SHORT, STR_DPI, STR_SAVELOCATION, STR_LANGUAGE, STR_NETWORK, STR_IPV6, STR_UDP, STR_PROXY, STR_PROXY_FORCE, STR_WARNING, STR_SAVE_CHAT_HISTORY, STR_AUDIONOTIFICATIONS, STR_RINGTONE, STR_IS_TYPING, STR_CLOSE_TO_TRAY, STR_START_IN_TRAY, STR_AUTO_STARTUP, STR_RANDOMIZE_NOSPAM, STR_REVERT_NOSPAM, STR_NOSPAM, STR_NOSPAM_WARNING, STR_SHOW_NOSPAM, STR_HIDE_NOSPAM, STR_BLOCK_FRIEND_REQUESTS, // Interact with texts / clipboard STR_COPY, STR_COPY_TOX_ID, STR_COPYWITHOUTNAMES, STR_COPY_WITH_NAMES, STR_CUT, STR_PASTE, STR_DELETE, STR_SELECTALL, STR_REMOVE, STR_REMOVE_FRIEND, STR_REMOVE_GROUP, STR_LEAVE, STR_LEAVE_GROUP, STR_ACCEPT, STR_REQ_ACCEPT = STR_ACCEPT, STR_CTOPIC, STR_CHANGE_GROUP_TOPIC = STR_CTOPIC, STR_IGNORE, STR_REQ_DECLINE = STR_IGNORE, STR_SET_ALIAS, STR_ALIAS, STR_SENDMESSAGE, STR_SENDSCREENSHOT, STR_CLICKTOSAVE, STR_CLICKTOOPEN, STR_CANCELLED, STR_DPI_050, STR_DPI_060, STR_DPI_070, STR_DPI_080, STR_DPI_090, STR_DPI_100, STR_DPI_110, STR_DPI_120, STR_DPI_130, STR_DPI_140, STR_DPI_150, STR_DPI_160, STR_DPI_170, STR_DPI_180, STR_DPI_190, STR_DPI_200, STR_DPI_210, STR_DPI_220, STR_DPI_230, STR_DPI_240, STR_DPI_250, STR_DPI_260, STR_DPI_270, STR_DPI_280, STR_DPI_290, STR_DPI_300, STR_DPI_TINY, STR_DPI_NORMAL, STR_DPI_BIG, STR_DPI_LARGE, STR_DPI_HUGE, STR_CONTACT_SEARCH_ADD_HINT, STR_PROXY_DISABLED, STR_PROXY_FALLBACK, STR_PROXY_ALWAYS_USE, STR_PROXY_EDIT_HINT_IP, STR_PROXY_EDIT_HINT_PORT, STR_NO, STR_YES, STR_OFF, STR_ON, STR_SHOW, STR_HIDE, STR_EXIT, STR_VIDEO_IN_NONE, STR_AUDIO_IN_NONE = STR_VIDEO_IN_NONE, STR_VIDEO_IN_DESKTOP, STR_AUDIO_IN_DEFAULT_LOOPBACK, STR_AUDIO_IN_ANDROID, STR_DEFAULT_FRIEND_REQUEST_MESSAGE, STR_WINDOW_TITLE_VIDEO_PREVIEW, STR_MUTE, STR_UNMUTE, STR_SELECT_AVATAR_TITLE, STR_AVATAR_TOO_LARGE_MAX_SIZE_IS, STR_CANT_FIND_FILE_OR_EMPTY, STR_CLEAR_HISTORY, STR_THEME, STR_THEME_DEFAULT, STR_THEME_LIGHT, STR_THEME_DARK, STR_THEME_HIGHCONTRAST, STR_THEME_CUSTOM, STR_THEME_ZENBURN, STR_THEME_SOLARIZED_LIGHT, STR_THEME_SOLARIZED_DARK, STR_SEND_TYPING_NOTIFICATIONS, STR_STATUS_NOTIFICATIONS, STR_DELETE_MESSAGE, STR_KEEP, NUM_STRS // add strings before this line } UTOX_I18N_STR; STRING *ui_gettext(UTOX_LANG lang, UTOX_I18N_STR string_id); UTOX_LANG ui_guess_lang_by_posix_locale(const char *locale, UTOX_LANG deflt); UTOX_LANG ui_guess_lang_by_windows_lang_id(uint16_t lang_id, UTOX_LANG deflt); #endif uTox-0.17.1/langs/it.h000066400000000000000000000124451354126257400144470ustar00rootroot00000000000000msgid(LANG_NATIVE_NAME) msgstr("Italiano") msgid(LANG_ENGLISH_NAME) msgstr("ITALIAN") msgid(REQ_SENT) msgstr("Richiesta d'amicizia inviata. Il contatto apparirà online quando accetterà la richiesta.") msgid(REQ_INVALID_ID) msgstr("Errore: Tox ID non valido") msgid(REQ_EMPTY_ID) msgstr("Errore: Nessun Tox ID specificato") msgid(REQ_LONG_MSG) msgstr("Errore: Il messaggio è troppo lungo") msgid(REQ_NO_MSG) msgstr("Errore: Il messaggio è vuoto") msgid(REQ_SELF_ID) msgstr("Errore: Non puoi inserire il tuo Tox ID") msgid(REQ_ALREADY_FRIENDS) msgstr("Errore: Questo Tox ID è già nella tua lista dei contatti") msgid(REQ_UNKNOWN) msgstr("Errore: Sconosciuto") msgid(REQ_BAD_CHECKSUM) msgstr("Errore: Tox ID non valido (checksum errato)") msgid(REQ_BAD_NOSPAM) msgstr("Errore: Tox ID non valido (valore \"nospam\" errato)") msgid(REQ_NO_MEMORY) msgstr("Errore: Memoria insufficiente") msgid(SEND_FILE) msgstr("Invia file") msgid(SAVE_FILE) msgstr("Salva file") msgid(WHERE_TO_SAVE_FILE_PROMPT) msgstr("Dove vuoi salvare \"%.*s\"?") msgid(SEND_FILE_PROMPT) msgstr("Seleziona uno o più files da inviare.") msgid(SCREEN_CAPTURE_PROMPT) msgstr("Seleziona l'area dello schermo che vuoi inviare.") msgid(TRANSFER_NEW) msgstr("Nuovo trasferimento file") msgid(TRANSFER_STARTED) msgstr("Trasferimento file iniziato") msgid(TRANSFER___) msgstr("…") msgid(TRANSFER_PAUSED) msgstr("Trasferimento file in pausa") msgid(TRANSFER_BROKEN) msgstr("Trasferimento file interrotto") msgid(TRANSFER_CANCELLED) msgstr("Trasferimento file annullato") msgid(TRANSFER_COMPLETE) msgstr("Trasferimento file completato") msgid(CALL_CANCELLED) msgstr("Chiamata terminata") msgid(CALL_INVITED) msgstr("Ti sta chiamando") msgid(CALL_RINGING) msgstr("Sta squillando") msgid(CALL_STARTED) msgstr("Chiamata iniziata") msgid(ADDFRIENDS) msgstr("Aggiungi contatto") msgid(MESSAGE) msgstr("Messaggio") msgid(ADD) msgstr("Aggiungi") msgid(CREATEGROUPCHAT) msgstr("Crea chat di gruppo") msgid(FRIENDREQUEST) msgstr("Richieste d'amicizia") msgid(USERSETTINGS) msgstr("Impostazioni") msgid(NAME) msgstr("Nome") msgid(STATUSMESSAGE) msgstr("Messaggio di stato") msgid(PREVIEW) msgstr("Anteprima") msgid(AUDIOINPUTDEVICE) msgstr("Audio (input)") msgid(AUDIOFILTERING) msgstr("Cancellazione rumore") msgid(AUDIOOUTPUTDEVICE) msgstr("Audio (output)") msgid(VIDEOINPUTDEVICE) msgstr("Video (input)") msgid(OTHERSETTINGS) msgstr("Altro") msgid(UI) msgstr("UI") msgid(USER_INTERFACE) msgstr("Interfaccia Utente") msgid(UTOX_SETTINGS) msgstr("Impostazioni uTox") msgid(NETWORK_SETTINGS) msgstr("Impostazioni Rete") msgid(AUDIO_VIDEO) msgstr("Audio/Video") msgid(DPI) msgstr("Dimensione Caratteri") msgid(SAVELOCATION) msgstr("Salva Locazione") msgid(LANGUAGE) msgstr("Lingua") msgid(NETWORK) msgstr("Rete") msgid(WARNING) msgstr("Cambiando le impostazioni della Rete o del Proxy, verrai temporaneamente disconnesso dalla rete Tox") msgid(SAVE_CHAT_HISTORY) msgstr("Salvare cronologia chat?") msgid(AUDIONOTIFICATIONS) msgstr("Abilita notifiche audio per le chiamate (Suoneria)") msgid(IS_TYPING) msgstr("sta scrivendo...") msgid(CLOSE_TO_TRAY) msgstr("Chiudi nella traybar") msgid(START_IN_TRAY) msgstr("Avvia nella traybar") msgid(COPY) msgstr("Copia") msgid(COPYWITHOUTNAMES) msgstr("Copia (escludi nome contatto)") msgid(COPY_WITH_NAMES) msgstr("Copia (includi nome contatto)") msgid(CUT) msgstr("Taglia") msgid(PASTE) msgstr("Incolla") msgid(DELETE) msgstr("Cancella") msgid(SELECTALL) msgstr("Seleziona tutto") msgid(REMOVE) msgstr("Rimuovi") msgid(REMOVE_FRIEND) msgstr("Rimuovi contatto") msgid(REMOVE_GROUP) msgstr("Rimuovi gruppo") msgid(LEAVE) msgstr("Abbandona") msgid(LEAVE_GROUP) msgstr("Abbandona gruppo") msgid(CTOPIC) msgstr("Modifica titolo") msgid(ACCEPT) msgstr("Accetta") msgid(IGNORE) msgstr("Ignora") msgid(SENDSCREENSHOT) msgstr("Invia uno screenshot") msgid(CLICKTOSAVE) msgstr("Clicca per salvare") msgid(CLICKTOOPEN) msgstr("Clicca per aprire") msgid(CANCELLED) msgstr("Annullato") msgid(DPI_TINY) msgstr("Piccolo (50%)") msgid(DPI_NORMAL) msgstr("Normale (100%)") msgid(DPI_BIG) msgstr("Grande (150%)") msgid(DPI_LARGE) msgstr("Più grande (200%)") msgid(DPI_HUGE) msgstr("Enorme (250%)") msgid(FILTER_ALL) msgstr("Tutti") msgid(PROXY_DISABLED) msgstr("Disabilitato") msgid(PROXY_ALWAYS_USE) msgstr("Abilitato") msgid(YES) msgstr("Sì") msgid(VIDEO_IN_NONE) msgstr("Disabilitato") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("Per favore accetta questa richiesta d'amicizia.") msgid(PROXY_EDIT_HINT_PORT) msgstr("Porta") msgid(WINDOW_TITLE_VIDEO_PREVIEW) msgstr("uTox video test") msgid(MUTE) msgstr("Disattiva") msgid(UNMUTE) msgstr("Attiva") msgid(SELECT_AVATAR_TITLE) msgstr("Seleziona avatar") msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS) msgstr("Avatar troppo grande. Dimensione massima: ") msgid(CANT_FIND_FILE_OR_EMPTY) msgstr("Impossibile trovare il file o il file è vuoto.") msgid(CLEAR_HISTORY) msgstr("Cancella cronologia chat") msgid(AUTO_STARTUP) msgstr("Esegui all'avvio del sistema") msgid(THEME) msgstr("Tema") msgid(THEME_DEFAULT) msgstr("Default") msgid(THEME_LIGHT) msgstr("Chiaro") msgid(THEME_DARK) msgstr("Scuro") msgid(THEME_HIGHCONTRAST) msgstr("Alto contrasto") msgid(THEME_CUSTOM) msgstr("Personalizzato (vedi documentazione)") msgid(SEND_TYPING_NOTIFICATIONS) msgstr("Invia notifica quando sto scrivendo") uTox-0.17.1/langs/ja.h000066400000000000000000000120221354126257400144140ustar00rootroot00000000000000msgid(LANG_NATIVE_NAME) msgstr("日本語") msgid(LANG_ENGLISH_NAME) msgstr("JAPANESE") msgid(REQ_SENT) msgstr("フレンド要求が送信されました。要求が承諾されるとオンライン表示になります。") msgid(REQ_INVALID_ID) msgstr("エラー: 無効なTox IDです") msgid(REQ_EMPTY_ID) msgstr("エラー: Tox IDが指定されていません") msgid(REQ_LONG_MSG) msgstr("エラー: メッセージが長すぎます") msgid(REQ_NO_MSG) msgstr("エラー: 空のメッセージ") msgid(REQ_SELF_ID) msgstr("エラー: Tox IDは自身のIDです") msgid(REQ_ALREADY_FRIENDS) msgstr("エラー: Tox IDは既にフレンドリストの中です") msgid(REQ_UNKNOWN) msgstr("エラー: 不明") msgid(REQ_BAD_CHECKSUM) msgstr("エラー: Tox IDは不正です (不正なチェックサム)") msgid(REQ_BAD_NOSPAM) msgstr("エラー: Tox IDは不正です (不正なnospam値)") msgid(REQ_NO_MEMORY) msgstr("エラー: メモリ不足です") msgid(TRANSFER_NEW) msgstr("新しいファイルの転送") msgid(TRANSFER_STARTED) msgstr("ファイルの転送が開始しました") //TODO: Same as in English? Localize or remove. //msgid(TRANSFER___) //msgstr("...") msgid(TRANSFER_PAUSED) msgstr("ファイルの転送が停止しました") msgid(TRANSFER_BROKEN) msgstr("ファイルの転送が失敗しました") msgid(TRANSFER_CANCELLED) msgstr("ファイルの転送をキャンセルしました") msgid(TRANSFER_COMPLETE) msgstr("ファイルの転送が完了しました") msgid(CALL_CANCELLED) msgstr("通話をキャンセルしました") msgid(CALL_INVITED) msgstr("通話を招待しました") msgid(CALL_RINGING) msgstr("通話が鳴っています") msgid(CALL_STARTED) msgstr("通話を開始しました") msgid(ADDFRIENDS) msgstr("フレンド追加") //TODO: Same as in English? Localize or remove. //msgid(TOXID) //msgstr("Tox ID") msgid(MESSAGE) msgstr("メッセージ") msgid(ADD) msgstr("追加") msgid(FRIENDREQUEST) msgstr("フレンド要求") msgid(USERSETTINGS) msgstr("ユーザ設定") msgid(NAME) msgstr("名前") msgid(STATUSMESSAGE) msgstr("状態メッセージ") msgid(PREVIEW) msgstr("プレビュー") msgid(AUDIOINPUTDEVICE) msgstr("音声入力デバイス") msgid(AUDIOOUTPUTDEVICE) msgstr("音声出力デバイス") msgid(VIDEOINPUTDEVICE) msgstr("ビデオ入力デバイス") msgid(OTHERSETTINGS) msgstr("他の設定") msgid(DPI) msgstr("解像度") msgid(SAVELOCATION) msgstr("場所の保存") msgid(LANGUAGE) msgstr("言語") msgid(NETWORK) msgstr("ネットワーク") //TODO: Same as in English? Localize or remove. //msgid(IPV6) //msgstr("IPv6:") //TODO: Same as in English? Localize or remove. //msgid(UDP) //msgstr("UDP:") msgid(PROXY) msgstr("プロキシ (SOCKS 5)") msgid(WARNING) msgstr("ネットワークやプロキシの設定を変えるとToxネットワークの接続が切断されます") msgid(SAVE_CHAT_HISTORY) msgstr("ロギング") //TODO: Same as in English? Localize or remove. //msgid(IS_TYPING) //msgstr("is typing...") msgid(COPY) msgstr("コピー") msgid(COPYWITHOUTNAMES) msgstr("コピー(名前以外)") msgid(CUT) msgstr("カット") msgid(PASTE) msgstr("ペースト") msgid(DELETE) msgstr("削除") msgid(SELECTALL) msgstr("すべてを選択") msgid(REMOVE) msgstr("削除") msgid(LEAVE) msgstr("退出") msgid(ACCEPT) msgstr("承認") msgid(IGNORE) msgstr("無視する") msgid(CLICKTOSAVE) msgstr("クリックで保存") msgid(CLICKTOOPEN) msgstr("クリックで開く") msgid(CANCELLED) msgstr("キャンセルしました") //TODO: Localize or remove. //msgid(DPI_TINY) //msgstr("Tiny (50%)") //TODO: Localize or remove. //msgid(DPI_NORMAL) //msgstr("Normal (100%)") //TODO: Localize or remove. //msgid(DPI_BIG) //msgstr("Big (150%)") //TODO: Localize or remove. //msgid(DPI_LARGE) //msgstr("Large (200%)") //TODO: Localize or remove. //msgid(DPI_HUGE) //msgstr("Huge (250%)") //TODO: Localize or remove. //msgid(FILTER_ALL) //msgstr("All") //TODO: Localize or remove. //msgid(FILTER_ONLINE) //msgstr("Online") //TODO: Localize or remove. //msgid(PROXY_DISABLED) //msgstr("Disabled") //TODO: Localize or remove. //msgid(PROXY_FALLBACK) //msgstr("Fallback") //TODO: Localize or remove. //msgid(PROXY_ALWAYS_USE) //msgstr("Always use") //TODO: Localize or remove. //msgid(NO) //msgstr("No") //TODO: Localize or remove. //msgid(YES) //msgstr("Yes") //TODO: Localize or remove. //msgid(VIDEO_IN_NONE) //msgstr("None") //TODO: Localize or remove. //msgid(VIDEO_IN_DESKTOP) //msgstr("Desktop") //TODO: Localize or remove. //msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) //msgstr("Please accept this friend request.") //TODO: Localize or remove. //msgid(PROXY_EDIT_HINT_IP) //msgstr("IP") //TODO: Localize or remove. //msgid(PROXY_EDIT_HINT_PORT) //msgstr("Port") //TODO: Localize or remove. //msgid(AUDIO_IN_DEFAULT_LOOPBACK) //msgstr("Default Loopback") //TODO: Localize or remove. //msgid(WINDOW_TITLE_VIDEO_PREVIEW) //msgstr("Video Preview") //TODO: Localize or remove. //msgid(AUDIONOTIFICATIONS) //msgstr("Enable Audible Notification (Ringtone)") uTox-0.17.1/langs/lv.h000066400000000000000000000073271354126257400144570ustar00rootroot00000000000000msgid(LANG_NATIVE_NAME) msgstr("Latviešu") msgid(LANG_ENGLISH_NAME) msgstr("LATVIAN") msgid(REQ_SENT) msgstr("Draugu pieprasījums ir nosūtīts. Jūsu draugs parādīsies tiešsaistē kad pieprasījums būs pieņemts.") msgid(REQ_INVALID_ID) msgstr("Kļūda: Nederīgs Tox ID") msgid(REQ_EMPTY_ID) msgstr("Kļūda: No Tox ID specified") msgid(REQ_LONG_MSG) msgstr("Kļūda: Ziņa ir pārāk gara") msgid(REQ_NO_MSG) msgstr("Kļūda: Tukša ziņa") msgid(REQ_SELF_ID) msgstr("Kļūda: Tox ID is self ID") msgid(REQ_ALREADY_FRIENDS) msgstr("Kļūda: Tox ID jau ir draugu sarakstā") msgid(REQ_UNKNOWN) msgstr("Kļūda: Unknown") msgid(REQ_BAD_CHECKSUM) msgstr("Kļūda: Nederīgs Tox ID (bad checksum)") msgid(REQ_BAD_NOSPAM) msgstr("Kļūda: Nederīgs Tox ID (bad nospam value)") msgid(REQ_NO_MEMORY) msgstr("Kļūda: No memory") msgid(TRANSFER_NEW) msgstr("Jauna faila pārsūtīšana") msgid(TRANSFER_STARTED) msgstr("Faila pārsūtīšana sākta") msgid(TRANSFER_PAUSED) msgstr("Faila pārsūtīšana apturēta") msgid(TRANSFER_BROKEN) msgstr("Kļūda faila pārsūtīšanā") msgid(TRANSFER_CANCELLED) msgstr("Faila pārsūtīšana atcelta") msgid(TRANSFER_COMPLETE) msgstr("Faila pārsūtīšana pabeigta") msgid(CALL_CANCELLED) msgstr("Zvans atcelts") msgid(CALL_INVITED) msgstr("Saruna aicinājums") msgid(CALL_RINGING) msgstr("Jums zvana") msgid(CALL_STARTED) msgstr("Zvans uzsākts") msgid(ADDFRIENDS) msgstr("Pievienot draugus") msgid(MESSAGE) msgstr("Ziņa") msgid(ADD) msgstr("Pievienot") msgid(FRIENDREQUEST) msgstr("Draugu pieprasījums") msgid(USERSETTINGS) msgstr("Lietotāja iestatījumi") msgid(NAME) msgstr("Vārds") msgid(STATUSMESSAGE) msgstr("Statusa ziņojums") msgid(PREVIEW) msgstr("Priekšskatījums") msgid(AUDIOINPUTDEVICE) msgstr("Audio ievades ierīce") msgid(AUDIOOUTPUTDEVICE) msgstr("Audio izvades ierīce") msgid(VIDEOINPUTDEVICE) msgstr("Video ievades ierīce") msgid(OTHERSETTINGS) msgstr("Citi iestatījumi") msgid(SAVELOCATION) msgstr("Saglabāt novietojumu") msgid(LANGUAGE) msgstr("Valoda") msgid(NETWORK) msgstr("Tīkls") msgid(PROXY) msgstr("Starpniekserveris (SOCKS 5)") msgid(WARNING) msgstr("Mainot starpniekservera iestatījumus, jūs tiksit īslaicīgi atvienots no Tox tīkla") msgid(SAVE_CHAT_HISTORY) msgstr("Žurnāli") msgid(IS_TYPING) msgstr("raksta...") msgid(COPY) msgstr("Kopēt") msgid(COPYWITHOUTNAMES) msgstr("Kopēt (bez vārdiem)") msgid(CUT) msgstr("Izgriezt") msgid(PASTE) msgstr("Ielīmēt") msgid(DELETE) msgstr("Dzēst") msgid(SELECTALL) msgstr("Atlasīt visu") msgid(REMOVE) msgstr("Noņemt") msgid(LEAVE) msgstr("Pamest") msgid(ACCEPT) msgstr("Pieņemt") msgid(IGNORE) msgstr("Ignorēt") msgid(CLICKTOSAVE) msgstr("Spiest, lai saglabātu") msgid(CLICKTOOPEN) msgstr("Spiest, lai atvērtu") msgid(CANCELLED) msgstr("Atcelts") msgid(DPI_TINY) msgstr("Mazs (50%)") msgid(DPI_NORMAL) msgstr("Normāls (100%)") msgid(DPI_BIG) msgstr("Liels (150%)") msgid(DPI_LARGE) msgstr("Ļoti liels (200%)") msgid(DPI_HUGE) msgstr("Milzīgs (250%)") msgid(FILTER_ALL) msgstr("Viss") msgid(FILTER_ONLINE) msgstr("Tiešsaistē") msgid(PROXY_DISABLED) msgstr("Atslēgts") msgid(PROXY_FALLBACK) msgstr("Alternatīvs starpniekserveris (fallback)") msgid(PROXY_ALWAYS_USE) msgstr("Vienmēr izmantot") msgid(NO) msgstr("Nē") msgid(YES) msgstr("Jā") msgid(VIDEO_IN_NONE) msgstr("Nav") msgid(VIDEO_IN_DESKTOP) msgstr("Galddators") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("Lūdzu, pieņemiet šo drauga pieprasījumu.") msgid(PROXY_EDIT_HINT_PORT) msgstr("Ports") //TODO: Localize or remove. //msgid(AUDIO_IN_DEFAULT_LOOPBACK) //msgstr("Default Loopback") msgid(WINDOW_TITLE_VIDEO_PREVIEW) msgstr("Priekšskatījums") msgid(AUDIONOTIFICATIONS) msgstr("Ieslēgt zvana signālu") uTox-0.17.1/langs/nl.h000066400000000000000000000115431354126257400144420ustar00rootroot00000000000000msgid(LANG_NATIVE_NAME) msgstr("Nederlands") msgid(LANG_ENGLISH_NAME) msgstr("DUTCH") msgid(REQ_SENT) msgstr("Vriendschapsverzoek verstuurd. Uw vriend zal online verschijnen zodra hij/zij deze heeft geaccepteerd.") msgid(REQ_INVALID_ID) msgstr("Fout: Ongeldig Tox ID") msgid(REQ_EMPTY_ID) msgstr("Fout: Geen Tox ID gegeven") msgid(REQ_LONG_MSG) msgstr("Fout: Het bericht is te lang") msgid(REQ_NO_MSG) msgstr("Fout: Het bericht is leeg") msgid(REQ_SELF_ID) msgstr("Fout: Het Tox ID is gelijk aan die van uzelf") msgid(REQ_ALREADY_FRIENDS) msgstr("Fout: Het desbetreffende Tox ID staat al in uw vriendenlijst") msgid(REQ_UNKNOWN) msgstr("Fout: Onbekend") msgid(REQ_BAD_CHECKSUM) msgstr("Fout: Ongeldig Tox ID (foutief controlecijfer)") msgid(REQ_BAD_NOSPAM) msgstr("Fout: Ongeldig Tox ID (foutieve nospam waarde)") msgid(REQ_NO_MEMORY) msgstr("Fout: Niet genoeg geheugen") msgid(TRANSFER_NEW) msgstr("Nieuwe bestandsoverdracht") msgid(TRANSFER_STARTED) msgstr("Bestandsoverdracht gestart") //TODO: Same as in English? Localize or remove. //msgid(TRANSFER___) //msgstr("...") msgid(TRANSFER_PAUSED) msgstr("Bestandsoverdracht gepauzeerd") msgid(TRANSFER_BROKEN) msgstr("Bestandsoverdracht onderbroken") msgid(TRANSFER_CANCELLED) msgstr("Bestandsoverdracht geannuleerd") msgid(TRANSFER_COMPLETE) msgstr("Bestandsoverdracht voltooid") msgid(CALL_CANCELLED) msgstr("Gesprek geannuleerd") msgid(CALL_INVITED) msgstr("Gespreksuitnodiging verstuurd") //TODO: Same as in English? Localize or remove. //msgid(CALL_RINGING) //msgstr("Call ringing") msgid(CALL_STARTED) msgstr("Gesprek gestart") msgid(ADDFRIENDS) msgstr("Vrienden Toevoegen") //TODO: Same as in English? Localize or remove. //msgid(TOXID) //msgstr("Tox ID") msgid(MESSAGE) msgstr("Bericht") msgid(ADD) msgstr("Toevoegen") msgid(FRIENDREQUEST) msgstr("Vriendschapsverzoek") msgid(USERSETTINGS) msgstr("Gebruikersinstellingen") msgid(NAME) msgstr("Naam") msgid(STATUSMESSAGE) msgstr("Statusbericht") msgid(PREVIEW) msgstr("Voorbeeld") msgid(AUDIOINPUTDEVICE) msgstr("Geluid Invoerapparaat") msgid(AUDIOOUTPUTDEVICE) msgstr("Geluid Uitvoerapparaat") msgid(VIDEOINPUTDEVICE) msgstr("Video Invoerapparaat") msgid(OTHERSETTINGS) msgstr("Andere Instellingen") //TODO: Same as in English? Localize or remove. //msgid(DPI) //msgstr("DPI") msgid(SAVELOCATION) msgstr("Opslaglocatie") msgid(LANGUAGE) msgstr("Taal") msgid(NETWORK) msgstr("Netwerk") //TODO: Same as in English? Localize or remove. //msgid(IPV6) //msgstr("IPv6:") //TODO: Same as in English? Localize or remove. //msgid(UDP) //msgstr("UDP:") //TODO: Same as in English? Localize or remove. //msgid(PROXY) //msgstr("Proxy (SOCKS 5)") msgid(WARNING) msgstr("Het veranderen van Netwerk/Proxy instellingen zal de verbinding met het Tox netwerk tijdelijk verbreken") msgid(SAVE_CHAT_HISTORY) msgstr("Logboek registratie") msgid(IS_TYPING) msgstr("is bezig met typen...") msgid(COPY) msgstr("Kopiëren") msgid(COPYWITHOUTNAMES) msgstr("Kopieër (zonder namen)") msgid(CUT) msgstr("Knippen") msgid(PASTE) msgstr("Plakken") msgid(DELETE) msgstr("Wissen") msgid(SELECTALL) msgstr("Alles Selecteren") msgid(REMOVE) msgstr("Verwijderen") msgid(LEAVE) msgstr("Verlaten") msgid(ACCEPT) msgstr("Accepteren") msgid(IGNORE) msgstr("Negeren") msgid(CLICKTOSAVE) msgstr("Klik om op te slaan") msgid(CLICKTOOPEN) msgstr("Klik om te openen") msgid(CANCELLED) msgstr("Geannuleerd") //TODO: Localize or remove. //msgid(DPI_TINY) //msgstr("Tiny (50%)") //TODO: Localize or remove. //msgid(DPI_NORMAL) //msgstr("Normal (100%)") //TODO: Localize or remove. //msgid(DPI_BIG) //msgstr("Big (150%)") //TODO: Localize or remove. //msgid(DPI_LARGE) //msgstr("Large (200%)") //TODO: Localize or remove. //msgid(DPI_HUGE) //msgstr("Huge (250%)") //TODO: Localize or remove. //msgid(FILTER_ALL) //msgstr("All") //TODO: Localize or remove. //msgid(FILTER_ONLINE) //msgstr("Online") //TODO: Localize or remove. //msgid(PROXY_DISABLED) //msgstr("Disabled") //TODO: Localize or remove. //msgid(PROXY_FALLBACK) //msgstr("Fallback") //TODO: Localize or remove. //msgid(PROXY_ALWAYS_USE) //msgstr("Always use") //TODO: Localize or remove. //msgid(NO) //msgstr("No") //TODO: Localize or remove. //msgid(YES) //msgstr("Yes") //TODO: Localize or remove. //msgid(VIDEO_IN_NONE) //msgstr("None") //TODO: Localize or remove. //msgid(VIDEO_IN_DESKTOP) //msgstr("Desktop") //TODO: Localize or remove. //msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) //msgstr("Please accept this friend request.") //TODO: Localize or remove. //msgid(PROXY_EDIT_HINT_IP) //msgstr("IP") //TODO: Localize or remove. //msgid(PROXY_EDIT_HINT_PORT) //msgstr("Port") //TODO: Localize or remove. //msgid(AUDIO_IN_DEFAULT_LOOPBACK) //msgstr("Default Loopback") //TODO: Localize or remove. //msgid(WINDOW_TITLE_VIDEO_PREVIEW) //msgstr("Video Preview") //TODO: Localize or remove. //msgid(AUDIONOTIFICATIONS) //msgstr("Enable Audible Notification (Ringtone)") uTox-0.17.1/langs/no.h000066400000000000000000000116401354126257400144430ustar00rootroot00000000000000msgid(LANG_NATIVE_NAME) msgstr("Norsk") msgid(LANG_ENGLISH_NAME) msgstr("NORWEGIAN") msgid(REQ_SENT) msgstr("Venneforespørsel er sent. Din venn vil bli vist som pålogget når venneforespørselen blir godtatt.") msgid(REQ_INVALID_ID) msgstr("Feil: Ugyldig Tox ID") msgid(REQ_EMPTY_ID) msgstr("Feil: Ingen Tox ID spesifisert") msgid(REQ_LONG_MSG) msgstr("Feil: For lang melding") msgid(REQ_NO_MSG) msgstr("Feil: Ingen melding") msgid(REQ_SELF_ID) msgstr("Feil: Tox ID er din ID") msgid(REQ_ALREADY_FRIENDS) msgstr("Feil: Tox ID er allerede i vennelisten din") msgid(REQ_UNKNOWN) msgstr("Feil: Ukjent") msgid(REQ_BAD_CHECKSUM) msgstr("Feil: Ugyldig Tox ID (dårlig sjekksum)") msgid(REQ_BAD_NOSPAM) msgstr("Feil: Ugyldig Tox ID (dårlig antispam verdi)") msgid(REQ_NO_MEMORY) msgstr("Feil: Ingen minne") msgid(SEND_FILE) msgstr("Send Fil") msgid(SAVE_FILE) msgstr("Lagre Fil") msgid(WHERE_TO_SAVE_FILE_PROMPT) msgstr("Hvor vil du lagre \"%.*s\"?") msgid(SEND_FILE_PROMPT) msgstr("Velg en eller flere filer du vil sende.") msgid(SCREEN_CAPTURE_PROMPT) msgstr("Dra en boks rundt området av skjermen du vil sende.") msgid(TRANSFER_NEW) msgstr("Ny filoverføring") msgid(TRANSFER_STARTED) msgstr("Startet filoverføring") msgid(TRANSFER_PAUSED) msgstr("Filoverføring pauset") msgid(TRANSFER_BROKEN) msgstr("Filoverføring mislyktes") msgid(TRANSFER_CANCELLED) msgstr("Filoverføring avbrutt") msgid(TRANSFER_COMPLETE) msgstr("Filoverføring fullført") msgid(CALL_CANCELLED) msgstr("Samtale avbrutt") msgid(CALL_INVITED) msgstr("Samtale invitert") msgid(CALL_RINGING) msgstr("Samtale ringer") msgid(CALL_STARTED) msgstr("Samtale startet") msgid(ADDFRIENDS) msgstr("Legg til venner") msgid(MESSAGE) msgstr("Melding") msgid(ADD) msgstr("Legg til") msgid(CREATEGROUPCHAT) msgstr("Lag Gruppesamtale") msgid(FRIENDREQUEST) msgstr("Venneforespørsel") msgid(USERSETTINGS) msgstr("Brukerinnstillinger") msgid(NAME) msgstr("Navn") msgid(STATUSMESSAGE) msgstr("Statusmelding") msgid(PREVIEW) msgstr("Forhåndsvisning") msgid(AUDIOINPUTDEVICE) msgstr("Lydinnspillingsenhet") msgid(AUDIOFILTERING) msgstr("Filtrer Audio") msgid(AUDIOOUTPUTDEVICE) msgstr("Lydavspillingsenhet") msgid(VIDEOINPUTDEVICE) msgstr("Videoavspillingsenhet") msgid(OTHERSETTINGS) msgstr("Andre Innstillinger") msgid(SAVELOCATION) msgstr("Lagre Lokasjon") msgid(LANGUAGE) msgstr("Språk") msgid(NETWORK) msgstr("Nettverk") msgid(WARNING) msgstr("Endring av nettverks/Proxy instillinger vil midlertidig frakoble deg fra Tox nettverket") msgid(SAVE_CHAT_HISTORY) msgstr("Lagre logger fra samtaler") msgid(AUDIONOTIFICATIONS) msgstr("Aktiver Lydvarsling (Ringetone)") msgid(IS_TYPING) msgstr("skriver...") msgid(CLOSE_TO_TRAY) msgstr("Lukk Til Statusfeltet") msgid(START_IN_TRAY) msgstr("Start i Statusfeltet") msgid(COPY) msgstr("Kopier") msgid(COPYWITHOUTNAMES) msgstr("Kopier (Uten Navn)") msgid(COPY_WITH_NAMES) msgstr("Kopier (Inkluder Navn)") msgid(CUT) msgstr("Klipp ut") msgid(PASTE) msgstr("Lim inn") msgid(DELETE) msgstr("Slett") msgid(SELECTALL) msgstr("Velg alle") msgid(REMOVE) msgstr("Fjern") msgid(LEAVE) msgstr("Forlat") msgid(CTOPIC) msgstr("Endre tittel") msgid(ACCEPT) msgstr("Godta") msgid(IGNORE) msgstr("Ignorer") msgid(SENDSCREENSHOT) msgstr("Send et skjermbilde") msgid(CLICKTOSAVE) msgstr("Klikk for å lagre") msgid(CLICKTOOPEN) msgstr("Klikk for å åpne") msgid(CANCELLED) msgstr("Avbrutt") msgid(DPI_TINY) msgstr("Liten (50%)") msgid(DPI_NORMAL) msgstr("Normal (100%)") msgid(DPI_BIG) msgstr("Stor (150%)") msgid(DPI_LARGE) msgstr("Større (200%)") msgid(DPI_HUGE) msgstr("Enorm (250%)") msgid(FILTER_ALL) msgstr("Alle") msgid(FILTER_ONLINE) msgstr("Pålogget") msgid(PROXY_DISABLED) msgstr("Deaktivert") msgid(PROXY_FALLBACK) msgstr("Reserve") msgid(PROXY_ALWAYS_USE) msgstr("Alltid bruk") msgid(NO) msgstr("Nei") msgid(YES) msgstr("Ja") msgid(VIDEO_IN_NONE) msgstr("Ingen") msgid(VIDEO_IN_DESKTOP) msgstr("Skrivebord") msgid(AUDIO_IN_DEFAULT_LOOPBACK) msgstr("Standard Loopback") msgid(AUDIO_IN_ANDROID) msgstr("OpenSL Inspilling") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("Aksepter denne venneforespørselen.") msgid(WINDOW_TITLE_VIDEO_PREVIEW) msgstr("Video Forhåndsvisning") msgid(MUTE) msgstr("Slå av") msgid(UNMUTE) msgstr("Slå på") msgid(SELECT_AVATAR_TITLE) msgstr("Velg Avatar") msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS) msgstr("Avataren er for stor. Maksimum størrelse: ") msgid(CANT_FIND_FILE_OR_EMPTY) msgstr("Finner ikke valgt fil eller filen er tom.") msgid(CLEAR_HISTORY) msgstr("Fjern historikk") msgid(AUTO_STARTUP) msgstr("Start ved systemoppstart") msgid(THEME) msgstr("Tema") msgid(THEME_DEFAULT) msgstr("Standard") msgid(THEME_LIGHT) msgstr("Lyst tema") msgid(THEME_DARK) msgstr("Mørkt tema") msgid(THEME_HIGHCONTRAST) msgstr("Høy kontrast") msgid(THEME_CUSTOM) msgstr("Brukerdefinert (se dokumentasjon)") msgid(THEME_ZENBURN) msgstr("Zenburn") msgid(SEND_TYPING_NOTIFICATIONS) msgstr("Send skrive notifikasjon") uTox-0.17.1/langs/pl.h000066400000000000000000000364131354126257400144470ustar00rootroot00000000000000msgid(LANG_NATIVE_NAME) msgstr("Polski") msgid(LANG_ENGLISH_NAME) msgstr("Polish") /****************************************************************************** *** Splash Message & Change Log *** ******************************************************************************/ msgid(SPLASH_TITLE) msgstr("Witaj w nowym uTox!") msgid(SPLASH_TEXT) msgstr("uTox został zaktualizowany do wersji 0.9.8! Nazwa kodowa wersji: Srsly v3") msgid(CHANGE_LOG_TITLE) msgstr("Zmiany w v0.9.8") msgid(CHANGE_LOG_TEXT) msgstr( " Usunięto błąd podczas tworzenia nowego profilu\n" "\nv0.9.7\n" " Usprawniono interfejs użytkownika \n" " Zamieniono wszystkie listy Tak/Nie na przełączniki\n" " Naprawiono zapisywanie hostów proxy i portów podczas restartów.\n" "\nv0.9.5\n" " Wideo w środku okna dla OSX\n" " Usunięto błąd zapisywania historii\n" "\nv0.9.3\n" " Usunięto błąd z wiadomościami który powodował sporadyczne awarie w Windows\n" " Zmniejszono liczbę wiadomości które można ponownie wysyłać na raz\n" "\nv0.9.2\n" " Poprawiono kod źródłowy/Zmienono ścieżki\n" "\nv0.9.1\n" " Usunięto błąd podczas wysyłania wiadomości do nowego znajomego\n" "\nv0.9.0\n" " Kolejka wiadomości\n" " Poprawiono czaty grupowe\n" " Eksperymentalna funkcja wideo w środku okna\n" " Mała lista kontaktów\n" " Usprawniono przetwarzanie wiadomości\n" "\n") /****************************************************************************** *** MISC & UNSORTED *** ******************************************************************************/ msgid(REQ_SENT) msgstr("Wysłano zaproszenie do znajomego. Znajomy stanie się dostępny po jego przyjęciu") msgid(REQ_INVALID_ID) msgstr("Błąd: Nieprawidłowy Tox ID") msgid(REQ_ADDED_NO_FREQ_SENT) msgstr("Uwaga: Dodano znajomego, ale zaproszenie nie zostało wysłane (brakuje nospam)") msgid(REQ_EMPTY_ID) msgstr("Błąd: Nie podano Tox ID") msgid(REQ_LONG_MSG) msgstr("Błąd: Wiadomość jest za długa") msgid(REQ_NO_MSG) msgstr("Błąd: Pusta wiadomość") msgid(REQ_SELF_ID) msgstr("Błąd: Próba dodania własnego Tox ID") msgid(REQ_ALREADY_FRIENDS) msgstr("Błąd: Podany Tox ID jest już na liście znajomych") msgid(REQ_UNKNOWN) msgstr("Błąd: Nieznany") msgid(REQ_BAD_CHECKSUM) msgstr("Błąd: Nieprawidłowy Tox ID (zła suma kontrolna)") msgid(REQ_BAD_NOSPAM) msgstr("Błąd: Nieprawidłowy Tox ID (zła wartość nospam)") msgid(REQ_NO_MEMORY) msgstr("Błąd: Brak pamięci") msgid(SEND_FILE) msgstr("Wyślij plik") msgid(SAVE_FILE) msgstr("Zapisz plik") msgid(WHERE_TO_SAVE_FILE_PROMPT) msgstr("Gdzie chcesz zapisać plik \"%.*s\"?") msgid(WHERE_TO_SAVE_FILE) msgstr("Gdzie chcesz zapisać plik?") msgid(SEND_FILE_PROMPT) msgstr("Wybierz jeden lub więcej plików do wysłania.") msgid(SCREEN_CAPTURE_PROMPT) msgstr("Zaznacz część ekranu do przesłania.") /****************************************************************************** *** File Transfer Strings *** ******************************************************************************/ msgid(TRANSFER_NEW) msgstr("Nowy transfer pliku") msgid(TRANSFER_STARTED) msgstr("Transfer pliku rozpoczęty") msgid(TRANSFER_PAUSED) msgstr("Transfer pliku wstrzymany") msgid(TRANSFER_BROKEN) msgstr("Transfer pliku nieudany") msgid(TRANSFER_CANCELLED) msgstr("Transfer pliku anulowany") msgid(TRANSFER_COMPLETE) msgstr("Transfer pliku zakończony") /****************************************************************************** *** Keyboard and Mouse Cursor Strings *** ******************************************************************************/ msgid(CURSOR_CLICK_LEFT) msgstr("Kliknięcie lewym przyciskiem myszy") msgid(CURSOR_CLICK_RIGHT) msgstr("Kliknięcie prawym przyciskiem myszy") /****************************************************************************** *** Audio / Video Call Strings *** ******************************************************************************/ msgid(CALL_START_AUDIO) msgstr("Rozpocznij rozmowę głosową") msgid(CALL_START_VIDEO) msgstr("Rozpocznij rozmowę wideo") msgid(CALL_DECLINE) msgstr("Odrzuć połączenie") msgid(CALL_CANCELLED) msgstr("Połączenie anulowane") msgid(CALL_INVITED) msgstr("Rozmowa przychodząca") msgid(CALL_RINGING) msgstr("Dzwonienie") msgid(CALL_STARTED) msgstr("Rozmowa rozpoczęta") msgid(CALL_ENDED) msgstr("Rozmowa zakończona") msgid(CALL_FRIEND_HAD_ENDED_CALL) msgstr(" zakończył rozmowę!") msgid(CALL_VIDEO_SHOW_INLINE) msgstr("Pokaż wideo w środku okna") /****************************************************************************** *** Friend & Friend Settings Strings *** ******************************************************************************/ msgid(FRIEND_ALIAS) msgstr("Ustaw pseudonim znajomego") msgid(FRIEND_PUBLIC_KEY) msgstr("Klucz publiczny znajomego") msgid(FRIEND_AUTOACCEPT) msgstr("Akceptuj pliki przychodzące bez potwierdzenia") msgid(FRIEND_EXPORT_CHATLOG) msgstr("Eksportuj historię czatu znajomego do pliku tekstowego") /****************************************************************************** *** Group Strings *** ******************************************************************************/ msgid(GROUPCHAT_JOIN_AUDIO) msgstr("Dołącz do grupowej rozmowy audio") msgid(GROUP_CREATE_WITH_AUDIO) msgstr("Włącz głos audio") msgid(GROUP_CREATE_TEXT) msgstr("Utwórz grupę tekstową") msgid(GROUP_CREATE_VOICE) msgstr("Utwórz grupę z rozmową głosową") msgid(CREATEGROUPCHAT) msgstr("Utwórz grupę") msgid(REMOVE_GROUP) msgstr("Usuń grupę") msgid(LEAVE_GROUP) msgstr("Opuść grupę") /****************************************************************************** *** Group Settings *** ******************************************************************************/ msgid(GROUPCHAT_SETTINGS) msgstr("Ustawienia grupy") msgid(GROUP_NOTIFICATIONS) msgstr("Powiadomienia o aktywności w grupie") msgid(GROUP_NOTIFICATIONS_ON) msgstr("Włączone") msgid(GROUP_NOTIFICATIONS_MENTION) msgstr("Tylko przy wspomnieniu o mnie") msgid(GROUP_NOTIFICATIONS_OFF) msgstr("Wyłączone") msgid(GROUP_TOPIC) msgstr("Ustaw temat grupy") /****************************************************************************** *** Settings / Profile Strings *** ******************************************************************************/ msgid(PROFILE_BUTTON) msgstr("Profil") msgid(DEVICES_BUTTON) msgstr("Urządzenia") msgid(USER_INTERFACE_BUTTON) msgstr("Interfejs użytkownika") msgid(AUDIO_VIDEO_BUTTON) msgstr("Audio i Wideo") msgid(ADVANCED_BUTTON) msgstr("Zaawansowane") msgid(NOTIFICATIONS_BUTTON) msgstr("Powiadomienia") msgid(AUTO_UPDATE) msgstr("Automatycznie aktualizuj uTox") msgid(PROFILE_SETTINGS) msgstr("Ustawienia profilu") msgid(PROFILE_PW_WARNING) msgstr("UWAGA: µTox zacznie automatycznie szyfrować tym hasłem.") msgid(PROFILE_PW_NO_RECOVER) msgstr("Nie ma sposobu by odzyskać utracone hasła.") /*** Profile ***/ /*** Devices ***/ msgid(DEVICES_ADD_NEW) msgstr("Dodaj nowe urządzenie do sieci") msgid(DEVICES_NUMBER) msgstr("Lista połączonych urządzeń") /*** Network ***/ /*** User Interface ***/ /*** Audio/Video ***/ /****************************************************************************** *** UNSORTED STRINGS *** *** TODO: *** *** FIXME: *** ******************************************************************************/ msgid(ADDFRIENDS) msgstr("Dodaj nowy kontakt") msgid(MESSAGE) msgstr("Wiadomość") msgid(FILTER_ONLINE) msgstr("Dostępne kontakty") msgid(FILTER_ALL) msgstr("Wszystkie kontakty") msgid(FILTER_CONTACT_TOGGLE) msgstr("Tylko podłączone kontakty") msgid(ADD) msgstr("Dodaj") msgid(FRIENDREQUEST) msgstr("Zaproszenie do znajomych") msgid(USERSETTINGS) msgstr("Ustawienia profilu") msgid(FRIEND_SETTINGS) msgstr("Ustawienia znajomego") msgid(NAME) msgstr("Nazwa") msgid(STATUSMESSAGE) msgstr("Opis") msgid(PREVIEW) msgstr("Podgląd") msgid(AUDIOINPUTDEVICE) msgstr("Urządzenie wejściowe audio") msgid(AUDIOFILTERING) msgstr("Filtrowanie audio") msgid(AUDIOOUTPUTDEVICE) msgstr("Urządzenie wyjściowe audio") msgid(VIDEOINPUTDEVICE) msgstr("Urządzenie wejściowe wideo") msgid(PUSH_TO_TALK) msgstr("Naciśnij i mów") msgid(STATUS_ONLINE) msgstr("Dostępny") msgid(STATUS_AWAY) msgstr("Zaraz wracam") msgid(STATUS_BUSY) msgstr("Zajęty") msgid(STATUS_OFFLINE) msgstr("Niedostępny") msgid(STATUS_MESSAGE) msgstr("uTox %.*s zmienił status na %s.") msgid(SETTINGS_UI_MINI_ROSTER) msgstr("Użyj małej listy kontaktów") msgid(NOT_CONNECTED) msgstr("Niepodłączony") msgid(OTHERSETTINGS) msgstr("Inne ustawienia") msgid(UI) msgstr("Interfejs") msgid(USER_INTERFACE) msgstr("Interfejs użytkownika") msgid(UTOX_SETTINGS) msgstr("Ustawienia uTox") msgid(NETWORK_SETTINGS) msgstr("Ustawienia sieci") msgid(PROFILE_PASSWORD) msgstr("Hasło profilu") msgid(LOCK_UTOX) msgstr("Rozłącza z siecią Tox i blokuje ten profil.") msgid(SHOW_UI_PASSWORD) msgstr("Wyświetl pole hasła") msgid(SHOW_UI_PASSWORD_TOOLTIP) msgstr("Kliknij, aby wyświetlić pole hasła profilu. Zmiany zostaną wprowadzone natychmiastowo!") msgid(HIDE_UI_PASSWORD) msgstr("Schowaj pole hasła") msgid(HIDE_UI_PASSWORD_TOOLTIP) msgstr("Kliknij, aby schować pole hasła.") msgid(PASSWORD_TOO_SHORT) msgstr("Hasło musi mieć co najmniej 4 znaki") msgid(LOCK) msgstr("Zablokuj") msgid(AUDIO_VIDEO) msgstr("Audio/Wideo") msgid(SAVELOCATION) msgstr("Ścieżka zapisywania danych") msgid(LANGUAGE) msgstr("Język") msgid(NETWORK) msgstr("Sieć") msgid(PROXY_FORCE) msgstr("Wymuszaj użycie proxy") msgid(WARNING) msgstr("Zmiana ustawień sieci/proxy na chwilę rozłączy Cię z siecią Tox") msgid(SAVE_CHAT_HISTORY) msgstr("Zapisuj historię") msgid(AUDIONOTIFICATIONS) msgstr("Włącz powiadomienia Audio (dzwonek)") msgid(RINGTONE) msgstr("Dzwonek") msgid(IS_TYPING) msgstr("pisze...") msgid(CLOSE_TO_TRAY) msgstr("Zamknij do zasobnika") msgid(START_IN_TRAY) msgstr("Uruchom w zasobniku") msgid(SHOW_QR) msgstr("Wyświetl kod QR") msgid(HIDE_QR) msgstr("Schowaj kod QR") msgid(SAVE_QR) msgstr("Zapisz kod QR") msgid(COPY_TOX_ID) msgstr("Kopiuj jako tekst") msgid(COPY) msgstr("Kopiuj") msgid(COPYWITHOUTNAMES) msgstr("Kopiuj (bez nazw)") msgid(COPY_WITH_NAMES) msgstr("Kopiuj (z nazwami)") msgid(CUT) msgstr("Wytnij") msgid(PASTE) msgstr("Wklej") msgid(DELETE) msgstr("Usuń") msgid(SELECTALL) msgstr("Zaznacz wszystko") msgid(REMOVE) msgstr("Usuń") msgid(REMOVE_FRIEND) msgstr("Usuń znajomego") msgid(LEAVE) msgstr("Opuść") msgid(CTOPIC) msgstr("Zmień temat") msgid(ACCEPT) msgstr("Akceptuj") msgid(IGNORE) msgstr("Ignoruj") msgid(SET_ALIAS) msgstr("Ustaw pseudonim") msgid(ALIAS) msgstr("Pseudonim") msgid(SENDMESSAGE) msgstr("Wyślij wiadomość") msgid(SENDSCREENSHOT) msgstr("Wyślij zrzut ekranu") msgid(CLICKTOSAVE) msgstr("Kliknij, aby zapisać") msgid(CLICKTOOPEN) msgstr("Kliknij, aby otworzyć") msgid(CANCELLED) msgstr("Anulowano") msgid(DPI_060) msgstr("Niestandardowe DPI 60%") msgid(DPI_070) msgstr("Niestandardowe DPI 70%") msgid(DPI_080) msgstr("Niestandardowe DPI 80%") msgid(DPI_090) msgstr("Niestandardowe DPI 90%") msgid(DPI_100) msgstr("Niestandardowe DPI 100%") msgid(DPI_110) msgstr("CNiestandardowe DPI 110%") msgid(DPI_120) msgstr("Niestandardowe DPI 120%") msgid(DPI_130) msgstr("Niestandardowe DPI 130%") msgid(DPI_140) msgstr("Niestandardowe DPI 140%") msgid(DPI_150) msgstr("Niestandardowe DPI 150%") msgid(DPI_160) msgstr("Niestandardowe DPI 160%") msgid(DPI_170) msgstr("Niestandardowe DPI 170%") msgid(DPI_180) msgstr("Niestandardowe DPI 180%") msgid(DPI_190) msgstr("Niestandardowe DPI 190%") msgid(DPI_200) msgstr("Niestandardowe DPI 200%") msgid(DPI_210) msgstr("Niestandardowe DPI 210%") msgid(DPI_220) msgstr("Niestandardowe DPI 220%") msgid(DPI_230) msgstr("Niestandardowe DPI 230%") msgid(DPI_240) msgstr("Niestandardowe DPI 240%") msgid(DPI_250) msgstr("Niestandardowe DPI 250%") msgid(DPI_260) msgstr("Niestandardowe DPI 260%") msgid(DPI_270) msgstr("Niestandardowe DPI 270%") msgid(DPI_280) msgstr("Niestandardowe DPI 280%") msgid(DPI_290) msgstr("Niestandardowe DPI 290%") msgid(DPI_300) msgstr("Niestandardowe DPI 300%") msgid(DPI_TINY) msgstr("Małe (50%)") msgid(DPI_NORMAL) msgstr("Normalne (100%)") msgid(DPI_BIG) msgstr("Duże (150%)") msgid(DPI_LARGE) msgstr("Wielkie (200%)") msgid(DPI_HUGE) msgstr("Ogromne (250%)") msgid(PROXY_DISABLED) msgstr("Wyłączone") msgid(PROXY_FALLBACK) msgstr("Zapasowe") msgid(PROXY_ALWAYS_USE) msgstr("Zawsze używaj") msgid(NO) msgstr("Nie") msgid(YES) msgstr("Tak") msgid(OFF) msgstr("Wyłączone") msgid(ON) msgstr("Włączone") msgid(SHOW) msgstr("Pokaż") msgid(HIDE) msgstr("Ukryj") msgid(EXIT) msgstr("Zakończ") msgid(VIDEO_IN_NONE) msgstr("Brak") msgid(VIDEO_IN_DESKTOP) msgstr("Pulpit") msgid(AUDIO_IN_DEFAULT_LOOPBACK) msgstr("Domyślny Loopback") msgid(AUDIO_IN_ANDROID) msgstr("Wejście OpenSL") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("Proszę, zaakceptuj to zaproszenie do znajomych.") msgid(CONTACT_SEARCH_ADD_HINT) msgstr("Szukaj/dodaj znajomych") msgid(PROXY_EDIT_HINT_IP) msgstr("Adres IP") msgid(WINDOW_TITLE_VIDEO_PREVIEW) msgstr("Podgląd wideo") msgid(MUTE) msgstr("Wycisz") msgid(UNMUTE) msgstr("Wyłącz wyciszenie") msgid(SELECT_AVATAR_TITLE) msgstr("Wybierz awatar") msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS) msgstr("Awatar zbyt duży. Rozmiar maksymalny to: ") msgid(CANT_FIND_FILE_OR_EMPTY) msgstr("Nie można znaleźć wybranego pliku lub wybrany plik jest pusty.") msgid(CLEAR_HISTORY) msgstr("Wyczyść historię") msgid(AUTO_STARTUP) msgstr("Uruchamiaj wraz ze startem systemu") msgid(THEME) msgstr("Motyw") msgid(THEME_DEFAULT) msgstr("Domyślny") msgid(THEME_LIGHT) msgstr("Jasny") msgid(THEME_DARK) msgstr("Ciemny") msgid(THEME_HIGHCONTRAST) msgstr("Wysoki kontrast") msgid(THEME_CUSTOM) msgstr("Własny (zobacz dokumentację)") msgid(SEND_TYPING_NOTIFICATIONS) msgstr("Wysyłaj powiadomienia gdy piszę") msgid(STATUS_NOTIFICATIONS) msgstr("Powiadomienia o zmianach statusu") msgid(RANDOMIZE_NOSPAM) msgstr("Losuj Nospam") msgid(REVERT_NOSPAM) msgstr("Przywróć Nospam") msgid(NOSPAM_WARNING) msgstr("Zmiana Twojego nospam spowoduje, że Twoje Tox ID przestanie działać. uTox nie aktualizuje ID na serwerach nazw.") msgid(BLOCK_FRIEND_REQUESTS) msgstr("Blokuj zaproszenia do znajomych") msgid(SHOW_NOSPAM) msgstr("Pokaż ustawienia nospam") msgid(HIDE_NOSPAM) msgstr("Schowaj ustawienia nospam") msgid(DELETE_FRIEND) msgstr("Usuń znajomego") msgid(DELETE_MESSAGE) msgstr("Jesteś pewien, że chcesz skasować ") msgid(KEEP) msgstr("Zatrzymaj") uTox-0.17.1/langs/pt.h000066400000000000000000000126561354126257400144620ustar00rootroot00000000000000msgid(LANG_NATIVE_NAME) msgstr("Português") msgid(LANG_ENGLISH_NAME) msgstr("PORTUGUESE") msgid(REQ_SENT) msgstr("Pedido de amizade enviado. Assim que seja aceite, o seu amigo aparecerá online.") msgid(REQ_INVALID_ID) msgstr("Error: ID Tox invalida") msgid(REQ_EMPTY_ID) msgstr("Erro: Nenhuma ID Tox especificada") msgid(REQ_LONG_MSG) msgstr("Erro: Mensagem demasiado longa") msgid(REQ_NO_MSG) msgstr("Erro: Mensagem em branco") msgid(REQ_SELF_ID) msgstr("Erro: Este é o seu próprio ID Tox") msgid(REQ_ALREADY_FRIENDS) msgstr("Erro: ID Tox já se encontra na lista de amigos") msgid(REQ_UNKNOWN) msgstr("Erro: Desconhecido") msgid(REQ_BAD_CHECKSUM) msgstr("Erro: ID Tox invalida (verificação de conteúdo invalida)") msgid(REQ_BAD_NOSPAM) msgstr("Erro: ID Tox invalida (valor nospam invalido)") msgid(REQ_NO_MEMORY) msgstr("Erro: Sem memoria disponivel") msgid(SEND_FILE) msgstr("Enviar Ficheiro") msgid(SAVE_FILE) msgstr("Guardar Ficheiro") msgid(WHERE_TO_SAVE_FILE_PROMPT) msgstr("Onde deseja guardar \"%.*s\"?") msgid(SEND_FILE_PROMPT) msgstr("Selecione um ou mais ficheiros para envio.") msgid(SCREEN_CAPTURE_PROMPT) msgstr("Arraste a caixa em volta da área do ecrã que deseja enviar.") msgid(TRANSFER_NEW) msgstr("Nova transferência de ficheiros") msgid(TRANSFER_STARTED) msgstr("Transferência de ficheiros iniciada") msgid(TRANSFER___) msgstr("...") msgid(TRANSFER_PAUSED) msgstr("Transferência de ficheiros em pausa") msgid(TRANSFER_BROKEN) msgstr("Transferência de ficheiros interrompida") msgid(TRANSFER_CANCELLED) msgstr("Transferência de ficheiros cancelada") msgid(TRANSFER_COMPLETE) msgstr("Transferência de ficheiros completa") msgid(CALL_CANCELLED) msgstr("Chamada cancelada") msgid(CALL_INVITED) msgstr("Chamada enviada") msgid(CALL_RINGING) msgstr("A chamar") msgid(CALL_STARTED) msgstr("Chamada iniciada") msgid(ADDFRIENDS) msgstr("Adicionar Amigos") msgid(TOXID) msgstr("ID Tox") msgid(MESSAGE) msgstr("Mensagem") msgid(ADD) msgstr("Adicionar") msgid(CREATEGROUPCHAT) msgstr("Criar Conversa de Grupo") msgid(FRIENDREQUEST) msgstr("Pedido de Amizade") msgid(USERSETTINGS) msgstr("Configurações de Utilizador") msgid(NAME) msgstr("Nome") msgid(STATUSMESSAGE) msgstr("Mensagem de Estado") msgid(PREVIEW) msgstr("Pré-visualização") msgid(AUDIOINPUTDEVICE) msgstr("Dispositivo de Entrada de Áudio") msgid(AUDIOFILTERING) msgstr("Filtrar Audio") msgid(AUDIOOUTPUTDEVICE) msgstr("Dispositivo de Saída de Áudio") msgid(VIDEOINPUTDEVICE) msgstr("Dispositivo de Entrada de Vídeo") msgid(OTHERSETTINGS) msgstr("Outras Configurações") msgid(DPI) msgstr("DPI") msgid(SAVELOCATION) msgstr("Local de Gravação") msgid(LANGUAGE) msgstr("Linguagem") msgid(NETWORK) msgstr("Rede") msgid(IPV6) msgstr("IPv6:") msgid(UDP) msgstr("UDP:") msgid(PROXY) msgstr("Proxy (SOCKS 5)") msgid(WARNING) msgstr("Alterar as configurações de Rede/Proxy irá temporariamente desconecta-lo da rede Tox") msgid(SAVE_CHAT_HISTORY) msgstr("Registos de Conversação") msgid(AUDIONOTIFICATIONS) msgstr("Ativar Notificação Auditiva (Toque de Chamada)") msgid(IS_TYPING) msgstr("está a escrever...") msgid(CLOSE_TO_TRAY) msgstr("Fechar na Tray") msgid(START_IN_TRAY) msgstr("Inicializar na Tray") msgid(COPY) msgstr("Copiar") msgid(COPYWITHOUTNAMES) msgstr("Copiar (Excluindo Nomes)") msgid(COPY_WITH_NAMES) msgstr("Copiar (Incluindo Nomes)") msgid(CUT) msgstr("Cortar") msgid(PASTE) msgstr("Colar") msgid(DELETE) msgstr("Apagar") msgid(SELECTALL) msgstr("Selecionar Tudo") msgid(REMOVE) msgstr("Remover") msgid(LEAVE) msgstr("Sair") msgid(CTOPIC) msgstr("Mudar topico") msgid(ACCEPT) msgstr("Aceitar") msgid(IGNORE) msgstr("Ignorar") msgid(SENDSCREENSHOT) msgstr("Enviar captura de ecrã") msgid(CLICKTOSAVE) msgstr("Clicar para gravar") msgid(CLICKTOOPEN) msgstr("Clicar para abrir") msgid(CANCELLED) msgstr("Cancelado") msgid(DPI_TINY) msgstr("Pequeno (50%)") msgid(DPI_NORMAL) msgstr("Normal (100%)") msgid(DPI_BIG) msgstr("Grande (150%)") msgid(DPI_LARGE) msgstr("Largo (200%)") msgid(DPI_HUGE) msgstr("Gigante (250%)") msgid(FILTER_ALL) msgstr("Todos") msgid(FILTER_ONLINE) msgstr("Online") msgid(PROXY_DISABLED) msgstr("Desactivado") msgid(PROXY_FALLBACK) msgstr("Reserva") msgid(PROXY_ALWAYS_USE) msgstr("Usar sempre") msgid(NO) msgstr("Não") msgid(YES) msgstr("Sim") msgid(VIDEO_IN_NONE) msgstr("Nenhum") msgid(VIDEO_IN_DESKTOP) msgstr("Ambiente de Trabalho") msgid(AUDIO_IN_DEFAULT_LOOPBACK) msgstr("Loopback Pré-definido") msgid(AUDIO_IN_ANDROID) msgstr("Entrada OpenSL") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("Por favor, aceite este pedido de amizade.") msgid(WINDOW_TITLE_VIDEO_PREVIEW) msgstr("Pré-visualização de Vídeo") msgid(MUTE) msgstr("Silenciar") msgid(UNMUTE) msgstr("Com som") msgid(SELECT_AVATAR_TITLE) msgstr("Selecionar Avatar") msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS) msgstr("Avatar demasiado grande. Tamanho máximo: ") msgid(CANT_FIND_FILE_OR_EMPTY) msgstr("Ficheiro não encontrado ou em branco.") msgid(CLEAR_HISTORY) msgstr("Limpar historico") msgid(AUTO_STARTUP) msgstr("Inicializar ao arranque de sistema") msgid(THEME) msgstr("Aparência") msgid(THEME_DEFAULT) msgstr("Tema Pré-definido") msgid(THEME_LIGHT) msgstr("Tema claro") msgid(THEME_DARK) msgstr("Tema escuro") msgid(THEME_HIGHCONTRAST) msgstr("Alto contraste") msgid(THEME_CUSTOM) msgstr("Customizado (ver documentação)") msgid(THEME_ZENBURN) msgstr("Zenburn") msgid(SEND_TYPING_NOTIFICATIONS) msgstr("Alertar amigo quando escreve") uTox-0.17.1/langs/ro.h000066400000000000000000000114461354126257400144530ustar00rootroot00000000000000msgid(LANG_NATIVE_NAME) msgstr("Română") msgid(LANG_ENGLISH_NAME) msgstr("ROMANIAN") msgid(REQ_SENT) msgstr("Cerere de prietenie trimisă. Prietenul tău va apărea online după ce va fi acceptată cererea.") msgid(REQ_INVALID_ID) msgstr("Error: Tox ID invalid") msgid(REQ_EMPTY_ID) msgstr("Error: Niciun Tox ID identificat") msgid(REQ_LONG_MSG) msgstr("Error: Mesajul este prea lung") msgid(REQ_NO_MSG) msgstr("Error: Mesaj gol") msgid(REQ_SELF_ID) msgstr("Error: Tox ID este ID-ul în sine") msgid(REQ_ALREADY_FRIENDS) msgstr("Error: Tox ID este deja în lista ta de prieteni") msgid(REQ_UNKNOWN) msgstr("Error: Necunoscut") msgid(REQ_BAD_CHECKSUM) msgstr("Error: Tox ID invalid (control prost)") msgid(REQ_BAD_NOSPAM) msgstr("Error: Tox ID invalid (valoare nospam proastă)") msgid(REQ_NO_MEMORY) msgstr("Error: Insuficientă memorie") msgid(TRANSFER_NEW) msgstr("Transferul unui fişier nou") msgid(TRANSFER_STARTED) msgstr("Transferul fişierului a început") //TODO: Same as in English? Localize or remove. //msgid(TRANSFER___) //msgstr("...") msgid(TRANSFER_PAUSED) msgstr("Transferul fişierului a fost pus pe pauză") msgid(TRANSFER_BROKEN) msgstr("Transferul fişierului este stricat") msgid(TRANSFER_CANCELLED) msgstr("Transferul fişierului a fost anulat") msgid(TRANSFER_COMPLETE) msgstr("Transferul fişierului este complet") msgid(CALL_CANCELLED) msgstr("Apel anulat") msgid(CALL_INVITED) msgstr("Apel invitat") msgid(CALL_RINGING) msgstr("Apel sunat") msgid(CALL_STARTED) msgstr("Apel început") msgid(ADDFRIENDS) msgstr("Adăugare prieteni") //TODO: Same as in English? Localize or remove. //msgid(TOXID) //msgstr("Tox ID") msgid(MESSAGE) msgstr("Mesaj") msgid(ADD) msgstr("Adăugare") msgid(FRIENDREQUEST) msgstr("Cerere de prietenie") msgid(USERSETTINGS) msgstr("Setările userul-ui") msgid(NAME) msgstr("Nume") msgid(STATUSMESSAGE) msgstr("Mesaj de stare") msgid(PREVIEW) msgstr("Previzualizare") msgid(AUDIOINPUTDEVICE) msgstr("Dispozitiv de intrare audio") msgid(AUDIOOUTPUTDEVICE) msgstr("Dispozitiv de iesire audio") msgid(VIDEOINPUTDEVICE) msgstr("Dispozitiv de intrare video") msgid(OTHERSETTINGS) msgstr("Alte setări") //TODO: Same as in English? Localize or remove. //msgid(DPI) //msgstr("DPI") msgid(SAVELOCATION) msgstr("Salvare locaţie") msgid(LANGUAGE) msgstr("Limba") msgid(NETWORK) msgstr("Internet") //TODO: Same as in English? Localize or remove. //msgid(IPV6) //msgstr("IPv6:") //TODO: Same as in English? Localize or remove. //msgid(UDP) //msgstr("UDP:") //TODO: Same as in English? Localize or remove. //msgid(PROXY) //msgstr("Proxy (SOCKS 5)") msgid(WARNING) msgstr("Schimbarea setărilor Network/Proxy te vor deconecta de la internetul Tox") msgid(SAVE_CHAT_HISTORY) msgstr("Logare") //TODO: Same as in English? Localize or remove. //msgid(IS_TYPING) //msgstr("is typing...") msgid(COPY) msgstr("Copiere") msgid(COPYWITHOUTNAMES) msgstr("Copiere (niciun nume)") msgid(CUT) msgstr("Tăiere") msgid(PASTE) msgstr("Lipire") msgid(DELETE) msgstr("Stergere") msgid(SELECTALL) msgstr("Selectare tot") msgid(REMOVE) msgstr("Eliminare") msgid(LEAVE) msgstr("Plecare") msgid(ACCEPT) msgstr("Acceptare") msgid(IGNORE) msgstr("Ignorare") msgid(CLICKTOSAVE) msgstr("Click pentru a salva") msgid(CLICKTOOPEN) msgstr("Click pentru a deschide") msgid(CANCELLED) msgstr("Anulat") //TODO: Localize or remove. //msgid(DPI_TINY) //msgstr("Tiny (50%)") //TODO: Localize or remove. //msgid(DPI_NORMAL) //msgstr("Normal (100%)") //TODO: Localize or remove. //msgid(DPI_BIG) //msgstr("Big (150%)") //TODO: Localize or remove. //msgid(DPI_LARGE) //msgstr("Large (200%)") //TODO: Localize or remove. //msgid(DPI_HUGE) //msgstr("Huge (250%)") //TODO: Localize or remove. //msgid(FILTER_ALL) //msgstr("All") //TODO: Localize or remove. //msgid(FILTER_ONLINE) //msgstr("Online") //TODO: Localize or remove. //msgid(PROXY_DISABLED) //msgstr("Disabled") //TODO: Localize or remove. //msgid(PROXY_FALLBACK) //msgstr("Fallback") //TODO: Localize or remove. //msgid(PROXY_ALWAYS_USE) //msgstr("Always use") //TODO: Localize or remove. //msgid(NO) //msgstr("No") //TODO: Localize or remove. //msgid(YES) //msgstr("Yes") //TODO: Localize or remove. //msgid(VIDEO_IN_NONE) //msgstr("None") //TODO: Localize or remove. //msgid(VIDEO_IN_DESKTOP) //msgstr("Desktop") //TODO: Localize or remove. //msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) //msgstr("Please accept this friend request.") //TODO: Localize or remove. //msgid(PROXY_EDIT_HINT_IP) //msgstr("IP") //TODO: Localize or remove. //msgid(PROXY_EDIT_HINT_PORT) //msgstr("Port") //TODO: Localize or remove. //msgid(AUDIO_IN_DEFAULT_LOOPBACK) //msgstr("Default Loopback") //TODO: Localize or remove. //msgid(WINDOW_TITLE_VIDEO_PREVIEW) //msgstr("Video Preview") //TODO: Localize or remove. //msgid(AUDIONOTIFICATIONS) //msgstr("Enable Audible Notification (Ringtone)") uTox-0.17.1/langs/ru.h000066400000000000000000000640571354126257400144670ustar00rootroot00000000000000/****************************************************************************** *** Russian i18l Strings *** ******************************************************************************/ msgid(LANG_NATIVE_NAME) msgstr("Русский") msgid(LANG_ENGLISH_NAME) msgstr("RUSSIAN") /****************************************************************************** *** Splash Message & Change Log *** ******************************************************************************/ msgid(SPLASH_TITLE) msgstr("Добро пожаловать в новый uTox!") msgid(SPLASH_TEXT) msgstr("Вы только что обновились до версии 0.17.0! Название выпуска: Bork bork") msgid(CHANGE_LOG_TITLE) msgstr("Изменения в v0.17.0") msgid(CHANGE_LOG_TEXT) msgstr( "\n ВАЖНОЕ ЗАМЕЧАНИЕ ДЛЯ ПОЛЬЗОВАТЕЛЕЙ WINDOWS\n" " В данный момент с автообновлением проблема, апдейтер не работает с .exe-файлами.\n" " Чтобы быть уверенным, что автообновление будет работать,\n" " вам нужно переименовать .exe в \"uTox.exe\" и включить его в настройках\n" "\n" " Новые функции:\n" " Поддержка Toxcore 0.2.x!\n" " Настройки теперь сохраняются в человеко-читаемом формате (.ini)\n" " Поддержка Tox URI.\n" " Выпадающие меню теперь остаются открытыми после клика.\n" " Отображение QR-кода вашего ToxID.\n" " Добавлен эстонский язык.\n" " Исправления:\n" " Исправлена цветовая тема Zenburn.\n" " Записи о звонках сохраняются в истории сообщений.\n" " Улучшена работа с путями, содержащими не-ASCII символы.\n" " GTK поддерживается на большем количестве платформ.\n" " Исправлена ошибка при экспорте истории сообщений под macOS.\n" " Исправлена ошибка при передача файлов под macOS.\n" " Исправлено сохранение настроек (прокси, формат времени в чате, FPS).\n" " Поддержка сигналов на Linux системах.\n" " Иконка в трее теперь должна отображаться почти на всех Linux системах.\n" " Иконка в трее теперь отображается после перезапуска проводника Windows.\n" " Фильтрация аудио теперь снова работает.\n" " Исправлено большое количество дефектов интерфейса, включая области нажатия кнопок.\n" " Всплывающие подсказки больше не вылезают за пределы окна.\n" " Разработка\n" " Вы можете указать путь к библиотекам с помощью через CMAKE_PREFIX_PATH.\n" "\nv0.16.0\n" " Новые функции:\n" " Сохраняется язык интерфейса.\n" " Реализованы голосовые групповые звонки.\n" " Настройка FPS видео во время звонка.\n" " Исправления:\n" " Улучшена стабильность под OS X.\n" " Видео снова работает под Linux.\n" " Исправления и улучшения интерфейса. (Спасибо @redmanmale!)\n" " Исправлен заголовок окна предпросмотра видео под Windows. (Спасибо @thorpelawrence!)\n" " Исправлена часть сбоев в групповых чатах.\n" " Исправлено поведение двойного клика средней клавиши мыши в X11. (Спасибо @dkmoz!)\n" " Исправлен переход по ссылкам с Юникод-символами под Windows.\n" " При передаче файлов их имена очищаются от запрещённых символов под Windows.\n" " Сохраняются настройки подтверждения приёма файлов.\n" " Аудио уведомления теперь воспроизводятся только когда uTox не в фокусе.\n" " Сообщения помечаются прочитанными, если они пришли, когда чат был открыт.\n" " Выбор файла GTK теперь работает под OpenBSD и NetBSD.\n" " Исправлено поведение переключателя настройки автозапуска.\n" " Используется псевдоним контакта при уведомлении о наборе текста.\n" " Добавлены дата и время сообщения при экспорте чата.\n" " Разработка\n" " Прекращена поддержка ToxDNS.\n" " Добавлена инструкция по сборке под OS X (Спасибо @publicarray!)\n" " Прогон тестов под OS X (в дополнение к Linux).\n" " Добавлен скрипт на питоне для поиска отсутствующих переводов.\n" " Уменьшен размер MinSizeRel-сборок.\n" " Обновлены несколько переводов.\n" "\n" " Знаешь другой язык? Приятнее читать список изменений на своём языке?\n" " Помоги нам перевести uTox!\n" "\nv0.15.0\n" "\nНовые функции:\n" " Переделан интерфейс. (Спасибо redmanmale!)\n" " Сворачивающаяся боковая панель под Android.\n" " Исправления:\n" " Видео снова работает под Windows.\n" " При автоматическом приёме файлов в портативном режиме они сохраняются в ту же папку.\n" " Обновлён украинский перевод. (Спасибо v2e!)\n" " Dbus уведомления должны работать в большем количестве систем.\n" " Разработка\n" " Добавлена поддержка NetBSD, OpenBSD и FreeBSD.\n" " Переделан интерфейс.\n" "\nv0.9.7\n" " Некоторые незначительные исправления GUI\n" " Все выпадающие меню Да/Нет заменены переключателями\n" " Исправлено сохранение настроек прокси между запусками.\n" "\nv0.9.5\n" " Встроенное видео для OSX\n" " Исправлена ошибка ведения лога\n" "\nv0.9.3\n" " Исправлена ошибка сообщений, вызывающая случайные сбои в Windows\n" " Ограничено число сообщений для повторной отправки за раз\n" "\nv0.9.2\n" " Чистка исходников/Изменения директорий\n" "\nv0.9.1\n" " Исправлен сбой при отправке сообщения новому собеседнику\n" "\nv0.9.0\n" " Очередь сообщений\n" " Улучшенные и раскрашенные групповые чаты\n" " Экспериментальная поддержка встроенного видео\n" " Компактный список контактов\n" " Переработана обработка сообщений\n" "\n") /****************************************************************************** *** MISC & UNSORTED *** ******************************************************************************/ msgid(REQ_SENT) msgstr("Запрос на добавление в контакты отправлен. Ваш собеседник станет доступен в сети, как только подтвердит запрос.") msgid(REQ_INVALID_ID) msgstr("Ошибка: неправильный Tox ID") msgid(REQ_EMPTY_ID) msgstr("Ошибка: не указан Tox ID") msgid(REQ_LONG_MSG) msgstr("Ошибка: слишком длинное сообщение") msgid(REQ_NO_MSG) msgstr("Ошибка: пустое сообщение") msgid(REQ_SELF_ID) msgstr("Ошибка: Tox ID совпадает с собственным") msgid(REQ_ALREADY_FRIENDS) msgstr("Ошибка: Tox ID уже есть в списке контактов") msgid(REQ_UNKNOWN) msgstr("Неизвестная ошибка") msgid(REQ_BAD_CHECKSUM) msgstr("Ошибка: неправильный Tox ID (контрольная сумма не совпадает)") msgid(REQ_BAD_NOSPAM) msgstr("Ошибка: неправильный Tox ID (неверное значение антиспама)") msgid(REQ_NO_MEMORY) msgstr("Ошибка: не хватает памяти") msgid(SEND_FILE) msgstr("Отправить файл") msgid(SAVE_FILE) msgstr("Сохранить файл") msgid(WHERE_TO_SAVE_FILE_PROMPT) msgstr("Где вы хотите сохранить \"%.*s\"?") msgid(WHERE_TO_SAVE_FILE) msgstr("Где вы хотите сохранить файл?") msgid(SEND_FILE_PROMPT) msgstr("Выберите один или несколько файлов для отправки.") msgid(SCREEN_CAPTURE_PROMPT) msgstr("Выделите область экрана, которую вы хотите отправить.") /****************************************************************************** *** File Transfer Strings *** ******************************************************************************/ msgid(TRANSFER_NEW) msgstr("Передача нового файла") msgid(TRANSFER_STARTED) msgstr("Передача файла начата") msgid(TRANSFER___) msgstr("...") msgid(TRANSFER_PAUSED) msgstr("Передача файла приостановлена") msgid(TRANSFER_BROKEN) msgstr("Передача файла прервана") msgid(TRANSFER_CANCELLED) msgstr("Передача файла отменена") msgid(TRANSFER_COMPLETE) msgstr("Передача файла завершена") /****************************************************************************** *** Keyboard and Mouse Cursor Strings *** ******************************************************************************/ msgid(CURSOR_CLICK_LEFT) msgstr("Левый клик") msgid(CURSOR_CLICK_RIGHT) msgstr("Правый клик") /****************************************************************************** *** Audio / Video Call Strings *** ******************************************************************************/ msgid(CALL_START_AUDIO) msgstr("Позвонить") msgid(CALL_START_VIDEO) msgstr("Видео вызов") msgid(CALL_DECLINE) msgstr("Отклонить вызов") msgid(CALL_CANCELLED) msgstr("Вызов отменён") msgid(CALL_INVITED) msgstr("Входящий вызов") msgid(CALL_RINGING) msgstr("Исходящий вызов") msgid(CALL_STARTED) msgstr("Идёт вызов") msgid(CALL_ENDED) msgstr("Вызов завершён") msgid(CALL_FRIEND_HAD_ENDED_CALL) msgstr(" завершил вызов!") msgid(CALL_VIDEO_SHOW_INLINE) msgstr("Показывать видео встроенным") /****************************************************************************** *** Friend & Friend Settings Strings *** ******************************************************************************/ msgid(FRIEND_ALIAS) msgstr("Назначить псевдоним контакта") msgid(FRIEND_PUBLIC_KEY) msgstr("Открытый ключ контакта") msgid(FRIEND_AUTOACCEPT) msgstr("Принимать передаваемые файлы без подтверждения") msgid(FRIEND_EXPORT_CHATLOG) msgstr("Экспортировать историю переписки как текст") /****************************************************************************** *** Group Strings *** ******************************************************************************/ msgid(GROUPCHAT_JOIN_AUDIO) msgstr("Присоединиться к голосовому чату") msgid(GROUP_CREATE_WITH_AUDIO) msgstr("Со звуком") msgid(GROUP_CREATE_TEXT) msgstr("Создать текстовый групповой чат") msgid(GROUP_CREATE_VOICE) msgstr("Создать голосовой групповой чат") msgid(CREATEGROUPCHAT) msgstr("Создать групповой чат") msgid(REMOVE_GROUP) msgstr("Удалить группу") msgid(LEAVE_GROUP) msgstr("Покинуть группу") /****************************************************************************** *** Group Settings *** ******************************************************************************/ msgid(GROUPCHAT_SETTINGS) msgstr("Настройки группового чата") msgid(GROUP_NOTIFICATIONS) msgstr("Групповые уведомления") msgid(GROUP_NOTIFICATIONS_ON) msgstr("Вкл") msgid(GROUP_NOTIFICATIONS_MENTION) msgstr("Упомянутые") msgid(GROUP_NOTIFICATIONS_OFF) msgstr("Выкл") msgid(GROUP_TOPIC) msgstr("Тема группы") /****************************************************************************** *** Settings / Profile Strings *** ******************************************************************************/ msgid(PROFILE_BUTTON) msgstr("Профиль") msgid(DEVICES_BUTTON) msgstr("Устройства") msgid(USER_INTERFACE_BUTTON) msgstr("Интерфейс") msgid(AUDIO_VIDEO_BUTTON) msgstr("Аудио и видео") msgid(ADVANCED_BUTTON) msgstr("Дополнительно") msgid(NOTIFICATIONS_BUTTON) msgstr("Уведомления") msgid(AUTO_UPDATE) msgstr("Автоматически обновлять uTox") msgid(PROFILE_SETTINGS) msgstr("Настройки профиля") msgid(PROFILE_PW_WARNING) msgstr("ПРЕДУПРЕЖДЕНИЕ: µTox автоматически зашифрует профиль с использованием этого пароля.") msgid(PROFILE_PW_NO_RECOVER) msgstr("Не существует способов восстановления утраченных паролей.") /*** Profile ***/ /*** Devices ***/ msgid(DEVICES_ADD_NEW) msgstr("Добавить новое связанное устройство") msgid(DEVICES_NUMBER) msgstr("Число связанных устройств") /*** Network ***/ /*** User Interface ***/ /*** Audio/Video ***/ /****************************************************************************** *** UNSORTED STRINGS *** *** TODO: *** *** FIXME: *** ******************************************************************************/ msgid(ADDFRIENDS) msgstr("Добавить новый контакт") msgid(TOXID) msgstr("Tox ID") msgid(MESSAGE) msgstr("Сообщение") msgid(FILTER_ONLINE) msgstr("Контакты на связи") msgid(FILTER_ALL) msgstr("Все контакты") msgid(FILTER_CONTACT_TOGGLE) msgstr("Переключить видимость отсутствующих контактов.") msgid(ADD) msgstr("Добавить") msgid(FRIENDREQUEST) msgstr("Запрос на добавление в список контактов") msgid(USERSETTINGS) msgstr("Настройки пользователя") msgid(FRIEND_SETTINGS) msgstr("Настройки контакта") msgid(NAME) msgstr("Имя") msgid(STATUSMESSAGE) msgstr("Сообщение статуса") msgid(PREVIEW) msgstr("Предпросмотр") msgid(AUDIOINPUTDEVICE) msgstr("Устройство захвата звука") msgid(AUDIOFILTERING) msgstr("Фильтр звука") msgid(AUDIOOUTPUTDEVICE) msgstr("Устройство воспроизведения звука") msgid(VIDEOINPUTDEVICE) msgstr("Устройство захвата видео") msgid(VIDEOFRAMERATE) msgstr("Частота кадров видео (FPS)") msgid(PUSH_TO_TALK) msgstr("Нажать для разговора") msgid(STATUS) msgstr("Статус") msgid(STATUS_ONLINE) msgstr("в сети") msgid(STATUS_AWAY) msgstr("не на месте") msgid(STATUS_BUSY) msgstr("занят(а)") msgid(STATUS_OFFLINE) msgstr("не в сети") msgid(STATUS_MESSAGE) msgstr("uTox %.*s теперь %s.") msgid(SETTINGS_UI_MINI_ROSTER) msgstr("Компактный список контактов") msgid(SETTINGS_UI_AUTO_HIDE_SIDEBAR) msgstr("Скрывать боковую панель автоматически") msgid(NOT_CONNECTED) msgstr("Нет сети") msgid(NOT_CONNECTED_SETTINGS) msgstr("Изменить настройки сети") msgid(OTHERSETTINGS) msgstr("Прочие настройки") msgid(UI) msgstr("UI") msgid(USER_INTERFACE) msgstr("Интерфейс") msgid(UTOX_SETTINGS) msgstr("Настройки uTox") msgid(NETWORK_SETTINGS) msgstr("Настройки сети") msgid(PROFILE_PASSWORD) msgstr("Пароль профиля") msgid(LOCK_UTOX) msgstr("Отключиться от сети и заблокировать профиль") msgid(SHOW_UI_PASSWORD) msgstr("Показать поле пароля") msgid(SHOW_UI_PASSWORD_TOOLTIP) msgstr("Показать поле пароля профиля. Изменения, сделанные здесь, применяются сразу!") msgid(HIDE_UI_PASSWORD) msgstr("Скрыть поле пароля") msgid(HIDE_UI_PASSWORD_TOOLTIP) msgstr("Скрыть поле пароля профиля") msgid(PASSWORD_TOO_SHORT) msgstr("Пароль должен быть не менее 4 символов") msgid(LOCK) msgstr("Заблокировать") msgid(AUDIO_VIDEO) msgstr("Аудио/видео") msgid(DPI) msgstr("Разрешение, точек/дюйм") msgid(SAVELOCATION) msgstr("Сохранить расположение") msgid(LANGUAGE) msgstr("Язык") msgid(NETWORK) msgstr("Сеть") msgid(IPV6) msgstr("IPv6:") msgid(UDP) msgstr("UDP:") msgid(PROXY) msgstr("Прокси (SOCKS 5)") msgid(PROXY_FORCE) msgstr("Всегда использовать проки") msgid(WARNING) msgstr("Изменение сетевых настроек приведёт к временному отключению от сети Tox") msgid(SAVE_CHAT_HISTORY) msgstr("Сохранять историю чата") msgid(AUDIONOTIFICATIONS) msgstr("Включить звонок (звуковое уведомление)") msgid(RINGTONE) msgstr("Мелодия звонка") msgid(IS_TYPING) msgstr("печатает...") msgid(CLOSE_TO_TRAY) msgstr("Сворачивать вместо закрытия") msgid(START_IN_TRAY) msgstr("Запускать свёрнутым") msgid(SHOW_QR) msgstr("Показать QR") msgid(HIDE_QR) msgstr("Скрыть QR") msgid(SAVE_QR) msgstr("Сохранить QR") msgid(COPY_TOX_ID) msgstr("Копировать как текст") msgid(COPY) msgstr("Копировать") msgid(COPYWITHOUTNAMES) msgstr("Копировать (без имён)") msgid(COPY_WITH_NAMES) msgstr("Копировать (с именами)") msgid(CUT) msgstr("Вырезать") msgid(PASTE) msgstr("Вставить") msgid(DELETE) msgstr("Удалить") msgid(SELECTALL) msgstr("Выделить всё") msgid(REMOVE) msgstr("Удалить") msgid(REMOVE_FRIEND) msgstr("Удалить контакт") msgid(LEAVE) msgstr("Выйти") msgid(CTOPIC) msgstr("Сменить тему") msgid(ACCEPT) msgstr("Принять") msgid(IGNORE) msgstr("Игнорировать") msgid(SET_ALIAS) msgstr("Назначить псевдоним") msgid(ALIAS) msgstr("Псевдоним") msgid(SENDMESSAGE) msgstr("Отправить сообщение") msgid(SENDSCREENSHOT) msgstr("Отправить снимок экрана") msgid(CLICKTOSAVE) msgstr("Нажмите чтобы сохранить") msgid(CLICKTOOPEN) msgstr("Нажмите чтобы открыть") msgid(CANCELLED) msgstr("Отменено") msgid(DPI_060) msgstr("Пользовательское 60%") msgid(DPI_070) msgstr("Пользовательское 70%") msgid(DPI_080) msgstr("Пользовательское 80%") msgid(DPI_090) msgstr("Пользовательское 90%") msgid(DPI_100) msgstr("Пользовательское 100%") msgid(DPI_110) msgstr("Пользовательское 110%") msgid(DPI_120) msgstr("Пользовательское 120%") msgid(DPI_130) msgstr("Пользовательское 130%") msgid(DPI_140) msgstr("Пользовательское 140%") msgid(DPI_150) msgstr("Пользовательское 150%") msgid(DPI_160) msgstr("Пользовательское 160%") msgid(DPI_170) msgstr("Пользовательское 170%") msgid(DPI_180) msgstr("Пользовательское 180%") msgid(DPI_190) msgstr("Пользовательское 190%") msgid(DPI_200) msgstr("Пользовательское 200%") msgid(DPI_210) msgstr("Пользовательское 210%") msgid(DPI_220) msgstr("Пользовательское 220%") msgid(DPI_230) msgstr("Пользовательское 230%") msgid(DPI_240) msgstr("Пользовательское 240%") msgid(DPI_250) msgstr("Пользовательское 250%") msgid(DPI_260) msgstr("Пользовательское 260%") msgid(DPI_270) msgstr("Пользовательское 270%") msgid(DPI_280) msgstr("Пользовательское 280%") msgid(DPI_290) msgstr("Пользовательское 290%") msgid(DPI_300) msgstr("Пользовательское 300%") msgid(DPI_TINY) msgstr("Мелкое (50%)") msgid(DPI_NORMAL) msgstr("Нормальное (100%)") msgid(DPI_BIG) msgstr("Крупное (150%)") msgid(DPI_LARGE) msgstr("Большое (200%)") msgid(DPI_HUGE) msgstr("Огромное (250%)") msgid(PROXY_DISABLED) msgstr("Отключено") msgid(PROXY_FALLBACK) msgstr("Если необходимо") msgid(PROXY_ALWAYS_USE) msgstr("Всегда") msgid(NO) msgstr("Нет") msgid(YES) msgstr("Да") msgid(OFF) msgstr("Выкл") msgid(ON) msgstr("Вкл") msgid(SHOW) msgstr("Показать") msgid(HIDE) msgstr("Скрыть") msgid(VIDEO_IN_NONE) msgstr("Не выбрано") msgid(VIDEO_IN_DESKTOP) msgstr("Рабочий стол") msgid(AUDIO_IN_DEFAULT_LOOPBACK) msgstr("По умолчанию") msgid(AUDIO_IN_ANDROID) msgstr("OpenSL") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("Пожалуйста, добавьте меня в свой список контактов.") msgid(CONTACT_SEARCH_ADD_HINT) msgstr("Найти/добавить контакты") msgid(PROXY_EDIT_HINT_IP) msgstr("IP") msgid(PROXY_EDIT_HINT_PORT) msgstr("Порт") msgid(WINDOW_TITLE_VIDEO_PREVIEW) msgstr("Предпросмотр видео") msgid(MUTE) msgstr("Заглушить") msgid(UNMUTE) msgstr("Включить") msgid(SELECT_AVATAR_TITLE) msgstr("Выбрать изображение") msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS) msgstr("Изображение слишком большое. Максимальный размер: ") msgid(CANT_FIND_FILE_OR_EMPTY) msgstr("Невозможно найти выбранный файл или выбранный файл пуст.") msgid(CLEAR_HISTORY) msgstr("Очистить историю") msgid(AUTO_STARTUP) msgstr("Запускать при загрузке системы") msgid(THEME) msgstr("Тема") msgid(THEME_DEFAULT) msgstr("По умолчанию") msgid(THEME_LIGHT) msgstr("Светлая") msgid(THEME_DARK) msgstr("Тёмная") msgid(THEME_HIGHCONTRAST) msgstr("Высококонтрастная") msgid(THEME_CUSTOM) msgstr("Своя (см. документацию)") msgid(THEME_ZENBURN) msgstr("Zenburn") msgid(THEME_SOLARIZED_LIGHT) msgstr("Solarized светлая") msgid(THEME_SOLARIZED_DARK) msgstr("Solarized тёмная") msgid(SEND_TYPING_NOTIFICATIONS) msgstr("Отправлять уведомления о наборе текста") msgid(STATUS_NOTIFICATIONS) msgstr("Уведомления о статусе") msgid(RANDOMIZE_NOSPAM) msgstr("Сгенерировать новый антиспам") msgid(NOSPAM) msgstr("Антиспам") msgid(REVERT_NOSPAM) msgstr("Отменить изменение антиспама") msgid(NOSPAM_WARNING) msgstr("Изменение антиспама приведёт к тому, что ваш старый Tox ID больше не будет работать. uTox не обновляет ваш Tox ID на серверах имён.") msgid(BLOCK_FRIEND_REQUESTS) msgstr("Блокировать запросы на добавление в контакты") msgid(SHOW_NOSPAM) msgstr("Показать настройки антиспама") msgid(HIDE_NOSPAM) msgstr("Скрыть настройки антиспама") msgid(DELETE_FRIEND) msgstr("Удалить из контактов") msgid(DELETE_MESSAGE) msgstr("Вы уверены, что хотите удалить ") msgid(KEEP) msgstr("Оставить") uTox-0.17.1/langs/sv.h000066400000000000000000000342771354126257400144720ustar00rootroot00000000000000/****************************************************************************** *** Swedish i18l Strings *** ******************************************************************************/ msgid(LANG_NATIVE_NAME) msgstr("Svenska") msgid(LANG_ENGLISH_NAME) msgstr("Swedish") /****************************************************************************** *** Splash Message & Change Log *** ******************************************************************************/ // msgid(SPLASH_TITLE) // Don't translate this. //msgid(SPLASH_TEXT) // Don't translate this. // msgid(CHANGE_LOG_TITLE) // Don't translate this. // msgid(CHANGE_LOG_TEXT) // Don't translate this. /****************************************************************************** *** MISC & UNSORTED *** ******************************************************************************/ msgid(REQ_SENT) msgstr("Vänskapsbegäran skickad. Din vän kommer att visas som online efter att din begäran har accepterats.") msgid(REQ_INVALID_ID) msgstr("Fel: Ogiltigt Tox-ID") msgid(REQ_EMPTY_ID) msgstr("Fel: Inget Tox-ID angivet") msgid(REQ_LONG_MSG) msgstr("Fel: Meddelandet är för långt") msgid(REQ_NO_MSG) msgstr("Fel: Tomt meddelande") msgid(REQ_SELF_ID) msgstr("Fel: Du har angett ditt egna Tox-ID") msgid(REQ_ALREADY_FRIENDS) msgstr("Fel: Tox-ID är redan i din vänlista") msgid(REQ_UNKNOWN) msgstr("Fel: Okänt") msgid(REQ_BAD_CHECKSUM) msgstr("Fel: Ogiltigt Tox-ID (inkorrekt checksumma)") msgid(REQ_BAD_NOSPAM) msgstr("Fel: Ogiltigt Tox-ID (inkorrekt nospamvärde)") msgid(REQ_NO_MEMORY) msgstr("Fel: Inget minne") msgid(SEND_FILE) msgstr("Skicka fil") msgid(SAVE_FILE) msgstr("Spara fil") msgid(WHERE_TO_SAVE_FILE_PROMPT) msgstr("Vart vill du spara \"%.*s\"?") msgid(WHERE_TO_SAVE_FILE) msgstr("Vart vill du spara filen?") msgid(SEND_FILE_PROMPT) msgstr("Markera en eller flera filer att skicka.") msgid(SCREEN_CAPTURE_PROMPT) msgstr("Markera området på skärmen du vill skicka.") /****************************************************************************** *** File Transfer Strings *** ******************************************************************************/ msgid(TRANSFER_NEW) msgstr("Ny filöverföring") msgid(TRANSFER_STARTED) msgstr("Filöverföring påbörjad") msgid(TRANSFER___) msgstr("...") msgid(TRANSFER_PAUSED) msgstr("Filöverföring pausad") msgid(TRANSFER_BROKEN) msgstr("Filöverföring trasig") msgid(TRANSFER_CANCELLED) msgstr("Filöverföring avbruten") msgid(TRANSFER_COMPLETE) msgstr("Filöverföring färdig") /****************************************************************************** *** Keyboard and Mouse Cursor Strings *** ******************************************************************************/ msgid(CURSOR_CLICK_LEFT) msgstr("Vänsterklick") msgid(CURSOR_CLICK_RIGHT) msgstr("Högerklick") /****************************************************************************** *** Audio / Video Call Strings *** ******************************************************************************/ msgid(CALL_START_AUDIO) msgstr("Starta samtal") msgid(CALL_START_VIDEO) msgstr("Starta videosamtal") msgid(CALL_DECLINE) msgstr("Neka samtal") msgid(CALL_CANCELLED) msgstr("Samtal avbrutet") msgid(CALL_INVITED) msgstr("Inbjuden till samtal") msgid(CALL_RINGING) msgstr("Samtal ringer") msgid(CALL_STARTED) msgstr("Samtal påbörjat") msgid(CALL_FRIEND_HAD_ENDED_CALL) msgstr(" har avslutat samtalet!") msgid(CALL_VIDEO_SHOW_INLINE) msgstr("Visa video inline") /****************************************************************************** *** Friend & Friend Settings Strings *** ******************************************************************************/ msgid(FRIEND_ALIAS) msgstr("Sätt vännens alias") msgid(FRIEND_PUBLIC_KEY) msgstr("Vännens publika nyckel") msgid(FRIEND_AUTOACCEPT) msgstr("Acceptera inkommande filöverföringar utan bekräftelse") msgid(FRIEND_EXPORT_CHATLOG) msgstr("Exportera chattlogg i klartext") /****************************************************************************** *** Group Strings *** ******************************************************************************/ msgid(GROUPCHAT_JOIN_AUDIO) msgstr("Gå med i ljudchatt") msgid(GROUP_CREATE_TEXT) msgstr("Skapa en textgruppchatt") msgid(GROUP_CREATE_VOICE) msgstr("Skapa en gruppchatt med ljud") msgid(CREATEGROUPCHAT) msgstr("Skapa gruppchatt") msgid(REMOVE_GROUP) msgstr("Ta bort grupp") msgid(LEAVE_GROUP) msgstr("Lämna grupp") /****************************************************************************** *** Group Settings *** ******************************************************************************/ msgid(GROUPCHAT_SETTINGS) msgstr("Inställningar för Gruppchatt") msgid(GROUP_NOTIFICATIONS) msgstr("Gruppnotifieringar") msgid(GROUP_NOTIFICATIONS_ON) msgstr("På") msgid(GROUP_NOTIFICATIONS_MENTION) msgstr("Nämnd") msgid(GROUP_NOTIFICATIONS_OFF) msgstr("Av") msgid(GROUP_TOPIC) msgstr("Ställ in gruppens tema") /****************************************************************************** *** Settings / Profile Strings *** ******************************************************************************/ msgid(PROFILE_BUTTON) msgstr("Profil") msgid(DEVICES_BUTTON) msgstr("Apparater") msgid(USER_INTERFACE_BUTTON) msgstr("Gränssnitt") msgid(AUDIO_VIDEO_BUTTON) msgstr("Ljud & video") msgid(ADVANCED_BUTTON) msgstr("Avancerat") msgid(NOTIFICATIONS_BUTTON) msgstr("Notifieringar") msgid(AUTO_UPDATE) msgstr("Uppdatera µTox automatiskt") msgid(PROFILE_SETTINGS) msgstr("Profilinställningar") msgid(PROFILE_PW_WARNING) msgstr("VARNING: µTox kommer automatiskt börja kryptera med detta lösenord.") msgid(PROFILE_PW_NO_RECOVER) msgstr("Det går ej att återställa ett borttappat lösenord.") /*** Profile ***/ /*** Devices ***/ msgid(DEVICES_ADD_NEW) msgstr("Lägg till apparat till nätverket") msgid(DEVICES_NUMBER) msgstr("Antal länkade apparater") /*** Network ***/ /*** User Interface ***/ /*** Audio/Video ***/ /****************************************************************************** *** UNSORTED STRINGS *** *** TODO: *** *** FIXME: *** ******************************************************************************/ msgid(ADDFRIENDS) msgstr("Lägg till vän") msgid(TOXID) msgstr("Tox-ID") msgid(MESSAGE) msgstr("Meddelande") msgid(FILTER_ONLINE) msgstr("Online") msgid(FILTER_ALL) msgstr("Alla") msgid(FILTER_CONTACT_TOGGLE) msgstr("Växla filtrering av frånkopplade kontakter.") msgid(ADD) msgstr("Lägg till") msgid(FRIENDREQUEST) msgstr("Vänskapsinbjudan") msgid(USERSETTINGS) msgstr("Användarinställning") msgid(FRIEND_SETTINGS) msgstr("Väninställningar") msgid(NAME) msgstr("Namn") msgid(STATUSMESSAGE) msgstr("Statusmeddelande") msgid(PREVIEW) msgstr("Förhandsvisning") msgid(AUDIOINPUTDEVICE) msgstr("Ljudingång") msgid(AUDIOFILTERING) msgstr("Ljudfiltrering") msgid(AUDIOOUTPUTDEVICE) msgstr("Ljudutgång") msgid(VIDEOINPUTDEVICE) msgstr("Bildingång") msgid(PUSH_TO_TALK) msgstr("LCtrl för att tala") msgid(STATUS) msgstr("Status") msgid(STATUS_ONLINE) msgstr("Online") msgid(STATUS_AWAY) msgstr("Borta") msgid(STATUS_BUSY) msgstr("Upptagen") msgid(SETTINGS_UI_MINI_ROSTER) msgstr("Kompakt kontaktlista") msgid(SETTINGS_UI_AUTO_HIDE_SIDEBAR) msgstr("Dölj sidofältet automatiskt") msgid(NOT_CONNECTED) msgstr("Ej ansluten") msgid(NOT_CONNECTED_SETTINGS) msgstr("Modifiera nätverksinställningarna") msgid(OTHERSETTINGS) msgstr("Andra inställningar") msgid(UI) msgstr("UI") msgid(USER_INTERFACE) msgstr("Gränssnitt") msgid(UTOX_SETTINGS) msgstr("Inställningar för uTox") msgid(NETWORK_SETTINGS) msgstr("Nätverksinställningar") msgid(PROFILE_PASSWORD) msgstr("Profillösenord") msgid(LOCK_UTOX) msgstr("Kopplar ifrån Tox och låser profilen.") msgid(SHOW_UI_PASSWORD) msgstr("Visa lösenordsfältet") msgid(SHOW_UI_PASSWORD_TOOLTIP) msgstr("Klicka för att visa lösenordsfältet. Ändringar som görs här tar effekt direkt!") msgid(HIDE_UI_PASSWORD) msgstr("Dölj lösenordsfältet") msgid(HIDE_UI_PASSWORD_TOOLTIP) msgstr("Klicka för att dölja lösenordsfältet.") msgid(LOCK) msgstr("Lås") msgid(AUDIO_VIDEO) msgstr("Ljud/Video") msgid(DPI) msgstr("DPI") msgid(SAVELOCATION) msgstr("Sparplats") msgid(LANGUAGE) msgstr("Språk") msgid(NETWORK) msgstr("Nätverk") msgid(IPV6) msgstr("IPv6:") msgid(UDP) msgstr("UDP:") msgid(PROXY) msgstr("Proxy (SOCKS 5)") msgid(PROXY_FORCE) msgstr("Tvinga uTox att alltid använda proxyn") msgid(WARNING) msgstr("Om du ändrar Network/Proxy så kommer du att tillfälligt tappa din anslutning till Toxnätverket") msgid(SAVE_CHAT_HISTORY) msgstr("Spara chatthistorik") msgid(AUDIONOTIFICATIONS) msgstr("Aktivera ljudnotifikationer (ringsignal)") msgid(RINGTONE) msgstr("Rington") msgid(IS_TYPING) msgstr("skriver...") msgid(CLOSE_TO_TRAY) msgstr("Stäng till aktivitetsfältet") msgid(START_IN_TRAY) msgstr("Starta i aktivitetsfältet") msgid(COPY) msgstr("Kopiera") msgid(COPYWITHOUTNAMES) msgstr("Kopiera (utan namn)") msgid(COPY_WITH_NAMES) msgstr("Kopiera (inklusive namn)") msgid(CUT) msgstr("Klipp ut") msgid(PASTE) msgstr("Klistra in") msgid(DELETE) msgstr("Ta bort") msgid(SELECTALL) msgstr("Välj alla") msgid(REMOVE) msgstr("Ta bort") msgid(REMOVE_FRIEND) msgstr("Ta bort vän") msgid(LEAVE) msgstr("Lämna") msgid(CTOPIC) msgstr("Ändra tema") msgid(ACCEPT) msgstr("Tillåt") msgid(IGNORE) msgstr("Ignorera") msgid(SET_ALIAS) msgstr("Sätt alias") msgid(ALIAS) msgstr("Alias") msgid(SENDMESSAGE) msgstr("Skicka meddelande") msgid(SENDSCREENSHOT) msgstr("Skicka skärmdump") msgid(CLICKTOSAVE) msgstr("Klicka för att spara") msgid(CLICKTOOPEN) msgstr("Klicka för att öppna") msgid(CANCELLED) msgstr("Avbruten") msgid(DPI_060) msgstr("Anpassad DPI 60%") msgid(DPI_070) msgstr("Anpassad DPI 70%") msgid(DPI_080) msgstr("Anpassad DPI 80%") msgid(DPI_090) msgstr("Anpassad DPI 90%") msgid(DPI_100) msgstr("Anpassad DPI 100%") msgid(DPI_110) msgstr("Anpassad DPI 110%") msgid(DPI_120) msgstr("Anpassad DPI 120%") msgid(DPI_130) msgstr("Anpassad DPI 130%") msgid(DPI_140) msgstr("Anpassad DPI 140%") msgid(DPI_150) msgstr("Anpassad DPI 150%") msgid(DPI_160) msgstr("Anpassad DPI 160%") msgid(DPI_170) msgstr("Anpassad DPI 170%") msgid(DPI_180) msgstr("Anpassad DPI 180%") msgid(DPI_190) msgstr("Anpassad DPI 190%") msgid(DPI_200) msgstr("Anpassad DPI 200%") msgid(DPI_210) msgstr("Anpassad DPI 210%") msgid(DPI_220) msgstr("Anpassad DPI 220%") msgid(DPI_230) msgstr("Anpassad DPI 230%") msgid(DPI_240) msgstr("Anpassad DPI 240%") msgid(DPI_250) msgstr("Anpassad DPI 250%") msgid(DPI_260) msgstr("Anpassad DPI 260%") msgid(DPI_270) msgstr("Anpassad DPI 270%") msgid(DPI_280) msgstr("Anpassad DPI 280%") msgid(DPI_290) msgstr("Anpassad DPI 290%") msgid(DPI_300) msgstr("Anpassad DPI 300%") msgid(DPI_TINY) msgstr("Liten (50%)") msgid(DPI_NORMAL) msgstr("Normal (100%)") msgid(DPI_BIG) msgstr("Stor (150%)") msgid(DPI_LARGE) msgstr("Större (200%)") msgid(DPI_HUGE) msgstr("Enorm (250%)") msgid(PROXY_DISABLED) msgstr("Inaktiverad") msgid(PROXY_FALLBACK) msgstr("Fallback") msgid(PROXY_ALWAYS_USE) msgstr("Använd alltid") msgid(NO) msgstr("Nej") msgid(YES) msgstr("Ja") msgid(OFF) msgstr("Av") msgid(ON) msgstr("På") msgid(SHOW) msgstr("Visa") msgid(HIDE) msgstr("Dölj") msgid(VIDEO_IN_NONE) msgstr("Inget") msgid(VIDEO_IN_DESKTOP) msgstr("Skrivbord") msgid(AUDIO_IN_DEFAULT_LOOPBACK) msgstr("Standard loopback") // msgid(AUDIO_IN_ANDROID) Not needed // msgstr("OpenSL Input") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("Var god och acceptera min vänskapsbegäran.") msgid(CONTACT_SEARCH_ADD_HINT) msgstr("Sök/Lägg till vänner") msgid(PROXY_EDIT_HINT_IP) msgstr("IP") msgid(PROXY_EDIT_HINT_PORT) msgstr("Port") msgid(WINDOW_TITLE_VIDEO_PREVIEW) msgstr("Videoförhandsgranskning") msgid(MUTE) msgstr("Tysta") msgid(UNMUTE) msgstr("Avtysta") msgid(SELECT_AVATAR_TITLE) msgstr("Välj Avatar") msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS) msgstr("Avatar för stor. Maxstorlek: ") msgid(CANT_FIND_FILE_OR_EMPTY) msgstr("Kan ej hitta den markerade filen eller så är den tom.") msgid(CLEAR_HISTORY) msgstr("Rensa historik") msgid(AUTO_STARTUP) msgstr("Starta sammtidigt som datorn") msgid(THEME) msgstr("Tema") msgid(THEME_DEFAULT) msgstr("Standard") msgid(THEME_LIGHT) msgstr("Ljust tema") msgid(THEME_DARK) msgstr("Mörkt tema") msgid(THEME_HIGHCONTRAST) msgstr("Högkontrast") msgid(THEME_CUSTOM) msgstr("Anpassat (se dokumentation)") // msgid(THEME_ZENBURN) Not needed // msgstr("Zenburn") // msgid(THEME_SOLARIZED_LIGHT) Not needed // msgstr("Solarized-light") // msgid(THEME_SOLARIZED_DARK) Not needed // msgstr("Solarized-dark") msgid(SEND_TYPING_NOTIFICATIONS) msgstr("Skicka skrivnotifieringar") msgid(STATUS_NOTIFICATIONS) msgstr("Statusnotifieringar") msgid(RANDOMIZE_NOSPAM) msgstr("Slumpmässig Nospam") // msgid(NOSPAM) Not needed // msgstr("Nospam") msgid(REVERT_NOSPAM) msgstr("Återställ Nospam") msgid(NOSPAM_WARNING) msgstr("Ändrar du ditt nospam slutar ditt gamla Tox-ID att fungera. uTox uppdaterar inte ditt ID på namnservrar.") msgid(BLOCK_FRIEND_REQUESTS) msgstr("Blockera inkommande vänskapsbegäran") msgid(SHOW_NOSPAM) msgstr("Visa Nospam-inställningar") msgid(HIDE_NOSPAM) msgstr("Dölj Nospam-inställningar") msgid(DELETE_FRIEND) msgstr("Ta bort vän") msgid(DELETE_MESSAGE) msgstr("Är du säker på att du vill ta bort ") msgid(KEEP) msgstr("Behåll") uTox-0.17.1/langs/tr.h000066400000000000000000000114571354126257400144620ustar00rootroot00000000000000msgid(LANG_NATIVE_NAME) msgstr("Türk") msgid(LANG_ENGLISH_NAME) msgstr("TURKISH") msgid(REQ_SENT) msgstr("Arkadaşlık talebi gönderildi. Talebiniz karşı taraf tarafından kabul edildiğinde, arkadaşınız çevirimiçi olarak gözükecek.") msgid(REQ_INVALID_ID) msgstr("Hata: Geçersiz Tox ID") msgid(REQ_EMPTY_ID) msgstr("Hata: Bir Tox ID giriniz") msgid(REQ_LONG_MSG) msgstr("Hata: Mesaj çok uzun.") msgid(REQ_NO_MSG) msgstr("Hata: Bir mesaj giriniz.") msgid(REQ_SELF_ID) msgstr("Hata: Tox ID sizin kendi IDniz. Lütfen başka ID giriniz.") msgid(REQ_ALREADY_FRIENDS) msgstr("Hata: Tox ID zaten listenizde bulunuyor.") msgid(REQ_UNKNOWN) msgstr("Hata: Bilinmeyen hata.") msgid(REQ_BAD_CHECKSUM) msgstr("Hata: Geçersiz Tox ID (geçersiz sağlama toplamı)") msgid(REQ_BAD_NOSPAM) msgstr("Hata: Geçersiz Tox ID (geçersiz nospam değeri)") msgid(REQ_NO_MEMORY) msgstr("Hata: Yetersiz hafıza.") msgid(TRANSFER_NEW) msgstr("Yeni dosya transferi") msgid(TRANSFER_STARTED) msgstr("Dosya transferi başlatıldı") //TODO: Same as in English? Localize or remove. //msgid(TRANSFER___) //msgstr("...") msgid(TRANSFER_PAUSED) msgstr("Dosya transferi durduruldu") msgid(TRANSFER_BROKEN) msgstr("Dosya transferi hatası") msgid(TRANSFER_CANCELLED) msgstr("Dosya transferi iptal edildi") msgid(TRANSFER_COMPLETE) msgstr("Dosya transferi tamamlandı") msgid(CALL_CANCELLED) msgstr("Arama iptal edildi") msgid(CALL_INVITED) msgstr("Arama gönderildi") msgid(CALL_RINGING) msgstr("Aranıyor...") msgid(CALL_STARTED) msgstr("Arama başlatıldı") msgid(ADDFRIENDS) msgstr("Arkadaş Ekle") //TODO: Same as in English? Localize or remove. //msgid(TOXID) //msgstr("Tox ID") msgid(MESSAGE) msgstr("Mesaj Gönder") msgid(ADD) msgstr("Ekle") msgid(FRIENDREQUEST) msgstr("Arkadaşlık Talebi") msgid(USERSETTINGS) msgstr("Kullanıcı Ayarları") msgid(NAME) msgstr("İsim") msgid(STATUSMESSAGE) msgstr("Durum Mesajı") msgid(PREVIEW) msgstr("Önizleme") msgid(AUDIOINPUTDEVICE) msgstr("Ses Girişi Aygıtı") msgid(AUDIOOUTPUTDEVICE) msgstr("Ses Çıkışı Aygıtı") msgid(VIDEOINPUTDEVICE) msgstr("Görüntü Girişi Aygıtı") msgid(OTHERSETTINGS) msgstr("Diğer Ayarlar") //TODO: Same as in English? Localize or remove. //msgid(DPI) //msgstr("DPI") msgid(SAVELOCATION) msgstr("Konum Kaydet") msgid(LANGUAGE) msgstr("Dil") msgid(NETWORK) msgstr("Ağ") //TODO: Same as in English? Localize or remove. //msgid(IPV6) //msgstr("IPv6:") //TODO: Same as in English? Localize or remove. //msgid(UDP) //msgstr("UDP:") //TODO: Same as in English? Localize or remove. //msgid(PROXY) //msgstr("Proxy (SOCKS 5)") msgid(WARNING) msgstr("Ağ veya Proxy ayarlarını değiştirmek sizi Tox ağından koparır.") msgid(SAVE_CHAT_HISTORY) msgstr("Loglama") //TODO: Same as in English? Localize or remove. //msgid(IS_TYPING) //msgstr("is typing...") msgid(COPY) msgstr("Kopyala") msgid(COPYWITHOUTNAMES) msgstr("Kopyala (isimleri kopyalama)") msgid(CUT) msgstr("Kes") msgid(PASTE) msgstr("Yapıştır") msgid(DELETE) msgstr("Sil") msgid(SELECTALL) msgstr("Hepsini Seç") msgid(REMOVE) msgstr("Kaldır") msgid(LEAVE) msgstr("Ayrıl") msgid(ACCEPT) msgstr("Onayla") msgid(IGNORE) msgstr("Yoksay") msgid(CLICKTOSAVE) msgstr("Kaydetmek için tıklayın") msgid(CLICKTOOPEN) msgstr("Açmak için tıklayın") msgid(CANCELLED) msgstr("İptal Edildi") //TODO: Localize or remove. //msgid(DPI_TINY) //msgstr("Tiny (50%)") //TODO: Localize or remove. //msgid(DPI_NORMAL) //msgstr("Normal (100%)") //TODO: Localize or remove. //msgid(DPI_BIG) //msgstr("Big (150%)") //TODO: Localize or remove. //msgid(DPI_LARGE) //msgstr("Large (200%)") //TODO: Localize or remove. //msgid(DPI_HUGE) //msgstr("Huge (250%)") //TODO: Localize or remove. //msgid(FILTER_ALL) //msgstr("All") //TODO: Localize or remove. //msgid(FILTER_ONLINE) //msgstr("Online") //TODO: Localize or remove. //msgid(PROXY_DISABLED) //msgstr("Disabled") //TODO: Localize or remove. //msgid(PROXY_FALLBACK) //msgstr("Fallback") //TODO: Localize or remove. //msgid(PROXY_ALWAYS_USE) //msgstr("Always use") //TODO: Localize or remove. //msgid(NO) //msgstr("No") //TODO: Localize or remove. //msgid(YES) //msgstr("Yes") //TODO: Localize or remove. //msgid(VIDEO_IN_NONE) //msgstr("None") //TODO: Localize or remove. //msgid(VIDEO_IN_DESKTOP) //msgstr("Desktop") //TODO: Localize or remove. //msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) //msgstr("Please accept this friend request.") //TODO: Localize or remove. //msgid(PROXY_EDIT_HINT_IP) //msgstr("IP") //TODO: Localize or remove. //msgid(PROXY_EDIT_HINT_PORT) //msgstr("Port") //TODO: Localize or remove. //msgid(AUDIO_IN_DEFAULT_LOOPBACK) //msgstr("Default Loopback") //TODO: Localize or remove. //msgid(WINDOW_TITLE_VIDEO_PREVIEW) //msgstr("Video Preview") //TODO: Localize or remove. //msgid(AUDIONOTIFICATIONS) //msgstr("Enable Audible Notification (Ringtone)") uTox-0.17.1/langs/tw.h000066400000000000000000000175251354126257400144710ustar00rootroot00000000000000msgid(LANG_NATIVE_NAME) msgstr("繁體中文") msgid(LANG_ENGLISH_NAME) msgstr("TRADITIONAL CHINESE") msgid(REQ_SENT) msgstr("好友請求已發送。對方接受之後將顯示為在線狀態。") msgid(REQ_INVALID_ID) msgstr("錯誤:無效的 Tox ID") msgid(REQ_EMPTY_ID) msgstr("錯誤:未指定 Tox ID") msgid(REQ_LONG_MSG) msgstr("錯誤:消息過長") msgid(REQ_NO_MSG) msgstr("錯誤:空消息") msgid(REQ_SELF_ID) msgstr("錯誤:Tox ID 是你自己的賬號") msgid(REQ_ALREADY_FRIENDS) msgstr("錯誤:該 Tox ID 已存在於好友列表中") msgid(REQ_UNKNOWN) msgstr("錯誤:未知") msgid(REQ_BAD_CHECKSUM) msgstr("錯誤:無效的 Tox ID(錯誤的校檢碼)") msgid(REQ_BAD_NOSPAM) msgstr("錯誤:無效的 Tox ID(錯誤的防騷擾碼)") msgid(REQ_NO_MEMORY) msgstr("錯誤:內存不足") msgid(SEND_FILE) msgstr("傳送文件") msgid(SAVE_FILE) msgstr("保存文件") msgid(WHERE_TO_SAVE_FILE_PROMPT) msgstr("你要將 \"%.*s\"保存在哪裡?") msgid(WHERE_TO_SAVE_FILE) msgstr("你要將文件保存在哪裡?") msgid(SEND_FILE_PROMPT) msgstr("選擇一個或多個文件以傳送。") msgid(SCREEN_CAPTURE_PROMPT) msgstr("在屏幕上的目標區域截屏。") msgid(TRANSFER_NEW) msgstr("新建文件傳送任務") msgid(TRANSFER_STARTED) msgstr("文件傳送開始") msgid(TRANSFER___) msgstr("……") msgid(TRANSFER_PAUSED) msgstr("文件傳送暫停") msgid(TRANSFER_BROKEN) msgstr("文件傳送中斷") msgid(TRANSFER_CANCELLED) msgstr("文件傳送取消") msgid(TRANSFER_COMPLETE) msgstr("文件傳送完成") msgid(GROUPCHAT_JOIN_AUDIO) msgstr("參加語音聊天") msgid(CALL_START_AUDIO) msgstr("語音呼叫") msgid(CALL_START_VIDEO) msgstr("視頻呼叫") msgid(CALL_CANCELLED) msgstr("呼叫取消") msgid(CALL_INVITED) msgstr("呼叫請求") msgid(CALL_RINGING) msgstr("呼叫響鈴") msgid(CALL_STARTED) msgstr("呼叫開始") msgid(PROFILE_SETTINGS) msgstr("用戶設置") msgid(PROFILE_PW_WARNING) msgstr("注意:µTox 啟動後將必須提供該密碼。") msgid(PROFILE_PW_NO_RECOVER) msgstr("忘記密碼將無法找回。") msgid(ADDFRIENDS) msgstr("添加好友") //msgid(TOXID) //msgstr("Tox ID") msgid(MESSAGE) msgstr("消息") msgid(FILTER_ONLINE) msgstr("在線好友") msgid(FILTER_ALL) msgstr("全部好友") msgid(FILTER_CONTACT_TOGGLE) msgstr("切換是否過濾離線好友") msgid(ADD) msgstr("添加") msgid(CREATEGROUPCHAT) msgstr("創建一個群聊") msgid(FRIENDREQUEST) msgstr("好友請求") msgid(USERSETTINGS) msgstr("用戶設置") msgid(FRIEND_SETTINGS) msgstr("好友設置") msgid(NAME) msgstr("名字") msgid(STATUSMESSAGE) msgstr("簽名") msgid(PREVIEW) msgstr("預覽") msgid(AUDIOINPUTDEVICE) msgstr("音頻輸入設備") msgid(AUDIOFILTERING) msgstr("音頻過濾") msgid(AUDIOOUTPUTDEVICE) msgstr("音頻輸出設備") msgid(VIDEOINPUTDEVICE) msgstr("視頻輸入設備") msgid(PUSH_TO_TALK) msgstr("一鍵對講模式") msgid(STATUS) msgstr("狀態") msgid(STATUS_ONLINE) msgstr("在線") msgid(STATUS_AWAY) msgstr("離開") msgid(STATUS_BUSY) msgstr("忙碌") msgid(NOT_CONNECTED) msgstr("未連線") msgid(OTHERSETTINGS) msgstr("其他設置") msgid(UI) msgstr("用戶界面") msgid(USER_INTERFACE) msgstr("界面") msgid(UTOX_SETTINGS) msgstr("uTox設置") msgid(NETWORK_SETTINGS) msgstr("網絡設置") msgid(PROFILE_PASSWORD) msgstr("用戶密碼") msgid(LOCK_UTOX) msgstr("斷開 Tox 並鎖定用戶。") msgid(SHOW_UI_PASSWORD) msgstr("點擊顯示密碼配置欄。此處所作的更改將即刻生效!") msgid(LOCK) msgstr("鎖定") msgid(AUDIO_VIDEO) msgstr("音/視頻") msgid(DPI) msgstr("分辨率縮放") msgid(SAVELOCATION) msgstr("保存位置") msgid(LANGUAGE) msgstr("語言") msgid(NETWORK) msgstr("網絡") //msgid(IPV6) //msgstr("IPv6:") //msgid(UDP) //msgstr("UDP:") msgid(PROXY) msgstr("代理 (SOCKS 5)") msgid(WARNING) msgstr("修改網絡或代理設置將會暫時斷開Tox的網絡連接") msgid(SAVE_CHAT_HISTORY) msgstr("保留記錄") msgid(AUDIONOTIFICATIONS) msgstr("啟用聲音通知 (響鈴)") msgid(RINGTONE) msgstr("聲音") msgid(IS_TYPING) msgstr("正在打字...") msgid(CLOSE_TO_TRAY) msgstr("關閉後運行於托盤區") msgid(START_IN_TRAY) msgstr("最小化啟動於托盤區") msgid(COPY) msgstr("複製") msgid(COPYWITHOUTNAMES) msgstr("複製 (不包含名字)") msgid(COPY_WITH_NAMES) msgstr("複製 (包含名字)") msgid(CUT) msgstr("剪切") msgid(PASTE) msgstr("粘貼") msgid(DELETE) msgstr("刪除") msgid(SELECTALL) msgstr("全選") msgid(REMOVE) msgstr("移除") msgid(REMOVE_FRIEND) msgstr("移除好友") msgid(REMOVE_GROUP) msgstr("移除群組") msgid(LEAVE) msgstr("離開") msgid(LEAVE_GROUP) msgstr("離開群組") msgid(CTOPIC) msgstr("更改主題") msgid(ACCEPT) msgstr("接受") msgid(IGNORE) msgstr("忽略") msgid(SET_ALIAS) msgstr("設置別名") msgid(ALIAS) msgstr("別名") msgid(FRIEND_AUTOACCEPT) msgstr("無須確認直接接收其傳送的文件") msgid(SENDMESSAGE) msgstr("發送消息") msgid(SENDSCREENSHOT) msgstr("發送截屏") msgid(CLICKTOSAVE) msgstr("點擊保存") msgid(CLICKTOOPEN) msgstr("點擊打開") msgid(CANCELLED) msgstr("取消") msgid(DPI_060) msgstr("縮放至 60%") msgid(DPI_070) msgstr("縮放至 70%") msgid(DPI_080) msgstr("縮放至 80%") msgid(DPI_090) msgstr("縮放至 90%") msgid(DPI_100) msgstr("縮放至 100%") msgid(DPI_110) msgstr("縮放至 110%") msgid(DPI_120) msgstr("縮放至 120%") msgid(DPI_130) msgstr("縮放至 130%") msgid(DPI_140) msgstr("縮放至 140%") msgid(DPI_150) msgstr("縮放至 150%") msgid(DPI_160) msgstr("縮放至 160%") msgid(DPI_170) msgstr("縮放至 170%") msgid(DPI_180) msgstr("縮放至 180%") msgid(DPI_190) msgstr("縮放至 190%") msgid(DPI_200) msgstr("縮放至 200%") msgid(DPI_210) msgstr("縮放至 210%") msgid(DPI_220) msgstr("縮放至 220%") msgid(DPI_230) msgstr("縮放至 230%") msgid(DPI_240) msgstr("縮放至 240%") msgid(DPI_250) msgstr("縮放至 250%") msgid(DPI_260) msgstr("縮放至 260%") msgid(DPI_270) msgstr("縮放至 270%") msgid(DPI_280) msgstr("縮放至 280%") msgid(DPI_290) msgstr("縮放至 290%") msgid(DPI_300) msgstr("縮放至 300%") msgid(DPI_TINY) msgstr("小 (50%)") msgid(DPI_NORMAL) msgstr("正常 (100%)") msgid(DPI_BIG) msgstr("大 (150%)") msgid(DPI_LARGE) msgstr("較大 (200%)") msgid(DPI_HUGE) msgstr("極大 (250%)") msgid(PROXY_DISABLED) msgstr("已棄用") msgid(PROXY_FALLBACK) msgstr("逐漸退去") msgid(PROXY_ALWAYS_USE) msgstr("經常使用") msgid(NO) msgstr("否") msgid(YES) msgstr("是") msgid(OFF) msgstr("關") msgid(ON) msgstr("開") msgid(SHOW) msgstr("顯示") msgid(HIDE) msgstr("隱藏") msgid(VIDEO_IN_NONE) msgstr("無") msgid(VIDEO_IN_DESKTOP) msgstr("桌面") msgid(AUDIO_IN_DEFAULT_LOOPBACK) msgstr("默認環繞") msgid(AUDIO_IN_ANDROID) msgstr("OpenSL輸入") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("請接受這條好友請求。") msgid(CONTACT_SEARCH_ADD_HINT) msgstr("搜索/添加好友") //msgid(PROXY_EDIT_HINT_IP) //msgstr("IP") msgid(PROXY_EDIT_HINT_PORT) msgstr("端口") msgid(WINDOW_TITLE_VIDEO_PREVIEW) msgstr("視頻預覽") msgid(MUTE) msgstr("開啟靜音") msgid(UNMUTE) msgstr("取消靜音") msgid(SELECT_AVATAR_TITLE) msgstr("選擇頭像") msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS) msgstr("頭像過大。最大允許尺寸為: ") msgid(CANT_FIND_FILE_OR_EMPTY) msgstr("無法找到所選文件或所選文件為空。") msgid(CLEAR_HISTORY) msgstr("清空歷史") msgid(AUTO_STARTUP) msgstr("開機時自動啟動") msgid(THEME) msgstr("界面風格") msgid(THEME_DEFAULT) msgstr("默認") msgid(THEME_LIGHT) msgstr("輕淡風格") msgid(THEME_DARK) msgstr("深暗風格") msgid(THEME_HIGHCONTRAST) msgstr("高對比度") msgid(THEME_CUSTOM) msgstr("自定義 (參見文檔)") msgid(THEME_ZENBURN) msgstr("低調風") msgid(SEND_TYPING_NOTIFICATIONS) msgstr("發送正在打字的提醒") uTox-0.17.1/langs/uk.h000066400000000000000000000752401354126257400144540ustar00rootroot00000000000000/****************************************************************************** *** Ukrainian i18l Strings *** ******************************************************************************/ msgid(LANG_NATIVE_NAME) msgstr("Українська") msgid(LANG_ENGLISH_NAME) msgstr("UKRAINIAN") /****************************************************************************** *** Splash Message & Change Log *** ******************************************************************************/ msgid(SPLASH_TITLE) msgstr("Вас вітає новий uTox!") msgid(SPLASH_TEXT) msgstr("Ви щойно оновилися до версії 0.17.0! Ім'я випуску: bork bork") msgid(CHANGE_LOG_TITLE) msgstr("Зміни у v0.17.0") msgid(CHANGE_LOG_TEXT) msgstr( "\n ВАЖЛИВА ІНФОРМАЦІЯ ДЛЯ КОРИСТУВАЧІВ WINDOWS \n" " Наразі в оновлювача існує проблема з деякими іменами exe-файлів.\n" " Для того, щоб він надійно працював, переіменуйте exe-файл на \"uTox.exe\"\n" " та увімкніть його в налаштуваннях.\n" "\n" " Функції:\n" " Підтримка Toxcore 0.2.x!\n" " Збереження налаштувань у зрозумілому .ini-файлі.\n" " Підтримка Tox URI.\n" " Випадаючі опції залишаються відкритими після натискання.\n" " Можливість згенерувати QR-код вашого ToxID.\n" " Підтримка естонської мови.\n" " Виправлення:\n" " Кольорова схема Zenburn тепер працює.\n" " Дзвінки додаються до історії чату.\n" " Зберігання вбудованих малюнків працює для не-ASCII імен.\n" " GTK має працювати на різних платформах.\n" " Експорт історії чату на MacOS не призводить до збоїв.\n" " Підтримка передавання файлів на MacOS.n" " Налаштування проксі тепер зберігаються.\n" " Значок системного лотка, здається, має здебільшого працювати на (майже) всіх Linux-системах.\n" " Численні виправлення інтерфейсу.\n" " Підтримка сигналів на Linux-системах.\n" " Фільтрування аудіо знову можна увімкнути.\n" " Значок системного лотка Windows оновлюється у випадку збоїв Explorer'а.\n" " Неправильні значення FPS більше не виникають при завантаженні старих налаштувань.\n" " Формат дати тепер зберігається.\n" " Краща підтримка не-ASCII символів.\n" " Підказки тепер залишаютсья в межах вікна.\n" " Розробка:\n" " Тепер можливо вказати розташування бібліотеки у CMAKE_PREFIX_PATH.\n" "\nv0.16.0\n" " Функції:\n" " Мова тепер зберігається.\n" " Додано групові аудіорозмови.\n" " Можливість зміни частоти кадрів під час дзвінка.\n" " Виправлення:\n" " Більш стабільна робота в OSX.\n" " Відео знову працює у Linux.\n" " Виправлення інтерфейсу. (подяки redmanmale!)\n" " Виправлено заголовок вікна попереднього перегляду у Windows. (подяки thorpelawrence!)\n" " Виправлено деякі збої під час групової бесіди.\n" " Кнопки миші в X11 тепер працюють правильно. (подяки dkmoz!)\n" " У Windows тепер працюють веб-адреси в юнікоді.\n" " Очищення імен файлів у Windows.\n" " Налаштування автоприймання файлів тепер зберігаються.\n" " Звукові сповіщення тепер звучать тільки коли вікно uTox неактивне.\n" " Повідомлення позначаються як прочитані, якщо вони отримані у відкрите вікно чату.\n" " Діалог обрання файлів GTK тепер працює в OpenBSD та NetBSD.\n" " Виправлено перемикач автозапуску.\n" " Виправлено сповіщення про набирання повідомлення.\n" " При експорті історії чату вказано час повідомлень.\n" " Розробка:\n" " Припинено підтримку ToxDNS.\n" " Додано інструкції збирання для OSX. (подяки @publicarray!)\n" " В OSX тепер також виконуються тести.\n" " Додано сценарій на Python, що шукає відсутні переклади.\n" " Зменшено розмір збірки MinSizeRel.\n" " Оновлено численні переклади.\n" "\nv0.15.0\n" " Функції:\n" " Оновлений інтерфейс. (Подяки redmanmale!)\n" " Висувна бічна панель на Android.\n" " Виправлення:\n" " Відео знову працює у Windows.\n" " Автоприймання файлів у переносній версії тепер зберігає файли у переносну папку.\n" " Оновлено український переклад. (Подяки v2e!)\n" " Сповіщення через Dbus тепер мають працювати на різних системах.\n" " Розробка\n" " Додано підтримку NetBSD, OpenBSD та FreeBSD.\n" " Перебудовано інтерфейс.\n" "\nv0.14.0\n" " Функції:\n" " Справжній оновлювач.\n" " -- uTox тепер має вбудований оновлювач. Наразі тільки для Windows.\n" " -- Але його можна адаптувати до будь-якої платформи, якщо є бажання.\n" " Додано підтримку musl libc.\n" " uTox тепер зібрано з сильнішим захистом від експлойтів.\n" " Значно зменшено використання пам'яті для списку друзів.\n" " Виправлення:\n" " Нові антиспам-коди більше не починаються з 0000.\n" " Виправлено вирівнювання кнопок з обранням мови.\n" " tox_save більше не обрізається під час виходу.\n" " Значок у системному лотку тепер завжди має квадратне тло\n" " -- Навіть у несправних екранних менеджерах (uTox дивиться на Gnome...)\n" " Оновлено список початкових вузлів.\n" " Аватари тепер можна видаляти.\n" " Сповіщення більше не ігноруються, коли uTox згорнуто.\n" " Декілька виправлень передачі файлів.\n" " -- Особливо останнє, яке чомусь уникало оновлень.\n" " Розробка\n" " Усі попередження виправлено, додано -Werror\n" " Додано тести:\n" " Оновлювач uTox\n" " Читання та запис історії чату\n" " Ще трохи перероблено інтерфейс. Що заразом усунуло деякі недоліки інтерфейсу.\n" "\nv0.13.0\n" " Функції:\n" " Відтепер можна вставляти текст у кодуванні UTF-8 в uTox.\n" " Відтепер можна вручну обрати антиспам-код!\n" "\n Виправлення:\n" " Здебільшого виправлено груповий чат. (Принаймні він тепер не руйнує uTox раптово...)\n" " Знову можна зберігати історію чату у Windows.\n" " Очищення історії більше не руйнує uTox.\n" " Заткнено багато дірок, крізь які витікала пам'ять.\n" " Прокрутка клавішами PgUp/PgDn тепер оновлює усе вікно чату.\n" " Аватари знову завантажуються.\n" " Власні теми тепер працюють і не руйнують uTox, якщо перемкнутися на тему, яка не існує\n" " Численні покращення системи збирання.\n" " Багато виправлень передачі файлів.\n" "\n Розробка\n" " uTox тепер має модульне тестування! (Сподіваємося, в нас більше ніколи не буде багів.)\n" " Файли інтерфейсу розділено на ui та layout.\n" " В нас тепер є власний сервер компіляції!\n" "\nv0.12.2\n" " Виправлено підвисання інтерфейсу під час передачі файлів.\n" " Виправлено падіння під час передачі файлів на Windows.\n" "\nv0.11.1\n" " Виправлено падіння під час деяких передач.\n" " Виправлення багів\n" " Виправлено збирання на Windows XP\n" " Покращено запит на додання до друзів\n" " Додано можливість змінювати антиспам-код\n" " Додано вкладки налаштувань \"Сповіщення\" та \"Додатково\"\n" " Новий оновлювач\n" " Розпочато відокремлення ядра від інтерфейсу.\n" "\nv0.11.1\n" " Функція: Експорт історії чату\n" " Функція: Додано можливість відхиляти дзвінки\n" " Різні виправлення безпеки\n" " Виправлено проблему зі значком\n" " Краща система збирання\n" " Перехід до TokTok/c-toxcore\n" " Покращено процес розробки для спрощення додавання коду\n" " Нові теми: Solarized світла та Solarized темна\n" " Оновлено переклади\n" " оптимізація filter_audio\n" " Розпочато використання clang-format\n" " Припинено використання clang-format\n" " Нові, гарніші кнопки (подяка tsudoko!)\n" " Краща підтримка автоматичного прийняття передач файлів\n" " Виправлено проблеми інтерфейсу через заблокований екран\n" "\nv0.11.0\n" " Перепрошуємо, але історія змін для цієї версії uTox\n" " доступна лише для власників Золотої Картки uTox.\n" "\nv0.9.8\n" " Виправлено падіння під час створення нового профілю\n" "\nv0.9.7\n" " Невеличкі виправлення інтерфейсу\n" " Замінено усі випадні списки \"Так/Ні\" на перемикачі\n" " Виправлено збереження проксі та порту після перезапуску.\n" "\nv0.9.5\n" " Вбудоване відео на OSX\n" " Виправлено помилку журналювання\n" "\nv0.9.3\n" " Виправлено помилку в повідомленні, яка подекуди руйнувала uTox на Windows\n" " Обмежено кількість повідомлень для одночасного надсилання\n" "\nv0.9.2\n" " Чищення вихідних текстів/зміни дерева каталогів\n" "\nv0.9.1\n" " Виправлено падіння під час надсилання повідомлення новому другові\n" "\nv0.9.0\n" " Черга повідомлень\n" " Кращий, кольоровий груповий чат\n" " Експериментальна підтримка вбудованого відео\n" " Компактний список друзів\n" " Перебудова обробки повідомлень\n" "\n") /****************************************************************************** *** MISC & UNSORTED *** ******************************************************************************/ msgid(REQ_SENT) msgstr("Запит на додавання в друзі відправлений. Ваш друг з'явиться в мережі, як тільки підтвердить запит.") msgid(REQ_INVALID_ID) msgstr("Помилка: Невірний Tox ID") msgid(REQ_ADDED_NO_FREQ_SENT) msgstr("Увага: Друга додано, але запит не надіслано (відсутній антиспам)") msgid(REQ_EMPTY_ID) msgstr("Помилка: Не вказано Tox ID") msgid(REQ_LONG_MSG) msgstr("Помилка: Повідомлення занадто довге") msgid(REQ_NO_MSG) msgstr("Помилка: Порожнє повідомлення") msgid(REQ_SELF_ID) msgstr("Помилка: Tox ID є власним ID") msgid(REQ_ALREADY_FRIENDS) msgstr("Помилка: Tox ID вже є у списку друзів") msgid(REQ_UNKNOWN) msgstr("Помилка: Невідома") msgid(REQ_BAD_CHECKSUM) msgstr("Помилка: Невірний Tox ID (контрольна сума не збігається)") msgid(REQ_BAD_NOSPAM) msgstr("Помилка: Невірний Tox ID (невірний антиспам-код)") msgid(REQ_NO_MEMORY) msgstr("Помилка: Недостатньо пам'яті") msgid(SEND_FILE) msgstr("Надіслати файл") msgid(SAVE_FILE) msgstr("Збереження файлу") msgid(WHERE_TO_SAVE_FILE_PROMPT) msgstr("Оберіть місце для збереження\"%.*s\"") msgid(WHERE_TO_SAVE_FILE) msgstr("Куди ви хочете зберегти файл?") msgid(SEND_FILE_PROMPT) msgstr("Оберіть файл(и) для надсилання.") msgid(SCREEN_CAPTURE_PROMPT) msgstr("Позначте область екрана для надсилання.") /****************************************************************************** *** File Transfer Strings *** ******************************************************************************/ msgid(TRANSFER_NEW) msgstr("Передача файлу") msgid(TRANSFER_STARTED) msgstr("Розпочато передачу файлу") msgid(TRANSFER___) msgstr("...") msgid(TRANSFER_PAUSED) msgstr("Призупинено передачу файлу") msgid(TRANSFER_BROKEN) msgstr("Перервано передачу файлу") msgid(TRANSFER_CANCELLED) msgstr("Скасовано передачу файлу") msgid(TRANSFER_COMPLETE) msgstr("Завершено передачу файлу") /****************************************************************************** *** Keyboard and Mouse Cursor Strings *** ******************************************************************************/ msgid(CURSOR_CLICK_LEFT) msgstr("Ліва кнопка") msgid(CURSOR_CLICK_RIGHT) msgstr("Права кнопка") /****************************************************************************** *** Audio / Video Call Strings *** ******************************************************************************/ msgid(CALL_START_AUDIO) msgstr("Зателефонувати") msgid(CALL_START_VIDEO) msgstr("Здійснити відеодзвінок") msgid(CALL_DECLINE) msgstr("Відхилити дзвінок") msgid(CALL_CANCELLED) msgstr("Дзвінок відхилено") msgid(CALL_INVITED) msgstr("Вхідний дзвінок") msgid(CALL_RINGING) msgstr("Вихідний дзвінок") msgid(CALL_STARTED) msgstr("Розпочато розмову") msgid(CALL_ENDED) msgstr("Розмову закінчено") msgid(CALL_FRIEND_HAD_ENDED_CALL) msgstr(" закінчив розмову.") msgid(CALL_VIDEO_SHOW_INLINE) msgstr("Вбудувати відео") /****************************************************************************** *** Friend & Friend Settings Strings *** ******************************************************************************/ msgid(FRIEND_ALIAS) msgstr("Псевдонім друга") msgid(FRIEND_PUBLIC_KEY) msgstr("Відкритий ключ друга") msgid(FRIEND_AUTOACCEPT) msgstr("Приймати вхідні файли без підтвердження") msgid(FRIEND_EXPORT_CHATLOG) msgstr("Зберегти історію чату як текст") /****************************************************************************** *** Group Strings *** ******************************************************************************/ msgid(GROUPCHAT_JOIN_AUDIO) msgstr("Приєднатися до аудіо чату") msgid(GROUP_CREATE_TEXT) msgstr("Створити текстовий чат") msgid(GROUP_CREATE_VOICE) msgstr("Створити голосовий чат") msgid(CREATEGROUPCHAT) msgstr("Створити чат") msgid(REMOVE_GROUP) msgstr("Видалити чат") msgid(LEAVE_GROUP) msgstr("Вийти з чату") /****************************************************************************** *** Group Settings *** ******************************************************************************/ msgid(GROUPCHAT_SETTINGS) msgstr("Налаштування чату") msgid(GROUP_NOTIFICATIONS) msgstr("Повідомлення чату") msgid(GROUP_NOTIFICATIONS_ON) msgstr("Усі") msgid(GROUP_NOTIFICATIONS_MENTION) msgstr("Звернення") msgid(GROUP_NOTIFICATIONS_OFF) msgstr("Немає") msgid(GROUP_TOPIC) msgstr("Встановити тему") /****************************************************************************** *** Settings / Profile Strings *** ******************************************************************************/ msgid(PROFILE_BUTTON) msgstr("Профіль") msgid(DEVICES_BUTTON) msgstr("Пристрої") msgid(USER_INTERFACE_BUTTON) msgstr("Інтерфейс") msgid(AUDIO_VIDEO_BUTTON) msgstr("Аудіо/Відео") msgid(ADVANCED_BUTTON) msgstr("Додатково") msgid(NOTIFICATIONS_BUTTON) msgstr("Сповіщення") msgid(AUTO_UPDATE) msgstr("Автоматично оновлювати uTox") msgid(PROFILE_SETTINGS) msgstr("Налаштування профілю") msgid(PROFILE_PW_WARNING) msgstr("ПОПЕРЕДЖЕННЯ: µTox автоматично почне шифрування за допомогою цього пароля.") msgid(PROFILE_PW_NO_RECOVER) msgstr("Відновлення забутих паролів неможливо!") /*** Profile ***/ /*** Devices ***/ msgid(DEVICES_ADD_NEW) msgstr("Додати новий пристрій до мережі") msgid(DEVICES_NUMBER) msgstr("Кількість пов'язаних пристроїв") /*** Network ***/ /*** User Interface ***/ /*** Audio/Video ***/ /****************************************************************************** *** UNSORTED STRINGS *** *** TODO: *** *** FIXME: *** ******************************************************************************/ msgid(ADDFRIENDS) msgstr("Додати друзів") msgid(TOXID) msgstr("Tox ID") msgid(MESSAGE) msgstr("Повідомлення") msgid(FILTER_ONLINE) msgstr("Онлайн") msgid(FILTER_ALL) msgstr("Всі") msgid(FILTER_CONTACT_TOGGLE) msgstr("Перемикання фільтрації оффлайн контактів.") msgid(ADD) msgstr("Додати") msgid(FRIENDREQUEST) msgstr("Запит на додавання до списку друзів") msgid(USERSETTINGS) msgstr("Налаштування") msgid(FRIEND_SETTINGS) msgstr("Налаштування друзів") msgid(NAME) msgstr("Ім'я") msgid(STATUSMESSAGE) msgstr("Статус") msgid(PREVIEW) msgstr("Перевірка") msgid(AUDIOINPUTDEVICE) msgstr("Пристрій захоплення звуку") msgid(AUDIOFILTERING) msgstr("Фільтр аудіо") // Check the correctness msgid(AUDIOOUTPUTDEVICE) msgstr("Пристрій відтворення звуку") msgid(VIDEOINPUTDEVICE) msgstr("Пристрій захоплення відео") msgid(VIDEOFRAMERATE) msgstr("Частота кадрів відео (FPS)") msgid(PUSH_TO_TALK) msgstr("Натисніть щоб говорити") msgid(STATUS) msgstr("Статус") msgid(STATUS_ONLINE) msgstr("Онлайн") msgid(STATUS_AWAY) msgstr("Далеко") msgid(STATUS_BUSY) msgstr("Зайнятий") msgid(STATUS_OFFLINE) msgstr("Поза мережею") /* * Leave %.*s. They are variables * The first one is your friend's name * The second one is the state your friend is now in */ msgid(STATUS_MESSAGE) msgstr("uTox %.*s тепер %s.") msgid(SETTINGS_UI_MINI_ROSTER) msgstr("Компактний список друзів") msgid(SETTINGS_UI_AUTO_HIDE_SIDEBAR) msgstr("Ховати бічну панель") msgid(NOT_CONNECTED) msgstr("Роз'єднано") msgid(NOT_CONNECTED_SETTINGS) msgstr("Налаштування мережі") // чи "Перевірте налаштування мережі"? msgid(OTHERSETTINGS) msgstr("Інші налаштування") msgid(UI) msgstr("Інтерфейс") msgid(USER_INTERFACE) msgstr("Інтерфейс") msgid(UTOX_SETTINGS) msgstr("Налаштування uTox") msgid(NETWORK_SETTINGS) msgstr("Налаштування мережі") msgid(PROFILE_PASSWORD) msgstr("Пароль профілю") msgid(LOCK_UTOX) msgstr("Від'єднатися від мережі Tox і заблокувати даний профіль") msgid(SHOW_UI_PASSWORD) msgstr("Показати поле пароля") msgid(SHOW_UI_PASSWORD_TOOLTIP) msgstr("Натисніть щоб побачити поле для введення пароля. Зміни буде застосовано миттєво!") msgid(HIDE_UI_PASSWORD) msgstr("Сховати поле пароля") msgid(HIDE_UI_PASSWORD_TOOLTIP) msgstr("Клацніть, щоб приховати поле введення пароля від вашого профілю.") msgid(PASSWORD_TOO_SHORT) msgstr("Пароль повинен містити не менше 4 символів") msgid(LOCK) msgstr("Заблокувати") msgid(AUDIO_VIDEO) msgstr("Аудіо/Відео") msgid(DPI) msgstr("Масштаб") msgid(SAVELOCATION) msgstr("Місце збереження") msgid(LANGUAGE) msgstr("Мова") msgid(NETWORK) msgstr("Мережа") msgid(IPV6) msgstr("IPv6:") msgid(UDP) msgstr("UDP:") msgid(PROXY) msgstr("Проксі (SOCKS 5)") msgid(PROXY_FORCE) msgstr("Завжти використовувати проксі") msgid(WARNING) msgstr("Зміна налаштувань мережі або проксі-сервера потребує від'єднання від мережі Tox") msgid(SAVE_CHAT_HISTORY) msgstr("Зберігати історію чату") msgid(AUDIONOTIFICATIONS) msgstr("Ввімкнути звукове сповіщення (рингтон)") msgid(RINGTONE) msgstr("Сигнал") // Мелодія? msgid(IS_TYPING) msgstr("набирає повідомлення...") msgid(CLOSE_TO_TRAY) msgstr("Сховати в лоток") // Check the correctness (трей чи системний лоток) msgid(START_IN_TRAY) msgstr("Запускати в лотку") // Check the correctness (трей чи системний лоток) msgid(SHOW_QR) msgstr("Показати QR") msgid(HIDE_QR) msgstr("Сховати QR") msgid(SAVE_QR) msgstr("Зберегти QR") msgid(COPY_TOX_ID) msgstr("Скопіювати як текст") msgid(COPY) msgstr("Копіювати") msgid(COPYWITHOUTNAMES) msgstr("Копіювати (без імені)") msgid(COPY_WITH_NAMES) msgstr("Копіювати (з іменем)") msgid(CUT) msgstr("Вирізати") msgid(PASTE) msgstr("Вставити") msgid(DELETE) msgstr("Видалити") msgid(SELECTALL) msgstr("Вибрати все") msgid(REMOVE) msgstr("Видалити") msgid(REMOVE_FRIEND) msgstr("Видалити друга") msgid(LEAVE) msgstr("Вийти") msgid(CTOPIC) msgstr("Змінити тему") msgid(ACCEPT) msgstr("Прийняти") msgid(IGNORE) msgstr("Ігнорувати") msgid(SET_ALIAS) msgstr("Встановити псевдонім") msgid(ALIAS) msgstr("Псевдонім") msgid(SENDMESSAGE) msgstr("Надіслати повідомлення") msgid(SENDSCREENSHOT) msgstr("Надіслати знімок екрану") msgid(CLICKTOSAVE) msgstr("Натисніть для збереження") msgid(CLICKTOOPEN) msgstr("Натисніть для відкриття") msgid(CANCELLED) msgstr("Скасовано") msgid(DPI_060) msgstr("Масштаб 60%") msgid(DPI_070) msgstr("Масштаб 70%") msgid(DPI_080) msgstr("Масштаб 80%") msgid(DPI_090) msgstr("Масштаб 90%") msgid(DPI_100) msgstr("Масштаб 100%") msgid(DPI_110) msgstr("Масштаб 110%") msgid(DPI_120) msgstr("Масштаб 120%") msgid(DPI_130) msgstr("Масштаб 130%") msgid(DPI_140) msgstr("Масштаб 140%") msgid(DPI_150) msgstr("Масштаб 150%") msgid(DPI_160) msgstr("Масштаб 160%") msgid(DPI_170) msgstr("Масштаб 170%") msgid(DPI_180) msgstr("Масштаб 180%") msgid(DPI_190) msgstr("Масштаб 190%") msgid(DPI_200) msgstr("Масштаб 200%") msgid(DPI_210) msgstr("Масштаб 210%") msgid(DPI_220) msgstr("Масштаб 220%") msgid(DPI_230) msgstr("Масштаб 230%") msgid(DPI_240) msgstr("Масштаб 240%") msgid(DPI_250) msgstr("Масштаб 250%") msgid(DPI_260) msgstr("Масштаб 260%") msgid(DPI_270) msgstr("Масштаб 270%") msgid(DPI_280) msgstr("Масштаб 280%") msgid(DPI_290) msgstr("Масштаб 290%") msgid(DPI_300) msgstr("Масштаб 300%") msgid(DPI_TINY) msgstr("Дрібний (50%)") msgid(DPI_NORMAL) msgstr("Нормальний (100%)") msgid(DPI_BIG) msgstr("Крупний (150%)") msgid(DPI_LARGE) msgstr("Великий (200%)") msgid(DPI_HUGE) msgstr("Дуже великий (250%)") msgid(PROXY_DISABLED) msgstr("Вимкнено") msgid(PROXY_FALLBACK) msgstr("За потреби") msgid(PROXY_ALWAYS_USE) msgstr("Завжди") msgid(NO) msgstr("Ні") msgid(YES) msgstr("Так") msgid(OFF) msgstr("Ні") // Вимк.? msgid(ON) msgstr("Так") // Увімк.? msgid(SHOW) msgstr("Показати") msgid(HIDE) msgstr("Приховати") msgid(VIDEO_IN_NONE) msgstr("Не вибрано") msgid(VIDEO_IN_DESKTOP) msgstr("Стільниця") msgid(AUDIO_IN_DEFAULT_LOOPBACK) msgstr("Стандартна петля") // Check the correctness msgid(AUDIO_IN_ANDROID) msgstr("Ввід OpenSL") msgid(DEFAULT_FRIEND_REQUEST_MESSAGE) msgstr("Будь ласка, додайте мене в свій список друзів.") msgid(CONTACT_SEARCH_ADD_HINT) msgstr("Пошук/Додавання Друзів") msgid(PROXY_EDIT_HINT_IP) msgstr("IP") msgid(PROXY_EDIT_HINT_PORT) msgstr("Порт") msgid(WINDOW_TITLE_VIDEO_PREVIEW) msgstr("Попередній перегляд відео") msgid(MUTE) msgstr("Заглушити") msgid(UNMUTE) msgstr("Відновити") msgid(SELECT_AVATAR_TITLE) msgstr("Оберіть аватар") msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS) msgstr("Аватар занадто великий. Максимальний розмір: ") msgid(CANT_FIND_FILE_OR_EMPTY) msgstr("Вказаний файл не існує або порожній.") msgid(CLEAR_HISTORY) msgstr("Очистити історію") msgid(AUTO_STARTUP) msgstr("Запускати під час завантаження системи") msgid(THEME) msgstr("Тема") msgid(THEME_DEFAULT) msgstr("Базова") msgid(THEME_LIGHT) msgstr("Світла") msgid(THEME_DARK) msgstr("Темна") msgid(THEME_HIGHCONTRAST) msgstr("Контрастна") msgid(THEME_CUSTOM) msgstr("Власна (див. документацію)") msgid(THEME_ZENBURN) msgstr("Zenburn") msgid(THEME_SOLARIZED_LIGHT) msgstr("Solarized світла") msgid(THEME_SOLARIZED_DARK) msgstr("Solarized темна") msgid(SEND_TYPING_NOTIFICATIONS) msgstr("Повідомляти про набір відповіді") msgid(STATUS_NOTIFICATIONS) msgstr("Зміна статусу") msgid(RANDOMIZE_NOSPAM) msgstr("Згенерувати антиспам-код") msgid(NOSPAM) msgstr("Антиспам-код") msgid(REVERT_NOSPAM) msgstr("Відновити антиспам-код") msgid(NOSPAM_WARNING) msgstr("Зміна антиспам-коду зробить недійсним ваш старий Tox ID. uTox не оновлює ваш ID на серверах імен.") msgid(BLOCK_FRIEND_REQUESTS) msgstr("Заборонити запити на додання друзів") msgid(SHOW_NOSPAM) msgstr("Показати антиспам-код") msgid(HIDE_NOSPAM) msgstr("Сховати налаштування антиспам-коду") msgid(DELETE_FRIEND) msgstr("Видалити з друзів") msgid(DELETE_MESSAGE) msgstr("Дійсно видалити ") msgid(KEEP) msgstr("Залишити") uTox-0.17.1/src/000077500000000000000000000000001354126257400133375ustar00rootroot00000000000000uTox-0.17.1/src/android/000077500000000000000000000000001354126257400147575ustar00rootroot00000000000000uTox-0.17.1/src/android/.idea/000077500000000000000000000000001354126257400157375ustar00rootroot00000000000000uTox-0.17.1/src/android/.idea/.name000066400000000000000000000000071354126257400166550ustar00rootroot00000000000000androiduTox-0.17.1/src/android/.idea/android.iml000066400000000000000000000005201354126257400200570ustar00rootroot00000000000000 uTox-0.17.1/src/android/.idea/compiler.xml000066400000000000000000000012561354126257400202770ustar00rootroot00000000000000 uTox-0.17.1/src/android/.idea/copyright/000077500000000000000000000000001354126257400177475ustar00rootroot00000000000000uTox-0.17.1/src/android/.idea/copyright/profiles_settings.xml000066400000000000000000000001141354126257400242300ustar00rootroot00000000000000 uTox-0.17.1/src/android/.idea/misc.xml000066400000000000000000000012421354126257400174130ustar00rootroot00000000000000 uTox-0.17.1/src/android/.idea/modules.xml000066400000000000000000000004121354126257400201260ustar00rootroot00000000000000 uTox-0.17.1/src/android/.idea/vcs.xml000066400000000000000000000003361354126257400172560ustar00rootroot00000000000000 uTox-0.17.1/src/android/.idea/workspace.xml000066400000000000000000000463741354126257400204750ustar00rootroot00000000000000 1458026631571 uTox-0.17.1/src/android/AndroidManifest.xml000066400000000000000000000033651354126257400205570ustar00rootroot00000000000000 uTox-0.17.1/src/android/AndroidManifest.xml.in000066400000000000000000000034001354126257400211520ustar00rootroot00000000000000 uTox-0.17.1/src/android/audio.c000066400000000000000000000241021354126257400162230ustar00rootroot00000000000000/* uTox audio using OpenSL * todo: error checking, only record when needed, audio sources only in "playing" state when they have something to * play(does it make a difference?) */ #include "main.h" #include "../debug.h" #include "../settings.h" #include "../macros.h" #include "../utox.h" #include "../native/audio.h" #include "../native/thread.h" #include "../../langs/i18n_decls.h" #include #include #include #include "../native/audio.h" static SLObjectItf engineObject = NULL; static SLEngineItf engineEngine; static SLObjectItf outputMixObject = NULL; static SLObjectItf recorderObject = NULL; static SLRecordItf recorderRecord; static SLAndroidSimpleBufferQueueItf recorderBufferQueue; // dont change this #define FRAMES (960 * 3) static short recbuf[960 * 2]; typedef struct { SLObjectItf player; SLAndroidSimpleBufferQueueItf queue; uint8_t channels; uint8_t value; volatile bool queued[8]; uint8_t unqueue; short * buf; } AUDIO_PLAYER; AUDIO_PLAYER loopback, call_player[32]; static SLDataFormat_PCM format_pcm = {.formatType = SL_DATAFORMAT_PCM, .numChannels = 1, .samplesPerSec = SL_SAMPLINGRATE_48, .bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16, .containerSize = SL_PCMSAMPLEFORMAT_FIXED_16, .channelMask = SL_SPEAKER_FRONT_CENTER, .endianness = SL_BYTEORDER_LITTLEENDIAN }; volatile bool call[32]; pthread_mutex_t callback_lock; void * frames[128]; uint8_t frame_count; void playCallback(SLAndroidSimpleBufferQueueItf bq, void *context) { AUDIO_PLAYER *p = context; p->queued[p->unqueue++] = 0; if (p->unqueue == 8) { p->unqueue = 0; } } void init_player(AUDIO_PLAYER *p, uint8_t channels) { format_pcm.numChannels = channels; format_pcm.channelMask = ((channels == 1) ? SL_SPEAKER_FRONT_CENTER : (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT)); p->channels = channels; SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 8 }; SLDataSource audioSrc = { &loc_bufq, &format_pcm }; SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX, outputMixObject }; SLDataSink audioSnk = { &loc_outmix, NULL }; SLPlayItf bqPlayerPlay; const SLInterfaceID ids[] = { SL_IID_BUFFERQUEUE }; const SLboolean reqs[] = { SL_BOOLEAN_TRUE }; (*engineEngine)->CreateAudioPlayer(engineEngine, &p->player, &audioSrc, &audioSnk, 1, ids, reqs); (*p->player)->Realize(p->player, SL_BOOLEAN_FALSE); (*p->player)->GetInterface(p->player, SL_IID_PLAY, &bqPlayerPlay); (*p->player)->GetInterface(p->player, SL_IID_BUFFERQUEUE, &p->queue); (*p->queue)->RegisterCallback(p->queue, playCallback, p); (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING); p->buf = malloc(960 * 2 * 8 * channels); } void close_player(AUDIO_PLAYER *p) { (*p->player)->Destroy(p->player); free(p->buf); memset(p, 0, sizeof(*p)); } static void player_queue(AUDIO_PLAYER *p, const int16_t *data, uint8_t channels) { if (channels != p->channels && p->player) { close_player(p); } if (!p->player) { init_player(p, channels); } SLresult result; if (!p->queued[p->value]) { p->queued[p->value] = 1; memcpy(&p->buf[p->value * 960 * channels], data, 960 * 2 * channels); result = (*p->queue)->Enqueue(p->queue, &p->buf[p->value * 960 * channels], 960 * 2 * channels); p->value++; if (p->value == 8) { p->value = 0; } } else { LOG_TRACE("Audio", "dropped" ); } } /* thread dedicated to encoding audio frames */ /* todo: exit */ void encoder_thread(void *arg) { while (1) { void * frame; uint8_t c; pthread_mutex_lock(&callback_lock); c = frame_count; if (c) { frame = frames[0]; memmove(&frames[0], &frames[1], (c - 1) * sizeof(void *)); frame_count--; } pthread_mutex_unlock(&callback_lock); if (c) { if (settings.audio_preview) { player_queue(&loopback, frame, 1); } // TODO fix this int i; for (i = 0; i < 32; i++) { if (call[i]) { int r; uint8_t dest[960 * 2]; /*if((r = toxav_prepare_audio_frame(arg, i, dest, sizeof(dest), frame, 960)) < 0) { LOG_TRACE("Audio", "toxav_prepare_audio_frame error %i" , r); continue; } if((r = toxav_send_audio(arg, i, dest, r)) < 0) { LOG_TRACE("Audio", "toxav_send_audio error %i %s" , r, strerror(errno)); }*/ // toxav_audio_send_frame(av, friend[i].number, (const int16_t *)buf, perframe, // UTOX_DEFAULT_AUDIO_CHANNELS, UTOX_DEFAULT_SAMPLE_RATE_A, NULL); } } free(frame); } if (c <= 1) { yieldcpu(1); } } } /* these two callbacks assume they will be called from the same thread (not at the same time from different threads) */ void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context) { SLresult result; static bool b; short * buf = &recbuf[b ? 960 : 0]; pthread_mutex_lock(&callback_lock); if (frame_count == 128) { LOG_TRACE("Audio", "problem~!~" ); } else { void *frame = malloc(960 * 2); memcpy(frame, buf, 960 * 2); frames[frame_count++] = frame; } result = (*bq)->Enqueue(bq, buf, 960 * 2); b = !b; pthread_mutex_unlock(&callback_lock); } bool createAudioRecorder(void) { SLresult result; // configure audio source SLDataLocator_IODevice loc_dev = { SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, SL_DEFAULTDEVICEID_AUDIOINPUT, NULL }; SLDataSource audioSrc = { &loc_dev, NULL }; // configure audio sink SLDataLocator_AndroidSimpleBufferQueue loc_bq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2 }; SLDataSink audioSnk = { &loc_bq, &format_pcm }; // create audio recorder // (requires the RECORD_AUDIO permission) const SLInterfaceID id[1] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE }; const SLboolean req[1] = { SL_BOOLEAN_TRUE }; result = (*engineEngine)->CreateAudioRecorder(engineEngine, &recorderObject, &audioSrc, &audioSnk, 1, id, req); if (SL_RESULT_SUCCESS != result) { return 0; } // realize the audio recorder result = (*recorderObject)->Realize(recorderObject, SL_BOOLEAN_FALSE); if (SL_RESULT_SUCCESS != result) { return 0; } // get the record interface result = (*recorderObject)->GetInterface(recorderObject, SL_IID_RECORD, &recorderRecord); // get the buffer queue interface result = (*recorderObject)->GetInterface(recorderObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &recorderBufferQueue); // register callback on the buffer queue result = (*recorderBufferQueue)->RegisterCallback(recorderBufferQueue, bqRecorderCallback, NULL); pthread_mutex_init(&callback_lock, NULL); // thread(encoder_thread, av); return 1; } void startRecording(void) { SLresult result; result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_STOPPED); result = (*recorderBufferQueue)->Clear(recorderBufferQueue); result = (*recorderBufferQueue)->Enqueue(recorderBufferQueue, &recbuf[0], 960 * 2); result = (*recorderBufferQueue)->Enqueue(recorderBufferQueue, &recbuf[960], 960 * 2); result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_RECORDING); } void stopRecording(void) { SLresult result; result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_STOPPED); result = (*recorderBufferQueue)->Clear(recorderBufferQueue); pthread_mutex_lock(&callback_lock); unsigned int i; for (i = 0; i < frame_count; ++i) { free(frames[i]); frames[i] = NULL; } frame_count = 0; pthread_mutex_unlock(&callback_lock); } void createEngine(void) { SLresult result; result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, NULL, NULL); result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE); init_player(&loopback, 1); } /* ASSUMES LENGTH == 960 */ void audio_play(int32_t call_index, const int16_t *data, int length, uint8_t channels) { player_queue(&call_player[call_index], data, channels); } void audio_begin(int32_t call_index) { call[call_index] = 1; } void audio_end(int32_t call_index) { call[call_index] = 0; } void audio_detect(void) { createEngine(); createAudioRecorder(); postmessage_utox(AUDIO_IN_DEVICE, STR_AUDIO_IN_ANDROID, 1, (void *)(size_t)1); } bool audio_init(void *handle) { startRecording(); return 1; } bool audio_close(void *handle) { stopRecording(); return 1; } bool audio_frame(int16_t *buffer) { void * frame; uint8_t c; pthread_mutex_lock(&callback_lock); c = frame_count; if (c) { frame = frames[0]; memmove(&frames[0], &frames[1], (c - 1) * sizeof(void *)); frame_count--; } pthread_mutex_unlock(&callback_lock); if (c) { memcpy(buffer, frame, 960 * 2); free(frame); return 1; } return 0; } uTox-0.17.1/src/android/freetype.c000066400000000000000000000073371354126257400167600ustar00rootroot00000000000000#include "main.h" #include "freetype.h" #include "gl.h" #include "../macros.h" #include "../ui.h" #include "../ui/draw.h" #define PIXELS(x) (((x) + 32) / 64) FT_Library ftlib; FONT font[16], *sfont; GLYPH *font_getglyph(FONT *f, uint32_t ch) { uint32_t hash = ch % 128; GLYPH * g = f->glyphs[hash], *s = g; if (g) { while (g->ucs4 != ~0) { if (g->ucs4 == ch) { return g; } g++; } uint32_t count = (uint32_t)(g - s); g = realloc(s, (count + 2) * sizeof(GLYPH)); if (!g) { return NULL; } f->glyphs[hash] = g; g += count; } else { g = malloc(sizeof(GLYPH) * 2); if (!g) { return NULL; } f->glyphs[hash] = g; } g[1].ucs4 = ~0; FT_UInt index = FT_Get_Char_Index(f->face, ch); FT_Load_Glyph(f->face, index, FT_LOAD_RENDER); FT_GlyphSlotRec *p = f->face->glyph; g->ucs4 = ch; g->x = p->bitmap_left; g->y = PIXELS(f->face->size->metrics.ascender) - p->bitmap_top; g->width = p->bitmap.width; g->height = p->bitmap.rows; g->xadvance = (p->advance.x + (1 << 5)) >> 6; if (f->x + g->width > 512) { f->x = 0; f->y = f->my; } g->mx = f->x; g->my = f->y; glBindTexture(GL_TEXTURE_2D, f->texture); glTexSubImage2D(GL_TEXTURE_2D, 0, f->x, f->y, g->width, g->height, GL_ALPHA, GL_UNSIGNED_BYTE, p->bitmap.buffer); f->x += g->width; if (f->y + g->height > f->my) { f->my = f->y + g->height; } return g; } void initfonts(void) { FT_Init_FreeType(&ftlib); } static bool font_open(FONT *f, double size, uint8_t weight) { FT_New_Face(ftlib, "/system/fonts/Roboto-Regular.ttf", 0, &f->face); FT_Set_Char_Size(f->face, (size * 64.0 + 0.5), (size * 64.0 + 0.5), 0, 0); f->fontmap = malloc(512 * 512); f->x = 0; f->y = 0; f->my = 0; f->height = 512; glGenTextures(1, &f->texture); glBindTexture(GL_TEXTURE_2D, f->texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512, 512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, f->fontmap); return 1; } void loadfonts(void) { font_open(&font[FONT_TEXT], SCALE(12.0), 0); font_open(&font[FONT_TITLE], SCALE(12.0), 1); font_open(&font[FONT_SELF_NAME], SCALE(14.0), 1); font_open(&font[FONT_STATUS], SCALE(11.0), 0); font_open(&font[FONT_LIST_NAME], SCALE(12.0), 0); // font_open(&font[FONT_MSG], F(11.0), 2); // font_open(&font[FONT_MSG_NAME], F(10.0), 2); font_open(&font[FONT_MISC], SCALE(10.0), 0); // font_open(&font[FONT_MSG_LINK], F(11.0), 2); font_small_lineheight = (font[FONT_TEXT].face->size->metrics.height + (1 << 5)) >> 6; // font_msg_lineheight = (font[FONT_MSG].face->size->metrics.height + (1 << 5)) >> 6; } void freefonts(void) { for (size_t i = 0; i != COUNTOF(font); i++) { FONT *f = &font[i]; if (f->face) { FT_Done_Face(f->face); } for (size_t j = 0; j != COUNTOF(f->glyphs); j++) { GLYPH *g = f->glyphs[j]; if (g) { /*while(g->ucs4 != ~0) { if(g->pic) { XRenderFreePicture(display, g->pic); } g++; }*/ free(f->glyphs[j]); f->glyphs[j] = NULL; } } } } static int _drawtext(int x, int xmax, int y, char *str, uint16_t length) { return GL_drawtext(x, xmax, y, str, length); } #include "../shared/freetype-text.c" uTox-0.17.1/src/android/freetype.h000066400000000000000000000011701354126257400167520ustar00rootroot00000000000000#ifndef ANDROID_FREETYPE_H #define ANDROID_FREETYPE_H #include #include #include #include typedef struct { uint32_t ucs4; int16_t x, y; uint16_t width, height, xadvance, xxxx; int16_t mx, my; } GLYPH; typedef struct { FT_Face face; uint8_t *fontmap; uint16_t x, y, my, height; GLuint texture; GLYPH * glyphs[128]; } FONT; extern FT_Library ftlib; extern FONT font[16], *sfont; GLYPH *font_getglyph(FONT *f, uint32_t ch); void initfonts(void); void loadfonts(void); void freefonts(void); #endif // ANDROID_FREETYPE_H uTox-0.17.1/src/android/gl.c000066400000000000000000000373621354126257400155400ustar00rootroot00000000000000#include "gl.h" #include "freetype.h" #include "main.h" #include "../native/ui.h" #include "../debug.h" #include "../macros.h" #include "../settings.h" #include "../text.h" #include "../ui.h" #include "../ui/svg.h" #include "../main.h" // stbi const char vertex_shader[] = "uniform vec4 matrix;" "attribute vec2 pos;" "attribute vec2 tex;" "varying vec2 x;" "void main(){" "x = tex / 32768.0;" "gl_Position = vec4((pos + matrix.xy) * matrix.zw, 0.0, 1.0);" "}", fragment_shader[] = #ifndef NO_OPENGL_ES "precision mediump float;" #endif "uniform sampler2D samp;" "uniform vec3 k;" "uniform vec3 k2;" "varying vec2 x;" "void main(){" "gl_FragColor = (texture2D(samp, x) + vec4(k2, 0.0)) * vec4(k, 1.0);" "}"; static GLuint prog, white; static GLint matrix, k, k2, samp; static GLuint bitmap[BM_ENDMARKER]; static QUAD2D quads[64]; static EGLDisplay display; static EGLSurface surface; static EGLContext context; static EGLConfig config; #ifndef NO_OPENGL_ES #define glDrawQuads(x, y) glDrawElements(GL_TRIANGLES, (y)*6, GL_UNSIGNED_BYTE, &quad_indices[(x)*6]) static uint8_t quad_indices[384]; #else #define glDrawQuads(x, y) glDrawArrays(GL_QUADS, (x), 4 * (y)) #endif static void makequad(QUAD2D *quad, int16_t x, int16_t y, int16_t right, int16_t bottom) { quad->vertex[0].x = x; quad->vertex[0].y = y; quad->vertex[0].tx = 0; quad->vertex[0].ty = 0; quad->vertex[1].x = right; quad->vertex[1].y = y; quad->vertex[1].tx = 32768; quad->vertex[1].ty = 0; quad->vertex[2].x = right; quad->vertex[2].y = bottom; quad->vertex[2].tx = 32768; quad->vertex[2].ty = 32768; quad->vertex[3].x = x; quad->vertex[3].y = bottom; quad->vertex[3].tx = 0; quad->vertex[3].ty = 32768; } static void makeline(QUAD2D *quad, int16_t x, int16_t y, int16_t x2, int16_t y2) { quad->vertex[0].x = x; quad->vertex[0].y = y; quad->vertex[1].x = x2; quad->vertex[1].y = y2; } void makeglyph(QUAD2D *quad, int16_t x, int16_t y, uint16_t mx, uint16_t my, uint16_t width, uint16_t height) { quad->vertex[0].x = x; quad->vertex[0].y = y; quad->vertex[0].tx = mx * 64; quad->vertex[0].ty = my * 64; quad->vertex[1].x = x + width; quad->vertex[1].y = y; quad->vertex[1].tx = (mx + width) * 64; quad->vertex[1].ty = my * 64; quad->vertex[2].x = x + width; quad->vertex[2].y = y + height; quad->vertex[2].tx = (mx + width) * 64; quad->vertex[2].ty = (my + height) * 64; quad->vertex[3].x = x; quad->vertex[3].y = y + height; quad->vertex[3].tx = mx * 64; quad->vertex[3].ty = (my + height) * 64; } static void set_color(uint32_t a) { union { uint32_t c; struct { uint8_t r, g, b, a; }; } color; color.c = a; float c[] = { (float)color.r / 255.0, (float)color.g / 255.0, (float)color.b / 255.0 }; glUniform3fv(k, 1, c); } uint32_t colori; float colorf[3]; uint32_t setcolor(uint32_t a) { union { uint32_t c; struct { uint8_t r, g, b, a; }; } color; color.c = a; colorf[0] = (float)color.r / 255.0; colorf[1] = (float)color.g / 255.0; colorf[2] = (float)color.b / 255.0; uint32_t s = colori; colori = a; return s; } void drawrect(int x, int y, int right, int bottom, uint32_t color) { set_color(color); glBindTexture(GL_TEXTURE_2D, white); makequad(&quads[0], x, y, right, bottom); glDrawQuads(0, 1); } void draw_rect_fill(int x, int y, int width, int height, uint32_t color) { drawrect(x, y, x + width, y + height, color); } void draw_rect_frame(int x, int y, int width, int height, uint32_t color) { set_color(color); glBindTexture(GL_TEXTURE_2D, white); makequad(&quads[0], x, y, x + width, y + height); glDrawArrays(GL_LINE_LOOP, 0, 4); } void drawhline(int x, int y, int x2, uint32_t color) { set_color(color); glBindTexture(GL_TEXTURE_2D, white); makeline(&quads[0], x, y + 1, x2, y + 1); glDrawArrays(GL_LINES, 0, 2); } void drawvline(int x, int y, int y2, uint32_t color) { set_color(color); glBindTexture(GL_TEXTURE_2D, white); makeline(&quads[0], x + 1, y, x + 1, y2); glDrawArrays(GL_LINES, 0, 2); } void drawalpha(int bm, int x, int y, int width, int height, uint32_t color) { set_color(color); glBindTexture(GL_TEXTURE_2D, bitmap[bm]); makequad(&quads[0], x, y, x + width, y + height); glDrawQuads(0, 1); } void loadalpha(int bm, void *data, int width, int height) { glBindTexture(GL_TEXTURE_2D, bitmap[bm]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data); } typedef struct { int16_t x, y; uint16_t width, height; } RECT; static RECT clip[16]; static int clipk; void pushclip(int left, int top, int w, int h) { if (!clipk) { glEnable(GL_SCISSOR_TEST); } RECT *r = &clip[clipk++]; r->x = left; r->y = settings.window_height - (top + h); r->width = w; r->height = h; glScissor(r->x, r->y, r->width, r->height); } void popclip(void) { clipk--; if (!clipk) { glDisable(GL_SCISSOR_TEST); return; } RECT *r = &clip[clipk - 1]; glScissor(r->x, r->y, r->width, r->height); } void enddraw(int x, int y, int width, int height) { LOG_TRACE("AndroidGL", "Going to swap buffers"); if (!eglSwapBuffers(display, surface)) { LOG_ERR("AndroidGL", "OpenGL Swap errored! %d", eglGetError()); } } bool gl_init(void) { LOG_INFO("AndroidGL", "gl init\n"); GLuint vertshader, fragshader; GLint status; const GLchar *data; vertshader = glCreateShader(GL_VERTEX_SHADER); if (!vertshader) { LOG_TRACE("gl", "glCreateShader() failed (vert)" ); return false; } data = vertex_shader; glShaderSource(vertshader, 1, &data, NULL); glCompileShader(vertshader); glGetShaderiv(vertshader, GL_COMPILE_STATUS, &status); if (!status) { LOG_TRACE("gl", "glCompileShader() failed (vert):\n%s" , data); GLint infologsize = 0; glGetShaderiv(vertshader, GL_INFO_LOG_LENGTH, &infologsize); if (infologsize) { char *infolog = malloc(infologsize); glGetShaderInfoLog(vertshader, infologsize, NULL, (GLbyte *)infolog); LOG_TRACE("gl", "Infolog: %s" , infolog); free(infolog); } return false; } fragshader = glCreateShader(GL_FRAGMENT_SHADER); if (!fragshader) { return false; } data = &fragment_shader[0]; glShaderSource(fragshader, 1, &data, NULL); glCompileShader(fragshader); glGetShaderiv(fragshader, GL_COMPILE_STATUS, &status); if (!status) { LOG_TRACE("gl", "glCompileShader failed (frag):\n%s" , data); GLint infologsize = 0; glGetShaderiv(fragshader, GL_INFO_LOG_LENGTH, &infologsize); if (infologsize) { char *infolog = malloc(infologsize); glGetShaderInfoLog(fragshader, infologsize, NULL, (GLbyte *)infolog); LOG_TRACE("gl", "Infolog: %s" , infolog); free(infolog); } return false; } prog = glCreateProgram(); glAttachShader(prog, vertshader); glAttachShader(prog, fragshader); glBindAttribLocation(prog, 0, "pos"); glBindAttribLocation(prog, 1, "tex"); glLinkProgram(prog); glGetProgramiv(prog, GL_LINK_STATUS, &status); if (!status) { LOG_TRACE("gl", "glLinkProgram failed" ); GLint infologsize = 0; glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &infologsize); if (infologsize) { char *infolog = malloc(infologsize); glGetShaderInfoLog(prog, infologsize, NULL, (GLbyte *)infolog); LOG_TRACE("gl", "Infolog: %s" , infolog); free(infolog); } return false; } glUseProgram(prog); matrix = glGetUniformLocation(prog, "matrix"); k = glGetUniformLocation(prog, "k"); k2 = glGetUniformLocation(prog, "k2"); samp = glGetUniformLocation(prog, "samp"); LOG_TRACE("gl", "uniforms: %i %i %i" , matrix, k, samp); GLint zero = 0; float one[] = { 1.0, 1.0, 1.0 }; glUniform1iv(samp, 1, &zero); glUniform3fv(k2, 1, one); uint8_t wh = { 255 }; glGenTextures(1, &white); glBindTexture(GL_TEXTURE_2D, white); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &wh); // glVertexAttribPointer(0, 2, GL_SHORT, GL_FALSE, sizeof(VERTEX2D), &quads[0]); glVertexAttribPointer(1, 2, GL_UNSIGNED_SHORT, GL_FALSE, sizeof(VERTEX2D), &quads[0].vertex[0].tx); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); // Alpha blending glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); // glPixelStorei(GL_UNPACK_ALIGNMENT, 1); #ifndef NO_OPENGL_ES uint8_t i = 0; uint16_t ii = 0; do { quad_indices[ii] = i + 0; quad_indices[ii + 1] = i + 1; quad_indices[ii + 2] = i + 3; quad_indices[ii + 3] = i + 3; quad_indices[ii + 4] = i + 1; quad_indices[ii + 5] = i + 2; i += 4; ii += 6; } while (i); #endif glGenTextures(COUNTOF(bitmap), bitmap); svg_draw(0); loadfonts(); float vec[4]; vec[0] = -(float)settings.window_width / 2.0; vec[1] = -(float)settings.window_height / 2.0; vec[2] = 2.0 / (float)settings.window_width; vec[3] = -2.0 / (float)settings.window_height; glUniform4fv(matrix, 1, vec); LOG_INFO("AndroidGL", "GL init ready w %u h %u", settings.window_width, settings.window_height); ui_size(settings.window_width, settings.window_height); glViewport(0, 0, settings.window_width, settings.window_height); redraw(); return true; } /* gl initialization with EGL */ bool init_display(ANativeWindow *window) { LOG_INFO("AndroidGL", "gl display init\n"); const EGLint attrib_list[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; const EGLint attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 0, EGL_NONE }; EGLint numConfigs; display = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(display, NULL, NULL); eglChooseConfig(display, attribs, &config, 1, &numConfigs); EGLint format; eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format); ANativeWindow_setBuffersGeometry(window, 0, 0, format); surface = eglCreateWindowSurface(display, config, window, NULL); context = eglCreateContext(display, config, NULL, attrib_list); if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) { LOG_ERR("AndroidGL", "eglMakeCurrent failed!"); return false; } int32_t w, h; eglQuerySurface(display, surface, EGL_WIDTH, &w); eglQuerySurface(display, surface, EGL_HEIGHT, &h); settings.window_width = w; settings.window_height = h; bool init = gl_init(); if (init == false) { LOG_ERR("AndroidGL", "gl_init failed :<"); } return init; } void GL_draw_image(const NATIVE_IMAGE *data, int x, int y, uint32_t width, uint32_t height, uint32_t imgx, uint32_t imgy) { GLuint texture = data->img; makequad(&quads[0], x - imgx, y - imgy, x + width, y + height); glBindTexture(GL_TEXTURE_2D, texture); float one[] = { 1.0, 1.0, 1.0 }; float zero[] = { 0.0, 0.0, 0.0 }; glUniform3fv(k, 1, one); glUniform3fv(k2, 1, zero); glDrawQuads(0, 1); glUniform3fv(k2, 1, one); } NATIVE_IMAGE *GL_utox_image_to_native(const uint8_t *data, size_t size, uint16_t *w, uint16_t *h, bool keep_alpha) { unsigned width, height, bpp; uint8_t *out = stbi_load_from_memory(data, size, &width, &height, &bpp, 3); if (out == NULL || width == 0 || height == 0) { return 0; } *w = width; *h = height; GLuint texture = 0; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, out); free(out); return texture; } // Returns 1 if redraw is needed int GL_utox_android_redraw_window() { LOG_DEBUG("AndroidGL", "Redraw window"); int32_t new_width, new_height; eglQuerySurface(display, surface, EGL_WIDTH, &new_width); eglQuerySurface(display, surface, EGL_HEIGHT, &new_height); if (new_width != (int32_t)settings.window_width || new_height != (int32_t)settings.window_height) { LOG_DEBUG("AndroidGL", "Redraw window new size"); settings.window_width = new_width; settings.window_height = new_height; float vec[4]; vec[0] = -(float)settings.window_width / 2.0; vec[1] = -(float)settings.window_height / 2.0; vec[2] = 2.0 / (float)settings.window_width; vec[3] = -2.0 / (float)settings.window_height; glUniform4fv(matrix, 1, vec); ui_size(settings.window_width, settings.window_height); glViewport(0, 0, settings.window_width, settings.window_height); return 1; } return 0; } void GL_raze_surface(void) { // eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(display, context); eglDestroySurface(display, surface); eglTerminate(display); } int GL_drawtext(int x, int xmax, int y, char *str, uint16_t length) { glUniform3fv(k, 1, colorf); glBindTexture(GL_TEXTURE_2D, sfont->texture); int c = 0; while (length > 0) { uint32_t ch; uint8_t len = utf8_len_read(str, &ch); str += len; length -= len; GLYPH *g = font_getglyph(sfont, ch); if (g) { if (x + g->xadvance > xmax) { x = -x; break; } if (c == 64) { glDrawQuads(0, 64); c = 0; } makeglyph(&quads[c++], x + g->x, y + g->y, g->mx, g->my, g->width, g->height); x += g->xadvance; } } glDrawQuads(0, c); return x; } #if 0 void drawimage(NATIVE_IMAGE data, int x, int y, int width, int height, int maxwidth, bool zoom, double position) { GLuint texture = data; if(!zoom && width > maxwidth) { makequad(&quads[0], x, y, x + maxwidth, y + (height * maxwidth / width)); } else { makequad(&quads[0], x - (int)((double)(width - maxwidth) * position), y, x + width, y + height); } glBindTexture(GL_TEXTURE_2D, texture); float one[] = {1.0, 1.0, 1.0}; float zero[] = {0.0, 0.0, 0.0}; glUniform3fv(k, 1, one); glUniform3fv(k2, 1, zero); glDrawQuads(0, 1); glUniform3fv(k2, 1, one); } #endif uTox-0.17.1/src/android/gl.h000066400000000000000000000042241354126257400155340ustar00rootroot00000000000000#ifndef ANDROID_GL_H #define ANDROID_GL_H #include #include #include #include #define _GNU_SOURCE #include typedef struct native_image NATIVE_IMAGE; typedef struct { int16_t x, y; uint16_t tx, ty; } VERTEX2D; typedef struct { VERTEX2D vertex[4]; } QUAD2D; void makeglyph(QUAD2D *quad, int16_t x, int16_t y, uint16_t mx, uint16_t my, uint16_t width, uint16_t height); uint32_t setcolor(uint32_t a); void drawrect(int x, int y, int right, int bottom, uint32_t color); void draw_rect_fill(int x, int y, int width, int height, uint32_t color); void draw_rect_frame(int x, int y, int width, int height, uint32_t color); void drawhline(int x, int y, int x2, uint32_t color); void drawvline(int x, int y, int y2, uint32_t color); void drawalpha(int bm, int x, int y, int width, int height, uint32_t color); void loadalpha(int bm, void *data, int width, int height); void pushclip(int left, int top, int w, int h); void popclip(void); void enddraw(int x, int y, int width, int height); bool gl_init(void); /* gl initialization with EGL */ bool init_display(ANativeWindow *window); void GL_draw_image(const NATIVE_IMAGE *data, int x, int y, uint32_t width, uint32_t height, uint32_t imgx, uint32_t imgy); NATIVE_IMAGE *GL_utox_image_to_native(const uint8_t *data, size_t size, uint16_t *w, uint16_t *h, bool keep_alpha); int GL_utox_android_redraw_window(); void GL_raze_surface(void); int GL_drawtext(int x, int xmax, int y, char *str, uint16_t length); #if 0 void drawimage(NATIVE_IMAGE data, int x, int y, int width, int height, int maxwidth, bool zoom, double position) { GLuint texture = data; if(!zoom && width > maxwidth) { makequad(&quads[0], x, y, x + maxwidth, y + (height * maxwidth / width)); } else { makequad(&quads[0], x - (int)((double)(width - maxwidth) * position), y, x + width, y + height); } glBindTexture(GL_TEXTURE_2D, texture); float one[] = {1.0, 1.0, 1.0}; float zero[] = {0.0, 0.0, 0.0}; glUniform3fv(k, 1, one); glUniform3fv(k2, 1, zero); glDrawQuads(0, 1); glUniform3fv(k2, 1, one); } #endif #endif // ANDROID_GL_H uTox-0.17.1/src/android/logging.h000066400000000000000000000001521354126257400165540ustar00rootroot00000000000000#include #define debug(...) (__android_log_print(ANDROID_LOG_INFO, "utox", __VA_ARGS__)) uTox-0.17.1/src/android/main.c000066400000000000000000000573471354126257400160670ustar00rootroot00000000000000#include "main.h" #include "gl.h" #include "freetype.h" #include "../debug.h" #include "../filesys.h" #include "../flist.h" #include "../main.h" #include "../settings.h" #include "../stb.h" #include "../theme.h" #include "../tox.h" #include "../ui.h" #include "../utox.h" #include "../ui/svg.h" #include "../ui/edit.h" #include "../layout/background.h" #include "../native/keyboard.h" #include "../native/notify.h" #include #include #include #include #include #include #include #include #include static volatile bool destroy; bool have_focus = false; static bool shift; static ANativeActivity * activity; static ANativeWindow * window; static volatile ANativeWindow *windowN; static AInputQueue * inputQueue; static volatile AInputQueue * inputQueueNew; static volatile ARect rect; static volatile bool _redraw; const char *internalPath[UTOX_FILE_NAME_LENGTH]; static int pipefd[2]; typedef struct { uint32_t msg; uint16_t param1, param2; void * data; } PIPING; void postmessage_utox(UTOX_MSG msg, uint16_t param1, uint16_t param2, void *data) { PIPING piping = {.msg = msg, .param1 = param1, .param2 = param2, .data = data }; write(pipefd[1], &piping, sizeof(PIPING)); } void init_ptt(void) { settings.push_to_talk = 0; /* android is unsupported */ } bool check_ptt_key(void) { return 1; /* android is unsupported */ } void exit_ptt(void) { settings.push_to_talk = 0; /* android is unsupported */ } void image_set_filter(NATIVE_IMAGE *image, uint8_t filter) { /* Unsupported on android */ } void image_set_scale(NATIVE_IMAGE *image, double scale) { /* Unsupported on android */ } void draw_image(const NATIVE_IMAGE *data, int x, int y, uint32_t width, uint32_t height, uint32_t imgx, uint32_t imgy) { GL_draw_image(data, x, y, width, height, imgx, imgy); } void draw_inline_image(uint8_t *img_data, size_t size, uint16_t w, uint16_t h, int x, int y) { draw_image(img_data, x, y, w, h, 0, 0); } void thread(void func(void *), void *args) { pthread_t thread_temp; pthread_create(&thread_temp, NULL, (void *(*)(void *))func, args); } void yieldcpu(uint32_t ms) { usleep(1000 * ms); } uint64_t get_time(void) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC_RAW, &ts); return ((uint64_t)ts.tv_sec * (1000 * 1000 * 1000)) + (uint64_t)ts.tv_nsec; } /* These functions aren't support on Andorid HELP? * TODO: fix these! */ void copy(int value) { /* Unsupported on android */ } void paste(void) { /* Unsupported on android */ } void openurl(char *str) { /* Unsupported on android */ } void openfilesend(void) { /* Unsupported on android */ } void openfileavatar(void) { /* Unsupported on android */ } typedef struct msg_header MSG_HEADER; void file_save_inline_image_png(MSG_HEADER *msg) { /* Unsupported on android */ } void setselection(char *data, uint16_t length) { /* Unsupported on android */ } void edit_will_deactivate(void) { /* Unsupported on android */ } NATIVE_IMAGE *utox_image_to_native(const UTOX_IMAGE data, size_t size, uint16_t *w, uint16_t *h, bool keep_alpha) { return GL_utox_image_to_native(data, size, w, h, keep_alpha); } void image_free(NATIVE_IMAGE *image) { if (!image) { return; } GLuint texture = image; glDeleteTextures(1, &texture); } // TODO: DRY. This function exists in both posix/filesys.c and in android/main.c // Make a posix native_get_file that you pass a complete path to instead of letting it construct // one would fix this. static void opts_to_sysmode(UTOX_FILE_OPTS opts, char *mode) { if (opts & UTOX_FILE_OPTS_READ) { mode[0] = 'r'; } if (opts & UTOX_FILE_OPTS_APPEND) { mode[0] = 'a'; } else if (opts & UTOX_FILE_OPTS_WRITE) { mode[0] = 'w'; } mode[1] = 'b'; if ((opts & (UTOX_FILE_OPTS_WRITE | UTOX_FILE_OPTS_APPEND)) && (opts & UTOX_FILE_OPTS_READ)) { mode[2] = '+'; } mode[3] = 0; return; } FILE *native_get_file_simple(const char *path, UTOX_FILE_OPTS opts) { char mode[4] = { 0 }; opts_to_sysmode(opts, mode); FILE *fp = fopen(path, mode); if (!fp && opts & UTOX_FILE_OPTS_READ && opts & UTOX_FILE_OPTS_WRITE) { LOG_WARN("Android Native", "Unable to simple open, falling back to fd" ); // read wont create a file if it doesn't' already exist. If we're allowed to write, lets try // to create the file, then reopen it. int fd = open(path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); fp = fdopen(fd, mode); } return fp; } FILE *native_get_file(const uint8_t *name, size_t *size, UTOX_FILE_OPTS opts, bool portable_mode) { uint8_t path[UTOX_FILE_NAME_LENGTH] = { 0 }; snprintf(path, UTOX_FILE_NAME_LENGTH, ANDROID_INTERNAL_SAVE); // native_get_file should never be called with DELETE in combination with other FILE_OPTS. assert(opts <= UTOX_FILE_OPTS_DELETE); // WRITE and APPEND are mutually exclusive. WRITE will serve you a blank file. APPEND will append (duh). assert((opts & UTOX_FILE_OPTS_WRITE && opts & UTOX_FILE_OPTS_APPEND) == false); if (opts & UTOX_FILE_OPTS_READ || opts & UTOX_FILE_OPTS_MKDIR) { if (!native_create_dir(path)) { return NULL; } } if (strlen((char *)path) + strlen((char *)name) >= UTOX_FILE_NAME_LENGTH) { LOG_TRACE("Android Native", "Load directory name too long" ); return NULL; } else { snprintf((char *)path + strlen((char *)path), UTOX_FILE_NAME_LENGTH - strlen((char *)path), "%s", name); } if (opts == UTOX_FILE_OPTS_DELETE) { remove((char *)path); return NULL; } FILE *fp = native_get_file_simple((char *)path, opts); if (fp == NULL) { LOG_NOTE("Android Native", "Could not open %s" , path); return NULL; } if (size != NULL) { fseek(fp, 0, SEEK_END); *size = ftell(fp); fseek(fp, 0, SEEK_SET); } return fp; } bool native_move_file(const uint8_t *current_name, const uint8_t *new_name) { if(!current_name || !new_name) { return false; } return rename((char *)current_name, (char *)new_name); } void native_select_dir_ft(uint32_t fid, void *file) { return; /* TODO unsupported on android //fall back to working dir char *path = malloc(file->name_length + 1); memcpy(path, file->name, file->name_length); path[file->name_length] = 0; postmessage_toxcore(TOX_FILE_ACCEPT, fid, file->filenumber, path); */ } void native_autoselect_dir_ft(uint32_t fid, void *file) { return; /* TODO unsupported on android /* TODO: maybe do something different here? char *path = malloc(file->name_length + 1); memcpy(path, file->name, file->name_length); path[file->name_length] = 0; postmessage_toxcore(TOX_FILE_ACCEPT, fid, file->file_number, path); */ } bool native_create_dir(const uint8_t *filepath) { const int status = mkdir((char *)filepath, S_IRWXU); if (status == 0 || errno == EEXIST) { return true; } return false; } bool native_remove_file(const uint8_t *name, size_t length, bool portable_mode) { uint8_t path[UTOX_FILE_NAME_LENGTH] = { 0 }; snprintf((char *)path, UTOX_FILE_NAME_LENGTH, ANDROID_INTERNAL_SAVE); if (strlen((const char *)path) + length >= UTOX_FILE_NAME_LENGTH) { LOG_TRACE("Android Native", "File/directory name too long, unable to remove" ); return 0; } else { snprintf((char *)path + strlen((const char *)path), UTOX_FILE_NAME_LENGTH - strlen((const char *)path), "%.*s", (int)length, (char *)name); } if (remove((const char *)path)) { LOG_ERR("Android Native", "Unable to delete file!\n\t\t%s" , path); return 0; } else { LOG_INFO("Android Native", "File deleted!" ); LOG_TRACE("Android Native", "\t%s" , path); } return 1; } void native_export_chatlog_init(uint32_t friend_number) { /* Unsupported on Android */ } bool native_save_image_png(const char *name, const uint8_t *image, const int image_size) { /* Unsupported on Android */ } void flush_file(FILE *file) { fflush(file); int fd = fileno(file); fsync(fd); } int ch_mod(uint8_t *file) { /* You're probably looking for ./xlib as android isn't working when this was written. */ return -1; } int file_lock(FILE *file, uint64_t start, size_t length) { // Unsupported on android return 0; } bool native_video_init(void *handle) { return 0; /* Unsupported on android */ } void native_video_close(void *handle) { /* Unsupported on android */ } bool native_video_startread(void) { return 1; /* Unsupported on android */ } bool native_video_endread(void) { return 1; /* Unsupported on android */ } int native_video_getframe(uint8_t *y, uint8_t *u, uint8_t *v, uint16_t width, uint16_t height) { return 0; /* Unsupported on android */ } int file_unlock(FILE *file, uint64_t start, size_t length) { return 0; /* Unsupported on android */ } void setscale_fonts(void) { freefonts(); loadfonts(); } void setscale(void) { if (window) { svg_draw(0); } setscale_fonts(); } void notify(char *title, uint16_t title_length, const char *msg, uint16_t msg_length, void *object, bool is_group) { /* Unsupported on android */ } void desktopgrab(bool video) { /* Unsupported on android */ } void video_frame(uint16_t id, uint8_t *img_data, uint16_t width, uint16_t height, bool resize) { /* Unsupported on android */ } void video_begin(uint16_t id, char *name, uint16_t name_length, uint16_t width, uint16_t height) { /* Unsupported on android */ } void video_end(uint16_t id) { /* Unsupported on android */ } uint16_t native_video_detect(void) { return 0; /* Unsupported on android */ } bool video_init(void *handle) { return 0; /* Unsupported on android */ } void video_close(void *handle) { /* Unsupported on android */ } bool video_startread(void) { return 1; /* Unsupported on android */ } bool video_endread(void) { return 1; /* Unsupported on android */ } int video_getframe(uint8_t *y, uint8_t *u, uint8_t *v, uint16_t width, uint16_t height) { return 0; /* Unsupported on android */ } #define MAP(x, y) case AKEYCODE_##x : return y #define MAPS(x, y, z) case AKEYCODE_##x : return ((shift) ? z : y) #define MAPC(x) case AKEYCODE_##x : return (#x[0] + ((shift) ? 0 : ('a' - 'A'))) #define MAPN(x, y) case AKEYCODE_##x : return ((shift) ? y : #x[0]) static uint32_t getkeychar(int32_t key) /* get a character from an android keycode */ { switch (key) { MAP(ENTER, KEY_RETURN); MAP(DEL, KEY_BACK); MAP(DPAD_LEFT, KEY_LEFT); MAP(DPAD_RIGHT, KEY_RIGHT); MAP(DPAD_UP, KEY_UP); MAP(DPAD_DOWN, KEY_DOWN); MAP(SPACE, ' '); MAPS(MINUS, '-', '_'); MAPS(EQUALS, '=', '+'); MAPS(LEFT_BRACKET, '[', '{'); MAPS(RIGHT_BRACKET, ']', '}'); MAPS(BACKSLASH, '\\', '|'); MAPS(SEMICOLON, ';', ':'); MAPS(APOSTROPHE, '\'', '\"'); MAPS(COMMA, ',', '<'); MAPS(PERIOD, '.', '>'); MAPS(SLASH, '/', '?'); MAPS(GRAVE, '`', '~'); MAP(AT, '@'); MAP(STAR, '*'); MAP(PLUS, '+'); MAPC(A); MAPC(B); MAPC(C); MAPC(D); MAPC(E); MAPC(F); MAPC(G); MAPC(H); MAPC(I); MAPC(J); MAPC(K); MAPC(L); MAPC(M); MAPC(N); MAPC(O); MAPC(P); MAPC(Q); MAPC(R); MAPC(S); MAPC(T); MAPC(U); MAPC(V); MAPC(W); MAPC(X); MAPC(Y); MAPC(Z); MAPN(0, ')'); MAPN(1, '!'); MAPN(2, '@'); MAPN(3, '#'); MAPN(4, '$'); MAPN(5, '%'); MAPN(6, '^'); MAPN(7, '&'); MAPN(8, '*'); MAPN(9, '('); default: { LOG_TRACE("Android", "un-mapped %u", key); break; } } return 0; #undef MAP #undef MAPC } void redraw(void) { _redraw = 1; } void force_redraw(void) { redraw(); } void update_tray(void) { /* Unsupported on android */ } void config_osdefaults(UTOX_SAVE *r) { /* Unsupported on android */ } void utox_android_redraw_window(void) { if (!_redraw) { return; } _redraw = GL_utox_android_redraw_window(); panel_draw(&panel_root, 0, 0, settings.window_width, settings.window_height); } int lx = 0, ly = 0; uint64_t p_last_down; bool p_down, already_up; static void utox_andoid_input(AInputQueue *in_queue, AInputEvent *event) { if (AInputQueue_preDispatchEvent(inputQueue, event) == 0) { int32_t handled = 1; int32_t type = AInputEvent_getType(event); if (type == AINPUT_EVENT_TYPE_MOTION) { int32_t action = AMotionEvent_getAction(event); int32_t pointer_index = ((action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); int32_t action_bits = (action & AMOTION_EVENT_ACTION_MASK); float x = AMotionEvent_getX(event, pointer_index); float y = AMotionEvent_getY(event, pointer_index); switch (action_bits) { case AMOTION_EVENT_ACTION_DOWN: case AMOTION_EVENT_ACTION_POINTER_DOWN: { lx = x; ly = y; panel_mmove(&panel_root, 0, 0, settings.window_width, settings.window_height, x, y, 0, 0); panel_mdown(&panel_root); // pointer[pointer_index].down = true; // pointer[pointer_index].x = x; // pointer[pointer_index].y = y; // pointerinput2(pointer_index); already_up = 0; LOG_TRACE("Android", "down %f %f, %u" , x, y, pointer_index); p_down = 1; p_last_down = get_time(); break; } case AMOTION_EVENT_ACTION_UP: case AMOTION_EVENT_ACTION_POINTER_UP: { // panel_mmove(&panel_root, 0, 0, width, height, x, y, 0); if (!already_up) { panel_mup(&panel_root); panel_mleave(&panel_root); } // pointer[pointer_index].down = false; // pointer[pointer_index].x = x; // pointer[pointer_index].y = y; // pointerinput(pointer_index); LOG_TRACE("Android", "up %f %f, %u" , x, y, pointer_index); p_down = 0; break; } case AMOTION_EVENT_ACTION_MOVE: { panel_mmove(&panel_root, 0, 0, settings.window_width, settings.window_height, x, y, x - lx, y - ly); if (lx != (int)x || ly != (int)y) { p_down = 0; lx = x; ly = y; LOG_TRACE("Android", "move %f %f, %u" , x, y, pointer_index); } // pointer[pointer_index].x = x; // pointer[pointer_index].y = y; break; } } } else if (type == AINPUT_EVENT_TYPE_KEY) { int32_t action = AMotionEvent_getAction(event); int32_t key = AKeyEvent_getKeyCode(event); if (action == AKEY_EVENT_ACTION_DOWN) { switch (key) { case AKEYCODE_VOLUME_UP: case AKEYCODE_VOLUME_DOWN: { handled = 0; break; } case AKEYCODE_MENU: { // open menu break; } case AKEYCODE_SHIFT_LEFT: case AKEYCODE_SHIFT_RIGHT: { shift = 1; break; } case AKEYCODE_BACK: { // ANativeActivity_finish(activity); break; } default: { uint32_t c = getkeychar(key); if (c != 0) { if (edit_active()) { // LOG_TRACE("Android", "%u" , c); edit_char(c, 0, 0); } // inputchar(c); } break; } } } else if (action == AKEY_EVENT_ACTION_UP) { if (key == AKEYCODE_SHIFT_LEFT || key == AKEYCODE_SHIFT_RIGHT) { shift = 0; } } } AInputQueue_finishEvent(inputQueue, event, handled); } } static void android_main(struct android_app *state) { utox_init(); theme_load(THEME_DEFAULT); settings.verbose = ~0; // Make sure glue isn't stripped // ANativeActivity* nativeActivity = state->activity; // internalPath = nativeActivity->internalDataPath; pipe(pipefd); fcntl(pipefd[0], F_SETFL, O_NONBLOCK); // Override to max spam for android settings.verbose = LOG_LVL_TRACE; thread(toxcore_thread, NULL); initfonts(); ui_rescale(12); /* wait for tox thread to start */ while (!tox_thread_init) { yieldcpu(1); } /* Code has been changed, this probably should be moved! */ flist_start(); ui_rescale(15); while (!destroy) { if (p_down && (p_last_down + 500 * 1000 * 1000) < get_time()) { panel_mup(&panel_root); panel_mright(&panel_root); p_down = 0; already_up = 1; } inputQueue = (AInputQueue *)inputQueueNew; if (inputQueue != NULL) { AInputEvent *event = NULL; while (AInputQueue_hasEvents(inputQueue) && AInputQueue_getEvent(inputQueue, &event) >= 0) { utox_andoid_input(inputQueue, event); } } int rlen, len; PIPING piping; while ((len = read(pipefd[0], (void *)&piping, sizeof(PIPING))) > 0) { LOG_TRACE("Android", "Piping %u %u" , len, sizeof(PIPING)); while (len != sizeof(PIPING)) { if ((rlen = read(pipefd[0], (void *)&piping + len, sizeof(PIPING) - len)) > 0) { len += rlen; } } utox_message_dispatch(piping.msg, piping.param1, piping.param2, piping.data); } ANativeWindow *win = (ANativeWindow *)windowN; if (win != window) { // new window if (window != NULL) { LOG_INFO("AndroidNative", "Replace old Window"); freefonts(); GL_raze_surface(); } window = win; if (window != NULL) { if (init_display(window) == false) { LOG_INFO("AndroidNative", "init_err"); ANativeActivity_finish(activity); break; } } } if (window != NULL && have_focus) { utox_android_redraw_window(); } usleep(1000); } LOG_TRACE("Android", "ANDROID DESTROYED" ); } void showkeyboard(bool show) { JavaVM *vm = activity->vm; JNIEnv *env = activity->env; JavaVMAttachArgs lJavaVMAttachArgs; lJavaVMAttachArgs.version = JNI_VERSION_1_6; lJavaVMAttachArgs.name = "NativeThread"; lJavaVMAttachArgs.group = NULL; (*vm)->AttachCurrentThread(vm, &env, &lJavaVMAttachArgs); // error check jobject lNativeActivity = activity->clazz; jclass ClassNativeActivity = (*env)->GetObjectClass(env, lNativeActivity); jclass ClassInputMethodManager = (*env)->FindClass(env, "android/view/inputmethod/InputMethodManager"); jfieldID fid = (*env)->GetFieldID(env, ClassNativeActivity, "mIMM", "Landroid/view/inputmethod/InputMethodManager;"); jobject lInputMethodManager = (*env)->GetObjectField(env, lNativeActivity, fid); jmethodID MethodGetWindow = (*env)->GetMethodID(env, ClassNativeActivity, "getWindow", "()Landroid/view/Window;"); jobject lWindow = (*env)->CallObjectMethod(env, lNativeActivity, MethodGetWindow); jclass ClassWindow = (*env)->FindClass(env, "android/view/Window"); jmethodID MethodGetDecorView = (*env)->GetMethodID(env, ClassWindow, "getDecorView", "()Landroid/view/View;"); jobject lDecorView = (*env)->CallObjectMethod(env, lWindow, MethodGetDecorView); if (show) { jmethodID MethodShowSoftInput = (*env)->GetMethodID(env, ClassInputMethodManager, "showSoftInput", "(Landroid/view/View;I)Z"); jboolean lResult = (*env)->CallBooleanMethod(env, lInputMethodManager, MethodShowSoftInput, lDecorView, 0); utox_android_redraw_window(); } else { jclass ClassView = (*env)->FindClass(env, "android/view/View"); jmethodID MethodGetWindowToken = (*env)->GetMethodID(env, ClassView, "getWindowToken", "()Landroid/os/IBinder;"); jobject lBinder = (*env)->CallObjectMethod(env, lDecorView, MethodGetWindowToken); jmethodID MethodHideSoftInput = (*env)->GetMethodID(env, ClassInputMethodManager, "hideSoftInputFromWindow", "(Landroid/os/IBinder;I)Z"); jboolean lRes = (*env)->CallBooleanMethod(env, lInputMethodManager, MethodHideSoftInput, lBinder, 0); } /*jmethodID MethodToggle = (*env)->GetMethodID(env, ClassInputMethodManager, "toggleSoftInput", "(II)V"); (*env)->CallVoidMethod(env, lInputMethodManager, MethodToggle, 0, 0);*/ (*vm)->DetachCurrentThread(vm); } static void onDestroy(ANativeActivity *act) { destroy = 1; } static void onNativeWindowCreated(ANativeActivity *act, ANativeWindow *win) { LOG_NOTE("AndroidNative", "Native Window Made"); windowN = win; } static void onNativeWindowDestroyed(ANativeActivity *act, ANativeWindow *win) { LOG_NOTE("AndroidNative", "Native Window Killed"); windowN = NULL; } static void onWindowFocusChanged(ANativeActivity *act, int focus) { have_focus = (focus != 0); } static void onInputQueueCreated(ANativeActivity *act, AInputQueue *queue) { inputQueueNew = queue; } static void onInputQueueDestroyed(ANativeActivity *act, AInputQueue *queue) { inputQueueNew = NULL; } static void onContentRectChanged(ANativeActivity *activity, const ARect *r) { rect = *r; LOG_TRACE("AndroidNative", "window changed rect: %u %u %u %u" , rect.left, rect.right, rect.top, rect.bottom); settings.window_baseline = rect.bottom; _redraw = 1; } __attribute__((externally_visible)) void ANativeActivity_onCreate(ANativeActivity *act, void *savedState, size_t savedStateSize) { if (!act) { return; } activity = act; // Add callbacks here (find them in android/native_activity.h) act->callbacks->onDestroy = onDestroy; act->callbacks->onNativeWindowCreated = onNativeWindowCreated; act->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed; act->callbacks->onWindowFocusChanged = onWindowFocusChanged; act->callbacks->onInputQueueCreated = onInputQueueCreated; act->callbacks->onInputQueueDestroyed = onInputQueueDestroyed; act->callbacks->onContentRectChanged = onContentRectChanged; // start main thread (android_main) pthread_t thread; pthread_attr_t myattr; pthread_attr_init(&myattr); pthread_attr_setdetachstate(&myattr, PTHREAD_CREATE_DETACHED); pthread_create(&thread, &myattr, (void *(*)(void *))android_main, NULL); } void launch_at_startup(bool should) {} uTox-0.17.1/src/android/main.h000066400000000000000000000011531354126257400160540ustar00rootroot00000000000000#if defined(MAIN_H) && !defined(ANDROID_MAIN_H) #error "We should never include main from different platforms." #endif #ifndef ANDROID_MAIN_H #define ANDROID_MAIN_H #define MAIN_H #include #include #include #include #include #include #include #include #include #include #include // Early include to obtain GLuint. #include typedef struct native_image { GLuint img; } NATIVE_IMAGE; #define ANDROID_INTERNAL_SAVE "/data/data/tox.client.utox/files/" #endif uTox-0.17.1/src/android/res/000077500000000000000000000000001354126257400155505ustar00rootroot00000000000000uTox-0.17.1/src/android/res/drawable/000077500000000000000000000000001354126257400173315ustar00rootroot00000000000000uTox-0.17.1/src/android/res/drawable/i.png000066400000000000000000000161461354126257400202770ustar00rootroot00000000000000PNG  IHDR\rf-IDATxy\TƟaFtDPAǃi"izͅ,ͭ,,-.4%E ˭ wSqx\D DYgTX̙sfsɜ<9ĩ̂@8 r<|wHp/. 3$1eAT4Ӆ,8`xDI,`%("O{(<$[lA V e\w'%1գH)CʆDIjRxM 靁|`%O"R[NWS w_n'xg$8 (Wm>E#8`(?p6Pf4+%1QȋlДiN=CM~+gl|y8q((giVWdEI(xk>Lxg3YM~iiL+5%0Gb5A$f1 @-`LL8 %lrI!h'JyFA(kpl6+(~Ξk$DIYpx`3 #Ǡ2?o'ɔ߻OCnݺpl6#OzIKOY@i{~4oZl^ 5U< `h G٥k]pHpNnnŃ'LessW2ӠAWGzU~mk'կQ=8)3 ɋ/Zj!/\k"fMWwuPPPn>y $@Dʹ85yCS09Ns aDɹ}zr^=W:s)uR L#^q9jI???QMFpSE{h,iZҢe 9]:7BFV=fܘ.njޫjsdLrm\/<@HHHy|SZ}4o\L2q ~j_~|}ՙjM Y]e7tVUcfA@\T o*W6)ߨ,׆ª]a&LlB8\ կ_*.ʙ ~GF)hlkh)c#:.+.y:Nc)Fz=M7xzzʕQM*FoA1 @n$! vb3\\#SkJq K^L1pZ\PˡCx'C8y$Ij09uУ+B\tS۷+m޴"(BZ)Sx`@8= LAҪ0 uV\=dffj3222 %YS\Fj9%%%匠\/66֥Q>aXP ZN{wLRRe^A.nݪڻWx>jjs"@6Ou%RXl{(rvRX.=h߮t(.]ԌU=\xEwώZ8@#--M6t췧3_FF}JS!GsNZ L85OQ\|ɰ!ӿon~FF;)&Vc߾}=F]دO(ʹѣFw`U)RB߿gNwl|\GM?ۻw޽YIe;f5uᆹ@ӦM4𔿿bB.^B Q ;O8iy~&s/k/6ibV7|}}K$={9^Y杲{3{\!O(=Wr#^ʍzǎCG+ջw{{G]k6XmV]Nvwvv۷+F 8p+B<(2)j@2YF9y23m޺vZC^:[n {EI ћ> m)&|Y|΀~G%|, `(I@?8_*Fus'Mnr @FsDINu>l?ӡCÏ.oFxn:(xoǶS^^^)ǎ{|ra-|/% 6…}l~¹YM1pys5Xd8kl&X2Y@_QbwM+ߍ36 lZX"/Qcʥ?:Ŗgffju6(۸lR@Lao8 pٿ@O\JP?LzkҨԚLYE9>0ͯl:?yMI8'ʌqZfkҟ(c;wwn떭}ݡIII ]&J:Yf*OYWhl^7qcu?zhG˲ǧY8,J/r>ry6tJQƍ&N[^^^ew| {M!`:*i˦AAA$f;#СCrrr(p$Jw]f wOӧo%6U~ϝ={68قY(JM]fKv}cǎUd'͎9*--Q {(F*ccZf߾rNAA<&Sv+`M>G('?F{ɞ Qx/@0 UºRfT%ZVY/BS@C֋[C QAOKW?Y/BS_:J z"V!ΌWJŠV z-((Wl`զRSS_|989)9899Y}v0J;xw=Gڶk\ҿo͚57 b8Sv` WPj^,@邏3ϡ|XU /:=z4UHPřUYU kWUwC)&)))322ܝe$cU)RLVe8þl޴۷+)۶mk W_5g5)RfBӤ$Uljj'd5)RB,״ӞQ>̚9ѝ;wHiػwog5 +HR0~j;y͛XE <Ki<ŬQ/o QӘ_J;wTd(R\rW_y5J cF :j)Cn:x%JƍQ)[l6?m\wo9)??E(?i⤩1kc*+i\{ א)YYY M4ahԨQFY$Iş,~">>Mʍ:LOAXzhژ;;{5WBCCE[nÎ;gϞ]<')((`ogqc2/ IKK Q 6[tJ__| .??_=<]l6wK*@r׬B:`e&OuVMpp>Ks͝1Xnc\R [7^3|l(r(6.vvHHHo0~Rv-&@J?v\hQ~hڂu-UVV ŠU+橽oV/ 9R/Jx:~zۊU+}Ye F >'/(((wsZmMxӫ_>ض]<զ=},]u欙+W|U] zVe)'frʫ"""Rnt Ovnnǯu}>cRv"[t}\rNqP.{?^__|__ LpzxO|QK.Z̅p^(ª1 Lg E ,PΏ +Vb ω^!C +V peD8?^/ S ! P BB(B@!! P# O W^e.s LAs"sO2ٱcG5@8Nx)<3 INNv*L;VA:/5g+7o| ˄' Z< H)7RۯF2YI"R|n/x_NN`萡6o<pI=92"r]i׮Y[%2"?mPPPC!GC`\Jxl6\Z+t:Yj|rdKMDZ+#kFH!JZRY/BS߀K z^8zN^(%m!)+D!!UQ+i!%{ s֍e]/iX?BJQkqfQn[_R*: Jbɬ#!brav=ZR"!ÉtYB]O=xʱ7ii)&?MX[BWEI(džrQZz!&/!e(oʵ13v֘"^#!` ?8YQ3ܨ+g O7CpXW?C" @Ϲ@\ؑP3P"|C qv%g ?_8?KTB+fpj@_!NIs|)JEISkd yDTm*uy/`j&4P@u!܃m).8 vQϫa決qX5IENDB`uTox-0.17.1/src/android/window.c000066400000000000000000000021101354126257400164240ustar00rootroot00000000000000#include "../window.h" #include #include bool native_window_init(void) { return true; } static UTOX_WINDOW *native_window_create(UTOX_WINDOW *window, char *title, unsigned int class, int x, int y, int w, int h, int min_width, int min_height, void *gui_panel, bool override) { return NULL; } void native_window_raze(UTOX_WINDOW *window) { } UTOX_WINDOW *native_window_create_main(int x, int y, int w, int h, char **argv, int argc) { return NULL; } void native_window_create_video() { return; } UTOX_WINDOW *native_window_find_notify(void *window) { return NULL; } UTOX_WINDOW *native_window_create_notify(int x, int y, int w, int h, void* panel) { return NULL; } static void notify_tween_thread(void *obj) { } void window_set_focus(UTOX_WINDOW *win) { } void native_window_tween(UTOX_WINDOW *win) { } void native_window_create_screen_select() { } bool native_window_set_target(UTOX_WINDOW *new_win) { return true; } void native_screen_grab_desktop(bool video) { } uTox-0.17.1/src/av/000077500000000000000000000000001354126257400137455ustar00rootroot00000000000000uTox-0.17.1/src/av/CMakeLists.txt000066400000000000000000000016721354126257400165130ustar00rootroot00000000000000project(utoxAV LANGUAGES C) add_library(utoxAV STATIC utox_av.c audio.c video.c filter_audio.c ) if(WIN32) target_link_libraries(utoxAV OpenAL32) # Windows needs to be linked against OpenAL32 elseif(APPLE) find_package(libopus REQUIRED) include_directories(${LIBOPUS_INCLUDE_DIRS}) target_link_libraries(utoxAV ${LIBOPUS_LIBRARIES}) # Link OSX against opus else() # Both openal and opus are required for the static Linux builds on Jenkins. find_package(libopus REQUIRED) include_directories(${LIBOPUS_INCLUDE_DIRS}) target_link_libraries(utoxAV ${LIBOPUS_LIBRARIES}) find_package(OpenAL REQUIRED) include_directories(${OPENAL_INCLUDE_DIR}) target_link_libraries(utoxAV ${OPENAL_LIBRARY}) endif() if(ENABLE_FILTERAUDIO) find_package(libfilteraudio REQUIRED) include_directories(${LIBFILTERAUDIO_INCLUDE_DIRS}) target_link_libraries(utoxAV ${LIBFILTERAUDIO_LIBRARIES}) endif() uTox-0.17.1/src/av/audio.c000066400000000000000000001007411354126257400152150ustar00rootroot00000000000000#include "audio.h" #include "utox_av.h" #include "filter_audio.h" #include "../native/audio.h" #include "../native/keyboard.h" #include "../native/thread.h" #include "../native/time.h" #include "../debug.h" #include "../friend.h" #include "../groups.h" #include "../macros.h" #include "../main.h" // USER_STATUS_* #include "../self.h" #include "../settings.h" #include "../tox.h" #include "../utox.h" #include "../../langs/i18n_decls.h" #include #include #include #include #ifdef __APPLE__ #include #include #else #include #include #ifdef AUDIO_FILTERING #include #endif /* include for compatibility with older versions of OpenAL */ #ifndef ALC_ALL_DEVICES_SPECIFIER #include #endif #endif #ifdef AUDIO_FILTERING #include #endif static void utox_filter_audio_kill(Filter_Audio *filter_audio_handle) { #ifdef AUDIO_FILTERING kill_filter_audio(filter_audio_handle); #else (void)filter_audio_handle; #endif } bool utox_audio_thread_init = false; static ALCdevice *audio_out_handle, *audio_in_handle; static void * audio_out_device, *audio_in_device; static bool speakers_on, microphone_on; static int16_t speakers_count, microphone_count; /* TODO hacky fix. This source list should be a VLA with a way to link sources to friends. * NO SRSLY don't leave this like this! */ static ALuint ringtone, preview, notifytone; static ALuint RingBuffer, ToneBuffer; static bool audio_in_device_open(void) { if (!audio_in_device) { return false; } if (audio_in_device == (void *)1) { audio_in_handle = (void *)1; return true; } alGetError(); audio_in_handle = alcCaptureOpenDevice(audio_in_device, UTOX_DEFAULT_SAMPLE_RATE_A, AL_FORMAT_MONO16, (UTOX_DEFAULT_FRAME_A * UTOX_DEFAULT_SAMPLE_RATE_A * 4) / 1000); if (alGetError() == AL_NO_ERROR) { return true; } return false; } static bool audio_in_device_close(void) { if (audio_in_handle) { if (audio_in_handle == (void *)1) { audio_in_handle = NULL; microphone_on = false; return false; } if (microphone_on) { alcCaptureStop(audio_in_handle); } alcCaptureCloseDevice(audio_in_handle); } audio_in_handle = NULL; microphone_on = false; return false; } static bool audio_in_listen(void) { if (microphone_on) { microphone_count++; return true; } if (audio_in_handle) { if (audio_in_device == (void *)1) { audio_init(audio_in_handle); return true; } alcCaptureStart(audio_in_handle); } else if (audio_in_device) { /* Unable to get handle, try to open it again. */ audio_in_device_open(); if (audio_in_handle) { alcCaptureStart(audio_in_handle); } else { LOG_TRACE("uTox Audio", "Unable to listen to device!" ); } } if (audio_in_handle) { microphone_on = true; microphone_count = 1; return true; } microphone_on = false; microphone_count = 0; return false; } static bool audio_in_ignore(void) { if (!microphone_on) { return false; } if (--microphone_count > 0) { return true; } if (audio_in_handle) { if (audio_in_handle == (void *)1) { audio_close(audio_in_handle); microphone_on = false; microphone_count = 0; return false; } alcCaptureStop(audio_in_handle); } microphone_on = false; microphone_count = 0; return false; } bool utox_audio_in_device_set(ALCdevice *new_device) { if (microphone_on || microphone_count) { return false; } if (new_device) { audio_in_device = new_device; LOG_TRACE("uTox Audio", "Audio in device changed." ); return true; } audio_in_device = NULL; audio_in_handle = NULL; LOG_ERR("uTox Audio", "Audio out device set to null." ); return false; } ALCdevice *utox_audio_in_device_get(void) { if (audio_in_handle) { return audio_in_device; } return NULL; } static ALCcontext *context; static bool audio_out_device_open(void) { if (speakers_on) { speakers_count++; return true; } audio_out_handle = alcOpenDevice(audio_out_device); if (!audio_out_handle) { LOG_TRACE("uTox Audio", "alcOpenDevice() failed" ); speakers_on = false; return false; } context = alcCreateContext(audio_out_handle, NULL); if (!alcMakeContextCurrent(context)) { LOG_TRACE("uTox Audio", "alcMakeContextCurrent() failed" ); alcCloseDevice(audio_out_handle); audio_out_handle = NULL; speakers_on = false; return false; } ALint error; alGetError(); /* clear errors */ /* Create the buffers for the ringtone */ alGenSources((ALuint)1, &preview); if ((error = alGetError()) != AL_NO_ERROR) { LOG_TRACE("uTox Audio", "Error generating source with err %x" , error); speakers_on = false; speakers_count = 0; return false; } /* Create the buffers for incoming audio */ alGenSources((ALuint)1, &ringtone); if ((error = alGetError()) != AL_NO_ERROR) { LOG_TRACE("uTox Audio", "Error generating source with err %x" , error); speakers_on = false; speakers_count = 0; return false; } alGenSources((ALuint)1, ¬ifytone); if ((error = alGetError()) != AL_NO_ERROR) { LOG_TRACE("uTox Audio", "Error generating source with err %x" , error); speakers_on = false; speakers_count = 0; return false; } speakers_on = true; speakers_count = 1; return true; } static bool audio_out_device_close(void) { if (!audio_out_handle) { return false; } if (!speakers_on) { return false; } if (--speakers_count > 0) { return true; } alDeleteSources((ALuint)1, &preview); alDeleteSources((ALuint)1, &ringtone); alDeleteSources((ALuint)1, ¬ifytone); alcMakeContextCurrent(NULL); alcDestroyContext(context); alcCloseDevice(audio_out_handle); audio_out_handle = NULL; speakers_on = false; speakers_count = 0; return false; } bool utox_audio_out_device_set(ALCdevice *new_device) { if (new_device) { audio_out_device = new_device; LOG_TRACE("uTox Audio", "Audio out device changed." ); return true; } audio_out_device = NULL; audio_out_handle = NULL; LOG_TRACE("uTox Audio", "Audio in device set to null." ); return false; } ALCdevice *utox_audio_out_device_get(void) { if (audio_out_handle) { return audio_out_device; } return NULL; } void sourceplaybuffer(unsigned int f, const int16_t *data, int samples, uint8_t channels, unsigned int sample_rate) { if (!channels || channels > 2) { return; } ALuint source; if (f >= self.friend_list_size) { source = preview; } else { source = get_friend(f)->audio_dest; } ALuint bufid; ALint processed = 0, queued = 16; alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); alSourcei(source, AL_LOOPING, AL_FALSE); if (processed) { ALuint bufids[processed]; alSourceUnqueueBuffers(source, processed, bufids); alDeleteBuffers(processed - 1, bufids + 1); bufid = bufids[0]; } else if (queued < 16) { alGenBuffers(1, &bufid); } else { LOG_TRACE("uTox Audio", "dropped audio frame" ); return; } alBufferData(bufid, (channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, data, samples * 2 * channels, sample_rate); alSourceQueueBuffers(source, 1, &bufid); // LOG_TRACE("uTox Audio", "audio frame || samples == %i channels == %u rate == %u " , samples, channels, sample_rate); ALint state; alGetSourcei(source, AL_SOURCE_STATE, &state); if (state != AL_PLAYING) { alSourcePlay(source); // LOG_TRACE("uTox Audio", "Starting source %u" , i); } } static void audio_in_init(void) { const char *audio_in_device_list; audio_in_device_list = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER); if (audio_in_device_list) { audio_in_device = (void *)audio_in_device_list; LOG_TRACE("uTox Audio", "input device list:" ); while (*audio_in_device_list) { LOG_TRACE("uTox Audio", "\t%s" , audio_in_device_list); postmessage_utox(AUDIO_IN_DEVICE, UI_STRING_ID_INVALID, 0, (void *)audio_in_device_list); audio_in_device_list += strlen(audio_in_device_list) + 1; } } postmessage_utox(AUDIO_IN_DEVICE, STR_AUDIO_IN_NONE, 0, NULL); audio_detect(); /* Get audio devices for windows */ } static void audio_out_init(void) { const char *audio_out_device_list; if (alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT")) { audio_out_device_list = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER); } else { audio_out_device_list = alcGetString(NULL, ALC_DEVICE_SPECIFIER); } if (audio_out_device_list) { audio_out_device = (void *)audio_out_device_list; LOG_TRACE("uTox Audio", "output device list:" ); while (*audio_out_device_list) { LOG_TRACE("uTox Audio", "\t%s" , audio_out_device_list); postmessage_utox(AUDIO_OUT_DEVICE, 0, 0, (void *)audio_out_device_list); audio_out_device_list += strlen(audio_out_device_list) + 1; } } audio_out_handle = alcOpenDevice(audio_out_device); if (!audio_out_handle) { LOG_TRACE("uTox Audio", "alcOpenDevice() failed" ); return; } int attrlist[] = { ALC_FREQUENCY, UTOX_DEFAULT_SAMPLE_RATE_A, ALC_INVALID }; context = alcCreateContext(audio_out_handle, attrlist); if (!alcMakeContextCurrent(context)) { LOG_TRACE("uTox Audio", "alcMakeContextCurrent() failed" ); alcCloseDevice(audio_out_handle); return; } // ALint error; // alGetError(); /* clear errors */ // alGenSources((ALuint)1, &ringtone); // if ((error = alGetError()) != AL_NO_ERROR) { // LOG_TRACE("uTox Audio", "Error generating source with err %x" , error); // return; // } // alGenSources((ALuint)1, &preview); // if ((error = alGetError()) != AL_NO_ERROR) { // LOG_TRACE("uTox Audio", "Error generating source with err %x" , error); // return; // } alcCloseDevice(audio_out_handle); } static bool audio_source_init(ALuint *source) { ALint error; alGetError(); alGenSources((ALuint)1, source); if ((error = alGetError()) != AL_NO_ERROR) { LOG_TRACE("uTox Audio", "Error generating source with err %x" , error); return false; } return true; } static void audio_source_raze(ALuint *source) { LOG_INFO("Audio", "Deleting source"); alDeleteSources((ALuint)1, source); } // clang-format off enum { NOTE_none, NOTE_c3_sharp, NOTE_g3, NOTE_b3, NOTE_c4, NOTE_a4, NOTE_b4, NOTE_e4, NOTE_f4, NOTE_c5, NOTE_d5, NOTE_e5, NOTE_f5, NOTE_g5, NOTE_a5, NOTE_c6_sharp, NOTE_e6, }; static struct { uint8_t note; double freq; } notes[] = { {NOTE_none, 1 }, /* Can't be 0 or openal will skip this note/time */ {NOTE_c3_sharp, 138.59 }, {NOTE_g3, 196.00 }, {NOTE_b3, 246.94 }, {NOTE_c4, 261.63 }, {NOTE_a4, 440.f }, {NOTE_b4, 493.88 }, {NOTE_e4, 329.63 }, {NOTE_f4, 349.23 }, {NOTE_c5, 523.25 }, {NOTE_d5, 587.33 }, {NOTE_e5, 659.25 }, {NOTE_f5, 698.46 }, {NOTE_g5, 783.99 }, {NOTE_a5, 880.f }, {NOTE_c6_sharp, 1108.73 }, {NOTE_e6, 1318.51 }, }; static struct melodies { /* C99 6.7.8/10 uninitialized arithmetic types are 0 this is what we want. */ uint8_t count; uint8_t volume; uint8_t fade; uint8_t notes[8]; } normal_ring[16] = { {1, 14, 1, {NOTE_f5, }}, {1, 14, 1, {NOTE_f5, }}, {1, 14, 1, {NOTE_f5, }}, {1, 14, 1, {NOTE_c6_sharp, }}, {1, 14, 0, {NOTE_c5, }}, {1, 14, 1, {NOTE_c5, }}, {0, 0, 0, {0, }}, }, friend_offline[4] = { {1, 14, 1, {NOTE_c4, }}, {1, 14, 1, {NOTE_g3, }}, {1, 14, 1, {NOTE_g3, }}, {0, 0, 0, {0, }}, }, friend_online[4] = { {1, 14, 0, {NOTE_g3, }}, {1, 14, 1, {NOTE_g3, }}, {1, 14, 1, {NOTE_a4, }}, {1, 14, 1, {NOTE_b4, }}, }, friend_new_msg[8] = { {1, 0, 0, {0, }}, /* 3/8 sec of silence for spammy friends */ {1, 0, 0, {0, }}, {1, 0, 0, {0, }}, {1, 9, 0, {NOTE_g5, }}, {1, 9, 1, {NOTE_g5, }}, {1, 12, 1, {NOTE_a4, }}, {1, 10, 1, {NOTE_a4, }}, {1, 0, 0, {0, }}, }, friend_request[8] = { {1, 9, 0, {NOTE_g5, }}, {1, 9, 1, {NOTE_g5, }}, {1, 12, 1, {NOTE_b3, }}, {1, 10, 1, {NOTE_b3, }}, {1, 9, 0, {NOTE_g5, }}, {1, 9, 1, {NOTE_g5, }}, {1, 12, 1, {NOTE_b3, }}, {1, 10, 0, {NOTE_b3, }}, }; // clang-format on typedef struct melodies MELODY; // TODO: These should be functions rather than macros that only work in a specific context. #define FADE_STEP_OUT() (1 - ((double)(index % (sample_rate / notes_per_sec)) / (sample_rate / notes_per_sec))) #define FADE_STEP_IN() (((double)(index % (sample_rate / notes_per_sec)) / (sample_rate / notes_per_sec))) // GEN_NOTE_RAW is unused. Delete? #define GEN_NOTE_RAW(x, a) ((a * base_amplitude) * (sin((tau * x) * index / sample_rate))) #define GEN_NOTE_NUM(x, a) ((a * base_amplitude) * (sin((tau * notes[x].freq) * index / sample_rate))) #define GEN_NOTE_NUM_FADE(x, a) \ ((a * base_amplitude * FADE_STEP_OUT()) * (sin((tau * notes[x].freq) * index / sample_rate))) // GEN_NOTE_NUM_FADE_IN is unused. Delete? #define GEN_NOTE_NUM_FADE_IN(x, a) \ ((a * base_amplitude * FADE_STEP_IN()) * (sin((tau * notes[x].freq) * index / sample_rate))) static void generate_melody(MELODY melody[], uint32_t seconds, uint32_t notes_per_sec, ALuint *target) { ALint error; alGetError(); /* clear errors */ alGenBuffers((ALuint)1, target); if ((error = alGetError()) != AL_NO_ERROR) { LOG_TRACE("uTox Audio", "Error generating buffer with err %i" , error); return; } const uint32_t sample_rate = 22000; const uint32_t base_amplitude = 1000; const double tau = 6.283185307179586476925286766559; const size_t buf_size = seconds * sample_rate * 2; // 16 bit (2 bytes per sample) int16_t *samples = calloc(buf_size, sizeof(int16_t)); if (!samples) { LOG_TRACE("uTox Audio", "Unable to generate ringtone buffer!" ); return; } for (uint64_t index = 0; index < buf_size; ++index) { /* index / sample rate `mod` seconds. will give you full second long notes * you can change the length each tone is played by changing notes_per_sec * but you'll need to add additional case to cover the entire span of time */ const int position = ((index / (sample_rate / notes_per_sec)) % (seconds * notes_per_sec)); for (int i = 0; i < melody[position].count; ++i) { if (melody[position].fade) { samples[index] += GEN_NOTE_NUM_FADE(melody[position].notes[i], melody[position].volume); } else { samples[index] += GEN_NOTE_NUM(melody[position].notes[i], melody[position].volume); } } } alBufferData(*target, AL_FORMAT_MONO16, samples, buf_size, sample_rate); free(samples); } static void generate_tone_call_ringtone() { generate_melody(normal_ring, 4, 4, &RingBuffer); } static void generate_tone_friend_offline() { generate_melody(friend_offline, 1, 4, &ToneBuffer); } static void generate_tone_friend_online() { generate_melody(friend_online, 1, 4, &ToneBuffer); } static void generate_tone_friend_new_msg() { generate_melody(friend_new_msg, 1, 8, &ToneBuffer); } static void generate_tone_friend_request() { generate_melody(friend_request, 1, 8, &ToneBuffer); } void postmessage_audio(uint8_t msg, uint32_t param1, uint32_t param2, void *data) { while (audio_thread_msg && utox_audio_thread_init) { yieldcpu(1); } audio_msg.msg = msg; audio_msg.param1 = param1; audio_msg.param2 = param2; audio_msg.data = data; audio_thread_msg = 1; } // TODO: This function is 300 lines long. Cut it up. void utox_audio_thread(void *args) { time_t close_device_time = 0; ToxAV *av = args; #ifdef AUDIO_FILTERING LOG_INFO("uTox Audio", "Audio Filtering" #ifdef ALC_LOOPBACK_CAPTURE_SAMPLES " and Echo cancellation" #endif " enabled in this build" ); #endif // bool call[MAX_CALLS] = {0}, preview = 0; const int perframe = (UTOX_DEFAULT_FRAME_A * UTOX_DEFAULT_SAMPLE_RATE_A) / 1000; uint8_t buf[perframe * 2 * UTOX_DEFAULT_AUDIO_CHANNELS]; //, dest[perframe * 2 * UTOX_DEFAULT_AUDIO_CHANNELS]; memset(buf, 0, sizeof(buf)); LOG_TRACE("uTox Audio", "frame size: %u" , perframe); /* init Microphone */ audio_in_init(); // audio_in_device_open(); // audio_in_listen(); /* init Speakers */ audio_out_init(); // audio_out_device_open(); // audio_out_device_close(); #define PREVIEW_BUFFER_SIZE (UTOX_DEFAULT_SAMPLE_RATE_A / 2) int16_t *preview_buffer = calloc(PREVIEW_BUFFER_SIZE, 2); if (!preview_buffer) { LOG_ERR("uTox Audio", "Unable to allocate memory for preview buffer."); return; } unsigned int preview_buffer_index = 0; bool preview_on = false; utox_audio_thread_init = true; while (1) { if (audio_thread_msg) { const TOX_MSG *m = &audio_msg; if (m->msg == UTOXAUDIO_KILL) { break; } int call_ringing = 0; switch (m->msg) { case UTOXAUDIO_CHANGE_MIC: { while (audio_in_ignore()) { continue; } while (audio_in_device_close()) { continue; } break; } case UTOXAUDIO_CHANGE_SPEAKER: { while (audio_out_device_close()) { continue; } break; } case UTOXAUDIO_START_FRIEND: { FRIEND *f = get_friend(m->param1); if (f && !f->audio_dest) { audio_source_init(&f->audio_dest); } audio_out_device_open(); audio_in_listen(); break; } case UTOXAUDIO_STOP_FRIEND: { FRIEND *f = get_friend(m->param1); if (f && f->audio_dest) { audio_source_raze(&f->audio_dest); f->audio_dest = 0; } audio_in_ignore(); audio_out_device_close(); break; } case UTOXAUDIO_GROUPCHAT_START: { LOG_DEBUG("Audio", "Starting Groupchat Audio %u", m->param1); GROUPCHAT *g = get_group(m->param1); if (!g) { LOG_ERR("uTox Audio", "Could not get group %u", m->param1); break; } if (!g->audio_dest) { audio_source_init(&g->audio_dest); } audio_out_device_open(); audio_in_listen(); break; } case UTOXAUDIO_GROUPCHAT_STOP: { LOG_DEBUG("Audio", "Stopping Groupchat Audio %u", m->param1); GROUPCHAT *g = get_group(m->param1); if (!g) { LOG_ERR("uTox Audio", "Could not get group %u", m->param1); break; } if (g->audio_dest) { audio_source_raze(&g->audio_dest); g->audio_dest = 0; } audio_in_ignore(); audio_out_device_close(); break; } case UTOXAUDIO_START_PREVIEW: { preview_on = true; audio_out_device_open(); audio_in_listen(); break; } case UTOXAUDIO_STOP_PREVIEW: { preview_on = false; audio_in_ignore(); audio_out_device_close(); break; } case UTOXAUDIO_PLAY_RINGTONE: { if (settings.ringtone_enabled && self.status != USER_STATUS_DO_NOT_DISTURB) { LOG_INFO("uTox Audio", "Going to start ringtone!" ); audio_out_device_open(); generate_tone_call_ringtone(); alSourcei(ringtone, AL_LOOPING, AL_TRUE); alSourcei(ringtone, AL_BUFFER, RingBuffer); alSourcePlay(ringtone); call_ringing++; } break; } case UTOXAUDIO_STOP_RINGTONE: { call_ringing--; LOG_INFO("uTox Audio", "Going to stop ringtone!" ); alSourceStop(ringtone); yieldcpu(5); audio_out_device_close(); break; } case UTOXAUDIO_PLAY_NOTIFICATION: { if (settings.ringtone_enabled && self.status == USER_STATUS_AVAILABLE) { LOG_INFO("uTox Audio", "Going to start notification tone!" ); if (close_device_time <= time(NULL)) { audio_out_device_open(); } switch (m->param1) { case NOTIFY_TONE_FRIEND_ONLINE: { generate_tone_friend_online(); break; } case NOTIFY_TONE_FRIEND_OFFLINE: { generate_tone_friend_offline(); break; } case NOTIFY_TONE_FRIEND_NEW_MSG: { generate_tone_friend_new_msg(); break; } case NOTIFY_TONE_FRIEND_REQUEST: { generate_tone_friend_request(); break; } } alSourcei(notifytone, AL_LOOPING, AL_FALSE); alSourcei(notifytone, AL_BUFFER, ToneBuffer); alSourcePlay(notifytone); time(&close_device_time); close_device_time += 10; LOG_INFO("uTox Audio", "close device set!" ); } break; } case UTOXAUDIO_STOP_NOTIFICATION: { break; } case UTOXAUDIO_NEW_AV_INSTANCE: { av = m->data; audio_in_init(); audio_out_init(); } } audio_thread_msg = 0; if (close_device_time && time(NULL) >= close_device_time) { LOG_INFO("uTox Audio", "close device triggered!" ); audio_out_device_close(); close_device_time = 0; } } settings.audiofilter_enabled = filter_audio_check(); bool sleep = true; if (microphone_on) { ALint samples; bool frame = 0; /* If we have a device_in we're on linux so we can just call OpenAL, otherwise we're on something else so * we'll need to call audio_frame() to add to the buffer for us. */ if (audio_in_handle == (void *)1) { frame = audio_frame((void *)buf); if (frame) { /* We have an audio frame to use, continue without sleeping. */ sleep = false; } } else { alcGetIntegerv(audio_in_handle, ALC_CAPTURE_SAMPLES, sizeof(samples), &samples); if (samples >= perframe) { alcCaptureSamples(audio_in_handle, buf, perframe); frame = true; if (samples >= perframe * 2) { sleep = false; } } } #ifdef AUDIO_FILTERING #ifdef ALC_LOOPBACK_CAPTURE_SAMPLES if (f_a && settings.audiofilter_enabled) { alcGetIntegerv(audio_out_device, ALC_LOOPBACK_CAPTURE_SAMPLES, sizeof(samples), &samples); if (samples >= perframe) { int16_t buffer[perframe]; alcCaptureSamplesLoopback(audio_out_handle, buffer, perframe); pass_audio_output(f_a, buffer, perframe); set_echo_delay_ms(f_a, UTOX_DEFAULT_FRAME_A); if (samples >= perframe * 2) { sleep = false; } } } #endif #endif if (frame) { bool voice = true; #ifdef AUDIO_FILTERING if (f_a) { const int ret = filter_audio(f_a, (int16_t *)buf, perframe); if (ret == -1) { LOG_TRACE("uTox Audio", "filter audio error" ); } if (ret == 0) { voice = false; } } #endif /* If push to talk, we don't have to do anything */ if (!check_ptt_key()) { voice = false; // PTT is up, send nothing. } if (preview_on) { if (preview_buffer_index + perframe > PREVIEW_BUFFER_SIZE) { preview_buffer_index = 0; } sourceplaybuffer(self.friend_list_size, preview_buffer + preview_buffer_index, perframe, UTOX_DEFAULT_AUDIO_CHANNELS, UTOX_DEFAULT_SAMPLE_RATE_A); if (voice) { memcpy(preview_buffer + preview_buffer_index, buf, perframe * sizeof(int16_t)); } else { memset(preview_buffer + preview_buffer_index, 0, perframe * sizeof(int16_t)); } preview_buffer_index += perframe; } if (voice) { size_t active_call_count = 0; for (size_t i = 0; i < self.friend_list_count; i++) { if (UTOX_SEND_AUDIO(i)) { active_call_count++; TOXAV_ERR_SEND_FRAME error = 0; // LOG_TRACE("uTox Audio", "Sending audio frame!" ); FRIEND *f = get_friend(i); if (!f) { LOG_ERR("uToxAV", "Unable to get friend when sending audio frame %u", i); continue; } toxav_audio_send_frame(av, f->number, (const int16_t *)buf, perframe, UTOX_DEFAULT_AUDIO_CHANNELS, UTOX_DEFAULT_SAMPLE_RATE_A, &error); if (error) { LOG_TRACE("uTox Audio", "toxav_send_audio error friend == %lu, error == %i" , i, error); } else { // LOG_TRACE("uTox Audio", "Send a frame to friend %i" ,i); if (active_call_count >= UTOX_MAX_CALLS) { LOG_TRACE("uTox Audio", "We're calling more peers than allowed by UTOX_MAX_CALLS, This is a bug" ); break; } } } } Tox *tox = toxav_get_tox(av); uint32_t num_chats = tox_conference_get_chatlist_size(tox); if (num_chats) { for (size_t i = 0 ; i < num_chats; ++i) { if (get_group(i) && get_group(i)->active_call) { LOG_TRACE("uTox Audio", "Sending audio in groupchat %u", i); toxav_group_send_audio(tox, i, (int16_t *)buf, perframe, UTOX_DEFAULT_AUDIO_CHANNELS, UTOX_DEFAULT_SAMPLE_RATE_A); } } } } } } if (sleep) { yieldcpu(50); } } utox_filter_audio_kill(f_a); // missing some cleanup ? alDeleteSources(1, &ringtone); alDeleteSources(1, &preview); alDeleteBuffers(1, &RingBuffer); while (audio_in_device_close()) { continue; } while (audio_out_device_close()) {continue; } audio_thread_msg = 0; utox_audio_thread_init = false; free(preview_buffer); LOG_TRACE("uTox Audio", "Clean thread exit!"); } void callback_av_group_audio(void *UNUSED(tox), uint32_t groupnumber, uint32_t peernumber, const int16_t *pcm, unsigned int samples, uint8_t channels, unsigned int sample_rate, void *UNUSED(userdata)) { GROUPCHAT *g = get_group(groupnumber); if (!g) { LOG_ERR("uTox Audio", "Could not get group with number: %i", groupnumber); return; } LOG_INFO("uTox Audio", "Received audio in groupchat %i from peer %i", groupnumber, peernumber); if (!g->active_call) { LOG_INFO("uTox Audio", "Packets for inactive call %u", groupnumber); return; } uint64_t time = get_time(); if (time - g->last_recv_audio[peernumber] > (uint64_t)1 * 1000 * 1000 * 1000) { postmessage_utox(GROUP_UPDATE, groupnumber, peernumber, NULL); } g->last_recv_audio[peernumber] = time; if (channels < 1 || channels > 2) { LOG_ERR("uTox Audio", "Can't continue, with channel > 2 or < 1."); return; } if (g->muted) { LOG_INFO("uTox Audio", "Group %u audio muted.", groupnumber); return; } ALuint bufid; ALint processed = 0, queued = 16; alGetSourcei(g->source[peernumber], AL_BUFFERS_PROCESSED, &processed); alGetSourcei(g->source[peernumber], AL_BUFFERS_QUEUED, &queued); alSourcei(g->source[peernumber], AL_LOOPING, AL_FALSE); if (processed) { ALuint bufids[processed]; alSourceUnqueueBuffers(g->source[peernumber], processed, bufids); alDeleteBuffers(processed - 1, bufids + 1); bufid = bufids[0]; } else if(queued < 16) { alGenBuffers(1, &bufid); } else { LOG_WARN("uTox Audio", "dropped audio frame %i %i" , groupnumber, peernumber); return; } alBufferData(bufid, (channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, pcm, samples * 2 * channels, sample_rate); alSourceQueueBuffers(g->source[peernumber], 1, &bufid); ALint state; alGetSourcei(g->source[peernumber], AL_SOURCE_STATE, &state); if (state != AL_PLAYING) { alSourcePlay(g->source[peernumber]); LOG_DEBUG("uTox Audio", "Starting source %i %i" , groupnumber, peernumber); } } void group_av_peer_add(GROUPCHAT *g, int peernumber) { if (!g || peernumber < 0) { LOG_ERR("uTox Audio", "Invalid groupchat or peer number"); return; } LOG_INFO("uTox Audio", "Adding source for peer %u in group %u", peernumber, g->number); alGenSources(1, &g->source[peernumber]); } void group_av_peer_remove(GROUPCHAT *g, int peernumber) { if (!g || peernumber < 0) { LOG_ERR("uTox Audio", "Invalid groupchat or peer number"); return; } LOG_INFO("uTox Audio", "Deleting source for peer %u in group %u", peernumber, g->number); alDeleteSources(1, &g->source[peernumber]); } uTox-0.17.1/src/av/audio.h000066400000000000000000000052521354126257400152230ustar00rootroot00000000000000#ifndef AUDIO_H #define AUDIO_H #include #include #include typedef struct ALCdevice_struct ALCdevice; extern bool utox_audio_thread_init; enum { // kill the audio thread UTOXAUDIO_KILL, UTOXAUDIO_CHANGE_MIC, UTOXAUDIO_CHANGE_SPEAKER, UTOXAUDIO_START_FRIEND, UTOXAUDIO_STOP_FRIEND, UTOXAUDIO_GROUPCHAT_START, UTOXAUDIO_GROUPCHAT_STOP, UTOXAUDIO_START_PREVIEW, UTOXAUDIO_STOP_PREVIEW, UTOXAUDIO_PLAY_RINGTONE, UTOXAUDIO_STOP_RINGTONE, UTOXAUDIO_PLAY_NOTIFICATION, UTOXAUDIO_STOP_NOTIFICATION, UTOXAUDIO_NEW_AV_INSTANCE, }; enum { NOTIFY_TONE_NONE, NOTIFY_TONE_FRIEND_ONLINE, NOTIFY_TONE_FRIEND_OFFLINE, NOTIFY_TONE_FRIEND_NEW_MSG, NOTIFY_TONE_FRIEND_REQUEST, }; #define UTOX_DEFAULT_BITRATE_A 32 #define UTOX_MIN_BITRATE_AUDIO UTOX_DEFAULT_BITRATE_A //TODO: Find out what the minimum bit rate should be #define UTOX_DEFAULT_FRAME_A 20 #define UTOX_DEFAULT_SAMPLE_RATE_A 48000 #define UTOX_DEFAULT_AUDIO_CHANNELS 1 /* Check self */ #define UTOX_SENDING_AUDIO(f_number) (!!(get_friend(f_number)->call_state_self & TOXAV_FRIEND_CALL_STATE_SENDING_A)) // UTOX_ACCEPTING_AUDIO is unused. Delete? #define UTOX_ACCEPTING_AUDIO(f_number) (!!(get_friend(f_number)->call_state_self & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A)) /* Check friend */ #define UTOX_AVAILABLE_AUDIO(f_number) (!!(get_friend(f_number)->call_state_friend & TOXAV_FRIEND_CALL_STATE_SENDING_A)) /* Check both */ #define UTOX_SEND_AUDIO(f_number) \ (!!(get_friend(f_number)->call_state_self & TOXAV_FRIEND_CALL_STATE_SENDING_A) \ && !!(get_friend(f_number)->call_state_friend & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A)) // UTOX_ACCEPT_AUDIO is unused. Delete? #define UTOX_ACCEPT_AUDIO(f_number) \ (!!(get_friend(f_number)->call_state_self & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A) \ && !!(get_friend(f_number)->call_state_friend & TOXAV_FRIEND_CALL_STATE_SENDING_A)) bool utox_audio_in_device_set(ALCdevice *new_device); bool utox_audio_out_device_set(ALCdevice *new_device); ALCdevice *utox_audio_in_device_get(void); // utox_audio_out_device_get is unused. Delete? ALCdevice *utox_audio_out_device_get(void); void utox_audio_in_device_open(void); void utox_audio_in_device_close(void); void utox_audio_in_listen(void); void utox_audio_in_ignore(void); void sourceplaybuffer(unsigned int i, const int16_t *data, int samples, uint8_t channels, unsigned int sample_rate); /* send a message to the audio thread */ void postmessage_audio(uint8_t msg, uint32_t param1, uint32_t param2, void *data); void utox_audio_thread(void *args); #endif uTox-0.17.1/src/av/filter_audio.c000066400000000000000000000015421354126257400165610ustar00rootroot00000000000000#include "filter_audio.h" #include "audio.h" #include "../settings.h" #include #ifdef AUDIO_FILTERING #include #endif Filter_Audio *f_a = NULL; bool filter_audio_check(void) { #ifdef AUDIO_FILTERING if (!f_a && settings.audiofilter_enabled) { f_a = new_filter_audio(UTOX_DEFAULT_SAMPLE_RATE_A); if (!f_a) { LOG_INFO("Filter Audio", "filter audio failed" ); return false; } LOG_INFO("Filter Audio", "filter audio on" ); } else if (f_a && !settings.audiofilter_enabled) { //no return is needed for this one because its already false kill_filter_audio(f_a); f_a = NULL; LOG_INFO("Filter Audio", "filter audio off" ); } return settings.audiofilter_enabled; //if there is no change return the current value #else return false; #endif } uTox-0.17.1/src/av/filter_audio.h000066400000000000000000000003711354126257400165650ustar00rootroot00000000000000#ifndef FILTER_AUDIO_H #define FILTER_AUDIO_H #include #ifdef AUDIO_FILTERING #include #else #include typedef uint8_t Filter_Audio; #endif extern Filter_Audio *f_a; bool filter_audio_check(void); #endif uTox-0.17.1/src/av/utox_av.c000066400000000000000000000552441354126257400156100ustar00rootroot00000000000000#include "utox_av.h" #include "audio.h" #include "video.h" #include "../debug.h" #include "../flist.h" #include "../friend.h" #include "../groups.h" #include "../inline_video.h" #include "../macros.h" #include "../tox.h" #include "../utox.h" #include "../ui.h" #include "../native/audio.h" #include "../native/thread.h" #include #include bool utox_av_ctrl_init = false; static bool toxav_thread_msg = 0; void postmessage_utoxav(uint8_t msg, uint32_t param1, uint32_t param2, void *data) { while (toxav_thread_msg && utox_av_ctrl_init) { /* I'm not convinced this is the best way */ yieldcpu(1); } toxav_msg.msg = msg; toxav_msg.param1 = param1; toxav_msg.param2 = param2; toxav_msg.data = data; toxav_thread_msg = 1; } void utox_av_ctrl_thread(void *UNUSED(args)) { ToxAV *av = NULL; utox_av_ctrl_init = 1; LOG_TRACE("uToxAv", "Toxav thread init" ); volatile uint32_t call_count = 0; volatile bool audio_in = 0; // volatile bool video_on = 0; while (1) { if (toxav_thread_msg) { TOX_MSG *msg = &toxav_msg; if (msg->msg == UTOXAV_KILL) { break; } else if (msg->msg == UTOXAV_NEW_TOX_INSTANCE) { if (av) { /* toxcore restart */ toxav_kill(av); postmessage_audio(UTOXAUDIO_NEW_AV_INSTANCE, 0, 0, msg->data); postmessage_video(UTOXVIDEO_NEW_AV_INSTANCE, 0, 0, msg->data); } else { thread(utox_audio_thread, msg->data); thread(utox_video_thread, msg->data); } av = msg->data; set_av_callbacks(av); } if (!utox_audio_thread_init || !utox_video_thread_init) { yieldcpu(10); } switch (msg->msg) { case UTOXAV_INCOMING_CALL_PENDING: { call_count++; postmessage_audio(UTOXAUDIO_PLAY_RINGTONE, msg->param1, msg->param2, NULL); break; } case UTOXAV_INCOMING_CALL_ANSWER: { FRIEND *f = get_friend(msg->param1); if (!f) { LOG_ERR("uToxAV", "Could not to get friend when INCOMING_CALL_ANSWER %u", msg->param1); break; } f->call_started = time(NULL); message_add_type_notice(&f->msg, S(CALL_STARTED), SLEN(CALL_STARTED), true); postmessage_audio(UTOXAUDIO_STOP_RINGTONE, msg->param1, msg->param2, NULL); postmessage_audio(UTOXAUDIO_START_FRIEND, msg->param1, msg->param2, NULL); f->call_state_self = (TOXAV_FRIEND_CALL_STATE_SENDING_A | TOXAV_FRIEND_CALL_STATE_ACCEPTING_A); if (msg->param2) { utox_video_start(0); f->call_state_self |= (TOXAV_FRIEND_CALL_STATE_SENDING_V | TOXAV_FRIEND_CALL_STATE_ACCEPTING_V); } break; } case UTOXAV_INCOMING_CALL_REJECT: { call_count--; postmessage_audio(UTOXAUDIO_STOP_RINGTONE, msg->param1, msg->param2, NULL); break; } case UTOXAV_OUTGOING_CALL_PENDING: { call_count++; postmessage_audio(UTOXAUDIO_PLAY_RINGTONE, msg->param1, msg->param2, NULL); FRIEND *f = get_friend(msg->param1); if (!f) { LOG_ERR("uToxAV", "Could not to get friend when OUTGOING_CALL_PENDING %u", msg->param1); break; } f->call_state_self = (TOXAV_FRIEND_CALL_STATE_SENDING_A | TOXAV_FRIEND_CALL_STATE_ACCEPTING_A); if (msg->param2) { utox_video_start(0); f->call_state_self |= (TOXAV_FRIEND_CALL_STATE_SENDING_V | TOXAV_FRIEND_CALL_STATE_ACCEPTING_V); } break; } case UTOXAV_OUTGOING_CALL_ACCEPTED: { FRIEND *f = get_friend(msg->param1); if (!f) { LOG_ERR("uToxAV", "Could not to get friend when OUTGOING_CALL_ACCEPTED %u", msg->param1); break; } f->call_started = time(NULL); message_add_type_notice(&f->msg, S(CALL_STARTED), SLEN(CALL_STARTED), true); postmessage_audio(UTOXAUDIO_START_FRIEND, msg->param1, msg->param2, NULL); postmessage_audio(UTOXAUDIO_STOP_RINGTONE, msg->param1, msg->param2, NULL); LOG_NOTE("uToxAV", "Call accepted by friend" ); break; } case UTOXAV_OUTGOING_CALL_REJECTED: { postmessage_audio(UTOXAUDIO_STOP_RINGTONE, msg->param1, msg->param2, NULL); break; } case UTOXAV_CALL_END: { call_count--; FRIEND *f = get_friend(msg->param1); if (f && f->call_state_self & (TOXAV_FRIEND_CALL_STATE_SENDING_V | TOXAV_FRIEND_CALL_STATE_ACCEPTING_V)) { utox_video_stop(false); } if (f && f->call_started != 0) { char notice_msg[64]; int duration = difftime(time(NULL), f->call_started); snprintf(notice_msg, sizeof(notice_msg), "%s: %02u:%02u:%02u", S(CALL_ENDED), duration / 3600, (duration / 60) % 60, duration % 60); int notice_msg_len = strnlen(notice_msg, sizeof(notice_msg) - 1); if (notice_msg_len < 64) { message_add_type_notice(&f->msg, notice_msg, notice_msg_len, true); } f->call_started = 0; } postmessage_audio(UTOXAUDIO_STOP_FRIEND, msg->param1, msg->param2, NULL); postmessage_audio(UTOXAUDIO_STOP_RINGTONE, msg->param1, msg->param2, NULL); break; } case UTOXAV_GROUPCALL_START: { call_count++; LOG_INFO("uToxAv", "Starting group call in groupchat %u", msg->param1); postmessage_audio(UTOXAUDIO_GROUPCHAT_START, msg->param1, msg->param2, NULL); break; } case UTOXAV_GROUPCALL_END: { GROUPCHAT *g = get_group(msg->param1); if (!g) { LOG_ERR("uToxAv", "Could not get group %u", msg->param1); break; } if (!call_count) { LOG_ERR("uToxAv", "Trying to end a call when no call is active."); break; } LOG_INFO("uToxAv", "Ending group call in groupchat %u", msg->param1); postmessage_audio(UTOXAUDIO_GROUPCHAT_STOP, msg->param1, msg->param2, NULL); call_count--; break; } case UTOXAV_START_AUDIO: { if (msg->param1) { /* Start audio preview */ call_count++; LOG_TRACE("uToxAV", "Starting Audio Preview" ); postmessage_audio(UTOXAUDIO_START_PREVIEW, 0, 0, NULL); } break; } case UTOXAV_STOP_AUDIO: { if (!call_count) { LOG_TRACE("uToxAV", "WARNING, trying to stop audio while already closed!\nThis is bad!" ); break; } if (msg->param1) { call_count--; LOG_TRACE("uToxAV", "Stopping Audio Preview" ); postmessage_audio(UTOXAUDIO_STOP_PREVIEW, 0, 0, NULL); } break; } case UTOXAV_START_VIDEO: { if (msg->param2) { utox_video_start(1); } else { utox_video_start(0); TOXAV_ERR_BIT_RATE_SET bitrate_err = 0; toxav_video_set_bit_rate(av, msg->param1, UTOX_DEFAULT_BITRATE_V, &bitrate_err); } break; } case UTOXAV_STOP_VIDEO: { if (msg->param2) { utox_video_stop(1); } else { utox_video_stop(0); TOXAV_ERR_BIT_RATE_SET bitrate_err = 0; toxav_video_set_bit_rate(av, msg->param1, -1, &bitrate_err); } postmessage_utox(AV_CLOSE_WINDOW, msg->param1, 0, NULL); break; } case UTOXAV_SET_AUDIO_IN: { LOG_TRACE("uToxAV", "Set audio in" ); if (audio_in) { postmessage_audio(UTOXAUDIO_CHANGE_MIC, 0, 0, NULL); } utox_audio_in_device_set(msg->data); if (msg->data != utox_audio_in_device_get()) { LOG_TRACE("uToxAV", "Error changing audio in" ); audio_in = 0; call_count = 0; break; } // TODO get a count in audio.c and allow count restore // if (audio_in) { // utox_audio_in_device_open(); // utox_audio_in_listen(); // } break; } case UTOXAV_SET_AUDIO_OUT: { LOG_TRACE("uToxAV", "Set audio out" ); postmessage_audio(UTOXAUDIO_CHANGE_SPEAKER, 0, 0, NULL); utox_audio_out_device_set(msg->data); break; } case UTOXAV_SET_VIDEO_IN: { utox_video_change_device(msg->param1); LOG_TRACE("uToxAV", "Changed video input device" ); break; } case UTOXAV_SET_VIDEO_OUT: { break; } } } toxav_thread_msg = false; if (av) { toxav_iterate(av); yieldcpu(toxav_iteration_interval(av)); } else { yieldcpu(10); } } postmessage_audio(UTOXAUDIO_KILL, 0, 0, NULL); postmessage_video(UTOXVIDEO_KILL, 0, 0, NULL); // Wait for all a/v threads to return 0 while (utox_audio_thread_init || utox_video_thread_init) { yieldcpu(1); } toxav_thread_msg = false; utox_av_ctrl_init = false; toxav_kill(av); LOG_NOTE("UTOXAV", "Clean thread exit!"); return; } static void utox_av_incoming_call(ToxAV *UNUSED(av), uint32_t friend_number, bool audio, bool video, void *UNUSED(userdata)) { LOG_TRACE("uToxAV", "A/V Invite (%u)" , friend_number); FRIEND *f = get_friend(friend_number); if (!f) { LOG_ERR("uToxAV", "Unable to get friend %u for A/V invite.", friend_number); return; } f->call_state_self = 0; f->call_state_friend = (audio << 2 | video << 3 | audio << 4 | video << 5); LOG_TRACE("uToxAV", "uTox AV:\tcall friend (%u) state for incoming call: %i" , friend_number, f->call_state_friend); postmessage_utoxav(UTOXAV_INCOMING_CALL_PENDING, friend_number, 0, NULL); postmessage_utox(AV_CALL_INCOMING, friend_number, video, NULL); } static void utox_av_remote_disconnect(ToxAV *UNUSED(av), int32_t friend_number) { LOG_TRACE("uToxAV", "Remote disconnect from friend %u" , friend_number); FRIEND *f = get_friend(friend_number); if (!f) { LOG_ERR("uToxAV", "Unable to get friend %u for remote disconnect.", friend_number); return; } postmessage_utoxav(UTOXAV_CALL_END, friend_number, 0, NULL); f->call_state_self = 0; f->call_state_friend = 0; postmessage_utox(AV_CLOSE_WINDOW, friend_number + 1, 0, NULL); postmessage_utox(AV_CALL_DISCONNECTED, friend_number, 0, NULL); } void utox_av_local_disconnect(ToxAV *av, int32_t friend_number) { TOXAV_ERR_CALL_CONTROL error = 0; if (av) { /* TODO HACK: tox_callbacks doesn't have access to toxav, so it just sets it as NULL, this is bad! */ toxav_call_control(av, friend_number, TOXAV_CALL_CONTROL_CANCEL, &error); } switch (error) { case TOXAV_ERR_CALL_CONTROL_OK: { LOG_NOTE("uToxAV", "ToxAV has disconnected!" ); break; } case TOXAV_ERR_CALL_CONTROL_SYNC: { LOG_ERR("uToxAV", "ToxAV sync error!"); break; } case TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_FOUND: { LOG_ERR("uToxAV", "ToxAV friend #%i not found." , friend_number); break; } case TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_IN_CALL: { LOG_ERR("uToxAV", "ToxAV no existing call for friend #%i." , friend_number); break; } case TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION: { LOG_NOTE("uToxAV", "Call already paused, or already running." ); break; } } FRIEND *f = get_friend(friend_number); if (!f) { LOG_ERR("uToxAV", "Unable to get friend %u for A/V disconnect.", friend_number); return; } f->call_state_self = 0; f->call_state_friend = 0; postmessage_utox(AV_CLOSE_WINDOW, friend_number + 1, 0, NULL); /* TODO move all of this into a static function in that file !*/ postmessage_utox(AV_CALL_DISCONNECTED, friend_number, 0, NULL); postmessage_utoxav(UTOXAV_CALL_END, friend_number, 0, NULL); } void utox_av_local_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL control) { TOXAV_ERR_CALL_CONTROL err = 0; toxav_call_control(av, friend_number, control, &err); if (err) { LOG_TRACE("uToxAV", "Local call control error!" ); return; } TOXAV_ERR_BIT_RATE_SET bitrate_err = 0; FRIEND *f = get_friend(friend_number); if (!f) { LOG_ERR("uToxAV", "Unable to get friend %u for local call control.", friend_number); return; } switch (control) { case TOXAV_CALL_CONTROL_HIDE_VIDEO: { toxav_video_set_bit_rate(av, friend_number, 0, &bitrate_err); postmessage_utoxav(UTOXAV_STOP_VIDEO, friend_number, 0, NULL); f->call_state_self &= (0xFF ^ TOXAV_FRIEND_CALL_STATE_SENDING_V); break; } case TOXAV_CALL_CONTROL_SHOW_VIDEO: { toxav_video_set_bit_rate(av, friend_number, UTOX_DEFAULT_BITRATE_V, &bitrate_err); postmessage_utoxav(UTOXAV_START_VIDEO, friend_number, 0, NULL); f->call_state_self |= TOXAV_FRIEND_CALL_STATE_SENDING_V; break; } default: { LOG_ERR("uToxAV", "Unhandled local call control"); } // TODO // TOXAV_CALL_CONTROL_RESUME, // TOXAV_CALL_CONTROL_PAUSE, // TOXAV_CALL_CONTROL_CANCEL, // TOXAV_CALL_CONTROL_MUTE_AUDIO, // TOXAV_CALL_CONTROL_UNMUTE_AUDIO, } if (bitrate_err) { LOG_ERR("uToxAV", "Error setting/changing video bitrate"); } } // responds to a audio frame call back from toxav static void utox_av_incoming_frame_a(ToxAV *UNUSED(av), uint32_t friend_number, const int16_t *pcm, size_t sample_count, uint8_t channels, uint32_t sample_rate, void *UNUSED(userdata)) { // LOG_TRACE("uToxAv", "Incoming audio frame for friend %u " , friend_number); #ifdef NATIVE_ANDROID_AUDIO audio_play(friend_number, pcm, sample_count, channels); #else sourceplaybuffer(friend_number, pcm, sample_count, channels, sample_rate); #endif } static void utox_av_incoming_frame_v(ToxAV *UNUSED(toxAV), uint32_t friend_number, uint16_t width, uint16_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, int32_t ystride, int32_t ustride, int32_t vstride, void *UNUSED(user_data)) { /* copy the vpx_image */ /* 4 bits for the H*W, then a pixel for each color * size */ LOG_TRACE("uToxAV", "new video frame from friend %u" , friend_number); FRIEND *f = get_friend(friend_number); if (f == NULL) { LOG_ERR("uToxAV", "Incoming frame for a friend we don't know about! (%u)", friend_number); return; } f->video_width = width; f->video_height = height; size_t size = width * height * 4; UTOX_FRAME_PKG *frame = calloc(1, sizeof(UTOX_FRAME_PKG)); if (!frame) { LOG_ERR("uToxAV", "Can't malloc for incoming frame."); return; } frame->w = width; frame->h = height; frame->size = size; frame->img = malloc(size); if (!frame->img) { LOG_TRACE("uToxAV", "Could not allocate memory for image."); free(frame); return; } yuv420tobgr(width, height, y, u, v, ystride, ustride, vstride, frame->img); if (f->video_inline) { if (!inline_set_frame(width, height, size, frame->img)) { LOG_ERR("uToxAV", "Error setting frame for inline video."); } postmessage_utox(AV_INLINE_FRAME, friend_number, 0, NULL); free(frame->img); free(frame); } else { postmessage_utox(AV_VIDEO_FRAME, friend_number, 0, (void *)frame); } } static void utox_audio_friend_accepted(ToxAV *av, uint32_t friend_number, uint32_t state) { /* First accepted call back */ LOG_NOTE("uToxAV", "Friend accepted call" ); FRIEND *f = get_friend(friend_number); if (!f) { LOG_FATAL_ERR(EXIT_FAILURE, "uToxAV", "Unable to get friend when A/V call accepted %u", friend_number); } f->call_state_friend = state; if (SELF_SEND_VIDEO(friend_number) && !FRIEND_ACCEPTING_VIDEO(friend_number)) { utox_av_local_call_control(av, friend_number, TOXAV_CALL_CONTROL_HIDE_VIDEO); } postmessage_utoxav(UTOXAV_OUTGOING_CALL_ACCEPTED, friend_number, 0, NULL); postmessage_utox(AV_CALL_ACCEPTED, friend_number, 0, NULL); } /** respond to a Audio Video state change call back from toxav */ static void utox_callback_av_change_state(ToxAV *av, uint32_t friend_number, uint32_t state, void *UNUSED(userdata)) { FRIEND *f = get_friend(friend_number); if (!f) { LOG_ERR("uToxAV", "Unable to get friend when A/V state changed %u", friend_number); return; } if (state == 1) { // handle error LOG_ERR("uToxAV", "Change state with an error, this should never happen. Please send bug report!"); utox_av_remote_disconnect(av, friend_number); return; } else if (state == 2) { LOG_NOTE("uToxAV", "Call ended with friend_number %u." , friend_number); utox_av_remote_disconnect(av, friend_number); return; } else if (!f->call_state_friend) { utox_audio_friend_accepted(av, friend_number, state); } if (f->call_state_friend ^ (state & TOXAV_FRIEND_CALL_STATE_SENDING_A)) { if (state & TOXAV_FRIEND_CALL_STATE_SENDING_A) { LOG_INFO("uToxAV", "Friend %u is now sending audio." , friend_number); } else { LOG_INFO("uToxAV", "Friend %u is no longer sending audio." , friend_number); } } if (f->call_state_friend ^ (state & TOXAV_FRIEND_CALL_STATE_SENDING_V)) { if (state & TOXAV_FRIEND_CALL_STATE_SENDING_V) { LOG_INFO("uToxAV", "Friend %u is now sending video." , friend_number); } else { LOG_INFO("uToxAV", "Friend %u is no longer sending video." , friend_number); flist_reselect_current(); } } if (f->call_state_friend ^ (state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A)) { if (state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A) { LOG_INFO("uToxAV", "Friend %u is now accepting audio." , friend_number); } else { LOG_INFO("uToxAV", "Friend %u is no longer accepting audio." , friend_number); } } if (f->call_state_friend ^ (state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_V)) { if (state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_V) { LOG_INFO("uToxAV", "Friend %u is now accepting video." , friend_number); } else { LOG_INFO("uToxAV", "Friend %u is no longer accepting video." , friend_number); } } f->call_state_friend = state; } static void utox_incoming_video_rate_change(ToxAV *AV, uint32_t f_num, uint32_t v_bitrate, void *UNUSED(ud)) { /* Just accept what toxav wants the bitrate to be... */ if (v_bitrate > (uint32_t)UTOX_MIN_BITRATE_VIDEO) { TOXAV_ERR_BIT_RATE_SET error = 0; toxav_video_set_bit_rate(AV, f_num, v_bitrate, &error); if (error) { LOG_ERR("ToxAV", "Setting new Video bitrate has failed with error #%u" , error); } else { LOG_NOTE("uToxAV", "Video bitrate changed to %u" , v_bitrate); } } else { LOG_NOTE("uToxAV", "Video bitrate unchanged %u is less than %u" , v_bitrate, UTOX_MIN_BITRATE_VIDEO); } } static void utox_incoming_audio_rate_change(ToxAV *AV, uint32_t friend_number, uint32_t audio_bitrate, void *UNUSED(userdata)){ if (audio_bitrate > (uint32_t)UTOX_MIN_BITRATE_VIDEO) { TOXAV_ERR_BIT_RATE_SET error = 0; toxav_video_set_bit_rate(AV, friend_number, audio_bitrate, &error); if (error) { LOG_ERR("ToxAV", "Setting new audio bitrate has failed with error #%u" , error); } else { LOG_NOTE("uToxAV", "Audio bitrate changed to %u" , audio_bitrate); } } else { LOG_NOTE("uToxAV", "Audio bitrate unchanged %u is less than %u" , audio_bitrate, UTOX_MIN_BITRATE_AUDIO); } } void set_av_callbacks(ToxAV *av) { /* Friend update callbacks */ toxav_callback_call(av, &utox_av_incoming_call, NULL); toxav_callback_call_state(av, &utox_callback_av_change_state, NULL); /* Incoming data callbacks */ toxav_callback_audio_receive_frame(av, &utox_av_incoming_frame_a, NULL); toxav_callback_video_receive_frame(av, &utox_av_incoming_frame_v, NULL); /* Data type change callbacks. */ toxav_callback_video_bit_rate(av, &utox_incoming_video_rate_change, NULL); toxav_callback_audio_bit_rate(av, &utox_incoming_audio_rate_change, NULL); } uTox-0.17.1/src/av/utox_av.h000066400000000000000000000036001354126257400156020ustar00rootroot00000000000000/* toxav thread messages (sent from the client thread to the audio or video thread) */ #ifndef UTOX_AV_H #define UTOX_AV_H #include // if it weren't for TOXAV_CALL_CONTROL we could move this to the .c #include extern bool utox_av_ctrl_init; #define UTOX_MAX_CALLS 16 // UTOX_MAX_VIDEO_CALLS is never used. Remove? #define UTOX_MAX_VIDEO_CALLS 32 /* utox av thread commands */ enum { UTOXAV_KILL, UTOXAV_INCOMING_CALL_PENDING, UTOXAV_INCOMING_CALL_ANSWER, UTOXAV_INCOMING_CALL_REJECT, UTOXAV_OUTGOING_CALL_PENDING, UTOXAV_OUTGOING_CALL_ACCEPTED, UTOXAV_OUTGOING_CALL_REJECTED, UTOXAV_CALL_END, UTOXAV_GROUPCALL_START, UTOXAV_GROUPCALL_END, UTOXAV_START_AUDIO, UTOXAV_STOP_AUDIO, UTOXAV_START_VIDEO, UTOXAV_STOP_VIDEO, UTOXAV_SET_AUDIO_IN, UTOXAV_SET_AUDIO_OUT, UTOXAV_SET_VIDEO_IN, UTOXAV_SET_VIDEO_OUT, UTOXAV_NEW_TOX_INSTANCE, }; enum { // kill the video thread UTOXVIDEO_KILL, UTOXVIDEO_NEW_AV_INSTANCE, /* UTOXVIDEO_RECORD_START, UTOXVIDEO_RECORD_STOP, UTOXVIDEO_SET, UTOXVIDEO_PREVIEW_START, UTOXVIDEO_PREVIEW_STOP, */ }; typedef struct groupchat GROUPCHAT; /* send a message to the toxav thread */ void postmessage_utoxav(uint8_t msg, uint32_t param1, uint32_t param2, void *data); void utox_av_ctrl_thread(void *args); void utox_av_local_disconnect(ToxAV *av, int32_t friend_number); void utox_av_local_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL control); void set_av_callbacks(ToxAV *av); void callback_av_group_audio(void *tox, uint32_t groupnumber, uint32_t peernumber, const int16_t *pcm, unsigned int samples, uint8_t channels, unsigned int sample_rate, void *userdata); void group_av_peer_add(GROUPCHAT *g, int peernumber); void group_av_peer_remove(GROUPCHAT *g, int peernumber); #endif uTox-0.17.1/src/av/video.c000066400000000000000000000405341354126257400152250ustar00rootroot00000000000000#include "video.h" #include "utox_av.h" #include "../friend.h" #include "../debug.h" #include "../macros.h" #include "../self.h" #include "../settings.h" #include "../tox.h" #include "../utox.h" #include "../native/thread.h" #include "../native/video.h" #include #include #include #include #include bool utox_video_thread_init = false; static void * video_device[16] = { NULL }; /* TODO; magic number */ static int16_t video_device_count = 0; static uint32_t video_device_current = 0; static bool video_active = false; static utox_av_video_frame utox_video_frame; static bool video_device_status = false; static vpx_image_t input; static pthread_mutex_t video_thread_lock; static bool video_device_init(void *handle) { // initialize video (will populate video_width and video_height) if (handle == (void *)1) { if (!native_video_init((void *)1)) { LOG_TRACE("uToxVideo", "native_video_init() failed for desktop" ); return false; } } else { if (!handle || !native_video_init(*(void **)handle)) { LOG_TRACE("uToxVideo", "native_video_init() failed webcam" ); return false; } } vpx_img_alloc(&input, VPX_IMG_FMT_I420, video_width, video_height, 1); utox_video_frame.y = input.planes[0]; utox_video_frame.u = input.planes[1]; utox_video_frame.v = input.planes[2]; utox_video_frame.w = input.d_w; utox_video_frame.h = input.d_h; LOG_NOTE("uToxVideo", "video init done!" ); video_device_status = true; return true; } static void close_video_device(void *handle) { if (handle >= (void *)2) { native_video_close(*(void **)handle); vpx_img_free(&input); } video_device_status = false; } static bool video_device_start(void) { if (video_device_status) { native_video_startread(); video_active = true; return true; } video_active = false; return false; } static bool video_device_stop(void) { if (video_device_status) { native_video_endread(); video_active = false; return true; } video_active = false; return false; } #include "../ui/dropdown.h" #include "../layout/settings.h" // TODO move? void utox_video_append_device(void *device, bool localized, void *name, bool default_) { video_device[video_device_count++] = device; if (localized) { // Device name is localized with name containing UTOX_I18N_STR. // device is device handle pointer. dropdown_list_add_localized(&dropdown_video, (UTOX_I18N_STR)name, device); } else { // Device name is a hardcoded string. // device is a pointer to a buffer, that contains device handle pointer, // followed by device name string. dropdown_list_add_hardcoded(&dropdown_video, name, *(void **)device); } /* TODO remove all default settings */ // default == true, if this device will be chosen by video detecting code. if (default_) { dropdown_video.selected = dropdown_video.over = (dropdown_video.dropcount - 1); } } bool utox_video_change_device(uint16_t device_number) { pthread_mutex_lock(&video_thread_lock); static bool _was_active = false; if (!device_number) { video_device_current = 0; if (video_active) { video_device_stop(); close_video_device(video_device[video_device_current]); if (settings.video_preview) { settings.video_preview = false; postmessage_utox(AV_CLOSE_WINDOW, 0, 0, NULL); } } LOG_TRACE("uToxVideo", "Disabled Video device (none)" ); goto mutex_unlock; } if (video_active) { _was_active = true; video_device_stop(); close_video_device(video_device[video_device_current]); } else { _was_active = false; } video_device_current = device_number; if (!video_device_init(video_device[device_number])) { goto mutex_unlock; } if (!_was_active) { /* Just grab the new frame size */ if (video_device_status) { close_video_device(video_device[video_device_current]); } goto mutex_unlock; } LOG_TRACE("uToxVideo", "Trying to restart video with new device..." ); if (!video_device_start()) { LOG_ERR("uToxVideo", "Error, unable to start new device..."); if (settings.video_preview) { settings.video_preview = false; postmessage_utox(AV_CLOSE_WINDOW, 0, 0, NULL); } goto mutex_unlock; } pthread_mutex_unlock(&video_thread_lock); return true; mutex_unlock: pthread_mutex_unlock(&video_thread_lock); return false; } bool utox_video_start(bool preview) { if (video_active) { LOG_NOTE("uToxVideo", "video already running" ); return true; } if (!video_device_current) { LOG_NOTE("uToxVideo", "Not starting device None" ); return false; } if (preview) { settings.video_preview = true; } if (video_device_init(video_device[video_device_current]) && video_device_start()) { video_active = true; LOG_NOTE("uToxVideo", "started video" ); return true; } LOG_ERR("uToxVideo", "Unable to start video."); return false; } bool utox_video_stop(bool UNUSED(preview)) { if (!video_active) { LOG_TRACE("uToxVideo", "video already stopped!" ); return false; } video_active = false; settings.video_preview = false; postmessage_utox(AV_CLOSE_WINDOW, 0, 0, NULL); video_device_stop(); close_video_device(video_device[video_device_current]); LOG_TRACE("uToxVideo", "stopped video" ); return true; } static TOX_MSG video_msg; void postmessage_video(uint8_t msg, uint32_t param1, uint32_t param2, void *data) { while (video_thread_msg) { yieldcpu(1); } video_msg.msg = msg; video_msg.param1 = param1; video_msg.param2 = param2; video_msg.data = data; video_thread_msg = true; } // Populates the video device dropdown. static void init_video_devices(void) { // Add always-present null video input device. utox_video_append_device(NULL, 1, (void *)STR_VIDEO_IN_NONE, 1); // select a video device (autodectect) video_device_current = native_video_detect(); if (video_device_current) { // open the video device to get some info e.g. frame size // close it afterwards to not block the device while it is not used if (video_device_init(video_device[video_device_current])) { close_video_device(video_device[video_device_current]); } } } void utox_video_thread(void *args) { ToxAV *av = args; pthread_mutex_init(&video_thread_lock, NULL); init_video_devices(); utox_video_thread_init = 1; while (1) { if (video_thread_msg) { if (!video_msg.msg || video_msg.msg == UTOXVIDEO_KILL) { break; } switch (video_msg.msg) { case UTOXVIDEO_NEW_AV_INSTANCE: { av = video_msg.data; init_video_devices(); break; } } video_thread_msg = false; } if (video_active) { pthread_mutex_lock(&video_thread_lock); // capturing is enabled, capture frames const int r = native_video_getframe(utox_video_frame.y, utox_video_frame.u, utox_video_frame.v, utox_video_frame.w, utox_video_frame.h); if (r == 1) { if (settings.video_preview) { /* Make a copy of the video frame for uTox to display */ UTOX_FRAME_PKG *frame = malloc(sizeof(UTOX_FRAME_PKG)); frame->w = utox_video_frame.w; frame->h = utox_video_frame.h; frame->img = malloc(utox_video_frame.w * utox_video_frame.h * 4); yuv420tobgr(utox_video_frame.w, utox_video_frame.h, utox_video_frame.y, utox_video_frame.u, utox_video_frame.v, utox_video_frame.w, (utox_video_frame.w / 2), (utox_video_frame.w / 2), frame->img); postmessage_utox(AV_VIDEO_FRAME, UINT16_MAX, 1, (void *)frame); } size_t active_video_count = 0; for (size_t i = 0; i < self.friend_list_count; i++) { if (SEND_VIDEO_FRAME(i)) { LOG_TRACE("uToxVideo", "sending video frame to friend %lu" , i); active_video_count++; TOXAV_ERR_SEND_FRAME error = 0; FRIEND *f = get_friend(i); if (!f) { LOG_ERR("uToxVideo", "Could not get friend to send him video frame %lu", i); continue; } toxav_video_send_frame(av, f->number, utox_video_frame.w, utox_video_frame.h, utox_video_frame.y, utox_video_frame.u, utox_video_frame.v, &error); // LOG_TRACE("uToxVideo", "Sent video frame to friend %u" , i); if (error) { if (error == TOXAV_ERR_SEND_FRAME_SYNC) { LOG_ERR("uToxVideo", "Vid Frame sync error: w=%u h=%u", utox_video_frame.w, utox_video_frame.h); } else if (error == TOXAV_ERR_SEND_FRAME_PAYLOAD_TYPE_DISABLED) { LOG_ERR("uToxVideo", "ToxAV disagrees with our AV state for friend %lu, self %u, friend %u", i, f->call_state_self, f->call_state_friend); } else { LOG_ERR("uToxVideo", "toxav_send_video error friend: %i error: %u", f->number, error); } } else { if (active_video_count >= UTOX_MAX_CALLS) { LOG_ERR("uToxVideo", "Trying to send video frame to too many peers. Please report this bug!"); break; } } } } } else if (r == -1) { LOG_ERR("uToxVideo", "Err... something really bad happened trying to get this frame, I'm just going " "to plots now!"); video_device_stop(); close_video_device(video_device); } pthread_mutex_unlock(&video_thread_lock); yieldcpu(1000 / settings.video_fps); /* 60fps = 16.666ms || 25 fps = 40ms || the data quality is SO much better at 25... */ continue; /* We're running video, so don't sleep for an extra 100 ms */ } yieldcpu(100); } video_device_count = 0; video_device_current = 0; video_active = false; for (uint8_t i = 0; i < 16; ++i) { video_device[i] = NULL; } video_thread_msg = 0; utox_video_thread_init = 0; LOG_TRACE("uToxVideo", "Clean thread exit!"); } void yuv420tobgr(uint16_t width, uint16_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, unsigned int ystride, unsigned int ustride, unsigned int vstride, uint8_t *out) { for (unsigned long int i = 0; i < height; ++i) { for (unsigned long int j = 0; j < width; ++j) { uint8_t *point = out + 4 * ((i * width) + j); int t_y = y[((i * ystride) + j)]; const int t_u = u[(((i / 2) * ustride) + (j / 2))]; const int t_v = v[(((i / 2) * vstride) + (j / 2))]; t_y = t_y < 16 ? 16 : t_y; const int r = (298 * (t_y - 16) + 409 * (t_v - 128) + 128) >> 8; const int g = (298 * (t_y - 16) - 100 * (t_u - 128) - 208 * (t_v - 128) + 128) >> 8; const int b = (298 * (t_y - 16) + 516 * (t_u - 128) + 128) >> 8; point[2] = r > 255 ? 255 : r < 0 ? 0 : r; point[1] = g > 255 ? 255 : g < 0 ? 0 : g; point[0] = b > 255 ? 255 : b < 0 ? 0 : b; point[3] = ~0; } } } void yuv422to420(uint8_t *plane_y, uint8_t *plane_u, uint8_t *plane_v, uint8_t *input, uint16_t width, uint16_t height) { const uint8_t *end = input + width * height * 2; while (input != end) { uint8_t *line_end = input + width * 2; while (input != line_end) { *plane_y++ = *input++; *plane_v++ = *input++; *plane_y++ = *input++; *plane_u++ = *input++; } line_end = input + width * 2; while (input != line_end) { *plane_y++ = *input++; input++; // u *plane_y++ = *input++; input++; // v } } } static uint8_t rgb_to_y(int r, int g, int b) { const int y = ((9798 * r + 19235 * g + 3736 * b) >> 15); return y > 255 ? 255 : y < 0 ? 0 : y; } static uint8_t rgb_to_u(int r, int g, int b) { const int u = ((-5538 * r + -10846 * g + 16351 * b) >> 15) + 128; return u > 255 ? 255 : u < 0 ? 0 : u; } static uint8_t rgb_to_v(int r, int g, int b) { const int v = ((16351 * r + -13697 * g + -2664 * b) >> 15) + 128; return v > 255 ? 255 : v < 0 ? 0 : v; } void bgrtoyuv420(uint8_t *plane_y, uint8_t *plane_u, uint8_t *plane_v, uint8_t *rgb, uint16_t width, uint16_t height) { uint8_t *p; uint8_t r, g, b; for (uint16_t y = 0; y != height; y += 2) { p = rgb; for (uint16_t x = 0; x != width; x++) { b = *rgb++; g = *rgb++; r = *rgb++; *plane_y++ = rgb_to_y(r, g, b); } for (uint16_t x = 0; x != width / 2; x++) { b = *rgb++; g = *rgb++; r = *rgb++; *plane_y++ = rgb_to_y(r, g, b); b = *rgb++; g = *rgb++; r = *rgb++; *plane_y++ = rgb_to_y(r, g, b); b = ((int)b + (int)*(rgb - 6) + (int)*p + (int)*(p + 3) + 2) / 4; p++; g = ((int)g + (int)*(rgb - 5) + (int)*p + (int)*(p + 3) + 2) / 4; p++; r = ((int)r + (int)*(rgb - 4) + (int)*p + (int)*(p + 3) + 2) / 4; p++; *plane_u++ = rgb_to_u(r, g, b); *plane_v++ = rgb_to_v(r, g, b); p += 3; } } } void bgrxtoyuv420(uint8_t *plane_y, uint8_t *plane_u, uint8_t *plane_v, uint8_t *rgb, uint16_t width, uint16_t height) { uint8_t *p; uint8_t r, g, b; for (uint16_t y = 0; y != height; y += 2) { p = rgb; for (uint16_t x = 0; x != width; x++) { b = *rgb++; g = *rgb++; r = *rgb++; rgb++; *plane_y++ = rgb_to_y(r, g, b); } for (uint16_t x = 0; x != width / 2; x++) { b = *rgb++; g = *rgb++; r = *rgb++; rgb++; *plane_y++ = rgb_to_y(r, g, b); b = *rgb++; g = *rgb++; r = *rgb++; rgb++; *plane_y++ = rgb_to_y(r, g, b); b = ((int)b + (int)*(rgb - 8) + (int)*p + (int)*(p + 4) + 2) / 4; p++; g = ((int)g + (int)*(rgb - 7) + (int)*p + (int)*(p + 4) + 2) / 4; p++; r = ((int)r + (int)*(rgb - 6) + (int)*p + (int)*(p + 4) + 2) / 4; p++; p++; *plane_u++ = rgb_to_u(r, g, b); *plane_v++ = rgb_to_v(r, g, b); p += 4; } } } void scale_rgbx_image(uint8_t *old_rgbx, uint16_t old_width, uint16_t old_height, uint8_t *new_rgbx, uint16_t new_width, uint16_t new_height) { for (int y = 0; y != new_height; y++) { const int y0 = y * old_height / new_height; for (int x = 0; x != new_width; x++) { const int x0 = x * old_width / new_width; const int a = x + y * new_width; const int b = x0 + y0 * old_width; new_rgbx[a * 4] = old_rgbx[b * 4]; new_rgbx[a * 4 + 1] = old_rgbx[b * 4 + 1]; new_rgbx[a * 4 + 2] = old_rgbx[b * 4 + 2]; } } } uTox-0.17.1/src/av/video.h000066400000000000000000000046401354126257400152300ustar00rootroot00000000000000#ifndef VIDEO_H #define VIDEO_H #include #include #include uint16_t video_width, video_height, max_video_width, max_video_height; extern bool utox_video_thread_init; #define UTOX_DEFAULT_BITRATE_V 5000 #define UTOX_MIN_BITRATE_VIDEO 512 // UTOX_DEFAULT_VID_WIDTH, HEIGHT are unused. #define UTOX_DEFAULT_VID_WIDTH 1280 #define UTOX_DEFAULT_VID_HEIGHT 720 /* Check self */ #define SELF_SEND_VIDEO(f_number) (get_friend(f_number) && (!!(get_friend(f_number)->call_state_self & TOXAV_FRIEND_CALL_STATE_SENDING_V))) #define SELF_ACCEPT_VIDEO(f_number) (get_friend(f_number) && (!!(get_friend(f_number)->call_state_self & TOXAV_FRIEND_CALL_STATE_ACCEPTING_V))) /* Check friend */ #define FRIEND_SENDING_VIDEO(f_number) (get_friend(f_number) && (!!(get_friend(f_number)->call_state_friend & TOXAV_FRIEND_CALL_STATE_SENDING_V))) #define FRIEND_ACCEPTING_VIDEO(f_number) (get_friend(f_number) && (!!(get_friend(f_number)->call_state_friend & TOXAV_FRIEND_CALL_STATE_ACCEPTING_V))) /* Check both */ #define SEND_VIDEO_FRAME(f_number) (SELF_SEND_VIDEO(f_number) && FRIEND_ACCEPTING_VIDEO(f_number)) typedef struct UTOX_AV_VIDEO_FRAME { uint16_t w, h; uint8_t *y, *u, *v; } utox_av_video_frame; typedef struct utox_frame_pkg { uint16_t w, h; size_t size; void *img; } UTOX_FRAME_PKG; void utox_video_append_device(void *device, bool localized, void *name, bool default_); bool utox_video_change_device(uint16_t i); bool utox_video_start(bool preview); bool utox_video_stop(bool preview); void utox_video_thread(void *args); void postmessage_video(uint8_t msg, uint32_t param1, uint32_t param2, void *data); // Color format conversion functions void yuv420tobgr(uint16_t width, uint16_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, unsigned int ystride, unsigned int ustride, unsigned int vstride, uint8_t *out); void yuv422to420(uint8_t *plane_y, uint8_t *plane_u, uint8_t *plane_v, uint8_t *input, uint16_t width, uint16_t height); void bgrtoyuv420(uint8_t *plane_y, uint8_t *plane_u, uint8_t *plane_v, uint8_t *rgb, uint16_t width, uint16_t height); void bgrxtoyuv420(uint8_t *plane_y, uint8_t *plane_u, uint8_t *plane_v, uint8_t *rgb, uint16_t width, uint16_t height); // TODO: Documentation. void scale_rgbx_image(uint8_t *old_rgbx, uint16_t old_width, uint16_t old_height, uint8_t *new_rgbx, uint16_t new_width, uint16_t new_height); #endif uTox-0.17.1/src/avatar.c000066400000000000000000000145741354126257400147740ustar00rootroot00000000000000#include "avatar.h" #include "debug.h" #include "file_transfers.h" #include "filesys.h" #include "self.h" #include "tox.h" #include "native/image.h" #include #include /* frees the image of an avatar, does nothing if image is NULL */ static void avatar_free_image(AVATAR *avatar) { if (avatar) { image_free(avatar->img); avatar->img = NULL; avatar->size = 0; } } bool avatar_save(char hexid[TOX_PUBLIC_KEY_SIZE * 2], const uint8_t *data, size_t length) { char name[sizeof("avatars/") + TOX_PUBLIC_KEY_SIZE * 2 + sizeof(".png")] = { 0 }; FILE *fp; snprintf(name, sizeof("avatars/") + TOX_PUBLIC_KEY_SIZE * 2 + sizeof(".png"), "avatars/%.*s.png", TOX_PUBLIC_KEY_SIZE * 2, hexid); fp = utox_get_file(name, NULL, UTOX_FILE_OPTS_WRITE | UTOX_FILE_OPTS_MKDIR); if (!fp) { LOG_WARN("Avatar", "Could not save avatar for: %.*s", TOX_PUBLIC_KEY_SIZE * 2, hexid); return false; } fwrite(data, length, 1, fp); fclose(fp); return true; } static uint8_t *load_img_data(char hexid[TOX_PUBLIC_KEY_SIZE * 2], size_t *out_size) { char name[sizeof("avatars/") + TOX_PUBLIC_KEY_SIZE * 2 + sizeof(".png")] = { 0 }; snprintf(name, sizeof("avatars/") + TOX_PUBLIC_KEY_SIZE * 2 + sizeof(".png"), "avatars/%.*s.png", TOX_PUBLIC_KEY_SIZE * 2, hexid); size_t size = 0; FILE *fp = utox_get_file(name, &size, UTOX_FILE_OPTS_READ); if (fp == NULL) { LOG_TRACE("Avatar", "Could not read: %s", name); return NULL; } uint8_t *data = calloc(1, size); if (data == NULL) { LOG_ERR("Avatar", "Could not allocate memory for file of size %zu.", size); fclose(fp); return NULL; } if (fread(data, size, 1, fp) != 1) { LOG_WARN("Avatar", "Could not read from open file: %s", name); fclose(fp); free(data); return NULL; } fclose(fp); if (out_size) { *out_size = size; } return data; } bool avatar_delete(char hexid[TOX_PUBLIC_KEY_SIZE * 2]) { char name[sizeof("avatars/") + TOX_PUBLIC_KEY_SIZE * 2 + sizeof(".png")] = { 0 }; snprintf(name, sizeof(name), "avatars/%.*s.png", TOX_PUBLIC_KEY_SIZE * 2, hexid); int name_len = strnlen(name, sizeof(name) - 1); return utox_remove_file((uint8_t *)name, name_len); } static bool avatar_load(char hexid[TOX_PUBLIC_KEY_SIZE * 2], AVATAR *avatar, size_t *size_out) { size_t size = 0; uint8_t *img = load_img_data(hexid, &size); if (!img) { LOG_DEBUG("Avatar", "Unable to get saved avatar from disk for friend %.*s" , TOX_PUBLIC_KEY_SIZE * 2, hexid); return false; } if (size > UTOX_AVATAR_MAX_DATA_LENGTH) { free(img); LOG_WARN("Avatar", "Saved avatar file for friend (%.*s) too large for tox" , TOX_PUBLIC_KEY_SIZE * 2, hexid); return false; } avatar->img = utox_image_to_native(img, size, &avatar->width, &avatar->height, true); if (avatar->img) { avatar->format = UTOX_AVATAR_FORMAT_PNG; avatar->size = size; tox_hash(avatar->hash, img, size); if (size_out) { *size_out = size; } if (avatar == self.avatar) { // We need to save our avatar in PNG format so we can send it to friends! self.png_data = img; self.png_size = size; } else { free(img); } return true; } free(img); return false; } bool avatar_set(AVATAR *avatar, const uint8_t *data, size_t size) { if (avatar == NULL) { LOG_DEBUG("Avatar", "avatar is null."); return false; } if (size > UTOX_AVATAR_MAX_DATA_LENGTH) { LOG_ERR("Avatar", " avatar too large"); return false; } avatar_free_image(avatar); NATIVE_IMAGE *image = utox_image_to_native((UTOX_IMAGE)data, size, &avatar->width, &avatar->height, true); if (!NATIVE_IMAGE_IS_VALID(image)) { LOG_DEBUG("Avatar", "avatar is invalid"); return false; } avatar->img = image; avatar->format = UTOX_AVATAR_FORMAT_PNG; avatar->size = size; tox_hash(avatar->hash, data, size); return true; } /* sets self avatar, see self_set_and_save_avatar */ bool avatar_set_self(const uint8_t *data, size_t size) { return avatar_set(self.avatar, data, size); } void avatar_unset(AVATAR *avatar) { if (avatar == NULL) { LOG_TRACE("Avatar", " avatar is null" ); return; } avatar->format = UTOX_AVATAR_FORMAT_NONE; avatar_free_image(avatar); } void avatar_unset_self(void) { avatar_unset(self.avatar); } bool avatar_init(char hexid[TOX_PUBLIC_KEY_SIZE * 2], AVATAR *avatar) { avatar_unset(avatar); return avatar_load(hexid, avatar, NULL); } bool avatar_init_self(void) { self.avatar = calloc(1, sizeof(AVATAR)); if (self.avatar == NULL) { return false; } return avatar_load(self.id_str, self.avatar, NULL); } bool self_set_and_save_avatar(const uint8_t *data, uint32_t size) { if (avatar_set_self(data, size)) { avatar_save(self.id_str, data, size); return true; } return false; } void avatar_delete_self(void) { avatar_unset(self.avatar); avatar_delete(self.id_str); postmessage_toxcore(TOX_AVATAR_UNSET, 0, 0, NULL); } bool avatar_on_friend_online(Tox *tox, uint32_t friend_number) { if (!self.png_data) { uint8_t *avatar_data = load_img_data(self.id_str, &self.png_size); if (!avatar_data) { LOG_WARN("Avatar", "Unable to get out avatar data to send to friend."); self.png_data = NULL; self.png_size = 0; return false; } self.png_data = avatar_data; } ft_send_avatar(tox, friend_number); return true; } bool avatar_move(const uint8_t *source, const uint8_t *dest) { uint8_t current_name[sizeof("avatars/") + TOX_PUBLIC_KEY_SIZE * 2 + sizeof(".png")] = { 0 }; uint8_t new_name[sizeof("avatars/") + TOX_PUBLIC_KEY_SIZE * 2 + sizeof(".png")] = { 0 }; snprintf((char *)current_name, sizeof("avatars/") + TOX_PUBLIC_KEY_SIZE * 2 + sizeof(".png"), "avatars/%.*s.png", TOX_PUBLIC_KEY_SIZE * 2, source); snprintf((char *)new_name, sizeof("avatars/") + TOX_PUBLIC_KEY_SIZE * 2 + sizeof(".png"), "avatars/%.*s.png", TOX_PUBLIC_KEY_SIZE * 2, dest); return utox_move_file(current_name, new_name); } uTox-0.17.1/src/avatar.h000066400000000000000000000100001354126257400147550ustar00rootroot00000000000000#ifndef AVATAR_H #define AVATAR_H #include typedef struct native_image NATIVE_IMAGE; // TODO: remove? #define UTOX_AVATAR_MAX_DATA_LENGTH (64 * 1024) // NOTE: increasing this above 64k might cause // issues with other clients who do stupid things. #define UTOX_AVATAR_FORMAT_NONE 0 #define UTOX_AVATAR_FORMAT_PNG 1 /* data needed for each avatar in memory */ typedef struct avatar { NATIVE_IMAGE *img; /* converted avatar image to draw */ size_t size; uint16_t width, height; /* width and height of image (in pixels) */ uint8_t format; /* one of TOX_AVATAR_FORMAT */ uint8_t hash[TOX_HASH_LENGTH]; /* tox_hash for the png data of this avatar */ } AVATAR; /* Whether user's avatar is set. */ #define self_has_avatar() (self.avatar && self.avatar->format != UTOX_AVATAR_FORMAT_NONE) /* Whether friend f's avatar is set, where f is a pointer to a friend struct */ #define friend_has_avatar(f) (f) && (f->avatar->format != UTOX_AVATAR_FORMAT_NONE) /** tries to load avatar from disk for given client id string and set avatar based on saved png data * avatar is avatar to initialize. Will be unset if no file is found on disk or if file is corrupt or too large, * otherwise will be set to avatar found on disk * id is cid string of whose avatar to find(see also avatar_load in avatar.c) * if png_data_out is not NULL, the png data loaded from disk will be copied to it. * if it is not null, it should be at least UTOX_AVATAR_MAX_DATA_LENGTH bytes long * if png_size_out is not null, the size of the png data will be stored in it * * returns: true on successful loading, false on failure */ bool avatar_init(char hexid[TOX_PUBLIC_KEY_SIZE * 2], AVATAR *avatar); /** Converts png data given by data to a NATIVE_IMAGE and uses that to populate the avatar struct * avatar is pointer to an avatar struct to store result in. Remains unchanged if function fails. * data is pointer to png data to convert * size is size of data * * on success: returns true * on failure: returns false * * notes: fails if given size is larger than UTOX_AVATAR_MAX_DATA_LENGTH or data is not valid PNG data */ bool avatar_set(AVATAR *avatar, const uint8_t *data, size_t size); /* Helper function to set the user's avatar. */ bool avatar_set_self(const uint8_t *data, size_t size); /* Helper function to unset the user's avatar. */ void avatar_unset_self(void); /* Helper function to delete users avatar file. */ void avatar_delete_self(void); /* Unsets an avatar by setting its format to UTOX_AVATAR_FORMAT_NONE and freeing its image. */ void avatar_unset(AVATAR *avatar); /** Sets own avatar based on given png data and saves it to disk if successful. * data is png data to set avatar to. * size is size of data. * * on success: returns true * on failure: returns false * * Notes: Fails if size is too large or data is not a valid png file. */ bool self_set_and_save_avatar(const uint8_t *data, uint32_t size); /* Unsets own avatar and removes it from disk */ bool avatar_remove_self(void); /** Call this every time friend_number goes online from the tox_do thread. * * on success: returns true * on failure: returns false */ bool avatar_on_friend_online(Tox *tox, uint32_t friend_number); /** Colled by incoming file transfers to change the avater. * * If size <=0, we'll unset the avatar, else we'll set and update the friend */ void utox_incoming_avatar(uint32_t friend_number, uint8_t *avatar, size_t size); /* Saves the avatar for user with hexid * * returns true on success * returns false on failure */ bool avatar_save(char hexid[TOX_PUBLIC_KEY_SIZE * 2], const uint8_t *data, size_t length); /* Deletes the avatar for user with hexid * * returns true on success * returns false on failure */ bool avatar_delete(char hexid[TOX_PUBLIC_KEY_SIZE * 2]); /* Helper function to intialize the users avatar */ bool avatar_init_self(void); /* Moves the avatar to its new name */ bool avatar_move(const uint8_t *source, const uint8_t *dest); #endif uTox-0.17.1/src/branding.h000066400000000000000000000015151354126257400152760ustar00rootroot00000000000000/** * uTox Versions and header information * * This file contains defines regarding uTox branding and version information * It is generated from branding.h.in which cmake will generate to branding.h */ #define TITLE "uTox" #define SUB_TITLE "(Alpha)" // The updater relies on these version numbers, and values greater than an octet were never tested #define VERSION "0.17.1" #define VER_MAJOR 0 #define VER_MINOR 17 #define VER_PATCH 1 #define UTOX_VERSION_NUMBER (VER_MAJOR << 16 | VER_MINOR << 8 | VER_PATCH) // Assembly info #define UTOX_FILE_DESCRIPTION "The lightweight Tox client" #define UTOX_COPYRIGHT "Copyleft 2019 uTox contributors. Some rights reserved." #define UTOX_FILENAME_WINDOWS "uTox.exe" // Defaults #define DEFAULT_NAME "uTox User" #define DEFAULT_STATUS "Toxing on uTox, from the future!" #define DEFAULT_SCALE 11 uTox-0.17.1/src/branding.h.in000066400000000000000000000015661354126257400157110ustar00rootroot00000000000000/** * uTox Versions and header information * * This file contains defines regarding uTox branding and version information * It is generated from branding.h.in which cmake will generate to branding.h */ #define TITLE "uTox" #define SUB_TITLE "(Alpha)" // The updater relies on these version numbers, and values greater than an octet were never tested #define VERSION "@PROJECT_VERSION@" #define VER_MAJOR @PROJECT_VERSION_MAJOR@ #define VER_MINOR @PROJECT_VERSION_MINOR@ #define VER_PATCH @PROJECT_VERSION_PATCH@ #define UTOX_VERSION_NUMBER (VER_MAJOR << 16 | VER_MINOR << 8 | VER_PATCH) // Assembly info #define UTOX_FILE_DESCRIPTION "The lightweight Tox client" #define UTOX_COPYRIGHT "@PROJECT_COPYRIGHT@" #define UTOX_FILENAME_WINDOWS "uTox.exe" // Defaults #define DEFAULT_NAME "uTox User" #define DEFAULT_STATUS "Toxing on uTox, from the future!" #define DEFAULT_SCALE 11 uTox-0.17.1/src/chatlog.c000066400000000000000000000240121354126257400151230ustar00rootroot00000000000000#include "chatlog.h" #include "filesys.h" // TODO including native.h files should never be needed, refactor filesys.h to provide necessary API #include "debug.h" #include "messages.h" #include "text.h" #include "native/filesys.h" #include #include static FILE* chatlog_get_file(char hex[TOX_PUBLIC_KEY_SIZE * 2], bool append) { char name[TOX_PUBLIC_KEY_SIZE * 2 + sizeof(".new.txt")]; snprintf(name, sizeof(name), "%.*s.new.txt", TOX_PUBLIC_KEY_SIZE * 2, hex); FILE *file; if (append) { file = utox_get_file(name, NULL, UTOX_FILE_OPTS_READ | UTOX_FILE_OPTS_WRITE | UTOX_FILE_OPTS_MKDIR); if (!file) { return NULL; } fseek(file, 0, SEEK_END); } else { file = utox_get_file(name, NULL, UTOX_FILE_OPTS_READ); } return file; } size_t utox_save_chatlog(char hex[TOX_PUBLIC_KEY_SIZE * 2], uint8_t *data, size_t length) { FILE *fp = chatlog_get_file(hex, true); if (!fp) { LOG_ERR("uTox", "Error getting a file handle for this chatlog!"); return 0; } // Seek to the beginning of the file first because grayhatter has had issues with this on Windows. // (and he really doesn't want uTox eating people's chat logs) fseeko(fp, 0, SEEK_SET); fseeko(fp, 0, SEEK_END); off_t offset = ftello(fp); fwrite(data, length, 1, fp); fclose(fp); return offset; } static size_t utox_count_chatlog(char hex[TOX_PUBLIC_KEY_SIZE * 2]) { FILE *file = chatlog_get_file(hex, false); if (!file) { return 0; } LOG_FILE_MSG_HEADER header; size_t records_count = 0; while (fread(&header, sizeof(header), 1, file) == 1) { fseeko(file, header.author_length + header.msg_length + 1, SEEK_CUR); records_count++; } if (ferror(file) || !feof(file)) { /* TODO: consider removing or truncating the log file. * If !feof() this means that the file has an incomplete record, * which would prevent it from loading forever, even though * new records will keep being appended as usual. */ LOG_ERR("Chatlog", "Log read err; trying to count history for friend %.*s", TOX_PUBLIC_KEY_SIZE * 2, hex); fclose(file); return 0; } fclose(file); return records_count; } /* TODO create fxn that will try to recover a corrupt chat history. * * In the majority of bug reports the corrupt message is often the first, so in * theory we should be able to trim the start of the chatlog up to and including * the first \n char. We may have to do so multiple times, but once we find the * first valid message everything else should "work" */ MSG_HEADER **utox_load_chatlog(char hex[TOX_PUBLIC_KEY_SIZE * 2], size_t *size, uint32_t count, uint32_t skip) { /* Becasue every platform is different, we have to ask them to open the file for us. * However once we have it, every platform does the same thing, this should prevent issues * from occuring on a single platform. */ size_t records_count = utox_count_chatlog(hex); if (skip >= records_count) { if (skip > 0) { LOG_ERR("Chatlog", "Error, skipped all records"); } else { LOG_INFO("Chatlog", "No log exists."); } return NULL; } FILE *file = chatlog_get_file(hex, false); if (!file) { LOG_TRACE("Chatlog", "Log read:\tUnable to access file provided."); return NULL; } if (count > (records_count - skip)) { count = records_count - skip; } MSG_HEADER **data = calloc(count + 1, sizeof(MSG_HEADER *)); MSG_HEADER **start = data; if (!data) { LOG_ERR("Chatlog", "Log read:\tCouldn't allocate memory for log entries."); fclose(file); return NULL; } size_t start_at = records_count - count - skip; size_t actual_count = 0; size_t file_offset = 0; LOG_FILE_MSG_HEADER header; while (fread(&header, sizeof(header), 1, file) == 1) { if (start_at) { fseeko(file, header.author_length, SEEK_CUR); /* Skip the recorded author */ fseeko(file, header.msg_length, SEEK_CUR); /* Skip the message */ fseeko(file, 1, SEEK_CUR); /* Skip the newline char */ start_at--; file_offset = ftello(file); continue; } if (count) { /* we have to skip the author name for now, it's left here for group chats support in the future */ fseeko(file, header.author_length, SEEK_CUR); if (header.msg_length > 1 << 16) { LOG_ERR("Chatlog", "Can't malloc that much, you'll probably have to move or delete your" " history for this peer.\n\t\tFriend number %.*s, count %u," " actual_count %lu, start at %lu, error size %lu.\n", TOX_PUBLIC_KEY_SIZE * 2, hex, count, actual_count, start_at, header.msg_length); if (size) { *size = 0; } fclose(file); return start; } MSG_HEADER *msg = calloc(1, sizeof(MSG_HEADER)); if (!msg) { LOG_ERR("Chatlog", "Unable to malloc... sorry!"); free(start); fclose(file); return NULL; } msg->our_msg = header.author; msg->receipt_time = header.receipt; msg->time = header.time; msg->msg_type = header.msg_type; msg->disk_offset = file_offset; msg->via.txt.length = header.msg_length; msg->via.txt.msg = calloc(1, msg->via.txt.length); if (!msg->via.txt.msg) { LOG_ERR("Chatlog", "Unable to malloc for via.txt.msg... sorry!"); free(start); free(msg); fclose(file); return NULL; } msg->via.txt.author_length = header.author_length; // TODO: msg->via.txt.author used to be allocated but left empty. Commented out for now. // msg->via.txt.author = calloc(1, msg->via.txt.author_length); // if (!msg->via.txt.author) { // LOG_ERR("Chatlog", "Unable to malloc for via.txt.author... sorry!"); // free(msg->via.txt.msg); // free(msg); // fclose(file); // return NULL; // } if (fread(msg->via.txt.msg, msg->via.txt.length, 1, file) != 1) { LOG_ERR("Chatlog", "Log read:\tError reading record %u of length %u at offset %lu: stopping.", count, msg->via.txt.length, msg->disk_offset); // free(msg->via.txt.author); free(msg->via.txt.msg); free(msg); break; } msg->via.txt.length = utf8_validate((uint8_t *)msg->via.txt.msg, msg->via.txt.length); *data++ = msg; --count; ++actual_count; fseeko(file, 1, SEEK_CUR); /* seek an extra \n char */ file_offset = ftello(file); } } fclose(file); if (size) { *size = actual_count; } return start; } bool utox_update_chatlog(char hex[TOX_PUBLIC_KEY_SIZE * 2], size_t offset, uint8_t *data, size_t length) { FILE *file = chatlog_get_file(hex, true); if (!file) { LOG_ERR("History", "Unable to access file provided."); return false; } if (fseeko(file, offset, SEEK_SET)) { LOG_ERR("Chatlog", "History:\tUnable to seek to position %lu in file provided.", offset); fclose(file); return false; } fwrite(data, length, 1, file); fclose(file); return true; } bool utox_remove_friend_chatlog(char hex[TOX_PUBLIC_KEY_SIZE * 2]) { char name[TOX_PUBLIC_KEY_SIZE * 2 + sizeof(".new.txt")]; snprintf(name, sizeof(name), "%.*s.new.txt", TOX_PUBLIC_KEY_SIZE * 2, hex); return utox_remove_file((uint8_t*)name, sizeof(name)); } void utox_export_chatlog_init(uint32_t friend_number) { native_export_chatlog_init(friend_number); } void utox_export_chatlog(char hex[TOX_PUBLIC_KEY_SIZE * 2], FILE *dest_file) { if (!dest_file) { return; } LOG_FILE_MSG_HEADER header; FILE *file = chatlog_get_file(hex, false); struct tm *tm_curr; struct tm_tmp { int tm_year; int tm_mon; int tm_mday; } tm_prev = { .tm_mday = 1}; while (fread(&header, sizeof(header), 1, file) == 1) { tm_curr = localtime(&header.time); if (tm_curr->tm_year > tm_prev.tm_year || (tm_curr->tm_year == tm_prev.tm_year && tm_curr->tm_mon > tm_prev.tm_mon) || (tm_curr->tm_year == tm_prev.tm_year && tm_curr->tm_mon == tm_prev.tm_mon && tm_curr->tm_mday > tm_prev.tm_mday)) { char buffer[128]; size_t len = strftime(buffer, 128, "Day has changed to %A %B %d %Y\n", tm_curr); fwrite(buffer, len, 1, dest_file); } /* Write Timestamp */ fprintf(dest_file, "[%02d:%02d]", tm_curr->tm_hour, tm_curr->tm_min); tm_prev.tm_year = tm_curr->tm_year; tm_prev.tm_mon = tm_curr->tm_mon; tm_prev.tm_mday = tm_curr->tm_mday; int c; if (header.msg_type == MSG_TYPE_NOTICE) { fseek(file, header.author_length, SEEK_CUR); } else { /* Write Author */ fwrite(" <", 2, 1, dest_file); for (size_t i = 0; i < header.author_length; ++i) { c = fgetc(file); if (c != EOF) { fputc(c, dest_file); } } fwrite(">", 1, 1, dest_file); } /* Write text */ fwrite(" ", 1, 1, dest_file); for (size_t i = 0; i < header.msg_length; ++i) { c = fgetc(file); if (c != EOF) { fputc(c, dest_file); } } c = fgetc(file); /* the newline char */ fputc(c, dest_file); } fclose(file); fclose(dest_file); } uTox-0.17.1/src/chatlog.h000066400000000000000000000031731354126257400151350ustar00rootroot00000000000000#ifndef CHATLOG_H #define CHATLOG_H #include #include #include #include #define LOGFILE_SAVE_VERSION 3 typedef struct { uint8_t log_version; time_t time; size_t author_length; size_t msg_length; uint8_t author : 1; uint8_t receipt : 1; uint8_t flags : 5; uint8_t deleted : 1; uint8_t msg_type; uint8_t zeroes[2]; } LOG_FILE_MSG_HEADER; typedef struct msg_header MSG_HEADER; /** * Saves chat log for friend with id hex * * Returns the offset on success * Returns 0 on failure */ size_t utox_save_chatlog(char hex[TOX_PUBLIC_KEY_SIZE * 2], uint8_t *data, size_t length); // This one actually does the work of reading the logfile information. MSG_HEADER **utox_load_chatlog(char hex[TOX_PUBLIC_KEY_SIZE * 2], size_t *size, uint32_t count, uint32_t skip); /** utox_update_chatlog Updates the data for this friend's history. * * When given a friend_number and offset, utox_update_chatlog will overwrite the file, with * the supplied data * length. It makes no attempt to verify the data or length, it'll just * write blindly. */ bool utox_update_chatlog(char hex[TOX_PUBLIC_KEY_SIZE * 2], size_t offset, uint8_t *data, size_t length); /** * Deletes the chat log file for the friend with id hex * * Returns bool indicating if it succeeded */ bool utox_remove_friend_chatlog(char hex[TOX_PUBLIC_KEY_SIZE * 2]); /** * Setup for exporting the chat log to plain text */ void utox_export_chatlog_init(uint32_t friend_number); /** * Export the chat log to plain text */ void utox_export_chatlog(char hex[TOX_PUBLIC_KEY_SIZE * 2], FILE *dest_file); #endif uTox-0.17.1/src/chrono.c000066400000000000000000000022361354126257400147760ustar00rootroot00000000000000#include "chrono.h" #include "debug.h" #include "macros.h" #include #include #include #include "native/thread.h" bool chrono_thread_init = false; static void chrono_thread(void *args) { LOG_INFO("Chono", "Thread starting"); CHRONO_INFO *info = args; chrono_thread_init = true; while (info->ptr != info->target) { info->ptr += info->step; yieldcpu(info->interval_ms); } chrono_thread_init = false; if (info->callback) { info->callback(info->cb_data); } LOG_INFO("Chrono", "Thread exited cleanly"); } bool chrono_start(CHRONO_INFO *info) { if (!info) { LOG_ERR("Chrono", "Chrono info structure is null."); return false; } thread(chrono_thread, info); return true; } bool chrono_end(CHRONO_INFO *info) { if (!info) { LOG_ERR("Chrono", "Chrono info is null"); return false; } (*info).finished = true; while (chrono_thread_init) { //wait for thread to die yieldcpu(1); } return true; } void chrono_callback(uint32_t ms, void func(void *), void *funcargs) { yieldcpu(ms); func(funcargs); } uTox-0.17.1/src/chrono.h000066400000000000000000000012741354126257400150040ustar00rootroot00000000000000#ifndef CHRONO_H #define CHRONO_H #include #include struct chrono_info { uint8_t *ptr, *target; int step; uint32_t interval_ms; bool finished; void (*callback)(void *); void *cb_data; }; typedef struct chrono_info CHRONO_INFO; extern bool chrono_thread_init; /* * Starts the chrono thread using the information from info * Returns true on success * Returns false on failure */ bool chrono_start(CHRONO_INFO *info); /* * Ends the chrono thread * Returns true on success * Returns false on failure */ bool chrono_end(CHRONO_INFO *info); /* * Sleep and then */ void chrono_callback(uint32_t ms, void func(void *), void *funcargs); #endif uTox-0.17.1/src/cocoa/000077500000000000000000000000001354126257400144235ustar00rootroot00000000000000uTox-0.17.1/src/cocoa/CMakeLists.txt000066400000000000000000000012441354126257400171640ustar00rootroot00000000000000project(utoxNATIVE LANGUAGES C) add_library(utoxNATIVE STATIC ../posix/filesys.c cursor.h drawing.m grabdesktop.m interaction.m main.h main.m MainMenu.xib objc_main.h video.m window.c ) target_link_libraries(utoxNATIVE "-framework AppKit" "-framework ApplicationServices" "-framework AVFoundation" "-framework Cocoa" "-framework CoreData" "-framework CoreFoundation" "-framework CoreGraphics" "-framework CoreMedia" "-framework CoreText" "-framework CoreVideo" "-framework Foundation" "-framework OpenAL" "-framework OpenGL" "-framework QuartzCore" -lresolv ) uTox-0.17.1/src/cocoa/Info.plist.in000066400000000000000000000027201354126257400170010ustar00rootroot00000000000000 CFBundleDevelopmentRegion en CFBundleExecutable @EXECUTABLE_NAME@ CFBundleIconFile @APPLE_ICON@ CFBundleIdentifier io.utox.future CFBundleInfoDictionaryVersion 6.0 CFBundleName uTox CFBundleDisplayName uTox (Alpha) CFBundleSpokenName u Tox CFBundlePackageType APPL CFBundleShortVersionString @PROJECT_VERSION@ CFBundleVersion @PROJECT_VERSION@ LSMinimumSystemVersion @CMAKE_OSX_DEPLOYMENT_TARGET@ NSHumanReadableCopyright @PROJECT_COPYRIGHT@ NSMainNibFile @APPLE_MENU@ NSPrincipalClass NSApplication CFBundleURLTypes CFBundleURLName Tox CFBundleTypeRole Viewer CFBundleURLSchemes tox uTox-0.17.1/src/cocoa/MainMenu.xib000066400000000000000000000313711354126257400166450ustar00rootroot00000000000000 uTox-0.17.1/src/cocoa/cursor.h000066400000000000000000000056021354126257400161140ustar00rootroot00000000000000#ifndef SCA_CURSOR_H #define SCA_CURSOR_H #import static inline CGImageRef create_zoom_cursor(CGFloat scale, BOOL plus) { CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); CGColorRef black = CGColorCreateGenericRGB(0, 0, 0, 1.0); CGColorRef white = CGColorCreateGenericRGB(1, 1, 1, 1.0); CGContextRef draw = CGBitmapContextCreate(NULL, 16 * scale, 16 * scale, 8, 0, cs, (CGBitmapInfo)kCGImageAlphaPremultipliedLast); CGColorSpaceRelease(cs); CGContextBeginPath(draw); CGContextMoveToPoint(draw, 2. * scale, 14. * scale); CGContextAddLineToPoint(draw, 15. * scale, 1. * scale); //CGContextCloseSubpath(draw); CGContextSetStrokeColorWithColor(draw, black); CGContextSetLineWidth(draw, 3.0 * scale); CGContextDrawPath(draw, kCGPathStroke); CGContextBeginPath(draw); CGContextAddEllipseInRect(draw, CGRectInset((CGRect){0, 4 * scale, 12 * scale, 12 * scale}, 0.5, 0.5)); CGContextSetLineWidth(draw, scale); CGContextSetFillColorWithColor(draw, white); CGContextDrawPath(draw, kCGPathFillStroke); CGContextBeginPath(draw); CGContextAddRect(draw, (CGRect){3 * scale, 9 * scale, 6 * scale, 2 * scale}); if (plus) CGContextAddRect(draw, (CGRect){5 * scale, 7 * scale, 2 * scale, 6 * scale}); CGContextSetFillColorWithColor(draw, black); CGContextDrawPath(draw, kCGPathFill); CGImageRef glass = CGBitmapContextCreateImage(draw); CGContextRelease(draw); CGColorRelease(white); CGColorRelease(black); return glass; } static inline NSCursor *create_zoom_in_cursor(void) { CGImageRef base = create_zoom_cursor(1.0, YES); CGImageRef base2x = create_zoom_cursor(2.0, YES); NSBitmapImageRep *b = [[NSBitmapImageRep alloc] initWithCGImage:base]; NSBitmapImageRep *b2x = [[NSBitmapImageRep alloc] initWithCGImage:base2x]; NSImage *cur = [[NSImage alloc] initWithSize:(CGSize){16, 16}]; [cur addRepresentation:b2x]; b2x.size = (CGSize){16, 16}; [cur addRepresentation:b]; NSCursor *ret = [[NSCursor alloc] initWithImage:cur hotSpot:(CGPoint){6, 6}]; [b release]; [b2x release]; [cur release]; CGImageRelease(base); CGImageRelease(base2x); return ret; } static inline NSCursor *create_zoom_out_cursor(void) { CGImageRef base = create_zoom_cursor(1.0, NO); CGImageRef base2x = create_zoom_cursor(2.0, NO); NSBitmapImageRep *b = [[NSBitmapImageRep alloc] initWithCGImage:base]; NSBitmapImageRep *b2x = [[NSBitmapImageRep alloc] initWithCGImage:base2x]; NSImage *cur = [[NSImage alloc] initWithSize:(CGSize){16, 16}]; [cur addRepresentation:b2x]; b2x.size = (CGSize){16, 16}; [cur addRepresentation:b]; NSCursor *ret = [[NSCursor alloc] initWithImage:cur hotSpot:(CGPoint){6, 6}]; [b release]; [b2x release]; [cur release]; CGImageRelease(base); CGImageRelease(base2x); return ret; } #endif uTox-0.17.1/src/cocoa/drawing.m000066400000000000000000000504341354126257400162420ustar00rootroot00000000000000#import "main.h" #import "../debug.h" #import "../main.h" #import "../settings.h" #import "../ui.h" #import "../ui/draw.h" #import "../ui/svg.h" #import "../layout/background.h" #ifdef UTOX_COCOA_BRAVE #define DRAW_TARGET_CHK() #else #define DRAW_TARGET_CHK() \ if (!currently_drawing_into_view) { \ LOG_ERR("OSX", "bug: currently_drawing_into_view is nil in %s", __func__); \ abort(); \ } #endif CGImageRef bitmaps[BM_ENDMARKER + 1] = { NULL }; CTFontRef fonts[FONT_MISC + 1] = { NULL }; static uToxView *__unsafe_unretained currently_drawing_into_view; static struct __global_d_state { CTFontRef _use_font; uint32_t _use_font_color; CGColorRef _use_font_color_ref; } global_text_state = { 0 }; #ifdef UTOX_COCOA_USE_CALIBRATED // broken, but you have choices later #define CGColorSpace_CREATE CGColorSpaceCreateCalibratedRGB #define COLOR_WITH_RED colorWithCalibratedRed #else #define CGColorSpace_CREATE CGColorSpaceCreateDeviceRGB #define COLOR_WITH_RED colorWithDeviceRed #endif @implementation uToxView { NSMutableDictionary *_colorCache; } - (instancetype)initWithFrame:(NSRect)frameRect { self = [super initWithFrame:frameRect]; if (self) { _colorCache = [[NSMutableDictionary alloc] init]; self.autoresizesSubviews = YES; self.autoresizingMask = NSViewHeightSizable | NSViewWidthSizable; [self addSubview:[[[NSView alloc] initWithFrame:CGRectZero] autorelease]]; } return self; } - (void)becomeDrawTarget { currently_drawing_into_view = self; self.didDrawInlineVideoThisFrame = NO; CGContextSetTextMatrix([[NSGraphicsContext currentContext] graphicsPort], CGAffineTransformIdentity); } - (void)resignAsDrawTarget { if (!self.didDrawInlineVideoThisFrame) { [self.inlineVideo removeFromSuperview]; } currently_drawing_into_view = nil; } - (void)drawRect:(NSRect)dirtyRect { [self becomeDrawTarget]; panel_draw(&panel_root, 0, 0, settings.window_width, settings.window_height); [self resignAsDrawTarget]; } - (void)resizeSubviewsWithOldSize:(NSSize)oldSize { settings.window_width = self.frame.size.width; settings.window_height = self.frame.size.height; ui_size(settings.window_width, settings.window_height); [self.inputContext invalidateCharacterCoordinates]; } - (NSColor *)color:(uint32_t)packed { NSColor *ret = [_colorCache objectForKey:@(packed)]; if (!ret) { float r = ((packed >> 16) & 0xFF) / 255.0, g = ((packed >> 8) & 0xFF) / 255.0, b = ((packed)&0xFF) / 255.0; // calibrated colours don't match those in X11... ret = [NSColor COLOR_WITH_RED:r green:g blue:b alpha:1.0]; [_colorCache setObject:ret forKey:@(packed)]; } return ret; } - (void)dealloc { [_inlineVideo release]; _inlineVideo = nil; [super dealloc]; } @end /* convert invalid utf8 to valid garbage */ CFStringRef try_to_interpret_string(char *str, uint16_t length) { CFStringEncoding try_list[] = { kCFStringEncodingUTF8, kCFStringEncodingISOLatin1, 0 }; CFStringEncoding *c = try_list; CFStringRef string = NULL; while (*c) { string = CFStringCreateWithBytes(kCFAllocatorDefault, str, length, *c, NO); if (string) { break; } c++; } return string; } int drawtext_want_width(int x, int y, char *str, uint16_t length, BOOL wants_width) { DRAW_TARGET_CHK() CGContextRef context = [NSGraphicsContext currentContext].graphicsPort; CFStringRef string = try_to_interpret_string(str, length); if (!string) { return 0; } CTFontRef font = global_text_state._use_font; CGFloat sz = currently_drawing_into_view.frame.size.height; y = sz - y - CTFontGetSize(font); CFStringRef keys[] = { kCTFontAttributeName, kCTForegroundColorAttributeName }; CFTypeRef values[] = { font, global_text_state._use_font_color_ref }; CFDictionaryRef attributes = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&keys, (const void **)&values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFAttributedStringRef attrString = CFAttributedStringCreate(kCFAllocatorDefault, string, attributes); CFRelease(string); CFRelease(attributes); CTLineRef line = CTLineCreateWithAttributedString(attrString); // Set text position and draw the line into the graphics context CGContextSetTextPosition(context, x, y); CTLineDraw(line, context); CFRelease(line); CFRelease(attrString); return wants_width ? round(CTLineGetTypographicBounds(line, NULL, NULL, NULL) + CTLineGetTrailingWhitespaceWidth(line)) : 0; } void drawtext(int x, int y, const char *str, uint16_t length) { drawtext_want_width(x, y, str, length, NO); } int drawtext_getwidth(int x, int y, const char *str, uint16_t length) { return drawtext_want_width(x, y, str, length, YES); } void drawtextwidth(int x, int width, int y, const char *str, uint16_t length) { DRAW_TARGET_CHK() CGContextRef context = [NSGraphicsContext currentContext].graphicsPort; CFStringRef string = try_to_interpret_string(str, length); if (!string) { return; } CTFontRef font = global_text_state._use_font; CGFloat sz = currently_drawing_into_view.frame.size.height; y = sz - y - CTFontGetSize(font); CFStringRef keys[] = { kCTFontAttributeName, kCTForegroundColorAttributeName }; CFTypeRef values[] = { font, global_text_state._use_font_color_ref }; CFDictionaryRef attributes = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&keys, (const void **)&values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFAttributedStringRef attrString = CFAttributedStringCreate(kCFAllocatorDefault, string, attributes); CFAttributedStringRef ellipse = CFAttributedStringCreate(kCFAllocatorDefault, CFSTR("\u2026"), attributes); CFRelease(string); CFRelease(attributes); CTLineRef ellipse_line = CTLineCreateWithAttributedString(ellipse); CTLineRef line = CTLineCreateWithAttributedString(attrString); CTLineRef cut_line = CTLineCreateTruncatedLine(line, width, kCTLineTruncationEnd, ellipse_line); if (!cut_line) { LOG_WARN("OSX", "warning: space given not enough for drawtextwidth, bailing"); goto free_everything; } // Set text position and draw the line into the graphics context CGContextSetTextPosition(context, x, y); CTLineDraw(cut_line, context); CFRelease(cut_line); free_everything: CFRelease(line); CFRelease(ellipse_line); CFRelease(attrString); CFRelease(ellipse); } void drawtextwidth_right(int x, int width, int y, const char *str, uint16_t length) { DRAW_TARGET_CHK() CGContextRef context = [NSGraphicsContext currentContext].graphicsPort; CFStringRef string = try_to_interpret_string(str, length); if (!string) { return; } CTFontRef font = global_text_state._use_font; CGFloat sz = currently_drawing_into_view.frame.size.height; y = sz - y - CTFontGetSize(font); CFStringRef keys[] = { kCTFontAttributeName, kCTForegroundColorAttributeName }; CFTypeRef values[] = { font, global_text_state._use_font_color_ref }; CFDictionaryRef attributes = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&keys, (const void **)&values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFAttributedStringRef attrString = CFAttributedStringCreate(kCFAllocatorDefault, string, attributes); CFAttributedStringRef ellipse = CFAttributedStringCreate(kCFAllocatorDefault, CFSTR("\u2026"), attributes); CFRelease(string); CFRelease(attributes); CTLineRef ellipse_line = CTLineCreateWithAttributedString(ellipse); CTLineRef line = CTLineCreateWithAttributedString(attrString); CTLineRef cut_line = CTLineCreateTruncatedLine(line, width, kCTLineTruncationEnd, ellipse_line); if (!cut_line) { LOG_WARN("OSX", "warning: space given not enough for drawtextwidth, bailing"); goto free_everything; } CGFloat checkleading = width - CTLineGetTypographicBounds(cut_line, NULL, NULL, NULL); // Set text position and draw the line into the graphics context CGContextSetTextPosition(context, x + checkleading, y); CTLineDraw(cut_line, context); CFRelease(cut_line); free_everything: CFRelease(line); CFRelease(ellipse_line); CFRelease(attrString); CFRelease(ellipse); } void drawtextrange(int x, int x2, int y, const char *str, uint16_t length) { drawtextwidth(x, x2 - x, y, str, length); } void drawtextrangecut(int x, int x2, int y, const char *str, uint16_t length) { drawtextwidth(x, x2 - x, y, str, length); } int textwidth(const char *str, uint16_t length) { CFStringRef string = try_to_interpret_string(str, length); if (!string) { return 0; } CTFontRef font = global_text_state._use_font; CFStringRef keys[] = { kCTFontAttributeName }; CFTypeRef values[] = { font }; CFDictionaryRef attributes = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&keys, (const void **)&values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFAttributedStringRef attrString = CFAttributedStringCreate(kCFAllocatorDefault, string, attributes); CFRelease(string); CFRelease(attributes); CTLineRef line = CTLineCreateWithAttributedString(attrString); int ret = round(CTLineGetTypographicBounds(line, NULL, NULL, NULL) + CTLineGetTrailingWhitespaceWidth(line)); CFRelease(line); CFRelease(attrString); return ret; } int textfit(const char *str, uint16_t length, int width) { CFStringRef string = try_to_interpret_string(str, length); if (!string) { return 0; } CTFontRef font = global_text_state._use_font; CFStringRef keys[] = { kCTFontAttributeName }; CFTypeRef values[] = { font }; CFDictionaryRef attributes = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&keys, (const void **)&values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFAttributedStringRef attrString = CFAttributedStringCreate(kCFAllocatorDefault, string, attributes); CFRelease(attributes); CTLineRef line = CTLineCreateWithAttributedString(attrString); int ind = CTLineGetStringIndexForPosition(line, (CGPoint){ width, 0 }); CFRelease(line); CFRelease(attrString); if (ind == -1) { ++ind; } int ret = [[(NSString *)string substringToIndex:ind] lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; CFRelease(string); return ret; } int textfit_near(const char *str, uint16_t length, int width) { return textfit(str, length, width); } void setfont(int id) { global_text_state._use_font = fonts[id]; } uint32_t setcolor(uint32_t color) { uint32_t ret = global_text_state._use_font_color; if (global_text_state._use_font_color_ref) { CGColorRelease(global_text_state._use_font_color_ref); } CGColorSpaceRef cs = CGColorSpace_CREATE(); float r = ((color >> 16) & 0xFF) / 255.0, g = ((color >> 8) & 0xFF) / 255.0, b = ((color)&0xFF) / 255.0; CGFloat comp[4] = { r, g, b, 1.0 }; global_text_state._use_font_color_ref = CGColorCreate(cs, comp); CGColorSpaceRelease(cs); global_text_state._use_font_color = color; return ret; } void setscale_fonts(void) { for (int i = 0; i < sizeof(fonts) / sizeof(CTFontRef); ++i) { RELEASE_CHK(CFRelease, fonts[i]); } CFStringRef reg = (CFStringRef) [NSFont systemFontOfSize:0.0].fontName; CFStringRef bold = (CFStringRef) [NSFont boldSystemFontOfSize:0.0].fontName; LOG_TRACE("OSX Drawing", "Using %s fontfamily", CFStringGetCStringPtr(reg, kCFStringEncodingUTF8)); fonts[FONT_TEXT] = CTFontCreateWithNameAndOptions(reg, SCALE(12.0), NULL, kCTFontOptionsDefault); fonts[FONT_STATUS] = CTFontCreateWithNameAndOptions(reg, SCALE(11.0), NULL, kCTFontOptionsDefault); fonts[FONT_LIST_NAME] = CTFontCreateWithNameAndOptions(reg, SCALE(12.0), NULL, kCTFontOptionsDefault); fonts[FONT_TITLE] = CTFontCreateWithNameAndOptions(bold, SCALE(12.0), NULL, kCTFontOptionsDefault); fonts[FONT_SELF_NAME] = CTFontCreateWithNameAndOptions(bold, SCALE(14.0), NULL, kCTFontOptionsDefault); fonts[FONT_MISC] = CTFontCreateWithNameAndOptions(bold, SCALE(10.0), NULL, kCTFontOptionsDefault); CFRelease(reg); CFRelease(bold); AT_LEAST_ELCAPITAN_DO { font_small_lineheight = CTFontGetBoundingBox(fonts[FONT_TEXT]).size.height; } else { font_small_lineheight = (CTFontGetBoundingBox(fonts[FONT_TEXT]).size.height - CTFontGetDescent(fonts[FONT_TEXT])); } font_small_lineheight += CTFontGetLeading(fonts[FONT_TEXT]); } void setscale(void) { LOG_WARN("OSX", "%d", ui_scale); uToxAppDelegate *ad = (uToxAppDelegate *)[NSApplication sharedApplication].delegate; float old_scale = ui_scale; // handle OS X retina capability gracefully ui_scale *= ad.utox_window.backingScaleFactor; for (int i = 0; i < (sizeof(bitmaps) / sizeof(CGImageRef)); ++i) { RELEASE_CHK(CGImageRelease, bitmaps[i]); } svg_draw(1); // now we have 2x images, if applicable ui_scale = old_scale; ad.utox_window.minSize = (CGSize){ SCALE(MAIN_WIDTH), SCALE(MAIN_HEIGHT) }; } void cgdataprovider_is_finished(void *info, const void *data, size_t size) { free((void *)data); } void drawalpha(int bm, int x, int y, int width, int height, uint32_t color) { DRAW_TARGET_CHK() [NSGraphicsContext saveGraphicsState]; CGFloat sz = currently_drawing_into_view.frame.size.height; CGRect rect = {.origin = { .x = x, .y = sz - y - height, }, .size = { .width = width, .height = height, } }; float r = ((color >> 16) & 0xFF) / 255.0, g = ((color >> 8) & 0xFF) / 255.0, b = ((color)&0xFF) / 255.0; const CGFloat colour_parts[] = { r, g, b, 1.0 }; CGContextRef this = [[NSGraphicsContext currentContext] graphicsPort]; CGContextClipToMask(this, rect, bitmaps[bm]); CGContextSetFillColor(this, colour_parts); CGContextFillRect(this, rect); [NSGraphicsContext restoreGraphicsState]; } void loadalpha(int bm, void *data, int width, int height) { // TODO: inline assembly size_t bs = width * height * 4; unsigned char *buf = calloc(bs, 1); for (int i = 3; i < bs; i += 4) { buf[i] = *(unsigned char *)(data++); } CGColorSpaceRef cs = CGColorSpace_CREATE(); CGDataProviderRef dat = CGDataProviderCreateWithData(NULL, buf, bs, &cgdataprovider_is_finished); bitmaps[bm] = CGImageCreate(width, height, 8, 32, width * 4, cs, kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast, dat, NULL, NO, kCGRenderingIntentDefault); CGDataProviderRelease(dat); CGColorSpaceRelease(cs); } void draw_rect_frame(int x, int y, int width, int height, uint32_t color) { DRAW_TARGET_CHK() CGFloat sz = currently_drawing_into_view.frame.size.height; CGRect rect = CGRectInset((CGRect){ .origin = { .x = x, .y = sz - y - height, }, .size = { .width = width, .height = height, } }, 0.5, 0.5); [[currently_drawing_into_view color:color] set]; [[NSBezierPath bezierPathWithRect:rect] stroke]; } void draw_rect_fill(int x, int y, int width, int height, uint32_t color) { DRAW_TARGET_CHK() CGFloat sz = currently_drawing_into_view.frame.size.height; CGRect rect = { .origin = { .x = x, .y = sz - y - height, }, .size = { .width = width, .height = height, } }; [[currently_drawing_into_view color:color] set]; NSRectFill(rect); } void drawrect(int x, int y, int right, int bottom, uint32_t color) { draw_rect_fill(x, y, right - x, bottom - y, color); } void drawhline(int x, int y, int x2, uint32_t color) { DRAW_TARGET_CHK() CGFloat sz = currently_drawing_into_view.frame.size.height; CGRect rect = {.origin = { .x = x, .y = sz - y - 1, }, .size = { .width = x2 - x, .height = 1, } }; [[currently_drawing_into_view color:color] set]; NSRectFill(rect); } void drawvline(int x, int y, int y2, uint32_t color) { DRAW_TARGET_CHK() CGFloat sz = currently_drawing_into_view.frame.size.height; CGRect rect = {.origin = { .x = x, .y = sz - y2, }, .size = { .width = 1, .height = y2 - y, } }; [[currently_drawing_into_view color:color] set]; NSRectFill(rect); } void pushclip(int x, int y, int width, int height) { DRAW_TARGET_CHK() [NSGraphicsContext saveGraphicsState]; CGFloat sz = currently_drawing_into_view.frame.size.height; NSRectClip((CGRect){ x, sz - y - height, width, height }); } void popclip(void) { DRAW_TARGET_CHK() // will work fine as long as nobody does any other weirdness with gstate [NSGraphicsContext restoreGraphicsState]; } void enddraw(int x, int y, int width, int height) {} void draw_image(const NATIVE_IMAGE *image, int x, int y, uint32_t width, uint32_t height, uint32_t imgx, uint32_t imgy) { DRAW_TARGET_CHK() // LOG_WARN("OSX", "%lu %lu %lf", imgx, imgy, image->scale); CGFloat sz = currently_drawing_into_view.frame.size.height; CGRect rect = {.origin = { .x = x, .y = sz - y - height, }, .size = { .width = width, .height = height, } }; CGContextRef this = [NSGraphicsContext currentContext].graphicsPort; CGImageRef di = CGImageCreateWithImageInRect(image->image, (CGRect){ imgx, imgy, width / image->scale, height / image->scale }); CGContextDrawImage(this, rect, di); CFRelease(di); } void draw_inline_image(uint8_t *img_data, size_t size, uint16_t w, uint16_t h, int x, int y) { DRAW_TARGET_CHK() uToxIroncladVideoContent *inlineVideo = currently_drawing_into_view.inlineVideo; if (!inlineVideo) { inlineVideo = [[uToxIroncladVideoContent alloc] initWithFrame:(CGRect){ { 0, 0 }, { 16, 16 } }]; currently_drawing_into_view.inlineVideo = inlineVideo; } CGFloat sz = currently_drawing_into_view.frame.size.height; CGRect rect = {.origin = { .x = x, .y = sz - y - h, }, .size = { .width = w, .height = h, } }; if (!CGRectEqualToRect(rect, inlineVideo.frame)) { inlineVideo.frame = rect; [inlineVideo checkSize]; } if (inlineVideo.superview != currently_drawing_into_view) { [currently_drawing_into_view addSubview:inlineVideo]; } [inlineVideo displayImage:img_data w:w h:h]; currently_drawing_into_view.didDrawInlineVideoThisFrame = YES; } uTox-0.17.1/src/cocoa/grabdesktop.m000066400000000000000000000164421354126257400171150ustar00rootroot00000000000000#import #import #include "main.h" #include "../flist.h" #include "../friend.h" #include "../ui.h" #include "../av/utox_av.h" #include "../native/keyboard.h" static void stardust_display_capping_done(bool video, uint64_t ret, NSWindow *window); static inline CGRect CGRectCentreInRect(CGRect r1, CGRect r2) { return (CGRect){ { (r2.size.width - r1.size.width) / 2.0, (r2.size.height - r1.size.height) / 2.0 }, r1.size }; } @interface uToxStardustWindow : NSWindow @end @implementation uToxStardustWindow - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { return frameRect; } @end @implementation uToxStardustView { CGRect returnRect; } + (NSWindow *)createWindowOnScreen:(NSScreen *)target { NSWindow *ret = [[NSWindow alloc] initWithContentRect:CGRectMake(0, 0, target.frame.size.width, target.frame.size.height) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO screen:target]; ret.backgroundColor = [NSColor clearColor]; ret.opaque = NO; ret.level = NSStatusWindowLevel; return ret; } // Hacky patch I stole from https://developer.apple.com/reference/uikit/nstextalignment/nstextalignmentcenter #define NSTextAlignmentCenter 2 - (instancetype)initWithFrame:(NSRect)frameRect { self = [super initWithFrame:frameRect]; if (self) { returnRect = (CGRect) { 0 }; CGRect mainFrame = ((uToxAppDelegate *)[NSApp delegate]).utox_window.frame; CGRect posRect = CGRectOffset(CGRectCentreInRect((CGRect){ 0, 0, 480, 40 }, mainFrame), mainFrame.origin.x, mainFrame.origin.y); NSLog(@"%@", NSStringFromRect(posRect)); self.instruction = [[[NSTextField alloc] initWithFrame:posRect] autorelease]; self.instruction.stringValue = NSSTRING_FROM_LOCALIZED(SCREEN_CAPTURE_PROMPT); self.instruction.textColor = [NSColor whiteColor]; self.instruction.bezeled = NO; self.instruction.drawsBackground = NO; self.instruction.editable = NO; self.instruction.font = [NSFont systemFontOfSize:16.0]; self.instruction.alignment = NSTextAlignmentCenter; [self addSubview:self.instruction]; } return self; } - (void)drawRect:(NSRect)dirtyRect { // CGRect draw = CGRectStandardize(returnRect); [[NSColor colorWithCalibratedRed:0 green:0 blue:0 alpha:0.6] set]; NSRectFill(dirtyRect); if (returnRect.size.height != 0 || returnRect.size.width != 0) { CGContextRef c = [NSGraphicsContext currentContext].graphicsPort; CGContextSetBlendMode(c, kCGBlendModeClear); CGContextClearRect(c, returnRect); } } - (void)mouseDown:(NSEvent *)theEvent { returnRect.origin = theEvent.locationInWindow; returnRect = CGRectIntegral(returnRect); } - (void)mouseDragged:(NSEvent *)theEvent { CGRect oldRect = CGRectStandardize(returnRect); returnRect.size = (CGSize){ theEvent.locationInWindow.x - returnRect.origin.x, theEvent.locationInWindow.y - returnRect.origin.y }; [self setNeedsDisplayInRect:oldRect]; [self setNeedsDisplayInRect:CGRectStandardize(returnRect)]; if ([self.subviews containsObject:self.instruction]) { [self.instruction removeFromSuperview]; } } - (void)mouseUp:(NSEvent *)theEvent { returnRect = CGRectIntegral(CGRectStandardize(returnRect)); NSLog(@"%@", NSStringFromRect(returnRect)); CGDirectDisplayID dispid = [self.window.screen.deviceDescription[@"NSScreenNumber"] unsignedIntegerValue]; stardust_display_capping_done(self.isVideo, (uint64_t)dispid << 8, self.window); } - (void)keyDown:(NSEvent *)theEvent { // NSLog(@"%@", theEvent); switch (theEvent.keyCode) { case kVK_Escape: stardust_display_capping_done(self.isVideo, 1, self.window); break; default: break; } } - (CGRect)getRect { return returnRect; } - (NSView *)hitTest:(NSPoint)aPoint { return self; } @end stardust_context_t stardust_context = { 0 }; static void stardust_display_capping_done(bool video, uint64_t ret, NSWindow *window) { uToxStardustView *v = window.contentView; NSScreen * target = window.screen; if ((ret & 0xff) == 0) { CGDirectDisplayID screen_id = (ret >> 8) & 0xffffffffffffffUL; if (!video) { CGRect rect = [v getRect]; rect.origin.y = target.frame.size.height - rect.origin.y - rect.size.height; CGImageRef inliness = CGWindowListCreateImage(rect, kCGWindowListOptionOnScreenBelowWindow, window.windowNumber, kCGWindowImageDefault); NATIVE_IMAGE *img = malloc(sizeof(NATIVE_IMAGE)); img->scale = 1.0; img->image = inliness; CFMutableDataRef dat = CFDataCreateMutable(kCFAllocatorDefault, 0); CGImageDestinationRef dest = CGImageDestinationCreateWithData(dat, kUTTypePNG, 1, NULL); CGImageDestinationAddImage(dest, inliness, NULL); CGImageDestinationFinalize(dest); CFRelease(dest); size_t size = CFDataGetLength(dat); uint8_t *owned_ptr = malloc(size); memcpy(owned_ptr, CFDataGetBytePtr(dat), size); CFRelease(dat); friend_sendimage(flist_get_friend(), img, CGImageGetWidth(inliness), CGImageGetHeight(inliness), (UTOX_IMAGE)owned_ptr, size); } else { desktop_capture_from = screen_id; CGRect rect = [v getRect]; desktop_capture_scale = [window backingScaleFactor]; // for video, it must be divisible by 8 or we get distortion desktop_capture_rect = rect; desktop_capture_rect.size.width -= (uint32_t)desktop_capture_rect.size.width % 8; desktop_capture_rect.size.height -= (uint32_t)desktop_capture_rect.size.height % 8; postmessage_utoxav(UTOXAV_SET_VIDEO_IN, 0, 0, (void *)1); } } // CSA false positive: this has a +1 refcount from desktopgrab() [stardust_context.window release]; stardust_context.window = nil; stardust_context.view = nil; stardust_context.finished_callback = NULL; } // do not breakpoint in this function or you're gonna have a fun time void desktopgrab(bool video) { uToxAppDelegate *ad = (uToxAppDelegate *)[NSApp delegate]; NSScreen *target = [ad.utox_window screen]; NSWindow * window = [uToxStardustView createWindowOnScreen:target]; uToxStardustView *v = [[uToxStardustView alloc] initWithFrame:(CGRect){ 0, 0, window.frame.size.width, window.frame.size.height }]; v.video = video; window.contentView = v; [window makeKeyAndOrderFront:ad]; // dirty hack to get around a first responder issue stardust_context.window = window; stardust_context.view = v; stardust_context.finished_callback = &stardust_display_capping_done; [v release]; postmessage_utoxav(UTOXAV_SET_VIDEO_IN, 1, 0, NULL); } uTox-0.17.1/src/cocoa/interaction.m000066400000000000000000001013161354126257400171220ustar00rootroot00000000000000#include "main.h" #include "cursor.h" #include "../avatar.h" #include "../chatlog.h" #include "../file_transfers.h" #include "../filesys.h" #include "../flist.h" #include "../friend.h" #include "../groups.h" #include "../main.h" #include "../messages.h" #include "../self.h" #include "../settings.h" #include "../stb.h" #include "../text.h" #include "../tox.h" #include "../ui.h" #include "../utox.h" #include "../av/utox_av.h" #include "../native/clipboard.h" #include "../native/keyboard.h" #include "../native/notify.h" #include "../native/ui.h" #include "../ui/edit.h" #include "../ui/panel.h" #include "../layout/background.h" #include "../layout/friend.h" #include "../layout/group.h" NSCursor *cursors[8]; bool have_focus = false; void setup_cursors(void) { cursors[CURSOR_NONE] = [NSCursor arrowCursor]; cursors[CURSOR_HAND] = [NSCursor pointingHandCursor]; cursors[CURSOR_SELECT] = [NSCursor crosshairCursor]; cursors[CURSOR_TEXT] = [NSCursor IBeamCursor]; cursors[CURSOR_ZOOM_IN] = create_zoom_in_cursor(); cursors[CURSOR_ZOOM_OUT] = create_zoom_out_cursor(); } int getbuf(char *ptr, size_t len, int value); // below comment applies too static inline NSRange uToxRangeFromNSRange(NSRange utf16, NSString *s) { NSInteger start = [[s substringToIndex:utf16.location] lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; NSInteger len = [[s substringWithRange:utf16] lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; return NSMakeRange(start, len); } static inline void utf8_correct(NSRange *r, char *s, size_t len) { while ((s[r->location] >> 6) == 2 && r->location > 0) { --r->location; } int ind = r->location + r->length - 1; while ((s[ind] >> 6) == 2 && ind < len) { ++ind; } r->length = ind - r->location; } // find a PANEL by bruteforcing the UI tree. static int find_ui_object_recursive(const PANEL *root, const PANEL *target, int **outarrayptr, int n) { // if root == target and n == 0 (i.e. you initially called with the same ptr for root and target) // outarrayptr will be undefined, but the return will be 1 // root and target being the same is a bug in the caller though, but i thought // you should know this. if (root == target) { // alloc the path at the end so we don't have to know the length first. // we're going to fill in this array backwards *outarrayptr = calloc(n + 1, sizeof(int)); // NSLog(@"ALLOCATED IT AT %p %d", *outarrayptr, n); *outarrayptr += n; **outarrayptr = -1; // sentinel return 1; } PANEL **child = root->child; if (!child) { return 0; } do { if (!*child) { break; } int ret = find_ui_object_recursive(*child, target, outarrayptr, n + 1); if (ret) { (*outarrayptr)--; // when the initial call returns, *outarrayptr should be the same as the value // we got from calloc above. consider this comment a "soft assertion". **outarrayptr = child - root->child; return ret; } } while (++child); return 0; } #define _apply_generic_transform(type, a) \ { \ type *__ = (type *)a; \ int relx = (a->x < 0) ? width + a->x : a->x; \ int rely = (a->y < 0) ? height + a->y : a->y; \ x += relx; \ y += rely; \ width = (__->width <= 0) ? width + __->width - relx : __->width; \ height = (__->height <= 0) ? height + __->height - rely : __->height; \ } static CGRect find_ui_object_in_window(const PANEL *ui) { int * path = NULL; CGRect ret = CGRectZero; int did_find = find_ui_object_recursive(&panel_root, ui, &path, 0); PANEL *ui_element = &panel_root; if (did_find) { int x = ui_element->x, y = ui_element->y, width = settings.window_width, height = settings.window_height; for (int i = 0; path[i] != -1; i++) { // LOG_TRACE("Interaction", "@: %d %d %d %d", x, y, width, height); // LOG_TRACE("Interaction", "%d %d %d %p", i, path[i], ui_element->child[path[i]]->type, // ui_element->child[path[i]]->content_scroll); ui_element = ui_element->child[path[i]]; switch (ui_element->type) { case 6: _apply_generic_transform(EDIT, ui_element); height += SCALE(8); // seems to be the magic number break; default: _apply_generic_transform(PANEL, ui_element); break; } } ret = CGRectMake(x, settings.window_height - height - y, width, height); } free(path); return ret; } static inline void move_left_to_char(char c) { EDIT *edit = edit_get_active(); int loc = edit_getcursorpos(); if (loc == 0) { return; } if (edit->data[loc - 1] == c) { loc--; } while (loc != 0 && edit->data[loc - 1] != c) { int move = utf8_unlen(edit->data + loc); loc -= move; } edit_setselectedrange(loc, 0); redraw(); } static inline void select_left_to_char(char c) { EDIT *edit = edit_get_active(); int loc = edit_getcursorpos(), len = edit_selection(edit, NULL, 0); if (loc == 0) { return; } if (edit->data[loc - 1] == c) { loc--; len++; } while (loc != 0 && edit->data[loc - 1] != c) { int move = utf8_unlen(edit->data + loc); loc -= move; len += move; } edit_setselectedrange(loc, len); redraw(); } static inline void move_right_to_char(char c) { EDIT *edit = edit_get_active(); int loc = edit_getcursorpos(); if (loc > edit->length) { return; } if (edit->data[loc] == c) { loc += 1; } while (loc != edit->length && edit->data[loc] != c) { loc += utf8_len(&edit->data[loc]); } edit_setselectedrange(loc, 0); redraw(); } static inline void select_right_to_char(char c) { EDIT *edit = edit_get_active(); int loc = edit_getcursorpos(), end = loc + edit_selection(edit, NULL, 0); if (end > edit->length) { return; } if (edit->data[end] == c) { end += 1; } while (end != edit->length && edit->data[end] != c) { int move = utf8_len(edit->data + end); end += move; } edit_setselectedrange(loc, end - loc); redraw(); } @implementation uToxView (UserInteraction) + (NSSpeechSynthesizer *)sharedSpeechSynthesizer { static NSSpeechSynthesizer *ss; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ ss = [[NSSpeechSynthesizer alloc] initWithVoice:[NSSpeechSynthesizer defaultVoice]]; }); return ss; } - (void)mouseDown:(NSEvent *)theEvent { // NSLog(@"mouse down"); panel_mdown(&panel_root); int tclk = 0; switch (theEvent.clickCount) { case 3: tclk = 1; case 2: panel_dclick(&panel_root, tclk); default: break; } } - (void)mouseUp:(NSEvent *)theEvent { panel_mup(&panel_root); } - (void)rightMouseDown:(NSEvent *)theEvent { panel_mright(&panel_root); } - (void)rightMouseUp:(NSEvent *)theEvent { panel_mup(&panel_root); } - (void)mouseMoved:(NSEvent *)theEvent { cursor = 0; panel_mmove(&panel_root, 0, 0, settings.window_width, settings.window_height, theEvent.locationInWindow.x, self.frame.size.height - theEvent.locationInWindow.y, theEvent.deltaX, theEvent.deltaY); [cursors[cursor] set]; } - (void)mouseDragged:(NSEvent *)theEvent { cursor = 0; panel_mmove(&panel_root, 0, 0, settings.window_width, settings.window_height, theEvent.locationInWindow.x, self.frame.size.height - theEvent.locationInWindow.y, theEvent.deltaX, theEvent.deltaY); [cursors[cursor] set]; } - (void)rightMouseDragged:(NSEvent *)theEvent { cursor = 0; panel_mmove(&panel_root, 0, 0, settings.window_width, settings.window_height, theEvent.locationInWindow.x, self.frame.size.height - theEvent.locationInWindow.y, theEvent.deltaX, theEvent.deltaY); [cursors[cursor] set]; } - (void)mouseEntered:(NSEvent *)theEvent { [cursors[0] push]; } - (void)mouseExited:(NSEvent *)theEvent { panel_mleave(&panel_root); [NSCursor pop]; } - (void)scrollWheel:(NSEvent *)theEvent { panel_mwheel(&panel_root, 0, 0, settings.window_width, settings.window_height, theEvent.deltaY, theEvent.hasPreciseScrollingDeltas); } - (void)updateTrackingAreas { [self removeTrackingArea:[self.trackingAreas firstObject]]; NSTrackingArea *track = [[NSTrackingArea alloc] initWithRect:self.bounds options:NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways owner:self userInfo:nil]; [self addTrackingArea:track]; [track release]; } - (void)keyDown:(NSEvent *)theEvent { // option + [0-9] will jump to the n-th chat char n = 0; if (theEvent.charactersIgnoringModifiers.length == 1 && (theEvent.modifierFlags & NSDeviceIndependentModifierFlagsMask) == NSControlKeyMask) { switch (n = [theEvent.charactersIgnoringModifiers characterAtIndex:0]) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': flist_selectchat(n - '1'); redraw(); break; case '0': flist_selectchat(9); redraw(); break; default: goto defaultaction; } } else if (stardust_context.window && theEvent.keyCode == kVK_Escape) { stardust_context.finished_callback(stardust_context.view.isVideo, 1, stardust_context.window); } else { defaultaction: // easier to let MacOS interpret [self interpretKeyEvents:@[ theEvent ]]; } } #define BEEP_IF_EDIT_NOT_ACTIVE() \ if (!edit_active()) { \ NSBeep(); \ return; \ } - (void)insertText:(id)insertString { BEEP_IF_EDIT_NOT_ACTIVE() if ([insertString isKindOfClass:NSAttributedString.class]) { insertString = [insertString string]; } edit_paste((char *)[insertString UTF8String], [insertString lengthOfBytesUsingEncoding:NSUTF8StringEncoding], NO); } // TODO: NSTextInputClient #define FLAGS() \ (([NSEvent modifierFlags] & NSCommandKeyMask) ? 4 : 0) | (([NSEvent modifierFlags] & NSShiftKeyMask) ? 1 : 0) - (void)insertTab:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() edit_char(KEY_TAB, YES, FLAGS()); } - (void)insertNewline:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() edit_char(KEY_RETURN, YES, FLAGS()); } - (void)deleteBackward:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() edit_char(KEY_BACK, YES, FLAGS()); } - (void)deleteForward:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() edit_char(KEY_DEL, YES, FLAGS()); } - (void)moveLeft:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() edit_char(KEY_LEFT, YES, FLAGS()); } - (void)moveRight:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() edit_char(KEY_RIGHT, YES, FLAGS()); } - (void)moveUp:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() edit_char(KEY_UP, YES, FLAGS()); } - (void)moveDown:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() edit_char(KEY_DOWN, YES, FLAGS()); } - (void)selectAll:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() edit_char('A', YES, FLAGS()); } - (void)cut:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() copy(0); [self delete:sender]; } - (void) delete:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() if (edit_copy(NULL, 0)) { edit_char(KEY_DEL, YES, FLAGS()); } } - (void)moveToBeginningOfDocument:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() edit_setselectedrange(0, 0); redraw(); } - (void)moveToBeginningOfDocumentAndModifySelection:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() int loc = edit_getcursorpos(), len = edit_copy(NULL, 0); edit_setselectedrange(0, loc + len); redraw(); } - (void)moveToEndOfDocument:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() edit_setselectedrange(edit_get_active()->length, 0); redraw(); } - (void)moveToEndOfDocumentAndModifySelection:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() int loc = edit_getcursorpos(), len = edit_get_active()->length - loc; edit_setselectedrange(loc, len); redraw(); } - (void)moveToBeginningOfLine:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() move_left_to_char('\n'); } - (void)moveToBeginningOfLineAndModifySelection:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() select_left_to_char('\n'); } - (void)moveToEndOfLine:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() move_right_to_char('\n'); } - (void)moveToEndOfLineAndModifySelection:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() select_right_to_char('\n'); } - (void)moveWordLeft:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() // FIXME: words are not always separated by a space move_left_to_char(' '); } - (void)moveWordLeftAndModifySelection:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() // FIXME: words are not always separated by a space select_left_to_char(' '); } - (void)moveWordRight:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() // FIXME: words are not always separated by a space move_right_to_char(' '); } - (void)moveWordRightAndModifySelection:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() // FIXME: words are not always separated by a space select_right_to_char(' '); } - (void)moveLeftAndModifySelection:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() if (edit_getcursorpos() == 0) { return; } int loc = edit_getcursorpos() - 1, len = edit_copy(NULL, 0) + 1; while (edit_get_active()->data[loc] >> 6 == 2) { loc -= 1; len += 1; } edit_setselectedrange(loc, len); redraw(); } - (void)moveRightAndModifySelection:(id)sender { BEEP_IF_EDIT_NOT_ACTIVE() int loc = edit_getcursorpos(), len = edit_copy(NULL, 0); if (loc + len > edit_get_active()->length) { return; } int l = utf8_len(&edit_get_active()->data[loc + len]); len += l; edit_setselectedrange(loc, len); redraw(); } #undef FLAGS #undef BEEP_IF_EDIT_NOT_ACTIVE - (void)paste:(id)sender { paste(); } - (void)copy:(id)sender { copy(1); } - (void)focusPaneAddFriend:(id)sender { flist_selectaddfriend(); redraw(); } - (void)focusPanePreferences:(id)sender { flist_selectsettings(); redraw(); } - (void)createGroupchat:(id)sender { postmessage_toxcore(TOX_GROUP_CREATE, 1, 0, NULL); } - (void)tabPrevFriend:(id)sender { flist_previous_tab(); redraw(); } - (void)tabNextFriend:(id)sender { flist_next_tab(); redraw(); } - (void)startSpeaking:(id)sender { char *buf = malloc(65536); int len = getbuf(buf, 65536, 0); if (len != 0) { NSString *strtospk = [[NSString alloc] initWithBytes:buf length:len encoding:NSUTF8StringEncoding]; [[uToxView sharedSpeechSynthesizer] startSpeakingString:strtospk]; [strtospk release]; } free(buf); } - (void)stopSpeaking:(id)sender { [[uToxView sharedSpeechSynthesizer] stopSpeaking]; } - (NSString *)copyEditContents { NSString *strtocopy; char * buf = malloc(65536); int len = getbuf(buf, 65536, 0); strtocopy = [[NSString alloc] initWithBytes:buf length:len encoding:NSUTF8StringEncoding]; free(buf); return strtocopy; } #pragma mark - NSTextInputClient - (void)insertText:(id)aString replacementRange:(NSRange)replacementRange { // Get a valid range if (replacementRange.location == NSNotFound) { NSRange markedRange = self.markedRange; if (markedRange.location != NSNotFound) { replacementRange = markedRange; } else { replacementRange = self.selectedRange; } } if ([aString isKindOfClass:[NSAttributedString class]]) { aString = [aString string]; } edit_setselectedrange(replacementRange.location, replacementRange.length); uint16_t insl = [aString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; edit_paste((char *)[aString UTF8String], insl, 0); [self unmarkText]; } - (NSArray *)validAttributesForMarkedText { return @[]; } - (BOOL)hasMarkedText { return edit_getmark(NULL, NULL); } - (NSRange)markedRange { uint16_t loc, len; BOOL valid = edit_getmark(&loc, &len); if (!valid) { return (NSRange){ NSNotFound, 0 }; } else { return (NSRange){ loc, len }; } } - (void)unmarkText { edit_setmark(0, 0); } - (NSRange)selectedRange { if (!edit_active()) { return (NSRange){ NSNotFound, 0 }; } else { return (NSRange){ edit_getcursorpos(), edit_selection(edit_get_active(), NULL, 0) }; } } - (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange { NSLog(@"%@", NSStringFromRange(replacementRange)); uint16_t loc, len; BOOL valid; if ((valid = edit_getmark(&loc, &len)) && replacementRange.location != NSNotFound) { replacementRange.location += loc; } else if (valid) { replacementRange = NSMakeRange(loc, len); NSLog(@"valid=1 replace %d %d", loc, len); } else { replacementRange = NSMakeRange(edit_getcursorpos(), edit_selection(edit_get_active(), NULL, 0)); } if ([aString isKindOfClass:[NSAttributedString class]]) { aString = [aString string]; } edit_setselectedrange(replacementRange.location, replacementRange.length); uint16_t insl = [aString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; if (!insl) { edit_char(KEY_DEL, YES, 0); } else { edit_paste((char *)[aString UTF8String], insl, 0); } if ([aString length] == 0) { [self unmarkText]; } else { edit_setmark(replacementRange.location, insl); } NSRange selRanged = uToxRangeFromNSRange(selectedRange, aString); edit_setselectedrange(replacementRange.location + selRanged.location, selRanged.length); NSLog(@"%@", NSStringFromRange(selRanged)); } - (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange { char *buf = malloc(65536); int len = getbuf(buf, 65536, 0); if (aRange.location >= len) { free(buf); return nil; } if (aRange.location + aRange.length > len) { aRange.length = len - aRange.location; } utf8_correct(&aRange, buf, len); if (len == 0) { free(buf); return nil; } NSString *s = [[NSString alloc] initWithBytes:buf + aRange.location length:aRange.length encoding:NSUTF8StringEncoding]; NSAttributedString *a = [[NSAttributedString alloc] initWithString:s attributes:nil]; free(buf); [s release]; return [a autorelease]; } - (NSUInteger)characterIndexForPoint:(NSPoint)aPoint { NSLog(@"WARNING: unimplemented characterIndexForPoint:%@", NSStringFromPoint(aPoint)); NSLog(@"If you see this message, file a bug about \"characterIndexForPoint:\" !"); return 0; } - (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange { CGRect loc = find_ui_object_in_window(&edit_get_active()->panel); // NSLog(@"%@", NSStringFromRect(loc)); return [self.window convertRectToScreen:loc]; } @end // FIXME: asda static char clip_data[UINT16_MAX]; void setselection(char *data, uint16_t length) {} int getbuf(char *ptr, size_t len, int value) { int ret = 0; if (edit_active()) { // FIXME: asfasg ret = edit_copy(ptr, len); } else if (flist_get_type() == ITEM_FRIEND) { ret = messages_selection(&messages_friend, ptr, len, value); } else { ret = messages_selection(&messages_group, ptr, len, value); } return ret; } void copy(int value) { int len; NSString *strtocopy; len = getbuf(clip_data, sizeof(clip_data), value); strtocopy = [[NSString alloc] initWithBytes:clip_data length:len encoding:NSUTF8StringEncoding]; if (len) { [[NSPasteboard generalPasteboard] clearContents]; [[NSPasteboard generalPasteboard] writeObjects:@[ strtocopy ]]; } [strtocopy release]; } void paste(void) { NSPasteboard *pb = [NSPasteboard generalPasteboard]; NSArray *arr = [pb readObjectsForClasses:@[ NSImage.class, NSString.class ] options:nil]; id string_or_img = arr.firstObject; if ([string_or_img isKindOfClass:NSString.class]) { NSString *str = string_or_img; if (edit_active()) { edit_paste((char *)str.UTF8String, [str lengthOfBytesUsingEncoding:NSUTF8StringEncoding], 0); } else { NSBeep(); } } else /* NSImage */ { [string_or_img lockFocus]; NSBitmapImageRep *bmp = [[NSBitmapImageRep alloc] initWithFocusedViewRect:(CGRect){ CGPointZero, [string_or_img size] }]; [string_or_img unlockFocus]; CGImageRef img = CGImageRetain(bmp.CGImage); NATIVE_IMAGE *i = malloc(sizeof(NATIVE_IMAGE)); i->scale = 1.0; i->image = img; CFMutableDataRef dat = CFDataCreateMutable(kCFAllocatorDefault, 0); CGImageDestinationRef dest = CGImageDestinationCreateWithData(dat, kUTTypePNG, 1, NULL); CGImageDestinationAddImage(dest, img, NULL); CGImageDestinationFinalize(dest); CFRelease(dest); size_t size = CFDataGetLength(dat); uint8_t *owned_ptr = malloc(size); if (owned_ptr) { memcpy(owned_ptr, CFDataGetBytePtr(dat), size); friend_sendimage(flist_get_friend(), i, CGImageGetWidth(img), CGImageGetHeight(img), (UTOX_IMAGE)owned_ptr, size); } else { free(i); NSLog(@"ran out of memory, we will just do nothing and hope user doesn't notice because we're probably not " @"the only process being screwy"); } CFRelease(dat); [bmp release]; } } void showkeyboard(bool show) {} void edit_will_deactivate(void) { uToxAppDelegate *ad = (uToxAppDelegate *)[NSApplication sharedApplication].delegate; [ad.mainView.inputContext discardMarkedText]; [ad.mainView unmarkText]; } @interface NSUserNotification (uToxAdditions) - (void)set_identityImage:(id)arg1; - (void)set_identityImageHasBorder:(BOOL)arg1; @end void notify(char *title, uint16_t title_length, const char *msg, uint16_t msg_length, void *object, bool is_group) { if ([NSUserNotification class]) { NSUserNotification *usernotification = [[NSUserNotification alloc] init]; NSString *t = [[NSString alloc] initWithBytes:title length:title_length encoding:NSUTF8StringEncoding]; usernotification.title = t; NSString *msg_ = [[NSString alloc] initWithBytes:msg length:msg_length encoding:NSUTF8StringEncoding]; usernotification.informativeText = msg_; if (!is_group) { FRIEND *f = object; if (friend_has_avatar(f)) { NATIVE_IMAGE *im = f->avatar->img; size_t w = CGImageGetWidth(im->image) / im->scale, h = CGImageGetHeight(im->image) / im->scale; NSImage *i = [[NSImage alloc] initWithCGImage:im->image size:(CGSize){ w, h }]; if ([usernotification respondsToSelector:@selector(set_identityImage:)]) { [usernotification set_identityImage:i]; } else { NSLog(@"WARNING: OS X has broken the private api I use to set notification avatars. " "If you see this message please update uTox (if you're on latest, file a bug)"); } if ([usernotification respondsToSelector:@selector(set_identityImageHasBorder:)]) { [usernotification set_identityImageHasBorder:YES]; } else { NSLog(@"WARNING: OS X has broken the private api I use to set notification avatars. " "If you see this message please update uTox (if you're on latest, file a bug)"); } [i release]; } } [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:usernotification]; [t release]; [msg_ release]; [usernotification release]; } if ([NSApplication sharedApplication].isActive) { have_focus = true; } else { // Bounce icon. [[NSApplication sharedApplication] requestUserAttention:NSInformationalRequest]; [NSApplication sharedApplication].dockTile.badgeLabel = @"!"; have_focus = false; } } void update_tray(void) { uToxAppDelegate *ad = (uToxAppDelegate *)[NSApplication sharedApplication].delegate; ad.nameMenuItem.title = [[[NSString alloc] initWithBytes:self.name length:self.name_length encoding:NSUTF8StringEncoding] autorelease]; ad.statusMenuItem.title = [[[NSString alloc] initWithBytes:self.statusmsg length:self.statusmsg_length encoding:NSUTF8StringEncoding] autorelease]; } /* file utils */ void native_export_chatlog_init(uint32_t fid) { FRIEND *f = get_friend(fid); if (!f) { LOG_ERR("Cocoa", "Could not get friend with number: %u", fid); return; } NSSavePanel *picker = [NSSavePanel savePanel]; NSString *fname = [[NSString alloc] initWithBytesNoCopy:f->name length:f->name_length encoding:NSUTF8StringEncoding freeWhenDone:NO]; picker.message = [NSString stringWithFormat:NSSTRING_FROM_LOCALIZED(WHERE_TO_SAVE_FILE_PROMPT), f->name_length, f->name]; picker.nameFieldStringValue = fname; [fname release]; int ret = [picker runModal]; if (ret == NSFileHandlingPanelOKButton) { NSURL *destination = picker.URL; FILE *file = utox_get_file_simple(destination.path.UTF8String, UTOX_FILE_OPTS_WRITE | UTOX_FILE_OPTS_MKDIR); if (!file) { LOG_ERR("Cocoa", "Could not write to file: %s", destination.path.UTF8String); return; } utox_export_chatlog(f->id_str, file); } } void native_select_dir_ft(uint32_t fid, uint32_t num, FILE_TRANSFER *file) { NSSavePanel *picker = [NSSavePanel savePanel]; NSString *fname = [[NSString alloc] initWithBytesNoCopy:file->name length:file->name_length encoding:NSUTF8StringEncoding freeWhenDone:NO]; picker.message = [NSString stringWithFormat:NSSTRING_FROM_LOCALIZED(WHERE_TO_SAVE_FILE_PROMPT), file->name_length, file->name]; picker.nameFieldStringValue = fname; [fname release]; int ret = [picker runModal]; if (ret == NSFileHandlingPanelOKButton) { NSURL *destination = picker.URL; // FIXME: might be leaking postmessage_toxcore(TOX_FILE_ACCEPT, fid, num, strdup(destination.path.UTF8String)); } } void native_autoselect_dir_ft(uint32_t fid, FILE_TRANSFER *file) { NSString *downloads = [NSSearchPathForDirectoriesInDomains(NSDownloadsDirectory, NSUserDomainMask, YES) firstObject]; NSString *fname = [[NSString alloc] initWithBytesNoCopy:file->name length:file->name_length encoding:NSUTF8StringEncoding freeWhenDone:NO]; NSString *dest = [downloads stringByAppendingPathComponent:fname]; [fname release]; FILE *f = fopen(dest, "wb"); postmessage_toxcore(TOX_FILE_ACCEPT_AUTO, fid, file->file_number, f); } //@"Where do you want to save \"%.*s\"?" void file_save_inline_image_png(MSG_HEADER *msg) { NSSavePanel *picker = [NSSavePanel savePanel]; NSString *fname = [[NSString alloc] initWithBytes:msg->via.ft.name length:msg->via.ft.name_length encoding:NSUTF8StringEncoding]; picker.message = [NSString stringWithFormat:NSSTRING_FROM_LOCALIZED(WHERE_TO_SAVE_FILE_PROMPT), msg->via.ft.name_length, msg->via.ft.name]; picker.nameFieldStringValue = fname; [fname release]; int ret = [picker runModal]; if (ret == NSFileHandlingPanelOKButton) { NSURL *destination = picker.URL; NSData *d = [NSData dataWithBytesNoCopy:msg->via.ft.data length:msg->via.ft.data_size freeWhenDone:NO]; [d writeToURL:destination atomically:YES]; snprintf((char *)msg->via.ft.path, UTOX_FILE_NAME_LENGTH, "inline.png"); // TODO : this seems wrong msg->via.ft.inline_png = false; } } bool native_save_image_png(const char *name, const uint8_t *image, const int image_size) { NSSavePanel *picker = [NSSavePanel savePanel]; NSString *fname = [[NSString alloc] initWithBytes:name length:strlen(name) encoding:NSUTF8StringEncoding]; picker.message = [NSString stringWithFormat:NSSTRING_FROM_LOCALIZED(WHERE_TO_SAVE_FILE_PROMPT), strlen(name), name]; picker.nameFieldStringValue = fname; picker.allowedFileTypes = @[ @"png" ]; [fname release]; int ret = [picker runModal]; if (ret == NSFileHandlingPanelOKButton) { NSURL *destination = picker.URL; NSData *d = [NSData dataWithBytesNoCopy:image length:image_size freeWhenDone:NO]; [d writeToURL:destination atomically:YES]; return true; } return false; } //@"Select one or more files to send." void openfilesend(void) { NSOpenPanel *picker = [NSOpenPanel openPanel]; picker.title = NSSTRING_FROM_LOCALIZED(SEND_FILE); picker.message = NSSTRING_FROM_LOCALIZED(SEND_FILE_PROMPT); picker.allowsMultipleSelection = YES; int ret = [picker runModal]; if (ret == NSFileHandlingPanelOKButton) { NSArray *urls = picker.URLs; FRIEND *f = flist_get_friend(); if (!f) { LOG_ERR("Cocoa", "Could not get friend."); return; } for (NSURL *url in urls) { UTOX_MSG_FT *msg = calloc(1, sizeof(UTOX_MSG_FT)); if (!msg) { LOG_ERR("Cocoa", "Failed to malloc for file sending."); return; } msg->file = fopen(url.path.UTF8String, "r"); msg->name = (uint8_t*)strdup(url.path.UTF8String); postmessage_toxcore(TOX_FILE_SEND_NEW, f->number, 0, msg); LOG_INFO("Cocoa", "File %s sent!", url.path.UTF8String); } } } void show_messagebox(const char *caption, uint16_t caption_length, const char *message, uint16_t message_length) { NSString *message_native = [[NSString alloc] initWithBytes:message length:message_length encoding:NSUTF8StringEncoding]; NSString *caption_native = [[NSString alloc] initWithBytes:caption length:caption_length encoding:NSUTF8StringEncoding]; NSString *emsg = [[NSString alloc] initWithFormat:@"%@%@", caption_native, message_native]; [caption_native release]; [message_native release]; NSAlert *alert = [[NSAlert alloc] init]; alert.alertStyle = NSWarningAlertStyle; alert.messageText = emsg; [emsg release]; [alert runModal]; [alert release]; } void openfileavatar(void) { NSOpenPanel *picker = [NSOpenPanel openPanel]; picker.title = [[[NSString alloc] initWithBytes:S(SELECT_AVATAR_TITLE) length:SLEN(SELECT_AVATAR_TITLE) encoding:NSUTF8StringEncoding] autorelease]; picker.allowedFileTypes = @[ @"png" ]; int ret = [picker runModal]; if (ret == NSFileHandlingPanelOKButton) { int width, height, bpp, size; uint8_t *file_data = stbi_load((char *)picker.URL.path.UTF8String, &width, &height, &bpp, 0); uint8_t *img = stbi_write_png_to_mem(file_data, 0, width, height, bpp, &size); free(file_data); if (!img) { show_messagebox(S(CANT_FIND_FILE_OR_EMPTY), SLEN(CANT_FIND_FILE_OR_EMPTY), (char *)picker.URL.path.UTF8String, sizeof((char *)picker.URL.path.UTF8String)); return; } if (size > UTOX_AVATAR_MAX_DATA_LENGTH) { free(img); char size_str[16]; int len = sprint_humanread_bytes(size_str, sizeof(size_str), UTOX_AVATAR_MAX_DATA_LENGTH); show_messagebox(S(AVATAR_TOO_LARGE_MAX_SIZE_IS), SLEN(AVATAR_TOO_LARGE_MAX_SIZE_IS), size_str, len); } else { postmessage_utox(SELF_AVATAR_SET, size, 0, img); } } } uTox-0.17.1/src/cocoa/main.h000066400000000000000000000011211354126257400155130ustar00rootroot00000000000000#if defined(MAIN_H) && !defined(COCOA_MAIN_H) #error "We should never include main from different platforms." #endif #ifndef COCOA_MAIN_H #define COCOA_MAIN_H #define MAIN_H /* Don't put Objective-C declarations here so we don't have to compile * all of uTox as ObjC. Stuff that requires ObjC available goes in objc_main.h, * included below. */ #include #include #include #include typedef struct native_image NATIVE_IMAGE; int NATIVE_IMAGE_IS_VALID(NATIVE_IMAGE *img); #ifdef __OBJC__ #include "objc_main.h" #endif #endif uTox-0.17.1/src/cocoa/main.m000066400000000000000000000427421354126257400155360ustar00rootroot00000000000000#include "main.h" #include "../commands.h" #include "../debug.h" #include "../filesys.h" #include "../flist.h" #include "../main.h" #include "../settings.h" #include "../theme.h" #include "../tox.h" #include "../ui.h" #include "../utox.h" #include "../av/utox_av.h" #include "../av/video.h" #include "../native/notify.h" #include "../ui/dropdown.h" #include "../layout/settings.h" #import #import #include #include #include #include #include #include struct thread_call { void *(*func)(void *); void *argp; }; #define DEFAULT_WIDTH (382 * DEFAULT_SCALE) #define DEFAULT_HEIGHT (320 * DEFAULT_SCALE) int NATIVE_IMAGE_IS_VALID(NATIVE_IMAGE *img) { return img != NULL && img->image != nil; } NATIVE_IMAGE *utox_image_to_native(const UTOX_IMAGE data, size_t size, uint16_t *w, uint16_t *h, bool keep_alpha) { CFDataRef idata_copy = CFDataCreate(kCFAllocatorDefault, data, size); CGDataProviderRef src = CGDataProviderCreateWithCFData(idata_copy); CGImageRef underlying_img = CGImageCreateWithPNGDataProvider(src, NULL, YES, kCGRenderingIntentDefault); CGDataProviderRelease(src); CFRelease(idata_copy); if (underlying_img) { *w = CGImageGetWidth(underlying_img); *h = CGImageGetHeight(underlying_img); NATIVE_IMAGE *ret = malloc(sizeof(NATIVE_IMAGE)); ret->scale = 1.0; ret->image = underlying_img; return ret; } else { return NULL; } } void image_set_filter(NATIVE_IMAGE *image, uint8_t filter) {} void image_set_scale(NATIVE_IMAGE *image, double scale) { image->scale = scale; } void image_free(NATIVE_IMAGE *img) { if (!img) { return; } CGImageRelease(img->image); free(img); } void *thread_trampoline(void *call) { struct thread_call args = *(struct thread_call *)call; free(call); @autoreleasepool { return args.func(args.argp); } } void thread(void func(void *), void *args) { pthread_t thread_temp; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, 1 << 20); struct thread_call *call = malloc(sizeof(struct thread_call)); if (!call) { fputs("thread(): no memory so gonna peace", stderr); abort(); } call->func = func; call->argp = args; pthread_create(&thread_temp, &attr, thread_trampoline, call); pthread_attr_destroy(&attr); } void yieldcpu(uint32_t ms) { usleep(1000 * ms); } /* *** audio/video *** */ void audio_detect(void) {} bool audio_init(void *handle) { return 0; } bool audio_close(void *handle) { return 0; } bool audio_frame(int16_t *buffer) { return 0; } /* *** os *** */ #include #include uint64_t get_time(void) { struct timespec ts; clock_serv_t muhclock; mach_timespec_t machtime; host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &muhclock); clock_get_time(muhclock, &machtime); mach_port_deallocate(mach_task_self(), muhclock); ts.tv_sec = machtime.tv_sec; ts.tv_nsec = machtime.tv_nsec; return ((uint64_t)ts.tv_sec * (1000 * 1000 * 1000)) + (uint64_t)ts.tv_nsec; } void config_osdefaults(UTOX_SAVE *r) { r->window_x = 0; r->window_y = 0; r->window_width = DEFAULT_WIDTH; r->window_height = DEFAULT_HEIGHT; } bool native_remove_file(const uint8_t *name, size_t length, bool portable_mode) { uint8_t path[UTOX_FILE_NAME_LENGTH] = { 0 }; if (portable_mode) { const char *curr = [NSBundle.mainBundle.bundlePath stringByDeletingLastPathComponent].UTF8String; snprintf((char *)path, UTOX_FILE_NAME_LENGTH, "%s/tox/", curr); } else { const char *home = NSHomeDirectory().UTF8String; snprintf((char *)path, UTOX_FILE_NAME_LENGTH, "%s/.config/tox/", home); } if (strlen((const char *)path) + length >= UTOX_FILE_NAME_LENGTH) { LOG_TRACE("NATIVE", "File/directory name too long, unable to remove" ); return 0; } else { snprintf((char *)path + strlen((const char *)path), UTOX_FILE_NAME_LENGTH - strlen((const char *)path), "%.*s", (int)length, (char *)name); } if (remove((const char *)path)) { LOG_ERR("NATIVE", "Unable to delete file!\n\t\t%s" , path); return 0; } else { LOG_INFO("NATIVE", "File deleted!" ); LOG_TRACE("NATIVE", "\t%s" , path); } return 1; } int ch_mod(uint8_t *file) { return chmod((char *)file, S_IRUSR | S_IWUSR); } int file_lock(FILE *file, uint64_t start, size_t length) { int result = -1; struct flock fl; fl.l_type = F_WRLCK; fl.l_whence = SEEK_SET; fl.l_start = start; fl.l_len = length; result = fcntl(fileno(file), F_SETLK, &fl); if (result != -1) { return 1; } else { return 0; } } int file_unlock(FILE *file, uint64_t start, size_t length) { int result = -1; struct flock fl; fl.l_type = F_UNLCK; fl.l_whence = SEEK_SET; fl.l_start = start; fl.l_len = length; result = fcntl(fileno(file), F_SETLK, &fl); if (result != -1) { return 1; } else { return 0; } } void flush_file(FILE *file) { fflush(file); int fd = fileno(file); fsync(fd); } int resize_file(FILE *file, uint64_t size) { // https://github.com/trbs/fallocate/blob/master/fallocate/_fallocatemodule.c int fd = fileno(file); fstore_t stuff = { F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, size, 0 }; int err = fcntl(fd, F_PREALLOCATE, &stuff); if (err == -1) { stuff.fst_flags = F_ALLOCATEALL; err = fcntl(fd, F_PREALLOCATE, &stuff); } if (err != -1) { err = ftruncate(fd, size); } return err; } void postmessage_utox(UTOX_MSG msg, uint16_t param1, uint16_t param2, void *data) { /* If you notice any data races, or interesting bugs that appear in OSX but not xlib, * replace async( with sync( */ dispatch_async(dispatch_get_main_queue(), ^{ utox_message_dispatch(msg, param1, param2, data); }); } void init_ptt(void) { settings.push_to_talk = 1; } static bool is_ctrl_down = 0; bool check_ptt_key(void) { return settings.push_to_talk ? is_ctrl_down : 1; } void exit_ptt(void) { settings.push_to_talk = 0; } void redraw(void) { uToxAppDelegate *ad = (uToxAppDelegate *)[NSApp delegate]; [ad soilWindowContents]; } void openurl(char *str) { if (try_open_tox_uri(str)) { redraw(); return; } NSString *urls = [[NSString alloc] initWithCString:(char *)str encoding:NSUTF8StringEncoding]; NSURL *url = NULL; if (!strncasecmp((const char *)str, "http://", 7) || !strncasecmp((const char *)str, "https://", 8)) { url = [NSURL URLWithString:urls]; } else /* it's a path */ { url = [NSURL fileURLWithPath:urls]; } [[NSWorkspace sharedWorkspace] openURL:url]; [urls release]; } void launch_at_startup(bool should) { LSSharedFileListRef items = LSSharedFileListCreate(kCFAllocatorDefault, kLSSharedFileListSessionLoginItems, NULL); if (should) { CFRelease(LSSharedFileListInsertItemURL(items, kLSSharedFileListItemLast, NULL, NULL, (__bridge CFURLRef)[NSBundle mainBundle].bundleURL, NULL, NULL)); } else { CFArrayRef current_items = LSSharedFileListCopySnapshot(items, NULL); for (int i = 0; i < CFArrayGetCount(current_items); ++i) { LSSharedFileListItemRef it = (void *)CFArrayGetValueAtIndex(current_items, i); CFURLRef urlornull; #if MAC_OS_X_VERSION_MIN_REQUIRED < 101000 LSSharedFileListItemResolve(it, 0, &urlornull, NULL); #else urlornull = LSSharedFileListItemCopyResolvedURL(it, 0, NULL); #endif if (urlornull) { if (CFEqual(urlornull, (__bridge CFURLRef)[NSBundle mainBundle].bundleURL)) { // this is ours, remove it. LSSharedFileListItemRemove(items, it); CFRelease(urlornull); break; } CFRelease(urlornull); } } CFRelease(current_items); // we're not in the login items list. } CFRelease(items); } @implementation uToxAppDelegate { id global_event_listener; id local_event_listener; } - (void)applicationWillFinishLaunching:(NSNotification *)notification { [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleAppleEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL]; } - (void)applicationDidFinishLaunching:(NSNotification *)notification { setup_cursors(); NSImageView *dock_icon = [[NSImageView alloc] initWithFrame:CGRectZero]; dock_icon.image = [NSApplication sharedApplication].applicationIconImage; [NSApplication sharedApplication].dockTile.contentView = dock_icon; [dock_icon release]; global_event_listener = [NSEvent addGlobalMonitorForEventsMatchingMask:NSFlagsChangedMask handler:^(NSEvent *e) { is_ctrl_down = e.modifierFlags & NSFunctionKeyMask; }]; local_event_listener = [NSEvent addLocalMonitorForEventsMatchingMask:NSFlagsChangedMask handler:^NSEvent *(NSEvent *e) { is_ctrl_down = e.modifierFlags & NSFunctionKeyMask; return e; }]; ironclad = [[NSMutableDictionary alloc] init]; // hold COMMAND to start utox in portable mode // unfortunately, OS X doesn't have the luxury of passing argv in the GUI if ([NSEvent modifierFlags] & NSCommandKeyMask) { settings.portable_mode = 1; } /* load save data */ theme_load(settings.theme); char title_name[128]; snprintf(title_name, 128, "%s %s (version: %s)", TITLE, SUB_TITLE, VERSION); #define WINDOW_MASK (NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask) self.utox_window = [[NSWindow alloc] initWithContentRect:(NSRect) { settings.window_x, settings.window_y, settings.window_width, settings.window_height } styleMask:WINDOW_MASK backing:NSBackingStoreBuffered defer:NO screen:[NSScreen mainScreen]]; self.utox_window.releasedWhenClosed = NO; #undef WINDOW_MASK self.utox_window.delegate = self; self.utox_window.title = @(title_name); settings.window_width = self.utox_window.frame.size.width; settings.window_height = self.utox_window.frame.size.height; self.utox_window.contentView = [[[uToxView alloc] initWithFrame:(CGRect){ 0, 0, self.utox_window.frame.size }] autorelease]; ui_size(settings.window_width, settings.window_height); ui_rescale(ui_scale); /* start the tox thread */ thread(toxcore_thread, NULL); self.nameMenuItem = [[[NSMenuItem alloc] initWithTitle:@"j" action:NULL keyEquivalent:@""] autorelease]; self.statusMenuItem = [[[NSMenuItem alloc] initWithTitle:@"j" action:NULL keyEquivalent:@""] autorelease]; update_tray(); //[self.nameMenuItem release]; //[self.statusMenuItem release]; max_video_width = [NSScreen mainScreen].frame.size.width; max_video_height = [NSScreen mainScreen].frame.size.height; [self.utox_window makeFirstResponder:self.utox_window.contentView]; [self.utox_window makeKeyAndOrderFront:self]; } - (NSMenu *)applicationDockMenu:(NSApplication *)sender { if (!self.dockMenu) { self.dockMenu = [[[NSMenu alloc] init] autorelease]; [self.dockMenu addItem:self.nameMenuItem]; [self.dockMenu addItem:self.statusMenuItem]; } return self.dockMenu; } - (void)applicationDidBecomeActive:(NSNotification *)notification { if ([NSUserNotification class]) { // don't clutter up NC with stale messages [[NSUserNotificationCenter defaultUserNotificationCenter] removeAllDeliveredNotifications]; } // clear badge [NSApplication sharedApplication].dockTile.badgeLabel = nil; } - (void)applicationWillTerminate:(NSNotification *)notification { postmessage_utoxav(UTOXAV_KILL, 0, 0, NULL); postmessage_toxcore(TOX_KILL, 0, 0, NULL); UTOX_SAVE d = { // from bottom of screen // TODO: translate to xy from top .window_x = self.utox_window.frame.origin.x, .window_y = self.utox_window.frame.origin.y, .window_width = self.utox_window.frame.size.width, .window_height = self.utox_window.frame.size.height, }; config_save(&d); [NSEvent removeMonitor:global_event_listener]; [NSEvent removeMonitor:local_event_listener]; /* wait for threads to exit */ while (tox_thread_init) { yieldcpu(1); } } - (void)soilWindowContents { uToxView *cv = self.utox_window.contentView; [cv setNeedsDisplay:YES]; } - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender { if (settings.close_to_tray) { return NO; } else { return YES; } } - (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag { [self.utox_window makeKeyAndOrderFront:self]; return NO; } - (void)windowDidChangeScreen:(NSNotification *)notification { if (notification.object == self.utox_window) { NSScreen *screen = self.utox_window.screen; max_video_width = screen.frame.size.width; max_video_height = screen.frame.size.height; } } - (void)handleAppleEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent { NSString *theURL = [event paramDescriptorForKeyword:keyDirectObject].stringValue; uint8_t * cs_url = (const uint8_t *)theURL.UTF8String; do_tox_url(cs_url, strlen(cs_url)); [self soilWindowContents]; } - (uToxView *)mainView { return self.utox_window.contentView; } - (void)dealloc { [ironclad release]; [devices release]; [super dealloc]; } @end int main(int argc, char const *argv[]) { int8_t should_launch_at_startup; int8_t set_show_window; bool skip_updater; bool allow_root; utox_init(); settings.window_width = DEFAULT_WIDTH; settings.window_height = DEFAULT_HEIGHT; parse_args(argc, argv, &skip_updater, &should_launch_at_startup, &set_show_window, &allow_root); if (getuid() == 0 && !allow_root) { LOG_FATAL_ERR(EXIT_FAILURE, "NATIVE", "You can't run uTox as root unless --allow-root is set."); } if (should_launch_at_startup == 1 || should_launch_at_startup == -1) { LOG_TRACE("NATIVE", "Start on boot not supported on this OS!" ); } if (set_show_window == 1 || set_show_window == -1) { LOG_TRACE("NATIVE", "Showing/hiding windows not supported on this OS!" ); } if (skip_updater == true) { LOG_TRACE("NATIVE", "Disabling the updater is not supported on this OS. Updates are managed by the app store." ); } setlocale(LC_ALL, ""); /* set the width/height of the drawing region */ ui_size(settings.window_width, settings.window_height); /* event loop */ @autoreleasepool { NSApplication *app = [NSApplication sharedApplication]; NSArray *maybeMenus = nil; BOOL ok; if ([[NSBundle mainBundle] respondsToSelector:@selector(loadNibNamed:owner:topLevelObjects:)]) { ok = [[NSBundle mainBundle] loadNibNamed:@"MainMenu" owner:nil topLevelObjects:&maybeMenus]; } else { NSLog(@"warning: loading nib the deprecated way"); NSMutableArray *tlo = [[NSMutableArray alloc] init]; maybeMenus = tlo; NSDictionary *params = @{ NSNibTopLevelObjects : tlo }; ok = [NSBundle loadNibFile:[[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"] externalNameTable:params withZone:nil]; } if (ok) { for (id obj in maybeMenus) { if ([obj isKindOfClass:[NSMenu class]]) { app.mainMenu = obj; break; } } } [maybeMenus release]; uToxAppDelegate *appdelegate; app.delegate = appdelegate = [[uToxAppDelegate alloc] init]; [app run]; [appdelegate release]; // never executed } return 1; } uTox-0.17.1/src/cocoa/objc_main.h000066400000000000000000000074551354126257400165300ustar00rootroot00000000000000#ifndef uTox_objc_main_h #define uTox_objc_main_h #import #import #import #ifndef NS_DESIGNATED_INITIALIZER #if __has_attribute(objc_designated_initializer) #define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) #else #define NS_DESIGNATED_INITIALIZER #endif #endif @class uToxStardustView; extern CGDirectDisplayID desktop_capture_from; extern CGRect desktop_capture_rect; extern CGFloat desktop_capture_scale; typedef struct { NSWindow * window; uToxStardustView *view; void (*finished_callback)(bool, uint64_t, NSWindow *); } stardust_context_t; extern stardust_context_t stardust_context; void setup_cursors(void); #define RELEASE_CHK(func, obj) \ if ((obj)) \ func((obj)); //#define HAS_CUSTOM_EDIT_DRAW_IMPLEMENTATION #if MAC_OS_X_VERSION_MAX_ALLOWED < 101000 typedef struct { NSInteger majorVersion; NSInteger minorVersion; NSInteger patchVersion; } NSOperatingSystemVersion; #endif #define MAC_OS_AT_LEAST_DO(a, b, c) \ if ([[NSProcessInfo processInfo] respondsToSelector:@selector(isOperatingSystemAtLeastVersion:)] && \ [[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){ a, b, c }]) #define AT_LEAST_YOSEMITE_DO MAC_OS_AT_LEAST_DO(10, 10, 0) #define AT_LEAST_ELCAPITAN_DO MAC_OS_AT_LEAST_DO(10, 11, 0) #define AT_LEAST_SIERRA_DO MAC_OS_AT_LEAST_DO(10, 12, 0) // gotta use the old version checker here #define AT_LEAST_MAVERICKS_DO if (NSFoundationVersionNumber >= NSFoundationVersionNumber10_9) #define AT_LEAST_MOUNTAIN_LION_DO if (NSFoundationVersionNumber >= NSFoundationVersionNumber10_8) #define NSSTRING_FROM_LOCALIZED(msgid) \ [[[NSString alloc] initWithBytes:S(msgid) length:SLEN(msgid) encoding:NSUTF8StringEncoding] autorelease] struct native_image { CGImageRef image; double scale; }; @class uToxView; @interface uToxAppDelegate : NSResponder { uint16_t device_count; NSMutableDictionary *devices; NSMutableDictionary *ironclad; } @property(retain) NSWindow * utox_window; @property(retain) NSMenuItem *nameMenuItem; @property(retain) NSMenuItem *statusMenuItem; @property(retain) NSMenu * dockMenu; - (uToxView *)mainView; - (void)soilWindowContents; @end /* Webcam management */ @interface uToxAppDelegate (VideoDevices) - (void *)storeVideoDevicesList; - (AVCaptureDevice *)getCaptureDeviceFromHandle:(void *)handle; @end /* Video call satellite windows */ @interface uToxAppDelegate (IroncladManager) - (void)setIroncladWindow:(NSWindow *)w forID:(uint32_t)id; - (void)releaseIroncladWindowForID:(uint32_t)id; - (NSWindow *)ironcladWindowForID:(uint32_t)id; @end @interface uToxIroncladVideoContent : NSView - (void)displayImage:(uint8_t *)rgba w:(uint16_t)width h:(uint16_t)height; - (void)checkSize; @end /* Main UI */ @interface uToxView : NSView @property(retain) uToxIroncladVideoContent *inlineVideo; @property BOOL didDrawInlineVideoThisFrame; @end @interface uToxView (UserInteraction) @end /* Desktop rectangle selector */ @interface uToxStardustView : NSView + (NSWindow *)createWindowOnScreen:(NSScreen *)target; @property(strong) NSTextField *instruction; @property(getter=isVideo) BOOL video; - (CGRect)getRect; @end /* Video capture */ @interface uToxAV : NSObject - (instancetype)initWithHandle:(void *)video_dev_handle NS_DESIGNATED_INITIALIZER; @end @interface uToxIroncladView : NSView @property CGSize videoSize; + (NSWindow *)createWindow; - (void)displayImage:(uint8_t *)rgba w:(uint16_t)width h:(uint16_t)height; @end #endif uTox-0.17.1/src/cocoa/utox.iconset/000077500000000000000000000000001354126257400170655ustar00rootroot00000000000000uTox-0.17.1/src/cocoa/utox.iconset/icon_128x128.png000066400000000000000000000166341354126257400215520ustar00rootroot00000000000000PNG  IHDR>a pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATx]{pTU}{NyᝰRX:3"[(/jyFK˭vjXbKD|VJ|]-WADIȻ}9g !݁sSN=w;/RJ+UKW\a)ZP___-/Yi<$ B9BP'htVWf:t( 02e>+hca/|)R  JcidNPCw)&^?֢krXjW49m%-D(&Sw`1K P0bhe0H/K`+vL^=jljoO9"uoRt*&SBo-PTLH>>PAZw*9T߾:t[^'RXEfP*0oЛ#qYS@8}3a<+~Z~em`?'KqLѸǵW:b8EEO@Q3dZ[CJ_.o%@vM/A!$TZs,dbaBS!TAkW4%@67`XDƩx CP=&S!0dˏԗNloX@U<[&?P\r:?C5xWʽ$)--G0D @ iW5GA1 slњH?AWn^l~Ȓs… QWW3fҨO);wGo>:uBG0m]qUS'\X@튦;yg-;L4 V’%K<9vكFB+]QaH2e~$@]NRv>6F͛tR0wƋ/h4fY!>eNkOYx2sQ@]t@XD>6l;#e˖e |(++æMw^̟??EsP:{Mroa𠙖?rH ؼy3VcΝxG9O1A0,K=#ζ<`5kqu D5kgM/D `=&ζ֮hrV+*8L 9sK/j`ܹ3-uB"%@_GAcMakjjc Y͛z D:GcQ..1|L|>l߾~ȫ}M7Km, m8= I.Gi1TeL:5gb̙q(Nk.%@B+AӞ"pw'i{,u&!ȆQ,WH8VQL҈2gX`AE(&r `ʲ p `L-\* |f:VO,P_B Eʸo֟s碦&e^ (/âDH%-BҥKӲλZ@ aڴi9O~PDZFYL)SR'\r@RYMkDgu0LW#1 @*PL 3 #dѣG#_{!v_|SGU',#<oGl@WWא;۶mW5FGu>3ҽ(/9 Qa ${9wqdLlj_y 4I8x  D"}ݻܶvN?1߂zk@# #Ay9s &.;s p\xensi`a BR(c[fҸR` q<}W}GA:HX@0'v_rs,`uK\m xĸ_] ~F[1ho2PWk<H*ځMq7AU/~iGkwD_[H(bO2XARB'(#t4?Z\5]'ⵓ7q%]H/(ѹj2j*0|e0t[OGcc9&C#tl6`%>هS;n@tzu;b ݋ǡmcfNvD w]~_gyFyqBzw oBPS!K2ڄ Eca "k[gkEuC׎*Y{FlZ)"WXȖGfQc`HPHDљeYVxn  X22 k}r#^|te-ODYy2%!TmM+ !$^9WÕ>LsWwٴ-Rݐr8,$ò@`@>(Kyl%/~\hzZ@-{t,xgcQn-s~%vR:l.`k1(JucmǛ?NYܥ03(+P8bl?󍫚M%FBCQGȲ[I*@(r~JeRٚ% B|39]X4{4.RR]3n430\+_ČtH0ʹP,(T*xD+6|kS9ý biI׈?L6! ,`O6qj~h lNPvbeI)#D8u:cmhGyt;@ `NuHP^\99DIq(+.K4%ܫ{5#aIc:q4 #T)-a񐈚QP,h"=p+`#="t8AQoe. 9 ;$9:׾^H|.wa:7t`8L:833r 91h=LRJ(K JV\ iAȸ)2fF)f(;6w}W1{ 䔀|t^JO @r.@Oq @%;Hԇ-_?{_'`:%hR;߉s2IlD E$$ˀ.< zok՗ }ޛ2)ea%r3Z$ol_<2ZxoS r2}4& +,'XNw~%"AWWEW0ʬU$I8r9IENDB`uTox-0.17.1/src/cocoa/utox.iconset/icon_16x16.png000066400000000000000000000061661354126257400214010ustar00rootroot00000000000000PNG  IHDRa pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxڔkq?]3gQ8BRNvdBNA g"8ܺ%A׈pd ] 9PP/w y]r)M?S"@X$; R_E|d9yRd:Ϋ ^KKV Q(Vu'N0T*`0%"x MܯmSϒ @󼥽u\۽ tD 4 Xe\%"ͦjXD?{`_PVz2U"wCo0ty:; 6Xgkǧ6&q ?mUIF!L!FM:Lr7]{6o qr1%]lzy/p s02<IENDB`uTox-0.17.1/src/cocoa/utox.iconset/icon_256x256.png000066400000000000000000000317351354126257400215550ustar00rootroot00000000000000PNG  IHDR\rf pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_F)IDATxy|Օު^ ,96K0L `xބO@I2`&`ʊ"~(uRFhOFS5Fhn< ldóeTƛv#F$rSo2ZFxWF fUR0mw%`Z &fj2 @)+TT vVhw})nG  H7K!; l7׵ egv%`Y30,v%=MFųiYKơ1lg=KYF7DdflF!l*qwww}l]F8f-*į ΰ$N)i#~2LUeַ"(BojVО$ B1")^  (4|7wpUW+ɓ'~ D)Kx~E16XO%#-O^@#k,LS)?+kkkԄXfMQ8?p} ?O\p8vS )*$:3T8ds_(իuV^phh"<xx|Ih-KY}Ti\r oG-q_|9z)455d`P,[ O>$n&D"‹aa z**B+ 7 mmfB$aÆ xP sZ O=>‹8C|cMrI5Rܛ.]_WKtxqׂs^g#ܛ2?KGDQ-UxGq'W#k֬>I&x͛WrfܹKm薂@l^ ${VW_ ƨJhkg @Kda]dtھM6 ԧȸ`̙?X@Z贡MvYYM`E\\+w#D\Blz0 @IVK,ܹs}M^ ,L/O7?|̜9[d"S< 1. +[&_bAq`%`VS -L8su'kh~VS QH$38'/_8@FeSH*n(,z 0_y晾^,Jk}IV@$.) fm2c _FcOIhfP qMχ>!^LjЫ`$LbQNsĘ|,Qn'ӧO/PV UE:ʥp\8m4Xզ}S"?LӤ_{9C= @>V w6@P0TgsBF䭅xT>T}^ LesBqym"``YykH&l  HD"{ ) m!|&U)#Ii#G!|d> #$޽{>Uǎ#C.GCF (>oHJ;w?o] #`dx뭷$+BFҴ* @J)2y$ѣG) _|@P;a qdd֭hmm%C6W.mb<3dfӦM&CC^#C6ظq#bl޼fQHʃG@2Ė-[$A*wA&[lAGG|o{ qlc=F (?nV!駟t<9vnH)N APl۶ w}7b}QI*o޼ C[[MT~;y2wMETH*۶q??+*~ij$'k׮~A:=hMtT e[6mTǁ!T.RJlذׯo~Q  'E:tk<ǺuhM Ν;rJl޼WБ#կ~w.3gM@ Ŷmpe?Avڅ[o. 1.{oIqu!NӃ% F˿ VX+ZoINOK/ŗelٲ]]]EE/x*V 2Jt_믿n gu>c3gccy_x,$@%+WbS5G;`viOI)ꫯQ[[Ea?>Q__I& :Lؿ?݋۸ q5׌v؁o4!*OJ,M1^8rk^`38Q-عZZ,$vLZ@ ZAb1nB˲5LÝwމ;rVZU{`pLgG 0w2Fߊ sN66DJBt; w"pgϞ=km&5ȘdTd+|/%'DގE @bQ$&_<`f<3 R 0wtMرcGqr h*ȡB**js2*>K,~A$K&]1Qm`tٮgG… a=܃[ΛԮ0G'% fNYmO |K&ݿ"(BT? :+sҥKGO<~~Ӟ GB$%Fh G:-Xy$ .`ؿ6l(/h1 `5n!u Sb…^xK+]!|'n"/2:ضMF# ʅK.䄿/k%' ʉٳgc'oVT3"ˇ͛D=CD"C < E@#]vY^\m݆_d$1M_W~WW֮]۷HrK.){wƵ^} $zW_{=VZEOQ|G}}=Ƚދ7ҹ}$Dֆ&kdJJꫯFmm-^y\~Œ3/|wu~QO@T\p/a׮]d x'ק1R!'   H    H(}h%` j7ŵ#4ՁkrXq4B$Di9=gP+qy97ƑȜC“qs0n؊(C>eRk}ymYk38? p 鞺4X6H-žTc!q phz 8CbwdY?&8<{*0 1or $NƟ\ 8RgyCԌHqH Ue%P{*(pGKiBE 69@ Q'П31^rjpoCp;A rUe ~t/>a8w*H h@3p`Pm7wsg!4 @ELkw^j$ϬCI~[SX>:43@@ TC;΀OR4Sl8KZ X2?Ӌ֒NxFٍC̽g"b?;ؖ:*Z< H-  ;@fZȚT.E)ϻۣ2a)۴g,x A@" 6Xt TH#-JT`=6 yJy#,]|œN [nwJIP@8;f~.+V۪LB(  ;Ew== s4 # |;ΡsT`R!1; ,4 @)J%v7Y 7;ot8O8Z> L ;A}UpS,QvS !3~[Xmmv+>JC86x܆ўGwO}mDj I߾#=a|?ҲwE$DDO/ bwݛ3KgI:R,-]ݘ~ǎu< L^9Q2:Rt  տ3a^sڸWݣmELJS@LD*m {Ozϻ텕v{s8hEĄWS<YYψ 'ݾU (7G ( &6i p /Ŭ/I[ 0տ>Kp<8i.Q)?"H𔃓Lh<|l{&?.ٕɇ|(! `H=5 qΔ 6;G}$Duk;Ih9fEG tl@؁)?}'HS"8H~?ZT?^vL]SkHJ,尟P@_ ΟKrdx.:/o DY2"bB~M5pi?3~ >ԂXGW   2KHN"hv֌+*R =C y?Kf~5\XVALlՁ$pO: 5ΟŚ\ 95PA*$  o^>%7B'-Z-z*p    p{~GwsvKкfݭ$ Fsʄ35;v8X5 qoٱf! 1@{lX̒X{Fgތ 1IX5$[N ˳U} bݿ_TXPYyY%c$$^c KK+z pt|aVA'vsT@EzΙ gZG_CUL8a9sL".DySӌh0 1?vk쳌D%~D˸+XJž,8gj4S @@ 6tt:MihM 1pP1DjAMɿԢ^`Th؝&cRsH |O4L@ ` fS,d͊l z$DN";o ڀ{d{i(  ¯`nM¢ߗ,o=#/̓LP$.%V+:N"xW+hp m8͍U'MN qOA)ixtwۥHw&@3$Dh9 .agJ}DEig ![Ue$ouۊ~ * A-sNhwG 5qRn  &G8"Kގntck7!  UsyVN) $#9·}Cxq؛@}%5# Yoo{˯/I@=[h6DӁ6Wyíl1=TwmH.CgOAbd83A#)DׇyGsmJ6!(   *V}]ZcJP[!< ƣ6$As܋%Iq] &(\؅9vI&zUj)Qbq|G8G%5.`~ˤvI!ʢrӁRwxڠǞ4E @6uㇼ ƃ}^[U$DvFrZ6.<)3}g :`noPڀSkB(h?ٜJ-k]s4_`ˈN^:/5UD@$%D'jZ tvΠ uA\ Ȉ'e:ع/;L+@7 )i6iA.z) @v/we`' U2WM3ꢓp=xJс퉁c(0 i_p-mphsx=]9TCV`)KtGz&ʹ{]9] IO28 ]px*kyFO{QɿT5dZmp'O1jU|j0+ Ȟޫ+b!<' :]GPaNG)՝I:=V{3s=}kWJzW"9n:;@)#l`E@u}˃q IhpJUQBU"h #fɦlj}~ &4H4rfk1{sx'φJV +%㙤ӝqRL[OݝJx{9y@9An;Y1_+8vPf?<'`j6:ɈD43fdalXE R)ԽiS^{((>gꩾÑ=BqYu_,5Lgt?iΟb}?^͐G#:_y=4pZkGpm%-mHKemik[eΨv'-K?t:~~rL~LŀR $c(@-`@Z#q?A3,BApƹMf . qA0 aB078"3 Hkvr'J+HJKH6432hmhveCi%3vFʖ)+-SVIXIe97إ|$?\rzLeIH` f:hzЈ`$"/$lq` NAh`O_ܡ7K Grqv+<7XP*Y ? O{|cz}>BgJ > l ?c'?$4C@#>C9;W)@SF^0~$=<ÏrшP0APc8|.%B(!gy"[%E#'rцu:}!D`hSEVC8F , C_AcupB(vAn0X0! @rE [DhфORF#'ю)h\A/Ku7` o0j;9H~=NFB ps$P1 /5x4a4aXB~:xDD *,`r8H,3R4yY:z% Xz8p7Ӳ"_1\U,3',DO͊n,ȑ}lˀ LIENDB`uTox-0.17.1/src/cocoa/utox.iconset/icon_32x32.png000066400000000000000000000067471354126257400214020ustar00rootroot00000000000000PNG  IHDR szz pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxڼKOSAJ,!]V `0Shӕ@ eQH`zzZ1b],,,'U I%)P!@0fՅjX,d \.W@>d%]B,\.!D6)- rI㌲ȩǫ q.Քms z֋R( 7Go nKg Bͥͯc}|Խ]CvS:ɤESCePmǑեHj"5UmdQ(2J |.,Zzt TBd5fk$rNr&:(AJ7f*7iITj_?¥Ʉg!ٶ K$+p%nZ:6U4;U&0r pw8>IENDB`uTox-0.17.1/src/cocoa/utox.iconset/icon_512x512.png000066400000000000000000000652351354126257400215450ustar00rootroot00000000000000PNG  IHDRx pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_F_IDATxy|\e?sf֤K$e)-PX".^A. eu(])(nTPT^{J)mYni$$9sLɟllmc B-1s!DuV XC% 6mh6tBPw  WoܾfiWaZ~?wӦMl0"qJmȗ'hS,&jC4f#ş/ ՐYUPt~(5ЦX#ڒPQ mwlnv Go7W]KnuG1Q ״Ն8XMy2NB2va\x{+\ 8^WB27Ֆ$tLֺ V%n}>h nۺK:%gDž׶zi2 MGkCI[U:"ODB@os!>!lU F *|@o0` hKBG*nn֘NjW@C/]"կV/gQ;k݄q7<͞m5L+0dʅL+ȴ7/mo>t4VN (K@G$T$ ֘zk[e ޾]d_EV=d_lܑ=|1UF/Ɩ%ߥرZY = CZGKiȌ2 F($ܸUeUYַ~eFQIKgQU**/QQ,{Nd1]6̝i=W\[M~w p0PkZNuSoc nۺ]fʌ~K糊(E֣%.wcƹٓ߆x?ݻ'x fV]6,S@G@Vpf[󣗺5tm[iW_oϲWk)>b:"Ҟ0/33?|υՑ%{)΂3'8^x 2YmC@@4M*n|ܙeQ"av;첽| ?f;VN%yNBz͢/kҶzhD DbDiR cȉBADa8x] 4do## ΄='6w/ʖdʽ]?J^6 8\_BBŌ ?tD4."^Oΰ|y'D][m@dur)׶߸,ņP\r+`O_2[{nm:# N2岷?r+"2p,dDk| /#kg1yM\5s 4 noC6jIoՑ3˄4.E_x5K.[f鸼əm]HDٝg9zJC\D]o4 bT /~_n_E@ϵF p3ǺR6#Ȯ ni@fd793'h"BT5z4nqY6dM@3S;T3˺ڛ^wͽf~B7^T;ko֙e]͗׶^F"ʹ¿DڸӞm2ķ`!.~H{?">4n~֗uh[)61Ur_2KU;9;#,gϔ E`ϋi*{\K/'m@3o)k[̶^pĶu݈n뇑tXgܪ~ԬFl[p8׶-D W,vk FlK?,DVqfrpwPS҅i#}X|``-/]d$݋YD *SM7i{g$EIX{2,TYkOUO'x*n֞c=tfGL -,H{m0;6iiFEx"y/H톥;J8#u8-IoȟşF ՑEbc1c3;K#Da.7Vnf"\/},4JiGUϲ.Ko1܋Yd#GR״ԘjK)QT,4рYT=ՃK)V5-'u(>ǝ9? U{oI춹\ F%=9?7}ŏu׽ukz-,[S0;m&8d"3&bȗ}ӌ.˰#DS%zxKbs/$Gg#)^[ّ7,aTZ_4XtDUtѶ4d (dJCQt:"ru7C DimNPzinCS?UNzgv䑦eh,7; eʍW՞,`kXTscNEf N;ϙ}ny^tg;PBaˢjC22/tՑ}/尅#DcԴ5[mԋ}L Kp5N x[v^Mk[lb C}V%GUB$;Ґ.Oa"#gP t0=k8@4 W̶Db IDv?*рBdWUP1y='5-s2@TZ9:˫N"3BLPEr|Elb [Oּe>[4֙ş*4$#b[gƖ 1Ќִ5VR$C?10"柸OM7HO>gf#U1y\N?>Ѐs碾UUU@1eYi]]]{nٳd <; s掁@3='rU=Dd7Ke?p}8Cq!CšX,6iNKغu+lق-[g޽{yQF2^8f='r?ef/xSk9+Wĉ'N8G}4 hhh_߳g~ilذO?4}Yi^BYcKdU~_zSo]ݞqCO8Z v/_0BΟ?ǿۿ2 z)<xv֚,]޼/ MPk1Sn~deYl7iN$n{D"Xj7OGMMMl7? W_e!u| 3kϾ+aJM63L W,g[녫?O3 z*9u?\xG І3B І2엵^*&4m*_:"zV{™Ͻ&mo[V̛7o>Ϸn݊xΙL1k!y眸#hqM͋\DHEQUO'ay_SN9\p^WCJnq衇kW^{Oϼ^a !5G G˲*g5=YXluWn1P}6\/detv '?9>яNOH> jXo'7yՉB%nq}=H{?|'LJ\|O#_ԙ7[mX{+gߙgg8xw}8+g- pkq bPpjͯjC̎n/~ 5\Sy=}݇O?r^ ІԚ_U&VkZS{Ӱ:MM K/2WUUx{[ՑEt{|oMM6\mEv!pBs=k DE:a+DvW[nm^abm@ōW_me_|9~#@]t/4A4`vۈ7^Ѽ^]b)ֈ[c~*+W]w݅9sV7WZ[ Gڛeí1.1 O)K,nKCwioۜ7Cq;~@rݖ")^Yb)nȞLYoj*~, 핯|%n /Xc|V&XbɧjmّiLyN[j3CU-R֛;Ɍ7!PA⳼@ƖPdgf];|,3<_}Pf jC74MӆJ~˖-OG?Z/i4!jUĸWhR,^2˭2mK*e^Lʻ𖷼L9`tو{n+J 4TL^ @f˫_SSo}[7o/$n'\/YȞ !*&$PMk[nqqdWFm#?y,[eYnV̟?{ƪUxiLjkkϖz2ړ/o^ӲWh읊 !i&\}ռx4.gq9眲ac'yd/$TBiKHG_իW#J(|3hh(vѶ4܄| Amk_.g}6i3Ly VGux?"1@\:*W |c ;GhllEiw!AV0{l(K,hH^9bBuCYg FЀO> ~:y/ 8]fTY@aR.dZj@y*"O4lp_d x(48 HR첡"yoliЖh2zH;e1J3JCC=r@mū[fRBT=Sx(tN? FՕLЖ8W̄{_J+SO-|2ũj@PXa?pҥ5k/x<^H:Ц8WڒG¿<͔4M(=.G :"^7>h^0b@h})nUc)n'y$70:M* Im .a8@ (WhfZ|yY|>1Le`l{/.IV4s͟?׵!8@3zG)7-YBV0\hFC6ɾC9BV}.!yhF`B|@s3_( ak)B^1n Q# wX`/޼y\ VІi^2Wfb mBoΜ9e\Z@3̀9H͝ˎ 1Lد~w^gk3Ќ» D]]/xhf^E B`mm-^zTh-\Yb̫?WfxlU82%hF2D%X׊EU˪!  b 4ijakŶ (PގZWf"(4o(ʻ``9NGbH8Nx!k 4#H7#T׊F:.c@Iuy&t;QWa -l6kEe#L{/h&rˋE,@ih9 4SB EwwwyQ8p@e@ DŶYьF ~6ݻ@Vh\vF۹s'J3Ͷm@4^|E6غu+h&پ}{YD@eeΝgCC*$Zkl޼ A'1M7(y618@@4!|IhL(|ohtvvgCP_b#dz:֭c#dz':?@4/l Ak.UA D-NsBGe#T?6_W61M?sBqocCTc=Ɔin:R)61M|@wҟ'tuu!h( A DS)4m6l؀61MgPJ!hZ<#lb mmmӟĆ).~a61Mロ@S+:;;@4]blRկ@4ݾohۣ>~ ASN@~;&?@O<򗿰!hRǖ-[@&z+\eCФ{@6O~†Im6;A Dauwb߾}lp$1U2E6MNȆ b M6-Md-[f6ٶ sx((!NqW31M|vp?GOKK :q򗿌m۶Q&>={1߁pwo|#F:fL/~Ά oM15q<㨩Yg7 8Sah~{l"pK&xzի׼vjjj@SOqQ9p~_W,I'O>+Wq˲Bkv\uUG@mx'ObVXO<G}4:(455Mގ7< i4 tvv}b,^2OU8u&^R4| 裏! nc޽hkk֭[m6lٲ۶mCwwϵ, ,뮻7odrMO Ge{2 T>.Жx˵%6Fш?#Pzzz w@CC1k,$ DQ!s A*d뢧]]]pzSSӴ #<'X@A>H|\k[ۅ6 [Cv\{D@P^,D*:FKĽܛ@ @fxM%r]蘒ߒ%Kg|衇o~{dZ!ӆP1n֙NyO _ٲYd_%~@@!Ѽe g e#;#@iVx&ؑG9 66.da mIpk̸3<ɩNrBlل̪{ M)R1!oVQy(BO# \͂OnٲeSjkk_DV*=~ 0TTB% ;u]ݯUdԃ2UdslD=7P0RQy"7,q757UW]S qaAք=;r=/Wu5)r?}eZs1i:" .g4x i466ä\?AocPQƄSoSkBduX׮?}ӦMl3PɽW7jnL4lDOoC\O+V7&JCk,6";3pX4Ś;ΚW662kSg>-1/V{Ow]w}lM86ٰ#H-^L)V<"[)|x`H5Ə%UAt{?^şBiʕz!vml2 Zmyny[FAnj;҈g!l~ y#cq_9[#'4TLd0h@D\,7zի^5i_{Æ G>~ed 4&{9|D:f#5(L(^WLmmm~(lN;4$ [nť^ʍ~(: z;v%\}q(b8 z;w%\v6.g Z۶mÅ^;waw$Q;s'KKF%Ycc#N;q{^x!?0qF\|ŜO@De!%;q}\r 1Qxk^ ׿Ƈ?a1'Qw}ݸ[x%KSOZ[nwF$b rs饗B1dpGa1Q;w.9QN\yX~=E]˲JV\~رc( Ѐw%> .şʽJGˑL&pD![D4z]2 ֬Y|F@D /D"sك 6mb !{#mn:,D DT)>jпZ?!.2CTx p!g\qD"}5\m۶oK.Ź{~7?G]}Ր7M7݄zC@DSN_7n܈hkkc1Q%2 ԧJ)}׾q8D DTַ#ľ}O?8*Yuu5 <җn6 U3<'n:6> l?11111111& ;Z;)VHS̒Zd({nnm:aB$ d҆waM#m}nE)ՀJ{_KC@DG-F6gAb/cHj UdFߩs 9CiDAPv6ZYh{~{μ޺919C C:x ]{x'f=kOC_ 9 @@DSߗ~oZt^3CS3Yˎ@KPvወmn@@k/p4JE_ @ dBLJDs6gGuQX;޸:WV (D}x!-[S='9 hPq:j@E sЦ(,W$"޿{W oXUs+H}_1 0dI &]  M{CByB+ˮogA|`)@ b 9y}ÿߟ5qlW }T]US`/J@8|&U D DS{A۾u*DTdMt-rj"J-Zz-4D+%̋펓4?~@" "?_"vrWWn7%㖗í ,+D &"J6^PP\cfU|+a'@$HQ$?@h+ jnnۏK (>;1]3)%||6w6Sߪ=u?¿-~1YzmfpHt\~o9 Dns2A b *("g/~Y&@@[n 1ܲ? @ihC. i| { 1)]z_w(g-(l,D@Jb~`/U =|1HBYkFA; dU!uB۫H:dGNr%ՅɁ1A6٢PkdBk!rL]PX/l鍀!@/j?"&{2jFC^Uc #S(r PmIYFhǾ M(>5+ې(T\a/bR u,6NStT,LChL6H dձqF9*j5w+QЎ Bw;sX5cjK@k;-7'&ovqi5ڂfJuJKs+ MD DӜ iyJ4D!{ ր퇁\?ѸKB4N:7S=8O@;+†*[cA8+ƀ%Bk"/1P!6*J.ؼ@{}+X )?hɊUr2 }!1n5^]fiO4n@4A䏫_ةD>)̣?GB߲p 7AP ,@ɽ ~?4Q`jȔ)5$hSY`( "P䆫E~z-` ۨ~vVBzs7*Dlq .Y}Yo#Ұ޼|) D Da,bQRlXi[ nĉD DЅכF6$JoWEe ” gFk)j#IqpD4.H4Q5J#4:!l= Lۉ#D{hZ(V =0l^6!n$@8EG'Q(BN@H p E;j~;0*ѴxEG@ڒІ,`pSYT=Q/"7/7D D w g;. Ŷ*R]ΉMr;)x(!@&懬u~tޒ6 Q=D~䄈]3&)G&e=iTi}D@TC}FAfDƅ̸u!.fGC87V6PRpDBX{WVkg 6㛫w(' ʧ>60:f;?hxhRpݿ-ӈrH24[L9>n{Fe#ȟ O@Tf~] ;P3m݋ܦHQFlMd'b *!A6jͰfL{heSrrm+[Gzoˤk6@f*U*,X4w?8_ D@T! wr{iwg` O{ůR)7> $d %~n@@TA@{eoWkl؞oW6w{=Gͷ` n8@jr] !Y0گ^^9` >D@TEFǖ{+w糘6hSŸZGi1= v߰*n .qm/fB)|ޟhjq4s6)':|ʯg;j?AA8C?/1͜P-@jD[XYPa{ ݐi dO%DD7 M M  50$dk7{ѣ̋1egQ {n?ܚ|""?[Z’ACCH꿴#Nt^pߡPp GaϷcwZ BWD D4| s!@ o BiWAp[E1 1MqT_go#\PQ.[̲Z8t0^Q&SnŸl_ P=]:5k;j+7)H@45)jo.FLJnиhr!J1:jw ԦUf b x3_VYg#uRj%\ԉ .K0 ":?IM׭w\m4#yXdr9&CvI BJ eI b 뢅S:/ZfD.[0 [{ 0p0hrBYQc,6$rpMM O@4u/WoO? -x"|a-|U""qzs \@M$_m5E $_9o(]oјhVN*j (K"PUktm[11GW+4,L`IxBJ4vS"? 1D@4h窋[kz6_s.t!f矈hLE&ܯ_hD|z@>LY oƔhEUQOS}f;Mg~ uCf"Q񷢵4R/vQ3x#50 :#)gF/CDV!{X Tv&l<`&?Xx=FFvsE @@Tr_V& C͆Hc}9 $mE@Tb|SQ Q+oS?`(e'o` ׹/Ns;+fcfAK Ƚn\ @R@n80?Ln dTBmYgC1PG-5Va8Q7a xhJր!lo̺@Nce1X$@pQQ?Q碀-Cd2!s94<  ٠:D *{>Gn?Gs{Hh̭B­x5M_ p"2@hU~P wiwl̝ ]4h$"0q,7, -= M`3%nqCLD_Pf6kx#׏h*e`P$MZ ⢑$CzL Elhd5#8L+6VMFa¦\G@4DPNnrP׍|Pypu^8퀉QTsT ߅+~䃜31 ;P4<77JGo= `\lX;5 A)D@TR%L+\p[ XJ%y"IL !!\[nn'7o"wM@tp &iǟ]ho>nJBړpO~\ P@@4䗑 / *񆛣[lNkgs61 /La}P\:Va Ow;JoΆ!%W1*0*T=wi%\Wj pds,"o`tۨ~t/fU=Fg6?7#YSND Dc)~G`V۬V4m#ދl){/TD D1VʿpK~m4Eۋ9wθ(lܬ1{^_? P0z7t&Yn,X4m~" _{;0R.>OT#}hfd-؞Yp?Qa@cMNrGm &jޟ\ -`gcG6s5f%^w?w?f*ʼn DͯBBPr9kE_;qQ_>m6ݘMm>P8^CD DS2$4( 0Թ:2;JWۏlA͟x[E+3h@W4^5܃?ÙCswld ʀi8" {DvmM"~l/L@TV@{kE`Dvvb{Qdta1_{1K>?7-Z:BD DtPq,# &N7{߱U$.$""b """"""b """"""b """g}[_hRqp/ʹ90_"!wz:Yf`_ 񖈨HNЁB?@ yHO10Tdü-~*5C@A! p=}QL"$U*h@E+*<0Y0]_\eDD_U6*Pa@  _QxS?QRB1?\o_ SMJD~(/ (  e/Eo*@p^J ``U?X""6(9Åb}( @D%2H?"(3U_~3>Q%s ( rE@h`_7xUR&X>(12Q޽13BD&_<_[3E(o?Xj$ ~ps?RR0pa@[  &E! WDD40X!XuŞ,FP(Uho ,``e(@)!p0{*@z ` DT@[{ů|e`E M "JFQl4|2 @BA *UTsy C 2 \LDP-J*n {vݞ:пawK-:X؇ u!@109 _q>7wJ`$2z%YNaT HhS@G%܄0}gUN>lG+P}Q$00* \ZO.XC q:fdNc/2j弪,)첽@BiV ÷$T ՆWm޾oӞ}~q8@徎9`ι.~i9E7.Tv_oWϭI0?!zhliN$`IF 2 2 <ՃP׻W1 Ǽ[g­6r_Ty#ڵ[gvUpH>8L_{>!znaP9RN+ E{y imh͊4T񄨍2Rna@̸ Uޜ"*!aH~w֚pF{ߟۓ}[;;A:-"^@O~G7?G+rɀÅ?_s6cۨbMZsNJΎEM4C.^?dVAͅ>}:cp`?lC22&2֜SUerV4&k6D~H)Ȕ F&{(?|0&$T EZdVݙ՟reۓ=dRjv5L@)#z3@(H{ "CEW\- p8. ̩Ԙ9+5јDDA0? 7Pdr!1?""m6޻{K@ǢIyd\Nf*I;ӕ;쾾^ >'IRu xp!8dGQ30*r+з{XP bA`D$[]c6$D\Dc: BܲD8hj~obV /8GC( +‖0E {az |]>uuo:ت7QLJ;lGoMe3OԞ`P<`Y `Ɂ a nN5L1pF ßX8\#}2L!0gūxBVGc&UVTMKMKDMSBB_hn/Á\?(8P1(B>IvGaz=ȦZgG;wlggT2V}ݟrTJٮ3Hࣄb?\V=̨=Dw!~)B@0?XmH,1 0F"1gfM,fTGFu$&%VTĭ,DDy~PMZrp@P -܎ȇ|p"G"1zgoP=}vsऺy^V)خӎӮm[3no6fd:tT6<ߩ1 %E00XׯJ)0" 5@2P\Э! HQFtk`pRјQD$fTE2fEeܲďqÄe"b0Ӑ0F>al\(B`R (@!_t 0"02x9p xM` _rUFϺ \A/LSs/X` ~/hmhWg]3NVm3n_6RٴۛI;=t UԇpJ/G(C l4!z ?5L@Q7` R؋' zYbMKxѾͿ/e$"Q#Ș1+"VTF["bX2LaISD RaLaRX SBb'iGܢ:*t 8BD0l[#fԢ7=ƽ(ʁ wzFg>6uҮpmǁn.::V]Gg][gGe[*dT6릲qB=TA۰n=00t>H`Aa DJ=0 7Dd0d̊ʘe )0)LC SRD S!E԰@DMmİ `H)­ mIKzR0RO>0JzZ(u -neX+¿sh!l+PRpY^qmYѮRQv\hJ{=pu](}N؏ЏTW': {=  0Lj(aDUG??ڑ`|Zg.X:q~.ch DGSM+?A-!  C|n 06< `b_/B/>R{*0рR})#c #! LD P't)菵W'jhBH!`Bp@r0'gq ܪa}q7O}: }Xz-㟈c;D.ap=~=L ЅB9W@ptr*&vSBOts oPt)B 1L(P!@ PA sMn`3'cTL~`:Cx1~l:FJ & w@)Ap???@Y@_>05KS'?qF)X'M0Tß̞d~Q& 120}ԑ&X*f4`+.)ӹ~fOG~aT6LFASbTGPʿu ;PJУ(Yj7R1{ݫOfOe|Ng 5B0c=(‘Bԟ`FQ ! ,5)o2Dn3za(%5LD`0A>}~RFJ-Su}{Yj(2tB?3`"nLe@mѝ0#J (O珧O7CX)LhX DnmM3b_n# ޟt?E~_#L9r0# x 1(b_:1T.y~ x u%߆m`"F&3HLTKgg)z-5 $.Y'Od!\5ޠ0ab<{, Ҟ({bш|| d0yQr&( X_|K٦ц,aꞽ!U4ۉ3¸p,5ny* sf_Uy,@e_Bt(b?O&߱14LWL+rn = xdsobIENDB`uTox-0.17.1/src/cocoa/utox.iconset/icon_512x512@2x.png000066400000000000000000001734411354126257400221160ustar00rootroot00000000000000PNG  IHDR+ pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FLIDATxy\UgzHL$0I@&PPDTPT8" A8xz0rdHwHHBH'^wUWwIuz}?6I'JWZ]{/0YJ @ @@ @ @ l*{7?u00`7gM7jAFdM7oFdU덪$S-k*d|VTy@Vc&2}>㔗|/sj7^799#N%ƫ{xm-ZgNNYr0eM25[{/9~%*|-Q2227j'3JoMk`7Wr~ˊ zD~Za"ߴjU< `kXܜ5[fOon .>4 >4sSW8/w299%zM9y_l O?Q &֨>oMJ>VF65R`j.c- nx6o"sJr)O<.Rf\tϚ}`􁝫B33N1Aio]>ic/}9k7i | WI_lEз/ik$/MB0@6i}`i8t' >zmW(6{o&jќu0 .4G9Dg{ټvR䓦ѯїSӦ_ʯ>l]7n}`I`_; ]%n`F>Ph>cfj{i׭Xe~bmҰ8(`ssSmqe^aw,/4N&6qof; ~~osߧ[k}K{Mld'M?Y){lHB g|hp c3]CsB4/{RbVbD]|h3(Eu]eIyٜW\oßwnw ~JV4[ٸՖJ1}o@2\P G sT`]b gS|yk,]&hڵ+1yɻߛyW,0{3>kONҳ9pc4f?_?mK_;߷~0j6 JC>- Iv$( F>cCWa`5/?fF2=>k)9o{v' *i;zWFx7e ̫0~B() 2V>kFNuD?Ɯ(S_q69kw?[5΋<(]>,kÓ|ƞ*)JI;Vd{~[h _ַFӊ`AA鎁( Mv +_a'$?68I7]d\C `ki}=`jINak$df?˟S\2_G?4BOtpBa`AC LgpYVZWagE5,)}W4Q2@0c A@z\  Ιklg+s7rC@7s}֞WOLVNLk$ӝn9dLnwF>9&WU+(P*J+WLj3%9^s7r@k1驮"8U'fH2)hϥGu%䭓 Jortw@E*+Ẅj%}rڵ+]]Jea4.g&W&8bٮ#Wl [K3 \;[#S;%2%a@ax`U WWewg.ץӮ~an [Z=" Jsiz4¶H3d{+z~c7 KIÀL3 k岱\M$G¸:82k3L3ZnFW<]*\upv~bv#N-`>9^RHݽ;\& JTqMpƴkVv7nw˪Esz(.04oWT95]JV{MTracywW \UPUUGL _^~q_[=o?),0EͧUalqd{dk:?Oӏ򑑱qM d\E rՁ\u0>E#ӾAv1ʧ]epgv1Qje{J?OӏĒb)g#;\ET6 vʕU tRT`Hji󁩵Nuyَmj.Yg#6 (D9n#uF2k+D&.?]nf?OA/hUګIwzlv JSj?F[~+e|E,מ@nLPׄsc_}>歾r@ƿm:"?1s=RОl:ds`rNvXAU\( nlxr<68i+h;E[ a1&N'Mq?~DAMgIX.Xnl`Qqui׬{_hX|Og^z+  :'mbَ@*hKc7'd~1+a;㫞{($P O [|Oس xdN@em@nl_4!i׮x2h⬻($m12ټWؒWPߙnϧJ9@q[xl WO9+tėrPH`orc3o47(is8b?0A&sL&WjdG@<6/?1___zެ)$ƿ7&:?1s2ak-v4PqMpH<1W?/Y=o@$͘49O̼_H-V%+]34ft.GGxlh-q}dWI_j)"FEU ̢'UU+hKW;lwܷg?08L8.'vĊk Nwcۊ]1"d)q6\ /]qUe_Qysykh!ߦyٮXA{5p}^9]ۮ*^ׄ+7e49 o2smS%=ד6\ 5@s2{'vɿq.skW|0 LtdGW:(6_}3f?O05,YH*LM1=+eb'O#&pFAerN6|)HՆ'*ֆ%˯ts_-0r1FƅouvY4>K=ʬ)\6Fɰ??0/8`{(6̚dF5 Wm5.l~+0M2N~B&6.i91A@ɍ.Neh@mh\8+?!s>Ӡ#>o( ,aqQ]9nleL.=O p)F [r'f7_@`dafEuClS.R1mO'wɖ`3P6n'׆㣺7}Ňl{f7Q@ Nxl\`]UfM2/YW!*OWx± hn+.|-Y#WER8^'O4>2˯ 04^մdžc'# /]q6R_מNϧgY!\5# oH9e^튳qmxنc'qaaˢٿ'lIά%bא鱀2kr [YOT[ÒQ4>8@x#t:J䌿Nx1@9B@^!hzlS<.S4+t_}6vװQ]  yGWi5i2/(\Fu ?H`hc ƿgQ}t&,loO?8Pq!HwqQ}ӿ̉AGts:) =!qAnlT\|0hLfM2ks EgY{ )\Wfmr]`&8=<ٸ`аd }`ff^Ityt¿?v'7y뒯UWM<ذd) -!b]I4><.t 6nd"]qqqb[Fu%scL6.glȿŻop0C@7&U<Dždߺ̿NK\`r$2NA{p]= 7Drcr*hF05,^~Q41TV32ksYX'NVbC/0{ٞ8 Z#-l9jF41aK( . qqmè.<%t n_gb_| C1L$;Y Ldr^q]2 6l>jќ ;;`0yM3 cSHeZr 6$gm!@a@`>h""eZr (l N&d8i05.h>>?!ڽ2 _)SV9`& hs-AkLKn]^>k2o\|<,b~B^Ty9ymlW,O!|]d.@JNs2Nu {,"ea~bh|xJ'MHA{$d{`RqNrLeh|`W/J_#p0q~ӤN)ϼS.5e{`#=N#V)\Osr;Uq~$ 0G]}Cak>`c${ޟ-FrP8`sN3V1R>ؒogmߴ~S̟|`g?Bsy%ڜ|`G?5.j>  _ ӘtHA{,FkPrU`S+ܐ X;/ o¯$Nak+\=>¯6|y  ʋ[\ڻĠ=Nj˶Dz]l޳@2d咯.yEՆgf;g(l?v@̘4W'"e&CAa8`Kr )諂?͘4 ƫGu+AaK~a9'Ēm:0l+Euki:.e^IްJ'8[/WrY[\y=(o71yЇ5ɰtw:/  3lwzC@kTC35S7R, /l>.17CpmN2>o)7e~&iLQs=(, Z _IҘ>EͧP, lψ2?UW ZWUQ]GϠX@eװ|]VE>L)(4\ h+l)JN|6_aQ |OGu6aj?i`COB8@敜lè.aq)@Gukm !d#Q]چ/X@/Y.y[l"N9'+h+ rFu, x 56m ,!@,ٜSPKC5 /X@??\קߘ4=0`c.s])4E3|.r!@Wyo5blQ3l3|Յh\|ش_.s)O204,l>b6 e~g3r NoXWf]N}6qa @ 2?Uu>?`v /y_n\|@o= H#{n!@vn)\Ƈ6.hޝbBJ`7Ѹ L]6=ߚtIy i?~Əq)ͪZcƌQEEvر 8^qOO֦.uuuS6lІ A1Cy(]ꈓO#I&eq4Y)%vߵIiȤ1JǠ7 jhhɓ5iҤ;S鯨a\.W ֭[_~Y/֮]_|Q/ybN3R~Rvj|zv)vܲ0?~3??v بYfi̙u]بM4iy٬&Oɓ'kmmիj*ZJ>/_˗;8pII(?13;޿疽iW(wU%-Ӟ{=S{Gd2#:n87Nsy眞{9555Y׿SO^ $& !wQ,0B5|y7pCLK?5 ^{iﯹsj飾.Z͘1C3f[ׯ_z'OZZZx"a@BHFFĆ//sv@#_.ozGj* i#E ?]M{[csfh\|B> r:=9o"/hu C=Tzg(y?Y??CW6i]uxl>\3-ѻWqSasO=H3KTYSf].LLW7qDMoQG;L555exO<\qSl] ׆O*?)+Y-Vϛ(" R<>9r Z#LcvuWo1KZ2_^tR=joo(x kWDž`C~fP@@0eanJ+l'CrN&^svonFA\.zH`SZ1qE2Ovg_9 !FmҾ!l+\Wv:ټOPHjhhЉ'OZ\N?~_7:;;)F6NFMvD7'doA `$b0̚%?F _%SۙDmm?x] c E:;;V/E92K2P xl.hbVѸP羰W( @Qmd^IH;蠃tꩧc媾Qj͚5/[>,!HB*&TT WQ%/"!jƼnju˛uN]]wSOe?_;SoE! M[>lɽa+)0R0疅lwO?̙3GgqNluYonM=M!@%d |&9gO@i   Ϗ2mQ]%1eY|566Rl tqӓO>nM?8h`b%7t9a$&G nJ:f[CW7F7yWYSRCFc>hĉe[oOSPX1ry5SzR vߵIO*45=*/cTSS3C5aKNak=JHcǎ'?I7yGf„ ⋋Ͻj2Lv;HaKN>kfD3?H`4,^~Q<&81lnds&dhGj}߯?V\p~uY(#1pɻdL[F'6,^~E@;Pウq)Hl%C84"AO?]w.B7`H%\ч>!e22Bd9q!).n\t E@;+k;%Uy#َX&礘#6?W\I&Q I&M6 2b$PerN#V1RК6sƕOs xL] [ [v;8nӏ~#]9s&0c ]я~ۏ8/%lGexL)@ ?ڒ1o4i/^4Po??׾5Nd$zɱ&xP$0f{zj4>m&)hKW K:su}O1`X3x^} iv dlΛh|3==  2j;|`C^HAg$+Gozӛt=ӟ4תaĩE]{G~8y&=(y ڐTՄwP$PF KUG 7Gg04e]{w3fPh첋n&]s58q"!L>G 7UG6,YyʠqaqmŠ)lǽͿ0'?^{EAIr~# ҫc/ۓ\ &\=`( 5AgͲ#*O?u9( ԥ^oYӦM )}Qz V\~q~> {dž?TFп.'ʿ /mݦ3gRUv|c1drN+ l$* 9 ^t~}w;v}wq>ƪ?Ǝŋ)PWz5`wz`c(>\%E@[q~d?b~AVg}͙3mo{.xc&2fԄ6oMkdž0ɓuM7颋.R& v:unVwy 69 КH^aqylL+LgtQG֡J12 @\pnfM0 UG WnLtUІQ$35Mk3KlK@u?aK/T7p)09y)>=NqmfɌyM$8xL.v2y'tC͔)Stm#a50nV}CE,+V+hcPPqA=A[ߓ;V?\wuo? lVW^y.\ 2xɸt@O )h Ӹh$u#&h"oÍl{,佌ay睧o- y{߫8q"!d^;mOBydnG.6YWav[#mO{Z^{.A@AA>oN1\vO [# #믠@jW5MkKN-dL?DL>]?tR `:u~裏C*(pN#9t:5gjN\upLMЖnr2y'SࠃwJ#0UWW>P!J:XA[$W@u4 UtD9^`{׻ޥoYuuu Х^K/9 /'ڜS7Fj\|E@`ԉ7K4ӗ%e2 G|C(0O0Xv 04.j>Ul4ajź XMw1cPd ml*~ϡ8 3|: `c3]gߠ 7ܠO>ba[oUǏt `SЙ) 4,jHx*X2fJ1R^Xg`7nnfMo0{{&NH1K&k]3EYHu7:3a`"=3kn}{B Fw@GrU6Lvܘ`{mX&]h-\Ps .BNg̛7O ?:B .ft˚OS  Weϳ=NAG쿓7`N1F-ҤI(yA-y!qa\%h;{ bnK)^K,1b $/'p#@2 U]5Dt*?&}K0ԗ%UVVR ;~bC5t|e0WUMUMAGws=W{70(."b@.(@\exUnA*ɘv& Y/ssϥMUU,Y (ƀ0@ۓ%cWi9hXܜucfҗěnnYgE!4TГ^ ˍ 7㊧+(?Wueu9h]w?IϕݽWJ1竂ټO'r߀5k>l `fZ` •1~xUq=vS_/jd2r}{(aIoWjڃ øJ{Lqx߯ߟB.bM4B XPgȸJ˕ KnL3^^x!0d.00%˙ 3fd@KTSSC! i?p 1p}v򁩗gPgvtg_͝;W't0,| _Pb^xLp%`JQ j\T廒#θ8Ďed?yk6fΜ3`Az@Ag,W1c^  y(kҁD9'eO|8q"_/K6v9yQٜezy)I 0,;V)ĀJ^k#/=NʞFq tY;v2N6&/N;M3f̠=3ga6.'{7oڋ Pv>c>)#S/l/c `V_]J@_a?Ie(;WaO?1l8 QڑGC9BH_D@Y5.h:U]JWd[MM>Qnt02\|d2KYsウelI=}&/~Fs㎣kpt$ >Ne(2xgd{zEmm-gq>OZjL>=+tr@Y4.h:gM.1\>BQf͚?B=.ݱ|h\!I+yeQYY?se0$V+ͱ+g9=a?k֬Y(rz y6w9Js,@`4.leLw?_L0{Pmݱ\l\ؼ'@`cLIN&r:cH!hg֛f Qfr^yU'sI2?H guE(u^&F'Wml*^yn=Sx 0*|g}(D&|o*^3== lpӓ^5929(Q3Ϥ(}qQTWw(9[hoZxrjT"~D,۝+;)KÒ偫|o^'t*++)Q%v?q.mN԰dy@u7?8/ebq_FSN9ELBO^MZSړ%V#/9{kwF:l$edI鹌}7@`STأm:}r{`T;tfԕqu6'_a2lM; 3vtbfw2 ~iΜ9\|m^8jߴ@KݒqyvGBnvS:cևd*k{qJ'g op $]R0y6Of\L1M=A|-LFo}[)D6Ie;  +  Mk/SB2)^J:/}3@`XG]vaf +Kv9 Gâ*Ns{~^Euu:,|]gEL@qo19_3f^zLeכ E>L f[| ÐBk8ꨣ(BY^U 0 P|`8gȘ7 ^&r=9[aڴi1c(W'兙>>J|'l7 ҡJt`\Me$|k}4|Z+O{RJo|)B9xPwYӰ8UGJ&gY>￿ 9c(DYWGSCsTX)``9^z͞=Blzi|H g,|h-Qpe~Qx:!@CalK'3,ޛyKzGA&3fw*,|l*n'V7nTۼ؝,g8 @`43y7,lbn/V`.x}J^ӣ7ʚۗF1C$6kܹi5FQqW20 0}^G5^1KV{'E(^(,lRz߸d ݜ9s(l#B0N7jb>4ؒrbv7n&NH!`_Ia:SMzG=X3c UWWSrp!ة 0J5.h[U)r5ݕ]oNٳ)DU6^մίKɧ-l]wve @|o`\)YP .3f̠fzB%/ߛFj W& y)B ?Qrˏ, @`tj,NO3`AiӦQN(z{ "]Ji0/$Iմi!H!}]/3Na}Ah(._ee)D9n?'1) @`5&yk9^;E2:+x [S8iw`+Y(4ldU`)}mwk~`M %Ir!g3ޚ]) @`T7 RLX/)SP(vU{Wc AVWWG9^ 0i*L^370tp @y/5qa +nWq( =N2-kQX310(]6TEE2aWU^ĒkJ: XYA@ 0J4,Yxkƚtq^^ i̘1|: kb/o؆%L$##@omX2IVA@ȘO(Q/Ld9R(jP&`4M G`hc=WF{:@!E?ފ 0*3YR d(`H1#_~rS@l eFZ^k  0:Jv@SX  1l&㍸ 0:ƩncRz2Fǿ@e;CC5K&#khkef)je,&O5n0" "1(;/Y3FB*v"h!@ߨFG1}o.|m)@OF[S!y((B%^^&o^(6GCZkk=@EL Kgg'E2@~o`rʬ" \@*L 8 `S(s)D>p 0*XUg  =mmm r @ `:::()( /P6T@yP`hÆ  0ҭ_^qS(W^y" =9Ϋ@K`hZv-E2y)дn:@#;|8U6nܨ 04^"@`H{);{"_OF_~Y|Bvzg(c ``hc FfaÆ jii@CV}I0,455Q V\8)l#vR \N+VI0lJkjŊ;/n:=`xz1׿" _mmm?A!`[t)E#P OEWfnM-[_~B<`=-x衇(pS ;FZ~=~-[ 02qxB@?(_"@?\ 0ֆ (ZZZOR %"W y~_PH@#?gyB:;;CQ ]l@#;+ю@#ޚ5k?Br?P ﮻FzH`[t^|E `Tb?1J|^K!F'?A`hiiѽK!*\ 0*}{ߓBZ[[0:-_7F_\BNz+E0*`T{GOR#s=G}Bn7tE0d ~iٲes n `D_UVQ H<.#]wEP.#B<'xB1y R{}k_F xB?j[r5(c `Xя~Djy}:CQ o~jkkrQ }[ߢׯ_[?~i `Xn DZ-Z$=0,twws7w}ӟTׯ@_J! i9jiiW `H~UVQ lz)!{oB*uvvRC}SRWWFnI˖-@m|A}Z~=Ff};ߡ@{1}Գ>K1*c]qhj*~zG(0}{O$N;4Xb?nBmŊ:tS `ҥ^8)uukɒ%rկjժUx}38C>,K;@{ꩧ_w]yS `볟͛  {]qzW(P>wuN9__Zt)o:3u50 D׿t5P`q[nE;Xgg>*S `=z߯믿^A/^+VP`ljHwu)G t=P`p\RguJQ`ZJϧ;?seӣ/X@ZZZ/~QЇOP ,Y_@zq}E_{]wE!9:~g?0|g>:tww /TWW5k_^ł |r  _'>}Cz衇(O~?c8 kɒ%@y}b{OQ0* /T>=\zꩺ{1EDZ?Zf Fe˖.n)Z /+_k?OQ0"G!mƍ[t 'ӟ?3'#uWlF8N4sL}ӻn?`Xjkkӧ>)uttP va`Zbկcg?Y=#bXX\rVZE1ۍ/}ݧiӦ餓N'F!׃>H!e /o '~۵~z !W@ ꨣҹ瞫{Gmmmnٲe Pnq_#Zozӛ{R / /@1(9=cztuiʔ):#uV}}=EBY-^X</ښ5kt]w鮻1F>`tA:5qD(RwwƎ;*?яtwD{ >{-_\˗/.I9s:N;D^~+WO-[ENu/<10@ d\0e(+VhŊU &hܹŏw]SLyO'ГO>󟛽qqfժU 10o; vܲ07BU`@[NK.ҥK7n̙9she];k#Zfy577g3<˗kÆ [{444H[[>Or$v?d{n'疅+GDq#ΗUGCsϚ=sS+vZ#ٮX&U<&ƌ]vE :uOiӦiڴi0ae?{.ڵk/_֚5kzj=sZzyrmkkk5~Q\X\rVX? dbrS+:]Y2/;ӳwHCXq:̇h73A$]l{-me{LeAѡzJO=f>M8Q'NT]]ƍժV&QMM$B^|^]]]Ŧ[mmmQwwZ[[aÆGkk֯_u h vuQ/YD> O~KloLg` fcIɯ̸׭|ݓ&5zg"@`̘4e >cfx|f7ox89O^M%@I38֚5kf͚wyG8<!drNY6:|UXX3v3|`ޑi׮XnrqwyUgu 0P4Cv1oY_nJv$ "/6o~&JWdҟc!b֬YtR}K_gKtȇiBmd]Ӎ 6$M~&a&r^}Qa67ͻмg\ExI2Q؇N|X++S? ۈ;>ӺK'c$^>5R4&\!@ 4Y+rY#_a ;Տ1KZ{]qzy1C=:|\W+lUoDžoTMnEvٜy0̘Ը2WOΑdlS13m6=guf{ؿu]_W<+ \ P8&MwTZJ;; ?KvʧMwӠ;s^0,u#S\U#dpCV+0J>#_Rr 0F^(&l!ŝ0 ?׆~?ٮ[5:w=05.ls'3D^a[$a~6MJ>&Ν;NtW{cFC+WPa @ʆqupT\9jkX&׮v CN欌B4>i8"tſx?=_|K`WCCÈ;ZJ^x<0F_ Hgxk$+y L镂rVAU W(4D&E KC/yY9 n1T /ub AGw6~kQ6}TKK .I6JF^>22V=iC\U((Ey65,^[h@ MmxrvِWL!~@?~@>g>X-gV9vX#P+ ׄS oxVKxdg ه]'lYSu9 6F%=?:GFo^ؚ0'a;gjl+\ʬ)l*>фT ;miVT~Dd^+lG!t`G뮻N/yPm |#_9`>xDq՟QG5,mmm:K/ ;4H{鎀QIrIԲZyݭs9GO?4"%7xP.sU}}3 .?^ FV` |^]tz!Cկ~Uwq`[ ]wn6,:n&(y睵?ߍ7ިo}[?yWө:$ݺ⋵tR@9͙3Gߠ9:::tGAA3SO= (A /V\,%xjjjIgq?`c|d{1}՚5kx0 堃n6(K.>1@@`y睺 ̓@? e5uTuQ;{o}[y ;™g v_E7ojjjwutt袋.ҟ'QN;4UWW5kO?M ed}h-[L~:?`G;5iҤZf EunZ}cnMW_}8mo{fΜ9`EZx~Pl`0s߿U^x׿Rl`y߬=c@~+V蓟VZEN s駟Nlzuy穭"P&/ӣy{兩~k֬\z08I9W{1} %GqD~:3vZ x.=zzz`s=0s1g}x|F?)(;GֿqVgx`ٳu?SqSL|ԧ>MmKK.R=C0zjll|7}՚5k("`(yn6}_g?`8835iҤmmm@zuY[z)]|z(CWO~Rcǎݪ_Hgq?C;͘1C{^׵k(`v'g?Y^@|fr9]s5~ = g4eʔ>[b.-[0LqN:묳|֩J0PtRҢ 7 쳏Na$_99I鏽5UMV4JUO(**Z$79's ZGNAkNʾԭ̋ T.ϓ~Sx/kJ~>?gwo.6ԳK=)[zf_}g0do]ϴby*xCrNޛ j7ۧGS( `5 /mk&ڧN㻪@{SzRHUOW#4ᵪXw)%/ !#˖֫ةj?r CƆ8l:C]yeUE>Nbo n01@pjy32F=jI3vTTj4JOYOYKwWkrCzÀ>7T땏g*C3]T5&e4( ~G$6@j_[:??Jc7 Q]Bm<~ڎyAozZ:}z`ޔ\  `~4ҟ~[#WjGvwe vT&ܤ- @ Ac Alcs7~ l_\ QkϝxBu~ jLA߽J]o  \z48D:@ ^O_r;K 'NNTeƤ^ KrIhc>^dI€_ug&xu5^v~Roiɹ8]ZB~q4) ~vqrӫԽ8 Z$j8|\ϴ'K4 J4%F9'Xo_XM|)H>||Ȗ~$A;A?zf[,X)4M |`僒- ٽhVꯒ!~0ϊ%?Y5'NUX|ўܯN;})Ψ.dg@:.S|}]636~;BTUy(;*˘j/d/٩Q|L1ϗߚ/ٛSqx#iͿ1}πd_RDޔ@|l^9w6ub,PSg5Jwl~s!0\ `x7wf[7\gT3]+'%z-tcӯʾҩ7|0` A? lxO$i%4>!d `5~+M%^ju;k.03A~'0͝%1\ɭ6w}|ufZN)iw{{_h+7H>>Û `3UB_z7|7M֚ +1[TKnP$/6 _PńFK #&qɯ)i'YsqD)0R`}> &qS|"@phկ3*VrO&V%U8(7cLb@[lΏ!o ]^x%')zaqpcC= rUA]i`f}/ 0Dym2w_puGF1z鲹$[O5%;/!0Jo6(򿙝{u6)W:ϖҕ2[\5}+6s/fz8J̮Qˇf{ ~lMmsoor cy(]ԳؒYY#Bٶocz{W׽ɫKΕ(/+YՐ*"z؁~ӻ?V- J}k?z'uqoi_ q!AILazzh?=P 8Wh{PQn9s䫃MB MԗNn/'E*J:Y^yspS>dfn+%Y<.JA!IpO;_/|dؤ<%?UrMf}oKo{ -"7Hպ3wMVJn( %Q$s%!2l&{)P);S?ӕ^1sdoo6]F1+@@W[a-Vve5UAIFۭnRnLF'6P?lc)(^+YhΚ{<~.m <C@R뻦ˍ )!6̪K IH%?I̢ :mn;uo 0Z '5&GDJC'JŧW?=[]\}-u8dɕʍ˨S% )ct[!s5\O?V͉(فbJM~Z%K|gZaZP:]\w[ɕ8tVڧN=cv^V8.y)SMhm255V>6u9Iɍ iտp `K6ux̔>[fߥ+Nrff~V{Z%8F=j5_?VJ~ൗڏB=Mڏ[OEnÀ~Mlqdjm ij?NWM..߻#_o<6Sx|_~Q H\ ` TpB'a8lҦm9nlmt1]fn (vauv|C}cqf~f !% $o ('/دTH)KFɽ*nп7Bc{W]Dk$Wgv %vhbbs@1> J$HG2/l []:&>)FJwd?nTKXGy̮B+mK$?& M-#vWwJ2$_<ޯ@yId~q`?`a`4}gl=;P`fMIJJV7*qɭR|۫x/aC]PUv~O:=ѪkvGio/ F,-.(P!9%[I/W}N) *\4m}.=T܍R!!o>nF~jDy/ SqG@qw$Fvk  J&t_@*$g+nuS %EY5g |fL_gT@@Loҟefu64Mwk4\-;P`\VgvF&U2!M`yL6 `q `ymz6zsMR[h7 MV fْ10X* Oi}e@]PV6)e>8d```tkKX/ yYCy]鷽ޘ]dtJ.b`x>|mWD}PV&If%KfxO _w{_{5GMQV6)^gOޭ~R 5^Xz-44ۊ{ɦSIW}g ?W6M'?ֶe;#y+߻ {#d?%c۴\( I9r$+K~~[oJb`QPһ_ ~uk3م;ٍ)~v0e~ԞO%A@sp U2ά```ho!ņK%;Tl2P7\omgOfmq)i7bZ<`Jv$O_`m7eDY{^/ Uߛ, ߴd\ BYg$Iވ<kg]! ]BByAA2 0 0G< 0nK ,{hw=fٝ̈đoDFdFdFfef}?SSYYY=Y][[<>?`ap(! M6ڜ} Woc$g$D_4m 8:3.YxwucQ ofP+),xS&EбP4OJ &7:rP4h jQFG[ vЈqhQ `2]Cba}6SVFFkl|P@| [z, >]S4@A&Zoc%)%Px #cC$7 `J럺F}v7=u"-< fdv/E(Yf((,Ҍ?qjq,6sZ3;2P*7Lx~fg5 dA$_D 8E:,V N>>9 40v{a~t?@8L6S%@zsg͵;Zm|6+Q@H 'OoSPWsK)AIAQL`o + X8ng%; (06>vO8ܿ/ $axtɔX@3Qi~:em|+&G#`0꯲Y+"(]o즀F[}l`fܷdIA`ٲ T)`Q6F4b tMܷh? 663ퟵ f /#h7rw~n?$Y+xJz(ElAȏ7/ɋ'3[݉ZeNqE<_Lf*4K3qτx@ֻܡ οj<X(kp U+|Iˀ$[~,}m)*|-nJ& ďE[u?( dH*w'*9/Fg$%\=}0oOg}F8/Ef%[ L'(Q3gd߻S}.[<~6{s0/ekxܟ fego^-w3j<>=k/|]OfR%?.H/LuDaz&[$o&>y<>͒ FMw(FTE&I6^:oܿ|M]RqwwwKO `?s,䞽>x3e jt}{'zWn?P^@@H>=d Iz?*kW!+jNϗGiTQ29%@<-$Dzqn6{[Ax[̮pxL!0.1~s Po2I&M)Bgwhu'֯]1NW~s3C3K`mɌ'N@RSVW}vuEꑿ1-?,/.- @igLfC\зi z>#ec#o~aR#͖6__x$̿ sǷ.pK8 >w2PGNvGaqJgdIP?zN*l]=>}-K`uo~\(FC` Cf3Peͅ$e6uV[ゥGߠX2'u_*(|J|#&y` .g[^a<}5gοlӵ4C?.s+SO fVXE]g&./JHdqJ3Ͻ~ V3+3<ɉEϽ$d}Z]gt^|#F~l]p_g8pv*HVpw]գyG!עϽ{/Lt86 V>[z~P~cmk#egt>lI{zqC=?܉s B]鏏{2D((X}nv~>C='?w_~+}~aOoeP& 1 (gdP?0LRhd]䣄hxx}=ս? :BK?Ga_ʝ_HKF&F+ SPzIH9E63 ?>k-:ybxWuLq7o`~;z+g L ;\[gZ^_|ayUhw3?ysg~f?aeIɨpփsS/D3+jzsze@&Ќ6' Ttj@'SΫ:k_B\pJwϟEypW6% a9?&DfdI@r ]_O?w<;J;Nt.]KPi(hk͞q!u< ?[/./jWe FoxLQ ?4-v ^&[)~+k_![u:KyWBkN57sýͭ'@@Ӂ?lw ,h>m>MK~6+(A/ NطC_-_w<: ]O7s/i=7dzaN/} 5fȿiѽo{|LͶih믨uD?. |a e P0mOBɅ4ǣވ"d~ۓPp#:?m盺On%f])i(8+;u4+ƙ-_=;*|cai=]g_Ѕ}!]{&~?@;?~܌|`tnkW$pNU[?Yt'> ?qlh>T7 4M_tͯL|].{ryFtZ;x,=ֻMG^KS(';hJQ&.~ jܑ F3-)I 7Zo{l%C:K/K QtSXwf(X?or?]P0͏w?.|j=ß'e\ k;C Lʂւ`E-3&̞t܇szǾJuUϪu7i![k%cdR L `i唄9c5\mh1ѕa?Zm1TixT{_{YO;M#6g ) &*M墮շ& 7[ޠo~qoc/c}" 2cb(@`%Y+cmf\kt*zM';~3Rh?lgd 3lkۼ-ݝ! ''ǿ{n}<|n_uy'֘h@@XZ {/B#{<[:Lov4߶<)un~uϚrYרzT%3eq 4c/|ZFa?&=~=_sN_oS")y<9CZI9*) {Hm23^ +^_~-pqC]Z_@q#?8&rg gFlQ (fKLɍ:#n3oe۞o[-&}egqf l1HP0eNήtެ~;WzvAO.!IgxeN`sK`wd]Lwsۂ _"cD U|#2Kd`@@~tLJ^+ q{ߤLǘ_~\['YhZI %_ka~QLigzu> \|=ņ3z#P[]Z}8JM,<"~,‘>wUmOrv p/E_`:_l|Dqi=3t\ -ѦYG١o@FmWt;=[F/շ-3M?m ZC͖m$q]T1(R@l(+͌yss6 a:)xC_B?~Ke}Ц?}_Ε~6sr/p[[A+&Rc+_gBKtsܕhɫt5 c.b5&;="y}@Xa}HSf|B;(-f+Ѝ?x2KR2>FCegu4zgF L`uyo=1>}J(g+#oۺ*- _W֗ɶ5}oћ.6Ty~#F:Z3.˙Nm2o{lsc[^_|;ݜ҄oѲ ZK;$+sӭQ9#[l˓m7G;/up=h[Z%Xe` 6?k J[:,qևUMqEeZ\fĨK(d3|)Z+#Bמ7?]t/>Nl\;B}2 Iv@%@8+=>ћ~|?$`:=Oţr,H)C'P$c뜍& Vv ;ҟ?yܥ RʤS kӑV 05ҍ?%n7F!>jq$]L̄BhLI`3!iUM@,מη<6Z /n!\ܩ?s|I`}[܏X*7ke;^E4%:32bƳa,Uw=g{ǃ ss;xL'6OT_dlL| Ɏ58͋Gm{r߽Z2Zg#\7%3g,Zτ'G!f}/zsIou 7|f1nn!?@ w2'a_ћsNWrbݏ@7~E1%@,CPȾODAgt:x%?,5u;^="703#LIh$8ѝ$V .vG 637PelmW?5Ow~Ck3a0`Q̑i1j)vQ.:WHk~67'@晣tSѨfcx dd tsbmGOw/9%G%@~ /#0 GŻ;;G7:|Ej+d| f6gK6t6`?3ȶ<ٖmE^&9? <;()V+t嗲&wLfn?[8O{2P'L& 2 Y"a?uw" 鬙d?*rp@0gY~wdʿMF_6w)V=`ƌ44cw?1yMөι` 6j-O;x,~ ('>O_ )Vo}8 4?ηV@S08  ŒyK/ɮܥXy'6u ~\r rɆd&\LpG9%2+Όo~de0E76Pf| 5 c5qG$~N8(ƺodV9eSgJ_NfF{#ΜS/25s0-@3wC4(+zs $2WPe}o1̂  J̈́{X)Pu[s_I ˗&7Pf8iJC2gK ÷\F73hk/ߤEs,7Bfd02(+*o3k_p}!(sL&_Ȧ3(_gW <)k`6W^o&{*:`誂_3mFsϟ`h:o %#eӘ5ξ/gozb2O7SE_-@6Dn =eL9|Dyo$dNg3I9\gY+c8 @uin9ltaRT:?Xwl~Mo[qTat2S+ .qgPK߽0XBj0ˍHzfxgԻp_=$>}!oLt\)F,32Jat( ^G$sߦ;}q_/-#CY޽6Xo hr,TUP-i}`m4J N\G?=M$zTTX (V89 n`l.YICKr<)UF-cw[~{8ۂ%OIP&TbZ~;$4R5Yg@xr+g 6+O7&z3;PWb̀2aT(V}}0өx録l8mZwvn0̠;* V2ߔ-|^{(rʭhWUT4OZ(ӰBdv~9%F?OlDGiJQ'ˌ {?Aq"CK!fEzW6Yo'eK6&_2QL[? X9`)P& c2GvCM<6F6r"No.c74lgrz- ;@pw ( ʬ-J 47[贌|WѨo%P( GgxL ` @QOކghE"@ (c ۂ { p `tO?M`@q`݀o%!<P&#I (_8w*Pg G(17d_G"CW.Vдfk;7u@Yh1#L0IV,hc`v w}?0ތ|zF38s"(mj?8VFF %+J>n@ E3=@vC'}D3j:ϝacrpZ( ŹR7O~?躡̛ɽ91L*:YCE3~0YS*Yj#9{(`V!(oX}uШ 0{0@R`tq ; |ã?')i`ɮF(/%EP-):@%)(X7yoiZIFre0osoMO/ekec00" Y`r)ɷ2gLI1`ex-358@Rr )> 0)L~w`<F HFL@q42Y @#@\wF,7|?`0 @sOp=A@h;59 Ie0Pɯ Roڂ#=e#q ʈHכEþL/ii~p ٚ7sg 74Fn(z1vDCa|FQ9vDs DM-:Ϧ$ )ʏ^_> w?2p~`4ǣiXI6/ 4j_; O3?|̕mF* vwJ@te+L()>w#P1M`@@TV648ŀ-=xF6~n;(*>'`K1k%cȉ %@| M3(az22a\h홝hh&)>}?:ZFziକd#ja 닝L2:gdGs:pˇj:1/*ЬgGk:קGnJPlMΎ0MNkol.[ 4Ǎ#]xj=k7M3$O7* #?KȖ _-  ɻo{*C'(3Txxr.@ֳ~KqL/~ژF w#k(T`0fH *p JÛm:%(JNe9fInpWL[}=s*`d%oڟ ,:GfLY|?eld?2Ma'(serߖwQN(x{=]Or_L|R[RhQ|;X08R|,?P<7r _y;+^_:@3)ܨc&snWfrY;5 `}>w&VRz|<{rFb,-ʀ=Qe&, vzV8ԣ#j=_==S#N7Xf6*K!߸#NPJ.o?~mK܏X uUO~~ ExKb|&3w`M5qJ&9+Ykz& FPw?vW7nk ;. u&st;?J6H $o'oa*5ϭ|5JэyJ{ -Ư֕ u^<EK10 !j@2&LX/XѿQK'ޠWmrwԴǗ!> v'(K#n`$JƳQ3`Do^[Gt;^מtӥE~-~'b} 6qg&8] `}dt4c/i/mti(ukg_of<2+'?. i{`ov:տ'|M:;~<ǷPPюY& c3Cm:ErKO[:yNPx`%)g9 ¾_؋ޞQ ;!@4@RI?3._܎ۑ }`93*AIg|ZUrϏTܚvҿO@lJoc P(1e$;21׏˥A_􆏞z /j| x, @(P@(3}S2%~(.?V.(?{G! p: nP~P~ ~g) '-`_PK~ 2"3%2P+7KaPK~ |m8Y&?r>3+`"m&X׉UC>@Y3b@o+:T pῬ$S,qE?擎 E8f' @ `)Un4!~\J0_gf,o[R$H(@9O2_'S,~F0b`ڝDž|CX׉&Wu P( !_vݨO<'ے"jP5+`r4?y`!qKwY!S(@R)PX&Ox<'*GSA nSwO;_m 5B?(@٬IvˮEQGz>(A\/\w.`ЯMPT_0aA`*:#EY<'X/ʖ* |PU6&{gYnЯ{J%(Eu^nW."^1%@T ee@QQS˂c,^*"`2 LدrQK)pY\wd6GƥW'W Q䃿 >WؒרPvJBTmI_ _n/*B~~lG F10*W?i)(~Ee~\V'cEU6.* @Y P~]BO@>Qe%ɅqKƅ*'P)sXL8U_ 0ȿ.$  jU MG"/fUVXO*,*_eܞeE?2/5]:S6#ALU~:,wkI[re$P >70%%_q i a?:\gA)ǸnGˡk4 Qި,b@I 0yfkmA!9>_Y@P3|S`BΎ(" ̽*>F:_S5)_RP,v`smŷ| PzBY/ N uEE@ ^*#uu"@z0DNX@@9גPA@P0%QQ^`1 w ~I0j&@@*_PSߏ;u}X,_ˡsڽSyMf,_gsqר>P%*x,W9&J[ @_e?ܾjPVzbI_z P?Ңp_%Z PbU75cϲת^87iPx@,f0ܤ] G|MQ:M5"4ju^`*m.@P=n-WY3^N4KՖjFfPT ~Q׊5F=^Y&kugJVt?n4mns? _]rǷ]O@Q(sB0QwoL}W\5ی_#@Lu/1_P/K0 (pf /]!oZ^׽;o~i8}+Q3Պk(w=h+؊NXQpr?~W?!s?Bo/Ῥ(+PYJ" muœo顧2w?Mh[F{vgX7Xۯmy 7o#*o{ǟ>q ORL2 ,)%O P̠: `0;}I~rm~عdF@a`F2 RmhD,n7F6}'L4ſ)x1R`m_g? JI IF)T")`F.Un7-9r?sg_mmu7k;{sn8w 7 N^}nhC!4;kN_zwO>w_ݣ8d_pL &o82xA^a9x'J4,3:*37O߹|n{-si}]F }B`Pd,K)IwSöBݣ]gOntȿqݥӌWPuTaXVpC܏%׷+*$yz'/\l1&T< гQ)K e}+J YnwGi} x]#ESMvJ2Lw[/~is o?/߿U: `ԴiF˦-B,.E˿/]շ7Sq* rj;{p^)Fw/߿66^_/HўqR$͜.0T~3[R tA8^n+ -7'Qxt N^ڹw۽{%v%!j  F'Y_vTuJB}m13N`{2QS']?n ʖE=o :]n?r9(-̉p $S'd5XJ$Qtȗ;@.k8Ļ a\0 N'#][/I:\ݵA|z Q5~6@0&t:QTW@kU8ME7?W`,c\/-Ul?9zotkno=||-.uV)å@Zhf@+Bśf I)/fP%K#&wq}ϮOh4? 2oww NK^/U<+PeI@B|_6?K}xR& рFUfǪz]Zs77 f53=m`78u ]B@pg x*S`#$;G9[;Q_{p9ڃ{8wx=<9=:]7 `e 0ny@iLP# -ƅWb `JBB~KO}*s;;׺ujJ6%}gAw@XpDar3s`TI0r&( `q#~pٝ9jˎ⧻r; [Yv8|\=cpԴ:_lԿ*e/E'[1K P@fMLfx/Znk]6󝮶:kfݑo2X^v@f07{$Hw&u 䲜+ ( `uB%/IiI7}] }d#|kAD{'Gqp`wkowso/} j2Kӏ7QL'$ouO P` iFrG*z4#IOST t.mn<׾_w׼tnK $ /%HKх*܌0-_f0l[P\)Z8P7>~KGݐo B;7܆|^#aoNQs|o߯ Ri iZLRTqaϔ8k@Zu@=~TПf=``Yu u-{mf{l;fzvA$ dS8 l;ҰBY [AN1P WN5|mmp2MZNχ{`0;>  +"`Mee@X!*+Rg&[0rQ3 U4APhd6?o߹~`s;ϯ[5o5Youj -5rf%@Yd8LnQ/ YE"*(:W GU>7A_춟|ku={'Qstn=8A@?i$)&ט[(qkO(Ƈ֢`\?@ 0L- s}qc}ic?:mvּvW뭎Yk͚V* *%AnAX;[ [2PJq삑 JL _rqA>w7O/_7'$ۣgz=Oƒqr9: iF.WT-M+g~`"`܌OFyOʀB`ڒ`"`Nsku\wun6]5:f1ʂ0W$IS lO^AR*TP d&$@E. daj`˘/PW\W(#ܑ{w|w}`=/Q0٣މ=qpprlz`{t8_&;媟ohr$_? j 7?IvSgP`Zu&@"jǕFG=`h:OU$[ֺMou7N_﬙v׬ڦLo[ _Gٛ ?@ֹ. %E3%órS" }[$]( UҥĘ +}]q_F\~j}ޓ`_Mώ+7U?w7+ʪuIзA{wكq ;9? ӄ&ʀeX?IPgqABJYP'WrߋP'`_gQKL͟Y_y %D!F~ot:zkou׼V[o0𺭶~tZ-j{-u<meg8e@2tAn_A÷ {) r,Ȗ å@iPP0dzeF S,y%?_Em>㿑5Si u2er?^saltĽpS<:='eYo_iȯg=?M؟ha"`e@5UG'yRf$`pd_&f,̆5|@`uLkmtF뭷Z㭵Lk:mߴ}tZ^K-{cGϲ -ܻ`P,(a䇒zyh恆s_vC/ln7[2ߌ)W)˃ը̈p\Q5j E#JFޣrdi *YK?fJzA  0}'8= 'Q$<丿w|dV Mi Y_dSj9@")ϟ8VeS@u6W LJI$s`F@%Axu[-mf:~ZQLo2k|7-^۶oZx=_m3Uf' wB R83 ONp?4*w0 mk?rJ}aP/z}Qw7˭ΔOw>WNGICL8lhЪg6T?l?{/~({^طgO~x?}?8G^ppr=e U?MiYufRjŠOIQ &7kzz<.X"`EE/!i"UC`\eIP#}uEG`j;( f 篛vIKI/R?"4ˀICZ0}ڡ}?_9YLW qT-|4Uu( FEߌh]^l 6T >#iQ.u!P7N 04;㯱 f0AQY/E)02>Ug 7n?(ߣL0 #e9K4Wqβr7[B4kb4e@fTQIgG 00ns!-)^X_X࿈%"fY"ʬv˸$JE V+f7AnPgG0E/ͨ_ SזY?M举_?m_ _Mu{,_ 5U,bP7Oy ~83@Y oƼ@S: U˄&z7&OuzS[??OX``I, KYM. *f\R(J /ƕe߳,x5ӄIj:_V6;k'z!@0Xfl`fԝ 0B@jfN0`RQN3/fi I~5"/H"yYe)}YD, hW9Kc0if?UJI 3ڛֿybMyu@g'YA4RUfؒ_TXߡ.fYv_yԟS4n?˥ *v0i1T!P79oQb@%l|ULWizEٟ4/JПe_ֵ R%suoy(fuh<˺L`@o5̅IPXilq%4Uo$}Q6[iYBv7\`0dYPk8mtʀqA,ں4J q/møoZ?m& V/}1i v<;c*)8r`ʀYIB &q?*i?(e/ uB`T1P%Oif@S_3gy`g h2OgY4gϝ `AJ ߌyc*e3t?ͩ џ6' ȋ9 `6/U PLg]L[̪ RY(YuC? ^M2`\0M)1m90mo"/:U nY2e?o^i]] dR`i/!Eob7FA uQKʎu_Qye .N3/~F/7}e-ViYY kiF Ћ&*niZ,v_?__63`%I㢞BDxUIPM~?(.+~ , UUo"OWy$[y/Te/9v_(g}=3禊Iʀ~PKR]YU6 [ v o3`LxU].D0?`Y*uo" " Qƅ**@;ܟ i4я[/]j VL⛾nF1}AHP ( u7 v`m*SR؟Ugӿ, 윿vU r)%,>DsţfT)ƕv}v'ϿE_Phł]< e(&*-F㊀:E<i^wן Me9oA/)}ih"ܟF0`eYİɿۤPu~BQPuݸ  g%Oqv 0;`%Yٜ`EA!B(ZᾉB`RJ 0 s,|m~-N4S?|@SYME,fM?@ ky>`><[ p9u_@ο|K ,v! A%]}Za)3z@̄_WvċI>7aj^\MG_O+kJYO_L/)V6h.Ò&üMۋiJ*QL[T,JEo2/}BYp ̪h*ϫ8͂4=4(((-FUK*_S>dT~z_/Tyeٴ Oq0?O _Yguv kh◨cǝ0Us;}T'WWiԾ~, oʂe_ʷ9O(34ʁ& EAJaP4RԹ?/X/o`;.L0&jVVpω, N,) ͒v{/gyfY^ ,B0Ϡnyr8 `_רYwJ}aj 3h9N}?ז}~~,Qy˺2 v~^|EI0mhu4 fLq>ZV0{.ҟJYy4E, g.c + ؘWiD0MD9c`ҟ׼^t=vg>W"-wcpD/ Qδߦ۬~>Z ռ)fV,h",Jfåmg0KU|mU3;xtxzY0Ǭ :YǚyǿMNϵgs9?g^SO3P%q:,-!g`i,c?C oufBq63 +a+/@(4IENDB`uTox-0.17.1/src/cocoa/video.m000066400000000000000000000447031354126257400157170ustar00rootroot00000000000000#include "main.h" #include "../friend.h" #include "../debug.h" #include "../main.h" #include "../settings.h" #include "../tox.h" #include "../../langs/i18n_decls.h" #include "../av/utox_av.h" #include "../av/video.h" #include "../native/audio.h" #include "../native/ui.h" #include "../native/video.h" #import #import #include /* MAJOR TODO: S FOR THIS FILE * - check clean up and error handling with AVFoundation code. */ #define SCREEN_VIDEO_DEVICE_HANDLE ((void *)1) @implementation uToxAV { dispatch_queue_t _processingQueue; AVCaptureSession * _session; AVCaptureVideoDataOutput *_linkerVideo; CVImageBufferRef _currentFrame; pthread_mutex_t _frameLock; BOOL _shouldMangleDimensions; } - (instancetype)init { abort(); // never called, this is here to suppress a warning. } - (instancetype)initWithHandle:(void *)video_dev_handle { self = [super init]; if (self) { pthread_mutex_init(&_frameLock, NULL); _processingQueue = dispatch_queue_create("uToxAV processing queue", DISPATCH_QUEUE_SERIAL); _session = [[AVCaptureSession alloc] init]; if (video_dev_handle == SCREEN_VIDEO_DEVICE_HANDLE) { AVCaptureScreenInput *input = [[AVCaptureScreenInput alloc] initWithDisplayID:desktop_capture_from]; input.capturesCursor = YES; input.capturesMouseClicks = YES; input.cropRect = desktop_capture_rect; input.scaleFactor = 1.0 / desktop_capture_scale; [_session beginConfiguration]; [_session addInput:input]; //_session.sessionPreset = AVCaptureSessionPreset640x480; [_session commitConfiguration]; // CGRect tr = CGRectIntegral(AVMakeRectWithAspectRatioInsideRect(desktop_capture_rect.size, (CGRect){0, 0, // 640, 480})); video_width = desktop_capture_rect.size.width; video_height = desktop_capture_rect.size.height; _shouldMangleDimensions = NO; [input release]; } else { uToxAppDelegate *ad = (uToxAppDelegate *)[NSApp delegate]; AVCaptureDevice *dev = [[ad getCaptureDeviceFromHandle:video_dev_handle] retain]; if (!dev) { LOG_TRACE("uTox Video", "Unable to find video device!"); return nil; } NSError * error = NULL; AVCaptureInput *input = [[AVCaptureDeviceInput alloc] initWithDevice:dev error:&error]; [_session beginConfiguration]; if (!input) { LOG_TRACE("uTox Video", "Unable to open video device!"); return nil; } [_session addInput:input]; _session.sessionPreset = AVCaptureSessionPreset640x480; [_session commitConfiguration]; // pray here // we make the assumption that AVFoundation will give us 640x480 video here // but if it doesn't we're going to segfault eventually. video_width = 640; video_height = 480; _shouldMangleDimensions = YES; [input release]; [dev release]; } } return self; } - (void)beginCappingFrames { _linkerVideo = [[AVCaptureVideoDataOutput alloc] init]; [_linkerVideo setSampleBufferDelegate:self queue:_processingQueue]; if (_shouldMangleDimensions) { [_linkerVideo setVideoSettings:@{ (id)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_420YpCbCr8Planar), (id)kCVPixelBufferWidthKey : @640, (id)kCVPixelBufferHeightKey : @480 }]; } else { [_linkerVideo setVideoSettings:@{(id)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA) }]; } [_session addOutput:_linkerVideo]; [_session startRunning]; } - (void)stopCappingFrames { [_session stopRunning]; [_linkerVideo release]; } - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { // NSLog(@"video frame available"); pthread_mutex_lock(&_frameLock); CVImageBufferRef img = CMSampleBufferGetImageBuffer(sampleBuffer); if (!img) { NSLog(@"uToxAV WARNING: got bad sampleBuffer from avfoundation!!"); } else { CVPixelBufferUnlockBaseAddress(_currentFrame, kCVPixelBufferLock_ReadOnly); RELEASE_CHK(CFRelease, _currentFrame); _currentFrame = (CVImageBufferRef)CFRetain(img); // we're not going to do anything to it, so it's safe to lock it always CVPixelBufferLockBaseAddress(_currentFrame, kCVPixelBufferLock_ReadOnly); } pthread_mutex_unlock(&_frameLock); } - (BOOL)getCurrentFrameIntoChannelsY:(uint8_t *)y U:(uint8_t *)u V:(uint8_t *)v:(uint16_t)w:(uint16_t)h { if (!_currentFrame) { return NO; } pthread_mutex_lock(&_frameLock); CFRetain(_currentFrame); CFTypeID imageType = CFGetTypeID(_currentFrame); if (imageType == CVPixelBufferGetTypeID()) { // TODO maybe handle other formats if (CVPixelBufferGetPixelFormatType(_currentFrame) == kCVPixelFormatType_420YpCbCr8Planar) { uint8_t *yPlane = CVPixelBufferGetBaseAddressOfPlane(_currentFrame, 0); uint8_t *uPlane = CVPixelBufferGetBaseAddressOfPlane(_currentFrame, 1); uint8_t *vPlane = CVPixelBufferGetBaseAddressOfPlane(_currentFrame, 2); memcpy(y, yPlane, h * w); memcpy(u, uPlane, h * w / 4); memcpy(v, vPlane, h * w / 4); } else { bgrxtoyuv420(y, u, v, CVPixelBufferGetBaseAddress(_currentFrame), w, h); } } else if (imageType == CVOpenGLBufferGetTypeID()) { // OpenGL pbuffer } else if (imageType == CVOpenGLTextureGetTypeID()) { // OpenGL Texture (Do we need to handle these?) } CVPixelBufferRelease(_currentFrame); pthread_mutex_unlock(&_frameLock); return YES; } - (void)dealloc { [_session release]; dispatch_release(_processingQueue); [super dealloc]; } @end @implementation uToxAppDelegate (VideoDevices) - (uint16_t)storeVideoDevicesList { if (devices) { [devices release]; } device_count = 1; /* 1 for desktop */ devices = [[NSMutableDictionary alloc] init]; utox_video_append_device(SCREEN_VIDEO_DEVICE_HANDLE, 1, STR_VIDEO_IN_DESKTOP, 0); NSArray *vdevIDs = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; for (int i = 0; i < vdevIDs.count; i++) { AVCaptureDevice *dev = vdevIDs[i]; unsigned long len = strlen(dev.localizedName.UTF8String); char * data = malloc(sizeof(void *) + len + 1); void * ptr = (void *)((uint64_t)i + 2); memcpy(data, &ptr, sizeof(void *)); memcpy(data + sizeof(void *), dev.localizedName.UTF8String, len); data[sizeof(void *) + len] = 0; devices[@(i + 2)] = dev.uniqueID; utox_video_append_device(data, 0, data + sizeof(void *), 1); device_count++; } return (uint16_t)device_count; } - (AVCaptureDevice *)getCaptureDeviceFromHandle:(void *)handle { NSString *s = devices[@((uintptr_t)handle)]; if (!s) { return nil; } return [AVCaptureDevice deviceWithUniqueID:s]; } @end static uToxAV * active_video_session = NULL; CGDirectDisplayID desktop_capture_from = 0; CGRect desktop_capture_rect = { 0 }; CGFloat desktop_capture_scale = 1.0; #ifdef UTOX_COCOA_BRAVE #define AV_SESSION_CHK() #else #define AV_SESSION_CHK() \ if (!active_video_session) { \ LOG_WARN("uToxAV", "no active video session"); \ abort(); \ } #endif bool native_video_init(void *handle) { NSLog(@"using video: %p", handle); if (active_video_session) { LOG_ERR("Video", "overlapping video session!"); abort(); } active_video_session = [[uToxAV alloc] initWithHandle:handle]; if (!active_video_session) { NSLog(@"Video initialization FAILED with handle %p. ", handle); } return active_video_session ? 1 : 0; } void native_video_close(void *handle) { [active_video_session release]; active_video_session = nil; } bool native_video_startread(void) { AV_SESSION_CHK() [active_video_session beginCappingFrames]; return 1; } bool native_video_endread(void) { AV_SESSION_CHK() [active_video_session stopCappingFrames]; return 1; } int native_video_getframe(uint8_t *y, uint8_t *u, uint8_t *v, uint16_t width, uint16_t height) { AV_SESSION_CHK() return [active_video_session getCurrentFrameIntoChannelsY:y U:u V:v:width:height]; } uint16_t native_video_detect(void) { uToxAppDelegate *ad = (uToxAppDelegate *)[NSApp delegate]; return [ad storeVideoDevicesList]; } // display video @interface uToxIroncladVideoLayer : CAOpenGLLayer @property uint8_t *temporaryLoadTexture; @property int temporaryWidth; @property int temporaryHeight; @property GLuint texture; @end @implementation uToxIroncladVideoLayer - (void)drawInCGLContext:(CGLContextObj)ctx pixelFormat:(CGLPixelFormatObj)pf forLayerTime:(CFTimeInterval)t displayTime:(const CVTimeStamp *)ts { if (!self.texture) { glEnable(GL_TEXTURE_2D); glGenTextures(1, &_texture); glBindTexture(GL_TEXTURE_2D, self.texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } if (self.temporaryLoadTexture) { glBindTexture(GL_TEXTURE_2D, self.texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self.temporaryWidth, self.temporaryHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, self.temporaryLoadTexture); self.temporaryLoadTexture = NULL; } glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, 1.0, 1.0, 0.0, 0.0, 1.0); glViewport(0, 0, self.bounds.size.width, self.bounds.size.height); glMatrixMode(GL_MODELVIEW); glBindTexture(GL_TEXTURE_2D, self.texture); glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor4f(1.0, 1.0, 1.0, 1.0); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); static GLfloat payload[] = { 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, }; glVertexPointer(2, GL_FLOAT, 0, payload); glTexCoordPointer(2, GL_FLOAT, 0, payload); glDrawArrays(GL_TRIANGLES, 0, 6); } @end @implementation uToxIroncladVideoContent - (instancetype)initWithFrame:(NSRect)frameRect { self = [super initWithFrame:frameRect]; if (self) { self.layer = [uToxIroncladVideoLayer layer]; self.layer.frame = self.bounds; [(CAOpenGLLayer *)self.layer setAsynchronous:NO]; self.wantsLayer = YES; } return self; } - (void)displayImage:(uint8_t *)rgba w:(uint16_t)width h:(uint16_t)height { // LOG_TRACE("Video", "wants image of %hu %hu", width, height); ((uToxIroncladVideoLayer *)self.layer).temporaryLoadTexture = rgba; ((uToxIroncladVideoLayer *)self.layer).temporaryWidth = width; ((uToxIroncladVideoLayer *)self.layer).temporaryHeight = height; [self.layer setNeedsDisplay]; [self.layer displayIfNeeded]; } - (void)checkSize { self.layer.bounds = self.frame; } - (BOOL)isOpaque { return YES; } @end @interface uToxIroncladWindow : NSPanel @property NSUInteger video_id; // useless subclass, why isn't canBecomeKeyWindow assignable?? - (BOOL)canBecomeKeyWindow; - (BOOL)canBecomeMainWindow; @end @implementation uToxIroncladWindow - (BOOL)canBecomeKeyWindow { return NO; } - (BOOL)canBecomeMainWindow { return NO; } @end @implementation uToxIroncladView { uToxIroncladVideoContent *__strong _videoContent; } + (NSWindow *)createWindow { #define START_RECT \ (CGRect) { 0, 0, 100, 100 } NSWindow *ret = [[uToxIroncladWindow alloc] initWithContentRect:START_RECT styleMask:NSHUDWindowMask | NSUtilityWindowMask | NSClosableWindowMask | NSTitledWindowMask | NSResizableWindowMask backing:NSBackingStoreBuffered defer:YES]; ret.hidesOnDeactivate = NO; uToxIroncladView *iv = [[self alloc] initWithFrame:ret.frame]; ret.contentView = iv; [iv release]; return ret; #undef START_RECT } - (instancetype)initWithFrame:(NSRect)frameRect { self = [super initWithFrame:frameRect]; if (self) { _videoContent = [[uToxIroncladVideoContent alloc] initWithFrame:(CGRect){ 0, 0, frameRect.size.width, frameRect.size.height }]; _videoContent.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; [self addSubview:_videoContent]; } return self; } - (void)resizeSubviewsWithOldSize:(NSSize)oldSize { [super resizeSubviewsWithOldSize:oldSize]; [_videoContent checkSize]; } - (void)displayImage:(uint8_t *)rgba w:(uint16_t)width h:(uint16_t)height { [_videoContent displayImage:rgba w:width h:height]; } - (void)dealloc { [_videoContent release]; [super dealloc]; } @end @implementation uToxAppDelegate (IroncladManager) - (void)setIroncladWindow:(NSWindow *)w forID:(uint32_t)id { ironclad[@(id)] = w; w.delegate = self; } - (void)releaseIroncladWindowForID:(uint32_t)id { [ironclad removeObjectForKey:@(id)]; } - (NSWindow *)ironcladWindowForID:(uint32_t)id { return ironclad[@(id)]; } - (void)windowWillClose:(NSNotification *)notification { if ([notification.object isKindOfClass:uToxIroncladWindow.class]) { switch (((uToxIroncladWindow *)notification.object).video_id) { case UINT16_MAX: { settings.video_preview = 0; video_end(0); postmessage_utoxav(UTOXAV_STOP_VIDEO, UINT16_MAX, UINT16_MAX, NULL); break; } default: { FRIEND *f = get_friend(((uToxIroncladWindow *)notification.object).video_id); if (!f) { LOG_ERR("Cocoa", "Could not get friend with number: %u", ((uToxIroncladWindow *)notification.object).video_id); return; } postmessage_toxcore(TOX_CALL_DISCONNECT, f->number, 0, NULL); break; } } redraw(); } } @end void video_frame(uint16_t id, uint8_t *img_data, uint16_t width, uint16_t height, bool resize) { if (!img_data) { LOG_DEBUG("Video", "Receieved a null frame. Skipping..."); return; } uToxAppDelegate *utoxapp = (uToxAppDelegate *)[NSApp delegate]; NSWindow * win = [utoxapp ironcladWindowForID:id]; uToxIroncladView *view = win.contentView; if (!win) { LOG_WARN("Video", "BUG: video_frame called for bogus Ironclad id %lu", id); } CGSize s = view.videoSize; if (resize || s.width != width || s.height != height) { LOG_WARN("Video", "frame size changed, if this happens too often file a bug"); CGFloat chrome_metric_w = win.frame.size.width - [win.contentView frame].size.width; CGFloat chrome_metric_h = win.frame.size.height - [win.contentView frame].size.height; int rswidth = width + chrome_metric_w; int rsheight = height + chrome_metric_h; [win setFrame:(CGRect) { win.frame.origin.x, CGRectGetMaxY(win.frame) - rsheight, rswidth, rsheight } display:YES animate:NO]; win.contentAspectRatio = (CGSize){ width, height }; view.videoSize = (CGSize){ width, height }; } [view displayImage:img_data w:width h:height]; } void video_begin(uint16_t _id, char *name, uint16_t name_length, uint16_t width, uint16_t height) { if ([(uToxAppDelegate *)[NSApp delegate] ironcladWindowForID:_id]) return; uToxIroncladWindow *video_win = (uToxIroncladWindow *)[uToxIroncladView createWindow]; video_win.title = [[[NSString alloc] initWithBytes:name length:name_length encoding:NSUTF8StringEncoding] autorelease]; video_win.video_id = _id; uToxAppDelegate *utoxapp = (uToxAppDelegate *)[NSApp delegate]; NSWindow *utoxwin = utoxapp.utox_window; CGFloat chrome_metric_w = video_win.frame.size.width - [video_win.contentView frame].size.width; CGFloat chrome_metric_h = video_win.frame.size.height - [video_win.contentView frame].size.height; int rswidth = width + chrome_metric_w; int rsheight = height + chrome_metric_h; [video_win setFrame:(CGRect) { CGRectGetMaxX(utoxwin.frame), CGRectGetMaxY(utoxwin.frame) - rsheight, rswidth, rsheight } display:YES]; ((uToxIroncladView *)video_win.contentView).videoSize = (CGSize){ width, height }; video_win.contentAspectRatio = (CGSize){ width, height }; [utoxapp setIroncladWindow:video_win forID:_id]; [video_win makeKeyAndOrderFront:utoxapp]; [video_win release]; } void video_end(uint16_t id) { uToxAppDelegate *utoxapp = (uToxAppDelegate *)[NSApp delegate]; [utoxapp releaseIroncladWindowForID:id]; } uTox-0.17.1/src/cocoa/window.c000066400000000000000000000020201354126257400160700ustar00rootroot00000000000000#include "../window.h" #include #include bool native_window_init(void) { return true; } static UTOX_WINDOW *native_window_create(UTOX_WINDOW *window, char *title, unsigned int class, int x, int y, int w, int h, int min_width, int min_height, void *gui_panel, bool override) { return NULL; } void native_window_raze(UTOX_WINDOW *window) { } UTOX_WINDOW *native_window_create_main(int x, int y, int w, int h, char **argv, int argc) { return NULL; } void native_window_create_video() { } UTOX_WINDOW *native_window_find_notify(void *window) { return NULL; } UTOX_WINDOW *native_window_create_notify(int x, int y, int w, int h, PANEL *panel) { return NULL; } static void notify_tween_thread(void *obj) { } void native_window_tween(UTOX_WINDOW *win) { } void native_window_create_screen_select() { } bool native_window_set_target(UTOX_WINDOW *new_win) { return true; } void native_screen_grab_desktop(bool video) { } uTox-0.17.1/src/command_funcs.c000066400000000000000000000036251354126257400163250ustar00rootroot00000000000000#include "command_funcs.h" #include "friend.h" #include "groups.h" #include "debug.h" #include "tox.h" #include "macros.h" #include #include bool slash_send_file(void *object, char *filepath, int UNUSED(arg_length)) { if (filepath) { FRIEND *f = object; LOG_TRACE("slash_send_file", "File path is: %s" , filepath); postmessage_toxcore(TOX_FILE_SEND_NEW_SLASH, f->number, 0xFFFF, (void *)filepath); return true; } LOG_ERR("slash_send_file", " filepath was NULL."); return false; } bool slash_device(void *object, char *arg, int UNUSED(arg_length)) { FRIEND *f = object; uint8_t id[TOX_ADDRESS_SIZE * 2]; string_to_id(id, arg); void *data = malloc(TOX_ADDRESS_SIZE * sizeof(char)); if (data) { memcpy(data, id, TOX_ADDRESS_SIZE); postmessage_toxcore(TOX_FRIEND_NEW_DEVICE, f->number, 0, data); return true; } LOG_ERR("slash_device", " Could not allocate memory."); return false; } bool slash_alias(void *object, char *arg, int arg_length) { FRIEND *f = object; if (arg) { friend_set_alias(f, (uint8_t *)arg, arg_length); } else { friend_set_alias(f, NULL, 0); } utox_write_metadata(f); return true; } bool slash_invite(void *object, char *arg, int UNUSED(arg_length)) { GROUPCHAT *g = object; FRIEND *f = find_friend_by_name((uint8_t *)arg); if (f != NULL && f->online) { postmessage_toxcore(TOX_GROUP_SEND_INVITE, g->number, f->number, NULL); return true; } return false; } bool slash_topic(void *object, char *arg, int arg_length) { GROUPCHAT *g = object; void *d = malloc(arg_length); if (d) { memcpy(d, arg, arg_length); postmessage_toxcore(TOX_GROUP_SET_TOPIC, g->number, arg_length, d); return true; } LOG_ERR("slash_topic", " Could not allocate memory."); return false; } uTox-0.17.1/src/command_funcs.h000066400000000000000000000013571354126257400163320ustar00rootroot00000000000000#ifndef COMMAND_FUNCS_H #define COMMAND_FUNCS_H #include /** slash_send_file() * * takes a file from the message box, and send it to the current friend. * * TODO, make sure the file exists. */ bool slash_send_file(void *friend_handle, char *filepath, int arg_length); /** * Adds a device to a friend */ bool slash_device(void *f, char *argument, int arg_length); /** * Sets the current friend's alias to the value of arg */ bool slash_alias(void *f, char *arg, int arg_length); /** * Invites a friend to the current groupchat */ bool slash_invite(void *f, char *arg, int arg_length); /** * Sets the topic of the current groupchat to the value of arg */ bool slash_topic(void *object, char *arg, int arg_length); #endif uTox-0.17.1/src/commands.c000066400000000000000000000104411354126257400153040ustar00rootroot00000000000000#include "commands.h" #include "command_funcs.h" #include "debug.h" #include "flist.h" #include "tox.h" #include "layout/friend.h" // TODO, we should try to remove this dependency #include "ui/edit.h" #include struct Command commands[MAX_NUM_CMDS] = { { "alias", 5, slash_alias }, { "invite", 6, slash_invite }, { "d", 1, slash_device }, { "sendfile", 8, slash_send_file }, { "topic", 5, slash_topic }, { NULL, 0, NULL }, }; uint16_t utox_run_command(char *string, uint16_t string_length, char **cmd, char **argument, int trusted) { if (trusted == 0) { return 0; /* We don't currently support commands from non-trusted sources, before you run commands from friends * or elsewhere, you MUST implement error checking better than what exists */ } uint16_t cmd_length = 0, argument_length = 0; if (string[0] == '/') { /* Cool it's a command we support! */ // LOG_TRACE("Commands", "command found!" ); uint16_t i; for (i = 0; i < string_length; ++i) { if (string[i] == ' ') { cmd_length = i; break; } } ++i; for (; i < string_length; ++i) { if (string[i] != ' ') { argument_length = string_length - i; *argument = string + i; break; } } if (cmd_length) { --cmd_length; *cmd = string + 1; } } else { // LOG_TRACE("Commands", "No command found" ); /* Sad, we don't support this command. */ *argument = string; cmd = NULL; return 0; } int i = 0; while(commands[i].cmd){ if (commands[i].cmd_length == cmd_length && memcmp(commands[i].cmd, *cmd, cmd_length) == 0) { void* object = flist_get_friend() ? (void*)flist_get_friend() : (void*)flist_get_groupchat(); bool ret = commands[i].func(object, *argument, argument_length); if (ret) { cmd_length = -1; } break; } i++; } return cmd_length; } bool g_select_add_friend_later = 0; void do_tox_url(uint8_t *url_string, int len) { LOG_TRACE("Commands", "Command: %.*s" , len, url_string); //! lacks max length checks, writes to inputs even on failure, no notice of failure // doesnt reset unset inputs // slashes are removed later if (len > 4 && memcmp(url_string, "tox:", 4) == 0) { url_string += 4; len -= 4; } else { return; } // wtf?? uint8_t *b = (uint8_t *)edit_add_new_friend_id.data, *a = url_string, *end = url_string + len; uint16_t *l = &edit_add_new_friend_id.length; *l = 0; while (a != end) { switch (*a) { case 'a' ... 'z': case 'A' ... 'Z': case '0' ... '9': case '@': case '.': case ' ': { *b++ = *a; *l = *l + 1; break; } case '+': { *b++ = ' '; *l = *l + 1; break; } case '?': case '&': { a++; if (end - a >= 8 && memcmp(a, "message=", 8) == 0) { b = (uint8_t *)edit_add_new_friend_msg.data; l = &edit_add_new_friend_msg.length; *l = 0; a += 7; } else { // skip everythng up to the next & while (*a != '&' && a != end) { a++; } // set the track back to the & so we can proceed normally a--; } break; } case '/': { break; } default: { return; } } a++; } if (tox_thread_init != UTOX_TOX_THREAD_INIT_SUCCESS) { // if we receive a URL event before the profile is loaded, save it for later. // this usually happens when we are launched as the result of a URL click. g_select_add_friend_later = 1; } else { flist_selectaddfriend(); } } uTox-0.17.1/src/commands.h000066400000000000000000000012231354126257400153070ustar00rootroot00000000000000#ifndef COMMANDS_H #define COMMANDS_H #include #include #define MAX_NUM_CMDS 256 struct Command { char *cmd; int cmd_length; bool (*func)(void *object, char *arg, int arg_length); }; /** utox_run_command() * * takes data string and parses it for a command, if that command is supported, acts on that command, else it simply * results the processed command and argv. * * Returns the remaining string length. */ uint16_t utox_run_command(char *string, uint16_t string_length, char **cmd, char **argument, int trusted); extern bool g_select_add_friend_later; void do_tox_url(uint8_t *url_string, int len); #endif uTox-0.17.1/src/debug.h000066400000000000000000000036741354126257400146100ustar00rootroot00000000000000#ifndef DEBUG_H #define DEBUG_H #include #define EXIT_MALLOC 2 /* Malloc failure exit status. */ /* uTox debug levels */ typedef enum { LOG_LVL_OFF, LOG_LVL_FATAL, LOG_LVL_ERROR, // This is really bad LOG_LVL_WARNING, // This is kinda bad LOG_LVL_NOTICE, // This is just something we should know about LOG_LVL_INFO, // This is what's happening LOG_LVL_DEBUG, // Something is broken, whats' happening everywhere LOG_LVL_TRACE, // I'm not kidding anymore... WHAT IS BROKEN? LOG_LVL_NET_TRACE, // OH, it's Toxcore that's broken? Whew! } LOG_LVL; // returns current logging verbosity int utox_verbosity(); // define debugging macros in a platform specific way #ifdef __ANDROID__ #include "android/logging.h" #else void debug(const char *fmt, ...); #endif #define VERB(x) (utox_verbosity() >= LOG_LVL_##x) #define LOG_FATAL_ERR(ex, file, str, ...) debug("\n\n%-14s:" str "\n\n", file ": ", ## __VA_ARGS__ ); exit(ex) #define LOG_ERR(file, str, ...) (VERB(ERROR) ? debug("%-14s" str "\n", file ": ", ## __VA_ARGS__ ) : ((void)(0))) #define LOG_WARN(file, str, ...) (VERB(WARNING) ? debug("%-14s" str "\n", file ": ", ## __VA_ARGS__ ) : ((void)(0))) #define LOG_NOTE(file, str, ...) (VERB(NOTICE) ? debug("%-14s" str "\n", file ": ", ## __VA_ARGS__ ) : ((void)(0))) #define LOG_INFO(file, str, ...) (VERB(INFO) ? debug("%-14s" str "\n", file ": ", ## __VA_ARGS__ ) : ((void)(0))) #define LOG_DEBUG(file, str, ...) (VERB(DEBUG) ? debug("%-14s" str "\n", file ": ", ## __VA_ARGS__ ) : ((void)(0))) #define LOG_TRACE(file, str, ...) (VERB(TRACE) ? debug("%-14s" str "\n", file ": ", ## __VA_ARGS__ ) : ((void)(0))) #define LOG_NET_TRACE(file, str, ...) (VERB(NET_TRACE) ? debug("%-14s" str "\n", file ": ", ## __VA_ARGS__ ) : ((void)(0))) // User requested #define LOG_NORM(...) (VERB(OFF) ? debug(__VA_ARGS__ ) : ((void)(0))) #endif // DEBUG_H uTox-0.17.1/src/devices.c000066400000000000000000000140551354126257400151320ustar00rootroot00000000000000#include "devices.h" #include "debug.h" #ifdef ENABLE_MULTIDEVICE static bool realloc_devices_list(uint16_t new_size) { if (new_size == 0) { if (devices) { free(devices); devices = NULL; } return 0; } if (new_size == self.device_list_size) { return 1; } UTOX_DEVICE *tmp = realloc(devices, sizeof(UTOX_DEVICE) * new_size); if (!tmp) { LOG_ERR("Devices", "couldn't realloc for new_size %u" , new_size); return 0; } devices = tmp; self.device_list_size = new_size; return 1; } void utox_devices_init(void) { if (devices) { LOG_FATAL_ERR(EXIT_FAILURE, "Devices", "Unable to init base devices, *devices exists"); } devices = calloc(self.device_list_count, sizeof(UTOX_DEVICE)); self.device_list_size = self.device_list_count; if (!devices) { LOG_FATAL_ERR(EXIT_MALLOC, "Devices", "Unable to init base devices, *devices is null"); } }; void utox_devices_decon(void) { if (devices) { free(devices); devices = NULL; } } void utox_device_init(Tox *tox, uint16_t dev_num) { if (dev_num >= self.device_list_size) { if (!realloc_devices_list(dev_num + 1)) { LOG_ERR("Devices", "ERROR, unable to realloc for a new device"); return; } } if (!devices) { LOG_ERR("Devices", "devices is null"); return; } TOX_ERR_DEVICE_GET error = 0; tox_self_get_device(tox, dev_num, devices[dev_num].name, &devices[dev_num].status, devices[dev_num].pubkey, &error); if (error) { LOG_ERR("Devices", "Error getting device info dev_num %u error %u" , dev_num, error); } cid_to_string(devices[dev_num].pubkey_hex, devices[dev_num].pubkey); } static void devices_self_add_submit(uint8_t *name, size_t length, uint8_t id[TOX_ADDRESS_SIZE]) { if (length >= UINT16_MAX) { /* Max size of postmsg */ LOG_ERR("Devices", "Name length > UINT16_MAX"); /* TODO send error to GUI */ return; } uint8_t *data = malloc(length * sizeof(uint8_t) + sizeof(id[0]) * TOX_ADDRESS_SIZE); if (!data) { LOG_ERR("Devices", "Could not alloc space (%uB) for new device (%.s)", length * sizeof(uint8_t) + sizeof(id[0]) * TOX_ADDRESS_SIZE, length, name); return; } memcpy(data, id, TOX_ADDRESS_SIZE); memcpy(data + TOX_ADDRESS_SIZE, name, length * sizeof(uint8_t)); postmessage_toxcore(TOX_SELF_NEW_DEVICE, length, 0, data); } static void delete_this_device(void) { LOG_ERR("Devices", "Delete button pressed"); } void devices_update_list(void) {} void devices_update_ui(void) { if (!devices) { panel_settings_devices.child = calloc(3, sizeof(void *)); if (!panel_settings_devices.child) { LOG_FATAL_ERR(EXIT_MALLOC, "Devices", "Could not alloc memory"); } panel_settings_devices.child[0] = (void *)&button_add_new_device_to_self; panel_settings_devices.child[1] = (void *)&edit_add_new_device_to_self; panel_settings_devices.child[2] = NULL; return; } if (!panel_settings_devices.child) { panel_settings_devices.child = calloc(3 + self.device_list_count * 2, sizeof(void *)); if (!panel_settings_devices.child) { LOG_FATAL_ERR(EXIT_MALLOC, "Devices", "Could not alloc memory"); } panel_settings_devices.child[0] = (void *)&button_add_new_device_to_self; panel_settings_devices.child[1] = (void *)&edit_add_new_device_to_self; } else { panel_settings_devices.child = realloc(panel_settings_devices.child, (3 + self.device_list_count * 2) * sizeof(void *)); if (!panel_settings_devices.child) { LOG_FATAL_ERR(EXIT_MALLOC, "Devices", "Could not alloc memory"); } } uint16_t i; for (i = 0; i < self.device_list_count; ++i) { EDIT * edit = calloc(1, sizeof(EDIT)); BUTTON *dele = calloc(1, sizeof(BUTTON)); if (!edit || !dele) { LOG_FATAL_ERR(EXIT_MALLOC, "Devices", "Can't malloc for an extra device"); } PANEL p_edit = { .type = PANEL_EDIT, .x = SCALE(10), .y = SCALE(95) + (i * SCALE(27)), .width = SCALE(-25) - BM_SBUTTON_WIDTH, .height = SCALE(24), }, b_delete = { .type = PANEL_BUTTON, .x = SCALE(-10) - BM_SBUTTON_WIDTH, .y = SCALE(95) + (i * SCALE(29)), .width = BM_SBUTTON_WIDTH, .height = BM_SBUTTON_HEIGHT, }; edit->panel = p_edit; edit->length = TOX_PUBLIC_KEY_SIZE * 2, edit->data_size = TOX_PUBLIC_KEY_SIZE * 2, edit->data = devices[i].pubkey_hex, edit->readonly = 1, edit->noborder = 0, edit->select_completely = 1, dele->panel = b_delete; dele->bm_fill = BM_SBUTTON; dele->update = button_setcolors_success, dele->on_mup = delete_this_device, dele->button_text.i18nal = STR_DELETE; panel_settings_devices.child[(i * 2) + 2] = (void *)edit; panel_settings_devices.child[(i * 2) + 3] = (void *)dele; } panel_settings_devices.child[(i * 2) + 2] = NULL; } void devices_self_add(uint8_t *device, size_t length) { uint8_t name_cleaned[length]; uint16_t length_cleaned = 0; unsigned int i; for (i = 0; i < length; ++i) { if (device[i] != ' ') { name_cleaned[length_cleaned] = device[i]; ++length_cleaned; } } if (!length_cleaned) { addfriend_status = ADDF_NONAME; return; } uint8_t id[TOX_ADDRESS_SIZE]; if (length_cleaned == TOX_ADDRESS_SIZE * 2 && string_to_id(id, name_cleaned)) { /* TODO, names! */ devices_self_add_submit((uint8_t *)"Default device name", 19, id); } else { LOG_ERR("Devices", "error trying to add this device"); } } #endif uTox-0.17.1/src/devices.h000066400000000000000000000012521354126257400151320ustar00rootroot00000000000000/* Devices.h * * Functions to add and remove devices from our Tox device group */ #ifndef DEVICES_H #define DEVICES_H #include #include typedef struct UTOX_DEVICE { uint8_t pubkey[TOX_PUBLIC_KEY_SIZE]; uint8_t pubkey_hex[TOX_PUBLIC_KEY_SIZE * 2]; uint8_t name[TOX_MAX_NAME_LENGTH]; size_t name_length; //TOX_DEVICE_STATUS status; uint8_t status; } UTOX_DEVICE; UTOX_DEVICE *devices; void utox_devices_init(void); void utox_devices_decon(void); void utox_device_init(Tox *tox, uint16_t dev_num); void devices_update_list(void); void devices_update_ui(void); void devices_self_add(uint8_t *device, size_t length); #endif uTox-0.17.1/src/file_transfers.c000066400000000000000000001426241354126257400165220ustar00rootroot00000000000000#include "file_transfers.h" #include "avatar.h" #include "friend.h" #include "debug.h" #include "macros.h" #include "self.h" #include "settings.h" #include "text.h" #include "tox.h" #include "utox.h" #include "native/filesys.h" #include "native/image.h" #include "native/thread.h" #include "native/time.h" #include #include #include #define MAX_INCOMING_COUNT 32 #define MAX_INLINE_FILESIZE (1024 * 1024 * 4) static void fid_to_string(char *dest, uint8_t *src) { to_hex(dest, src, TOX_FILE_ID_LENGTH); } // Accepts a file number and returns indicating whether it's an incoming one or not. static bool is_incoming_ft(uint32_t file_number) { // This is Toxcore magic. return file_number >= (1 << 16); } // Accepts a Toxcore incoming file number and returns a normal one. static uint32_t detox_incoming_file_number(uint32_t file_number) { return (file_number >> 16) - 1; } static FILE_TRANSFER *get_file_transfer(uint32_t friend_number, uint32_t file_number) { FRIEND *f = get_friend(friend_number); if (!f) { return NULL; } if (is_incoming_ft(file_number)) { file_number = detox_incoming_file_number(file_number); if (f->ft_incoming_size && f->ft_incoming_size >= file_number) { return &f->ft_incoming[file_number]; } } else if (f->ft_outgoing_size && f->ft_outgoing_size >= file_number) { return &f->ft_outgoing[file_number]; } return NULL; } static FILE_TRANSFER *make_file_transfer(uint32_t friend_number, uint32_t file_number) { FRIEND *f = get_friend(friend_number); if (!f) { return NULL; } if (is_incoming_ft(file_number)) { file_number = detox_incoming_file_number(file_number); if (f->ft_incoming_size <= file_number) { LOG_TRACE("FileTransfer", "Realloc incoming %u|%u" , friend_number, file_number + 1); FILE_TRANSFER *new_ftlist = realloc(f->ft_incoming, sizeof(FILE_TRANSFER) * (file_number + 1)); if (!new_ftlist) { LOG_ERR("FileTransfer", "Unable to allocate memory for new incoming file transfer."); return NULL; } f->ft_incoming = new_ftlist; f->ft_incoming_size = file_number + 1; } return &f->ft_incoming[file_number]; } if (f->ft_outgoing_size <= file_number) { LOG_TRACE("FileTransfer", "Realloc outgoing %u|%u" , friend_number, file_number + 1); FILE_TRANSFER *new_ftlist = realloc(f->ft_outgoing, sizeof(FILE_TRANSFER) * (file_number + 1)); if (!new_ftlist) { LOG_ERR("FileTransfer", "Unable to allocate memory for new outgoing file transfer."); return NULL; } f->ft_outgoing = new_ftlist; f->ft_outgoing_size = file_number + 1; } return &f->ft_outgoing[file_number]; } /* Calculate the transfer speed for the UI. */ static void calculate_speed(FILE_TRANSFER *file) { if (file->speed > file->num_packets * 20 * 1371) { ++file->num_packets; return; } file->num_packets = 0; uint64_t time = get_time(); if (!file->last_check_time) { file->last_check_time = time; return; } // TODO replace magic number with something real. (grayhatter> I think it's cpu clock ticks) if (time - file->last_check_time >= 1000 * 1000 * 100) { file->speed = (((double)(file->current_size - file->last_check_transferred) * 1000.0 * 1000.0 * 1000.0) / (double)(time - file->last_check_time)) + 0.5; file->last_check_time = time; file->last_check_transferred = file->current_size; } FILE_TRANSFER *msg = calloc(1, sizeof(FILE_TRANSFER)); if (!msg) { LOG_ERR("FileTransfer", "Unable to malloc for internal message. (This is bad!)"); return; } *msg = *file; postmessage_utox(FILE_STATUS_UPDATE, file->status, 0, msg); } static void ft_decon(uint32_t friend_number, uint32_t file_number) { LOG_INFO("FileTransfer", "Cleaning up file transfers! (%u & %u)" , friend_number, file_number); FILE_TRANSFER *ft = get_file_transfer(friend_number, file_number); if (!ft) { LOG_ERR("FileTransfer", "Can't decon a FT that doesn't exist!"); return; } if (ft->in_use) { while (ft->decon_wait) { yieldcpu(10); } if (ft->incoming) { get_friend(friend_number)->ft_incoming_active_count--; } else { get_friend(friend_number)->ft_outgoing_active_count--; } if (ft->name) { free(ft->name); } if (ft->in_memory) { // free(ft->via.memory)? } else if (ft->avatar) { // free(ft->via.avatar)? } else if (ft->via.file) { fclose(ft->via.file); } } /* When decon is called we always want to reset the struct. */ memset(ft, 0, sizeof(FILE_TRANSFER)); } static bool resumeable_name(FILE_TRANSFER *ft, char *name) { if (ft->incoming) { char hex[TOX_HASH_LENGTH * 2]; fid_to_string(hex, ft->data_hash); snprintf(name, UTOX_FILE_NAME_LENGTH, "%.*s.ftinfo", TOX_HASH_LENGTH * 2, hex); uint8_t blank_id[TOX_HASH_LENGTH] = { 0 }; if (memcmp(ft->data_hash, blank_id, TOX_HASH_LENGTH) == 0) { LOG_ERR("FileTransfer", "Unable to use current data hash for incoming file.\n" "\t\tuTox can't resume file %.*s\n" "\t\tHash is %.*s\n", (uint32_t)ft->name_length, ft->name, TOX_HASH_LENGTH * 2, name); return false; } } else { snprintf(name, UTOX_FILE_NAME_LENGTH, "%.*s%02i.ftoutfo", TOX_PUBLIC_KEY_SIZE * 2, get_friend(ft->friend_number)->id_str, ft->file_number % 100); } return true; } static bool ft_update_resumable(FILE_TRANSFER *ft) { if (!ft->resume_file) { LOG_ERR("FileTransfer", "Unable to save filetransfer info. Got NULL file pointer."); return false; } // This file pointer has a tendency of being both invalid and non-null so we use fstat to check it. struct stat buffer; if (fstat(fileno(ft->resume_file), &buffer) != 0) { LOG_ERR("FileTransfer", "Unable to save file info. Invalid filepointer."); return false; } fseeko(ft->resume_file, SEEK_SET, 0); if (fwrite(ft, sizeof(FILE_TRANSFER), 1, ft->resume_file) != 1) { LOG_ERR("FileTransfer", "Unable to save file info... uTox can't resume file %.*s", ft->name_length, ft->name); return false; } fflush(ft->resume_file); return true; } /* Create the file transfer resume info file. */ static bool ft_init_resumable(FILE_TRANSFER *ft) { char name[UTOX_FILE_NAME_LENGTH]; if (!resumeable_name(ft, name)) { return false; } ft->resume_file = utox_get_file(name, NULL, UTOX_FILE_OPTS_WRITE | UTOX_FILE_OPTS_MKDIR); if (!ft->resume_file) { return false; } LOG_INFO("FileTransfer", ".ftinfo for file %.*s set; ready to resume!" , (uint32_t)ft->name_length, ft->name); return ft_update_resumable(ft); } /* Free/Remove/Unlink the file transfer resume info file. */ static void ft_decon_resumable(FILE_TRANSFER *ft) { char name[UTOX_FILE_NAME_LENGTH]; if (!resumeable_name(ft, name)) { return; } LOG_INFO("FileTransfer", "Going to decon file %s." , name); FILE *file = utox_get_file(name, NULL, UTOX_FILE_OPTS_READ | UTOX_FILE_OPTS_WRITE); if (!file) { return; } fclose(file); utox_get_file(name, NULL, UTOX_FILE_OPTS_DELETE); } static bool ft_find_resumeable(FILE_TRANSFER *ft) { char resume_name[UTOX_FILE_NAME_LENGTH]; if (!resumeable_name(ft, resume_name)) { return false; } size_t size = 0; FILE *resume_disk = utox_get_file(resume_name, &size, UTOX_FILE_OPTS_READ); if (!resume_disk) { if (ft->incoming) { LOG_INFO("FileTransfer", "Unable to load saved info... uTox can't resume file %.*s", (uint32_t)ft->name_length, ft->name); } ft->status = 0; return false; } if (size != sizeof(FILE_TRANSFER)) { LOG_ERR("FileTransfer", "Unable to resume this file, size mismatch"); fclose(resume_disk); return false; } FILE_TRANSFER resume_file; bool read_resumeable = fread(&resume_file, size, 1, resume_disk); fclose(resume_disk); if (!read_resumeable) { LOG_ERR("FileTransfer", "Failed to read resumeable file."); return false; } if (!resume_file.resumeable || !resume_file.in_use || resume_file.in_memory || resume_file.avatar || resume_file.inline_img) { return false; } memcpy(ft, &resume_file, sizeof(FILE_TRANSFER)); ft->name_length = 0; uint8_t *p = ft->path + strlen((char *)ft->path); while (*--p != '/' && *p != '\\') { ++ft->name_length; } ++p; ++ft->name_length; ft->name = calloc(1, ft->name_length + 1); if (!ft->name) { LOG_FATAL_ERR(EXIT_MALLOC, "FileTransfer", "Could not alloc for file name (%uB)", ft->name_length + 1); } snprintf((char *)ft->name, ft->name_length + 1, "%s", p); ft->via.file = NULL; ft->resume_file = NULL; ft->ui_data = NULL; return true; } /* Cancel active file. */ static void kill_file(FILE_TRANSFER *file) { switch (file->status) { case FILE_TRANSFER_STATUS_KILLED: { LOG_WARN("FileTransfer", "File already killed."); return; } case FILE_TRANSFER_STATUS_COMPLETED: { LOG_WARN("FileTransfer", "File already completed."); return; } default: { break; } } file->status = FILE_TRANSFER_STATUS_KILLED; postmessage_utox(FILE_STATUS_DONE, file->status, 0, file->ui_data); if (file->resumeable) { ft_decon_resumable(file); } ft_decon(file->friend_number, file->file_number); } /* Break active file, (when a friend goes offline). */ static void break_file(FILE_TRANSFER *file) { if (!file) { return; } switch (file->status) { case FILE_TRANSFER_STATUS_NONE: { return kill_file(file); } case FILE_TRANSFER_STATUS_COMPLETED: case FILE_TRANSFER_STATUS_KILLED: { // We don't break files that are already broken. return; } default: { break; } } file->status = FILE_TRANSFER_STATUS_BROKEN; postmessage_utox(FILE_STATUS_DONE, file->status, 0, file->ui_data); if (file->resumeable) { ft_update_resumable(file); } ft_decon(file->friend_number, file->file_number); } /* Pause active file. */ static void utox_pause_file(FILE_TRANSFER *file, bool us) { switch (file->status) { case FILE_TRANSFER_STATUS_NONE: { if (!file->incoming) { // New transfers start as paused them file->status = FILE_TRANSFER_STATUS_PAUSED_THEM; } else { LOG_TRACE("FileTransfer", "We can't pause an unaccepted file!"); } break; } case FILE_TRANSFER_STATUS_ACTIVE: { if (us) { LOG_TRACE("FileTransfer", "File now paused by us."); file->status = FILE_TRANSFER_STATUS_PAUSED_US; } else { LOG_TRACE("FileTransfer", "File now paused by them."); file->status = FILE_TRANSFER_STATUS_PAUSED_THEM; } break; } case FILE_TRANSFER_STATUS_PAUSED_US: case FILE_TRANSFER_STATUS_PAUSED_BOTH: case FILE_TRANSFER_STATUS_PAUSED_THEM: { if (us) { if (file->status == FILE_TRANSFER_STATUS_PAUSED_US) { LOG_TRACE("FileTransfer", "File already paused by us!"); } else if (file->status == FILE_TRANSFER_STATUS_PAUSED_THEM) { file->status = FILE_TRANSFER_STATUS_PAUSED_BOTH; LOG_TRACE("FileTransfer", "File now paused by both!"); } else if (file->status == FILE_TRANSFER_STATUS_PAUSED_BOTH) { LOG_TRACE("FileTransfer", "File already paused by both!"); } else { file->status = FILE_TRANSFER_STATUS_PAUSED_US; } } else { if (file->status == FILE_TRANSFER_STATUS_PAUSED_US) { file->status = FILE_TRANSFER_STATUS_PAUSED_BOTH; LOG_TRACE("FileTransfer", "File now paused by both!"); } else if (file->status == FILE_TRANSFER_STATUS_PAUSED_THEM) { LOG_TRACE("FileTransfer", "File was already paused by them!"); } else if (file->status == FILE_TRANSFER_STATUS_PAUSED_BOTH) { LOG_TRACE("FileTransfer", "File already paused by both!"); } else { file->status = FILE_TRANSFER_STATUS_PAUSED_THEM; } } break; } case FILE_TRANSFER_STATUS_BROKEN: { LOG_TRACE("FileTransfer", "Can't pause a broken file;"); break; } case FILE_TRANSFER_STATUS_COMPLETED: { LOG_TRACE("FileTransfer", "Can't pause a completed file;"); break; } case FILE_TRANSFER_STATUS_KILLED: { LOG_TRACE("FileTransfer", "Can't pause a killed file;"); break; } } FILE_TRANSFER *msg = calloc(1, sizeof(FILE_TRANSFER)); if (!msg) { LOG_ERR("FileTransfer", "Unable to malloc for internal message. (This is bad!)"); return; } *msg = *file; postmessage_utox(FILE_STATUS_UPDATE, file->status, 0, msg); // TODO free not freed data. } /* Start/Resume active file. */ static void run_file_local(FILE_TRANSFER *file) { switch (file->status) { case FILE_TRANSFER_STATUS_NONE: { file->status = FILE_TRANSFER_STATUS_ACTIVE; if (!file->resumeable && file->incoming) { file->resumeable = ft_init_resumable(file); } break; } case FILE_TRANSFER_STATUS_PAUSED_US: { file->status = FILE_TRANSFER_STATUS_ACTIVE; break; } case FILE_TRANSFER_STATUS_PAUSED_BOTH: { file->status = FILE_TRANSFER_STATUS_PAUSED_THEM; break; } case FILE_TRANSFER_STATUS_ACTIVE: case FILE_TRANSFER_STATUS_PAUSED_THEM: { return; } case FILE_TRANSFER_STATUS_BROKEN: case FILE_TRANSFER_STATUS_COMPLETED: case FILE_TRANSFER_STATUS_KILLED: { LOG_ERR("FileTransfer", "We tried to run file from an unknown state! (%u)" , file->status); return; } } FILE_TRANSFER *msg = calloc(1, sizeof(FILE_TRANSFER)); if (!msg) { LOG_ERR("FileTransfer", "Unable to malloc for internal message. (This is bad!)"); return; } *msg = *file; postmessage_utox(FILE_STATUS_UPDATE, file->status, 0, msg); } static void run_file_remote(FILE_TRANSFER *file) { switch (file->status) { case FILE_TRANSFER_STATUS_PAUSED_US: { break; } case FILE_TRANSFER_STATUS_PAUSED_BOTH: { file->status = FILE_TRANSFER_STATUS_PAUSED_US; break; } case FILE_TRANSFER_STATUS_PAUSED_THEM: case FILE_TRANSFER_STATUS_BROKEN: { file->status = FILE_TRANSFER_STATUS_ACTIVE; break; } default: { LOG_ERR("FileTransfer", "They tried to run file from an unknown state! (%u)" , file->status); break; } } FILE_TRANSFER *msg = calloc(1, sizeof(FILE_TRANSFER)); if (!msg) { LOG_ERR("FileTransfer", "Unable to malloc for internal message. (This is bad!)"); return; } *msg = *file; postmessage_utox(FILE_STATUS_UPDATE, file->status, 0, msg); } static void decode_inline_png(uint32_t friend_id, uint8_t *data, uint64_t size) { // TODO: start a new thread and decode the png in it. uint16_t width, height; // TODO: move the decode out of file_transfers.c NATIVE_IMAGE *native_image = utox_image_to_native((UTOX_IMAGE)data, size, &width, &height, 0); if (NATIVE_IMAGE_IS_VALID(native_image)) { uint8_t *msg = malloc(sizeof(uint16_t) * 2 + sizeof(NATIVE_IMAGE *)); if (!msg) { LOG_ERR("decode_inline_png", "Unable to malloc for inline data."); free(native_image); return; } memcpy(msg, &width, sizeof(uint16_t)); memcpy(msg + sizeof(uint16_t), &height, sizeof(uint16_t)); memcpy(msg + sizeof(uint16_t) * 2, &native_image, sizeof(NATIVE_IMAGE *)); postmessage_utox(FILE_INCOMING_NEW_INLINE, friend_id, 0, msg); } } /* Complete active file, (when the whole file transfer is successful). */ static void utox_complete_file(FILE_TRANSFER *file) { FILE_TRANSFER *msg = calloc(1, sizeof(FILE_TRANSFER)); if (!msg) { LOG_ERR("FileTransfer", "Unable to malloc for internal message. (This is bad!)"); return; } *msg = *file; postmessage_utox(FILE_STATUS_UPDATE, file->status, 0, msg); if (file->status == FILE_TRANSFER_STATUS_ACTIVE) { file->status = FILE_TRANSFER_STATUS_COMPLETED; if (file->incoming) { if (file->inline_img) { decode_inline_png(file->friend_number, file->via.memory, file->current_size); postmessage_utox(FILE_INCOMING_NEW_INLINE_DONE, file->friend_number, 0, file); } else if (file->avatar) { postmessage_utox(FRIEND_AVATAR_SET, file->friend_number, file->current_size, file->via.avatar); } } file->decon_wait = true; postmessage_utox(FILE_STATUS_UPDATE_DATA, file->status, 0, file); } else { LOG_ERR("FileTransfer", "Unable to complete file in non-active state (file:%u)" , file->file_number); } LOG_NOTE("FileTransfer", "File transfer is done (%u & %u)" , file->friend_number, file->file_number); postmessage_utox(FILE_STATUS_DONE, file->status, 0, file->ui_data); if (file->resumeable) { ft_decon_resumable(file); } ft_decon(file->friend_number, file->file_number); } /* Friend has come online, restart our outgoing transfers to this friend. */ void ft_friend_online(Tox *tox, uint32_t friend_number) { for (uint16_t i = 0; i < MAX_FILE_TRANSFERS; i++) { FILE_TRANSFER *file = calloc(1, sizeof(FILE_TRANSFER)); if (!file) { LOG_FATAL_ERR(EXIT_MALLOC, "FileTransfer", "Could not alloc file transfer struct"); } file->friend_number = friend_number; file->file_number = i; file->incoming = false; ft_find_resumeable(file); if (file->path[0]) { /* If we got a path from utox_file_load we should try to resume! */ file->via.file = fopen((char *)file->path, "rb+"); ft_send_file(tox, friend_number, file->via.file, file->path, strlen((char *)file->path), file->data_hash); } char name[UTOX_FILE_NAME_LENGTH]; if (resumeable_name(file, name)) { LOG_INFO("FileTransfer", "Loading outgoing %u, deleting origin file.", i); utox_get_file(name, NULL, UTOX_FILE_OPTS_DELETE); } free(file); } } /* Friend has gone offline, break our outgoing transfers to this friend. */ void ft_friend_offline(Tox *UNUSED(tox), uint32_t friend_number) { LOG_NOTE("FileTransfer", "Friend %u has gone offline, breaking transfers" , friend_number); FRIEND *f = get_friend(friend_number); if (!f) { return; } for (uint16_t i = 0; i < f->ft_outgoing_size; ++i) { break_file(&f->ft_outgoing[i]); } for (uint16_t i = 0; i < f->ft_incoming_size; ++i) { break_file(&f->ft_incoming[i]); } } /* Local command callback to change a file status. */ void ft_local_control(Tox *tox, uint32_t friend_number, uint32_t file_number, TOX_FILE_CONTROL control) { FILE_TRANSFER *info = get_file_transfer(friend_number, file_number); if (!info) { LOG_ERR("FileTransfer", "We know nothing of this file. This is probably an error. Friend(%u) FileNum(%u)", friend_number, file_number); return; } TOX_ERR_FILE_CONTROL error = 0; switch (control) { case TOX_FILE_CONTROL_RESUME: { if (info->status != FILE_TRANSFER_STATUS_ACTIVE) { if (get_friend(friend_number)->ft_outgoing_size < MAX_FILE_TRANSFERS) { if (tox_file_control(tox, friend_number, file_number, control, &error)) { LOG_INFO("FileTransfer", "We just resumed file (%u & %u)" , friend_number, file_number); } else { LOG_INFO("FileTransfer", "Toxcore doesn't like us! (%u & %u)" , friend_number, file_number); } } else { LOG_INFO("FileTransfer", "Can't start file, max file transfer limit reached! (%u & %u)", friend_number, file_number); } } else { LOG_INFO("FileTransfer", "File already active (%u & %u)" , friend_number, file_number); } run_file_local(info); break; } case TOX_FILE_CONTROL_PAUSE: { if (info->status != FILE_TRANSFER_STATUS_PAUSED_US && info->status != FILE_TRANSFER_STATUS_PAUSED_BOTH) { if (tox_file_control(tox, friend_number, file_number, control, &error)) { LOG_INFO("FileTransfer", "We just paused file (%u & %u)" , friend_number, file_number); } else { LOG_INFO("FileTransfer", "Toxcore doesn't like us! (%u & %u)" , friend_number, file_number); } } else { LOG_INFO("FileTransfer", "File already paused (%u & %u)" , friend_number, file_number); } utox_pause_file(info, true); break; } case TOX_FILE_CONTROL_CANCEL: { if (info->status != FILE_TRANSFER_STATUS_KILLED) { if (tox_file_control(tox, friend_number, file_number, control, &error)) { LOG_INFO("FileTransfer", "We just killed file (%u & %u)" , friend_number, file_number); } else { LOG_INFO("FileTransfer", "Toxcore doesn't like us! (%u & %u)" , friend_number, file_number); } } else { LOG_INFO("FileTransfer", "File already killed (%u & %u)" , friend_number, file_number); } kill_file(info); break; } } /* Do something with the error! */ switch (error) { case TOX_ERR_FILE_CONTROL_OK: { // Everything's fine. break; } case TOX_ERR_FILE_CONTROL_FRIEND_NOT_FOUND: { LOG_ERR("FileTransfer", "Unable to send command, Friend (%u) doesn't exist!" , info->friend_number); break; } case TOX_ERR_FILE_CONTROL_FRIEND_NOT_CONNECTED: { LOG_ERR("FileTransfer", "Unable to send command, Friend (%u) offline!" , info->friend_number); break; } case TOX_ERR_FILE_CONTROL_NOT_FOUND: { LOG_ERR("FileTransfer", "Unable to send command, ft (%u) doesn't exist!" , info->friend_number); break; } case TOX_ERR_FILE_CONTROL_DENIED: { LOG_ERR("FileTransfer", "Unable to send command, ft (%u) paused by other party." , info->friend_number); break; } default: { LOG_ERR("FileTransfer", "FileTransfer:\tThere was an error(%u) sending the command." "You probably want to see to that!\n", error); break; } } } /* Remote command callback for friends to change a file status */ static void file_transfer_callback_control(Tox *UNUSED(tox), uint32_t friend_number, uint32_t file_number, TOX_FILE_CONTROL control, void *UNUSED(userdata)) { FILE_TRANSFER *ft = get_file_transfer(friend_number, file_number); if (!ft || !ft->in_use) { return; } switch (control) { case TOX_FILE_CONTROL_RESUME: { LOG_TRACE("FileTransfer", "Friend (%i) has resumed file (%i)" , friend_number, file_number); run_file_remote(ft); break; } case TOX_FILE_CONTROL_PAUSE: { LOG_TRACE("FileTransfer", "Friend (%i) has paused file (%i)" , friend_number, file_number); utox_pause_file(ft, false); break; } case TOX_FILE_CONTROL_CANCEL: { if (ft->avatar) { LOG_TRACE("FileTransfer", "Friend (%i) rejected avatar" , friend_number); } else { LOG_TRACE("FileTransfer", "Friend (%i) has canceled file (%i)" , friend_number, file_number); } kill_file(ft); break; } } } static void incoming_avatar(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t size) { LOG_TRACE("FileTransfer", "Incoming avatar from friend %u." , friend_number); FRIEND *f = get_friend(friend_number); if (!f) { LOG_ERR("FileTransfer", "This friend doesn't exist... This is bad!"); return; } if (size == 0) { LOG_TRACE("FileTransfer", "Avatar from friend %u deleted." , friend_number); postmessage_utox(FRIEND_AVATAR_UNSET, friend_number, 0, NULL); ft_local_control(tox, friend_number, file_number, TOX_FILE_CONTROL_CANCEL); return; } else if (size > UTOX_AVATAR_MAX_DATA_LENGTH) { LOG_TRACE("FileTransfer", "Avatar from friend(%u) rejected. (Too Large %lu)" , friend_number, size); ft_local_control(tox, friend_number, file_number, TOX_FILE_CONTROL_CANCEL); return; } uint8_t file_id[TOX_FILE_ID_LENGTH] = { 0 }; tox_file_get_file_id(tox, friend_number, file_number, file_id, 0); /* Verify this is a new avatar */ if (f->avatar->format && memcmp(f->avatar->hash, file_id, TOX_HASH_LENGTH) == 0) { LOG_TRACE("FileTransfer", "Avatar from friend (%u) rejected: Same as Current" , friend_number); ft_local_control(tox, friend_number, file_number, TOX_FILE_CONTROL_CANCEL); return; } FILE_TRANSFER *ft = make_file_transfer(friend_number, file_number); if (!ft) { LOG_ERR("FileTransfer", "Unable to malloc ft to accept incoming avatar!"); tox_file_control(tox, friend_number, file_number, TOX_FILE_CONTROL_CANCEL, NULL); return; } f->ft_incoming_active_count++; memset(ft, 0, sizeof(FILE_TRANSFER)); ft->in_use = true; ft->friend_number = friend_number; ft->file_number = file_number; ft->target_size = size; tox_file_get_file_id(tox, friend_number, file_number, ft->data_hash, NULL); ft->incoming = true; ft->avatar = true; ft->via.avatar = calloc(1, size); if (!ft->via.avatar) { LOG_ERR("FileTransfer", "Unable to malloc for incoming avatar"); ft_local_control(tox, friend_number, file_number, TOX_FILE_CONTROL_CANCEL); return; } ft->status = FILE_TRANSFER_STATUS_PAUSED_US; ft_local_control(tox, friend_number, file_number, TOX_FILE_CONTROL_RESUME); } static void incoming_inline_image(Tox *tox, uint32_t friend_number, uint32_t file_number, size_t size) { LOG_INFO("FileTransfer", "Getting an incoming inline image"); FRIEND *f = get_friend(friend_number); if (!f) { LOG_ERR("FileTransfer", "This friend doesn't exist... This is bad!"); return; } FILE_TRANSFER *ft = make_file_transfer(friend_number, file_number); if (!ft) { LOG_ERR("FileTransfer", "Unable to malloc ft to accept incoming inline image!"); tox_file_control(tox, friend_number, file_number, TOX_FILE_CONTROL_CANCEL, NULL); return; } f->ft_incoming_active_count++; memset(ft, 0, sizeof(FILE_TRANSFER)); ft->in_use = true; ft->incoming = true; ft->in_memory = true; ft->inline_img = true; ft->friend_number = friend_number; ft->file_number = file_number; ft->target_size = size; ft->via.memory = calloc(1, size); if (!ft->via.memory) { LOG_ERR("FileTransfer", "Unable to malloc enough memory for incoming inline image of size %lu" , size); ft_local_control(tox, friend_number, file_number, TOX_FILE_CONTROL_CANCEL); return; } LOG_NOTE("FileTransfer", "Starting incoming inline image of size %lu" , size); ft_local_control(tox, friend_number, file_number, TOX_FILE_CONTROL_RESUME); ft->name = (uint8_t *)strdup("utox-inline.png"); ft->name_length = strlen("utox-inline.png"); if (!ft->name) { LOG_ERR("FileTransfer", "Error, couldn't allocate memory for ft->name."); ft->name_length = 0; } } /* Function called by core with a new file send request from a friend. */ static void incoming_file_callback_request(Tox *tox, uint32_t friend_number, uint32_t file_number, uint32_t kind, uint64_t size, const uint8_t *name, size_t name_length, void *UNUSED(user_data)) { LOG_NOTE("FileTransfer", "New incoming file transfer request from friend %u" , friend_number); FRIEND *f = get_friend(friend_number); if (f->ft_incoming_active_count >= MAX_INCOMING_COUNT) { LOG_ERR("FileTransfer", "Too many incoming file transfers from friend %u", friend_number); /* ft_local_control is preferred, but in this case it can't access the ft struct. */ tox_file_control(tox, friend_number, file_number, TOX_FILE_CANCEL, NULL); return; } if (kind == TOX_FILE_KIND_AVATAR) { return incoming_avatar(tox, friend_number, file_number, size); } if (settings.accept_inline_images && size < MAX_INLINE_FILESIZE && name_length == (sizeof("utox-inline.png") - 1) && memcmp(name, "utox-inline.png", name_length) == 0) { return incoming_inline_image(tox, friend_number, file_number, size); } FILE_TRANSFER *ft = make_file_transfer(friend_number, file_number); if (!ft) { LOG_ERR("FileTransfer", "Unable to get memory handle for transfer, canceling friend/file number (%u/%u)", friend_number, file_number); tox_file_control(tox, friend_number, file_number, TOX_FILE_CONTROL_CANCEL, 0); return; } f->ft_incoming_active_count++; memset(ft, 0, sizeof(FILE_TRANSFER)); ft->in_use = true; // Preload some data needed by ft_find_resumeable ft->friend_number = friend_number; ft->file_number = file_number; ft->incoming = true; tox_file_get_file_id(tox, friend_number, file_number, ft->data_hash, NULL); ft->name = calloc(1, name_length + 1); if (!ft->name) { LOG_FATAL_ERR(EXIT_MALLOC, "FileTransfer", "Could not allocate space for file name (%uB)", name_length + 1); } snprintf((char *)ft->name, name_length + 1, "%.*s", (int)name_length, name); ft->name_length = name_length; /* access the correct memory location for this file */ /* Load saved information about this file */ if (ft_find_resumeable(ft)) { LOG_NOTE("FileTransfer", "Incoming Existing file from friend (%u) " , friend_number); FILE *file = fopen((const char *)ft->path, "rb+"); if (file) { LOG_INFO("FileTransfer", "Cool file exists, let try to restart it."); ft->in_use = true; ft->in_memory = false; ft->avatar = false; ft->friend_number = friend_number; ft->file_number = file_number; ft->target_size = size; ft->via.file = file; FILE_TRANSFER *msg = calloc(1, sizeof(FILE_TRANSFER)); if (!msg) { LOG_ERR("FileTransfer", "Unable to malloc for internal message. (This is bad!)"); return; } *msg = *ft; postmessage_utox(FILE_SEND_NEW, friend_number, file_number, msg); TOX_ERR_FILE_SEEK error = 0; tox_file_seek(tox, friend_number, file_number, ft->current_size, &error); if (error) { LOG_ERR("FileTransfer", "seek error %i" , error); // TODO UI error here as well; ft_local_control(tox, friend_number, file_number, TOX_FILE_CONTROL_CANCEL); return; } LOG_INFO("FileTransfer", "seek & resume"); ft->status = FILE_TRANSFER_STATUS_NONE; ft_local_control(tox, friend_number, file_number, TOX_FILE_CONTROL_RESUME); ft->resumeable = ft_init_resumable(ft); return; } LOG_ERR("FileTransfer", "Unable to open file suggested by resume!"); // This is fine-ish, we'll just fallback to new incoming file. } ft->friend_number = friend_number; ft->file_number = file_number; ft->target_size = size; ft->resumeable = ft_init_resumable(ft); FILE_TRANSFER *msg = calloc(1, sizeof(FILE_TRANSFER)); if (!msg) { LOG_ERR("FileTransfer", "Unable to malloc for internal message. (This is bad!)"); return; } *msg = *ft; postmessage_utox(FILE_INCOMING_NEW, friend_number, detox_incoming_file_number(file_number), msg); /* The file doesn't exist on disk where we expected, let's prompt the user to accept it as a new file */ LOG_NOTE("FileTransfer", "New incoming file from friend (%u) file number (%u)\nFileTransfer:\t\tfilename: %s", friend_number, file_number, name); /* Auto accept if it's a utox-inline image, with the correct size */ } /* Called by toxcore to deliver the next chunk of incoming data. */ static void incoming_file_callback_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, const uint8_t *data, size_t length, void *UNUSED(user_data)) { LOG_INFO("FileTransfer", "Incoming chunk friend(%u), file(%u), start(%lu), end(%lu), \n", friend_number, file_number, position, length); FILE_TRANSFER *ft = get_file_transfer(friend_number, file_number); if (!ft || !ft->in_use) { LOG_ERR("FileTransfer", "ERROR incoming chunk for an out of use file transfer!"); return; } if (length == 0) { utox_complete_file(ft); return; } if (ft->inline_img && ft->via.memory) { if (position == 0) { uint8_t png_header[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a }; if (memcmp(data, png_header, 8) != 0) { // this isn't a png header, just die LOG_ERR("FileTransfer", "Friend %u sent an inline image thats' not a PNG" , friend_number); ft_local_control(tox, friend_number, file_number, TOX_FILE_CONTROL_CANCEL); return; } } memcpy(ft->via.memory + position, data, length); } else if (ft->avatar && ft->via.avatar) { memcpy(ft->via.avatar + position, data, length); } else if (ft->via.file) { uint8_t count = 10; while (!file_lock(ft->via.file, position, length)) { LOG_ERR("FileTransfer", "Can't get lock, sleeping..."); yieldcpu(10); if (count == 0) { break; } count--; // If you get a bug report about this hanging utox, just disable it, it's unlikely to be needed! } fseeko(ft->via.file, position, SEEK_SET); size_t write_size = fwrite(data, 1, length, ft->via.file); fflush(ft->via.file); file_unlock(ft->via.file, position, length); if (write_size != length) { LOG_ERR("FileTransfer", "\n\nFileTransfer:\tERROR WRITING DATA TO FILE! (%u & %u)\n\n", friend_number, file_number); ft_local_control(tox, friend_number, file_number, TOX_FILE_CANCEL); return; } calculate_speed(ft); } else { LOG_TRACE("FileTransfer", "File Handle failed!"); ft_local_control(tox, friend_number, file_number, TOX_FILE_CANCEL); return; } ft->current_size += length; if (ft->resume_update) { --ft->resume_update; } else { ft_update_resumable(ft); ft->resume_update = 20; // every 20 packets we update } // TODO dirty hack, this needs to be replaced // moved it cal_speed() // ft_update_resumable(ft); } uint32_t ft_send_avatar(Tox *tox, uint32_t friend_number) { if (!tox || !self.png_data) { LOG_ERR("FileTransfer", "Can't send an avatar without data"); return UINT32_MAX; } LOG_NOTE("FileTransfer", "Starting avatar to friend %u." , friend_number); // TODO send the unset avatar command. FRIEND *f = get_friend(friend_number); if (!f) { LOG_ERR("FileTransfer", "Unable to get friend %u to send avatar.", friend_number); return UINT32_MAX; } if (f->ft_outgoing_active_count > MAX_FILE_TRANSFERS) { LOG_ERR("FileTransfer", "Can't send this avatar too many in progress..."); return UINT32_MAX; } /* While It's not ideal, we don't make sure we can alloc the FILE_TRANSFER until * we get the file number from toxcore. This could happen, but I assume it'll be * rare enough. Either way, it'll be noisy if it fails so here's to hoping! */ uint8_t hash[TOX_HASH_LENGTH]; tox_hash(hash, self.png_data, self.png_size); TOX_ERR_FILE_SEND error = 0; uint32_t file_number = tox_file_send(tox, friend_number, TOX_FILE_KIND_AVATAR, self.png_size, hash, NULL, 0, &error); if (error || file_number == UINT32_MAX) { LOG_ERR("FileTransfer", "tox_file_send() failed error code %u", error); return UINT32_MAX; }; FILE_TRANSFER *ft = make_file_transfer(friend_number, file_number); if (!ft) { // This is the noisy case noted above. LOG_ERR("FileTransfer", "Unable to malloc to actually send avatar!"); tox_file_control(tox, friend_number, file_number, TOX_FILE_CONTROL_CANCEL, NULL); return UINT32_MAX; } /* All errors handled */ ++f->ft_outgoing_active_count; memset(ft, 0, sizeof(FILE_TRANSFER)); ft->in_use = true; ft->incoming = false; ft->avatar = true; ft->friend_number = friend_number; ft->file_number = file_number; memcpy(ft->data_hash, hash, TOX_HASH_LENGTH); ft->target_size = self.png_size; ft->status = FILE_TRANSFER_STATUS_PAUSED_THEM; LOG_INFO("FileTransfer", "File transfer #%u sent to friend %u", ft->file_number, ft->friend_number); return file_number; } uint32_t ft_send_file(Tox *tox, uint32_t friend_number, FILE *file, uint8_t *path, size_t path_length, uint8_t *hash) { if (!tox || !file) { LOG_ERR("FileTransfer", "Can't send a file without data"); return UINT32_MAX; } LOG_TRACE("FileTransfer", "Starting FILE to friend %u." , friend_number); FRIEND *f = get_friend(friend_number); if (!f) { LOG_ERR("FileTransfer", "Unable to get friend %u to send file.", friend_number); return UINT32_MAX; } if (f->ft_outgoing_active_count > MAX_FILE_TRANSFERS) { LOG_ERR("FileTransfer", "Can't send this file too many in progress..."); return UINT32_MAX; } fseeko(file, 0, SEEK_END); size_t size = ftello(file); const uint8_t *name = path + path_length; size_t name_length = 0; while (*--name != '/' && *name != '\\') { // TODO remove widows style path support from uTox. ++name_length; } ++name; TOX_ERR_FILE_SEND error = 0; uint32_t file_number = tox_file_send(tox, friend_number, TOX_FILE_KIND_DATA, size, hash, name, name_length, &error); if (error || file_number == UINT32_MAX) { switch (error) { case TOX_ERR_FILE_SEND_NULL: { LOG_ERR("FileTransfer", "Error, Toxcore reports NULL"); break; } case TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND: { LOG_ERR("FileTransfer", "Error, friend Not found."); break; } case TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED: { LOG_ERR("FileTransfer", "Error, friend not connected."); break; } case TOX_ERR_FILE_SEND_NAME_TOO_LONG: { LOG_ERR("FileTransfer", "Error, name too long '%s'" , name); break; } case TOX_ERR_FILE_SEND_TOO_MANY: { LOG_ERR("FileTransfer", "Error, too many files in progress"); break; } case TOX_ERR_FILE_SEND_OK: { break; } } LOG_ERR("FileTransfer", "tox_file_send() failed error code %u", error); return UINT32_MAX; } FILE_TRANSFER *ft = make_file_transfer(friend_number, file_number); if (!ft) { // This is the noisy case noted above. LOG_ERR("FileTransfer", "Unable to malloc to actually send file!"); tox_file_control(tox, friend_number, file_number, TOX_FILE_CONTROL_CANCEL, NULL); return UINT32_MAX; } ++f->ft_outgoing_active_count; memset(ft, 0, sizeof(FILE_TRANSFER)); ft->in_use = true; ft->incoming = false; ft->friend_number = friend_number; ft->file_number = file_number; ft->target_size = size; ft->name = calloc(1, name_length + 1); if (!ft->name) { LOG_ERR("FileTransfer", "Error, couldn't allocate memory for ft->name."); --f->ft_outgoing_active_count; return UINT32_MAX; } ft->name_length = name_length; snprintf((char *)ft->name, name_length + 1, "%.*s", (int)name_length, name); snprintf((char *)ft->path, UTOX_FILE_NAME_LENGTH, "%.*s", (int)path_length, path); ft->via.file = file; tox_file_get_file_id(tox, friend_number, file_number, ft->data_hash, NULL); ft->resumeable = ft_init_resumable(ft); ft->status = FILE_TRANSFER_STATUS_PAUSED_THEM; FILE_TRANSFER *msg = calloc(1, sizeof(FILE_TRANSFER)); if (!msg) { LOG_ERR("FileTransfer", "Unable to malloc for internal message. (This is bad!)"); return UINT32_MAX; } *msg = *ft; postmessage_utox(FILE_SEND_NEW, friend_number, file_number, msg); return file_number; } /* Returns file number on success, UINT32_MAX on failure. */ uint32_t ft_send_data(Tox *tox, uint32_t friend_number, uint8_t *data, size_t size, uint8_t *name, size_t name_length) { if (!tox || !data || !name) { LOG_ERR("FileTransfer", "Can't send data to friend without data"); return UINT32_MAX; } LOG_INFO("FileTransfer", "Starting raw data transfer to friend %u." , friend_number); // TODO send the unset avatar command. FRIEND *f = get_friend(friend_number); if (!f) { LOG_ERR("FileTransfer", "Unable to get friend %u to send raw data.", friend_number); return UINT32_MAX; } if (f->ft_outgoing_active_count >= MAX_FILE_TRANSFERS) { LOG_ERR("FileTransfer", "Can't send raw data too many in progress..."); return UINT32_MAX; } /* While It's not ideal, we don't make sure we can alloc the FILE_TRANSFER until * we get the file number from toxcore. This could happen, but I assume it'll be * rare enough. Either way, it'll be noisy if it fails so here's to hoping! */ uint8_t hash[TOX_HASH_LENGTH]; tox_hash(hash, data, size); // TODO skip this if the file is HUGE! TOX_ERR_FILE_SEND error = 0; uint32_t file_number = tox_file_send(tox, friend_number, TOX_FILE_KIND_DATA, size, hash, name, name_length, &error); if (error || file_number == UINT32_MAX) { LOG_ERR("FileTransfer", "tox_file_send() failed error code %u", error); return UINT32_MAX; }; FILE_TRANSFER *ft = make_file_transfer(friend_number, file_number); if (!ft) { // This is the noisy case noted above. LOG_ERR("FileTransfer", "Unable to malloc to actually send data!"); tox_file_control(tox, friend_number, file_number, TOX_FILE_CONTROL_CANCEL, NULL); return UINT32_MAX; } ++f->ft_outgoing_active_count; memset(ft, 0, sizeof(FILE_TRANSFER)); ft->in_use = true; ft->incoming = false; ft->in_memory = true; ft->inline_img = true; ft->name = calloc(1, name_length + 1); if (!ft->name) { LOG_ERR("FileTransfer", "Error, couldn't allocate memory for ft->name."); --f->ft_outgoing_active_count; return UINT32_MAX; } ft->name_length = name_length; snprintf((char *)ft->name, name_length + 1, "%.*s", (int)name_length, name); ft->friend_number = friend_number; ft->file_number = file_number; memcpy(ft->data_hash, hash, TOX_HASH_LENGTH); ft->via.memory = data; ft->target_size = size; ft->status = FILE_TRANSFER_STATUS_PAUSED_THEM; FILE_TRANSFER *msg = calloc(1, sizeof(FILE_TRANSFER)); if (!msg) { LOG_ERR("FileTransfer", "Unable to malloc for internal message. (This is bad!)"); return UINT32_MAX; } *msg = *ft; postmessage_utox(FILE_SEND_NEW, friend_number, file_number, msg); LOG_INFO("FileTransfer", "Inline image sent to friend. FT %u, Friend %u", ft->file_number, ft->friend_number); return file_number; } bool ft_set_ui_data(uint32_t friend_number, uint32_t file_number, MSG_HEADER *ui_data) { FILE_TRANSFER *file = get_file_transfer(friend_number, file_number); if (!file) { LOG_WARN("FileTransfer", "Unable to set ui_data for unknown file number %u with friend %u", file_number, friend_number); return false; } file->ui_data = ui_data; return true; } static void outgoing_file_callback_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, size_t length, void *UNUSED(user_data)) { LOG_INFO("FileTransfer", "Chunk requested for friend_id (%u), and file_id (%u). Start (%lu), End (%zu).\r", friend_number, file_number, position, length); FILE_TRANSFER *ft = get_file_transfer(friend_number, file_number); if (!ft) { LOG_ERR("FileTransfer", "Unabele to get file transfer (%u & %u)", friend_number, file_number); return; } if (length == 0) { LOG_NOTE("FileTransfer", "Outgoing transfer is done (%u & %u)", friend_number, file_number); utox_complete_file(ft); return; } if (position + length > ft->target_size) { LOG_ERR("FileTransfer", "Outing transfer size mismatch!"); return; } TOX_ERR_FILE_SEND_CHUNK error = 0; if (ft->in_memory) { if (!ft->via.memory) { LOG_ERR("FileTransfer", "ERROR READING FROM MEMORY! (%u & %u)", friend_number, file_number); return; } tox_file_send_chunk(tox, friend_number, file_number, position, ft->via.memory + position, length, &error); if (error) { LOG_ERR("FileTransfer", "Outgoing chunk error on memory (%u)", error); } calculate_speed(ft); } else if (ft->avatar) { if (!self.png_data) { LOG_ERR("FileTransfer", "ERROR READING FROM AVATAR! (%u & %u)", friend_number, file_number); return; } tox_file_send_chunk(tox, friend_number, file_number, position, self.png_data + position, length, &error); if (error) { LOG_ERR("FileTransfer", "Outgoing chunk error on avatar (%u)", error); } } else { // File if (ft->via.file) { uint8_t buffer[length]; fseeko(ft->via.file, position, SEEK_SET); if (fread(buffer, length, 1, ft->via.file) != 1) { LOG_ERR("FileTransfer", "ERROR READING FILE! (%u & %u)", friend_number, file_number); LOG_INFO("FileTransfer", "Size (%lu), Position (%lu), Length(%lu), size_transferred (%lu).", ft->target_size, position, length, ft->current_size); ft_local_control(tox, friend_number, file_number, TOX_FILE_CONTROL_CANCEL); return; } tox_file_send_chunk(tox, friend_number, file_number, position, buffer, length, &error); if (error) { LOG_ERR("FileTransfer", "Outgoing chunk error on file (%u)", error); } } calculate_speed(ft); } ft->current_size += length; } bool utox_file_start_write(uint32_t friend_number, uint32_t file_number, const char *file) { FILE_TRANSFER *ft = get_file_transfer(friend_number, file_number); if (!ft || !file) { LOG_ERR("FileTransfer", "FileTransfer:\tUnable to grab a file to start the write friend %u, file %u.", friend_number, file_number); return false; } snprintf((char *)ft->path, UTOX_FILE_NAME_LENGTH, "%s", file); ft->via.file = utox_get_file_simple((char *)ft->path, UTOX_FILE_OPTS_WRITE); if (!ft->via.file) { LOG_ERR("FileTransfer", "The file we're supposed to write to couldn't be opened\n\t\t\"%s\"", ft->path); break_file(ft); return false; } return true; } void utox_set_callbacks_file_transfer(Tox *tox) { /* Incoming files */ /* This is the callback for a new incoming file. */ tox_callback_file_recv(tox, incoming_file_callback_request); /* This is the callback with friend's actions for a file */ tox_callback_file_recv_control(tox, file_transfer_callback_control); /* This is the callback with a chunk data for a file. */ tox_callback_file_recv_chunk(tox, incoming_file_callback_chunk); /* Outgoing files */ /* This is the callback send to request a new file chunk */ tox_callback_file_chunk_request(tox, outgoing_file_callback_chunk); } uTox-0.17.1/src/file_transfers.h000066400000000000000000000044131354126257400165200ustar00rootroot00000000000000#ifndef FILE_TRANSFERS_H #define FILE_TRANSFERS_H #include #include #include #include typedef struct msg_header MSG_HEADER; #define MAX_FILE_TRANSFERS 32 typedef enum { FILE_TRANSFER_STATUS_NONE, FILE_TRANSFER_STATUS_ACTIVE, FILE_TRANSFER_STATUS_PAUSED_US, FILE_TRANSFER_STATUS_PAUSED_BOTH, FILE_TRANSFER_STATUS_PAUSED_THEM, FILE_TRANSFER_STATUS_BROKEN, FILE_TRANSFER_STATUS_COMPLETED, FILE_TRANSFER_STATUS_KILLED, } UTOX_FILE_TRANSFER_STATUS; typedef struct { FILE *file; uint8_t *name; } UTOX_MSG_FT; typedef struct file_transfer { bool in_use; bool incoming; bool in_memory; bool avatar; bool inline_img; bool resumeable; uint32_t friend_number; uint32_t file_number; uint8_t data_hash[TOX_HASH_LENGTH]; UTOX_FILE_TRANSFER_STATUS status; uint8_t path[1024]; // UTOX_FILE_NAME_LENGTH uint8_t *name; size_t name_length; size_t target_size; size_t current_size; union { uint8_t *memory; uint8_t *avatar; FILE *file; } via; /* speed + progress calculations. */ uint32_t speed, num_packets; uint64_t last_check_time, last_check_transferred; FILE *resume_file; uint8_t resume_update; MSG_HEADER *ui_data; bool decon_wait; // Used to pause decon/file cleanup, for the UI thread to copy the data; } FILE_TRANSFER; void ft_local_control(Tox *tox, uint32_t friend_number, uint32_t file_number, TOX_FILE_CONTROL control); uint32_t ft_send_avatar(Tox *tox, uint32_t friend_number); uint32_t ft_send_file(Tox *tox, uint32_t friend_number, FILE *file, uint8_t *name, size_t name_length, uint8_t *hash); uint32_t ft_send_data(Tox *tox, uint32_t friend_number, uint8_t *data, size_t size, uint8_t *name, size_t name_length); /** Sets the UI pointer to the File Transfer Message pointer. * * This is non robust and could use some LTC */ bool ft_set_ui_data(uint32_t friend_number, uint32_t file_number, MSG_HEADER *ui_data); bool utox_file_start_write(uint32_t friend_number, uint32_t file_number, const char *file); void utox_set_callbacks_file_transfer(Tox *tox); void ft_friend_online(Tox *tox, uint32_t friend_number); void ft_friend_offline(Tox *tox, uint32_t friend_number); #endif uTox-0.17.1/src/filesys.c000066400000000000000000000013541354126257400151640ustar00rootroot00000000000000#include "filesys.h" #include "native/filesys.h" #include "debug.h" #include "settings.h" #include FILE *utox_get_file(const char *name, size_t *size, UTOX_FILE_OPTS opts) { return native_get_file((uint8_t *)name, size, opts, settings.portable_mode); } FILE *utox_get_file_simple(const char *name, UTOX_FILE_OPTS opts) { return native_get_file_simple(name, opts); } bool utox_remove_file(const uint8_t *full_name, size_t length) { return native_remove_file(full_name, length, settings.portable_mode); } bool utox_move_file(const uint8_t *current_name, const uint8_t *new_name) { return native_move_file(current_name, new_name); } char *utox_get_filepath(const char *name) { return native_get_filepath(name); } uTox-0.17.1/src/filesys.h000066400000000000000000000037751354126257400152020ustar00rootroot00000000000000#ifndef FILESYS_H #define FILESYS_H #include #include #include #define UTOX_FILE_NAME_LENGTH 1024 /** * Options to define behavior when opening files. */ typedef enum UTOX_FILE_OPTS { UTOX_FILE_OPTS_READ = 1 << 0, UTOX_FILE_OPTS_WRITE = 1 << 1, UTOX_FILE_OPTS_APPEND = 1 << 2, UTOX_FILE_OPTS_MKDIR = 1 << 3, UTOX_FILE_OPTS_DELETE = 1 << 7, } UTOX_FILE_OPTS; /** * OS independent way of opening a file from the utox storage folder. * * This function takes care of the environment, checking for portable mode. * * @param name file name, relative to utox storage folder. * @param size size of the file. This variable is written to by the function. Can be NULL if you don't care about the size. * @param opts options to apply when opening the file, see UTOX_FILE_OPTS for available options. * @return open file pointer, or NULL on failure. */ FILE *utox_get_file(const char *name, size_t *size, UTOX_FILE_OPTS opts); /** * @brief OS independent way of opening a file from filesystem. * * @param name full path of file to open. * @param opts Options to apply when opening the file, see UTOX_FILE_OPTS for available options. * * @return open file pointer, or NULL on failure. */ FILE *utox_get_file_simple(const char *name, UTOX_FILE_OPTS opts); /** * TODO DOCUMENTATION */ bool utox_remove_file(const uint8_t *full_name, size_t length); bool utox_move_file(const uint8_t *current_name, const uint8_t *new_name); /** * Takes a null-terminated utf8 filepath and creates it with permissions 0700 * (in posix environments) if it doesn't already exist. In Windows environments * there are no security settings applied to the created folder. * * Returns a bool indicating if the path exists or not. */ bool native_create_dir(const uint8_t *filepath); /** * @brief Get full path of the file in the Tox profile folder. * * @param name name of the file. * @return null-terminated string, or NULL on failure. */ char *utox_get_filepath(const char *name); #endif uTox-0.17.1/src/flist.c000066400000000000000000001220151354126257400146250ustar00rootroot00000000000000#include "flist.h" // TODO: Separate from UI or include in UI. #include "avatar.h" #include "friend.h" #include "groups.h" #include "debug.h" #include "macros.h" #include "self.h" #include "settings.h" #include "text.h" #include "theme.h" #include "tox.h" #include "utox.h" #include "ui/contextmenu.h" #include "ui/draw.h" #include "ui/dropdown.h" #include "ui/edit.h" #include "ui/button.h" #include "ui/scrollable.h" #include "ui/switch.h" #include "ui/tooltip.h" #include "layout/background.h" #include "layout/friend.h" #include "layout/group.h" #include "layout/settings.h" #include "layout/sidebar.h" #include "native/time.h" #include "native/ui.h" #include #include #include #ifdef UNITY #include "xlib/mmenu.h" extern bool unity_running; #endif /* I think these are pointers to the panels they're named after. */ static ITEM item_add, item_settings, item_transfer; // full list of friends and group chats static ITEM *item; static uint32_t itemcount; // list of chats actually shown in the GUI after filtering // (actually indices pointing to chats in the chats array) static uint32_t *shown_list; static uint32_t showncount; // search and filter stuff static char * search_string; static uint8_t filter; static ITEM *mouseover_item; static ITEM *nitem; // item that selected_item is being dragged over static ITEM *selected_item = &item_add; static ITEM *right_mouse_item; static bool mouse_in_list; static bool selected_item_mousedown; static bool selected_item_mousedown_move_pend; static int selected_item_dy; // y offset of selected item being dragged from its original position static void flist_draw_itembox(ITEM *i, int x, int y, int width) { int height; if (settings.use_mini_flist) { height = SCALE(ROSTER_BOX_HEIGHT / 2); } else { height = SCALE(ROSTER_BOX_HEIGHT); } if (selected_item == i) { drawrect(x, y + 1, width, y + height, COLOR_BKGRND_MAIN); } else if (mouseover_item == i) { drawrect(x, y + 1, width, y + height, COLOR_BKGRND_LIST_HOVER); } } static void flist_draw_name(ITEM *i, int x, int y, int width, char *name, char *msg, uint16_t name_length, uint16_t msg_length, bool color_overide, uint32_t color) { if (!color_overide) { color = (selected_item == i) ? COLOR_MAIN_TEXT : COLOR_LIST_TEXT; } setcolor(color); setfont(FONT_LIST_NAME); /* Always draw name*/ drawtextrange(x, width - SCALE(SIDEBAR_PADDING * 5), y, name, name_length); if (!settings.use_mini_flist) { /* Name + user status msg*/ if (!color_overide) { color = (selected_item == i) ? COLOR_MAIN_TEXT_SUBTEXT : COLOR_LIST_TEXT_SUBTEXT; } setcolor(color); setfont(FONT_STATUS); drawtextrange(x, width - SCALE(SIDEBAR_PADDING * 5), y + SCALE(16), msg, msg_length); } } static void flist_draw_status_icon(uint8_t status, int x, int y, bool notify) { y -= BM_STATUS_WIDTH / 2; x -= BM_STATUS_WIDTH / 2; drawalpha(BM_ONLINE + status, x, y, BM_STATUS_WIDTH, BM_STATUS_WIDTH, status_color[status]); if (notify) { y += BM_STATUS_WIDTH / 2; y -= BM_STATUS_NOTIFY_WIDTH / 2; x += BM_STATUS_WIDTH / 2; x -= BM_STATUS_NOTIFY_WIDTH / 2; drawalpha(BM_STATUS_NOTIFY, x, y, BM_STATUS_NOTIFY_WIDTH, BM_STATUS_NOTIFY_WIDTH, status_color[status]); } } static void drawitem(ITEM *i, int x, int y, int width) { flist_draw_itembox(i, x + SCALE(SCROLL_WIDTH), y, width); int box_height; int avatar_x; int avatar_y; int name_x; int name_y; int default_w; int group_bitmap; int contact_bitmap; if (settings.use_mini_flist) { box_height = SCALE(ROSTER_BOX_HEIGHT / 2); avatar_x = x + SCALE(SCROLL_WIDTH); avatar_y = y + SCALE(ROSTER_AVATAR_TOP / 2); name_x = avatar_x + BM_CONTACT_WIDTH / 2 + SCALE(5); name_y = y + SCALE(ROSTER_NAME_TOP / 2); default_w = BM_CONTACT_WIDTH / 2; group_bitmap = BM_GROUP_MINI; contact_bitmap = BM_CONTACT_MINI; } else { box_height = SCALE(ROSTER_BOX_HEIGHT); avatar_x = x + SCALE(SCROLL_WIDTH); avatar_y = y + SCALE(ROSTER_AVATAR_TOP); name_x = avatar_x + BM_CONTACT_WIDTH + SCALE(5); name_y = y + SCALE(ROSTER_NAME_TOP); default_w = BM_CONTACT_WIDTH; group_bitmap = BM_GROUP; contact_bitmap = BM_CONTACT; } switch (i->type) { case ITEM_FRIEND: { FRIEND *f = get_friend(i->id_number); uint8_t status = f->online ? f->status : 3; // draw avatar or default image if (friend_has_avatar(f)) { draw_avatar_image(f->avatar->img, avatar_x, avatar_y, f->avatar->width, f->avatar->height, default_w, default_w); } else { drawalpha(contact_bitmap, avatar_x, avatar_y, default_w, default_w, (selected_item == i) ? COLOR_MAIN_TEXT : COLOR_LIST_TEXT); } flist_draw_name(i, name_x, name_y, width, UTOX_FRIEND_NAME(f), f->status_message, UTOX_FRIEND_NAME_LENGTH(f), f->status_length, 0, 0); flist_draw_status_icon(status, width - SCALE(15), y + box_height / 2, f->unread_msg); break; } case ITEM_GROUP: { GROUPCHAT *g = get_group(i->id_number); drawalpha(group_bitmap, avatar_x, avatar_y, default_w, default_w, (selected_item == i) ? COLOR_MAIN_TEXT : COLOR_LIST_TEXT); bool color_overide = false; uint32_t color = 0; if (g->muted) { color_overide = true; color = COLOR_GROUP_MUTED; } else { uint64_t time = get_time(); for (unsigned int j = 0; j < g->peer_count; ++j) { if (time - g->last_recv_audio[j] <= (uint64_t)1 * 1000 * 1000 * 1000) { color_overide = true; color = COLOR_GROUP_AUDIO; break; } } } flist_draw_name(i, name_x, name_y, width, g->name, g->topic, g->name_length, g->topic_length, color_overide, color); flist_draw_status_icon(0, SCALE(width - 15), y + box_height / 2, g->unread_msg); break; } case ITEM_FREQUEST: { FREQUEST *r = get_frequest(i->id_number); if (!r) { LOG_WARN("FList", "Can't get the request at this number."); break; } char name[TOX_ADDRESS_SIZE * 2]; id_to_string(name, r->bin_id); drawalpha(contact_bitmap, avatar_x, y + ROSTER_AVATAR_TOP, default_w, default_w, (selected_item == i) ? COLOR_MAIN_TEXT : COLOR_LIST_TEXT); flist_draw_name(i, name_x, name_y, width, name, r->msg, sizeof(name), r->length, 0, 0); break; } case ITEM_GROUP_CREATE: { drawalpha(group_bitmap, avatar_x, y + ROSTER_AVATAR_TOP, default_w, default_w, (selected_item == i) ? COLOR_MAIN_TEXT : COLOR_LIST_TEXT); flist_draw_name(i, name_x, name_y, width, S(CREATEGROUPCHAT), NULL, SLEN(CREATEGROUPCHAT), 0, 1, (selected_item == i) ? COLOR_MAIN_TEXT : COLOR_LIST_TEXT); break; } default: { LOG_ERR("F-List", "Trying to draw an item that we shouldn't be drawing!"); break; } } } // find index of given item in shown_list, or INT_MAX if it can't be found static unsigned int find_item_shown_index(ITEM *it) { for (unsigned int i = 0; i < showncount; ++i) { if (shown_list[i] == it - item) { // (it - item) returns the index of the item in the full items list return i; } } return INT_MAX; // can't be found! } void flist_re_scale(void) { if (settings.use_mini_flist) { scrollbar_flist.content_height = SCALE(ROSTER_BOX_HEIGHT / 2) * showncount; } else { scrollbar_flist.content_height = SCALE(ROSTER_BOX_HEIGHT) * showncount; } } bool friend_matches_search_string(FRIEND *f, char *str) { return !str || strstr_case(f->name, str) || (f->alias && strstr_case(f->alias, str)); } void flist_update_shown_list(void) { uint32_t j; // index in shown_list array for (uint32_t i = j = 0; i < itemcount; i++) { ITEM *it = &item[i]; if (it->type == ITEM_FRIEND) { FRIEND *f = get_friend(it->id_number); if ((!filter || f->online) && friend_matches_search_string(f, search_string)) { shown_list[j++] = i; } } else { shown_list[j++] = i; } } showncount = j; flist_re_scale(); } /* returns address of item at current index and appends the group create entry */ static ITEM *newitem(void) { item = realloc(item, (itemcount + 1) * sizeof(ITEM)); shown_list = realloc(shown_list, (itemcount + 1) * sizeof(uint32_t)); if (!item || !shown_list) { LOG_FATAL_ERR(EXIT_MALLOC, "flist", "Could not allocate memory for friend list."); } unsigned int index = itemcount - 1; item[index + 1].type = ITEM_GROUP_CREATE; item[index + 1].id_number = UINT32_MAX; itemcount++; flist_update_shown_list(); return &item[index]; } // return item that the user is mousing over static ITEM *item_hit(int mx, int my, int UNUSED(height)) { int real_height = SCALE(ROSTER_BOX_HEIGHT); if (settings.use_mini_flist) { real_height /= 2; } /* Mouse is outside the list */ if (mx < SCROLL_WIDTH || mx >= SCALE(230) || my < 0 // TODO magic numbers are bad 230 should be width || my >= (int)(showncount * real_height)) { /* TODO: Height is a bit buggy, Height needs /2 * figure out why! */ mouse_in_list = false; return NULL; } else { mouse_in_list = 1; } uint32_t item_idx = my / real_height; mouse_in_list = true; /* mouse is below the last item */ if (item_idx >= showncount) { return NULL; } return &item[shown_list[item_idx]]; } uint8_t flist_get_filter(void) { return filter; } void flist_set_filter(uint8_t new_filter) { filter = new_filter; flist_update_shown_list(); } void flist_search(char *str) { search_string = str; flist_update_shown_list(); } // change the selected item by [offset] items in the shown list static void change_tab(int offset) { /* Pg-Up/Dn broke on the create group icon, * remoing this if seems to work but I don't know what it was doing here * so I commented it incase it breaks stuff... */ // if (selected_item->type == ITEM_FRIEND || // selected_item->type == ITEM_GROUP) { unsigned int index = find_item_shown_index(selected_item); if (index != INT_MAX) { // flist_selectchat will check if out of bounds flist_selectchat((index + offset + showncount) % showncount); } // } } void flist_previous_tab(void) { change_tab(-1); } void flist_next_tab(void) { change_tab(1); } /* TODO: move this out of here! * maybe to ui.c ? */ static int current_width; // I know, but I'm in a hurry, so I'll fix this later static void page_close(ITEM *i) { switch (i->type) { case ITEM_FRIEND: { FRIEND *f = get_friend(i->id_number); current_width = f->msg.width; free(f->typed); f->typed_length = edit_chat_msg_friend.length; f->typed = calloc(1, f->typed_length); if (!f->typed) { LOG_ERR("flist", "Unable to calloc for f->typed."); return; } memcpy(f->typed, edit_chat_msg_friend.data, f->typed_length); f->msg.scroll = messages_friend.content_scroll->d; f->edit_history = edit_chat_msg_friend.history; f->edit_history_cur = edit_chat_msg_friend.history_cur; f->edit_history_length = edit_chat_msg_friend.history_length; panel_chat.disabled = true; panel_friend.disabled = true; panel_friend_chat.disabled = true; panel_friend_video.disabled = true; panel_friend_settings.disabled = true; panel_friend_confirm_deletion.disabled = true; settings.inline_video = true; panel_friend_request.disabled = true; break; } case ITEM_FREQUEST: { panel_chat.disabled = true; panel_friend_request.disabled = true; break; } case ITEM_GROUP: { GROUPCHAT *g = get_group(selected_item->id_number); if (g) { current_width = g->msg.width; free(g->typed); g->typed_length = edit_chat_msg_group.length; g->typed = calloc(1, g->typed_length); if (!g->typed) { LOG_ERR("F-List", "Unable to calloc for g->typed."); return; } memcpy(g->typed, edit_chat_msg_group.data, g->typed_length); g->msg.scroll = messages_group.content_scroll->d; g->edit_history = edit_chat_msg_group.history; g->edit_history_cur = edit_chat_msg_group.history_cur; g->edit_history_length = edit_chat_msg_group.history_length; } panel_chat.disabled = true; panel_group.disabled = true; break; } case ITEM_SETTINGS: { if (panel_profile_password.disabled) { panel_splash_page.disabled = true; settings.show_splash = false; panel_settings_master.disabled = true; panel_overhead.disabled = true; panel_profile_password_settings.disabled = true; panel_nospam_settings.disabled = true; button_settings.disabled = false; reset_settings_controls(); } break; } case ITEM_ADD: { button_add_new_contact.disabled = false; panel_add_friend.disabled = true; break; } case ITEM_GROUP_CREATE: { panel_chat.disabled = true; panel_group_create.disabled = true; break; } case ITEM_NONE: { break; } } } static void page_open(ITEM *i) { switch (i->type) { case ITEM_FREQUEST: { panel_chat.disabled = false; panel_friend_request.disabled = false; break; } case ITEM_FRIEND: { FRIEND *f = get_friend(i->id_number); if (!f) { LOG_ERR("Flist", "Could not get friend data from item"); return; } #ifdef UNITY if (unity_running) { mm_rm_entry(f->id_bin); } #endif memcpy(edit_chat_msg_friend.data, f->typed, f->typed_length); edit_chat_msg_friend.length = f->typed_length; f->msg.width = current_width; f->msg.id = f->number; f->unread_msg = false; /* We use the MESSAGES struct from the friend, but we need the info from the panel. */ messages_friend.object = ((void **)&f->msg); messages_updateheight((MESSAGES *)messages_friend.object, current_width); ((MESSAGES *)messages_friend.object)->cursor_over_msg = UINT32_MAX; ((MESSAGES *)messages_friend.object)->cursor_over_position = UINT32_MAX; ((MESSAGES *)messages_friend.object)->cursor_down_msg = UINT32_MAX; ((MESSAGES *)messages_friend.object)->cursor_down_position = UINT32_MAX; ((MESSAGES *)messages_friend.object)->cursor_over_uri = UINT32_MAX; scrollbar_friend.content_height = f->msg.height; messages_friend.content_scroll->d = f->msg.scroll; edit_chat_msg_friend.history = f->edit_history; edit_chat_msg_friend.history_cur = f->edit_history_cur; edit_chat_msg_friend.history_length = f->edit_history_length; edit_setfocus(&edit_chat_msg_friend); panel_chat.disabled = 0; panel_friend.disabled = 0; panel_friend_chat.disabled = 0; panel_friend_video.disabled = 1; panel_friend_settings.disabled = 1; break; } case ITEM_GROUP: { GROUPCHAT *g = get_group(i->id_number); if (!g) { LOG_FATAL_ERR(EXIT_FAILURE, "F-List", "Selected group no longer exists. Group number: %u", i->id_number); } memcpy(edit_chat_msg_group.data, g->typed, g->typed_length); edit_chat_msg_group.length = g->typed_length; g->msg.width = current_width; g->msg.id = g->number; g->unread_msg = 0; /* We use the MESSAGES struct from the group, but we need the info from the panel. */ messages_group.object = &g->msg; messages_updateheight((MESSAGES *)messages_group.object, current_width); ((MESSAGES *)messages_group.object)->cursor_over_msg = UINT32_MAX; ((MESSAGES *)messages_group.object)->cursor_over_position = UINT32_MAX; ((MESSAGES *)messages_group.object)->cursor_down_msg = UINT32_MAX; ((MESSAGES *)messages_group.object)->cursor_down_position = UINT32_MAX; ((MESSAGES *)messages_group.object)->cursor_over_uri = UINT32_MAX; messages_group.content_scroll->content_height = g->msg.height; messages_group.content_scroll->d = g->msg.scroll; edit_setfocus(&edit_chat_msg_group); edit_chat_msg_group.history = g->edit_history; edit_chat_msg_group.history_cur = g->edit_history_cur; edit_chat_msg_group.history_length = g->edit_history_length; panel_chat.disabled = false; panel_group.disabled = false; panel_group_chat.disabled = false; panel_group_video.disabled = true; panel_group_settings.disabled = true; panel_group_create.disabled = true; break; } case ITEM_SETTINGS: { if (panel_profile_password.disabled) { button_settings.disabled = 1; panel_overhead.disabled = 0; panel_settings_master.disabled = 0; } break; } case ITEM_ADD: { button_add_new_contact.disabled = 1; panel_overhead.disabled = 0; panel_add_friend.disabled = 0; edit_setfocus(&edit_add_new_friend_id); break; } case ITEM_GROUP_CREATE: { panel_chat.disabled = false; panel_group_create.disabled = false; // postmessage_toxcore(TOX_GROUP_CREATE, 0, 0, NULL); break; } case ITEM_NONE: { break; } } } static void show_page(ITEM *i) { // TODO!! // panel_item[selected_item->type - 1].disabled = 1; // panel_item[i->type - 1].disabled = 0; edit_resetfocus(); /* First things first, we need to deselect and store the old data. */ page_close(selected_item); /* Now we activate/select the new page, and load stored data */ page_open(i); selected_item = i; addfriend_status = 0; } void flist_start(void) { selected_item = &item_settings; button_settings.disabled = true; item_add.type = ITEM_ADD; item_settings.type = ITEM_SETTINGS; itemcount = self.friend_list_count + self.groups_list_count; itemcount += 1; /* for ITEM_GROUP_CREATE */ item = calloc(itemcount, sizeof(ITEM)); shown_list = calloc(itemcount, sizeof(uint32_t)); if (!item || !shown_list) { LOG_FATAL_ERR(EXIT_MALLOC, "flist", "Could not allocate memory for friend list."); } ITEM *i = item; for (uint32_t num = 0; num < self.friend_list_count; ++num) { const FRIEND *f = get_friend(num); if (!f) { continue; } i->type = ITEM_FRIEND; i->id_number = f->number; i++; } for (uint32_t num = 0; num < self.groups_list_count; num++) { const GROUPCHAT *g = get_group(num); if (!g) { continue; } i->type = ITEM_GROUP; i->id_number = g->number; i++; } i->type = ITEM_GROUP_CREATE; i->id_number = UINT32_MAX; search_string = NULL; flist_update_shown_list(); } void flist_add_friend(FRIEND *f, const char *msg, const int msg_length) { ITEM *i = newitem(); if (!i) { LOG_ERR("Flist", "Failed to create an item in the friend list for a friend."); return; } i->type = ITEM_FRIEND; i->id_number = f->number; if (msg_length > 0) { message_add_type_text(&f->msg, true, msg, msg_length, true, false); } } void flist_add_friend_accepted(FRIEND *f, FREQUEST *req) { for (uint32_t i = 0; i < itemcount; ++i) { if (item[i].type == ITEM_FREQUEST && item[i].id_number == req->number) { LOG_INFO("FList", "Friend found and accepted."); item[i].type = ITEM_FRIEND; item[i].id_number = f->number; if (&item[i] == selected_item) { // panel_item[selected_item->type - 1].disabled = 1; // panel_item[ITEM_FRIEND - 1].disabled = 0; messages_friend.object = &f->msg; ((MESSAGES *)messages_friend.object)->cursor_over_msg = UINT32_MAX; messages_friend.content_scroll->content_height = f->msg.height; messages_friend.content_scroll->d = f->msg.scroll; if (req->length > 0) { message_add_type_text(&f->msg, false, req->msg, req->length, true, false); } f->msg.id = f->number; } return; } } } void flist_add_group(GROUPCHAT *g) { ITEM *i = newitem(); if (!i) { LOG_ERR("Flist", "Failed to create an item in the friend list for a groupchat."); return; } i->type = ITEM_GROUP; i->id_number = g->number; } void flist_add_frequest(FREQUEST *r) { ITEM *i = newitem(); if (!i) { LOG_ERR("Flist", "Failed to create an item in the friend list for a friend request."); return; } i->type = ITEM_FREQUEST; i->id_number = r->number; } void group_av_peer_remove(GROUPCHAT *g, int peernumber); // FIXME removing multiple items without moving the mouse causes asan neg-size-param error on memmove! static void deleteitem(ITEM *i) { uint32_t countof_item = itemcount; right_mouse_item = NULL; if (i == selected_item) { if (i == &item[itemcount] - 1) { if (i == item) { show_page(&item_add); } else { show_page(i - 1); } } else { show_page(i + 1); } } switch (i->type) { case ITEM_FRIEND: { FRIEND *f = get_friend(i->id_number); postmessage_toxcore(TOX_FRIEND_DELETE, f->number, 0, f); break; } case ITEM_GROUP: { GROUPCHAT *g = get_group(i->id_number); postmessage_toxcore(TOX_GROUP_PART, g->number, 0, NULL); group_free(g); break; } case ITEM_FREQUEST: { friend_request_free(i->id_number); break; } default: { return; } } itemcount--; int size = (&item[itemcount] - i) * sizeof(ITEM); memmove(i, i + 1, size); if (i != selected_item && selected_item > i && selected_item >= item && selected_item < item + countof_item) { selected_item--; } flist_update_shown_list(); redraw(); // flist_draw(); } void flist_delete_sitem(void) { if (selected_item >= item && selected_item < item + itemcount) { deleteitem(selected_item); } } void flist_delete_rmouse_item(void) { if (right_mouse_item >= item && right_mouse_item < item + itemcount) { deleteitem(right_mouse_item); } } void flist_freeall(void) { for (ITEM *i = item; i != item + itemcount; i++) { switch (i->type) { case ITEM_FRIEND: { friend_free(get_friend(i->id_number)); break; } case ITEM_GROUP: { group_free(get_group(i->id_number)); break; } case ITEM_FREQUEST: { friend_request_free(i->id_number); break; } default: { break; } } } itemcount = 0; showncount = 0; free(item); free(shown_list); } void flist_selectchat(int index) { if (index >= 0 && (unsigned)index < showncount) { show_page(&item[shown_list[index]]); } } void flist_reselect_current(void) { show_page(selected_item); } void flist_selectsettings(void) { show_page(&item_settings); } void flist_selectaddfriend(void) { show_page(&item_add); } void flist_selectswap(void) { show_page(&item_transfer); } /****************************************************************************** ****** Updated functions ****** ******************************************************************************/ static struct { ITEM_TYPE type; uint8_t * data; } push_pop; static void push_selected(void) { push_pop.type = selected_item->type; switch (push_pop.type) { case ITEM_NONE: case ITEM_SETTINGS: case ITEM_ADD: { return; } case ITEM_FRIEND: { push_pop.data = calloc(1, TOX_PUBLIC_KEY_SIZE); FRIEND *f = get_friend(selected_item->id_number); if (!f) { LOG_ERR("Flist", "id_number is out of sync with friend_list"); // TODO should this be an exit code? // It's a critical error that could do // a lot of damage return; } memcpy(push_pop.data, &f->id_bin, TOX_PUBLIC_KEY_SIZE); break; } case ITEM_FREQUEST: case ITEM_GROUP: case ITEM_GROUP_CREATE: { return; } } } static void pop_selected(void) { switch (push_pop.type) { case ITEM_NONE: case ITEM_SETTINGS: { show_page(&item_settings); return; } case ITEM_ADD: { show_page(&item_add); return; } case ITEM_FRIEND: { for (uint16_t i = 0; i < itemcount; ++i) { if (item[i].type == ITEM_FRIEND) { FRIEND *f = get_friend(item[i].id_number); if (memcmp(push_pop.data, &f->id_bin, TOX_PUBLIC_KEY_SIZE) == 0) { show_page(&item[i]); return; } } } show_page(&item_settings); break; } case ITEM_FREQUEST: case ITEM_GROUP: case ITEM_GROUP_CREATE: { show_page(&item_settings); return; } } } void flist_select_last(void) { /* -2 should be the last, -1 is the create group */ show_page(&item[itemcount - 2]); } void flist_dump_contacts(void) { push_selected(); flist_freeall(); } void flist_reload_contacts(void) { flist_start(); pop_selected(); } FRIEND *flist_get_friend(void) { if (flist_get_type() == ITEM_FRIEND) { return get_friend(selected_item->id_number); } return NULL; } FREQUEST *flist_get_frequest(void) { if (flist_get_type() == ITEM_FREQUEST) { return get_frequest(selected_item->id_number); } return NULL; } GROUPCHAT *flist_get_groupchat(void) { if (flist_get_type() == ITEM_GROUP) { return get_group(selected_item->id_number); } return NULL; } ITEM_TYPE flist_get_type(void) { return selected_item->type; } /** * @brief Extract string ToxId from Tox URI. * * @param str Null-terminated Tox URI. * @param tox_id Extracted ToxId; it has to be at least TOX_ADDRESS_SIZE * 2 + 1. * * @return True if success false otherwise. */ static bool get_tox_id_from_uri(const char *str, char *tox_id) { const char *tox_uri_scheme = "tox:"; const int tox_uri_scheme_length = 4; if (strncmp(str, tox_uri_scheme, tox_uri_scheme_length) == 0 && strlen(str) - tox_uri_scheme_length == TOX_ADDRESS_SIZE * 2) { memcpy(tox_id, &str[tox_uri_scheme_length], TOX_ADDRESS_SIZE * 2); tox_id[TOX_ADDRESS_SIZE * 2] = '\0'; return true; } return false; } bool try_open_tox_uri(const char *str) { char tox_id[TOX_ADDRESS_SIZE * 2 + 1]; if (!get_tox_id_from_uri(str, tox_id)) { return false; } FRIEND *friend = get_friend_by_id(tox_id); if (friend) { flist_selectchat(friend->number); } else if (tox_thread_init == UTOX_TOX_THREAD_INIT_SUCCESS) { edit_setstr(&edit_add_new_friend_id, tox_id, TOX_ADDRESS_SIZE * 2); edit_setstr(&edit_search, (char *)"", 0); flist_selectaddfriend(); edit_setfocus(&edit_add_new_friend_msg); } return true; } /****************************************************************************** ****** UI functions ****** ******************************************************************************/ void flist_draw(void *UNUSED(n), int x, int y, int width, int UNUSED(height)) { int real_height = 0; if (settings.use_mini_flist) { real_height = SCALE(ROSTER_BOX_HEIGHT / 2); } else { real_height = SCALE(ROSTER_BOX_HEIGHT); } ITEM *mi = NULL; // item being dragged int my; // y of item being dragged for (unsigned int i = 0; i < showncount; i++) { ITEM *it = &item[shown_list[i]]; if (it == selected_item && (selected_item_dy >= 5 || selected_item_dy <= -5)) { mi = it; my = y + selected_item_dy; } else { drawitem(it, x, y, width); } y += real_height; } if (mi) { drawitem(mi, x, my, width); } } bool flist_mmove(void *UNUSED(n), int UNUSED(x), int UNUSED(y), int UNUSED(width), int height, int mx, int my, int UNUSED(dx), int dy) { int real_height = 0; if (settings.use_mini_flist) { real_height = ROSTER_BOX_HEIGHT / 2; } else { real_height = ROSTER_BOX_HEIGHT; } ITEM *i = item_hit(mx, my, height); bool draw = false; if (i != mouseover_item) { mouseover_item = i; draw = true; } if (selected_item_mousedown) { // drag item selected_item_dy += dy; nitem = NULL; if (selected_item_mousedown_move_pend == true && (selected_item_dy >= 5 || selected_item_dy <= -5)) { selected_item_mousedown_move_pend = false; show_page(i); } if (abs(selected_item_dy) >= real_height / 2) { int d; // offset, in number of items, of where the dragged item is compared to where it started if (selected_item_dy > 0) { d = (selected_item_dy + real_height / 2) / real_height; } else { d = (selected_item_dy - real_height / 2) / real_height; } unsigned int index = find_item_shown_index(selected_item); if (index != INT_MAX) { // selected_item was found in shown list index += d; // get item being dragged over // set item being dragged over if (index < itemcount) { nitem = &item[shown_list[index]]; } } } draw = true; } else { tooltip_draw(); } return draw; } bool flist_mdown(void *UNUSED(n)) { tooltip_mdown(); /* may need to return on true */ if (mouseover_item) { // show_page(mouseover_item); selected_item_mousedown = true; selected_item_mousedown_move_pend = true; return true; } return false; } static void flist_init_friend_settings_page(void) { FRIEND *f = get_friend(right_mouse_item->id_number); panel_friend_chat.disabled = true; panel_friend_video.disabled = true; panel_friend_settings.disabled = false; edit_setstr(&edit_friend_pubkey, (char *)&f->id_str, TOX_PUBLIC_KEY_SIZE * 2); maybe_i18nal_string_set_plain(&edit_friend_alias.empty_str, f->name, f->name_length); edit_setstr(&edit_friend_alias, f->alias, f->alias_length); switch_friend_autoaccept_ft.switch_on = f->ft_autoaccept; } static void flist_init_group_settings_page(void) { GROUPCHAT *g = get_group(right_mouse_item->id_number); panel_group_chat.disabled = true; panel_group_video.disabled = true; panel_group_settings.disabled = false; edit_setstr(&edit_group_topic, g->name, g->name_length); dropdown_notify_groupchats.over = dropdown_notify_groupchats.selected = g->notify; } typedef enum { SHOW_SETTINGS, SHOW_INLINE_VID, CLEAR_HISTOR, DELETE_FRIEND, } FLIST_CONTEXT_MENU; static void contextmenu_friend(FLIST_CONTEXT_MENU rcase) { FRIEND *f = get_friend(right_mouse_item->id_number); panel_friend_chat.disabled = false; panel_friend_video.disabled = true; panel_friend_settings.disabled = true; switch (rcase) { case SHOW_SETTINGS: { /* should be settings page */ flist_init_friend_settings_page(); break; } case SHOW_INLINE_VID: { /* Should be show inline video */ panel_friend_chat.disabled = true; panel_friend_video.disabled = false; panel_friend_settings.disabled = true; settings.inline_video = true; f->video_inline = true; postmessage_utox(AV_CLOSE_WINDOW, f->number + 1, 0, NULL); break; } case CLEAR_HISTOR: { /* should be clean history */ friend_history_clear(get_friend(right_mouse_item->id_number)); break; } case DELETE_FRIEND: { /* Should be: delete friend */ panel_friend_chat.disabled = true; panel_friend_confirm_deletion.disabled = false; break; } } } static void contextmenu_list_onselect(uint8_t i) { if (right_mouse_item) { switch (right_mouse_item->type) { case ITEM_FRIEND: { contextmenu_friend(i); return; } case ITEM_GROUP: { panel_group_chat.disabled = false; GROUPCHAT *g = get_group(right_mouse_item->id_number); if (i == 0) { flist_init_group_settings_page(); } else if (i == 1) { if (right_mouse_item != selected_item) { show_page(right_mouse_item); } char str[g->name_length + 7]; strcpy(str, "/topic "); memcpy(str + 7, g->name, g->name_length); edit_setfocus(&edit_chat_msg_group); edit_paste(str, sizeof(str), 0); } else if (i == 2 && g->av_group) { g->muted = !g->muted; } else { flist_delete_rmouse_item(); } return; } case ITEM_FREQUEST: { FREQUEST *req = get_frequest(right_mouse_item->id_number); if (!req) { LOG_ERR("F-List", "Could not get friend request number: %u", right_mouse_item->id_number); return; } if (i == 0) { postmessage_toxcore(TOX_FRIEND_ACCEPT, 0, 0, req); } else { flist_delete_rmouse_item(); } return; } default: { LOG_TRACE("F-List", "blerg" ); return; } } } else { if (i) { postmessage_toxcore(TOX_GROUP_CREATE, 0, 0, NULL); } else { show_page(&item_add); } } } bool flist_mright(void *UNUSED(n)) { static UTOX_I18N_STR menu_friend[] = { STR_FRIEND_SETTINGS, STR_CALL_VIDEO_SHOW_INLINE, STR_CLEAR_HISTORY, STR_REMOVE_FRIEND }; static UTOX_I18N_STR menu_group_unmuted[] = { STR_GROUPCHAT_SETTINGS, STR_CHANGE_GROUP_TOPIC, STR_MUTE, STR_REMOVE_GROUP }; static UTOX_I18N_STR menu_group_muted[] = { STR_GROUPCHAT_SETTINGS, STR_CHANGE_GROUP_TOPIC, STR_UNMUTE, STR_REMOVE_GROUP }; static UTOX_I18N_STR menu_group[] = { STR_GROUPCHAT_SETTINGS, STR_CHANGE_GROUP_TOPIC, STR_REMOVE_GROUP }; static UTOX_I18N_STR menu_request[] = { STR_REQ_ACCEPT, STR_REQ_DECLINE }; if (mouseover_item) { right_mouse_item = mouseover_item; switch (mouseover_item->type) { case ITEM_FRIEND: { contextmenu_new(COUNTOF(menu_friend), menu_friend, contextmenu_list_onselect); show_page(mouseover_item); break; } case ITEM_GROUP: { GROUPCHAT *g = get_group(mouseover_item->id_number); if (g->av_group) { if (g->muted) { contextmenu_new(COUNTOF(menu_group_muted), menu_group_muted, contextmenu_list_onselect); } else { contextmenu_new(COUNTOF(menu_group_unmuted), menu_group_unmuted, contextmenu_list_onselect); } } else { contextmenu_new(COUNTOF(menu_group), menu_group, contextmenu_list_onselect); } show_page(mouseover_item); break; } case ITEM_GROUP_CREATE: { break; } case ITEM_FREQUEST: { contextmenu_new(COUNTOF(menu_request), menu_request, contextmenu_list_onselect); break; } default: { LOG_ERR("F-List", "MRIGHT on a flist entry that shouldn't exist!"); break; } } return true; } else if (mouse_in_list) { right_mouse_item = NULL; /* Unset right_mouse_item so that we don't interact with the incorrect context menu * I'm not sure if this belongs here or in flist_mmove, or maybe item_hit. */ } return false; } bool flist_mwheel(void *UNUSED(n), int UNUSED(height), double UNUSED(d), bool UNUSED(smooth)) { return false; } bool flist_mup(void *UNUSED(n)) { bool draw = false; tooltip_mup(); /* may need to return one true */ if (mouseover_item && selected_item_mousedown_move_pend == true) { show_page(mouseover_item); draw = true; } if (selected_item_mousedown && abs(selected_item_dy) >= 5) { if (nitem && find_item_shown_index(nitem) != INT_MAX) { if (selected_item->type == ITEM_FRIEND) { if (nitem->type == ITEM_FRIEND) { ITEM temp = *selected_item; *selected_item = *nitem; *nitem = temp; selected_item = nitem; } if (nitem->type == ITEM_GROUP) { FRIEND *f = get_friend(selected_item->id_number); GROUPCHAT *g = get_group(nitem->id_number); if (f->online) { postmessage_toxcore(TOX_GROUP_SEND_INVITE, g->number, f->number, NULL); } } } if (selected_item->type == ITEM_GROUP) { if (nitem->type == ITEM_FRIEND || nitem->type == ITEM_GROUP) { ITEM temp = *selected_item; *selected_item = *nitem; *nitem = temp; selected_item = nitem; } } nitem = NULL; } draw = true; } selected_item_mousedown = 0; selected_item_mousedown_move_pend = 0; selected_item_dy = 0; return draw; } bool flist_mleave(void *UNUSED(n)) { if (mouseover_item) { mouseover_item = NULL; return true; } return false; } uTox-0.17.1/src/flist.h000066400000000000000000000046201354126257400146330ustar00rootroot00000000000000#ifndef FLIST_H #define FLIST_H #include #include typedef struct groupchat GROUPCHAT; typedef struct utox_friend FRIEND; typedef struct utox_friend_request FREQUEST; // call to switch to previous or next friend in list void flist_previous_tab(void); void flist_next_tab(void); // update the shown list, should be called whenever something relevant to the filters is done // (like changing name, going online, etc.) void flist_update_shown_list(void); // set or get current list filter. Updates list afterwards uint8_t flist_get_filter(void); void flist_set_filter(uint8_t filter); // set the search string in the list. Disable search by setting it to NULL. Updates list afterwards // warning: list will just remember the pointer, it will assume you won't deallocate the memory, and it // won't deallocate it after setting to NULL. The string should be NULL-terminated. void flist_search(char *str); /* non-exhaustive list of panels we to select from, it's probably better to replace this but I don't know with what. */ typedef enum { ITEM_NONE, ITEM_SETTINGS, ITEM_ADD, ITEM_FRIEND, ITEM_FREQUEST, ITEM_GROUP, ITEM_GROUP_CREATE, } ITEM_TYPE; typedef struct { ITEM_TYPE type; uint32_t id_number; } ITEM; void flist_start(void); void flist_add_friend(FRIEND *f, const char *msg, const int msg_length); void flist_add_friend_accepted(FRIEND *f, FREQUEST *req); void flist_add_group(GROUPCHAT *g); void flist_add_frequest(FREQUEST *f); void flist_delete_sitem(void); void flist_delete_rmouse_item(void); void flist_selectchat(int index); void flist_selectaddfriend(void); void flist_reselect_current(void); void flist_selectsettings(void); void flist_selectswap(void); void flist_re_scale(void); void flist_freeall(void); /* New naming patten */ void flist_select_last(void); void flist_dump_contacts(void); void flist_reload_contacts(void); FRIEND *flist_get_friend(void); FREQUEST *flist_get_frequest(void); GROUPCHAT *flist_get_groupchat(void); ITEM_TYPE flist_get_type(void); bool try_open_tox_uri(const char *str); /* UI functions */ void flist_draw(void *n, int x, int y, int width, int height); bool flist_mmove(void *n, int x, int y, int width, int height, int mx, int my, int dx, int dy); bool flist_mdown(void *n); bool flist_mright(void *n); bool flist_mwheel(void *n, int height, double d, bool smooth); bool flist_mup(void *n); bool flist_mleave(void *n); #endif uTox-0.17.1/src/friend.c000066400000000000000000000445721354126257400147660ustar00rootroot00000000000000#include "friend.h" #include "avatar.h" #include "chatlog.h" #include "debug.h" #include "filesys.h" #include "flist.h" #include "macros.h" #include "self.h" #include "settings.h" #include "text.h" #include "tox.h" #include "utox.h" #include "av/audio.h" #include "layout/friend.h" // TODO, remove this and sent the name differently #include "native/image.h" #include "native/notify.h" #include "ui/edit.h" // friend_set_name() #include #include static FRIEND *friend = NULL; FRIEND *get_friend(uint32_t friend_number) { if (friend_number >= self.friend_list_size) { //friend doesnt exist if true LOG_WARN("Friend", "Friend number (%u) out of bounds.", friend_number); return NULL; } return &friend[friend_number]; } static FRIEND *friend_make(uint32_t friend_number) { if (friend_number >= self.friend_list_size) { LOG_INFO("Friend", "Reallocating friend array to %u. Current size: %u", (friend_number + 1), self.friend_list_size); FRIEND *tmp = realloc(friend, sizeof(FRIEND) * (friend_number + 1)); if (!tmp) { LOG_ERR("Friend", "Could not reallocate friends array."); return NULL; } friend = tmp; self.friend_list_size = friend_number + 1; } // TODO should we memset(0); before return? return &friend[friend_number]; } static FREQUEST *frequests = NULL; static uint16_t frequest_list_size = 0; FREQUEST *get_frequest(uint16_t frequest_number) { if (frequest_number >= frequest_list_size) { //frequest doesnt exist if true LOG_ERR("Friend", "Request number out of bounds."); return NULL; } return &frequests[frequest_number]; } static FREQUEST *frequest_make(uint16_t frequest_number) { if (frequest_number >= frequest_list_size) { LOG_INFO("Friend", "Reallocating frequest array to %u. Current size: %u", (frequest_number + 1), frequest_list_size); FREQUEST *tmp = realloc(frequests, sizeof(FREQUEST) * (frequest_number + 1)); if (!tmp) { LOG_ERR("Friend", "Could not reallocate frequests array."); return NULL; } frequests = tmp; frequest_list_size = frequest_number + 1; } // TODO should we memset(0); before return? return &frequests[frequest_number]; } uint16_t friend_request_new(const uint8_t *id, const uint8_t *msg, size_t length) { uint16_t curr_num = frequest_list_size; FREQUEST *r = frequest_make(frequest_list_size); // TODO search for empty request slots if (!r) { LOG_ERR("Friend", "Unable to get space for Friend Request."); return UINT16_MAX; } r->number = curr_num; memcpy(r->bin_id, id, TOX_ADDRESS_SIZE); r->msg = malloc(length + 1); if (!r->msg) { LOG_ERR("Friend", "Unable to get space for friend request message."); return UINT16_MAX; } memcpy(r->msg, msg, length); r->msg[length] = 0; // Toxcore doesn't promise null term on strings r->length = length; return curr_num; } void friend_request_free(uint16_t number) { FREQUEST *r = get_frequest(number); if (!r) { LOG_ERR("Friend", "Unable to free a missing request."); return; } free(r->msg); // TODO this needs a test if (r->number >= frequest_list_size -1) { FREQUEST *tmp = realloc(frequests, sizeof(FREQUEST) * (frequest_list_size - 1)); if (tmp) { frequests = tmp; --frequest_list_size; } } } /* TODO incoming friends "leaks" */ void free_friends(void) { for (uint32_t i = 0; i < self.friend_list_count; i++){ FRIEND *f = get_friend(i); if (!f) { LOG_WARN("Friend", "Could not get friend %u. Skipping", i); continue; } friend_free(f); } if (friend) { free(friend); } } void utox_write_metadata(FRIEND *f) { /* Create path */ char dest[UTOX_FILE_NAME_LENGTH]; snprintf(dest, UTOX_FILE_NAME_LENGTH, "%.*s.fmetadata", TOX_PUBLIC_KEY_SIZE * 2, f->id_str); FILE *file = utox_get_file(dest, NULL, UTOX_FILE_OPTS_WRITE); if (!file) { LOG_ERR("Friend", "Unable to get file to write metadata for friend %u", f->number); return; } FRIEND_META_DATA metadata = { 0 }; size_t total_size = sizeof(metadata); metadata.version = METADATA_VERSION; metadata.ft_autoaccept = f->ft_autoaccept; metadata.skip_msg_logging = f->skip_msg_logging; if (f->alias && f->alias_length) { metadata.alias_length = f->alias_length; total_size += metadata.alias_length; } uint8_t *data = calloc(1, total_size); if (data) { memcpy(data, &metadata, sizeof(metadata)); if (f->alias && f->alias_length) { memcpy(data + sizeof(metadata), f->alias, metadata.alias_length); } fwrite(data, total_size, 1, file); free(data); } fclose(file); } static void friend_meta_data_read(FRIEND *f) { /* Will need to be rewritten if anything is added to friend's meta data */ char path[UTOX_FILE_NAME_LENGTH]; snprintf(path, UTOX_FILE_NAME_LENGTH, "%.*s.fmetadata", TOX_PUBLIC_KEY_SIZE * 2, f->id_str); size_t size = 0; FILE *file = utox_get_file(path, &size, UTOX_FILE_OPTS_READ); if (!file) { LOG_TRACE("Friend", "Meta Data not found %s", path); return; } if (size < sizeof(FRIEND_META_DATA)) { LOG_ERR("Metadata", "Stored metadata is incomplete."); fclose(file); return; } FRIEND_META_DATA *metadata = calloc(1, size); if (!metadata) { LOG_ERR("Metadata", "Could not allocate memory for metadata." ); fclose(file); return; } bool read_meta = fread(metadata, size, 1, file); fclose(file); if (!read_meta) { LOG_ERR("Metadata", "Failed to read metadata from disk."); free(metadata); return; } if (metadata->version != 0) { LOG_ERR("Metadata", "WARNING! This version of utox does not support this metadata file version." ); free(metadata); return; } if (metadata->alias_length) { friend_set_alias(f, &metadata->data[0], metadata->alias_length); } else { friend_set_alias(f, NULL, 0); /* uTox expects this to be 0/NULL if there's no alias. */ } f->ft_autoaccept = metadata->ft_autoaccept; free(metadata); return; } void utox_friend_init(Tox *tox, uint32_t friend_number) { LOG_INFO("Friend", "Initializing friend: %u", friend_number); FRIEND *f = friend_make(friend_number); // get friend pointer if (!f) { LOG_ERR("Friend", "Could not create init friend %u", friend_number); return; } self.friend_list_count++; uint8_t name[TOX_MAX_NAME_LENGTH]; memset(f, 0, sizeof(FRIEND)); // Get and set the public key for this friend number and set it. tox_friend_get_public_key(tox, friend_number, f->id_bin, 0); cid_to_string(f->id_str, f->id_bin); // Set the friend number we got from toxcore f->number = friend_number; // Get and set friend name and length int size = tox_friend_get_name_size(tox, friend_number, 0); tox_friend_get_name(tox, friend_number, name, 0); // Set the name for utox as well friend_setname(f, name, size); // Get and set the status message size = tox_friend_get_status_message_size(tox, friend_number, 0); f->status_message = calloc(1, size); if (!f->status_message) { LOG_FATAL_ERR(EXIT_MALLOC, "Friend", "Could not alloc for status message (%uB)", size); } tox_friend_get_status_message(tox, friend_number, (uint8_t *)f->status_message, 0); f->status_length = size; /* TODO; consider error handling these two */ f->online = tox_friend_get_connection_status(tox, friend_number, NULL); f->status = tox_friend_get_status(tox, friend_number, NULL); f->avatar = calloc(1, sizeof(AVATAR)); if (!f->avatar) { LOG_FATAL_ERR(EXIT_MALLOC, "Friend", "Could not alloc for avatar"); } avatar_init(f->id_str, f->avatar); MESSAGES *m = &f->msg; messages_init(m, friend_number); // Set scroll position to bottom of window. f->msg.scroll = 1.0; f->msg.panel.type = PANEL_MESSAGES; f->msg.panel.content_scroll = &scrollbar_friend; f->msg.panel.y = MAIN_TOP; f->msg.panel.height = CHAT_BOX_TOP; f->msg.panel.width = -SCROLL_WIDTH; // Get the chat backlog messages_read_from_log(friend_number); // Load the meta data, if it exists. friend_meta_data_read(f); } void utox_friend_list_init(Tox *tox) { LOG_INFO("Friend", "Initializing friend list."); self.friend_list_size = tox_self_get_friend_list_size(tox); friend = calloc(self.friend_list_size, sizeof(FRIEND)); if (!friend) { LOG_FATAL_ERR(EXIT_MALLOC, "Friend", "Could not allocate friend list with size: %u", self.friend_list_size); } for (uint32_t i = 0; i < self.friend_list_size; ++i) { utox_friend_init(tox, i); } LOG_INFO("Friend", "Friendlist sucessfully initialized with %u friends.", self.friend_list_size); } void friend_setname(FRIEND *f, uint8_t *name, size_t length) { if (f->name && f->name_length) { char *p; size_t p_size = sizeof(" is now known as ") + f->name_length + length; p = calloc(1, p_size); if (!p) { LOG_FATAL_ERR(EXIT_MALLOC, "Friend", "Could not alloc space for name change message (%uB)", p_size); } snprintf(p, p_size, "%.*s is now known as %.*s", (int)f->name_length, f->name, (int)length, name); size_t p_len = strnlen(p, p_size - 1); if (length != f->name_length || memcmp(f->name, name, (length < f->name_length ? length : f->name_length))) { message_add_type_notice(&f->msg, p, p_len, 1); } free(f->name); free(p); } if (length == 0) { f->name = calloc(1, TOX_PUBLIC_KEY_SIZE * 2 + 1); cid_to_string(f->name, f->id_bin); f->name_length = TOX_PUBLIC_KEY_SIZE * 2; } else { f->name = calloc(1, length + 1); memcpy(f->name, name, length); f->name_length = length; } if (!f->name) { LOG_FATAL_ERR(EXIT_MALLOC, "Friend", "Could not alloc space for friend name"); } f->name[f->name_length] = '\0'; if (!f->alias_length) { if (flist_get_type()== ITEM_FRIEND) { FRIEND *selected = flist_get_friend(); if (!selected) { LOG_ERR("Friend", "Unable to get selected friend."); return; } if (selected && f->number == selected->number) { maybe_i18nal_string_set_plain(&edit_friend_alias.empty_str, f->name, f->name_length); } } } flist_update_shown_list(); } void friend_set_alias(FRIEND *f, uint8_t *alias, uint16_t length) { if (length > 0) { if (!alias) { LOG_ERR("Friend Alias", "Got alias length, but no alias."); return; } LOG_TRACE("Friend", "New Alias set for friend %s." , f->name); } else { LOG_TRACE("Friend", "Alias for friend %s unset." , f->name); } free(f->alias); if (length == 0) { f->alias = NULL; f->alias_length = 0; } else { f->alias = calloc(1, length + 1); if (!f->alias) { LOG_ERR("Friend", "Unable to malloc for alias set for friend %s."); return; } memcpy(f->alias, alias, length); f->alias_length = length; } } void friend_sendimage(FRIEND *f, NATIVE_IMAGE *native_image, uint16_t width, uint16_t height, UTOX_IMAGE png_image, size_t png_size) { struct TOX_SEND_INLINE_MSG *tsim = malloc(sizeof(struct TOX_SEND_INLINE_MSG)); if (!tsim) { LOG_ERR("Friend", "Unable to malloc for inline image."); return; } tsim->image = png_image; tsim->image_size = png_size; postmessage_toxcore(TOX_FILE_SEND_NEW_INLINE, f - friend, 0, tsim); message_add_type_image(&f->msg, 1, native_image, width, height, 0); } void friend_recvimage(FRIEND *f, NATIVE_IMAGE *native_image, uint16_t width, uint16_t height) { if (!NATIVE_IMAGE_IS_VALID(native_image)) { return; } message_add_type_image(&f->msg, 0, native_image, width, height, 0); } void friend_notify_msg(FRIEND *f, const char *msg, size_t msg_length) { char title[sizeof("uTox new message from ") + UTOX_FRIEND_NAME_LENGTH(f)]; snprintf((char *)title, sizeof(title), "uTox new message from %.*s", (int)UTOX_FRIEND_NAME_LENGTH(f), UTOX_FRIEND_NAME(f)); size_t title_length = strnlen(title, sizeof(title) - 1); postmessage_utox(FRIEND_MESSAGE, f->number, 0, NULL); notify(title, title_length, msg, msg_length, f, 0); if (flist_get_friend() != f) { f->unread_msg = true; } if (flist_get_friend() != f || !have_focus) { postmessage_audio(UTOXAUDIO_PLAY_NOTIFICATION, NOTIFY_TONE_FRIEND_NEW_MSG, 0, NULL); } } bool friend_set_online(FRIEND *f, bool online) { if (f->online == online) { return false; } f->online = online; if (!f->online) { friend_set_typing(f, 0); } flist_update_shown_list(); return true; } void friend_set_typing(FRIEND *f, int typing) { f->typing = typing; } void friend_addid(uint8_t *id, char *msg, uint16_t msg_length) { char *data = malloc(TOX_ADDRESS_SIZE + msg_length); if (!data) { LOG_ERR("Friend", "Unable to malloc for friend request."); return; } memcpy(data, id, TOX_ADDRESS_SIZE); memcpy(data + TOX_ADDRESS_SIZE, msg, msg_length); postmessage_toxcore(TOX_FRIEND_NEW, msg_length, 0, data); } void friend_add(char *name, uint16_t length, char *msg, uint16_t msg_length) { if (!length) { addfriend_status = ADDF_NONAME; return; } uint8_t name_cleaned[length]; uint16_t length_cleaned = 0; for (unsigned int i = 0; i < length; ++i) { if (name[i] != ' ') { name_cleaned[length_cleaned] = name[i]; ++length_cleaned; } } if (!length_cleaned) { addfriend_status = ADDF_NONAME; return; } uint8_t id[TOX_ADDRESS_SIZE]; if (length_cleaned == TOX_ADDRESS_SIZE * 2 && string_to_id(id, (char *)name_cleaned)) { friend_addid(id, msg, msg_length); } else if (length_cleaned == TOX_PUBLIC_KEY_SIZE * 2) { string_to_id(id, (char*)name_cleaned); uint8_t *data = calloc(sizeof(uint8_t), TOX_PUBLIC_KEY_SIZE); if (!data) { LOG_ERR("Calloc", "Memory allocation failed!"); return; } memcpy(data, id, TOX_PUBLIC_KEY_SIZE); postmessage_toxcore(TOX_FRIEND_NEW_NO_REQ, TOX_PUBLIC_KEY_SIZE, 0, data); addfriend_status = ADDF_NOFREQUESTSENT; } else { addfriend_status = ADDF_BADNAME; } } void friend_history_clear(FRIEND *f) { if (!f) { LOG_ERR("Friend", "Unable to clear history for missing friend."); return; } messages_clear_all(&f->msg); utox_remove_friend_chatlog(f->id_str); } void friend_free(FRIEND *f) { LOG_INFO("Friend", "Freeing friend: %u", f->number); for (uint16_t i = 0; i < f->edit_history_length; ++i) { free(f->edit_history[i]); f->edit_history[i] = NULL; } free(f->edit_history); free(f->name); free(f->status_message); free(f->typed); free(f->avatar); for (uint32_t i = 0; i < f->msg.number; ++i) { MSG_HEADER *msg = f->msg.data[i]; message_free(msg); } free(f->msg.data); if (f->call_state_self) { // postmessage_audio(AUDIO_END, f->number, 0, NULL); /* TODO end a video call too! if(f->calling == CALL_OK_VIDEO) { postmessage_video(VIDEO_CALL_END, f->number, 0, NULL); }*/ } memset(f, 0, sizeof(FRIEND)); self.friend_list_count--; } FRIEND *find_friend_by_name(uint8_t *name) { for (size_t i = 0; i < self.friend_list_count; i++) { FRIEND *f = get_friend(i); if (!f) { LOG_ERR("Friend", "Could not get friend %u", i); continue; } if ((f->alias && memcmp(f->alias, name, MIN(f->alias_length, strlen((char *)name))) == 0) || memcmp(f->name, name, MIN(f->name_length, strlen((char *)name))) == 0) { return f; } } return NULL; } FRIEND *get_friend_by_id(const char *id_str) { for (size_t i = 0; i < self.friend_list_count; i++) { FRIEND *f = get_friend(i); if (!f) { LOG_ERR("Friend", "Could not get friend %u", i); continue; } if (strncmp(f->id_str, id_str, TOX_PUBLIC_KEY_SIZE * 2) == 0) { return f; } } return NULL; } void friend_notify_status(FRIEND *f, const uint8_t *msg, size_t msg_length, char *state) { if (!settings.status_notifications) { return; } char title[UTOX_FRIEND_NAME_LENGTH(f) + SLEN(STATUS_MESSAGE) + strlen(state)]; snprintf(title, sizeof(title), S(STATUS_MESSAGE), (int)UTOX_FRIEND_NAME_LENGTH(f), UTOX_FRIEND_NAME(f), state); size_t title_length = strnlen(title, sizeof(title) - 1); notify(title, title_length, (char *)msg, msg_length, f, 0); /* This function is called before the status is changed. so we have to go by the inverse * obviously not ideal, TODO fix later with the friends struct refactor. */ if (f->online) { postmessage_audio(UTOXAUDIO_PLAY_NOTIFICATION, NOTIFY_TONE_FRIEND_OFFLINE, 0, NULL); } else { postmessage_audio(UTOXAUDIO_PLAY_NOTIFICATION, NOTIFY_TONE_FRIEND_ONLINE, 0, NULL); } } bool string_to_id(uint8_t *w, char *a) { uint8_t *end = w + TOX_ADDRESS_SIZE; while (w != end) { char c, v; c = *a++; if (c >= '0' && c <= '9') { v = (c - '0') << 4; } else if (c >= 'A' && c <= 'F') { v = (c - 'A' + 10) << 4; } else if (c >= 'a' && c <= 'f') { v = (c - 'a' + 10) << 4; } else { return false; } c = *a++; if (c >= '0' && c <= '9') { v |= (c - '0'); } else if (c >= 'A' && c <= 'F') { v |= (c - 'A' + 10); } else if (c >= 'a' && c <= 'f') { v |= (c - 'a' + 10); } else { return false; } *w++ = v; } return true; } void cid_to_string(char *dest, uint8_t *src) { to_hex(dest, src, TOX_PUBLIC_KEY_SIZE); } uTox-0.17.1/src/friend.h000066400000000000000000000116171354126257400147650ustar00rootroot00000000000000#ifndef FRIEND_H #define FRIEND_H #include "messages.h" #include typedef struct avatar AVATAR; typedef struct edit_change EDIT_CHANGE; typedef struct file_transfer FILE_TRANSFER; typedef uint8_t *UTOX_IMAGE; typedef unsigned int ALuint; typedef enum { ADDF_NONE, ADDF_SENT, ADDF_DISCOVER, ADDF_BADNAME, // either invalid tox id or just friend's public key (missing nospam) ADDF_NONAME, ADDF_TOOLONG, // if message length is too long. ADDF_NOMESSAGE, // if no message (message length must be >= 1 byte). ADDF_OWNKEY, // if user's own key. ADDF_ALREADYSENT, // if friend request already sent or already a friend. ADDF_UNKNOWN, // for unknown error. ADDF_BADCHECKSUM, // if bad checksum in address. ADDF_SETNEWNOSPAM, // if the friend was already there but the nospam was different. ADDF_NOMEM, // if increasing the friend list size fails. ADDF_NOFREQUESTSENT, // friend added but no frequest sent } DNS_STATE; typedef struct friend_meta_data { uint8_t version; uint8_t ft_autoaccept : 1; uint8_t ft_autoaccept_path : 1; uint8_t skip_msg_logging : 1; uint8_t unused : 5; uint8_t zero[30]; size_t alias_length; size_t ft_autoaccept_path_length; uint8_t data[]; } FRIEND_META_DATA; #define METADATA_VERSION 0 typedef struct friend_meta_data_old { size_t alias_length; uint8_t data[]; } FRIEND_META_DATA_OLD; #define TOX_FRIEND_ID_STR_SIZE TOX_PUBLIC_KEY_SIZE * 2 typedef struct utox_friend { uint8_t id_bin[TOX_PUBLIC_KEY_SIZE]; char id_str[TOX_FRIEND_ID_STR_SIZE]; uint8_t number; char *name; char *alias; char *status_message; uint8_t *typed; size_t name_length; size_t alias_length; size_t status_length; size_t typed_length; /* Friend Status */ uint8_t status; bool online; bool typing; bool video_inline; AVATAR *avatar; /* Messages */ bool skip_msg_logging; bool unread_msg; MESSAGES msg; EDIT_CHANGE **edit_history; uint16_t edit_history_cur, edit_history_length; /* Audio / Video */ int32_t call_state_self, call_state_friend; uint16_t video_width, video_height; ALuint audio_dest; time_t call_started; /* File transfers */ bool ft_autoaccept; FILE_TRANSFER *ft_incoming; uint16_t ft_incoming_size; uint16_t ft_incoming_active_count; FILE_TRANSFER *ft_outgoing; uint16_t ft_outgoing_size; uint16_t ft_outgoing_active_count; } FRIEND; typedef struct utox_friend_request { uint16_t number; uint8_t bin_id[TOX_ADDRESS_SIZE]; char *msg; size_t length; } FREQUEST; // add friend page uint8_t addfriend_status; #define UTOX_FRIEND_NAME(f) ((f->alias) ? f->alias : f->name) #define UTOX_FRIEND_NAME_LENGTH(f) ((f->alias) ? f->alias_length : f->name_length) /* * Gets the friend at position friend_number */ FRIEND *get_friend(uint32_t friend_number); FRIEND *get_friend_by_id(const char *id_str); FREQUEST *get_frequest(uint16_t frequest_number); /* Add a new friend request */ uint16_t friend_request_new(const uint8_t *id, const uint8_t *msg, size_t length); void friend_request_free(uint16_t number); /* * Frees all of your friends */ void free_friends(void); void utox_friend_init(Tox *tox, uint32_t friend_number); void utox_friend_list_init(Tox *tox); void friend_setname(FRIEND *f, uint8_t *name, size_t length); void friend_set_alias(FRIEND *f, uint8_t *alias, uint16_t length); void friend_sendimage(FRIEND *f, NATIVE_IMAGE *native_image, uint16_t width, uint16_t height, UTOX_IMAGE png_image, size_t png_size); void friend_recvimage(FRIEND *f, NATIVE_IMAGE *native_image, uint16_t width, uint16_t height); void friend_notify_msg(FRIEND *f, const char *msg, size_t msg_length); /* set friend online status. Returns: true if status changed, false otherwise */ bool friend_set_online(FRIEND *f, bool online); void friend_set_typing(FRIEND *f, int typing); void friend_addid(uint8_t *id, char *msg, uint16_t msg_length); void friend_add(char *name, uint16_t length, char *msg, uint16_t msg_length); void friend_history_clear(FRIEND *f); void friend_free(FRIEND *f); /* Searches for a friend using the specified name */ FRIEND *find_friend_by_name(uint8_t *name); /* Notifies the user that a friend is online or offline */ void friend_notify_status(FRIEND *f, const uint8_t *msg, size_t msg_length, char *state); // Saves user meta data to disk void utox_write_metadata(FRIEND *f); /** convert string to tox id * on success: returns 1 * on failure: returns 0 * notes: dest must be TOX_FRIEND_ADDRESS_SIZE bytes large, some data may be written to dest even on failure */ bool string_to_id(uint8_t *dest, char *src); /* same as id_to_string(), but for TOX_PUBLIC_KEY_SIZE */ void cid_to_string(char *dest, uint8_t *src); #endif uTox-0.17.1/src/groups.c000066400000000000000000000267671354126257400150440ustar00rootroot00000000000000#include "groups.h" #include "flist.h" #include "debug.h" #include "macros.h" #include "self.h" #include "settings.h" #include "text.h" #include "av/audio.h" #include "av/utox_av.h" #include "native/notify.h" #include "ui/edit.h" #include "layout/group.h" #include #include #include #include static GROUPCHAT *group = NULL; GROUPCHAT *get_group(uint32_t group_number) { if (group_number >= self.groups_list_size) { LOG_ERR("get_group", " index: %u is out of bounds." , group_number); return NULL; } return &group[group_number]; } /* * Create a new slot for the group if group_number is greater than self.groups_list_size and return a pointer to it * If group_number is less than self.groups_list_size return a pointer to that slot */ static GROUPCHAT *group_make(uint32_t group_number) { if (group_number >= self.groups_list_size) { LOG_INFO("Groupchats", "Reallocating groupchat array to %u. Current size: %u", (group_number + 1), self.groups_list_size); GROUPCHAT *tmp = realloc(group, sizeof(GROUPCHAT) * (group_number + 1)); if (!tmp) { LOG_FATAL_ERR(EXIT_MALLOC, "Groupchats", "Could not reallocate groupchat array to %u.", group_number + 1); } group = tmp; self.groups_list_size++; } memset(&group[group_number], 0, sizeof(GROUPCHAT)); return &group[group_number]; } bool group_create(uint32_t group_number, bool av_group) { GROUPCHAT *g = group_make(group_number); if (!g) { LOG_ERR("Groupchats", "Could not get/create group %u", group_number); return false; } group_init(g, group_number, av_group); return true; } void group_init(GROUPCHAT *g, uint32_t group_number, bool av_group) { pthread_mutex_lock(&messages_lock); /* make sure that messages has posted before we continue */ if (!g->peer) { g->peer = calloc(UTOX_MAX_GROUP_PEERS, sizeof(GROUP_PEER *)); if (!g->peer) { LOG_FATAL_ERR(EXIT_MALLOC, "Groupchats", "Could not alloc for group peers (%uB)", UTOX_MAX_GROUP_PEERS * sizeof(GROUP_PEER *)); } } snprintf((char *)g->name, sizeof(g->name), "Groupchat #%u", group_number); g->name_length = strnlen(g->name, sizeof(g->name) - 1); g->topic_length = sizeof("Drag friends to invite them") - 1; memcpy(g->topic, "Drag friends to invite them", sizeof("Drag friends to invite them") - 1); g->msg.scroll = 1.0; g->msg.panel.type = PANEL_MESSAGES; g->msg.panel.content_scroll = &scrollbar_group; g->msg.panel.y = MAIN_TOP; g->msg.panel.height = CHAT_BOX_TOP; g->msg.panel.width = -SCROLL_WIDTH; g->msg.is_groupchat = true; g->number = group_number; g->notify = settings.group_notifications; g->av_group = av_group; pthread_mutex_unlock(&messages_lock); self.groups_list_count++; } uint32_t group_add_message(GROUPCHAT *g, uint32_t peer_id, const uint8_t *message, size_t length, uint8_t m_type) { pthread_mutex_lock(&messages_lock); /* make sure that messages has posted before we continue */ if (peer_id >= UTOX_MAX_GROUP_PEERS) { LOG_ERR("Groupchats", "Unable to add message from peer %u - peer id too large.", peer_id); pthread_mutex_unlock(&messages_lock); return UINT32_MAX; } const GROUP_PEER *peer = g->peer[peer_id]; if (!peer) { LOG_ERR("Groupchats", "Unable to get peer %u for adding message.", peer_id); pthread_mutex_unlock(&messages_lock); return UINT32_MAX; } MSG_HEADER *msg = calloc(1, sizeof(MSG_HEADER)); if (!msg) { LOG_ERR("Groupchats", "Unable to allocate memory for message header."); pthread_mutex_unlock(&messages_lock); return UINT32_MAX; } msg->our_msg = (g->our_peer_number == peer_id ? true : false); msg->msg_type = m_type; msg->via.grp.length = length; msg->via.grp.author_id = peer_id; msg->via.grp.author_length = peer->name_length; msg->via.grp.author_color = peer->name_color; time(&msg->time); msg->via.grp.author = calloc(1, peer->name_length); if (!msg->via.grp.author) { LOG_ERR("Groupchat", "Unable to allocate space for author nickname."); free(msg); pthread_mutex_unlock(&messages_lock); return UINT32_MAX; } memcpy(msg->via.grp.author, peer->name, peer->name_length); msg->via.grp.msg = calloc(1, length); if (!msg->via.grp.msg) { LOG_ERR("Groupchat", "Unable to allocate space for message."); free(msg->via.grp.author); free(msg); pthread_mutex_unlock(&messages_lock); return UINT32_MAX; } memcpy(msg->via.grp.msg, message, length); pthread_mutex_unlock(&messages_lock); MESSAGES *m = &g->msg; return message_add_group(m, msg); } void group_peer_add(GROUPCHAT *g, uint32_t peer_id, bool UNUSED(our_peer_number), uint32_t name_color) { pthread_mutex_lock(&messages_lock); /* make sure that messages has posted before we continue */ if (!g->peer) { g->peer = calloc(UTOX_MAX_GROUP_PEERS, sizeof(GROUP_PEER *)); if (!g->peer) { LOG_FATAL_ERR(EXIT_MALLOC, "Groupchats", "Could not alloc for group peers (%uB)", UTOX_MAX_GROUP_PEERS * sizeof(GROUP_PEER *)); } LOG_NOTE("Groupchat", "Needed to calloc peers for this group chat. (%u)" , peer_id); } const char *default_peer_name = ""; // Allocate space for the struct and the dynamic array holding the peer's name. GROUP_PEER *peer = calloc(1, sizeof(GROUP_PEER) + strlen(default_peer_name) + 1); if (!peer) { LOG_FATAL_ERR(EXIT_MALLOC, "Groupchat", "Unable to allocate space for group peer."); } strcpy2(peer->name, default_peer_name); peer->name_length = 0; peer->name_color = name_color; peer->id = peer_id; g->peer[peer_id] = peer; g->peer_count++; if (g->av_group) { group_av_peer_add(g, peer_id); //add a source for the peer } pthread_mutex_unlock(&messages_lock); } void group_peer_del(GROUPCHAT *g, uint32_t peer_id) { group_add_message(g, peer_id, (uint8_t *)"<- has Quit!", 12, MSG_TYPE_NOTICE); pthread_mutex_lock(&messages_lock); /* make sure that messages has posted before we continue */ if (!g->peer) { LOG_TRACE("Groupchat", "Unable to del peer from NULL group"); pthread_mutex_unlock(&messages_lock); return; } GROUP_PEER *peer = g->peer[peer_id]; if (peer) { LOG_TRACE("Groupchat", "Freeing peer %u, name %.*s" , peer_id, (int)peer->name_length, peer->name); free(peer); } else { LOG_TRACE("Groupchat", "Unable to find peer for deletion"); pthread_mutex_unlock(&messages_lock); return; } g->peer_count--; g->peer[peer_id] = NULL; pthread_mutex_unlock(&messages_lock); } void group_peer_name_change(GROUPCHAT *g, uint32_t peer_id, const uint8_t *name, size_t length) { pthread_mutex_lock(&messages_lock); /* make sure that messages has posted before we continue */ if (!g->peer) { LOG_TRACE("Groupchat", "Unable to add peer to NULL group"); pthread_mutex_unlock(&messages_lock); return; } GROUP_PEER *peer = g->peer[peer_id]; if (!peer) { LOG_FATAL_ERR(EXIT_FAILURE, "Groupchat", "We can't set a name for a null peer! %u" , peer_id); } if (peer->name_length) { char old[TOX_MAX_NAME_LENGTH]; char msg[TOX_MAX_NAME_LENGTH]; memcpy(old, peer->name, peer->name_length); snprintf(msg, sizeof(msg), "<- has changed their name from %.*s", peer->name_length, old); GROUP_PEER *new_peer = realloc(peer, sizeof(GROUP_PEER) + sizeof(char) * length); if (!new_peer) { free(peer); LOG_FATAL_ERR(EXIT_MALLOC, "Groupchat", "couldn't realloc for group peer name!"); } peer = new_peer; peer->name_length = utf8_validate(name, length); memcpy(peer->name, name, length); g->peer[peer_id] = peer; pthread_mutex_unlock(&messages_lock); size_t msg_length = strnlen(msg, sizeof(msg) - 1); group_add_message(g, peer_id, (uint8_t *)msg, msg_length, MSG_TYPE_NOTICE); return; } /* Hopefully, they just joined, because that's the UX message we're going with! */ GROUP_PEER *new_peer = realloc(peer, sizeof(GROUP_PEER) + sizeof(char) * length); if (!new_peer) { free(peer); LOG_FATAL_ERR(EXIT_MALLOC, "Groupchat", "Unable to realloc for group peer who just joined."); } peer = new_peer; peer->name_length = utf8_validate(name, length); memcpy(peer->name, name, length); g->peer[peer_id] = peer; pthread_mutex_unlock(&messages_lock); group_add_message(g, peer_id, (uint8_t *)"<- has joined the chat!", 23, MSG_TYPE_NOTICE); } void group_reset_peerlist(GROUPCHAT *g) { /* ARE YOU KIDDING... WHO THOUGHT THIS API WAS OKAY?! */ for (size_t i = 0; i < g->peer_count; ++i) { if (g->peer[i]) { free(g->peer[i]); } } free(g->peer); } void group_free(GROUPCHAT *g) { LOG_INFO("Groupchats", "Freeing group %u", g->number); for (size_t i = 0; i < g->edit_history_length; ++i) { free(g->edit_history[i]); } free(g->edit_history); group_reset_peerlist(g); for (size_t i = 0; i < g->msg.number; ++i) { free(g->msg.data[i]->via.grp.author); // Freeing this here was causing a double free. // TODO: Is it needed to prevent a memory leak in some cases? // free(g->msg.data[i]->via.grp.msg); message_free(g->msg.data[i]); } free(g->msg.data); memset(g, 0, sizeof(GROUPCHAT)); self.groups_list_count--; } void raze_groups(void) { LOG_INFO("Groupchats", "Freeing groupchat array"); for (size_t i = 0; i < self.groups_list_count; i++) { GROUPCHAT *g = get_group(i); if (!g) { LOG_ERR("Groupchats", "Could not get group %u. Skipping...", i); continue; } group_free(g); } free(group); group = NULL; } void init_groups(Tox *tox) { self.groups_list_size = tox_conference_get_chatlist_size(tox); if (self.groups_list_size == 0) { return; } LOG_INFO("Groupchats", "Group list size: %u", self.groups_list_size); group = calloc(self.groups_list_size, sizeof(GROUPCHAT)); if (!group) { LOG_FATAL_ERR(EXIT_MALLOC, "Groupchats", "Could not allocate memory for groupchat array with size of: %u", self.groups_list_size); } uint32_t groups[self.groups_list_size]; tox_conference_get_chatlist(tox, groups); for (size_t i = 0; i < self.groups_list_size; i++) { group_create(groups[i], false); //TODO: figure out if groupchats are text or audio } LOG_INFO("Groupchat", "Initialzied groupchat array with %u groups", self.groups_list_size); } void group_notify_msg(GROUPCHAT *g, const char *msg, size_t msg_length) { if (g->notify == GNOTIFY_NEVER) { return; } if (g->notify == GNOTIFY_HIGHLIGHTS && strstr(msg, self.name) == NULL) { return; } char title[g->name_length + 25]; snprintf(title, sizeof(title), "uTox new message in %.*s", g->name_length, g->name); size_t title_length = strnlen(title, sizeof(title) - 1); notify(title, title_length, msg, msg_length, g, 1); if (flist_get_groupchat() != g) { postmessage_audio(UTOXAUDIO_PLAY_NOTIFICATION, NOTIFY_TONE_FRIEND_NEW_MSG, 0, NULL); } } uTox-0.17.1/src/groups.h000066400000000000000000000050431354126257400150310ustar00rootroot00000000000000#ifndef GROUPS_H #define GROUPS_H #include "messages.h" #include typedef unsigned int ALuint; typedef struct edit_change EDIT_CHANGE; #define UTOX_MAX_GROUP_PEERS 256 /* UTOX_SAVE limits 8 as the max */ typedef enum { GNOTIFY_NEVER, /* 0: never send notifications, */ GNOTIFY_HIGHLIGHTS, /* 1: only send when mentioned, */ GNOTIFY_ALWAYS, /* 2: always send notifications */ } GNOTIFY_TYPE; typedef struct group_peer { uint32_t id; uint32_t name_color; size_t name_length; uint8_t name[]; } GROUP_PEER; typedef struct groupchat { bool connected; uint16_t number; uint32_t our_peer_number; bool unread_msg; bool av_group; bool active_call; bool muted; ALuint audio_dest; /* Audio sources */ unsigned int source[UTOX_MAX_GROUP_PEERS]; /* TODO: thread safety (This should work fine but it isn't very clean.) */ volatile uint64_t last_recv_audio[UTOX_MAX_GROUP_PEERS]; GNOTIFY_TYPE notify; char name[128]; uint16_t name_length; char topic[256]; /* TODO magic numbers */ uint16_t topic_length; char *typed; uint16_t typed_length; MESSAGES msg; EDIT_CHANGE **edit_history; uint16_t edit_history_cur, edit_history_length; uint32_t peer_count; GROUP_PEER **peer; } GROUPCHAT; /* Initialize a new groupchat */ void group_init(GROUPCHAT *g, uint32_t group_number, bool av_group); // Returns the message number on success, returns UINT32_MAX on failure. uint32_t group_add_message(GROUPCHAT *g, uint32_t peer_id, const uint8_t *message, size_t length, uint8_t m_type); /* Add a peer to a group */ void group_peer_add(GROUPCHAT *g, uint32_t peer_id, bool our_peer_number, uint32_t name_color); /* Delete a peer from a group */ void group_peer_del(GROUPCHAT *g, uint32_t peer_id); /* Updates the peers name */ void group_peer_name_change(GROUPCHAT *g, uint32_t peer_id, const uint8_t *name, size_t length); /* Frees every peer */ void group_reset_peerlist(GROUPCHAT *g); /* Frees a group */ void group_free(GROUPCHAT *g); /* Creates a notification for messages received */ void group_notify_msg(GROUPCHAT *g, const char *msg, size_t length); /* Gets the group qt the specified index */ GROUPCHAT *get_group(uint32_t group_number); /* Free all groups */ void raze_groups(void); /* * Initalize the groupchats array * This function should only be called once at startup after tox and the self struct have been setup */ void init_groups(Tox *tox); /**/ bool group_create(uint32_t group_number, bool av_group); #endif uTox-0.17.1/src/inline_video.c000066400000000000000000000041051354126257400161470ustar00rootroot00000000000000/** inline_video.c * * TODO : a lot... * * We need to resive the video frame, and maybe center... * * Consider drawing messages under the video? * Consider do we want to draw buttons on screen? * Consider double click to pop out * * Consider auto selecting inline video */ #include "inline_video.h" #include "debug.h" #include "macros.h" #include "settings.h" #include "ui.h" #include "av/video.h" #include "native/image.h" #include #include static UTOX_FRAME_PKG current_frame = { 0, 0, 0, 0 }; bool inline_set_frame(uint16_t w, uint16_t h, size_t size, void *img) { current_frame.w = w; current_frame.h = h; current_frame.size = size; uint8_t *tmp = realloc(current_frame.img, size); if (!size || !tmp) { current_frame.w = 0; current_frame.h = 0; current_frame.size = 0; tmp ? free(tmp) : free(current_frame.img); return false; } current_frame.img = tmp; memcpy(current_frame.img, img, size); return true; } void inline_video_draw(INLINE_VID *UNUSED(p), int x, int y, int width, int height) { if (!settings.inline_video) { return; } LOG_TRACE("Inline Video", "Drawing new frame." ); if (current_frame.img && current_frame.size) { draw_inline_image(current_frame.img, current_frame.size, MIN(current_frame.w, width), MIN(current_frame.h, height), x, y + MAIN_TOP_FRAME_THICK); } } bool inline_video_mmove(INLINE_VID *UNUSED(p), int UNUSED(x), int UNUSED(y), int UNUSED(width), int UNUSED(height), int UNUSED(mx), int UNUSED(my), int UNUSED(dx), int UNUSED(dy)) { return 0; } bool inline_video_mdown(INLINE_VID *UNUSED(p)) { return 0; } bool inline_video_mright(INLINE_VID *UNUSED(p)) { return 0; } bool inline_video_mwheel(INLINE_VID *UNUSED(p), int UNUSED(height), double UNUSED(d), bool UNUSED(smooth)) { return 0; } bool inline_video_mup(INLINE_VID *UNUSED(p)) { return 0; } bool inline_video_mleave(INLINE_VID *UNUSED(p)) { return 0; } uTox-0.17.1/src/inline_video.h000066400000000000000000000012671354126257400161620ustar00rootroot00000000000000#ifndef INLINE_VIDEO_H #define INLINE_VIDEO_H #include "ui/panel.h" #include #include #include typedef struct inline_vid { PANEL panel; } INLINE_VID; bool inline_set_frame(uint16_t w, uint16_t h, size_t size, void *img); void inline_video_draw(INLINE_VID *p, int x, int y, int width, int height); bool inline_video_mmove(INLINE_VID *p, int x, int y, int width, int height, int mx, int my, int dx, int dy); bool inline_video_mdown(INLINE_VID *p); bool inline_video_mright(INLINE_VID *p); bool inline_video_mwheel(INLINE_VID *p, int height, double d, bool smooth); bool inline_video_mup(INLINE_VID *p); bool inline_video_mleave(INLINE_VID *p); #endif uTox-0.17.1/src/layout/000077500000000000000000000000001354126257400146545ustar00rootroot00000000000000uTox-0.17.1/src/layout/CMakeLists.txt000066400000000000000000000002641354126257400174160ustar00rootroot00000000000000project(utoxLAYOUT LANGUAGES C) add_library(utoxLAYOUT STATIC friend.c group.c notify.c settings.c sidebar.c userbadge.c background.c tray.c ) uTox-0.17.1/src/layout/README.md000066400000000000000000000011211354126257400161260ustar00rootroot00000000000000## Hi, and thanks for helping with uTox. We're all glad for the support! The structure for the layout/ directory is a bit different. All of the #includes should be placed inline instead of the header; ideally right before the first use. But thats a loose requirement. Apart from that, the PRIMARY goal should be readability, a close second would be easy of editing, meaning fewer files are probably better. But #include exists for a reason. Make the code easy to read, then both my and your life easy and everyone will be happy! Thanks again! ![who's awesome?](https://cmdline.org/who.png) uTox-0.17.1/src/layout/background.c000066400000000000000000000066251354126257400171500ustar00rootroot00000000000000#include "background.h" #include "friend.h" #include "group.h" #include "notify.h" #include "settings.h" #include "sidebar.h" #include "../macros.h" #include "../theme.h" #include "../ui.h" #include "../ui/draw.h" #include "../ui/panel.h" #include "../ui/text.h" #include static void draw_background(int x, int y, int width, int height) { /* Default background */ drawrect(x, y, width, height, COLOR_BKGRND_MAIN); if (!panel_chat.disabled) { /* Top frame for main chat panel */ drawrect(x, 0, width, SCALE(MAIN_TOP_FRAME_THICK), COLOR_BKGRND_ALT); drawhline(x, SCALE(MAIN_TOP_FRAME_THICK), width, COLOR_EDGE_NORMAL); /* Frame for the bottom chat text entry box */ drawrect(x, height + SCALE(CHAT_BOX_TOP), width, height, COLOR_BKGRND_ALT); drawhline(x, height + SCALE(CHAT_BOX_TOP), width, COLOR_EDGE_NORMAL); } // Chat and chat header separation if (panel_settings_master.disabled) { drawhline(x, SCALE(MAIN_TOP_FRAME_THICK), width, COLOR_EDGE_NORMAL); } } static void draw_splash_page(int x, int y, int w, int h) { setcolor(COLOR_MAIN_TEXT); y += SCALE(10); x += SCALE(10); /* Generic Splash */ setfont(FONT_SELF_NAME); int ny = utox_draw_text_multiline_within_box(x, y, w + x, y, y + h, font_small_lineheight, S(SPLASH_TITLE), SLEN(SPLASH_TITLE), ~0, ~0, 0, 0, 1); setfont(FONT_TEXT); ny = utox_draw_text_multiline_within_box(x, ny, w + x, ny, ny + h, font_small_lineheight, S(SPLASH_TEXT), SLEN(SPLASH_TEXT), ~0, ~0, 0, 0, 1); ny += SCALE(30); /* Change log */ setfont(FONT_SELF_NAME); ny = utox_draw_text_multiline_within_box(x, ny, w + x, y, ny + h, font_small_lineheight, S(CHANGE_LOG_TITLE), SLEN(CHANGE_LOG_TITLE), ~0, ~0, 0, 0, 1); setfont(FONT_TEXT); /* ny =*/ utox_draw_text_multiline_within_box(x, ny, w + x, ny, ny + h, font_small_lineheight, S(CHANGE_LOG_TEXT), SLEN(CHANGE_LOG_TEXT), ~0, ~0, 0, 0, 1); } PANEL panel_root = { .type = PANEL_NONE, .drawfunc = draw_background, .disabled = 0, .child = (PANEL*[]) { &panel_side_bar, &panel_main, NULL } }, /* Main panel, holds the overhead/settings, or the friend/group containers */ panel_main = { .type = PANEL_NONE, .disabled = 0, .child = (PANEL*[]) { &panel_chat, &panel_overhead, NULL } }, /* Chat panel, friend or group, depending on what's selected */ panel_chat = { .type = PANEL_NONE, .disabled = 1, .child = (PANEL*[]) { &panel_group, &panel_group_create, &panel_friend, &panel_friend_request, NULL } }, /* Settings master panel, holds the lower level settings */ panel_overhead = { .type = PANEL_NONE, .disabled = 0, .child = (PANEL*[]) { &panel_splash_page, &panel_profile_password, &panel_add_friend, &panel_settings_master, // (PANEL*)&button_notify_create, // FIXME, left as a comment for later work on popup notifications NULL } }, panel_splash_page = { .type = PANEL_NONE, .disabled = 1, .drawfunc = draw_splash_page, .content_scroll = &scrollbar_settings, .child = (PANEL*[]) { NULL, } }; uTox-0.17.1/src/layout/background.h000066400000000000000000000003741354126257400171500ustar00rootroot00000000000000#ifndef LAYOUT_BACKGROUND_H #define LAYOUT_BACKGROUND_H typedef struct panel PANEL; extern PANEL panel_root, panel_main, panel_chat, panel_overhead, panel_splash_page; #endif // LAYOUT_BACKGROUND_H uTox-0.17.1/src/layout/create.h000066400000000000000000000054131354126257400162730ustar00rootroot00000000000000#ifndef LAYOUT_CREATE_H #define LAYOUT_CREATE_H /* Space keeping file for the macros I want to create to make changing/creating * layouts easier and/of faster. */ /* These macros are broken right now. * TODO: Fix them. */ /* #define CREATE_BUTTON(n, a, b, w, h) button_##n = { \ panel.type = PANEL_BUTTON, \ panel.x = a, \ panel.y = b, \ panel.width = w, \ panel.height = h, \ }; #define CREATE_EDIT(n, a, b, w, h) edit_##n = { \ panel.type = PANEL_EDIT, \ panel.x = a, \ panel.y = b, \ panel.width = w, \ panel.height = h, \ }; #define CREATE_SWITCH(n, a, b, w, h) switch_##n = { \ panel.type = PANEL_SWITCH, \ panel.x = a, \ panel.y = b, \ panel.width = w, \ panel.height = h, \ }; #define CREATE_DROPDOWN(n, a, b, h, w) dropdown_##n = { \ panel.type = PANEL_DROPDOWN, \ panel.x = a, \ panel.y = b, \ panel.height = h, \ panel.width = w, \ }; */ #define CREATE_BUTTON(n, a, b, w, h) \ button_##n.panel.type = PANEL_BUTTON; \ button_##n.panel.x = a; \ button_##n.panel.y = b; \ button_##n.panel.width = w; \ button_##n.panel.height = h; #define CREATE_EDIT(n, a, b, w, h) \ edit_##n.panel.type = PANEL_EDIT; \ edit_##n.panel.x = a; \ edit_##n.panel.y = b; \ edit_##n.panel.width = w; \ edit_##n.panel.height = h; #define CREATE_SWITCH(n, a, b, w, h) \ switch_##n.panel.type = PANEL_SWITCH; \ switch_##n.panel.x = a; \ switch_##n.panel.y = b; \ switch_##n.panel.width = w; \ switch_##n.panel.height = h; #define CREATE_DROPDOWN(n, a, b, h, w) \ dropdown_##n.panel.type = PANEL_DROPDOWN; \ dropdown_##n.panel.x = a; \ dropdown_##n.panel.y = b; \ dropdown_##n.panel.height = h; \ dropdown_##n.panel.width = w; #endif // LAYOUT_CREATE_H uTox-0.17.1/src/layout/friend.c000066400000000000000000000576031354126257400163020ustar00rootroot00000000000000#include "friend.h" #include "settings.h" #include "sidebar.h" #include "../avatar.h" #include "../debug.h" #include "../flist.h" #include "../friend.h" #include "../macros.h" #include "../settings.h" #include "../theme.h" #include "../tox.h" #include "../native/dialog.h" #include "../ui/draw.h" #include "../ui/edit.h" #include "../ui/scrollable.h" #include "../ui/svg.h" #include "../ui/text.h" #include "../main.h" // add friend status // TODO this is stupid wrong #include /* Header for friend chat window */ static void draw_friend(int x, int y, int w, int height) { FRIEND *f = flist_get_friend(); if (!f) { LOG_ERR("Friend", "Could not get selected friend.\n"); return; } // draw avatar or default image if (friend_has_avatar(f)) { draw_avatar_image(f->avatar->img, x + SCALE(10), SCALE(10), f->avatar->width, f->avatar->height, BM_CONTACT_WIDTH, BM_CONTACT_WIDTH); } else { drawalpha(BM_CONTACT, x + SCALE(10), SCALE(10), BM_CONTACT_WIDTH, BM_CONTACT_WIDTH, COLOR_MAIN_TEXT); } setcolor(COLOR_MAIN_TEXT); setfont(FONT_TITLE); if (f->alias) { drawtextrange(x + SCALE(60), settings.window_width - SCALE(128), SCALE(18), f->alias, f->alias_length); } else { drawtextrange(x + SCALE(60), settings.window_width - SCALE(128), SCALE(18), f->name, f->name_length); } setcolor(COLOR_MAIN_TEXT_SUBTEXT); setfont(FONT_STATUS); drawtextrange(x + SCALE(60), settings.window_width - SCALE(128), SCALE(32), f->status_message, f->status_length); if (f->typing) { int typing_y = ((y + height) + SCALE(CHAT_BOX_TOP - 14)); setfont(FONT_MISC); // @TODO: separate these colors if needed setcolor(COLOR_MAIN_TEXT_HINT); if (f->alias) { drawtextwidth_right(x, SCALE(MESSAGES_X - NAME_OFFSET - 16), typing_y, f->alias, f->alias_length); } else { drawtextwidth_right(x, SCALE(MESSAGES_X - NAME_OFFSET - 16), typing_y, f->name, f->name_length); } drawtextwidth(x + SCALE(MESSAGES_X - 18), x + w, typing_y, S(IS_TYPING), SLEN(IS_TYPING)); } } /* Draw an invite to be a friend window */ static void draw_friend_request(int x, int y, int w, int h) { FREQUEST *req = flist_get_frequest(); if (!req) { LOG_ERR("Layout Friend", "Unable to draw a friend request without a friend request."); return; } setcolor(COLOR_MAIN_TEXT); setfont(FONT_SELF_NAME); drawstr(x + SCALE(10), SCALE(20), FRIENDREQUEST); if (req->msg && req->length) { setfont(FONT_TEXT); utox_draw_text_multiline_within_box(x + SCALE(10), y + SCALE(70), w + x, y, y + h, font_small_lineheight, req->msg, req->length, ~0, ~0, 0, 0, true); } } static void draw_friend_settings(int x, int y, int UNUSED(width), int UNUSED(height)) { setcolor(COLOR_MAIN_TEXT); setfont(FONT_SELF_NAME); drawstr(x + SCALE(10), y + SCALE(MAIN_TOP + 10), FRIEND_PUBLIC_KEY); drawstr(x + SCALE(10), y + SCALE(MAIN_TOP + 60), FRIEND_ALIAS); drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(MAIN_TOP + 112), FRIEND_AUTOACCEPT); } static void draw_friend_deletion(int x, int UNUSED(y), int UNUSED(w), int UNUSED(height)) { FRIEND *f = flist_get_friend(); if (!f) { LOG_ERR("Friend", "Could not get selected friend."); return; } setcolor(COLOR_MAIN_TEXT); setfont(FONT_SELF_NAME); int length = f->name_length + 2; char str[length]; snprintf(str, length, "%.*s?", (int)f->name_length, f->name); const int push = UTOX_STR_WIDTH(DELETE_MESSAGE); drawstr(x + SCALE(10), SCALE(70), DELETE_MESSAGE); drawtextrange(push + x + SCALE(10), settings.window_width, SCALE(70), str, length - 1); } /* Draw add a friend window */ static void draw_add_friend(int x, int UNUSED(y), int UNUSED(w), int height) { setcolor(COLOR_MAIN_TEXT); setfont(FONT_SELF_NAME); drawstr(x + SCALE(10), SCALE(20), ADDFRIENDS); setcolor(COLOR_MAIN_TEXT_SUBTEXT); setfont(FONT_TEXT); drawstr(x + SCALE(10), SCALE(MAIN_TOP + 10), TOXID); drawstr(x + SCALE(10), SCALE(MAIN_TOP + 58), MESSAGE); if (!addfriend_status) { return; } setfont(FONT_MISC); setcolor(C_RED); STRING *str; switch (addfriend_status) { case ADDF_SENT: str = SPTR(REQ_SENT); break; case ADDF_BADNAME: str = SPTR(REQ_INVALID_ID); break; case ADDF_NONAME: str = SPTR(REQ_EMPTY_ID); break; case ADDF_TOOLONG: // if message length is too long. str = SPTR(REQ_LONG_MSG); break; case ADDF_NOMESSAGE: // if no message (message length must be >= 1 byte). str = SPTR(REQ_NO_MSG); break; case ADDF_OWNKEY: // if user's own key. str = SPTR(REQ_SELF_ID); break; case ADDF_ALREADYSENT: // if friend request already sent or already a friend. str = SPTR(REQ_ALREADY_FRIENDS); break; case ADDF_BADCHECKSUM: // if bad checksum in address. str = SPTR(REQ_BAD_CHECKSUM); break; case ADDF_SETNEWNOSPAM: // if the friend was already there but the nospam was different. str = SPTR(REQ_BAD_NOSPAM); break; case ADDF_NOMEM: // if increasing the friend list size fails. str = SPTR(REQ_NO_MEMORY); break; case ADDF_NOFREQUESTSENT: str = SPTR(REQ_ADDED_NO_FREQ_SENT); break; case ADDF_UNKNOWN: // for unknown error. case ADDF_NONE: // this case must never be rendered, but if it does, assume it's an error default: str = SPTR(REQ_UNKNOWN); break; } utox_draw_text_multiline_within_box(x + SCALE(10), MAIN_TOP + SCALE(166), settings.window_width - BM_SBUTTON_WIDTH - SCALE(10), 0, height, font_small_lineheight, str->str, str->length, 0xFFFF, 0, 0, 0, 1); } SCROLLABLE scrollbar_friend = { .panel = { .type = PANEL_SCROLLABLE, }, .color = C_SCROLL, }; PANEL messages_friend = { .type = PANEL_MESSAGES, .content_scroll = &scrollbar_friend, }; PANEL panel_friend = { .type = PANEL_NONE, .disabled = 1, .child = (PANEL*[]) { &panel_friend_chat, &panel_friend_video, &panel_friend_settings, &panel_friend_confirm_deletion, NULL } }, panel_friend_chat = { .type = PANEL_NONE, .disabled = 0, .drawfunc = draw_friend, .child = (PANEL*[]) { (PANEL*)&scrollbar_friend, (PANEL*)&edit_chat_msg_friend, // this needs to be one of the first, to get events before the others (PANEL*)&messages_friend, (PANEL*)&button_call_decline, (PANEL*)&button_call_audio, (PANEL*)&button_call_video, (PANEL*)&button_send_file, (PANEL*)&button_send_screenshot, (PANEL*)&button_chat_send_friend, NULL } }, panel_friend_video = { .type = PANEL_INLINE_VIDEO, .disabled = 1, .child = (PANEL*[]) { NULL } }, panel_friend_settings = { .type = PANEL_NONE, .disabled = 1, .drawfunc = draw_friend_settings, .child = (PANEL*[]) { (PANEL*)&edit_friend_pubkey, (PANEL*)&edit_friend_alias, (PANEL*)&switch_friend_autoaccept_ft, (PANEL*)&button_export_chatlog, NULL } }, panel_friend_confirm_deletion = { .type = PANEL_NONE, .disabled = true, .drawfunc = draw_friend_deletion, .child = (PANEL*[]) { (PANEL *)&button_confirm_deletion, (PANEL *)&button_deny_deletion, NULL } }, panel_friend_request = { .type = PANEL_NONE, .disabled = 1, .drawfunc = draw_friend_request, .child = (PANEL*[]) { (PANEL*)&button_accept_friend, (PANEL*)&button_ignore_friend, NULL } }, panel_add_friend = { .type = PANEL_NONE, .disabled = 1, .drawfunc = draw_add_friend, .child = (PANEL*[]) { (PANEL*)&button_send_friend_request, (PANEL*)&edit_add_new_friend_id, (PANEL*)&edit_add_new_friend_msg, NULL } }; static void button_add_new_contact_on_mup(void) { if (tox_thread_init == UTOX_TOX_THREAD_INIT_SUCCESS) { /* Only change if we're logged in! */ edit_setstr(&edit_add_new_friend_id, (char *)edit_search.data, edit_search.length); edit_setstr(&edit_search, (char *)"", 0); flist_selectaddfriend(); edit_setfocus(&edit_add_new_friend_msg); } } static void button_send_friend_request_on_mup(void) { friend_add(edit_add_new_friend_id.data, edit_add_new_friend_id.length, edit_add_new_friend_msg.data, edit_add_new_friend_msg.length); edit_resetfocus(); } #include "../tox.h" static void button_call_decline_on_mup(void) { FRIEND *f = flist_get_friend(); if (!f) { LOG_ERR("Friend", "Could not get selected friend."); return; } if (f->call_state_friend) { LOG_TRACE("Layout Friend", "Declining call: %u", f->number); postmessage_toxcore(TOX_CALL_DISCONNECT, f->number, 0, NULL); } } #include "../av/utox_av.h" #include "../av/audio.h" #include "../ui/button.h" static void button_call_decline_update(BUTTON *b) { FRIEND *f = flist_get_friend(); if (!f) { LOG_ERR("Friend", "Could not get selected friend."); return; } if (UTOX_AVAILABLE_AUDIO(f->number) && !UTOX_SENDING_AUDIO(f->number)) { button_setcolors_danger(b); b->nodraw = b->disabled = b->panel.disabled = false; } else { button_setcolors_disabled(b); b->nodraw = b->disabled = b->panel.disabled = true; } } static void button_call_audio_on_mup(void) { FRIEND *f = flist_get_friend(); if (!f) { LOG_ERR("Friend", "Could not get selected friend."); return; } if (f->call_state_self) { if (UTOX_SENDING_AUDIO(f->number)) { LOG_TRACE("Layout Friend", "Ending call: %u", f->number); /* var 3/4 = bool send video */ postmessage_toxcore(TOX_CALL_DISCONNECT, f->number, 0, NULL); } else { LOG_TRACE("Layout Friend", "Canceling call: friend = %d", f->number); postmessage_toxcore(TOX_CALL_DISCONNECT, f->number, 0, NULL); } } else if (UTOX_AVAILABLE_AUDIO(f->number)) { LOG_TRACE("Layout Friend", "Accept Call: %u", f->number); postmessage_toxcore(TOX_CALL_ANSWER, f->number, 0, NULL); } else if (f->online) { postmessage_toxcore(TOX_CALL_SEND, f->number, 0, NULL); LOG_TRACE("Layout Friend", "Calling friend: %u", f->number); } } static void button_call_audio_update(BUTTON *b) { FRIEND *f = flist_get_friend(); if (!f) { LOG_ERR("Friend", "Could not get selected friend."); return; } if (UTOX_SENDING_AUDIO(f->number)) { button_setcolors_danger(b); b->disabled = false; } else if (UTOX_AVAILABLE_AUDIO(f->number)) { button_setcolors_warning(b); b->disabled = false; } else { if (f->online) { button_setcolors_success(b); b->disabled = false; } else { button_setcolors_disabled(b); b->disabled = true; } } } #include "../av/video.h" static void button_call_video_on_mup(void) { FRIEND *f = flist_get_friend(); if (!f) { LOG_ERR("Friend", "Could not get selected friend."); return; } if (f->call_state_self) { if (SELF_ACCEPT_VIDEO(f->number)) { LOG_TRACE("Layout Friend", "Canceling call (video): %u", f->number); postmessage_toxcore(TOX_CALL_PAUSE_VIDEO, f->number, 1, NULL); } else if (UTOX_SENDING_AUDIO(f->number)) { LOG_TRACE("Layout Friend", "Audio call inprogress, adding video"); postmessage_toxcore(TOX_CALL_RESUME_VIDEO, f->number, 1, NULL); } else { LOG_TRACE("Layout Friend", "Ending call (video): %u", f->number); postmessage_toxcore(TOX_CALL_DISCONNECT, f->number, 1, NULL); } } else if (f->call_state_friend) { LOG_TRACE("Layout Friend", "Accept Call (video): %u %u", f->number, f->call_state_friend); postmessage_toxcore(TOX_CALL_ANSWER, f->number, 1, NULL); } else if (f->online) { postmessage_toxcore(TOX_CALL_SEND, f->number, 1, NULL); LOG_TRACE("Layout Friend", "Calling friend (video): %u", f->number); } } static void button_call_video_update(BUTTON *b) { FRIEND *f = flist_get_friend(); if (!f) { LOG_ERR("Friend", "Could not get selected friend."); return; } if (SELF_SEND_VIDEO(f->number)) { button_setcolors_danger(b); b->disabled = false; } else if (FRIEND_SENDING_VIDEO(f->number)) { button_setcolors_warning(b); b->disabled = false; } else { if (f->online) { button_setcolors_success(b); b->disabled = false; } else { button_setcolors_disabled(b); b->disabled = true; } } } static void button_accept_friend_on_mup(void) { FREQUEST *req = flist_get_frequest(); postmessage_toxcore(TOX_FRIEND_ACCEPT, 0, 0, req); panel_friend_request.disabled = true; } static void button_ignore_friend_on_mup(void){ FREQUEST *req = flist_get_frequest(); if (!req) { LOG_ERR("Friend", "Could not get selected friend request"); return; } flist_delete_sitem(); panel_friend_request.disabled = true; } static void button_menu_update(BUTTON *b) { b->c1 = COLOR_BKGRND_MENU; b->c2 = COLOR_BKGRND_MENU_HOVER; b->c3 = COLOR_BKGRND_MENU_ACTIVE; b->ct1 = COLOR_MENU_TEXT; b->ct2 = COLOR_MENU_TEXT; if (b->mousedown || b->disabled) { b->ct1 = COLOR_MENU_TEXT_ACTIVE; b->ct2 = COLOR_MENU_TEXT_ACTIVE; } b->cd = COLOR_BKGRND_MENU_ACTIVE; } BUTTON button_add_new_contact = { .bm_icon = BM_ADD, .icon_w = _BM_ADD_WIDTH, .icon_h = _BM_ADD_WIDTH, .update = button_menu_update, .on_mup = button_add_new_contact_on_mup, .disabled = true, .nodraw = true, .tooltip_text = {.i18nal = STR_ADDFRIENDS }, }; BUTTON button_send_friend_request = { .bm_fill = BM_SBUTTON, .button_text = {.i18nal = STR_ADD }, .update = button_setcolors_success, .on_mup = button_send_friend_request_on_mup, .disabled = false, }; BUTTON button_call_decline = { .bm_fill = BM_LBUTTON, .bm_icon = BM_DECLINE, .icon_w = _BM_LBICON_WIDTH, .icon_h = _BM_LBICON_HEIGHT, .on_mup = button_call_decline_on_mup, .update = button_call_decline_update, .tooltip_text = {.i18nal = STR_CALL_DECLINE }, .nodraw = true, .disabled = true, }; BUTTON button_call_audio = { .bm_fill = BM_LBUTTON, .bm_icon = BM_CALL, .icon_w = _BM_LBICON_WIDTH, .icon_h = _BM_LBICON_HEIGHT, .on_mup = button_call_audio_on_mup, .update = button_call_audio_update, .tooltip_text = {.i18nal = STR_CALL_START_AUDIO }, }; BUTTON button_call_video = { .bm_fill = BM_LBUTTON, .bm_icon = BM_VIDEO, .icon_w = _BM_LBICON_WIDTH, .icon_h = _BM_LBICON_HEIGHT, .on_mup = button_call_video_on_mup, .update = button_call_video_update, .tooltip_text = {.i18nal = STR_CALL_START_VIDEO }, }; static void button_send_file_on_mup(void) { FRIEND *f = flist_get_friend(); if (!f) { LOG_ERR("Friend", "Could not get selected friend."); return; } if (f->online) { openfilesend(); } } static void button_send_file_update(BUTTON *b) { FRIEND *f = flist_get_friend(); if (!f) { LOG_ERR("Friend", "Could not get selected friend."); return; } if (f->online) { b->disabled = false; button_setcolors_success(b); } else { b->disabled = true; button_setcolors_disabled(b); } } BUTTON button_send_file = { .bm_fill = BM_CHAT_BUTTON_LEFT, .bm_icon = BM_FILE, .icon_w = _BM_FILE_WIDTH, .icon_h = _BM_FILE_HEIGHT, .on_mup = button_send_file_on_mup, .update = button_send_file_update, .disabled = true, .tooltip_text = {.i18nal = STR_SEND_FILE }, }; #include "../screen_grab.h" static void button_send_screenshot_on_mup(void) { FRIEND *f = flist_get_friend(); if (f != NULL && f->online) { utox_screen_grab_desktop(0); } } static void button_send_screenshot_update(BUTTON *b) { FRIEND *f = flist_get_friend(); if (!f) { LOG_ERR("Friend", "Could not get selected friend."); return; } if (f->online) { b->disabled = false; button_setcolors_success(b); } else { b->disabled = true; button_setcolors_disabled(b); } } BUTTON button_send_screenshot = { .bm_fill = BM_CHAT_BUTTON_RIGHT, .bm_icon = BM_CHAT_BUTTON_OVERLAY_SCREENSHOT, .icon_w = _BM_CHAT_BUTTON_OVERLAY_WIDTH, .icon_h = _BM_CHAT_BUTTON_OVERLAY_HEIGHT, .update = button_send_screenshot_update, .on_mup = button_send_screenshot_on_mup, .tooltip_text = {.i18nal = STR_SENDSCREENSHOT }, }; BUTTON button_accept_friend = { .panel = { .type = PANEL_BUTTON, .x = -140, .y = -80, .width = _BM_SBUTTON_WIDTH, .height = _BM_SBUTTON_HEIGHT, }, .bm_fill = BM_SBUTTON, .button_text = {.i18nal = STR_ADD }, .update = button_setcolors_success, .on_mup = button_accept_friend_on_mup, }; BUTTON button_ignore_friend = { .panel = { .type = PANEL_BUTTON, .x = -80, .y = -80, .width = _BM_SBUTTON_WIDTH, .height = _BM_SBUTTON_HEIGHT, }, .bm_fill = BM_SBUTTON, .button_text = {.i18nal = STR_IGNORE}, .update = button_setcolors_danger, .on_mup = button_ignore_friend_on_mup, }; static void switchfxn_autoaccept_ft(void) { FRIEND *f = flist_get_friend(); if (f) { f->ft_autoaccept = !f->ft_autoaccept; utox_write_metadata(f); } } #include "../ui/switch.h" UISWITCH switch_friend_autoaccept_ft = { .style_outer = BM_SWITCH, .style_toggle = BM_SWITCH_TOGGLE, .style_icon_off = BM_NO, .style_icon_on = BM_YES, .update = switch_update, .on_mup = switchfxn_autoaccept_ft, .tooltip_text = {.i18nal = STR_FRIEND_AUTOACCEPT }, }; static void edit_add_new_contact(EDIT *UNUSED(edit)) { friend_add(edit_add_new_friend_id.data, edit_add_new_friend_id.length, edit_add_new_friend_msg.data, edit_add_new_friend_msg.length); } static char e_friend_pubkey_str[TOX_PUBLIC_KEY_SIZE * 2]; EDIT edit_friend_pubkey = { // .length == .data_size, because .data is not \0-terminated .length = sizeof e_friend_pubkey_str, .data_size = sizeof e_friend_pubkey_str, .data = e_friend_pubkey_str, .readonly = true, .noborder = false, .select_completely = true, }; static void edit_friend_alias_onenter(EDIT *UNUSED(edit)) { FRIEND *f = flist_get_friend(); if (!f) { LOG_ERR("Friend", "Could not get selected friend."); return; } friend_set_alias(f, (uint8_t *)edit_friend_alias.data, edit_friend_alias.length); utox_write_metadata(f); } static char e_friend_alias_str[128]; EDIT edit_friend_alias = { .data_size = sizeof e_friend_alias_str, .data = e_friend_alias_str, .onenter = edit_friend_alias_onenter, .onlosefocus = edit_friend_alias_onenter, .empty_str = {.plain = STRING_INIT("") }, // set dynamically to the friend's name }; static char e_add_new_friend_id_data[TOX_ADDRESS_SIZE * 4]; EDIT edit_add_new_friend_id = { .data_size = sizeof e_add_new_friend_id_data, .data = e_add_new_friend_id_data, .onenter = edit_add_new_contact, }; SCROLLABLE e_add_new_friend_msg_scroll = { .panel = { .type = PANEL_SCROLLABLE, }, .d = 1.0, .color = C_SCROLL, }; static char e_add_new_friend_msg_data[1024]; EDIT edit_add_new_friend_msg = { .multiline = 1, .scroll = &e_add_new_friend_msg_scroll, .data = e_add_new_friend_msg_data, .data_size = sizeof e_add_new_friend_msg_data, .empty_str = {.i18nal = STR_DEFAULT_FRIEND_REQUEST_MESSAGE }, }; #include "../commands.h" static void e_chat_msg_onenter(EDIT *edit) { char * text = edit->data; uint16_t length = edit->length; if (length <= 0) { return; } uint16_t command_length = 0; //, argument_length = 0; char * command = NULL, *argument = NULL; command_length = utox_run_command(text, length, &command, &argument, 1); // TODO: Magic number if (command_length == UINT16_MAX) { edit->length = 0; return; } // LOG_TRACE("Layout Friend", "cmd %u", command_length); bool action = false; if (command_length) { length = length - command_length - 2; /* first / and then the SPACE */ text = argument; if ((command_length == 2) && (!memcmp(command, "me", 2))) { if (argument) { action = true; } else { return; } } } if (!text) { return; } FRIEND *f = flist_get_friend(); if (f) { /* Display locally */ if (action) { message_add_type_action(&f->msg, 1, text, length, 1, 1); } else { message_add_type_text(&f->msg, 1, text, length, 1, 1); } } edit->length = 0; } static void e_chat_msg_onchange(EDIT *UNUSED(edit)) { FRIEND *f = flist_get_friend(); if (f) { if (!f->online) { return; } postmessage_toxcore(TOX_SEND_TYPING, f->number, 0, NULL); } } SCROLLABLE e_chat_msg_friend_scroll = { .panel = { .type = PANEL_SCROLLABLE, }, .d = 1.0, .color = C_SCROLL, }; static char e_chat_msg_friend_data[65535]; EDIT edit_chat_msg_friend = { .data = e_chat_msg_friend_data, .data_size = sizeof e_chat_msg_friend_data, .multiline = true, .onenter = e_chat_msg_onenter, .onchange = e_chat_msg_onchange, .scroll = &e_chat_msg_friend_scroll, }; /* Button to send chat message */ static void button_chat_send_friend_on_mup(void) { // TODO clear the chat bar with a /slash command e_chat_msg_onenter(&edit_chat_msg_friend); // reset focus to the chat window on send to prevent segfault. May break on android. edit_setfocus(&edit_chat_msg_friend); } static void button_chat_send_friend_update(BUTTON *b) { FRIEND *f = flist_get_friend(); if (f) { if (f->online) { button_setcolors_success(b); } else { button_setcolors_disabled(b); } } } BUTTON button_chat_send_friend = { .bm_fill = BM_CHAT_SEND, .bm_icon = BM_CHAT_SEND_OVERLAY, .icon_w = _BM_CHAT_SEND_OVERLAY_WIDTH, .icon_h = _BM_CHAT_SEND_OVERLAY_HEIGHT, .on_mup = button_chat_send_friend_on_mup, .update = button_chat_send_friend_update, .tooltip_text = {.i18nal = STR_SENDMESSAGE }, }; static void button_confirm_deletion_on_mup(void) { flist_delete_rmouse_item(); } static void button_deny_deletion_on_mup(void) { panel_friend_confirm_deletion.disabled = true; panel_friend_chat.disabled = false; } BUTTON button_confirm_deletion = { .bm_fill = BM_SBUTTON, .update = button_setcolors_danger, .tooltip_text = {.i18nal = STR_DELETE}, .button_text = {.i18nal = STR_DELETE}, .on_mup = button_confirm_deletion_on_mup, }; BUTTON button_deny_deletion = { .bm_fill = BM_SBUTTON, .update = button_setcolors_success, .tooltip_text = {.i18nal = STR_KEEP}, .button_text = {.i18nal = STR_KEEP}, .on_mup = button_deny_deletion_on_mup, }; uTox-0.17.1/src/layout/friend.h000066400000000000000000000024061354126257400162760ustar00rootroot00000000000000#ifndef LAYOUT_FRIEND_H #define LAYOUT_FRIEND_H typedef struct scrollable SCROLLABLE; extern SCROLLABLE scrollbar_friend; typedef struct panel PANEL; extern PANEL messages_friend; extern PANEL panel_friend, panel_add_friend, panel_friend_chat, panel_friend_video, panel_friend_settings, panel_friend_request, panel_friend_confirm_deletion; typedef struct button BUTTON; // Top Bar extern BUTTON button_call_decline, button_call_audio, button_call_video; // Bottom Bar extern BUTTON button_send_file, button_send_screenshot, button_chat_send_friend; // Friend Requests extern BUTTON button_send_friend_request, button_accept_friend, button_ignore_friend; // Friend Settings extern BUTTON button_export_chatlog; // Friend Deletion model extern BUTTON button_confirm_deletion, button_deny_deletion; typedef struct uiswitch UISWITCH; extern UISWITCH switch_friend_autoaccept_ft; typedef struct edit EDIT; extern EDIT edit_add_new_friend_id, edit_add_new_friend_msg, edit_chat_msg_friend, edit_friend_pubkey, edit_friend_alias; #endif // LAYOUT_FRIEND_H uTox-0.17.1/src/layout/group.c000066400000000000000000000414371354126257400161650ustar00rootroot00000000000000#include "group.h" #include "create.h" #include "../commands.h" #include "../debug.h" #include "../flist.h" #include "../groups.h" #include "../macros.h" #include "../settings.h" #include "../text.h" #include "../theme.h" #include "../tox.h" #include "../ui/button.h" #include "../ui/draw.h" #include "../ui/edit.h" #include "../ui/panel.h" #include "../ui/scrollable.h" #include "../ui/svg.h" #include "../ui/switch.h" #include #include #include #include #include SCROLLABLE scrollbar_group = { .panel = { .type = PANEL_SCROLLABLE, }, .color = C_SCROLL, }; static void draw_group(int x, int UNUSED(y), int UNUSED(w), int UNUSED(height)) { GROUPCHAT *g = flist_get_groupchat(); if (!g) { LOG_ERR("Group", "Could not get selected groupchat."); return; } drawalpha(BM_GROUP, x + SCALE(10), SCALE(10), BM_CONTACT_WIDTH, BM_CONTACT_WIDTH, COLOR_MAIN_TEXT); setcolor(COLOR_MAIN_TEXT); setfont(FONT_TITLE); drawtextrange(x + SCALE(60), settings.window_width - SCALE(64), SCALE(2), g->name, g->name_length); setcolor(COLOR_MAIN_TEXT_SUBTEXT); setfont(FONT_STATUS); drawtextrange(x + SCALE(60), settings.window_width - SCALE(64), SCALE(16), g->topic, g->topic_length); uint32_t i = 0; unsigned k = x + SCALE(60); unsigned int pos_y = 15; while (i < g->peer_count) { GROUP_PEER *peer = g->peer[i]; if (peer && peer->name_length) { char buf[TOX_MAX_NAME_LENGTH]; snprintf((char *)buf, sizeof(buf), "%.*s, ", (int)peer->name_length, peer->name); int buf_len = strnlen(buf, sizeof(buf) - 1); unsigned w = textwidth(buf, buf_len); if (peer->name_color) { setcolor(peer->name_color); } else { setcolor(COLOR_GROUP_PEER); } if (k + w >= (settings.window_width - SCALE(64))) { if (pos_y == 15) { pos_y += 6; k = x + SCALE(60); } else { drawtext(k, SCALE(pos_y * 2), "...", 3); break; } } drawtext(k, SCALE(pos_y * 2), buf, buf_len); k += w; } i++; } } static void draw_group_settings(int x, int y, int UNUSED(width), int UNUSED(height)) { setcolor(COLOR_MAIN_TEXT); setfont(FONT_SELF_NAME); drawstr(x + SCALE(10), y + SCALE(MAIN_TOP + 10), GROUP_TOPIC); drawstr(x + SCALE(10), y + SCALE(MAIN_TOP + 60), GROUP_NOTIFICATIONS); } static void draw_group_create(int x, int y, int UNUSED(width), int UNUSED(height)) { setcolor(COLOR_MAIN_TEXT); setfont(FONT_SELF_NAME); drawstr(x + SCALE(10), y + SCALE(MAIN_TOP + 10), CREATEGROUPCHAT); drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(MAIN_TOP + 40), GROUP_CREATE_WITH_AUDIO); } static void button_create_group_on_mup(void) { postmessage_toxcore(TOX_GROUP_CREATE, 0, switch_group_type.switch_on, NULL); } static void switchfxn_group_type(void) { if (switch_group_type.switch_on) { maybe_i18nal_string_set_i18nal(&button_create_group.button_text, STR_GROUP_CREATE_VOICE); } else { maybe_i18nal_string_set_i18nal(&button_create_group.button_text, STR_GROUP_CREATE_TEXT); } } PANEL panel_group = { .type = PANEL_NONE, .disabled = 1, .child = (PANEL*[]) { &panel_group_chat, &panel_group_video, &panel_group_settings, NULL } }, panel_group_create = { .type = PANEL_NONE, .disabled = true, .drawfunc = draw_group_create, .child = (PANEL*[]) { (PANEL*)&button_create_group, (PANEL*)&switch_group_type, NULL } }, panel_group_chat = { .type = PANEL_NONE, .disabled = 0, .drawfunc = draw_group, .child = (PANEL*[]) { (PANEL*)&scrollbar_group, (PANEL*)&edit_chat_msg_group, // this needs to be one of the first, to get events before the others (PANEL*)&messages_group, (PANEL*)&button_group_audio, (PANEL*)&button_chat_send_group, NULL } }, panel_group_video = { .type = PANEL_NONE, .disabled = 1, .child = (PANEL*[]) { NULL } }, panel_group_settings = { .type = PANEL_NONE, .disabled = 1, .drawfunc = draw_group_settings, .child = (PANEL*[]) { (PANEL*)&edit_group_topic, (PANEL*)&dropdown_notify_groupchats, NULL } }, messages_group = { .type = PANEL_MESSAGES, .content_scroll = &scrollbar_group, }; static void button_group_audio_on_mup(void) { GROUPCHAT *g = flist_get_groupchat(); if (!g) { LOG_ERR("Group", "Could not get selected groupchat."); return; } // We have to take the long way around, because the UI shouldn't depend on AV if (g->active_call) { postmessage_toxcore(TOX_GROUP_AUDIO_END, g->number, 0, NULL); } else { postmessage_toxcore(TOX_GROUP_AUDIO_START, g->number, 0, NULL); } } static void button_group_audio_update(BUTTON *b) { GROUPCHAT *g = flist_get_groupchat(); if (!g) { LOG_ERR("Group", "Could not get selected groupchat."); return; } if (g->av_group) { b->disabled = false; if (g->active_call) { button_setcolors_danger(b); } else { button_setcolors_success(b); } } else { b->disabled = true; button_setcolors_disabled(b); } } BUTTON button_group_audio = { .bm_fill = BM_LBUTTON, .bm_icon = BM_CALL, .icon_w = _BM_LBICON_WIDTH, .icon_h = _BM_LBICON_HEIGHT, .on_mup = button_group_audio_on_mup, .update = button_group_audio_update, .tooltip_text = {.i18nal = STR_GROUPCHAT_JOIN_AUDIO }, }; static uint32_t peers_deduplicate(char **dedup, size_t *dedup_size, GROUP_PEER **peers, uint32_t peer_count) { uint32_t count = 0; for (size_t peer = 0; peer < peer_count; peer++) { GROUP_PEER *p = peers[peer]; if (!p) { continue; } uint8_t *nick = p->name; size_t nick_len = p->name_length; size_t i = 0; if (nick) { bool found = false; while (!found && i < count) { if (nick_len == dedup_size[i] && !memcmp(nick, dedup[i], nick_len)) { found = true; } i++; } if (!found) { dedup[count] = (char *)nick; dedup_size[count] = nick_len; count++; } } } return count; } static struct { uint16_t start, end, cursorpos; uint32_t length, spacing; bool active; bool edited; } completion; static uint8_t nick_completion_search(EDIT *edit, char *found_nick, int direction) { char * text = edit->data; uint32_t i, peers, prev_index, compsize = completion.length; char * nick = NULL; size_t nick_len = 0; bool found = 0; static char * dedup[65536]; /* TODO magic numbers */ static size_t dedup_size[65536]; /* TODO magic numbers */ GROUPCHAT * g = flist_get_groupchat(); if (!g) { LOG_ERR("Group", "Could not get selected groupchat."); return 0; } peers = peers_deduplicate(dedup, dedup_size, g->peer, g->peer_count); i = 0; while (!found) { if (i >= peers) { found = 1; i = 0; } else { nick = dedup[i]; nick_len = dedup_size[i]; if (nick_len == completion.end - completion.start - completion.spacing && !memcmp(nick, text + completion.start, nick_len)) { found = 1; } else { i++; } } } prev_index = i; found = 0; do { if (direction == -1 && i == 0) { i = peers; } i += direction; if (i >= peers) { i = 0; } nick = dedup[i]; nick_len = dedup_size[i]; if (nick_len >= compsize && !memcmp_case(nick, text + completion.start, compsize)) { found = 1; } } while (!found && i != prev_index); if (found) { memcpy(found_nick, nick, nick_len); return nick_len; } else { return 0; } } static void nick_completion_replace(EDIT *edit, char *nick, uint32_t size) { char * text = edit->data; uint16_t length = edit->length; uint16_t maxlength = edit->data_size - 1; int offset; completion.spacing = 1; size += 1; if (!completion.start) { size += 1; completion.spacing += 1; nick[size - 2] = ':'; } nick[size - 1] = ' '; if (length > completion.end) { size -= 1; completion.spacing -= 1; } if (completion.start + size > maxlength) { size = maxlength - completion.start; } offset = completion.end - completion.start - size; edit_do(edit, completion.start, completion.end - completion.start, 1); memmove(text + completion.end - offset, text + completion.end, length - offset > maxlength ? maxlength - completion.end + offset : length - completion.end); memcpy(text + completion.start, nick, size); edit_do(edit, completion.start, size, 0); if (length - offset > maxlength) { edit->length = maxlength; } else { edit->length -= offset; } completion.end -= offset; } static void e_chat_msg_ontab(EDIT *edit) { char *text = edit->data; uint16_t length = edit->length; if (flist_get_type() == ITEM_FRIEND || flist_get_type() == ITEM_GROUP) { char nick[130]; uint8_t nick_length; if (completion.cursorpos != edit_getcursorpos()) { completion.active = 0; } if (!completion.active) { if ((length == 6 && !memcmp(text, "/topic", 6)) || (length == 7 && !memcmp(text, "/topic ", 7))) { GROUPCHAT *g = flist_get_groupchat(); if (!g) { LOG_ERR("Group", "Could not get selected groupchat."); return; } text[6] = ' '; memcpy(text + 7, g->name, g->name_length); edit->length = g->name_length + 7; edit_setcursorpos(edit, edit->length); return; } completion.start = edit_getcursorpos(); while (completion.start > 0 && text[completion.start - 1] != ' ') { completion.start--; } completion.end = completion.start; while (completion.end < length && text[completion.end] != ' ') { completion.end++; } completion.active = 1; completion.length = completion.end - completion.start; } nick_length = nick_completion_search(edit, nick, 1); if (nick_length) { completion.edited = 1; if (!(nick_length == completion.end - completion.start - completion.spacing && !memcmp(nick, text + completion.start, nick_length))) { nick_completion_replace(edit, nick, nick_length); } edit_setcursorpos(edit, completion.end); completion.cursorpos = edit_getcursorpos(); } } else { completion.active = 0; } } void e_group_msg_onenter(EDIT *edit) { char *text = edit->data; uint16_t length = edit->length; if (length <= 0) { return; } uint16_t command_length = 0; //, argument_length = 0; char *command = NULL; char *argument = NULL; command_length = utox_run_command(text, length, &command, &argument, 1); // TODO: Magic number if (command_length == UINT16_MAX) { edit->length = 0; return; } // LOG_NOTE("Group", "cmd %u\n", command_length); bool action = false; if (command_length) { length = length - command_length - 2; /* first / and then the SPACE */ text = argument; if ((command_length == 2) && (!memcmp(command, "me", 2))) { if (argument) { action = true; } else { return; } } } if (!text) { return; } GROUPCHAT *g = flist_get_groupchat(); if (g) { void *d = malloc(length); if (!d) { LOG_ERR("Layout Group", "edit_msg_onenter:\t Ran out of memory."); return; } memcpy(d, text, length); postmessage_toxcore((action ? TOX_GROUP_SEND_ACTION : TOX_GROUP_SEND_MESSAGE), g->number, length, d); } else { LOG_ERR("Groups", "No Group selected!"); } completion.active = 0; edit->length = 0; } static void e_chat_msg_onshifttab(EDIT *edit) { char *text = edit->data; if (flist_get_type() == ITEM_GROUP) { char nick[130]; uint8_t nick_length; if (completion.cursorpos != edit_getcursorpos()) { completion.active = 0; } if (completion.active) { nick_length = nick_completion_search(edit, nick, -1); if (nick_length) { completion.edited = 1; if (!(nick_length == completion.end - completion.start - completion.spacing && !memcmp(nick, text + completion.start, nick_length))) { nick_completion_replace(edit, nick, nick_length); } edit_setcursorpos(edit, completion.end); completion.cursorpos = edit_getcursorpos(); } } } else { completion.active = 0; } } static void edit_msg_onlosefocus(EDIT *UNUSED(edit)) { completion.active = 0; } SCROLLABLE e_chat_msg_group_scroll = { .panel = { .type = PANEL_SCROLLABLE, }, .d = 1.0, .color = C_SCROLL, }; static char e_chat_msg_group_data[65535]; EDIT edit_chat_msg_group = { .multiline = true, .data_size = sizeof e_chat_msg_group_data, .data = e_chat_msg_group_data, .onenter = e_group_msg_onenter, .ontab = e_chat_msg_ontab, .onshifttab = e_chat_msg_onshifttab, .onlosefocus = edit_msg_onlosefocus, .scroll = &e_chat_msg_group_scroll, }; static void e_group_topic_onenter(EDIT *edit) { GROUPCHAT *g = flist_get_groupchat(); if (!g) { LOG_ERR("Layout Groups", "Can't set a topic when a group isn't selected!"); return; } void *d = malloc(edit->length); if (!d){ LOG_ERR("Layout Groups", "Unable to change group topic."); return; } memcpy(d, edit->data, edit->length); postmessage_toxcore(TOX_GROUP_SET_TOPIC, g->number, edit->length, d); } static char e_group_topic_data[1024]; EDIT edit_group_topic = { .panel = { .type = PANEL_EDIT, .x = 10, .y = 88, .width = -10, .height = 24 }, .data = e_group_topic_data, .data_size = sizeof e_group_topic_data, .onenter = e_group_topic_onenter, .onlosefocus = e_group_topic_onenter, .noborder = false, .empty_str = {.plain = STRING_INIT("") }, }; static void button_chat_send_on_mup(void) { if (flist_get_type() == ITEM_GROUP) { e_group_msg_onenter(&edit_chat_msg_group); // reset focus to the chat window on send to prevent segfault. May break on android. edit_setfocus(&edit_chat_msg_group); } } static void button_chat_send_group_update(BUTTON *b) { b->disabled = false; button_setcolors_success(b); } BUTTON button_chat_send_group = { .bm_fill = BM_CHAT_SEND, .bm_icon = BM_CHAT_SEND_OVERLAY, .icon_w = _BM_CHAT_SEND_OVERLAY_WIDTH, .icon_h = _BM_CHAT_SEND_OVERLAY_HEIGHT, .on_mup = button_chat_send_on_mup, .update = button_chat_send_group_update, .tooltip_text = {.i18nal = STR_SENDMESSAGE }, .nodraw = false }; BUTTON button_create_group = { .panel = { .type = PANEL_BUTTON, .x = 10, .y = MAIN_TOP + 67, .width = _BM_SBUTTON_WIDTH, .height = _BM_SBUTTON_HEIGHT }, .bm_fill = BM_SBUTTON, .update = button_setcolors_success, .on_mup = button_create_group_on_mup, .disabled = false, .button_text = {.i18nal = STR_GROUP_CREATE_TEXT }, }; UISWITCH switch_group_type = { .panel = { .type = PANEL_SWITCH, .x = 10, .y = MAIN_TOP + 35, .width = _BM_SWITCH_WIDTH, .height = _BM_SWITCH_HEIGHT }, .style_outer = BM_SWITCH, .style_toggle = BM_SWITCH_TOGGLE, .style_icon_off = BM_NO, .style_icon_on = BM_YES, .update = switch_update, .on_mup = switchfxn_group_type, .tooltip_text = {.i18nal = STR_GROUP_CREATE_VOICE }, }; uTox-0.17.1/src/layout/group.h000066400000000000000000000013421354126257400161610ustar00rootroot00000000000000#ifndef LAYOUT_GROUP_H #define LAYOUT_GROUP_H typedef struct scrollable SCROLLABLE; extern SCROLLABLE scrollbar_group; typedef struct panel PANEL; extern PANEL panel_group, panel_group_create, panel_group_chat, panel_group_video, panel_group_settings, messages_group; typedef struct button BUTTON; extern BUTTON button_group_audio, button_chat_send_group, button_create_group; typedef struct dropdown DROPDOWN; extern DROPDOWN dropdown_notify_groupchats; typedef struct uiswitch UISWITCH; extern UISWITCH switch_group_type; typedef struct edit EDIT; extern EDIT edit_chat_msg_group, edit_group_topic; #endif // LAYOUT_GROUP_H uTox-0.17.1/src/layout/notify.c000066400000000000000000000055661354126257400163440ustar00rootroot00000000000000#include "notify.h" #include "userbadge.h" #include "../avatar.h" #include "../debug.h" #include "../notify.h" #include "../self.h" #include "../theme.h" #include "../tox.h" #include "../ui.h" #include "../ui/svg.h" #include "../ui/draw.h" #include "../ui/button.h" bool btn_move_window_down; static void draw_notification(int x, int y, int w, int h) { if (!tox_thread_init) { return; } drawrect(x, y, w, h, COLOR_BKGRND_MAIN); if (self_has_avatar()) { draw_avatar_image(self.avatar->img, SIDEBAR_AVATAR_LEFT, SIDEBAR_AVATAR_TOP, self.avatar->width, self.avatar->height, BM_CONTACT_WIDTH, BM_CONTACT_WIDTH); } else { drawalpha(BM_CONTACT, SIDEBAR_AVATAR_LEFT, SIDEBAR_AVATAR_TOP, BM_CONTACT_WIDTH, BM_CONTACT_WIDTH, COLOR_MENU_TEXT); } setcolor(!button_name.mouseover ? COLOR_MENU_TEXT : COLOR_MENU_TEXT_SUBTEXT); setfont(FONT_SELF_NAME); drawtext(SIDEBAR_NAME_LEFT, SIDEBAR_NAME_TOP, "This is a test of the new uTox popup", 36); } PANEL panel_notify_generic = { .type = PANEL_NONE, .drawfunc = draw_notification, .disabled = 0, .child = (PANEL*[]) { (PANEL*)&button_notify_one, (PANEL*)&button_notify_two, (PANEL*)&button_notify_three, // (PANEL*)&button_move_notify, NULL } }; static void btn_notify_one_mup(void) { LOG_ERR("Layout Notify", "Button 1 pressed"); } BUTTON button_notify_one = { // .bm_fill = BM_SBUTTON, .update = button_setcolors_success, .on_mup = btn_notify_one_mup, .nodraw = false, }; static void btn_notify_two_mup(void) { LOG_ERR("Layout Notify", "Button 2 pressed"); } BUTTON button_notify_two = { // .bm_fill = BM_SBUTTON, .update = button_setcolors_success, .on_mup = btn_notify_two_mup, .nodraw = false, }; static void btn_notify_three_mup(void) { LOG_ERR("Layout Notify", "Button 3 pressed"); } BUTTON button_notify_three = { // .bm_fill = BM_SBUTTON, .update = button_setcolors_success, .on_mup = btn_notify_three_mup, .nodraw = false, }; #if 0 static void btn_move_window_mdn(void) { LOG_NOTE("Layout Notify", "button move down\n"); btn_move_window_down = true; } static void btn_move_window_mup(void) { LOG_NOTE("Layout Notify", "button move up\n"); btn_move_window_down = false; } #endif static void btn_move_notify_mup(void) { LOG_NOTE("Layout Notify", "button tween\n"); // window_tween(); } BUTTON button_move_notify = { .nodraw = false, .disabled = false, .on_mup = btn_move_notify_mup, }; static void btn_notify_create_mup(void) { notify_new(NOTIFY_TYPE_MSG); } BUTTON button_notify_create = { .bm_fill = BM_SBUTTON, .update = button_setcolors_success, .on_mup = btn_notify_create_mup, .button_text = {.i18nal = STR_SHOW }, .tooltip_text = {.i18nal = STR_SHOW }, }; uTox-0.17.1/src/layout/notify.h000066400000000000000000000006501354126257400163360ustar00rootroot00000000000000#ifndef LAYOUT_NOTIFY_H #define LAYOUT_NOTIFY_H #include typedef struct panel PANEL; extern PANEL panel_notify_generic; typedef struct button BUTTON; extern BUTTON button_notify_one, button_notify_two, button_notify_three, button_move_notify, button_notify_create; // TODO, no good capin' extern bool btn_move_window_down; #endif // LAYOUT_NOTIFY_H uTox-0.17.1/src/layout/settings.c000066400000000000000000001336661354126257400166770ustar00rootroot00000000000000#include "settings.h" #include "../debug.h" #include "../flist.h" #include "../macros.h" #include "../self.h" #include "../theme.h" #include "../tox.h" #include "../updater.h" #include "../av/video.h" #include "../native/clipboard.h" #include "../native/dialog.h" #include "../native/filesys.h" #include "../native/keyboard.h" #include "../native/notify.h" #include "../native/os.h" #include "../ui/button.h" #include "../ui/contextmenu.h" #include "../ui/draw.h" #include "../ui/dropdown.h" #include "../ui/edit.h" #include "../ui/scrollable.h" #include "../ui/svg.h" #include "../ui/switch.h" #include #include #include /* Top bar for user settings */ static void draw_settings_header(int x, int y, int w, int UNUSED(height)) { (void)w; // Silence an irreverent warning when GIT_VERSION is undefined setcolor(COLOR_MAIN_TEXT); setfont(FONT_SELF_NAME); drawstr(x + SCALE(10), y + SCALE(10), UTOX_SETTINGS); #ifdef GIT_VERSION setfont(FONT_TEXT); char ver_string[64]; int ver_string_len; snprintf(ver_string, sizeof(ver_string), "Toxcore v%u.%u.%u", tox_version_major(), tox_version_minor(), tox_version_patch()); ver_string_len = strnlen(ver_string, sizeof(ver_string) - 1); drawtextwidth_right(x + w - textwidth(ver_string, ver_string_len), textwidth(ver_string, ver_string_len), SCALE(10), ver_string, ver_string_len); setfont(FONT_SELF_NAME); // x adjustment depends on the font type being set first x += SCALE(25) + UTOX_STR_WIDTH(UTOX_SETTINGS); setfont(FONT_TEXT); drawtext(x, SCALE(10), GIT_VERSION, strlen(GIT_VERSION)); #endif } #define DRAW_UNDERLINE() drawhline(x, y + SCALE(28), next_x, COLOR_EDGE_NORMAL) #define DRAW_OVERLINE() drawhline(x, y + SCALE(0), next_x, COLOR_EDGE_ACTIVE); \ drawhline(x, y + SCALE(1), next_x, COLOR_EDGE_ACTIVE) static void draw_settings_sub_header(int x, int y, int width, int UNUSED(height)) { drawhline(x, y, x + width, COLOR_EDGE_NORMAL); setfont(FONT_SELF_NAME); int last_x = x + width; /* Draw the text and bars for general settings */ setcolor(!button_settings_sub_profile.mouseover ? COLOR_MAIN_TEXT : COLOR_MAIN_TEXT_SUBTEXT); int next_x = x + SCALE(20) + UTOX_STR_WIDTH(PROFILE_BUTTON); drawstr(x + SCALE(10), y + SCALE(10), PROFILE_BUTTON); if (panel_settings_profile.disabled) { DRAW_UNDERLINE(); } else { DRAW_OVERLINE(); } drawvline(next_x, y, y + SCALE(28), COLOR_EDGE_NORMAL); x = next_x; /* Draw the text and bars for device settings */ #ifdef ENABLE_MULTIDEVICE setcolor(!button_settings_sub_devices.mouseover ? COLOR_MAIN_TEXT : COLOR_MAIN_TEXT_SUBTEXT); next_x += SCALE(20) + UTOX_STR_WIDTH(DEVICES_BUTTON); drawstr(x + SCALE(10), y, + SCALE(10), DEVICES_BUTTON); if (panel_settings_devices.disabled) { DRAW_UNDERLINE(); } else { DRAW_OVERLINE(); } drawvline(next_x, y, y, + SCALE(28), COLOR_EDGE_NORMAL); x = next_x; #endif /* Draw the text and bars for User interface settings */ setcolor(!button_settings_sub_ui.mouseover ? COLOR_MAIN_TEXT : COLOR_MAIN_TEXT_SUBTEXT); next_x += SCALE(20) + UTOX_STR_WIDTH(USER_INTERFACE_BUTTON); drawstr(x + SCALE(10), y + SCALE(10), USER_INTERFACE_BUTTON); if (panel_settings_ui.disabled) { DRAW_UNDERLINE(); } else { DRAW_OVERLINE(); } drawvline(next_x, y, y + SCALE(28), COLOR_EDGE_NORMAL); x = next_x; /* Draw the text and bars for A/V settings */ setcolor(!button_settings_sub_av.mouseover ? COLOR_MAIN_TEXT : COLOR_MAIN_TEXT_SUBTEXT); next_x += SCALE(20) + UTOX_STR_WIDTH(AUDIO_VIDEO_BUTTON); drawstr(x + SCALE(10), y + SCALE(10), AUDIO_VIDEO_BUTTON); if (panel_settings_av.disabled) { DRAW_UNDERLINE(); } else { DRAW_OVERLINE(); } drawvline(next_x, y, y + SCALE(28), COLOR_EDGE_NORMAL); x = next_x; /* Draw the text and bars for notification settings */ setcolor(!button_settings_sub_notifications.mouseover ? COLOR_MAIN_TEXT : COLOR_MAIN_TEXT_SUBTEXT); next_x += SCALE(20) + UTOX_STR_WIDTH(NOTIFICATIONS_BUTTON); drawstr(x + SCALE(10), y + SCALE(10), NOTIFICATIONS_BUTTON); if (panel_settings_notifications.disabled) { DRAW_UNDERLINE(); } else { DRAW_OVERLINE(); } drawvline(next_x, y, y + SCALE(28), COLOR_EDGE_NORMAL); x = next_x; /* Draw the text and bars for advanced settings */ setcolor(!button_settings_sub_adv.mouseover ? COLOR_MAIN_TEXT : COLOR_MAIN_TEXT_SUBTEXT); next_x += SCALE(20) + UTOX_STR_WIDTH(ADVANCED_BUTTON); drawstr(x + SCALE(10), y + SCALE(10), ADVANCED_BUTTON); if (panel_settings_adv.disabled) { DRAW_UNDERLINE(); } else { DRAW_OVERLINE(); } drawvline(next_x, y, y + SCALE(28), COLOR_EDGE_NORMAL); x = next_x; next_x = last_x; DRAW_UNDERLINE(); } /* draw switch profile top bar */ /* Text content for settings page */ static void draw_settings_text_profile(int x, int y, int UNUSED(w), int UNUSED(h)) { setcolor(COLOR_MAIN_TEXT); setfont(FONT_SELF_NAME); drawstr(x + SCALE(10), y + SCALE(10), NAME); drawstr(x + SCALE(10), y + SCALE(65), STATUSMESSAGE); drawstr(x + SCALE(10), y + SCALE(120), TOXID); if (self.qr_image && !button_qr.disabled) { // Enlarge original QR for better recognition const double image_scale = SCALE(4); const uint32_t image_size = self.qr_image_size * image_scale; button_qr.panel.width = button_qr.panel.height = UN_SCALE(self.qr_image_size * image_scale); image_set_scale(self.qr_image, image_scale); draw_image(self.qr_image, x + SCALE(10), y + SCALE(175), image_size, image_size, 0, 0); image_set_scale(self.qr_image, 1.0); } } // Devices settings page static void draw_settings_text_devices(int x, int y, int UNUSED(w), int UNUSED(h)) { setcolor(COLOR_MAIN_TEXT); setfont(FONT_SELF_NAME); drawstr(x + SCALE(10), y + SCALE(10), DEVICES_ADD_NEW); drawstr(x + SCALE(10), y + SCALE(60), DEVICES_NUMBER); char str[10]; snprintf(str, sizeof(str), "%zu", self.device_list_count); size_t str_len = strnlen(str, sizeof(str) - 1); drawtext(x + SCALE(10), y + SCALE(75), str, str_len); } static void draw_settings_text_password(int x, int y, int UNUSED(w), int UNUSED(h)) { setcolor(COLOR_MAIN_TEXT); setfont(FONT_SELF_NAME); drawstr(x + SCALE(10), y + SCALE(245), PROFILE_PASSWORD); setfont(FONT_MISC); setcolor(C_RED); drawstr(x + SCALE(10), y + SCALE(319), PROFILE_PW_WARNING); drawstr(x + SCALE(10), y + SCALE(331), PROFILE_PW_NO_RECOVER); } static void draw_nospam_settings(int x, int y, int UNUSED(w), int UNUSED(h)){ setfont(FONT_MISC); setcolor(C_RED); drawstr(x + SCALE(95), y + SCALE(248), NOSPAM_WARNING); setcolor(COLOR_MAIN_TEXT); setfont(FONT_SELF_NAME); drawstr(x + SCALE(10), y + SCALE(245), NOSPAM); } // UI settings page static void draw_settings_text_ui(int x, int y, int UNUSED(w), int UNUSED(height)) { setcolor(COLOR_MAIN_TEXT); setfont(FONT_SELF_NAME); drawstr(x + SCALE(10), y + SCALE(10), LANGUAGE); drawstr(x + SCALE(150), y + SCALE(65), DPI); drawstr(x + SCALE(10), y + SCALE(65), THEME); drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(120), SAVE_CHAT_HISTORY); drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(150), CLOSE_TO_TRAY); drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(180), START_IN_TRAY); drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(210), AUTO_STARTUP); drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(240), SETTINGS_UI_MINI_ROSTER); #if PLATFORM_ANDROID drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(270), SETTINGS_UI_AUTO_HIDE_SIDEBAR); #endif } // Audio/Video settings page static void draw_settings_text_av(int x, int y, int UNUSED(w), int UNUSED(height)) { setcolor(COLOR_MAIN_TEXT); setfont(FONT_SELF_NAME); // The element is draw_pos_y_inc units apart and they start draw_pos_y down. uint16_t draw_pos_y = 15; uint16_t draw_pos_y_inc = 30; drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(draw_pos_y), PUSH_TO_TALK); draw_pos_y += draw_pos_y_inc; #ifdef AUDIO_FILTERING drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(draw_pos_y), AUDIOFILTERING); draw_pos_y += draw_pos_y_inc; #endif // These are 60 apart as there needs to be room for a dropdown between them. draw_pos_y_inc = 60; drawstr(x + SCALE(10), y + SCALE(draw_pos_y), AUDIOINPUTDEVICE); draw_pos_y += draw_pos_y_inc; drawstr(x + SCALE(10), y + SCALE(draw_pos_y - 7), AUDIOOUTPUTDEVICE); draw_pos_y += draw_pos_y_inc; drawstr(x + SCALE(10), y + SCALE(draw_pos_y - 15), VIDEOFRAMERATE); draw_pos_y += draw_pos_y_inc; drawstr(x + SCALE(10), y + SCALE(draw_pos_y - 23), VIDEOINPUTDEVICE); draw_pos_y += draw_pos_y_inc; drawstr(x + SCALE(10), y + SCALE(draw_pos_y - 30), PREVIEW); } // Notification settings page static void draw_settings_text_notifications(int x, int y, int UNUSED(w), int UNUSED(height)) { setcolor(COLOR_MAIN_TEXT); setfont(FONT_SELF_NAME); drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(15), RINGTONE); drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(45), STATUS_NOTIFICATIONS); drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(75), SEND_TYPING_NOTIFICATIONS); drawstr(x + SCALE(10), y + SCALE(105), GROUP_NOTIFICATIONS); } static void draw_settings_text_adv(int x, int y, int UNUSED(w), int UNUSED(height)) { setfont(FONT_MISC); setcolor(C_RED); drawstr(x + SCALE(10), y + SCALE(5), WARNING); setcolor(COLOR_MAIN_TEXT); setfont(FONT_SELF_NAME); drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(30), IPV6); drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(60), UDP); drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(90), PROXY); drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(120), PROXY_FORCE); // TODO draw ONLY when settings.use_proxy = true drawtext(x + SCALE(353), y + SCALE(89), ":", 1); // Little addr port separator drawstr(x + SCALE(20)+ BM_SWITCH_WIDTH, y + SCALE(150), AUTO_UPDATE); drawstr(x + SCALE(20)+ BM_SWITCH_WIDTH, y + SCALE(180), BLOCK_FRIEND_REQUESTS); } SCROLLABLE scrollbar_settings = { .panel = { .type = PANEL_SCROLLABLE, }, .color = C_SCROLL, }; /* Draw the text for profile password window */ static void draw_profile_password(int x, int UNUSED(y), int UNUSED(w), int UNUSED(height)) { setcolor(COLOR_MAIN_TEXT); setfont(FONT_SELF_NAME); drawstr(x + SCALE(10), SCALE(10), PROFILE_PASSWORD); setcolor(COLOR_MAIN_TEXT_SUBTEXT); setfont(FONT_TEXT); drawstr(x + SCALE(10), SCALE(MAIN_TOP + 5), PROFILE_PASSWORD); } PANEL boxfor_password_entry_login = { .type = PANEL_NONE, .x = 0, .y = 0, .child = (PANEL*[]) { (PANEL*)&edit_profile_password, NULL } }, boxfor_password_entry_change = { .type = PANEL_NONE, .x = 0, .y = 180, .child = (PANEL*[]) { (PANEL*)&edit_profile_password, NULL } }, panel_profile_password = { .type = PANEL_NONE, .disabled = 0, .drawfunc = draw_profile_password, .child = (PANEL*[]) { (PANEL*)&boxfor_password_entry_login, NULL } }, panel_nospam_settings = { .type = PANEL_NONE, .disabled = true, .drawfunc = draw_nospam_settings, .content_scroll = &scrollbar_settings, .child = (PANEL*[]) { (PANEL*)&edit_nospam, (PANEL*)&button_change_nospam, (PANEL*)&button_revert_nospam, NULL } }, panel_profile_password_settings = { .type = PANEL_NONE, .disabled = 1, .drawfunc = draw_settings_text_password, .child = (PANEL*[]) { (PANEL*)&boxfor_password_entry_change, (PANEL*)&button_lock_uTox, NULL } }, panel_settings_master = { .type = PANEL_NONE, .disabled = 1, .drawfunc = draw_settings_header, .child = (PANEL*[]) { &panel_settings_subheader, NULL } }, panel_settings_subheader = { .y = MAIN_TOP_FRAME_THIN, .type = PANEL_NONE, .disabled = 0, .drawfunc = draw_settings_sub_header, .child = (PANEL*[]) { (PANEL*)&button_settings_sub_profile, (PANEL*)&button_settings_sub_devices, (PANEL*)&button_settings_sub_ui, (PANEL*)&button_settings_sub_av, (PANEL*)&button_settings_sub_notifications, (PANEL*)&button_settings_sub_adv, (PANEL*)&scrollbar_settings, &panel_settings_profile, &panel_settings_devices, &panel_settings_ui, &panel_settings_av, &panel_settings_notifications, &panel_settings_adv, NULL } }, /* Panel to draw settings page */ panel_settings_profile = { .type = PANEL_NONE, .disabled = 0, .drawfunc = draw_settings_text_profile, .content_scroll = &scrollbar_settings, .child = (PANEL*[]) { (PANEL*)&edit_name, (PANEL*)&edit_status_msg, // Text: Tox ID (PANEL*)&edit_toxid, (PANEL*)&button_copyid, (PANEL*)&button_show_qr, (PANEL*)&button_qr, NULL } }, /* Panel to draw settings page */ panel_settings_devices = { .type = PANEL_NONE, .disabled = 1, .drawfunc = draw_settings_text_devices, .content_scroll = &scrollbar_settings, .child = NULL, }, panel_settings_ui = { .type = PANEL_NONE, .drawfunc = draw_settings_text_ui, .disabled = 1, .content_scroll = &scrollbar_settings, .child = (PANEL*[]) { (PANEL*)&dropdown_language, (PANEL*)&dropdown_dpi, (PANEL*)&dropdown_theme, (PANEL*)&switch_save_chat_history, (PANEL*)&switch_close_to_tray, (PANEL*)&switch_start_in_tray, (PANEL*)&switch_auto_startup, (PANEL*)&switch_mini_contacts, #if PLATFORM_ANDROID (PANEL*)&switch_magic_sidebar, #endif NULL } }, panel_settings_av = { .type = PANEL_NONE, .disabled = 1, .drawfunc = draw_settings_text_av, .content_scroll = &scrollbar_settings, .child = (PANEL*[]) { (PANEL*)&button_callpreview, (PANEL*)&switch_push_to_talk, (PANEL*)&button_videopreview, (PANEL*)&edit_video_fps, (PANEL*)&dropdown_audio_in, (PANEL*)&dropdown_audio_out, (PANEL*)&dropdown_video, (PANEL*)&switch_audio_filtering, NULL } }, panel_settings_notifications = { .type = PANEL_NONE, .disabled = true, .drawfunc = draw_settings_text_notifications, .content_scroll = &scrollbar_settings, .child = (PANEL*[]) { (PANEL*)&dropdown_global_group_notifications, (PANEL*)&switch_status_notifications, (PANEL*)&switch_typing_notes, (PANEL*)&switch_audible_notifications, NULL } }, panel_settings_adv = { .type = PANEL_NONE, .disabled = true, .drawfunc = draw_settings_text_adv, .content_scroll = &scrollbar_settings, .child = (PANEL*[]) { (PANEL*)&edit_proxy_ip, (PANEL*)&edit_proxy_port, (PANEL*)&switch_proxy, (PANEL*)&switch_proxy_force, (PANEL*)&switch_ipv6, (PANEL*)&switch_udp, (PANEL*)&switch_auto_update, (PANEL*)&button_show_password_settings, &panel_profile_password_settings, (PANEL*)&switch_block_friend_requests, (PANEL*)&button_show_nospam, &panel_nospam_settings, NULL, } }; extern SCROLLABLE scrollbar_settings; static void button_bottommenu_update(BUTTON *b) { b->c1 = COLOR_BKGRND_MENU; b->c2 = COLOR_BKGRND_MENU_HOVER; b->c3 = COLOR_BKGRND_MENU_ACTIVE; b->ct1 = COLOR_MENU_TEXT; b->ct2 = COLOR_MENU_TEXT; if (b->mousedown || b->disabled) { b->ct1 = COLOR_MENU_TEXT_ACTIVE; b->ct2 = COLOR_MENU_TEXT_ACTIVE; } b->cd = COLOR_BKGRND_MENU_ACTIVE; } static void button_settings_on_mup(void) { if (tox_thread_init == UTOX_TOX_THREAD_INIT_SUCCESS) { flist_selectsettings(); } } static void update_show_nospam_button_text(void) { if (panel_nospam_settings.disabled) { maybe_i18nal_string_set_i18nal(&button_show_nospam.button_text, STR_SHOW_NOSPAM); } else { maybe_i18nal_string_set_i18nal(&button_show_nospam.button_text, STR_HIDE_NOSPAM); } } static void update_show_password_button_text(void) { if (panel_profile_password_settings.disabled) { maybe_i18nal_string_set_i18nal(&button_show_password_settings.button_text, STR_SHOW_UI_PASSWORD); maybe_i18nal_string_set_i18nal(&button_show_password_settings.tooltip_text, STR_SHOW_UI_PASSWORD_TOOLTIP); } else { maybe_i18nal_string_set_i18nal(&button_show_password_settings.button_text, STR_HIDE_UI_PASSWORD); maybe_i18nal_string_set_i18nal(&button_show_password_settings.tooltip_text, STR_HIDE_UI_PASSWORD_TOOLTIP); } } BUTTON button_settings = { .bm_icon = BM_SETTINGS, .icon_w = _BM_ADD_WIDTH, .icon_h = _BM_ADD_WIDTH, .update = button_bottommenu_update, .on_mup = button_settings_on_mup, .disabled = false, .nodraw = false, .tooltip_text = {.i18nal = STR_USERSETTINGS }, }; static void close_dropdowns(PANEL *p) { if (!p->child) { return; } PANEL *ch; for (int i = 0; (ch = p->child[i]); ++i) { PANEL_TYPE type = ch->type; if (type == PANEL_DROPDOWN) { dropdown_close((DROPDOWN*)ch); } else if (type == PANEL_NONE) { close_dropdowns(ch); } } } void reset_settings_controls(void) { update_show_nospam_button_text(); update_show_password_button_text(); close_dropdowns(&panel_settings_master); } static void disable_all_setting_sub(void) { flist_selectsettings(); panel_settings_profile.disabled = true; panel_settings_devices.disabled = true; panel_settings_ui.disabled = true; panel_settings_av.disabled = true; panel_settings_notifications.disabled = true; panel_settings_adv.disabled = true; reset_settings_controls(); } static void button_settings_sub_profile_on_mup(void) { scrollbar_settings.content_height = SCALE(260); disable_all_setting_sub(); panel_settings_profile.disabled = false; } static void button_settings_sub_devices_on_mup(void) { scrollbar_settings.content_height = SCALE(260); disable_all_setting_sub(); panel_settings_devices.disabled = false; } static void button_settings_sub_ui_on_mup(void) { scrollbar_settings.content_height = SCALE(280); disable_all_setting_sub(); panel_settings_ui.disabled = false; } static void button_settings_sub_av_on_mup(void) { scrollbar_settings.content_height = SCALE(350); disable_all_setting_sub(); panel_settings_av.disabled = false; } static void button_settings_sub_adv_on_mup(void) { scrollbar_settings.content_height = SCALE(300); disable_all_setting_sub(); panel_settings_adv.disabled = false; } static void button_settings_sub_notifications_on_mup(void){ scrollbar_settings.content_height = SCALE(300); disable_all_setting_sub(); panel_settings_notifications.disabled = false; } static void button_add_device_to_self_mdown(void) { #ifdef ENABLE_MULTIDEVICE devices_self_add(edit_add_new_device_to_self.data, edit_add_new_device_to_self.length); edit_resetfocus(); #endif } BUTTON button_settings_sub_profile = { .nodraw = true, .on_mup = button_settings_sub_profile_on_mup, .tooltip_text = {.i18nal = STR_PROFILE_BUTTON }, .button_text = {.i18nal = STR_PROFILE_BUTTON }, }, button_settings_sub_devices = { .nodraw = true, .on_mup = button_settings_sub_devices_on_mup, .tooltip_text = {.i18nal = STR_DEVICES_BUTTON }, .button_text = {.i18nal = STR_DEVICES_BUTTON }, }, button_settings_sub_ui = { .nodraw = true, .on_mup = button_settings_sub_ui_on_mup, .tooltip_text = {.i18nal = STR_USER_INTERFACE_BUTTON }, .button_text = {.i18nal = STR_USER_INTERFACE_BUTTON }, }, button_settings_sub_av = { .nodraw = true, .on_mup = button_settings_sub_av_on_mup, .tooltip_text = {.i18nal = STR_AUDIO_VIDEO_BUTTON }, .button_text = {.i18nal = STR_AUDIO_VIDEO_BUTTON }, }, button_settings_sub_notifications = { .nodraw = true, .on_mup = button_settings_sub_notifications_on_mup, .tooltip_text = {.i18nal = STR_NOTIFICATIONS_BUTTON }, .button_text = {.i18nal = STR_NOTIFICATIONS_BUTTON }, }, button_settings_sub_adv = { .nodraw = true, .on_mup = button_settings_sub_adv_on_mup, .tooltip_text = {.i18nal = STR_ADVANCED_BUTTON }, .button_text = {.i18nal = STR_ADVANCED_BUTTON }, }, button_add_new_device_to_self = { .bm_fill = BM_SBUTTON, .button_text = {.i18nal = STR_ADD }, // .update = button_setcolors_success, .on_mup = button_add_device_to_self_mdown, }; #include "../tox.h" static void button_lock_uTox_on_mup(void) { if (tox_thread_init && edit_profile_password.length > 3) { flist_selectsettings(); panel_profile_password.disabled = false; panel_settings_master.disabled = true; tox_settingschanged(); } else { show_messagebox(NULL, 0, S(PASSWORD_TOO_SHORT), SLEN(PASSWORD_TOO_SHORT)); memset(edit_profile_password.data, '\0', edit_profile_password.data_size); edit_profile_password.length = 0; } button_show_password_settings.disabled = false; button_show_password_settings.nodraw = false; update_show_nospam_button_text(); update_show_password_button_text(); } static void button_show_password_settings_on_mup(void) { panel_nospam_settings.disabled = true; panel_profile_password_settings.disabled = !panel_profile_password_settings.disabled; update_show_nospam_button_text(); update_show_password_button_text(); } #include "../chatlog.h" #include "../flist.h" #include "../friend.h" static void button_export_chatlog_on_mup(void) { FRIEND *f = flist_get_friend(); if (!f) { LOG_ERR("Settings", "Could not get selected friend."); return; } utox_export_chatlog_init(f->number); } static void button_change_nospam_on_mup(void) { button_revert_nospam.disabled = false; long int nospam = rand() | rand() << 16; postmessage_toxcore(TOX_SELF_CHANGE_NOSPAM, nospam, 0, NULL); } static void button_revert_nospam_on_mup(void) { if (button_revert_nospam.disabled) { return; } if (self.old_nospam == 0 || self.nospam == self.old_nospam) { //nospam can not be 0 LOG_ERR("Settings", "Invalid or current nospam: %u.", self.old_nospam); return; } postmessage_toxcore(TOX_SELF_CHANGE_NOSPAM, self.old_nospam, 0, NULL); button_revert_nospam.disabled = true; } static void button_revert_nospam_on_update(BUTTON *b) { if (button_revert_nospam.disabled) { button_setcolors_disabled(b); } else { button_setcolors_success(b); } } static void button_show_nospam_on_mup(void) { panel_profile_password_settings.disabled = true; panel_nospam_settings.disabled = !panel_nospam_settings.disabled; update_show_nospam_button_text(); update_show_password_button_text(); } static void button_copyid_on_mup(void) { edit_setfocus(&edit_toxid); copy(0); } static void button_show_qr_on_mup(void) { if (button_qr.disabled) { maybe_i18nal_string_set_i18nal(&button_show_qr.button_text, STR_HIDE_QR); } else { maybe_i18nal_string_set_i18nal(&button_show_qr.button_text, STR_SHOW_QR); } button_qr.disabled = !button_qr.disabled; button_qr.panel.disabled = button_qr.disabled; } static void contextmenu_qr_onselect(uint8_t i) { if (i == 0) { if (!native_save_image_png(self.name, self.qr_data, self.qr_data_size)) { LOG_ERR("Self", "Unable to save QR code."); } } } static void button_qr_on_mright(void) { static UTOX_I18N_STR menu[] = { STR_SAVE_QR }; contextmenu_new(COUNTOF(menu), menu, contextmenu_qr_onselect); } #include "../settings.h" #include "../av/utox_av.h" static void button_audiopreview_on_mup(void) { if (!settings.audio_preview) { postmessage_utoxav(UTOXAV_START_AUDIO, 1, 0, NULL); } else { postmessage_utoxav(UTOXAV_STOP_AUDIO, 1, 0, NULL); } settings.audio_preview = !settings.audio_preview; } static void button_audiopreview_update(BUTTON *b) { if (settings.audio_preview) { button_setcolors_danger(b); } else { button_setcolors_success(b); } } static void button_videopreview_on_mup(void) { if (settings.video_preview) { postmessage_utoxav(UTOXAV_STOP_VIDEO, UINT16_MAX, 1, NULL); } else if (video_width && video_height) { postmessage_utoxav(UTOXAV_START_VIDEO, UINT16_MAX, 1, NULL); } else { LOG_ERR("Button", "Video_width = 0, can't preview\n"); return; } settings.video_preview = !settings.video_preview; } static void button_videopreview_update(BUTTON *b) { if (settings.video_preview) { button_setcolors_danger(b); } else { button_setcolors_success(b); } } static void button_show_qr_update(BUTTON *b) { button_setcolors_success(b); b->panel.x = 85 + UN_SCALE(UTOX_STR_WIDTH(COPY_TOX_ID)); } BUTTON button_copyid = { .bm_fill = BM_SBUTTON, .update = button_setcolors_success, .on_mup = button_copyid_on_mup, .disabled = false, .button_text = {.i18nal = STR_COPY_TOX_ID }, }; BUTTON button_show_qr = { .panel = { .type = PANEL_BUTTON, .x = 85 + _BM_SBUTTON_WIDTH, .y = 117, .width = _BM_SBUTTON_WIDTH, .height = _BM_SBUTTON_HEIGHT }, .bm_fill = BM_SBUTTON, .update = button_show_qr_update, .on_mup = button_show_qr_on_mup, .disabled = false, .button_text = {.i18nal = STR_SHOW_QR }, }; BUTTON button_qr = { .panel = { .type = PANEL_BUTTON, .x = 10, .y = 175, .disabled = true, }, .nodraw = true, .disabled = true, .onright = button_qr_on_mright, }; BUTTON button_callpreview = { .bm_fill = BM_LBUTTON, .bm_icon = BM_CALL, .icon_w = _BM_LBICON_WIDTH, .icon_h = _BM_LBICON_HEIGHT, .on_mup = button_audiopreview_on_mup, .update = button_audiopreview_update, .disabled = false, }; BUTTON button_videopreview = { .bm_fill = BM_LBUTTON, .bm_icon = BM_VIDEO, .icon_w = _BM_LBICON_WIDTH, .icon_h = _BM_LBICON_HEIGHT, .on_mup = button_videopreview_on_mup, .update = button_videopreview_update, .disabled = false, }; BUTTON button_lock_uTox = { .bm_fill = BM_SBUTTON, .update = button_setcolors_success, .on_mup = button_lock_uTox_on_mup, .button_text = {.i18nal = STR_LOCK }, .tooltip_text = {.i18nal = STR_LOCK_UTOX }, }; BUTTON button_show_password_settings = { .bm_fill = BM_SBUTTON, .update = button_setcolors_success, .on_mup = button_show_password_settings_on_mup, .button_text = {.i18nal = STR_SHOW_UI_PASSWORD }, .tooltip_text = {.i18nal = STR_SHOW_UI_PASSWORD_TOOLTIP }, }; BUTTON button_export_chatlog = { .bm_fill = BM_SBUTTON, .update = button_setcolors_success, .on_mup = button_export_chatlog_on_mup, .disabled = false, .button_text = {.i18nal = STR_FRIEND_EXPORT_CHATLOG }, .tooltip_text = {.i18nal = STR_FRIEND_EXPORT_CHATLOG }, }; BUTTON button_change_nospam = { .bm_fill = BM_SBUTTON, .update = button_setcolors_success, .on_mup = button_change_nospam_on_mup, .button_text = {.i18nal = STR_RANDOMIZE_NOSPAM}, .tooltip_text = {.i18nal = STR_RANDOMIZE_NOSPAM}, }; BUTTON button_revert_nospam = { .bm_fill = BM_SBUTTON, .update = button_revert_nospam_on_update, .on_mup = button_revert_nospam_on_mup, .disabled = true, .button_text = {.i18nal = STR_REVERT_NOSPAM}, .tooltip_text = {.i18nal = STR_REVERT_NOSPAM}, }; BUTTON button_show_nospam = { .bm_fill = BM_SBUTTON, .update = button_setcolors_success, .tooltip_text = {.i18nal = STR_SHOW_NOSPAM}, .button_text = {.i18nal = STR_SHOW_NOSPAM}, .on_mup = button_show_nospam_on_mup, }; static void switchfxn_logging(void) { settings.logging_enabled = !settings.logging_enabled; } static void switchfxn_mini_contacts(void) { settings.use_mini_flist = !settings.use_mini_flist; flist_re_scale(); } static void switchfxn_ipv6(void) { settings.enable_ipv6 = !settings.enable_ipv6; tox_settingschanged(); } static void switchfxn_udp(void) { settings.enable_udp = !settings.enable_udp; tox_settingschanged(); } static void switchfxn_close_to_tray(void) { settings.close_to_tray = !settings.close_to_tray; } static void switchfxn_start_in_tray(void) { settings.start_in_tray = !settings.start_in_tray; } static void switchfxn_auto_startup(void) { settings.start_with_system = !settings.start_with_system; launch_at_startup(settings.start_with_system); } static void switchfxn_typing_notes(void) { settings.send_typing_status = !settings.send_typing_status; } static void switchfxn_audible_notifications(void) { settings.ringtone_enabled = !settings.ringtone_enabled; } static void switchfxn_push_to_talk(void) { if (!settings.push_to_talk) { init_ptt(); } else { exit_ptt(); } } static void switchfxn_audio_filtering(void) { settings.audiofilter_enabled = !settings.audiofilter_enabled; } static void switchfxn_status_notifications(void) { settings.status_notifications = !settings.status_notifications; } static void switchfxn_auto_update(void) { settings.auto_update = !settings.auto_update; updater_start(0); } static void switchfxn_block_friend_requests(void) { settings.block_friend_requests = !settings.block_friend_requests; } UISWITCH switch_save_chat_history = { .style_outer = BM_SWITCH, .style_toggle = BM_SWITCH_TOGGLE, .style_icon_off = BM_NO, .style_icon_on = BM_YES, .update = switch_update, .on_mup = switchfxn_logging, .tooltip_text = {.i18nal = STR_SAVE_CHAT_HISTORY }, }; UISWITCH switch_mini_contacts = { .style_outer = BM_SWITCH, .style_toggle = BM_SWITCH_TOGGLE, .style_icon_off = BM_NO, .style_icon_on = BM_YES, .update = switch_update, .on_mup = switchfxn_mini_contacts, .tooltip_text = {.i18nal = STR_SETTINGS_UI_MINI_ROSTER }, }; static void switchfxn_magic_sidebar(void) { settings.magic_flist_enabled = !settings.magic_flist_enabled; } UISWITCH switch_magic_sidebar = { .panel = { .type = PANEL_SWITCH, .x = -10 - _BM_SWITCH_WIDTH, .y = 210, .width = _BM_SWITCH_WIDTH, .height = _BM_SWITCH_HEIGHT }, .style_outer = BM_SWITCH, .style_toggle = BM_SWITCH_TOGGLE, .style_icon_off = BM_NO, .style_icon_on = BM_YES, .update = switch_update, .on_mup = switchfxn_magic_sidebar, .tooltip_text = {.i18nal = STR_SETTINGS_UI_AUTO_HIDE_SIDEBAR }, }; UISWITCH switch_ipv6 = { .style_outer = BM_SWITCH, .style_toggle = BM_SWITCH_TOGGLE, .style_icon_off = BM_NO, .style_icon_on = BM_YES, .update = switch_update, .on_mup = switchfxn_ipv6, .tooltip_text = {.i18nal = STR_IPV6 }, }; UISWITCH switch_udp = { .style_outer = BM_SWITCH, .style_toggle = BM_SWITCH_TOGGLE, .style_icon_off = BM_NO, .style_icon_on = BM_YES, .update = switch_update, .on_mup = switchfxn_udp, .tooltip_text = {.i18nal = STR_UDP }, }; UISWITCH switch_close_to_tray = { .style_outer = BM_SWITCH, .style_toggle = BM_SWITCH_TOGGLE, .style_icon_off = BM_NO, .style_icon_on = BM_YES, .update = switch_update, .on_mup = switchfxn_close_to_tray, .tooltip_text = {.i18nal = STR_CLOSE_TO_TRAY }, }; UISWITCH switch_start_in_tray = { .style_outer = BM_SWITCH, .style_toggle = BM_SWITCH_TOGGLE, .style_icon_off = BM_NO, .style_icon_on = BM_YES, .update = switch_update, .on_mup = switchfxn_start_in_tray, .tooltip_text = {.i18nal = STR_START_IN_TRAY }, }; UISWITCH switch_auto_startup = { .style_outer = BM_SWITCH, .style_toggle = BM_SWITCH_TOGGLE, .style_icon_off = BM_NO, .style_icon_on = BM_YES, .update = switch_update, .on_mup = switchfxn_auto_startup, .tooltip_text = {.i18nal = STR_AUTO_STARTUP }, }; UISWITCH switch_typing_notes = { .style_outer = BM_SWITCH, .style_toggle = BM_SWITCH_TOGGLE, .style_icon_off = BM_NO, .style_icon_on = BM_YES, .update = switch_update, .on_mup = switchfxn_typing_notes, .tooltip_text = {.i18nal = STR_SEND_TYPING_NOTIFICATIONS }, }; UISWITCH switch_audible_notifications = { .style_outer = BM_SWITCH, .style_toggle = BM_SWITCH_TOGGLE, .style_icon_off = BM_NO, .style_icon_on = BM_YES, .update = switch_update, .on_mup = switchfxn_audible_notifications, .tooltip_text = {.i18nal = STR_AUDIONOTIFICATIONS }, }; UISWITCH switch_push_to_talk = { .style_outer = BM_SWITCH, .style_toggle = BM_SWITCH_TOGGLE, .style_icon_off = BM_NO, .style_icon_on = BM_YES, .update = switch_update, .on_mup = switchfxn_push_to_talk, .tooltip_text = {.i18nal = STR_PUSH_TO_TALK }, }; UISWITCH switch_audio_filtering = { .style_outer = BM_SWITCH, .style_toggle = BM_SWITCH_TOGGLE, .style_icon_off = BM_NO, .style_icon_on = BM_YES, .update = switch_update, .on_mup = switchfxn_audio_filtering, .tooltip_text = {.i18nal = STR_AUDIOFILTERING }, }; UISWITCH switch_status_notifications = { .style_outer = BM_SWITCH, .style_toggle = BM_SWITCH_TOGGLE, .style_icon_off = BM_NO, .style_icon_on = BM_YES, .update = switch_update, .on_mup = switchfxn_status_notifications, .tooltip_text = {.i18nal = STR_STATUS_NOTIFICATIONS }, }; UISWITCH switch_auto_update = { .style_outer = BM_SWITCH, .style_toggle = BM_SWITCH_TOGGLE, .style_icon_off = BM_NO, .style_icon_on = BM_YES, .update = switch_update, .on_mup = switchfxn_auto_update, .tooltip_text = {.i18nal = STR_AUTO_UPDATE } }; UISWITCH switch_block_friend_requests = { .style_outer = BM_SWITCH, .style_toggle = BM_SWITCH_TOGGLE, .style_icon_off = BM_NO, .style_icon_on = BM_YES, .update = switch_update, .on_mup = switchfxn_block_friend_requests, .tooltip_text = {.i18nal = STR_BLOCK_FRIEND_REQUESTS }, }; static void switchfxn_proxy(void) { settings.use_proxy = !settings.use_proxy; if (settings.use_proxy) { switch_proxy_force.panel.disabled = false; } else { settings.force_proxy = false; switch_proxy_force.switch_on = false; switch_proxy_force.panel.disabled = true; switch_udp.panel.disabled = false; } memcpy(proxy_address, edit_proxy_ip.data, edit_proxy_ip.length); proxy_address[edit_proxy_ip.length] = 0; edit_proxy_port.data[edit_proxy_port.length] = 0; settings.proxy_port = strtol((char *)edit_proxy_port.data, NULL, 0); tox_settingschanged(); } static void switchfxn_proxy_force(void) { settings.force_proxy = !settings.force_proxy; if (settings.force_proxy) { switch_udp.switch_on = false; settings.enable_udp = false; switch_udp.panel.disabled = true; } else { switch_udp.panel.disabled = false; } edit_proxy_port.data[edit_proxy_port.length] = 0; settings.proxy_port = strtol((char *)edit_proxy_port.data, NULL, 0); tox_settingschanged(); } UISWITCH switch_proxy = { .style_outer = BM_SWITCH, .style_toggle = BM_SWITCH_TOGGLE, .style_icon_off = BM_NO, .style_icon_on = BM_YES, .update = switch_update, .on_mup = switchfxn_proxy, .tooltip_text = {.i18nal = STR_PROXY } }; UISWITCH switch_proxy_force = { .style_outer = BM_SWITCH, .style_toggle = BM_SWITCH_TOGGLE, .style_icon_off = BM_NO, .style_icon_on = BM_YES, .update = switch_update, .on_mup = switchfxn_proxy_force, .tooltip_text = {.i18nal = STR_PROXY_FORCE }, }; static void dropdown_audio_in_onselect(uint16_t i, const DROPDOWN *dm) { DROP_ELEMENT *e = &((DROP_ELEMENT *)dm->userdata)[i]; void * handle = e->handle; postmessage_utoxav(UTOXAV_SET_AUDIO_IN, 0, 0, handle); } static void dropdown_audio_out_onselect(uint16_t i, const DROPDOWN *dm) { DROP_ELEMENT *e = &((DROP_ELEMENT *)dm->userdata)[i]; void * handle = e->handle; postmessage_utoxav(UTOXAV_SET_AUDIO_OUT, 0, 0, handle); } static void edit_video_fps_onlosefocus(EDIT *UNUSED(edit)) { edit_video_fps.data[edit_video_fps.length] = '\0'; char *temp; uint16_t value = strtol((char *)edit_video_fps.data, &temp, 10); if (*temp == '\0' && value >= 1 && value <= UINT8_MAX) { settings.video_fps = value; return; } LOG_WARN("Settings", "FPS value (%s) is invalid. It must be integer in range of [1,%u]. Setting default value (%u).", edit_video_fps.data, UINT8_MAX, DEFAULT_FPS); settings.video_fps = DEFAULT_FPS; snprintf((char *)edit_video_fps.data, edit_video_fps.data_size, "%u", DEFAULT_FPS); edit_video_fps.length = strnlen((char *)edit_video_fps.data, edit_video_fps.data_size - 1); } #include "../screen_grab.h" static void dropdown_video_onselect(uint16_t i, const DROPDOWN *UNUSED(dm)) { if (i == 1) { utox_screen_grab_desktop(1); } else { postmessage_utoxav(UTOXAV_SET_VIDEO_IN, i, 0, NULL); } } static void dropdown_dpi_onselect(uint16_t i, const DROPDOWN *UNUSED(dm)) { ui_rescale(i + 5); } static void dropdown_language_onselect(uint16_t i, const DROPDOWN *UNUSED(dm)) { settings.language = (UTOX_LANG)i; /* The draw functions need the fonts' and scale to be reset when changing languages. */ ui_rescale(ui_scale); } static STRING *dropdown_language_ondisplay(uint16_t i, const DROPDOWN *UNUSED(dm)) { UTOX_LANG tmp_language = (UTOX_LANG)i; return SPTRFORLANG(tmp_language, STR_LANG_NATIVE_NAME); } static void dropdown_theme_onselect(const uint16_t i, const DROPDOWN *UNUSED(dm)) { theme_load(i); settings.theme = i; } #include"../groups.h" static void dropdown_notify_groupchats_onselect(const uint16_t i, const DROPDOWN *UNUSED(dm)) { GROUPCHAT *g = flist_get_groupchat(); if (!g) { LOG_ERR("Settings", "Could not get selected groupchat."); return; } g->notify = i; LOG_INFO("Settings", "g->notify = %u\n", i); } static void dropdown_global_group_notifications_onselect(const uint16_t i, const DROPDOWN *UNUSED(dm)) { settings.group_notifications = i; } static UTOX_I18N_STR dpidrops[] = { STR_DPI_TINY, STR_DPI_060, STR_DPI_070, STR_DPI_080, STR_DPI_090, STR_DPI_NORMAL, STR_DPI_110, STR_DPI_120, STR_DPI_130, STR_DPI_140, STR_DPI_BIG, STR_DPI_160, STR_DPI_170, STR_DPI_180, STR_DPI_190, STR_DPI_LARGE, STR_DPI_210, STR_DPI_220, STR_DPI_230, STR_DPI_240, STR_DPI_HUGE, }; DROPDOWN dropdown_audio_in = { .ondisplay = dropdown_list_ondisplay, .onselect = dropdown_audio_in_onselect }; DROPDOWN dropdown_audio_out = { .ondisplay = dropdown_list_ondisplay, .onselect = dropdown_audio_out_onselect }; DROPDOWN dropdown_video = { .ondisplay = dropdown_list_ondisplay, .onselect = dropdown_video_onselect, }; DROPDOWN dropdown_dpi = { .ondisplay = simple_dropdown_ondisplay, .onselect = dropdown_dpi_onselect, .dropcount = COUNTOF(dpidrops), .userdata = dpidrops }; DROPDOWN dropdown_language = { .panel = { .type = PANEL_DROPDOWN, .x = 10, .y = 30, .width = -10, .height = 24 }, .ondisplay = dropdown_language_ondisplay, .onselect = dropdown_language_onselect, .dropcount = NUM_LANGS, }; static UTOX_I18N_STR themedrops[] = { STR_THEME_DEFAULT, STR_THEME_LIGHT, STR_THEME_DARK, STR_THEME_HIGHCONTRAST, STR_THEME_CUSTOM, STR_THEME_ZENBURN, STR_THEME_SOLARIZED_LIGHT, STR_THEME_SOLARIZED_DARK, }; DROPDOWN dropdown_theme = { .ondisplay = simple_dropdown_ondisplay, .onselect = dropdown_theme_onselect, .dropcount = COUNTOF(themedrops), .userdata = themedrops }; static UTOX_I18N_STR notifydrops[] = { STR_GROUP_NOTIFICATIONS_OFF, STR_GROUP_NOTIFICATIONS_MENTION, STR_GROUP_NOTIFICATIONS_ON, }; DROPDOWN dropdown_notify_groupchats = { .panel = { .type = PANEL_DROPDOWN, .x = 10, .y = 138, .width = 100, .height = 24 }, .ondisplay = simple_dropdown_ondisplay, .onselect = dropdown_notify_groupchats_onselect, .dropcount = COUNTOF(notifydrops), .userdata = notifydrops }; DROPDOWN dropdown_global_group_notifications = { .ondisplay = simple_dropdown_ondisplay, .onselect = dropdown_global_group_notifications_onselect, .dropcount = COUNTOF(notifydrops), .userdata = notifydrops }; static char edit_name_data[128], edit_status_msg_data[128], edit_proxy_ip_data[256], edit_proxy_port_data[8], edit_video_fps_data[3 + 1], /* range is [1-255] */ edit_profile_password_data[65535], edit_nospam_data[(sizeof(uint32_t) * 2) + 1] = { 0 }; #ifdef ENABLE_MULTIDEVICE static char edit_add_self_device_data[TOX_ADDRESS_SIZE * 4]; #endif static void edit_name_onenter(EDIT *edit) { char * data = edit->data; uint16_t length = edit->length; memcpy(self.name, data, length); self.name_length = length; update_tray(); postmessage_toxcore(TOX_SELF_SET_NAME, length, 0, self.name); } EDIT edit_name = { .data = edit_name_data, .data_size = sizeof edit_name_data, .onenter = edit_name_onenter, .onlosefocus = edit_name_onenter, }; static void edit_status_msg_onenter(EDIT *edit) { char * data = edit->data; uint16_t length = edit->length; if (length) { length = (length <= TOX_MAX_STATUS_MESSAGE_LENGTH) ? length : TOX_MAX_STATUS_MESSAGE_LENGTH; memcpy(self.statusmsg, data, length); self.statusmsg_length = length; } else { self.statusmsg_length = length; } update_tray(); postmessage_toxcore(TOX_SELF_SET_STATUS, length, 0, self.statusmsg); //! } EDIT edit_status_msg = { .data = edit_status_msg_data, .data_size = sizeof edit_status_msg_data, .onenter = edit_status_msg_onenter, .onlosefocus = edit_status_msg_onenter, }; static void edit_proxy_ip_port_onlosefocus(EDIT *UNUSED(edit)) { edit_proxy_port.data[edit_proxy_port.length] = 0; settings.proxy_port = strtol((char *)edit_proxy_port.data, NULL, 0); if (memcmp(proxy_address, edit_proxy_ip.data, edit_proxy_ip.length) == 0 && proxy_address[edit_proxy_ip.length] == 0) { return; } memset(proxy_address, 0, 256); /* Magic number from toxcore */ memcpy(proxy_address, edit_proxy_ip.data, edit_proxy_ip.length); proxy_address[edit_proxy_ip.length] = 0; if (settings.use_proxy) { tox_settingschanged(); } } EDIT edit_proxy_ip = { .data = edit_proxy_ip_data, .data_size = sizeof edit_proxy_ip_data, .onlosefocus = edit_proxy_ip_port_onlosefocus, .empty_str = {.i18nal = STR_PROXY_EDIT_HINT_IP }, /* TODO .ontab = change to proxy port field */ }; EDIT edit_proxy_port = { .data = edit_proxy_port_data, .data_size = sizeof edit_proxy_port_data, .onlosefocus = edit_proxy_ip_port_onlosefocus, .empty_str = {.i18nal = STR_PROXY_EDIT_HINT_PORT }, }; EDIT edit_video_fps = { .data = edit_video_fps_data, .data_size = sizeof edit_video_fps_data, .onlosefocus = edit_video_fps_onlosefocus, /* .empty_str = {.i18nal = STR_PROXY_EDIT_HINT_PORT }, */ }; static void edit_profile_password_update(EDIT *UNUSED(edit)) { if (tox_thread_init) { postmessage_toxcore(TOX_SAVE, 0, 0, NULL); } } EDIT edit_profile_password = { .data_size = sizeof edit_profile_password_data, .data = edit_profile_password_data, // .onchange = edit_profile_password_update, .onlosefocus = edit_profile_password_update, .password = 1, }; EDIT edit_toxid = { .length = TOX_ADDRESS_SIZE * 2, .data = self.id_str, .readonly = 1, .noborder = 0, .select_completely = 1, }; static void edit_change_nospam_onenter(EDIT *edit) { char *endptr; edit_nospam_data[edit->length] = '\0'; long int nospam = strtol(edit_nospam_data, &endptr, 16); if (nospam == 0 || nospam < 0) { LOG_ERR("Nospam", "Invalid nospam value: %lu", nospam); return; } else if (endptr == edit_nospam_data) { LOG_ERR("Nospam", "No numbers found."); return; } postmessage_toxcore(TOX_SELF_CHANGE_NOSPAM, nospam, 0, NULL); } EDIT edit_nospam = { .data_size = sizeof edit_nospam_data, .data = edit_nospam_data, .noborder = false, .onenter = edit_change_nospam_onenter, .onlosefocus = edit_change_nospam_onenter, }; static char edit_add_new_device_to_self_data[TOX_ADDRESS_SIZE * 4]; static void edit_add_new_device_to_self_onenter(EDIT *UNUSED(edit)) { #ifdef ENABLE_MULTIDEVICE devices_self_add(edit_add_new_device_to_self.data, edit_add_new_device_to_self.length); #endif } EDIT edit_add_new_device_to_self = { .data = edit_add_new_device_to_self_data, .data_size = sizeof edit_add_new_device_to_self_data, .onenter = edit_add_new_device_to_self_onenter, }; uTox-0.17.1/src/layout/settings.h000066400000000000000000000057311354126257400166730ustar00rootroot00000000000000#ifndef LAYOUT_SETTINGS_H #define LAYOUT_SETTINGS_H typedef struct scrollable SCROLLABLE; extern SCROLLABLE scrollbar_settings; typedef struct panel PANEL; extern PANEL panel_settings_master, panel_settings_subheader, panel_settings_profile, panel_profile_password_settings, panel_settings_devices, panel_settings_ui, panel_settings_av, panel_settings_notifications, panel_settings_adv, panel_nospam_settings; extern PANEL panel_profile_password; typedef struct button BUTTON; extern BUTTON button_settings, button_settings_sub_profile, button_settings_sub_devices, button_settings_sub_net, button_settings_sub_ui, button_settings_sub_av, button_settings_sub_adv, button_settings_sub_notifications; extern BUTTON button_add_new_device_to_self; extern BUTTON button_callpreview, button_videopreview, button_copyid, button_show_qr, button_qr, button_lock_uTox, button_show_password_settings, button_change_nospam, button_revert_nospam, button_show_nospam; typedef struct uiswitch UISWITCH; extern UISWITCH /* User Interface Tab */ switch_save_chat_history, switch_close_to_tray, switch_start_in_tray, switch_auto_startup, switch_mini_contacts, switch_magic_sidebar, /* AV Tab */ switch_push_to_talk, switch_audio_filtering, /* Notifications Tab */ switch_audible_notifications, switch_status_notifications, switch_typing_notes, /* Advanced Tab */ switch_ipv6, switch_udp, switch_proxy, switch_proxy_force, switch_auto_update, switch_block_friend_requests; typedef struct dropdown DROPDOWN; extern DROPDOWN /* Profile */ dropdown_language, /* User interface */ dropdown_theme, dropdown_dpi, /* AV */ dropdown_audio_in, dropdown_audio_out, dropdown_video, /* Notifications */ dropdown_global_group_notifications; typedef struct edit EDIT; extern EDIT /* Profile */ edit_name, edit_status_msg, edit_toxid, /* Advanced */ edit_proxy_ip, edit_proxy_port, edit_profile_password, edit_nospam, /* Video */ edit_video_fps, /* MDevice */ edit_add_new_device_to_self; void reset_settings_controls(void); #endif // LAYOUT_SETTINGS_H uTox-0.17.1/src/layout/sidebar.c000066400000000000000000000164721354126257400164430ustar00rootroot00000000000000#include "sidebar.h" #include "settings.h" #include "friend.h" #include "../avatar.h" #include "../flist.h" #include "../macros.h" #include "../self.h" #include "../theme.h" #include "../tox.h" #include "../native/ui.h" #include "../ui.h" #include "../ui/draw.h" #include "../ui/scrollable.h" #include "../ui/edit.h" #include "../ui/button.h" #include "../ui/svg.h" #include // Scrollbar or friend list SCROLLABLE scrollbar_flist = { .panel = { .type = PANEL_SCROLLABLE, }, .color = C_SCROLL, .x = 2, .left = 1, .small = 1, }; static void draw_background_sidebar(int x, int y, int width, int height) { /* Friend list (roster) background */ drawrect(x, y, width, height, COLOR_BKGRND_LIST); /* Current user badge background */ drawrect(x, y, width, SCALE(70), COLOR_BKGRND_MENU); // TODO magic numbers are bad } /* Top left self interface Avatar, name, statusmsg, status icon */ static void draw_user_badge(int x, int y, int width, int UNUSED(height)) { if (tox_thread_init == UTOX_TOX_THREAD_INIT_SUCCESS) { /* Only draw the user badge if toxcore is running */ /*draw avatar or default image */ x += SCALE(SIDEBAR_PADDING); y += SCALE(SIDEBAR_PADDING); if (self_has_avatar()) { draw_avatar_image(self.avatar->img, x, y, self.avatar->width, self.avatar->height, BM_CONTACT_WIDTH, BM_CONTACT_WIDTH); } else { drawalpha(BM_CONTACT, x, y, BM_CONTACT_WIDTH, BM_CONTACT_WIDTH, COLOR_MENU_TEXT); } /* Draw online/all friends filter text. */ setcolor(!button_filter_friends.mouseover ? COLOR_MENU_TEXT_SUBTEXT : COLOR_MAIN_TEXT_HINT); setfont(FONT_STATUS); drawtextrange(x, width - SCALE(SIDEBAR_PADDING), y + SCALE(SIDEBAR_PADDING) + BM_CONTACT_WIDTH, flist_get_filter() ? S(FILTER_ONLINE) : S(FILTER_ALL), flist_get_filter() ? SLEN(FILTER_ONLINE) : SLEN(FILTER_ALL)); x += SCALE(SIDEBAR_PADDING) + BM_CONTACT_WIDTH; /* Draw name */ setcolor(!button_name.mouseover ? COLOR_MENU_TEXT : COLOR_MENU_TEXT_SUBTEXT); setfont(FONT_SELF_NAME); drawtextrange(x, width - SCALE(SIDEBAR_PADDING * 5), y + SCALE(SIDEBAR_PADDING), self.name, self.name_length); /*&Draw current status message @TODO: separate these colors if needed (COLOR_MAIN_TEXT_HINT) */ setcolor(!button_status_msg.mouseover ? COLOR_MENU_TEXT_SUBTEXT : COLOR_MAIN_TEXT_HINT); setfont(FONT_STATUS); drawtextrange(x, width - SCALE(SIDEBAR_PADDING * 5), y + SCALE(SIDEBAR_PADDING * 4), self.statusmsg, self.statusmsg_length); /* Draw status button icon */ drawalpha(BM_STATUSAREA, width - BM_STATUSAREA_WIDTH - SCALE(SIDEBAR_PADDING), y + SCALE(SIDEBAR_PADDING), BM_STATUSAREA_WIDTH, BM_STATUSAREA_HEIGHT, button_usr_state.mouseover ? COLOR_BKGRND_LIST_HOVER : COLOR_BKGRND_LIST); uint8_t status = tox_connected ? self.status : 3; drawalpha(BM_ONLINE + status, width - BM_STATUS_WIDTH - BM_STATUSAREA_WIDTH / 2 - SCALE(1), y + SCALE(SIDEBAR_PADDING) + BM_STATUSAREA_HEIGHT / 2 - BM_STATUS_WIDTH / 2, BM_STATUS_WIDTH, BM_STATUS_WIDTH, status_color[status]); } else { drawalpha(BM_CONTACT, SCALE(SIDEBAR_PADDING), SIDEBAR_AVATAR_TOP, BM_CONTACT_WIDTH, BM_CONTACT_WIDTH, COLOR_MENU_TEXT); setcolor(!button_name.mouseover ? COLOR_MENU_TEXT : COLOR_MENU_TEXT_SUBTEXT); setfont(FONT_SELF_NAME); drawtextrange(SCALE(SIDEBAR_NAME_LEFT), SCALE(230) - SCALE(SIDEBAR_PADDING), SIDEBAR_NAME_TOP, S(NOT_CONNECTED), SLEN(NOT_CONNECTED)); // TODO rm magic number if (tox_thread_init == UTOX_TOX_THREAD_INIT_ERROR) { setcolor(!button_status_msg.mouseover ? COLOR_MENU_TEXT_SUBTEXT : COLOR_MAIN_TEXT_HINT); setfont(FONT_STATUS); drawtextrange(SIDEBAR_STATUSMSG_LEFT, SCALE(230), SIDEBAR_STATUSMSG_TOP, S(NOT_CONNECTED_SETTINGS), SLEN(NOT_CONNECTED_SETTINGS)); // TODO rm magic number } } } /* Left side bar, holds the user, the roster, and the setting buttons */ PANEL panel_side_bar = { .type = PANEL_NONE, .disabled = 0, .drawfunc = draw_background_sidebar, .width = 230, .child = (PANEL*[]) { &panel_self, &panel_quick_buttons, &panel_flist, NULL } }, /* The user badge and buttons */ panel_self = { .type = PANEL_NONE, .disabled = 0, .drawfunc = draw_user_badge, .child = (PANEL*[]) { (PANEL*)&button_avatar, (PANEL*)&button_name, (PANEL*)&button_usr_state, (PANEL*)&button_status_msg, NULL } }, /* Left sided toggles */ panel_quick_buttons = { .type = PANEL_NONE, .disabled = 0, .child = (PANEL*[]) { (PANEL*)&button_filter_friends, /* Top of roster */ (PANEL*)&edit_search, /* Bottom of roster*/ (PANEL*)&button_settings, (PANEL*)&button_add_new_contact, NULL } }, /* The friends and group was called list */ panel_flist = { .type = PANEL_NONE, .disabled = 0, .child = (PANEL*[]) { // TODO rename these &panel_flist_list, (PANEL*)&scrollbar_flist, NULL } }, panel_flist_list = { .type = PANEL_LIST, .content_scroll = &scrollbar_flist, }; #include "../friend.h" static void e_search_onchange(EDIT *edit) { char *data = edit->data; uint16_t length = edit->length > sizeof search_data ? sizeof search_data - 1 : edit->length; if (length) { button_add_new_contact.panel.disabled = 0; button_add_new_contact.nodraw = 0; button_settings.panel.disabled = 1; button_settings.nodraw = 1; memcpy(search_data, data, length); search_data[length] = 0; flist_search((char *)search_data); } else { button_add_new_contact.panel.disabled = 1; button_add_new_contact.nodraw = 1; button_settings.panel.disabled = 0; button_settings.nodraw = 0; flist_search(NULL); } redraw(); } static void e_search_onenter(EDIT *edit) { char * data = edit->data; uint16_t length = edit->length; if (length == 76) { // FIXME, this should be error checked! // No, srsly... this is lucky, not right. friend_add(data, length, (char *)"", 0); edit_setstr(&edit_search, (char *)"", 0); } else { if (tox_thread_init == UTOX_TOX_THREAD_INIT_SUCCESS) { /* Only change if we're logged in! */ edit_setstr(&edit_add_new_friend_id, data, length); edit_setstr(&edit_search, (char *)"", 0); flist_selectaddfriend(); edit_setfocus(&edit_add_new_friend_msg); } } return; } static char e_search_data[1024]; EDIT edit_search = { .data = e_search_data, .data_size = sizeof e_search_data, .onchange = e_search_onchange, .onenter = e_search_onenter, .style = AUXILIARY_STYLE, .vcentered = true, .empty_str = { .i18nal = STR_CONTACT_SEARCH_ADD_HINT }, }; uTox-0.17.1/src/layout/sidebar.h000066400000000000000000000012011354126257400164300ustar00rootroot00000000000000#ifndef LAYOUT_SIDEBAR_H #define LAYOUT_SIDEBAR_H typedef struct scrollable SCROLLABLE; extern SCROLLABLE scrollbar_flist; typedef struct panel PANEL; extern PANEL panel_side_bar, panel_self, panel_flist, panel_flist_list, panel_quick_buttons, panel_lower_buttons; typedef struct button BUTTON; extern BUTTON button_avatar, button_name, button_status_msg, button_usr_state, button_filter_friends, button_add_new_contact; typedef struct edit EDIT; extern EDIT edit_search; #endif //LAYOUT_SIDEBAR_H uTox-0.17.1/src/layout/tray.c000066400000000000000000000020741354126257400160020ustar00rootroot00000000000000#include "tray.h" #include "../macros.h" #include "../theme.h" #include "../ui/button.h" #include "../ui/draw.h" #include "../ui/panel.h" #include "../ui/text.h" static void tray_draw(int x, int y, int w, int h) { drawrect(x, y, w, h, COLOR_BKGRND_MAIN); draw_rect_frame(x, y, w, h, 0); setcolor(COLOR_MENU_TEXT); setfont(FONT_SELF_NAME); drawtext(SCALE(5), SCALE(5), "This is a test of the new uTox popup", 36); } PANEL panel_tray = { .type = PANEL_NONE, .drawfunc = tray_draw, .disabled = 0, .child = (PANEL*[]) { (PANEL*) &btn_tray_exit, NULL, } }; static void tray_exit(void) { LOG_FATAL_ERR(EXIT_SUCCESS, "Layout Notify", "Exit pressed"); } BUTTON btn_tray_exit = { .panel = { .type = PANEL_BUTTON, .x = 5, .y = 5, .width = 270, .height = 40, }, // .bm_fill = BM_SBUTTON, .update = button_setcolors_success, .on_mup = tray_exit, .nodraw = false, .button_text = {.i18nal = STR_EXIT }, .tooltip_text = {.i18nal = STR_EXIT }, }; uTox-0.17.1/src/layout/tray.h000066400000000000000000000002671354126257400160110ustar00rootroot00000000000000#ifndef LAYOUT_TRAY_H #define LAYOUT_TRAY_H typedef struct panel PANEL; extern PANEL panel_tray; typedef struct button BUTTON; extern BUTTON btn_tray_exit; #endif // LAYOUT_TRAY_H uTox-0.17.1/src/layout/userbadge.c000066400000000000000000000074021354126257400167640ustar00rootroot00000000000000#include "userbadge.h" #include "settings.h" #include "../avatar.h" #include "../flist.h" #include "../macros.h" #include "../self.h" #include "../tox.h" #include "../native/dialog.h" #include "../ui/button.h" #include "../ui/contextmenu.h" #include "../ui/edit.h" /* On-press functions followed by the update functions when needed... */ static void button_avatar_on_mup(void) { if (tox_thread_init == UTOX_TOX_THREAD_INIT_SUCCESS) { openfileavatar(); } } static void button_name_on_mup(void) { flist_selectsettings(); if (tox_thread_init != UTOX_TOX_THREAD_INIT_SUCCESS) { // jump to the network settings when unable to create tox instance panel_settings_adv.disabled = false; panel_settings_profile.disabled = true; panel_settings_devices.disabled = true; panel_settings_ui.disabled = true; panel_settings_av.disabled = true; panel_settings_notifications.disabled = true; } else { panel_settings_profile.disabled = false; panel_settings_devices.disabled = true; panel_settings_ui.disabled = true; panel_settings_av.disabled = true; panel_settings_adv.disabled = true; panel_settings_notifications.disabled = true; edit_setfocus(&edit_name); } } static void button_statusmsg_on_mup(void) { flist_selectsettings(); if (tox_thread_init != UTOX_TOX_THREAD_INIT_SUCCESS) { // jump to the network settings when unable to create tox instance panel_settings_adv.disabled = false; panel_settings_profile.disabled = true; panel_settings_devices.disabled = true; panel_settings_ui.disabled = true; panel_settings_av.disabled = true; panel_settings_notifications.disabled = true; } else { panel_settings_profile.disabled = false; panel_settings_devices.disabled = true; panel_settings_ui.disabled = true; panel_settings_av.disabled = true; panel_settings_adv.disabled = true; panel_settings_notifications.disabled = true; edit_setfocus(&edit_status_msg); } } #ifdef UNITY #include "xlib/mmenu.h" extern bool unity_running; #endif static void button_status_on_mup(void) { self.status++; if (self.status == 3) { // TODO typedef enum self.status = 0; } #ifdef UNITY if (unity_running) { mm_set_status(self.status); } #endif postmessage_toxcore(TOX_SELF_SET_STATE, self.status, 0, NULL); } static void contextmenu_avatar_onselect(uint8_t i) { if (i == 0) { avatar_delete_self(); } } static void button_avatar_onright(void) { if (self_has_avatar()) { static UTOX_I18N_STR menu[] = { STR_REMOVE }; contextmenu_new(COUNTOF(menu), menu, contextmenu_avatar_onselect); } } BUTTON button_avatar = { .nodraw = true, .on_mup = button_avatar_on_mup, .onright = button_avatar_onright, }; BUTTON button_name = { .nodraw = true, .on_mup = button_name_on_mup, }; BUTTON button_status_msg = { .nodraw = true, .on_mup = button_statusmsg_on_mup, }; BUTTON button_usr_state = { .nodraw = true, .on_mup = button_status_on_mup, .tooltip_text = { .i18nal = STR_STATUS }, }; static void button_filter_friends_on_mup(void) { // this only works because right now there are only 2 filters // (none or online), basically a bool flist_set_filter(!flist_get_filter()); } BUTTON button_filter_friends = { .nodraw = true, .on_mup = button_filter_friends_on_mup, .tooltip_text = {.i18nal = STR_FILTER_CONTACT_TOGGLE }, }; uTox-0.17.1/src/layout/userbadge.h000066400000000000000000000006131354126257400167660ustar00rootroot00000000000000#ifndef LAYOUT_USERBADGE_H #define LAYOUT_USERBADGE_H typedef struct button BUTTON; extern BUTTON button_avatar, button_name, button_status_msg, button_usr_state, button_filter_friends; typedef struct edit EDIT; extern EDIT edit_search, edit_add_new_friend, edit_add_new_friend_msg; #endif // LAYOUT_USERBADGE_H uTox-0.17.1/src/logging.c000066400000000000000000000007471354126257400151410ustar00rootroot00000000000000#include "debug.h" #include "settings.h" #include #include int utox_verbosity() { return settings.verbose; } #ifndef __ANDROID__ // Android needs to provide it's own logging functions void debug(const char *fmt, ...){ if (!settings.debug_file) { return; } va_list list; va_start(list, fmt); vfprintf(settings.debug_file, fmt, list); va_end(list); #ifdef __WIN32__ fflush(settings.debug_file); #endif } #endif uTox-0.17.1/src/macros.h000066400000000000000000000020231354126257400147710ustar00rootroot00000000000000#ifndef MACROS_H #define MACROS_H #ifndef MIN // Windows or muslc likes to be broken #define MIN(a,b) (((a)<(b))?(a):(b)) #else #include // Provides MAX/MIN #endif #ifndef MAX // Windows or muslc likes to be broken #define MAX(a,b) (((a)>(b))?(a):(b)) #else #include // Provides MAX/MIN #endif // True if x and y are within the supplied rectangle #define inrect(x, y, rx, ry, width, height) \ ((x) >= (rx) && (y) >= (ry) && (x) < ((rx) + (width)) && (y) < ((ry) + (height))) // This is hacky and almost never better, try to use an alternative. #define strcpy2(x, y) (memcpy(x, y, sizeof(y) - 1)) // Is the video stream just a selection of the desktop #define isdesktop(x) ((size_t)(x) == 1) #define COUNTOF(x) (sizeof(x) / sizeof(*(x))) // Wrap var in UNUSED(var) to correctly suppress warnings #ifdef UNUSED #undef UNUSED #endif #ifdef __GNUC__ #define UNUSED(x) UNUSED_##x __attribute__((__unused__)) #elif defined(__LCLINT__) #define UNUSED(x) /*@unused@*/ x #else #define UNUSED(x) x #endif #endif uTox-0.17.1/src/main.c000066400000000000000000000244541354126257400144400ustar00rootroot00000000000000#include "main.h" #include "debug.h" #include "settings.h" #include "theme.h" #include "updater.h" #include "native/filesys.h" #include "native/main.h" #include "native/thread.h" #include "av/utox_av.h" #include #include #include /* The utox_ functions contained in src/main.c are wrappers for the platform native_ functions * if you need to localize them to a specific platform, move them from here, to each * src//main.x and change from utox_ to native_ */ bool utox_data_save_tox(uint8_t *data, size_t length) { FILE *fp = utox_get_file("tox_save.tox", NULL, UTOX_FILE_OPTS_WRITE); if (!fp) { LOG_ERR("uTox", "Can not open tox_save.tox to write to it."); return true; } if (fwrite(data, length, 1, fp) != 1) { LOG_ERR("uTox", "Unable to write Tox save to file."); fclose(fp); return true; } flush_file(fp); fclose(fp); return false; } uint8_t *utox_data_load_tox(size_t *size) { const char name[][20] = { "tox_save.tox", "tox_save.tox.atomic", "tox_save.tmp", "tox_save" }; for (uint8_t i = 0; i < 4; i++) { size_t length = 0; FILE *fp = utox_get_file(name[i], &length, UTOX_FILE_OPTS_READ); if (!fp) { continue; } uint8_t *data = calloc(1, length + 1); if (!data) { LOG_ERR("uTox", "Could not allocate memory for tox save."); fclose(fp); // Quit. We're out of memory, calloc will fail again. return NULL; } if (fread(data, length, 1, fp) != 1) { LOG_ERR("uTox", "Could not read: %s.", name[i]); fclose(fp); free(data); // Return NULL, because if a Tox save exits we don't want to fall // back to an old version, we need the user to decide what to do. return NULL; } fclose(fp); *size = length; return data; } return NULL; } bool utox_data_save_ftinfo(char hex[TOX_PUBLIC_KEY_SIZE * 2], uint8_t *data, size_t length) { char name[TOX_PUBLIC_KEY_SIZE * 2 + sizeof(".ftinfo")]; snprintf(name, sizeof(name), "%.*s.ftinfo", TOX_PUBLIC_KEY_SIZE * 2, hex); FILE *fp = utox_get_file(name, NULL, UTOX_FILE_OPTS_WRITE); if (fp == NULL) { return false; } if (fwrite(data, length, 1, fp) != 1) { LOG_ERR("uTox", "Unable to write ftinfo to file."); fclose(fp); return false; } fclose(fp); return true; } /* Shared function between all four platforms */ void parse_args(int argc, char *argv[], bool *skip_updater, int8_t *should_launch_at_startup, int8_t *set_show_window, bool *allow_root ) { // set default options if (skip_updater) { *skip_updater = false; } if (should_launch_at_startup) { *should_launch_at_startup = 0; } if (set_show_window) { *set_show_window = 0; } if (allow_root) { *allow_root = false; } static struct option long_options[] = { { "theme", required_argument, NULL, 't' }, { "portable", no_argument, NULL, 'p' }, { "set", required_argument, NULL, 's' }, { "unset", required_argument, NULL, 'u' }, { "skip-updater", no_argument, NULL, 'N' }, { "delete-updater", required_argument, NULL, 'D'}, { "version", no_argument, NULL, 0 }, { "silent", no_argument, NULL, 'S' }, { "verbose", no_argument, NULL, 'v' }, { "help", no_argument, NULL, 'h' }, { "debug", required_argument, NULL, 1 }, { "allow-root", no_argument, NULL, 2 }, { 0, 0, 0, 0 } }; settings.debug_file = stdout; int opt, long_index = 0; while ((opt = getopt_long(argc, argv, "t:ps:u:nvh", long_options, &long_index)) != -1) { // loop through each option; ":" after each option means an argument is required switch (opt) { case 't': { if (!strcmp(optarg, "default")) { settings.theme = THEME_DEFAULT; } else if (!strcmp(optarg, "dark")) { settings.theme = THEME_DARK; } else if (!strcmp(optarg, "light")) { settings.theme = THEME_LIGHT; } else if (!strcmp(optarg, "highcontrast")) { settings.theme = THEME_HIGHCONTRAST; } else if (!strcmp(optarg, "zenburn")) { settings.theme = THEME_ZENBURN; } else if (!strcmp(optarg, "solarized-light")) { settings.theme = THEME_SOLARIZED_LIGHT; } else if (!strcmp(optarg, "solarized-dark")) { settings.theme = THEME_SOLARIZED_DARK; } else { LOG_NORM("Please specify correct theme (please check user manual for list of correct values).\n"); exit(EXIT_FAILURE); } break; } case 'p': { LOG_INFO("uTox", "Launching uTox in portable mode: All data will be saved to the tox folder in the current " "working directory\n"); settings.portable_mode = 1; break; } case 's': { if (!strcmp(optarg, "start-on-boot")) { if (should_launch_at_startup) { *should_launch_at_startup = 1; } } else if (!strcmp(optarg, "show-window")) { if (set_show_window) { *set_show_window = 1; } } else if (!strcmp(optarg, "hide-window")) { if (set_show_window) { *set_show_window = -1; } } else { LOG_NORM("Please specify a correct set option (please check user manual for list of correct values).\n"); exit(EXIT_FAILURE); } break; } case 'u': { if (!strcmp(optarg, "start-on-boot")) { if (should_launch_at_startup) { *should_launch_at_startup = -1; } } else { LOG_NORM("Please specify a correct unset option (please check user manual for list of correct values).\n"); exit(EXIT_FAILURE); } break; } case 'N': { if (skip_updater) { *skip_updater = true; } break; } case 'D': { if (strstr(optarg, "uTox_updater")) { // We're using the windows version of strstr() here // because it's currently the only platform supported // by the updater. // TODO expose this as a function in updater.c remove(optarg); } break; } case 0: { LOG_NORM("uTox version: %s\n", VERSION); #ifdef GIT_VERSION LOG_NORM("git version %s\n", GIT_VERSION); #endif exit(EXIT_SUCCESS); break; } case 'S': { settings.verbose = LOG_LVL_FATAL; break; } case 'v': { settings.verbose++; break; } case 1: { settings.debug_file = fopen(optarg, "a+"); if (!settings.debug_file) { settings.debug_file = stdout; LOG_NORM("Could not open %s. Logging to stdout.\n", optarg); } break; } case 2: { if (allow_root) { *allow_root = true; } break; } case 'h': { LOG_NORM("µTox - Lightweight Tox client version %s.\n\n", VERSION); LOG_NORM("The following options are available:\n"); LOG_NORM(" -t --theme= Specify a UI theme, where can be one of default, " "dark, light, highcontrast, zenburn.\n"); LOG_NORM(" -p --portable Launch in portable mode: All data will be saved to the tox " "folder in the current working directory.\n"); LOG_NORM(" -s --set=